Rebar Addon for FreeCAD
StraightRebar.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__ = "StraightRebar"
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 getpointsOfStraightRebar(FacePRM, rt_cover, lb_cover, coverAlong, orientation):
41  """ getpointsOfStraightRebar(FacePRM, RightTopcover, LeftBottomcover, CoverAlong, Orientation):
42  Return points of the Straight rebar in the form of array for sketch.
43 
44  Case I: When Orientation is 'Horizontal':
45  We have two option in CoverAlong i.e. 'Bottom Side' or 'Top Side'
46  Case II: When Orientation is 'Vertical':
47  We have two option in CoverAlong i.e. 'Left Side' or 'Right Side'
48  """
49  if orientation == "Horizontal":
50  if coverAlong[0] == "Bottom Side":
51  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + lb_cover
52  y1 = FacePRM[1][1] - FacePRM[0][1] / 2 + coverAlong[1]
53  x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + FacePRM[0][0] - rt_cover
54  y2 = FacePRM[1][1] - FacePRM[0][1] / 2 + coverAlong[1]
55  elif coverAlong[0] == "Top Side":
56  cover = FacePRM[0][1] - coverAlong[1]
57  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + lb_cover
58  y1 = FacePRM[1][1] - FacePRM[0][1] / 2 + cover
59  x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + FacePRM[0][0] - rt_cover
60  y2 = FacePRM[1][1] - FacePRM[0][1] / 2 + cover
61  elif orientation == "Vertical":
62  if coverAlong[0] == "Left Side":
63  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + coverAlong[1]
64  y1 = FacePRM[1][1] - FacePRM[0][1] / 2 + lb_cover
65  x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + coverAlong[1]
66  y2 = FacePRM[1][1] - FacePRM[0][1] / 2 + FacePRM[0][1] - rt_cover
67  elif coverAlong[0] == "Right Side":
68  cover = FacePRM[0][0] - coverAlong[1]
69  x1 = FacePRM[1][0] - FacePRM[0][0] / 2 + cover
70  y1 = FacePRM[1][1] - FacePRM[0][1] / 2 + lb_cover
71  x2 = FacePRM[1][0] - FacePRM[0][0] / 2 + cover
72  y2 = FacePRM[1][1] - FacePRM[0][1] / 2 + FacePRM[0][1] - rt_cover
73  return [FreeCAD.Vector(x1, y1, 0), FreeCAD.Vector(x2, y2, 0)]
74 
76  def __init__(self, Rebar = None):
77  self.CustomSpacing = None
78  if not Rebar:
79  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
80  self.SelectedObj = selected_obj.Object
81  self.FaceName = selected_obj.SubElementNames[0]
82  else:
83  self.FaceName = Rebar.Base.Support[0][1][0]
84  self.SelectedObj = Rebar.Base.Support[0][0]
85  self.form = FreeCADGui.PySideUic.loadUi(os.path.splitext(__file__)[0] + ".ui")
86  self.form.setWindowTitle(QtGui.QApplication.translate("RebarAddon", "Straight Rebar", None))
87  self.form.orientation.addItems(["Horizontal", "Vertical"])
88  self.form.coverAlong.addItems(["Bottom Side", "Top Side"])
89  self.form.amount_radio.clicked.connect(self.amount_radio_clicked)
90  self.form.spacing_radio.clicked.connect(self.spacing_radio_clicked)
91  self.form.customSpacing.clicked.connect(lambda: runRebarDistribution(self))
92  self.form.removeCustomSpacing.clicked.connect(lambda: removeRebarDistribution(self))
93  self.form.PickSelectedFace.setCheckable(True)
94  self.form.PickSelectedFace.toggle()
95  self.form.PickSelectedFace.clicked.connect(lambda: getSelectedFace(self))
96  self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/StraightRebarH.svg"))
97  self.form.orientation.currentIndexChanged.connect(self.changeOrientation)
98  self.form.coverAlong.currentIndexChanged.connect(self.changeCoverAlong)
99  self.form.toolButton.setIcon(self.form.toolButton.style().standardIcon(QtGui.QStyle.SP_DialogHelpButton))
100  self.form.toolButton.clicked.connect(lambda: showPopUpImageDialog(os.path.split(os.path.abspath(__file__))[0] + "/icons/StraightRebarDetailed.svg"))
101  self.Rebar = Rebar
102 
103  def changeOrientation(self):
104  orientation = self.form.orientation.currentText()
105  if orientation == "Horizontal":
106  self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/StraightRebarH.svg"))
107  self.form.r_sideCoverLabel.setText("Right Side Cover")
108  self.form.l_sideCoverLabel.setText("Left Side Cover")
109  self.form.coverAlong.clear()
110  self.form.coverAlong.addItems(["Bottom Side", "Top Side"])
111  else:
112  self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/StraightRebarV.svg"))
113  self.form.r_sideCoverLabel.setText("Top Side Cover")
114  self.form.l_sideCoverLabel.setText("Bottom Side Cover")
115  self.form.coverAlong.clear()
116  self.form.coverAlong.addItems(["Right Side", "Left Side"])
117 
118  def changeCoverAlong(self):
119  coverAlong = self.form.coverAlong.currentText()
120  if coverAlong == "Bottom Side":
121  self.form.bottomCoverLabel.setText("Bottom Cover")
122  elif coverAlong == "Top Side":
123  self.form.bottomCoverLabel.setText("Top Cover")
124  elif coverAlong == "Right Side":
125  self.form.bottomCoverLabel.setText("Right Cover")
126  else:
127  self.form.bottomCoverLabel.setText("Left Cover")
128 
130  return int(QtGui.QDialogButtonBox.Ok) | int(QtGui.QDialogButtonBox.Apply) | int(QtGui.QDialogButtonBox.Cancel)
131 
132  def clicked(self, button):
133  if button == int(QtGui.QDialogButtonBox.Apply):
134  self.accept(button)
135 
136  def accept(self, signal = None):
137  f_cover = self.form.frontCover.text()
138  f_cover = FreeCAD.Units.Quantity(f_cover).Value
139  cover = self.form.bottomCover.text()
140  cover = FreeCAD.Units.Quantity(cover).Value
141  lb_cover = self.form.l_sideCover.text()
142  lb_cover = FreeCAD.Units.Quantity(lb_cover).Value
143  rt_cover = self.form.r_sideCover.text()
144  rt_cover = FreeCAD.Units.Quantity(rt_cover).Value
145  orientation = self.form.orientation.currentText()
146  coverAlong = self.form.coverAlong.currentText()
147  diameter = self.form.diameter.text()
148  diameter = FreeCAD.Units.Quantity(diameter).Value
149  amount_check = self.form.amount_radio.isChecked()
150  spacing_check = self.form.spacing_radio.isChecked()
151  if not self.Rebar:
152  if amount_check:
153  amount = self.form.amount.value()
154  rebar = makeStraightRebar(f_cover, (coverAlong, cover), rt_cover, lb_cover, diameter, True, amount, orientation, self.SelectedObj, self.FaceName)
155  elif spacing_check:
156  spacing = self.form.spacing.text()
157  spacing = FreeCAD.Units.Quantity(spacing).Value
158  rebar = makeStraightRebar(f_cover, (coverAlong, cover), rt_cover, lb_cover, diameter, False, spacing, orientation, self.SelectedObj, self.FaceName)
159  else:
160  if amount_check:
161  amount = self.form.amount.value()
162  rebar = editStraightRebar(self.Rebar, f_cover, (coverAlong, cover), rt_cover, lb_cover, diameter, True, amount, orientation, self.SelectedObj, self.FaceName)
163  elif spacing_check:
164  spacing = self.form.spacing.text()
165  spacing = FreeCAD.Units.Quantity(spacing).Value
166  rebar = editStraightRebar(self.Rebar, f_cover, (coverAlong, cover), rt_cover, lb_cover, diameter, False, spacing, orientation, self.SelectedObj, self.FaceName)
167  if self.CustomSpacing:
168  rebar.CustomSpacing = self.CustomSpacing
169  FreeCAD.ActiveDocument.recompute()
170  self.Rebar = rebar
171  if signal == int(QtGui.QDialogButtonBox.Apply):
172  pass
173  else:
174  FreeCADGui.Control.closeDialog(self)
175 
177  self.form.spacing.setEnabled(False)
178  self.form.amount.setEnabled(True)
179 
181  self.form.amount.setEnabled(False)
182  self.form.spacing.setEnabled(True)
183 
184 
185 def makeStraightRebar(f_cover, coverAlong, rt_cover, lb_cover, diameter, amount_spacing_check, amount_spacing_value, orientation = "Horizontal", structure = None, facename = None):
186  """ Adds the straight reinforcement bar to the selected structural object.
187 
188  Case I: When orientation of straight rebar is 'Horizontal':
189  makeStraightRebar(FrontCover, CoverAlong, RightCover, LeftCover, Diameter, AmountSpacingCheck, AmountSpacingValue, Orientation = "Horizontal",
190  Structure, Facename)
191  Note: Type of CoverAlong argument is a tuple. Syntax: (<Along>, <Value>). Here we have horizontal orientation so we can pass Top Side
192  and Bottom Side to <Along> arguments.
193  For eg. ("Top Side", 20) and ("Bottom Side", 20)
194 
195  Case II: When orientation of straight rebar is 'Vertical':
196  makeStraightRebar(FrontCover, CoverAlong, TopCover, BottomCover, Diameter, AmountSpacingCheck, AmountSpacingValue, Orientation = "Horizontal",
197  Structure, Facename)
198  Note: Type of CoverAlong argument is a tuple. Syntax: (<Along>, <Value>). Here we have vertical orientation so we can pass Left Side
199  and Right Side to <Along> arguments.
200  For eg. ("Left Side", 20) and ("Right Side", 20)
201  """
202  if not structure and not facename:
203  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
204  structure = selected_obj.Object
205  facename = selected_obj.SubElementNames[0]
206  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
207  #StructurePRM = getTrueParametersOfStructure(structure)
208  FacePRM = getParametersOfFace(structure, facename)
209  if not FacePRM:
210  FreeCAD.Console.PrintError("Cannot identified shape or from which base object sturctural element is derived\n")
211  return
212  # Get points of Striaght rebar
213  points = getpointsOfStraightRebar(FacePRM, rt_cover, lb_cover, coverAlong, orientation)
214  import Part
215  import Arch
216  sketch = FreeCAD.activeDocument().addObject('Sketcher::SketchObject', 'Sketch')
217  sketch.MapMode = "FlatFace"
218  sketch.Support = [(structure, facename)]
219  FreeCAD.ActiveDocument.recompute()
220  sketch.addGeometry(Part.LineSegment(points[0], points[1]), False)
221  if amount_spacing_check:
222  rebar = Arch.makeRebar(structure, sketch, diameter, amount_spacing_value, f_cover)
223  FreeCAD.ActiveDocument.recompute()
224  else:
225  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
226  rebar = Arch.makeRebar(structure, sketch, diameter, int((size - diameter) / amount_spacing_value), f_cover)
227  # Adds properties to the rebar object
228  rebar.ViewObject.addProperty("App::PropertyString", "RebarShape", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Shape of rebar")).RebarShape = "StraightRebar"
229  rebar.ViewObject.setEditorMode("RebarShape", 2)
230  rebar.addProperty("App::PropertyDistance", "FrontCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Front cover of rebar")).FrontCover = f_cover
231  rebar.setEditorMode("FrontCover", 2)
232  rebar.addProperty("App::PropertyDistance", "RightTopCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Right/Top Side cover of rebar")).RightTopCover = rt_cover
233  rebar.setEditorMode("RightTopCover", 2)
234  rebar.addProperty("App::PropertyDistance", "LeftBottomCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Left/Bottom Side cover of rebar")).LeftBottomCover = lb_cover
235  rebar.setEditorMode("LeftBottomCover", 2)
236  rebar.addProperty("App::PropertyString", "CoverAlong", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Cover along")).CoverAlong = coverAlong[0]
237  rebar.setEditorMode("CoverAlong", 2)
238  rebar.addProperty("App::PropertyDistance", "Cover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Cover of rebar along user selected side")).Cover = coverAlong[1]
239  rebar.setEditorMode("Cover", 2)
240  rebar.addProperty("App::PropertyBool", "AmountCheck", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Amount radio button is checked")).AmountCheck
241  rebar.setEditorMode("AmountCheck", 2)
242  rebar.addProperty("App::PropertyDistance", "TrueSpacing", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Spacing between of rebars")).TrueSpacing = amount_spacing_value
243  rebar.setEditorMode("TrueSpacing", 2)
244  rebar.addProperty("App::PropertyString", "Orientation", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Shape of rebar")).Orientation = orientation
245  rebar.setEditorMode("Orientation", 2)
246  if amount_spacing_check:
247  rebar.AmountCheck = True
248  else:
249  rebar.AmountCheck = False
250  rebar.TrueSpacing = amount_spacing_value
251  rebar.Label = "StraightRebar"
252  FreeCAD.ActiveDocument.recompute()
253  return rebar
254 
255 def editStraightRebar(Rebar, f_cover, coverAlong, rt_cover, lb_cover, diameter, amount_spacing_check, amount_spacing_value, orientation, structure = None, facename = None):
256  sketch = Rebar.Base
257  if structure and facename:
258  sketch.Support = [(structure, facename)]
259  FreeCAD.ActiveDocument.recompute()
260  # Check if sketch support is empty.
261  if not sketch.Support:
262  showWarning("You have checked remove external geometry of base sketchs when needed.\nTo unchecked Edit->Preferences->Arch.")
263  return
264  # Assigned values
265  facename = sketch.Support[0][1][0]
266  structure = sketch.Support[0][0]
267  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
268  #StructurePRM = getTrueParametersOfStructure(structure)
269  # Get parameters of the face where sketch of rebar is drawn
270  FacePRM = getParametersOfFace(structure, facename)
271  # Get points of Striaght rebar
272  points = getpointsOfStraightRebar(FacePRM, rt_cover, lb_cover, coverAlong, orientation)
273  sketch.movePoint(0, 1, points[0], 0)
274  FreeCAD.ActiveDocument.recompute()
275  sketch.movePoint(0, 2, points[1], 0)
276  FreeCAD.ActiveDocument.recompute()
277  Rebar.OffsetStart = f_cover
278  Rebar.OffsetEnd = f_cover
279  if amount_spacing_check:
280  Rebar.Amount = amount_spacing_value
281  FreeCAD.ActiveDocument.recompute()
282  Rebar.AmountCheck = True
283  else:
284  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
285  Rebar.Amount = int((size - diameter) / amount_spacing_value)
286  FreeCAD.ActiveDocument.recompute()
287  Rebar.AmountCheck = False
288  Rebar.FrontCover = f_cover
289  Rebar.RightTopCover = rt_cover
290  Rebar.LeftBottomCover = lb_cover
291  Rebar.CoverAlong = coverAlong[0]
292  Rebar.Cover = coverAlong[1]
293  Rebar.TrueSpacing = amount_spacing_value
294  Rebar.Diameter = diameter
295  Rebar.Orientation = orientation
296  FreeCAD.ActiveDocument.recompute()
297  return Rebar
298 
299 def editDialog(vobj):
300  FreeCADGui.Control.closeDialog()
301  obj = _StraightRebarTaskPanel(vobj.Object)
302  obj.form.frontCover.setText(str(vobj.Object.FrontCover))
303  obj.form.r_sideCover.setText(str(vobj.Object.RightTopCover))
304  obj.form.l_sideCover.setText(str(vobj.Object.LeftBottomCover))
305  obj.form.bottomCover.setText(str(vobj.Object.Cover))
306  obj.form.diameter.setText(str(vobj.Object.Diameter))
307  obj.form.orientation.setCurrentIndex(obj.form.orientation.findText(str(vobj.Object.Orientation)))
308  obj.form.coverAlong.setCurrentIndex(obj.form.coverAlong.findText(str(vobj.Object.CoverAlong)))
309  if vobj.Object.AmountCheck:
310  obj.form.amount.setValue(vobj.Object.Amount)
311  else:
312  obj.form.amount_radio.setChecked(False)
313  obj.form.spacing_radio.setChecked(True)
314  obj.form.amount.setDisabled(True)
315  obj.form.spacing.setEnabled(True)
316  obj.form.spacing.setText(str(vobj.Object.TrueSpacing))
317  #obj.form.PickSelectedFace.setVisible(False)
318  FreeCADGui.Control.showDialog(obj)
319 
321  selected_obj = check_selected_face()
322  if selected_obj:
323  FreeCADGui.Control.showDialog(_StraightRebarTaskPanel())
def check_selected_face()
Definition: Rebarfunc.py:255
def getpointsOfStraightRebar(FacePRM, rt_cover, lb_cover, coverAlong, orientation)
def getSelectedFace(self)
Definition: Rebarfunc.py:278
def getFaceNumber(s)
Definition: Rebarfunc.py:72
def runRebarDistribution(self)
def showPopUpImageDialog(img)
Definition: PopUpImage.py:43
def removeRebarDistribution(self)
def showWarning(message)
Definition: Rebarfunc.py:293
def CommandStraightRebar()
def editDialog(vobj)
def editStraightRebar(Rebar, f_cover, coverAlong, rt_cover, lb_cover, diameter, amount_spacing_check, amount_spacing_value, orientation, structure=None, facename=None)
def getParametersOfFace(structure, facename, sketch=True)
Definition: Rebarfunc.py:126
def makeStraightRebar(f_cover, coverAlong, rt_cover, lb_cover, diameter, amount_spacing_check, amount_spacing_value, orientation="Horizontal", structure=None, facename=None)