Example #1
0
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)
Example #2
0
    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
Example #5
0
    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)
Example #6
0
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
Example #7
0
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)
Example #9
0
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)
Example #10
0
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
Example #11
0
    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
Example #12
0
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
Example #13
0
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
Example #14
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
Example #15
0
    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()
Example #16
0
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
Example #17
0
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')
Example #18
0
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
Example #21
0
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
Example #22
0
    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()
Example #23
0
    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
Example #24
0
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()
Example #25
0
    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"))
Example #26
0
    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()
Example #28
0
    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()
Example #30
0
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