def __repr__(self): """Show the string representation of the object.""" text = "Workplane" text += " x=" + str(DraftVecUtils.rounded(self.u)) text += " y=" + str(DraftVecUtils.rounded(self.v)) text += " z=" + str(DraftVecUtils.rounded(self.axis)) return text
def __repr__(self): return ( "Workplane x=" + str(DraftVecUtils.rounded(self.u)) + " y=" + str(DraftVecUtils.rounded(self.v)) + " z=" + str(DraftVecUtils.rounded(self.axis)) )
def getIfcExtrusionData(obj,scale=1): """getIfcExtrusionData(obj,[scale]): returns a closed path (a list of tuples), a tuple expressing an extrusion vector, and a list of 3 tuples for base position, x axis and z axis. Or returns None, if a base loop and an extrusion direction cannot be extracted. Scale can indicate a scale factor.""" if hasattr(obj,"Additions"): if obj.Additions: # provisorily treat objs with additions as breps return None if hasattr(obj,"Subtractions"): if obj.Subtractions: # provisorily treat objs with subtractions as breps return None if hasattr(obj,"Proxy"): if hasattr(obj.Proxy,"getProfiles"): p = obj.Proxy.getProfiles(obj,noplacement=True) v = obj.Proxy.getExtrusionVector(obj,noplacement=True) if (len(p) == 1) and v: p = p[0] r = FreeCAD.Placement() #b = p.CenterOfMass r = obj.Proxy.getPlacement(obj) #b = obj.Placement.multVec(FreeCAD.Vector()) #r.Rotation = DraftVecUtils.getRotation(v,FreeCAD.Vector(0,0,1)) d = [r.Base,DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(1,0,0))),DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(0,0,1)))] #r = r.inverse() #print "getExtrusionData: computed placement:",r import Part if len(p.Edges) == 1: if isinstance(p.Edges[0].Curve,Part.Circle): # Circle profile r1 = p.Edges[0].Curve.Radius*scale return "circle", [getTuples(p.Edges[0].Curve.Center,scale), r1], getTuples(v,scale), d elif isinstance(p.Edges[0].Curve,Part.Ellipse): # Ellipse profile r1 = p.Edges[0].Curve.MajorRadius*scale r2 = p.Edges[0].Curve.MinorRadius*scale return "ellipse", [getTuples(p.Edges[0].Curve.Center,scale), r1, r2], getTuples(v,scale), d curves = False for e in p.Edges: if isinstance(e.Curve,Part.Circle): curves = True elif not isinstance(e.Curve,Part.Line): print "Arch.getIfcExtrusionData: Warning: unsupported edge type in profile" if curves: # Composite profile ecurves = [] for e in p.Edges: if isinstance(e.Curve,Part.Circle): p1 = e.FirstParameter p2 = e.LastParameter ecurves.append(["arc",getTuples(e.Curve.Center,scale),e.Curve.Radius*scale,[p1,p2]]) else: ecurves.append(["line",[getTuples(vt.Point,scale) for vt in e.Vertexes]]) return "composite", ecurves, getTuples(v,scale), d else: # Polyline profile return "polyline", getTuples(p,scale), getTuples(v,scale), d return None
def getExtrusionVector(self,obj,noplacement=False): "Returns an extrusion vector of this component, if applicable" n,l,w,h = self.getDefaultValues(obj) if Draft.getType(obj) == "Structure": if l > h: v = n.multiply(l) if noplacement: import DraftVecUtils v = DraftVecUtils.rounded(FreeCAD.Rotation(FreeCAD.Vector(0,1,0),-90).multVec(v)) return v return n.multiply(h)
def getTuples(data,scale=1,placement=None,normal=None,close=True): """getTuples(data,[scale,placement,normal,close]): returns a tuple or a list of tuples from a vector or from the vertices of a shape. Scale can indicate a scale factor""" import Part if isinstance(data,FreeCAD.Vector): if placement: data = placement.multVec(data) data = DraftVecUtils.rounded(data) return (data.x*scale,data.y*scale,data.z*scale) elif isinstance(data,Part.Shape): t = [] if len(data.Wires) == 1: import Part,DraftGeomUtils data = Part.Wire(DraftGeomUtils.sortEdges(data.Wires[0].Edges)) verts = data.Vertexes try: c = data.CenterOfMass v1 = verts[0].Point.sub(c) v2 = verts[1].Point.sub(c) if DraftVecUtils.angle(v2,v1,normal) >= 0: # inverting verts order if the direction is couterclockwise verts.reverse() except: pass for v in verts: pt = v.Point if placement: if not placement.isNull(): pt = placement.multVec(pt) pt = DraftVecUtils.rounded(pt) t.append((pt.x*scale,pt.y*scale,pt.z*scale)) if close: # faceloops must not be closed, but ifc profiles must. t.append(t[0]) else: print "Arch.getTuples(): Wrong profile data" return t
def getIfcExtrusionData(obj,scale=1): """getIfcExtrusionData(obj,[scale]): returns a closed path (a list of tuples), a tuple expressing an extrusion vector, and a list of 3 tuples for base position, x axis and z axis. Or returns None, if a base loop and an extrusion direction cannot be extracted. Scale can indicate a scale factor.""" if hasattr(obj,"Additions"): if obj.Additions: # provisorily treat objs with additions as breps return None if hasattr(obj,"Subtractions"): if obj.Subtractions: # provisorily treat objs with subtractions as breps return None if hasattr(obj,"Proxy"): if hasattr(obj.Proxy,"getProfiles"): p = obj.Proxy.getProfiles(obj,noplacement=True) v = obj.Proxy.getExtrusionVector(obj,noplacement=True) if (len(p) == 1) and v: p = p[0] r = FreeCAD.Placement() #b = p.CenterOfMass r = obj.Proxy.getPlacement(obj) #b = obj.Placement.multVec(FreeCAD.Vector()) #r.Rotation = DraftVecUtils.getRotation(v,FreeCAD.Vector(0,0,1)) d = [r.Base,DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(1,0,0))),DraftVecUtils.rounded(r.Rotation.multVec(FreeCAD.Vector(0,0,1)))] #r = r.inverse() #print "getExtrusionData: computed placement:",r import Part if len(p.Edges) == 1: if isinstance(p.Edges[0].Curve,Part.Circle): r1 = p.Edges[0].Curve.Radius*scale return "circle", [getTuples(p.Edges[0].Curve.Center,scale), r1], getTuples(v,scale), d elif isinstance(p.Edges[0].Curve,Part.Ellipse): r1 = p.Edges[0].Curve.MajorRadius*scale r2 = p.Edges[0].Curve.MinorRadius*scale return "ellipse", [getTuples(p.Edges[0].Curve.Center,scale), r1, r2], getTuples(v,scale), d return "polyline", getTuples(p,scale), getTuples(v,scale), d return None
def createMeshView(obj, direction=FreeCAD.Vector(0, 0, -1), outeronly=False, largestonly=False): """createMeshView(obj,[direction,outeronly,largestonly]): creates a flat shape that is the projection of the given mesh object in the given direction (default = on the XY plane). If outeronly is True, only the outer contour is taken into consideration, discarding the inner holes. If largestonly is True, only the largest segment of the given mesh will be used.""" import Mesh, math, Part, DraftGeomUtils if not obj.isDerivedFrom("Mesh::Feature"): return mesh = obj.Mesh # 1. Flattening the mesh proj = [] for f in mesh.Facets: nf = [] for v in f.Points: v = FreeCAD.Vector(v) a = v.negative().getAngle(direction) l = math.cos(a) * v.Length p = v.add(FreeCAD.Vector(direction).multiply(l)) p = DraftVecUtils.rounded(p) nf.append(p) proj.append(nf) flatmesh = Mesh.Mesh(proj) # 2. Removing wrong faces facets = [] for f in flatmesh.Facets: if f.Normal.getAngle(direction) < math.pi: facets.append(f) cleanmesh = Mesh.Mesh(facets) #Mesh.show(cleanmesh) # 3. Getting the bigger mesh from the planar segments if largestonly: c = cleanmesh.getSeparateComponents() #print(c) cleanmesh = c[0] segs = cleanmesh.getPlanarSegments(1) meshes = [] for s in segs: f = [cleanmesh.Facets[i] for i in s] meshes.append(Mesh.Mesh(f)) a = 0 for m in meshes: if m.Area > a: boundarymesh = m a = m.Area #Mesh.show(boundarymesh) cleanmesh = boundarymesh # 4. Creating a Part and getting the contour shape = None for f in cleanmesh.Facets: p = Part.makePolygon(f.Points + [f.Points[0]]) #print(p,len(p.Vertexes),p.isClosed()) try: p = Part.Face(p) if shape: shape = shape.fuse(p) else: shape = p except Part.OCCError: pass shape = shape.removeSplitter() # 5. Extracting the largest wire if outeronly: count = 0 largest = None for w in shape.Wires: if len(w.Vertexes) > count: count = len(w.Vertexes) largest = w if largest: try: f = Part.Face(w) except Part.OCCError: print("Unable to produce a face from the outer wire.") else: shape = f return shape
def createMeshView(obj,direction=FreeCAD.Vector(0,0,-1),outeronly=False,largestonly=False): """createMeshView(obj,[direction,outeronly,largestonly]): creates a flat shape that is the projection of the given mesh object in the given direction (default = on the XY plane). If outeronly is True, only the outer contour is taken into consideration, discarding the inner holes. If largestonly is True, only the largest segment of the given mesh will be used.""" import Mesh, math, Part, DraftGeomUtils if not obj.isDerivedFrom("Mesh::Feature"): return mesh = obj.Mesh # 1. Flattening the mesh proj = [] for f in mesh.Facets: nf = [] for v in f.Points: v = FreeCAD.Vector(v) a = v.negative().getAngle(direction) l = math.cos(a)*v.Length p = v.add(FreeCAD.Vector(direction).multiply(l)) p = DraftVecUtils.rounded(p) nf.append(p) proj.append(nf) flatmesh = Mesh.Mesh(proj) # 2. Removing wrong faces facets = [] for f in flatmesh.Facets: if f.Normal.getAngle(direction) < math.pi: facets.append(f) cleanmesh = Mesh.Mesh(facets) #Mesh.show(cleanmesh) # 3. Getting the bigger mesh from the planar segments if largestonly: c = cleanmesh.getSeparateComponents() #print c cleanmesh = c[0] segs = cleanmesh.getPlanarSegments(1) meshes = [] for s in segs: f = [cleanmesh.Facets[i] for i in s] meshes.append(Mesh.Mesh(f)) a = 0 for m in meshes: if m.Area > a: boundarymesh = m a = m.Area #Mesh.show(boundarymesh) cleanmesh = boundarymesh # 4. Creating a Part and getting the contour shape = None for f in cleanmesh.Facets: p = Part.makePolygon(f.Points+[f.Points[0]]) #print p,len(p.Vertexes),p.isClosed() try: p = Part.Face(p) if shape: shape = shape.fuse(p) else: shape = p except Part.OCCError: pass shape = shape.removeSplitter() # 5. Extracting the largest wire if outeronly: count = 0 largest = None for w in shape.Wires: if len(w.Vertexes) > count: count = len(w.Vertexes) largest = w if largest: try: f = Part.Face(w) except Part.OCCError: print "Unable to produce a face from the outer wire." else: shape = f return shape
def __repr__(self): return "Workplane x=" + str(DraftVecUtils.rounded( self.u)) + " y=" + str(DraftVecUtils.rounded( self.v)) + " z=" + str(DraftVecUtils.rounded(self.axis))