Пример #1
0
 def update(self, surf, direction, uv):
     """ Update the 3D view printing curve.
     @param self Auto call object.
     @param surf Surf where get the curve.
     @param direction 0 if u direction, 1 if v.
     @param uv Curve uv index, between 0 and 1.
     @return Curve from object (as Part::Feature).
     """
     # Errors
     if not surf:
         return None
     # Get curve
     if direction == 0:
         curve = self.getU(surf, uv)
     elif direction == 1:
         curve = self.getV(surf, uv)
     else:
         return None
     # Draw at 3D view
     self.clean()
     Part.show(curve.toShape())
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs)-1]
     self.obj.Label = 'surfISOCurve'
     return self.obj
Пример #2
0
 def update(self, draft, trim, ship):
     """ Update free surface 3D view
     @param traft Draft.
     @param trim Trim in degrees.
     """
     # Destroy old object if exist
     self.clean()
     # Set free surface bounds
     bbox = ship.Shape.BoundBox
     L = 1.5 * bbox.XLength
     B = 3.0 * bbox.YLength
     # Create plane
     x = -0.5 * L
     y = -0.5 * B
     point = Base.Vector(x, y, 0.0)
     plane = Part.makePlane(L, B, point, Base.Vector(0, 0, 1))
     # Set position
     plane.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 1, 0), trim)
     plane.translate(Base.Vector(0, 0, draft))
     # Create the FreeCAD object
     Part.show(plane)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs) - 1]
     self.obj.Label = 'FreeSurface'
     # Set properties of object
     guiObj = FreeCADGui.ActiveDocument.getObject(self.obj.Name)
     guiObj.ShapeColor = (0.4, 0.8, 0.85)
     guiObj.Transparency = 50
Пример #3
0
 def update(self, draft, trim, ship):
     """ Update free surface 3D view
     @param traft Draft.
     @param trim Trim in degrees.
     """
     # Destroy old object if exist
     self.clean()
     # Set free surface bounds
     bbox = ship.Shape.BoundBox
     L = 1.5 * bbox.XLength
     B = 3.0 * bbox.YLength
     # Create plane
     x = - 0.5 * L
     y = - 0.5 * B
     point = Base.Vector(x,y,0.0)
     plane = Part.makePlane(L,B, point, Base.Vector(0,0,1))
     # Set position
     plane.rotate(Base.Vector(0,0,0), Base.Vector(0,1,0), trim)
     plane.translate(Base.Vector(0,0,draft))
     # Create the FreeCAD object
     Part.show(plane)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs)-1]
     self.obj.Label = 'FreeSurface'
     # Set properties of object
     guiObj = FreeCADGui.ActiveDocument.getObject(self.obj.Name)
     guiObj.ShapeColor = (0.4,0.8,0.85)
     guiObj.Transparency = 50
Пример #4
0
def mainFrameCoeff(ship, draft):
    """ Calculate main frame coefficient.
    @param ship Selected ship instance
    @param draft Draft.
    @return Main frame coefficient
    """
    cm       = 0.0
    maxY     = 0.0
    minY     = 0.0
    # We will take a duplicate of ship shape in order to place it
    shape = ship.Shape.copy()
    shape.translate(Vector(0.0,0.0,-draft))
    x    = 0.0
    area = 0.0
    # Now we need to know the x range of values
    bbox = shape.BoundBox
    xmin = bbox.XMin
    xmax = bbox.XMax
    # Create the box
    L = xmax - xmin
    B = bbox.YMax - bbox.YMin
    p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
    box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin + 1.0, p)
    # Compute common part with ship
    for s in shape.Solids:
        # Get solids intersection
        try:
            common = box.common(s)
        except:
            continue
        if common.Volume == 0.0:
            continue
        # Recompute object adding it to the scene, when we have
        # computed desired data we can remove it.
        try:
            Part.show(common)
        except:
            continue
        # Divide by faces and compute only section placed ones
        faces  = common.Faces
        for f in faces:
            faceBounds = f.BoundBox
            # Orientation filter
            if faceBounds.XMax - faceBounds.XMin > 0.00001:
                continue
            # Place filter
            if abs(faceBounds.XMax - x) > 0.00001:
                continue
            # Valid face, compute area
            area = area + f.Area
            maxY = max(maxY, faceBounds.YMax)
            minY = max(minY, faceBounds.YMin)
        # Destroy last object generated
        App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
    dy = maxY - minY
    if dy*draft > 0.0:
        cm = area / (dy*draft)
    return cm
Пример #5
0
 def buildObjs(self):
     """ Builds objects to show.
     """
     Part.show(self.U)
     objs = FreeCAD.ActiveDocument.Objects
     self.objU = objs[len(objs)-1]
     Part.show(self.V)
     objs = FreeCAD.ActiveDocument.Objects
     self.objV = objs[len(objs)-1]
Пример #6
0
def upper_tabletop_2(d, dressup=True):
    m = Part.makeBox(d["length"], d["width"], d["upper_tabletop_t"])
    m.translate(Base.Vector(-d["length"] / 2, -d["width"] / 2, 0))
    m = dc.model.fillet_edges_by_length(m, 35, d["upper_tabletop_t"])

    print("Upper tabletop length: ", d["length"])
    print("Upper tabletop width: ", d["width"])

    ccx = d["length"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    ccy = d["width"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    hx = ccx / 2.0
    hy = ccy / 2.0

    hole_points = [
        Base.Vector(hx, hy, 0),
        Base.Vector(-hx, hy, 0),
        Base.Vector(-hx, -hy, 0),
        Base.Vector(hx, -hy, 0)
    ]

    a = 135
    for p in hole_points:
        hole = Part.makeCylinder(d["hole_dia_tabletop"] / 2.0,
                                 d["upper_tabletop_t"], p,
                                 Base.Vector(0, 0, 1), 360)

        insert_1 = Part.makeBox(d["leg_t"], d["insertion_width_1"],
                                d["insertion_length"])
        insert_1 = dc.model.fillet_edges_by_length(insert_1,
                                                   d["leg_edge_radii"],
                                                   d["insertion_length"])
        insert_1.translate(Base.Vector(-d["leg_t"] / 2, -d["cx"], 0))
        insert_1.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), a)
        insert_1.translate(p)

        insert_2 = Part.makeBox(d["leg_t"], d["insertion_width_2"],
                                d["insertion_length"])
        insert_2 = dc.model.fillet_edges_by_length(insert_2,
                                                   d["leg_edge_radii"],
                                                   d["insertion_length"])
        insert_2.translate(
            Base.Vector(-d["leg_t"] / 2, -d["insertion_width_3"] / 2.0, 0))
        insert_2.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), a)
        insert_2.translate(p)

        m = m.cut(insert_1).cut(insert_2).cut(hole)
        a = a + 90

    if dressup:
        m = dc.model.fillet_edges_longer_than(m, d["tabletop_edge_radii"], 300)

    m.translate(Base.Vector(0, 0, -d["upper_tabletop_t"]))
    return m
Пример #7
0
def _cutTopCurve(doc, obj, length, orientationBF, curveRadius):
    topCurvePlane = obj.newObject(_featureClassMapping["Plane"],
                                  "topCurvePlane")
    topCurvePlane.AttachmentOffset = App.Placement(
        App.Vector(0, 0, 0),
        App.Rotation(0, math.degrees(orientationBF),
                     0)  # Yaw = x, Pitch = z, Roll = y (in deg)
    )
    topCurvePlane.MapReversed = False
    topCurvePlane.Support = [(doc.YZ_Plane, '')]
    topCurvePlane.MapMode = "FlatFace"

    # Create bottom curve sketch
    topSketch = obj.newObject(_featureClassMapping["Sketch"], "topSketch")
    topSketch.Support = (topCurvePlane, '')
    topSketch.MapMode = "FlatFace"

    centerY = length / 2 - curveRadius  # one
    topEdgeY = length / 2 + 1
    topSketch.addGeometry(
        Part.ArcOfCircle(
            Part.Circle(App.Vector(0, centerY, 0), App.Vector(0, 0, 1),
                        curveRadius), 0, math.pi), False)  # (in radian)
    topSketch.addConstraint(Sketcher.Constraint('Radius', 0, curveRadius))

    points = ((curveRadius, centerY), (curveRadius, topEdgeY),
              (-curveRadius, topEdgeY), (-curveRadius, centerY))
    for i in range(len(points) - 1):
        topSketch.addGeometry(
            Part.LineSegment(App.Vector(*(points[i])),
                             App.Vector(*(points[i + 1]))))

    topSketch.addConstraint(Sketcher.Constraint("Vertical", 1))
    topSketch.addConstraint(Sketcher.Constraint("Horizontal", 2))
    topSketch.addConstraint(Sketcher.Constraint("Vertical", 3))

    coincidentPairs = ((0, 1, 1, 1), (0, 2, 3, 2), (1, 2, 2, 1), (2, 2, 3, 1))
    for p in coincidentPairs:
        topSketch.addConstraint(Sketcher.Constraint("Coincident", *p))

    topSketch.addConstraint(
        Sketcher.Constraint("DistanceY", -1, 1, 0, 3, centerY))
    topSketch.addConstraint(
        Sketcher.Constraint("DistanceY", -1, -1, 1, 2, topEdgeY))

    # Cut curve
    pocket = obj.newObject(_featureClassMapping["Pocket"], "topCurvePocket")
    pocket.Profile = topSketch
    pocket.Length = 5
    pocket.Type = 1
    pocket.UpToFace = None
    pocket.Reversed = 0
    pocket.Midplane = 1
    pocket.Offset = 0
Пример #8
0
def lower_tabletop_2(d, dressup=True):
    ccx = d["length"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    ccy = d["width"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)

    length = ccx + (2 * d["leg_distance_from_corner"] +
                    d["insertion_width_3"]) / math.sqrt(2.0)
    width = ccy + (2 * d["leg_distance_from_corner"] +
                   d["insertion_width_3"]) / math.sqrt(2.0)

    print("Lower tabletop length: ", length)
    print("Lower tabletop width: ", width)

    m = Part.makeBox(length, width, d["lower_tabletop_t"])
    m.translate(Base.Vector(-length / 2.0, -width / 2.0, 0))
    m = dc.model.fillet_edges_by_length(m, 35, d["lower_tabletop_t"])

    hx = ccx / 2.0
    hy = ccy / 2.0

    hole_points = [
        Base.Vector(hx, hy, 0),
        Base.Vector(-hx, hy, 0),
        Base.Vector(-hx, -hy, 0),
        Base.Vector(hx, -hy, 0)
    ]

    a = 45
    for p in hole_points:
        hole = Part.makeCylinder(d["hole_dia_tabletop"] / 2.0,
                                 d["lower_tabletop_t"], p,
                                 Base.Vector(0, 0, 1), 360)
        insert = Part.makeBox(d["leg_t"], d["insertion_width_3"],
                              d["insertion_length"])
        insert = dc.model.fillet_edges_by_length(insert, d["leg_edge_radii"],
                                                 d["insertion_length"])
        insert.translate(
            Base.Vector(-d["leg_t"] / 2, -d["insertion_width_3"] / 2, 0))
        insert.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), -a)
        insert.translate(p)
        m = m.cut(hole).cut(insert)
        a = a + 90

    if dressup:
        m = dc.model.fillet_edges_longer_than(m, d["tabletop_edge_radii"], 150)

    m.translate(Base.Vector(0, 0, -d["lower_tabletop_t"]))
    return m
Пример #9
0
def load():
    """ Loads the tool. Getting the border don't require any
     option, so can be executed directly without any task panel. """
    edges = Geometry.getBorders()
    if not edges:
        wrn = Translator.translate("Can't get any edge from selected objects")
        FreeCAD.Console.PrintWarning(wrn)
        return
    obj = edges[0]
    for i in range(0, len(edges)):
        obj = obj.oldFuse(edges[i])
    Part.show(obj)
    objs = FreeCAD.ActiveDocument.Objects
    obj = objs[len(objs) - 1]
    obj.Label = 'Border'
Пример #10
0
def load():
    """ Loads the tool. Getting the border don't require any
     option, so can be executed directly without any task panel. """
    edges = Geometry.getBorders()
    if not edges:
        wrn = Translator.translate("Can't get any edge from selected objects")
        FreeCAD.Console.PrintWarning(wrn)
        return
    obj = edges[0]
    for i in range(0,len(edges)):
        obj = obj.oldFuse(edges[i])
    Part.show(obj)
    objs = FreeCAD.ActiveDocument.Objects
    obj = objs[len(objs)-1]
    obj.Label = 'Border'
Пример #11
0
def _createCylinder(doc,
                    obj,
                    cylindricalRadius,
                    length,
                    hasTopCurve,
                    hasBottomCurve,
                    addition=0.001):
    sketch = obj.newObject(_featureClassMapping["Sketch"], "cylinderSketch")
    sketch.Support = (doc.XY_Plane, [''])
    sketch.MapMode = "FlatFace"

    sketch.addGeometry(
        Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1),
                    cylindricalRadius), False)

    sketch.addConstraint(Sketcher.Constraint('Radius', 0, cylindricalRadius))

    # Extrude face
    pad = obj.newObject(_featureClassMapping["Pad"], "cylinderPad")
    pad.Profile = sketch
    pad.Type = 4
    pad.Length = length / 2 + (addition if hasTopCurve else 0)
    pad.Length2 = length / 2 + (addition if hasBottomCurve else 0)
    pad.UpToFace = None
    pad.Reversed = 0
    pad.Midplane = 0
    pad.Offset = 0.0
Пример #12
0
def wettedArea(shape, draft, trim):
    """ Calculate wetted ship area.
    @param shape Ship external faces instance.
    @param draft Draft.
    @param trim Trim in degrees.
    @return Wetted ship area.
    """
    area     = 0.0
    nObjects = 0
    # We will take a duplicate of ship shape in order to place it
    shape = shape.copy()
    shape.translate(Vector(0.0,0.0,-draft))
    shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
    # Now we need to know the x range of values
    bbox = shape.BoundBox
    xmin = bbox.XMin
    xmax = bbox.XMax
    # Create the box
    L = xmax - xmin
    B = bbox.YMax - bbox.YMin
    p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
    box = Part.makeBox(3.0*L, 3.0*B, - bbox.ZMin + 1.0, p)
    # Compute common part with ship
    for f in shape.Faces:
        # Get solids intersection
        try:
            common = box.common(f)
        except:
            continue
        area = area + common.Area
    return area
Пример #13
0
 def __init__(self, obj, solids):
     """ Creates a new ship on active document.
     @param obj Part::FeaturePython created object.
     @param faces Ship solids components.
     """
     # Add uniqueness property to identify Ship instances
     obj.addProperty(
         "App::PropertyBool", "IsShip", "Ship",
         str(Translator.translate(
             "True if is a valid ship instance"))).IsShip = True
     # Add main dimensions
     obj.addProperty(
         "App::PropertyLength", "Length", "Ship",
         str(Translator.translate("Ship length (Lpp) [m]"))).Length = 0.0
     obj.addProperty(
         "App::PropertyLength", "Beam", "Ship",
         str(Translator.translate("Ship beam (B) [m]"))).Beam = 0.0
     obj.addProperty(
         "App::PropertyLength", "Draft", "Ship",
         str(Translator.translate("Ship draft (T) [m]"))).Draft = 0.0
     # Add shapes
     obj.Shape = Part.makeCompound(solids)
     obj.addProperty("Part::PropertyPartShape", "ExternalFaces", "Ship",
                     str(Translator.translate("Ship only external faces")))
     obj.Proxy = self
Пример #14
0
def glasstop(d, dressup=True):
    m = Part.makeBox(d["length"], d["width"], d["glass_t"])
    m.translate(Base.Vector(-d["length"] / 2, -d["width"] / 2, -d["glass_t"]))

    if dressup:
        m = dc.model.chamfer_edges_longer_than(m, 2, 100)

    return m
Пример #15
0
def _cutBottomCurve(doc, obj, length, curveRadius):
    # Create bottom curve sketch
    bottomSketch = obj.newObject(_featureClassMapping["Sketch"],
                                 "bottomSketch")
    bottomSketch.Support = (doc.YZ_Plane, '')
    bottomSketch.MapMode = "FlatFace"

    centerY = curveRadius - length / 2
    bottomEdgeY = -(length / 2 + 1)
    bottomSketch.addGeometry(
        Part.ArcOfCircle(
            Part.Circle(App.Vector(0, centerY, 0), App.Vector(0, 0, 1),
                        curveRadius), -math.pi, 0), False)  # (in radian)
    bottomSketch.addConstraint(Sketcher.Constraint('Radius', 0, curveRadius))

    points = [(-curveRadius, centerY), (-curveRadius, bottomEdgeY),
              (curveRadius, bottomEdgeY), (curveRadius, centerY)]
    for i in range(len(points) - 1):
        bottomSketch.addGeometry(
            Part.LineSegment(App.Vector(*(points[i])),
                             App.Vector(*(points[i + 1]))))

    bottomSketch.addConstraint(Sketcher.Constraint("Vertical", 1))
    bottomSketch.addConstraint(Sketcher.Constraint("Horizontal", 2))
    bottomSketch.addConstraint(Sketcher.Constraint("Vertical", 3))

    coincidentPairs = ((0, 1, 1, 1), (0, 2, 3, 2), (1, 2, 2, 1), (2, 2, 3, 1))
    for p in coincidentPairs:
        bottomSketch.addConstraint(Sketcher.Constraint("Coincident", *p))

    bottomSketch.addConstraint(
        Sketcher.Constraint("DistanceY", -1, 1, 0, 3, centerY))
    bottomSketch.addConstraint(
        Sketcher.Constraint("DistanceY", -1, -1, 1, 2, bottomEdgeY))

    # Cut curve
    pocket = obj.newObject(_featureClassMapping["Pocket"], "bottomCurvePocket")
    pocket.Profile = bottomSketch
    pocket.Length = 5
    pocket.Type = 1
    pocket.UpToFace = None
    pocket.Reversed = 0
    pocket.Midplane = 1
    pocket.Offset = 0
Пример #16
0
 def saveData(self, ship, trim, drafts):
     """ Write data file.
     @param ship Selected ship instance
     @param trim Trim in degrees.
     @param drafts List of drafts to be performed.
     @return True if error happens.
     """
     # Open the file
     filename = self.path + 'hydrostatics.dat'
     try:
         Output = open(filename, "w")
     except IOError:
         msg = Translator.translate("Can't write '" + filename + "' file.\n")
         FreeCAD.Console.PrintError(msg)
         return True
     # Print header
     Output.write(header)
     Output.write(" #\n")
     Output.write(" # File automatically exported by FreeCAD-Ship\n")
     Output.write(" # This file contains transversal areas data, filled with following columns:\n")
     Output.write(" #  1: Ship displacement [ton]\n")
     Output.write(" #  2: Draft [m]\n")
     Output.write(" #  3: Wetted surface [m2]\n")
     Output.write(" #  4: 1cm triming ship moment [ton m]\n")
     Output.write(" #  5: Bouyance center x coordinate\n")
     Output.write(" #  6: Floating area\n")
     Output.write(" #  7: KBt\n")
     Output.write(" #  8: BMt\n")
     Output.write(" #  9: Cb (block coefficient)\n")
     Output.write(" # 10: Cf (Floating coefficient)\n")
     Output.write(" # 11: Cm (Main frame coefficient)\n")
     Output.write(" #\n")
     Output.write(" #################################################################\n")
     # Get external faces
     faces = self.externalFaces(ship.Shape)
     if len(faces) == 0:
         msg = Translator.translate("Can't detect external faces from ship object.\n")
         FreeCAD.Console.PrintError(msg)
     else:
         faces = Part.makeShell(faces)
     # Print data
     FreeCAD.Console.PrintMessage("Computing hydrostatics...\n")
     for i in range(0,len(drafts)):
         FreeCAD.Console.PrintMessage("\t%d / %d\n" % (i+1, len(drafts)))
         draft = drafts[i]
         point = Tools.Point(ship,faces,draft,trim)
         string = "%f %f %f %f %f %f %f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb, point.farea, point.KBt, point.BMt, point.Cb, point.Cf, point.Cm)
         Output.write(string)
     # Close file
     Output.close()
     self.dataFile = filename
     msg = Translator.translate("Data saved at '" + self.dataFile + "'.\n")
     FreeCAD.Console.PrintMessage(msg)
     return False
Пример #17
0
 def update(self, surf, direction, r):
     """ Update the 3D view printing curve.
     @param surf Surf where get the curve.
     @param direction Slice plane normal vector.
     @param r Absolute position at Slice plane normal direction.
     @return Curve from object (as Part::Feature).
     """
     # Errors
     if not surf:
         return None
     # Get curve
     curve = self.getSlice(surf, direction, r)
     # Draw at 3D view
     self.clean()
     self.objs = []
     for i in range(0, len(curve)):
         for j in range(0, len(curve[i])):
             Part.show(curve[i][j])
             objs = FreeCAD.ActiveDocument.Objects
             objs[len(objs) - 1].Label = 'surfSliceCurve'
             self.objs.append(objs[len(objs) - 1])
     return self.objs
def create_line(start, stop):
    """
    Creates and returns a FreeCAD line from a given set of start and stop coordinates
    Expects start and stop to be numpy arrays
    """
    assert start.shape == (3, ) or start.shape == (1, 3)
    assert stop.shape == (3, ) or stop.shape == (1, 3)
    assert any(np.not_equal(
        start, stop)), "Start and stop coordinate should not be identical"

    start = tuple(start)
    stop = tuple(stop)
    return Part.makeLine(start, stop)
Пример #19
0
 def update(self, surf, direction, r):
     """ Update the 3D view printing curve.
     @param surf Surf where get the curve.
     @param direction Slice plane normal vector.
     @param r Absolute position at Slice plane normal direction.
     @return Curve from object (as Part::Feature).
     """
     # Errors
     if not surf:
         return None
     # Get curve
     curve = self.getSlice(surf, direction, r)
     # Draw at 3D view
     self.clean()
     self.objs = []
     for i in range(0,len(curve)):
         for j in range(0,len(curve[i])):
             Part.show(curve[i][j])
             objs = FreeCAD.ActiveDocument.Objects
             objs[len(objs)-1].Label = 'surfSliceCurve'
             self.objs.append(objs[len(objs)-1])
     return self.objs
Пример #20
0
 def __init__(self, obj, faces):
     """ Creates a new ship on active document.
     @param faces Ship faces (Part::Shape entities).
     """
     # Add uniqueness property to identify Ship instances
     obj.addProperty("App::PropertyBool","IsShip","Ship", str(Translator.translate("True if is a valid ship instance"))).IsShip=True
     # Add main dimensions
     obj.addProperty("App::PropertyLength","Length","Ship", str(Translator.translate("Ship length (Lpp) [m]"))).Length=0.0
     obj.addProperty("App::PropertyLength","Beam","Ship", str(Translator.translate("Ship beam (B) [m]"))).Beam=0.0
     obj.addProperty("App::PropertyLength","Draft","Ship", str(Translator.translate("Ship draft (T) [m]"))).Draft=0.0
     # Add shapes
     obj.Shape = Part.makeShell(faces)
     obj.Proxy = self
     self.obj = obj
Пример #21
0
 def __init__(self, obj, solids):
     """ Creates a new ship on active document.
     @param obj Part::FeaturePython created object.
     @param faces Ship solids components.
     """
     # Add uniqueness property to identify Ship instances
     obj.addProperty("App::PropertyBool","IsShip","Ship", str(Translator.translate("True if is a valid ship instance"))).IsShip=True
     # Add main dimensions
     obj.addProperty("App::PropertyLength","Length","Ship", str(Translator.translate("Ship length (Lpp) [m]"))).Length=0.0
     obj.addProperty("App::PropertyLength","Beam","Ship", str(Translator.translate("Ship beam (B) [m]"))).Beam=0.0
     obj.addProperty("App::PropertyLength","Draft","Ship", str(Translator.translate("Ship draft (T) [m]"))).Draft=0.0
     # Add shapes
     obj.Shape = Part.makeCompound(solids)
     obj.addProperty("Part::PropertyPartShape","ExternalFaces","Ship", str(Translator.translate("Ship only external faces")))
     obj.Proxy = self
Пример #22
0
        def process(self):
            if not self.outputs['Compound'].is_linked:
                return
            if not any(sock.is_linked for sock in self.inputs):
                return

            solids_s = self.inputs['Solids'].sv_get(default=[[None]])
            curves_s = self.inputs['Curves'].sv_get(default=[[None]])
            surfaces_s = self.inputs['Surfaces'].sv_get(default=[[None]])

            if self.inputs['Solids'].is_linked:
                solids_s = ensure_nesting_level(solids_s,
                                                2,
                                                data_types=(Part.Shape, ))
                solids_level = get_data_nesting_level(
                    solids_s, data_types=(Part.Shape, ))
            else:
                solids_level = 2
            if self.inputs['Curves'].is_linked:
                curves_s = ensure_nesting_level(curves_s,
                                                2,
                                                data_types=(SvCurve, ))
                curves_level = get_data_nesting_level(curves_s,
                                                      data_types=(SvCurve, ))
            else:
                curves_level = 2
            if self.inputs['Surfaces'].is_linked:
                surfaces_s = ensure_nesting_level(surfaces_s,
                                                  2,
                                                  data_types=(SvSurface, ))
                surfaces_level = get_data_nesting_level(
                    surfaces_s, data_types=(SvSurface, ))
            else:
                surfaces_level = 2

            max_level = max(solids_level, curves_level, surfaces_level)
            compounds_out = []
            for solids, curves, surfaces in zip_long_repeat(
                    solids_s, curves_s, surfaces_s):
                shapes = solids + curves + surfaces
                shapes = [to_solid(s) for s in shapes if s is not None]
                compound = Part.Compound(shapes)
                compounds_out.append(compound)

            self.outputs['Compound'].sv_set(compounds_out)
Пример #23
0
def _cutThroughHole(doc, obj, orientation, distFromAxis, holeRadius):
    x = distFromAxis * math.cos(orientation)
    y = distFromAxis * math.sin(orientation)

    sketch = obj.newObject(_featureClassMapping["Sketch"], "cylinderSketch")
    sketch.Support = (doc.XY_Plane, [''])
    sketch.MapMode = "FlatFace"

    holeCircle = sketch.addGeometry(
        Part.Circle(App.Vector(0, 0), App.Vector(0, 0, 1), 1))
    sketch.addConstraint(Sketcher.Constraint('Radius', 0, holeRadius))
    sketch.addConstraint(Sketcher.Constraint('DistanceX', -1, 1, 0, 3, x))
    sketch.addConstraint(Sketcher.Constraint('DistanceY', -1, 1, 0, 3, y))

    pocket = obj.newObject(_featureClassMapping["Pocket"], "holeCut")
    pocket.Profile = sketch
    pocket.Type = 1
    pocket.Midplane = 1
    pocket.Offset = 0
Пример #24
0
        def execute(self, context):
            node = self.get_node(context)
            if not node: return {'CANCELLED'}

            if not node.inputs['Folder Path'].is_linked:
                self.report({'WARNING'}, "Folder path is not specified")
                return {'FINISHED'}
            if not node.inputs['Solids'].is_linked:
                self.report({'WARNING'},
                            "Object to be exported is not specified")
                return {'FINISHED'}

            folder_path = node.inputs[0].sv_get()[0][0]
            objects = node.inputs['Solids'].sv_get()
            #objects = flatten_data(objects, data_types=(Part.Shape, SvCurve, SvSurface))
            base_name = node.base_name
            if not base_name:
                base_name = "sv_solid"
            for i, shape in enumerate(objects):
                #shape = map_recursive(to_solid, object, data_types=(Part.Shape, SvCurve, SvSurface))
                debug("Exporting", shape)
                if isinstance(shape, (list, tuple)):
                    shape = flatten_data(shape, data_types=(Part.Shape, ))
                if isinstance(shape, (list, tuple)):
                    debug("Make compound:", shape)
                    shape = Part.Compound(shape)
                file_path = folder_path + base_name + "_" + "%05d" % i

                if node.mode == "BREP":
                    file_path += ".brp"
                    shape.exportBrep(file_path)
                elif node.mode == "IGES":
                    file_path += ".igs"
                    shape.exportIges(file_path)
                else:
                    file_path += ".stp"
                    shape.exportStep(file_path)
                self.report({'INFO'}, f"Saved object #{i} to {file_path}")

            return {'FINISHED'}
Пример #25
0
 def __init__(self, obj, faces):
     """ Creates a new ship on active document.
     @param faces Ship faces (Part::Shape entities).
     """
     # Add uniqueness property to identify Ship instances
     obj.addProperty(
         "App::PropertyBool", "IsShip", "Ship",
         str(Translator.translate(
             "True if is a valid ship instance"))).IsShip = True
     # Add main dimensions
     obj.addProperty(
         "App::PropertyLength", "Length", "Ship",
         str(Translator.translate("Ship length (Lpp) [m]"))).Length = 0.0
     obj.addProperty(
         "App::PropertyLength", "Beam", "Ship",
         str(Translator.translate("Ship beam (B) [m]"))).Beam = 0.0
     obj.addProperty(
         "App::PropertyLength", "Draft", "Ship",
         str(Translator.translate("Ship draft (T) [m]"))).Draft = 0.0
     # Add shapes
     obj.Shape = Part.makeShell(faces)
     obj.Proxy = self
     self.obj = obj
Пример #26
0
 def update(self, L, B, T):
     """ Update the 3D view printing annotations.
     @param L Ship length.
     @param B Ship beam.
     @param T Ship draft.
     """
     # Destroy all previous entities
     self.clean()
     # Draw base line
     xStart = -0.6 * L
     xEnd = 0.6 * L
     baseLine = Part.makeLine((xStart, 0, 0), (xEnd, 0, 0))
     Part.show(baseLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.baseLine = objs[len(objs) - 1]
     self.baseLine.Label = 'BaseLine'
     self.baseLineLabel = DrawText('BaseLineText',
                                   str(Translator.translate('Base line')),
                                   Base.Vector(xEnd, 0, 0))
     # Draw free surface
     fsLine = Part.makeLine((xStart, 0, T), (xEnd, 0, T))
     Part.show(fsLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.fsLine = objs[len(objs) - 1]
     self.fsLine.Label = 'FreeSurface'
     self.fsLineLabel = DrawText('FSText',
                                 str(Translator.translate('Free surface')),
                                 Base.Vector(xEnd, 0, T))
     # Draw forward perpendicular
     zStart = -0.1 * T
     zEnd = 1.1 * T
     fpLine = Part.makeLine((0.5 * L, 0, zStart), (0.5 * L, 0, zEnd))
     Part.show(fpLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.fpLine = objs[len(objs) - 1]
     self.fpLine.Label = 'ForwardPerpendicular'
     self.fpLineLabel = DrawText(
         'FPText', str(Translator.translate('Forward perpendicular')),
         Base.Vector(0.5 * L, 0, zEnd))
     # Draw after perpendicular
     apLine = Part.makeLine((-0.5 * L, 0, zStart), (-0.5 * L, 0, zEnd))
     Part.show(apLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.apLine = objs[len(objs) - 1]
     self.apLine.Label = 'AfterPerpendicular'
     self.apLineLabel = DrawText(
         'APText', str(Translator.translate('After perpendicular')),
         Base.Vector(-0.5 * L, 0, zEnd))
     # Draw amin frame
     amLine = Part.makeLine((0, -0.5 * B, zStart), (0, -0.5 * B, zEnd))
     Part.show(amLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.amLine = objs[len(objs) - 1]
     self.amLine.Label = 'AminFrame'
     self.amLineLabel = DrawText('AMText',
                                 str(Translator.translate('Amin frame')),
                                 Base.Vector(0, -0.5 * B, zEnd))
Пример #27
0
 def execute(self, obj):
     ''' Print a short message when doing a recomputation, this method is mandatory '''
     # FreeCAD.Console.PrintMessage("Recompute Ship\n")
     obj.Shape = Part.makeShell(obj.Shape.Faces)
Пример #28
0
 def update(self, L, B, T):
     """ Update the 3D view printing annotations.
     @param L Ship length.
     @param B Ship beam.
     @param T Ship draft.
     """
     # Destroy all previous entities
     self.clean()
     # Draw base line
     xStart   = -0.6*L;
     xEnd     =  0.6*L;
     baseLine = Part.makeLine((xStart,0,0),(xEnd,0,0))
     Part.show(baseLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.baseLine = objs[len(objs)-1]
     self.baseLine.Label = 'BaseLine'
     self.baseLineLabel = DrawText('BaseLineText', str(Translator.translate('Base line')), Base.Vector(xEnd,0,0))
     # Draw free surface
     fsLine = Part.makeLine((xStart,0,T),(xEnd,0,T))
     Part.show(fsLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.fsLine = objs[len(objs)-1]
     self.fsLine.Label = 'FreeSurface'
     self.fsLineLabel = DrawText('FSText', str(Translator.translate('Free surface')), Base.Vector(xEnd,0,T))
     # Draw forward perpendicular
     zStart = -0.1*T
     zEnd   =  1.1*T
     fpLine = Part.makeLine((0.5*L,0,zStart),(0.5*L,0,zEnd))
     Part.show(fpLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.fpLine = objs[len(objs)-1]
     self.fpLine.Label = 'ForwardPerpendicular'
     self.fpLineLabel = DrawText('FPText', str(Translator.translate('Forward perpendicular')), Base.Vector(0.5*L,0,zEnd))
     # Draw after perpendicular
     apLine = Part.makeLine((-0.5*L,0,zStart),(-0.5*L,0,zEnd))
     Part.show(apLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.apLine = objs[len(objs)-1]
     self.apLine.Label = 'AfterPerpendicular'
     self.apLineLabel = DrawText('APText', str(Translator.translate('After perpendicular')), Base.Vector(-0.5*L,0,zEnd))
     # Draw amin frame
     amLine = Part.makeLine((0,-0.5*B,zStart),(0,-0.5*B,zEnd))
     Part.show(amLine)
     objs = FreeCAD.ActiveDocument.Objects
     self.amLine = objs[len(objs)-1]
     self.amLine.Label = 'AminFrame'
     self.amLineLabel = DrawText('AMText', str(Translator.translate('Amin frame')), Base.Vector(0,-0.5*B,zEnd))
Пример #29
0
 def discretize(self, nS, nP):
     """ Discretize the surface.
     @param nS Number of sections
     @param nP Number of points per section
     """
     self.obj.addProperty("App::PropertyInteger","nSections","Ship", str(Translator.translate("Number of sections"))).nSections=nS
     self.obj.addProperty("App::PropertyIntegerList","nPoints","Ship", str(Translator.translate("List of number of points per sections (accumulated histogram)"))).nPoints=[0]
     self.obj.addProperty("App::PropertyFloatList","xSection","Ship", str(Translator.translate("List of sections x coordinate"))).xSection=[]
     self.obj.addProperty("App::PropertyVectorList","mSections","Ship", str(Translator.translate("List of sections points"))).mSections=[]
     nPoints   = [0]
     xSection  = []
     mSections = []
     # Get bounds
     shape = self.obj.Shape
     bbox = shape.BoundBox
     x0 = bbox.XMin
     x1 = bbox.XMax
     y0 = bbox.YMin
     y1 = bbox.YMax
     z0 = bbox.ZMin
     z1 = bbox.ZMax
     # Create a set of planes to perfom edges sections
     planes = []
     dz = (z1 - z0) / (nP - 1)
     for j in range(0,nP):
         z = z0 + j*dz
         rX = x1 - x0
         rY = max(y1 - y0, abs(y1), abs(y0))
         planes.append(Part.makePlane(4*rX,4*rY,Base.Vector(-2*rX,-2*rY,z),Base.Vector(0,0,1)))
     # Division are performed at x axis
     dx = (x1 - x0) / (nS - 1.0)
     for i in range(0,nS):
         section = []
         x = x0 + i*dx
         xSection.append(x)
         percen = i*100 / (nS-1)
         FreeCAD.Console.PrintMessage('%d%%\n' % (percen));
         # Slice the surface to get curves
         wires = shape.slice(Vector(1.0,0.0,0.0), x)
         if not wires:
             if (i != 0) or (i != nS-1):
                 msg = 'Found empty section at x=%g\n' % (x)
                 msg = Translator.translate(msg)
                 FreeCAD.Console.PrintWarning(msg)
                 FreeCAD.Console.PrintWarning('\tThis may happens if a bad defined (or really complex) surface has been provided.\n')
                 FreeCAD.Console.PrintWarning('\tPlease, ensure that this section is correct, or fix surfaces and create a new ship.\n')
                 nPoints.append(0)
                 continue
         # Desarrollate wires into edges list
         edges = []
         for j in range(0,len(wires)):
             wire = wires[j].Edges
             for k in range(0,len(wire)):
                 edges.append(wire[k])
         # Slice curves to get points (Length based)
         points = []
         for k in range(0,nP):
             planePoints = []
             for j in range(0,len(edges)):
                 aux = self.lineFaceSection(edges[j], planes[k])
                 for l in range(0,len(aux)):
                     planePoints.append(Vector(aux[l].X, aux[l].Y, aux[l].Z))
             if not planePoints:                             # No section found, symmetry plane point will used
                 planePoints.append(Vector(x,0,z0 + k*dz))
             # Get Y coordinates
             auxY = []
             for l in range(0,len(planePoints)):
                 auxY.append(planePoints[l].y)
             # Sort them
             auxY.sort()
             # And store
             for l in range(0,len(planePoints)):
                 points.append(Vector(planePoints[l].x, auxY[l], planePoints[l].z))
         # Store points
         section = points[:]
         nPoints.append(len(section))
         for j in range(0,len(section)):
             mSections.append(section[j])
     # Save data
     for i in range(1,len(nPoints)):
         nPoints[i] = nPoints[i] + nPoints[i-1]
     self.obj.nPoints   = nPoints[:]
     self.obj.xSection  = xSection[:]
     self.obj.mSections = mSections[:]
     msg = '%d Discretization points performed\n' % (len(mSections))
     msg = Translator.translate(msg)
     FreeCAD.Console.PrintMessage(msg)
Пример #30
0
 def onChanged(self, fp, prop):
     ''' Print the name of the property that has changed '''
     # FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
     if prop == "Length" or prop == "Beam" or prop == "Draft":
         fp.Shape = Part.makeShell(self.faces)
Пример #31
0
def _cutKnob(doc, obj, orientation, distFromAxis, radius, outerRadius,
             baseToCenter):
    """
        ringLength = to bypass the app
    """
    knobPlane = obj.newObject(_featureClassMapping["Plane"], "knobPlane")
    knobPlane.AttachmentOffset = App.Placement(App.Vector(0, 0, baseToCenter),
                                               App.Rotation(0, 0, 0))
    knobPlane.MapReversed = False
    knobPlane.Support = [(doc.XY_Plane, '')]
    knobPlane.MapMode = "FlatFace"

    sketch = obj.newObject(_featureClassMapping["Sketch"], "knobSketch")
    sketch.Support = (knobPlane, '')
    sketch.MapMode = "FlatFace"

    sketch.addGeometry(
        Part.ArcOfCircle(Part.Circle(App.Vector(0, 0), App.Vector(0, 0, 1), 1),
                         math.pi / 2, 3 * math.pi / 2), False)

    sketch.addConstraint(Sketcher.Constraint('Radius', 0, radius))

    # Enforce 180 deg span of arc
    sketch.addGeometry(
        Part.LineSegment(App.Vector(0.0, 0.0), App.Vector(1.0, 0.0)), True)
    sketch.addConstraint(Sketcher.Constraint('Coincident', 1, 1, 0, 1))
    sketch.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 0, 3))

    sketch.addGeometry(
        Part.LineSegment(App.Vector(0.0, 0.0), App.Vector(1.0, 0.0)), True)
    sketch.addConstraint(Sketcher.Constraint('Coincident', 2, 1, 0, 3))
    sketch.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 0, 2))
    sketch.addConstraint(Sketcher.Constraint('Angle', 1, 2, 2, 1, math.pi))

    # Complete shape
    sketch.addGeometry(
        Part.LineSegment(App.Vector(0, radius), App.Vector(1.0, radius)),
        False)  # 3
    sketch.addGeometry(
        Part.LineSegment(App.Vector(0.0, -radius), App.Vector(1.0, -radius)),
        False)  # 4
    sketch.addConstraint(Sketcher.Constraint('Tangent', 3, 1, 0, 1))
    sketch.addConstraint(Sketcher.Constraint('Tangent', 4, 1, 0, 2))
    sketch.addConstraint(Sketcher.Constraint('Equal', 3, 4))
    sketch.addConstraint(Sketcher.Constraint('Distance', 3, outerRadius))

    sketch.addGeometry(
        Part.LineSegment(App.Vector(1.0, radius), App.Vector(1.0, -radius)),
        False)  # 5
    sketch.addConstraint(Sketcher.Constraint('Coincident', 5, 1, 3, 2))
    sketch.addConstraint(Sketcher.Constraint('Coincident', 5, 2, 4, 2))

    # Enforce orientation
    sketch.addGeometry(
        Part.LineSegment(App.Vector(0.0, radius), App.Vector(1.0, radius)),
        True)  # 6
    sketch.addConstraint(Sketcher.Constraint('Horizontal', 6))
    sketch.addConstraint(Sketcher.Constraint('Distance', 6, radius))
    sketch.addConstraint(Sketcher.Constraint('Coincident', 6, 1, 0, 1))
    sketch.addConstraint(Sketcher.Constraint('Angle', 6, 1, 3, 1, orientation))

    # Enforce disp
    x = distFromAxis * math.cos(orientation)
    y = distFromAxis * math.sin(orientation)
    sketch.addConstraint(Sketcher.Constraint('DistanceX', -1, 1, 0, 3, x))
    sketch.addConstraint(Sketcher.Constraint('DistanceY', -1, 1, 0, 3, y))

    pocket = obj.newObject(_featureClassMapping["Pocket"], "knobCut")
    pocket.Profile = sketch
    pocket.Length = 10.0
    pocket.Length2 = 100.0
    pocket.Type = 1
    pocket.UpToFace = None
    pocket.Reversed = 1
    pocket.Midplane = 0
    pocket.Offset = 0.000000
Пример #32
0
 def externalFaces(self, shape):
     """ Returns detected external faces.
     @param shape Shape where external faces wanted.
     @return List of external faces detected.
     """
     result = []
     faces  = shape.Faces
     bbox   = shape.BoundBox
     L      = bbox.XMax - bbox.XMin
     B      = bbox.YMax - bbox.YMin
     T      = bbox.ZMax - bbox.ZMin
     dist   = math.sqrt(L*L + B*B + T*T)
     FreeCAD.Console.PrintMessage("Computing external faces...\n")
     # Valid/unvalid faces detection loop
     for i in range(0,len(faces)):
         FreeCAD.Console.PrintMessage("\t%d / %d\n" % (i+1, len(faces)))
         f = faces[i]
         # Create a line normal to surface at middle point
         u = 0.0
         v = 0.0
         try:
             surf    = f.Surface
             u       = 0.5*(surf.getUKnots()[0]+surf.getUKnots()[-1])
             v       = 0.5*(surf.getVKnots()[0]+surf.getVKnots()[-1])
         except:
             cog   = f.CenterOfMass
             [u,v] = f.Surface.parameter(cog)
         p0 = f.valueAt(u,v)
         try:
             n  = f.normalAt(u,v).normalize()
         except:
             continue
         p1 = p0 + n.multiply(1.5*dist)
         line = Part.makeLine(p0, p1)
         # Look for faces in front of this
         nPoints = 0
         for j in range(0,len(faces)):
             f2 = faces[j]
             section = self.lineFaceSection(line, f2)
             if len(section) <= 2:
                 continue
             # Add points discarding start and end
             nPoints = nPoints + len(section) - 2
         # In order to avoid special directions we can modify line
         # normal a little bit.
         angle = 5
         line.rotate(p0,Vector(1,0,0),angle)
         line.rotate(p0,Vector(0,1,0),angle)
         line.rotate(p0,Vector(0,0,1),angle)
         nPoints2 = 0
         for j in range(0,len(faces)):
             if i == j:
                 continue
             f2 = faces[j]
             section = self.lineFaceSection(line, f2)
             if len(section) <= 2:
                 continue
             # Add points discarding start and end
             nPoints2 = nPoints + len(section) - 2
         # If the number of intersection points is pair, is a
         # external face. So if we found an odd points intersection,
         # face must be discarded.
         if (nPoints % 2) or (nPoints2 % 2):
             continue
         result.append(f)
     return result
Пример #33
0
 def update(self, names, pos):
     """ Update the 3D view printing annotations.
     @param names Weight names.
     @param pos Weight positions (FreeCAD::Base::Vector).
     """
     # Destroy all previous entities
     self.clean()
     for i in range(0, len(names)):
         # Draw gravity line
         line = Part.makeLine((pos[i].x, pos[i].y, pos[i].z),
                              (pos[i].x, pos[i].y, pos[i].z - 9.81))
         Part.show(line)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'Line'
         # Draw circles
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(1.0, 0.0, 0.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleX'
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0, 1.0, 0.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleY'
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0, 0.0, 1.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleZ'
         # Draw annotation
         self.objects.append(
             DrawText(names[i] + 'Text', names[i],
                      Base.Vector(pos[i].x + 1.0, pos[i].y, pos[i].z)))
Пример #34
0
 def import_shape_from_file(cls):
     # Get shape from file path
     cls.fcd_shape = Part.Shape()
     cls.fcd_shape.read(cls._design_path)
Пример #35
0
def upper_tabletop_3(d, dressup=True):
    s = 35
    x1 = d["length"] / 2.0
    y1 = d["width"] / 2.0
    x2 = x1 - 25
    y2 = y1 - 25

    p = [None] * 12

    p[0] = Base.Vector(-x1, y2, 0)
    p[1] = Base.Vector(-x2, y1, 0)

    p[3] = Base.Vector(x2, y1, 0)
    p[4] = Base.Vector(x1, y2, 0)

    p[6] = Base.Vector(x1, -y2, 0)
    p[7] = Base.Vector(x2, -y1, 0)

    p[9] = Base.Vector(-x2, -y1, 0)
    p[10] = Base.Vector(-x1, -y2, 0)

    p[2] = dc.model.sagpoint(p[1], p[3], s)
    p[5] = dc.model.sagpoint(p[4], p[6], s)
    p[8] = dc.model.sagpoint(p[7], p[9], s)
    p[11] = dc.model.sagpoint(p[10], p[0], s)

    wire = [
        Part.makeLine(p[0], p[1]),
        dc.model.makeArc(p[1:4]),
        Part.makeLine(p[3], p[4]),
        dc.model.makeArc(p[4:7]),
        Part.makeLine(p[6], p[7]),
        dc.model.makeArc(p[7:10]),
        Part.makeLine(p[9], p[10]),
        dc.model.makeArc([p[10], p[11], p[0]])
    ]

    face = Part.Face(Part.Wire(wire))
    m = face.extrude(Base.Vector(0, 0, d["upper_tabletop_t"]))
    m = dc.model.fillet_edges_by_length(m, 60, d["upper_tabletop_t"])

    print("Upper tabletop length: ", d["length"])
    print("Upper tabletop width: ", d["width"])

    ccx = d["length"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    ccy = d["width"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    hx = ccx / 2.0
    hy = ccy / 2.0

    hole_points = [
        Base.Vector(hx, hy, 0),
        Base.Vector(-hx, hy, 0),
        Base.Vector(-hx, -hy, 0),
        Base.Vector(hx, -hy, 0)
    ]

    a = 135
    for p in hole_points:
        hole = Part.makeCylinder(d["hole_dia_tabletop"] / 2.0,
                                 d["upper_tabletop_t"] / 2.0, p,
                                 Base.Vector(0, 0, 1), 360)

        insert_1 = Part.makeBox(d["leg_t"], d["insertion_width_1"],
                                d["insertion_length"])
        insert_1 = dc.model.fillet_edges_by_length(insert_1,
                                                   d["leg_edge_radii"],
                                                   d["insertion_length"])
        insert_1.translate(Base.Vector(-d["leg_t"] / 2, -d["cx"], 0))
        insert_1.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), a)
        insert_1.translate(p)

        insert_2 = Part.makeBox(d["leg_t"], d["insertion_width_2"],
                                d["insertion_length"])
        insert_2 = dc.model.fillet_edges_by_length(insert_2,
                                                   d["leg_edge_radii"],
                                                   d["insertion_length"])
        insert_2.translate(
            Base.Vector(-d["leg_t"] / 2, -d["insertion_width_3"] / 2.0, 0))
        insert_2.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), a)
        insert_2.translate(p)

        m = m.cut(insert_1).cut(insert_2).cut(hole)
        a = a + 90

    if dressup:
        m = dc.model.fillet_edges_longer_than(m, d["tabletop_edge_radii"], 300)

    m.translate(Base.Vector(0, 0, -d["upper_tabletop_t"]))
    return m
Пример #36
0
def lower_tabletop_3(d, dressup=True):
    ccx = d["length"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)
    ccy = d["width"] - 2 * math.sqrt(
        ((d["cx"] + d["leg_distance_from_corner"])**2) / 2.0)

    length = ccx + (2 * d["leg_distance_from_corner"] +
                    d["insertion_width_3"]) / math.sqrt(2.0)
    width = ccy + (2 * d["leg_distance_from_corner"] +
                   d["insertion_width_3"]) / math.sqrt(2.0)

    print("Lower tabletop length: ", length)
    print("Lower tabletop width: ", width)

    x1 = length / 2.0
    y1 = width / 2.0
    x2 = x1 - 25
    y2 = y1 - 25

    p = [None] * 12

    p[0] = Base.Vector(-x1, y2, 0)
    p[1] = Base.Vector(-x2, y1, 0)

    p[3] = Base.Vector(x2, y1, 0)
    p[4] = Base.Vector(x1, y2, 0)

    p[6] = Base.Vector(x1, -y2, 0)
    p[7] = Base.Vector(x2, -y1, 0)

    p[9] = Base.Vector(-x2, -y1, 0)
    p[10] = Base.Vector(-x1, -y2, 0)

    p[2] = dc.model.sagpoint(p[1], p[3], -45)
    p[5] = dc.model.sagpoint(p[4], p[6], -45)
    p[8] = dc.model.sagpoint(p[7], p[9], -45)
    p[11] = dc.model.sagpoint(p[10], p[0], -45)

    wire = [
        Part.makeLine(p[0], p[1]),
        dc.model.makeArc(p[1:4]),
        Part.makeLine(p[3], p[4]),
        dc.model.makeArc(p[4:7]),
        Part.makeLine(p[6], p[7]),
        dc.model.makeArc(p[7:10]),
        Part.makeLine(p[9], p[10]),
        dc.model.makeArc([p[10], p[11], p[0]])
    ]

    face = Part.Face(Part.Wire(wire))
    m = face.extrude(Base.Vector(0, 0, d["lower_tabletop_t"]))
    m = dc.model.fillet_edges_by_length(m, 20, d["lower_tabletop_t"])

    hx = ccx / 2.0
    hy = ccy / 2.0

    hole_points = [
        Base.Vector(hx, hy, 0),
        Base.Vector(-hx, hy, 0),
        Base.Vector(-hx, -hy, 0),
        Base.Vector(hx, -hy, 0)
    ]

    a = 45
    for p in hole_points:
        hole = Part.makeCylinder(d["hole_dia_tabletop"] / 2.0,
                                 d["lower_tabletop_t"], p,
                                 Base.Vector(0, 0, 1), 360)
        insert = Part.makeBox(d["leg_t"], d["insertion_width_3"],
                              d["insertion_length"])
        insert = dc.model.fillet_edges_by_length(insert, d["leg_edge_radii"],
                                                 d["insertion_length"])
        insert.translate(
            Base.Vector(-d["leg_t"] / 2, -d["insertion_width_3"] / 2, 0))
        insert.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1), -a)
        insert.translate(p)
        m = m.cut(hole).cut(insert)
        a = a + 90

    if dressup:
        m = dc.model.fillet_edges_longer_than(m, d["tabletop_edge_radii"], 150)

    m.translate(Base.Vector(0, 0, -d["lower_tabletop_t"]))
    return m
Пример #37
0
 def update(self, names, pos):
     """ Update the 3D view printing annotations.
     @param names Weight names.
     @param pos Weight positions (FreeCAD::Base::Vector).
     """
     # Destroy all previous entities
     self.clean()
     for i in range(0, len(names)):
         # Draw gravity line
         line = Part.makeLine((pos[i].x,pos[i].y,pos[i].z),(pos[i].x,pos[i].y,pos[i].z - 9.81))
         Part.show(line)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'Line'
         # Draw circles
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(1.0,0.0,0.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleX'            
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0,1.0,0.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleY'            
         circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0,0.0,1.0))
         Part.show(circle)
         objs = FreeCAD.ActiveDocument.Objects
         self.objects.append(objs[-1])
         objs[-1].Label = names[i] + 'CircleZ'            
         # Draw annotation
         self.objects.append(DrawText(names[i] + 'Text', names[i], Base.Vector(pos[i].x+1.0,pos[i].y,pos[i].z)))
Пример #38
0
 def update(self, L, B, T, sectionsL, sectionsB, sectionsT, shape):
     """ Update the 3D view printing annotations.
     @param L Ship Lpp.
     @param B Ship beam.
     @param T Ship draft.
     @param sectionsL Transversal sections.
     @param sectionsB Longitudinal sections.
     @param sectionsT Water lines.
     @param shape Ship surfaces shell
     @return Sections object. None if errors happens.
     """
     FreeCAD.Console.PrintMessage(Translator.translate('Computing sections...\n'))
     # Destroy all previous entities
     self.clean()
     # Receive data
     nL = len(sectionsL)
     nB = len(sectionsB)
     nT = len(sectionsT)
     if not (nL or nB or nT):
         return None
     # Found sections
     sections = []
     for i in range(0,nL):
         pos = sectionsL[i]
         section = shape.slice(Vector(1.0,0.0,0.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             if pos == 0.0:
                 section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
                 edges2 = section[j].Edges
                 for k in range(0,len(edges2)):
                     edges.append(edges2[k])
             elif pos < 0:
                 section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
                 edges = section[j].Edges                    
             for k in range(0,len(edges)):
                 sections.append(edges[k])
     for i in range(0,nB):
         pos = sectionsB[i]
         section = shape.slice(Vector(0.0,1.0,0.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
             edges2 = section[j].Edges
             for k in range(0,len(edges2)):
                 edges.append(edges2[k])
             for k in range(0,len(edges)):
                 sections.append(edges[k])
     for i in range(0,nT):
         pos = sectionsT[i]
         section = shape.slice(Vector(0.0,0.0,1.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             if pos == T:
                 section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
                 edges2 = section[j].Edges
                 for k in range(0,len(edges2)):
                     edges.append(edges2[k])
             elif pos > T:
                 section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
                 edges = section[j].Edges                    
             for k in range(0,len(edges)):
                 sections.append(edges[k])
     # Convert all BSplines into a shape
     if not sections:
         msg = Translator.translate('Any valid ship section found\n')
         FreeCAD.Console.PrintWarning(msg)
         return
     obj = sections[0]
     for i in range(1,len(sections)):
         obj = obj.oldFuse(sections[i])  # Only group the edges, don't try to build more complex entities
     # Create the representable object
     Part.show(obj)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs)-1]
     self.obj.Label = 'OutlineDraw'
     return self.obj
Пример #39
0
 def execute(self, obj):
     ''' Print a short message when doing a recomputation, this method is mandatory '''
     # FreeCAD.Console.PrintMessage("Recompute Ship\n")
     obj.Shape = Part.makeShell(self.faces)
Пример #40
0
def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
    """ Compute ship transversal areas.
    @param ship Ship instance.
    @param draft Ship draft.
    @param roll Ship roll angle.
    @param trim Ship trim angle.
    @param yaw Ship yaw angle. Ussually you don't want to use this 
    value.
    @param n Number of sections to perform.
    @return Transversal areas (every area value is composed by x 
    coordinate and computed area)
    """
    if n < 2:
        return []
    # We will take a duplicate of ship shape in order to place it
    shape = ship.Shape.copy()
    shape.translate(Vector(0.0,0.0,-draft))
    # Rotations composition is Roll->Trim->Yaw
    shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
    shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
    shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,0.0,1.0), yaw)
    # Now we need to know the x range of values
    bbox = shape.BoundBox
    xmin = bbox.XMin
    xmax = bbox.XMax
    dx   = (xmax - xmin) / (n-1.0)
    # First area is equal to zero.
    areas = [[xmin, 0.0]]
    # Since we need face entities, in order to compute sections we will
    # create boxes with front face at transversal area position, 
    # compute solid common, divide by faces, and preserve only desired
    # ones.
    App.Console.PrintMessage("Computing transversal areas...\n")
    App.Console.PrintMessage("Some Inventor representation errors can be shown, ignore it please.\n")
    for i in range(1,n-1):
        App.Console.PrintMessage("%d / %d\n" % (i, n-2))
        x    = xmin + i*dx
        area = 0.0
        # Create the box
        L = xmax - xmin
        B = bbox.YMax - bbox.YMin
        p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
        box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin + 1.0, p)
        # Compute common part with ship
        for s in shape.Solids:
            # Get solids intersection
            try:
                common = box.common(s)
            except:
                continue
            if common.Volume == 0.0:
                continue
            # Recompute object adding it to the scene, when we have
            # computed desired data we can remove it.
            try:
                Part.show(common)
            except:
                continue
            # Divide by faces and compute only section placed ones
            faces  = common.Faces
            for f in faces:
                faceBounds = f.BoundBox
                # Orientation filter
                if faceBounds.XMax - faceBounds.XMin > 0.00001:
                    continue
                # Place filter
                if abs(faceBounds.XMax - x) > 0.00001:
                    continue
                # Valid face, compute area
                area = area + f.Area
            # Destroy last object generated
            App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
        # Append transversal area
        areas.append([x, area])
    # Last area is equal to zero
    areas.append([xmax, 0.0])
    App.Console.PrintMessage("Done!\n")
    return areas
Пример #41
0
def Plot(scale, sections, shape):
    """ Creates the outline draw.
    @param scale Plane scale (format 1:scale)
    @param sections Sections computed.
    @param shape Ship surfaces shell
    @return plotted object (DocumentObject)
    """
    msg = Translator.translate('Performing plot (Scale 1:%d)...\n' % (scale))
    FreeCAD.Console.PrintMessage(msg)
    scale = 1000.0 / scale
    # Take positions
    bounds = [0.0, 0.0, 0.0]
    bbox = shape.BoundBox
    bounds[0] = bbox.XLength
    bounds[1] = bbox.YLength
    bounds[2] = bbox.ZLength
    xTot = scale*bounds[1] + 32.0 + scale*bounds[0]
    yTot = scale*bounds[2] + 32.0 + scale*bounds[1]
    xMid = 210.0
    yMid = 185.0
    x0 = xMid - 0.5*xTot
    y0 = 297.0 - yMid - 0.5*yTot # 297 = A3_width
    # Get border
    edges = Geometry.getEdges([shape])
    border = edges[0]
    for i in range(0,len(edges)):
        border = border.oldFuse(edges[i])   # Only group objects, don't try to build more complex entities
        border = border.oldFuse(edges[i].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0)))
    # Fuse sections & borders
    # obj = sections.oldFuse(border)
    obj = border.oldFuse(sections)
    # Send to 3D view
    Part.show(obj)
    objs = FreeCAD.ActiveDocument.Objects
    obj = objs[len(objs)-1]
    # Create a new plane
    FreeCAD.ActiveDocument.addObject('Drawing::FeaturePage','OutlineDrawPlot')
    FreeCAD.ActiveDocument.OutlineDrawPlot.Template = FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
    # Side view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawSideView')
    FreeCAD.ActiveDocument.OutlineDrawSideView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawSideView.Direction = (1.0,0.0,0.0)
    FreeCAD.ActiveDocument.OutlineDrawSideView.Rotation = -90.0
    FreeCAD.ActiveDocument.OutlineDrawSideView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawSideView.X = 420.0 - x0 - 0.5*scale*bounds[1] # 420 = A3_height
    FreeCAD.ActiveDocument.OutlineDrawSideView.Y = y0 + 0.5*scale*bounds[2]
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawSideView)
    # Front view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawFrontView')
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Direction = (0.0,1.0,0.0)
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Rotation = -90.0
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawFrontView.X = 420.0 - x0 - scale*bounds[1] - 32 - 0.5*scale*bounds[0]
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Y = y0 + 0.5*scale*bounds[2]
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawFrontView)
    # Up view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawUpView')
    FreeCAD.ActiveDocument.OutlineDrawUpView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawUpView.Direction = (0.0,0.0,1.0)
    FreeCAD.ActiveDocument.OutlineDrawUpView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawUpView.X = 420.0 - x0 - scale*bounds[1] - 32 - 0.5*scale*bounds[0]
    FreeCAD.ActiveDocument.OutlineDrawUpView.Y = y0 + scale*bounds[2] + 32
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawUpView)
    FreeCAD.ActiveDocument.recompute()
    return obj
Пример #42
0
def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
    """ Compute ship displacement.
    @param ship Ship instance.
    @param draft Ship draft.
    @param roll Ship roll angle.
    @param trim Ship trim angle.
    @param yaw Ship yaw angle. Ussually you don't want to use this 
    value.
    @return [disp, B, Cb], \n
    disp = Ship displacement [ton].
    B    = Bouyance center [m].
    Cb   = Block coefficient.
    @note Bouyance center will returned as FreeCAD.Vector class.
    @note Returned Bouyance center is in non modified ship coordinates
    """
    # We will take a duplicate of ship shape in order to place it
    shape = ship.Shape.copy()
    shape.translate(Vector(0.0,0.0,-draft))
    # Rotations composition is Roll->Trim->Yaw
    shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
    shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
    shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,0.0,1.0), yaw)
    # Now we need to know box dimensions
    bbox = shape.BoundBox
    xmin = bbox.XMin
    xmax = bbox.XMax
    # Create the box
    L = xmax - xmin
    B = bbox.YMax - bbox.YMin
    p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
    box = Part.makeBox(3.0*L, 3.0*B, -bbox.ZMin + 1.0, p)
    vol = 0.0
    cog = Vector()
    for solid in shape.Solids:
        # Compute common part with ship
        try:
            common = box.common(solid)
        except:
            continue
        # Get data
        vol = vol + common.Volume
        for s in common.Solids:
            sCoG  = s.CenterOfMass
            cog.x = cog.x + sCoG.x*s.Volume
            cog.y = cog.y + sCoG.y*s.Volume
            cog.z = cog.z + sCoG.z*s.Volume
    cog.x = cog.x / vol
    cog.y = cog.y / vol
    cog.z = cog.z / vol
    Vol = L*B*abs(bbox.ZMin)
    # Undo transformations
    B   = Vector()
    B.x = cog.x*math.cos(math.radians(-yaw)) - cog.y*math.sin(math.radians(-yaw))
    B.y = cog.x*math.sin(math.radians(-yaw)) + cog.y*math.cos(math.radians(-yaw))
    B.z = cog.z
    cog.x = B.x*math.cos(math.radians(-trim)) - B.z*math.sin(math.radians(-trim))
    cog.y = B.y
    cog.z = B.x*math.sin(math.radians(-trim)) + B.z*math.cos(math.radians(-trim))
    B.x = cog.x
    B.y = cog.y*math.cos(math.radians(-roll)) - cog.z*math.sin(math.radians(-roll))
    B.z = cog.y*math.sin(math.radians(-roll)) + cog.z*math.cos(math.radians(-roll))
    B.z = B.z + draft
    # Return data
    dens = 1.025 # [tons/m3], salt water
    return [dens*vol, B, vol/Vol]
Пример #43
0
 def discretize(self, nS, nP):
     """ Discretize the surface.
     @param nS Number of sections
     @param nP Number of points per section
     """
     self.obj.addProperty(
         "App::PropertyInteger", "nSections", "Ship",
         str(Translator.translate("Number of sections"))).nSections = nS
     self.obj.addProperty(
         "App::PropertyIntegerList", "nPoints", "Ship",
         str(
             Translator.translate(
                 "List of number of points per sections (accumulated histogram)"
             ))).nPoints = [0]
     self.obj.addProperty(
         "App::PropertyFloatList", "xSection", "Ship",
         str(Translator.translate(
             "List of sections x coordinate"))).xSection = []
     self.obj.addProperty(
         "App::PropertyVectorList", "mSections", "Ship",
         str(Translator.translate(
             "List of sections points"))).mSections = []
     nPoints = [0]
     xSection = []
     mSections = []
     # Get bounds
     shape = self.obj.Shape
     bbox = shape.BoundBox
     x0 = bbox.XMin
     x1 = bbox.XMax
     y0 = bbox.YMin
     y1 = bbox.YMax
     z0 = bbox.ZMin
     z1 = bbox.ZMax
     # Create a set of planes to perfom edges sections
     planes = []
     dz = (z1 - z0) / (nP - 1)
     for j in range(0, nP):
         z = z0 + j * dz
         rX = x1 - x0
         rY = max(y1 - y0, abs(y1), abs(y0))
         planes.append(
             Part.makePlane(4 * rX, 4 * rY,
                            Base.Vector(-2 * rX, -2 * rY, z),
                            Base.Vector(0, 0, 1)))
     # Division are performed at x axis
     dx = (x1 - x0) / (nS - 1.0)
     for i in range(0, nS):
         section = []
         x = x0 + i * dx
         xSection.append(x)
         percen = i * 100 / (nS - 1)
         FreeCAD.Console.PrintMessage('%d%%\n' % (percen))
         # Slice the surface to get curves
         wires = shape.slice(Vector(1.0, 0.0, 0.0), x)
         if not wires:
             if (i != 0) or (i != nS - 1):
                 msg = 'Found empty section at x=%g\n' % (x)
                 msg = Translator.translate(msg)
                 FreeCAD.Console.PrintWarning(msg)
                 FreeCAD.Console.PrintWarning(
                     '\tThis may happens if a bad defined (or really complex) surface has been provided.\n'
                 )
                 FreeCAD.Console.PrintWarning(
                     '\tPlease, ensure that this section is correct, or fix surfaces and create a new ship.\n'
                 )
                 nPoints.append(0)
                 continue
         # Desarrollate wires into edges list
         edges = []
         for j in range(0, len(wires)):
             wire = wires[j].Edges
             for k in range(0, len(wire)):
                 edges.append(wire[k])
         # Slice curves to get points
         points = []
         for k in range(0, nP):
             planePoints = []
             for j in range(0, len(edges)):
                 aux = self.lineFaceSection(edges[j], planes[k])
                 for l in range(0, len(aux)):
                     planePoints.append(Vector(aux[l].X, aux[l].Y,
                                               aux[l].Z))
             if not planePoints:  # No section found, symmetry plane point will used
                 planePoints.append(Vector(x, 0, z0 + k * dz))
             # Get Y coordinates
             auxY = []
             for l in range(0, len(planePoints)):
                 auxY.append(planePoints[l].y)
             # Sort them
             auxY.sort()
             # And store
             for l in range(0, len(planePoints)):
                 points.append(
                     Vector(planePoints[l].x, auxY[l], planePoints[l].z))
         # Store points
         section = points[:]
         nPoints.append(len(section))
         for j in range(0, len(section)):
             mSections.append(section[j])
     # Save data
     for i in range(1, len(nPoints)):
         nPoints[i] = nPoints[i] + nPoints[i - 1]
     self.obj.nPoints = nPoints[:]
     self.obj.xSection = xSection[:]
     self.obj.mSections = mSections[:]
     msg = '%d Discretization points performed\n' % (len(mSections))
     msg = Translator.translate(msg)
     FreeCAD.Console.PrintMessage(msg)
Пример #44
0
 def create_default_shape(cls):
     # Create default shape, a simple box
     cls.fcd_shape = Part.makeBox(cls.default_length, cls.default_width,
                                  cls.default_height)
Пример #45
0
def leg(d, dressup=True):
    s1 = d["leg_s1"]
    s2 = d["leg_s2"]
    s3 = d["leg_s3"]
    s4 = d["leg_s4"]
    s5 = d["leg_s5"]

    x0 = d["insertion_width_1"]
    x1 = 105
    x2 = d["cx"] - d["insertion_width_3"] / 2.0
    x3 = x2 + d["insertion_width_2"]
    x4 = d["cx"] + d["insertion_width_3"] / 2.0
    x5 = x2 - 20
    x6 = 100
    x7 = x6 - 50

    y0 = d["height"] - d["upper_tabletop_t"] + d["insertion_length"]
    y1 = d["height"] - d["upper_tabletop_t"] - 5
    y2 = y0 - 10
    y3 = d["height_1"] + 100
    y4 = d["height_1"] - d["insertion_length"]
    y5 = y4 + 15

    print("Leg length: ", y0)
    print("Leg width: ", x3)

    p = [None] * 21

    p[0] = Base.Vector(0, y0, 0)
    p[1] = Base.Vector(x0, y0, 0)
    p[2] = Base.Vector(x0, y1, 0)

    p[4] = Base.Vector(x1, y3, 0)

    p[6] = Base.Vector(x2, y1, 0)
    p[7] = Base.Vector(x2, y0, 0)
    p[8] = Base.Vector(x3, y0, 0)
    p[9] = Base.Vector(x3, y1, 0)

    p[11] = Base.Vector(x4, y5, 0)
    p[12] = Base.Vector(x4, y4, 0)
    p[13] = Base.Vector(x2, y4, 0)
    p[14] = Base.Vector(x2, y5, 0)
    p[15] = Base.Vector(x5, y5, 0)

    p[17] = Base.Vector(x6, 0, 0)
    p[18] = Base.Vector(x7, 0, 0)

    p[20] = Base.Vector(0, y2, 0)

    p[3] = dc.model.sagpoint(p[2], p[4], s1)
    p[5] = dc.model.sagpoint(p[4], p[6], s2)
    p[10] = dc.model.sagpoint(p[9], p[11], s3)
    p[16] = dc.model.sagpoint(p[15], p[17], s4)
    p[19] = dc.model.sagpoint(p[18], p[20], s5)

    wire = [
        Part.makeLine(p[0], p[1]),
        Part.makeLine(p[1], p[2]),
        dc.model.makeArc(p[2:5]),
        dc.model.makeArc(p[4:7]),
        Part.makeLine(p[6], p[7]),
        Part.makeLine(p[7], p[8]),
        Part.makeLine(p[8], p[9]),
        dc.model.makeArc(p[9:12]),
        Part.makeLine(p[11], p[12]),
        Part.makeLine(p[12], p[13]),
        Part.makeLine(p[13], p[14]),
        Part.makeLine(p[14], p[15]),
        dc.model.makeArc(p[15:18]),
        Part.makeLine(p[17], p[18]),
        dc.model.makeArc(p[18:]),
        Part.makeLine(p[20], p[0])
    ]

    face = Part.Face(Part.Wire(wire))
    m = face.extrude(Base.Vector(0, 0, d["leg_t"]))

    m = dc.model.fillet_edge_xy(m, 7, p[2])
    m = dc.model.fillet_edge_xy(m, 12, p[4])
    m = dc.model.fillet_edge_xy(m, 7, p[6])
    m = dc.model.fillet_edge_xy(m, 7, p[9])
    m = dc.model.fillet_edge_xy(m, 7, p[14])
    m = dc.model.fillet_edge_xy(m, 12, p[15])
    m = dc.model.fillet_edge_xy(m, 30, p[20])
    m.rotate(Base.Vector(0, 0, 0), Base.Vector(1, 0, 0), 90)
    m.translate(Base.Vector(0, d["leg_t"] / 2.0, 0))

    hole = Part.makeCylinder(
        d["hole_dia_leg"] / 2.0, d["height"],
        Base.Vector(d["cx"], 0, d["height_1"] - d["insertion_length"]),
        Base.Vector(0, 0, 1), 360)
    m = m.cut(hole)

    if dressup:
        m = dc.model.fillet_edges_longer_than(m, d["leg_edge_radii"], 95)

    return m
Пример #46
0
 def execute(self, fp):
     """ Called when a recomputation is needed. 
     @param fp Part::FeaturePython object.
     """
     fp.Shape = Part.makeCompound(fp.Shape.Solids)
Пример #47
0
def Plot(scale, sections, shape):
    """ Creates the outline draw.
    @param scale Plane scale (format 1:scale)
    @param sections Sections computed.
    @param shape Ship surfaces shell
    @return plotted object (DocumentObject)
    """
    msg = Translator.translate('Performing plot (Scale 1:%d)...\n' % (scale))
    FreeCAD.Console.PrintMessage(msg)
    scale = 1000.0 / scale
    # Take positions
    bounds = [0.0, 0.0, 0.0]
    bbox = shape.BoundBox
    bounds[0] = bbox.XLength
    bounds[1] = bbox.YLength
    bounds[2] = bbox.ZLength
    xTot = scale * bounds[1] + 32.0 + scale * bounds[0]
    yTot = scale * bounds[2] + 32.0 + scale * bounds[1]
    xMid = 210.0
    yMid = 185.0
    x0 = xMid - 0.5 * xTot
    y0 = 297.0 - yMid - 0.5 * yTot  # 297 = A3_width
    # Get border
    edges = Geometry.getEdges([shape])
    border = edges[0]
    for i in range(0, len(edges)):
        border = border.oldFuse(
            edges[i]
        )  # Only group objects, don't try to build more complex entities
        border = border.oldFuse(edges[i].mirror(Vector(0.0, 0.0, 0.0),
                                                Vector(0.0, 1.0, 0.0)))
    # Fuse sections & borders
    # obj = sections.oldFuse(border)
    obj = border.oldFuse(sections)
    # Send to 3D view
    Part.show(obj)
    objs = FreeCAD.ActiveDocument.Objects
    obj = objs[len(objs) - 1]
    # Create a new plane
    FreeCAD.ActiveDocument.addObject('Drawing::FeaturePage', 'OutlineDrawPlot')
    FreeCAD.ActiveDocument.OutlineDrawPlot.Template = FreeCAD.getResourceDir(
    ) + 'Mod/Drawing/Templates/A3_Landscape.svg'
    # Side view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
                                     'OutlineDrawSideView')
    FreeCAD.ActiveDocument.OutlineDrawSideView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawSideView.Direction = (1.0, 0.0, 0.0)
    FreeCAD.ActiveDocument.OutlineDrawSideView.Rotation = -90.0
    FreeCAD.ActiveDocument.OutlineDrawSideView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawSideView.X = 420.0 - x0 - 0.5 * scale * bounds[
        1]  # 420 = A3_height
    FreeCAD.ActiveDocument.OutlineDrawSideView.Y = y0 + 0.5 * scale * bounds[2]
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
        FreeCAD.ActiveDocument.OutlineDrawSideView)
    # Front view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
                                     'OutlineDrawFrontView')
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Direction = (0.0, 1.0, 0.0)
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Rotation = -90.0
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawFrontView.X = 420.0 - x0 - scale * bounds[
        1] - 32 - 0.5 * scale * bounds[0]
    FreeCAD.ActiveDocument.OutlineDrawFrontView.Y = y0 + 0.5 * scale * bounds[2]
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
        FreeCAD.ActiveDocument.OutlineDrawFrontView)
    # Up view
    FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
                                     'OutlineDrawUpView')
    FreeCAD.ActiveDocument.OutlineDrawUpView.Source = obj
    FreeCAD.ActiveDocument.OutlineDrawUpView.Direction = (0.0, 0.0, 1.0)
    FreeCAD.ActiveDocument.OutlineDrawUpView.Scale = scale
    FreeCAD.ActiveDocument.OutlineDrawUpView.X = 420.0 - x0 - scale * bounds[
        1] - 32 - 0.5 * scale * bounds[0]
    FreeCAD.ActiveDocument.OutlineDrawUpView.Y = y0 + scale * bounds[2] + 32
    FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
        FreeCAD.ActiveDocument.OutlineDrawUpView)
    FreeCAD.ActiveDocument.recompute()
    return obj
Пример #48
0
 def update(self, L, B, T, sectionsL, sectionsB, sectionsT, shape):
     """ Update the 3D view printing annotations.
     @param L Ship Lpp.
     @param B Ship beam.
     @param T Ship draft.
     @param sectionsL Transversal sections.
     @param sectionsB Longitudinal sections.
     @param sectionsT Water lines.
     @param shape Ship surfaces shell
     @return Sections object. None if errors happens.
     """
     FreeCAD.Console.PrintMessage(Translator.translate('Computing sections...\n'))
     # Destroy all previous entities
     self.clean()
     # Receive data
     nL = len(sectionsL)
     nB = len(sectionsB)
     nT = len(sectionsT)
     if not (nL or nB or nT):
         return None
     # Found sections
     sections = []
     for i in range(0,nL):
         pos = sectionsL[i]
         # Cut ship
         section = shape.slice(Vector(1.0,0.0,0.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             # We have 3 cases, 
             # * when section is before midship, then only starboard section will be considered
             # * When section is midship, then all section must be preserved
             # * When section is after midship, then only board will be considered
             if pos > 0.01:
                 # Look for edges at the wrong side and delete it
                 for k in range(len(edges)-1,-1,-1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMin < -0.001:
                         del edges[k]
             elif pos < -0.01:
                 # Look for edges at the wrong side and delete it
                 for k in range(len(edges)-1,-1,-1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMax > 0.001:
                         del edges[k]
             sections.extend(edges)
     for i in range(0,nB):
         pos = sectionsB[i]
         section = shape.slice(Vector(0.0,1.0,0.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             # Longitudinal sections will preserve board and starboard ever. Since we take from one side,
             # we nned to mirror it.
             section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
             edges2 = section[j].Edges
             sections.extend(edges)
             sections.extend(edges2)
     for i in range(0,nT):
         pos = sectionsT[i]
         section = shape.slice(Vector(0.0,0.0,1.0), pos)
         for j in range(0,len(section)):
             edges = section[j].Edges
             # We have 3 cases, 
             # * when section is below draft, then only board section will be considered
             # * When section is draft, then all section must be preserved
             # * When section is above draft, then only starboard will be considered
             if pos > T + 0.01:
                 # Look for edges at the wrong side and delete it
                 for k in range(len(edges)-1,-1,-1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMax > 0.001:
                         del edges[k]
             elif pos < T - 0.01:
                 # Look for edges at the wrong side and delete it
                 for k in range(len(edges)-1,-1,-1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMin < -0.001:
                         del edges[k]
             sections.extend(edges)
     # Convert all BSplines into a shape
     if not sections:
         msg = Translator.translate('Any valid ship section found')
         FreeCAD.Console.PrintWarning(msg)
         return
     obj = sections[0]
     for i in range(1,len(sections)):
         obj = obj.oldFuse(sections[i])  # Only group the edges, don't try to build more complex entities
     # Create the representable object
     Part.show(obj)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs)-1]
     self.obj.Label = 'OutlineDraw'
     return self.obj