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 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 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 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: 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 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 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 _get_indices(shape, offsetv: int, offsetvn: int) -> Tuple[List[str], List[str], List[str]]: """ Return a tuple containing 3 lists: 1. vertexes 2. vertex normals 3. and face indices offset with a given amount. """ vlist = [] vnlist = [] flist = [] # Triangulates shapes with curves mesh = MeshPart.meshFromShape(Shape=shape, LinearDeflection=0.1, AngularDeflection=0.7, Relative=True) for v in mesh.Topology[0]: p = Draft.precision() vlist.append( str(round(v[0], p)) + ' ' + str(round(v[1], p)) + ' ' + str(round(v[2], p))) for vn in mesh.Facets: vnlist.append( str(vn.Normal[0]) + ' ' + str(vn.Normal[1]) + ' ' + str(vn.Normal[2])) for i, vn in enumerate(mesh.Topology[1]): flist.append( str(vn[0] + offsetv) + '//' + str(i + offsetvn) + ' ' + str(vn[1] + offsetv) + '//' + str(i + offsetvn) + ' ' + str(vn[2] + offsetv) + '//' + str(i + offsetvn)) return vlist, vnlist, flist
def exportVisible(self): if self.doc.FileName=="": raise Exception("Please save the document first to give it a filename.") # TODO: These should be configurable parameters degrees = 3 millimeters = 0.1 angl = degrees * math.pi/180 visibleObjs=self.getVisibleObjects() if not len(visibleObjs): raise Exception("No visible objects to export") # for obj in visibleObjs: # print(obj.Name) mesh = Mesh.Mesh() for obj in visibleObjs: # Don't spam console with missing attribute errors for "Shape" if not hasattr(obj, "Shape"): continue try: shape = obj.Shape.copy(False) shape.Placement= obj.getGlobalPlacement() # See Mesh Design workbench => Tesselate shape => Standard # LinearDeflection is "Surface deviation" # AngularDeflection is "Angular deviation" but in radians (i.e. 3.14159 is 180°) mesh2 = MeshPart.meshFromShape(Shape=shape, LinearDeflection=millimeters, AngularDeflection=angl, Relative=False) mesh = mesh.unite(mesh2) except: print(obj.Name, sys.exc_info()[1]) mesh.write(Filename=self.getStlFileName())
def part2meshStandard(self, part, surfDev=0.1, angDev=0.523599, fineRes=False): """ 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 Standard algorithm, and defines mesh by surface and angular deviation. Default surface deviation is 0.1mm, and default angular deviation is 0.523599rad (30deg) """ if fineRes == True: surfDev = 0.05 angDev = 0.523599 #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=shape, LinearDeflection=surfDev, AngularDeflection=angDev, Relative=False) meshes.append(mesh) print("Converted parts to mesh objects using Standard algorithm.") log.info("Converted parts to mesh objects using Standard algorithm.") return meshes
# 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
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 shape2polyhedron(shape): import MeshPart return mesh2polyhedron(MeshPart.meshFromShape(Shape=shape,\ Deflection= params.GetFloat('meshdeflection',0.0)))
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
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")
# 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)
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
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")