def findbestmatchingrotation(r1): import FreeCAD vangl = \ (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 11.25, 12.0, 13.0, 14.0, 15.0, 16.0, (180.0/11.0), 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 22.5, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, (360.0/11.0), 33.0, 33.75, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0,(540.0/11.0), 50.0, 51.0, (360.0/7.0), 52.0, 53.0, 54.0, 55.0, 56.0, 56.25, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0,(720.0/11.0), 66.0, 67.0, 67.5, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 78.75, 79.0, 80.0, 81.0,(900.0/11.0), 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0,(1080.0/11.0), 99.0, 100.0, 101.0, 101.25, 102.0, (720.0/7.0), 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 112.0, 112.5, 113.0, 114.0, (1260.0/11), 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 123.75, 124.0, 125.0, 126.0, 127.0, 128.0, 129.0, 130.0,(1440.0/11.0), 131.0, 132.0, 133.0, 134.0, 135.0, 136.0, 137.0, 138.0, 139.0, 140.0, 141.0, 142.0, 143.0, 144.0, 145.0, 146.0, 146.25, 147.0, (1620.0/11.0), 148.0, 149.0, 150.0, 151.0, 152.0, 153.0, 154.0, (1080.0/7.0), 155.0, 156.0, 157.0, 157.5, 158.0, 159.0, 160.0, 161.0, 162.0, 163.0, (1800.0/11.0), 164.0, 165.0, 166.0, 167.0, 168.0, 168.75, 169.0, 170.0, 171.0, 172.0, 173.0, 174.0, 175.0, 176.0, 177.0,178.0, 179.0,180.0, -179.0, -178.0, -177.0, -176.0, -175.0, -174.0, -173.0, -172.0, -171.0, -170.0, -169.0, -168.75, -168.0, -167.0, -166.0, -165.0, -164.0, (-1800.0/11.0), -163.0, -162.0, -161.0, -160.0, -159.0, -158.0, -157.5, -157.0, -156.0, -155.0, (-1080.0/7.0), -154.0, -153.0, -152.0, -151.0, -150.0, -149.0, -148.0, (-1620.0/11.0), -147.0, -146.25, -146.0, -145.0, -144.0, -143.0, -142.0, -141.0, -140.0, -139.0,-138.0, -137.0, -136.0, -135.0, -134.0, -133.0, -132.0, -131.0, (-1440/11.0), -130.0, -129.0, -128.0,-127.0, -126.0, -125.0, -124.0, -123.75, -123.0, -122.0, -121.0, -120.0, -119.0, -118.0, -117.0, -116.0, -115.0,(-1260.0/11.0), -114.0, -113.0, -112.5, -112.0, -111.0, -110.0, -109.0, -108.0, -107.0, -106.0, -105.0,-104.0, -103.0,(-720.0/7.0), -102.0, -101.25, -101.0, -100.0, -99.0, (-1080.0/11.0), -98.0, -97.0, -96.0, -95.0, -94.0, -93.0, -92.0, -91.0, -90.0, -89.0, -88.0, -87.0, -86.0, -85.0, -84.0, -83.0, -82.0,(-900.0/11.0), -81.0, -80.0, -79.0, -78.75, -78.0, -77.0, -76.0, -75.0, -74.0, -73.0, -72.0, -71.0, -70.0, -69.0, -68.0, -67.5, -67.0, -66.0, (-720.0/11.0), -65.0, -64.0, -63.0, -62.0, -61.0, -60.0, -59.0, -58.0, -57.0, -56.25, -56.0, -55.0, -54.0, -53.0, -52.0,(-360.0/7.0), -51.0, -50.0, (-540.0/11.0), -49.0, -48.0, -47.0, -46.0, -45.0, -44.0, -43.0, -42.0, -41.0, -40.0, -39.0, -38.0, -37.0, -36.0, -35.0, -34.0, -33.75, -33.0,(-360.0/11.0), -32.0, -31.0, -30.0, -29.0, -28.0, -27.0, -26.0, -25.0, -24.0, -23.0, -22.5, -22.0, -21.0, -20.0, -19.0, -18.0, -17.0,(-180.0/11.0), -16.0, -15.0, -14.0, -13.0, -12.0, -11.25, -11.0, -10.0, -9.0, -8.0, -7.0, -6.0, -5.0, -4.0, -3.0, -2.0, -1.0) def tup2nvect(tup): """convert a tuple to a normalized vector""" v = FreeCAD.Vector(*tup) v.normalize() return v def wkaxes(): """well known axes for rotations""" vtupl = ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1), (-1, 1, 0), (-1, 0, 1), (0, 1, -1), (1, 1, 1), (1, 1, -1), (1, -1, 1), (-1, 1, 1)) return tuple(tup2nvect(tup) for tup in vtupl) bestrot = FreeCAD.Rotation() dangle = comparerotations(r1, bestrot) for axis in wkaxes(): for angle in vangl: for axissign in (1.0, -1.0): r2 = FreeCAD.Rotation(axis * axissign, angle) dangletest = comparerotations(r1, r2) if dangletest < dangle: bestrot = r2 dangle = dangletest return (bestrot, dangle)
def accept(self): # get FreeCAD object associated with nodes chosen. for nodeobjs in App.ActiveDocument.Nodes.Group: if nodeobjs.node_name == self.node1_box.currentText(): nodeobj1 = nodeobjs node1_lnk = App.ActiveDocument.getObjectsByLabel(nodeobjs.node_name.split("|")[0])[0] ''' # check if both nodes are not the same if nodeobj1.node_name == nodeobj2.node_name: mb = QtGui.QMessageBox() mb.setText("both nodes can not be the same") mb.exec() return ''' App.Console.PrintMessage(" Accept2: " +"\n") # find the position and rotation LCS objects for orientation matraces # node 1 position and rotation LCS posLCS1_str = self.node1_LCS_pos_box.currentText() rotLCS1_str = self.node1_LCS_rot_box.currentText() linkedobj1 = node1_lnk.getLinkedObject() for linkedsub in linkedobj1.getSubObjects(): if linkedobj1.getObject(linkedsub[0:-1]).Label == posLCS1_str: posLCS1 = linkedobj1.getObject(linkedsub[0:-1]) if linkedobj1.getObject(linkedsub[0:-1]).Label == rotLCS1_str: rotLCS1 = linkedobj1.getObject(linkedsub[0:-1]) # fixed position and rotation LCS posLCSf_str = self.fixed_LCS_pos_box.currentText() rotLCSf_str = self.fixed_LCS_rot_box.currentText() modelobj = App.ActiveDocument.Model for modsub in modelobj.getSubObjects(): if modelobj.getObject(modsub[0:-1]).Label == posLCSf_str: posLCSf = modelobj.getObject(modsub[0:-1]) if modelobj.getObject(modsub[0:-1]).Label == rotLCSf_str: rotLCSf = modelobj.getObject(modsub[0:-1]) App.Console.PrintMessage(" Accept3: " + rotLCSf.Name +"\n") # get placements for node 1 position and rotation LCSs posLCS1_pl = node1_lnk.Placement.multiply(posLCS1.Placement) rotLCS1_pl = node1_lnk.Placement.multiply(rotLCS1.Placement) App.Console.PrintMessage(" orient2 "+posLCSf.Name) # make FreeCAD placement matrix from node1 position and orientation matrix if nodeobj1.orientation_des == 'euler321': rotz = App.Units.parseQuantity("(180/pi)*" + str(nodeobj1.orientation[0][0])) roty = App.Units.parseQuantity("(180/pi)*" + str(nodeobj1.orientation[0][1])) rotx = App.Units.parseQuantity("(180/pi)*" + str(nodeobj1.orientation[0][2])) node1_pl = App.Placement(nodeobj1.position, App.Rotation(rotz, roty, rotx)) App.Console.PrintMessage(" orient1: " + str(node1_pl)) node1_pl_inv = node1_pl.inverse() App.Console.PrintMessage(" orient2") # get placements for fixed position and rotation LCSs posLCSf_pl = posLCSf.Placement rotLCSf_pl = rotLCSf.Placement # create joint object num_joints = len(App.ActiveDocument.Joints.getSubObjects()) + 1 new_joint = App.ActiveDocument.Joints.newObject("App::FeaturePython","Joint" + str(num_joints)) MBDyn_objects.MBDynJoints.FC_totalpinjoint(new_joint) new_joint.ViewObject.Proxy = 0 new_joint.joint_label = num_joints # set node1 joint parameters new_joint.node1_label = nodeobj1.node_label rel_posLCS1_pl = node1_pl_inv.multiply(posLCS1_pl) rel_rotLCS1_pl = node1_pl_inv.multiply(rotLCS1_pl) App.Console.PrintMessage(" orient4: "+str(rel_rotLCS1_pl)) # new_joint.position1 = linkLCS1_pos - node1_pl_inv.multVec(nodeobj1.position) new_joint.position1 = rel_posLCS1_pl.Base new_joint.pos_orientation_des1 = 'xy' new_joint.pos_orientation1 = [App.Vector(rel_posLCS1_pl.Matrix.A11, rel_posLCS1_pl.Matrix.A21, rel_posLCS1_pl.Matrix.A31), App.Vector(rel_posLCS1_pl.Matrix.A12, rel_posLCS1_pl.Matrix.A22, rel_posLCS1_pl.Matrix.A32), App.Vector(0,0,0)] new_joint.rot_orientation_des1 = 'xy' new_joint.rot_orientation1 = [App.Vector(rel_rotLCS1_pl.Matrix.A11, rel_rotLCS1_pl.Matrix.A21, rel_rotLCS1_pl.Matrix.A31), App.Vector(rel_rotLCS1_pl.Matrix.A12, rel_rotLCS1_pl.Matrix.A22, rel_rotLCS1_pl.Matrix.A32), App.Vector(0,0,0)] # set fixed joint parameters new_joint.positionf = posLCSf_pl.Base new_joint.pos_orientation_desf = 'xy' new_joint.pos_orientationf = [App.Vector(posLCSf_pl.Matrix.A11, posLCSf_pl.Matrix.A21, posLCSf_pl.Matrix.A31), App.Vector(posLCSf_pl.Matrix.A12, posLCSf_pl.Matrix.A22, posLCSf_pl.Matrix.A32), App.Vector(0,0,0)] new_joint.rot_orientation_desf = 'xy' new_joint.rot_orientationf = [App.Vector(rotLCSf_pl.Matrix.A11, rotLCSf_pl.Matrix.A21, rotLCSf_pl.Matrix.A31), App.Vector(rotLCSf_pl.Matrix.A12, rotLCSf_pl.Matrix.A22, rotLCSf_pl.Matrix.A32), App.Vector(0,0,0)] # set position and rotation constraints from check boxes. new_joint.pos_constraint = [self.posx_checkBox.isChecked(), self.posy_checkBox.isChecked(), self.posz_checkBox.isChecked()] new_joint.rot_constraint = [self.rotx_checkBox.isChecked(), self.roty_checkBox.isChecked(), self.rotz_checkBox.isChecked()] new_joint.vel_constraint = [self.velx_checkBox.isChecked(), self.vely_checkBox.isChecked(), self.velz_checkBox.isChecked()] new_joint.angvel_constraint = [self.angvelx_checkBox.isChecked(), self.angvely_checkBox.isChecked(), self.angvelz_checkBox.isChecked()] self.done(1)
def center(obj,x,y,z): obj.Placement = FreeCAD.Placement(\ FreeCAD.Vector(-x/2.0,-y/2.0,-z/2.0),\ FreeCAD.Rotation(0,0,0,1))
def make_arc_3points(points, placement=None, face=False, support=None, map_mode="Deactivated", primitive=False): """Draw a circular arc defined by three points in the circumference. Parameters ---------- points: list of Base::Vector3 A list that must be three points. placement: Base::Placement, optional It defaults to `None`. It is a placement, comprised of a `Base` (`Base::Vector3`), and a `Rotation` (`Base::Rotation`). If it exists it moves the center of the new object to the point indicated by `placement.Base`, while `placement.Rotation` is ignored so that the arc keeps the same orientation with which it was created. If both `support` and `placement` are given, `placement.Base` is used for the `AttachmentOffset.Base`, and again `placement.Rotation` is ignored. face: bool, optional It defaults to `False`. If it is `True` it will create a face in the closed arc. Otherwise only the circumference edge will be shown. support: App::PropertyLinkSubList, optional It defaults to `None`. It is a list containing tuples to define the attachment of the new object. A tuple in the list needs two elements; the first is an external object, and the second is another tuple with the names of sub-elements on that external object likes vertices or faces. :: support = [(obj, ("Face1"))] support = [(obj, ("Vertex1", "Vertex5", "Vertex8"))] This parameter sets the `Support` property but it only really affects the position of the new object when the `map_mode` is set to other than `'Deactivated'`. map_mode: str, optional It defaults to `'Deactivated'`. It defines the type of `'MapMode'` of the new object. This parameter only works when a `support` is also provided. Example: place the new object on a face or another object. :: support = [(obj, ("Face1"))] map_mode = 'FlatFace' Example: place the new object on a plane created by three vertices of an object. :: support = [(obj, ("Vertex1", "Vertex5", "Vertex8"))] map_mode = 'ThreePointsPlane' primitive: bool, optional It defaults to `False`. If it is `True`, it will create a Part primitive instead of a Draft object. In this case, `placement`, `face`, `support`, and `map_mode` are ignored. Returns ------- Part::Part2DObject or Part::Feature The new arc object. Normally it returns a parametric Draft object (`Part::Part2DObject`). If `primitive` is `True`, it returns a basic `Part::Feature`. None Returns `None` if there is a problem and the object cannot be created. """ _name = "make_arc_3points" utils.print_header(_name, "Arc by 3 points") try: utils.type_check([(points, (list, tuple))], name=_name) except TypeError: _err(translate("draft", "Points:") + " {}".format(points)) _err( translate( "draft", "Wrong input: must be list or tuple of three points exactly.")) return None if len(points) != 3: _err(translate("draft", "Points:") + " {}".format(points)) _err( translate( "draft", "Wrong input: must be list or tuple of three points exactly.")) return None if placement is not None: try: utils.type_check([(placement, App.Placement)], name=_name) except TypeError: _err(translate("draft", "Placement:") + " {}".format(placement)) _err( translate("draft", "Wrong input: incorrect type of placement.")) return None p1, p2, p3 = points _msg("p1: {}".format(p1)) _msg("p2: {}".format(p2)) _msg("p3: {}".format(p3)) try: utils.type_check([(p1, App.Vector), (p2, App.Vector), (p3, App.Vector)], name=_name) except TypeError: _err(translate("draft", "Wrong input: incorrect type of points.")) return None try: _edge = Part.Arc(p1, p2, p3) except Part.OCCError as error: _err( translate("draft", "Cannot generate shape:") + " " + "{}".format(error)) return None edge = _edge.toShape() radius = edge.Curve.Radius center = edge.Curve.Center _msg(translate("draft", "Radius:") + " " + "{}".format(radius)) _msg(translate("draft", "Center:") + " " + "{}".format(center)) if primitive: _msg(translate("draft", "Create primitive object")) obj = App.ActiveDocument.addObject("Part::Feature", "Arc") obj.Shape = edge return obj rot = App.Rotation(edge.Curve.XAxis, edge.Curve.YAxis, edge.Curve.Axis, "ZXY") _placement = App.Placement(center, rot) start = edge.FirstParameter end = math.degrees(edge.LastParameter) obj = Draft.makeCircle(radius, placement=_placement, face=face, startangle=start, endangle=end, support=support) if App.GuiUp: gui_utils.autogroup(obj) original_placement = obj.Placement if placement and not support: obj.Placement.Base = placement.Base _msg( translate("draft", "Final placement:") + " " + "{}".format(obj.Placement)) if face: _msg(translate("draft", "Face: True")) if support: _msg(translate("draft", "Support:") + " " + "{}".format(support)) _msg(translate("draft", "Map mode:") + " " + "{}".format(map_mode)) obj.MapMode = map_mode if placement: obj.AttachmentOffset.Base = placement.Base obj.AttachmentOffset.Rotation = original_placement.Rotation _msg( translate("draft", "Attachment offset: {}".format( obj.AttachmentOffset))) _msg( translate("draft", "Final placement:") + " " + "{}".format(obj.Placement)) return obj
def execute(self, obj): if self.clone(obj): return if not obj.Base: return if not obj.Base.Shape: return if not obj.Base.Shape.Wires: return if not obj.Diameter.Value: return if not obj.Amount: return father = obj.Host fathershape = None if not father: # support for old-style rebars if obj.InList: if hasattr(obj.InList[0], "Armatures"): if obj in obj.InList[0].Armatures: father = obj.InList[0] if father: if father.isDerivedFrom("Part::Feature"): fathershape = father.Shape wire = obj.Base.Shape.Wires[0] if hasattr(obj, "Rounding"): #print(obj.Rounding) if obj.Rounding: radius = obj.Rounding * obj.Diameter.Value import DraftGeomUtils wire = DraftGeomUtils.filletWire(wire, radius) bpoint, bvec = self.getBaseAndAxis(wire) if not bpoint: return axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1)) if fathershape: size = (ArchCommands.projectToVector(fathershape.copy(), axis)).Length else: size = 1 if hasattr(obj, "Direction"): if not DraftVecUtils.isNull(obj.Direction): axis = FreeCAD.Vector(obj.Direction) axis.normalize() if fathershape: size = (ArchCommands.projectToVector( fathershape.copy(), axis)).Length else: size = 1 if hasattr(obj, "Distance"): if obj.Distance.Value: size = obj.Distance.Value spacinglist = None if hasattr(obj, "CustomSpacing"): if obj.CustomSpacing: spacinglist = strprocessOfCustomSpacing(obj.CustomSpacing) influenceArea = sum( spacinglist) - spacinglist[0] / 2 - spacinglist[-1] / 2 if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size: return # all tests ok! if hasattr(obj, "Length"): length = getLengthOfRebar(obj) if length: obj.Length = length pl = obj.Placement import Part circle = Part.makeCircle(obj.Diameter.Value / 2, bpoint, bvec) circle = Part.Wire(circle) try: bar = wire.makePipeShell([circle], True, False, 2) basewire = wire.copy() except Part.OCCError: print("Arch: error sweeping rebar profile along the base sketch") return # building final shape shapes = [] placementlist = [] self.wires = [] rot = FreeCAD.Rotation() if obj.Amount == 1: barplacement = CalculatePlacement(obj.Amount, 1, obj.Diameter.Value, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value, obj.ViewObject.RebarShape) placementlist.append(barplacement) if hasattr(obj, "Spacing"): obj.Spacing = 0 else: if obj.OffsetStart.Value: baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value) else: baseoffset = None if obj.ViewObject.RebarShape == "Stirrup": interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value + obj.Diameter.Value) else: interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value) interval = interval / (obj.Amount - 1) for i in range(obj.Amount): barplacement = CalculatePlacement(obj.Amount, i + 1, obj.Diameter.Value, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value, obj.ViewObject.RebarShape) placementlist.append(barplacement) if hasattr(obj, "Spacing"): obj.Spacing = interval # Calculate placement of bars from custom spacing. if spacinglist: placementlist[:] = [] if obj.ViewObject.RebarShape == "Stirrup": reqInfluenceArea = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value + obj.Diameter.Value) else: reqInfluenceArea = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value) # Avoid unnecessary checks to pass like. For eg.: when we have values # like influenceArea is 100.00001 and reqInflueneArea is 100 if round(influenceArea) > round(reqInfluenceArea): FreeCAD.Console.PrintWarning( "Influence area of rebars is greater than " + str(reqInfluenceArea) + ".\n") elif round(influenceArea) < round(reqInfluenceArea): FreeCAD.Console.PrintWarning( "Last span is greater that end offset.\n") for i in range(len(spacinglist)): if i == 0: barplacement = CustomSpacingPlacement( spacinglist, 1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value) placementlist.append(barplacement) else: barplacement = CustomSpacingPlacement( spacinglist, i + 1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value) placementlist.append(barplacement) obj.Amount = len(spacinglist) obj.Spacing = 0 obj.PlacementList = placementlist for i in range(len(obj.PlacementList)): if i == 0: bar.Placement = obj.PlacementList[i] shapes.append(bar) basewire.Placement = obj.PlacementList[i] self.wires.append(basewire) else: bar = bar.copy() bar.Placement = obj.PlacementList[i] shapes.append(bar) w = basewire.copy() w.Placement = obj.PlacementList[i] self.wires.append(w) if shapes: obj.Shape = Part.makeCompound(shapes) obj.Placement = pl obj.TotalLength = obj.Length * len(obj.PlacementList)
def doElbow(propList=['DN50',60.3,3,90,45.225], pypeline=None): ''' propList = [ DN (string): nominal diameter OD (float): outside diameter thk (float): shell thickness BA (float): bend angle BR (float): bend radius ] pypeline = string ''' elist=[] FreeCAD.activeDocument().openTransaction('Insert elbow') selex=FreeCADGui.Selection.getSelectionEx() if len(selex)==0: # no selection -> insert one elbow at origin elist.append(makeElbow(propList)) elif len(selex)==1 and len(selex[0].SubObjects)==1: #one selection -> ... if selex[0].SubObjects[0].ShapeType=="Vertex": # ...on vertex elist.append(makeElbow(propList,selex[0].SubObjects[0].Point)) elif selex[0].SubObjects[0].ShapeType=="Edge" and selex[0].SubObjects[0].curvatureAt(0)!=0: # ...on center of curved edge P=selex[0].SubObjects[0].centerOfCurvatureAt(0) N=selex[0].SubObjects[0].normalAt(0).cross(selex[0].SubObjects[0].tangentAt(0)).normalize() elb=makeElbow(propList,P) if isPipe(selex[0].Object): #..on the edge of a pipe ax=selex[0].Object.Shape.Solids[0].CenterOfMass-P rot=FreeCAD.Rotation(elb.Ports[0],ax) elb.Placement.Rotation=rot.multiply(elb.Placement.Rotation) Port0=getElbowPort(elb) elb.Placement.move(P-Port0) elif isElbow(selex[0].Object): #..on the edge of an elbow p0,p1=[selex[0].Object.Placement.Rotation.multVec(p) for p in selex[0].Object.Ports] if fCmd.isParallel(p0,N): elb.Placement.Rotation=FreeCAD.Rotation(elb.Ports[0],p0*-1) else: elb.Placement.Rotation=FreeCAD.Rotation(elb.Ports[0],p1*-1) delta=getElbowPort(elb) elb.Placement.move(P-delta) else: #..on any other curved edge print('hello') rot=FreeCAD.Rotation(elb.Ports[0],N) elb.Placement.Rotation=rot.multiply(elb.Placement.Rotation) # elb.Placement.move(elb.Placement.Rotation.multVec(elb.Ports[0])*-1) v=portsDir(elb)[0].negative()*elb.Ports[0].Length elb.Placement.move(v) elist.append(elb) FreeCAD.activeDocument().recompute() else: # multiple selection -> insert one elbow at intersection of two edges or beams or pipes ## things=[] for objEx in selex: if len(fCmd.beams([objEx.Object]))==1: # if the object is a beam or pipe, append it to the "things".. things.append(objEx.Object) else: # ..else append its edges for edge in fCmd.edges([objEx]): things.append(edge) if len(things)>=2: break try: #create the feature elb=elist.append(makeElbowBetweenThings(*things[:2],propList=propList)) except: FreeCAD.Console.PrintError('Creation of elbow is failed\n') if pypeline: for e in elist: moveToPyLi(e,pypeline) FreeCAD.activeDocument().commitTransaction() FreeCAD.activeDocument().recompute() return elist
def CreateFromTemplate(job, template): if template.get('version') and 1 == int(template['version']): stockType = template.get('create') if stockType: placement = None posX = template.get('posX') posY = template.get('posY') posZ = template.get('posZ') rotX = template.get('rotX') rotY = template.get('rotY') rotZ = template.get('rotZ') rotW = template.get('rotW') if posX is not None and posY is not None and posZ is not None and rotX is not None and rotY is not None and rotZ is not None and rotW is not None: pos = FreeCAD.Vector(float(posX), float(posY), float(posZ)) rot = FreeCAD.Rotation(float(rotX), float(rotY), float(rotZ), float(rotW)) placement = FreeCAD.Placement(pos, rot) elif posX is not None or posY is not None or posZ is not None or rotX is not None or rotY is not None or rotZ is not None or rotW is not None: PathLog.warning( translate( 'PathStock', 'Corrupted or incomplete placement information in template - ignoring' )) if stockType == StockType.FromBase: xneg = template.get('xneg') xpos = template.get('xpos') yneg = template.get('yneg') ypos = template.get('ypos') zneg = template.get('zneg') zpos = template.get('zpos') neg = None pos = None if xneg is not None and xpos is not None and yneg is not None and ypos is not None and zneg is not None and zpos is not None: neg = FreeCAD.Vector( FreeCAD.Units.Quantity(xneg).Value, FreeCAD.Units.Quantity(yneg).Value, FreeCAD.Units.Quantity(zneg).Value) pos = FreeCAD.Vector( FreeCAD.Units.Quantity(xpos).Value, FreeCAD.Units.Quantity(ypos).Value, FreeCAD.Units.Quantity(zpos).Value) elif xneg is not None or xpos is not None or yneg is not None or ypos is not None or zneg is not None or zpos is not None: PathLog.error( translate( 'PathStock', 'Corrupted or incomplete specification for creating stock from base - ignoring extent' )) return CreateFromBase(job, neg, pos, placement) if stockType == StockType.CreateBox: length = template.get('length') width = template.get('width') height = template.get('height') extent = None if length is not None and width is not None and height is not None: extent = FreeCAD.Vector( FreeCAD.Units.Quantity(length).Value, FreeCAD.Units.Quantity(width).Value, FreeCAD.Units.Quantity(height).Value) elif length is not None or width is not None or height is not None: PathLog.error( translate( 'PathStock', 'Corrupted or incomplete size for creating a stock box - ignoring size' )) return CreateBox(job, extent, placement) if stockType == StockType.CreateCylinder: radius = template.get('radius') height = template.get('height') if radius is not None and height is not None: pass elif radius is not None or height is not None: radius = None height = None PathLog.error( translate( 'PathStock', 'Corrupted or incomplete size for creating a stock cylinder - ignoring size' )) return CreateCylinder(job, radius, height, placement) PathLog.error( translate('PathStock', 'Unsupported stock type named {}').format(stockType)) else: PathLog.error( translate('PathStock', 'Unsupported PathStock template version {}').format( template.get('version'))) return None
def testMatrix(self): ''' Test Matrix/Vector/Placement/Rotation operations''' def plm_equal(plm1, plm2): from math import sqrt qpair = zip(plm1.Rotation.Q, plm2.Rotation.Q) qdiff1 = sqrt(sum([(v1 - v2)**2 for v1, v2 in qpair])) qdiff2 = sqrt(sum([(v1 + v2)**2 for v1, v2 in qpair])) return (plm1.Base - plm2.Base).Length < 1e-7 and (qdiff1 < 1e-12 or dqiff2 < 1e-12) sheet = self.doc.addObject('Spreadsheet::Sheet', 'Spreadsheet') mat = FreeCAD.Matrix() mat.scale(2, 1, 2) imat = mat.inverse() vec = FreeCAD.Vector(2, 1, 2) rot = FreeCAD.Rotation(FreeCAD.Vector(0, 1, 0), 45) irot = rot.inverted() pla = FreeCAD.Placement(vec, rot) ipla = pla.inverse() sheet.set('A1', '=create(<<vector>>, 2, 1, 2)') # different ways of calling mscale() sheet.set('B1', '=mscale(create(<<matrix>>), A1)') sheet.set('C1', '=mscale(create(<<matrix>>), tuple(2, 1, 2))') sheet.set('A2', '=mscale(create(<<matrix>>), 2, 1, 2)') # test matrix power operation sheet.set('B2', '=A2^-2') sheet.set('C2', '=A2^-1') sheet.set('D2', '=A2^0') sheet.set('E2', '=A2^1') sheet.set('F2', '=A2^2') sheet.set( 'G2', '=create(<<matrix>>, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)' ) sheet.set('H2', '=G2^-1') sheet.set('A3', '=create(<<rotation>>, create(<<vector>>, 0, 1, 0), 45)') # test rotation power operation sheet.set('B3', '=A3^-2') sheet.set('C3', '=A3^-1') sheet.set('D3', '=A3^0') sheet.set('E3', '=A3^1') sheet.set('F3', '=A3^2') sheet.set('A4', '=create(<<placement>>, A1, A3)') # test placement power operation sheet.set('B4', '=A4^-2') sheet.set('C4', '=A4^-1') sheet.set('D4', '=A4^0') sheet.set('E4', '=A4^1') sheet.set('F4', '=A4^2') # vector transformation with mixing matrix and placement and rotation sheet.set('A5', '=A2*A3*A4*A1') sheet.set('B5', '=B2*B4*B3*A1') sheet.set('C5', '=C3*C2*C4*A1') sheet.set('D5', '=D3*D4*D2*A1') sheet.set('E5', '=E4*E2*E3*A1') sheet.set('F5', '=F3*F4*F2*A1') # inverse of the above transformation with power -1 and minvert() sheet.set('A6', '=A4^-1 * minvert(A3) * A2^-1 * A5') sheet.set('B6', '=minvert(B3) * B4^-1 * minvert(B2) * B5') sheet.set('C6', '=C4^-1 * C2^-1 * C3^-1 * C5') sheet.set('D6', '=minvert(D4*D2) * minvert(D3) * D5') sheet.set('E6', '=(E2 * E3)^-1 * E4^-1 * E5') sheet.set('F6', '=(F3*F4*F2)^-1 * F5') self.doc.recompute() self.assertEqual(sheet.A1, vec) self.assertEqual(sheet.B1, mat) self.assertEqual(sheet.C1, mat) self.assertEqual(sheet.A2, mat) self.assertEqual(sheet.B2, imat * imat) self.assertEqual(sheet.B2, mat**-2) self.assertEqual(sheet.C2, imat) self.assertEqual(sheet.C2, mat**-1) self.assertEqual(sheet.D2, FreeCAD.Matrix()) self.assertEqual(sheet.D2, mat**0) self.assertEqual(sheet.E2, mat) self.assertEqual(sheet.E2, mat**1) self.assertEqual(sheet.F2, mat * mat) self.assertEqual(sheet.F2, mat**2) self.assertTrue( sheet.H2.startswith(u'ERR: Cannot invert singular matrix')) self.assertEqual(sheet.A3, rot) rtol = 1e-12 self.assertTrue(sheet.B3.isSame(irot * irot, rtol)) self.assertTrue(sheet.B3.isSame(rot**-2, rtol)) self.assertTrue(sheet.C3.isSame(irot, rtol)) self.assertTrue(sheet.C3.isSame(rot**-1, rtol)) self.assertTrue(sheet.D3.isSame(FreeCAD.Rotation(), rtol)) self.assertTrue(sheet.D3.isSame(rot**0, rtol)) self.assertTrue(sheet.E3.isSame(rot, rtol)) self.assertTrue(sheet.E3.isSame(rot**1, rtol)) self.assertTrue(sheet.F3.isSame(rot * rot, rtol)) self.assertTrue(sheet.F3.isSame(rot**2, rtol)) self.assertEqual(sheet.A4, pla) self.assertTrue(plm_equal(sheet.B4, ipla * ipla)) self.assertTrue(plm_equal(sheet.B4, pla**-2)) self.assertTrue(plm_equal(sheet.C4, ipla)) self.assertTrue(plm_equal(sheet.C4, pla**-1)) self.assertTrue(plm_equal(sheet.D4, FreeCAD.Placement())) self.assertTrue(plm_equal(sheet.D4, pla**0)) self.assertTrue(plm_equal(sheet.E4, pla)) self.assertTrue(plm_equal(sheet.E4, pla**1)) self.assertTrue(plm_equal(sheet.F4, pla * pla)) self.assertTrue(plm_equal(sheet.F4, pla**2)) tol = 1e-10 self.assertLess( sheet.A5.distanceToPoint( sheet.A2.multiply(sheet.A3.Matrix).multiply( sheet.A4.Matrix).multVec(vec)), tol) self.assertLess( sheet.B5.distanceToPoint( sheet.B2.multiply(sheet.B4.Matrix).multiply( sheet.B3.Matrix).multVec(vec)), tol) self.assertLess( sheet.C5.distanceToPoint( sheet.C3.Matrix.multiply(sheet.C2).multiply( sheet.C4.Matrix).multVec(vec)), tol) self.assertLess( sheet.D5.distanceToPoint( sheet.D3.Matrix.multiply(sheet.D4.Matrix).multiply( sheet.D2).multVec(vec)), tol) self.assertLess( sheet.E5.distanceToPoint( sheet.E4.Matrix.multiply(sheet.E2).multiply( sheet.E3.Matrix).multVec(vec)), tol) self.assertLess( sheet.F5.distanceToPoint( sheet.F3.Matrix.multiply(sheet.F4.Matrix).multiply( sheet.F2).multVec(vec)), tol) self.assertLess(sheet.A6.distanceToPoint(vec), tol) self.assertLess(sheet.B6.distanceToPoint(vec), tol) self.assertLess(sheet.C6.distanceToPoint(vec), tol) self.assertLess(sheet.D6.distanceToPoint(vec), tol) self.assertLess(sheet.E6.distanceToPoint(vec), tol) self.assertLess(sheet.F6.distanceToPoint(vec), tol)
def createAdjustedLVandPV(obj, name, solidName, delta): # Allow for difference in placement between FreeCAD and GDML adjObj = obj rot = FreeCAD.Rotation(obj.Placement.Rotation) adjObj.Placement.move(rot.multVec(delta)) #.negative() createLVandPV(adjObj, name, solidName)
def make_sketch(objectslist, autoconstraints=False, addTo=None, delete=False, name="Sketch", radiusPrecision=-1): """makeSketch(objectslist,[autoconstraints],[addTo],[delete],[name],[radiusPrecision]) Makes a Sketch objectslist with the given Draft objects. Parameters ---------- objectlist: can be single or list of objects of Draft type objects, Part::Feature, Part.Shape, or mix of them. autoconstraints(False): if True, constraints will be automatically added to wire nodes, rectangles and circles. addTo(None) : if set to an existing sketch, geometry will be added to it instead of creating a new one. delete(False): if True, the original object will be deleted. If set to a string 'all' the object and all its linked object will be deleted name('Sketch'): the name for the new sketch object radiusPrecision(-1): If <0, disable radius constraint. If =0, add indiviaul radius constraint. If >0, the radius will be rounded according to this precision, and 'Equal' constraint will be added to curve with equal radius within precision. """ if not App.ActiveDocument: App.Console.PrintError("No active document. Aborting\n") return import Part from Sketcher import Constraint import Sketcher StartPoint = 1 EndPoint = 2 MiddlePoint = 3 deletable = None if not isinstance(objectslist, (list, tuple)): objectslist = [objectslist] for obj in objectslist: if isinstance(obj, Part.Shape): shape = obj elif not hasattr(obj, 'Shape'): App.Console.PrintError(translate("draft", "not shape found")) return None else: shape = obj.Shape if not DraftGeomUtils.isPlanar(shape): App.Console.PrintError( translate("draft", "All Shapes must be co-planar")) return None if addTo: nobj = addTo else: nobj = App.ActiveDocument.addObject("Sketcher::SketchObject", name) deletable = nobj if App.GuiUp: nobj.ViewObject.Autoconstraints = False # Collect constraints and add in one go to improve performance constraints = [] radiuses = {} def addRadiusConstraint(edge): try: if radiusPrecision < 0: return if radiusPrecision == 0: constraints.append( Constraint('Radius', nobj.GeometryCount - 1, edge.Curve.Radius)) return r = round(edge.Curve.Radius, radiusPrecision) constraints.append( Constraint('Equal', radiuses[r], nobj.GeometryCount - 1)) except KeyError: radiuses[r] = nobj.GeometryCount - 1 constraints.append(Constraint('Radius', nobj.GeometryCount - 1, r)) except AttributeError: pass def convertBezier(edge): if DraftGeomUtils.geomType(edge) == "BezierCurve": return (edge.Curve.toBSpline(edge.FirstParameter, edge.LastParameter).toShape()) else: return (edge) rotation = None for obj in objectslist: ok = False tp = utils.get_type(obj) if tp in ["Circle", "Ellipse"]: if obj.Shape.Edges: if rotation is None: rotation = obj.Placement.Rotation edge = obj.Shape.Edges[0] if len(edge.Vertexes) == 1: newEdge = DraftGeomUtils.orientEdge(edge) nobj.addGeometry(newEdge) else: # make new ArcOfCircle circle = DraftGeomUtils.orientEdge(edge) angle = edge.Placement.Rotation.Angle axis = edge.Placement.Rotation.Axis circle.Center = DraftVecUtils.rotate( edge.Curve.Center, -angle, axis) first = math.radians(obj.FirstAngle) last = math.radians(obj.LastAngle) arc = Part.ArcOfCircle(circle, first, last) nobj.addGeometry(arc) addRadiusConstraint(edge) ok = True elif tp == "Rectangle": if rotation is None: rotation = obj.Placement.Rotation if obj.FilletRadius.Value == 0: for edge in obj.Shape.Edges: nobj.addGeometry(DraftGeomUtils.orientEdge(edge)) if autoconstraints: last = nobj.GeometryCount - 1 segs = [last - 3, last - 2, last - 1, last] if obj.Placement.Rotation.Q == (0, 0, 0, 1): constraints.append( Constraint("Coincident", last - 3, EndPoint, last - 2, StartPoint)) constraints.append( Constraint("Coincident", last - 2, EndPoint, last - 1, StartPoint)) constraints.append( Constraint("Coincident", last - 1, EndPoint, last, StartPoint)) constraints.append( Constraint("Coincident", last, EndPoint, last - 3, StartPoint)) constraints.append(Constraint("Horizontal", last - 3)) constraints.append(Constraint("Vertical", last - 2)) constraints.append(Constraint("Horizontal", last - 1)) constraints.append(Constraint("Vertical", last)) ok = True elif tp in ["Wire", "Polygon"]: if obj.FilletRadius.Value == 0: closed = False if tp == "Polygon": closed = True elif hasattr(obj, "Closed"): closed = obj.Closed if obj.Shape.Edges: if (len(obj.Shape.Vertexes) < 3): e = obj.Shape.Edges[0] nobj.addGeometry( Part.LineSegment(e.Curve, e.FirstParameter, e.LastParameter)) else: # Use the first three points to make a working plane. We've already # checked to make sure everything is coplanar plane = Part.Plane( *[i.Point for i in obj.Shape.Vertexes[:3]]) normal = plane.Axis if rotation is None: axis = App.Vector(0, 0, 1).cross(normal) angle = DraftVecUtils.angle( normal, App.Vector(0, 0, 1)) * App.Units.Radian rotation = App.Rotation(axis, angle) for edge in obj.Shape.Edges: # edge.rotate(App.Vector(0,0,0), rotAxis, rotAngle) edge = DraftGeomUtils.orientEdge(edge, normal) nobj.addGeometry(edge) if autoconstraints: last = nobj.GeometryCount segs = list( range(last - len(obj.Shape.Edges), last - 1)) for seg in segs: constraints.append( Constraint("Coincident", seg, EndPoint, seg + 1, StartPoint)) if DraftGeomUtils.isAligned( nobj.Geometry[seg], "x"): constraints.append( Constraint("Vertical", seg)) elif DraftGeomUtils.isAligned( nobj.Geometry[seg], "y"): constraints.append( Constraint("Horizontal", seg)) if closed: constraints.append( Constraint("Coincident", last - 1, EndPoint, segs[0], StartPoint)) ok = True elif tp == "BSpline": if obj.Shape.Edges: nobj.addGeometry(obj.Shape.Edges[0].Curve) nobj.exposeInternalGeometry(nobj.GeometryCount - 1) ok = True elif tp == "BezCurve": if obj.Shape.Edges: bez = obj.Shape.Edges[0].Curve bsp = bez.toBSpline(bez.FirstParameter, bez.LastParameter) nobj.addGeometry(bsp) nobj.exposeInternalGeometry(nobj.GeometryCount - 1) ok = True elif tp == 'Shape' or hasattr(obj, 'Shape'): shape = obj if tp == 'Shape' else obj.Shape if not DraftGeomUtils.isPlanar(shape): App.Console.PrintError( translate( "draft", "The given object is not planar and cannot be converted into a sketch." )) return None if rotation is None: #rotation = obj.Placement.Rotation norm = DraftGeomUtils.getNormal(shape) if norm: rotation = App.Rotation(App.Vector(0, 0, 1), norm) else: App.Console.PrintWarning( translate( "draft", "Unable to guess the normal direction of this object" )) rotation = App.Rotation() norm = obj.Placement.Rotation.Axis if not shape.Wires: for e in shape.Edges: # unconnected edges newedge = convertBezier(e) nobj.addGeometry( DraftGeomUtils.orientEdge(newedge, norm, make_arc=True)) addRadiusConstraint(newedge) # if not addTo: # nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(shape).Rotation if autoconstraints: for wire in shape.Wires: last_count = nobj.GeometryCount edges = wire.OrderedEdges for edge in edges: newedge = convertBezier(edge) nobj.addGeometry( DraftGeomUtils.orientEdge(newedge, norm, make_arc=True)) addRadiusConstraint(newedge) for i, g in enumerate(nobj.Geometry[last_count:]): if edges[i].Closed: continue seg = last_count + i if DraftGeomUtils.isAligned(g, "x"): constraints.append(Constraint("Vertical", seg)) elif DraftGeomUtils.isAligned(g, "y"): constraints.append(Constraint("Horizontal", seg)) if seg == nobj.GeometryCount - 1: if not wire.isClosed(): break g2 = nobj.Geometry[last_count] seg2 = last_count else: seg2 = seg + 1 g2 = nobj.Geometry[seg2] end1 = g.value(g.LastParameter) start2 = g2.value(g2.FirstParameter) if DraftVecUtils.equals(end1, start2): constraints.append( Constraint("Coincident", seg, EndPoint, seg2, StartPoint)) continue end2 = g2.value(g2.LastParameter) start1 = g.value(g.FirstParameter) if DraftVecUtils.equals(end2, start1): constraints.append( Constraint("Coincident", seg, StartPoint, seg2, EndPoint)) elif DraftVecUtils.equals(start1, start2): constraints.append( Constraint("Coincident", seg, StartPoint, seg2, StartPoint)) elif DraftVecUtils.equals(end1, end2): constraints.append( Constraint("Coincident", seg, EndPoint, seg2, EndPoint)) else: for wire in shape.Wires: for edge in wire.OrderedEdges: newedge = convertBezier(edge) nobj.addGeometry( DraftGeomUtils.orientEdge(newedge, norm, make_arc=True)) ok = True format_object(nobj, obj) if ok and delete and hasattr(obj, 'Shape'): doc = obj.Document def delObj(obj): if obj.InList: App.Console.PrintWarning( translate( "draft", "Cannot delete object {} with dependency". format(obj.Label)) + "\n") else: doc.removeObject(obj.Name) try: if delete == 'all': objs = [obj] while objs: obj = objs[0] objs = objs[1:] + obj.OutList delObj(obj) else: delObj(obj) except Exception as ex: App.Console.PrintWarning( translate( "draft", "Failed to delete object {}: {}".format( obj.Label, ex)) + "\n") if rotation: nobj.Placement.Rotation = rotation else: print("-----error!!! rotation is still None...") nobj.addConstraint(constraints) return nobj
def accept(self): if self.form.groupNewDocument.isChecked() or (FreeCAD.ActiveDocument == None): doc = FreeCAD.newDocument() if self.form.projectName.text(): doc.Label = self.form.projectName.text() FreeCAD.ActiveDocument = doc if not FreeCAD.ActiveDocument: FreeCAD.Console.PrintError("No active document, aborting.\n") import Draft,Arch site = None outline = None if self.form.groupSite.isChecked(): site = Arch.makeSite() site.Label = self.form.siteName.text() site.Address = self.form.siteAddress.text() site.Longitude = self.form.siteLongitude.value() site.Latitude = self.form.siteLatitude.value() if hasattr(site,"NorthDeviation"): site.NorthDeviation = self.form.siteDeviation.value() elif hasattr(site,"Declination"): site.Declination = self.form.siteDeviation.value() site.Elevation = FreeCAD.Units.Quantity(self.form.siteElevation.text()).Value if self.form.groupBuilding.isChecked(): building = Arch.makeBuilding() if site: site.Group = [building] building.Label = self.form.buildingName.text() building.BuildingType = self.form.buildingUse.currentText() buildingWidth = FreeCAD.Units.Quantity(self.form.buildingWidth.text()).Value buildingLength = FreeCAD.Units.Quantity(self.form.buildingLength.text()).Value distVAxes = FreeCAD.Units.Quantity(self.form.distVAxes.text()).Value distHAxes = FreeCAD.Units.Quantity(self.form.distHAxes.text()).Value levelHeight = FreeCAD.Units.Quantity(self.form.levelHeight.text()).Value color = self.form.lineColor.property("color").getRgbF()[:3] if buildingWidth and buildingLength: outline = Draft.makeRectangle(buildingLength,buildingWidth,face=False) outline.Label = "Building Outline" outline.ViewObject.DrawStyle = "Dashed" outline.ViewObject.LineColor = color outline.ViewObject.LineWidth = self.form.lineWidth.value()*2 grp = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup") grp.Label = "Layout" building.addObject(grp) grp.addObject(outline) if self.form.buildingName.text(): outtext = Draft.makeText([self.form.buildingName.text()],point=FreeCAD.Vector(Draft.getParam("textheight",0.20)*0.3,-Draft.getParam("textheight",0.20)*1.43,0)) outtext.Label = "Building Label" outtext.ViewObject.TextColor = color grp.addObject(outtext) axisV = None if self.form.countVAxes.value() and distVAxes: axisV = Arch.makeAxis(num = self.form.countVAxes.value(), size = distVAxes, name="vaxis") axisV.Label = "Vertical Axes" axisV.ViewObject.BubblePosition = "Both" axisV.ViewObject.LineWidth = self.form.lineWidth.value() axisV.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisV.ViewObject.BubbleSize = Draft.getParam("textheight",0.20)*1.43 axisV.ViewObject.LineColor = color if outline: axisV.setExpression('Length', outline.Name+'.Height * 1.1') axisV.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y - '+axisV.Name+'.Length * 0.05') axisV.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x') axisH = None if self.form.countHAxes.value() and distHAxes: axisH = Arch.makeAxis(num = self.form.countHAxes.value(), size = distHAxes, name="haxis") axisH.Label = "Horizontal Axes" axisH.ViewObject.BubblePosition = "Both" axisH.ViewObject.NumberingStyle = "A,B,C" axisH.ViewObject.LineWidth = self.form.lineWidth.value() axisH.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisH.ViewObject.BubbleSize = Draft.getParam("textheight",0.20)*1.43 axisH.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),90) axisH.ViewObject.LineColor = color if outline: axisH.setExpression('Length', outline.Name+'.Length * 1.1') axisH.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x + '+axisH.Name+'.Length * 0.945') axisH.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y') if axisV and axisH: axisG = Arch.makeAxisSystem([axisH,axisV]) axisG.Label = "Axes" grp.addObject(axisG) else: if axisV: grp.addObject(axisV) if axisH: grp.addObject(axisH) if self.form.countLevels.value() and levelHeight: h = 0 alabels = [] for i in range(self.form.countLevels.value()): lev = Arch.makeFloor() lev.Label = "Level "+str(i) alabels.append(lev.Label) lev.Height = levelHeight lev.Placement.move(FreeCAD.Vector(0,0,h)) h += levelHeight building.addObject(lev) if self.form.levelsWP.isChecked(): prx = Draft.makeWorkingPlaneProxy(FreeCAD.Placement()) prx.Placement.move(FreeCAD.Vector(0,0,h)) lev.addObject(prx) if self.form.levelsAxis.isChecked(): axisL = Arch.makeAxis(num = self.form.countLevels.value(), size = levelHeight, name="laxis") axisL.Label = "Level Axes" axisL.ViewObject.BubblePosition = "None" axisL.ViewObject.LineWidth = self.form.lineWidth.value() axisL.ViewObject.FontSize = Draft.getParam("textheight",0.20) axisL.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector (0.577350269189626, -0.5773502691896257, 0.5773502691896257),120) axisL.ViewObject.LineColor = color axisL.ViewObject.LabelOffset.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) axisL.Labels = alabels axisL.ViewObject.ShowLabel = True if outline: axisL.setExpression('Length', outline.Name+'.Length * 1.1') axisL.setExpression('Placement.Base.x', outline.Name+'.Placement.Base.x + '+axisL.Name+'.Length * 0.945') axisL.setExpression('Placement.Base.y', outline.Name+'.Placement.Base.y') grp.addObject(axisL) axisL.ViewObject.LabelOffset.Base = FreeCAD.Vector(-axisL.Length.Value + Draft.getParam("textheight",0.20)*0.43,0,Draft.getParam("textheight",0.20)*0.43) self.form.hide() FreeCAD.ActiveDocument.recompute() if outline: FreeCADGui.Selection.clearSelection() FreeCADGui.Selection.addSelection(outline) FreeCADGui.SendMsgToActiveView("ViewSelection") FreeCADGui.Selection.clearSelection() if hasattr(FreeCADGui,"Snapper"): FreeCADGui.Snapper.show() return True
def createFromProperties(propsets,ifcfile,parametrics): """ Creates a FreeCAD parametric object from a set of properties. """ obj = None sets = [] appset = None guiset = None for pset in propsets.keys(): if ifcfile[pset].Name == "FreeCADPropertySet": appset = {} for pid in propsets[pset]: p = ifcfile[pid] appset[p.Name] = p.NominalValue.wrappedValue elif ifcfile[pset].Name == "FreeCADGuiPropertySet": guiset = {} for pid in propsets[pset]: p = ifcfile[pid] guiset[p.Name] = p.NominalValue.wrappedValue if appset: oname = None otype = None if "FreeCADType" in appset.keys(): if "FreeCADName" in appset.keys(): obj = FreeCAD.ActiveDocument.addObject(appset["FreeCADType"],appset["FreeCADName"]) if "FreeCADAppObject" in appset: mod,cla = appset["FreeCADAppObject"].split(".") if "'" in mod: mod = mod.split("'")[-1] if "'" in cla: cla = cla.split("'")[0] import importlib mod = importlib.import_module(mod) getattr(mod,cla)(obj) sets.append(("App",appset)) if FreeCAD.GuiUp: if guiset: if "FreeCADGuiObject" in guiset: mod,cla = guiset["FreeCADGuiObject"].split(".") if "'" in mod: mod = mod.split("'")[-1] if "'" in cla: cla = cla.split("'")[0] import importlib mod = importlib.import_module(mod) getattr(mod,cla)(obj.ViewObject) sets.append(("Gui",guiset)) if obj and sets: for realm,pset in sets: if realm == "App": target = obj else: target = obj.ViewObject for key,val in pset.items(): if key.startswith("FreeCAD_") or key.startswith("FreeCADGui_"): name = key.split("_")[1] if name in target.PropertiesList: if not target.getEditorMode(name): ptype = target.getTypeIdOfProperty(name) if ptype in ["App::PropertyString","App::PropertyEnumeration","App::PropertyInteger","App::PropertyFloat"]: setattr(target,name,val) elif ptype in ["App::PropertyLength","App::PropertyDistance"]: setattr(target,name,val*1000) elif ptype == "App::PropertyBool": if val in [".T.",True]: setattr(target,name,True) else: setattr(target,name,False) elif ptype == "App::PropertyVector": setattr(target,name,FreeCAD.Vector([float(s) for s in val.split("(")[1].strip(")").split(",")])) elif ptype == "App::PropertyArea": setattr(target,name,val*1000000) elif ptype == "App::PropertyPlacement": data = val.split("[")[1].strip("]").split("(") data = [data[1].split(")")[0],data[2].strip(")")] v = FreeCAD.Vector([float(s) for s in data[0].split(",")]) r = FreeCAD.Rotation(*[float(s) for s in data[1].split(",")]) setattr(target,name,FreeCAD.Placement(v,r)) elif ptype == "App::PropertyLink": link = val.split("_")[1] parametrics.append([target,name,link]) else: print("Unhandled FreeCAD property:",name," of type:",ptype) return obj,parametrics
def z_RotateObject(doc, rot): # z-Rotate objs=GetListOfObjects(FreeCAD, doc) FreeCAD.getDocument(doc.Name).getObject(objs[0].Name).Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),rot)) return 0
def make_text(string, placement=None, screen=False): """Create a Text object containing the given list of strings. The current color and text height and font specified in preferences are used. Parameters ---------- string: str, or list of str String to display on screen. If it is a list, each element in the list should be a string. In this case each element will be printed in its own line, that is, a newline will be added at the end of each string. If an empty string is passed `''` this won't cause an error but the text `'Label'` will be displayed in the 3D view. placement: Base::Placement, Base::Vector3, or Base::Rotation, optional It defaults to `None`. If it is provided, it is the placement of the new text. The input could be a full placement, just a vector indicating the translation, or just a rotation. screen: bool, optional It defaults to `False`, in which case the text is placed in 3D space oriented like any other object, on top of a given plane, by the default the XY plane. If it is `True`, the text will always face perpendicularly to the camera direction, that is, it will be flat on the screen. Returns ------- App::FeaturePython A scripted object of type `'Text'`. This object does not have a `Shape` attribute, as the text is created on screen by Coin (pivy). None If there is a problem it will return `None`. """ _name = "make_text" utils.print_header(_name, "Text") found, doc = utils.find_doc(App.activeDocument()) if not found: _err(translate("draft", "No active document. Aborting.")) return None _msg("string: {}".format(string)) try: utils.type_check([(string, (str, list))]) except TypeError: _err( translate( "draft", "Wrong input: must be a list of strings or a single string.")) return None if not all(isinstance(element, str) for element in string): _err( translate( "draft", "Wrong input: must be a list of strings or a single string.")) return None if isinstance(string, str): string = [string] _msg("placement: {}".format(placement)) if not placement: placement = App.Placement() try: utils.type_check([(placement, (App.Placement, App.Vector, App.Rotation))], name=_name) except TypeError: _err( translate( "draft", "Wrong input: must be a placement, a vector, or a rotation.")) return None # Convert the vector or rotation to a full placement if isinstance(placement, App.Vector): placement = App.Placement(placement, App.Rotation()) elif isinstance(placement, App.Rotation): placement = App.Placement(App.Vector(), placement) new_obj = doc.addObject("App::FeaturePython", "Text") Text(new_obj) new_obj.Text = string new_obj.Placement = placement if App.GuiUp: ViewProviderText(new_obj.ViewObject) h = utils.get_param("textheight", 2) new_obj.ViewObject.DisplayMode = "3D text" if screen: _msg("screen: {}".format(screen)) new_obj.ViewObject.DisplayMode = "2D text" h = h * 10 new_obj.ViewObject.FontSize = h new_obj.ViewObject.FontName = utils.get_param("textfont", "") new_obj.ViewObject.LineSpacing = 1 gui_utils.format_object(new_obj) gui_utils.select(new_obj) return new_obj
def draw(self): #helper Variables #Find the widest component of the anchor and set the width to that baseWidth = (gv.printedToPrintedDia + 2 * gv.mountToPrintedPadding if gv.printedToPrintedDia + 2 * gv.mountToPrintedPadding > gv.yBeltAnchorWidth else gv.yBeltAnchorWidth) baseLength = (gv.yBeltAnchorLength + 2 * gv.printedToPrintedDia + 4 * gv.mountToPrintedPadding) #Make file and build part try: Gui.getDocument("yBeltAnchor") Gui.getDocument("yBeltAnchor").resetEdit() App.getDocument("yBeltAnchor").recompute() App.closeDocument("yBeltAnchor") App.setActiveDocument("") App.ActiveDocument = None Gui.ActiveDocument = None except: pass #Create Document App.newDocument("yBeltAnchor") App.setActiveDocument("yBeltAnchor") App.ActiveDocument = App.getDocument("yBeltAnchor") Gui.ActiveDocument = Gui.getDocument("yBeltAnchor") #Make base #Sketch points p1x = -baseLength / 2 p1y = -baseWidth / 2 p2x = -baseLength / 2 p2y = baseWidth / 2 p3x = baseLength / 2 p3y = baseWidth / 2 p4x = baseLength / 2 p4y = -baseWidth / 2 #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.000000, 0.000000, 0.000000, 1.000000)) Gui.activeDocument().activeView().setCamera( '#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA \n position 0 0 87 \n orientation 0 0 1 0 \n nearDistance -112.88701 \n farDistance 287.28702 \n aspectRatio 1 \n focalDistance 87 \n height 143.52005 }' ) # Gui.activeDocument().setEdit('Sketch') App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 0, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 0)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 2)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Symmetric', 1, 2, 0, 1, -1, 1)) App.ActiveDocument.recompute() #add dimensions App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceY', 1, baseWidth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceX', 0, baseLength)) App.ActiveDocument.recompute() # Gui.getDocument("yBeltAnchor").resetEdit() App.getDocument("yBeltAnchor").recompute() #Pad base App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch") App.ActiveDocument.Pad.Length = gv.tabThickness App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Cut hole on right side #Sketch points p1x = gv.yBeltAnchorLength / 2 + gv.mountToPrintedPadding + gv.printedToPrintedDia / 2 p1y = 0 #Make sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch001') App.activeDocument().Sketch001.Support = uf.getFace( App.ActiveDocument.Pad, 0, 0, 0, 0, gv.tabThickness, 0) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch001') App.ActiveDocument.Sketch001.addGeometry( Part.Circle(App.Vector(p1x, p1y, 0), App.Vector(0, 0, 1), gv.printedToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 0, 3, -1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Radius', 0, gv.printedToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('DistanceX', -1, 1, 0, 3, p1x)) App.ActiveDocument.recompute() # Gui.getDocument('yBeltAnchor').resetEdit() App.getDocument('yBeltAnchor').recompute() #Cut hole through all App.activeDocument().addObject("PartDesign::Pocket", "Pocket") App.activeDocument().Pocket.Sketch = App.activeDocument().Sketch001 App.activeDocument().Pocket.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch001") Gui.activeDocument().hide("Pad") # Gui.ActiveDocument.Pocket.ShapeColor=Gui.ActiveDocument.Pad.ShapeColor # Gui.ActiveDocument.Pocket.LineColor=Gui.ActiveDocument.Pad.LineColor # Gui.ActiveDocument.Pocket.PointColor=Gui.ActiveDocument.Pad.PointColor App.ActiveDocument.Pocket.Length = 5.000000 App.ActiveDocument.Pocket.Type = 1 App.ActiveDocument.Pocket.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Mirror the hole App.activeDocument().addObject("PartDesign::Mirrored", "Mirrored") App.ActiveDocument.recompute() App.activeDocument().Mirrored.Originals = [ App.activeDocument().Pocket, ] App.activeDocument().Mirrored.MirrorPlane = ( App.activeDocument().Sketch001, ["V_Axis"]) Gui.activeDocument().Pocket.Visibility = False # Gui.ActiveDocument.Mirrored.ShapeColor=Gui.ActiveDocument.Pocket.ShapeColor # Gui.ActiveDocument.Mirrored.DisplayMode=Gui.ActiveDocument.Pocket.DisplayMode #Make the column #Sketch points p1x = -gv.yBeltAnchorWidth / 2 p1y = -gv.yBeltAnchorLength / 2 p2x = -gv.yBeltAnchorWidth / 2 p2y = gv.yBeltAnchorLength / 2 p3x = gv.yBeltAnchorWidth / 2 p3y = gv.yBeltAnchorLength / 2 p4x = gv.yBeltAnchorWidth / 2 p4y = -gv.yBeltAnchorLength / 2 App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch002') App.activeDocument().recompute() App.activeDocument().Sketch002.Support = uf.getFace( App.ActiveDocument.Mirrored, 0, 0, 0, 0, gv.tabThickness, 0) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch002') App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 0, 1)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Horizontal', 0)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Horizontal', 2)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Symmetric', 1, 2, 0, 1, -1, 1)) App.ActiveDocument.recompute() #Add Dimensions App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('DistanceY', 1, gv.yBeltAnchorWidth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('DistanceX', 2, -gv.yBeltAnchorLength)) App.ActiveDocument.recompute() # Gui.getDocument('yBeltAnchor').resetEdit() App.getDocument('yBeltAnchor').recompute() #Extrude column App.activeDocument().addObject("PartDesign::Pad", "Pad001") App.activeDocument().Pad001.Sketch = App.activeDocument().Sketch002 App.activeDocument().Pad001.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch002") Gui.activeDocument().hide("Mirrored") # Gui.ActiveDocument.Pad001.ShapeColor=Gui.ActiveDocument.Mirrored.ShapeColor # Gui.ActiveDocument.Pad001.LineColor=Gui.ActiveDocument.Mirrored.LineColor # Gui.ActiveDocument.Pad001.PointColor=Gui.ActiveDocument.Mirrored.PointColor App.ActiveDocument.Pad001.Length = gv.yBeltAnchorHeight - gv.tabThickness App.ActiveDocument.Pad001.Reversed = 0 App.ActiveDocument.Pad001.Midplane = 0 App.ActiveDocument.Pad001.Length2 = 100.000000 App.ActiveDocument.Pad001.Type = 0 App.ActiveDocument.Pad001.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Cut slot in column #Sketch Points p1x = -gv.yBeltAnchorSlotWidth / 2 p1y = gv.tabThickness p2x = -gv.yBeltAnchorSlotWidth / 2 p2y = gv.yBeltAnchorHeight - gv.yBeltAnchorBridgeThickness p3x = gv.yBeltAnchorSlotWidth / 2 p3y = gv.yBeltAnchorHeight - gv.yBeltAnchorBridgeThickness p4x = gv.yBeltAnchorSlotWidth / 2 p4y = gv.tabThickness #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch003') App.activeDocument().recompute() App.activeDocument().Sketch003.Support = uf.getFace( App.ActiveDocument.Pad001, None, None, -gv.yBeltAnchorWidth / 2, 0, None, None) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch003') App.ActiveDocument.Sketch003.addExternal( "Pad001", uf.getEdge(App.ActiveDocument.Pad001, 0, 0, -gv.yBeltAnchorWidth / 2, 0, gv.tabThickness, 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 0, 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Horizontal', 0)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Horizontal', 2)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Vertical', 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 0, 1, -3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Symmetric', 1, 2, 2, 2, -2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addExternal("Pad001", "Edge1") App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Distance', 1, 2, -4, gv.yBeltAnchorBridgeThickness)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('DistanceX', 0, gv.yBeltAnchorSlotWidth)) App.ActiveDocument.recompute() # Gui.getDocument('yBeltAnchor').resetEdit() App.getDocument('yBeltAnchor').recompute() #Cut Slot through all App.activeDocument().addObject("PartDesign::Pocket", "Pocket001") App.activeDocument().Pocket001.Sketch = App.activeDocument().Sketch003 App.activeDocument().Pocket001.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch003") Gui.activeDocument().hide("Pad001") # Gui.ActiveDocument.Pocket001.ShapeColor=Gui.ActiveDocument.Pad001.ShapeColor # Gui.ActiveDocument.Pocket001.LineColor=Gui.ActiveDocument.Pad001.LineColor # Gui.ActiveDocument.Pocket001.PointColor=Gui.ActiveDocument.Pad001.PointColor App.ActiveDocument.Pocket001.Length = 5.000000 App.ActiveDocument.Pocket001.Type = 1 App.ActiveDocument.Pocket001.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Refine Shape App.ActiveDocument.addObject( 'Part::Feature', 'Pocket001' ).Shape = App.ActiveDocument.Pocket001.Shape.removeSplitter() App.ActiveDocument.ActiveObject.Label = App.ActiveDocument.Pocket001.Label Gui.ActiveDocument.Pocket001.hide() # Gui.ActiveDocument.ActiveObject.ShapeColor=Gui.ActiveDocument.Pocket001.ShapeColor # Gui.ActiveDocument.ActiveObject.LineColor=Gui.ActiveDocument.Pocket001.LineColor # Gui.ActiveDocument.ActiveObject.PointColor=Gui.ActiveDocument.Pocket001.PointColor App.ActiveDocument.recompute() #Make view axiometric # Gui.activeDocument().activeView().viewAxometric()
def _svg_dimension(obj, plane, scale, linewidth, fontsize, stroke, pointratio, techdraw, rotation): """Return the SVG representation of a linear dimension.""" if not App.GuiUp: _wrn("'{}': SVG can only be generated " "in GUI mode".format(obj.Label)) return "" if not hasattr(obj.ViewObject, "Proxy") or not obj.ViewObject.Proxy: _err("'{}': doesn't have Proxy, " "SVG cannot be generated".format(obj.Label)) return "" vobj = obj.ViewObject prx = vobj.Proxy if not hasattr(prx, "p1"): _err("'{}': doesn't have points, " "SVG cannot be generated".format(obj.Label)) return "" ts = len(prx.string) * vobj.FontSize.Value / 4.0 rm = (prx.p3 - prx.p2).Length / 2.0 - ts _diff32 = prx.p3 - prx.p2 _diff23 = prx.p2 - prx.p3 _v32 = DraftVecUtils.scaleTo(_diff32, rm) _v23 = DraftVecUtils.scaleTo(_diff23, rm) p2a = get_proj(prx.p2 + _v32, plane) p2b = get_proj(prx.p3 + _v23, plane) p1 = get_proj(prx.p1, plane) p2 = get_proj(prx.p2, plane) p3 = get_proj(prx.p3, plane) p4 = get_proj(prx.p4, plane) tbase = get_proj(prx.tbase, plane) r = prx.textpos.rotation.getValue().getValue() _rv = App.Rotation(r[0], r[1], r[2], r[3]) rv = _rv.multVec(App.Vector(1, 0, 0)) angle = -DraftVecUtils.angle(get_proj(rv, plane)) # angle = -DraftVecUtils.angle(p3.sub(p2)) svg = '' nolines = False if hasattr(vobj, "ShowLine"): if not vobj.ShowLine: nolines = True # drawing lines if not nolines: svg += '<path ' if vobj.DisplayMode == "2D": tangle = angle if tangle > math.pi / 2: tangle = tangle - math.pi # elif (tangle <= -math.pi/2) or (tangle > math.pi/2): # tangle = tangle + math.pi if rotation != 0: # print("dim: tangle:", tangle, # " rot: ", rotation, # " text: ", prx.string) if abs(tangle + math.radians(rotation)) < 0.0001: tangle += math.pi _v = App.Vector(0, 2.0 / scale, 0) _rot = DraftVecUtils.rotate(_v, tangle) tbase = tbase + _rot if not nolines: svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' ' svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' ' svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' ' svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" ' else: tangle = 0 if rotation != 0: tangle = -math.radians(rotation) tbase = tbase + App.Vector(0, -2.0 / scale, 0) if not nolines: svg += 'd="M ' + str(p1.x) + ' ' + str(p1.y) + ' ' svg += 'L ' + str(p2.x) + ' ' + str(p2.y) + ' ' svg += 'L ' + str(p2a.x) + ' ' + str(p2a.y) + ' ' svg += 'M ' + str(p2b.x) + ' ' + str(p2b.y) + ' ' svg += 'L ' + str(p3.x) + ' ' + str(p3.y) + ' ' svg += 'L ' + str(p4.x) + ' ' + str(p4.y) + '" ' if not nolines: svg += 'fill="none" stroke="' svg += stroke + '" ' svg += 'stroke-width="' + str(linewidth) + ' px" ' svg += 'style="stroke-width:' + str(linewidth) svg += ';stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:square" ' svg += 'freecad:basepoint1="' + str(p1.x) + ' ' + str(p1.y) + '" ' svg += 'freecad:basepoint2="' + str(p4.x) + ' ' + str(p4.y) + '" ' svg += 'freecad:dimpoint="' + str(p2.x) + ' ' + str(p2.y) + '"' svg += '/>\n' # drawing dimension and extension lines overshoots if hasattr(vobj, "DimOvershoot") and vobj.DimOvershoot.Value: shootsize = vobj.DimOvershoot.Value / pointratio svg += get_overshoot(p2, shootsize, stroke, linewidth, angle) svg += get_overshoot(p3, shootsize, stroke, linewidth, angle + math.pi) if hasattr(vobj, "ExtOvershoot") and vobj.ExtOvershoot.Value: shootsize = vobj.ExtOvershoot.Value / pointratio shootangle = -DraftVecUtils.angle(p1 - p2) svg += get_overshoot(p2, shootsize, stroke, linewidth, shootangle) svg += get_overshoot(p3, shootsize, stroke, linewidth, shootangle) # drawing arrows if hasattr(vobj, "ArrowType"): arrowsize = vobj.ArrowSize.Value / pointratio if hasattr(vobj, "FlipArrows"): if vobj.FlipArrows: angle = angle + math.pi svg += get_arrow(obj, vobj.ArrowType, p2, arrowsize, stroke, linewidth, angle) svg += get_arrow(obj, vobj.ArrowType, p3, arrowsize, stroke, linewidth, angle + math.pi) # drawing text svg += svgtext.get_text(plane, techdraw, stroke, fontsize, vobj.FontName, tangle, tbase, prx.string) return svg
def attachToTube(port=None): pypes=[p for p in FreeCADGui.Selection.getSelection() if hasattr(p,'PType')] tube=None try: tubes=[t for t in pypes if t.PType=='Pipe'] if tubes: tube=tubes[0] pypes.pop(pypes.index(tube)) for p in pypes: p.MapMode = 'Concentric' if not port: port=tube.Proxy.nearestPort(p.Shape.Solids[0].CenterOfMass)[0] if port==0: if p.PType!='Flange': p.MapReversed = True else: p.MapReversed = False p.Support = [(tube,'Edge3')] elif port==1: if p.PType!='Flange': p.MapReversed = False else: p.MapReversed = True p.Support = [(tube,'Edge1')] if p.PType=='Elbow': p.AttachmentOffset = FreeCAD.Placement(FreeCAD.Vector(0, 0, p.Ports[0].Length), FreeCAD.Rotation(p.Ports[1],FreeCAD.Vector(0, 0, 1).negative())) FreeCAD.Console.PrintMessage('%s attached to %s\n' %(p.Label,tube.Label)) else: for p in pypes: p.MapMode='Deactivated' FreeCAD.Console.PrintMessage('Object Detached\n') except: FreeCAD.Console.PrintError('Nothing attached\n')
def get_svg(obj, scale=1, linewidth=0.35, fontsize=12, fillstyle="shape color", direction=None, linestyle=None, color=None, linespacing=None, techdraw=False, rotation=0, fillspaces=False, override=True): """Return a string containing an SVG representation of the object. Paramaeters ----------- scale: float, optional It defaults to 1. It allows scaling line widths down, so they are resolution-independent. linewidth: float, optional It defaults to 0.35. fontsize: float, optional It defaults to 12, which is interpreted as `pt` unit (points). It is used if the given object contains any text. fillstyle: str, optional It defaults to 'shape color'. direction: Base::Vector3, optional It defaults to `None`. It is an arbitrary projection vector or a `WorkingPlane.Plane` instance. linestyle: optional It defaults to `None`. color: optional It defaults to `None`. linespacing: float, optional It defaults to `None`. techdraw: bool, optional It defaults to `False`. If it is `True`, it sets some options for generating SVG strings for displaying inside TechDraw. rotation: float, optional It defaults to 0. fillspaces: bool, optional It defaults to `False`. override: bool, optional It defaults to `True`. """ # If this is a group, recursively call this function to gather # all the SVG strings from the contents of the group if hasattr(obj, "isDerivedFrom"): if (obj.isDerivedFrom("App::DocumentObjectGroup") or utils.get_type(obj) in ["Layer", "BuildingPart"]): svg = "" for child in obj.Group: svg += get_svg(child, scale, linewidth, fontsize, fillstyle, direction, linestyle, color, linespacing, techdraw, rotation, fillspaces, override) return svg pathdata = [] svg = "" linewidth = float(linewidth) / scale if not override: if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "LineWidth"): if hasattr(obj.ViewObject.LineWidth, "Value"): lw = obj.ViewObject.LineWidth.Value else: lw = obj.ViewObject.LineWidth linewidth = lw * linewidth fontsize = (float(fontsize) / scale) / 2 if linespacing: linespacing = float(linespacing) / scale else: linespacing = 0.5 # print(obj.Label, "line spacing", linespacing, "scale", scale) # The number of times the dots are smaller than the arrow size pointratio = 0.75 plane = None if direction: if isinstance(direction, App.Vector): if direction != App.Vector(0, 0, 0): plane = WorkingPlane.plane() plane.alignToPointAndAxis_SVG(App.Vector(0, 0, 0), direction.negative().negative(), 0) else: raise ValueError("'direction' cannot be: Vector(0, 0, 0)") elif isinstance(direction, WorkingPlane.plane): plane = direction stroke = "#000000" tstroke = stroke if color and override: if "#" in color: stroke = color else: stroke = utils.get_rgb(color) tstroke = stroke elif App.GuiUp: # find print color pc = get_print_color(obj) if pc: stroke = utils.get_rgb(pc) # get line color elif hasattr(obj, "ViewObject"): if hasattr(obj.ViewObject, "LineColor"): stroke = utils.get_rgb(obj.ViewObject.LineColor) elif hasattr(obj.ViewObject, "TextColor"): stroke = utils.get_rgb(obj.ViewObject.TextColor) if hasattr(obj.ViewObject, "TextColor"): tstroke = utils.get_rgb(obj.ViewObject.TextColor) lstyle = "none" if override: lstyle = get_line_style(linestyle, scale) else: if hasattr(obj, "ViewObject") and hasattr(obj.ViewObject, "DrawStyle"): lstyle = get_line_style(obj.ViewObject.DrawStyle, scale) if not obj: pass elif isinstance(obj, Part.Shape): svg = _svg_shape(svg, obj, plane, fillstyle, pathdata, stroke, linewidth, lstyle) elif utils.get_type(obj) in ["Dimension", "LinearDimension"]: svg = _svg_dimension(obj, plane, scale, linewidth, fontsize, stroke, pointratio, techdraw, rotation) elif utils.get_type(obj) == "AngularDimension": if not App.GuiUp: _wrn("Export of dimensions to SVG is only available in GUI mode") if App.GuiUp: if obj.ViewObject.Proxy: if hasattr(obj.ViewObject.Proxy, "circle"): prx = obj.ViewObject.Proxy # drawing arc fill = "none" if obj.ViewObject.DisplayMode == "2D": svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=[prx.circle]) else: if hasattr(prx, "circle1"): svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=[prx.circle1]) svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=[prx.circle2]) else: svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=[prx.circle]) # drawing arrows if hasattr(obj.ViewObject, "ArrowType"): p2 = get_proj(prx.p2, plane) p3 = get_proj(prx.p3, plane) arrowsize = obj.ViewObject.ArrowSize.Value / pointratio arrowlength = 4 * obj.ViewObject.ArrowSize.Value _v1a = prx.circle.valueAt(prx.circle.FirstParameter + arrowlength) _v1b = prx.circle.valueAt(prx.circle.FirstParameter) _v2a = prx.circle.valueAt(prx.circle.LastParameter - arrowlength) _v2b = prx.circle.valueAt(prx.circle.LastParameter) u1 = get_proj(_v1a - _v1b, plane) u2 = get_proj(_v2a - _v2b, plane) angle1 = -DraftVecUtils.angle(u1) angle2 = -DraftVecUtils.angle(u2) if hasattr(obj.ViewObject, "FlipArrows"): if obj.ViewObject.FlipArrows: angle1 = angle1 + math.pi angle2 = angle2 + math.pi svg += get_arrow(obj, obj.ViewObject.ArrowType, p2, arrowsize, stroke, linewidth, angle1) svg += get_arrow(obj, obj.ViewObject.ArrowType, p3, arrowsize, stroke, linewidth, angle2) # drawing text if obj.ViewObject.DisplayMode == "2D": _diff = (prx.circle.LastParameter - prx.circle.FirstParameter) t = prx.circle.tangentAt(prx.circle.FirstParameter + _diff / 2.0) t = get_proj(t, plane) tangle = DraftVecUtils.angle(t) if (tangle <= -math.pi / 2) or (tangle > math.pi / 2): tangle = tangle + math.pi _diff = (prx.circle.LastParameter - prx.circle.FirstParameter) _va = prx.circle.valueAt(prx.circle.FirstParameter + _diff / 2.0) tbase = get_proj(_va, plane) _v = App.Vector(0, 2.0 / scale, 0) tbase = tbase + DraftVecUtils.rotate(_v, tangle) # print(tbase) else: tangle = 0 tbase = get_proj(prx.tbase, plane) svg += svgtext.get_text(plane, techdraw, stroke, fontsize, obj.ViewObject.FontName, tangle, tbase, prx.string) elif utils.get_type(obj) == "Label": if getattr(obj.ViewObject, "Line", True): # Some Labels may have no Line property # Draw multisegment line proj_points = list(map(lambda x: get_proj(x, plane), obj.Points)) path_dir_list = [format_point(proj_points[0], action='M')] path_dir_list += map(format_point, proj_points[1:]) path_dir_str = " ".join(path_dir_list) svg_path = '<path ' svg_path += 'fill="none" ' svg_path += 'stroke="{}" '.format(stroke) svg_path += 'stroke-width="{}" '.format(linewidth) svg_path += 'stroke-linecap="square" ' svg_path += 'd="{}"'.format(path_dir_str) svg_path += '/>' svg += svg_path # Draw arrow. # We are different here from 3D view # if Line is set to 'off', no arrow is drawn if hasattr(obj.ViewObject, "ArrowType") and len(obj.Points) >= 2: last_segment = App.Vector(obj.Points[-1] - obj.Points[-2]) _v = get_proj(last_segment, plane) angle = -DraftVecUtils.angle(_v) + math.pi svg += get_arrow(obj, obj.ViewObject.ArrowType, proj_points[-1], obj.ViewObject.ArrowSize.Value / pointratio, stroke, linewidth, angle) if not App.GuiUp: _wrn("Export of texts to SVG is only available in GUI mode") # print text if App.GuiUp: fontname = obj.ViewObject.TextFont position = get_proj(obj.Placement.Base, plane) rotation = obj.Placement.Rotation justification = obj.ViewObject.Justification text = obj.Text svg += svgtext.get_text(plane, techdraw, stroke, fontsize, fontname, rotation, position, text, linespacing, justification) elif utils.get_type(obj) in ["Annotation", "DraftText", "Text"]: # returns an svg representation of a document annotation if not App.GuiUp: _wrn("Export of texts to SVG is only available in GUI mode") if App.GuiUp: n = obj.ViewObject.FontName if utils.get_type(obj) == "Annotation": p = get_proj(obj.Position, plane) r = obj.ViewObject.Rotation.getValueAs("rad") t = obj.LabelText else: # DraftText (old) or Text (new, 0.19) p = get_proj(obj.Placement.Base, plane) r = obj.Placement.Rotation t = obj.Text j = obj.ViewObject.Justification svg += svgtext.get_text(plane, techdraw, tstroke, fontsize, n, r, p, t, linespacing, j) elif utils.get_type(obj) == "Axis": # returns the SVG representation of an Arch Axis system if not App.GuiUp: _wrn("Export of axes to SVG is only available in GUI mode") if App.GuiUp: vobj = obj.ViewObject fn = obj.ViewObject.FontName fill = 'none' rad = vobj.BubbleSize.Value / 2 n = 0 for e in obj.Shape.Edges: svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=[e]) for t in obj.ViewObject.Proxy.getTextData(): pos = t[1].add(App.Vector(0, -fontsize / 2, 0)) svg += svgtext.get_text(plane, techdraw, tstroke, fontsize, fn, 0.0, pos, t[0], 1.0, "center") for b in obj.ViewObject.Proxy.getShapeData(): if hasattr(b, "Curve") and isinstance(b.Curve, Part.Circle): svg += get_circle(plane, fill, stroke, linewidth, "none", b) else: sfill = stroke svg += get_path(obj, plane, sfill, pathdata, stroke, linewidth, "none", fill_opacity=None, edges=b.Edges) elif utils.get_type(obj) == "Pipe": fill = stroke if obj.Base and obj.Diameter: svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, edges=obj.Base.Shape.Edges) for f in obj.Shape.Faces: if len(f.Edges) == 1: if isinstance(f.Edges[0].Curve, Part.Circle): svg += get_circle(plane, fill, stroke, linewidth, lstyle, f.Edges[0]) elif utils.get_type(obj) == "Rebar": fill = "none" basewire = obj.Base.Shape.Wires[0].copy() # Not applying rounding because the results are not correct # if hasattr(obj, "Rounding") and obj.Rounding: # basewire = DraftGeomUtils.filletWire( # basewire, obj.Rounding * obj.Diameter.Value # ) wires = [] for placement in obj.PlacementList: wire = basewire.copy() wire.Placement = placement.multiply(basewire.Placement) wires.append(wire) svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=None, wires=wires) elif utils.get_type(obj) == "PipeConnector": pass elif utils.get_type(obj) == "Space": fill_opacity = 1 # returns an SVG fragment for the text of a space if not App.GuiUp: _wrn("Export of spaces to SVG is only available in GUI mode") if App.GuiUp: vobj = obj.ViewObject if fillspaces and hasattr(obj, "Proxy"): if not hasattr(obj.Proxy, "face"): obj.Proxy.getArea(obj, notouch=True) if hasattr(obj.Proxy, "face"): # setting fill if App.GuiUp and hasattr(vobj, "ShapeColor"): fill = utils.get_rgb(vobj.ShapeColor, testbw=False) fill_opacity = 1 - vobj.Transparency / 100.0 else: fill = "#888888" svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=fill_opacity, wires=[obj.Proxy.face.OuterWire]) c = utils.get_rgb(vobj.TextColor) n = vobj.FontName a = 0 if rotation != 0: a = math.radians(rotation) t1 = vobj.Proxy.text1.string.getValues() t2 = vobj.Proxy.text2.string.getValues() scale = vobj.FirstLine.Value / vobj.FontSize.Value f1 = fontsize * scale if round(plane.axis.getAngle(App.Vector(0, 0, 1)), 2) not in [0, 3.14]: # if not in XY view, place the label at center p2 = obj.Shape.CenterOfMass else: _v = vobj.Proxy.coords.translation.getValue().getValue() p2 = obj.Placement.multVec(App.Vector(_v)) _h = vobj.Proxy.header.translation.getValue().getValue() lspc = App.Vector(_h) p1 = p2 + lspc j = vobj.TextAlign t3 = svgtext.get_text(plane, techdraw, c, f1, n, a, get_proj(p1, plane), t1, linespacing, j, flip=True) svg += t3 if t2: ofs = App.Vector(0, -lspc.Length, 0) if a: Z = App.Vector(0, 0, 1) ofs = App.Rotation(Z, -rotation).multVec(ofs) t4 = svgtext.get_text(plane, techdraw, c, fontsize, n, a, get_proj(p1, plane).add(ofs), t2, linespacing, j, flip=True) svg += t4 elif hasattr(obj, 'Shape'): # In the past we tested for a Part Feature # elif obj.isDerivedFrom('Part::Feature'): # # however, this doesn't work for App::Links; instead we # test for a 'Shape'. All Part::Features should have a Shape, # and App::Links can have one as well. if obj.Shape.isNull(): return '' fill_opacity = 1 # setting fill if obj.Shape.Faces: if App.GuiUp: try: m = obj.ViewObject.DisplayMode except AttributeError: m = None vobj = obj.ViewObject if m != "Wireframe": if (fillstyle == "shape color") and hasattr( vobj, "ShapeColor"): fill = utils.get_rgb(vobj.ShapeColor, testbw=False) fill_opacity = 1 - vobj.Transparency / 100.0 elif fillstyle in ("none", None): fill = "none" else: fill = 'url(#' + fillstyle + ')' svg += get_pattern(fillstyle) else: fill = "none" else: fill = "#888888" else: fill = 'none' if len(obj.Shape.Vertexes) > 1: wiredEdges = [] if obj.Shape.Faces: for i, f in enumerate(obj.Shape.Faces): # place outer wire first wires = [f.OuterWire] wires.extend([ w for w in f.Wires if w.hashCode() != f.OuterWire.hashCode() ]) svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=fill_opacity, wires=f.Wires, pathname='%s_f%04d' % (obj.Name, i)) wiredEdges.extend(f.Edges) else: for i, w in enumerate(obj.Shape.Wires): svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=fill_opacity, edges=w.Edges, pathname='%s_w%04d' % (obj.Name, i)) wiredEdges.extend(w.Edges) if len(wiredEdges) != len(obj.Shape.Edges): for i, e in enumerate(obj.Shape.Edges): if DraftGeomUtils.findEdge(e, wiredEdges) is None: svg += get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=fill_opacity, edges=[e], pathname='%s_nwe%04d' % (obj.Name, i)) else: # closed circle or spline if obj.Shape.Edges: if isinstance(obj.Shape.Edges[0].Curve, Part.Circle): svg = get_circle(plane, fill, stroke, linewidth, lstyle, obj.Shape.Edges[0]) else: svg = get_path(obj, plane, fill, pathdata, stroke, linewidth, lstyle, fill_opacity=fill_opacity, edges=obj.Shape.Edges) if (App.GuiUp and hasattr(obj.ViewObject, "EndArrow") and obj.ViewObject.EndArrow and hasattr(obj.ViewObject, "ArrowType") and len(obj.Shape.Vertexes) > 1): p1 = get_proj(obj.Shape.Vertexes[-1].Point, plane) p2 = get_proj(obj.Shape.Vertexes[-2].Point, plane) angle = -DraftVecUtils.angle(p2 - p1) arrowsize = obj.ViewObject.ArrowSize.Value / pointratio svg += get_arrow(obj, obj.ViewObject.ArrowType, p1, arrowsize, stroke, linewidth, angle) # techdraw expects bottom-to-top coordinates if techdraw: svg = '<g transform ="scale(1,-1)">\n ' + svg + '</g>\n' return svg
FuseObjs_wColors(FreeCAD, FreeCADGui, doc.Name, objs[0].Name, objs[1].Name) objs = GetListOfObjects(FreeCAD, doc) FuseObjs_wColors(FreeCAD, FreeCADGui, doc.Name, objs[0].Name, objs[1].Name) #stop doc.Label = CheckedModelName objs = GetListOfObjects(FreeCAD, doc) objs[0].Label = CheckedModelName restore_Main_Tools() #rotate if required objs = GetListOfObjects(FreeCAD, doc) FreeCAD.getDocument(doc.Name).getObject( objs[0].Name).Placement = FreeCAD.Placement( FreeCAD.Vector(all_params[variant].F / 2, 0, 0), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), all_params[variant].rotation)) #out_dir=destination_dir+all_params[variant].dest_dir_prefix+'/' script_dir = os.path.dirname(os.path.realpath(__file__)) expVRML.say(script_dir) #out_dir=script_dir+os.sep+destination_dir+os.sep+all_params[variant].dest_dir_prefix out_dir = models_dir + destination_dir if not os.path.exists(out_dir): os.makedirs(out_dir) #out_dir="./generated_qfp/" # export STEP model exportSTEP(doc, ModelName, out_dir) if LIST_license[0] == "":
def import_part(self, part_path, pos=[0, 0, 0], ypr=[0,0,0]): obj = importPartFromFile(self.doc, part_path) obj.Placement.Base = FreeCAD.Vector(pos) obj.Placement.Rotation = FreeCAD.Rotation(ypr[0], ypr[1], ypr[2]) self.set_view() return obj
def make_circle(radius, placement=None, face=None, startangle=None, endangle=None, support=None): """make_circle(radius, [placement, face, startangle, endangle]) or make_circle(edge,[face]): Creates a circle object with given parameters. Parameters ---------- radius : the radius of the circle. placement : If placement is given, it is used. face : Bool If face is False, the circle is shown as a wireframe, otherwise as a face. startangle : start angle of the arc (in degrees) endangle : end angle of the arc (in degrees) if startangle and endangle are equal, a circle is created, if they are different an arc is created edge : edge.Curve must be a 'Part.Circle' the circle is created from the given edge support : TODO: Describe """ if not App.ActiveDocument: App.Console.PrintError("No active document. Aborting\n") return if placement: utils.type_check([(placement, App.Placement)], "make_circle") if startangle != endangle: _name = "Arc" else: _name = "Circle" obj = App.ActiveDocument.addObject("Part::Part2DObjectPython", _name) Circle(obj) if face is not None: obj.MakeFace = face if isinstance(radius, Part.Edge): edge = radius if DraftGeomUtils.geomType(edge) == "Circle": obj.Radius = edge.Curve.Radius placement = App.Placement(edge.Placement) delta = edge.Curve.Center.sub(placement.Base) placement.move(delta) # Rotation of the edge rotOk = App.Rotation(edge.Curve.XAxis, edge.Curve.YAxis, edge.Curve.Axis, "ZXY") placement.Rotation = rotOk if len(edge.Vertexes) > 1: v0 = edge.Curve.XAxis v1 = (edge.Vertexes[0].Point).sub(edge.Curve.Center) v2 = (edge.Vertexes[-1].Point).sub(edge.Curve.Center) # Angle between edge.Curve.XAxis and the vector from center to start of arc a0 = math.degrees(App.Vector.getAngle(v0, v1)) # Angle between edge.Curve.XAxis and the vector from center to end of arc a1 = math.degrees(App.Vector.getAngle(v0, v2)) obj.FirstAngle = a0 obj.LastAngle = a1 else: obj.Radius = radius if (startangle is not None) and (endangle is not None): if startangle == -0: startangle = 0 obj.FirstAngle = startangle obj.LastAngle = endangle obj.Support = support if placement: obj.Placement = placement if App.GuiUp: ViewProviderDraft(obj.ViewObject) gui_utils.format_object(obj) gui_utils.select(obj) return obj
def draw(self): try: Gui.getDocument(self.name) Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() App.closeDocument(self.name) App.setActiveDocument("") App.ActiveDocument = None Gui.ActiveDocument = None except: pass #make document App.newDocument(self.name) App.setActiveDocument(self.name) App.ActiveDocument = App.getDocument(self.name) Gui.ActiveDocument = Gui.getDocument(self.name) #Make profile of angle and extrude it p1x = 0 p1y = 0 p2x = 0 p2y = gv.extruderMountAngleWidth p3x = p2y p3y = p2y p4x = p3x p4y = gv.extruderMountAngleWidth - gv.extruderMountAngleThickness p5x = gv.extruderMountAngleThickness p5y = p4y p6x = p5x p6y = p1y #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.500000, 0.500000, 0.500000, 0.500000)) # Gui.activeDocument().activeView().setCamera('#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA\n position 87 0 0 \n orientation 0.57735026 0.57735026 0.57735026 2.0943952 \n nearDistance -112.887\n farDistance 287.28699\n aspectRatio 1\n focalDistance 87\n height 143.52005\n\n}') # Gui.activeDocument().setEdit('Sketch') App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', -1, 1, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('PointOnObject', 0, 2, -2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p5x, p5y, 0), App.Vector(p6x, p6y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 4, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 4)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p6x, p6y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 4, 2, 5, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 5, 2, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 5)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Equal', 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Equal', 2, 5)) App.ActiveDocument.recompute() #Add dimensions App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceY', 0, gv.extruderMountAngleWidth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceY', 2, -gv.extruderMountAngleThickness)) App.ActiveDocument.recompute() # Gui.getDocument('extruderMountAngle').resetEdit() App.getDocument('extruderMountAngle').recompute() #Extrude the extruder mount angle App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch") App.ActiveDocument.Pad.Length = gv.xCarriageWidth App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Cut holes for mounting to xCarriage #Sketch Points p1x = (gv.extruderMountAngleWidth - gv.extruderMountAngleThickness) / 2 p1y = gv.xCarriageWidth p2x = p1x p2y = gv.xCarriageWidth - gv.xCarriageMountHoleHorizOffset p3x = p1x p3y = gv.xCarriageMountHoleHorizOffset p4x = p1x p4y = 0 #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch001') App.activeDocument().Sketch001.Support = uf.getFace( App.ActiveDocument.Pad, None, None, gv.extruderMountAngleThickness, 0, None, None) #(App.ActiveDocument.Pad,["Face5"]) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch001') # App.ActiveDocument.Sketch001.addExternal("Pad","Edge16") App.ActiveDocument.Sketch001.addExternal( "Pad", uf.getEdge( App.ActiveDocument.Pad, gv.xCarriageWidth, 0, gv.extruderMountAngleThickness, 0, (gv.extruderMountAngleWidth - gv.extruderMountAngleThickness) / 2, 0)) App.ActiveDocument.Sketch001.addExternal( "Pad", uf.getEdge( App.ActiveDocument.Pad, 0, 0, gv.extruderMountAngleThickness, 0, (gv.extruderMountAngleWidth - gv.extruderMountAngleThickness) / 2, 0)) App.ActiveDocument.Sketch001.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 0, 1, -3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Vertical', 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 2, 2, -4)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Vertical', 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Symmetric', -3, 1, -3, 2, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Equal', 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.toggleConstruction(0) App.ActiveDocument.Sketch001.toggleConstruction(1) App.ActiveDocument.Sketch001.toggleConstruction(2) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1), gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 3, 3, 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1), gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 4, 3, 1, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Equal', 4, 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Radius', 3, gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('DistanceY', 0, -gv.xCarriageMountHoleHorizOffset)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #Cut mounting holes through all App.activeDocument().addObject("PartDesign::Pocket", "Pocket") App.activeDocument().Pocket.Sketch = App.activeDocument().Sketch001 App.activeDocument().Pocket.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch001") Gui.activeDocument().hide("Pad") # Gui.ActiveDocument.Pocket.ShapeColor=Gui.ActiveDocument.Pad.ShapeColor # Gui.ActiveDocument.Pocket.LineColor=Gui.ActiveDocument.Pad.LineColor # Gui.ActiveDocument.Pocket.PointColor=Gui.ActiveDocument.Pad.PointColor App.ActiveDocument.Pocket.Length = 5.000000 App.ActiveDocument.Pocket.Type = 1 App.ActiveDocument.Pocket.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Make mounting holes for extruderMountPlate #SketchPoints p1x = (gv.extruderMountAngleWidth + gv.extruderMountAngleThickness) / 2 p1y = gv.xCarriageWidth p2x = p1x p2y = gv.xCarriageWidth - gv.xCarriageMountHoleHorizOffset p3x = p1x p3y = gv.xCarriageMountHoleHorizOffset p4x = p1x p4y = 0 #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch002') App.activeDocument().Sketch002.Support = uf.getFace( App.ActiveDocument.Pocket, None, None, None, None, gv.extruderMountAngleWidth - gv.extruderMountAngleThickness, 0) #(App.ActiveDocument.Pocket,["Face10"]) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch002') App.ActiveDocument.Sketch002.addExternal( "Pocket", uf.getEdge( App.ActiveDocument.Pocket, gv.xCarriageWidth, 0, (gv.extruderMountAngleWidth + gv.extruderMountAngleThickness) / 2, 0, (gv.extruderMountAngleWidth - gv.extruderMountAngleThickness), 0)) App.ActiveDocument.Sketch002.addExternal( "Pocket", uf.getEdge( App.ActiveDocument.Pocket, 0, 0, (gv.extruderMountAngleWidth + gv.extruderMountAngleThickness) / 2, 0, (gv.extruderMountAngleWidth - gv.extruderMountAngleThickness), 0)) App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('PointOnObject', 0, 1, -3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('PointOnObject', 2, 2, -4)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Symmetric', -3, 1, -3, 2, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Equal', 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.toggleConstruction(0) App.ActiveDocument.Sketch002.toggleConstruction(1) App.ActiveDocument.Sketch002.toggleConstruction(2) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1), gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 3, 3, 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1), gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 4, 3, 1, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Equal', 4, 3)) App.ActiveDocument.recompute() #Add dimensions App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Radius', 3, gv.mountToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('DistanceY', 0, -gv.xCarriageMountHoleHorizOffset)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #Cut mounting holes through all App.activeDocument().addObject("PartDesign::Pocket", "Pocket001") App.activeDocument().Pocket001.Sketch = App.activeDocument().Sketch002 App.activeDocument().Pocket001.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch002") Gui.activeDocument().hide("Pocket") # Gui.ActiveDocument.Pocket001.ShapeColor=Gui.ActiveDocument.Pocket.ShapeColor # Gui.ActiveDocument.Pocket001.LineColor=Gui.ActiveDocument.Pocket.LineColor # Gui.ActiveDocument.Pocket001.PointColor=Gui.ActiveDocument.Pocket.PointColor App.ActiveDocument.Pocket001.Length = 5.000000 App.ActiveDocument.Pocket001.Type = 1 App.ActiveDocument.Pocket001.UpToFace = None App.ActiveDocument.recompute()
def execute(self,obj): tol = 1 # tolerance for alignment. This is only visual, we can keep it low... ptol = 0.001 # tolerance for coincident points import math,Part,DraftGeomUtils,ArchCommands if len(obj.Pipes) < 2: return if len(obj.Pipes) > 3: FreeCAD.Console.PrintWarning(translate("Arch","Only the 3 first wires will be connected")+"\n") if obj.Radius.Value == 0: return wires = [] order = [] for o in obj.Pipes: wires.append(o.Proxy.getWire(o)) if wires[0].Vertexes[0].Point.sub(wires[1].Vertexes[0].Point).Length <= ptol: order = ["start","start"] point = wires[0].Vertexes[0].Point elif wires[0].Vertexes[0].Point.sub(wires[1].Vertexes[-1].Point).Length <= ptol: order = ["start","end"] point = wires[0].Vertexes[0].Point elif wires[0].Vertexes[-1].Point.sub(wires[1].Vertexes[-1].Point).Length <= ptol: order = ["end","end"] point = wires[0].Vertexes[-1].Point elif wires[0].Vertexes[-1].Point.sub(wires[1].Vertexes[0].Point).Length <= ptol: order = ["end","start"] point = wires[0].Vertexes[-1].Point else: FreeCAD.Console.PrintError(translate("Arch","Common vertex not found")+"\n") return if order[0] == "start": v1 = wires[0].Vertexes[1].Point.sub(wires[0].Vertexes[0].Point).normalize() else: v1 = wires[0].Vertexes[-2].Point.sub(wires[0].Vertexes[-1].Point).normalize() if order[1] == "start": v2 = wires[1].Vertexes[1].Point.sub(wires[1].Vertexes[0].Point).normalize() else: v2 = wires[1].Vertexes[-2].Point.sub(wires[1].Vertexes[-1].Point).normalize() p = obj.Pipes[0].Proxy.getProfile(obj.Pipes[0]) p = Part.Face(p) if len(obj.Pipes) == 2: if obj.ConnectorType != "Corner": obj.ConnectorType = "Corner" if round(v1.getAngle(v2),tol) in [0,round(math.pi,tol)]: FreeCAD.Console.PrintError(translate("Arch","Pipes are already aligned")+"\n") return normal = v2.cross(v1) offset = math.tan(math.pi/2-v1.getAngle(v2)/2)*obj.Radius.Value v1.multiply(offset) v2.multiply(offset) self.setOffset(obj.Pipes[0],order[0],offset) self.setOffset(obj.Pipes[1],order[1],offset) # find center perp = v1.cross(normal).normalize() perp.multiply(obj.Radius.Value) center = point.add(v1).add(perp) # move and rotate the profile to the first point delta = point.add(v1)-p.CenterOfMass p.translate(delta) vp = DraftGeomUtils.getNormal(p) rot = FreeCAD.Rotation(vp,v1) p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle)) sh = p.revolve(center,normal,math.degrees(math.pi-v1.getAngle(v2))) #sh = Part.makeCompound([sh]+[Part.Vertex(point),Part.Vertex(point.add(v1)),Part.Vertex(center),Part.Vertex(point.add(v2))]) else: if obj.ConnectorType != "Tee": obj.ConnectorType = "Tee" if wires[2].Vertexes[0].Point == point: order.append("start") elif wires[0].Vertexes[-1].Point == point: order.append("end") else: FreeCAD.Console.PrintError(translate("Arch","Common vertex not found")+"\n") if order[2] == "start": v3 = wires[2].Vertexes[1].Point.sub(wires[2].Vertexes[0].Point).normalize() else: v3 = wires[2].Vertexes[-2].Point.sub(wires[2].Vertexes[-1].Point).normalize() if round(v1.getAngle(v2),tol) in [0,round(math.pi,tol)]: pair = [v1,v2,v3] elif round(v1.getAngle(v3),tol) in [0,round(math.pi,tol)]: pair = [v1,v3,v2] elif round(v2.getAngle(v3),tol) in [0,round(math.pi,tol)]: pair = [v2,v3,v1] else: FreeCAD.Console.PrintError(translate("Arch","At least 2 pipes must align")+"\n") return offset = obj.Radius.Value v1.multiply(offset) v2.multiply(offset) v3.multiply(offset) self.setOffset(obj.Pipes[0],order[0],offset) self.setOffset(obj.Pipes[1],order[1],offset) self.setOffset(obj.Pipes[2],order[2],offset) normal = pair[0].cross(pair[2]) # move and rotate the profile to the first point delta = point.add(pair[0])-p.CenterOfMass p.translate(delta) vp = DraftGeomUtils.getNormal(p) rot = FreeCAD.Rotation(vp,pair[0]) p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle)) t1 = p.extrude(pair[1].multiply(2)) # move and rotate the profile to the second point delta = point.add(pair[2])-p.CenterOfMass p.translate(delta) vp = DraftGeomUtils.getNormal(p) rot = FreeCAD.Rotation(vp,pair[2]) p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle)) t2 = p.extrude(pair[2].negative().multiply(2)) # create a cut plane cp = Part.makePolygon([point,point.add(pair[0]),point.add(normal),point]) cp = Part.Face(cp) if cp.normalAt(0,0).getAngle(pair[2]) < math.pi/2: cp.reverse() cf, cv, invcv = ArchCommands.getCutVolume(cp,t2) t2 = t2.cut(cv) sh = t1.fuse(t2) obj.Shape = sh
def _create_objects(doc=None, font_file="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" ): """Create the objects of the test file. Parameters ---------- doc: App::Document, optional It defaults to `None`, which then defaults to the current active document, or creates a new document. """ if not doc: doc = App.activeDocument() if not doc: doc = App.newDocument() # Line, wire, and fillet _msg(16 * "-") _msg("Line") Draft.make_line(Vector(0, 0, 0), Vector(500, 500, 0)) t_xpos = -50 t_ypos = -200 _set_text(["Line"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Wire") Draft.make_wire( [Vector(500, 0, 0), Vector(1000, 500, 0), Vector(1000, 1000, 0)]) t_xpos += 500 _set_text(["Wire"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Fillet") line_h_1 = Draft.make_line(Vector(1500, 0, 0), Vector(1500, 500, 0)) line_h_2 = Draft.make_line(Vector(1500, 500, 0), Vector(2000, 500, 0)) if App.GuiUp: line_h_1.ViewObject.DrawStyle = "Dotted" line_h_2.ViewObject.DrawStyle = "Dotted" doc.recompute() Draft.make_fillet([line_h_1, line_h_2], 400) t_xpos += 900 _set_text(["Fillet"], Vector(t_xpos, t_ypos, 0)) # Circle, arc, arc by 3 points _msg(16 * "-") _msg("Circle") circle = Draft.make_circle(350) circle.Placement.Base = Vector(2500, 500, 0) t_xpos += 1050 _set_text(["Circle"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Circular arc") arc = Draft.make_circle(350, startangle=0, endangle=100) arc.Placement.Base = Vector(3200, 500, 0) t_xpos += 800 _set_text(["Circular arc"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Circular arc 3 points") Draft.make_arc_3points( [Vector(4600, 0, 0), Vector(4600, 800, 0), Vector(4000, 1000, 0)]) t_xpos += 600 _set_text(["Circular arc 3 points"], Vector(t_xpos, t_ypos, 0)) # Ellipse, polygon, rectangle _msg(16 * "-") _msg("Ellipse") ellipse = Draft.make_ellipse(500, 300) ellipse.Placement.Base = Vector(5500, 250, 0) t_xpos += 1600 _set_text(["Ellipse"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Polygon") polygon = Draft.make_polygon(5, 250) polygon.Placement.Base = Vector(6500, 500, 0) t_xpos += 950 _set_text(["Polygon"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Rectangle") rectangle = Draft.make_rectangle(500, 1000, 0) rectangle.Placement.Base = Vector(7000, 0, 0) t_xpos += 650 _set_text(["Rectangle"], Vector(t_xpos, t_ypos, 0)) # Text _msg(16 * "-") _msg("Text") text = Draft.make_text(["Testing", "text"], Vector(7700, 500, 0)) if App.GuiUp: text.ViewObject.FontSize = 100 t_xpos += 700 _set_text(["Text"], Vector(t_xpos, t_ypos, 0)) # Linear dimension _msg(16 * "-") _msg("Linear dimension") line = Draft.make_wire([Vector(8700, 200, 0), Vector(8700, 1200, 0)]) dimension = Draft.make_linear_dimension(Vector(8600, 200, 0), Vector(8600, 1000, 0), Vector(8400, 750, 0)) if App.GuiUp: dimension.ViewObject.ArrowSize = 15 dimension.ViewObject.ExtLines = 1000 dimension.ViewObject.ExtOvershoot = 100 dimension.ViewObject.DimOvershoot = 50 dimension.ViewObject.FontSize = 100 dimension.ViewObject.ShowUnit = False doc.recompute() dim_obj = Draft.make_linear_dimension_obj(line, 1, 2, Vector(9000, 750, 0)) if App.GuiUp: dim_obj.ViewObject.ArrowSize = 15 dim_obj.ViewObject.ArrowType = "Arrow" dim_obj.ViewObject.ExtLines = 100 dim_obj.ViewObject.ExtOvershoot = 100 dim_obj.ViewObject.DimOvershoot = 50 dim_obj.ViewObject.FontSize = 100 dim_obj.ViewObject.ShowUnit = False t_xpos += 680 _set_text(["Dimension"], Vector(t_xpos, t_ypos, 0)) # Radius and diameter dimension _msg(16 * "-") _msg("Radius and diameter dimension") arc_h = Draft.make_circle(500, startangle=0, endangle=90) arc_h.Placement.Base = Vector(9500, 0, 0) doc.recompute() dimension_r = Draft.make_radial_dimension_obj(arc_h, 1, "radius", Vector(9750, 200, 0)) if App.GuiUp: dimension_r.ViewObject.ArrowSize = 15 dimension_r.ViewObject.FontSize = 100 dimension_r.ViewObject.ShowUnit = False arc_h2 = Draft.make_circle(450, startangle=-120, endangle=80) arc_h2.Placement.Base = Vector(10000, 1000, 0) doc.recompute() dimension_d = Draft.make_radial_dimension_obj(arc_h2, 1, "diameter", Vector(10750, 900, 0)) if App.GuiUp: dimension_d.ViewObject.ArrowSize = 15 dimension_d.ViewObject.FontSize = 100 dimension_d.ViewObject.ShowUnit = False t_xpos += 950 _set_text(["Radius dimension", "Diameter dimension"], Vector(t_xpos, t_ypos, 0)) # Angular dimension _msg(16 * "-") _msg("Angular dimension") Draft.make_line(Vector(10500, 300, 0), Vector(11500, 1000, 0)) Draft.make_line(Vector(10500, 300, 0), Vector(11500, 0, 0)) angle1 = -20 angle2 = 40 dimension_a = Draft.make_angular_dimension(Vector(10500, 300, 0), [angle1, angle2], Vector(11500, 300, 0)) if App.GuiUp: dimension_a.ViewObject.ArrowSize = 15 dimension_a.ViewObject.FontSize = 100 t_xpos += 1700 _set_text(["Angle dimension"], Vector(t_xpos, t_ypos, 0)) # BSpline _msg(16 * "-") _msg("BSpline") Draft.make_bspline([ Vector(12500, 0, 0), Vector(12500, 500, 0), Vector(13000, 500, 0), Vector(13000, 1000, 0) ]) t_xpos += 1500 _set_text(["BSpline"], Vector(t_xpos, t_ypos, 0)) # Point _msg(16 * "-") _msg("Point") point = Draft.make_point(13500, 500, 0) if App.GuiUp: point.ViewObject.PointSize = 10 t_xpos += 900 _set_text(["Point"], Vector(t_xpos, t_ypos, 0)) # Shapestring _msg(16 * "-") _msg("Shapestring") try: shape_string = Draft.make_shapestring("Testing", font_file, 100) shape_string.Placement.Base = Vector(14000, 500) except Exception: _wrn("Shapestring could not be created") _wrn("Possible cause: the font file may not exist") _wrn(font_file) rect = Draft.make_rectangle(500, 100) rect.Placement.Base = Vector(14000, 500) t_xpos += 600 _set_text(["Shapestring"], Vector(t_xpos, t_ypos, 0)) # Facebinder _msg(16 * "-") _msg("Facebinder") box = doc.addObject("Part::Box", "Cube") box.Length = 200 box.Width = 500 box.Height = 100 box.Placement.Base = Vector(15000, 0, 0) if App.GuiUp: box.ViewObject.Visibility = False facebinder = Draft.make_facebinder([(box, ("Face1", "Face3", "Face6"))]) facebinder.Extrusion = 10 t_xpos += 780 _set_text(["Facebinder"], Vector(t_xpos, t_ypos, 0)) # Cubic bezier curve, n-degree bezier curve _msg(16 * "-") _msg("Cubic bezier") Draft.make_bezcurve([ Vector(15500, 0, 0), Vector(15578, 485, 0), Vector(15879, 154, 0), Vector(15975, 400, 0), Vector(16070, 668, 0), Vector(16423, 925, 0), Vector(16500, 500, 0) ], degree=3) t_xpos += 680 _set_text(["Cubic bezier"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("N-degree bezier") Draft.make_bezcurve([ Vector(16500, 0, 0), Vector(17000, 500, 0), Vector(17500, 500, 0), Vector(17500, 1000, 0), Vector(17000, 1000, 0), Vector(17063, 1256, 0), Vector(17732, 1227, 0), Vector(17790, 720, 0), Vector(17702, 242, 0) ]) t_xpos += 1200 _set_text(["n-Bezier"], Vector(t_xpos, t_ypos, 0)) # Label _msg(16 * "-") _msg("Label") place = App.Placement(Vector(18500, 500, 0), App.Rotation()) label = Draft.make_label(target_point=Vector(18000, 0, 0), placement=place, custom_text="Example label", distance=-250) label.Text = "Testing" if App.GuiUp: label.ViewObject.ArrowSize = 15 label.ViewObject.TextSize = 100 doc.recompute() t_xpos += 1200 _set_text(["Label"], Vector(t_xpos, t_ypos, 0)) # Orthogonal array and orthogonal link array _msg(16 * "-") _msg("Orthogonal array") rect_h = Draft.make_rectangle(500, 500) rect_h.Placement.Base = Vector(1500, 2500, 0) if App.GuiUp: rect_h.ViewObject.Visibility = False Draft.make_ortho_array(rect_h, Vector(600, 0, 0), Vector(0, 600, 0), Vector(0, 0, 0), 3, 2, 1, use_link=False) t_xpos = 1700 t_ypos = 2200 _set_text(["Array"], Vector(t_xpos, t_ypos, 0)) rect_h_2 = Draft.make_rectangle(500, 100) rect_h_2.Placement.Base = Vector(1500, 5000, 0) if App.GuiUp: rect_h_2.ViewObject.Visibility = False _msg(16 * "-") _msg("Orthogonal link array") Draft.make_ortho_array(rect_h_2, Vector(800, 0, 0), Vector(0, 500, 0), Vector(0, 0, 0), 2, 4, 1, use_link=True) t_ypos += 2600 _set_text(["Link array"], Vector(t_xpos, t_ypos, 0)) # Polar array and polar link array _msg(16 * "-") _msg("Polar array") wire_h = Draft.make_wire([ Vector(5500, 3000, 0), Vector(6000, 3500, 0), Vector(6000, 3200, 0), Vector(5800, 3200, 0) ]) if App.GuiUp: wire_h.ViewObject.Visibility = False Draft.make_polar_array(wire_h, 8, 200, Vector(5000, 3000, 0), use_link=False) t_xpos = 4600 t_ypos = 2200 _set_text(["Polar array"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Polar link array") wire_h_2 = Draft.make_wire([ Vector(5500, 6000, 0), Vector(6000, 6000, 0), Vector(5800, 5700, 0), Vector(5800, 5750, 0) ]) if App.GuiUp: wire_h_2.ViewObject.Visibility = False Draft.make_polar_array(wire_h_2, 8, 200, Vector(5000, 6000, 0), use_link=True) t_ypos += 3200 _set_text(["Polar link array"], Vector(t_xpos, t_ypos, 0)) # Circular array and circular link array _msg(16 * "-") _msg("Circular array") poly_h = Draft.make_polygon(5, 200) poly_h.Placement.Base = Vector(8000, 3000, 0) if App.GuiUp: poly_h.ViewObject.Visibility = False Draft.make_circular_array(poly_h, 500, 600, 3, 1, Vector(0, 0, 1), Vector(0, 0, 0), use_link=False) t_xpos = 7700 t_ypos = 1700 _set_text(["Circular array"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Circular link array") poly_h_2 = Draft.make_polygon(6, 150) poly_h_2.Placement.Base = Vector(8000, 6250, 0) if App.GuiUp: poly_h_2.ViewObject.Visibility = False Draft.make_circular_array(poly_h_2, 550, 450, 3, 1, Vector(0, 0, 1), Vector(0, 0, 0), use_link=True) t_ypos += 3100 _set_text(["Circular link array"], Vector(t_xpos, t_ypos, 0)) # Path array and path link array _msg(16 * "-") _msg("Path array") poly_h = Draft.make_polygon(3, 250) poly_h.Placement.Base = Vector(10000, 3000, 0) if App.GuiUp: poly_h.ViewObject.Visibility = False bspline_path = Draft.make_bspline([ Vector(10500, 2500, 0), Vector(11000, 3000, 0), Vector(11500, 3200, 0), Vector(12000, 4000, 0) ]) Draft.make_path_array(poly_h, bspline_path, 5, use_link=False) t_xpos = 10400 t_ypos = 2200 _set_text(["Path array"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Path link array") poly_h_2 = Draft.make_polygon(4, 200) poly_h_2.Placement.Base = Vector(10000, 5000, 0) if App.GuiUp: poly_h_2.ViewObject.Visibility = False bspline_path_2 = Draft.make_bspline([ Vector(10500, 4500, 0), Vector(11000, 6800, 0), Vector(11500, 6000, 0), Vector(12000, 5200, 0) ]) Draft.make_path_array(poly_h_2, bspline_path_2, 6, use_link=True) t_ypos += 2000 _set_text(["Path link array"], Vector(t_xpos, t_ypos, 0)) # Point array _msg(16 * "-") _msg("Point array") poly_h = Draft.make_polygon(3, 250) poly_h.Placement.Base = Vector(12500, 2500, 0) point_1 = Draft.make_point(13000, 3000, 0) point_2 = Draft.make_point(13000, 3500, 0) point_3 = Draft.make_point(14000, 2500, 0) point_4 = Draft.make_point(14000, 3000, 0) add_list, delete_list = Draft.upgrade([point_1, point_2, point_3, point_4]) compound = add_list[0] if App.GuiUp: compound.ViewObject.PointSize = 5 Draft.make_point_array(poly_h, compound) t_xpos = 13000 t_ypos = 2200 _set_text(["Point array"], Vector(t_xpos, t_ypos, 0)) # Clone and mirror _msg(16 * "-") _msg("Clone") wire_h = Draft.make_wire([ Vector(15000, 2500, 0), Vector(15200, 3000, 0), Vector(15500, 2500, 0), Vector(15200, 2300, 0) ]) Draft.make_clone(wire_h, Vector(0, 1000, 0)) t_xpos = 15000 t_ypos = 2100 _set_text(["Clone"], Vector(t_xpos, t_ypos, 0)) _msg(16 * "-") _msg("Mirror") wire_h = Draft.make_wire([ Vector(17000, 2500, 0), Vector(16500, 4000, 0), Vector(16000, 2700, 0), Vector(16500, 2500, 0), Vector(16700, 2700, 0) ]) Draft.mirror(wire_h, Vector(17100, 2000, 0), Vector(17100, 4000, 0)) t_xpos = 17000 t_ypos = 2200 _set_text(["Mirror"], Vector(t_xpos, t_ypos, 0)) doc.recompute()
def setProperties(self,vobj): pl = vobj.PropertiesList if not "LineWidth" in pl: vobj.addProperty("App::PropertyFloat","LineWidth","BuildingPart",QT_TRANSLATE_NOOP("App::Property","The line width of this object")) vobj.LineWidth = 1 if not "OverrideUnit" in pl: vobj.addProperty("App::PropertyString","OverrideUnit","BuildingPart",QT_TRANSLATE_NOOP("App::Property","An optional unit to express levels")) if not "DisplayOffset" in pl: vobj.addProperty("App::PropertyPlacement","DisplayOffset","BuildingPart",QT_TRANSLATE_NOOP("App::Property","A transformation to apply to the level mark")) vobj.DisplayOffset = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90)) if not "ShowLevel" in pl: vobj.addProperty("App::PropertyBool","ShowLevel","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If true, show the level")) vobj.ShowLevel = True if not "ShowUnit" in pl: vobj.addProperty("App::PropertyBool","ShowUnit","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If true, show the unit on the level tag")) if not "OriginOffset" in pl: vobj.addProperty("App::PropertyBool","OriginOffset","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If true, display offset will affect the origin mark too")) if not "ShowLabel" in pl: vobj.addProperty("App::PropertyBool","ShowLabel","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If true, the object's label is displayed")) vobj.ShowLabel = True if not "FontName" in pl: vobj.addProperty("App::PropertyFont","FontName","BuildingPart",QT_TRANSLATE_NOOP("App::Property","The font to be used for texts")) vobj.FontName = Draft.getParam("textfont","Arial") if not "FontSize" in pl: vobj.addProperty("App::PropertyLength","FontSize","BuildingPart",QT_TRANSLATE_NOOP("App::Property","The font size of texts")) vobj.FontSize = Draft.getParam("textheight",2.0) if not "DiffuseColor" in pl: vobj.addProperty("App::PropertyColorList","DiffuseColor","BuildingPart",QT_TRANSLATE_NOOP("App::Property","The individual face colors")) # Interaction properties if not "SetWorkingPlane" in pl: vobj.addProperty("App::PropertyBool","SetWorkingPlane","Interaction",QT_TRANSLATE_NOOP("App::Property","If true, when activated, the working plane will automatically adapt to this level")) vobj.SetWorkingPlane = True if not "AutoWorkingPlane" in pl: vobj.addProperty("App::PropertyBool","AutoWorkingPlane","Interaction",QT_TRANSLATE_NOOP("App::Property","If set to True, the working plane will be kept on Auto mode")) if not "ViewData" in pl: vobj.addProperty("App::PropertyFloatList","ViewData","Interaction",QT_TRANSLATE_NOOP("App::Property","Camera position data associated with this object")) vobj.setEditorMode("ViewData",2) if not "RestoreView" in pl: vobj.addProperty("App::PropertyBool","RestoreView","Interaction",QT_TRANSLATE_NOOP("App::Property","If set, the view stored in this object will be restored on double-click")) if not "DoubleClickActivates" in pl: vobj.addProperty("App::PropertyBool","DoubleClickActivates","Interaction",QT_TRANSLATE_NOOP("App::Property","If True, double-clicking this object in the tree activates it")) # inventor saving if not "SaveInventor" in pl: vobj.addProperty("App::PropertyBool","SaveInventor","Interaction",QT_TRANSLATE_NOOP("App::Property","If this is enabled, the inventor representation of this object will be saved in the FreeCAD file, allowing to reference it in other files in lightweight mode.")) if not "SavedInventor" in pl: vobj.addProperty("App::PropertyFileIncluded","SavedInventor","Interaction",QT_TRANSLATE_NOOP("App::Property","A slot to save the inventor representation of this object, if enabled")) vobj.setEditorMode("SavedInventor",2) # children properties if not "ChildrenOverride" in pl: vobj.addProperty("App::PropertyBool","ChildrenOverride","Children",QT_TRANSLATE_NOOP("App::Property","If true, show the objects contained in this Building Part will adopt these line, color and transparency settings")) if not "ChildrenLineWidth" in pl: vobj.addProperty("App::PropertyFloat","ChildrenLineWidth","Children",QT_TRANSLATE_NOOP("App::Property","The line width of child objects")) vobj.LineWidth = 1 if not "ChildrenLineColor" in pl: vobj.addProperty("App::PropertyColor","ChildrenLineColor","Children",QT_TRANSLATE_NOOP("App::Property","The line color of child objects")) c = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View").GetUnsigned("DefaultShapeLineColor",255) vobj.ChildrenLineColor = (float((c>>24)&0xFF)/255.0,float((c>>16)&0xFF)/255.0,float((c>>8)&0xFF)/255.0,0.0) if not "ChildrenShapeColor" in pl: vobj.addProperty("App::PropertyColor","ChildrenShapeColor","Children",QT_TRANSLATE_NOOP("App::Property","The shape color of child objects")) c = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View").GetUnsigned("DefaultShapeColor",4294967295) vobj.ChildrenLineColor = (float((c>>24)&0xFF)/255.0,float((c>>16)&0xFF)/255.0,float((c>>8)&0xFF)/255.0,0.0) if not "ChildrenTransparency" in pl: vobj.addProperty("App::PropertyPercent","ChildrenTransparency","Children",QT_TRANSLATE_NOOP("App::Property","The transparency of child objects")) # clip properties if not "CutView" in pl: vobj.addProperty("App::PropertyBool","CutView","Clip",QT_TRANSLATE_NOOP("App::Property","Cut the view above this level")) if not "CutMargin" in pl: vobj.addProperty("App::PropertyLength","CutMargin","Clip",QT_TRANSLATE_NOOP("App::Property","The distance between the level plane and the cut line")) vobj.CutMargin = 1600 if not "AutoCutView" in pl: vobj.addProperty("App::PropertyBool","AutoCutView","Clip",QT_TRANSLATE_NOOP("App::Property","Turn cutting on when activating this level")) # autogroup properties if not "AutogroupSize" in pl: vobj.addProperty("App::PropertyIntegerList","AutogroupSize","AutoGroup",QT_TRANSLATE_NOOP("App::Property","The capture box for newly created objects expressed as [XMin,YMin,ZMin,XMax,YMax,ZMax]")) if not "AutogroupBox" in pl: vobj.addProperty("App::PropertyBool","AutogroupBox","AutoGroup",QT_TRANSLATE_NOOP("App::Property","Turns auto group box on/off")) if not "AutogroupAutosize" in pl: vobj.addProperty("App::PropertyBool","AutogroupAutosize","AutoGroup",QT_TRANSLATE_NOOP("App::Property","Automatically set size from contents")) if not "AutogroupMargin" in pl: vobj.addProperty("App::PropertyLength","AutogroupMargin","AutoGroup",QT_TRANSLATE_NOOP("App::Property","A margin to use when autosize is turned on"))
def draw(self): if self.side == "Right": self.rodDia = gv.yRodDiaR self.bushingNutFaceToFace = gv.yBushingNutR[2] self.bushingNutThickness = gv.yBushingNutR[3] elif self.side == "Left": self.rodDia = gv.yRodDiaL self.bushingNutFaceToFace = gv.yBushingNutL[2] self.bushingNutThickness = gv.yBushingNutL[3] #helper Variables columnWidth = gv.PBBHMaxFaceToFace / math.cos( math.pi / 6) + 2 * gv.bushingNutPadding #Make file and build part try: Gui.getDocument(self.name) Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() App.closeDocument(self.name) App.setActiveDocument("") App.ActiveDocument = None Gui.ActiveDocument = None except: pass #Create Document App.newDocument(self.name) App.setActiveDocument(self.name) App.ActiveDocument = App.getDocument(self.name) Gui.ActiveDocument = Gui.getDocument(self.name) #Make base #Sketch points p1x = -gv.printBedBusingSupportWidth / 2 p1y = -gv.PBBHDepth / 2 p2x = -gv.printBedBusingSupportWidth / 2 p2y = gv.PBBHDepth / 2 p3x = gv.printBedBusingSupportWidth / 2 p3y = gv.PBBHDepth / 2 p4x = gv.printBedBusingSupportWidth / 2 p4y = -gv.PBBHDepth / 2 #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.000000, 0.000000, 0.000000, 1.000000)) Gui.activeDocument().activeView().setCamera( '#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA \n position 0 0 87 \n orientation 0 0 1 0 \n nearDistance -112.88701 \n farDistance 287.28702 \n aspectRatio 1 \n focalDistance 87 \n height 143.52005 }' ) # Gui.activeDocument().setEdit('Sketch') App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.Sketch.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 0, 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 0)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Horizontal', 2)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Vertical', 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Symmetric', 1, 2, 0, 1, -1, 1)) App.ActiveDocument.recompute() #add dimensions App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceY', 1, gv.PBBHDepth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('DistanceX', 0, gv.printBedBusingSupportWidth)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #Pad base App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch") App.ActiveDocument.Pad.Length = gv.tabThickness App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Cut slot on right side #Sketch points p1x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 - gv.slotWidth p1y = 0 p2x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 p2y = 0 p3x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 - gv.slotWidth p3y = -gv.printedToPrintedDia / 2 p4x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 - gv.slotWidth p4y = gv.printedToPrintedDia / 2 p5x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 p5y = gv.printedToPrintedDia / 2 p6x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding - gv.printedToPrintedDia / 2 p6y = -gv.printedToPrintedDia / 2 p7x = gv.printBedBusingSupportWidth / 2 - gv.slotPadding p7y = 0 #Make sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch001') App.activeDocument().Sketch001.Support = uf.getFace( App.ActiveDocument.Pad, None, None, None, None, gv.tabThickness, 0) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch001') App.ActiveDocument.Sketch001.addExternal( "Pad", uf.getEdge(App.ActiveDocument.Pad, 0, 1, 0, 0, gv.tabThickness, 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.ArcOfCircle( Part.Circle(App.Vector(p1x, p1y, 0), App.Vector(0, 0, 1), 4.217310), math.pi / 2, -math.pi / 2)) App.ActiveDocument.Sketch001.addGeometry( Part.ArcOfCircle( Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1), 4.217310), -math.pi / 2, math.pi / 2)) App.ActiveDocument.Sketch001.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p6x, p6y, 0))) App.ActiveDocument.Sketch001.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0))) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Tangent', 0, 2)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Tangent', 0, 3)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Tangent', 1, 2)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Tangent', 1, 3)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 0, 1, 3, 1)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 2, 1)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 1, 1)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 1, 2)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Horizontal', 2)) App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Equal', 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 0, 3, -1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addGeometry( Part.Point(App.Vector(32.724319, -0.106919, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 4, 1, -1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('PointOnObject', 4, 1, 1)) #add dimensions App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('DistanceX', 2, gv.slotWidth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Radius', 1, gv.printedToPrintedDia / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch001.addConstraint( Sketcher.Constraint('Distance', 4, 1, -3, gv.slotPadding)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #Cut slot through all App.activeDocument().addObject("PartDesign::Pocket", "Pocket") App.activeDocument().Pocket.Sketch = App.activeDocument().Sketch001 App.activeDocument().Pocket.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch001") Gui.activeDocument().hide("Pad") # Gui.ActiveDocument.Pocket.ShapeColor=Gui.ActiveDocument.Pad.ShapeColor # Gui.ActiveDocument.Pocket.LineColor=Gui.ActiveDocument.Pad.LineColor # Gui.ActiveDocument.Pocket.PointColor=Gui.ActiveDocument.Pad.PointColor App.ActiveDocument.Pocket.Length = 5.000000 App.ActiveDocument.Pocket.Type = 1 App.ActiveDocument.Pocket.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Mirror the slot App.activeDocument().addObject("PartDesign::Mirrored", "Mirrored") App.ActiveDocument.recompute() App.activeDocument().Mirrored.Originals = [ App.activeDocument().Pocket, ] App.activeDocument().Mirrored.MirrorPlane = ( App.activeDocument().Sketch001, ["V_Axis"]) Gui.activeDocument().Pocket.Visibility = False # Gui.activeDocument().setEdit('Mirrored') # Gui.ActiveDocument.Mirrored.ShapeColor=Gui.ActiveDocument.Pocket.ShapeColor # Gui.ActiveDocument.Mirrored.DisplayMode=Gui.ActiveDocument.Pocket.DisplayMode App.ActiveDocument.Mirrored.Originals = [ App.ActiveDocument.Pocket, ] App.ActiveDocument.Mirrored.MirrorPlane = ( App.ActiveDocument.Sketch001, ["V_Axis"]) App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() #Make bushing holder column #Sketch Points p1x = -columnWidth / 2 p1y = gv.tabThickness p2x = -columnWidth / 2 p2y = gv.PBBHStandoff p3x = 0 p3y = gv.PBBHStandoff p4x = columnWidth / 2 p4y = gv.PBBHStandoff p5x = columnWidth / 2 p5y = gv.tabThickness #Make Sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch002') App.activeDocument().Sketch002.Support = uf.getFace( App.ActiveDocument.Mirrored, 0, 0, -gv.PBBHDepth / 2, 0, None, None) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch002') App.ActiveDocument.Sketch002.addExternal( "Mirrored", uf.getEdge(App.ActiveDocument.Mirrored, 0, 0, -gv.PBBHDepth / 2, 0, gv.tabThickness, 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('PointOnObject', 0, 1, -3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 0)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.ArcOfCircle( Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1), self.rodDia / 2 + gv.bushingNutRodGap), 0, math.pi)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('PointOnObject', 1, 3, -2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 2, 1, 1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('PointOnObject', 2, 2, -3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Vertical', 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Line(App.Vector(p5x, p5y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 3, 1, 2, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Equal', 0, 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Symmetric', 1, 1, 0, 2, 1, 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addGeometry( Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1), self.rodDia / 2 + gv.bushingNutRodGap)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Coincident', 4, 3, 1, 3)) App.ActiveDocument.recompute() #Add dimensions App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Distance', 0, 1, 2, 2, columnWidth)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Distance', -1, 1, 1, 3, gv.PBBHStandoff)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch002.addConstraint( Sketcher.Constraint('Radius', 4, self.rodDia / 2 + gv.bushingNutRodGap)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #Extrude column App.activeDocument().addObject("PartDesign::Pad", "Pad001") App.activeDocument().Pad001.Sketch = App.activeDocument().Sketch002 App.activeDocument().Pad001.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch002") Gui.activeDocument().hide("Mirrored") # Gui.ActiveDocument.Pad001.ShapeColor=Gui.ActiveDocument.Mirrored.ShapeColor # Gui.ActiveDocument.Pad001.LineColor=Gui.ActiveDocument.Mirrored.LineColor # Gui.ActiveDocument.Pad001.PointColor=Gui.ActiveDocument.Mirrored.PointColor App.ActiveDocument.Pad001.Length = gv.PBBHDepth App.ActiveDocument.Pad001.Reversed = 1 App.ActiveDocument.Pad001.Midplane = 0 App.ActiveDocument.Pad001.Length2 = 100.000000 App.ActiveDocument.Pad001.Type = 0 App.ActiveDocument.Pad001.UpToFace = None App.ActiveDocument.recompute() # Gui.activeDocument().resetEdit() # Gui.activeDocument().activeView().viewAxometric() #Refine shape App.ActiveDocument.addObject( 'Part::Feature', 'Pad002').Shape = App.ActiveDocument.Pad001.Shape.removeSplitter() App.ActiveDocument.ActiveObject.Label = App.ActiveDocument.Pad001.Label Gui.ActiveDocument.Pad001.hide() # Gui.ActiveDocument.ActiveObject.ShapeColor=Gui.ActiveDocument.Pad001.ShapeColor # Gui.ActiveDocument.ActiveObject.LineColor=Gui.ActiveDocument.Pad001.LineColor # Gui.ActiveDocument.ActiveObject.PointColor=Gui.ActiveDocument.Pad001.PointColor App.ActiveDocument.recompute() #make bushing nut trap #Sketch Points mat = uf.hexagonPoints(0, gv.PBBHStandoff, self.bushingNutFaceToFace, 0) p1x = mat[0][0] p1y = mat[0][1] p2x = mat[1][0] p2y = mat[1][1] p3x = mat[2][0] p3y = mat[2][1] p4x = mat[3][0] p4y = mat[3][1] p5x = mat[4][0] p5y = mat[4][1] p6x = mat[5][0] p6y = mat[5][1] p7x = mat[6][0] p7y = mat[6][1] hexRadius = mat[7][0] App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch003') App.activeDocument().Sketch003.Support = uf.getFace( App.ActiveDocument.Pad002, 0, 0, -gv.PBBHDepth / 2, 0, None, None) App.activeDocument().recompute() # Gui.activeDocument().setEdit('Sketch003') App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 0, 2, 1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 1, 2, 2, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0))) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 2, 2, 3, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p5x, p5y, 0), App.Vector(p6x, p6y, 0))) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 3, 2, 4, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Line(App.Vector(p6x, p6y, 0), App.Vector(p1x, p1y, 0))) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 4, 2, 5, 1)) App.ActiveDocument.recompute() App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', 5, 2, 0, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addGeometry( Part.Circle(App.Vector(p7x, p7y, 0), App.Vector(0, 0, 1), hexRadius)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 0, 1, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 0, 2, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 1, 2, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 2, 2, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 3, 2, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('PointOnObject', 4, 2, 6)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Equal', 5, 0)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Equal', 0, 1)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Equal', 1, 2)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Equal', 2, 3)) App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Equal', 3, 4)) App.ActiveDocument.Sketch003.toggleConstruction(6) App.ActiveDocument.Sketch003.addExternal( "Pad002", uf.getEdge(App.ActiveDocument.Pad002, 0, 0, -gv.PBBHDepth / 2, 0, None, None, radius=self.rodDia / 2 + gv.bushingNutRodGap)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Coincident', -3, 3, 6, 3)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Horizontal', 4)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch003.addConstraint( Sketcher.Constraint('Distance', 0, 2, 4, self.bushingNutFaceToFace)) App.ActiveDocument.recompute() # Gui.getDocument(self.name).resetEdit() App.getDocument(self.name).recompute() #cut nut trap out App.activeDocument().addObject("PartDesign::Pocket", "Pad003") App.activeDocument().Pad003.Sketch = App.activeDocument().Sketch003 App.activeDocument().Pad003.Length = 5.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch003") Gui.activeDocument().hide("Pad002") # Gui.ActiveDocument.Pad003.ShapeColor=Gui.ActiveDocument.Pad001.ShapeColor # Gui.ActiveDocument.Pad003.LineColor=Gui.ActiveDocument.Pad001.LineColor # Gui.ActiveDocument.Pad003.PointColor=Gui.ActiveDocument.Pad001.PointColor App.ActiveDocument.Pad003.Length = gv.yBushingNutR[3] App.ActiveDocument.Pad003.Type = 0 App.ActiveDocument.Pad003.UpToFace = None App.ActiveDocument.recompute()
def addtofreecad(self,doc=None,fcpar=None): def center(obj,x,y,z): obj.Placement = FreeCAD.Placement(\ FreeCAD.Vector(-x/2.0,-y/2.0,-z/2.0),\ FreeCAD.Rotation(0,0,0,1)) import FreeCAD,Part if not doc: doc=FreeCAD.newDocument() namel=self.name.lower() multifeature={'union':"Part::MultiFuse",'imp_union':"Part::MultiFuse", 'intersection':"Part::MultiCommon"} if namel in multifeature: if len(self.children)>1: obj=doc.addObject(multifeature[namel],namel) subobjs = [child.addtofreecad(doc,obj) for child in self.children] obj.Shapes = subobjs for subobj in subobjs: subobj.ViewObject.hide() elif len(self.children)==1: obj = self.children[0].addtofreecad(doc,fcpar or True) else: obj = fcpar elif namel == 'difference': if len(self.children)==1: obj = self.children[0].addtofreecad(doc,fcpar or True) else: obj=doc.addObject("Part::Cut",namel) base = self.children[0].addtofreecad(doc,obj) if len(self.children)==2: tool = self.children[1].addtofreecad(doc,obj) else: tool = Node(name='imp_union',\ children=self.children[1:]).addtofreecad(doc,obj) obj.Base = base obj.Tool = tool base.ViewObject.hide() tool.ViewObject.hide() elif namel == 'cube': obj=doc.addObject('Part::Box',namel) x,y,z=self.arguments['size'] obj.Length=x obj.Width=y obj.Height=z if self.arguments['center']: center(obj,x,y,z) elif namel == 'sphere': obj=doc.addObject("Part::Sphere",namel) obj.Radius = self.arguments['r'] elif namel == 'cylinder': h = self.arguments['h'] r1 ,r2 = self.arguments['r1'], self.arguments['r2'] if '$fn' in self.arguments and self.arguments['$fn'] > 2 \ and self.arguments['$fn']<=Node.fnmin: if r1 == r2: import Draft base = Draft.makePolygon(int(self.arguments['$fn']),r1) obj = doc.addObject("Part::Extrusion",'prism') obj.Base= base obj.Dir = (0,0,h) if self.arguments['center']: center(obj,0,0,h) base.ViewObject.hide() elif True: #use Frustum Feature with makeRuledSurface obj=doc.addObject("Part::FeaturePython",'frustum') Frustum(obj,r1,r2,int(self.arguments['$fn']),h) ViewProviderTree(obj.ViewObject) if self.arguments['center']: center(obj,0,0,h) else: #Use Part::Loft and GetWire Feature obj=doc.addObject('Part::Loft','frustum') import Draft p1 = Draft.makePolygon(int(self.arguments['$fn']),r1) p2 = Draft.makePolygon(int(self.arguments['$fn']),r2) if self.arguments['center']: p1.Placement = FreeCAD.Placement(\ FreeCAD.Vector(0.0,0.0,-h/2.0),FreeCAD.Rotation()) p2.Placement = FreeCAD.Placement(\ FreeCAD.Vector(0.0,0.0,h/2.0),FreeCAD.Rotation()) else: p2.Placement = FreeCAD.Placement(\ FreeCAD.Vector(0.0,0.0,h),FreeCAD.Rotation()) w1=doc.addObject("Part::FeaturePython",'polygonwire1') w2=doc.addObject("Part::FeaturePython",'polygonwire2') GetWire(w1,p1) GetWire(w2,p2) ViewProviderTree(w1.ViewObject) ViewProviderTree(w2.ViewObject) obj.Sections=[w1,w2] obj.Solid=True obj.Ruled=True p1.ViewObject.hide() p2.ViewObject.hide() w1.ViewObject.hide() w2.ViewObject.hide() else: if r1 == r2: obj=doc.addObject("Part::Cylinder",namel) obj.Height = h obj.Radius = r1 else: obj=doc.addObject("Part::Cone",'cone') obj.Height = h obj.Radius1, obj.Radius2 = r1, r2 if self.arguments['center']: center(obj,0,0,h) elif namel == 'polyhedron': obj = doc.addObject("Part::Feature",namel) points=self.arguments['points'] faces=self.arguments['triangles'] shell=Part.Shell([Part.Face(Part.makePolygon(\ [tuple(points[pointindex]) for pointindex in \ (face+face[0:1])])) for face in faces]) # obj.Shape=Part.Solid(shell).removeSplitter() solid=Part.Solid(shell).removeSplitter() if solid.Volume < 0: # solid.complement() solid.reverse() obj.Shape=solid#.removeSplitter() elif namel == 'polygon': obj = doc.addObject("Part::Feature",namel) points=self.arguments['points'] paths = self.arguments.get('paths') if not paths: faces=[Part.Face(Part.makePolygon([(x,y,0) for x,y in points+points[0:1]]))] else: faces= [Part.Face(Part.makePolygon([(points[pointindex][0],points[pointindex][1],0) for \ pointindex in (path+path[0:1])])) for path in paths] obj.Shape=subtractfaces(faces) elif namel == 'square': obj = doc.addObject("Part::Plane",namel) x,y = self.arguments['size'] obj.Length = x obj.Width = y if self.arguments['center']: center(obj,x,y,0) elif namel == 'circle': r = self.arguments['r'] import Draft if '$fn' in self.arguments and self.arguments['$fn'] != 0 \ and self.arguments['$fn']<=Node.fnmin: obj=Draft.makePolygon(int(self.arguments['$fn']),r) else: obj=Draft.makeCircle(r) # create a Face #obj = doc.addObject("Part::Circle",namel);obj.Radius = r elif namel == 'color': if len(self.children) == 1: obj = self.children[0].addtofreecad(doc,fcpar or True) else: obj = Node(name='imp_union',\ children=self.children).addtofreecad(doc,fcpar or True) obj.ViewObject.ShapeColor = tuple([float(p) for p in self.arguments[:3]]) #RGB transp = 100 - int(math.floor(100*self.arguments[3])) #Alpha obj.ViewObject.Transparency = transp elif namel == 'multmatrix': assert(len(self.children)>0) m1l=[round(f,12) for f in sum(self.arguments,[])] #Thats the original matrix m1=FreeCAD.Matrix(*tuple(m1l)) #Thats the original matrix if isspecialorthogonalpython(fcsubmatrix(m1)): #a Placement can represent the transformation if len(self.children) == 1: obj = self.children[0].addtofreecad(doc,fcpar or True) else: obj = Node(name='imp_union',\ children=self.children).addtofreecad(doc,fcpar or True) #FreeCAD.Console.PrintMessage('obj %s\nmat %s/n' % (obj.Placement,m1)) obj.Placement=FreeCAD.Placement(m1).multiply(obj.Placement) else: #we need to apply the matrix transformation to the Shape using a custom PythonFeature obj=doc.addObject("Part::FeaturePython",namel) if len(self.children) == 1: child = self.children[0].addtofreecad(doc,obj) else: child = Node(name='imp_union',\ children=self.children).addtofreecad(doc,obj) MatrixTransform(obj,m1,child) #This object is not mutable from the GUI ViewProviderTree(obj.ViewObject) #elif namel == 'import': pass #Custom Feature elif namel == 'linear_extrude': height = self.arguments['height'] twist = self.arguments.get('twist') if not twist: obj = doc.addObject("Part::Extrusion",namel) else: #twist obj=doc.addObject("Part::FeaturePython",'twist_extrude') if len(self.children)==0: base= Node('import',self.arguments).addtofreecad(doc,obj) elif len(self.children)==1: base = self.children[0].addtofreecad(doc,obj) else: base = Node(name='imp_union',\ children=self.children).addtofreecad(doc,obj) if False and base.isDerivedFrom('Part::MultiFuse'): #does not solve all the problems newobj=doc.addObject("Part::FeaturePython",'refine') RefineShape(newobj,base) ViewProviderTree(newobj.ViewObject) base.ViewObject.hide() base=newobj if not twist: obj.Base= base obj.Dir = (0,0,height) else: #twist Twist(obj,base,height,-twist) ViewProviderTree(obj.ViewObject) if self.arguments['center']: center(obj,0,0,height) base.ViewObject.hide() elif namel == 'rotate_extrude': obj = doc.addObject("Part::Revolution",namel) if len(self.children)==0: base= Node('import',self.arguments).addtofreecad(doc,obj) elif len(self.children)==1: base = self.children[0].addtofreecad(doc,obj) else: base = Node(name='imp_union',\ children=self.children).addtofreecad(doc,obj) if False and base.isDerivedFrom('Part::MultiFuse'): #creates 'Axe and meridian are confused' Errors newobj=doc.addObject("Part::FeaturePython",'refine') RefineShape(newobj,base) ViewProviderTree(newobj.ViewObject) base.ViewObject.hide() base=newobj obj.Source= base obj.Axis = (0.00,1.00,0.00) obj.Base = (0.00,0.00,0.00) obj.Angle = 360.00 base.ViewObject.hide() obj.Placement=FreeCAD.Placement(FreeCAD.Vector(),FreeCAD.Rotation(0,0,90)) elif namel == 'projection': if self.arguments['cut']: planename='xy_plane_used_for_project_cut' obj=doc.addObject('Part::MultiCommon','projection_cut') plane = doc.getObject(planename) if not plane: plane=doc.addObject("Part::Plane",planename) plane.Length=Node.planedim*2 plane.Width=Node.planedim*2 plane.Placement = FreeCAD.Placement(FreeCAD.Vector(\ -Node.planedim,-Node.planedim,0),FreeCAD.Rotation(0,0,0,1)) #plane.ViewObject.hide() subobjs = [child.addtofreecad(doc,obj) for child in self.children] subobjs.append(plane) obj.Shapes = subobjs for subobj in subobjs: subobj.ViewObject.hide() else: #Do a proper projection raise(NotImplementedError) elif namel == 'import': filename = self.arguments.get('file') scale = self.arguments.get('scale') origin = self.arguments.get('origin') if filename: import os docname=os.path.split(filename)[1] objname,extension = docname.split('.',1) if not os.path.isabs(filename): try: global lastimportpath filename=os.path.join(lastimportpath,filename) except: raise #no path given # Check for a mesh fileformat support by the Mesh mddule if extension.lower() in reverseimporttypes()['Mesh']: import Mesh mesh1 = doc.getObject(objname) #reuse imported object if not mesh1: Mesh.insert(filename) mesh1=doc.getObject(objname) mesh1.ViewObject.hide() sh=Part.Shape() sh.makeShapeFromMesh(mesh1.Mesh.Topology,0.1) solid = Part.Solid(sh) obj=doc.addObject("Part::FeaturePython",'import_%s_%s'%(extension,objname)) #obj=doc.addObject('Part::Feature',) ImportObject(obj,mesh1) #This object is not mutable from the GUI ViewProviderTree(obj.ViewObject) solid=solid.removeSplitter() if solid.Volume < 0: #sh.reverse() #sh = sh.copy() solid.complement() obj.Shape=solid#.removeSplitter() elif extension in ['dxf']: layera = self.arguments.get('layer') featname='import_dxf_%s_%s'%(objname,layera) # reusing an allready imported object does not work if the #shape in not yet calculated import importDXF global dxfcache layers=dxfcache.get(id(doc),[]) if layers: try: groupobj=[go for go in layers if (not layera) or go.Label == layera] except: groupobj= None else: groupobj= None if not groupobj: groupname=objname layers = importDXF.processdxf(doc,filename) or importDXF.layers dxfcache[id(doc)] = layers[:] for l in layers: for o in l.Group: o.ViewObject.hide() l.ViewObject.hide() groupobj=[go for go in layers if (not layera) or go.Label == layera] edges=[] for shapeobj in groupobj[0].Group: edges.extend(shapeobj.Shape.Edges) try: f=edgestofaces(edges) except: FreeCAD.Console.PrintError(\ 'processing of dxf import faild\nPlease rework \'%s\' manualy\n' % layera) f=Part.Shape() #empty Shape obj=doc.addObject("Part::FeaturePython",'import_dxf_%s_%s'%(objname,layera)) #obj=doc.addObject('Part::Feature',) ImportObject(obj,groupobj[0]) #This object is not mutable from the GUI ViewProviderTree(obj.ViewObject) obj.Shape=f else: FreeCAD.Console.ErrorMessage(\ 'Filetype of %s not supported\n' % (filename)) raise(NotImplementedError) if obj: #handle origin and scale if scale is not None and scale !=1: if origin is not None and any([c != 0 for c in origin]): raise(NotImplementedError)# order of transformations unkown child = obj m1=FreeCAD.Matrix() m1.scale(scale,scale,scale) obj=doc.addObject("Part::FeaturePython",'scale_import') MatrixTransform(obj,m1,child) #This object is not mutable from the GUI ViewProviderTree(obj.ViewObject) elif origin is not None and any([c != 0 for c in origin]): placement=FreeCAD.Placement(FreeCAD.Vector(*[-c for c in origin]),FreeCAD.Rotation()) obj.Placement=placement.multiply(obj.Placement) else: FreeCAD.Console.ErrorMessage('Import of %s failed\n' % (filename)) elif namel == 'minkowski': childrennames=[child.name.lower() for child in self.children] if len(self.children) == 2 and \ childrennames.count('cube')==1 and \ (childrennames.count('sphere') + \ childrennames.count('cylinder')) == 1: if self.children[0].name.lower() == 'cube': cube = self.children[0] roundobj = self.children[1] elif self.children[1].name.lower() == 'cube': cube = self.children[1] roundobj = self.children[0] roundobjname=roundobj.name.lower() issphere = roundobjname == 'sphere' cubeobj=doc.addObject('Part::Box','roundedcube') x,y,z=cube.arguments['size'] r=roundobj.arguments.get('r') or \ roundobj.arguments.get('r1') cubeobj.Length=x+2*r cubeobj.Width=y+2*r cubeobj.Height=z+2*r*issphere obj=doc.addObject("Part::Fillet","%s_%s"%(namel,roundobjname)) obj.Base = cubeobj cubeobj.ViewObject.hide() if issphere: obj.Edges = [(i,r,r) for i in range(1,13)] else:#cylinder obj.Edges = [(i,r,r) for i in [1,3,5,7]] if cube.arguments['center']: center(cubeobj,x+2*r,y+2*r,z+2*r*issphere) else: #htandle a rotated cylinder #OffsetShape raise(NotImplementedError) elif childrennames.count('sphere')==1: sphereindex=childrennames.index('sphere') sphere=self.children[sphereindex] offset=sphere.arguments['r'] nonsphere=self.children[0:sphereindex]+\ self.sphere[sphereindex+1:] obj=doc.addObject("Part::FeaturePython",'Offset') if len(nonsphere) == 1: child = nonsphere[0].addtofreecad(doc,obj) else: child = Node(name='imp_union',\ children=nonsphere).addtofreecad(doc,obj) OffsetShape(obj,child,offset) ViewProviderTree(obj.ViewObject) elif False: raise(NotImplementedError) pass # handle rotated cylinders and select edges that #radius = radius0 * m1.multiply(FreeCAD.Vector(0,0,1)).dot(edge.Curve.tangent(0)[0]) else: raise(NotImplementedError) elif namel == 'surface': obj = doc.addObject("Part::Feature",namel) #include filename? obj.Shape,xoff,yoff=makeSurfaceVolume(self.arguments['file']) if self.arguments['center']: center(obj,xoff,yoff,0.0) return obj #import os #scadstr = 'surface(file = "%s", center = %s );' % \ # (self.arguments['file'], 'true' if self.arguments['center'] else 'false') #docname=os.path.split(self.arguments['file'])[1] #objname,extension = docname.split('.',1) #obj = openscadmesh(doc,scadstr,objname) elif namel in ['glide','hull']: raise(NotImplementedError) elif namel in ['render','subdiv'] or True: lenchld=len(self.children) if lenchld == 1: FreeCAD.Console.PrintMessage('Not recognized %s\n' % (self)) obj = self.children[0].addtofreecad(doc,fcpar) elif lenchld >1: obj = Node(name='imp_union',\ children=self.children).addtofreecad(doc,fcpar or True) else: obj = doc.addObject("Part::Feature",'Not_Impl_%s'%namel) if fcpar == True: #We are the last real object, our parent is not rendered. return obj if fcpar: try: obj.ViewObject.hide() except: raise if True: #never refine the Shape, as it itroduces crashes return obj else: #refine Shape import Draft if obj.Type =='Part::Extrusion' and obj.Base.Type == 'Part::Part2DObjectPython' and \ isinstance(obj.Base.Proxy,Draft._Polygon) or \ (not obj.isDerivedFrom('Part::Extrusion') and \ not obj.isDerivedFrom('Part::Boolean') and \ not obj.isDerivedFrom('Part::Cut') and \ not obj.isDerivedFrom('Part::MultiCommon') and \ not obj.isDerivedFrom('Part::MultiFuse') and \ not obj.isDerivedFrom('Part::Revolution') ) \ or (obj.isDerivedFrom('Part::FeaturePython') and isinstance(obj.Proxy,RefineShape)): return obj else: newobj=doc.addObject("Part::FeaturePython",'refine') RefineShape(newobj,obj) ViewProviderTree(newobj.ViewObject) obj.ViewObject.hide() return newobj else: doc.recompute()
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 latticeBaseFeature.isObjectLattice(lattice): latticeExecuter.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 __init__(self, obj, label, node1, node2): x = node1.position_X y = node1.position_Y z = node1.position_Z obj.addExtension("App::GroupExtensionPython", self) #Create scripted object: obj.addProperty("App::PropertyString", "label", "In line joint", "label").label = label obj.addProperty("App::PropertyString", "joint", "In line joint", "joint").joint = 'in plane' obj.addProperty("App::PropertyString", "node 1", "In line joint", "node 1").node_1 = node1.label obj.addProperty("App::PropertyString", "node 2", "In line joint", "node 2").node_2 = node2.label #The absolute position is set at the node 1 position, only for animation, not for MBDyn sumulation: obj.addProperty("App::PropertyDistance", "position X", "Initial absolute position", "position X", 1).position_X = x obj.addProperty("App::PropertyDistance", "position Y", "Initial absolute position", "position Y", 1).position_Y = y obj.addProperty("App::PropertyDistance", "position Z", "Initial absolute position", "position Z", 1).position_Z = z #The relative plane position is initially set to (0,0,0), this is, the line passes through node 1 obj.addProperty("App::PropertyDistance", "relative plane position X", "Relative plane position", "relative plane position X" ).relative_plane_position_X = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) obj.addProperty("App::PropertyDistance", "relative plane position Y", "Relative plane position", "relative plane position Y" ).relative_plane_position_Y = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) obj.addProperty("App::PropertyDistance", "relative plane position Z", "Relative plane position", "relative plane position Z" ).relative_plane_position_Z = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) #The relative plane orientation is initially set to (0,0,1), this is, the X-Y plane. obj.addProperty("App::PropertyString", "relative normal direction", "Relative normal direction", "relative normal direction" ).relative_normal_direction = '0., 0., 1.' #The relative offset is initially set to (0,0,0), this is, node 2 is at the plane, without offset obj.addProperty( "App::PropertyDistance", "relative offset X", "Node offset relative to line", "relative offset X").relative_offset_X = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) obj.addProperty( "App::PropertyDistance", "relative offset Y", "Node offset relative to line", "relative offset Y").relative_offset_Y = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) obj.addProperty( "App::PropertyDistance", "relative offset Z", "Node offset relative to line", "relative offset Z").relative_offset_Z = FreeCAD.Units.Quantity( 0.0, FreeCAD.Units.Unit('mm')) #Animation parameters: obj.addProperty("App::PropertyEnumeration", "animate", "Animation", "animate") obj.animate = ['false', 'true'] obj.addProperty("App::PropertyEnumeration", "frame", "Animation", "frame") obj.frame = ['global', 'local'] obj.addProperty("App::PropertyString", "structural dummy", "Animation", "structural dummy").structural_dummy = '2' obj.addProperty( "App::PropertyString", "force vector multiplier", "Animation", "force vector multiplier").force_vector_multiplier = '1' obj.Proxy = self length = FreeCAD.ActiveDocument.getObjectsByLabel( "x: structural: " + node1.label )[0].Length.Value # Calculate the body characteristic length. Will be used to size the arrows that represent the node. p1 = FreeCAD.Vector(0, 0, 0) #Add x vector of the coordinate system: p2 = FreeCAD.Vector(length, 0, 0) l = Draft.makeLine(p1, p2) l.Label = 'x: joint: ' + label l.ViewObject.LineColor = (1.00, 0.00, 0.00) l.ViewObject.PointColor = (1.00, 0.00, 0.00) l.Placement = FreeCAD.Placement( FreeCAD.Vector(x, y, z), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0), FreeCAD.Vector(0, 0, 0)) l.ViewObject.EndArrow = True l.ViewObject.ArrowType = u"Arrow" l.ViewObject.LineWidth = 1.00 l.ViewObject.PointSize = 1.00 l.ViewObject.ArrowSize = str(length / 15) + ' mm' l.ViewObject.Selectable = False #Add y vector of the coordinate system: p2 = FreeCAD.Vector(0, length, 0) l = Draft.makeLine(p1, p2) l.Label = 'y: joint: ' + label l.ViewObject.LineColor = (0.00, 1.00, 0.00) l.ViewObject.PointColor = (0.00, 1.00, 0.00) l.Placement = FreeCAD.Placement( FreeCAD.Vector(x, y, z), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0), FreeCAD.Vector(0, 0, 0)) l.ViewObject.EndArrow = True l.ViewObject.ArrowType = u"Arrow" l.ViewObject.LineWidth = 1.00 l.ViewObject.PointSize = 1.00 l.ViewObject.ArrowSize = str(length / 15) + ' mm' l.ViewObject.Selectable = False #Add z vector of the coordinate system: p2 = FreeCAD.Vector(0, 0, length) l = Draft.makeLine(p1, p2) l.Label = 'z: joint: ' + label l.ViewObject.ArrowType = u"Dot" l.ViewObject.LineColor = (0.00, 0.00, 1.00) l.ViewObject.PointColor = (0.00, 0.00, 1.00) l.Placement = FreeCAD.Placement( FreeCAD.Vector(x, y, z), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0), FreeCAD.Vector(0, 0, 0)) l.ViewObject.EndArrow = True l.ViewObject.LineWidth = 1.00 l.ViewObject.PointSize = 1.00 l.ViewObject.ArrowSize = str(length / 15) + ' mm' l.ViewObject.Selectable = False #Add the vector to visualize reaction forces Llength = FreeCAD.Units.Quantity( FreeCAD.ActiveDocument.getObjectsByLabel("X")[0].End[0] / 4, FreeCAD.Units.Unit('mm')) p1 = FreeCAD.Vector(x, y, z) p2 = FreeCAD.Vector(x + Llength, y + Llength, z + Llength) d = Draft.makeLine(p1, p2) d.ViewObject.LineColor = (1.00, 0.00, 0.00) d.ViewObject.PointColor = (1.00, 0.00, 0.00) d.ViewObject.LineWidth = 1.00 d.ViewObject.PointSize = 1.00 d.ViewObject.EndArrow = True d.ViewObject.ArrowType = u"Arrow" d.ViewObject.ArrowSize = str(Llength / 75) #+' mm' d.ViewObject.Selectable = False d.Label = "jf: " + label FreeCAD.ActiveDocument.recompute()
def CreateFromTemplate(job, template): if template.get("version") and 1 == int(template["version"]): stockType = template.get("create") if stockType: placement = None posX = template.get("posX") posY = template.get("posY") posZ = template.get("posZ") rotX = template.get("rotX") rotY = template.get("rotY") rotZ = template.get("rotZ") rotW = template.get("rotW") if (posX is not None and posY is not None and posZ is not None and rotX is not None and rotY is not None and rotZ is not None and rotW is not None): pos = FreeCAD.Vector(float(posX), float(posY), float(posZ)) rot = FreeCAD.Rotation(float(rotX), float(rotY), float(rotZ), float(rotW)) placement = FreeCAD.Placement(pos, rot) elif (posX is not None or posY is not None or posZ is not None or rotX is not None or rotY is not None or rotZ is not None or rotW is not None): PathLog.warning( "Corrupted or incomplete placement information in template - ignoring" ) if stockType == StockType.FromBase: xneg = template.get("xneg") xpos = template.get("xpos") yneg = template.get("yneg") ypos = template.get("ypos") zneg = template.get("zneg") zpos = template.get("zpos") neg = None pos = None if (xneg is not None and xpos is not None and yneg is not None and ypos is not None and zneg is not None and zpos is not None): neg = FreeCAD.Vector( FreeCAD.Units.Quantity(xneg).Value, FreeCAD.Units.Quantity(yneg).Value, FreeCAD.Units.Quantity(zneg).Value, ) pos = FreeCAD.Vector( FreeCAD.Units.Quantity(xpos).Value, FreeCAD.Units.Quantity(ypos).Value, FreeCAD.Units.Quantity(zpos).Value, ) elif (xneg is not None or xpos is not None or yneg is not None or ypos is not None or zneg is not None or zpos is not None): PathLog.error( "Corrupted or incomplete specification for creating stock from base - ignoring extent" ) return CreateFromBase(job, neg, pos, placement) if stockType == StockType.CreateBox: PathLog.track(" create box") length = template.get("length") width = template.get("width") height = template.get("height") extent = None if length is not None and width is not None and height is not None: PathLog.track(" have extent") extent = FreeCAD.Vector( FreeCAD.Units.Quantity(length).Value, FreeCAD.Units.Quantity(width).Value, FreeCAD.Units.Quantity(height).Value, ) elif length is not None or width is not None or height is not None: PathLog.error( "Corrupted or incomplete size for creating a stock box - ignoring size" ) else: PathLog.track( " take placement (%s) and extent (%s) from model" % (placement, extent)) return CreateBox(job, extent, placement) if stockType == StockType.CreateCylinder: radius = template.get("radius") height = template.get("height") if radius is not None and height is not None: pass elif radius is not None or height is not None: radius = None height = None PathLog.error( "Corrupted or incomplete size for creating a stock cylinder - ignoring size" ) return CreateCylinder(job, radius, height, placement) PathLog.error( translate("PathStock", "Unsupported stock type named {}").format(stockType)) else: PathLog.error( translate("PathStock", "Unsupported PathStock template version {}").format( template.get("version"))) return None