def makePrism(l): print l hp=l[-1] p1=l[0] bl=l[:-1] bl.append(p1) print bl s=Part.makePolygon(bl) f=Part.makeFilledFace(s.Edges) Part.show(f) cb=App.ActiveDocument.ActiveObject cb.Label="Prism Bottom Face" cb.ViewObject.hide() n=f.Faces[0].normalAt(0,0) n2=FreeCAD.Vector(0,0,1) r=FreeCAD.Rotation(n,n2) k1=r.multVec(p1) sp1=sympy.point.Point2D(k1.x,k1.y) z=k1.z sp1 k4=r.multVec(hp) sp4=sympy.point.Point2D(k4.x,k4.y) sp4 bl2=[] for p in bl: k=r.multVec(p) bl2.append(k) s=Part.makePolygon(bl2) f=Part.makeFilledFace(s.Edges) Part.show(f) cb=App.ActiveDocument.ActiveObject cb.Label="Prism Bottom Face Helper" cb.ViewObject.hide() h=k4.z-k1.z # und wieder zurueck r2=FreeCAD.Rotation(n2,n) ex=App.ActiveDocument.addObject("Part::Extrusion","Extrude") ex.Base = cb ex.Dir = (0,0,h) ex.Solid = (True) ex.Placement.Rotation=r2 ex.ViewObject.Transparency=80 ex.Label="Prism" App.activeDocument().recompute()
def makePrism(l): print(l) hp = l[-1] p1 = l[0] bl = l[:-1] bl.append(p1) print(bl) s = Part.makePolygon(bl) f = Part.makeFilledFace(s.Edges) Part.show(f) cb = App.ActiveDocument.ActiveObject cb.Label = "Prism Bottom Face" cb.ViewObject.hide() n = f.Faces[0].normalAt(0, 0) n2 = FreeCAD.Vector(0, 0, 1) r = FreeCAD.Rotation(n, n2) k1 = r.multVec(p1) sp1 = sympy.point.Point2D(k1.x, k1.y) z = k1.z sp1 k4 = r.multVec(hp) sp4 = sympy.point.Point2D(k4.x, k4.y) sp4 bl2 = [] for p in bl: k = r.multVec(p) bl2.append(k) s = Part.makePolygon(bl2) f = Part.makeFilledFace(s.Edges) Part.show(f) cb = App.ActiveDocument.ActiveObject cb.Label = "Prism Bottom Face Helper" cb.ViewObject.hide() h = k4.z - k1.z # und wieder zurueck r2 = FreeCAD.Rotation(n2, n) ex = App.ActiveDocument.addObject("Part::Extrusion", "Extrude") ex.Base = cb ex.Dir = (0, 0, h) ex.Solid = (True) ex.Placement.Rotation = r2 ex.ViewObject.Transparency = 80 ex.Label = "Prism" App.activeDocument().recompute()
def makeCylinder(p1,p2,p3,p4): s=Part.makePolygon([p1,p2,p3,p1]) f=Part.makeFilledFace(s.Edges) n=f.Faces[0].normalAt(0,0) # Drehung n2=FreeCAD.Vector(0,0,1) r=FreeCAD.Rotation(n,n2) k1=r.multVec(p1) sp1=sympy.point.Point2D(k1.x,k1.y) z=k1.z sp1 k2=r.multVec(p2) sp2=sympy.point.Point2D(k2.x,k2.y) sp2 k3=r.multVec(p3) sp3=sympy.point.Point2D(k3.x,k3.y) sp3 k4=r.multVec(p4) sp4=sympy.point.Point2D(k4.x,k4.y) sp4 t=sympy.Triangle(sp1,sp2,sp3) rad=t.circumradius.evalf() center=t.circumcenter print rad print center x=center.x.evalf() y=center.y.evalf() circ=Part.makeCircle(rad,FreeCAD.Vector(x,y,z)) Part.show(circ) cb=App.ActiveDocument.ActiveObject h=k4.z-k3.z # und wieder zurueck r2=FreeCAD.Rotation(n2,n) ex=App.ActiveDocument.addObject("Part::Extrusion","Extrude") ex.Base = cb ex.Dir = (0,0,h) ex.Solid = (True) ex.Placement.Rotation=r2 ex.ViewObject.Transparency=80 cb.ViewObject.hide() s2=Part.makePolygon([p1,p2,p3,p4]) Part.show(s2) for p in [p1,p2,p3,p4]: k1=App.ActiveDocument.addObject("Part::Sphere","Sphere") k1.Placement.Base=p k1.Radius=0.5 k1.ViewObject.ShapeColor=(1.0,0.0,0.0) App.activeDocument().recompute()
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 makeCylinder(p1,p2,p3,p4): s=Part.makePolygon([p1,p2,p3,p1]) f=Part.makeFilledFace(s.Edges) n=f.Faces[0].normalAt(0,0) # Drehung n2=FreeCAD.Vector(0,0,1) r=FreeCAD.Rotation(n,n2) k1=r.multVec(p1) sp1=sympy.point.Point2D(k1.x,k1.y) z=k1.z sp1 k2=r.multVec(p2) sp2=sympy.point.Point2D(k2.x,k2.y) sp2 k3=r.multVec(p3) sp3=sympy.point.Point2D(k3.x,k3.y) sp3 k4=r.multVec(p4) sp4=sympy.point.Point2D(k4.x,k4.y) sp4 t=sympy.Triangle(sp1,sp2,sp3) rad=t.circumradius.evalf() center=t.circumcenter print(rad) print(center) x=center.x.evalf() y=center.y.evalf() circ=Part.makeCircle(rad,FreeCAD.Vector(x,y,z)) Part.show(circ) cb=App.ActiveDocument.ActiveObject h=k4.z-k3.z # und wieder zurueck r2=FreeCAD.Rotation(n2,n) ex=App.ActiveDocument.addObject("Part::Extrusion","Extrude") ex.Base = cb ex.Dir = (0,0,h) ex.Solid = (True) ex.Placement.Rotation=r2 ex.ViewObject.Transparency=80 cb.ViewObject.hide() s2=Part.makePolygon([p1,p2,p3,p4]) Part.show(s2) for p in [p1,p2,p3,p4]: k1=App.ActiveDocument.addObject("Part::Sphere","Sphere") k1.Placement.Base=p k1.Radius=0.5 k1.ViewObject.ShapeColor=(1.0,0.0,0.0) App.activeDocument().recompute()
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 computeShape(self, obj): """ Computes simulation involved shapes. @param obj Created Part::FeaturePython object. @return Shape """ print("[ShipSimulation] Computing mesh shape...") nx = obj.FS_Nx ny = obj.FS_Ny mesh = FSMesh(obj) planes = [] # Create planes Percentage = 0 Count = 0 print("0%") for i in range(1,nx-1): for j in range(1,ny-1): Count = Count+1 done = int(round(100 * Count / ((nx-2)*(ny-2)))) if done != Percentage: Percentage = done print("%i%%" % (done)) v0 = (mesh[i][j].pos + mesh[i-1][j].pos + mesh[i][j-1].pos + mesh[i-1][j-1].pos).multiply(0.25) v1 = (mesh[i][j].pos + mesh[i+1][j].pos + mesh[i][j-1].pos + mesh[i+1][j-1].pos).multiply(0.25) v2 = (mesh[i][j].pos + mesh[i+1][j].pos + mesh[i][j+1].pos + mesh[i+1][j+1].pos).multiply(0.25) v3 = (mesh[i][j].pos + mesh[i-1][j].pos + mesh[i][j+1].pos + mesh[i-1][j+1].pos).multiply(0.25) p = Part.makePolygon([v0,v1,v2,v3,v0]) planes.append(Part.makeFilledFace(p.Edges)) # Join into a compound return Part.makeCompound(planes)
def curves_to_face(sv_curves, planar=True, force_nurbs=True): """ Make a Part.Face from a list of SvCurve. Curves must have NURBS representation, must form a closed loop, and it must be planar, otherwise an exception will be raised. input: * list of SvCurve. * planar: True to make a flat face; in this case, all curves must lie exactly in one plane * force_nurbs: True if you want NURBS surface as output even when curves are not NURBS output: * SvSolidFaceSurface for face's surface; SvFreeCadNurbsSurface if force_nurbs == True. """ # Check sv_curves = [curve_to_freecad(curve) for curve in sv_curves] all_nurbs = all( isinstance(curve, SvFreeCadNurbsCurve) for curve in sv_curves) edges = [Part.Edge(curve.curve) for curve in sv_curves] try: wire = Part.Wire(edges) except Part.OCCError as e: fc_curves = [edge.Curve for edge in edges] raise Exception(f"Can't build a Wire out of edges: {fc_curves}: {e}") if not wire.isClosed(): last_point = None distance = None for i, edge in enumerate(wire.Edges): p1, p2 = get_edge_endpoints(edge) if last_point is not None: distance = last_point.distanceToPoint(p1) print( f"#{i-1}-{i}: distance={distance}: ({last_point.x}, {last_point.y}, {last_point.z}) - ({p1.x}, {p1.y}, {p1.z})" ) last_point = p2 p1 = get_edge_endpoints(wire.Edges[-1])[1] p2 = get_edge_endpoints(wire.Edges[0])[0] distance = p1.distanceToPoint(p2) print(f"Last - first distance = {distance}") raise Exception(f"The wire is not closed: {sv_curves}") if planar: try: fc_face = Part.Face(wire) except Part.OCCError as e: raise Exception( f"Can't create a Face from {sv_curves}: {e}\nProbably these curves are not all lying in the same plane?" ) surface = SvSolidFaceSurface(fc_face) else: fc_face = Part.makeFilledFace(edges) surface = SvSolidFaceSurface(fc_face) if all_nurbs or force_nurbs: surface = surface.to_nurbs() return surface
def frame_rectangular(tel_w, tel_h , tel_ww, tel_wh, tel_th, et=0): """ Return the shape of a rectangular frame. """ import Part i_tel_w = tel_w - tel_ww * 2 i_tel_h = tel_h - tel_wh * 2 ep0 = (tel_w * -0.5, 0, 0) ep1 = (tel_w * 0.5, 0, 0) ep2 = (tel_w * 0.5, 0, tel_h) ep3 = (tel_w * -0.5, 0, tel_h) ip0 = (i_tel_w * -0.5, 0, tel_ww) ip1 = (i_tel_w * 0.5, 0, tel_ww) ip2 = (i_tel_w * 0.5, 0, tel_ww + i_tel_h) ip3 = (i_tel_w * -0.5, 0, tel_ww + i_tel_h) tel_b = (ep0, ep1, ip1, ip0, ep0) tel_bp = Part.makePolygon([Vector(*vtx) for vtx in tel_b]) tel_r = (ep1, ep2, ip2, ip1, ep1) tel_rp = Part.makePolygon([Vector(*vtx) for vtx in tel_r]) tel_t = (ep2, ep3, ip3, ip2, ep2) tel_tp = Part.makePolygon([Vector(*vtx) for vtx in tel_t]) tel_l = (ep3, ep0, ip0, ip3, ep3) tel_lp = Part.makePolygon([Vector(*vtx) for vtx in tel_l]) tel_fb = Part.makeFilledFace(tel_bp.Edges) tel_fbs = tel_fb.extrude(Vector(0, tel_th, 0)) tel_fr = Part.makeFilledFace(tel_rp.Edges) tel_frs = tel_fr.extrude(Vector(0, tel_th, 0)) tel_ft = Part.makeFilledFace(tel_tp.Edges) tel_fts = tel_ft.extrude(Vector(0, tel_th, 0)) tel_fl = Part.makeFilledFace(tel_lp.Edges) tel_fls = tel_fl.extrude(Vector(0, tel_th, 0)) return Part.makeCompound([tel_fbs, tel_frs, tel_fts, tel_fls])
def facies( ): fc0 = Part.makeFilledFace(Part.__sortEdges__([AD.Line001.Shape.Edge1, AD.Line002.Shape.Edge1, AD.Line003.Shape.Edge1, AD.Line004.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc0 Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) fc1 = Part.makeFilledFace(Part.__sortEdges__([AD.Line002.Shape.Edge1, AD.Line005.Shape.Edge1, AD.Line006.Shape.Edge1, AD.Line007.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc1 Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) fc2 =Part.makeFilledFace(Part.__sortEdges__([AD.Line003.Shape.Edge1, AD.Line007.Shape.Edge1, AD.Line008.Shape.Edge1, AD.Line009.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc2 Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) fc3=Part.makeFilledFace(Part.__sortEdges__([AD.Line001.Shape.Edge1, AD.Line005.Shape.Edge1, AD.Line012.Shape.Edge1, AD.Line011.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc3 Gui.SendMsgToActiveView("ViewFit") Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) fc4=Part.makeFilledFace(Part.__sortEdges__([AD.Line004.Shape.Edge1, AD.Line011.Shape.Edge1, AD.Line010.Shape.Edge1, AD.Line009.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc4 Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) fc5 =Part.makeFilledFace(Part.__sortEdges__([AD.Line012.Shape.Edge1, AD.Line006.Shape.Edge1, AD.Line008.Shape.Edge1, AD.Line010.Shape.Edge1, ])) AD.addObject('Part::Feature','Face').Shape = fc5 Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration)
def get_face(*vs): """ Takes a sequence of vectors and returns a face """ s = vs[0:-1] e = vs[1:] l = [] for i in range(0,len(s)): l.append(Part.Line(s[i],e[i])) l.append(Part.Line(vs[-1],vs[0])) shape = Part.Shape(l) return Part.makeFilledFace(shape.Edges)
def createShape(obj): '''create the FilledFace Shape for the edges of obj''' lls = [] if obj.e1 != None: lls += [obj.e1.Shape.Edges[obj.n1 - 1]] if obj.e2 != None: lls += [obj.e2.Shape.Edges[obj.n2 - 1]] if obj.e3 != None: lls += [obj.e3.Shape.Edges[obj.n3 - 1]] # check wire closed !!! try: obj.Shape = Part.makeFilledFace(Part.__sortEdges__(lls)) except: obj.Shape = Part.Shape()
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 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 union(thingsA,thingsB,tol=1e-5): if type(thingsB) is not list: thingsB = [thingsB] if type(thingsA) is list: thingA = thingsA[0] if len(thingsA) > 1: thingsB += thingsA[1::] else: thingA = thingsA if (thingA.ShapeType == 'Face') and (thingsB[0].ShapeType == 'Face'): # face fusing is not working anymore, so we have to make them 3d then fuse, then section to get the proper fused face aCOM = thingA.CenterOfMass u, v = thingA.Surface.parameter(aCOM) x, y, z = thingA.normalAt(u, v) vNorm = thingA.normalAt(u, v) things3D = extrude(thingsB+[thingA], x, y, z) a3D = things3D[-1] b3D = things3D[0:-1] tol = 0 pieces, map = a3D.generalFuse(b3D, tol) cpound = BOPTools.JoinAPI.connect(pieces.Solids, tolerance=tol) u3D = cpound.Solids[0].removeSplitter() bb = u3D.BoundBox dl = bb.DiagonalLength u3D.translate(-vNorm/2) u3DCOM = thingA.CenterOfMass cutPlane = Part.makePlane(dl, dl, aCOM, vNorm) cpCOM = cutPlane.CenterOfMass dCOM = u3DCOM - cpCOM cutPlane.translate(dCOM) sectionShape = u3D.section(cutPlane) u = [Part.makeFilledFace(sectionShape.Edges)] elif (thingA.ShapeType == 'Solid') and (thingsB[0].ShapeType == 'Solid'): pieces, map = thingA.generalFuse(thingsB, tol) cpound = BOPTools.JoinAPI.connect(pieces.Solids, tolerance=tol) u = cpound.Solids else: u = [] if (len(u) is 1): return u[0] else: return u
def expand_face(face,d): """ Expands a face along it's plane so that the centers are the same, and the min edge length is d. """ minLength = reduce(lambda x,y: min(x,y), map(lambda e: e.Length, face.Edges)) factor = d / minLength center = face.CenterOfMass def scaleV(v): return (v - center).scale(factor,factor,factor) + center newLines = [] for e in face.Edges: vs = map(lambda v: v.Point, e.Vertexes) newLines.append(Part.Line(scaleV(vs[0]),scaleV(vs[1]))) shape = Part.Shape(newLines) return Part.makeFilledFace(shape.Edges)
def glass(ea_w, ea_h, ef_w, ef_h, v_a, frame_th, glass_th): """Return the shape of a rectangular glass panel. TODO: Check if a Part::Box is faster """ import Part v_w = ea_w - ef_w + v_a * 2 v_h = ea_h - ef_h + v_a * 2 vp0 = (v_w * -0.5, 0, ef_w - v_a) vp1 = (v_w * 0.5, 0, ef_w - v_a) vp2 = (v_w * 0.5, 0, ef_h - v_a + v_h) vp3 = (v_w * -0.5, 0, ef_h - v_a + v_h) glass_pt = (vp0, vp1, vp2, vp3, vp0) glass_p = Part.makePolygon([Vector(*vtx) for vtx in glass_pt]) glass_f = Part.makeFilledFace(glass_p.Edges) glass_s = glass_f.extrude(Vector(0, glass_th, 0)) return glass_s
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]) print("pp") print(pp) w = Part.makePolygon(pp) print("w") print(w) try: f = Part.Face(w) except: 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 facies(): def PL0(): ls00 = Part.LineSegment() ls00.StartPoint = v00 ls00.EndPoint = v01 AD.addObject("Part::Feature", "Line").Shape = ls00.toShape() # ls01 = Part.LineSegment() ls01.StartPoint = v01 ls01.EndPoint = v02 AD.addObject("Part::Feature", "Line").Shape = ls01.toShape() # ls02 = Part.LineSegment() ls02.StartPoint = v02 ls02.EndPoint = v03 AD.addObject("Part::Feature", "Line").Shape = ls02.toShape() # ls03 = Part.LineSegment() ls03.StartPoint = v03 ls03.EndPoint = v00 AD.addObject("Part::Feature", "Line").Shape = ls03.toShape() # end PL0 # def PL1(): ls10 = Part.LineSegment() ls10.StartPoint = v01 ls10.EndPoint = v04 AD.addObject("Part::Feature", "Line").Shape = ls10.toShape() # ls11 = Part.LineSegment() ls11.StartPoint = v04 ls11.EndPoint = v05 AD.addObject("Part::Feature", "Line").Shape = ls11.toShape() # ls12 = Part.LineSegment() ls12.StartPoint = v05 ls12.EndPoint = v02 AD.addObject("Part::Feature", "Line").Shape = ls12.toShape() # end PL1 # def PL3(): ls30 = Part.LineSegment() ls30.StartPoint = v06 ls30.EndPoint = v07 AD.addObject("Part::Feature", "Line").Shape = ls30.toShape() # ls31 = Part.LineSegment() ls31.StartPoint = v07 ls31.EndPoint = v00 AD.addObject("Part::Feature", "Line").Shape = ls31.toShape() # end PL3 # def PL4(): ls40 = Part.LineSegment() ls40.StartPoint = v07 ls40.EndPoint = v04 AD.addObject("Part::Feature", "Line").Shape = ls40.toShape() # end PL4 # # begin faces # ls0 = Part.LineSegment() ls0.StartPoint = v0 ls0.EndPoint = v1 AD.addObject("Part::Feature", "Line").Shape = ls0.toShape() # # PL0() Gui.SendMsgToActiveView("ViewFit") PL1() Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) #pPL2() ls20 = Part.LineSegment() ls20.StartPoint = v05 ls20.EndPoint = v06 AD.addObject("Part::Feature", "Line").Shape = ls20.toShape() # ls21 = Part.LineSegment() ls21.StartPoint = v06 ls21.EndPoint = v03 AD.addObject("Part::Feature", "Line").Shape = ls21.toShape() Gui.SendMsgToActiveView("ViewFit") Gui.activeDocument().activeView().viewAxonometric() PL3() Gui.SendMsgToActiveView("ViewFit") PL4() Gui.SendMsgToActiveView("ViewFit") # AD.removeObject("Line") AD.recompute() Gui.SendMsgToActiveView("ViewFit") # # fc0 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line001.Shape.Edge1, AD.Line002.Shape.Edge1, AD.Line003.Shape.Edge1, AD.Line004.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc0 Gui.SendMsgToActiveView("ViewFit") # fc1 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line002.Shape.Edge1, AD.Line005.Shape.Edge1, AD.Line006.Shape.Edge1, AD.Line007.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc1 Gui.SendMsgToActiveView("ViewFit") # fc2 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line003.Shape.Edge1, AD.Line007.Shape.Edge1, AD.Line008.Shape.Edge1, AD.Line009.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc2 Gui.SendMsgToActiveView("ViewFit") # fc3 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line001.Shape.Edge1, AD.Line005.Shape.Edge1, AD.Line012.Shape.Edge1, AD.Line011.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc3 Gui.SendMsgToActiveView("ViewFit") Gui.SendMsgToActiveView("ViewFit") # fc4 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line004.Shape.Edge1, AD.Line011.Shape.Edge1, AD.Line010.Shape.Edge1, AD.Line009.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc4 Gui.SendMsgToActiveView("ViewFit") # fc5 = Part.makeFilledFace( Part.__sortEdges__([ AD.Line012.Shape.Edge1, AD.Line006.Shape.Edge1, AD.Line008.Shape.Edge1, AD.Line010.Shape.Edge1, ])) AD.addObject('Part::Feature', 'Face').Shape = fc5 Gui.SendMsgToActiveView("ViewFit") # sHH0 = Part.Shell([ AD.Face.Shape.Face1, AD.Face001.Shape.Face1, AD.Face002.Shape.Face1, AD.Face003.Shape.Face1, AD.Face004.Shape.Face1, AD.Face005.Shape.Face1, ]) AD.addObject('Part::Feature', 'Shell').Shape = sHH0.removeSplitter() Gui.SendMsgToActiveView("ViewFit") winsound.Beep(freq, duration) # sLL0 = Part.Solid(sHH0) AD.addObject('Part::Feature', 'Solid').Shape = sLL0.removeSplitter() winsound.Beep(freq, duration)
def Myarray2NurbsD3(arr, label="MyWall", degree=3, obj=None): cylinder = True pst = np.array(arr) NbVPoles, NbUPoles, _t1 = pst.shape #degree=3 #degree=1 udegree = degree vdegree = degree if degree == 1: cylinder = False ps = [[ FreeCAD.Vector(pst[v, u, 0], pst[v, u, 1], pst[v, u, 2]) for u in range(NbUPoles) ] for v in range(NbVPoles)] kv = [1.0 / (NbVPoles - 3) * i for i in range(NbVPoles - 2)] mv = [4] + [1] * (NbVPoles - 4) + [4] if degree == 1: kv = [1.0 / (NbVPoles - 1) * i for i in range(NbVPoles)] mv = [2] + [1] * (NbVPoles - 2) + [2] if NbVPoles == 2: print "KKKK" kv = [0, 1] mv = [2, 2] vdegree = 1 if cylinder: ku = [1.0 / (NbUPoles - 1) * i for i in range(NbUPoles)] mu = [2] + [1] * (NbUPoles - 2) + [2] # bug ku = [1.0 / (NbUPoles) * i for i in range(NbUPoles + 1)] mu = [1] * (NbUPoles + 1) print len(ps) print sum(mu) if degree == 1: ku = [1.0 / (NbUPoles - 1) * i for i in range(NbUPoles)] mu = [1] * (NbUPoles) else: ku = [1.0 / (NbUPoles - 3) * i for i in range(NbUPoles - 2)] mu = [4] + [1] * (NbUPoles - 4) + [4] if degree == 1: ku = [1.0 / (NbUPoles - 1) * i for i in range(NbUPoles)] mu = [2] + [1] * (NbUPoles - 2) + [2] bs = Part.BSplineSurface() bs.buildFromPolesMultsKnots(ps, mv, mu, kv, ku, False, cylinder, vdegree, udegree) sh = bs.toShape() if 1: vcp = True try: sp = App.getDocument("Needle").Poles vcp = sp.ViewObject.ControlPoints except: sp = App.ActiveDocument.addObject("Part::Spline", "Poles") sp.Shape = sh sp.ViewObject.ControlPoints = vcp sp.ViewObject.hide() if obj.makeSolid: try: fa = bs.uIso(0) sha1 = Part.Wire(fa.toShape()) sha = Part.Face(sha1) fb = bs.uIso(1) shb1 = Part.Wire(fb.toShape()) shb = Part.Face(shb1) sol = Part.Solid(Part.Shell([sha.Face1, shb.Face1, sh.Face1])) except: try: sha = Part.makeFilledFace( Part.__sortEdges__([ App.ActiveDocument.Poles.Shape.Edge3, ])) shb = Part.makeFilledFace( Part.__sortEdges__([ App.ActiveDocument.Poles.Shape.Edge1, ])) sol = Part.Solid(Part.Shell([sha.Face1, shb.Face1, sh.Face1])) except: sol = sh else: sol = sh return (sol, bs)
def calculateAdaptivePocket(self, obj, base, subObjTups): '''calculateAdaptivePocket(obj, base, subObjTups) Orient multiple faces around common facial center of mass. Identify edges that are connections for adjacent faces. Attempt to separate unconnected edges into top and bottom loops of the pocket. Trim the top and bottom of the pocket if available and requested. return: tuple with pocket shape information''' low = [] high = [] removeList = [] Faces = [] allEdges = [] makeHighFace = 0 tryNonPlanar = False isHighFacePlanar = True isLowFacePlanar = True faceType = 0 for (sub, face) in subObjTups: Faces.append(face) # identify max and min face heights for top loop (zmin, zmax) = self.getMinMaxOfFaces(Faces) # Order faces around common center of mass subObjTups = self.orderFacesAroundCenterOfMass(subObjTups) # find connected edges and map to edge names of base (connectedEdges, touching) = self.findSharedEdges(subObjTups) (low, high) = self.identifyUnconnectedEdges(subObjTups, touching) if len(high) > 0 and obj.AdaptivePocketStart is True: # attempt planar face with top edges of pocket allEdges = [] makeHighFace = 0 tryNonPlanar = False for (sub, face, ei) in high: allEdges.append(face.Edges[ei]) (hzmin, hzmax) = self.getMinMaxOfFaces(allEdges) try: highFaceShape = Part.Face( Part.Wire(Part.__sortEdges__(allEdges))) except Exception as ee: PathLog.warning(ee) PathLog.error( translate( "Path", "A planar adaptive start is unavailable. The non-planar will be attempted." )) tryNonPlanar = True else: makeHighFace = 1 if tryNonPlanar is True: try: highFaceShape = Part.makeFilledFace( Part.__sortEdges__(allEdges)) # NON-planar face method except Exception as eee: PathLog.warning(eee) PathLog.error( translate( "Path", "The non-planar adaptive start is also unavailable." ) + "(1)") isHighFacePlanar = False else: makeHighFace = 2 if makeHighFace > 0: FreeCAD.ActiveDocument.addObject('Part::Feature', 'topEdgeFace') highFace = FreeCAD.ActiveDocument.ActiveObject highFace.Shape = highFaceShape removeList.append(highFace.Name) # verify non-planar face is within high edge loop Z-boundaries if makeHighFace == 2: mx = hzmax + obj.StepDown.Value mn = hzmin - obj.StepDown.Value if highFace.Shape.BoundBox.ZMax > mx or highFace.Shape.BoundBox.ZMin < mn: PathLog.warning("ZMaxDiff: {}; ZMinDiff: {}".format( highFace.Shape.BoundBox.ZMax - mx, highFace.Shape.BoundBox.ZMin - mn)) PathLog.error( translate( "Path", "The non-planar adaptive start is also unavailable." ) + "(2)") isHighFacePlanar = False makeHighFace = 0 else: isHighFacePlanar = False if len(low) > 0 and obj.AdaptivePocketFinish is True: # attempt planar face with bottom edges of pocket allEdges = [] for (sub, face, ei) in low: allEdges.append(face.Edges[ei]) # (lzmin, lzmax) = self.getMinMaxOfFaces(allEdges) try: lowFaceShape = Part.Face( Part.Wire(Part.__sortEdges__(allEdges))) # lowFaceShape = Part.makeFilledFace(Part.__sortEdges__(allEdges)) # NON-planar face method except Exception as ee: PathLog.error(ee) PathLog.error("An adaptive finish is unavailable.") isLowFacePlanar = False else: FreeCAD.ActiveDocument.addObject('Part::Feature', 'bottomEdgeFace') lowFace = FreeCAD.ActiveDocument.ActiveObject lowFace.Shape = lowFaceShape removeList.append(lowFace.Name) else: isLowFacePlanar = False # Start with a regular pocket envelope strDep = obj.StartDepth.Value finDep = obj.FinalDepth.Value cuts = [] starts = [] finals = [] starts.append(obj.StartDepth.Value) finals.append(zmin) if obj.AdaptivePocketStart is True or len(subObjTups) == 1: strDep = zmax + obj.StepDown.Value starts.append(zmax + obj.StepDown.Value) finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0 depthparams = PathUtils.depth_params( clearance_height=obj.ClearanceHeight.Value, safe_height=obj.SafeHeight.Value, start_depth=strDep, step_down=obj.StepDown.Value, z_finish_step=finish_step, final_depth=finDep, user_depths=None) shape = Part.makeCompound(Faces) env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=depthparams) cuts.append(env.cut(base[0].Shape)) # Might need to change to .cut(job.Stock.Shape) if pocket has no bottom # job = PathUtils.findParentJob(obj) # envBody = env.cut(job.Stock.Shape) if isHighFacePlanar is True and len(subObjTups) > 1: starts.append(hzmax + obj.StepDown.Value) # make shape to trim top of reg pocket strDep1 = obj.StartDepth.Value + (hzmax - hzmin) if makeHighFace == 1: # Planar face finDep1 = highFace.Shape.BoundBox.ZMin + obj.StepDown.Value else: # Non-Planar face finDep1 = hzmin + obj.StepDown.Value depthparams1 = PathUtils.depth_params( clearance_height=obj.ClearanceHeight.Value, safe_height=obj.SafeHeight.Value, start_depth=strDep1, step_down=obj.StepDown.Value, z_finish_step=finish_step, final_depth=finDep1, user_depths=None) envTop = PathUtils.getEnvelope(base[0].Shape, subshape=highFace.Shape, depthparams=depthparams1) cbi = len(cuts) - 1 cuts.append(cuts[cbi].cut(envTop)) if isLowFacePlanar is True and len(subObjTups) > 1: # make shape to trim top of pocket if makeHighFace == 1: # Planar face strDep2 = lowFace.Shape.BoundBox.ZMax else: # Non-Planar face strDep2 = hzmax finDep2 = obj.FinalDepth.Value depthparams2 = PathUtils.depth_params( clearance_height=obj.ClearanceHeight.Value, safe_height=obj.SafeHeight.Value, start_depth=strDep2, step_down=obj.StepDown.Value, z_finish_step=finish_step, final_depth=finDep2, user_depths=None) envBottom = PathUtils.getEnvelope(base[0].Shape, subshape=lowFace.Shape, depthparams=depthparams2) cbi = len(cuts) - 1 cuts.append(cuts[cbi].cut(envBottom)) # package pocket details into tuple sdi = len(starts) - 1 fdi = len(finals) - 1 cbi = len(cuts) - 1 pocket = (cuts[cbi], False, '3DPocket', 0.0, 'X', starts[sdi], finals[fdi]) if FreeCAD.GuiUp: import FreeCADGui for rn in removeList: FreeCADGui.ActiveDocument.getObject(rn).Visibility = False for rn in removeList: FreeCAD.ActiveDocument.getObject(rn).purgeTouched() self.tempObjectNames.append(rn) return pocket
def Activated(self): result = [] try: s = Gui.Selection.getSelectionEx() if len(s) > 1: errMessage = "Select edges from one object" faced.errorDialog(errMessage) return if hasattr(s[0], "SubObjects"): if s[0].HasSubObjects: selectedObj = s[0].SubObjects else: selectedObj = s[0].Object.Shape.Edges[0] else: return edges = [] _resultFaces = [] AllFaces = s[0].Object.Shape.Faces for i in range(0, len(AllFaces)): edges.clear() edges = (AllFaces[i].OuterWire.OrderedEdges) temp = [] temp.clear() for j in range(0, len(edges)): found = False for obj in selectedObj: if ((edges[j]).isEqual(obj)): found = True print("found") else: temp.append(edges[j].copy()) if (len(temp) > 0): #recreate the shape #Register undo App.ActiveDocument.openTransaction( translate("Design456", "RemoveEdge")) nFace = None nWire = _part.Wire(temp) if nWire.isClosed(): try: nFace = _part.makeFilledFace(temp) except: pass if (nFace is None) or (nFace.isNull()): print("failed") nF = App.ActiveDocument.addObject( "Part::Feature", "nWire") nF.Shape = nWire else: _resultFaces.append(nFace) App.ActiveDocument.recompute() shell = _part.makeShell(_resultFaces) App.ActiveDocument.recompute() final = App.ActiveDocument.addObject("Part::Feature", "RemoveEdge") final.Shape = shell App.ActiveDocument.recompute() App.ActiveDocument.removeObject(s[0].Object.Name) except Exception as err: App.Console.PrintError("'Design456_RemoveEdge' 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 Myarray2NurbsD3(arr,label="MyWall",degree=3): pstb=np.array(arr).swapaxes(0,1) pst2=np.concatenate([pstb[7:-1],pstb[1:7]]) psta=pst2.swapaxes(1,0) # ptsa=np.array(arr) try: NbVPoles,NbUPoles,_t1 =psta.shape except: return (Part.Shape(),Part.Shape()) # bs=Part.BSplineSurface() # bs.interpolate(psta) pst=psta FreeCAD.shoe_pst=pst # bs.setVPeriodic() pst[:,:,1] *= -1 psta=pst # die flaeche bs=createBS(pst) # try: fa=App.ActiveDocument.curveA # except: fa=App.ActiveDocument.addObject('Part::Spline','curveA') # # fa.Shape=bs.toShape() color=(random.random(),random.random(),random.random()) #- kann qwg # for i,pps in enumerate(psta): # if i == 0 : continue # bc=Part.BSplineCurve() # bc.interpolate(pps) # App.ActiveDocument.Ribs.OutList[i].Shape=bc.toShape() # App.ActiveDocument.Ribs.OutList[i].ViewObject.LineColor=color # # for i,pps in enumerate(psta.swapaxes(0,1)): # bc=Part.BSplineCurve() # bc.interpolate(pps[2:]) # App.ActiveDocument.Meridians.OutList[i].Shape=bc.toShape() # App.ActiveDocument.Meridians.OutList[i].ViewObject.LineColor=color if 1: sf2=bs.copy() sf2.setVPeriodic() uks=sf2.getUKnots() sf2.segment(uks[1],1,0,1) sh2=sf2.toShape() uks=bs.getUKnots() bs.segment(uks[1],1,0,1) sh=bs.toShape() vcp=False try: sp=App.ActiveDocument.Poles vcp=sp.ViewObject.ControlPoints except: sp=App.ActiveDocument.addObject("Part::Spline","Poles") sp.Shape=sh2 sp.ViewObject.ControlPoints=vcp #sp.ViewObject.hide() try: fa=bs.uIso(0) sha1 = Part.Wire(fa.toShape()) sha = Part.Face(sha1) fb=bs.uIso(1) shb1 = Part.Wire(fb.toShape()) shb = Part.Face(shb1) sol=Part.Solid(Part.Shell([sha.Face1,shb.Face1,sh.Face1])) except: try: sha=Part.makeFilledFace(Part.__sortEdges__([App.ActiveDocument.Poles.Shape.Edge3, ])) shb=Part.makeFilledFace(Part.__sortEdges__([App.ActiveDocument.Poles.Shape.Edge1, ])) sol=Part.Solid(Part.Shell([sha.Face1,shb.Face1,sh.Face1])) except: sol=sh return (sol,bs)
def roundedRectangle(xDim,yDim,r=None,drillCorners=False,ear=False): if drillCorners is False: drillCorners=[False,False,False,False] elif drillCorners is True: drillCorners=[True,True,True,True] elif type(drillCorners) is tuple: drillCorners = list(drillCorners) elif len(drillCorners) is not 4: print("Invalid value for drillCorners in roundedRectangle function") return None if r is None: radii=[0,0,0,0] elif (type(r) is float) or (type(r) is int): radii=[r,r,r,r] elif (type(r) is list) or (type(r) is tuple) and len(r) is 4: radii=[r[0],r[1],r[2],r[3]] else: print("Invalid value for r in roundedRectangle function") return None if (radii[0] + radii[3] > yDim) or (radii[1] + radii[2] > yDim) or (radii[0] + radii[1] > xDim) or (radii[3] + radii[2] > xDim): print("This rounded rectangle is impossible to draw!") return None p0 = FreeCAD.Vector(radii[0],yDim,0) p1 = FreeCAD.Vector(xDim-radii[1],yDim,0) p2 = FreeCAD.Vector(xDim,yDim-radii[1],0) p3 = FreeCAD.Vector(xDim,radii[2],0) p4 = FreeCAD.Vector(xDim-radii[2],0,0) p5 = FreeCAD.Vector(radii[3],0,0) p6 = FreeCAD.Vector(0,radii[3],0) p7 = FreeCAD.Vector(0,yDim-radii[0],0) polygonWire=Part.makePolygon([p0,p1,p2,p3,p4,p5,p6,p7],True) polygonFace=Part.Face(polygonWire) circles = [] if radii[0]>0: # northwest c0 = circle(radii[0]) cornerOffsetXY = radii[0] if drillCorners[0] is True: cornerOffsetXY = cornerOffsetXY*2**(0.5)/2 c0 = translate(c0,cornerOffsetXY,yDim-cornerOffsetXY,0) circles.append(c0) if radii[1]>0: # northeast c1 = circle(radii[1]) cornerOffsetXY = radii[1] if drillCorners[1] is True: cornerOffsetXY = cornerOffsetXY*2**(0.5)/2 c1 = translate(c1,xDim-cornerOffsetXY,yDim-cornerOffsetXY,0) circles.append(c1) if radii[2]>0: # southeast c2 = circle(radii[2]) cornerOffsetXY = radii[2] if drillCorners[2] is True: cornerOffsetXY = cornerOffsetXY*2**(0.5)/2 c2 = translate(c2,xDim-cornerOffsetXY,cornerOffsetXY,0) if ear is True: c2 = Part.makePlane(2*radii[2],radii[2]) rounder = Part.makeCircle(radii[2], FreeCAD.Vector(2*radii[2],radii[2],0)) rounder = Part.makeFilledFace([rounder]) #rounder = Part.Face(rounder) c2 = c2.cut(rounder) c2.translate(FreeCAD.Vector((xDim-radii[2],0,0))) circles.append(c2.Faces[0]) if radii[3]>0: # southwest c3 = circle(radii[3]) cornerOffsetXY = radii[3] if drillCorners[3] is True: cornerOffsetXY = cornerOffsetXY*2**(0.5)/2 c3 = translate(c3,cornerOffsetXY,cornerOffsetXY,0) if ear is True: c3 = Part.makePlane(2*radii[3],radii[3]) rounder = Part.makeCircle(radii[3], FreeCAD.Vector(0,radii[3],0)) rounder = Part.makeFilledFace([rounder]) #rounder = Part.Face(rounder) c3 = c3.cut(rounder) c3.translate(FreeCAD.Vector((-radii[3],0,0))) circles.append(c3.Faces[0]) if len(circles) > 0: roundedGuy = union(polygonFace, circles) else: roundedGuy = polygonFace; return roundedGuy
def circle(radius): '''Create circle centered on origin (which plane?)''' circEdge = Part.makeCircle(radius) #circWire = Part.Wire(circEdge) circFace = Part.makeFilledFace([circEdge]) return circFace
def bisectCrossSections(obj, layerThickness, layerLocation=0.5, archPanels=False): '''bisectSliceWire(obj, layerThickness, layerLocation) splits an object into wires at layerThickness intervals along the Z axis, and distributes the wire shapes on a plane. If you want to laser cut a 3-dimensional object in 4mm plywood, run bisectSliceWire(object, 4), and you will get the laser cutting paths necessary. layerLocation is a range from [0.0, 1.0] that specifies where in each layerThickness segment the wire should cut, where 0.0 is the bottom, 0.5 is the center, and 1.0 is the top. Values outside the accepted range are truncated. This script was initially based on slicePart() from the script available on http://freecadbuch.de/doku.php?id=blog:schnittmodell_eines_hauses_fuer_den_laser-schneider This script uses an optimisation for complex objects that includes cutting the original object into two, and then cutting each segment in two, repeating until the segments are suitably small. This has resulted in a time optimisation on the order of 50-60x on my laptop, for a freecad object that was created from a mesh, as shown in https://www.youtube.com/watch?v=avVNfIswkMU ''' layerLocation = max(0.0, layerLocation) # enforce sensible limits layerLocation = min(1.0, layerLocation) sections = [] workSections = [obj] i = 0 while len(workSections) > 0: o = workSections.pop(0) b = o.Shape.BoundBox lx = b.XLength ly = b.YLength lz = b.ZLength if lz < layerThickness: sections.append(o) continue label_boxbothalf = "box_bottom_half_{0}".format(i) label_bothalf = "bottom_half_{0}".format(i) label_tophalf = "top_half_{0}".format(i) # create bottom half with Intersection boolean op s = App.ActiveDocument.addObject("Part::Box", label_boxbothalf) s.Placement = App.Placement( App.Vector(b.XMin - 1, b.YMin - 1, b.ZMin - 1), App.Rotation(App.Vector(0, 0, 1), 0)) s.Length = lx + 2 s.Width = ly + 2 s.Height = (lz / 2) + 1 bottom_half = App.activeDocument().addObject("Part::MultiCommon", label_bothalf) bottom_half.Shapes = [o, s] # create top half with Difference boolean op top_half = App.activeDocument().addObject("Part::Cut", label_tophalf) top_half.Base = o top_half.Tool = s App.ActiveDocument.recompute() if bottom_half.Shape.BoundBox.ZLength > layerThickness * 2: workSections.append(bottom_half) else: sections.append(bottom_half) if top_half.Shape.BoundBox.ZLength > layerThickness * 2: workSections.append(top_half) else: sections.append(top_half) i = i + 1 g2 = App.ActiveDocument.addObject("App::DocumentObjectGroup", str(obj.Label) + "_Slices") total_zmin = obj.Shape.BoundBox.ZMin total_zmax = obj.Shape.BoundBox.ZMax lx = obj.Shape.BoundBox.XLength + 5 ly = obj.Shape.BoundBox.YLength + 5 out_x = 0 out_y = 0 start_z = total_zmin + (layerThickness * layerLocation) step = layerThickness total_step = 0 current_z = start_z cross_sections = [] while current_z <= total_zmax: # Find the correct section in sections[] for section in sections: if section.Shape.BoundBox.ZMin <= current_z and section.Shape.BoundBox.ZMax >= current_z: try: wires = list() for i in section.Shape.slice(FreeCAD.Base.Vector(0, 0, 1), current_z): wires.append(i) comp = Part.Compound(wires) layer = FreeCAD.ActiveDocument.addObject( "Part::Feature", "MyLayer") layer.Shape = comp layer.purgeTouched() layer.Placement.Base = FreeCAD.Vector( out_x, out_y, -current_z) if archPanels: cross_sections.append(layer) out_x = out_x + lx if out_x > 400: out_x = 0 out_y = out_y + ly g2.addObject(layer) break except Exception as e: print "Caught exception:", repr(e) total_step += step current_z = start_z + total_step for section in sections: section.ViewObject.Visibility = False if archPanels: for cross_section in cross_sections: tmp = Part.makeFilledFace( Part.__sortEdges__([ cross_section.Shape.Edge1, ])) if tmp.isNull(): raise RuntimeError('Failed to create face') face = App.ActiveDocument.addObject('Part::Feature', 'Face') face.Shape = tmp del tmp cross_section.ViewObject.Visibility = False Arch.makePanel(face, thickness=layerThickness) App.activeDocument().recompute()
def run_FreeCAD_conny(self): edges=self.getPinObjects(pinname='Shapes_in',sort=False) sayl() neighbor=[] gaps=[] ec=len(edges) # say("len edges",ec) # say("edges") e2=[] for e in edges: #say(e,e.__class__) try: e2 += [e.Edge1] except: e2 += [e] e=e2 #say(e) #return for i in range(ec): sf=-1 sflag=0 sdist=10**8 f=-1 flag=0 dist=10**8 vs=edges[i].Vertexes[0].Point ve=edges[i].Vertexes[1].Point #say(vs,ve) for j in range(ec): if i == j: continue if (edges[j].Vertexes[0].Point-vs).Length <sdist: sf=j sdist=(edges[j].Vertexes[0].Point-vs).Length sflag=0 if (edges[j].Vertexes[1].Point-vs).Length <sdist: sf=j sdist=(edges[j].Vertexes[1].Point-vs).Length sflag=1 if (edges[j].Vertexes[0].Point-ve).Length <dist: f=j dist=(edges[j].Vertexes[0].Point-ve).Length flag=0 if (edges[j].Vertexes[1].Point-ve).Length <dist: f=j dist=(edges[j].Vertexes[1].Point-ve).Length flag=1 neighbor += [(sf,sflag,sdist,f,flag,dist)] # print (i,sf,sflag,sdist,f,flag,dist) # find neighbors chain of edges e=0 # starting edge try: ee=neighbor[e][0] except: say("keine daten abbruch") return chain=[e,ee] for i in range(14): if neighbor[ee][0] not in chain: ee2=neighbor[ee][0] chain += [ee2] e=ee ee=ee2 elif neighbor[ee][3] not in chain: ee2=neighbor[ee][3] chain += [ee2] e=ee ee=ee2 print("chain",chain) # calculate gap filler for the chain pts=[] col=[] cc=len(chain) for i in range(cc): lmin=10**8 ep=chain[i-1] e=chain[i] ff=-1 # shortest gap between two edges of the chain for f in range(2): for fp in range(2): pa,pb=edges[e].Vertexes[f].Point,edges[ep].Vertexes[fp].Point l=(pa-pb).Length if l<lmin: lmin=l paa,pbb=pa,pb polsa=edges[e].toNurbs().Edge1.Curve.getPoles() polsb=edges[ep].toNurbs().Edge1.Curve.getPoles() if ff == -1: if (polsa[0]-polsb[0]).Length < (polsa[-1]-polsb[-1]).Length: ff=0 else: ff = 1 ff2= 1 - ff if self.getData('ff') else 0 if f==ff2: na=[polsa[0],polsa[1]] else: na=[polsa[-1],polsa[-2]] if fp==ff2: nb=[polsb[0],polsb[1]] else: nb=[polsb[-1],polsb[-2]] # create the gap filler if (na[0]-nb[0]).Length> 0.0001: #+# k should depend on size of gap (na[0]-nb[0]).Length k=self.getData("tangentForce")*0.05 nn=[na[0],na[0]+(na[0]-na[1])*k,nb[0]+(nb[0]-nb[1])*k,nb[0]] ###simple line connection ##t=Part.makePolygon(nn) ##col += [Part.makePolygon([paa,pbb]).Edge1] t=Part.BSplineCurve() t.buildFromPolesMultsKnots(nn,[4,4],[0,1],False,3) gaps += [t.toShape().Edge1] col += [t.toShape().Edge1] col += [edges[ep].Edge1] # special case only two edges if ec==2: col=[] gaps=[] polsa=edges[0].toNurbs().Edge1.Curve.getPoles() polsb=edges[1].toNurbs().Edge1.Curve.getPoles() ff= 1 if self.getData('ff') else 0 for [na,nb] in [ [[polsa[0],polsa[1]],[polsb[-1],polsb[-2]]], [[polsa[-1],polsa[-2]],[polsb[0],polsb[1]]] ]: if (na[0]-nb[0]).Length> 0.0001: k=self.getData("tangentForce")*0.05 nn=[na[0],na[0]+(na[0]-na[1])*k,nb[0]+(nb[0]-nb[1])*k,nb[0]] t=Part.BSplineCurve() t.buildFromPolesMultsKnots(nn,[4,4],[0,1],False,3) gaps += [t.toShape().Edge1] col += [t.toShape().Edge1] col += [edges[1]] col += [edges[0]] #say(col) if self.getData("createFace"): ss=Part.sortEdges(col) sh=Part.makeFilledFace(ss[0]) else: sh=Part.Compound(col) self.setPinObject("Shape_out",sh) #say("col",col) #say("gaps",gaps) self.setPinObject("gaps",Part.Compound(gaps))