Rebar Addon for FreeCAD
BentShapeRebar.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # ***************************************************************************
3 # * *
4 # * Copyright (c) 2017 - Amritpal Singh <amrit3701@gmail.com> *
5 # * *
6 # * This program is free software; you can redistribute it and/or modify *
7 # * it under the terms of the GNU Lesser General Public License (LGPL) *
8 # * as published by the Free Software Foundation; either version 2 of *
9 # * the License, or (at your option) any later version. *
10 # * for detail see the LICENCE text file. *
11 # * *
12 # * This program is distributed in the hope that it will be useful, *
13 # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 # * GNU Library General Public License for more details. *
16 # * *
17 # * You should have received a copy of the GNU Library General Public *
18 # * License along with this program; if not, write to the Free Software *
19 # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
20 # * USA *
21 # * *
22 # ***************************************************************************
23 
24 __title__ = "BentShapeRebar"
25 __author__ = "Amritpal Singh"
26 __url__ = "https://www.freecadweb.org"
27 
28 from PySide import QtCore, QtGui
29 from Rebarfunc import *
30 from PySide.QtCore import QT_TRANSLATE_NOOP
31 from RebarDistribution import runRebarDistribution, removeRebarDistribution
32 from PopUpImage import showPopUpImageDialog
33 import FreeCAD
34 import FreeCADGui
35 import ArchCommands
36 import os
37 import sys
38 import math
39 
40 def getpointsOfBentShapeRebar(FacePRM, l_cover, r_cover, b_cover, t_cover, bentLength, bentAngle, orientation):
41  """ getpointsOfBentShapeRebar(FacePRM, LeftCover, RightCover, BottomCover, TopCover, BentLength, BentAngle, Orientation):
42  Return points of the LShape rebar in the form of array for sketch.
43  It takes four different orientations input i.e. 'Bottom', 'Top', 'Left', 'Right'.
44  """
45  if orientation == "Bottom":
46  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
47  y1 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
48  x2 = x1 + bentLength
49  y2 = y1
50  dis = (FacePRM[0][1] - t_cover - b_cover) * math.tan(math.radians(bentAngle - 90))
51  x3 = x2 + dis
52  y3 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover
53  x4 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover - bentLength - dis
54  y4 = y3
55  x5 = x4 + dis
56  y5 = y2
57  x6 = x5 + bentLength
58  y6 = y5
59  elif orientation == "Top":
60  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
61  y1 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover
62  x2 = x1 + bentLength
63  y2 = y1
64  dis = (FacePRM[0][1] - t_cover - b_cover) * math.tan(math.radians(bentAngle - 90))
65  x3 = x2 + dis
66  y3 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
67  x4 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover - bentLength - dis
68  y4 = y3
69  x5 = x4 + dis
70  y5 = y2
71  x6 = x5 + bentLength
72  y6 = y5
73  elif orientation == "Left":
74  x1 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
75  y1 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
76  x2 = x1
77  y2 = y1 - bentLength
78  dis = (FacePRM[0][0] - r_cover - l_cover) * math.tan(math.radians(bentAngle - 90))
79  x3 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
80  y3 = y2 - dis
81  x4 = x3
82  y4 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover + bentLength + dis
83  x5 = x2
84  y5 = y4 - dis
85  x6 = x5
86  y6 = y5 - bentLength
87  elif orientation == "Right":
88  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + l_cover
89  y1 = FacePRM[1][1] + FacePRM[0][1] / 2 - t_cover
90  x2 = x1
91  y2 = y1 - bentLength
92  dis = (FacePRM[0][0] - r_cover - l_cover) * math.tan(math.radians(bentAngle - 90))
93  x3 = FacePRM[1][0] + FacePRM[0][0] / 2 - r_cover
94  y3 = y2 - dis
95  x4 = x3
96  y4 = FacePRM[1][1] - FacePRM[0][1] / 2 + b_cover + bentLength + dis
97  x5 = x2
98  y5 = y4 - dis
99  x6 = x5
100  y6 = y5 - bentLength
101  return [FreeCAD.Vector(x1, y1, 0), FreeCAD.Vector(x2, y2, 0),\
102  FreeCAD.Vector(x3, y3, 0), FreeCAD.Vector(x4, y4, 0),\
103  FreeCAD.Vector(x5, y5, 0), FreeCAD.Vector(x6, y6, 0)]
104 
106  def __init__(self, Rebar = None):
107  if not Rebar:
108  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
109  self.SelectedObj = selected_obj.Object
110  self.FaceName = selected_obj.SubElementNames[0]
111  else:
112  self.FaceName = Rebar.Base.Support[0][1][0]
113  self.SelectedObj = Rebar.Base.Support[0][0]
114  self.form = FreeCADGui.PySideUic.loadUi(os.path.splitext(__file__)[0] + ".ui")
115  self.form.setWindowTitle(QtGui.QApplication.translate("RebarAddon", "Bent Shape Rebar", None))
116  self.form.orientation.addItems(["Bottom", "Top", "Right", "Left"])
117  self.form.amount_radio.clicked.connect(self.amount_radio_clicked)
118  self.form.spacing_radio.clicked.connect(self.spacing_radio_clicked)
119  self.form.customSpacing.clicked.connect(lambda: runRebarDistribution(self))
120  self.form.removeCustomSpacing.clicked.connect(lambda: removeRebarDistribution(self))
121  self.form.PickSelectedFace.clicked.connect(lambda: getSelectedFace(self))
122  self.form.orientation.currentIndexChanged.connect(self.getOrientation)
123  self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/BentShapeRebar.svg"))
124  self.form.toolButton.setIcon(self.form.toolButton.style().standardIcon(QtGui.QStyle.SP_DialogHelpButton))
125  self.form.toolButton.clicked.connect(lambda: showPopUpImageDialog(os.path.split(os.path.abspath(__file__))[0] + "/icons/BentShapeRebarDetailed.svg"))
126  self.Rebar = Rebar
127 
128  def getOrientation(self):
129  orientation = self.form.orientation.currentText()
130  #if orientation == "Bottom":
131  # self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/LShapeRebarBR.svg"))
132  #elif orientation == "Top":
133  # self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/LShapeRebarBL.svg"))
134  #elif orientation == "Right":
135  # self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/LShapeRebarTR.svg"))
136  #else:
137  # self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/LShapeRebarTL.svg"))
138 
140  return int(QtGui.QDialogButtonBox.Ok) | int(QtGui.QDialogButtonBox.Apply) | int(QtGui.QDialogButtonBox.Cancel)
141 
142  def clicked(self, button):
143  if button == int(QtGui.QDialogButtonBox.Apply):
144  self.accept(button)
145 
146  def accept(self, signal = None):
147  f_cover = self.form.frontCover.text()
148  f_cover = FreeCAD.Units.Quantity(f_cover).Value
149  b_cover = self.form.bottomCover.text()
150  b_cover = FreeCAD.Units.Quantity(b_cover).Value
151  l_cover = self.form.l_sideCover.text()
152  l_cover = FreeCAD.Units.Quantity(l_cover).Value
153  r_cover = self.form.r_sideCover.text()
154  r_cover = FreeCAD.Units.Quantity(r_cover).Value
155  t_cover = self.form.topCover.text()
156  t_cover = FreeCAD.Units.Quantity(t_cover).Value
157  bentLength = self.form.bentLength.text()
158  bentLength = FreeCAD.Units.Quantity(bentLength).Value
159  bentAngle = self.form.bentAngle.value()
160  diameter = self.form.diameter.text()
161  diameter = FreeCAD.Units.Quantity(diameter).Value
162  rounding = self.form.rounding.value()
163  orientation = self.form.orientation.currentText()
164  amount_check = self.form.amount_radio.isChecked()
165  spacing_check = self.form.spacing_radio.isChecked()
166  if not self.Rebar:
167  if amount_check:
168  amount = self.form.amount.value()
169  rebar = makeBentShapeRebar(f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, True, amount, orientation, self.SelectedObj, self.FaceName)
170  elif spacing_check:
171  spacing = self.form.spacing.text()
172  spacing = FreeCAD.Units.Quantity(spacing).Value
173  rebar = makeBentShapeRebar(f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, False, spacing, orientation, self.SelectedObj, self.FaceName)
174  else:
175  if amount_check:
176  amount = self.form.amount.value()
177  rebar = editBentShapeRebar(self.Rebar, f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, True, amount, orientation, self.SelectedObj, self.FaceName)
178  elif spacing_check:
179  spacing = self.form.spacing.text()
180  spacing = FreeCAD.Units.Quantity(spacing).Value
181  rebar = editBentShapeRebar(self.Rebar, f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, False, spacing, orientation, self.SelectedObj, self.FaceName)
182  if self.CustomSpacing:
183  rebar.CustomSpacing = self.CustomSpacing
184  FreeCAD.ActiveDocument.recompute()
185  self.Rebar = rebar
186  if signal == int(QtGui.QDialogButtonBox.Apply):
187  pass
188  else:
189  FreeCADGui.Control.closeDialog(self)
190 
192  self.form.spacing.setEnabled(False)
193  self.form.amount.setEnabled(True)
194 
196  self.form.amount.setEnabled(False)
197  self.form.spacing.setEnabled(True)
198 
199 
200 def makeBentShapeRebar(f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, amount_spacing_check, amount_spacing_value, orientation = "Bottom Left", structure = None, facename = None):
201  """ makeBentShapeRebar(FrontCover, BottomCover, LeftCover, RightCover, Diameter, TopCover, BentLength, BentAngle, Rounding,
202  AmountSpacingCheck, AmountSpacingValue, Orientation, Structure, Facename): Adds the Bent-Shape reinforcement bar to the
203  selected structural object.
204  It takes four different orientations input i.e. 'Bottom', 'Top', 'Left', 'Right'.
205  """
206  if not structure and not facename:
207  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
208  structure = selected_obj.Object
209  facename = selected_obj.SubElementNames[0]
210  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
211  #StructurePRM = getTrueParametersOfStructure(structure)
212  FacePRM = getParametersOfFace(structure, facename)
213  if not FacePRM:
214  FreeCAD.Console.PrintError("Cannot identified shape or from which base object sturctural element is derived\n")
215  return
216  # Get points of L-Shape rebar
217  points = getpointsOfBentShapeRebar(FacePRM, l_cover, r_cover, b_cover, t_cover, bentLength, bentAngle, orientation)
218  import Part
219  import Arch
220  sketch = FreeCAD.activeDocument().addObject('Sketcher::SketchObject', 'Sketch')
221  sketch.MapMode = "FlatFace"
222  sketch.Support = [(structure, facename)]
223  FreeCAD.ActiveDocument.recompute()
224  sketch.addGeometry(Part.LineSegment(points[0], points[1]), False)
225  sketch.addGeometry(Part.LineSegment(points[1], points[2]), False)
226  sketch.addGeometry(Part.LineSegment(points[2], points[3]), False)
227  sketch.addGeometry(Part.LineSegment(points[3], points[4]), False)
228  sketch.addGeometry(Part.LineSegment(points[4], points[5]), False)
229  import Sketcher
230  if amount_spacing_check:
231  rebar = Arch.makeRebar(structure, sketch, diameter, amount_spacing_value, f_cover)
232  FreeCAD.ActiveDocument.recompute()
233  else:
234  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
235  rebar = Arch.makeRebar(structure, sketch, diameter, int((size - diameter) / amount_spacing_value), f_cover)
236  rebar.Rounding = rounding
237  # Adds properties to the rebar object
238  rebar.ViewObject.addProperty("App::PropertyString", "RebarShape", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Shape of rebar")).RebarShape = "BentShapeRebar"
239  rebar.ViewObject.setEditorMode("RebarShape", 2)
240  rebar.addProperty("App::PropertyDistance", "FrontCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Front cover of rebar")).FrontCover = f_cover
241  rebar.setEditorMode("FrontCover", 2)
242  rebar.addProperty("App::PropertyDistance", "LeftCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Left Side cover of rebar")).LeftCover = l_cover
243  rebar.setEditorMode("LeftCover", 2)
244  rebar.addProperty("App::PropertyDistance", "RightCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Right Side cover of rebar")).RightCover = r_cover
245  rebar.setEditorMode("RightCover", 2)
246  rebar.addProperty("App::PropertyDistance", "BottomCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Bottom cover of rebar")).BottomCover = b_cover
247  rebar.setEditorMode("BottomCover", 2)
248  rebar.addProperty("App::PropertyBool", "AmountCheck", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Amount radio button is checked")).AmountCheck
249  rebar.setEditorMode("AmountCheck", 2)
250  rebar.addProperty("App::PropertyDistance", "TopCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Top cover of rebar")).TopCover = t_cover
251  rebar.setEditorMode("TopCover", 2)
252  rebar.addProperty("App::PropertyDistance", "TrueSpacing", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Spacing between of rebars")).TrueSpacing = amount_spacing_value
253  rebar.addProperty("App::PropertyString", "Orientation", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Shape of rebar")).Orientation = orientation
254  rebar.setEditorMode("Orientation", 2)
255  rebar.setEditorMode("TrueSpacing", 2)
256  rebar.addProperty("App::PropertyDistance", "BentLength", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "BentLength cover of rebar")).BentLength = bentLength
257  rebar.setEditorMode("BentLength", 2)
258  rebar.addProperty("App::PropertyDistance", "BentAngle", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Bent Angle of rebar")).BentAngle = bentAngle
259  rebar.setEditorMode("BentAngle", 2)
260 
261  if amount_spacing_check:
262  rebar.AmountCheck = True
263  else:
264  rebar.AmountCheck = False
265  rebar.TrueSpacing = amount_spacing_value
266  rebar.Label = "BentShapeRebar"
267  FreeCAD.ActiveDocument.recompute()
268  return rebar
269 
270 def editBentShapeRebar(Rebar, f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, amount_spacing_check, amount_spacing_value, orientation, structure = None, facename = None):
271  sketch = Rebar.Base
272  if structure and facename:
273  sketch.Support = [(structure, facename)]
274  # Check if sketch support is empty.
275  if not sketch.Support:
276  showWarning("You have checked remove external geometry of base sketchs when needed.\nTo unchecked Edit->Preferences->Arch.")
277  return
278  # Assigned values
279  facename = sketch.Support[0][1][0]
280  structure = sketch.Support[0][0]
281  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
282  #StructurePRM = getTrueParametersOfStructure(structure)
283  # Get parameters of the face where sketch of rebar is drawn
284  FacePRM = getParametersOfFace(structure, facename)
285  # Get points of L-Shape rebar
286  points = getpointsOfBentShapeRebar(FacePRM, l_cover, r_cover, b_cover, t_cover, bentLength, bentAngle, orientation)
287  sketch.movePoint(0, 1, points[0], 0)
288  FreeCAD.ActiveDocument.recompute()
289  sketch.movePoint(0, 2, points[1], 0)
290  FreeCAD.ActiveDocument.recompute()
291  sketch.movePoint(1, 1, points[1], 0)
292  FreeCAD.ActiveDocument.recompute()
293  sketch.movePoint(1, 2, points[2], 0)
294  FreeCAD.ActiveDocument.recompute()
295 
296  sketch.movePoint(2, 1, points[2], 0)
297  FreeCAD.ActiveDocument.recompute()
298  sketch.movePoint(2, 2, points[3], 0)
299  FreeCAD.ActiveDocument.recompute()
300  sketch.movePoint(3, 1, points[3], 0)
301  FreeCAD.ActiveDocument.recompute()
302  sketch.movePoint(3, 2, points[4], 0)
303  FreeCAD.ActiveDocument.recompute()
304 
305  sketch.movePoint(4, 1, points[4], 0)
306  FreeCAD.ActiveDocument.recompute()
307  sketch.movePoint(4, 2, points[5], 0)
308  FreeCAD.ActiveDocument.recompute()
309 
310  Rebar.OffsetStart = f_cover
311  Rebar.OffsetEnd = f_cover
312  if amount_spacing_check:
313  Rebar.Amount = amount_spacing_value
314  FreeCAD.ActiveDocument.recompute()
315  Rebar.AmountCheck = True
316  else:
317  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
318  Rebar.Amount = int((size - diameter) / amount_spacing_value)
319  FreeCAD.ActiveDocument.recompute()
320  Rebar.AmountCheck = False
321  Rebar.Diameter = diameter
322  Rebar.FrontCover = f_cover
323  Rebar.LeftCover = l_cover
324  Rebar.RightCover = r_cover
325  Rebar.BottomCover = b_cover
326  Rebar.TopCover = t_cover
327  Rebar.BentLength = bentLength
328  Rebar.BentAngle = bentAngle
329  Rebar.Rounding = rounding
330  Rebar.TrueSpacing = amount_spacing_value
331  Rebar.Orientation = orientation
332  FreeCAD.ActiveDocument.recompute()
333  return Rebar
334 
335 def editDialog(vobj):
336  FreeCADGui.Control.closeDialog()
337  obj = _BentShapeRebarTaskPanel(vobj.Object)
338  obj.form.frontCover.setText(str(vobj.Object.FrontCover))
339  obj.form.l_sideCover.setText(str(vobj.Object.LeftCover))
340  obj.form.r_sideCover.setText(str(vobj.Object.RightCover))
341  obj.form.bottomCover.setText(str(vobj.Object.BottomCover))
342  obj.form.diameter.setText(str(vobj.Object.Diameter))
343  obj.form.topCover.setText(str(vobj.Object.TopCover))
344  obj.form.bentLength.setText(str(vobj.Object.BentLength))
345  obj.form.bentAngle.setValue(vobj.Object.BentAngle)
346  obj.form.rounding.setValue(vobj.Object.Rounding)
347  obj.form.orientation.setCurrentIndex(obj.form.orientation.findText(str(vobj.Object.Orientation)))
348  if vobj.Object.AmountCheck:
349  obj.form.amount.setValue(vobj.Object.Amount)
350  else:
351  obj.form.amount_radio.setChecked(False)
352  obj.form.spacing_radio.setChecked(True)
353  obj.form.amount.setDisabled(True)
354  obj.form.spacing.setEnabled(True)
355  obj.form.spacing.setText(str(vobj.Object.TrueSpacing))
356  #obj.form.PickSelectedFace.setVisible(False)
357  FreeCADGui.Control.showDialog(obj)
358 
360  selected_obj = check_selected_face()
361  if selected_obj:
362  FreeCADGui.Control.showDialog(_BentShapeRebarTaskPanel())
def check_selected_face()
Definition: Rebarfunc.py:255
def getSelectedFace(self)
Definition: Rebarfunc.py:278
def getFaceNumber(s)
Definition: Rebarfunc.py:72
def runRebarDistribution(self)
def getpointsOfBentShapeRebar(FacePRM, l_cover, r_cover, b_cover, t_cover, bentLength, bentAngle, orientation)
def showPopUpImageDialog(img)
Definition: PopUpImage.py:43
def removeRebarDistribution(self)
def editBentShapeRebar(Rebar, f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, amount_spacing_check, amount_spacing_value, orientation, structure=None, facename=None)
def showWarning(message)
Definition: Rebarfunc.py:293
def makeBentShapeRebar(f_cover, b_cover, l_cover, r_cover, diameter, t_cover, bentLength, bentAngle, rounding, amount_spacing_check, amount_spacing_value, orientation="Bottom Left", structure=None, facename=None)
def editDialog(vobj)
def getParametersOfFace(structure, facename, sketch=True)
Definition: Rebarfunc.py:126
def CommandBentShapeRebar()