示例#1
0
    def getRebarData(self,obj):

        if len(obj.InList) != 1:
            return
        if Draft.getType(obj.InList[0]) != "Structure":
            return
        if not obj.InList[0].Shape:
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.InList[0]
        wire = obj.Base.Shape.Wires[0]
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1))
        size = (ArchCommands.projectToVector(father.Shape.copy(),axis)).Length
        if hasattr(obj,"Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)
                axis.normalize()
        if hasattr(obj,"Distance"):
            if obj.Distance.Value:
                size = obj.Distance.Value
        if hasattr(obj,"Rounding"):
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire,radius)
        wires = []
        if obj.Amount == 1:
            offset = DraftVecUtils.scaleTo(axis,size/2)
            wire.translate(offset)
            wires.append(wire)
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis,obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            vinterval = DraftVecUtils.scaleTo(axis,interval)
            for i in range(obj.Amount):
                if i == 0:
                    if baseoffset:
                        wire.translate(baseoffset)
                    wires.append(wire)
                else:
                    wire = wire.copy()
                    wire.translate(vinterval)
                    wires.append(wire)
        return [wires,obj.Diameter.Value/2]
示例#2
0
    def getRebarData(self, obj):

        if len(obj.InList) != 1:
            return
        if Draft.getType(obj.InList[0]) != "Structure":
            return
        if not obj.InList[0].Shape:
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.InList[0]
        wire = obj.Base.Shape.Wires[0]
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1))
        size = (ArchCommands.projectToVector(father.Shape.copy(), axis)).Length
        if hasattr(obj, "Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)
                axis.normalize()
        if hasattr(obj, "Distance"):
            if obj.Distance.Value:
                size = obj.Distance.Value
        if hasattr(obj, "Rounding"):
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire, radius)
        wires = []
        if obj.Amount == 1:
            offset = DraftVecUtils.scaleTo(axis, size / 2)
            wire.translate(offset)
            wires.append(wire)
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            vinterval = DraftVecUtils.scaleTo(axis, interval)
            for i in range(obj.Amount):
                if i == 0:
                    if baseoffset:
                        wire.translate(baseoffset)
                    wires.append(wire)
                else:
                    wire = wire.copy()
                    wire.translate(vinterval)
                    wires.append(wire)
        return [wires, obj.Diameter.Value / 2]
示例#3
0
    def execute(self, obj):
        self.Width = float(obj.Width)
        self.Height = float(obj.Height)
        self.Length = float(obj.Length)
        self.Radius = float(obj.Radius)
        self.Thickness = float(obj.Thickness)
        self.Chamfer = obj.Chamfer
        Result = None
        # base rectangle vertices and walls after a cut
        V1_FSQ = [
            App.Vector(0, 0, 0),
            App.Vector(self.Width, 0, 0),
            App.Vector(self.Width, self.Length, 0),
            App.Vector(0.0, self.Length, 0),
            App.Vector(0, 0, 0)
        ]

        # cut middle part to make walls
        V2_FSQ = [
            App.Vector(self.Thickness, self.Thickness, 0),
            App.Vector(self.Width - self.Thickness, self.Thickness, 0),
            App.Vector(self.Width - self.Thickness,
                       self.Length - self.Thickness, 0),
            App.Vector(self.Thickness, self.Length - self.Thickness, 0),
            App.Vector(self.Thickness, self.Thickness, 0)
        ]

        W1 = Part.makePolygon(V1_FSQ)
        W11 = DraftGeomUtils.filletWire(W1, self.Radius, chamfer=self.Chamfer)

        firstFace1 = Part.Face(W11)  # one used with secondFace to cut
        firstFace2 = firstFace1.copy()  # Other used to make the bottom

        W2 = Part.makePolygon(V2_FSQ)
        W22 = DraftGeomUtils.filletWire(W2, self.Radius, chamfer=self.Chamfer)

        secondFace = Part.Face(W22)

        resultButtom = firstFace1.cut(secondFace)
        extrude1 = resultButtom.extrude(App.Vector(0, 0, self.Height))
        extrude2 = firstFace2.extrude(App.Vector(0, 0, self.Thickness))
        fused = extrude1.fuse(extrude2)
        Result = fused.removeSplitter()
        obj.Shape = Result
示例#4
0
 def execute(self, obj):
     if (obj.FacesNumber >= 3) and (obj.Radius.Value > 0):
         import Part
         plm = obj.Placement
         angle = (math.pi * 2) / obj.FacesNumber
         if obj.DrawMode == 'inscribed':
             delta = obj.Radius.Value
         else:
             delta = obj.Radius.Value / math.cos(angle / 2.0)
         pts = [App.Vector(delta, 0, 0)]
         for i in range(obj.FacesNumber - 1):
             ang = (i + 1) * angle
             pts.append(
                 App.Vector(delta * math.cos(ang), delta * math.sin(ang),
                            0))
         pts.append(pts[0])
         shape = Part.makePolygon(pts)
         if "ChamferSize" in obj.PropertiesList:
             if obj.ChamferSize.Value != 0:
                 w = DraftGeomUtils.filletWire(shape,
                                               obj.ChamferSize.Value,
                                               chamfer=True)
                 if w:
                     shape = w
         if "FilletRadius" in obj.PropertiesList:
             if obj.FilletRadius.Value != 0:
                 w = DraftGeomUtils.filletWire(shape,
                                               obj.FilletRadius.Value)
                 if w:
                     shape = w
         if hasattr(obj, "MakeFace"):
             if obj.MakeFace:
                 shape = Part.Face(shape)
         else:
             shape = Part.Face(shape)
         obj.Shape = shape
         if hasattr(obj, "Area") and hasattr(shape, "Area"):
             obj.Area = shape.Area
         obj.Placement = plm
     obj.positionBySupport()
def smBase(thk=2.0, length=10.0, radius=1.0, Side="Inside", MainObject=None):
    WireList = MainObject.Shape.Wires[0]
    #print(sketch_normal)
    if WireList.isClosed():
        sketch_face = Part.makeFace(MainObject.Shape.Wires,
                                    "Part::FaceMakerBullseye")
        wallSolid = sketch_face.extrude(sketch_face.normalAt(0, 0) * thk)
    else:
        if len(WireList.Edges) > 1:
            if Side == "Inside":
                wire = WireList.makeOffset2D(thk / 2.0,
                                             openResult=True,
                                             join=2)
            elif Side == "Outside":
                wire = WireList.makeOffset2D(-thk / 2.0,
                                             openResult=True,
                                             join=2)
            else:
                wire = WireList
            #Part.show(wire)
            filletedWire = DraftGeomUtils.filletWire(wire, (radius + thk / 2))
            #Part.show(filletedWire)
            offsetwire = filletedWire.makeOffset2D(thk / 2.0, openResult=True)
            #Part.show(offsetwire)
            sketch_face = offsetwire.makeOffset2D(thk,
                                                  openResult=True,
                                                  fill=True)
            #Part.show(sketch_face)
            Edge_Dir = sketch_face.normalAt(0, 0)
            offsetSolid = offsetwire.extrude(Edge_Dir * length)
            CutList = []
            for x in offsetSolid.Faces:
                if issubclass(type(x.Surface), Part.Plane):
                    offsetSolid = x.extrude(x.normalAt(0, 0) * -thk)
                    CutList.append(offsetSolid)
                    #Part.show(offsetSolid)
            wallSolid = sketch_face.extrude(Edge_Dir * length)
            offsetSolids = CutList[0].multiFuse(CutList[1:])
            wallSolid = wallSolid.fuse(offsetSolids)
        else:
            if MainObject.TypeId == 'Sketcher::SketchObject':
                mat = MainObject.getGlobalPlacement()
                normal = mat.multVec(FreeCAD.Vector(0, 0, 1))
                sketch_face = MainObject.Shape.Wires[0].extrude(normal *
                                                                -length)
                #Part.show(sketch_face)
                wallSolid = sketch_face.extrude(
                    sketch_face.Faces[0].normalAt(0, 0) * -thk)

    Gui.ActiveDocument.getObject(MainObject.Name).Visibility = False
    return wallSolid
示例#6
0
    def execute(self, obj):
        self.Height = float(obj.Height)
        self.Radius = float(obj.Radius)
        self.SideOneRadius = float(obj.SideOneRadius)
        self.Thickness = float(obj.Thickness)
        self.Chamfer = obj.Chamfer

        Result = None
        # base None-uniformed vertices and walls after a cut

        V1_FSQ = []
        V1_FSQ = self.Vertices
        W1 = Part.makePolygon(V1_FSQ)

        if self.Radius > 0:
            W11 = DraftGeomUtils.filletWire(W1,
                                            self.Radius,
                                            chamfer=self.Chamfer)
        else:
            W11 = W1

        firstFace1 = Part.Face(W11)  # One used with secondFace to cut

        if self.SideOneRadius > 0:
            W12 = DraftGeomUtils.filletWire(W1,
                                            self.SideOneRadius,
                                            chamfer=self.Chamfer)
        else:
            W12 = W1  # Other used to make the bottom

        firstFace2 = Part.Face(W12)
        secondFace = firstFace2.makeOffset2D(-self.Thickness)
        resultButtom = firstFace1.cut(secondFace)
        extrude1 = resultButtom.extrude(App.Vector(0, 0, self.Height))
        extrude2 = firstFace2.extrude(App.Vector(0, 0, self.Thickness))
        fused = extrude1.fuse(extrude2)
        Result = fused.removeSplitter()
        obj.Shape = Result
示例#7
0
    def execute(self, obj):

        if self.clone(obj):
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.Host
        fathershape = None
        if not father:
            # support for old-style rebars
            if obj.InList:
                if hasattr(obj.InList[0], "Armatures"):
                    if obj in obj.InList[0].Armatures:
                        father = obj.InList[0]
        if father:
            if father.isDerivedFrom("Part::Feature"):
                fathershape = father.Shape

        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj, "Rounding"):
            #print(obj.Rounding)
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire, radius)
        bpoint, bvec = self.getBaseAndAxis(wire)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1))
        if fathershape:
            size = (ArchCommands.projectToVector(fathershape.copy(),
                                                 axis)).Length
        else:
            size = 1
        if hasattr(obj, "Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)
                axis.normalize()
                if fathershape:
                    size = (ArchCommands.projectToVector(
                        fathershape.copy(), axis)).Length
                else:
                    size = 1
        if hasattr(obj, "Distance"):
            if obj.Distance.Value:
                size = obj.Distance.Value
        #print(axis)
        #print(size)
        spacinglist = None
        if hasattr(obj, "CustomSpacing"):
            if obj.CustomSpacing:
                spacinglist = strprocessOfCustomSpacing(obj.CustomSpacing)
                influenceArea = sum(
                    spacinglist) - spacinglist[0] / 2 - spacinglist[-1] / 2
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return
        # all tests ok!
        if hasattr(obj, "Length"):
            length = getLengthOfRebar(obj)
            if length:
                obj.Length = length
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value / 2, bpoint, bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle], True, False, 2)
            basewire = wire.copy()
        except Part.OCCError:
            print("Arch: error sweeping rebar profile along the base sketch")
            return
        # building final shape
        shapes = []
        placementlist = []
        self.wires = []
        if father:
            rot = father.Placement.Rotation
        else:
            rot = FreeCAD.Rotation()
        if obj.Amount == 1:
            barplacement = CalculatePlacement(obj.Amount, 1, size, axis, rot,
                                              obj.OffsetStart.Value,
                                              obj.OffsetEnd.Value)
            placementlist.append(barplacement)
            if hasattr(obj, "Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            for i in range(obj.Amount):
                barplacement = CalculatePlacement(obj.Amount, i + 1, size,
                                                  axis, rot,
                                                  obj.OffsetStart.Value,
                                                  obj.OffsetEnd.Value)
                placementlist.append(barplacement)
            if hasattr(obj, "Spacing"):
                obj.Spacing = interval
        # Calculate placement of bars from custom spacing.
        if spacinglist:
            placementlist[:] = []
            reqInfluenceArea = size - (obj.OffsetStart.Value +
                                       obj.OffsetEnd.Value)
            # Avoid unnecessary checks to pass like. For eg.: when we have values
            # like influenceArea is 100.00001 and reqInflueneArea is 100
            if round(influenceArea) > round(reqInfluenceArea):
                return FreeCAD.Console.PrintError(
                    "Influence area of rebars is greater than " +
                    str(reqInfluenceArea) + ".\n")
            elif round(influenceArea) < round(reqInfluenceArea):
                FreeCAD.Console.PrintWarning(
                    "Last span is greater that end offset.\n")
            for i in range(len(spacinglist)):
                if i == 0:
                    barplacement = CustomSpacingPlacement(
                        spacinglist, 1, axis, father.Placement.Rotation,
                        obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
                else:
                    barplacement = CustomSpacingPlacement(
                        spacinglist, i + 1, axis, father.Placement.Rotation,
                        obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
            obj.Amount = len(spacinglist)
            obj.Spacing = 0
        obj.PlacementList = placementlist
        for i in range(len(obj.PlacementList)):
            if i == 0:
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
                basewire.Placement = obj.PlacementList[i]
                self.wires.append(basewire)
            else:
                bar = bar.copy()
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
                w = basewire.copy()
                w.Placement = obj.PlacementList[i]
                self.wires.append(w)
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
        obj.TotalLength = obj.Length * len(obj.PlacementList)
示例#8
0
    def execute(self,obj):
        if len(obj.InList) != 1:
            return
        if Draft.getType(obj.InList[0]) != "Structure":
            return
        if not obj.InList[0].Shape:
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.InList[0]
        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj,"Rounding"):
            #print obj.Rounding
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire,radius)
        bpoint, bvec = self.getBaseAndAxis(obj)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1))
        size = (ArchCommands.projectToVector(father.Shape.copy(),axis)).Length
        if hasattr(obj,"Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction) #.normalize()
                # don't normalize so the vector can also be used to determine the distance
                size = axis.Length
        #print axis
        #print size
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return

        # all tests ok!
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value/2,bpoint,bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle],True,False,2)
        except:
            print "Arch: error sweeping rebar profile along the base sketch"
            return
        # building final shape
        shapes = []
        if obj.Amount == 1:
            offset = DraftVecUtils.scaleTo(axis,size/2)
            bar.translate(offset)
            shapes.append(bar)
            if hasattr(obj,"Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis,obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            vinterval = DraftVecUtils.scaleTo(axis,interval)
            for i in range(obj.Amount):
                if i == 0:
                    if baseoffset:
                        bar.translate(baseoffset)
                    shapes.append(bar)
                else:
                    bar = bar.copy()
                    bar.translate(vinterval)
                    shapes.append(bar)
            if hasattr(obj,"Spacing"):
                obj.Spacing = interval
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
示例#9
0
def getUShapeRebarSVGData(
    rebar,
    view_plane,
    rebars_svg,
    rebars_stroke_width,
    rebars_color_style,
    longitudinal_line_dia=None,
):
    """getUShapeRebarSVGData(UShapeRebar, ViewPlane, RebarsSVG,
    RebarsStrokeWidth, RebarsColorStyle, longitudinal_line_dia):
    Returns dictionary containing UShape rebar svg data.

    rebars_color_style can be:
        - "shape color" to select color of rebar shape
        - color name or hex value of color

    Returns dictionary format:
    {
        "svg": u_rebar_svg,
        "visibility": is_rebar_visible,
    }
    """
    if longitudinal_line_dia is None:
        longitudinal_line_dia = 2 * 2 * rebars_stroke_width

    rebars_color = getRebarColor(rebar, rebars_color_style)

    u_rebar_svg = ElementTree.Element("g", attrib={"id": str(rebar.Name)})
    is_rebar_visible = False
    drawing_plane_normal = view_plane.axis
    if round(drawing_plane_normal.cross(getRebarsSpanAxis(rebar)).Length) == 0:
        basewire = rebar.Base.Shape.Wires[0].copy()
        basewire.Placement = rebar.PlacementList[0].multiply(
            basewire.Placement)
        edges = Part.__sortEdges__(
            DraftGeomUtils.filletWire(
                basewire,
                rebar.Rounding * rebar.Diameter.Value,
            ).Edges)
        for edge in edges:
            if DraftGeomUtils.geomType(edge) == "Line":
                p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                             view_plane)
                p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                             view_plane)
                if round(p1.x) == round(p2.x) and round(p1.y) == round(p2.y):
                    edge_svg = getPointSVG(p1,
                                           radius=longitudinal_line_dia / 2,
                                           fill=rebars_color)
                else:
                    edge_svg = getLineSVG(p1, p2, rebars_stroke_width,
                                          rebars_color)
                    if not isLineInSVG(p1, p2, rebars_svg):
                        is_rebar_visible = True
                if is_rebar_visible:
                    u_rebar_svg.append(edge_svg)
                    is_rebar_visible = True
            elif DraftGeomUtils.geomType(edge) == "Circle":
                p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                             view_plane)
                p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                             view_plane)
                if round(p1.x) == round(p2.x) or round(p1.y) == round(p2.y):
                    edge_svg = getLineSVG(p1, p2, rebars_stroke_width,
                                          rebars_color)
                    if not isLineInSVG(p1, p2, rebars_svg):
                        is_rebar_visible = True
                else:
                    edge_svg = getRoundEdgeSVG(edge, view_plane,
                                               rebars_stroke_width,
                                               rebars_color)
                    if not isRoundCornerInSVG(
                            edge,
                            rebar.Rounding * rebar.Diameter.Value,
                            view_plane,
                            rebars_svg,
                    ):
                        is_rebar_visible = True
                if is_rebar_visible:
                    u_rebar_svg.append(edge_svg)
    else:
        basewire = rebar.Base.Shape.Wires[0]
        for placement in rebar.PlacementList:
            wire = basewire.copy()
            wire.Placement = placement.multiply(basewire.Placement)

            edges = Part.__sortEdges__(
                DraftGeomUtils.filletWire(
                    wire,
                    rebar.Rounding * rebar.Diameter.Value,
                ).Edges)
            for edge in edges:
                if DraftGeomUtils.geomType(edge) == "Line":
                    p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                                 view_plane)
                    p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                                 view_plane)
                    if round(p1.x) == round(p2.x) and round(p1.y) == round(
                            p2.y):
                        edge_svg = getPointSVG(
                            p1,
                            radius=longitudinal_line_dia / 2,
                            fill=rebars_color,
                        )
                    else:
                        edge_svg = getLineSVG(p1, p2, rebars_stroke_width,
                                              rebars_color)
                        if not isLineInSVG(p1, p2, rebars_svg):
                            is_rebar_visible = True
                    if is_rebar_visible or not isLineInSVG(p1, p2, rebars_svg):
                        u_rebar_svg.append(edge_svg)
                        is_rebar_visible = True
                elif DraftGeomUtils.geomType(edge) == "Circle":
                    p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                                 view_plane)
                    p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                                 view_plane)
                    if round(p1.x) == round(p2.x) or round(p1.y) == round(
                            p2.y):
                        edge_svg = getLineSVG(p1, p2, rebars_stroke_width,
                                              rebars_color)
                        if not isLineInSVG(p1, p2, rebars_svg):
                            is_rebar_visible = True
                    else:
                        edge_svg = getRoundEdgeSVG(edge, view_plane,
                                                   rebars_stroke_width,
                                                   rebars_color)
                        if not isRoundCornerInSVG(
                                edge,
                                rebar.Rounding * rebar.Diameter.Value,
                                view_plane,
                                rebars_svg,
                        ):
                            is_rebar_visible = True
                    if is_rebar_visible:
                        u_rebar_svg.append(edge_svg)
    return {
        "svg": u_rebar_svg,
        "visibility": is_rebar_visible,
    }
示例#10
0
def getStirrupSVGData(rebar, view_plane, rebars_svg, rebars_stroke_width,
                      rebars_color_style):
    """getStirrupSVGData(StirrupRebar, ViewPlane, RebarsSVG, RebarsStrokeWidth,
    RebarsColorStyle):
    Returns dictionary containing stirrup svg data.

    rebars_color_style can be:
        - "shape color" to select color of rebar shape
        - color name or hex value of color

    Returns dictionary format:
    {
        "svg": stirrup_svg,
        "visibility": is_rebar_visible,
    }
    """
    rebars_color = getRebarColor(rebar, rebars_color_style)

    stirrup_svg = ElementTree.Element("g", attrib={"id": str(rebar.Name)})
    is_rebar_visible = False
    drawing_plane_normal = view_plane.axis
    stirrup_span_axis = getRebarsSpanAxis(rebar)
    if round(drawing_plane_normal.cross(stirrup_span_axis).Length) == 0:
        basewire = rebar.Base.Shape.Wires[0].copy()
        basewire.Placement = rebar.PlacementList[0].multiply(
            basewire.Placement)
        edges = Part.__sortEdges__(
            DraftGeomUtils.filletWire(
                basewire,
                rebar.Rounding * rebar.Diameter.Value,
            ).Edges)
        for edge in edges:
            if DraftGeomUtils.geomType(edge) == "Line":
                p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                             view_plane)
                p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                             view_plane)
                edge_svg = getLineSVG(p1, p2, rebars_stroke_width,
                                      rebars_color)
                if is_rebar_visible or not isLineInSVG(p1, p2, rebars_svg):
                    stirrup_svg.append(edge_svg)
                    is_rebar_visible = True
            elif DraftGeomUtils.geomType(edge) == "Circle":
                edge_svg = getRoundEdgeSVG(edge, view_plane,
                                           rebars_stroke_width, rebars_color)
                if is_rebar_visible or not isRoundCornerInSVG(
                        edge,
                        rebar.Rounding * rebar.Diameter.Value,
                        view_plane,
                        rebars_svg,
                ):
                    stirrup_svg.append(edge_svg)
                    is_rebar_visible = True

    else:
        if round(stirrup_span_axis.cross(view_plane.u).Length) == 0:
            stirrup_alignment = "V"
        else:
            stirrup_alignment = "H"
        basewire = DraftGeomUtils.filletWire(
            rebar.Base.Shape.Wires[0], rebar.Rounding * rebar.Diameter.Value)
        for placement in rebar.PlacementList:
            wire = basewire.copy()
            wire.Placement = placement.multiply(basewire.Placement)
            p1, p2 = getStirrupSVGPoints(wire, stirrup_alignment, view_plane)
            rebar_svg = getLineSVG(p1, p2, rebars_stroke_width, rebars_color)
            if not isLineInSVG(p1, p2, rebars_svg):
                is_rebar_visible = True
            if is_rebar_visible:
                stirrup_svg.append(rebar_svg)
    return {
        "svg": stirrup_svg,
        "visibility": is_rebar_visible,
    }
示例#11
0
文件: wire.py 项目: zikpuppy/FreeCAD
    def execute(self, obj):
        import Part
        plm = obj.Placement
        if obj.Base and (not obj.Tool):
            if obj.Base.isDerivedFrom("Sketcher::SketchObject"):
                shape = obj.Base.Shape.copy()
                if obj.Base.Shape.isClosed():
                    if hasattr(obj, "MakeFace"):
                        if obj.MakeFace:
                            shape = Part.Face(shape)
                    else:
                        shape = Part.Face(shape)
                obj.Shape = shape
        elif obj.Base and obj.Tool:
            if hasattr(obj.Base, 'Shape') and hasattr(obj.Tool, 'Shape'):
                if (not obj.Base.Shape.isNull()) and (
                        not obj.Tool.Shape.isNull()):
                    sh1 = obj.Base.Shape.copy()
                    sh2 = obj.Tool.Shape.copy()
                    shape = sh1.fuse(sh2)
                    if DraftGeomUtils.isCoplanar(shape.Faces):
                        shape = DraftGeomUtils.concatenate(shape)
                        obj.Shape = shape
                        p = []
                        for v in shape.Vertexes:
                            p.append(v.Point)
                        if obj.Points != p: obj.Points = p
        elif obj.Points:
            if obj.Points[0] == obj.Points[-1]:
                if not obj.Closed: obj.Closed = True
                obj.Points.pop()
            if obj.Closed and (len(obj.Points) > 2):
                pts = obj.Points
                if hasattr(obj, "Subdivisions"):
                    if obj.Subdivisions > 0:
                        npts = []
                        for i in range(len(pts)):
                            p1 = pts[i]
                            npts.append(pts[i])
                            if i == len(pts) - 1:
                                p2 = pts[0]
                            else:
                                p2 = pts[i + 1]
                            v = p2.sub(p1)
                            v = DraftVecUtils.scaleTo(
                                v, v.Length / (obj.Subdivisions + 1))
                            for j in range(obj.Subdivisions):
                                npts.append(
                                    p1.add(App.Vector(v).multiply(j + 1)))
                        pts = npts
                shape = Part.makePolygon(pts + [pts[0]])
                if "ChamferSize" in obj.PropertiesList:
                    if obj.ChamferSize.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.ChamferSize.Value,
                                                      chamfer=True)
                        if w:
                            shape = w
                if "FilletRadius" in obj.PropertiesList:
                    if obj.FilletRadius.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.FilletRadius.Value)
                        if w:
                            shape = w
                try:
                    if hasattr(obj, "MakeFace"):
                        if obj.MakeFace:
                            shape = Part.Face(shape)
                    else:
                        shape = Part.Face(shape)
                except Part.OCCError:
                    pass
            else:
                edges = []
                pts = obj.Points[1:]
                lp = obj.Points[0]
                for p in pts:
                    if not DraftVecUtils.equals(lp, p):
                        if hasattr(obj, "Subdivisions"):
                            if obj.Subdivisions > 0:
                                npts = []
                                v = p.sub(lp)
                                v = DraftVecUtils.scaleTo(
                                    v, v.Length / (obj.Subdivisions + 1))
                                edges.append(
                                    Part.LineSegment(lp, lp.add(v)).toShape())
                                lv = lp.add(v)
                                for j in range(obj.Subdivisions):
                                    edges.append(
                                        Part.LineSegment(lv,
                                                         lv.add(v)).toShape())
                                    lv = lv.add(v)
                            else:
                                edges.append(Part.LineSegment(lp, p).toShape())
                        else:
                            edges.append(Part.LineSegment(lp, p).toShape())
                        lp = p
                try:
                    shape = Part.Wire(edges)
                except Part.OCCError:
                    print("Error wiring edges")
                    shape = None
                if "ChamferSize" in obj.PropertiesList:
                    if obj.ChamferSize.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.ChamferSize.Value,
                                                      chamfer=True)
                        if w:
                            shape = w
                if "FilletRadius" in obj.PropertiesList:
                    if obj.FilletRadius.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.FilletRadius.Value)
                        if w:
                            shape = w
            if shape:
                obj.Shape = shape
                if hasattr(obj, "Area") and hasattr(shape, "Area"):
                    obj.Area = shape.Area
                if hasattr(obj, "Length"):
                    obj.Length = shape.Length

        obj.Placement = plm
        obj.positionBySupport()
        self.onChanged(obj, "Placement")
示例#12
0
    def execute(self, obj):
        """This method is run when the object is created or recomputed."""
        import Part

        if (obj.Length.Value == 0) or (obj.Height.Value == 0):
            obj.positionBySupport()
            return

        plm = obj.Placement

        shape = None

        if hasattr(obj, "Rows") and hasattr(obj, "Columns"):
            # TODO: verify if this is needed:
            if obj.Rows > 1:
                rows = obj.Rows
            else:
                rows = 1
            if obj.Columns > 1:
                columns = obj.Columns
            else:
                columns = 1
            # TODO: till here

            if (rows > 1) or (columns > 1):
                shapes = []
                l = obj.Length.Value / columns
                h = obj.Height.Value / rows
                for i in range(columns):
                    for j in range(rows):
                        p1 = App.Vector(i * l, j * h, 0)
                        p2 = App.Vector(p1.x + l, p1.y, p1.z)
                        p3 = App.Vector(p1.x + l, p1.y + h, p1.z)
                        p4 = App.Vector(p1.x, p1.y + h, p1.z)
                        p = Part.makePolygon([p1, p2, p3, p4, p1])
                        if "ChamferSize" in obj.PropertiesList:
                            if obj.ChamferSize.Value != 0:
                                w = DraftGeomUtils.filletWire(
                                    p, obj.ChamferSize.Value, chamfer=True)
                                if w:
                                    p = w
                        if "FilletRadius" in obj.PropertiesList:
                            if obj.FilletRadius.Value != 0:
                                w = DraftGeomUtils.filletWire(
                                    p, obj.FilletRadius.Value)
                                if w:
                                    p = w
                        if hasattr(obj, "MakeFace"):
                            if obj.MakeFace:
                                p = Part.Face(p)
                        shapes.append(p)
                if shapes:
                    shape = Part.makeCompound(shapes)

        if not shape:
            p1 = App.Vector(0, 0, 0)
            p2 = App.Vector(p1.x + obj.Length.Value, p1.y, p1.z)
            p3 = App.Vector(p1.x + obj.Length.Value, p1.y + obj.Height.Value,
                            p1.z)
            p4 = App.Vector(p1.x, p1.y + obj.Height.Value, p1.z)
            shape = Part.makePolygon([p1, p2, p3, p4, p1])
            if "ChamferSize" in obj.PropertiesList:
                if obj.ChamferSize.Value != 0:
                    w = DraftGeomUtils.filletWire(shape,
                                                  obj.ChamferSize.Value,
                                                  chamfer=True)
                    if w:
                        shape = w
            if "FilletRadius" in obj.PropertiesList:
                if obj.FilletRadius.Value != 0:
                    w = DraftGeomUtils.filletWire(shape,
                                                  obj.FilletRadius.Value)
                    if w:
                        shape = w
            if hasattr(obj, "MakeFace"):
                if obj.MakeFace:
                    shape = Part.Face(shape)
            else:
                shape = Part.Face(shape)

        obj.Shape = shape

        if hasattr(obj, "Area") and hasattr(shape, "Area"):
            obj.Area = shape.Area

        obj.Placement = plm

        obj.positionBySupport()
示例#13
0
    def execute(self, obj):

        if self.clone(obj):
            return

        if len(obj.InList) != 1:
            return
        if Draft.getType(obj.InList[0]) != "Structure":
            return
        if not obj.InList[0].Shape:
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.InList[0]
        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj, "Rounding"):
            #print obj.Rounding
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire, radius)
        bpoint, bvec = self.getBaseAndAxis(wire)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0, 0, -1))
        size = (ArchCommands.projectToVector(father.Shape.copy(), axis)).Length
        if hasattr(obj, "Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)  #.normalize()
                # don't normalize so the vector can also be used to determine the distance
                size = axis.Length
        #print axis
        #print size
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return

        # all tests ok!
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value / 2, bpoint, bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle], True, False, 2)
        except Part.OCCError:
            print "Arch: error sweeping rebar profile along the base sketch"
            return
        # building final shape
        shapes = []
        if obj.Amount == 1:
            offset = DraftVecUtils.scaleTo(axis, size / 2)
            bar.translate(offset)
            shapes.append(bar)
            if hasattr(obj, "Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis, obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            vinterval = DraftVecUtils.scaleTo(axis, interval)
            for i in range(obj.Amount):
                if i == 0:
                    if baseoffset:
                        bar.translate(baseoffset)
                    shapes.append(bar)
                else:
                    bar = bar.copy()
                    bar.translate(vinterval)
                    shapes.append(bar)
            if hasattr(obj, "Spacing"):
                obj.Spacing = interval
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
def getRebarShapeSVG(
    rebar,
    view_direction: Union[FreeCAD.Vector,
                          WorkingPlane.Plane] = FreeCAD.Vector(0, 0, 0),
    include_mark: bool = True,
    stirrup_extended_edge_offset: float = 2,
    rebar_stroke_width: float = 0.35,
    rebar_color_style: str = "shape color",
    include_dimensions: bool = True,
    rebar_dimension_units: str = "mm",
    rebar_length_dimension_precision: int = 0,
    include_units_in_dimension_label: bool = False,
    bent_angle_dimension_exclude_list: Union[Tuple[float, ...],
                                             List[float]] = (
                                                 45,
                                                 90,
                                                 180,
                                             ),
    dimension_font_family: str = "DejaVu Sans",
    dimension_font_size: float = 2,
    helical_rebar_dimension_label_format: str = "%L,r=%R,pitch=%P",
    scale: float = 1,
    max_height: float = 0,
    max_width: float = 0,
    side_padding: float = 1,
    horizontal_shape: bool = False,
) -> ElementTree.Element:
    """Generate and return rebar shape svg.

    Parameters
    ----------
    rebar: <ArchRebar._Rebar> or <rebar2.BaseRebar>
        Rebar to generate its shape svg.
    view_direction: FreeCAD.Vector or WorkingPlane.Plane, optional
        The view point direction for rebar shape.
        Default is FreeCAD.Vector(0, 0, 0) to automatically choose
        view_direction.
    include_mark: bool, optional
        If True, then rebar.Mark will be included in rebar shape svg.
        Default is True.
    stirrup_extended_edge_offset: float, optional
        The offset of extended end edges of stirrup, so that end edges of
        stirrup with 90 degree bent angle do not overlap with stirrup edges.
        Default is 2.
    rebar_stroke_width: float, optional
        The stroke-width of rebar in svg.
        Default is 0.35
    rebar_color_style: {"shape color", "color_name", "hex_value_of_color"}
        The color style of rebar.
        "shape color" means select color of rebar shape.
    include_dimensions: bool, optional
        If True, then each rebar edge dimensions and bent angle dimensions will
        be included in rebar shape svg.
    rebar_dimension_units: str, optional
        The units to be used for rebar length dimensions.
        Default is "mm".
    rebar_length_dimension_precision: int, optional
        The number of decimals that should be shown for rebar length as
        dimension label. Set it to None to use user preferred unit precision
        from FreeCAD unit preferences.
        Default is 0
    include_units_in_dimension_label: bool, optional
        If it is True, then rebar length units will be shown in dimension label.
        Default is False.
    bent_angle_dimension_exclude_list: list or tuple of float, optional
        The list of bent angles to not include their dimensions.
        Default is (45, 90, 180).
    dimension_font_family: str, optional
        The font-family of dimension text.
        Default is "DejaVu Sans".
    dimension_font_size: float, optional
        The font-size of dimension text.
        Default is 2
    helical_rebar_dimension_label_format: str, optional
        The format of helical rebar dimension label.
            %L -> Length of helical rebar
            %R -> Helix radius of helical rebar
            %P -> Helix pitch of helical rebar
        Default is "%L,r=%R,pitch=%P".
    scale: float, optional
        The scale value to scale rebar svg. The scale parameter helps to
        scale down rebar_stroke_width and dimension_font_size to make them
        resolution independent.
        If max_height or max_width is set to non-zero value, then scale
        parameter will be ignored.
        Default is 1
    max_height: float, optional
        The maximum height of rebar shape svg.
        Default is 0 to set rebar shape svg height based on scale parameter.
    max_width: float, optional
        The maximum width of rebar shape svg.
        Default is 0 to set rebar shape svg width based on scale parameter.
    side_padding: float, optional
        The padding on each side of rebar shape.
        Default is 1.
    horizontal_shape: bool, optional
        If True, then rebar shape will be made horizontal by rotating max
        length edge of rebar shape.
        Default is False.

    Returns
    -------
    ElementTree.Element
        The generated rebar shape svg.
    """
    if isinstance(view_direction, FreeCAD.Vector):
        if DraftVecUtils.isNull(view_direction):
            if (hasattr(rebar, "RebarShape")
                    and rebar.RebarShape == "HelicalRebar"):
                view_direction = rebar.Base.Placement.Rotation.multVec(
                    FreeCAD.Vector(0, -1, 0))
                if hasattr(rebar, "Direction") and not DraftVecUtils.isNull(
                        rebar.Direction):
                    view_direction = FreeCAD.Vector(rebar.Direction)
                    view_direction.normalize()
            else:
                view_direction = getRebarsSpanAxis(rebar)
        view_plane = getSVGPlaneFromAxis(view_direction)
    elif isinstance(view_direction, WorkingPlane.Plane):
        view_plane = view_direction
    else:
        FreeCAD.Console.PrintError(
            "Invalid view_direction type. Supported view_direction types: "
            "FreeCAD.Vector, WorkingPlane.Plane\n")
        return ElementTree.Element("g")

    if rebar_length_dimension_precision is None:
        # Get user preferred unit precision
        precision: int = FreeCAD.ParamGet(
            "User parameter:BaseApp/Preferences/Units").GetInt("Decimals")
    else:
        precision = abs(int(rebar_length_dimension_precision))

    rebar_color = getRebarColor(rebar, rebar_color_style)

    # Create required svg elements
    svg = getSVGRootElement()
    rebar_shape_svg = ElementTree.Element("g", attrib={"id": str(rebar.Name)})
    svg.append(rebar_shape_svg)
    rebar_edges_svg = ElementTree.Element("g")
    edge_dimension_svg = ElementTree.Element("g")
    rebar_shape_svg.extend([rebar_edges_svg, edge_dimension_svg])

    # Get basewire and fillet_basewire (basewire with round edges)
    basewire = rebar.Base.Shape.Wires[0].copy()
    fillet_radius = rebar.Rounding * rebar.Diameter.Value
    if fillet_radius:
        fillet_basewire = DraftGeomUtils.filletWire(basewire, fillet_radius)
    else:
        fillet_basewire = basewire

    (
        rebar_shape_min_x,
        rebar_shape_min_y,
        rebar_shape_max_x,
        rebar_shape_max_y,
    ) = getVertexesMinMaxXY(fillet_basewire.Vertexes, view_plane)

    # If rebar shape should be horizontal and its width is less than its
    # height, then we should rotate basewire to make rebar shape horizontal
    rebar_shape_rotation_angle = 0
    if horizontal_shape:
        line_type_edges = [
            edge for edge in basewire.Edges
            if DraftGeomUtils.geomType(edge) == "Line"
        ]
        if line_type_edges:
            max_length_edge = max(line_type_edges, key=lambda x: x.Length)
            rebar_shape_rotation_angle = math.degrees(
                DraftVecUtils.angle(
                    max_length_edge.lastVertex().Point.sub(
                        max_length_edge.firstVertex().Point),
                    view_plane.u,
                    view_plane.axis,
                ))
        elif (rebar_shape_max_x - rebar_shape_min_x) < (rebar_shape_max_y -
                                                        rebar_shape_min_y):
            rebar_shape_rotation_angle = -90
        basewire.rotate(basewire.CenterOfMass, view_plane.axis,
                        rebar_shape_rotation_angle)

        fillet_radius = rebar.Rounding * rebar.Diameter.Value
        if fillet_radius:
            fillet_basewire = DraftGeomUtils.filletWire(
                basewire, fillet_radius)
        else:
            fillet_basewire = basewire

        (
            rebar_shape_min_x,
            rebar_shape_min_y,
            rebar_shape_max_x,
            rebar_shape_max_y,
        ) = getVertexesMinMaxXY(fillet_basewire.Vertexes, view_plane)

    # Check if stirrup will be having extended edges separated apart
    if (hasattr(rebar, "RebarShape") and rebar.RebarShape == "Stirrup"
            and hasattr(rebar, "BentAngle") and rebar.BentAngle == 90):
        apply_stirrup_extended_edge_offset = True
    else:
        apply_stirrup_extended_edge_offset = False

    # Apply max_height and max_width of rebar shape svg And calculate scaling
    # factor
    rebar_shape_height = (rebar_shape_max_y - rebar_shape_min_y) or 1
    rebar_shape_width = (rebar_shape_max_x - rebar_shape_min_x) or 1
    h_scaling_factor = v_scaling_factor = scale
    if max_height:
        v_scaling_factor = (
            max_height - dimension_font_size *
            ((2 if include_mark else 0) +
             (2 if include_dimensions else 0)) - 2 * side_padding -
            (stirrup_extended_edge_offset
             if apply_stirrup_extended_edge_offset and (round(
                 getProjectionToSVGPlane(
                     Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                     view_plane,
                 ).y) in (round(rebar_shape_min_y), round(rebar_shape_max_y)))
             else 0)) / rebar_shape_height
    if max_width:
        h_scaling_factor = (
            max_width - dimension_font_size *
            (2 if include_dimensions else 0) - 2 * side_padding -
            (stirrup_extended_edge_offset
             if apply_stirrup_extended_edge_offset and (round(
                 getProjectionToSVGPlane(
                     Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                     view_plane,
                 ).x) in (round(rebar_shape_min_x), round(rebar_shape_max_x)))
             else 0)) / rebar_shape_width
    scale = min(h_scaling_factor, v_scaling_factor)
    svg_height = (
        rebar_shape_height * scale + dimension_font_size *
        ((2 if include_mark else 0) +
         (2 if include_dimensions else 0)) + 2 * side_padding +
        (stirrup_extended_edge_offset if apply_stirrup_extended_edge_offset and
         (round(
             getProjectionToSVGPlane(
                 Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                 view_plane,
             ).y) in (round(rebar_shape_min_y), round(rebar_shape_max_y))) else
         0))
    svg_width = (
        rebar_shape_width * scale + dimension_font_size *
        (2 if include_dimensions else 0) + 2 * side_padding +
        (stirrup_extended_edge_offset if apply_stirrup_extended_edge_offset and
         (round(
             getProjectionToSVGPlane(
                 Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                 view_plane,
             ).x) in (round(rebar_shape_min_x), round(rebar_shape_max_x))) else
         0))

    # Move (min_x, min_y) point in svg plane to (0, 0) so that entire basewire
    # should be visible in svg view box and apply required scaling
    translate_x = round(
        -(rebar_shape_min_x -
          (dimension_font_size if include_dimensions else 0) / scale -
          side_padding / scale -
          (stirrup_extended_edge_offset /
           scale if apply_stirrup_extended_edge_offset and (round(
               getProjectionToSVGPlane(
                   Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                   view_plane,
               ).x) == round(rebar_shape_min_x)) else 0)))
    translate_y = round(
        -(rebar_shape_min_y -
          ((2 if include_mark else 0) +
           (1 if include_dimensions else 0)) * dimension_font_size / scale -
          side_padding / scale -
          (stirrup_extended_edge_offset /
           scale if apply_stirrup_extended_edge_offset and (round(
               getProjectionToSVGPlane(
                   Part.__sortEdges__(basewire.Edges)[0].firstVertex().Point,
                   view_plane,
               ).y) == round(rebar_shape_min_y)) else 0)))
    rebar_shape_svg.set(
        "transform",
        "scale({}) translate({} {})".format(scale, translate_x, translate_y),
    )

    svg.set("width", "{}mm".format(round(svg_width)))
    svg.set("height", "{}mm".format(round(svg_height)))
    svg.set("viewBox", "0 0 {} {}".format(round(svg_width), round(svg_height)))

    # Scale down rebar_stroke_width and dimension_font_size to make them
    # resolution independent
    rebar_stroke_width /= scale
    dimension_font_size /= scale

    # Include rebar.Mark in rebar shape svg
    if include_mark:
        if hasattr(rebar, "Mark"):
            mark = rebar.Mark
        elif hasattr(rebar, "MarkNumber"):
            mark = rebar.MarkNumber
        else:
            mark = ""
        rebar_shape_svg.append(
            getSVGTextElement(
                mark,
                rebar_shape_min_x,
                rebar_shape_min_y -
                (0.5 + bool(include_dimensions)) * dimension_font_size,
                dimension_font_family,
                1.5 * dimension_font_size,
            ))

    if hasattr(rebar, "RebarShape") and rebar.RebarShape == "HelicalRebar":
        helical_rebar_shape_svg = Draft.getSVG(
            rebar,
            direction=view_plane,
            linewidth=rebar_stroke_width,
            fillstyle="none",
            color=rebar_color,
        )
        if helical_rebar_shape_svg:
            helical_rebar_shape_svg_element = ElementTree.fromstring(
                "<g>{}</g>".format(helical_rebar_shape_svg))
            rebar_edges_svg.append(helical_rebar_shape_svg_element)
            helical_rebar_center = getProjectionToSVGPlane(
                rebar.Base.Shape.CenterOfMass, view_plane)
            helical_rebar_shape_svg_element.set(
                "transform",
                "rotate({} {} {})".format(
                    rebar_shape_rotation_angle,
                    helical_rebar_center.x,
                    helical_rebar_center.y,
                ),
            )

        if include_dimensions:
            # Create rebar dimension svg
            top_mid_point = FreeCAD.Vector(
                (rebar_shape_min_x + rebar_shape_max_x) / 2, rebar_shape_min_y)
            helical_rebar_length = str(
                round(
                    FreeCAD.Units.Quantity("{}mm".format(
                        rebar.Base.Shape.Wires[0].Length)).getValueAs(
                            rebar_dimension_units).Value,
                    precision,
                ))
            helix_radius = str(
                round(
                    rebar.Base.Radius.getValueAs(rebar_dimension_units).Value,
                    precision,
                ))
            helix_pitch = str(
                round(
                    rebar.Base.Pitch.getValueAs(rebar_dimension_units).Value,
                    precision,
                ))
            if "." in helical_rebar_length:
                helical_rebar_length = helical_rebar_length.rstrip("0").rstrip(
                    ".")
            if "." in helix_radius:
                helix_radius = helix_radius.rstrip("0").rstrip(".")
            if "." in helix_pitch:
                helix_pitch = helix_pitch.rstrip("0").rstrip(".")
            if include_units_in_dimension_label:
                helical_rebar_length += rebar_dimension_units
                helix_radius += rebar_dimension_units
                helix_pitch += rebar_dimension_units
            edge_dimension_svg.append(
                getSVGTextElement(
                    helical_rebar_dimension_label_format.replace(
                        "%L", helical_rebar_length).replace(
                            "%R", helix_radius).replace("%P", helix_pitch),
                    top_mid_point.x,
                    top_mid_point.y - rebar_stroke_width * 2,
                    dimension_font_family,
                    dimension_font_size,
                    "middle",
                ))
    else:
        if stirrup_extended_edge_offset and apply_stirrup_extended_edge_offset:
            basewire = getBasewireOfStirrupWithExtendedEdges(
                rebar, view_plane, stirrup_extended_edge_offset / scale)
            basewire.rotate(
                basewire.CenterOfMass,
                view_plane.axis,
                rebar_shape_rotation_angle,
            )

            fillet_radius = rebar.Rounding * rebar.Diameter.Value
            if fillet_radius:
                fillet_basewire = DraftGeomUtils.filletWire(
                    basewire, fillet_radius)
            else:
                fillet_basewire = basewire

        edges = Part.__sortEdges__(fillet_basewire.Edges)
        straight_edges = Part.__sortEdges__(rebar.Base.Shape.Wires[0].Edges)
        for edge in list(straight_edges):
            if DraftGeomUtils.geomType(edge) != "Line":
                straight_edges.remove(edge)

        current_straight_edge_index = 0
        for edge_index, edge in enumerate(edges):
            if DraftGeomUtils.geomType(edge) == "Line":
                p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                             view_plane)
                p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                             view_plane)
                # Create Edge svg
                if round(p1.x) == round(p2.x) and round(p1.y) == round(p2.y):
                    edge_svg = getPointSVG(p1,
                                           radius=2 * rebar_stroke_width,
                                           fill=rebar_color)
                else:
                    edge_svg = getLineSVG(p1, p2, rebar_stroke_width,
                                          rebar_color)

                if include_dimensions:
                    # Create edge dimension svg
                    mid_point = FreeCAD.Vector((p1.x + p2.x) / 2,
                                               (p1.y + p2.y) / 2)
                    dimension_rotation = (math.degrees(
                        math.atan((p2.y - p1.y) / (p2.x - p1.x))) if
                                          round(p2.x) != round(p1.x) else -90)
                    edge_length = str(
                        round(
                            FreeCAD.Units.Quantity("{}mm".format(
                                straight_edges[current_straight_edge_index].
                                Length)).getValueAs(
                                    rebar_dimension_units).Value,
                            precision,
                        ))
                    if "." in edge_length:
                        edge_length = edge_length.rstrip("0").rstrip(".")
                    if include_units_in_dimension_label:
                        edge_length += rebar_dimension_units
                    edge_dimension_svg.append(
                        getSVGTextElement(
                            edge_length,
                            mid_point.x,
                            mid_point.y - rebar_stroke_width * 2,
                            dimension_font_family,
                            dimension_font_size,
                            "middle",
                        ))
                    edge_dimension_svg[-1].set(
                        "transform",
                        "rotate({} {} {})".format(
                            dimension_rotation,
                            round(mid_point.x),
                            round(mid_point.y),
                        ),
                    )
                    current_straight_edge_index += 1
                    if (0 <= edge_index - 1 and DraftGeomUtils.geomType(
                            edges[edge_index - 1]) == "Line"):
                        radius = max(fillet_radius, dimension_font_size * 0.8)
                        bent_angle_svg = getEdgesAngleSVG(
                            edges[edge_index - 1],
                            edge,
                            radius,
                            view_plane,
                            dimension_font_family,
                            dimension_font_size * 0.8,
                            bent_angle_dimension_exclude_list,
                            0.2 / scale,
                        )
                        edge_dimension_svg.append(bent_angle_svg)
            elif DraftGeomUtils.geomType(edge) == "Circle":
                p1 = getProjectionToSVGPlane(edge.Vertexes[0].Point,
                                             view_plane)
                p2 = getProjectionToSVGPlane(edge.Vertexes[1].Point,
                                             view_plane)
                if round(p1.x) == round(p2.x) or round(p1.y) == round(p2.y):
                    edge_svg = getLineSVG(p1, p2, rebar_stroke_width,
                                          rebar_color)
                else:
                    edge_svg = getRoundEdgeSVG(edge, view_plane,
                                               rebar_stroke_width, rebar_color)
                    if include_dimensions:
                        # Create bent angle svg
                        if 0 <= edge_index - 1 and edge_index + 1 < len(edges):
                            prev_edge = edges[edge_index - 1]
                            next_edge = edges[edge_index + 1]
                            if (DraftGeomUtils.geomType(prev_edge) ==
                                    DraftGeomUtils.geomType(next_edge) ==
                                    "Line"):
                                radius = max(fillet_radius,
                                             dimension_font_size * 0.8)
                                bent_angle_svg = getEdgesAngleSVG(
                                    prev_edge,
                                    next_edge,
                                    radius,
                                    view_plane,
                                    dimension_font_family,
                                    dimension_font_size * 0.8,
                                    bent_angle_dimension_exclude_list,
                                    0.2 / scale,
                                )
                                edge_dimension_svg.append(bent_angle_svg)
            else:
                edge_svg = ElementTree.Element("g")
            rebar_edges_svg.append(edge_svg)

    return svg
示例#15
0
    def execute(self,obj):

        if self.clone(obj):
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.Host
        fathershape = None
        if not father:
            # support for old-style rebars
            if obj.InList:
                if hasattr(obj.InList[0],"Armatures"):
                    if obj in obj.InList[0].Armatures:
                        father = obj.InList[0]
        if father:
            if father.isDerivedFrom("Part::Feature"):
                fathershape = father.Shape

        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj,"Rounding"):
            #print(obj.Rounding)
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire,radius)
        bpoint, bvec = self.getBaseAndAxis(wire)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1))
        if fathershape:
            size = (ArchCommands.projectToVector(fathershape.copy(),axis)).Length
        else:
            size = 1
        if hasattr(obj,"Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)
                axis.normalize()
                if fathershape:
                    size = (ArchCommands.projectToVector(fathershape.copy(),axis)).Length
                else:
                    size = 1
        if hasattr(obj,"Distance"):
            if obj.Distance.Value:
                size = obj.Distance.Value
        spacinglist = None
        if hasattr(obj, "CustomSpacing"):
            if obj.CustomSpacing:
                spacinglist = strprocessOfCustomSpacing(obj.CustomSpacing)
                influenceArea = sum(spacinglist) - spacinglist[0] / 2 - spacinglist[-1] / 2
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return
        # all tests ok!
        if hasattr(obj, "Length"):
            length = getLengthOfRebar(obj)
            if length:
                obj.Length = length
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value/2,bpoint,bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle],True,False,2)
            basewire = wire.copy()
        except Part.OCCError:
            print("Arch: error sweeping rebar profile along the base sketch")
            return
        # building final shape
        shapes = []
        placementlist = []
        self.wires = []
        rot = FreeCAD.Rotation()
        if obj.Amount == 1:
            barplacement = CalculatePlacement(obj.Amount, 1, obj.Diameter.Value, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value, obj.ViewObject.RebarShape)
            placementlist.append(barplacement)
            if hasattr(obj,"Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis,obj.OffsetStart.Value)
            else:
                baseoffset = None
            if obj.ViewObject.RebarShape == "Stirrup":
                interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value + obj.Diameter.Value)
            else:
                interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            for i in range(obj.Amount):
                barplacement = CalculatePlacement(obj.Amount, i+1, obj.Diameter.Value, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value, obj.ViewObject.RebarShape)
                placementlist.append(barplacement)
            if hasattr(obj,"Spacing"):
                obj.Spacing = interval
        # Calculate placement of bars from custom spacing.
        if spacinglist:
            placementlist[:] = []
            if obj.ViewObject.RebarShape == "Stirrup":
                reqInfluenceArea = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value + obj.Diameter.Value)
            else:
                reqInfluenceArea = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            # Avoid unnecessary checks to pass like. For eg.: when we have values
            # like influenceArea is 100.00001 and reqInflueneArea is 100
            if round(influenceArea) > round(reqInfluenceArea):
                FreeCAD.Console.PrintWarning("Influence area of rebars is greater than "+ str(reqInfluenceArea) + ".\n")
            elif round(influenceArea) < round(reqInfluenceArea):
                FreeCAD.Console.PrintWarning("Last span is greater that end offset.\n")
            for i in range(len(spacinglist)):
                if i == 0:
                    barplacement = CustomSpacingPlacement(spacinglist, 1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
                else:
                    barplacement = CustomSpacingPlacement(spacinglist, i+1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
            obj.Amount = len(spacinglist)
            obj.Spacing = 0
        obj.PlacementList = placementlist
        for i in range(len(obj.PlacementList)):
            if i == 0:
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
                basewire.Placement = obj.PlacementList[i]
                self.wires.append(basewire)
            else:
                bar = bar.copy()
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
                w = basewire.copy()
                w.Placement = obj.PlacementList[i]
                self.wires.append(w)
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
        obj.TotalLength = obj.Length * len(obj.PlacementList)