def getbase(wire): "returns a full shape from a base wire" dvec = fcgeo.vec(wire.Edges[0]).cross(normal) dvec.normalize() if obj.Align == "Left": dvec = dvec.multiply(width) w2 = fcgeo.offsetWire(wire,dvec) w1 = Part.Wire(fcgeo.sortEdges(wire.Edges)) sh = fcgeo.bind(w1,w2) elif obj.Align == "Right": dvec = dvec.multiply(width) dvec = fcvec.neg(dvec) w2 = fcgeo.offsetWire(wire,dvec) w1 = Part.Wire(fcgeo.sortEdges(wire.Edges)) sh = fcgeo.bind(w1,w2) elif obj.Align == "Center": dvec = dvec.multiply(width/2) w1 = fcgeo.offsetWire(wire,dvec) dvec = fcvec.neg(dvec) w2 = fcgeo.offsetWire(wire,dvec) sh = fcgeo.bind(w1,w2) # fixing self-intersections sh.fix(0.1,0,1) if height and (not flat): norm = Vector(normal).multiply(height) sh = sh.extrude(norm) return sh
def getSVG(self): "Returns a SVG fragment" if not self.sorted: self.sort() svg = '' for f in self.faces: svg += '<path ' edges = fcgeo.sortEdges(f.Edges) v = edges[0].Vertexes[0].Point svg += 'd="M ' + str(v.x) + ' ' + str(v.y) + ' ' for e in edges: if isinstance(e.Curve, Part.Line) or isinstance( e.Curve, Part.BSplineCurve): v = e.Vertexes[-1].Point svg += 'L ' + str(v.x) + ' ' + str(v.y) + ' ' elif isinstance(e.Curve, Part.Circle): r = e.Curve.Radius v = e.Vertexes[-1].Point svg += 'A ' + str(r) + ' ' + str(r) + ' 0 0 1 ' + str( v.x) + ' ' svg += str(v.y) + ' ' svg += '" ' svg += 'stroke="#000000" ' svg += 'stroke-width="0.01 px" ' svg += 'style="stroke-width:0.01;' svg += 'stroke-miterlimit:1;' svg += 'stroke-dasharray:none;' svg += 'fill:#aaaaaa"' svg += '/>\n' return svg
def getPath(self, face, plane): import Part from draftlibs import fcgeo "returns a svg path from a face" svg = '<path ' edges = fcgeo.sortEdges(face.Edges) v = self.getProj(edges[0].Vertexes[0].Point, plane) svg += 'd="M ' + str(v.x) + ' ' + str(v.y) + ' ' for e in edges: if isinstance(e.Curve, Part.Line) or isinstance( e.Curve, Part.BSplineCurve): v = self.getProj(e.Vertexes[-1].Point, plane) svg += 'L ' + str(v.x) + ' ' + str(v.y) + ' ' elif isinstance(e.Curve, Part.Circle): r = e.Curve.Radius v = self.getProj(e.Vertexes[-1].Point, plane) svg += 'A ' + str(r) + ' ' + str(r) + ' 0 0 1 ' + str( v.x) + ' ' svg += str(v.y) + ' ' svg += '" ' svg += 'stroke="#000000" ' svg += 'stroke-width="0.01 px" ' svg += 'style="stroke-width:0.01;' svg += 'stroke-miterlimit:1;' svg += 'stroke-dasharray:none;' svg += 'fill:#aaaaaa"' svg += '/>\n' return svg
def flattenFace(self, face): "Returns a face where all vertices have Z = 0" verts = [] edges = fcgeo.sortEdges(face.Edges) for e in edges: v = e.Vertexes[0].Point verts.append(FreeCAD.Vector(v.x, v.y, 0)) verts.append(verts[0]) try: sh = Part.makePolygon(verts) sh = Part.Face(sh) except: if DEBUG: print "Error: Unable to flatten face" return None else: return sh
def getPathData(self,w): "Returns a SVG path data string from a 2D wire" edges = fcgeo.sortEdges(w.Edges) v = edges[0].Vertexes[0].Point svg = 'M '+ str(v.x) +' '+ str(v.y) + ' ' for e in edges: if isinstance(e.Curve,Part.Line) or isinstance(e.Curve,Part.BSplineCurve): v = e.Vertexes[-1].Point svg += 'L '+ str(v.x) +' '+ str(v.y) + ' ' elif isinstance(e.Curve,Part.Circle): r = e.Curve.Radius v = e.Vertexes[-1].Point svg += 'A '+ str(r) + ' '+ str(r) +' 0 0 1 '+ str(v.x) +' ' svg += str(v.y) + ' ' svg += 'z ' return svg
def projectFace(self, face): "projects a single face on the WP" verts = [] edges = fcgeo.sortEdges(face.Edges) for e in edges: v = e.Vertexes[0].Point v = self.wp.getLocalCoords(v) verts.append(v) verts.append(verts[0]) try: sh = Part.makePolygon(verts) sh = Part.Face(sh) except: if DEBUG: print "Error: Unable to project face on the WP" return None else: return sh
def getIndices(shape,offset): "returns a list with 2 lists: vertices and face indexes, offsetted with the given amount" vlist = [] flist = [] for v in shape.Vertexes: vlist.append(" "+str(round(v.X,4))+" "+str(round(v.Z,4))+" "+str(round(v.Y,4))) for f in shape.Faces: fi = "" # OCC vertices are unsorted. We need to sort in the right order... edges = fcgeo.sortEdges(f.Wire.Edges) print edges for e in edges: print e.Vertexes[0].Point,e.Vertexes[1].Point v = e.Vertexes[0] fi+=" "+str(findVert(v,shape.Vertexes)+offset) flist.append(fi) return vlist,flist
def flattenFace(self,face): "Returns a face where all vertices have Z = 0" wires = [] for w in face[0].Wires: verts = [] edges = fcgeo.sortEdges(w.Edges) for e in edges: v = e.Vertexes[0].Point verts.append(FreeCAD.Vector(v.x,v.y,0)) verts.append(verts[0]) wires.append(Part.makePolygon(verts)) try: sh = Part.Face(wires) except: if DEBUG: print "Error: Unable to flatten face" return None else: return [sh]+face[1:]
def projectFace(self,face): "projects a single face on the WP" wires = [] norm = face[0].normalAt(0,0) for w in face[0].Wires: verts = [] edges = fcgeo.sortEdges(w.Edges) for e in edges: v = e.Vertexes[0].Point v = self.wp.getLocalCoords(v) verts.append(v) verts.append(verts[0]) wires.append(Part.makePolygon(verts)) try: sh = ArchCommands.makeFace(wires) except: if DEBUG: print "Error: Unable to project face on the WP" return None else: # restoring flipped normals vnorm = self.wp.getLocalCoords(norm) if vnorm.getAngle(sh.normalAt(0,0)) > 1: sh.reverse() return [sh]+face[1:]
def make_curves(self): item = "" edges=[] s=Gui.Selection.getSelectionEx() for i in s: for e in i.SubElementNames: edges.append(getattr(i.Object.Shape,e)) sorted_edges = [] sorted_edges = fcgeo.sortEdges(edges) #item += '#another test after sorted_edges \n' def isSameVertex(V1, V2):#borrowed from yorik's fcgeo.py- thanks yorik! ''' Test if vertexes have same coordinates with precision 10E(-precision)''' if round(V1.X-V2.X,1)==0 and round(V1.Y-V2.Y,1)==0 and round(V1.Z-V2.Z,1)==0 : return True else : return False start=sorted_edges[0] end=sorted_edges[-1] startingZ = start.Vertexes[0].Z #set starting depth to same Z as starting curve element self.form.lineEditStartDepth.setText(str(start.Vertexes[0].Z)) item += "curve = area.Curve()\n" if isSameVertex(start.Vertexes[0],end.Vertexes[1]) : item += '#closed path\n' path = 'closedpath' else: item += '#open path\n' path = 'openpath' if path == 'openpath' : item += "curve.append(area.Point(" + str(start.Vertexes[0].X) + "," + str(start.Vertexes[0].Y)+ "))\n" for s in sorted_edges: #edges.append(s) if (isinstance(s.Curve,Part.Circle)): mp = fcgeo.findMidpoint(s) ce = s.Curve.Center tang1 = s.Curve.tangent(s.ParameterRange[0]) ; tang2 = s.Curve.tangent(s.ParameterRange[1]) cross1 = Vector.cross(Base.Vector(tang1[0][0],tang1[0][1],tang1[0][2]),Base.Vector(tang2[0][0],tang2[0][1],tang2[0][2])) if cross1[2] > 0: direct = '1 ' #we seem to be working in a rh system in FreeCAD else: direct = '-1 ' item += "curve.append(area.Vertex("+str(direct)+ ", area.Point( "+ str(s.Vertexes[-1].Point[0])+", "+str(s.Vertexes[-1].Point[1])+ "), area.Point("+str(s.Curve.Center [0])+ ", " + str(s.Curve.Center[1])+ ")))\n" elif (isinstance(s.Curve,Part.Line)): item += "curve.append(area.Point( "+str(s.Vertexes[-1].Point[0])+", " +str(s.Vertexes[-1].Point[1])+ "))\n" else: pass #export curve elements to heekscnc #to reverse the curve: #item += "curve.append(area.Point(" + str(end.Vertexes[0].X) + "," + str(end.Vertexes[0].Y) + "))" if path == 'closedpath': item += "curve.append(area.Point(" + str(start.Vertexes[1].X) + "," + str(start.Vertexes[1].Y)+ "))\n" item += "curve.Reverse()\n" self.form.textEditCurve.append(item)