Example #1
0
 def makeHelix(cls, pitch, height, radius, angle=360.0):
     """
     Make a helix with a given pitch, height and radius
     By default a cylindrical surface is used to create the helix. If
     the fourth parameter is set (the apex given in degree) a conical surface is used instead'
     """
     return Wire(FreeCADPart.makeHelix(pitch, height, radius, angle))
 def makeHelix(cls, pitch, height, radius, angle=360.0):
     """
     Make a helix with a given pitch, height and radius
     By default a cylindrical surface is used to create the helix. If
     the fourth parameter is set (the apex given in degree) a conical surface is used instead'
     """
     return Wire(FreeCADPart.makeHelix(pitch, height, radius, angle))
Example #3
0
 def generateModel(self):
     self.status.updateStatus("Creating .FCStd file")
     doc = FreeCAD.newDocument(self.fileName)
     pitch = math.pi * self.module * self.teeth / math.tan(self.helixAngle)
     self.status.updateStatus("Calculating parameters for helix")
     pitchRadius = self.module * self.teeth / 2
     self.status.updateStatus("Drafting helix")
     helix = Part.makeHelix(pitch, self.faceWidth * self.module,
                            pitchRadius, 0, self.leftHand, False)
     doc.addObject("Part::Feature", "helix")
     doc.helix.Shape = helix
     self.status.updateStatus("Generating involute profile")
     doc.addObject("Part::Sweep", "helicalGear")
     profile, height=InvoluteProfile.generateProfile(self.pressureAngle,\
                                                     self.module,self.teeth,\
                                                     self.faceWidth,\
                                                     self.clearance,self.fillet,\
                                                     self.status)
     self.status.updateStatus("Sweeping involute profile")
     doc.helicalGear.Sections = doc.findObjects("Part::Feature",
                                                profile.Name)
     doc.helicalGear.Spine = doc.helix
     doc.helicalGear.Solid = True
     doc.helicalGear.Frenet = True
     FreeCADGui.ActiveDocument.getObject(profile.Name).Visibility = False
     FreeCADGui.ActiveDocument.getObject("helix").Visibility = False
     doc.recompute()
     self.status.updateStatus("Done")
Example #4
0
def helical_path(pitch, length, radius, angle=0, lefthand=False):
    # FIXME: update to master branch of cadquery
    wire = cadquery.Wire(FreeCADPart.makeHelix(pitch, length, radius, angle, lefthand))
    #wire = cadquery.Wire.makeHelix(pitch, length, radius, angle=angle, lefthand=lefthand)
    shape = cadquery.Wire.combine([wire])
    path = cadquery.Workplane("XY").newObject([shape])
    return path
Example #5
0
File: meca.py Project: nnayo/egere
    def __init__(self, doc, name='helix'):
        self.data = {
            'len lo': 70., # mm
            'len up': 120., # mm
            'int diameter': 36., # mm
            'thick': 1., # mm
        }

        len_lo = self.data['len lo']

        # blocking thread (pas de vis de blocage)
        radius = self.data['int diameter'] / 2

        helix = Part.makeHelix(4., 16., radius)

        p0 = (radius, 0, 0)
        p1 = (radius, 0, 3)
        p2 = (radius - 1, 0, 2)
        p3 = (radius - 1, 0, 1)

        e0 = Part.makeLine(p0, p1)
        e1 = Part.makeLine(p1, p2)
        e2 = Part.makeLine(p2, p3)
        e3 = Part.makeLine(p3, p0)
        section = Part.Wire([e0, e1, e2, e3])
        helix = Part.Wire(helix).makePipeShell([section], 1, 1)
        helix.translate(Vector(0, 0, len_lo - 20))

        helix = helix.fuse(helix)

        comp = helix

        MecaComponent.__init__(self, doc, comp, name, (1., 1., 0.))
Example #6
0
def helical_path(pitch, length, radius, angle=0, lefthand=False):
    # FIXME: update to master branch of cadquery
    wire = cadquery.Wire(
        FreeCADPart.makeHelix(pitch, length, radius, angle, lefthand))
    #wire = cadquery.Wire.makeHelix(pitch, length, radius, angle=angle, lefthand=lefthand)
    shape = cadquery.Wire.combine([wire])
    path = cadquery.Workplane("XY").newObject([shape])
    return path
Example #7
0
def make_helix(pitch, height, radius, apex_angle=0):
    # FIXME: in FreeCAD pydoc, there is also "makeLongHelix",
    # which seems to be more suitable here because it said to be "multi-edge";
    # However, in my experiments, makeLongHelix always makes
    # a helix with exactly one turn, while makeHelix makes as many
    # turns as necessary.
    wire = Part.makeHelix(pitch, height, radius, apex_angle)
    fc_edge = wire.Edges[0]
    curve = SvSolidEdgeCurve(fc_edge)
    return curve
Example #8
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 d == 0:
                # 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)

            R = A.Length
            #print("arc: p1=(%.2f, %.2f) p2=(%.2f, %.2f) -> center=(%.2f, %.2f)" % (startPoint.x, startPoint.y, endPoint.x, endPoint.y, center.x, center.y))
            #print("arc: A=(%.2f, %.2f) B=(%.2f, %.2f) -> d=%.2f" % (A.x, A.y, B.x, B.y, d))
            #print("arc: R=%.2f angle=%.2f" % (R, angle/math.pi))
            if startPoint.z == endPoint.z:
                midPoint = center + FreeCAD.Vector(math.cos(angle),
                                                   math.sin(angle), 0) * R
                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 #9
0
def edgeForCmd(cmd, startPoint):
    """(cmd, startPoint).
    Returns an Edge representing the given command, assuming a given startPoint."""

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

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

        if 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 = getAngle(A) + math.pi/2
            if cmd.Name in CmdMoveCW:
                angle -= math.pi
        else:
            C = A + B
            angle = 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 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' % (getAngle(A)/math.pi, getAngle(B)/math.pi))
        if cmd.Name in CmdMoveCW:
            cw = True
        else:
            cw = False
        angle = diffAngle(getAngle(A), 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 * getAngle(A) / math.pi)
        e = helix.Edges[0]
        helix.translate(startPoint - e.valueAt(e.FirstParameter))
        return helix.Edges[0]
    return None
Example #10
0
def edgeForCmd(cmd, startPoint):
    """edgeForCmd(cmd, startPoint).
    Returns an Edge representing the given command, assuming a given startPoint."""

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

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

        if 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 = getAngle(A) + math.pi/2
            if cmd.Name in CmdMoveCW:
                angle -= math.pi
        else:
            C = A + B
            angle = 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 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' % (getAngle(A)/math.pi, getAngle(B)/math.pi))
        if cmd.Name in CmdMoveCW:
            cw = True
        else:
            cw = False
        angle = diffAngle(getAngle(A), 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 * getAngle(A) / math.pi)
        e = helix.Edges[0]
        helix.translate(startPoint - e.valueAt(e.FirstParameter))
        return helix.Edges[0]
    return None
Example #11
0
 def makeHelix(cls, pitch, height, radius, angle=0, lefthand=False, heightstyle=False):
     """
     Make a helix along +z axis
     :param pitch: displacement of 1 turn measured along surface.
     :param height: full length of helix surface (measured sraight along surface's face)
     :param radius: starting radius of helix
     :param angle: if > 0, conical surface is used instead of a cylindrical. (angle < 0 not supported)
     :param lefthand: if True, helix direction is reversed
     :param heightstyle: if True, pitch and height are measured parallel to z-axis
     """
     # FreeCAD doc: https://www.freecadweb.org/wiki/Part_API (search for makeHelix)
     return Wire(FreeCADPart.makeHelix(pitch, height, radius, angle, lefthand, heightstyle))
    def createGeometry(self, fp):
        import FreeCAD, Part, math, sys
        if fp.Base and fp.Height and fp.Base.Shape.isValid():
            solids = []
            for lower_face in fp.Base.Shape.Faces:
                upper_face = lower_face.copy()
                face_transform = FreeCAD.Matrix()
                face_transform.rotateZ(math.radians(fp.Angle.Value))
                face_transform.scale(fp.Scale[0], fp.Scale[1], 1.0)
                face_transform.move(FreeCAD.Vector(0, 0, fp.Height.Value))
                upper_face.transformShape(
                    face_transform, False,
                    True)  # True to check for non-uniform scaling

                spine = Part.makePolygon([(0, 0, 0), (0, 0, fp.Height.Value)])
                if fp.Angle.Value == 0.0:
                    auxiliary_spine = Part.makePolygon([
                        (1, 1, 0), (fp.Scale[0], fp.Scale[1], fp.Height.Value)
                    ])
                else:
                    num_revolutions = abs(fp.Angle.Value) / 360.0
                    pitch = fp.Height.Value / num_revolutions
                    height = fp.Height.Value
                    radius = 1.0
                    if fp.Angle.Value < 0.0:
                        left_handed = True
                    else:
                        left_handed = False

                    auxiliary_spine = Part.makeHelix(pitch, height, radius,
                                                     0.0, left_handed)

                faces = [lower_face, upper_face]
                for wire1, wire2 in zip(lower_face.Wires, upper_face.Wires):
                    pipe_shell = Part.BRepOffsetAPI.MakePipeShell(spine)
                    pipe_shell.setSpineSupport(spine)
                    pipe_shell.add(wire1)
                    pipe_shell.add(wire2)
                    pipe_shell.setAuxiliarySpine(auxiliary_spine, True, 0)
                    print(pipe_shell.getStatus())
                    assert (pipe_shell.isReady())
                    pipe_shell.build()
                    faces.extend(pipe_shell.shape().Faces)
                try:
                    fullshell = Part.Shell(faces)
                    solid = Part.Solid(fullshell)
                    if solid.Volume < 0:
                        solid.reverse()
                    assert (solid.Volume >= 0)
                    solids.append(solid)
                except Part.OCCError:
                    solids.append(Part.Compound(faces))
                fp.Shape = Part.Compound(solids)
    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.CmdMoveFast):
            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 d == 0:
                # 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)

            R = A.Length
            #print("arc: p1=(%.2f, %.2f) p2=(%.2f, %.2f) -> center=(%.2f, %.2f)" % (startPoint.x, startPoint.y, endPoint.x, endPoint.y, center.x, center.y))
            #print("arc: A=(%.2f, %.2f) B=(%.2f, %.2f) -> d=%.2f" % (A.x, A.y, B.x, B.y, d))
            #print("arc: R=%.2f angle=%.2f" % (R, angle/math.pi))
            if startPoint.z == endPoint.z:
                midPoint = center + FreeCAD.Vector(math.cos(angle), math.sin(angle), 0) * R
                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 #14
0
 def generateModel(self):
     XAXIS = FreeCAD.Vector(1, 0, 0)
     INTERFERANCE = 0.1
     ORIGIN = FreeCAD.Vector(0, 0, 0)
     COPY = True
     # doc=FreeCAD.newDocument(self.fileName);
     doc = FreeCAD.newDocument("Worm Gear")
     #temporary file name for testing
     # tooth=InvoluteProfile.generateTooth(self.pressureAngle,self.module,\
     #                                     self.teeth,self.clearance,\
     #                                     self.fillet);
     ###
     #temporary variables for testing
     MODULE = 4
     TEETH = 18
     PRESSURE_ANGLE = 20
     CLEARANCE = 0.5
     FILLET = 0.25
     clearance = CLEARANCE * MODULE
     ###
     tooth = InvoluteProfile.generateTooth(PRESSURE_ANGLE, MODULE, TEETH,
                                           CLEARANCE, FILLET)
     tooth = Draft.rotate(tooth, 90, ORIGIN, XAXIS, not (COPY))
     pitch = math.pi * MODULE
     helixRadius = MODULE * TEETH * math.cos(
         math.radians(PRESSURE_ANGLE)) / 2 - clearance
     helix = Part.makeHelix(pitch, MODULE * 20, helixRadius)
     doc.addObject("Part::Feature", "helix")
     doc.helix.Shape = helix
     doc.addObject("Part::Sweep", "threads")
     doc.threads.Sections = doc.findObjects("Part::Feature", tooth.Name)
     doc.threads.Spine = doc.helix
     doc.threads.Solid = True
     doc.threads.Frenet = True
     worm = Part.makeCylinder(tooth.Shape.BoundBox.XMin + INTERFERANCE,
                              MODULE * 20)
     doc.addObject("Part::Feature", "worm")
     doc.worm.Shape = worm
     doc.addObject("Part::MultiFuse", "wormGear")
     doc.wormGear.Shapes = [
         doc.threads,
         doc.worm,
     ]
     FreeCADGui.ActiveDocument.getObject(tooth.Name).Visibility = False
     FreeCADGui.ActiveDocument.getObject("helix").Visibility = False
     FreeCADGui.ActiveDocument.getObject("threads").Visibility = False
     FreeCADGui.ActiveDocument.getObject("worm").Visibility = False
     doc.recompute()
Example #15
0
 def execute(self, fp):
    pitch = fp.Pitch
    radius = fp.Diameter/2
    height = fp.Height
    barradius = fp.BarDiameter/2
    myhelix=Part.makeHelix(pitch,height,radius)
    g=myhelix.Edges[0].Curve
    c=Part.Circle()
    c.Center=g.value(0) # start point of the helix
    c.Axis=(0,1,0)
    c.Radius=barradius
    p=c.toShape()
    section = Part.Wire([p])
    makeSolid=1 #change to 1 to make a solid
    isFrenet=1
    myspring=Part.Wire(myhelix).makePipeShell([section],makeSolid,isFrenet)
    fp.Shape = myspring
Example #16
0
def drawsolid(d,l,p,wd):
    pitch = p; height= l; radius = d/2.0;barradius = wd/2
    myhelix=Part.makeHelix(pitch,height,radius)
    g=myhelix.Edges[0].Curve
    c=Part.Circle()
    c.Center=g.value(0) # start point of the helix
    c.Axis=(0,1,0)
    c.Radius=barradius
    p=c.toShape()
    section = Part.Wire([p])
    makeSolid=True
    isFrenet=True
    myspring=Part.Wire(myhelix).makePipeShell([section],makeSolid,True)
    
    solidlist= [myspring]
    result = ''
    result+= exportWebGL.getHTML(solidlist)
    return result
Example #17
0
 def execute(self, fp):
     pitch = fp.Pitch
     radius = fp.Diameter / 2
     height = fp.Height
     barradius = fp.BarDiameter / 2
     myhelix = Part.makeHelix(pitch, height, radius)
     g = myhelix.Edges[0].Curve
     c = Part.Circle()
     c.Center = g.value(0)  # start point of the helix
     c.Axis = (0, 1, 0)
     c.Radius = barradius
     p = c.toShape()
     section = Part.Wire([p])
     makeSolid = 1  #change to 1 to make a solid
     isFrenet = 1
     myspring = Part.Wire(myhelix).makePipeShell([section], makeSolid,
                                                 isFrenet)
     fp.Shape = myspring
Example #18
0
def drawsolid(d, l, p, wd):
    pitch = p
    height = l
    radius = d / 2.0
    barradius = wd / 2
    myhelix = Part.makeHelix(pitch, height, radius)
    g = myhelix.Edges[0].Curve
    c = Part.Circle()
    c.Center = g.value(0)  # start point of the helix
    c.Axis = (0, 1, 0)
    c.Radius = barradius
    p = c.toShape()
    section = Part.Wire([p])
    makeSolid = True
    isFrenet = True
    myspring = Part.Wire(myhelix).makePipeShell([section], makeSolid, True)

    solidlist = [myspring]
    result = ''
    result += exportWebGL.getHTML(solidlist)
    return result
Example #19
0
def cone_setup(doc, profil, data):
    """create all the shapes needed for the cone parts"""

    # if the final shapes already existed (true if one shape exists)
    # return them immediatly
    cone_top_obj = doc.getObject('_cone_top_base')
    cone_side_obj = doc.getObject('_cone_side_base')
    cone_struct_obj = doc.getObject('_cone_struct_base')
    cone_top_thread_obj = doc.getObject('_cone_top_thread')
    cone_struct_thread_obj = doc.getObject('_cone_struct_thread')

    if cone_top_obj:
        cone_top = cone_top_obj.Shape.copy()
        cone_side0 = cone_side_obj.Shape.copy()
        cone_side1 = cone_side_obj.Shape.copy()
        cone_side2 = cone_side_obj.Shape.copy()
        cone_struct = cone_struct_obj.Shape.copy()
        cone_top_thread = cone_top_thread_obj.Shape.copy()
        cone_struct_thread = cone_struct_thread_obj.Shape.copy()

        return cone_top, cone_side0, cone_side1, cone_side2, cone_struct, \
                cone_top_thread, cone_struct_thread

    side = profil['side']
    radius = profil['radius']
    diam_int = data['diameter']
    diam_ext = data['diameter'] + data['thick']
    length = data['len_lo'] + data['len_hi']
    struct_thick = data['struct_thick']

    # to modify the sphere to make it a ellipsoid
    matrix = Matrix()
    matrix.scale(1., 1., length / (diam_ext / 2))

    # to suppress the lower half of the sphere/ellipsoid
    lower = Part.makeBox(diam_ext, diam_ext, length)
    lower.translate(Vector(-diam_ext / 2, -diam_ext / 2, 0))

    gui_doc = FreeCADGui.ActiveDocument

    # make the external shape base of the cone
    sphere = Part.makeSphere(diam_ext / 2)
    sphere = sphere.transformGeometry(matrix)
    cone_base_ext = sphere.common(lower)
    cone_base_ext_obj = doc.addObject("Part::Feature", '_cone_base_ext')
    cone_base_ext_obj.Shape = cone_base_ext
    gui_doc.getObject('_cone_base_ext').Visibility = False

    # make the internal shape base of the cone
    sphere = Part.makeSphere(diam_int / 2)
    sphere = sphere.transformGeometry(matrix)
    cone_base_int = sphere.common(lower)
    cone_base_int_obj = doc.addObject("Part::Feature", '_cone_base_int')
    cone_base_int_obj.Shape = cone_base_int
    gui_doc.getObject('_cone_base_int').Visibility = False

    # make the skin
    skin = cone_base_ext.cut(cone_base_int)
    skin_obj = doc.addObject("Part::Feature", '_skin')
    skin_obj.Shape = skin
    gui_doc.getObject('_skin').Visibility = False

    # use profile shapes to make suppressed parts of the skin

    # full profil part
    shape = []
    shape.append(Vector(radius - 10, side / 2, 0))
    shape.append(Vector(radius + diam_ext, side / 2, 0))
    shape.append(Vector(radius + diam_ext, -side / 2, 0))
    shape.append(Vector(radius - 10, -side / 2, 0))
    shape.append(Vector(radius - 10, side / 2, 0))

    wire = Part.makePolygon(shape)
    face = Part.Face(wire)

    # make the volume
    long_cut_base = face.extrude(Vector(0, 0, length))
    long_cut_obj = doc.addObject("Part::Feature", '_long_cut_base')
    long_cut_obj.Shape = long_cut_base
    gui_doc.getObject('_long_cut_base').Visibility = False

    # full profil part
    shape = []
    shape.append(Vector(radius, side / 2, 0))
    shape.append(Vector(radius + diam_ext, side / 2, 0))
    shape.append(Vector(radius + diam_ext, -side / 2, 0))
    shape.append(Vector(radius, -side / 2, 0))
    shape.append(Vector(radius, side / 2, 0))

    wire = Part.makePolygon(shape)
    face = Part.Face(wire)

    # make the volume
    short_cut_base = face.extrude(Vector(0, 0, data['len_lo']))
    short_cut_obj = doc.addObject("Part::Feature", '_short_cut_base')
    short_cut_obj.Shape = short_cut_base
    gui_doc.getObject('_short_cut_base').Visibility = False

    # create 1/3 cylinder
    cylinder = Part.makeCylinder(diam_ext / 2, length, Vector(0, 0, 0), Vector(0, 0, 1), 120)
    cylinder_obj = doc.addObject("Part::Feature", '_cylinder_1_3')
    cylinder_obj.Shape = cylinder
    gui_doc.getObject('_cylinder_1_3').Visibility = False

    # thread bases
    radius_ext = diam_ext / 2 - struct_thick - 5
    thread_ext = Part.makeHelix(8, struct_thick - 8, radius_ext)
    radius_int = diam_ext / 2 - struct_thick - 9
    thread_int = Part.makeHelix(8, struct_thick, radius_int)

    # tube to make the space for threads
    tube_thread_ext = Part.makeCylinder(radius_ext, struct_thick)
    tube_thread_int = Part.makeCylinder(radius_int, struct_thick)
    tube_thread = tube_thread_ext.cut(tube_thread_int)
    tube_thread_obj = doc.addObject("Part::Feature", '_tube_thread')
    tube_thread_obj.Shape = tube_thread
    gui_doc.getObject('_tube_thread').Visibility = False

    # tube to cut the top of the structure
    tube_cut_ext = Part.makeCylinder(diam_ext / 2 - struct_thick / 2, struct_thick)
    tube_cut_int = tube_thread_int
    tube_cut = tube_cut_ext.cut(tube_cut_int)
    tube_cut_obj = doc.addObject("Part::Feature", '_tube_cut')
    tube_cut_obj.Shape = tube_cut
    gui_doc.getObject('_tube_cut').Visibility = False

    # tube to make the locking of the cone
    tube_lock_0 = Part.makeCylinder(diam_ext / 2 - struct_thick - 2, struct_thick / 2)
    tube_lock_1 = Part.makeCylinder(diam_ext / 2 - struct_thick + 2, struct_thick / 2)
    tube_lock_2 = Part.makeCylinder(diam_ext / 2, struct_thick / 4)

    tube_lock_int = tube_lock_1.cut(tube_lock_0)
    tube_lock_int.translate(Vector(0, 0, data['len_lo'] - 0.25 * data['struct_thick']))
    tube_lock_obj = doc.addObject("Part::Feature", '_tube_lock_int')
    tube_lock_obj.Shape = tube_lock_int
    gui_doc.getObject('_tube_lock_int').Visibility = False

    tube_lock_ext = tube_lock_2.cut(tube_lock_0)
    tube_lock_ext.translate(Vector(0, 0, data['len_lo'] - 0.25 * data['struct_thick']))
    tube_lock_obj = doc.addObject("Part::Feature", '_tube_lock_ext')
    tube_lock_obj.Shape = tube_lock_ext
    gui_doc.getObject('_tube_lock_ext').Visibility = False

    # make cone top part
    cone_top = cone_top_make(doc, gui_doc, data, skin, lower, cone_base_int, tube_cut, tube_thread, tube_lock_int)
    cone_top = cone_top.copy()

    cone_side = cone_side_make(doc, gui_doc, skin, lower, data, cone_base_int, long_cut_base, cylinder, tube_lock_int, tube_lock_ext)

    cone_side0 = cone_side.copy()
    cone_side0.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 0)
    cone_side1 = cone_side.copy()
    cone_side1.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 120)
    cone_side2 = cone_side.copy()
    cone_side2.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 240)

    cone_struct = cone_struct_make(doc, gui_doc, cone_base_ext, short_cut_base, data, cone_top, cone_side, tube_thread)

    # internal thread profile
    p0 = (radius_int, 0, 0)
    p1 = (radius_int + 4, 0, 4)
    p2 = (radius_int, 0, 8)

    e0 = Part.makeLine(p0, p1)
    e1 = Part.makeLine(p1, p2)
    e2 = Part.makeLine(p2, p0)
 
    section = Part.Wire([e0, e1, e2])
    cone_struct_thread = Part.Wire(thread_int).makePipeShell([section], 1, 1)

    cone_struct_thread_obj = doc.addObject("Part::Feature", '_cone_struct_thread')
    cone_struct_thread_obj.Shape = cone_struct_thread.copy()
    gui_doc.getObject('_cone_struct_thread').Visibility = False

    # external thread profile
    p0 = (radius_ext, 0, 0)
    p1 = (radius_ext - 4, 0, 4)
    p2 = (radius_ext, 0, 8)

    e0 = Part.makeLine(p0, p1)
    e1 = Part.makeLine(p1, p2)
    e2 = Part.makeLine(p2, p0)
 
    section = Part.Wire([e0, e1, e2])
    cone_top_thread = Part.Wire(thread_ext).makePipeShell([section], 1, 1)

    cone_top_thread_obj = doc.addObject("Part::Feature", '_cone_top_thread')
    cone_top_thread_obj.Shape = cone_top_thread.copy()
    gui_doc.getObject('_cone_top_thread').Visibility = False

    return cone_top, cone_side0, cone_side1, cone_side2, cone_struct, \
            cone_top_thread, cone_struct_thread
Example #20
0
    def createGeometry(self, fp):
        import FreeCAD, Part, math, sys
        if fp.Base and fp.Height and fp.Base.Shape.isValid():
            solids = []
            for lower_face in fp.Base.Shape.Faces:
                upper_face = lower_face.copy()
                face_transform = FreeCAD.Matrix()
                face_transform.rotateZ(math.radians(fp.Angle.Value))
                face_transform.scale(fp.Scale[0], fp.Scale[1], 1.0)
                face_transform.move(FreeCAD.Vector(0, 0, fp.Height.Value))
                upper_face.transformShape(
                    face_transform, False,
                    True)  # True to check for non-uniform scaling

                spine = Part.makePolygon([(0, 0, 0), (0, 0, fp.Height.Value)])
                if fp.Angle.Value == 0.0:
                    auxiliary_spine = Part.makePolygon([
                        (1, 1, 0), (fp.Scale[0], fp.Scale[1], fp.Height.Value)
                    ])
                else:
                    num_revolutions = abs(fp.Angle.Value) / 360.0
                    pitch = fp.Height.Value / num_revolutions
                    height = fp.Height.Value
                    radius = 1.0
                    if fp.Angle.Value < 0.0:
                        left_handed = True
                    else:
                        left_handed = False

                    auxiliary_spine = Part.makeHelix(pitch, height, radius,
                                                     0.0, left_handed)

                    # OCC versions before 7.5 had a problem with using a helix as the auxilliary spine, so approximate
                    # it piecewise
                    occ_version = Part.OCC_VERSION.split(".")
                    if int(occ_version[0]) <= 7 and int(occ_version[1]) < 5:
                        num_points = int(
                            max(3, num_revolutions *
                                36))  # Every ten degrees is adequate
                        wire = auxiliary_spine.Wires[0]
                        points = wire.discretize(Number=num_points)
                        auxiliary_spine = Part.makePolygon(points)

                faces = [lower_face, upper_face]
                for wire1, wire2 in zip(lower_face.Wires, upper_face.Wires):
                    pipe_shell = Part.BRepOffsetAPI.MakePipeShell(spine)
                    pipe_shell.setSpineSupport(spine)
                    pipe_shell.add(wire1)
                    pipe_shell.add(wire2)
                    pipe_shell.setAuxiliarySpine(auxiliary_spine, True, 0)
                    print(pipe_shell.getStatus())
                    assert (pipe_shell.isReady())
                    pipe_shell.build()
                    faces.extend(pipe_shell.shape().Faces)
                try:
                    fullshell = Part.Shell(faces)
                    solid = Part.Solid(fullshell)
                    if solid.Volume < 0:
                        solid.reverse()
                    assert (solid.Volume >= 0)
                    solids.append(solid)
                except Part.OCCError:
                    solids.append(Part.Compound(faces))
                fp.Shape = Part.Compound(solids)