Automate Reinforcement GSoC proposal

Contributions from the participants, questions and answers to their projects.
Discussions of proposals for upcoming events.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

Invictus wrote: Sat Apr 06, 2019 6:20 am Hi Suraj,

This is Abhijeet Oundhakar from SEFI. I'm able to spend some time on this now. Could you please let me know what help you need?
Hi Abhijeet Oundhakar
Nice to see you here. I want to know about the different scenarios for Reinforcement process as @yorik had sugested at https://forum.freecadweb.org/viewtopic. ... 10#p297235

As I discussed about the Master Configuration file at https://forum.freecadweb.org/viewtopic. ... 20#p298456, what are the common parameters that can be set globally for Reinforcement of entire building.

You may also give your suggestions about the proposed solution:
https://docs.google.com/document/d/1-LI ... swczgr391v

Invictus wrote: Sat Apr 06, 2019 6:20 am Please get in touch at oundhakar at gmail dot com.
OK, I will.


Regards
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

Joel_graff wrote: Wed Apr 03, 2019 8:30 pm
So several months ago, I tried to adapt the rebar addon for doing concrete box culvert layouts for highway engineering. What's nice about box culverts is that there's rarely need for customization - most use cases already have layouts prescribed, given the slab / wall thickness, clear spans, etc.
Hi @Joel_graff
We can include Reinforcement for box culverts to Future Scope of project and I will implement that afterwards. It will be very helpful if you can share more stuff or some reference links about Reinforcement details for box culverts.

Regards
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Joel_graff »

Suraj Dadral wrote: Sat Apr 06, 2019 8:51 pm Hi @Joel_graff
We can include Reinforcement for box culverts to Future Scope of project and I will implement that afterwards. It will be very helpful if you can share more stuff or some reference links about Reinforcement details for box culverts.

Regards
You can find valuable design charts in the Illinois DOT Culvert Design Manual at:

http://www.idot.illinois.gov/Assets/up ... 202017.pdf

It's a big PDF. Apologies if it takes a long time to download. If you can't get it, let me know, I can probably break it up. The charts in Section 3 - Design will be most helpful.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

I created a simple function for Single Tie Column Reinforcement and can be found here:
https://github.com/SurajDadral/FreeCAD- ... ngleTie.py

Code: Select all

import FreeCADGui
import sys
sys.path.append("../")
from Stirrup import makeStirrup
from StraightRebar import makeStraightRebar

def singleTieColumn1Reinforcement(ydir_cover, zdir_cover, offset_of_tie, bentAngle, bentFactor, dia_of_tie,\
        amount_spacing_check, amount_spacing_value, dia_of_rebars, t_offset_of_rebars, b_offset_of_rebars,\
        rebar_type = "StraightRebar", structure = None):
    """ singleTieColumn1Reinforcement(YDirectionCover, ZDirectionCover, OffsetOfTie,
    BentAngle, BentFactor, DiameterOfTie, AmountSpacingCheck, AmountSpacingValue,
    DiameterOfRebars, RebarType, Structure)
    Adds the Single Tie reinforcement to the selected structural column object."""
    selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
    structure = selected_obj.Object
    
    # Calculate parameters for Straight rebars
    f_cover = ydir_cover + dia_of_rebars/2 + dia_of_tie/2
    rl_cover = zdir_cover + dia_of_rebars/2 + dia_of_tie/2
    t_cover = t_offset_of_rebars
    b_cover = b_offset_of_rebars
    orientation = "Vertical"
    facename = "Face2"
    amount_spacing_check = True
    amount_spacing_value = 2
    list_coverAlong = ["Right Side", "Left Side"]

    # Create Straight Rebars
    for coverAlong in list_coverAlong:
        makeStraightRebar(f_cover, (coverAlong, rl_cover), t_cover, b_cover, dia_of_rebars, amount_spacing_check, amount_spacing_value, orientation, structure, facename)

    # Calculate Rounding of Stirrup
    rounding = (float(dia_of_tie)/2 + dia_of_rebars/2)/dia_of_tie

    # Create Stirrups
    facename = "Face6"
    l_cover = r_cover = ydir_cover
    t_cover = b_cover = zdir_cover
    f_cover = offset_of_tie
    makeStirrup(l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor, dia_of_tie, rounding,\
        amount_spacing_check, amount_spacing_value, structure, facename)

This will create reinforcement of following type:
Image

To use this, clone branch "automate" from repository: https://github.com/SurajDadral/FreeCAD-Reinforcement and move this to appropriate place.
We can use this by issuing following commands:
from ColumnReinforcement import SingleTie
SingleTie.singleTieColumn1Reinforcement(40,20,60,90,2,20,True,10,30,0,0)

#SingleTie.singleTieColumn1Reinforcement(YDirectionCover, ZDirectionCover, OffsetOfTie,BentAngle, BentFactor, DiameterOfTie, AmountSpacingCheck, AmountSpacingValue,DiameterOfRebars, RebarType, Structure)

Make sure to select "Structure" object before issuing commands.

Currently, this will create:
- Straight rebars and not L-shaped rebars.

I will add support for them soon.

Give your suggestions and reviews.

Regards
Last edited by Suraj Dadral on Fri Apr 19, 2019 3:58 pm, edited 2 times in total.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Automate Reinforcement GSoC proposal

Post by Kunda1 »

Suraj Dadral wrote: Mon Apr 08, 2019 10:46 am We can use this by issuing following commands:
@Suraj do you mind putting code in the bbcode code tags, please? It's easier to read an maintains indentation. Thanks.
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
User avatar
amrit3701
Posts: 343
Joined: Mon Jun 13, 2016 5:37 pm

Re: Automate Reinforcement GSoC proposal

Post by amrit3701 »

Suraj Dadral wrote: Mon Apr 08, 2019 10:46 am I created a simple function for Single Tie Column Reinforcement and can be found here:
Hi @Suraj,

I haven't tested your code yet. I will review it tomorrow. I am just writing to say that as I saw from my GSoC dashboard you haven't uploaded your final proposal yet. Deadline for submitting GSoC proposal is very closer (only few hours left). You can also re-upload the final pdf even after submission.

Thanks,
Amritpal Singh
Github, Like my work, sponsor me!
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

amrit3701 wrote: Mon Apr 08, 2019 7:34 pm I haven't tested your code yet. I will review it tomorrow. I am just writing to say that as I saw from my GSoC dashboard you haven't uploaded your final proposal yet. Deadline for submitting GSoC proposal is very closer (only few hours left). You can also re-upload the final pdf even after submission.
Thanks @amrit3701
I have just uploaded my final proposal.

Regards
User avatar
amrit3701
Posts: 343
Joined: Mon Jun 13, 2016 5:37 pm

Re: Automate Reinforcement GSoC proposal

Post by amrit3701 »

Suraj Dadral wrote: Mon Apr 08, 2019 10:46 am Give your suggestions and reviews.
Very good! This is exactly same you will do during GSoC.
Screenshot 2019-04-09 at 7.15.16 PM.png
Screenshot 2019-04-09 at 7.15.16 PM.png (391.06 KiB) Viewed 2137 times
Reviews on your code:
  • You used some constants for creating rebars which is not good. For eg. "Face2" for creating straight rebars and "Face6" for creating stirrups. All structures have not this face numbering. You need to find side faces and top faces somehow from obj.Shape.Faces. Maybe you can select stirrups face from a user as input and then all other faces which are perpendicular to stirrup face are sides faces. You can also get normal vector to face by obj.Shape.Faces[0].normalAt(0, 0).
  • Maximum length of a line should be of 80 characters.
Amritpal Singh
Github, Like my work, sponsor me!
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

amrit3701 wrote: Tue Apr 09, 2019 2:25 pm
  • You used some constants for creating rebars which is not good. For eg. "Face2" for creating straight rebars and "Face6" for creating stirrups. All structures have not this face numbering. You need to find side faces and top faces somehow from obj.Shape.Faces. Maybe you can select stirrups face from a user as input and then all other faces which are perpendicular to stirrup face are sides faces. You can also get normal vector to face by obj.Shape.Faces[0].normalAt(0, 0).
I implemented as above. Code snippet to find face perpendicular to x-axis:

Code: Select all

index = 1
faces = structure.Shape.Faces
for face in faces:
    normal = face.normalAt(0, 0)
    if normal.x == 1 and normal.y == 0 and normal.z == 0:
        facename = "Face" + str(index)
    index = index + 1
Code snippet to find face perpendicular to z-axis:

Code: Select all

index = 1
faces = structure.Shape.Faces
for face in faces:
    normal = face.normalAt(0, 0)
    if normal.x == 0 and normal.y == 0 and normal.z == 1:
        facename = "Face" + str(index)
    index = index + 1
And complete code is here:

Code: Select all

import FreeCADGui
import sys

sys.path.append("../")
from Stirrup import makeStirrup
from StraightRebar import makeStraightRebar


def singleTieColumn1Reinforcement(
    xdir_cover,
    ydir_cover,
    offset_of_tie,
    bentAngle,
    bentFactor,
    dia_of_tie,
    amount_spacing_check,
    amount_spacing_value,
    dia_of_rebars,
    t_offset_of_rebars,
    b_offset_of_rebars,
    rebar_type="StraightRebar",
    structure=None,
):
    """ singleTieColumn1Reinforcement(XDirectionCover, YDirectionCover,
    OffsetOfTie, BentAngle, BentFactor, DiameterOfTie, AmountSpacingCheck,
    AmountSpacingValue, DiameterOfRebars, RebarType, Structure)
    Adds the Single Tie reinforcement to the selected structural column
    object."""
    if not structure:
        selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
        structure = selected_obj.Object

    # Calculate parameters for Straight rebars
    f_cover = xdir_cover + dia_of_rebars / 2 + dia_of_tie / 2
    rl_cover = ydir_cover + dia_of_rebars / 2 + dia_of_tie / 2
    t_cover = t_offset_of_rebars
    b_cover = b_offset_of_rebars
    orientation = "Vertical"
    # facename = "Face2"
    # find facename of face perpendicular to x-axis
    index = 1
    faces = structure.Shape.Faces
    for face in faces:
        normal = face.normalAt(0, 0)
        if normal.x == 1 and normal.y == 0 and normal.z == 0:
            facename = "Face" + str(index)
        index = index + 1

    rebar_amount_spacing_check = True
    rebar_amount_spacing_value = 2
    list_coverAlong = ["Right Side", "Left Side"]

    # Create Straight Rebars
    for coverAlong in list_coverAlong:
        makeStraightRebar(
            f_cover,
            (coverAlong, rl_cover),
            t_cover,
            b_cover,
            dia_of_rebars,
            rebar_amount_spacing_check,
            rebar_amount_spacing_value,
            orientation,
            structure,
            facename,
        )

    # Calculate parameters for Stirrup
    rounding = (float(dia_of_tie) / 2 + dia_of_rebars / 2) / dia_of_tie

    # facename = "Face6"
    # find facename of face perpendicular to z-axis
    index = 1
    faces = structure.Shape.Faces
    for face in faces:
        normal = face.normalAt(0, 0)
        if normal.x == 0 and normal.y == 0 and normal.z == 1:
            facename = "Face" + str(index)
        index = index + 1

    l_cover = r_cover = xdir_cover
    t_cover = b_cover = ydir_cover
    f_cover = offset_of_tie

    # Create Stirrups
    makeStirrup(
        l_cover,
        r_cover,
        t_cover,
        b_cover,
        f_cover,
        bentAngle,
        bentFactor,
        dia_of_tie,
        rounding,
        amount_spacing_check,
        amount_spacing_value,
        structure,
        facename,
    )
Pros:
User will select structure instead of face of structure. This will
enable the way, in future, user will select number of structures to
create reinforcement in single step.

Cons:
If Axis or Angle of Structure changed, then this method fails to work. I will try to fix it.

Regards
User avatar
Suraj Dadral
Posts: 307
Joined: Fri Sep 07, 2018 5:32 pm
Contact:

Re: Automate Reinforcement GSoC proposal

Post by Suraj Dadral »

I added following code snippet to move stirrups with structure in functions makeStirrup() and editStirrup():

Code: Select all

# Rotate Stirrups with Structure
structureAngle=math.degrees(structure.Placement.Rotation.Angle)
stirrupAngle=structureAngle-90
rebar.Placement.Rotation.__setattr__('Angle',math.radians(stirrupAngle))
Complete file:

Code: Select all

from PySide import QtCore, QtGui
from Rebarfunc import *
from PySide.QtCore import QT_TRANSLATE_NOOP
from RebarDistribution import runRebarDistribution, removeRebarDistribution
from PopUpImage import showPopUpImageDialog
import FreeCAD
import FreeCADGui
import ArchCommands
import os
import sys
import math

def getpointsOfStirrup(FacePRM, l_cover, r_cover, t_cover, b_cover, bentAngle, bentFactor, diameter, rounding, facenormal):
    """ getpointsOfStirrup(FacePRM, LeftCover, RightCover, TopCover, BottomCover, BentAngle, BentFactor, Diameter, Rounding, FaceNormal):
    Return the coordinates points of the Stirrup in the form of array."""
    angle = 180 - bentAngle
    tangent_part_length = extendedTangentPartLength(rounding, diameter, angle)
    tangent_length = extendedTangentLength(rounding, diameter, angle)
    if round(facenormal[0]) in {1,-1}:
        x1 = FacePRM[1][0]
        y1 = FacePRM[1][1] - FacePRM[0][0] / 2 + l_cover
        z1 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover + tangent_part_length
        y2 = FacePRM[1][1] - FacePRM[0][0] / 2 + l_cover
        z2 = FacePRM[1][2] - FacePRM[0][1] / 2 + b_cover
        y3 = FacePRM[1][1] + FacePRM[0][0] / 2 - r_cover
        z3 = FacePRM[1][2] - FacePRM[0][1] / 2 + b_cover
        y4 = FacePRM[1][1] + FacePRM[0][0] / 2 - r_cover
        z4 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover
        y5 = FacePRM[1][1] - FacePRM[0][0] / 2 + l_cover - tangent_part_length
        z5 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover
        side_length = abs(y5 - y4) - tangent_part_length
        normal_dis = (diameter * (side_length + tangent_part_length)) / side_length
        x2 = x1 - normal_dis / 4
        x3 = x2 - normal_dis / 4
        x4 = x3 - normal_dis / 4
        x5 = x4 - normal_dis / 4
        x0 = x1 + normal_dis / 4
        y0 = y1 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(angle))
        z0 = z1 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(angle))
        x6 = x5 - normal_dis / 4
        y6 = y5 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(90 - angle))
        z6 = z5 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(90 - angle))
    elif round(facenormal[1]) in {1,-1}:
        x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
        y1 = FacePRM[1][1]
        z1 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover + tangent_part_length
        x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
        z2 = FacePRM[1][2] - FacePRM[0][1] / 2 + b_cover
        x3 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
        z3 = FacePRM[1][2] - FacePRM[0][1] / 2 + b_cover
        x4 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
        z4 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover
        x5 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover - tangent_part_length
        z5 = FacePRM[1][2] + FacePRM[0][1] / 2 - t_cover
        side_length = abs(x5 - x4) - tangent_part_length
        normal_dis = (diameter * (side_length + tangent_part_length)) / side_length
        y2 = y1 - normal_dis / 4
        y3 = y2 - normal_dis / 4
        y4 = y3 - normal_dis / 4
        y5 = y4 - normal_dis / 4
        y0 = y1 + normal_dis / 4
        x0 = x1 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(angle))
        z0 = z1 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(angle))
        x6 = x5 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(90 - angle))
        y6 = y5 - normal_dis / 4
        z6 = z5 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(90 - angle))
    elif round(facenormal[2]) in {1,-1}:
        x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
        y1 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover + tangent_part_length
        z1 = FacePRM[1][2]
        x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
        y2 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover
        x3 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
        y3 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover
        x4 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
        y4 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
        x5 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover - tangent_part_length
        y5 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
        side_length = abs(x5 - x4) - tangent_part_length
        normal_dis = (diameter * (side_length + tangent_part_length)) / side_length
        z2 = z1 - normal_dis / 4
        z3 = z2 - normal_dis / 4
        z4 = z3 - normal_dis / 4
        z5 = z4 - normal_dis / 4
        z0 = z1 + normal_dis / 4
        x0 = x1 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(angle))
        y0 = y1 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(angle))
        x6 = x5 + (tangent_length + bentFactor * diameter) * math.sin(math.radians(90 - angle))
        y6 = y5 - (tangent_length + bentFactor * diameter) * math.cos(math.radians(90 - angle))
        z6 = z5 - normal_dis / 4
    return [FreeCAD.Vector(x0, y0, z0), FreeCAD.Vector(x1, y1, z1),\
            FreeCAD.Vector(x2, y2, z2), FreeCAD.Vector(x3, y3, z3),\
            FreeCAD.Vector(x4, y4, z4), FreeCAD.Vector(x5, y5, z5),\
            FreeCAD.Vector(x6, y6, z6)]

class _StirrupTaskPanel:
    def __init__(self, Rebar = None):
        self.CustomSpacing = None
        if not Rebar:
            selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
            self.SelectedObj = selected_obj.Object
            self.FaceName = selected_obj.SubElementNames[0]
        else:
            self.FaceName = Rebar.Base.Support[0][1][0]
            self.SelectedObj = Rebar.Base.Support[0][0]
        self.form = FreeCADGui.PySideUic.loadUi(os.path.splitext(__file__)[0] + ".ui")
        self.form.setWindowTitle(QtGui.QApplication.translate("RebarAddon", "Stirrup Rebar", None))
        self.form.bentAngle.addItems(["135", "90"])
        self.form.amount_radio.clicked.connect(self.amount_radio_clicked)
        self.form.spacing_radio.clicked.connect(self.spacing_radio_clicked)
        self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0]+"/icons/Stirrup.svg").scaled(150, 150, QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation))
        self.form.customSpacing.clicked.connect(lambda: runRebarDistribution(self))
        self.form.removeCustomSpacing.clicked.connect(lambda: removeRebarDistribution(self))
        self.form.PickSelectedFace.clicked.connect(lambda: getSelectedFace(self))
        # self.form.toolButton.setIcon(self.form.toolButton.style().standardIcon(QtGui.QStyle.SP_DialogHelpButton))
        self.form.toolButton.clicked.connect(lambda: showPopUpImageDialog(os.path.split(os.path.abspath(__file__))[0] + "/icons/StirrupDetailed.svg"))
        self.Rebar = Rebar

    def getStandardButtons(self):
        return int(QtGui.QDialogButtonBox.Ok) | int(QtGui.QDialogButtonBox.Apply) | int(QtGui.QDialogButtonBox.Cancel)

    def clicked(self, button):
        if button == int(QtGui.QDialogButtonBox.Apply):
            self.accept(button)

    def accept(self, signal = None):
        l_cover = self.form.l_sideCover.text()
        l_cover = FreeCAD.Units.Quantity(l_cover).Value
        r_cover = self.form.r_sideCover.text()
        r_cover = FreeCAD.Units.Quantity(r_cover).Value
        t_cover = self.form.t_sideCover.text()
        t_cover = FreeCAD.Units.Quantity(t_cover).Value
        b_cover = self.form.b_sideCover.text()
        b_cover = FreeCAD.Units.Quantity(b_cover).Value
        f_cover = self.form.frontCover.text()
        f_cover = FreeCAD.Units.Quantity(f_cover).Value
        diameter = self.form.diameter.text()
        diameter = FreeCAD.Units.Quantity(diameter).Value
        bentAngle = int(self.form.bentAngle.currentText())
        bentFactor = self.form.bentFactor.value()
        rounding = self.form.rounding.value()
        amount_check = self.form.amount_radio.isChecked()
        spacing_check = self.form.spacing_radio.isChecked()
        if not self.Rebar:
            if amount_check:
                amount = self.form.amount.value()
                rebar = makeStirrup(l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor, diameter,\
                    rounding, True, amount, self.SelectedObj, self.FaceName)
            elif spacing_check:
                spacing = self.form.spacing.text()
                spacing = FreeCAD.Units.Quantity(spacing).Value
                rebar = makeStirrup(l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor, diameter,\
                    rounding, False, spacing, self.SelectedObj, self.FaceName)
        else:
            if amount_check:
                amount = self.form.amount.value()
                rebar = editStirrup(self.Rebar, l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor,\
                    diameter, rounding, True, amount, self.SelectedObj, self.FaceName)
            elif spacing_check:
                spacing = self.form.spacing.text()
                spacing = FreeCAD.Units.Quantity(spacing).Value
                rebar = editStirrup(self.Rebar, l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor,\
                    diameter, rounding, False, spacing, self.SelectedObj, self.FaceName)
        if self.CustomSpacing:
            rebar.CustomSpacing = self.CustomSpacing
            FreeCAD.ActiveDocument.recompute()
        self.Rebar = rebar
        if signal == int(QtGui.QDialogButtonBox.Apply):
            pass
        else:
            FreeCADGui.Control.closeDialog(self)

    def amount_radio_clicked(self):
        self.form.spacing.setEnabled(False)
        self.form.amount.setEnabled(True)

    def spacing_radio_clicked(self):
        self.form.amount.setEnabled(False)
        self.form.spacing.setEnabled(True)


def makeStirrup(l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor, diameter, rounding,\
        amount_spacing_check, amount_spacing_value, structure = None, facename = None):
    """ makeStirrup(LeftCover, RightCover, TopCover, BottomCover, FrontCover, BentAngle,
    BentFactor, Diameter, Rounding, AmountSpacingCheck, AmountSpacingValue, Structure, Facename):
    Adds the Stirrup reinforcement bar to the selected structural object."""
    if not structure and not facename:
        selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
        structure = selected_obj.Object
        facename = selected_obj.SubElementNames[0]
    face = structure.Shape.Faces[getFaceNumber(facename) - 1]
    #StructurePRM = getTrueParametersOfStructure(structure)
    FacePRM = getParametersOfFace(structure, facename, False)
    FaceNormal = face.normalAt(0,0)
    #FaceNormal = face.Placement.Rotation.inverted().multVec(FaceNormal)
    if not FacePRM:
        FreeCAD.Console.PrintError("Cannot identified shape or from which base object sturctural element is derived\n")
        return
    # Calculate the coordinate values of Stirrup
    points = getpointsOfStirrup(FacePRM, l_cover, r_cover, t_cover, b_cover, bentAngle, bentFactor, diameter, rounding, FaceNormal)
    import Draft
    line = Draft.makeWire(points, closed = False, face = True, support = None)
    import Arch
    line.Support = [(structure, facename)]
    if amount_spacing_check:
        rebar = Arch.makeRebar(structure, line, diameter, amount_spacing_value, f_cover)
    else:
        size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
        rebar = Arch.makeRebar(structure, line, diameter,\
            int((size - diameter) / amount_spacing_value), f_cover)
    rebar.Direction = FaceNormal.negative()
    rebar.Rounding = rounding

    # Rotate Stirrups with Structure
    structureAngle=math.degrees(structure.Placement.Rotation.Angle)
    stirrupAngle=structureAngle-90
    rebar.Placement.Rotation.__setattr__('Angle',math.radians(stirrupAngle))

    # Adds properties to the rebar object
    rebar.ViewObject.addProperty("App::PropertyString", "RebarShape", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property","Shape of rebar")).RebarShape = "Stirrup"
    rebar.ViewObject.setEditorMode("RebarShape", 2)
    rebar.addProperty("App::PropertyDistance", "LeftCover", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Left Side cover of rebar")).LeftCover = l_cover
    rebar.setEditorMode("LeftCover", 2)
    rebar.addProperty("App::PropertyDistance", "RightCover", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Right Side cover of rebar")).RightCover = r_cover
    rebar.setEditorMode("RightCover", 2)
    rebar.addProperty("App::PropertyDistance", "TopCover", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Top Side cover of rebar")).TopCover = t_cover
    rebar.setEditorMode("TopCover", 2)
    rebar.addProperty("App::PropertyDistance", "BottomCover", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Bottom Side cover of rebar")).BottomCover = b_cover
    rebar.setEditorMode("BottomCover", 2)
    rebar.addProperty("App::PropertyDistance", "FrontCover", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Top cover of rebar")).FrontCover = f_cover
    rebar.setEditorMode("FrontCover", 2)
    rebar.addProperty("App::PropertyInteger", "BentAngle", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Bent angle between at the end of rebar")).BentAngle = bentAngle
    rebar.setEditorMode("BentAngle", 2)
    rebar.addProperty("App::PropertyInteger", "BentFactor", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Bent Length is the equal to BentFactor * Diameter")).BentFactor = bentFactor
    rebar.setEditorMode("BentFactor", 2)
    rebar.addProperty("App::PropertyBool", "AmountCheck", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Amount radio button is checked")).AmountCheck
    rebar.setEditorMode("AmountCheck", 2)
    rebar.addProperty("App::PropertyDistance", "TrueSpacing", "RebarDialog",\
        QT_TRANSLATE_NOOP("App::Property", "Spacing between of rebars")).TrueSpacing = amount_spacing_value
    rebar.setEditorMode("TrueSpacing", 2)
    if amount_spacing_check:
        rebar.AmountCheck = True
    else:
        rebar.AmountCheck = False
        rebar.TrueSpacing = amount_spacing_value
    rebar.Label = "Stirrup"
    FreeCAD.ActiveDocument.recompute()
    return rebar

def editStirrup(Rebar, l_cover, r_cover, t_cover, b_cover, f_cover, bentAngle, bentFactor, diameter, rounding,\
        amount_spacing_check, amount_spacing_value, structure = None, facename = None):
    sketch = Rebar.Base
    if structure and facename:
        sketch.Support = [(structure, facename)]
    # Check if sketch support is empty.
    if not sketch.Support:
        showWarning("You have checked remove external geometry of base sketchs when needed.\nTo unchecked Edit->Preferences->Arch.")
        return
    # Assigned values
    facename = sketch.Support[0][1][0]
    structure = sketch.Support[0][0]
    face = structure.Shape.Faces[getFaceNumber(facename) - 1]
    #StructurePRM = getTrueParametersOfStructure(structure)
    # Get parameters of the face where sketch of rebar is drawn
    FacePRM = getParametersOfFace(structure, facename, False)
    FaceNormal = face.normalAt(0, 0)
    #FaceNormal = face.Placement.Rotation.inverted().multVec(FaceNormal)
    # Calculate the coordinates value of Stirrup rebar
    points = getpointsOfStirrup(FacePRM, l_cover, r_cover, t_cover, b_cover, bentAngle, bentFactor, diameter, rounding, FaceNormal)
    Rebar.Base.Points = points
    FreeCAD.ActiveDocument.recompute()
    Rebar.Direction = FaceNormal.negative()
    Rebar.OffsetStart = f_cover
    Rebar.OffsetEnd = f_cover
    Rebar.BentAngle = bentAngle
    Rebar.BentFactor = bentFactor
    Rebar.Rounding = rounding
    Rebar.Diameter = diameter
    if amount_spacing_check:
        Rebar.Amount = amount_spacing_value
        FreeCAD.ActiveDocument.recompute()
        Rebar.AmountCheck = True
    else:
        size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
        Rebar.Amount = int((size - diameter) / amount_spacing_value)
        FreeCAD.ActiveDocument.recompute()
        Rebar.AmountCheck = False
    Rebar.FrontCover = f_cover
    Rebar.LeftCover = l_cover
    Rebar.RightCover = r_cover
    Rebar.TopCover = t_cover
    Rebar.BottomCover = b_cover
    Rebar.TrueSpacing = amount_spacing_value
 
    # Rotate Stirrups with Structure
    structureAngle=math.degrees(structure.Placement.Rotation.Angle)
    stirrupAngle=structureAngle-90
    Rebar.Placement.Rotation.__setattr__('Angle',math.radians(stirrupAngle))

    FreeCAD.ActiveDocument.recompute()
    return Rebar

def editDialog(vobj):
    FreeCADGui.Control.closeDialog()
    obj = _StirrupTaskPanel(vobj.Object)
    obj.form.frontCover.setText(str(vobj.Object.FrontCover))
    obj.form.l_sideCover.setText(str(vobj.Object.LeftCover))
    obj.form.r_sideCover.setText(str(vobj.Object.RightCover))
    obj.form.t_sideCover.setText(str(vobj.Object.TopCover))
    obj.form.b_sideCover.setText(str(vobj.Object.BottomCover))
    obj.form.diameter.setText(str(vobj.Object.Diameter))
    obj.form.bentAngle.setCurrentIndex(obj.form.bentAngle.findText(str(vobj.Object.BentAngle)))
    obj.form.bentFactor.setValue(vobj.Object.BentFactor)
    obj.form.rounding.setValue(vobj.Object.Rounding)
    if vobj.Object.AmountCheck:
        obj.form.amount.setValue(vobj.Object.Amount)
    else:
        obj.form.amount_radio.setChecked(False)
        obj.form.spacing_radio.setChecked(True)
        obj.form.amount.setDisabled(True)
        obj.form.spacing.setEnabled(True)
        obj.form.spacing.setText(str(vobj.Object.TrueSpacing))
    #obj.form.PickSelectedFace.setVisible(False)
    FreeCADGui.Control.showDialog(obj)

def CommandStirrup():
    selected_obj = check_selected_face()
    if selected_obj:
        FreeCADGui.Control.showDialog(_StirrupTaskPanel())
Please review and suggest changes, if any.

Regards,
Post Reply