Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import Tk
- from tkinter.filedialog import askopenfilename
- # progress bar display command line function for later
- def printProgressBar (iteration, total, prefix = '', decimals = 1, length = 100,
- fill = '█'):
- """
- Call in a loop to create terminal progress bar
- @params:
- iteration - Required : current iteration (Int)
- total - Required : total iterations (Int)
- prefix - Optional : prefix string (Str)
- suffix - Optional : suffix string (Str)
- decimals - Optional : positive number of decimals in percent complete (Int)
- length - Optional : character length of bar (Int)
- fill - Optional : bar fill character (Str)
- """
- percent = ("{0:." + str(decimals) + "f}").format(100 *
- (iteration / float(total)))
- filledLength = int(length * iteration // total)
- bar = fill * filledLength + '-' * (length - filledLength)
- print('\r%s |%s| %s%%' % (prefix, bar, percent), end = '\r')
- # Print New Line on Complete
- if iteration == total:
- print()
- # prompt user for file selection
- root = Tk( )
- root.title("OBJ")
- filepath = askopenfilename(initialdir="Users/",
- filetypes =(("Wavefront Object File", "*.obj"),
- ("All Files","*.*")),
- title = "Choose a .obj file."
- )
- import os
- import numpy as np
- from numpy import array
- import errno
- # the obj file
- fyle = open(filepath,"r")
- # the name (without extension) of the selected file
- filename = os.path.basename(os.path.splitext(filepath)[0])
- # the text we want to work with
- lines = fyle.readlines()
- # lines are saved to memory so we can close the .obj
- fyle.close()
- # function for writing generic .mat and .det files
- def writeMatFileAndDetFile(name):
- mat_file = open(name + ".mat", "w")
- mat_file.write("c ========================================================")
- mat_file.write("==================== \n")
- mat_file.write("c \n")
- mat_file.write("c MATERIAL \n")
- mat_file.write("c \n")
- mat_file.write("c File : " + name + ".mat \n")
- mat_file.write("c Created for OBJ Model Translation \n")
- mat_file.write("c \n")
- mat_file.write("c ========================================================")
- mat_file.write("==================== \n")
- mat_file.write("\n")
- mat_file.write("*materials / \n")
- mat_file.write("ALUMINUM Al / 1\n")
- mat_file.close()
- det_file = open(name + ".det", "w")
- det_file.write("c ========================================================")
- det_file.write("==================== \n")
- det_file.write("c \n")
- det_file.write("c DETECTOR \n")
- det_file.write("c \n")
- det_file.write("c File : " + name + ".det \n")
- det_file.write("c Created for OBJ Model Translation \n")
- det_file.write("c \n")
- det_file.write("c ========================================================")
- det_file.write("==================== \n")
- det_file.write("\n")
- det_file.write("*materials / \n")
- det_file.write("ALUMINUM Al / 1\n")
- det_file.close()
- # count number of distinct objects (cubes)
- o = 0
- for line in lines:
- if line[0] == "o":
- o += 1
- print("number of cubes =", o)
- # generate array with size = number of cubes
- vec = array([0.0] * 3)
- arr = array([vec] * 8)
- cube = array([arr] * o)
- # each element of cube is an array of
- # the 8 co-ordinates that make up the cube
- i = -1
- j = 0
- for line in lines:
- vec_line = line.split(" ")
- if line[0] == "o":
- i += 1
- j = 0
- if line[0] == "v" and line[1] == " ":
- cube[i][j] = array([float(vec_line[1]),
- float(vec_line[2]),float(vec_line[3])])
- j += 1
- # helper functions for determining opposite corners of boxes
- def pythag(arr1,arr2):
- return np.sqrt(pow(arr1[0]-arr2[0],2)
- + pow(arr1[1]-arr2[1],2)
- + pow(arr1[2]-arr2[2],2))
- diags = [0] * 7
- for j in range(len(cube[0]) - 1):
- diags[j] = pythag(cube[0][0], cube[0][j + 1])
- dindex = diags.index(max(diags)) + 1
- diag = max(diags)
- side = min(diags)
- # cube[i][0] and cube[i][dindex] are opposite corners of the ith cube
- # these are the only values needed to make NOVICE boxes
- # ***NEGATIVE DIMENSION ERRORS MEAN THIS IS SOMEHOW NOT TRUE***
- # >probably means the .obj cubes are inconsistently formatted
- ################################################################################
- # code for fixing co-ordinate accuracy problem
- # uses 'Decimal' format to limit (in)accuracy of numbers
- from decimal import Decimal, getcontext
- # c1[i] is the corner opposite c2[i] for the ith cube
- c1 = cube[:,0]
- c2 = cube[:,dindex]
- cs = np.zeros([len(c1),6])
- # cs has format [x1 y1 z1 x2 y2 z2]
- for i in range(6):
- if i<3:
- cs[:,i] = c1[:,i]
- else:
- cs[:,i] = c2[:,i-3]
- # csd is the array cs but with elements cast as decimal with 6 d.p.
- csd = [[]*6] * len(cs)
- for i in range(len(cs)):
- csd[i] = [Decimal(member).quantize(Decimal('1.000000')) for member in cs[i]]
- # convert back to numpy array
- csd = array(csd)
- xmin = min(csd[:,0] + csd[:,3])
- xmax = max(csd[:,0] + csd[:,3])
- ymin = min(csd[:,1] + csd[:,4])
- ymax = max(csd[:,1] + csd[:,4])
- zmin = min(csd[:,2] + csd[:,5])
- zmax = max(csd[:,2] + csd[:,5])
- # round side to work with grid
- side = Decimal(side).quantize(Decimal('1.000000'))
- print("cube size =", side)
- # create grid arrays starting from min dimensions
- xgrid = [xmin]
- ygrid = [ymin]
- zgrid = [zmin]
- i = 0
- while xgrid[i] < xmax:
- xgrid.append(xgrid[i] + side)
- i += 1
- i = 0
- while ygrid[i] < ymax:
- ygrid.append(ygrid[i] + side)
- i += 1
- i = 0
- while zgrid[i] < zmax:
- zgrid.append(zgrid[i] + side)
- i += 1
- i = 0 # just in case
- # go through array csd and change every number to closest match in grid
- from operator import itemgetter
- def mindex(a):
- return min(enumerate(abs(a)), key=itemgetter(1))[0]
- for i in range(len(csd)):
- xidx1 = mindex(array(xgrid) - csd[:,0][i])
- xidx2 = mindex(array(xgrid) - csd[:,3][i])
- yidx1 = mindex(array(ygrid) - csd[:,1][i])
- yidx2 = mindex(array(ygrid) - csd[:,4][i])
- zidx1 = mindex(array(zgrid) - csd[:,2][i])
- zidx2 = mindex(array(zgrid) - csd[:,5][i])
- csd[:,0][i] = xgrid[xidx1]
- csd[:,3][i] = xgrid[xidx2]
- csd[:,1][i] = ygrid[yidx1]
- csd[:,4][i] = ygrid[yidx2]
- csd[:,2][i] = zgrid[zidx1]
- csd[:,5][i] = zgrid[zidx2]
- ################################################################################
- # code for simplifying the voxelated model into minimum number of boxes
- x_range = max(xgrid) - min(xgrid)
- y_range = max(ygrid) - min(ygrid)
- z_range = max(zgrid) - min(zgrid)
- ranges = [x_range, y_range, z_range]
- max_dim = np.argmax(ranges)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement