def create_figure(path_dict, figure_path, path_dict2=None, pair_mapping=None, transp_backg=False): assert ((path_dict2 is None) + (pair_mapping is None)) != 1, \ 'please specify all kwargs or none of them' if pair_mapping is not None: # for k in tqdm(pair_mapping): # mesh= Mesh.from_file(path_dict[k[0]]) # mesh2 = Mesh.from_file(path_dict2[k[1]]) for k, values in tqdm(pair_mapping.items()): mesh = Mesh.from_file(path_dict[k]) mesh = _add_normalizing_vector_point(mesh, 300, -300) fig = vpl.figure() fig.background_color = 'black' vpl.mesh_plot(mesh, color='pink', opacity=0.3) #make dendrite translucent for v in values: # add second, third,.. .stl to same plot mesh2 = Mesh.from_file(path_dict2[str(v)]) vpl.mesh_plot(mesh2) save_path = figure_path + str(k) + '.png' vpl.save_fig( save_path, magnification=5, off_screen=True, ) if transp_backg == True: #make black background transparent _transparent_background(save_path) fig.close() else: for k in tqdm(path_dict): # Read the STL using numpy-stl mesh = Mesh.from_file(path_dict[k]) if debug == True: mesh = _add_normalizing_vector_point(mesh, 300, -300) fig = vpl.figure() fig.background_color = 'black' vpl.mesh_plot(mesh) save_path = figure_path + str(k) + '.png' vpl.save_fig( save_path, magnification=5, off_screen=True, ) if transp_backg == True: #make black background transparent _transparent_background(save_path) fig.close()
def create_ctm(zip): """ Convert an uploaded model file to a ctm file """ app.logger.warn('create ctm from zip') if not zip: return None app.logger.warn('extract zip') with ZipFile(zip.getAbsolutePath(), 'r', ZIP_DEFLATED) as zipFile: uploadFileName = zipFile.infolist()[0].filename app.logger.warn('read zip file') uploadFileData = zipFile.read(uploadFileName) filename, fileExt = os.path.splitext(uploadFileName) with tempfile.NamedTemporaryFile(suffix=fileExt) as uploadFile: app.logger.warn('created temp file, now write') uploadFile.write(uploadFileData) # Convert to bin if ascii uploadFile.seek(0) if uploadFile.read(5) == b'solid': app.logger.warn('Solid Ascii, convert to binary') Mesh.from_file(uploadFile.name).save(uploadFile.name) # Convert to ctm in uploads storage ctmFile = File.fromName(filename + '.ctm') ctmFile.mime_type = 'application/octet-stream' app.logger.warn('run ctm conv') ctmConvert = subprocess.run( ["ctmconv", uploadFile.name, ctmFile.getAbsolutePath()], stderr=subprocess.PIPE) if ctmConvert.returncode > 0: # TODO: Deal with this error properly app.logger.error(ctmConvert.stderr) app.logger.warn('ctm conv done, set size') ctmFile.size = os.stat(ctmFile.getAbsolutePath()).st_size app.logger.warn('ctmCreated') return ctmFile
def test_mesh(self): import time fig = vpl.gcf() path = vpl.data.get_rabbit_stl() _mesh = Mesh.from_file(path) self = vpl.mesh_plot(_mesh.vectors) fig.show(False) t0 = time.time() for i in range(100): # self.color = np.random.random(3) # print(self.color) self.set_tri_scalars((_mesh.x[:, 0] + 3 * i) % 20) _mesh.rotate(np.ones(3), .1, np.mean(_mesh.vectors, (0, 1))) fig.update() self.update_points() # time.sleep(.01) if (time.time() - t0) > 1: break fig.show()
def test_doc_03(self): import vtkplotlib as vpl from stl.mesh import Mesh mesh = Mesh.from_file(vpl.data.get_rabbit_stl()) vertices = mesh.vectors vpl.plot(vertices, join_ends=True, color="dark red")
def dimensions(infile): """Accepts a 3D mesh file as infile, and returns the x,y,z dimensions of the object in mm""" mesh = Mesh.from_file(infile) return [ float(mesh.x.max()) - float(mesh.x.min()), float(mesh.y.max()) - float(mesh.y.min()), float(mesh.z.max()) - float(mesh.z.min()) ]
def generate_thumbnail(infile, outfile, size=None): """Generate a thumbnail or previewfile into 'outfile' using the design file in 'infile'""" mesh = Mesh.from_file(infile) vpl.mesh_plot(mesh) # Front of design and slightly up vpl.view(camera_position=[0, -1, 0.5]) vpl.save_fig(outfile, pixels=size or [1280, 1280], off_screen=True)
def test(): from stl.mesh import Mesh import vtkplotlib as vpl mesh = Mesh.from_file(vpl.data.get_rabbit_stl()) plot = vpl.mesh_plot(mesh, scalars=mesh.x) vpl.scalar_bar(plot) vpl.show()
def set_from_path(self, path, ignore_numpystl=False): # Ideally let numpy-stl open the file if it is installed. if NUMPY_STL_AVAILABLE and not ignore_numpystl: self.vectors = NumpyMesh.from_file(path).vectors return # Otherwise try vtk's STL reader - however it's not as reliable. self.polydata = vtk_read_stl(path) self.connect()
def test_doc_05(self): import vtkplotlib as vpl from stl.mesh import Mesh # path = "if you have an STL file then put it's path here." # Otherwise vtkplotlib comes with a small STL file for demos/testing. path = vpl.data.get_rabbit_stl() # Read the STL using numpy-stl mesh = Mesh.from_file(path) # Plot the mesh vpl.mesh_plot(mesh)
def load(self, scene, filename): #open zipfile with ZipFile(filename, 'r') as openedZipfile: tree = ET.fromstring(openedZipfile.read(self.xmlFilename)) version = tree.find('version').text if self.get_version() == version: logging.debug( "Ano, soubor je stejna verze jako knihovna pro jeho nacitani. Pokracujeme" ) else: logging.debug("Problem, tuto verzi neumim nacitat.") return False models = tree.find('models') models_data = [] for model in models.findall('model'): model_data = {} model_data['file_name'] = model.get('name') model_data['normalization'] = ast.literal_eval( model.find('normalization').text) model_data['position'] = ast.literal_eval( model.find('position').text) model_data['rotation'] = ast.literal_eval( model.find('rotation').text) model_data['scale'] = ast.literal_eval( model.find('scale').text) models_data.append(model_data) #scene.models = [] for m in models_data: logging.debug("Jmeno souboru je: " + m['file_name']) tmp = scene.controller.app_config.tmp_place model_filename = tmp + m['file_name'] openedZipfile.extract(m['file_name'], tmp) mesh = Mesh.from_file(filename=model_filename) os.remove(model_filename) #mesh = Mesh.from_file(filename="", fh=openedZipfile.open(m['file_name'])) model = ModelTypeStl.load_from_mesh( mesh, filename=m['file_name'], normalize=not m['normalization']) model.rot = numpy.array(m['rotation']) model.pos = numpy.array(m['position']) model.pos *= 0.1 model.scale = numpy.array(m['scale']) model.update_min_max() model.parent = scene scene.models.append(model)
def test_doc_07(self): import vtkplotlib as vpl from stl.mesh import Mesh import numpy as np # Open an STL as before path = vpl.data.get_rabbit_stl() mesh = Mesh.from_file(path) # `tri_scalars` must have one value per triangle and have shape (n,) or (n, 1). # Create some scalars showing "how upwards facing" each triangle is. tri_scalars = np.inner(mesh.units, np.array([0, 0, 1])) vpl.mesh_plot(mesh, tri_scalars=tri_scalars)
def test_doc_06(self): import vtkplotlib as vpl from stl.mesh import Mesh # Open an STL as before path = vpl.data.get_rabbit_stl() mesh = Mesh.from_file(path) # Plot it with the z values as the scalars. scalars is 'per vertex' or 1 # value for each corner of each triangle and should have shape (n, 3). plot = vpl.mesh_plot(mesh, scalars=mesh.z) # Optionally the plot created by mesh_plot can be passed to color_bar vpl.color_bar(plot, "Heights")
def test_doc_08(self): import vtkplotlib as vpl from stl.mesh import Mesh import numpy as np path = vpl.data.get_rabbit_stl() mesh = Mesh.from_file(path) # This is the length of each side of each triangle. edge_scalars = vpl.geometry.distance( mesh.vectors[:, np.arange(1, 4) % 3] - mesh.vectors) vpl.mesh_plot_with_edge_scalars(mesh, edge_scalars, centre_scalar=0, cmap="Greens")
def test_ppf(stl_path, pred_path, gt_path): model_mesh = Mesh.from_file(stl_path) model_pcn = get_pcn_from_mesh(model_mesh) detector = cv2.ppf_match_3d_PPF3DDetector(0.025, 0.05) detector.trainModel(model_pcn) for scene_pc, cam_pos, pose_gt in iterate_predicted(pred_path, gt_path): cam_p, cam_rot = cam_pos viewpoint = tuple(cam_p) _, scene_pcn = cv2.ppf_match_3d.computeNormalsPC3d( scene_pc, 4, False, viewpoint) matches = detector.match(scene_pcn, 1.0 / 40.0, 0.15) print('---- Predicted pose:') for m in matches: print(m.pose) print('---- GT pose:') for p, q, rot in pose_gt: print(p, rot)
def main(): in_path = Path(sys.argv[1]) mesh = Mesh.from_file(in_path.as_posix()) print(mesh[0::3, :].min()) x0 = (mesh.x.min() + mesh.x.max()) / 2 y0 = (mesh.y.min() + mesh.y.max()) / 2 #z0 = (mesh.z.min() + mesh.z.max()) / 2 z0 = mesh.z.min() print(f'Center: {x0}, {y0}, {z0}') out_path = f'{in_path.stem}_0.stl' print(out_path) mesh.x -= x0 mesh.y -= y0 mesh.z -= z0 mesh.save(out_path)
def path_str_to_vectors(path, ignore_numpystl=False): # Ideally let numpy-stl open the file if it is installed. if NUMPY_STL_AVAILABLE and not ignore_numpystl: return NumpyMesh.from_file(path).vectors # Otherwise try vtk's STL reader - however it's far from flawless. # A lot of redundancy here. # -Read the STL using vtk's STLReader # -Extract the polydata # -Extract the vectors from the polydata # This can then be given to mesh_plot which will convert it straight # back again to a polydata. from vtkplotlib.plots.polydata import PolyData from vtkplotlib.unicode_paths import PathHandler from vtkplotlib._vtk_errors import handler with PathHandler(path) as path_handler: reader = vtk.vtkSTLReader() handler.attach(reader) reader.SetFileName(path_handler.access_path) # vtk does a really good job of point merging but it's really not # worth the hassle to use it just to save a bt of RAM as everything # else in this script assumes an (n, 3, 3) table of vectors. Disable it # for speed. # reader.SetMerging(False) # Normally Reader doesn't do any reading until it's been plotted. # Update forces it to read. reader.Update() pd = PolyData(reader.GetOutput()) # For some reason VTK just doesn't like some files. There are some vague # warnings in their docs - this could be what they're on about. If it # doesn't work ``reader.GetOutput()`` gives an empty polydata. if pd.vtk_polydata.GetNumberOfPoints() == 0: raise RuntimeError( "VTK's STLReader failed to read the STL file and no STL io backend is installed. VTK's STLReader is rather patchy. To read this file please ``pip install numpy-stl`` first." ) return normalise_mesh_type((pd.points, pd.polygons))
def test_type_normalise(self): from stl.mesh import Mesh mesh = Mesh.from_file(path) vectors = mesh.vectors unique_points = set( tuple(i) for i in vectors.reshape(len(vectors) * 3, 3)) points_enum = {point: i for (i, point) in enumerate(unique_points)} points = np.array(sorted(unique_points, key=points_enum.get)) point_args = np.apply_along_axis(lambda x: points_enum[tuple(x)], -1, vectors) for fmt in (path, mesh, vectors, (points, point_args)): normalised = vpl.plots.MeshPlot.normalise_mesh_type(fmt) self.assertTrue(np.array_equal(normalised, vectors)) for i in range(2): try: normalised = vpl.plots.MeshPlot.path_str_to_vectors(path, i) self.assertTrue(np.array_equal(normalised, vectors)) except RuntimeError as ex: print(repr(ex))
def get_projections(file, camera_directions=CAMERA_DIRS): """ Get projection views in given camera directions from an STL file. Returns: Numpy array of shape (PROJ_SHAPE, len(camera_directions)). """ views = [] for dir in camera_directions[::-1]: mesh = Mesh.from_file(file) vpl.mesh_plot(mesh, color="black") r = vpl.view(camera_position=(0, 0, 0), camera_direction=dir) vpl.reset_camera() vpl.zoom_to_contents(padding=1) # Upscale first so downscale is more accurate arr = vpl.screenshot_fig(magnification=10, off_screen=True) # Change 3-channel RGB image to single channel binary matrix arr = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY) arr[arr == 0] = 1 arr[arr == 218] = 0 arr = cv2.resize(arr, dsize=PROJ_SHAPE, interpolation=cv2.INTER_LINEAR) vpl.close() views.append(arr) views = np.array(views).reshape( (PROJ_SHAPE[0], PROJ_SHAPE[1], len(camera_directions))) return views
def registration(raw): correct = np.array(raw) # To shift up the points, 11 is a threshold to determine whether to shift up or not numCols = len(raw[2]) to_shift_up = [0] * numCols for col in range(numCols): if raw[2][col] < 11: to_shift_up[col] = 30 else: to_shift_up[col] = 0 raw[0] = raw[0] + to_shift_up # Axes Transformation, values are selected through trial and error as per MATLAB code x_shift = -43.5 y_shift = 95 z_shift = 148 correct[0] = raw[1] * 90.0 / 569.0 + x_shift correct[1] = (raw[0] * (-88) / 569) + y_shift correct[2] = raw[2] * (-5.01) + z_shift np.set_printoptions(precision=3) # Prints array in 3 decimal places # Rotation skew_value = 0.08 skew_y = np.array([[1, 0, skew_value], [0, 1, 0], [0, 0, 1]]) correct = np.dot(skew_y, correct) tz = np.deg2rad(1) ty = np.deg2rad(-0.5) Rz = [[math.cos(tz), -1 * math.sin(tz), 0], [math.sin(tz), math.cos(tz), 0], [0, 0, 1]] Ry = [[math.cos(ty), 0, math.sin(ty)], [0, 1, 0], [-1 * math.sin(ty), 0, math.cos(ty)]] correct = np.dot(Rz, correct) correct = np.dot(Ry, correct) # Get STL (ground truth) model path = "ground_truth_in_stl_form.stl" stl_mesh = Mesh.from_file(path) stl_points = np.around( np.unique(stl_mesh.vectors.reshape([stl_mesh.vectors.size // 3, 3]), axis=0), 2) # Displays the model, eliminate outlier points that are too far # Range values for each axis as selected per MATLAB code minz = -200 maxz = 400 miny = -100 maxy = 400 minx = -100 maxx = 500 # p represents point cloud px = np.bitwise_and(stl_points[0, :] > minx, stl_points[0, :] < maxx) py = np.bitwise_and(stl_points[1, :] > miny, stl_points[1, :] < maxy) pz = np.bitwise_and(stl_points[2, :] > minz, stl_points[2, :] < maxz) p = np.bitwise_and(px, py, pz) # Transpose segmented points to be in dimensions (number of rows, 3) segmented_points = np.transpose(correct) num_rows = np.ma.size(segmented_points, 0) stl_points = np.transpose(stl_points) # Array to store the error for colour map error = np.ones((num_rows, 1)) # For loop determines the colour map or the error when mapping segmented points to stl for i in range(num_rows): point = segmented_points[ i, :] # extracting each row from segmented points point_p2 = stl_points[:, i] # euclidean distance between the segmented points and the stl model dist = scipy.spatial.distance.euclidean(point_p2, point) dist = dist / 100 if (dist > 10): error[ i] = 0 # if the error is too big then it won't display on the colour map because # it is a point of less interest elif np.mean(stl_points[p, 1]) < point[1]: error[i] = np.mean(dist) else: error[i] = np.mean(dist) # Outputs maximum and minimum error highest = max(error) lowest = min(error) print(f"The maximum error is {highest}mm") print(f"The minimum error is {lowest}mm") # Use a temp variable to store the error array of each point temp = error # Convert error array into rgb and store in colours array error = error * 255 / highest zeroes = np.zeros((5640, 2)) colours = np.append(zeroes, error, axis=1) # Displays colour map depending on error, the threshold are selected using trial and error for i in range(len(temp)): if temp[i] > 1.5: colours[i] = [255, 0, 0] # green colour means less accurate continue if temp[i] < 1.1: colours[i] = [0, 255, 0] # blue colour means more accurate continue # Display the STL Point Cloud and Segmented Points pcd_image = open3d.geometry.PointCloud() pcd_image.points = open3d.utility.Vector3dVector(segmented_points) pcd_image.colors = open3d.utility.Vector3dVector(colours) # Writing segmented points cloud to an open3d image open3d.io.write_point_cloud("point_cloud_segmented.ply", pcd_image) # Read the point cloud pcd_image = open3d.io.read_point_cloud("point_cloud_segmented.ply") # Load original STL file mesh1 = trimesh.load('ground_truth_in_stl_form.stl') # Convert stl file to ply. The STl file is the ground truth model mesh2 = mesh1.copy() mesh2.export('ground_truth.ply') # Set parameters for icp registration source = open3d.io.read_point_cloud("ground_truth.ply") target = open3d.io.read_point_cloud("point_cloud_segmented.ply") threshold = 0.005 # Transformation matrix - Identity Matrix initial_trans = np.identity(4) # Evaluate registration performance evaluation = open3d.registration.evaluate_registration( source, target, threshold, initial_trans) # Obtain a registered model reg_p2p = open3d.registration.registration_icp(source, target, threshold, initial_trans) # Plot registered model draw_registration_result_original_color(source, target, reg_p2p.transformation) # Plot the error distribution plt.hist(temp, bins=50) plt.gca().set(title='Error/Distance', ylabel='Frequency') plt.show()
import stl import numpy as np import sys from stl.mesh import Mesh print((sys.argv)) stl_mesh = Mesh.from_file(sys.argv[1]) data = np.zeros(stl_mesh.data.size, dtype=Mesh.dtype) new_mesh = Mesh(data) new_mesh.normals[:] = stl_mesh.normals new_mesh.vectors[:] = stl_mesh.vectors target = open(sys.argv[2], "w") for i in range(0, new_mesh.normals.shape[0]): x1 = new_mesh.vectors[i, 0, 0] x2 = new_mesh.vectors[i, 1, 0] x3 = new_mesh.vectors[i, 2, 0] y1 = new_mesh.vectors[i, 0, 1] y2 = new_mesh.vectors[i, 1, 1] y3 = new_mesh.vectors[i, 2, 1] z1 = new_mesh.vectors[i, 0, 2] z2 = new_mesh.vectors[i, 1, 2] z3 = new_mesh.vectors[i, 2, 2] xc = 1.0 / 3.0 * (x1 + x2 + x3) yc = 1.0 / 3.0 * (y1 + y2 + y3) zc = 1.0 / 3.0 * (z1 + z2 + z3) nx = new_mesh.normals[i, 0] ny = new_mesh.normals[i, 1] nz = new_mesh.normals[i, 2] normalmag = np.sqrt(pow(nx, 2) + pow(ny, 2) + pow(nz, 2)) + 1e-15 target.write("%f %f %f %f %f %f\n" % (xc, yc, zc, nx / normalmag, ny / normalmag, nz / normalmag)) target.close()
import vtkplotlib as vpl from stl.mesh import Mesh # Read the STL using numpy-stl mesh = Mesh.from_file('/home/javacasm/Descargas/Bearing_608_V02_tolMin.stl') # Plot the mesh vpl.mesh_plot(mesh) # Show the figure vpl.show()
new_scalars[:, 0] = new_scalars[:, 1] = tri_scalars for i in range(3): new_scalars[i::3, 2] = centre_scalars return MeshPlot(new_vectors, scalars=new_scalars, opacity=opacity, fig=fig) if __name__ == "__main__": import time import vtkplotlib as vpl from stl.mesh import Mesh fig = vpl.gcf() path = vpl.data.get_rabbit_stl() # path = "rabbit2.stl" _mesh = Mesh.from_file(path) mesh_data = _mesh.vectors mesh_data = path # vpl.mesh_plot(mesh_data) edge_scalars = vpl.geometry.distance(_mesh.vectors[:, np.arange(1, 4) % 3] - _mesh.vectors) self = vpl.mesh_plot_with_edge_scalars(_mesh, edge_scalars, centre_scalar=0) mesh_data = _mesh
def get_stl_object_by_name(file_name): return Mesh.from_file(file_name)
# other = vpl.plot(points, color="r").polydata self = PolyData() ## self.points = points ### ### n, m = 10, 50 ### itr_of_arrays = np.random.randint(0, len(points), (n, m)) #### lines = np.concatenate((np.ones((n, 1), int) * m, lines), axis=1) ### # lines = [np.random.randint(0, len(t), np.random.randint(3, 5)) for i in range(10)] # self = vpl.plots.polydata.PolyData() # self.points = points # self.lines = join_line_ends(lines) # self.to_plot() from stl.mesh import Mesh vectors = Mesh.from_file(vpl.data.get_rabbit_stl()).vectors points = vpl.nuts_and_bolts.flatten_all_but_last(vectors) self.points = points polygons = np.arange(len(points)).reshape((len(points) // 3, 3)) self.polygons = polygons # point_colors = points[:, np.newaxis, 0] # self.point_colors = point_colors point_colors = vpl.colors.normalise(points, axis=0)#[:, 0] self.point_colors = point_colors plot = self.to_plot() # plot.set_scalar_range((0, 1))
def volume(infile): """Accepts a 3D mesh file as inline, and returns the volume of the object in cubic mm""" mesh = Mesh.from_file(infile) vol, _, _ = mesh.get_mass_properties() return float(vol)
import stl import numpy as np import sys from stl.mesh import Mesh print(sys.argv) filename = str(sys.argv[1]) stl_mesh = Mesh.from_file(filename) data = np.zeros(stl_mesh.data.size, dtype=Mesh.dtype) new_mesh = Mesh(data) new_mesh.normals[:] = stl_mesh.normals new_mesh.vectors[:] = stl_mesh.vectors for i in range(0, new_mesh.normals.shape[0]): nsum = 0 x1 = new_mesh.vectors[i, 0, 0] x2 = new_mesh.vectors[i, 1, 0] x3 = new_mesh.vectors[i, 2, 0] y1 = new_mesh.vectors[i, 0, 1] y2 = new_mesh.vectors[i, 1, 1] y3 = new_mesh.vectors[i, 2, 1] z1 = new_mesh.vectors[i, 0, 2] z2 = new_mesh.vectors[i, 1, 2] z3 = new_mesh.vectors[i, 2, 2] # Shoe-Lace if (abs(z1 - z2) < 0.5 and abs(z2 - z3) < 0.5 and abs(z3 - z1) < 0.5): nsum = nsum + (x2 - x1) * (y1 + y2) nsum = nsum + (x3 - x2) * (y3 + y2) nsum = nsum + (x1 - x3) * (y1 + y3) if (nsum <= 0): continue else: new_mesh.vectors[i, 1, :] = stl_mesh.vectors[i, 2, :]
def load(self, scene, filename): #open zipfile with ZipFile(filename, 'r') as openedZipfile: tree = ET.fromstring(openedZipfile.read(self.xmlFilename)) version = tree.find('version').text if self.get_version() == version: logging.debug( "Ano, soubor je stejna verze jako knihovna pro jeho nacitani. Pokracujeme" ) else: logging.debug("Problem, tuto verzi neumim nacitat.") return False models = tree.find('models') models_data = [] for model in models.findall('model'): model_data = {} model_data['file_name'] = model.get('name') if not model.find('extruder') == None: model_data['extruder'] = ast.literal_eval( model.find('extruder').text) if not model.find('group') == None: model_data['group'] = ast.literal_eval( model.find('group').text) model_data['normalization'] = ast.literal_eval( model.find('normalization').text) model_data['position'] = ast.literal_eval( model.find('position').text) model_data['rotation'] = ast.literal_eval( model.find('rotation').text) model_data['scale'] = ast.literal_eval( model.find('scale').text) models_data.append(model_data) #scene.models = [] models_groups = {} groups_properties = {} for m in models_data: logging.debug("Jmeno souboru je: " + m['file_name']) tmp = scene.controller.app_config.tmp_place model_filename = tmp + m['file_name'] openedZipfile.extract(m['file_name'], tmp) mesh = Mesh.from_file(filename=model_filename) os.remove(model_filename) #mesh = Mesh.from_file(filename="", fh=openedZipfile.open(m['file_name'])) if 'group' in m: model = ModelTypeStl.load_from_mesh( mesh, filename=m['file_name'], normalize=not m['normalization']) else: model = ModelTypeStl.load_from_mesh( mesh, filename=m['file_name'], normalize=not m['normalization']) if 'extruder' in m: model.extruder = int(m['extruder']) if 'group' in m: model.is_multipart_model = True model.parent = scene model.normalization_flag = m['normalization'] if m['group'] in models_groups: models_groups[m['group']].append(model) else: models_groups[m['group']] = [] models_groups[m['group']].append(model) if m['group'] in groups_properties: groups_properties[m['group']]['pos'] = numpy.array( m['position']) * 0.1 groups_properties[m['group']]['rot'] = numpy.array( m['rotation']) groups_properties[m['group']]['scale'] = numpy.array( m['scale']) else: groups_properties[m['group']] = {} groups_properties[m['group']]['pos'] = numpy.array( m['position']) * 0.1 groups_properties[m['group']]['rot'] = numpy.array( m['rotation']) groups_properties[m['group']]['scale'] = numpy.array( m['scale']) else: model.rot = numpy.array(m['rotation']) model.pos = numpy.array(m['position']) model.pos *= 0.1 model.scale = numpy.array(m['scale']) model.update_min_max() model.parent = scene model.update_min_max() model.normalization_flag = m['normalization'] scene.models.append(model) for group in models_groups: mm = MultiModel(models_groups[group], scene) mm.pos = groups_properties[group]['pos'] mm.rot = groups_properties[group]['rot'] mm.scale = groups_properties[group]['scale'] scene.multipart_models.append(mm) mm.update_min_max()
None) # dual rotation for extra variation # rotate(axis, theta=0, point=None) mesh.rotate(axis, math.radians(self.rotationAngle), None) # Plot the mesh vtkplotlib.mesh_plot(mesh, color="blue") vtkplotlib.save_fig( os.path.normpath(path + '/_' + axisName + str(x) + '.png')) #saves the figure as an image vtkplotlib.figure.close(vtkplotlib.gcf()) # folder to put the images in: imgFolder = "images" # source for the STL file: stlPath = os.path.normpath("/path/to/file.stl") generator = genSTLImages() # instatiate the class currentDir = pathlib.Path().absolute() # get the path where this is executed newFolder = os.path.join(currentDir, imgFolder) # add the sub folder name generator.checkForFolderHere( newFolder) # makes the sub directory if it doesn't exist generator.deleteExistingImages( newFolder) # gets rid of existing images if they are in that subfolder mesh = Mesh.from_file(stlPath) # Read the STL using numpy-stl generator.generateImages(mesh, newFolder)