def read_in_step_files_and_save_as_single_stl_files(read_folder, write_folder, ignore_files=['']): list_of_solid_parts = [] try: os.mkdir(write_folder) print('making folder', write_folder) except: print('error making folder', write_folder) #print('read_folder',read_folder) #print(os.listdir(read_folder)) for file in os.listdir(read_folder): if file not in ignore_files: if file.endswith(".step") or file.endswith(".stp"): #print('reading in ' ,os.path.join(read_folder, file)) multipart_step = Part.read(os.path.join(read_folder, file)) stl_filename = write_folder + '/' + os.path.splitext( file)[0] + '.stl' if len(multipart_step.Solids) == 0: singlepart_step = multipart_step solid_mesh = MeshPart.meshFromShape(singlepart_step, LinearDeflection=0.1) list_of_solid_parts.append(solid_mesh) else: solid_mesh = MeshPart.meshFromShape(multipart_step, LinearDeflection=0.1) solid_mesh.write(stl_filename)
def triangulate(shape): "triangulates the given face" p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") mesher = p.GetInt("ColladaMesher", 0) tessellation = p.GetFloat("ColladaTessellation", 1.0) grading = p.GetFloat("ColladaGrading", 0.3) segsperedge = p.GetInt("ColladaSegsPerEdge", 1) segsperradius = p.GetInt("ColladaSegsPerRadius", 2) secondorder = p.GetBool("ColladaSecondOrder", False) optimize = p.GetBool("ColladaOptimize", True) allowquads = p.GetBool("ColladaAllowQuads", False) if mesher == 0: return shape.tessellate(tessellation) elif mesher == 1: return MeshPart.meshFromShape(Shape=shape, MaxLength=tessellation).Topology else: return MeshPart.meshFromShape(Shape=shape, GrowthRate=grading, SegPerEdge=segsperedge, SegPerRadius=segsperradius, SecondOrder=secondorder, Optimize=optimize, AllowQuad=allowquads).Topology
def execute(self, obj): import MeshPart base = obj.Base if hasattr(base, 'Mesh') and isinstance(base, Mesh.Mesh): self.mesh = base elif hasattr(base, 'Shape') and base.Shape: self.mesh = MeshPart.meshFromShape(base.Shape.copy(False)) else: self.mesh = MeshPart.meshFromShape(base.copy(False))
def CreateSections(self): FreeCADVersion = FreeCAD.Version() if FreeCADVersion[0] == '0' and int(FreeCADVersion[1]) < 19: FreeCAD.Console.PrintError( "This feature is only available on versions > 0.18") return try: self.SectionsGroup = FreeCAD.ActiveDocument.Sections except: self.SectionsGroup = FreeCAD.ActiveDocument.addObject( "App::DocumentObjectGroup", 'Sections') self.SectionsGroup.Label = "Sections" GuideLineIndex = self.IPFui.GLGCB.currentIndex() if GuideLineIndex < 0: FreeCAD.Console.PrintMessage("No Guide Lines Group") return GuideLineName = self.GuideLinesList[GuideLineIndex] GuideLine = FreeCAD.ActiveDocument.getObject(GuideLineName).Group # GuideLinesGroup = FreeCAD.ActiveDocument.GuideLines.Group CopyMesh = FreeCAD.ActiveDocument.Surface.Mesh.copy() Base = CopyMesh.Placement.Base CopyMesh.Placement.move(Base.negative()) for Wire in GuideLine: CopyShape = Wire.Shape.copy() CopyShape.Placement.move(Base.negative()) Param1 = MeshPart.findSectionParameters(CopyShape.Edge1, CopyMesh, FreeCAD.Vector(0, 0, 1)) Param1.insert(0, CopyShape.Edge1.FirstParameter + 1) Param1.append(CopyShape.Edge1.LastParameter - 1) Param2 = MeshPart.findSectionParameters(CopyShape.Edge2, CopyMesh, FreeCAD.Vector(0, 0, 1)) Param2.insert(0, CopyShape.Edge2.FirstParameter + 1) Param2.append(CopyShape.Edge2.LastParameter - 1) Points1 = [CopyShape.Edge1.valueAt(i) for i in Param1] Points2 = [CopyShape.Edge2.valueAt(i) for i in Param2] Section = MeshPart.projectPointsOnMesh(Points1 + Points2, CopyMesh, FreeCAD.Vector(0, 0, 1)) Pwire = Draft.makeWire(Section) Pwire.Placement.move(Base) self.SectionsGroup.addObject(Pwire) FreeCAD.ActiveDocument.recompute()
def meshoponobjs(opname,inobjs): """ takes a string (operation name) and a list of Feature Objects returns a mesh and a list of objects that were used Part Objects will be meshed """ objs=[] meshes=[] for obj in inobjs: if obj.isDerivedFrom('Mesh::Feature'): objs.append(obj) meshes.append(obj.Mesh) elif obj.isDerivedFrom('Part::Feature'): #mesh the shape import FreeCAD params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD") objs.append(obj) if False: # disabled due to issue 1292 import MeshPart meshes.append(MeshPart.meshFromShape(obj.Shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0))) else: import Mesh meshes.append(Mesh.Mesh(obj.Shape.tessellate(params.GetFloat(\ 'meshmaxlength',1.0)))) else: pass #neither a mesh nor a part if len(objs) > 0: return (meshoptempfile(opname,meshes),objs) else: return (None,[])
def freecad_mesh(geometry): mesh = MeshPart.meshFromShape(geometry, Fineness=2, SecondOrder=0, Optimize=1, AllowQuad=0) result = {} # Point IDs might be in arbitrary order, so create a lookup to be sure # that we have the correct point ids point_ids = {} points = [] for point_count, point in enumerate(mesh.Points): points.append([point.x, point.y, point.z]) point_ids[point.Index] = point_count result['nodes'] = np.array(points, dtype=np.float64) triangles = [] for facet_count, facet in enumerate(mesh.Facets): if len(facet.PointIndices) != 3: raise NotImplementedError("Only triangles currently supported") triangles.append([point_ids[n] for n in facet.PointIndices]) result['triangles'] = np.array(triangles) return result
def wiresFromFaceGroups(mesh, faceGroups): wires = [] for faceGroup in faceGroups: wires.append(MeshPart.wireFromSegment(mesh, faceGroup.toSegment())) return wires
def process3D_ObjectsViaOpenSCAD(doc, ObjList, Operation): import FreeCAD, Mesh, Part params = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/OpenSCAD") if False: # disabled due to issue 1292 import MeshPart meshes = [MeshPart.meshFromShape(obj.Shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0)) for obj in ObjList] else: meshes = [Mesh.Mesh(obj.Shape.tessellate(params.GetFloat(\ 'meshmaxlength',1.0))) for obj in ObjList] if max(mesh.CountPoints for mesh in meshes) < \ params.GetInt('tempmeshmaxpoints',5000): stlmesh = meshoptempfile(Operation, meshes) sh = Part.Shape() sh.makeShapeFromMesh(stlmesh.Topology, 0.1) solid = Part.Solid(sh) obj = doc.addObject('Part::Feature', Operation) #non parametric objec solid = solid.removeSplitter() if solid.Volume < 0: solid.complement() obj.Shape = solid #.removeSplitter() if FreeCAD.GuiUp: for index in ObjList: index.ViewObject.hide() return (obj)
def standard_mesher(self): solids = self.inputs[self["shape_type"]].sv_get() surface_deviation = self.inputs["Surface Deviation"].sv_get()[0] angle_deviation = self.inputs["Angle Deviation"].sv_get()[0] verts = [] faces = [] for solid, s_dev, ang_dev in zip( *mlr([solids, surface_deviation, angle_deviation])): if self.shape_type == 'Solid': shape = solid else: shape = solid.face mesh = MeshPart.meshFromShape( Shape=shape, LinearDeflection=s_dev, AngularDeflection=math.radians(ang_dev), Relative=self.relative_surface_deviation) verts.append([v[:] for v in mesh.Topology[0]]) b_faces = mesh.Topology[1] b_faces = clean(b_faces).tolist() if is_triangles_only( b_faces) else b_faces faces.append(b_faces) return verts, faces
def part2mesh(self, part, resolution, mode='fine'): """ Converts CAD object to mesh object, and adds mesh object to CAD document if part is a list of objects, returns a list of meshes. If part isn't a list, freecad throws an error. Use this to determine if part is a list of parts or a single object, and handle each case correctly. Returns a list of mesh objects This function uses the FreeCAD Mefisto algorithm, and defines mesh by maximum edge length (resolution) """ resolution = float(resolution) #Check if this is a single file or list and make it a list if type(part) != list: part = [part] meshes = [] for i in range(len(part)): shape = part[i].Shape.copy(False) shape.Placement = part[i].getGlobalPlacement() print('Meshing part ' + part[i].Label) log.info('Meshing part ' + part[i].Label) mesh = MeshPart.meshFromShape(shape, MaxLength=resolution) meshes.append(mesh) print("Converted parts to mesh objects at resolution: {:f}".format( resolution)) log.info("Converted parts to mesh objects at resolution: {:f}".format( resolution)) return meshes
def shape2polyhedron(shape): import MeshPart fa = params.GetFloat('exportFa',12.0) return mesh2polyhedron(MeshPart.meshFromShape(shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0)))
def opExecute(self, obj): '''opExecute(obj) ... process engraving operation''' PathLog.track() output = "" if obj.Comment != "": output += '(' + str(obj.Comment) + ')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str( obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return print("base object: " + self.baseobject.Name) if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError( translate( "Path_Surface", "This operation requires OpenCamLib to be installed.") + "\n") return if self.baseobject.TypeId.startswith('Mesh'): mesh = self.baseobject.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: import PathScripts.PathPreferences as PathPreferences deflection = PathPreferences.defaultGeometryTolerance() self.baseobject.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(self.baseobject.Shape, Deflection=deflection) bb = mesh.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point(q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)
def half_shape(k, dir, radius): e4ins = [ elidupree_4in_wire(radius, index) for index in reversed(range(10)) ] start = Part.makeLoft( e4ins + [ under_door_wire.translated(vector(40 * (index - 5) / 10, 0, 0)) for index in range(6) ] #+ [elidupree_4in_wire(1, elidupree_4in_output_outer_radius - wall_thickness, index) for index in range (5)] , ) #start.sewShape() #print(start.fix(0.01, 0.005, 0.02)) show(start, "start" + k, invisible=True) outside = start.makeOffsetShape(-wall_thickness, 0.01) #, fill=True) #show(start.Face6, "ver"+k) #adapter = start.makeThickness([start.Face6], wall_thickness, 0.01) show(outside, "outside" + k, invisible=True) cover1 = Part.Face( [under_door_wire.makeOffset2D(wall_thickness), under_door_wire]) show(cover1, "cover1" + k, invisible=True) cover2 = Part.Face([e4ins[0].makeOffset2D(wall_thickness), e4ins[0]]) solid = Part.Solid( Part.Shell(Part.Compound([start, outside, cover1, cover2]).Faces)) if dir == 1: solid = solid.mirror(vector(), vector(1, 0, 0)) show(solid, "solid" + k, invisible=True) import MeshPart mesh = MeshPart.meshFromShape(solid, 0.005, 0.1) Mesh.show(mesh, "mesh" + k)
def process3D_ObjectsViaOpenSCADShape(ObjList, Operation, maxmeshpoints=None): import FreeCAD import Mesh import Part params = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/OpenSCAD") if False: # disabled due to issue 1292 import MeshPart meshes = [MeshPart.meshFromShape(obj.Shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0)) for obj in ObjList] else: meshes = [Mesh.Mesh(obj.Shape.tessellate(params.GetFloat(\ 'meshmaxlength',1.0))) for obj in ObjList] if max(mesh.CountPoints for mesh in meshes) < \ (maxmeshpoints or params.GetInt('tempmeshmaxpoints', 5000)): stlmesh = meshoptempfile(Operation, meshes) sh = Part.Shape() sh.makeShapeFromMesh(stlmesh.Topology, 0.1) solid = Part.Solid(sh) solid = solid.removeSplitter() if solid.Volume < 0: solid.complement() return solid
def getShapeFromMesh(mesh): import Part, MeshPart if mesh.isSolid() and (mesh.countComponents() == 1): # use the best method faces = [] for f in mesh.Facets: p = f.Points + [f.Points[0]] pts = [] for pp in p: pts.append(FreeCAD.Vector(pp[0], pp[1], pp[2])) faces.append(Part.Face(Part.makePolygon(pts))) shell = Part.makeShell(faces) solid = Part.Solid(shell) solid = solid.removeSplitter() return solid faces = [] segments = mesh.getPlanarSegments( 0.001) # use rather strict tolerance here for i in segments: if len(i) > 0: wires = MeshPart.wireFromSegment(mesh, i) if wires: faces.append(makeFace(wires)) try: se = Part.makeShell(faces) except: return None else: try: solid = Part.Solid(se) except: return se else: return solid
def writePartFile(self): """ Construct multi-element STL based on mesh part faces. """ if self.mesh_obj.MeshUtility == "gmsh": self.part_obj.Shape.exportBrep(self.temp_file_shape) else: if ("Boolean" in self.part_obj.Name) and self.mesh_obj.MeshUtility: FreeCAD.Console.PrintError( 'cfMesh and snappyHexMesh do not accept boolean fragments.' ) with open(self.temp_file_geo, 'w') as fid: for k in range(len(self.patch_faces)): for l in range(len(self.patch_faces[k])): patch_faces = self.patch_faces[k][l] patch_name = self.patch_names[k][l] if len(patch_faces): # Put together the faces making up this patch; mesh them and output to file patch_shape = Part.makeCompound([ self.mesh_obj.Part.Shape.Faces[f] for f in patch_faces ]) CfdTools.cfdMessage( "Triangulating part {}, patch {} ...".format( self.part_obj.Label, patch_name)) mesh_stl = MeshPart.meshFromShape( patch_shape, LinearDeflection=self.mesh_obj. STLLinearDeflection) CfdTools.cfdMessage(" writing to file\n") CfdTools.writePatchToStl(patch_name, mesh_stl, fid, self.scale)
def process3D_ObjectsViaOpenSCAD(doc,ObjList,Operation): import FreeCAD,Mesh,Part params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD") if False: # disabled due to issue 1292 import MeshPart meshes = [MeshPart.meshFromShape(obj.Shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0)) for obj in ObjList] else: meshes = [Mesh.Mesh(obj.Shape.tessellate(params.GetFloat(\ 'meshmaxlength',1.0))) for obj in ObjList] if max(mesh.CountPoints for mesh in meshes) < \ params.GetInt('tempmeshmaxpoints',5000): stlmesh = meshoptempfile(Operation,meshes) sh=Part.Shape() sh.makeShapeFromMesh(stlmesh.Topology,0.1) solid = Part.Solid(sh) obj=doc.addObject('Part::Feature',Operation) #non parametric objec solid=solid.removeSplitter() if solid.Volume < 0: solid.complement() obj.Shape=solid#.removeSplitter() if FreeCAD.GuiUp: for index in ObjList : index.ViewObject.hide() return(obj)
def Activated(self): import Mesh import MeshPart from .GDMLObjects import GDMLTessellated, GDMLTriangular, \ ViewProvider, ViewProviderExtension for obj in FreeCADGui.Selection.getSelection(): #if len(obj.InList) == 0: # allowed only for for top level objects print('Action Tessellate') if hasattr(obj, 'Shape'): shape = obj.Shape.copy(False) mesh = MeshPart.meshFromShape(Shape=shape,Fineness=2,\ SecondOrder=0,Optimize=1,AllowQuad=0) print('Points : ' + str(mesh.CountPoints)) #print(mesh.Points) print('Facets : ' + str(mesh.CountFacets)) #print(mesh.Facets) parent = None name = 'GDMLTessellate_Tess_' + obj.Name if hasattr(obj, 'InList'): if len(obj.InList) > 0: parent = obj.InList[0] myTess = parent.newObject('Part::FeaturePython', name) if parent == None: myTess = FreeCAD.ActiveDocument.addObject( \ 'Part::FeaturePython',name) GDMLTessellated(myTess,mesh.Topology[0],mesh.Topology[1], \ "mm", getSelectedMaterial()) myTess.Placement = obj.Placement FreeCAD.ActiveDocument.recompute() if FreeCAD.GuiUp: ViewProvider(myTess.ViewObject) obj.ViewObject.Visibility = False myTess.ViewObject.DisplayMode = 'Flat Lines' FreeCADGui.SendMsgToActiveView("ViewFit")
def writePartFile(self): """ Construct multi-element STL based on mesh part faces. """ if self.mesh_obj.MeshUtility == "gmsh": self.part_obj.Shape.exportBrep(self.temp_file_shape) else: if ("Boolean" in self.part_obj.Name) and self.mesh_obj.MeshUtility: FreeCAD.Console.PrintError( 'cfMesh and snappyHexMesh do not accept boolean fragments.' ) with open(self.temp_file_geo, 'w') as fullMeshFile: for (i, objFaces) in enumerate(self.part_obj.Shape.Faces): faceName = ("face{}".format(i)) CfdTools.cfdMessage("Triangulating part: {}:{} ...".format( self.part_obj.Label, faceName)) mesh_stl = MeshPart.meshFromShape( objFaces, LinearDeflection=self.mesh_obj.STLLinearDeflection) CfdTools.cfdMessage(" writing to file\n") fullMeshFile.write("solid {}\n".format(faceName)) for face in mesh_stl.Facets: n = face.Normal fullMeshFile.write(" facet normal {} {} {}\n".format( n[0], n[1], n[2])) fullMeshFile.write(" outer loop\n") for j in range(3): p = face.Points[j] fullMeshFile.write(" vertex {} {} {}".format( self.scale * p[0], self.scale * p[1], self.scale * p[2])) fullMeshFile.write("\n") fullMeshFile.write(" endloop\n") fullMeshFile.write(" endfacet\n") fullMeshFile.write("endsolid {}\n".format(faceName))
def getShapeFromMesh(mesh): import Part, MeshPart if mesh.isSolid() and (mesh.countComponents() == 1): # use the best method faces = [] for f in mesh.Facets: p=f.Points+[f.Points[0]] pts = [] for pp in p: pts.append(FreeCAD.Vector(pp[0],pp[1],pp[2])) faces.append(Part.Face(Part.makePolygon(pts))) shell = Part.makeShell(faces) solid = Part.Solid(shell) solid = solid.removeSplitter() return solid faces = [] segments = mesh.getPlanarSegments(0.001) # use rather strict tolerance here for i in segments: if len(i) > 0: wires = MeshPart.wireFromSegment(mesh, i) if wires: faces.append(makeFace(wires)) try: se = Part.makeShell(faces) except: return None else: try: solid = Part.Solid(se) except: return se else: return solid
def process3D_ObjectsViaOpenSCADShape(ObjList, Operation, maxmeshpoints=None): import FreeCAD, Mesh, Part params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD") if False: # disabled due to issue 1292 import MeshPart meshes = [ MeshPart.meshFromShape( obj.Shape, params.GetFloat("meshmaxlength", 1.0), params.GetFloat("meshmaxarea", 0.0), params.GetFloat("meshlocallen", 0.0), params.GetFloat("meshdeflection", 0.0), ) for obj in ObjList ] else: meshes = [Mesh.Mesh(obj.Shape.tessellate(params.GetFloat("meshmaxlength", 1.0))) for obj in ObjList] if max(mesh.CountPoints for mesh in meshes) < (maxmeshpoints or params.GetInt("tempmeshmaxpoints", 5000)): stlmesh = meshoptempfile(Operation, meshes) sh = Part.Shape() sh.makeShapeFromMesh(stlmesh.Topology, 0.1) solid = Part.Solid(sh) solid = solid.removeSplitter() if solid.Volume < 0: solid.complement() return solid
def write_part_file(self): """ Construct multi-element STL based on mesh part faces. """ # Check if part is a boolean segment if ("Boolean" in self.part_obj.Name) and self.mesh_obj.MeshUtility: FreeCAD.Console.PrintError( 'cfMesh and snappyHexMesh does not accept boolean segments.') fullMeshFile = open(self.temp_file_geo + '.stl', 'w') for (i, objFaces) in enumerate(self.part_obj.Shape.Faces): faceName = ("face{}".format(i)) meshStl = MeshPart.meshFromShape( objFaces, LinearDeflection=self.mesh_obj.STLLinearDeflection) fullMeshFile.write("solid {}\n".format(faceName)) for face in meshStl.Facets: n = face.Normal fullMeshFile.write(" facet normal {} {} {}\n".format( n[0], n[1], n[2])) fullMeshFile.write(" outer loop\n") for j in range(3): p = face.Points[j] fullMeshFile.write(" vertex {} {} {}".format( self.scale * p[0], self.scale * p[1], self.scale * p[2])) fullMeshFile.write("\n") fullMeshFile.write(" endloop\n") fullMeshFile.write(" endfacet\n") fullMeshFile.write("endsolid {}\n".format(faceName)) fullMeshFile.close()
def _export_to_stl(self, freecad_object): shape = freecad_object.Shape meshed_object = freecad_object.Document.addObject( "Mesh::Feature", "Mesh") meshed_object.Mesh = MeshPart.meshFromShape(Shape=shape, MaxLength=520) meshed_object.Mesh.write(self.stl_path)
def export_part_as_stl(part, file_path, linear_deflection=0.1, angular_deflection=0.0523599): # The lower Angular Deflection makes rounded features more precise in the mesh mesh = MeshPart.meshFromShape(part, LinearDeflection=linear_deflection, AngularDeflection=angular_deflection) mesh.write(file_path)
def opExecute(self, obj): '''opExecute(obj) ... process engraving operation''' PathLog.track() output = "" if obj.Comment != "": output += '(' + str(obj.Comment)+')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str(obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return print("base object: " + self.baseobject.Name) if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError( translate("Path_Surface", "This operation requires OpenCamLib to be installed.\n")) return if self.baseobject.TypeId.startswith('Mesh'): mesh = self.baseobject.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: from PathScripts.PathPreferences import PathPreferences deflection = PathPreferences.defaultGeometryTolerance() self.baseobject.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(self.baseobject.Shape, Deflection=deflection) bb = mesh.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point( q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)
def getShapeFromMesh(mesh,fast=True,tolerance=0.001,flat=False,cut=True): import Part, MeshPart, DraftGeomUtils if mesh.isSolid() and (mesh.countComponents() == 1) and fast: # use the best method faces = [] for f in mesh.Facets: p=f.Points+[f.Points[0]] pts = [] for pp in p: pts.append(FreeCAD.Vector(pp[0],pp[1],pp[2])) try: f = Part.Face(Part.makePolygon(pts)) except: pass else: faces.append(f) shell = Part.makeShell(faces) solid = Part.Solid(shell) solid = solid.removeSplitter() return solid faces = [] segments = mesh.getPlanarSegments(tolerance) #print len(segments) for i in segments: if len(i) > 0: wires = MeshPart.wireFromSegment(mesh, i) if wires: if flat: nwires = [] for w in wires: nwires.append(DraftGeomUtils.flattenWire(w)) wires = nwires try: faces.append(makeFace(wires,method=int(cut)+1)) except: return None try: se = Part.makeShell(faces) se = se.removeSplitter() if flat: return se except Part.OCCError: try: cp = Part.makeCompound(faces) except Part.OCCError: return None else: return cp else: try: solid = Part.Solid(se) except Part.OCCError: return se else: return solid
def triangulate(shape): "triangulates the given face" p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") mesher = p.GetInt("ColladaMesher",0) tessellation = p.GetFloat("ColladaTessellation",1.0) grading = p.GetFloat("ColladaGrading",0.3) segsperedge = p.GetInt("ColladaSegsPerEdge",1) segsperradius = p.GetInt("ColladaSegsPerRadius",2) secondorder = p.GetBool("ColladaSecondOrder",False) optimize = p.GetBool("ColladaOptimize",True) allowquads = p.GetBool("ColladaAllowQuads",False) if mesher == 0: return shape.tessellate(tessellation) elif mesher == 1: return MeshPart.meshFromShape(Shape=shape,MaxLength=tessellation).Topology else: return MeshPart.meshFromShape(Shape=shape,GrowthRate=grading,SegPerEdge=segsperedge, SegPerRadius=segsperradius,SecondOrder=secondorder,Optimize=optimize, AllowQuad=allowquads).Topology
def mefisto_mesher(solids, max_edge_length): verts = [] faces = [] for solid, max_edge in zip(*mlr([solids, max_edge_length])): mesh = MeshPart.meshFromShape(Shape=solid, MaxLength=max_edge) verts.append([v[:] for v in mesh.Topology[0]]) faces.append(mesh.Topology[1]) return verts, faces
def exportarEnSTL(self, cuerpo, rutaFichero = "C:/FabCAD/obj.stl"): doc = FreeCAD.getDocument(cuerpo.doc.nombre) doc.recompute() mesh = doc.addObject("Mesh::Feature","Mesh") part = doc.getObject(extraerStringPadre(cuerpo)) shape = Part.getShape(part,extraerString(cuerpo)) mesh.Mesh = MeshPart.meshFromShape(Shape=shape,Fineness=4,SecondOrder=0,Optimize=1,AllowQuad=0) mesh.Mesh.write(rutaFichero)
def mesher(shape): """Mesh a shape.""" # Generate mesh mesh = MeshPart.meshFromShape( Shape=shape, LinearDeflection=self.linear_deflection, AngularDeflection=self.angular_deflection, Relative=False, ) # Harmonize normals mesh.harmonizeNormals() return mesh
def shape2polyhedron(shape): import MeshPart fa = params.GetFloat("exportFa", 12.0) return mesh2polyhedron( MeshPart.meshFromShape( shape, params.GetFloat("meshmaxlength", 1.0), params.GetFloat("meshmaxarea", 0.0), params.GetFloat("meshlocallen", 0.0), params.GetFloat("meshdeflection", 0.0), ) )
def mefisto_mesher(self): solids = self.inputs[0].sv_get() max_edge_length = self.inputs['Max Edge Length'].sv_get()[0] verts = [] faces = [] for solid, max_edge in zip(*mlr([solids, max_edge_length])): mesh = MeshPart.meshFromShape(Shape=solid, MaxLength=max_edge) verts.append([v[:] for v in mesh.Topology[0]]) faces.append(mesh.Topology[1]) return verts, faces
def save_components_as_stl(dictionary_of_parts, output_folder): try: os.makedirs(output_folder) except: pass for component in dictionary_of_parts: filename_list = [] file = dictionary_of_parts[component]['step_filename'] multipart_step = Part.read(file) #path =os.path.join(output_folder, os.path.splitext(file)[0] + '_' + str(file_counter) + '.stl') file_counter = 1 for solid in multipart_step.Solids: solid_mesh = MeshPart.meshFromShape(solid, LinearDeflection=0.01) stl_filename = os.path.join( output_folder, os.path.splitext(os.path.split(file)[1])[0] + '_' + str(file_counter) + '.stl') filename_list.append(stl_filename) solid_mesh.write(stl_filename) file_counter = file_counter + 1 if len(multipart_step.Solids) == 0: singlepart_step = multipart_step solid_mesh = MeshPart.meshFromShape(singlepart_step, LinearDeflection=0.01) stl_filename = os.path.join( output_folder, os.path.splitext(os.path.split(file)[1])[0] + '_' + str(file_counter) + '.stl') filename_list.append(stl_filename) solid_mesh.write(stl_filename) file_counter = file_counter + 1 dictionary_of_parts[component]['stl_filename'] = filename_list return dictionary_of_parts
def export_stl(self, prefix="", name=""): """ exports to stl the piece to print Parameters: ----------- prefix : str Prefix to the piece, may be useful if name is not given and want to add a prefix to the self.name an underscore will be added between prefix and name name : str Name of the piece, if not given, it will take self.name """ if not name: filename = self.name if prefix: filename = prefix + '_' + filename pos0 = self.pos0 rotation = FreeCAD.Rotation(self.prnt_ax, VZ) shp = self.shp # ----------- moving the shape doesnt work: # I think that is because it is bound to a FreeCAD object #shp.Placement.Base = self.pos.negative() + self.place.negative() #shp.translate (self.pos.negative() + self.place.negative()) #shp.rotate (V0, rotation.Axis, math.degrees(rotation.Angle)) #shp.Placement.Base = self.place #shp.Placement.Rotation = fcfun.V0ROT # ----------- option 1. making a copy of the shape # and then deleting it (nullify) #shp_cpy = shp.copy() #shp_cpy.translate (pos0.negative() + self.place.negative()) #shp_cpy.rotate (V0, rotation.Axis, math.degrees(rotation.Angle)) #shp_cpy.exportStl(stl_path + filename + 'stl') #shp_cpy.nullify() # ----------- option 2. moving the freecad object self.fco.Placement.Base = pos0.negative() + self.place.negative() self.fco.Placement.Rotation = rotation self.doc.recompute() # exportStl is not working well with FreeCAD 0.17 #self.fco.Shape.exportStl(self.stl_path + filename + '.stl') mesh_shp = MeshPart.meshFromShape(self.fco.Shape, LinearDeflection=kparts.LIN_DEFL, AngularDeflection=kparts.ANG_DEFL) mesh_shp.write(stlFileName) del mesh_shp self.fco.Placement.Base = self.place self.fco.Placement.Rotation = V0ROT self.doc.recompute()
def export_stl (self, name = ""): #filepath = os.getcwd() if not name: name = self.name #stlPath = filepath + "/freecad/stl/" stlPath = filepath + stl_dir stlFileName = stlPath + name + ".stl" # exportStl is not working well with FreeCAD 0.17 #self.shp.exportStl(stlFileName) mesh_shp = MeshPart.meshFromShape(self.shp, LinearDeflection=kparts.LIN_DEFL, AngularDeflection=kparts.ANG_DEFL) mesh_shp.write(stlFileName) del mesh_shp
def standard_mesher(solids, surface_deviation, angle_deviation, relative_surface_deviation): verts = [] faces = [] for solid, s_dev, ang_dev in zip( *mlr([solids, surface_deviation, angle_deviation])): mesh = MeshPart.meshFromShape(Shape=solid, LinearDeflection=s_dev, AngularDeflection=math.radians(ang_dev), Relative=relative_surface_deviation) verts.append([v[:] for v in mesh.Topology[0]]) faces.append(mesh.Topology[1]) return verts, faces
def meshToShape(obj,mark=True): '''meshToShape(object,[mark]): turns a mesh into a shape, joining coplanar facets. If mark is True (default), non-solid objects will be marked in red''' name = obj.Name import Part,MeshPart from draftlibs import fcgeo if "Mesh" in obj.PropertiesList: faces = [] mesh = obj.Mesh plac = obj.Placement segments = mesh.getPlanes(0.001) # use rather strict tolerance here print len(segments)," segments ",segments for i in segments: print "treating",segments.index(i),i if len(i) > 0: wires = MeshPart.wireFromSegment(mesh, i) print "wire done" print wires if wires: faces.append(makeFace(wires)) print "done facing" print "faces",faces try: se = Part.makeShell(faces) solid = Part.Solid(se) except: pass else: if solid.isClosed(): FreeCAD.ActiveDocument.removeObject(name) newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name) newobj.Shape = solid newobj.Placement = plac if not solid.isClosed(): if mark: newobj.ViewObject.ShapeColor = (1.0,0.0,0.0,1.0) return newobj return None
gui_doc.getObject("Cut").ShapeColor = (0.00,0.33,0.50) gui_doc.getObject("Cut").DisplayMode = "Shaded" # Tube gui_doc.getObject("Sweep").ShapeColor = (0.00,0.33,0.00) gui_doc.getObject("Sweep").DisplayMode = "Shaded" gui_doc.getObject("Sweep").Visibility = True # Sketches gui_doc.getObject("Circle").Visibility = False gui_doc.getObject("BSpline").Visibility = False ## Save file fname = "/mana_item" file_path = os.path.dirname(__file__) + fname + ".FCStd" stl_path = os.path.dirname(__file__) + fname + ".STL" stl_path2 = os.path.dirname(__file__) + fname + "_fine" + ".STL" doc.saveAs(file_path) Mesh.export([tube, cut], stl_path) print("Successfully generate the mana item!") ## Manually handle meshes cut_mesh = doc.addObject("Mesh::Feature","Cut mesh") tube_mesh = doc.addObject("Mesh::Feature","Sweep mesh") cut_mesh.Mesh = MeshPart.meshFromShape(Shape=cut.Shape, Fineness=2, SecondOrder=0, Optimize=1, AllowQuad=0) tube_mesh.Mesh = MeshPart.meshFromShape(Shape=tube.Shape, Fineness=2, SecondOrder=0, Optimize=1, AllowQuad=0) Mesh.export([tube_mesh, cut_mesh], stl_path2) doc.cut_mesh.Visibility = False doc.tube_mesh.Visibility = False
def execute(self, obj): import MeshPart FreeCAD.Console.PrintWarning( translate("PathSurface", "Hold on. This might take a minute.\n")) output = "" toolLoad = PathUtils.getLastToolLoad(obj) if toolLoad is None or toolLoad.ToolNumber == 0: self.vertFeed = 100 self.horizFeed = 100 self.radius = 0.25 obj.ToolNumber = 0 obj.ToolDescription = "UNDEFINED" else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value tool = PathUtils.getTool(obj, toolLoad.ToolNumber) self.radius = tool.Diameter/2 obj.ToolNumber = toolLoad.ToolNumber obj.ToolDescription = toolLoad.Name if obj.UserLabel == "": obj.Label = obj.Name + " (" + obj.ToolDescription + ")" else: obj.Label = obj.UserLabel + " (" + obj.ToolDescription + ")" if obj.Base: for b in obj.Base: if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError(translate( "PathSurface", "This operation requires OpenCamLib to be installed.\n")) return mesh = b[0] if mesh.TypeId.startswith('Mesh'): mesh = mesh.Mesh bb = mesh.BoundBox else: bb = mesh.Shape.BoundBox mesh = MeshPart.meshFromShape(mesh.Shape, MaxLength=2) s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point( q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) path = Path.Path(output) obj.Path = path
def execute(self, obj): import MeshPart FreeCAD.Console.PrintWarning( translate("Path_Surface", "Hold on. This might take a minute.\n")) output = "" if obj.Comment != "": output += '(' + str(obj.Comment)+')\n' toolLoad = obj.ToolController if toolLoad is None or toolLoad.ToolNumber == 0: FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.") else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value self.vertRapid = toolLoad.VertRapid.Value self.horizRapid = toolLoad.HorizRapid.Value tool = toolLoad.Proxy.getTool(toolLoad) if not tool or tool.Diameter == 0: FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.") return else: self.radius = tool.Diameter/2 output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")" # if obj.Base: # for b in obj.Base: parentJob = PathUtils.findParentJob(obj) if parentJob is None: return mesh = parentJob.Base if mesh is None: return print("base object: " + mesh.Name) if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError( translate("Path_Surface", "This operation requires OpenCamLib to be installed.\n")) return if mesh.TypeId.startswith('Mesh'): mesh = mesh.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: from PathScripts.PathPreferences import PathPreferences deflection = PathPreferences.defaultGeometryTolerance() mesh = MeshPart.meshFromShape(mesh.Shape, Deflection=deflection) bb = mesh.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point( q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) if obj.Active: path = Path.Path(output) obj.Path = path obj.ViewObject.Visibility = True else: path = Path.Path("(inactive operation)") obj.Path = path obj.ViewObject.Visibility = False
def opExecute(self, obj): '''opExecute(obj) ... process surface operation''' PathLog.track() # OCL must be installed try: import ocl except: FreeCAD.Console.PrintError( translate("Path_Surface", "This operation requires OpenCamLib to be installed.") + "\n") return print("StepOver is " + str(obj.StepOver)) if obj.StepOver > 100: obj.StepOver = 100 if obj.StepOver < 1: obj.StepOver = 1 output = "" if obj.Comment != "": output += '(' + str(obj.Comment) + ')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str(obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return for base in self.model: print("base object: " + base.Name) if base.TypeId.startswith('Mesh'): mesh = base.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: import PathScripts.PathPreferences as PathPreferences deflection = PathPreferences.defaultGeometryTolerance() base.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(base.Shape, Deflection=deflection) if obj.BoundBox == "BaseBoundBox": bb = mesh.BoundBox else: bb = parentJob.Stock.Shape.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] # offset the triangle in Z with DepthOffset t = ocl.Triangle(ocl.Point(p[0], p[1], p[2] + obj.DepthOffset.Value), ocl.Point(q[0], q[1], q[2] + obj.DepthOffset.Value), ocl.Point(r[0], r[1], r[2] + obj.DepthOffset.Value)) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)
def execute(self, obj): import MeshPart FreeCAD.Console.PrintWarning( translate("PathSurface", "Hold on. This might take a minute.\n")) output = "" if obj.Comment != "": output += '(' + str(obj.Comment)+')\n' toolLoad = PathUtils.getLastToolLoad(obj) if toolLoad is None or toolLoad.ToolNumber == 0: self.vertFeed = 100 self.horizFeed = 100 self.vertRapid = 100 self.horizRapid = 100 self.radius = 0.25 obj.ToolNumber = 0 obj.ToolDescription = "UNDEFINED" else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value self.vertRapid = toolLoad.VertRapid.Value self.horizRapid = toolLoad.HorizRapid.Value tool = PathUtils.getTool(obj, toolLoad.ToolNumber) if tool.Diameter == 0: self.radius = 0.25 else: self.radius = tool.Diameter/2 obj.ToolNumber = toolLoad.ToolNumber obj.ToolDescription = toolLoad.Name if obj.UserLabel == "": obj.Label = obj.Name + " :" + obj.ToolDescription else: obj.Label = obj.UserLabel + " :" + obj.ToolDescription output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")" # if obj.Base: # for b in obj.Base: parentJob = PathUtils.findParentJob(obj) if parentJob is None: return mesh = parentJob.Base if mesh is None: return print "base object: " + mesh.Name if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError(translate( "PathSurface", "This operation requires OpenCamLib to be installed.\n")) return #mesh = b[0] if mesh.TypeId.startswith('Mesh'): mesh = mesh.Mesh bb = mesh.BoundBox else: bb = mesh.Shape.BoundBox mesh = MeshPart.meshFromShape(mesh.Shape, MaxLength=2) s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point( q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) if obj.Active: path = Path.Path(output) obj.Path = path obj.ViewObject.Visibility = True else: path = Path.Path("(inactive operation)") obj.Path = path obj.ViewObject.Visibility = False
def shape2polyhedron(shape): import MeshPart return mesh2polyhedron(MeshPart.meshFromShape(Shape=shape,\ Deflection= params.GetFloat('meshdeflection',0.0)))
# FreeCAD TemplatePyMod module # (c) 2010 Werner Mayer LGPL import Mesh,Part,MeshPart faces = [] mesh = App.ActiveDocument.ActiveObject.Mesh segments = mesh.getPlanarSegments(0.00001) # use rather strict tolerance here for i in segments: if len(i) > 0: # a segment can have inner holes wires = MeshPart.wireFromSegment(mesh, i) # we assume that the exterior boundary is that one with the biggest bounding box if len(wires) > 0: ext=None max_length=0 for i in wires: if i.BoundBox.DiagonalLength > max_length: max_length = i.BoundBox.DiagonalLength ext = i wires.remove(ext) # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails for i in wires: i.reverse() # make sure that the exterior wires comes as first in the list wires.insert(0, ext) faces.append(Part.Face(wires))
# opening of file file = cwd + list_of_files[i] FreeCAD.newDocument() FreeCAD.setActiveDocument("Unnamed") doc = FreeCAD.getDocument("Unnamed") FreeCAD.ActiveDocument = doc Part.insert(file,"Unnamed") # before converting to mesh we need to merge all shapes in the document if len(doc.Objects) > 1: FreeCAD.activeDocument().addObject("Part::MultiFuse","Fusion") FreeCAD.activeDocument().Fusion.Shapes = [doc.Objects[k] for k in range(len(doc.Objects) - 1)] FreeCAD.ActiveDocument.recompute() mesh = doc.addObject("Mesh::Feature","Mesh") mesh.Mesh = MeshPart.meshFromShape(doc.getObject("Fusion").Shape,\ Fineness=5,SecondOrder=0,Optimize=0,AllowQuad=0.5) else: mesh = doc.addObject("Mesh::Feature","Mesh") mesh.Mesh = MeshPart.meshFromShape(doc.getObject(doc.Objects[0].Name).Shape,\ Fineness=5,SecondOrder=0,Optimize=0,AllowQuad=0.5) del doc, mesh # saving the stl file file_stl = file.replace(".step", ".stl") FreeCAD.ActiveDocument.getObject("Mesh").Mesh.write(file_stl,"STL") FreeCAD.closeDocument("Unnamed") # using meshlab to convert stl files to dae file_dae = file.replace(".step", ".dae") convert = "meshlabserver -i " + file_stl + " -o " + file_dae
cyl1.Radius = 0.2 * radius cyl1.Height = 1.1 * height cyl1.Placement = Base.Placement(Base.Vector(-1.1 * radius, 0.0, -0.2 * height), Base.Rotation(0.0, 0.0, 0.0, 1)) arr = Draft.makeArray(cyl1, Base.Vector(1, 0, 0), Base.Vector(0, 1, 0), 2, 2) arr.ArrayType = "polar" arr.NumberPolar = 6 dif2 = doc.addObject("Part::Cut", "dif2") dif2.Base = dif dif2.Tool = arr cyl2 = doc.addObject("Part::Cylinder", "cyl2") cyl2.Radius = 0.3 * radius cyl2.Height = height dif3 = doc.addObject("Part::Cut", "dif3") dif3.Base = dif2 dif3.Tool = cyl2 doc.recompute() Part.export([dif3], 'screwdriver_handle.step') doc.saveAs('screwdriver_handle.FCStd') mesh = doc.addObject("Mesh::Feature", "Mesh") mesh.Mesh = MeshPart.meshFromShape(Shape=dif3.Shape, MaxLength=0.002) mesh.Mesh.write("./screwdriver_handle.bdf", "NAS", "mesh")
# opening of file file = cwd + list_of_files[i] FreeCAD.newDocument() FreeCAD.setActiveDocument("Unnamed") doc = FreeCAD.getDocument("Unnamed") FreeCAD.ActiveDocument = doc Part.insert(file,"Unnamed") # before converting to mesh we need to merge all shapes in the document if len(doc.Objects) > 1: FreeCAD.activeDocument().addObject("Part::MultiFuse","Fusion") FreeCAD.activeDocument().Fusion.Shapes = [doc.Objects[k] for k in range(len(doc.Objects) - 1)] FreeCAD.ActiveDocument.recompute() mesh = doc.addObject("Mesh::Feature","Mesh") mesh.Mesh = MeshPart.meshFromShape(doc.getObject("Fusion").Shape,5,0,0,0.5) else: mesh = doc.addObject("Mesh::Feature","Mesh") mesh.Mesh = MeshPart.meshFromShape(doc.getObject(doc.Objects[0].Name).Shape,5,0,0,0.5) del doc, mesh # saving the stl file file_stl = file.replace(".step", ".stl") FreeCAD.ActiveDocument.getObject("Mesh").Mesh.write(file_stl,"STL") FreeCAD.closeDocument("Unnamed") # using meshlab to convert stl files to dae file_dae = file.replace(".step", ".dae") convert = "meshlabserver -i " + file_stl + " -o " + file_dae os.system(convert)
pointstr=','.join(['[%f,%f,%f]' % tuple(vec) for vec in mesh.Topology[0]]) trianglestr=','.join(['[%d,%d,%d]' % tuple(tri) for tri in mesh.Topology[1]]) return 'polyhedron ( points = [%s], triangles = [%s]);' % (pointstr,trianglestr) def vector2d(v): return [v[0],v[1]] def vertexs2polygon(vertex): pointstr=','.join(['[%f, %f]' % tuple(vector2d(v.Point)) for v in vertex]) return 'polygon ( points = [%s], paths = undef, convexity = 1);}' % pointstr def shape2polyhedron(shape): import MeshPart fa = params.GetFloat('exportFa',12.0) return mesh2polyhedron(MeshPart.meshFromShape(shape,params.GetFloat(\ 'meshmaxlength',1.0), params.GetFloat('meshmaxarea',0.0),\ params.GetFloat('meshlocallen',0.0),\ params.GetFloat('meshdeflection',0.0))) def process_object(csg,ob): print "Placement" print "Pos : "+str(ob.Placement.Base) print "axis : "+str(ob.Placement.Rotation.Axis) print "angle : "+str(ob.Placement.Rotation.Angle) if ob.Type == "Part::Sphere" : print "Sphere Radius : "+str(ob.Radius) check_multmatrix(csg,ob,0,0,0) global fafs csg.write("sphere($fn = 0, "+fafs+", r = "+str(ob.Radius)+");\n")