Exemplo n.º 1
0
    def execute(self,obj):
        
        if self.clone(obj):
            return
 
        pl = obj.Placement
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        chamfer = obj.Chamfer.Value
        dentheight = obj.DentHeight.Value
        dentwidth = obj.DentWidth.Value
        
        if (length == 0) or (width == 0) or (height == 0):
            return
        if ((chamfer+dentwidth) >= width) or (dentheight >= height):
            return
    
        import Part
        p = []
        p.append(Vector(0,0,0))
        p.append(Vector(length,0,0))
        p.append(Vector(length,width,0))
        p.append(Vector(0,width,0))
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(0,0,height))
        if chamfer > 0:
            p = []
            p.append(Vector(0,width-chamfer,0))
            p.append(Vector(chamfer,width,0))
            p.append(Vector(0,width,0))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            s = f.extrude(Vector(0,0,height))
            shape = shape.cut(s)
            p = []
            p.append(Vector(length,width-chamfer,0))
            p.append(Vector(length-chamfer,width,0))
            p.append(Vector(length,width,0))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            s = f.extrude(Vector(0,0,height))
            shape = shape.cut(s)
            p = []
            p.append(Vector(0,width-chamfer,0))
            p.append(Vector(0,width,chamfer))
            p.append(Vector(0,width,0))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            s = f.extrude(Vector(length,0,0))
            shape = shape.cut(s)
            p = []
            p.append(Vector(0,width-chamfer,height))
            p.append(Vector(0,width,height-chamfer))
            p.append(Vector(0,width,height))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            s = f.extrude(Vector(length,0,0))
            shape = shape.cut(s)
        if (dentheight > 0) and (dentwidth > 0):
            p = []
            p.append(Vector(0,((width-chamfer)-dentwidth)/2,0))
            p.append(Vector(0,((width-chamfer)-dentwidth)/2+dentwidth,0))
            p.append(Vector(0,((width-chamfer)-dentwidth)/2+dentwidth,dentheight))
            p.append(Vector(0,((width-chamfer)-dentwidth)/2,dentheight))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            s = f.extrude(Vector(length,0,0))
            shape = shape.cut(s)
            s.translate(Vector(0,0,height))
            shape = shape.fuse(s)
        
        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)
Exemplo n.º 2
0
def process(filename):
    """Process the filename and create a Draft Wire from the data.

    The common airfoil dat format has many flavors.
    This code should work with almost every dialect.

    Parameters
    ----------
    filename : str
        The path to the filename to be opened.

    Returns
    -------
    Part::Part2DObject or None.
        The created Draft Wire object or None if the file contains less
        than 3 points.
    """
    # Regex to identify data rows and throw away unused metadata
    xval = r'(?P<xval>\-?\s*\d*\.*\d*([Ee]\-?\d+)?)'
    yval = r'(?P<yval>\-?\s*\d*\.*\d*([Ee]\-?\d+)?)'
    _regex = r'^\s*' + xval + r'\,?\s*' + yval + r'\s*$'

    regex = re.compile(_regex)
    afile = pythonopen(filename, 'r')
    # read the airfoil name which is always at the first line
    airfoilname = afile.readline().strip()

    coords = []
    # upside = True
    # last_x = None

    # Collect the data
    for lin in afile:
        curdat = regex.match(lin)
        if (curdat is not None
                and curdat.group("xval")
                and curdat.group("yval")):
            x = float(curdat.group("xval"))
            y = float(curdat.group("yval"))

            # Some files specify the number of upper and lower points on the 2nd line:
            # "       67.       72."
            # See: http://airfoiltools.com/airfoil
            # This line must be skipped:
            if x < 2 and y < 2:
                # the normal processing
                coords.append(Vector(x, y, 0))

    afile.close()

    if len(coords) < 3:
        FCC.PrintError(translate("ImportAirfoilDAT", "Did not find enough coordinates") + "\n")
        return None

    # sometimes coords are divided in upper an lower side
    # so that x-coordinate begin new from leading or trailing edge
    # check for start coordinates in the middle of list
    if coords[0:-1].count(coords[0]) > 1:
        flippoint = coords.index(coords[0], 1)
        upper = coords[0:flippoint]
        lower = coords[flippoint+1:]
        lower.reverse()
        for i in lower:
            upper.append(i)
        coords = upper

    # do we use the parametric Draft Wire?
    if useDraftWire:
        obj = Draft.make_wire(coords, True)
        # obj.label = airfoilname
    else:
        # alternate solution, uses common Part Faces
        lines = []
        first_v = None
        last_v = None
        for v in coords:
            if first_v is None:
                first_v = v

            # Line between v and last_v if they're not equal
            if (last_v is not None) and (last_v != v):
                lines.append(Part.makeLine(last_v, v))

            # The new last_v
            last_v = v

        # close the wire if needed
        if last_v != first_v:
            lines.append(Part.makeLine(last_v, first_v))

        wire = Part.Wire(lines)
        face = Part.Face(wire)
        obj = FreeCAD.ActiveDocument.addObject('Part::Feature', airfoilname)
        obj.Shape = face

    return obj
Exemplo n.º 3
0
import draftguitools.gui_arrays
import draftguitools.gui_annotationstyleeditor
from draftguitools.gui_layers import Layer

# ---------------------------------------------------------------------------
# Preflight stuff
# ---------------------------------------------------------------------------
# update the translation engine
FreeCADGui.updateLocale()

# sets the default working plane
plane = WorkingPlane.plane()
FreeCAD.DraftWorkingPlane = plane
defaultWP = Draft.getParam("defaultWP", 0)
if defaultWP == 1:
    plane.alignToPointAndAxis(Vector(0, 0, 0), Vector(0, 0, 1), 0)
elif defaultWP == 2:
    plane.alignToPointAndAxis(Vector(0, 0, 0), Vector(0, 1, 0), 0)
elif defaultWP == 3:
    plane.alignToPointAndAxis(Vector(0, 0, 0), Vector(1, 0, 0), 0)

# last snapped objects, for quick intersection calculation
lastObj = [0, 0]

# Set modifier keys
from draftguitools.gui_tool_utils import MODCONSTRAIN
from draftguitools.gui_tool_utils import MODSNAP
from draftguitools.gui_tool_utils import MODALT

# ---------------------------------------------------------------------------
# General functions
Exemplo n.º 4
0
 def getDeviation(self):
     """Return a deviation vector that represents the base of the circle."""
     import Part
     c = Part.makeCircle(1, Vector(0, 0, 0), self.normal)
     return c.Vertexes[0].Point
Exemplo n.º 5
0
    def alignToPointAndAxis_SVG(self, point, axis, offset=0):
        """Align the working plane to a point and an axis (vector).

        It aligns `u` and `v` based on the magnitude of the components
        of `axis`.
        Also set `weak` to `False`.

        Parameters
        ----------
        point : Base::Vector3
            The new `position` of the plane, adjusted by
            the `offset`.
        axis : Base::Vector3
            A vector whose unit vector will be used as the new `axis`
            of the plane.
            The magnitudes of the `x`, `y`, `z` components of the axis
            determine the orientation of `u` and `v` of the plane.
        offset : float, optional
            Defaults to zero. A value which will be used to offset
            the plane in the direction of its `axis`.

        Cases
        -----
        The `u` and `v` are always calculated the same

            * `u` is the cross product of the positive or negative of `axis`
              with a `reference vector`.
              ::
                  u = [+1|-1] axis.cross(ref_vec)
            * `v` is `u` rotated 90 degrees around `axis`.

        Whether the `axis` is positive or negative, and which reference
        vector is used, depends on the absolute values of the `x`, `y`, `z`
        components of the `axis` unit vector.

         #. If `x > y`, and `y > z`
             The reference vector is +Z
             ::
                 u = -1 axis.cross(+Z)
         #. If `y > z`, and `z >= x`
             The reference vector is +X.
             ::
                 u = -1 axis.cross(+X)
         #. If `y >= x`, and `x > z`
             The reference vector is +Z.
             ::
                 u = +1 axis.cross(+Z)
         #. If `x > z`, and `z >= y`
             The reference vector is +Y.
             ::
                 u = +1 axis.cross(+Y)
         #. If `z >= y`, and `y > x`
             The reference vector is +X.
             ::
                 u = +1 axis.cross(+X)
         #. otherwise
             The reference vector is +Y.
             ::
                 u = -1 axis.cross(+Y)
        """
        self.doc = FreeCAD.ActiveDocument
        self.axis = axis
        self.axis.normalize()
        ref_vec = Vector(0.0, 1.0, 0.0)

        if ((abs(axis.x) > abs(axis.y)) and (abs(axis.y) > abs(axis.z))):
            ref_vec = Vector(0.0, 0., 1.0)
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "Case new"

        elif ((abs(axis.y) > abs(axis.z)) and (abs(axis.z) >= abs(axis.x))):
            ref_vec = Vector(1.0, 0.0, 0.0)
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "Y>Z, View Y"

        elif ((abs(axis.y) >= abs(axis.x)) and (abs(axis.x) > abs(axis.z))):
            ref_vec = Vector(0.0, 0., 1.0)
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "ehem. XY, Case XY"

        elif ((abs(axis.x) > abs(axis.z)) and (abs(axis.z) >= abs(axis.y))):
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "X>Z, View X"

        elif ((abs(axis.z) >= abs(axis.y)) and (abs(axis.y) > abs(axis.x))):
            ref_vec = Vector(1.0, 0., 0.0)
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "Y>X, Case YZ"

        else:
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi / 2, self.axis)
            # projcase = "else"

        # spat_vec = self.u.cross(self.v)
        # spat_res = spat_vec.dot(axis)
        # Console.PrintMessage(projcase + " spat Prod = " + str(spat_res) + "\n")

        offsetVector = Vector(axis)
        offsetVector.multiply(offset)
        self.position = point.add(offsetVector)
        self.weak = False
Exemplo n.º 6
0
 def p1(self, point=None):
     """Set or get the base point of the rectangle."""
     if point:
         self.setorigin(point)
     else:
         return Vector(self.coords.point.getValues()[0].getValue())
Exemplo n.º 7
0
 def p3(self, point=None):
     """Set or get the opposite (diagonal) point of the rectangle."""
     if point:
         self.update(point)
     else:
         return Vector(self.coords.point.getValues()[2].getValue())
Exemplo n.º 8
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()
Exemplo n.º 9
0
def setup(doc=None, solvertype="ccxtools"):
    # setup model

    if doc is None:
        doc = init_doc()

    # geometry objects
    # bottom box
    bottom_box_obj = doc.addObject("Part::Box", "BottomBox")
    bottom_box_obj.Length = 100
    bottom_box_obj.Width = 25
    bottom_box_obj.Height = 500
    bottom_box_obj.Placement = FreeCAD.Placement(
        Vector(186, 0, -247),
        Rotation(0, 0, 0),
        Vector(0, 0, 0),
    )
    doc.recompute()

    # top half cylinder, https://forum.freecadweb.org/viewtopic.php?f=18&t=43001#p366111
    top_halfcyl_obj = doc.addObject("Part::Cylinder", "TopHalfCylinder")
    top_halfcyl_obj.Radius = 30
    top_halfcyl_obj.Height = 500
    top_halfcyl_obj.Angle = 180
    top_halfcyl_sh = Part.getShape(top_halfcyl_obj,
                                   '',
                                   needSubElement=False,
                                   refine=True)
    top_halfcyl_obj.Shape = top_halfcyl_sh
    top_halfcyl_obj.Placement = FreeCAD.Placement(
        Vector(0, -42, 0),
        Rotation(0, 90, 0),
        Vector(0, 0, 0),
    )
    doc.recompute()

    # all geom fusion
    geom_obj = doc.addObject("Part::MultiFuse", "AllGeomFusion")
    geom_obj.Shapes = [bottom_box_obj, top_halfcyl_obj]
    if FreeCAD.GuiUp:
        bottom_box_obj.ViewObject.hide()
        top_halfcyl_obj.ViewObject.hide()
    doc.recompute()

    if FreeCAD.GuiUp:
        geom_obj.ViewObject.Document.activeView().viewAxonometric()
        geom_obj.ViewObject.Document.activeView().fitAll()

    # analysis
    analysis = ObjectsFem.makeAnalysis(doc, "Analysis")

    # solver
    if solvertype == "calculix":
        solver_object = analysis.addObject(
            ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX"))[0]
    elif solvertype == "ccxtools":
        solver_object = analysis.addObject(
            ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools"))[0]
        solver_object.WorkingDir = u""
    if solvertype == "calculix" or solvertype == "ccxtools":
        solver_object.AnalysisType = "static"
        solver_object.GeometricalNonlinearity = "linear"
        solver_object.ThermoMechSteadyState = False
        solver_object.MatrixSolverType = "default"
        solver_object.IterationsControlParameterTimeUse = False
        solver_object.SplitInputWriter = False
        """
        # solver parameter from fandaL, but they are not needed (see forum topic)
        solver_object.IterationsControlParameterTimeUse = True
        solver_object.IterationsControlParameterCutb = '0.25,0.5,0.75,0.85,,,1.5,'
        solver_object.IterationsControlParameterIter = '4,8,9,200,10,400,,200,,'
        solver_object.IterationsUserDefinedTimeStepLength = True
        solver_object.TimeInitialStep = 0.1
        solver_object.TimeEnd = 1.0
        solver_object.IterationsUserDefinedIncrementations = True  # parameter DIRECT
        """

    # material
    material_obj = analysis.addObject(
        ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial"))[0]
    mat = material_obj.Material
    mat["Name"] = "Steel-Generic"
    mat["YoungsModulus"] = "200000 MPa"
    mat["PoissonRatio"] = "0.30"
    material_obj.Material = mat
    analysis.addObject(material_obj)

    # constraint fixed
    con_fixed = analysis.addObject(
        ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed"))[0]
    con_fixed.References = [
        (geom_obj, "Face5"),
        (geom_obj, "Face6"),
        (geom_obj, "Face8"),
        (geom_obj, "Face9"),
    ]

    # constraint pressure
    con_pressure = analysis.addObject(
        ObjectsFem.makeConstraintPressure(doc, name="ConstraintPressure"))[0]
    con_pressure.References = [(geom_obj, "Face10")]
    con_pressure.Pressure = 100.0  # Pa ? = 100 Mpa ?
    con_pressure.Reversed = False

    # constraint contact
    con_contact = doc.Analysis.addObject(
        ObjectsFem.makeConstraintContact(doc, name="ConstraintContact"))[0]
    con_contact.References = [
        (geom_obj,
         "Face7"),  # first seams slave face, TODO proof in writer code!
        (geom_obj,
         "Face3"),  # second seams master face, TODO proof in writer code!
    ]
    con_contact.Friction = 0.0
    con_contact.Slope = 1000000.0  # contact stiffness 1000000.0 kg/(mm*s^2)

    # mesh
    from .meshes.mesh_contact_box_halfcylinder_tetra10 import create_nodes, create_elements
    fem_mesh = Fem.FemMesh()
    control = create_nodes(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating nodes.\n")
    control = create_elements(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating elements.\n")
    femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc,
                                                             mesh_name))[0]
    femmesh_obj.FemMesh = fem_mesh
    femmesh_obj.Part = geom_obj
    femmesh_obj.SecondOrderLinear = False

    doc.recompute()
    return doc
Exemplo n.º 10
0
def pointsH(H, W, D, t1, t2, t3):
    p1 = Vector(0, 0, 0)
    p2 = Vector(W, 0, 0)
    p3 = Vector(W, t2, 0)
    p4 = Vector(W / 2 + t1 / 2, t2, 0)
    p5 = Vector(W / 2 + t1 / 2, H - t3, 0)
    p6 = Vector(W / 2 + D / 2, H - t3, 0)
    p7 = Vector(W / 2 + D / 2, H, 0)
    p8 = Vector(W / 2 - D / 2, H, 0)
    p9 = Vector(W / 2 - D / 2, H - t3, 0)
    p10 = Vector(W / 2 - t1 / 2, H - t3, 0)
    p11 = Vector(W / 2 - t1 / 2, t2, 0)
    p12 = Vector(0, t2, 0)
    return [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p1]
Exemplo n.º 11
0
def pointsOmega(H, W, D, t1, t2, t3):
    p1 = Vector(0, 0, 0)
    p2 = Vector(W, 0, 0)
    p3 = Vector(W, H - t3, 0)
    p4 = Vector(W + D - t1, H - t3, 0)
    p5 = Vector(W + D - t1, H, 0)
    p6 = Vector(W - t1, H, 0)
    p7 = Vector(W - t1, t2, 0)
    p8 = Vector(t1, t2, 0)
    p9 = Vector(t1, H, 0)
    p10 = Vector(t1 - D, H, 0)
    p11 = Vector(t1 - D, H - t3, 0)
    p12 = Vector(0, H - t3, 0)
    return [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p1]
Exemplo n.º 12
0
def setup(doc=None, solvertype="ccxtools"):

    if doc is None:
        doc = init_doc()

    # geometry object
    # name is important because the other method in this module use obj name
    l1 = Part.makeLine((-142.5, -142.5, 0), (142.5, -142.5, 0))
    l2 = Part.makeLine((142.5, -142.5, 0), (142.5, 142.5, 0))
    l3 = Part.makeLine((142.5, 142.5, 0), (-142.5, 142.5, 0))
    l4 = Part.makeLine((-142.5, 142.5, 0), (-142.5, -142.5, 0))
    wire = Part.Wire([l1, l2, l3, l4])
    shape = wire.extrude(Vector(0, 0, 1000))
    geom_obj = doc.addObject('Part::Feature', 'SquareTube')
    geom_obj.Shape = shape
    doc.recompute()

    if FreeCAD.GuiUp:
        geom_obj.ViewObject.Document.activeView().viewAxonometric()
        geom_obj.ViewObject.Document.activeView().fitAll()

    # analysis
    analysis = ObjectsFem.makeAnalysis(doc, "Analysis")

    # solver
    if solvertype == "calculix":
        solver_object = analysis.addObject(
            ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX")
        )[0]
    elif solvertype == "ccxtools":
        solver_object = analysis.addObject(
            ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools")
        )[0]
        solver_object.WorkingDir = u""
    else:
        FreeCAD.Console.PrintWarning(
            "Not known or not supported solver type: {}. "
            "No solver object was created.\n".format(solvertype)
        )
    if solvertype == "calculix" or solvertype == "ccxtools":
        solver_object.SplitInputWriter = False
        solver_object.AnalysisType = "static"
        solver_object.GeometricalNonlinearity = "linear"
        solver_object.ThermoMechSteadyState = False
        solver_object.MatrixSolverType = "default"
        solver_object.IterationsControlParameterTimeUse = False

    # shell thickness
    thickness = analysis.addObject(
        ObjectsFem.makeElementGeometry2D(doc, 0, "ShellThickness")
    )[0]
    thickness.Thickness = 15.0

    # material
    material_object = analysis.addObject(
        ObjectsFem.makeMaterialSolid(doc, "FemMaterial")
    )[0]
    mat = material_object.Material
    mat["Name"] = "Steel-Generic"
    mat["YoungsModulus"] = "200000 MPa"
    mat["PoissonRatio"] = "0.30"
    mat["Density"] = "7900 kg/m^3"
    material_object.Material = mat

    # fixed_constraint
    fixed_constraint = analysis.addObject(
        ObjectsFem.makeConstraintFixed(doc, name="ConstraintFixed"))[0]
    fixed_constraint.References = [
        (doc.SquareTube, "Edge4"),
        (doc.SquareTube, "Edge7"),
        (doc.SquareTube, "Edge10"),
        (doc.SquareTube, "Edge12")]

    # force_constraint1
    force_constraint1 = analysis.addObject(
        ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1"))[0]
    force_constraint1.References = [(doc.SquareTube, "Edge9")]
    force_constraint1.Force = 100000.00
    force_constraint1.Direction = (doc.SquareTube, ["Edge9"])
    force_constraint1.Reversed = True

    # force_constraint2
    force_constraint2 = analysis.addObject(
        ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2"))[0]
    force_constraint2.References = [(doc.SquareTube, "Edge3")]
    force_constraint2.Force = 100000.00
    force_constraint2.Direction = (doc.SquareTube, ["Edge3"])
    force_constraint2.Reversed = True

    # force_constraint3
    force_constraint3 = analysis.addObject(
        ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3"))[0]
    force_constraint3.References = [(doc.SquareTube, "Edge11")]
    force_constraint3.Force = 100000.00
    force_constraint3.Direction = (doc.SquareTube, ["Edge11"])
    force_constraint3.Reversed = True

    # force_constraint4
    force_constraint4 = analysis.addObject(
        ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4"))[0]
    force_constraint4.References = [(doc.SquareTube, "Edge6")]
    force_constraint4.Force = 100000.00
    force_constraint4.Direction = (doc.SquareTube, ["Edge6"])
    force_constraint4.Reversed = True

    # mesh
    from .meshes.mesh_square_pipe_end_twisted_tria6 import create_nodes, create_elements
    fem_mesh = Fem.FemMesh()
    control = create_nodes(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating nodes.\n")
    control = create_elements(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating elements.\n")
    femmesh_obj = analysis.addObject(
        ObjectsFem.makeMeshGmsh(doc, mesh_name)
    )[0]
    femmesh_obj.FemMesh = fem_mesh
    femmesh_obj.Part = geom_obj
    femmesh_obj.SecondOrderLinear = False

    doc.recompute()
    return doc
Exemplo n.º 13
0
    def execute(self,obj):
        
        if self.clone(obj):
            return

        pl = obj.Placement
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        chamfer = obj.Chamfer.Value
        dentlength = obj.DentLength.Value
        dentheight = obj.DentHeight.Value
        dents = obj.Dents
    
        if (length == 0) or (width == 0) or (height == 0):
            return
        if (chamfer >= width/2) or (chamfer >= height/2):
            return
    
        import Part
        p = []
        if chamfer > 0:
            p.append(Vector(0,chamfer,0))
            p.append(Vector(0,width-chamfer,0))
            p.append(Vector(0,width,chamfer))
            p.append(Vector(0,width,height-chamfer))
            p.append(Vector(0,width-chamfer,height))
            p.append(Vector(0,chamfer,height))
            p.append(Vector(0,0,height-chamfer))
            p.append(Vector(0,0,chamfer))
        else:
            p.append(Vector(0,0,0))
            p.append(Vector(0,width,0))
            p.append(Vector(0,width,height))
            p.append(Vector(0,0,height))
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(length,0,0))
        if (dentlength > 0) and (dentheight > 0):
            p = []
            p.append(Vector(0,0,0))
            p.append(Vector(dentlength,0,0))
            p.append(Vector(dentlength,width,0))
            p.append(Vector(0,width,0))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            d1 = f.extrude(Vector(0,0,dentheight))
            d2 = d1.copy()
            d2.translate(Vector(length-dentlength,0,0))
            shape = shape.cut(d1)
            shape = shape.cut(d2)
        for dent in dents:
            dent = dent.split(";")
            if len(dent) == 7:
                dentlength = float(dent[0])
                dentwidth = float(dent[1])
                dentheight = float(dent[2])
                dentslant = float(dent[3])
                dentchamfer = chamfer
                dentlevel = float(dent[4])
                dentrotation = float(dent[5])
                dentoffset = float(dent[6])
                if (dentlength == 0) or (dentwidth == 0) or (dentheight == 0):
                    continue
                if dentslant >= dentheight:
                    continue
                p = []
                p.append(Vector(0-dentchamfer,0,0))
                p.append(Vector(dentlength,0,dentslant))
                p.append(Vector(dentlength,0,dentheight))
                p.append(Vector(0-dentchamfer,0,dentheight))
                p.append(p[0])
                p = Part.makePolygon(p)
                f = Part.Face(p)
                dentshape = f.extrude(Vector(0,dentwidth,0))
                dentshape.rotate(Vector(0,0,0),Vector(0,0,1),dentrotation)
                if dentrotation == 0:
                    dentshape.translate(Vector(length,dentoffset,0))
                elif dentrotation == 90:
                    dentshape.translate(Vector(length-dentoffset,width,0))
                elif dentrotation == 180:
                    dentshape.translate(Vector(0,width-dentoffset,0))
                elif dentrotation == 270:
                    dentshape.translate(Vector(dentoffset,0,0))
                dentshape.translate(Vector(0,0,dentlevel))
                shape = shape.fuse(dentshape)
        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)
Exemplo n.º 14
0
    def execute(self,obj):
        
        if self.clone(obj):
            return

        pl = obj.Placement
        slabtype = obj.SlabType
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        base = obj.SlabBase.Value
        holenumber = obj.HoleNumber
        holemajor = obj.HoleMajor.Value
        holeminor = obj.HoleMinor.Value
        holespacing = obj.HoleSpacing.Value
            
        slant = (height-base) / 3 # this gives the inclination of the vertical walls
        
        if (length == 0) or (width == 0) or (height == 0):
            return
        if base >= height:
            return
        if height < (base*2):
            return
        if (holenumber > 0) and ( (holespacing == 0) or (holemajor == 0) or (holeminor == 0) ):
            return
        if holemajor < holeminor:
            return
        import Part
    
        p = []
        if slabtype == "Champagne":
            p.append(Vector(0,0,0))
            p.append(Vector(0,slant,height-base))
            p.append(Vector(0,0,height-base))
            p.append(Vector(0,0,height))
            p.append(Vector(0,width,height))
            p.append(Vector(0,width,height-base))
            p.append(Vector(0,width-slant,height-base))
            p.append(Vector(0,width,0))
        elif slabtype == "Hat":
            p.append(Vector(0,0,0))
            p.append(Vector(0,0,base))
            p.append(Vector(0,slant,base))
            p.append(Vector(0,slant*2,height))
            p.append(Vector(0,width-slant*2,height))
            p.append(Vector(0,width-slant,base))
            p.append(Vector(0,width,base))
            p.append(Vector(0,width,0))
        else:
            return None
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(length,0,0))
        
        if holenumber > 0:
            holespan = holenumber * holeminor + (holenumber - 1) * holespacing
            holestart = (width/2 - holespan/2) + holeminor/2
            if holeminor != holemajor:
                e = Part.Ellipse(Vector(0,0,0),Vector(0,holeminor/2,0),Vector(0,0,holemajor/2)).toShape()
                e.translate(Vector(0,0,-holemajor/2))
            else:
                e = Part.Circle(Vector(0,0,0),Vector(1,0,0),holemajor/2).toShape()
            w = Part.Wire([e])
            f = Part.Face(w)
            tube = f.extrude(Vector(length,0,0))
            for i in range(holenumber):
                x = holestart + i*(holeminor+holespacing)
                s = tube.copy()
                s.translate(Vector(0,x,height/2))
                shape = shape.cut(s)
            
        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)
Exemplo n.º 15
0
def isDrillable(obj, candidate, tooldiameter=None):
    """
    Checks candidates to see if they can be drilled.
    Candidates can be either faces - circular or cylindrical or circular edges.
    The tooldiameter can be optionally passed.  if passed, the check will return
    False for any holes smaller than the tooldiameter.
    obj=Shape
    candidate = Face or Edge
    tooldiameter=float
    """
    PathLog.track('obj: {} candidate: {} tooldiameter {}'.format(obj, candidate, tooldiameter))
    drillable = False
    if candidate.ShapeType == 'Face':
        face = candidate
        # eliminate flat faces
        if (round(face.ParameterRange[0], 8) == 0.0) and (round(face.ParameterRange[1], 8) == round(math.pi * 2, 8)):
            for edge in face.Edges:  # Find seam edge and check if aligned to Z axis.
                if (isinstance(edge.Curve, Part.Line)):
                    PathLog.debug("candidate is a circle")
                    v0 = edge.Vertexes[0].Point
                    v1 = edge.Vertexes[1].Point
                    #check if the cylinder seam is vertically aligned.  Eliminate tilted holes
                    if (numpy.isclose(v1.sub(v0).x, 0, rtol=1e-05, atol=1e-06)) and \
                            (numpy.isclose(v1.sub(v0).y, 0, rtol=1e-05, atol=1e-06)):
                        drillable = True
                        # vector of top center
                        lsp = Vector(face.BoundBox.Center.x, face.BoundBox.Center.y, face.BoundBox.ZMax)
                        # vector of bottom center
                        lep = Vector(face.BoundBox.Center.x, face.BoundBox.Center.y, face.BoundBox.ZMin)
                        # check if the cylindrical 'lids' are inside the base
                        # object.  This eliminates extruded circles but allows
                        # actual holes.
                        if obj.isInside(lsp, 1e-6, False) or obj.isInside(lep, 1e-6, False):
                            PathLog.track("inside check failed. lsp: {}  lep: {}".format(lsp,lep))
                            drillable = False
                        # eliminate elliptical holes
                        elif not hasattr(face.Surface, "Radius"):
                            PathLog.debug("candidate face has no radius attribute")
                            drillable = False
                        else:
                            if tooldiameter is not None:
                                drillable = face.Surface.Radius >= tooldiameter/2
                            else:
                                drillable = True
    else:
        for edge in candidate.Edges:
            if isinstance(edge.Curve, Part.Circle) and edge.isClosed():
                PathLog.debug("candidate is a circle or ellipse")
                if not hasattr(edge.Curve, "Radius"):
                    PathLog.debug("No radius.  Ellipse.")
                    drillable = False
                else:
                    PathLog.debug("Has Radius, Circle")
                    if tooldiameter is not None:
                        drillable = edge.Curve.Radius >= tooldiameter/2
                        if not drillable:
                            FreeCAD.Console.PrintMessage(
                                    "Found a drillable hole with diameter: {}: "
                                    "too small for the current tool with "
                                    "diameter: {}".format(edge.Curve.Radius*2, tooldiameter))
                    else:
                        drillable = True
    PathLog.debug("candidate is drillable: {}".format(drillable))
    return drillable
Exemplo n.º 16
0
    def execute(self, obj):

        "constructs the shape of the stairs"

        if self.clone(obj):
            return

        import Part
        self.steps = []
        self.pseudosteps = []
        self.structures = []
        pl = obj.Placement
        landings = 0

        base = None

        if obj.Base:
            if hasattr(obj.Base, "Shape"):
                if obj.Base.Shape:
                    if obj.Base.Shape.Solids:
                        base = obj.Base.Shape.copy()

        # special case NumberOfSteps = 1 : multi-edges landing
        if (not base) and obj.Width.Value and obj.Height.Value and (
                obj.NumberOfSteps > 0):
            if obj.Base:
                if not obj.Base.isDerivedFrom("Part::Feature"):
                    return
                if obj.Base.Shape.Solids:
                    obj.Shape = obj.Base.Shape.copy()
                    obj.Placement = FreeCAD.Placement(
                        obj.Base.Placement).multiply(pl)
                    obj.TreadDepth = 0.0
                    obj.RiserHeight = 0.0
                    return
                if not obj.Base.Shape.Edges:
                    return
                if obj.Base.Shape.Faces:
                    return
                if (len(obj.Base.Shape.Edges) == 1):
                    edge = obj.Base.Shape.Edges[0]
                    if isinstance(edge.Curve, (Part.LineSegment, Part.Line)):
                        # preparing for multi-edges landing / segment staircase
                        if obj.NumberOfSteps > 1:

                            if obj.Landings == "At center":
                                landings = 1
                                self.makeStraightStairsWithLanding(obj, edge)
                            else:
                                self.makeStraightStairs(obj, edge)

                        # preparing for multi-edges landing / segment staircase
                        if obj.NumberOfSteps == 1:
                            self.makeStraightLanding(obj, edge)
                        if obj.NumberOfSteps == 0:
                            pass  # Should delete the whole shape

                    else:
                        if obj.Landings == "At center":
                            landings = 1
                            self.makeCurvedStairsWithLandings(obj, edge)
                        else:
                            self.makeCurvedStairs(obj, edge)

                elif (len(obj.Base.Shape.Edges) >= 1):
                    if obj.NumberOfSteps == 1:
                        edges = obj.Base.Shape.Edges
                        self.makeMultiEdgesLanding(obj, edges)

            else:
                if not obj.Length.Value:
                    return
                edge = Part.LineSegment(Vector(0, 0, 0),
                                        Vector(obj.Length.Value, 0,
                                               0)).toShape()
                if obj.Landings == "At center":
                    landings = 1
                    self.makeStraightStairsWithLanding(obj, edge)
                else:
                    self.makeStraightStairs(obj, edge)

        if self.structures or self.steps:
            base = Part.makeCompound(self.structures + self.steps)
        elif self.pseudosteps:
            shape = Part.makeCompound(self.pseudosteps)
            obj.Shape = shape
            obj.Placement = pl
            return

        base = self.processSubShapes(obj, base, pl)
        if base:
            if not base.isNull():
                obj.Shape = base
                obj.Placement = pl

        # compute step data
        if obj.NumberOfSteps > 1:
            l = obj.Length.Value
            h = obj.Height.Value
            if obj.Base:
                if obj.Base.isDerivedFrom("Part::Feature"):
                    l = obj.Base.Shape.Length
                    if obj.Base.Shape.BoundBox.ZLength:
                        h = obj.Base.Shape.BoundBox.ZLength
            if obj.LandingDepth:
                obj.TreadDepth = float(l -
                                       (landings * obj.LandingDepth.Value)) / (
                                           obj.NumberOfSteps - (1 + landings))
            else:
                obj.TreadDepth = float(l - (landings * obj.Width.Value)) / (
                    obj.NumberOfSteps - (1 + landings))
            obj.RiserHeight = float(h) / obj.NumberOfSteps
            obj.BlondelRatio = obj.RiserHeight.Value * 2 + obj.TreadDepth.Value
Exemplo n.º 17
0
 def getLength(self):
     """Return the length of the line."""
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[-1].getValue())
     return (p2.sub(p1)).Length
Exemplo n.º 18
0
    def makeMultiEdgesLanding(self, obj, edges):

        "builds a 'multi-edges' landing from edges"  # 'copying' from makeStraightLanding()

        import Part, DraftGeomUtils

        v, vLength, vWidth, vBase = [], [], [], []
        p1o, p2o, p1, p2, p3, p4 = [], [], [], [], [], []
        outline, outlineP1P2, outlineP3P4 = [], [], []

        enum_edges = enumerate(edges)
        for i, edge in enum_edges:
            v.append(DraftGeomUtils.vec(edge))
            vLength.append(Vector(v[i].x, v[i].y, 0))
            # TODO obj.Width[i].Value for different 'edges' / 'sections' of the landing
            vWidth.append(
                DraftVecUtils.scaleTo(vLength[i].cross(Vector(0, 0, 1)),
                                      obj.Width.Value))
            vBase.append(edges[i].Vertexes[0].Point)
            vBase[i] = self.vbaseFollowLastSement(obj, vBase[i])

            # step + structure							# assume all left-align first # no nosing
            p1o.append(vBase[i].add(
                Vector(0, 0, -abs(obj.TreadThickness.Value))))
            p2o.append(p1o[i].add(vLength[i]))
            p1.append(
                self.align(vBase[i], obj.Align, vWidth[i]).add(
                    Vector(0, 0, -abs(obj.TreadThickness.Value))))
            p2.append(p1[i].add(vLength[i]))
            p3.append(p2[i].add(vWidth[i]))
            p4.append(p3[i].add(DraftVecUtils.neg(vLength[i])))

            if obj.Align == 'Left':
                outlineP1P2.append(p1[i])
                outlineP1P2.append(
                    p2[i]
                )  # can better skip 1 'supposedly' overlapping point every pair?
                if i > 0:
                    print("Debug - intersection calculation")
                    print(p3[i - 1])
                    print(p4[i - 1])
                    print(p3[i])
                    print(p4[i])
                    intersection = DraftGeomUtils.findIntersection(
                        p3[i - 1], p4[i - 1], p3[i], p4[i], True, True)
                    print(intersection)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP3P4.insert(0, p4[i])

            elif obj.Align == 'Right':
                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(
                        p1[i - 1], p2[i - 1], p1[i], p2[i], True, True)
                    outlineP1P2.append(intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

            elif obj.Align == 'Center':
                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(
                        p1[i - 1], p2[i - 1], p1[i], p2[i], True, True)
                    outlineP1P2.append(intersection[0])
                    intersection = DraftGeomUtils.findIntersection(
                        p3[i - 1], p4[i - 1], p3[i], p4[i], True, True)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                    outlineP3P4.insert(0, p4[i])

            else:
                outlineP1P2.append(p1[i])
                outlineP1P2.append(p2[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

        # add back last/first 'missing' point(s)
        if obj.Align in ['Left', 'Center']:
            outlineP3P4.insert(0, p3[i])
        if obj.Align in ['Right', 'Center']:
            outlineP1P2.append(p2[i])

        outline = outlineP1P2 + outlineP3P4
        outline.append(p1[0])
        print(outlineP1P2)
        print(outlineP3P4)
        print(outline)

        stepFace = Part.Face(Part.makePolygon(outline))

        if obj.TreadThickness.Value:
            step = stepFace.extrude(Vector(0, 0,
                                           abs(obj.TreadThickness.Value)))
            self.steps.append(step)
        else:
            self.pseudosteps.append(step)

        if obj.StructureThickness.Value:
            landingFace = stepFace
            struct = landingFace.extrude(
                Vector(0, 0, -abs(obj.StructureThickness.Value)))

        if struct:
            self.structures.append(struct)

        obj.AbsTop = vBase[1]
Exemplo n.º 19
0
 def p2(self):
     """Get the second point (on u axis) of the rectangle."""
     return Vector(self.coords.point.getValues()[3].getValue())
Exemplo n.º 20
0
    def makeStraightLanding(self,
                            obj,
                            edge,
                            numberofsteps=None,
                            callByMakeStraightStairsWithLanding=False):
        "builds a landing from a straight edge"

        # general data
        if not numberofsteps:
            numberofsteps = obj.NumberOfSteps
        import Part, DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        vLength = Vector(v.x, v.y, 0)
        vWidth = vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                                obj.Width.Value)
        vBase = edge.Vertexes[0].Point

        # if not call by makeStraightStairsWithLanding() - not 're-base' in function there, then 're-base' here
        if not callByMakeStraightStairsWithLanding:
            vBase = self.vbaseFollowLastSement(obj, vBase)
            obj.AbsTop = vBase

        vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing.Value))
        h = obj.Height.Value
        l = obj.Length.Value
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                l = obj.Base.Shape.Length
                if obj.Base.Shape.BoundBox.ZLength:
                    h = obj.Base.Shape.BoundBox.ZLength

        if obj.LandingDepth:
            fLength = float(l - obj.LandingDepth.Value) / (numberofsteps - 2)
        else:
            fLength = float(l - obj.Width.Value) / (numberofsteps - 2)

        fHeight = float(h) / numberofsteps
        a = math.atan(fHeight / fLength)
        print("landing data:", fLength, ":", fHeight)

        # step
        p1 = self.align(vBase, obj.Align, vWidth)
        p1o = p1.add(Vector(0, 0, -abs(obj.TreadThickness.Value)))

        p1 = p1.add(vNose).add(Vector(0, 0, -abs(obj.TreadThickness.Value)))
        p2 = p1.add(DraftVecUtils.neg(vNose)).add(vLength)
        p3 = p2.add(vWidth)
        p4 = p3.add(DraftVecUtils.neg(vLength)).add(vNose)

        p4o = p3.add(DraftVecUtils.neg(vLength))
        if not callByMakeStraightStairsWithLanding:
            p2o = p2
            p3o = p3

        if obj.Flight == "HalfTurnLeft":
            p1 = p1.add(-vWidth)
            p2 = p2.add(-vWidth)

        step = Part.Face(Part.makePolygon([p1, p2, p3, p4, p1]))
        if obj.TreadThickness.Value:
            step = step.extrude(Vector(0, 0, abs(obj.TreadThickness.Value)))
            self.steps.append(step)
        else:
            self.pseudosteps.append(step)

        # structure
        lProfile = []
        struct = None
        p7 = None
        p1 = p1.add(DraftVecUtils.neg(vNose))
        p2 = p1.add(Vector(0, 0, -fHeight)).add(
            Vector(0, 0, -obj.StructureThickness.Value / math.cos(a)))
        resheight = p1.sub(p2).Length - obj.StructureThickness.Value
        reslength = resheight / math.tan(a)
        p3 = p2.add(DraftVecUtils.scaleTo(vLength, reslength)).add(
            Vector(0, 0, resheight))
        p6 = p1.add(vLength)
        if obj.TreadThickness.Value:
            if obj.Flight == "Straight":
                p7 = p6.add(Vector(0, 0, obj.TreadThickness.Value))
        reslength = fLength + (
            obj.StructureThickness.Value / math.sin(a) -
            (fHeight - obj.TreadThickness.Value) / math.tan(a))
        if p7:
            p5 = p7.add(DraftVecUtils.scaleTo(vLength, reslength))
        else:
            if obj.Flight == "Straight":
                p5 = p6.add(DraftVecUtils.scaleTo(vLength, reslength))
            else:
                p5 = None
        resheight = obj.StructureThickness.Value + obj.TreadThickness.Value
        reslength = resheight / math.tan(a)
        if obj.Flight == "Straight":
            p4 = p5.add(DraftVecUtils.scaleTo(vLength, -reslength)).add(
                Vector(0, 0, -resheight))
        else:
            p4 = p6.add(Vector(0, 0, -obj.StructureThickness.Value))
        if obj.Structure == "Massive":
            if obj.StructureThickness.Value:
                if p7:
                    struct = Part.Face(
                        Part.makePolygon([p1, p2, p3, p4, p5, p7, p6, p1]))
                elif p5:
                    struct = Part.Face(
                        Part.makePolygon([p1, p2, p3, p4, p5, p6, p1]))
                else:
                    struct = Part.Face(
                        Part.makePolygon([p1, p2, p3, p4, p6, p1]))
                evec = vWidth
                mvec = FreeCAD.Vector(0.0, 0)
                if obj.StructureOffset.Value:
                    mvec = DraftVecUtils.scaleTo(vWidth,
                                                 obj.StructureOffset.Value)
                    struct.translate(mvec)
                if obj.Flight == "HalfTurnLeft":
                    evec = DraftVecUtils.scaleTo(
                        evec, 2 * evec.Length - 2 * mvec.Length)
                else:
                    evec = DraftVecUtils.scaleTo(
                        evec, evec.Length - (2 * mvec.Length))
                struct = struct.extrude(evec)
        elif obj.Structure in ["One stringer", "Two stringers"]:
            if obj.StringerWidth.Value and obj.StructureThickness.Value:
                p1b = p1.add(Vector(0, 0, -fHeight))
                reslength = fHeight / math.tan(a)
                p1c = p1.add(DraftVecUtils.scaleTo(vLength, reslength))
                p5b = None
                p5c = None
                if obj.TreadThickness.Value:
                    reslength = obj.StructureThickness.Value / math.sin(a)
                    p5b = p5.add(DraftVecUtils.scaleTo(vLength, -reslength))
                    reslength = obj.TreadThickness.Value / math.tan(a)
                    p5c = p5b.add(DraftVecUtils.scaleTo(
                        vLength, -reslength)).add(
                            Vector(0, 0, -obj.TreadThickness.Value))
                    pol = Part.Face(
                        Part.makePolygon(
                            [p1c, p1b, p2, p3, p4, p5, p5b, p5c, p1c]))
                else:
                    pol = Part.Face(
                        Part.makePolygon([p1c, p1b, p2, p3, p4, p5, p1c]))
                evec = DraftVecUtils.scaleTo(vWidth, obj.StringerWidth.Value)
                if obj.Structure == "One stringer":
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                    else:
                        mvec = DraftVecUtils.scaleTo(
                            vWidth,
                            (vWidth.Length / 2) - obj.StringerWidth.Value / 2)
                    pol.translate(mvec)
                    struct = pol.extrude(evec)
                elif obj.Structure == "Two stringers":
                    pol2 = pol.copy()
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                        pol.translate(mvec)
                        mvec = vWidth.add(mvec.negative())
                        pol2.translate(mvec)
                    else:
                        pol2.translate(vWidth)
                    s1 = pol.extrude(evec)
                    s2 = pol2.extrude(evec.negative())
                    struct = Part.makeCompound([s1, s2])

        # Overwriting result of above functions if case fit - should better avoid running the above in first place (better rewrite later)
        if not callByMakeStraightStairsWithLanding:
            if obj.StructureThickness.Value:
                struct = None
                landingFace = Part.Face(
                    Part.makePolygon([p1o, p2o, p3o, p4o, p1o]))
                struct = landingFace.extrude(
                    Vector(0, 0, -abs(obj.StructureThickness.Value)))

        if struct:
            self.structures.append(struct)
Exemplo n.º 21
0
 def p4(self):
     """Get the fourth point (on v axis) of the rectangle."""
     return Vector(self.coords.point.getValues()[1].getValue())
Exemplo n.º 22
0
    def makeStraightStairs(self, obj, edge, numberofsteps=None):

        "builds a simple, straight staircase from a straight edge"

        # Upgrade obj if it is from an older version of FreeCAD
        if not (hasattr(obj, "StringerOverlap")):
            obj.addProperty(
                "App::PropertyLength", "StringerOverlap", "Structure",
                QT_TRANSLATE_NOOP(
                    "App::Property",
                    "The overlap of the stringers above the bottom of the treads"
                ))

        # general data
        import Part, DraftGeomUtils
        if not numberofsteps:
            numberofsteps = obj.NumberOfSteps
            # if not numberofsteps - not call by makeStraightStairsWithLanding()
            # if not 're-base' there (StraightStair is part of StraightStairsWithLanding 'flight'), then 're-base' here (StraightStair is individual 'flight')
            callByMakeStraightStairsWithLanding = False
        else:
            callByMakeStraightStairsWithLanding = True

        v = DraftGeomUtils.vec(edge)
        vLength = DraftVecUtils.scaleTo(
            v,
            float(edge.Length) / (numberofsteps - 1))
        vLength = Vector(vLength.x, vLength.y, 0)
        if round(v.z, Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        vHeight = Vector(0, 0, float(h) / numberofsteps)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                       obj.Width.Value)
        vBase = edge.Vertexes[0].Point

        if not callByMakeStraightStairsWithLanding:
            if obj.LastSegment:
                print("obj.LastSegment is: ")
                print(obj.LastSegment.Name)
                lastSegmentAbsTop = obj.LastSegment.AbsTop
                print("lastSegmentAbsTop is: ")
                print(lastSegmentAbsTop)
                vBase = Vector(
                    vBase.x, vBase.y,
                    lastSegmentAbsTop.z)  # use Last Segment top's z-coordinate
            obj.AbsTop = vBase.add(Vector(0, 0, h))

        vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing.Value))
        a = math.atan(vHeight.Length / vLength.Length)

        # steps
        for i in range(numberofsteps - 1):
            p1 = vBase.add((Vector(vLength).multiply(i)).add(
                Vector(vHeight).multiply(i + 1)))
            p1 = self.align(p1, obj.Align, vWidth)
            p1 = p1.add(vNose).add(Vector(0, 0,
                                          -abs(obj.TreadThickness.Value)))
            p2 = p1.add(DraftVecUtils.neg(vNose)).add(vLength)
            p3 = p2.add(vWidth)
            p4 = p3.add(DraftVecUtils.neg(vLength)).add(vNose)
            step = Part.Face(Part.makePolygon([p1, p2, p3, p4, p1]))
            if obj.TreadThickness.Value:
                step = step.extrude(Vector(0, 0,
                                           abs(obj.TreadThickness.Value)))
                self.steps.append(step)
            else:
                self.pseudosteps.append(step)

        # structure
        lProfile = []
        struct = None
        if obj.Structure == "Massive":
            if obj.StructureThickness.Value:
                for i in range(numberofsteps - 1):
                    if not lProfile:
                        lProfile.append(vBase)
                    last = lProfile[-1]
                    if len(lProfile) == 1:
                        last = last.add(
                            Vector(0, 0, -abs(obj.TreadThickness.Value)))
                    lProfile.append(last.add(vHeight))
                    lProfile.append(lProfile[-1].add(vLength))
                resHeight1 = obj.StructureThickness.Value / math.cos(a)
                lProfile.append(lProfile[-1].add(Vector(0, 0, -resHeight1)))
                resHeight2 = ((numberofsteps - 1) * vHeight.Length) - (
                    resHeight1 + obj.TreadThickness.Value)
                resLength = (vLength.Length / vHeight.Length) * resHeight2
                h = DraftVecUtils.scaleTo(vLength, -resLength)
                lProfile.append(lProfile[-1].add(Vector(h.x, h.y,
                                                        -resHeight2)))
                lProfile.append(vBase)
                #print(lProfile)
                pol = Part.makePolygon(lProfile)
                struct = Part.Face(pol)
                evec = vWidth
                if obj.StructureOffset.Value:
                    mvec = DraftVecUtils.scaleTo(vWidth,
                                                 obj.StructureOffset.Value)
                    struct.translate(mvec)
                    evec = DraftVecUtils.scaleTo(
                        evec, evec.Length - (2 * mvec.Length))
                struct = struct.extrude(evec)
        elif obj.Structure in ["One stringer", "Two stringers"]:
            if obj.StringerWidth.Value and obj.StructureThickness.Value:
                hyp = math.sqrt(vHeight.Length**2 + vLength.Length**2)
                l1 = Vector(vLength).multiply(numberofsteps - 1)
                h1 = Vector(vHeight).multiply(numberofsteps - 1).add(
                    Vector(
                        0, 0, -abs(obj.TreadThickness.Value) +
                        obj.StringerOverlap.Value))
                p1 = vBase.add(l1).add(h1)
                p1 = self.align(p1, obj.Align, vWidth)
                if obj.StringerOverlap.Value <= float(h) / numberofsteps:
                    lProfile.append(p1)
                else:
                    p1b = vBase.add(l1).add(Vector(0, 0, float(h)))
                    p1a = p1b.add(
                        Vector(vLength).multiply(
                            (p1b.z - p1.z) / vHeight.Length))
                    lProfile.append(p1a)
                    lProfile.append(p1b)
                h2 = (obj.StructureThickness.Value / vLength.Length) * hyp
                lProfile.append(p1.add(Vector(0, 0, -abs(h2))))
                h3 = lProfile[-1].z - vBase.z
                l3 = (h3 / vHeight.Length) * vLength.Length
                v3 = DraftVecUtils.scaleTo(vLength, -l3)
                lProfile.append(lProfile[-1].add(Vector(0, 0,
                                                        -abs(h3))).add(v3))
                l4 = (obj.StructureThickness.Value / vHeight.Length) * hyp
                v4 = DraftVecUtils.scaleTo(vLength, -l4)
                lProfile.append(lProfile[-1].add(v4))
                lProfile.append(lProfile[0])
                #print(lProfile)
                pol = Part.makePolygon(lProfile)
                pol = Part.Face(pol)
                evec = DraftVecUtils.scaleTo(vWidth, obj.StringerWidth.Value)
                if obj.Structure == "One stringer":
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                    else:
                        mvec = DraftVecUtils.scaleTo(
                            vWidth,
                            (vWidth.Length / 2) - obj.StringerWidth.Value / 2)
                    pol.translate(mvec)
                    struct = pol.extrude(evec)
                elif obj.Structure == "Two stringers":
                    pol2 = pol.copy()
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                        pol.translate(mvec)
                        mvec = vWidth.add(mvec.negative())
                        pol2.translate(mvec)
                    else:
                        pol2.translate(vWidth)
                    s1 = pol.extrude(evec)
                    s2 = pol2.extrude(evec.negative())
                    struct = Part.makeCompound([s1, s2])
        if struct:
            self.structures.append(struct)
Exemplo n.º 23
0
 def get(self):
     """Get a vector from the point."""
     p = self.coords.point.getValues()[0]
     return Vector(p[0], p[1], p[2])
Exemplo n.º 24
0
    def makeStraightStairsWithLanding(self, obj, edge):

        "builds a straight staircase with a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part, DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        if obj.LandingDepth:
            reslength = edge.Length - obj.LandingDepth.Value
        else:
            reslength = edge.Length - obj.Width.Value
        vLength = DraftVecUtils.scaleTo(
            v,
            float(reslength) / (obj.NumberOfSteps - 2))
        vLength = Vector(vLength.x, vLength.y, 0)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                       obj.Width.Value)
        p1 = edge.Vertexes[0].Point
        if round(v.z, Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        hstep = h / obj.NumberOfSteps
        landing = int(obj.NumberOfSteps / 2)

        if obj.LastSegment:
            print("obj.LastSegment is: ")
            print(obj.LastSegment.Name)
            lastSegmentAbsTop = obj.LastSegment.AbsTop
            print("lastSegmentAbsTop is: ")
            print(lastSegmentAbsTop)
            p1 = Vector(
                p1.x, p1.y,
                lastSegmentAbsTop.z)  # use Last Segment top's z-coordinate
            print(p1)
        obj.AbsTop = p1.add(Vector(0, 0, h))

        p2 = p1.add(
            DraftVecUtils.scale(vLength,
                                landing - 1).add(Vector(0, 0,
                                                        landing * hstep)))
        if obj.LandingDepth:
            p3 = p2.add(DraftVecUtils.scaleTo(vLength, obj.LandingDepth.Value))
        else:
            p3 = p2.add(DraftVecUtils.scaleTo(vLength, obj.Width.Value))
        if obj.Flight == "HalfTurnLeft":
            p3r = p2
            p4r = p2.add(
                DraftVecUtils.scale(
                    -vLength, obj.NumberOfSteps - (landing + 1)).add(
                        Vector(0, 0, (obj.NumberOfSteps - landing) * hstep)))
        else:
            p4 = p3.add(
                DraftVecUtils.scale(
                    vLength, obj.NumberOfSteps - (landing + 1)).add(
                        Vector(0, 0, (obj.NumberOfSteps - landing) * hstep)))
        self.makeStraightStairs(obj,
                                Part.LineSegment(p1, p2).toShape(), landing)

        self.makeStraightLanding(obj,
                                 Part.LineSegment(p2, p3).toShape(), None,
                                 True)

        if obj.Flight == "HalfTurnLeft":
            self.makeStraightStairs(obj,
                                    Part.LineSegment(p3r, p4r).toShape(),
                                    obj.NumberOfSteps - landing)
        else:
            self.makeStraightStairs(obj,
                                    Part.LineSegment(p3, p4).toShape(),
                                    obj.NumberOfSteps - landing)
Exemplo n.º 25
0
    def getLocalCoords(self, point):
        """Return the coordinates of the given point, from the plane.

        If the `point` was constructed using the plane as origin,
        return the relative coordinates from the `point` to the plane.

        A vector is calculated from the plane's `position`
        to the external `point`, and this vector is projected onto
        each of the `u`, `v` and `axis` of the plane to determine
        the local, relative vector.

        Parameters
        ----------
        point : Base::Vector3
            The point external to the plane.

        Returns
        -------
        Base::Vector3
            The relative coordinates of the point from the plane.

        See Also
        --------
        getGlobalCoords, getLocalRot, getGlobalRot

        Notes
        -----
        The following graphic explains the coordinates.
        ::
                                  g GlobalCoords (1, 11)
                                  |
                                  |
                                  |
                              (n) p point (1, 6)
                                  | LocalCoords (1, 1)
                                  |
            ----plane--------c-------- position (0, 5)

        In the graphic

            * `p` is an arbitrary point, external to the plane
            * `c` is the plane's `position`
            * `g` is the global coordinates of `p` when added to the plane
            * `n` is the relative coordinates of `p` when referred to the plane

        To do
        -----
        Maybe a better name would be getRelativeCoords?
        """
        pt = point.sub(self.position)
        xv = DraftVecUtils.project(pt, self.u)
        x = xv.Length
        # If the angle between the projection xv and u
        # is larger than 1 radian (57.29 degrees), use the negative
        # of the magnitude. Why exactly 1 radian?
        if xv.getAngle(self.u) > 1:
            x = -x
        yv = DraftVecUtils.project(pt, self.v)
        y = yv.Length
        if yv.getAngle(self.v) > 1:
            y = -y
        zv = DraftVecUtils.project(pt, self.axis)
        z = zv.Length
        if zv.getAngle(self.axis) > 1:
            z = -z
        return Vector(x, y, z)
Exemplo n.º 26
0
def xy(point):
    """xy(point)
    Convenience function to return the projection of the Vector in the XY-plane."""
    return Vector(point.x, point.y, 0)
def setup(doc=None, solvertype="ccxtools"):

    # init FreeCAD document
    if doc is None:
        doc = init_doc()

    # explanation object
    # just keep the following line and change text string in get_explanation method
    manager.add_explanation_obj(
        doc, get_explanation(manager.get_header(get_information())))

    # geometric object
    # name is important because the other method in this module use obj name
    cube = doc.addObject("Part::Box", "Cube")
    cube.Height = "20 mm"
    cube.Length = "100 mm"
    cylinder = doc.addObject("Part::Cylinder", "Cylinder")
    cylinder.Height = "20 mm"
    cylinder.Radius = "6 mm"
    cylinder.Placement = FreeCAD.Placement(
        Vector(10, 12, 10),
        Rotation(0, 0, 90),
        Vector(0, 0, 0),
    )
    cut = doc.addObject("Part::Cut", "Cut")
    cut.Base = cube
    cut.Tool = cylinder

    # mirroring
    mirror = doc.addObject("Part::Mirroring", "Mirror")
    mirror.Source = cut
    mirror.Normal = (1, 0, 0)
    mirror.Base = (100, 100, 20)

    # fusing
    fusion = doc.addObject("Part::Fuse", "Fusion")
    fusion.Base = cut
    fusion.Tool = mirror
    fusion.Refine = True

    # compound filter
    geom_obj = CompoundFilter.makeCompoundFilter(name='CompoundFilter')
    geom_obj.Base = fusion
    geom_obj.FilterType = 'window-volume'
    doc.recompute()

    if FreeCAD.GuiUp:
        geom_obj.Base.ViewObject.hide()
        geom_obj.ViewObject.Document.activeView().viewAxonometric()
        geom_obj.ViewObject.Document.activeView().fitAll()

    # analysis
    analysis = ObjectsFem.makeAnalysis(doc, "Analysis")

    # solver
    if solvertype == "calculix":
        solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX")
    elif solvertype == "ccxtools":
        solver_obj = ObjectsFem.makeSolverCalculixCcxTools(
            doc, "CalculiXccxTools")
        solver_obj.WorkingDir = u""
    else:
        FreeCAD.Console.PrintWarning(
            "Not known or not supported solver type: {}. "
            "No solver object was created.\n".format(solvertype))
    if solvertype == "calculix" or solvertype == "ccxtools":
        solver_obj.SplitInputWriter = False
        solver_obj.AnalysisType = "static"
        solver_obj.GeometricalNonlinearity = "linear"
        solver_obj.ThermoMechSteadyState = False
        solver_obj.MatrixSolverType = "default"
        solver_obj.IterationsControlParameterTimeUse = False
    analysis.addObject(solver_obj)

    # material
    material_obj = ObjectsFem.makeMaterialSolid(doc, "FemMaterial")
    mat = material_obj.Material
    mat["Name"] = "CalculiX-Steel"
    mat["YoungsModulus"] = "210000 MPa"
    mat["PoissonRatio"] = "0.30"
    mat["Density"] = "7900 kg/m^3"
    mat["ThermalExpansionCoefficient"] = "0.012 mm/m/K"
    material_obj.Material = mat

    # constraint pressure
    con_pressure = ObjectsFem.makeConstraintPressure(
        doc, name="FemConstraintPressure")
    con_pressure.References = [(geom_obj, "Face8")]
    con_pressure.Pressure = 10.0
    con_pressure.Reversed = False
    analysis.addObject(con_pressure)

    # constraint displacement
    con_disp = ObjectsFem.makeConstraintDisplacement(
        doc, name="FemConstraintDisplacment")
    con_disp.References = [(geom_obj, "Face4"), (geom_obj, "Face5")]
    con_disp.xFree = False
    con_disp.xFix = True
    analysis.addObject(con_disp)

    # constraints transform
    con_transform1 = ObjectsFem.makeConstraintTransform(
        doc, name="FemConstraintTransform1")
    con_transform1.References = [(geom_obj, "Face4")]
    con_transform1.TransformType = "Cylindrical"
    con_transform1.X_rot = 0.0
    con_transform1.Y_rot = 0.0
    con_transform1.Z_rot = 0.0
    analysis.addObject(con_transform1)

    con_transform2 = ObjectsFem.makeConstraintTransform(
        doc, name="FemConstraintTransform2")
    con_transform2.References = [(geom_obj, "Face5")]
    con_transform2.TransformType = "Cylindrical"
    con_transform2.X_rot = 0.0
    con_transform2.Y_rot = 0.0
    con_transform2.Z_rot = 0.0
    analysis.addObject(con_transform2)

    # mesh
    from .meshes.mesh_transform_beam_hinged_tetra10 import create_nodes, create_elements
    fem_mesh = Fem.FemMesh()
    control = create_nodes(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating nodes.\n")
    control = create_elements(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating elements.\n")
    femmesh_obj = analysis.addObject(
        ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
    femmesh_obj.FemMesh = fem_mesh
    femmesh_obj.Part = geom_obj
    femmesh_obj.SecondOrderLinear = False
    femmesh_obj.CharacteristicLengthMax = '7 mm'

    doc.recompute()
    return doc
Exemplo n.º 28
0
def edgeForCmd(cmd, startPoint):
    """edgeForCmd(cmd, startPoint).
    Returns an Edge representing the given command, assuming a given startPoint."""

    PathLog.debug("cmd: {}".format(cmd))
    PathLog.debug("startpoint {}".format(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))
            PathLog.debug("StartPoint:{}".format(startPoint))
            PathLog.debug("MidPoint:{}".format(midPoint))
            PathLog.debug("EndPoint:{}".format(endPoint))

            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
Exemplo n.º 29
0
    def execute(self,obj):
        "builds the wall shape"
        
        if self.clone(obj):
            return

        import Part, DraftGeomUtils
        pl = obj.Placement
        normal,length,width,height = self.getDefaultValues(obj)
        base = None
        face = None

        if obj.Base:
            # computing a shape from a base object
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
                if not obj.Base.Shape.isValid():
                    if not obj.Base.Shape.Solids:
                        # let pass invalid objects if they have solids...
                        return

                if hasattr(obj,"Face"):
                    if obj.Face > 0:
                        if len(obj.Base.Shape.Faces) >= obj.Face:
                            face = obj.Base.Shape.Faces[obj.Face-1]
                if face:
                    # case 1: this wall is based on a specific face of its base object
                    normal = face.normalAt(0,0)
                    if normal.getAngle(Vector(0,0,1)) > math.pi/4:
                        normal.multiply(width)
                        base = face.extrude(normal)
                        if obj.Align == "Center":
                            base.translate(normal.negative().multiply(0.5))
                        elif obj.Align == "Right":
                            base.translate(normal.negative())
                    else:
                        normal.multiply(height)
                        base = face.extrude(normal)
                elif obj.Base.Shape.Solids:
                    # case 2: the base is already a solid
                    base = obj.Base.Shape.copy()
                elif obj.Base.Shape.Edges:
                    # case 3: the base is flat, we need to extrude it
                    if not obj.Base.Shape.Faces:
                        # set the length property
                        if hasattr(obj.Base.Shape,"Length"):
                            l = obj.Base.Shape.Length
                            if obj.Length != l:
                                obj.Length = l
                    profiles = self.getProfiles(obj)
                    if profiles:
                        normal.multiply(height)
                        base = profiles.pop()
                        base.fix(0.1,0,1)
                        base = base.extrude(normal)
                        for p in profiles:
                            p.fix(0.1,0,1)
                            p = p.extrude(normal)
                            base = base.fuse(p)
                    else:
                        base = None
                else:
                    base = None
                    FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object")))

            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 and (not sh.isNull()):
                            base = sh
                        else:
                            FreeCAD.Console.PrintWarning(str(translate("Arch","This mesh is an invalid solid")))
                            obj.Base.ViewObject.show()
        else:
            # computing a shape from scratch
            if length and width and height:
                base = Part.makeBox(length,width,height)

        base = self.processSubShapes(obj,base,pl)
        self.applyShape(obj,base,pl)
Exemplo n.º 30
0
    def execute(self,obj):
        
        if self.clone(obj):
            return
  
        pl = obj.Placement
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        chamfer = obj.Chamfer.Value
        groovedepth = obj.GrooveDepth.Value
        grooveheight = obj.GrooveHeight.Value
        spacing = obj.GrooveSpacing.Value
        number = obj.GrooveNumber
        dents = obj.Dents

        if (length == 0) or (width == 0) or (height == 0):
            return
        if (chamfer >= width/2) or (chamfer >= length/2):
            return
    
        import Part
        p = []
        if chamfer > 0:
            p.append(Vector(chamfer,0,0))
            p.append(Vector(length-chamfer,0,0))
            p.append(Vector(length,chamfer,0))
            p.append(Vector(length,width-chamfer,0))
            p.append(Vector(length-chamfer,width,0))
            p.append(Vector(chamfer,width,0))
            p.append(Vector(0,width-chamfer,0))
            p.append(Vector(0,chamfer,0))
        else:
            p.append(Vector(0,0,0))
            p.append(Vector(length,0,0))
            p.append(Vector(length,width,0))
            p.append(Vector(0,width,0))
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(0,0,height))

        if (groovedepth > 0) and (grooveheight > 0) and (spacing > 0) and (number > 0) and (groovedepth < length/2) and (groovedepth < width/2):
            p1 = []
            p1.append(Vector(0,0,0))
            p1.append(Vector(length,0,0))
            p1.append(Vector(length,width,0))
            p1.append(Vector(0,width,0))
            p1.append(p1[0])
            p1 = Part.makePolygon(p1)
            f1 = Part.Face(p1)
            groove = f1.extrude(Vector(0,0,grooveheight))
            p2 = []
            p2.append(Vector(groovedepth,groovedepth,0))
            p2.append(Vector(length-groovedepth,groovedepth,0))
            p2.append(Vector(length-groovedepth,width-groovedepth,0))
            p2.append(Vector(groovedepth,width-groovedepth,0))
            p2.append(p2[0])
            p2 = Part.makePolygon(p2)
            f2 = Part.Face(p2)
            s = f2.extrude(Vector(0,0,grooveheight))
            groove = groove.cut(s)
            for i in range(number):
                g = groove.copy()
                g.translate(Vector(0,0,spacing + i*(spacing+grooveheight)))
                shape = shape.cut(g)

        for dent in dents:
            dent = dent.split(";")
            if len(dent) == 7:
                dentlength = float(dent[0])
                dentwidth = float(dent[1])
                dentheight = float(dent[2])
                dentslant = float(dent[3])
                dentchamfer = chamfer
                dentlevel = float(dent[4])
                dentrotation = float(dent[5])
                dentoffset = float(dent[6])
                if (dentlength == 0) or (dentwidth == 0) or (dentheight == 0):
                    continue
                if dentslant >= dentheight:
                    continue
                p = []
                p.append(Vector(0-dentchamfer,0,0))
                p.append(Vector(dentlength,0,dentslant))
                p.append(Vector(dentlength,0,dentheight))
                p.append(Vector(0-dentchamfer,0,dentheight))
                p.append(p[0])
                p = Part.makePolygon(p)
                f = Part.Face(p)
                dentshape = f.extrude(Vector(0,dentwidth,0))
                dentshape.rotate(Vector(0,0,0),Vector(0,0,1),dentrotation)
                if dentrotation == 0:
                    dentshape.translate(Vector(length,dentoffset,0))
                elif dentrotation == 90:
                    dentshape.translate(Vector(length-dentoffset,width,0))
                elif dentrotation == 180:
                    dentshape.translate(Vector(0,width-dentoffset,0))
                elif dentrotation == 270:
                    dentshape.translate(Vector(dentoffset,0,0))
                dentshape.translate(Vector(0,0,dentlevel))
                shape = shape.fuse(dentshape)
                
        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)