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 createOrUpdateSimpleAssemblyShape(doc): visibleImportObjects = [ obj for obj in doc.Objects if 'importPart' in obj.Content and hasattr(obj, 'ViewObject') and obj.ViewObject.isVisible() and hasattr(obj, 'Shape') and len(obj.Shape.Faces) > 0 ] if len(visibleImportObjects) == 0: QtGui.QMessageBox.critical(QtGui.QApplication.activeWindow(), "Cannot create SimpleAssemblyShape", "No visible ImportParts found") return sas = doc.getObject('SimpleAssemblyShape') if sas == None: sas = doc.addObject("Part::FeaturePython", "SimpleAssemblyShape") SimpleAssemblyShape(sas) #sas.ViewObject.Proxy = 0 ViewProviderSimpleAssemblyShape(sas.ViewObject) faces = [] shape_list = [] for obj in visibleImportObjects: faces = faces + obj.Shape.Faces shape_list.append(obj.Shape) shell = Part.makeShell(faces) try: # solid = Part.Solid(shell) # solid = Part.makeCompound (shape_list) if a2plib.getUseSolidUnion(): if len(shape_list) > 1: shape_base = shape_list[0] shapes = shape_list[1:] solid = shape_base.fuse(shapes) else: #one shape only numShellFaces = len(shell.Faces) solid = Part.Solid( shell ) # This does not work if shell includes spherical faces. FC-Bug ?? numSolidFaces = len(solid.Faces) # Check, whether all faces where processed... if numShellFaces != numSolidFaces: solid = shell # Some faces are missing, take shell as result as workaround.. else: numShellFaces = len(shell.Faces) solid = Part.Solid( shell ) # This does not work if shell includes spherical faces. FC-Bug ?? numSolidFaces = len(solid.Faces) # Check, whether all faces where processed... if numShellFaces != numSolidFaces: solid = shell # Some faces are missing, take shell as result as workaround.. except: # keeping a shell if solid is failing solid = shell sas.Shape = solid #shell sas.ViewObject.Visibility = False
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 createOrUpdateSimpleAssemblyShape(doc): visibleImportObjects = [ obj for obj in doc.Objects if 'importPart' in obj.Content and hasattr(obj, 'ViewObject') and obj.ViewObject.isVisible() and hasattr(obj, 'Shape') and len(obj.Shape.Faces) > 0 ] if len(visibleImportObjects) == 0: QtGui.QMessageBox.critical( QtGui.QApplication.activeWindow(), translate("A2plus_MuxAssembly", "Cannot create SimpleAssemblyShape"), translate("A2plus_MuxAssembly", "No visible ImportParts found")) return sas = doc.getObject('SimpleAssemblyShape') if sas is None: sas = doc.addObject("Part::FeaturePython", "SimpleAssemblyShape") SimpleAssemblyShape(sas) #sas.ViewObject.Proxy = 0 ViewProviderSimpleAssemblyShape(sas.ViewObject) faces = [] shape_list = [] for obj in visibleImportObjects: faces = faces + obj.Shape.Faces shape_list.append(obj.Shape) if len(faces) == 1: shell = Part.makeShell([faces]) else: shell = Part.makeShell(faces) try: if a2plib.getUseSolidUnion(): if len(shape_list) > 1: shape_base = shape_list[0] shapes = shape_list[1:] solid = shape_base.fuse(shapes) else: solid = Part.Solid(shape_list[0]) else: solid = Part.Solid( shell ) # This does not work if shell includes spherical faces. FC-Bug ?? # Fall back to shell if faces are misiing if len(shell.Faces) != len(solid.Faces): solid = shell except: # keeping a shell if solid is failing FreeCAD.Console.PrintWarning('Union of Shapes FAILED\n') solid = shell sas.Shape = solid #shell sas.ViewObject.Visibility = False
def _is_inside(poly, part): """Given a polygon, find a point inside of it, and then check if that point is in the (3D) part Parameters ---------- poly : part : Returns ------- Boolean """ # Find the midpoint in x, then find the intersections with the polygon on # that vertical line. Then find the midpoint in y along the first # intersection line (if there're multiple) min_x, min_y, max_x, max_y = poly.bounds x = (min_x + max_x) / 2 x_line = LineString([(x, min_y), (x, max_y)]) intersec = x_line.intersection(poly) if type(intersec) == MultiLineString: intersec = intersec[0] x_line_intercept_min, x_line_intercept_max = intersec.xy[1].tolist( ) y = (x_line_intercept_min + x_line_intercept_max) / 2 # Get 3D coordinates and check if it's in the freecad shape x, y, z = _inverse_project([x, y]) freecad_solid = Part.Solid( FreeCAD.ActiveDocument.getObject(part.built_fc_name).Shape) return freecad_solid.isInside(Base.Vector(x, y, z), 1e-5, True)
def execute(self, obj): if not hasattr(obj, "Sources"): return src_shapes = [] for o in obj.Sources: sh = o.Shape.copy() #pl = sh.Placement sh.Placement = o.getGlobalPlacement() #.multiply(pl) src_shapes.append(sh) solids = [] num_faces = len(src_shapes[0].Faces) for i in range(num_faces): faces = [src_shapes[0].Faces[i], src_shapes[-1].Faces[i]] loft = [] num_wires = len(faces[0].Wires) for j in range(num_wires): wires = [] for o in src_shapes: wires.append(o.Faces[i].Wires[j]) loft = Part.makeLoft(wires, False, obj.Ruled, obj.Closed, obj.MaxDegree) faces.extend(loft.Faces) shell = Part.Shell(faces) solids.append(Part.Solid(shell)) obj.Shape = Part.Compound(solids)
def process_mesh_file(fname, ext): import Mesh, Part fullname = fname + '.' + ext filename = os.path.join(pathName, fullname) objname = os.path.split(fname)[1] mesh1 = doc.getObject(objname) #reuse imported object if not mesh1: Mesh.insert(filename) mesh1 = doc.getObject(objname) if mesh1 is not None: if gui: mesh1.ViewObject.hide() sh = Part.Shape() sh.makeShapeFromMesh(mesh1.Mesh.Topology, 0.1) solid = Part.Solid(sh) obj = doc.addObject('Part::Feature', "Mesh") #ImportObject(obj,mesh1) #This object is not mutable from the GUI #ViewProviderTree(obj.ViewObject) solid = solid.removeSplitter() if solid.Volume < 0: #sh.reverse() #sh = sh.copy() solid.complement() obj.Shape = solid #.removeSplitter() else: #mesh1 is None FreeCAD.Console.PrintError('Mesh not imported %s.%s %s\n' % \ (objname,ext,filename)) import Part obj = doc.addObject('Part::Feature', "FailedMeshImport") obj.Shape = Part.Compound([]) return (obj)
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 p_polyhedron_action(p) : '''polyhedron_action : polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA faces EQ OSQUARE path_set ESQUARE COMMA keywordargument_list RPAREN SEMICOL | polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA triangles EQ OSQUARE points_list_3d ESQUARE COMMA keywordargument_list RPAREN SEMICOL''' if printverbose: print("Polyhedron Points") v = [] for i in p[6] : if printverbose: print(i) v.append(FreeCAD.Vector(float(i[0]),float(i[1]),float(i[2]))) if printverbose: print(v) print ("Polyhedron "+p[9]) print (p[12]) faces_list = [] mypolyhed = doc.addObject('Part::Feature',p[1]) for i in p[12] : if printverbose: print(i) v2 = FreeCAD.Vector pp =[v2(v[k]) for k in i] # Add first point to end of list to close polygon pp.append(pp[0]) w = Part.makePolygon(pp) try: f = Part.Face(w) except Exception: secWireList = w.Edges[:] f = Part.makeFilledFace(Part.__sortEdges__(secWireList)) #f = make_face(v[int(i[0])],v[int(i[1])],v[int(i[2])]) faces_list.append(f) shell=Part.makeShell(faces_list) solid=Part.Solid(shell).removeSplitter() if solid.Volume < 0: solid.reverse() mypolyhed.Shape=solid p[0] = [mypolyhed]
def execute(self, fp): scale = fp.Radius / 1.7320508075689 phy = 1.61803398875 f = list() k = scale for i in (-scale, scale): for j in (-scale, scale): f.append( Part.Face( Part.makePolygon([(i, j, -k), (i / phy, j * phy, 0), (i, j, k), (i * phy, 0, k / phy), (i * phy, 0, -k / phy), (i, j, -k)]))) f.append( Part.Face( Part.makePolygon([(j, -k, i), (j * phy, 0, i / phy), (j, k, i), (0, k / phy, i * phy), (0, -k / phy, i * phy), (j, -k, i)]))) f.append( Part.Face( Part.makePolygon([(-k, i, j), (0, i / phy, j * phy), (k, i, j), (k / phy, i * phy, 0), (-k / phy, i * phy, 0), (-k, i, j)]))) fp.Shape = Part.Solid(Part.Shell(f))
def makeSurfaceVolume(filename): import FreeCAD,Part f1=open(filename) coords=[] miny=1 for line in f1.readlines(): sline=line.strip() if sline and not sline.startswith('#'): ycoord=len(coords) lcoords=[] for xcoord, num in enumerate(sline.split()): fnum=float(num) lcoords.append(FreeCAD.Vector(float(xcoord),float(ycoord),fnum)) miny=min(fnum,miny) coords.append(lcoords) s=Part.BSplineSurface() s.interpolate(coords) plane=Part.makePlane(len(coords[0])-1,len(coords)-1,FreeCAD.Vector(0,0,miny-1)) l1=Part.makeLine(plane.Vertexes[0].Point,s.value(0,0)) l2=Part.makeLine(plane.Vertexes[1].Point,s.value(1,0)) l3=Part.makeLine(plane.Vertexes[2].Point,s.value(0,1)) l4=Part.makeLine(plane.Vertexes[3].Point,s.value(1,1)) f0=plane.Faces[0] f0.reverse() f1=Part.Face(Part.Wire([plane.Edges[0],l1.Edges[0],s.vIso(0).toShape(),l2.Edges[0]])) f2=Part.Face(Part.Wire([plane.Edges[1],l3.Edges[0],s.uIso(0).toShape(),l1.Edges[0]])) f3=Part.Face(Part.Wire([plane.Edges[2],l4.Edges[0],s.vIso(1).toShape(),l3.Edges[0]])) f4=Part.Face(Part.Wire([plane.Edges[3],l2.Edges[0],s.uIso(1).toShape(),l4.Edges[0]])) f5=s.toShape().Faces[0] solid=Part.Solid(Part.Shell([f0,f1,f2,f3,f4,f5])) return solid,(len(coords[0])-1)/2.0,(len(coords)-1)/2.0
def computeShape(self, solid): """ Create faces shape. This method also calls to generate boxes. @param solid Solid shape that represent the tank. @return Computed solid shape. None if can't build it. """ # Study input to try to build a solid if solid.isDerivedFrom('Part::Feature'): # Get shape shape = solid.Shape if not shape: return None solid = shape if not solid.isDerivedFrom('Part::TopoShape'): return None # Get shells shells = solid.Shells if not shells: return None # Build solids solids = [] for s in shells: solid = Part.Solid(s) if solid.Volume < 0.0: solid.reverse() solids.append(solid) # Create compound shape = Part.CompSolid(solids) return shape
def createGeometry(self, fp): if all((fp.Radius1, fp.Radius2, fp.FacesNumber, fp.Height)): import math import FreeCAD, Part #from draftlibs import fcgeo plm = fp.Placement wires = [] faces = [] for ir, r in enumerate((fp.Radius1, fp.Radius2)): angle = (math.pi * 2) / fp.FacesNumber pts = [FreeCAD.Vector(r.Value, 0, ir * fp.Height.Value)] for i in range(fp.FacesNumber - 1): ang = (i + 1) * angle pts.append(FreeCAD.Vector(r.Value*math.cos(ang),\ r.Value*math.sin(ang),ir*fp.Height.Value)) pts.append(pts[0]) shape = Part.makePolygon(pts) face = Part.Face(shape) if ir == 0: #top face face.reverse() wires.append(shape) faces.append(face) #shellperi=Part.makeRuledSurface(*wires) shellperi = Part.makeLoft(wires) shell = Part.Shell(shellperi.Faces + faces) fp.Shape = Part.Solid(shell) fp.Placement = plm
def make(self): # Make cross-section cross_section = profile_to_cross_section( self.profile, lefthand=self.lefthand, start_count=self.start_count, min_vertices=self.min_vertices, ) # Make helical path profile_bb = self.profile.val().BoundingBox() #lead = (profile_bb.zmax - profile_bb.zmin) * self.start_count lead = self.pitch * self.start_count path = helical_path(lead, self.length, 1, lefthand=self.lefthand) # Sweep into solid thread = cross_section.sweep(path, isFrenet=True) # Making thread a valid solid # FIXME: this should be implemented inside cadquery itself thread_shape = thread.objects[0].wrapped if not thread_shape.isValid(): log.warning("thread shape not valid") new_thread = thread_shape.copy() new_thread.sewShape() thread.objects[0].wrapped = FreeCADPart.Solid(new_thread) if not thread.objects[0].wrapped.isValid(): log.error("sewn thread STILL not valid") raise SolidValidityError( "created thread solid cannot be made watertight") #solid = thread.val().wrapped #face = App.ActiveDocument.Face.Shape.copy() return thread
def execute(self, obj): size = obj.Count if size > 0: import Part if size in Polyhedron.indexes: shellList = [] doc = FreeCAD.ActiveDocument for indexes in self.getPolyhedronMatrix(obj): if (size == 4): theWire = Part.makePolygon([ obj.Points[indexes[0]], obj.Points[indexes[1]], obj.Points[indexes[2]], obj.Points[indexes[0]] ]) if (size == 8): theWire = Part.makePolygon([ obj.Points[indexes[0]], obj.Points[indexes[1]], obj.Points[indexes[2]], obj.Points[indexes[3]], obj.Points[indexes[0]] ]) try: doc.recompute() theFace = Part.Face(theWire) except: secWireList = theWire.Edges[:] theFace = Part.makeFilledFace( Part.__sortEdges__(secWireList)) shellList.append(theFace) obj.Shape = Part.Solid(Part.Shell(shellList))
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 execute(self, fp): if fp.BendAngle<180: if fp.thk>fp.OD/2: fp.thk=fp.OD/2 fp.ID=fp.OD-2*fp.thk fp.Profile=str(fp.OD)+"x"+str(fp.thk) CenterOfBend=FreeCAD.Vector(fp.BendRadius,fp.BendRadius,0) ## make center-line ## R=Part.makeCircle(fp.BendRadius,CenterOfBend,FreeCAD.Vector(0,0,1),225-float(fp.BendAngle)/2,225+float(fp.BendAngle)/2) ## move the cl so that Placement.Base is the center of elbow ## from math import pi, cos, sqrt d=(fp.BendRadius*sqrt(2)-fp.BendRadius/cos(fp.BendAngle/180*pi/2)) P=FreeCAD.Vector(-d*cos(pi/4),-d*cos(pi/4),0) R.translate(P) ## calculate Ports position ## fp.Ports=[R.valueAt(R.FirstParameter),R.valueAt(R.LastParameter)] ## make the shape of the elbow ## c=Part.makeCircle(fp.OD/2,fp.Ports[0],R.tangentAt(R.FirstParameter)*-1) b=Part.makeSweepSurface(R,c) p1=Part.Face(Part.Wire(c)) p2=Part.Face(Part.Wire(Part.makeCircle(fp.OD/2,fp.Ports[1],R.tangentAt(R.LastParameter)))) sol=Part.Solid(Part.Shell([b,p1,p2])) planeFaces=[f for f in sol.Faces if type(f.Surface)==Part.Plane] #elbow=sol.makeThickness(planeFaces,-fp.thk,1.e-3) #fp.Shape = elbow if fp.thk<fp.OD/2: fp.Shape=sol.makeThickness(planeFaces,-fp.thk,1.e-3) else: fp.Shape=sol super(Elbow,self).execute(fp) # perform common operations
def closeHole(shape): '''closeHole(shape): closes a hole in an open shape''' import DraftGeomUtils, Part # creating an edges lookup table lut = {} for face in shape.Faces: for edge in face.Edges: hc = edge.hashCode() if lut.has_key(hc): lut[hc] = lut[hc] + 1 else: lut[hc] = 1 # filter out the edges shared by more than one face bound = [] for e in shape.Edges: if lut[e.hashCode()] == 1: bound.append(e) bound = DraftGeomUtils.sortEdges(bound) try: nface = Part.Face(Part.Wire(bound)) shell = Part.makeShell(shape.Faces + [nface]) solid = Part.Solid(shell) except: raise else: return solid
def execute(self, fp): scale = fp.Radius / 1.90211303259 phy = 1.61803398875 f = list() for i in (-scale, scale): for j in (-scale, scale): k = scale f.append( Part.Face( Part.makePolygon([(-k, 0, i * phy), (k, 0, i * phy), (0, j * phy, i * 1), (-k, 0, i * phy)]))) f.append( Part.Face( Part.makePolygon([(0, i * phy, -k), (0, i * phy, k), (j * phy, i * 1, 0), (0, i * phy, -k)]))) f.append( Part.Face( Part.makePolygon([(i * phy, -k, 0), (i * phy, k, 0), (i * 1, 0, j * phy), (i * phy, -k, 0)]))) for k in (-scale, scale): f.append( Part.Face( Part.makePolygon([(i * 1, 0, k * phy), (0, j * phy, k * 1), (i * phy, j * 1, 0), (i * 1, 0, k * phy)]))) fp.Shape = Part.Solid(Part.Shell(f))
def toSolid(theObjectName): theObject = App.activeDocument().getObject(theObjectName) App.activeDocument().addObject("Part::Feature", "Solid") App.activeDocument().Solid.Shape = Part.Solid( Part.Shell(theObject.Shape.Faces)) App.activeDocument().Solid.Label = theObjectName App.ActiveDocument.recompute()
def recreateObject(self): # FIXME: # Here we have # We try to create a wire-closed to replace the sides we delete. # This will be way to complex . with many bugs :( try: App.ActiveDocument.removeObject(self.newEdge.Name) _result = [] _resultFace = [] _result.clear() for faceVert in self.savedVertices: convert = [] for vert in faceVert: convert.append(vert.Point) _Newvertices = convert newPolygon = _part.makePolygon(_Newvertices, True) convert.clear() newFace = _part.makeFilledFace(newPolygon.Edges) if newFace.isNull(): raise RuntimeError('Failed to create face') nFace = App.ActiveDocument.addObject("Part::Feature", "nFace") nFace.Shape = newFace _result.append(nFace) _resultFace.append(newFace) self.newFaces = _result solidObjShape = _part.Solid(_part.makeShell(_resultFace)) newObj = App.ActiveDocument.addObject("Part::Feature", "comp") newObj.Shape = solidObjShape newObj = self.sewShape(newObj) newObj = self.setTolerance(newObj) solidObjShape = _part.Solid(newObj.Shape) final = App.ActiveDocument.addObject("Part::Feature", "Extended") final.Shape = solidObjShape App.ActiveDocument.removeObject(newObj.Name) for face in self.newFaces: App.ActiveDocument.removeObject(face.Name) except Exception as err: App.Console.PrintError("'recreate Object' Failed. " "{err}\n".format(err=str(err))) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)
def execute(self, obj): faces = _utils.getShape(obj, "Faces", "Face") shell = Part.Shell(faces) solid = Part.Solid(shell) if solid.isValid(): obj.Shape = solid elif shell.isValid(): obj.Shape = shell else: obj.Shape = Part.Compound(faces)
def make_solid(obj, consumeInputs=False): doc = FreeCAD.ActiveDocument shell = obj.Shape.Faces shell = Part.Solid(Part.Shell(shell)) solid = doc.addObject("Part::Feature", obj.Label + "_solid") solid.Label = obj.Label + "_solid" solid.Shape = shell doc.recompute() del shell, solid return solid
def toSolid(document, part, name): """Convert object to a solid. These are commands, which FreeCAD runs when a user converts a part to a solid. """ s = part.Shape.Faces s = Part.Solid(Part.Shell(s)) o = document.addObject("Part::Feature", name) o.Label = name o.Shape = s return o
def createGeometry(self, fp): import FreeCAD, Part, math, sys #tangle = -twist #openscad uses degrees clockwise if fp.Base and fp.Angle and fp.Height and \ fp.Base.Shape.isValid(): #wire=fp.Base.Shape.Wires[0].transformGeometry(fp.Base.Placement.toMatrix()) solids = [] for faceb in fp.Base.Shape.Faces: #fp.Base.Shape.Faces[0].check() #faceb=fp.Base.Shape.Faces[0] #faceb=fp.Base.Shape.removeSplitter().Faces[0] faceu = faceb.copy() facetransform = FreeCAD.Matrix() facetransform.rotateZ(math.radians(fp.Angle.Value)) facetransform.move(FreeCAD.Vector(0, 0, fp.Height.Value)) faceu.transformShape(facetransform) step = 2 + abs(int( fp.Angle.Value // 90)) #resolution in z direction # print abs(int(fp.Angle.Value // 90)) #resolution in z direction # print step zinc = fp.Height.Value / (step - 1.0) angleinc = math.radians(fp.Angle.Value) / (step - 1.0) spine = Part.makePolygon([(0,0,i*zinc) \ for i in range(step)]) auxspine = Part.makePolygon([(math.cos(i*angleinc),\ math.sin(i*angleinc),i*fp.Height.Value/(step-1)) \ for i in range(step)]) faces = [faceb, faceu] for wire in faceb.Wires: pipeshell = Part.BRepOffsetAPI.MakePipeShell(spine) pipeshell.setSpineSupport(spine) pipeshell.add(wire) # Was before function change # pipeshell.setAuxiliarySpine(auxspine,True,False) if sys.version_info.major < 3: pipeshell.setAuxiliarySpine(auxspine, True, long(0)) else: pipeshell.setAuxiliarySpine(auxspine, True, 0) print(pipeshell.getStatus()) assert (pipeshell.isReady()) #fp.Shape=pipeshell.makeSolid() pipeshell.build() faces.extend(pipeshell.shape().Faces) try: fullshell = Part.Shell(faces) solid = Part.Solid(fullshell) if solid.Volume < 0: solid.reverse() assert (solid.Volume >= 0) solids.append(solid) except Part.OCCError: solids.append(Part.Compound(faces)) fp.Shape = Part.Compound(solids)
def rebuildArchShape(objects=None): """rebuildArchShape([objects]): takes the faces from the base shape of the given ( or selected if objects is None) Arch objects, and tries to rebuild a valid solid from them.""" import FreeCAD,FreeCADGui,Part if not objects: objects = FreeCADGui.Selection.getSelection() if not isinstance(objects,list): objects = [objects] for obj in objects: success = False if obj.isDerivedFrom("Part::Feature"): if hasattr(obj,"Base"): if obj.Base: try: print "Attempting to rebuild ",obj.Label if obj.Base.isDerivedFrom("Part::Feature"): if not obj.Base.Shape.isNull(): faces = [] for f in obj.Base.Shape.Faces: f2 = Part.Face(f.Wires) #print "rebuilt face: isValid is ",f2.isValid() faces.append(f2) if faces: shell = Part.Shell(faces) if shell: #print "rebuilt shell: isValid is ",shell.isValid() solid = Part.Solid(shell) if solid: if not solid.isValid(): solid.sewShape() solid = Part.Solid(solid) #print "rebuilt solid: isValid is ",solid.isValid() if solid.isValid(): print "Success" obj.Base.Shape = solid success = True except: pass if not success: print "Failed" FreeCAD.ActiveDocument.recompute()
def createGeometry(self, fp): import FreeCAD, Part, math, sys if fp.Base and fp.Height and fp.Base.Shape.isValid(): solids = [] for lower_face in fp.Base.Shape.Faces: upper_face = lower_face.copy() face_transform = FreeCAD.Matrix() face_transform.rotateZ(math.radians(fp.Angle.Value)) face_transform.scale(fp.Scale[0], fp.Scale[1], 1.0) face_transform.move(FreeCAD.Vector(0, 0, fp.Height.Value)) upper_face.transformShape( face_transform, False, True) # True to check for non-uniform scaling spine = Part.makePolygon([(0, 0, 0), (0, 0, fp.Height.Value)]) if fp.Angle.Value == 0.0: auxiliary_spine = Part.makePolygon([ (1, 1, 0), (fp.Scale[0], fp.Scale[1], fp.Height.Value) ]) else: num_revolutions = abs(fp.Angle.Value) / 360.0 pitch = fp.Height.Value / num_revolutions height = fp.Height.Value radius = 1.0 if fp.Angle.Value < 0.0: left_handed = True else: left_handed = False auxiliary_spine = Part.makeHelix(pitch, height, radius, 0.0, left_handed) faces = [lower_face, upper_face] for wire1, wire2 in zip(lower_face.Wires, upper_face.Wires): pipe_shell = Part.BRepOffsetAPI.MakePipeShell(spine) pipe_shell.setSpineSupport(spine) pipe_shell.add(wire1) pipe_shell.add(wire2) pipe_shell.setAuxiliarySpine(auxiliary_spine, True, 0) print(pipe_shell.getStatus()) assert (pipe_shell.isReady()) pipe_shell.build() faces.extend(pipe_shell.shape().Faces) try: fullshell = Part.Shell(faces) solid = Part.Solid(fullshell) if solid.Volume < 0: solid.reverse() assert (solid.Volume >= 0) solids.append(solid) except Part.OCCError: solids.append(Part.Compound(faces)) fp.Shape = Part.Compound(solids)
def execute(self, host): shell = makeDomeShape(host.Radius.getValueAs('mm'), host.FrequencyParameter) if host.ShapeType == 'Solid': host.Shape = Part.Solid(shell) elif host.ShapeType == 'Shell': host.Shape = shell elif host.ShapeType == 'Wireframe': host.Shape = Part.Compound(shell.Edges) elif host.ShapeType == 'Vertices': host.Shape = Part.Compound(shell.Vertexes) else: assert (False)
def execute(self, fp): scale = fp.Radius / 1.2247448 a = scale * 0.70710678118 #1/sqrt(2) f = list() for i in (-scale, scale): f.append( Part.Face( Part.makePolygon([(0, scale, a), (0, -scale, a), (i, 0, -a), (0, scale, a)]))) f.append( Part.Face( Part.makePolygon([(scale, 0, -a), (-scale, 0, -a), (0, i, a), (scale, 0, -a)]))) fp.Shape = Part.Solid(Part.Shell(f))
def GetPathSolidOld(self, tool, cmd, curpos): e1 = PathGeom.edgeForCmd(cmd, curpos) # curpos = e1.valueAt(e1.LastParameter) n1 = e1.tangentAt(0) n1[2] = 0.0 try: n1.normalize() except: return (None, e1.valueAt(e1.LastParameter)) height = self.height rad = tool.Diameter / 2.0 - 0.001 * curpos[ 2] # hack to overcome occ bug if type( e1.Curve ) is Part.Circle and e1.Curve.Radius <= rad: # hack to overcome occ bug rad = e1.Curve.Radius - 0.001 # return (None, e1.valueAt(e1.LastParameter)) xf = n1[0] * rad yf = n1[1] * rad xp = curpos[0] yp = curpos[1] zp = curpos[2] v1 = Vector(yf + xp, -xf + yp, zp) v2 = Vector(yf + xp, -xf + yp, zp + height) v3 = Vector(-yf + xp, xf + yp, zp + height) v4 = Vector(-yf + xp, xf + yp, zp) # vc1 = Vector(xf + xp, yf + yp, zp) # vc2 = Vector(xf + xp, yf + yp, zp + height) l1 = Part.makeLine(v1, v2) l2 = Part.makeLine(v2, v3) # l2 = Part.Edge(Part.Arc(v2, vc2, v3)) l3 = Part.makeLine(v3, v4) l4 = Part.makeLine(v4, v1) # l4 = Part.Edge(Part.Arc(v4, vc1, v1)) w1 = Part.Wire([l1, l2, l3, l4]) w2 = Part.Wire(e1) try: ex1 = w2.makePipeShell([w1], True, True) except: # Part.show(w1) # Part.show(w2) return (None, e1.valueAt(e1.LastParameter)) cyl1 = Part.makeCylinder(rad, height, curpos) curpos = e1.valueAt(e1.LastParameter) cyl2 = Part.makeCylinder(rad, height, curpos) ex1s = Part.Solid(ex1) f1 = ex1s.fuse([cyl1, cyl2]).removeSplitter() return (f1, curpos)