Example #1
0
def make_node_xz(width, height, thickness, x_positive=True):

    p1 = FreeCAD.Vector(0., -thickness / 2.0, height / 2.0)
    p2 = FreeCAD.Vector(0., -thickness / 2.0, -height / 2.0)
    if x_positive is True:
        pa = FreeCAD.Vector(width, -thickness / 2.0, 0.)
    else:
        pa = FreeCAD.Vector(-width, -thickness / 2.0, 0.)

    l1 = Part.makeLine(p1, p2)
    a2 = Part.Arc(p2, pa, p1).toShape()
    wire = Part.Wire([l1, a2])
    face = Part.Face(wire)
    node = face.extrude(FreeCAD.Vector(0, thickness, 0))

    return node
Example #2
0
def fretboardSection(c, r, w, t, v):
    """
    Creates a Wire for a Fretboard Loft
    c: center Vector
    r: Radius float
    w: Width float
    t: Thickness float
    v: Direction Vector
    """

    # Half angle of the top Arc
    alpha = math.asin(w/(2*r))
    alpha_deg = todeg(alpha)
    
    # Guess top Arc
    arc = Part.makeCircle(r, c, v, -alpha_deg, alpha_deg)
    
    # If arc fails: Guess at 90deg
    if arc.Vertexes[0].Point.z <= 0:
        arc = Part.makeCircle(r, c, v, 90-alpha_deg, 90+alpha_deg)
    
    # If arc fails again: Impossible
    if arc.Vertexes[0].Point.z <= 0:
        raise ModelException("Current Fretboard's radius is inconsistent with Fretboard's geometry")

    # Arc end points
    a = arc.Vertexes[0].Point
    b = arc.Vertexes[1].Point

    # Side fretboard height
    h = r * math.cos(alpha) - r + t

    # Fretboard bottom at side a
    x = Vector(a.x, a.y, a.z -h)

    # Fretboard bottom at side b
    d = Vector(b.x, b.y, b.z -h)

    # Fretboard top at center
    p = Vector(c.x, c.y, c.z +r)

    # Finally, the wire: arc(ba) -> seg(ax) -> seg(xd) -> seg(db)
    return Part.Wire(Part.Shape([
        Part.Arc(a,p,b), 
        Part.LineSegment(a,x), 
        Part.LineSegment(x,d), 
        Part.LineSegment(d,b)]).Edges)
Example #3
0
def make_node_yz(width, height, thickness, x_positive=True):

    p1 = FreeCAD.Vector(-thickness / 2.0, 0, height / 2.0)
    p2 = FreeCAD.Vector(-thickness / 2.0, 0, -height / 2.0)
    if x_positive is True:
        pa = FreeCAD.Vector(-thickness / 2.0, width, 0.)
    else:
        pa = FreeCAD.Vector(-thickness / 2.0, -width, 0.)

    l1 = Part.Line(p1, p2)
    a2 = Part.Arc(p2, pa, p1)
    shape = Part.Shape([l1, a2])
    wire = Part.Wire(shape.Edges)
    face = Part.Face(wire)
    node = face.extrude(FreeCAD.Vector(thickness, 0, 0))

    return node
Example #4
0
 def getreversed(self, edges):
     """
     Reverses the edge array and the direction of each edge
     """
     outedges = []
     for edge in reversed(edges):
         # reverse the start and end points
         startPoint = edge.valueAt(edge.LastParameter)
         endPoint = edge.valueAt(edge.FirstParameter)
         if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
             outedges.append(Part.makeLine(startPoint, endPoint))
         elif type(edge.Curve) == Part.Circle:
             arcMid = edge.valueAt((edge.FirstParameter + edge.LastParameter) / 2)
             outedges.append(Part.Arc(startPoint, arcMid, endPoint).toShape())
         else:
             PathLog.error("Edge should not be helix")
     return outedges
Example #5
0
def getarc(data):
    "turns an OCA arc definition into a FreeCAD Part Edge"
    print "found arc ", data
    c = None
    if (data[0] == "ARC"):
        # 3-points arc
        pts = data[1:]
        verts = []
        for p in range(len(pts)):
            if (pts[p] == "P"):
                verts.append(getpoint(pts[p:p + 3]))
            elif (pts[p][0] == "P"):
                verts.append(getpoint([pts[p]]))
        if verts[0] and verts[1] and verts[2]:
            c = Part.Arc(verts[0], verts[1], verts[2])
    elif (data[0][0] == "P"):
        # 2-point circle
        verts = []
        rad = None
        for p in range(len(data)):
            if (data[p] == "P"):
                verts.append(getpoint(data[p:p + 4]))
            elif (data[p][0] == "P"):
                verts.append(getpoint([data[p]]))
            elif (data[p] == "VAL"):
                rad = float(data[p + 1])
            elif (data[p][0] == "L"):
                lines.append(objects[data[p]])
        c = Part.Circle()
        c.Center = verts[0]
        if rad: c.Radius = rad
        else: c.Radius = DraftVecUtils.new(verts[0], verts[1]).Length
    elif (data[0][0] == "L"):
        # 2-lines circle
        lines = []
        rad = None
        for p in range(len(data)):
            if (data[p] == "VAL"):
                rad = float(data[p + 1])
            elif (data[p][0] == "L"):
                lines.append(objects[data[p]])
        circles = DraftGeomUtils.circleFrom2LinesRadius(
            lines[0], lines[1], rad)
        if circles: c = circles[0]
    if c: return c.toShape()
def make_truncated_arched_cutout_aperture(
    aperture_height, centre_position, aperture_width, arc_radius
):
    """Creates a wire outline of a rectangle with an arc removed from the centre of one edge.

    Args:
        arc_radius (float): Radius of the arc.
        centre_position (float): position along width making the centre of the cutout arc.
        aperture_height (float): Total height of the aperture
        aperture_width (float): Total width of the aperture

    Returns:
        wire1 (FreeCAD wire definition): An outline description of the shape.
        face1 (FreeCAD face definition): A surface description of the shape.
    """
    # Create the initial four vertices where line meets curve.
    v1 = Base.Vector(0, aperture_height - arc_radius, -aperture_width + centre_position)
    v2 = Base.Vector(0, aperture_height - arc_radius, centre_position)
    v3 = Base.Vector(
        0,
        -float(arc_radius) + sqrt(arc_radius ** 2 - centre_position ** 2),
        centre_position,
    )
    v4 = Base.Vector(0, -arc_radius, -arc_radius)
    v5 = Base.Vector(0, -arc_radius, -aperture_width + centre_position)
    cv1 = Base.Vector(
        0,
        0,
        0,
    )
    # Create lines
    line1 = Part.LineSegment(v5, v1)
    line2 = Part.LineSegment(v1, v2)
    line3 = Part.LineSegment(v2, v3)
    line4 = Part.LineSegment(v4, v5)
    # Create curves
    arc1 = Part.Arc(v3, cv1, v4)
    # Make a shape
    shape1 = Part.Shape([line1, line2, line3, arc1, line4])
    # Make a wire outline.
    wire1 = Part.Wire(shape1.Edges)
    # Make a face.
    face1 = Part.Face(wire1)

    return wire1, face1
Example #7
0
    def generatePCB(self, PCB, doc, groupBRD, gruboscPlytki):
        doc.addObject('Sketcher::SketchObject', 'PCB_Border')
        doc.PCB_Border.Placement = FreeCAD.Placement(
            FreeCAD.Vector(0.0, 0.0, 0.0),
            FreeCAD.Rotation(0.0, 0.0, 0.0, 1.0))
        #
        for i in PCB[0]:
            if i[0] == 'Arc':  # arc by 3 points
                x1 = i[1]
                y1 = i[2]
                x2 = i[3]
                y2 = i[4]
                [x3, y3] = self.arcMidPoint([x2, y2], [x1, y1], i[5])

                arc = Part.Arc(FreeCAD.Vector(x1, y1, 0.0),
                               FreeCAD.Vector(x3, y3, 0.0),
                               FreeCAD.Vector(x2, y2, 0.0))
                doc.PCB_Border.addGeometry(
                    self.Draft2Sketch(arc, doc.PCB_Border))
            elif i[0] == 'Arc_2':  # arc by center / start angle / stop angle / radius
                doc.PCB_Border.addGeometry(
                    Part.ArcOfCircle(
                        Part.Circle(FreeCAD.Vector(i[1], i[2], 0),
                                    FreeCAD.Vector(0, 0, 1), i[3]), i[4],
                        i[5]))
            elif i[0] == 'Circle':
                doc.PCB_Border.addGeometry(
                    Part.Circle(FreeCAD.Vector(i[1], i[2]),
                                FreeCAD.Vector(0, 0, 1), i[3]))
            elif i[0] == 'Line':
                doc.PCB_Border.addGeometry(
                    Part.Line(FreeCAD.Vector(i[1], i[2], 0),
                              FreeCAD.Vector(i[3], i[4], 0)))
        #
        #if PCB[1]:
        PCBboard = doc.addObject("Part::FeaturePython", "Board")
        PCBboardObject(PCBboard)
        PCBboard.Thickness = gruboscPlytki
        PCBboard.Border = doc.PCB_Border
        viewProviderPCBboardObject(PCBboard.ViewObject)
        groupBRD.addObject(doc.Board)
        FreeCADGui.activeDocument().getObject(
            PCBboard.Name).ShapeColor = PCBconf.PCB_COLOR
        FreeCADGui.activeDocument().PCB_Border.Visibility = False
        self.updateView()
def make_keyhole_aperture_flat_end(pipe_radius, keyhole_height, keyhole_width):
    """Creates a wire outline of a circular pipe with a keyhole extension on the side.
    aperture_height and aperture_width are the full height and width
    (the same as if it were a rectangle).
    The end curves are defined as 180 degree arcs.

    Args:
        pipe_radius (Base.Unit): Radius of the main beam pipe.
        keyhole_height (Base.Unit): Total height of the keyhole slot.
        keyhole_width (Base.Unit): Total width of the keyhole slot.

    Returns:
        wire1 (FreeCAD wire definition): An outline description of the shape.
        face1 (FreeCAD face definition): A surface description of the shape.
    """
    # X intersection of keyhole with pipe.
    x_intersection = Units.Quantity(
        sqrt(pipe_radius ** 2 - (keyhole_height / 2.0) ** 2), 1
    )
    # Create the initial four vertices for the lines.
    v1 = Base.Vector(0, keyhole_height / 2.0, x_intersection)
    v2 = Base.Vector(0, keyhole_height / 2.0, keyhole_width)
    v3 = Base.Vector(0, -keyhole_height / 2.0, keyhole_width)
    v4 = Base.Vector(0, -keyhole_height / 2.0, x_intersection)
    v5 = Base.Vector(0, 0, x_intersection + keyhole_width)
    # Create lines
    line1 = Part.LineSegment(v1, v2)
    line2 = Part.LineSegment(v2, v3)
    line3 = Part.LineSegment(v3, v4)

    # angle at which the keyhole intersects the pipe.
    half_angle = asin(keyhole_height / (2 * pipe_radius))
    # Create curves
    curve1 = Part.Circle(Base.Vector(0, 0, 0), Base.Vector(1, 0, 0), pipe_radius)
    arc1 = Part.Arc(
        curve1, half_angle, (2 * pi) - half_angle
    )  # angles are in radian here

    # Make a shape
    shape1 = Part.Shape([arc1, line1, line2, line3])
    # Make a wire outline.
    wire1 = Part.Wire(shape1.Edges)
    # Make a face.
    face1 = Part.Face(wire1)
    return wire1, face1
    def makeBottle1(self):
        aPnt1 = Base.Vector(-self.width / 2., 0, 0)
        aPnt2 = Base.Vector(-self.width / 2., -self.thickness / 4., 0)
        aPnt3 = Base.Vector(0, -self.thickness / 2., 0)
        aPnt4 = Base.Vector(self.width / 2., -self.thickness / 4., 0)
        aPnt5 = Base.Vector(self.width / 2., 0, 0)
        ## 上面定义5个点:只与myThickness,myWidth有关

        aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4)
        aSegment1 = Part.LineSegment(aPnt1, aPnt2)
        aSegment2 = Part.LineSegment(aPnt4, aPnt5)
        ## 上面构建2条线和一个圆弧: 线1: 1-2; 线2: 4-5; 圆弧:2-3-4

        aEdge1 = aSegment1.toShape()
        aEdge2 = aArcOfCircle.toShape()
        aEdge3 = aSegment2.toShape()
        aWire = Part.Wire([aEdge1, aEdge2, aEdge3])
        ## 由几何结构(line和circle)构造形状Shape:(Solid-Shell-Face-Wire-Edge-Vertex)

        aTrsf = Base.Matrix()
        ##  Matrix是变换到三维的一个常用工具,他包含了几乎所有的变换

        aTrsf.rotateZ(math.pi)  # rotate around the z-axis
        aMirroredWire = aWire.transformGeometry(aTrsf)  #
        myWireProfile = Part.Wire([aWire, aMirroredWire])
        myFaceProfile = Part.Face(myWireProfile)  # 将线变成了面
        aPrismVec = Base.Vector(0, 0, self.height)
        myBody = myFaceProfile.extrude(aPrismVec)
        #    myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)
        ##上面语句为,先180镜像,之后形成一个closed face,之后
        # 用extrude进行拉升 myHeight的高度
        # 随后使用makeFillet,扣除 myThickness/12.0 的厚度

        neckLocation = Base.Vector(0, 0, self.height)
        neckNormal = Base.Vector(0, 0, 1)
        myNeckRadius = self.thickness / 4.
        myNeckHeight = self.height / 10.
        myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal)
        myBody = myBody.fuse(myNeck)
        #    myBody = myBody.makeFillet(myThickness/12.0,myBody.Edges)
        #    App.getDocument('Cube').addObject('Part::PartFeature','Shape') = myBody.toShape()
        #    Gui.getDocument("Cube").getObject("Shape").ShapeColor=color

        Part.show(myBody)
        Gui.getDocument("Bottle").getObject("Shape001").ShapeColor = self.color
def make_arched_base_trapezoid_aperture(
    aperture_height, base_width, top_width, arc_radius
):
    """Creates a wire outline of a rectangle with an arc removed from one edge..

    Args:
        arc_radius (float): Radius of the arc.
        aperture_height (float): Total height of the aperture.
        base_width (float): Total width of the base of the aperture.
        top_width (float): Total width of the top of the aperture.

    Returns:
        wire1 (FreeCAD wire definition): An outline description of the shape.
        face1 (FreeCAD face definition): A surface description of the shape.
    """
    # Create the initial four vertices where line meets curve.
    v1 = Base.Vector(0, aperture_height / 2.0, -top_width / 2.0)
    v2 = Base.Vector(0, aperture_height / 2.0, top_width / 2.0)
    v3 = Base.Vector(0, -aperture_height / 2.0, base_width / 2.0)
    v4 = Base.Vector(0, -aperture_height / 2.0, -base_width / 2.0)
    cv1 = Base.Vector(
        0,
        -aperture_height / 2.0
        + arc_radius
        - sqrt(arc_radius ** 2 - (base_width ** 2) / 4),
        0,
    )
    # Create lines
    line1 = Part.LineSegment(v4, v1)
    line2 = Part.LineSegment(v1, v2)
    line3 = Part.LineSegment(v2, v3)
    # Create curves
    arc1 = Part.Arc(v3, cv1, v4)
    # arc1_edge = arc1.toShape()
    # Make a shape
    shape1 = Part.Shape([line1, line2, line3, arc1])
    # Make a wire outline.
    wire1 = Part.Wire(shape1.Edges)
    # Make a face.
    face1 = Part.Face(wire1)

    return wire1, face1
Example #11
0
def getTransitionEnd(trans, height, profile, tip):
    """Generate last profile"""

    height = height + trans.Length / 2
    a = trans.Vertexes[0].Point
    b = trans.Vertexes[1].Point
    l1 = Part.LineSegment(Vector(a), Vector(a.x, a.y, a.z - height))
    l2 = Part.LineSegment(Vector(b.x, b.y, b.z - height), Vector(b))
    l3 = Part.LineSegment(Vector(b), Vector(a))
    lX = geom.wireFromPrim([
        Part.LineSegment(Vector(a.x, a.y, a.z - height),
                         Vector(b.x, b.y, b.z - height))
    ])
    center = lX.CenterOfMass
    length = lX.Length
    arc = Part.Arc(Vector(a.x, a.y, a.z - height),
                   Vector(center.x, center.y, center.z - length / 2),
                   Vector(b.x, b.y, b.z - height))
    wire = geom.wireFromPrim([l1, arc, l2, l3])
    return wire
Example #12
0
 def getPoint(self, point, info):
     if not point:  # cancelled
         self.tracker.off()
         return
     if not (point in self.points):  # avoid same point twice
         self.points.append(point)
     if len(self.points) < 3:
         if len(self.points) == 2:
             self.tracker.on()
         FreeCADGui.Snapper.getPoint(last=self.points[-1],
                                     callback=self.getPoint,
                                     movecallback=self.drawArc)
     else:
         import Part
         e = Part.Arc(self.points[0], self.points[1],
                      self.points[2]).toShape()
         o = FreeCAD.ActiveDocument.addObject("Part::Feature", "Arc")
         o.Shape = e
         self.tracker.off()
         FreeCAD.ActiveDocument.recompute()
Example #13
0
def smMakeReliefFace(edge, dir, gap, reliefW, reliefD, reliefType):
    p1 = edge.valueAt(edge.FirstParameter + gap)
    p2 = edge.valueAt(edge.FirstParameter + gap + reliefW )
    if reliefType == "Round" and reliefD > reliefW :
      p3 = edge.valueAt(edge.FirstParameter + gap + reliefW) + dir.normalize() * (reliefD-reliefW/2)
      p34 = edge.valueAt(edge.FirstParameter + gap + reliefW/2) + dir.normalize() * reliefD
      p4 = edge.valueAt(edge.FirstParameter + gap) + dir.normalize() * (reliefD-reliefW/2)
      e1 = Part.makeLine(p1, p2)
      e2 = Part.makeLine(p2, p3)
      e3 = Part.Arc(p3, p34, p4).toShape()
      e4 = Part.makeLine(p4, p1)
    else :
      p3 = edge.valueAt(edge.FirstParameter + gap + reliefW) + dir.normalize() * reliefD
      p4 = edge.valueAt(edge.FirstParameter + gap) + dir.normalize() * reliefD
      e1 = Part.makeLine(p1, p2)
      e2 = Part.makeLine(p2, p3)
      e3 = Part.makeLine(p3, p4)
      e4 = Part.makeLine(p4, p1)

    w = Part.Wire([e1,e2,e3,e4])
    return Part.Face(w)
Example #14
0
    def _airfoil(self, base, thickness, diameter, length):
        # Calculate the tangent points
        radius = diameter / 2.0
        theta = math.pi - math.atan2(length - radius, radius)
        x = -(radius * math.cos(theta))
        y = radius * math.sin(theta)

        v1 = FreeCAD.Vector(-x, y, base)
        v2 = FreeCAD.Vector(-x, -y, base)
        v3 = FreeCAD.Vector(radius, 0, base)
        v4 = FreeCAD.Vector(radius - length, 0, base)

        arc = Part.Arc(v1, v3, v2)
        line1 = Part.LineSegment(v1, v4)
        line2 = Part.LineSegment(v2, v4)
        shape = Part.Shape([arc, line1, line2])
        wire = Part.Wire(shape.Edges)
        face = Part.Face(wire)
        airfoil = face.extrude(FreeCAD.Vector(0, 0, thickness))

        return airfoil
def make_arched_cutout_aperture(aperture_height, aperture_width, arc_radius):
    """Creates a wire outline of a rectangle with an arc removed from the centre of one edge.

    Args:
        arc_radius (float): Radius of the arc.
        aperture_height (float): Total height of the aperture
        aperture_width (float): Total width of the aperture

    Returns:
        wire1 (FreeCAD wire definition): An outline description of the shape.
        face1 (FreeCAD face definition): A surface description of the shape.
    """
    # Create the initial four vertices where line meets curve.
    v1 = Base.Vector(0, aperture_height / 2.0, -aperture_width / 2.0)
    v2 = Base.Vector(0, aperture_height / 2.0, aperture_width / 2.0)
    v3 = Base.Vector(0, -aperture_height / 2.0, aperture_width / 2.0)
    v4 = Base.Vector(0, -aperture_height / 2.0, arc_radius)
    v5 = Base.Vector(0, -aperture_height / 2.0, -arc_radius)
    v6 = Base.Vector(0, -aperture_height / 2.0, -aperture_width / 2.0)
    cv1 = Base.Vector(
        0,
        -aperture_height / 2.0 + arc_radius,
        0,
    )
    # Create lines
    line1 = Part.LineSegment(v6, v1)
    line2 = Part.LineSegment(v1, v2)
    line3 = Part.LineSegment(v2, v3)
    line4 = Part.LineSegment(v3, v4)
    line5 = Part.LineSegment(v5, v6)
    # Create curves
    arc1 = Part.Arc(v4, cv1, v5)
    # Make a shape
    shape1 = Part.Shape([line1, line2, line3, line4, arc1, line5])
    # Make a wire outline.
    wire1 = Part.Wire(shape1.Edges)
    # Make a face.
    face1 = Part.Face(wire1)

    return wire1, face1
def makeBottleTut(myWidth=50.0, myHeight=70.0, myThickness=30.0):
    aPnt1 = Base.Vector(-myWidth / 2., 0, 0)
    aPnt2 = Base.Vector(-myWidth / 2., -myThickness / 4., 0)
    aPnt3 = Base.Vector(0, -myThickness / 2., 0)
    aPnt4 = Base.Vector(myWidth / 2., -myThickness / 4., 0)
    aPnt5 = Base.Vector(myWidth / 2., 0, 0)

    aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4)
    aSegment1 = Part.LineSegment(aPnt1, aPnt2)
    aSegment2 = Part.LineSegment(aPnt4, aPnt5)

    aEdge1 = aSegment1.toShape()
    aEdge2 = aArcOfCircle.toShape()
    aEdge3 = aSegment2.toShape()
    aWire = Part.Wire([aEdge1, aEdge2, aEdge3])

    aTrsf = Base.Matrix()
    aTrsf.rotateZ(math.pi)  # rotate around the z-axis

    aMirroredWire = aWire.copy()
    aMirroredWire.transformShape(aTrsf)
    myWireProfile = Part.Wire([aWire, aMirroredWire])

    myFaceProfile = Part.Face(myWireProfile)
    aPrismVec = Base.Vector(0, 0, myHeight)
    myBody = myFaceProfile.extrude(aPrismVec)

    myBody = myBody.makeFillet(myThickness / 12.0, myBody.Edges)

    neckLocation = Base.Vector(0, 0, myHeight)
    neckNormal = Base.Vector(0, 0, 1)

    myNeckRadius = myThickness / 4.
    myNeckHeight = myHeight / 10.
    myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation,
                               neckNormal)
    myBody = myBody.fuse(myNeck)

    return myBody
Example #17
0
    def generateGlue(self, wires, doc, grp, layerName, layerColor,
                     layerNumber):
        if PCBconf.PCBlayers[PCBconf.softLayers[self.databaseType][layerNumber]
                             [1]][0] == 1:
            side = 'TOP'
        else:
            side = 'BOTTOM'
        #
        for i, j in wires.items():
            ser = doc.addObject('Sketcher::SketchObject',
                                "Sketch_{0}".format(layerName))
            ser.ViewObject.Visibility = False
            for k in j:
                if k[0] == 'line':
                    ser.addGeometry(
                        Part.Line(FreeCAD.Vector(k[1], k[2], 0),
                                  FreeCAD.Vector(k[3], k[4], 0)))
                elif k[0] == 'circle':
                    ser.addGeometry(
                        Part.Circle(FreeCAD.Vector(k[1], k[2]),
                                    FreeCAD.Vector(0, 0, 1), k[3]))
                elif k[0] == 'arc':
                    x1 = k[1]
                    y1 = k[2]
                    x2 = k[3]
                    y2 = k[4]
                    [x3, y3] = self.arcMidPoint([x2, y2], [x1, y1], k[5])

                    arc = Part.Arc(FreeCAD.Vector(x1, y1, 0.0),
                                   FreeCAD.Vector(x3, y3, 0.0),
                                   FreeCAD.Vector(x2, y2, 0.0))
                    ser.addGeometry(self.Draft2Sketch(arc, ser))
            #
            glue = createGlue()
            glue.base = ser
            glue.width = i
            glue.side = side
            glue.color = layerColor
            glue.generate()
Example #18
0
    def test62(self):
        """Verify splitArcAt returns proper subarcs."""
        p1 = Vector(10,-10,0)
        p2 = Vector(0,0,0)
        p3 = Vector(10,10,0)

        arc = Part.Edge(Part.Arc(p1, p2, p3))

        o = 10*math.sin(math.pi/4)
        p12 = Vector(10 - o, -o, 0)
        p23 = Vector(10 - o, +o, 0)

        e = PathGeom.splitArcAt(arc, p2)
        self.assertCurve(e[0], p1, p12, p2)
        self.assertCurve(e[1], p2, p23, p3)

        p34 = Vector(10 - 10*math.sin(1*math.pi/8), -10*math.cos(1*math.pi/8), 0)
        p45 = Vector(10 - 10*math.sin(5*math.pi/8), -10*math.cos(5*math.pi/8), 0)

        e = PathGeom.splitArcAt(arc, p12)
        self.assertCurve(e[0], p1, p34, p12)
        self.assertCurve(e[1], p12, p45, p3)
Example #19
0
    def test60(self):
        """Verify arcToHelix returns proper helix."""
        p1 = Vector(10, -10, 0)
        p2 = Vector(0, 0, 0)
        p3 = Vector(10, 10, 0)

        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 0, 2)
        self.assertCurve(e, p1, p2 + Vector(0, 0, 1), p3 + Vector(0, 0, 2))

        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 3, 7)
        self.assertCurve(e, p1 + Vector(0, 0, 3), p2 + Vector(0, 0, 5),
                         p3 + Vector(0, 0, 7))

        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 9, 1)
        self.assertCurve(e, p1 + Vector(0, 0, 9), p2 + Vector(0, 0, 5),
                         p3 + Vector(0, 0, 1))

        dz = Vector(0, 0, 3)
        p11 = p1 + dz
        p12 = p2 + dz
        p13 = p3 + dz

        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 0, 8)
        self.assertCurve(e, p1, p2 + Vector(0, 0, 4), p3 + Vector(0, 0, 8))

        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 2, -2)
        self.assertCurve(e, p1 + Vector(0, 0, 2), p2, p3 + Vector(0, 0, -2))

        o = 10 * math.sin(math.pi / 4)
        p1 = Vector(10, -10, 1)
        p2 = Vector(10 - 10 * math.sin(math.pi / 4),
                    -10 * math.cos(math.pi / 4), 1)
        p3 = Vector(0, 0, 1)
        e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 0, 5)
        self.assertCurve(e, Vector(10, -10, 0), Vector(p2.x, p2.y, 2.5),
                         Vector(0, 0, 5))
Example #20
0
 def AddArc(self, x1, z1, x2, z2):
     midPoint = FreeCAD.Base.Vector(x1, 0, z1)
     endPoint = FreeCAD.Base.Vector(x2, 0, z2)
     self.edges.append(
         Part.Arc(self.lastPoint, midPoint, endPoint).toShape())
     self.lastPoint = endPoint
Example #21
0
    def updateData(self, obj, prop):
        if hasattr(self, "arc"):
            from pivy import coin
            import Part, DraftGeomUtils
            import DraftGui
            arcsegs = 24

            # calculate the arc data
            if DraftVecUtils.isNull(obj.Normal):
                norm = App.Vector(0, 0, 1)
            else:
                norm = obj.Normal
            radius = (obj.Dimline.sub(obj.Center)).Length
            self.circle = Part.makeCircle(radius, obj.Center, norm,
                                          obj.FirstAngle.Value,
                                          obj.LastAngle.Value)
            self.p2 = self.circle.Vertexes[0].Point
            self.p3 = self.circle.Vertexes[-1].Point
            mp = DraftGeomUtils.findMidpoint(self.circle.Edges[0])
            ray = mp.sub(obj.Center)

            # set text value
            if obj.LastAngle.Value > obj.FirstAngle.Value:
                a = obj.LastAngle.Value - obj.FirstAngle.Value
            else:
                a = (360 - obj.FirstAngle.Value) + obj.LastAngle.Value
            su = True
            if hasattr(obj.ViewObject, "ShowUnit"):
                su = obj.ViewObject.ShowUnit
            if hasattr(obj.ViewObject, "Decimals"):
                self.string = DraftGui.displayExternal(a,
                                                       obj.ViewObject.Decimals,
                                                       'Angle', su)
            else:
                self.string = DraftGui.displayExternal(a, None, 'Angle', su)
            if obj.ViewObject.Override:
                self.string = obj.ViewObject.Override.replace("$dim",\
                    self.string)
            self.text.string = self.text3d.string = utils.string_encode_coin(
                self.string)

            # check display mode
            try:
                m = obj.ViewObject.DisplayMode
            except:  # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet)
                m = ["2D", "3D"][utils.get_param("dimstyle", 0)]

            # set the arc
            if m == "3D":
                # calculate the spacing of the text
                spacing = (len(self.string) *
                           obj.ViewObject.FontSize.Value) / 8.0
                pts1 = []
                cut = None
                pts2 = []
                for i in range(arcsegs + 1):
                    p = self.circle.valueAt(self.circle.FirstParameter + (
                        (self.circle.LastParameter -
                         self.circle.FirstParameter) / arcsegs) * i)
                    if (p.sub(mp)).Length <= spacing:
                        if cut is None:
                            cut = i
                    else:
                        if cut is None:
                            pts1.append([p.x, p.y, p.z])
                        else:
                            pts2.append([p.x, p.y, p.z])
                self.coords.point.setValues(pts1 + pts2)
                i1 = len(pts1)
                i2 = i1 + len(pts2)
                self.arc.coordIndex.setValues(
                    0,
                    len(pts1) + len(pts2) + 1,
                    list(range(len(pts1))) + [-1] + list(range(i1, i2)))
                if (len(pts1) >= 3) and (len(pts2) >= 3):
                    self.circle1 = Part.Arc(
                        App.Vector(pts1[0][0], pts1[0][1], pts1[0][2]),
                        App.Vector(pts1[1][0], pts1[1][1], pts1[1][2]),
                        App.Vector(pts1[-1][0], pts1[-1][1],
                                   pts1[-1][2])).toShape()
                    self.circle2 = Part.Arc(
                        App.Vector(pts2[0][0], pts2[0][1], pts2[0][2]),
                        App.Vector(pts2[1][0], pts2[1][1], pts2[1][2]),
                        App.Vector(pts2[-1][0], pts2[-1][1],
                                   pts2[-1][2])).toShape()
            else:
                pts = []
                for i in range(arcsegs + 1):
                    p = self.circle.valueAt(self.circle.FirstParameter + (
                        (self.circle.LastParameter -
                         self.circle.FirstParameter) / arcsegs) * i)
                    pts.append([p.x, p.y, p.z])
                self.coords.point.setValues(pts)
                self.arc.coordIndex.setValues(0, arcsegs + 1,
                                              list(range(arcsegs + 1)))

            # set the arrow coords and rotation
            self.trans1.translation.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.coord1.point.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.trans2.translation.setValue((self.p3.x, self.p3.y, self.p3.z))
            self.coord2.point.setValue((self.p3.x, self.p3.y, self.p3.z))
            # calculate small chords to make arrows look better
            arrowlength = 4 * obj.ViewObject.ArrowSize.Value
            u1 = (self.circle.valueAt(self.circle.FirstParameter + arrowlength)
                  ).sub(self.circle.valueAt(
                      self.circle.FirstParameter)).normalize()
            u2 = (self.circle.valueAt(self.circle.LastParameter)).sub(
                self.circle.valueAt(self.circle.LastParameter -
                                    arrowlength)).normalize()
            if hasattr(obj.ViewObject, "FlipArrows"):
                if obj.ViewObject.FlipArrows:
                    u1 = u1.negative()
                    u2 = u2.negative()
            w2 = self.circle.Curve.Axis
            w1 = w2.negative()
            v1 = w1.cross(u1)
            v2 = w2.cross(u2)
            q1 = App.Placement(DraftVecUtils.getPlaneRotation(u1, v1,
                                                              w1)).Rotation.Q
            q2 = App.Placement(DraftVecUtils.getPlaneRotation(u2, v2,
                                                              w2)).Rotation.Q
            self.trans1.rotation.setValue((q1[0], q1[1], q1[2], q1[3]))
            self.trans2.rotation.setValue((q2[0], q2[1], q2[2], q2[3]))

            # setting text pos & rot
            self.tbase = mp
            if hasattr(obj.ViewObject, "TextPosition"):
                if not DraftVecUtils.isNull(obj.ViewObject.TextPosition):
                    self.tbase = obj.ViewObject.TextPosition

            u3 = ray.cross(norm).normalize()
            v3 = norm.cross(u3)
            r = App.Placement(DraftVecUtils.getPlaneRotation(u3, v3,
                                                             norm)).Rotation
            offset = r.multVec(App.Vector(0, 1, 0))

            if hasattr(obj.ViewObject, "TextSpacing"):
                offset = DraftVecUtils.scaleTo(
                    offset, obj.ViewObject.TextSpacing.Value)
            else:
                offset = DraftVecUtils.scaleTo(offset, 0.05)
            if m == "3D":
                offset = offset.negative()
            self.tbase = self.tbase.add(offset)
            q = r.Q
            self.textpos.translation.setValue(
                [self.tbase.x, self.tbase.y, self.tbase.z])
            self.textpos.rotation = coin.SbRotation(q[0], q[1], q[2], q[3])

            # set the angle property
            if round(obj.Angle, utils.precision()) != round(
                    a, utils.precision()):
                obj.Angle = a
Example #22
0
 def arc_through_to(self, through, to):
     points = (self.current_position, through, to)
     self.components.append(
         Part.Arc(*[self.vector(coordinates) for coordinates in points]))
     self.current_position = to
Example #23
0
    def edgeForCmd(cls, cmd, startPoint):
        """(cmd, startPoint).
        Returns an Edge representing the given command, assuming a given startPoint."""

        endPoint = cls.commandEndPoint(cmd, startPoint)
        if (cmd.Name in cls.CmdMoveStraight) or (cmd.Name in cls.CmdMoveRapid):
            if cls.pointsCoincide(startPoint, endPoint):
                return None
            return Part.Edge(Part.LineSegment(startPoint, endPoint))

        if cmd.Name in cls.CmdMoveArc:
            center = startPoint + cls.commandEndPoint(cmd, Vector(0, 0, 0),
                                                      'I', 'J', 'K')
            A = cls.xy(startPoint - center)
            B = cls.xy(endPoint - center)
            d = -B.x * A.y + B.y * A.x

            if cls.isRoughly(d, 0, 0.005):
                PathLog.debug("Half circle arc at: (%.2f, %.2f, %.2f)" %
                              (center.x, center.y, center.z))
                # we're dealing with half a circle here
                angle = cls.getAngle(A) + math.pi / 2
                if cmd.Name in cls.CmdMoveCW:
                    angle -= math.pi
            else:
                C = A + B
                angle = cls.getAngle(C)
                PathLog.debug(
                    "Arc (%8f) at: (%.2f, %.2f, %.2f) -> angle=%f" %
                    (d, center.x, center.y, center.z, angle / math.pi))

            R = A.Length
            PathLog.debug(
                "arc: p1=(%.2f, %.2f) p2=(%.2f, %.2f) -> center=(%.2f, %.2f)" %
                (startPoint.x, startPoint.y, endPoint.x, endPoint.y, center.x,
                 center.y))
            PathLog.debug("arc: A=(%.2f, %.2f) B=(%.2f, %.2f) -> d=%.2f" %
                          (A.x, A.y, B.x, B.y, d))
            PathLog.debug("arc: R=%.2f angle=%.2f" % (R, angle / math.pi))
            if cls.isRoughly(startPoint.z, endPoint.z):
                midPoint = center + Vector(math.cos(angle), math.sin(angle),
                                           0) * R
                PathLog.debug(
                    "arc: (%.2f, %.2f) -> (%.2f, %.2f) -> (%.2f, %.2f)" %
                    (startPoint.x, startPoint.y, midPoint.x, midPoint.y,
                     endPoint.x, endPoint.y))
                return Part.Edge(Part.Arc(startPoint, midPoint, endPoint))

            # It's a Helix
            #print('angle: A=%.2f B=%.2f' % (cls.getAngle(A)/math.pi, cls.getAngle(B)/math.pi))
            if cmd.Name in cls.CmdMoveCW:
                cw = True
            else:
                cw = False
            angle = cls.diffAngle(cls.getAngle(A), cls.getAngle(B),
                                  'CW' if cw else 'CCW')
            height = endPoint.z - startPoint.z
            pitch = height * math.fabs(2 * math.pi / angle)
            if angle > 0:
                cw = not cw
            #print("Helix: R=%.2f h=%.2f angle=%.2f pitch=%.2f" % (R, height, angle/math.pi, pitch))
            helix = Part.makeHelix(pitch, height, R, 0, not cw)
            helix.rotate(Vector(), Vector(0, 0, 1),
                         180 * cls.getAngle(A) / math.pi)
            e = helix.Edges[0]
            helix.translate(startPoint - e.valueAt(e.FirstParameter))
            return helix.Edges[0]
        return None
Example #24
0
def makeArc(p):
    arc = Part.Arc(p[0], p[1], p[2])
    return arc.toShape()
Example #25
0
    def inOutBoneCommands(self, bone, boneAngle, fixedLength):
        corner = bone.corner(self.toolRadius)

        bone.tip = bone.inChord.End  # in case there is no bone

        PathLog.debug("corner = (%.2f, %.2f)" % (corner.x, corner.y))
        #debugMarker(corner, 'corner', (1., 0., 1.), self.toolRadius)

        length = fixedLength
        if bone.obj.Incision == Incision.Custom:
            length = bone.obj.Custom
        if bone.obj.Incision == Incision.Adaptive:
            length = bone.adaptiveLength(boneAngle, self.toolRadius)

        if length == 0:
            PathLog.info("no bone after all ..")
            return [bone.lastCommand, bone.outChord.g1Command()]

        boneInChord = bone.inChord.move(length, boneAngle)
        boneOutChord = boneInChord.moveTo(bone.outChord.Start)

        #debugCircle(boneInChord.Start, self.toolRadius, 'boneStart')
        #debugCircle(boneInChord.End, self.toolRadius, 'boneEnd')

        bone.tip = boneInChord.End

        if bone.smooth == 0:
            return [
                bone.lastCommand,
                boneInChord.g1Command(),
                boneOutChord.g1Command(),
                bone.outChord.g1Command()
            ]

        # reconstruct the corner and convert to an edge
        offset = corner - bone.inChord.End
        iChord = Chord(bone.inChord.Start + offset, bone.inChord.End + offset)
        oChord = Chord(bone.outChord.Start + offset,
                       bone.outChord.End + offset)
        iLine = iChord.asLine()
        oLine = oChord.asLine()
        cornerShape = Part.Shape([iLine, oLine])

        # construct a shape representing the cut made by the bone
        vt0 = FreeCAD.Vector(0, self.toolRadius, 0)
        vt1 = FreeCAD.Vector(length, self.toolRadius, 0)
        vb0 = FreeCAD.Vector(0, -self.toolRadius, 0)
        vb1 = FreeCAD.Vector(length, -self.toolRadius, 0)
        vm2 = FreeCAD.Vector(length + self.toolRadius, 0, 0)

        boneBot = Part.LineSegment(vb1, vb0)
        boneLid = Part.LineSegment(vb0, vt0)
        boneTop = Part.LineSegment(vt0, vt1)

        # what we actually want is an Arc - but findIntersect only returns the coincident if one exists
        # which really sucks because that's the one we're probably not interested in ....
        boneArc = Part.Arc(vt1, vm2, vb1)
        #boneArc = Part.Circle(FreeCAD.Vector(length, 0, 0), FreeCAD.Vector(0,0,1), self.toolRadius)
        boneWire = Part.Shape([boneTop, boneArc, boneBot, boneLid])
        boneWire.rotate(FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(0, 0, 1),
                        boneAngle * 180 / math.pi)
        boneWire.translate(bone.inChord.End)
        self.boneShapes = [cornerShape, boneWire]

        bone.inCommands = self.smoothChordCommands(bone,
                                                   bone.inChord, boneInChord,
                                                   Part.Edge(iLine), boneWire,
                                                   corner,
                                                   bone.smooth & Smooth.In,
                                                   (1., 0., 0.))
        bone.outCommands = self.smoothChordCommands(bone, boneOutChord,
                                                    bone.outChord,
                                                    Part.Edge(oLine), boneWire,
                                                    corner,
                                                    bone.smooth & Smooth.Out,
                                                    (0., 1., 0.))
        return bone.inCommands + bone.outCommands
Example #26
0
def part_arc_from_points_and_center(p_1, p_2, m):
    p_1, p_12, p_2 = arc_from_points_and_center(p_1, p_2, m)
    return Part.Arc(App.Vector(*p_1, 0.), App.Vector(*p_12, 0.), App.Vector(*p_2, 0.))
Example #27
0
    def execute(self, obj):
        "creates the panel shape"

        if self.clone(obj):
            return

        import Part, DraftGeomUtils

        # base tests
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
            elif obj.Base.isDerivedFrom("Mesh::Feature"):
                if not obj.Base.Mesh.isSolid():
                    return
        else:
            if obj.Length.Value:
                length = obj.Length.Value
            else:
                return
            if obj.Width.Value:
                width = obj.Width.Value
            else:
                return
        if obj.Thickness.Value:
            thickness = obj.Thickness.Value
        else:
            if not obj.Base:
                return
            elif obj.Base.isDerivedFrom("Part::Feature"):
                if not obj.Base.Shape.Solids:
                    return

        # creating base shape
        pl = obj.Placement
        base = None
        normal = None
        if hasattr(obj, "Normal"):
            if obj.Normal.Length > 0:
                normal = Vector(obj.Normal)
                normal.normalize()
                normal.multiply(thickness)
        baseprofile = None
        if obj.Base:
            base = obj.Base.Shape.copy()
            if not base.Solids:
                p = FreeCAD.Placement(obj.Base.Placement)
                if base.Faces:
                    baseprofile = base
                    if not normal:
                        normal = baseprofile.Faces[0].normalAt(
                            0, 0).multiply(thickness)
                    base = base.extrude(normal)
                elif base.Wires:
                    fm = False
                    if hasattr(obj, "FaceMaker"):
                        if obj.FaceMaker != "None":
                            try:
                                base = Part.makeFace(
                                    base.Wires,
                                    "Part::FaceMaker" + str(obj.FaceMaker))
                                fm = True
                            except:
                                FreeCAD.Console.PrintError(
                                    translate("Arch",
                                              "Facemaker returned an error") +
                                    "\n")
                                return
                    if not fm:
                        closed = True
                        for w in base.Wires:
                            if not w.isClosed():
                                closed = False
                        if closed:
                            baseprofile = ArchCommands.makeFace(base.Wires)
                            if not normal:
                                normal = baseprofile.normalAt(
                                    0, 0).multiply(thickness)
                            base = baseprofile.extrude(normal)
                elif obj.Base.isDerivedFrom("Mesh::Feature"):
                    if obj.Base.Mesh.isSolid():
                        if obj.Base.Mesh.countComponents() == 1:
                            sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
                            if sh.isClosed() and sh.isValid() and sh.Solids:
                                base = sh
        else:
            if not normal:
                normal = Vector(0, 0, 1).multiply(thickness)
            l2 = length / 2 or 0.5
            w2 = width / 2 or 0.5
            v1 = Vector(-l2, -w2, 0)
            v2 = Vector(l2, -w2, 0)
            v3 = Vector(l2, w2, 0)
            v4 = Vector(-l2, w2, 0)
            base = Part.makePolygon([v1, v2, v3, v4, v1])
            baseprofile = Part.Face(base)
            base = baseprofile.extrude(normal)

        if hasattr(obj, "Area"):
            if baseprofile:
                obj.Area = baseprofile.Area

        if hasattr(obj, "WaveLength"):
            if baseprofile and obj.WaveLength.Value and obj.WaveHeight.Value:
                # corrugated element
                bb = baseprofile.BoundBox
                bb.enlarge(bb.DiagonalLength)
                p1 = Vector(bb.getPoint(0).x, bb.getPoint(0).y, bb.Center.z)
                if obj.WaveType == "Curved":
                    p2 = p1.add(
                        Vector(obj.WaveLength.Value / 2, 0,
                               obj.WaveHeight.Value))
                    p3 = p2.add(
                        Vector(obj.WaveLength.Value / 2, 0,
                               -obj.WaveHeight.Value))
                    e1 = Part.Arc(p1, p2, p3).toShape()
                    p4 = p3.add(
                        Vector(obj.WaveLength.Value / 2, 0,
                               -obj.WaveHeight.Value))
                    p5 = p4.add(
                        Vector(obj.WaveLength.Value / 2, 0,
                               obj.WaveHeight.Value))
                    e2 = Part.Arc(p3, p4, p5).toShape()
                else:
                    if obj.WaveHeight.Value < obj.WaveLength.Value:
                        p2 = p1.add(
                            Vector(obj.WaveHeight.Value, 0,
                                   obj.WaveHeight.Value))
                        p3 = p2.add(
                            Vector(
                                obj.WaveLength.Value -
                                2 * obj.WaveHeight.Value, 0, 0))
                        p4 = p3.add(
                            Vector(obj.WaveHeight.Value, 0,
                                   -obj.WaveHeight.Value))
                        e1 = Part.makePolygon([p1, p2, p3, p4])
                        p5 = p4.add(
                            Vector(obj.WaveHeight.Value, 0,
                                   -obj.WaveHeight.Value))
                        p6 = p5.add(
                            Vector(
                                obj.WaveLength.Value -
                                2 * obj.WaveHeight.Value, 0, 0))
                        p7 = p6.add(
                            Vector(obj.WaveHeight.Value, 0,
                                   obj.WaveHeight.Value))
                        e2 = Part.makePolygon([p4, p5, p6, p7])
                    else:
                        p2 = p1.add(
                            Vector(obj.WaveLength.Value / 2, 0,
                                   obj.WaveHeight.Value))
                        p3 = p2.add(
                            Vector(obj.WaveLength.Value / 2, 0,
                                   -obj.WaveHeight.Value))
                        e1 = Part.makePolygon([p1, p2, p3])
                        p4 = p3.add(
                            Vector(obj.WaveLength.Value / 2, 0,
                                   -obj.WaveHeight.Value))
                        p5 = p4.add(
                            Vector(obj.WaveLength.Value / 2, 0,
                                   obj.WaveHeight.Value))
                        e2 = Part.makePolygon([p3, p4, p5])
                edges = [e1, e2]
                for i in range(int(bb.XLength / (obj.WaveLength.Value * 2))):
                    e1 = e1.copy()
                    e1.translate(Vector(obj.WaveLength.Value * 2, 0, 0))
                    e2 = e2.copy()
                    e2.translate(Vector(obj.WaveLength.Value * 2, 0, 0))
                    edges.extend([e1, e2])
                basewire = Part.Wire(edges)
                baseface = basewire.extrude(Vector(0, bb.YLength, 0))
                base = baseface.extrude(Vector(0, 0, thickness))
                rot = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), normal)
                base.rotate(bb.Center, rot.Axis, math.degrees(rot.Angle))
                if obj.WaveDirection.Value:
                    base.rotate(bb.Center, normal, obj.WaveDirection.Value)
                n1 = normal.negative().normalize().multiply(
                    obj.WaveHeight.Value * 2)
                self.vol = baseprofile.copy()
                self.vol.translate(n1)
                self.vol = self.vol.extrude(n1.negative().multiply(2))
                base = self.vol.common(base)
                base = base.removeSplitter()
                if not base:
                    FreeCAD.Console.PrintError(
                        transpate("Arch", "Error computing shape of ") +
                        obj.Label + "\n")
                    return False

        if base and (obj.Sheets > 1) and normal and thickness:
            bases = [base]
            for i in range(1, obj.Sheets):
                n = FreeCAD.Vector(normal).normalize().multiply(i * thickness)
                b = base.copy()
                b.translate(n)
                bases.append(b)
            base = Part.makeCompound(bases)

        if base and normal and hasattr(obj, "Offset"):
            if obj.Offset.Value:
                v = DraftVecUtils.scaleTo(normal, obj.Offset.Value)
                base.translate(v)

        # process subshapes
        base = self.processSubShapes(obj, base, pl)

        # applying
        if base:
            if not base.isNull():
                if base.isValid() and base.Solids:
                    if base.Volume < 0:
                        base.reverse()
                    if base.Volume < 0:
                        FreeCAD.Console.PrintError(
                            translate("Arch", "Couldn't compute a shape"))
                        return
                    base = base.removeSplitter()
                    obj.Shape = base
                    if not pl.isNull():
                        obj.Placement = pl
def superWireReverse(debuglist,closed=False):
    '''superWireReverse(debuglist,[closed]): forces a wire between edges
    that don't necessarily have coincident endpoints. If closed=True, wire
    will always be closed. debuglist has a tuple for every edge.The first
    entry is the edge, the second is the flag 'does not nedd to be inverted'
    '''
    #taken from draftlibs
    def median(v1,v2):
        vd = v2.sub(v1)
        vd.scale(.5,.5,.5)
        return v1.add(vd)
    try:
        from DraftGeomUtils import findMidpoint
    except ImportError: #workaround for Version 0.12
        from draftlibs.fcgeo import findMidpoint #workaround for Version 0.12
    import Part
    #edges = sortEdges(edgeslist)
    print debuglist
    newedges = []
    for i in range(len(debuglist)):
        curr = debuglist[i]
        if i == 0:
            if closed:
                prev = debuglist[-1]
            else:
                prev = None
        else:
            prev = debuglist[i-1]
        if i == (len(debuglist)-1):
            if closed:
                nexte = debuglist[0]
            else:
                nexte = None
        else:
            nexte = debuglist[i+1]
        print i,prev,curr,nexte
        if prev:
            if curr[0].Vertexes[-1*(not curr[1])].Point == \
                    prev[0].Vertexes[-1*prev[1]].Point:
                p1 = curr[0].Vertexes[-1*(not curr[1])].Point
            else:
                p1 = median(curr[0].Vertexes[-1*(not curr[1])].Point,\
                        prev[0].Vertexes[-1*prev[1]].Point)
        else:
            p1 = curr[0].Vertexes[-1*(not curr[1])].Point
        if nexte:
            if curr[0].Vertexes[-1*curr[1]].Point == \
                nexte[0].Vertexes[-1*(not nexte[1])].Point:
                p2 = nexte[0].Vertexes[-1*(not nexte[1])].Point
            else:
                p2 = median(curr[0].Vertexes[-1*(curr[1])].Point,\
                        nexte[0].Vertexes[-1*(not nexte[1])].Point)
        else:
            p2 = curr[0].Vertexes[-1*(curr[1])].Point
        if isinstance(curr[0].Curve,Part.Line):
            print "line",p1,p2
            newedges.append(Part.Line(p1,p2).toShape())
        elif isinstance(curr[0].Curve,Part.Circle):
            p3 = findMidpoint(curr[0])
            print "arc",p1,p3,p2
            newedges.append(Part.Arc(p1,p3,p2).toShape())
        else:
            print "Cannot superWire edges that are not lines or arcs"
            return None
    print newedges
    return Part.Wire(newedges)
import sys
FREECADPATH = r"e:\FreeCAD 0.17x64\bin"
sys.path.append(FREECADPATH)  # шлях до бібліотек FreeCAD

import math
import FreeCAD as App  # модуль для роботи з програмою
import FreeCADGui as Gui  # модуль для роботи з GUI
import Part  # workbench-модуль для створення і керування BRep об'єктами

v1 = App.Vector(0, 0, 0)  # вектор (або точка)
v2 = App.Vector(0, 10, 0)
v3 = App.Vector(5, 5, 0)
l1 = Part.LineSegment(v1, v2)  # лінія
e1 = l1.toShape()  # ребро
# або e1=Part.makeLine((0,0,0),(0,10,0)) # ребро
a1 = Part.Arc(v1, v3, v2)  # дуга за трьома точками
e2 = a1.toShape()  # ребро
# або e2=Part.makeCircle(5,App.Vector(0,5,0),App.Vector(0,0,1),-90,90)

bs = Part.BSplineCurve()  # B-сплайн
bs.interpolate([(0, 0, 0), (0, 1, 1), (0, -1, 2)])  # шляхом інтерполяції
# або
#bs.approximate([(0,0,0),(0,1,1),(0,-1,2)]) # шляхом апроксимації
#bs.buildFromPoles([(0,0,0),(0,1,1),(0,-1,2)]) # за списком полюсів
e3 = bs.toShape()  # ребро

w1 = Part.Wire([e1, e2])  # цикл (сукупність ребер)
f1 = Part.Face(w1)  # грань
trsf = App.Matrix()  # матриця трансформації
trsf.rotateZ(math.pi / 4)  # повернути навколо осі z
trsf.move(App.Vector(5, 0, 0))  # перемістити
def make_rounded_rectangle_aperture(aperture_height, aperture_width, corner_radius):
    """Creates a wire outline of a rectangle.
    aperture_height and aperture_width are the full height and width.


    Args:
        aperture_height (float): Total height of the aperture
        aperture_width (float): Total width of the aperture

    Returns:
        wire1 (FreeCAD wire definition): An outline description of the shape.
        face1 (FreeCAD face definition): A surface description of the shape.
    """
    # Create the initial four vertices where line meets curve.
    v1 = Base.Vector(0, aperture_height / 2.0 - corner_radius, -aperture_width / 2.0)
    v2 = Base.Vector(0, aperture_height / 2.0, -aperture_width / 2.0 + corner_radius)
    v3 = Base.Vector(0, aperture_height / 2.0, aperture_width / 2.0 - corner_radius)
    v4 = Base.Vector(0, aperture_height / 2.0 - corner_radius, aperture_width / 2.0)
    v5 = Base.Vector(0, -aperture_height / 2.0 + corner_radius, aperture_width / 2.0)
    v6 = Base.Vector(0, -aperture_height / 2.0, aperture_width / 2.0 - corner_radius)
    v7 = Base.Vector(0, -aperture_height / 2.0, -aperture_width / 2.0 + corner_radius)
    v8 = Base.Vector(0, -aperture_height / 2.0 + corner_radius, -aperture_width / 2.0)
    # Create lines
    line1 = Part.LineSegment(v2, v3)
    line2 = Part.LineSegment(v4, v5)
    line3 = Part.LineSegment(v6, v7)
    line4 = Part.LineSegment(v8, v1)

    centre_curve_offset = corner_radius * (1 - 1 / sqrt(2))
    vc1 = Base.Vector(
        0,
        aperture_height / 2.0 - centre_curve_offset,
        -aperture_width / 2.0 + centre_curve_offset,
    )
    vc2 = Base.Vector(
        0,
        aperture_height / 2.0 - centre_curve_offset,
        aperture_width / 2.0 - centre_curve_offset,
    )
    vc3 = Base.Vector(
        0,
        -aperture_height / 2.0 + centre_curve_offset,
        aperture_width / 2.0 - centre_curve_offset,
    )
    vc4 = Base.Vector(
        0,
        -aperture_height / 2.0 + centre_curve_offset,
        -aperture_width / 2.0 + centre_curve_offset,
    )

    arc1 = Part.Arc(v1, vc1, v2)
    arc2 = Part.Arc(v3, vc2, v4)
    arc3 = Part.Arc(v5, vc3, v6)
    arc4 = Part.Arc(v7, vc4, v8)
    # Make a shape
    shape1 = Part.Shape([arc1, line1, arc2, line2, arc3, line3, arc4, line4])
    # Make a wire outline.
    wire1 = Part.Wire(shape1.Edges)
    # Make a face.
    face1 = Part.Face(wire1)
    return wire1, face1