def _test_conversion(from_, to, mode, speedups): for name in from_.listdir(): source_file = from_.join(name) expected_file = to.join(name) if not expected_file.exists(): continue mesh = stl.StlMesh(source_file, speedups=speedups) with open(str(expected_file), 'rb') as expected_fh: expected = expected_fh.read() # For binary files, skip the header if mode is stl.BINARY: expected = expected[80:] with tempfile.TemporaryFile() as dest_fh: mesh.save(name, dest_fh, mode) # Go back to the beginning to read dest_fh.seek(0) dest = dest_fh.read() # For binary files, skip the header if mode is stl.BINARY: dest = dest[80:] assert dest.strip() == expected.strip()
def test_stl_mesh(ascii_file, tmpdir, speedups): tmp_file = tmpdir.join('tmp.stl') mesh = stl.StlMesh(ascii_file, speedups=speedups) with pytest.raises(ValueError): mesh.save(filename=str(tmp_file), mode='test') mesh.save(str(tmp_file)) mesh.save(str(tmp_file), update_normals=False)
def importStl(filename): part_path = sys.argv[2] mesh = stl.StlMesh(os.path.join(part_path, filename)) faces = [] vertices = [] vertices = mesh.points.reshape(-1, 3) points, uidx = np.unique(vertices, axis=0, return_inverse=True) faces = uidx.reshape(-1, 3) return points, faces
def read(self, f, assethandler=None, options=None): ''' Read mesh model in STL format ''' data = model.MeshData() #stl.MAX_COUNT = 1e10 p = stl.StlMesh(f) npoints = p.v0.shape[0] idx = numpy.array(range(0, npoints)) data.vertex = numpy.concatenate([p.v0, p.v1, p.v2]) data.vertex_index = numpy.vstack( [idx, idx + npoints, idx + 2 * npoints]).T return data
def test_mass_properties_for_moon(binary_ascii_path, speedups): ''' Checks the results of method get_mass_properties() on STL ASCII and binary files Moon.stl One checks the results obtained with stl with the ones obtained with meshlab ''' filename = binary_ascii_path.join('Moon.stl') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, cog, inertia = mesh.get_mass_properties() assert close([volume], [0.888723]) assert close(cog, [0.906913, 0.170731, 1.500001]) assert close( inertia, [[+0.562097, -0.000457, +0.000000], [-0.000457, +0.656851, +0.000000], [+0.000000, +0.000000, +0.112465]])
def test_mass_properties_for_half_donut(binary_ascii_path, speedups): ''' Checks the results of method get_mass_properties() on STL ASCII and binary files HalfDonut.stl One checks the results obtained with stl with the ones obtained with meshlab ''' filename = binary_ascii_path.join('HalfDonut.stl') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, cog, inertia = mesh.get_mass_properties() assert close([volume], [2.343149]) assert close(cog, [1.500001, 0.209472, 1.500001]) assert close( inertia, [[+1.390429, +0.000000, +0.000000], [+0.000000, +2.701025, +0.000000], [+0.000000, +0.000000, +1.390429]])
def test_mass_properties_for_star(binary_ascii_path, filename, speedups): ''' Checks the results of method get_mass_properties() on STL ASCII and binary files Star.stl and STL binary file StarWithEmptyHeader.stl (with no header) One checks the results obtained with stl with the ones obtained with meshlab ''' filename = binary_ascii_path.join(filename) if not filename.exists(): pytest.skip('STL file does not exist') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, cog, inertia = mesh.get_mass_properties() assert close([volume], [1.416599]) assert close(cog, [1.299040, 0.170197, 1.499999]) assert close( inertia, [[+0.509549, +0.000000, -0.000000], [+0.000000, +0.991236, +0.000000], [-0.000000, +0.000000, +0.509550]])
def test_mass_properties_for_half_donut(binary_ascii_path, speedups): """ Checks the results of method get_mass_properties() on STL ASCII and binary files HalfDonut.stl One checks the results obtained with stl with the ones obtained with meshlab """ filename = binary_ascii_path.join('HalfDonut.stl') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, cog, inertia = mesh.get_mass_properties() assert (abs(volume - 2.343149) < tolerance) assert (numpy.allclose(cog, numpy.array([1.500001, 0.209472, 1.500001]), atol=tolerance)) assert (numpy.allclose(inertia, numpy.array([[+1.390429, +0.000000, +0.000000], [+0.000000, +2.701025, +0.000000], [+0.000000, +0.000000, +1.390429]]), atol=tolerance))
def test_mass_properties_for_moon(binary_ascii_path, speedups): """ Checks the results of method get_mass_properties() on STL ASCII and binary files Moon.stl One checks the results obtained with stl with the ones obtained with meshlab """ filename = binary_ascii_path.join('Moon.stl') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, cog, inertia = mesh.get_mass_properties() assert (abs(volume - 0.888723) < tolerance) assert (numpy.allclose(cog, numpy.array([0.906913, 0.170731, 1.500001]), atol=tolerance)) assert (numpy.allclose(inertia, numpy.array([[+0.562097, -0.000457, +0.000000], [-0.000457, +0.656851, +0.000000], [+0.000000, +0.000000, +0.112465]]), atol=tolerance))
def _get_bound(self): import sys import os from pysph.tools.particle_packing import get_bounding_box if self.filename is not None: file, ext = os.path.splitext(self.filename) print(ext) if (ext == '.txt') or (ext == '.csv'): self.dim = 2 elif ext == '.stl': self.dim = 3 else: print('file extension %s not supported' % ext) sys.exit() if self.dim == 2: try: self.x, self.y = np.loadtxt(self.filename, unpack=True) self.x *= self.scale self.y *= self.scale except IOError: print('read the file') print('The supported file format is \"x y\"') sys.exit() if self.dim == 3: try: data = stl.StlMesh(self.filename) self.x = self.scale * data.x self.y = self.scale * data.y self.z = self.scale * data.z except IOError: print('read the file') print('The supported file format is \"x y\"') sys.exit() if self.z is None: self.dim = 2 self.z = np.zeros_like(self.x) return get_bounding_box(self.dx, self.x, self.y, self.z, self.L, self.B, self.H)
def test_mass_properties_for_half_donut_with_density(binary_ascii_path, speedups): ''' Checks the results of method get_mass_properties_with_density() on STL ASCII and binary files HalfDonut.stl One checks the results obtained with stl with the ones obtained with meshlab ''' filename = binary_ascii_path.join('HalfDonut.stl') mesh = stl.StlMesh(str(filename), speedups=speedups) volume, mass, cog, inertia = mesh.get_mass_properties_with_density(1.23) assert close([mass], [2.882083302268982]) assert close([volume], [2.343149026234945]) assert close(cog, [1.500001, 0.209472, 1.500001]) print('inertia') numpy.set_printoptions(suppress=True) print(inertia) assert close(inertia, [[+1.71022851, +0.00000001, -0.00000011], [+0.00000001, +3.32226227, +0.00000002], [-0.00000011, +0.00000002, +1.71022859]])
def _test_conversion(from_, to, mode): for name in os.listdir(from_): source_file = os.path.join(from_, name) expected_file = os.path.join(to, name) mesh = stl.StlMesh(source_file) with open(expected_file) as expected_fh: expected = expected_fh.read() # For binary files, skip the header if mode is stl.BINARY: expected = expected[80:] with tempfile.TemporaryFile() as dest_fh: mesh.save(name, dest_fh, mode) # Go back to the beginning to read dest_fh.seek(0) dest = dest_fh.read() # For binary files, skip the header if mode is stl.BINARY: dest = dest[80:] assert dest.strip() == expected.strip()
def test_mass_properties_for_star(): """ Checks the results of method get_mass_properties() on STL ASCII and binary files Star.stl and STL binary file StarWithEmptyHeader.stl (with no header) One checks the results obtained with stl with the ones obtained with meshlab """ for m in (join('stl_ascii', 'Star.stl'), join('stl_binary', 'Star.stl'), join('stl_binary', 'StarWithEmptyHeader.stl')): filename = join('tests', m) mesh = stl.StlMesh(filename) volume, cog, inertia = mesh.get_mass_properties() assert (abs(volume - 1.416599) < tolerance) assert (numpy.allclose(cog, numpy.array([1.299040, 0.170197, 1.499999]), atol=tolerance)) assert (numpy.allclose(inertia, numpy.array([[+0.509549, +0.000000, -0.000000], [+0.000000, +0.991236, +0.000000], [-0.000000, +0.000000, +0.509550]]), atol=tolerance))
# COVERTS STLs to PNGs by mapping XYZ coords onto RGB values from stl import stl import png import math import numpy as np filenam = "pill" fil = filenam + ".stl" mesh = stl.StlMesh( fil, calculate_normals=False) #do not calculate normals automatically ### The two data sets that we will convert to pixels #print mesh.normals #print mesh.normals[0][0] #print mesh.vectors #you can also read as one complete list with mesh.data def getRGBfromI(RGBint): blue = RGBint & 255 green = (RGBint >> 8) & 255 red = (RGBint >> 16) & 255 return red, green, blue def remap(value, leftMin, leftMax, rightMin, rightMax): #like processing's map() function # Figure out how 'wide' each range is leftSpan = leftMax - leftMin
def get_points_from_stl(stl_path): stl_mesh = stl.StlMesh(stl_path) points = np.vstack((stl_mesh.v0, stl_mesh.v1, stl_mesh.v2)) return points[::15]
def __init__(self, fp): print 'init opening file: ', fp self.mesh = stl.StlMesh(fp) self.boundingBox() self.centerGeometry()
def __init__(self, stl_path, rigid_tx_mm, max_dist_mm): self.max_dist_mm = max_dist_mm self.rigid_tx_mm = rigid_tx_mm spn_mesh = stl.StlMesh(stl_path) self.__set_mesh_points(spn_mesh)
def stl2png(infilename, outstream): mesh = stl.StlMesh( infilename, calculate_normals=False) #do not calculate normals automatically ###------------ Converting Vertices -------------### origdist = getcartesianrange(mesh.vectors) print "origdist = " + str(origdist) vertcolrlist = [] # Put the colours in here #max integer for 24 bit is 16777215 whitepx = getRGBfromI(16777215) # max for 32bit is 2147483647, not using this anymore offwhitepx = getRGBfromI(16777214) blackpx = getRGBfromI(1) n = 0 for vect in mesh.vectors: ### get Normal ## NOT ACTUALLY NEEDED T # nxint = remap(mesh.normals[n][0],-1,1,2,16777213) # nxcolrs = getRGBfromI(nxint) # nyint = remap(mesh.normals[n][1],-1,1,2,16777213) # nycolrs = getRGBfromI(nyint) # nzint = remap(mesh.normals[n][2],-1,1,2,16777213) # nzcolrs = getRGBfromI(nzint) # n+= 1 # ncolrs = nxcolrs + nycolrs + nzcolrs + offwhitepx #single offwhite space #vertcolrlist.extend(ncolrs) #get xyz's for all three vertices for xyz in vect: # print xyz xint = remap(xyz[0], origdist * -1, origdist, 2, 16777213) #half way is 1073741823 xcolrs = getRGBfromI(xint) yint = remap(xyz[1], origdist * -1, origdist, 2, 16777213) ycolrs = getRGBfromI(yint) zint = remap(xyz[2], origdist * -1, origdist, 2, 16777213) zcolrs = getRGBfromI(zint) colrs = xcolrs + ycolrs + zcolrs #+ whitepx # using a single whitespacer vertcolrlist.extend(colrs) #blackcolrs = blackpx + blackpx + blackpx + blackpx + blackpx + blackpx # using a black spacer blackcolrs = blackpx # using a single black spacer vertcolrlist.extend(blackcolrs) # print len(vertcolrlist) # vertcolrlist is now a totally flat list of RGB pixels # work out how many pixels wide/tall we want our image to be num_pixels = len(vertcolrlist) / 3 # three for RGB width = int(math.sqrt(num_pixels)) height = num_pixels / width # print "num_pixels = " + str(num_pixels) # print "height = " + str(height) # print "width = " + str(width) ## maybe avoid multiples of 10 so that we don't get 'banding' #n % k == 0 if width % 10 == 0: # print "this is a multiple of 10! " width -= 2 # Somehow this is not working properly, catches error but doesnt solve it if (height * width) != num_pixels: # print 'WARNING' if (height * width) < num_pixels: while ((height * width) < num_pixels): height += 1 remainder = height * width - num_pixels # print "remainder = " + str(remainder) black0px = getRGBfromI(0) newpixels = (black0px * remainder ) #remainder rendered as black pixels vertcolrlist.extend(newpixels) # print len(vertcolrlist) # print "new height = " + str(height) # print "new width = " + str(width) # print "remainder done" # now use numpy to reshape our 1D list into a 2D matrix a = np.array(vertcolrlist) b = np.reshape(a, (height, width * 3)) # three for RGB # pprint gives a nicely formatted output import pprint #pprint.pprint(vertcolrlist) w = png.Writer(width, height) w.write(outstream, b)