def execute(self, obj): f = _utils.getShape(obj, "Source", "Face") bs = f.toNurbs().Faces[0].Surface surfs = list() u0, u1, v0, v1 = bs.bounds() cutKnotsU = [u0, u1] cutKnotsV = [v0, v1] if obj.Option == "Auto": if obj.Direction in ["U", "Both"]: knots = bs.getUKnots() mults = bs.getUMultiplicities() cutKnotsU = self.get_intervals(knots, mults) if obj.Direction in ["V", "Both"]: knots = bs.getVKnots() mults = bs.getVMultiplicities() cutKnotsV = self.get_intervals(knots, mults) elif obj.Option == "Custom": for k in obj.KnotsU: if (k > u0) and (k < u1): cutKnotsU.append(k) for k in obj.KnotsV: if (k > v0) and (k < v1): cutKnotsV.append(k) cutKnotsU = list(set(cutKnotsU)) cutKnotsV = list(set(cutKnotsV)) cutKnotsU.sort() cutKnotsV.sort() for i in range(len(cutKnotsU) - 1): for j in range(len(cutKnotsV) - 1): s = bs.copy() s.segment(cutKnotsU[i], cutKnotsU[i + 1], cutKnotsV[j], cutKnotsV[j + 1]) surfs.append(s) obj.Shape = Part.Shell([s.toShape() for s in surfs])
def lloyd_on_solid_surface(solid, sites, thickness, n_iterations, tolerance=1e-4, weight_field=None): if solid.Shells: shell = solid.Shells[0] else: shell = Part.Shell(solid.Faces) def iteration(pts): all_pts = pts + project_solid_normals(shell, pts, thickness) diagram = Voronoi(all_pts) centers = [] for site_idx in range(len(pts)): region_idx = diagram.point_region[site_idx] region = diagram.regions[region_idx] region_verts = np.array([diagram.vertices[i] for i in region]) center = weighted_center(region_verts, weight_field) centers.append(tuple(center)) return centers def restrict(points): result = [] for point in points: v = Base.Vector(point) if any(face.isInside(v, tolerance, True) for face in shell.Faces): result.append(point) else: dist, vs, infos = shell.distToShape(Part.Vertex(v)) v = vs[0][0] result.append((v.x, v.y, v.z)) return result points = restrict(sites) for i in range(n_iterations): points = iteration(points) points = restrict(points) return points
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 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 testShapeFix_Shell(self): surface = Part.Plane() face = surface.toShape(-1, 1, -1, 1) shell = Part.Shell([face]) Part.ShapeFix.Shell() with self.assertRaises(TypeError): Part.ShapeFix.Face([]) fix = Part.ShapeFix.Shell(shell) fix.init(shell) print (fix) fix.perform() fix.shell() fix.shape() fix.fixFaceTool() fix.setNonManifoldFlag(True) fix.fixFaceOrientation(shell) self.assertEqual(len(fix.errorFaces().Faces), 0) self.assertEqual(fix.numberOfShells(), 1) fix.FixFaceMode = True self.assertEqual(fix.FixFaceMode, True) fix.FixOrientationMode = True self.assertEqual(fix.FixOrientationMode, 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 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 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 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 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 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 mergeShells(list_of_faces_shells, flag_single = False, split_connections = []): faces = [] for sh in list_of_faces_shells: faces.extend(sh.Faces) if flag_single: return Part.makeShell(faces) else: groups = splitIntoGroupsBySharing(faces, lambda sh: sh.Edges, split_connections) return Part.makeCompound([Part.Shell(group) for group in groups])
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 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 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 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 sweep_wire(self, w, solid=False): faces = [] for e in w.Edges: faces.append(self.sweep_edge(e, solid)) shell = Part.Shell(faces) shell.sewShape() if solid: cyl = Part.makeCylinder(self.max_radius * 2, self.nb_of_turns * self.lead) cyl.Placement = self._placement.multiply( FreeCAD.Placement(FreeCAD.Vector(), FreeCAD.Vector(1, 0, 0), -90)) common = cyl.common(shell) cut_faces = common.Faces new_edges = [] for e1 in common.Edges: found = False for e2 in shell.Edges: if nurbs_tools.is_same(e1.Curve, e2.Curve, tol=1e-7, full=False): found = True #print("found similar edges") continue if not found: new_edges.append(e1) #print(len(Part.sortEdges(new_edges))) el1, el2 = Part.sortEdges(new_edges)[0:2] f1 = Part.makeFace(Part.Wire(el1), 'Part::FaceMakerSimple') f2 = Part.makeFace(Part.Wire(el2), 'Part::FaceMakerSimple') cut_faces.extend([f1, f2]) try: shell = Part.Shell(cut_faces) shell.sewShape() return Part.Solid(shell) except Part.OCCError: print("Failed to create solid") return Part.Compound(cut_faces) return shell
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 createGeometry(self, fp): import FreeCAD, Part, math, sys if fp.Base 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.scale(fp.Scale[0], fp.Scale[1], 1.0) facetransform.move(FreeCAD.Vector(0, 0, fp.Height.Value)) faceu.transformShape(facetransform) step = 2 + abs(int( fp.Angle.Value // 90)) #resolution in z direction 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*zinc) \ for i in range(step)]) faces = [faceb, faceu] for wire1, wire2 in zip(faceb.Wires, faceu.Wires): pipeshell = Part.BRepOffsetAPI.MakePipeShell(spine) pipeshell.setSpineSupport(spine) pipeshell.add(wire1) pipeshell.add(wire2) pipeshell.setAuxiliarySpine(auxspine, True, 0) print(pipeshell.getStatus()) assert (pipeshell.isReady()) 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 applyPlacement(shape): if shape.Placement.isNull(): return shape else: import Part if shape.ShapeType == 'Solid': return Part.Solid(shape.childShapes()[0]) elif shape.ShapeType == 'Face': return Part.Face(shape.childShapes()) elif shape.ShapeType == 'Compound': return Part.Compound(shape.childShapes()) elif shape.ShapeType == 'Wire': return Part.Wire(shape.childShapes()) elif shape.ShapeType == 'Shell': return Part.Shell(shape.childShapes()) else: return Part.Compound([shape])
def computeAreas(self, obj): "computes border and ridge roof edges length" if hasattr(obj, "RidgeLength") and hasattr(obj, "BorderLength"): rl = 0 bl = 0 rn = 0 bn = 0 import Part, math if obj.Shape: if obj.Shape.Faces: fset = [] for f in obj.Shape.Faces: if f.normalAt(0, 0).getAngle(FreeCAD.Vector( 0, 0, 1)) < math.pi / 2: fset.append(f) if fset: try: shell = Part.Shell(fset) except: pass else: lut = {} if shell.Faces: for f in shell.Faces: for e in f.Edges: hc = e.hashCode() if hc in lut: lut[hc] = lut[hc] + 1 else: lut[hc] = 1 for e in shell.Edges: if lut[e.hashCode()] == 1: bl += e.Length bn += 1 elif lut[e.hashCode()] == 2: rl += e.Length rn += 1 if obj.RidgeLength.Value != rl: obj.RidgeLength = rl print(str(rn) + " ridge edges in roof " + obj.Name) if obj.BorderLength.Value != bl: obj.BorderLength = bl print(str(bn) + " border edges in roof " + obj.Name) ArchComponent.Component.computeAreas(self, obj)
def execute(self, fp): O=FreeCAD.Vector(0,0,0) vectL=FreeCAD.Vector(fp.L,0,0) vectW=FreeCAD.Vector(0,fp.W,0) vectH=FreeCAD.Vector(0,0,fp.H) base=[vectL,vectW,vectH] outline=[] for i in range(3): f1=Part.Face(Part.makePolygon([O,base[0],base[0]+base[1],base[1],O])) outline.append(f1) f2=f1.copy() f2.translate(base[2]) outline.append(f2) base.append(base.pop(0)) box=Part.Solid(Part.Shell(outline)) tank=box.makeThickness([box.Faces[0],box.Faces[2]],-fp.thk,1.e-3) fp.Shape=tank
def applyPlacement(shape): if shape.Placement.isNull(): return shape else: import Part if shape.ShapeType == 'Solid': return Part.Solid(shape.childShapes()[0]) elif shape.ShapeType == 'Face': return Part.Face(shape.childShapes()) elif shape.ShapeType == 'Compound': return Part.Compound(shape.childShapes()) elif shape.ShapeType == 'Wire': return Part.Wire(shape.childShapes()) elif shape.ShapeType == 'Shell': return Part.Shell(shape.childShapes()) else: raise ValueError('Unsupported shape type')
def convert_meshes_to_part_objects_2(): import Part doc = FreeCAD.newDocument("Box_5") box = doc.addObject("Part::Box", "myBox") box.Height = 5 box.Length = 5 box.Width = 5 doc.recompute() import Mesh import Part import MeshPart obj = box # a Mesh object must be preselected mesh = obj.Mesh segments = mesh.getPlanarSegments( 0.00001) # use rather strict tolerance here faces = [] 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)) solid = Part.Solid(Part.Shell(faces)) Part.show(solid) setview()
def createBentCylinderDoesNotWork(obj, rCirc): """Create a cylinder of radius rCirc in x-y plane which is bent in the middle and is streight in the ends. The little streight part is necessary, because otherwise the part is not displayed correctly after performing a boolean operations. Thus we need some overlapping between bent part and the socket. :param group: Group where to add created objects. :param rCirc: Radius of the cylinder. See documentation picture elbow-cacluations.png """ # Convert alpha to degree value dims = Elbow.extractDimensions(obj) aux = dims.calculateAuxiliararyPoints() alpha = float(dims.BendAngle.getValueAs("deg")) rBend = dims.M / 2.0 # Put a base on the streight part. base = Part.makeCircle(rCirc, aux["p5"], aux["p5"]) # Add trajectory line1 = Part.makeLine(aux["p5"], aux["p2"]) arc = Part.makeCircle( rBend, aux["p3"], FreeCAD.Vector(0, 0, 1), 225 - alpha / 2, 225 + alpha / 2) line2 = Part.makeLine(aux["p4"], aux["p6"]) trajectory = Part.Shape([line1, arc, line2]) # Show trajectory for debugging. # W Part.Wire([line1, arc, line2]) # Part.show(W) # Add a cap (circle, at the other end of the bent cylinder). cap = Part.makeCircle(rCirc, aux["p5"], aux["p5"]) # Sweep the circle along the trajectory. sweep = Part.makeSweepSurface(trajectory, base) # Does not work sweep = Part.makeSweepSurface(W, base) # Does not work. # The sweep is only a 2D service consisting of walls only. # Add circles on both ends of this wall. end1 = Part.Face(Part.Wire(base)) # Create other end. end2 = Part.Face(Part.Wire(cap)) solid = Part.Solid(Part.Shell([end1, sweep, end2])) return solid
def upgradeToAggregateIfNeeded(list_of_shapes, types=None): """upgradeToAggregateIfNeeded(list_of_shapes, types = None): upgrades non-aggregate type shapes to aggregate-type shapes if the list has a mix of aggregate and non-aggregate type shapes. Returns the new list. Recursively traverses into compounds. aggregate shape types are Wire, Shell, CompSolid non-aggregate shape types are Vertex, Edge, Face, Solid Compounds are something special: they are recursively traversed to upgrade the contained shapes. Examples: list_of_shapes contains only faces -> nothing happens list_of_shapes contains faces and shells -> faces are converted to shells 'types' argument is needed for recursive traversal. Do not supply.""" import Part if types is None: types = set() for shape in list_of_shapes: types.add(shape.ShapeType) subshapes = compoundLeaves(shape) for subshape in subshapes: types.add(subshape.ShapeType) if "Wire" in types: list_of_shapes = [ (Part.Wire([shape]) if shape.ShapeType == "Edge" else shape) for shape in list_of_shapes ] if "Shell" in types: list_of_shapes = [ (Part.Shell([shape]) if shape.ShapeType == "Face" else shape) for shape in list_of_shapes ] if "CompSolid" in types: list_of_shapes = [ (Part.CompSolid([shape]) if shape.ShapeType == "Solid" else shape) for shape in list_of_shapes ] if "Compound" in types: list_of_shapes = [(Part.Compound( upgradeToAggregateIfNeeded(shape.childShapes(), types)) if shape.ShapeType == "Compound" else shape) for shape in list_of_shapes] return list_of_shapes
def run_FreeCAD_Tread(self,produce=False, **kwargs): k=self.getData("noise") def rav(v): '''add a random vector to a vector''' return v+FreeCAD.Vector(0.5-random.random(),0.5-random.random(),(0.5-random.random())*1)*k pts=[self.getData("point_"+str(i)) for i in range(8)] pol=Part.makePolygon(pts+[pts[0]]) f=Part.Face(pol) v=FreeCAD.Vector(0,0,120) pts2=[p+v for p in pts] pol2=Part.makePolygon(pts2+[pts2[0]]) f2=Part.Face(pol2) colf=[f,f2] for i in range(8): pol=Part.makePolygon([pts[i-1],rav(pts[i]),rav(pts2[i]),rav(pts2[i-1]),pts[i-1]]) f=Part.makeFilledFace(pol.Edges) colf += [f] comp=Part.Compound(colf) comp.Placement.Rotation=FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) self.setPinObject("Compound_out",comp) for tol in range(60,150): colf2=[c.copy() for c in colf] try: for f in colf2: f.Tolerance=tol sh=Part.Shell(colf2) sol=Part.Solid(sh) sol.Placement.Rotation=FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) if sol.isValid(): say("solid created with tol",tol) if produce: Part.show(sol) #cc=self.getObject();cc.Shape=sol self.setPinObject("Shape_out",sol) break except: pass
def computeAreas(self, obj): '''computes border and ridge roof edges length''' if hasattr(obj, "RidgeLength") and hasattr(obj, "BorderLength"): rl = 0 bl = 0 rn = 0 bn = 0 if obj.Shape: if obj.Shape.Faces: faceLst = [] for face in obj.Shape.Faces: if face.normalAt(0, 0).getAngle(Vector( 0.0, 0.0, 1.0)) < math.pi / 2.0: faceLst.append(face) if faceLst: try: shell = Part.Shell(faceLst) except: pass else: lut = {} if shell.Faces: for face in shell.Faces: for edge in face.Edges: hc = edge.hashCode() if hc in lut: lut[hc] = lut[hc] + 1 else: lut[hc] = 1 for edge in shell.Edges: if lut[edge.hashCode()] == 1: bl += edge.Length bn += 1 elif lut[edge.hashCode()] == 2: rl += edge.Length rn += 1 if obj.RidgeLength.Value != rl: obj.RidgeLength = rl #print(str(rn)+" ridge edges in roof "+obj.Name) if obj.BorderLength.Value != bl: obj.BorderLength = bl #print(str(bn)+" border edges in roof "+obj.Name) ArchComponent.Component.computeAreas(self, obj)
def buildFaces(shells, root, name, transform): faces = [] for shell in shells: for face in shell.getFaces(): surface = face.build() if (surface): faces.append(surface) for wire in shell.getWires(): buildWire(root, wire, transform) if (len(faces) > 0): try: createBody(root, name, Part.Shell(faces), transform) except Exception as e: logAlways(e) for face in faces: createBody(root, name, face, transform) return