Advertisement
Guest User

Untitled

a guest
May 29th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.89 KB | None | 0 0
  1. from tkinter import Tk
  2. from tkinter.filedialog import askopenfilename
  3.  
  4. # progress bar display command line function for later
  5. def printProgressBar (iteration, total, prefix = '', decimals = 1, length = 100,
  6. fill = '█'):
  7.     """
  8.    Call in a loop to create terminal progress bar
  9.    @params:
  10.        iteration   - Required  : current iteration (Int)
  11.        total       - Required  : total iterations (Int)
  12.        prefix      - Optional  : prefix string (Str)
  13.        suffix      - Optional  : suffix string (Str)
  14.        decimals    - Optional  : positive number of decimals in percent complete (Int)
  15.        length      - Optional  : character length of bar (Int)
  16.        fill        - Optional  : bar fill character (Str)
  17.    """
  18.     percent = ("{0:." + str(decimals) + "f}").format(100 *
  19.     (iteration / float(total)))
  20.     filledLength = int(length * iteration // total)
  21.     bar = fill * filledLength + '-' * (length - filledLength)
  22.     print('\r%s |%s| %s%%' % (prefix, bar, percent), end = '\r')
  23.     # Print New Line on Complete
  24.     if iteration == total:
  25.         print()
  26.  
  27.  
  28. # prompt user for file selection
  29. root = Tk( )
  30. root.title("OBJ")
  31. filepath = askopenfilename(initialdir="Users/",
  32.                            filetypes =(("Wavefront Object File", "*.obj"),
  33.                            ("All Files","*.*")),
  34.                            title = "Choose a .obj file."
  35.                            )
  36.  
  37.  
  38. import os
  39. import numpy as np
  40. from numpy import array
  41. import errno
  42.  
  43.  
  44. # the obj file
  45. fyle = open(filepath,"r")
  46.  
  47. # the name (without extension) of the selected file
  48. filename = os.path.basename(os.path.splitext(filepath)[0])
  49.  
  50. # the text we want to work with
  51. lines = fyle.readlines()
  52. # lines are saved to memory so we can close the .obj
  53. fyle.close()
  54.  
  55. # function for writing generic .mat and .det files
  56. def writeMatFileAndDetFile(name):
  57.     mat_file = open(name + ".mat", "w")
  58.     mat_file.write("c ========================================================")
  59.     mat_file.write("==================== \n")
  60.     mat_file.write("c \n")
  61.     mat_file.write("c                          MATERIAL \n")
  62.     mat_file.write("c \n")
  63.     mat_file.write("c      File         : " + name + ".mat \n")
  64.     mat_file.write("c      Created for OBJ Model Translation \n")
  65.     mat_file.write("c \n")
  66.     mat_file.write("c ========================================================")
  67.     mat_file.write("==================== \n")
  68.     mat_file.write("\n")
  69.     mat_file.write("*materials / \n")
  70.     mat_file.write("ALUMINUM Al /   1\n")
  71.     mat_file.close()
  72.    
  73.     det_file = open(name + ".det", "w")
  74.     det_file.write("c ========================================================")
  75.     det_file.write("==================== \n")
  76.     det_file.write("c \n")
  77.     det_file.write("c                          DETECTOR \n")
  78.     det_file.write("c \n")
  79.     det_file.write("c      File         : " + name + ".det \n")
  80.     det_file.write("c      Created for OBJ Model Translation \n")
  81.     det_file.write("c \n")
  82.     det_file.write("c ========================================================")
  83.     det_file.write("==================== \n")
  84.     det_file.write("\n")
  85.     det_file.write("*materials / \n")
  86.     det_file.write("ALUMINUM Al /   1\n")
  87.     det_file.close()
  88.  
  89.  
  90. # count number of distinct objects (cubes)
  91. o = 0
  92. for line in lines:
  93.     if line[0] == "o":
  94.         o += 1
  95. print("number of cubes =", o)
  96.  
  97.  
  98. # generate array with size = number of cubes
  99. vec = array([0.0] * 3)
  100. arr = array([vec] * 8)
  101. cube = array([arr] * o)
  102. # each element of cube is an array of
  103. # the 8 co-ordinates that make up the cube
  104. i = -1
  105. j = 0
  106. for line in lines:
  107.     vec_line = line.split(" ")
  108.     if line[0] == "o":
  109.         i += 1
  110.         j = 0
  111.     if line[0] == "v" and line[1] == " ":
  112.         cube[i][j] = array([float(vec_line[1]),
  113.         float(vec_line[2]),float(vec_line[3])])
  114.         j += 1
  115.  
  116.  
  117. # helper functions for determining opposite corners of boxes
  118. def pythag(arr1,arr2):
  119.     return np.sqrt(pow(arr1[0]-arr2[0],2)
  120.                     + pow(arr1[1]-arr2[1],2)
  121.                     + pow(arr1[2]-arr2[2],2))
  122.  
  123. diags = [0] * 7
  124.  
  125. for j in range(len(cube[0]) - 1):
  126.     diags[j] = pythag(cube[0][0], cube[0][j + 1])
  127.  
  128. dindex = diags.index(max(diags)) + 1
  129. diag = max(diags)
  130. side = min(diags)
  131.  
  132. # cube[i][0] and cube[i][dindex] are opposite corners of the ith cube
  133. # these are the only values needed to make NOVICE boxes
  134. # ***NEGATIVE DIMENSION ERRORS MEAN THIS IS SOMEHOW NOT TRUE***
  135. #   >probably means the .obj cubes are inconsistently formatted
  136.  
  137.  
  138. ################################################################################
  139. # code for fixing co-ordinate accuracy problem
  140. # uses 'Decimal' format to limit (in)accuracy of numbers
  141. from decimal import Decimal, getcontext
  142.  
  143. # c1[i] is the corner opposite c2[i] for the ith cube
  144. c1 = cube[:,0]
  145. c2 = cube[:,dindex]
  146. cs = np.zeros([len(c1),6])
  147.  
  148. # cs has format [x1 y1 z1 x2 y2 z2]
  149. for i in range(6):
  150.     if i<3:
  151.         cs[:,i] = c1[:,i]
  152.     else:
  153.         cs[:,i] = c2[:,i-3]
  154.  
  155. # csd is the array cs but with elements cast as decimal with 6 d.p.
  156. csd = [[]*6] * len(cs)
  157. for i in range(len(cs)):
  158.     csd[i] = [Decimal(member).quantize(Decimal('1.000000')) for member in cs[i]]
  159.  
  160. # convert back to numpy array
  161. csd = array(csd)
  162.  
  163. xmin = min(csd[:,0] + csd[:,3])
  164. xmax = max(csd[:,0] + csd[:,3])
  165. ymin = min(csd[:,1] + csd[:,4])
  166. ymax = max(csd[:,1] + csd[:,4])
  167. zmin = min(csd[:,2] + csd[:,5])
  168. zmax = max(csd[:,2] + csd[:,5])
  169. # round side to work with grid
  170. side = Decimal(side).quantize(Decimal('1.000000'))
  171. print("cube size =", side)
  172.  
  173. # create grid arrays starting from min dimensions
  174. xgrid = [xmin]
  175. ygrid = [ymin]
  176. zgrid = [zmin]
  177.  
  178. i = 0
  179. while xgrid[i] < xmax:
  180.     xgrid.append(xgrid[i] + side)
  181.     i += 1
  182. i = 0
  183. while ygrid[i] < ymax:
  184.     ygrid.append(ygrid[i] + side)
  185.     i += 1
  186. i = 0
  187. while zgrid[i] < zmax:
  188.     zgrid.append(zgrid[i] + side)
  189.     i += 1
  190. i = 0 # just in case
  191.  
  192.  
  193. # go through array csd and change every number to closest match in grid
  194. from operator import itemgetter
  195.  
  196. def mindex(a):
  197.     return min(enumerate(abs(a)), key=itemgetter(1))[0]
  198.  
  199. for i in range(len(csd)):
  200.     xidx1 = mindex(array(xgrid) - csd[:,0][i])
  201.     xidx2 = mindex(array(xgrid) - csd[:,3][i])
  202.  
  203.     yidx1 = mindex(array(ygrid) - csd[:,1][i])
  204.     yidx2 = mindex(array(ygrid) - csd[:,4][i])
  205.  
  206.     zidx1 = mindex(array(zgrid) - csd[:,2][i])
  207.     zidx2 = mindex(array(zgrid) - csd[:,5][i])
  208.  
  209.     csd[:,0][i] = xgrid[xidx1]
  210.     csd[:,3][i] = xgrid[xidx2]
  211.  
  212.     csd[:,1][i] = ygrid[yidx1]
  213.     csd[:,4][i] = ygrid[yidx2]
  214.  
  215.     csd[:,2][i] = zgrid[zidx1]
  216.     csd[:,5][i] = zgrid[zidx2]
  217.  
  218.  
  219.  
  220. ################################################################################
  221. # code for simplifying the voxelated model into minimum number of boxes
  222.  
  223. x_range = max(xgrid) - min(xgrid)
  224. y_range = max(ygrid) - min(ygrid)
  225. z_range = max(zgrid) - min(zgrid)
  226.  
  227. ranges = [x_range, y_range, z_range]
  228. max_dim = np.argmax(ranges)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement