def execute(self,obj): nOfStrings = len(obj.Strings) lattice = screen(obj.ArrayLink) if lattice is None: plms = [App.Placement() for i in range(0,nOfStrings)] else: if not lattice2BaseFeature.isObjectLattice(lattice): lattice2Executer.warning(obj,"ShapeString's link to array must point to a lattice. It points to a generic shape. Results may be unexpected.") leaves = LCE.AllLeaves(lattice.Shape) plms = [leaf.Placement for leaf in leaves] #update foolObj's properties self.makeFoolObj(obj) #make sure we have one - fixes defunct Lattice ShapeString after save-load for (proptype, propname, group, hint) in self.foolObj.properties: if propname != "String": #ignore "String", that will be taken care of in the following loop setattr(self.foolObj, propname, getattr(obj, propname)) self.foolObj.FontFile = findFont(obj.FontFile) obj.FullPathToFont = self.foolObj.FontFile shapes = [] for i in range( 0 , min(len(plms),len(obj.Strings)) ): if len(obj.Strings[i]) > 0: #generate shapestring using Draft self.foolObj.String = obj.Strings[i] self.foolObj.Shape = None self.draft_shape_string.execute(self.foolObj) shape = self.foolObj.Shape #calculate alignment point if obj.XAlign == 'None' and obj.YAlign == 'None': pass #need not calculate boundbox else: if obj.AlignPrecisionBoundBox: bb = getPrecisionBoundBox(shape) else: bb = shape.BoundBox alignPnt = App.Vector() if obj.XAlign == 'Left': alignPnt.x = bb.XMin elif obj.XAlign == 'Right': alignPnt.x = bb.XMax elif obj.XAlign == 'Middle': alignPnt.x = bb.Center.x if obj.YAlign == 'Bottom': alignPnt.y = bb.YMin elif obj.YAlign == 'Top': alignPnt.y = bb.YMax elif obj.YAlign == 'Middle': alignPnt.y = bb.Center.y #Apply alignment shape.Placement = App.Placement(alignPnt*(-1.0), App.Rotation()).multiply(shape.Placement) #Apply placement from array shape.Placement = plms[i].multiply(shape.Placement) shapes.append(shape.copy()) if len(shapes) == 0: scale = 1.0 if lattice is not None: scale = lattice.Shape.BoundBox.DiagonalLength/math.sqrt(3)/math.sqrt(len(shps)) if scale < DistConfusion * 100: scale = 1.0 obj.Shape = markers.getNullShapeShape(scale) raise ValueError('No strings were converted into shapes') #Feeding empty compounds to FreeCAD seems to cause rendering issues, otherwise it would have been a good idea to output nothing. result = Part.makeCompound(shapes) result.Placement = obj.Placement obj.Shape = result
def derivedExecute(self,obj): # cache stuff if lattice2BaseFeature.isObjectLattice(obj.ShapeLink): lattice2Executer.warning(obj,"ShapeLink points to a placement/array of placements. The placement/array will be reinterpreted as a generic shape; the results may be unexpected.") base = obj.ShapeLink.Shape if obj.CompoundTraversal == "Use as a whole": baseChildren = [base] else: if base.ShapeType != 'Compound': base = Part.makeCompound([base]) if obj.CompoundTraversal == "Recursive": baseChildren = LCE.AllLeaves(base) else: baseChildren = base.childShapes() #cache mode comparisons, for speed posIsNone = obj.TranslateMode == '(none)' posIsParent = obj.TranslateMode == 'parent' posIsChild = obj.TranslateMode == 'child' posIsCenterM = obj.TranslateMode == 'child.CenterOfMass' posIsCenterBB = obj.TranslateMode == 'child.CenterOfBoundBox' posIsVertex = obj.TranslateMode == 'child.Vertex' oriIsNone = obj.OrientMode == '(none)' oriIsParent = obj.OrientMode == 'parent' oriIsChild = obj.OrientMode == 'child' oriIsInertial = obj.OrientMode == 'child.InertiaAxes' oriIsEdge = obj.OrientMode == 'child.Edge' oriIsFace = obj.OrientMode == 'child.FaceAxis' # initialize output containers and loop variables outputPlms = [] #list of placements # the essence for child in baseChildren: pos = App.Vector() ori = App.Rotation() if posIsNone: pass elif posIsParent: pos = base.Placement.Base elif posIsChild: pos = child.Placement.Base elif posIsCenterM: leaves = LCE.AllLeaves(child) totalW = 0 weightAttrib = {"Vertex":"", "Edge":"Length", "Wire":"Length", "Face":"Area", "Shell":"Area", "Solid":"Volume", "CompSolid":""}[leaves[0].ShapeType] #Center of mass of a compound is a weghted average of centers # of mass of individual objects. for leaf in leaves: w = 1.0 if not weightAttrib else (getattr(leaf, weightAttrib)) if leaf.ShapeType == 'Vertex': leafCM = leaf.Point #elif child.ShapeType == 'CompSolid': #todo else: leafCM = leaf.CenterOfMass pos += leafCM * w totalW += w pos = pos * (1.0/totalW) elif posIsCenterBB: import lattice2BoundBox bb = lattice2BoundBox.getPrecisionBoundBox(child) pos = bb.Center elif posIsVertex: v = child.Vertexes[obj.TranslateElementIndex - 1] pos = v.Point else: raise ValueError(obj.Name + ": translation mode not implemented: "+obj.TranslateMode) if oriIsNone: pass elif oriIsParent: ori = base.Placement.Rotation elif oriIsChild: ori = child.Placement.Rotation elif oriIsInertial: leaves = LCE.AllLeaves(child) if len(leaves)>1: raise ValueError(obj.Name + ": calculation of principal axes of compounds is not supported yet") props = leaves[0].PrincipalProperties XAx = props['FirstAxisOfInertia'] ZAx = props['ThirdAxisOfInertia'] ori = Utils.makeOrientationFromLocalAxes(ZAx, XAx) elif oriIsEdge: edge = child.Edges[obj.OrientElementIndex - 1] XAx = edge.Curve.tangent(edge.Curve.FirstParameter)[0] ori1 = Utils.makeOrientationFromLocalAxes(ZAx= XAx) ori2 = Utils.makeOrientationFromLocalAxes(ZAx= App.Vector(1,0,0),XAx= App.Vector(0,0,1)) ori = ori1.multiply(ori2) elif oriIsFace: face = child.Faces[obj.OrientElementIndex - 1] ZAx = face.Surface.Axis else: raise ValueError(obj.Name + ": orientation mode not implemented: "+obj.OrientMode) plm = App.Placement(pos, ori) outputPlms.append(plm) return outputPlms
def execute(self,obj): nOfStrings = len(obj.Strings) lattice = obj.ArrayLink if lattice is None: plms = [App.Placement() for i in range(0,nOfStrings)] else: if not lattice2BaseFeature.isObjectLattice(lattice): lattice2Executer.warning(obj,"ShapeString's link to array must point to a lattice. It points to a generic shape. Results may be unexpected.") leaves = LCE.AllLeaves(lattice.Shape) plms = [leaf.Placement for leaf in leaves] #update foolObj's properties self.makeFoolObj(obj) #make sure we have one - fixes defunct Lattice ShapeString after save-load for (proptype, propname, group, hint) in self.foolObj.properties: if propname != "String": #ignore "String", that will be taken care of in the following loop setattr(self.foolObj, propname, getattr(obj, propname)) self.foolObj.FontFile = findFont(obj.FontFile) obj.FullPathToFont = self.foolObj.FontFile shapes = [] for i in range( 0 , min(len(plms),len(obj.Strings)) ): if len(obj.Strings[i]) > 0: #generate shapestring using Draft self.foolObj.String = obj.Strings[i] self.foolObj.Shape = None self.draft_shape_string.execute(self.foolObj) shape = self.foolObj.Shape #calculate alignment point if obj.XAlign == 'None' and obj.YAlign == 'None': pass #need not calculate boundbox else: if obj.AlignPrecisionBoundBox: bb = getPrecisionBoundBox(shape) else: bb = shape.BoundBox alignPnt = App.Vector() if obj.XAlign == 'Left': alignPnt.x = bb.XMin elif obj.XAlign == 'Right': alignPnt.x = bb.XMax elif obj.XAlign == 'Middle': alignPnt.x = bb.Center.x if obj.YAlign == 'Bottom': alignPnt.y = bb.YMin elif obj.YAlign == 'Top': alignPnt.y = bb.YMax elif obj.YAlign == 'Middle': alignPnt.y = bb.Center.y #Apply alignment shape.Placement = App.Placement(alignPnt*(-1.0), App.Rotation()).multiply(shape.Placement) #Apply placement from array shape.Placement = plms[i].multiply(shape.Placement) shapes.append(shape.copy()) if len(shapes) == 0: scale = 1.0 if lattice is not None: scale = lattice.Shape.BoundBox.DiagonalLength/math.sqrt(3)/math.sqrt(len(shps)) if scale < DistConfusion * 100: scale = 1.0 obj.Shape = markers.getNullShapeShape(scale) raise ValueError('No strings were converted into shapes') #Feeding empty compounds to FreeCAD seems to cause rendering issues, otherwise it would have been a good idea to output nothing. obj.Shape = Part.makeCompound(shapes)
def derivedExecute(self,obj): # cache stuff if lattice2BaseFeature.isObjectLattice(screen(obj.ShapeLink)): lattice2Executer.warning(obj,"ShapeLink points to a placement/array of placements. The placement/array will be reinterpreted as a generic shape; the results may be unexpected.") base = screen(obj.ShapeLink).Shape if obj.CompoundTraversal == "Use as a whole": baseChildren = [base] else: if base.ShapeType != 'Compound': base = Part.makeCompound([base]) if obj.CompoundTraversal == "Recursive": baseChildren = LCE.AllLeaves(base) else: baseChildren = base.childShapes() #cache mode comparisons, for speed posIsNone = obj.TranslateMode == '(none)' posIsParent = obj.TranslateMode == 'parent' posIsChild = obj.TranslateMode == 'child' posIsCenterM = obj.TranslateMode == 'child.CenterOfMass' posIsCenterBB = obj.TranslateMode == 'child.CenterOfBoundBox' posIsVertex = obj.TranslateMode == 'child.Vertex' oriIsNone = obj.OrientMode == '(none)' oriIsParent = obj.OrientMode == 'parent' oriIsChild = obj.OrientMode == 'child' oriIsInertial = obj.OrientMode == 'child.InertiaAxes' oriIsEdge = obj.OrientMode == 'child.Edge' oriIsFace = obj.OrientMode == 'child.FaceAxis' # initialize output containers and loop variables outputPlms = [] #list of placements # the essence for child in baseChildren: pos = App.Vector() ori = App.Rotation() if posIsNone: pass elif posIsParent: pos = base.Placement.Base elif posIsChild: pos = child.Placement.Base elif posIsCenterM: leaves = LCE.AllLeaves(child) totalW = 0 weightAttrib = {"Vertex":"", "Edge":"Length", "Wire":"Length", "Face":"Area", "Shell":"Area", "Solid":"Volume", "CompSolid":""}[leaves[0].ShapeType] #Center of mass of a compound is a weghted average of centers # of mass of individual objects. for leaf in leaves: w = 1.0 if not weightAttrib else (getattr(leaf, weightAttrib)) if leaf.ShapeType == 'Vertex': leafCM = leaf.Point #elif child.ShapeType == 'CompSolid': #todo else: leafCM = leaf.CenterOfMass pos += leafCM * w totalW += w pos = pos * (1.0/totalW) elif posIsCenterBB: import lattice2BoundBox bb = lattice2BoundBox.getPrecisionBoundBox(child) pos = bb.Center elif posIsVertex: v = child.Vertexes[obj.TranslateElementIndex - 1] pos = v.Point else: raise ValueError(obj.Name + ": translation mode not implemented: "+obj.TranslateMode) if oriIsNone: pass elif oriIsParent: ori = base.Placement.Rotation elif oriIsChild: ori = child.Placement.Rotation elif oriIsInertial: leaves = LCE.AllLeaves(child) if len(leaves)>1: raise ValueError(obj.Name + ": calculation of principal axes of compounds is not supported yet") props = leaves[0].PrincipalProperties XAx = props['FirstAxisOfInertia'] ZAx = props['ThirdAxisOfInertia'] ori = Utils.makeOrientationFromLocalAxes(ZAx, XAx) elif oriIsEdge: edge = child.Edges[obj.OrientElementIndex - 1] XAx = edge.Curve.tangent(edge.Curve.FirstParameter)[0] ori1 = Utils.makeOrientationFromLocalAxes(ZAx= XAx) ori2 = Utils.makeOrientationFromLocalAxes(ZAx= App.Vector(1,0,0),XAx= App.Vector(0,0,1)) ori = ori1.multiply(ori2) elif oriIsFace: face = child.Faces[obj.OrientElementIndex - 1] ZAx = face.Surface.Axis else: raise ValueError(obj.Name + ": orientation mode not implemented: "+obj.OrientMode) plm = App.Placement(pos, ori) outputPlms.append(plm) return outputPlms