Rebar Addon for FreeCAD
HelicalRebar.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__ = "HelicalRebar"
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 PopUpImage import showPopUpImageDialog
32 import FreeCAD
33 import FreeCADGui
34 import ArchCommands
35 import os
36 import sys
37 import math
38 
39 def getpointsOfHelicalRebar(FacePRM, s_cover, b_cover, t_cover, pitch, edges, diameter, size, direction):
40  """ getpointsOfHelicalRebar(FacePRM, s_cover, b_cover, t_cover):
41  Return points of the LShape rebar in the form of array for sketch."""
42  dx = s_cover + diameter / 2
43  dz = float(pitch) / edges
44  R = diameter / 2 - dx
45  R = FacePRM[0][0] / 2 - s_cover
46  points = []
47  if direction[2] in {-1,1}:
48  z = 0
49  l = 0
50  if direction[2] == 1:
51  zz = FacePRM[1][2] - t_cover
52  elif direction[2] == -1:
53  zz = FacePRM[1][2] + b_cover
54  count = 0
55  flag = False
56  while (round(z) < abs(size - b_cover - t_cover)):
57  for i in range(0, int(edges) + 1):
58  if not i and flag:
59  continue
60  if not flag:
61  z -= dz
62  flag = True
63  iAngle = i * 360 / edges
64  x = FacePRM[1][0] + R * math.cos(math.radians(iAngle))
65  y = FacePRM[1][1] + R * math.sin(math.radians(iAngle))
66  points.append(FreeCAD.Vector(x, y, zz))
67  count += 1
68  if direction[2] == 1:
69  zz -= dz
70  elif direction[2] == -1:
71  zz += dz
72  z += dz
73  return points
74 
75 def createHelicalWire(FacePRM, s_cover, b_cover, t_cover, pitch, size, direction, helix = None):
76  """ createHelicalWire(FacePRM, SideCover, BottomCover, TopCover, Pitch, Size, Direction, Helix = None):
77  It creates a helical wire."""
78  import Part
79  if not helix:
80  helix = FreeCAD.ActiveDocument.addObject("Part::Helix","Helix")
81  helix.Pitch = pitch
82  helix.Radius = FacePRM[0][0] / 2 - s_cover
83  helix.Angle = 0
84  helix.LocalCoord = 0
85  helix.Height = size - b_cover - t_cover
86  if round(direction.x) == 1:
87  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0] - b_cover, FacePRM[1][1], FacePRM[1][2])
88  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, -1, 0), 90)
89  elif round(direction.x) == -1:
90  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0] + t_cover, FacePRM[1][1], FacePRM[1][2])
91  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, -1, 0), -90)
92  elif round(direction.y) == 1:
93  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0], FacePRM[1][1] - b_cover, FacePRM[1][2])
94  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 90)
95  elif round(direction.y) == -1:
96  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0], FacePRM[1][1] + t_cover, FacePRM[1][2])
97  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(-1, 0, 0), 90)
98  elif round(direction.z) == 1:
99  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0], FacePRM[1][1], FacePRM[1][2] - size + b_cover)
100  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0)
101  elif round(direction.z) == -1:
102  helix.Placement.Base = FreeCAD.Vector(FacePRM[1][0], FacePRM[1][1], FacePRM[1][2] + b_cover)
103  helix.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(0, 0, -1), 0)
104  FreeCAD.ActiveDocument.recompute()
105  return helix
106 
108  def __init__(self, Rebar = None):
109  self.form = FreeCADGui.PySideUic.loadUi(os.path.splitext(__file__)[0] + ".ui")
110  self.form.setWindowTitle(QtGui.QApplication.translate("Arch", "Helical Rebar", None))
111  if not Rebar:
112  normal = facenormalDirection()
113  else:
114  normal = facenormalDirection(Rebar.Base.Support[0][0], Rebar.Base.Support[0][1][0])
115  if not round(normal.z) in {1, -1}:
116  self.form.topCoverLabel.setText(translate("RebarAddon", "Left Cover"))
117  self.form.bottomCoverLabel.setText(translate("RebarAddon", "Right Cover"))
118  self.form.PickSelectedFace.clicked.connect(self.getSelectedFace)
119  self.form.image.setPixmap(QtGui.QPixmap(os.path.split(os.path.abspath(__file__))[0] + "/icons/HelicalRebar.svg"))
120  self.form.toolButton.clicked.connect(lambda: showPopUpImageDialog(os.path.split(os.path.abspath(__file__))[0] + "/icons/HelicalRebarDetailed.svg"))
121  self.form.toolButton.setIcon(self.form.toolButton.style().standardIcon(QtGui.QStyle.SP_DialogHelpButton))
122  self.Rebar = Rebar
123  self.SelectedObj = None
124  self.FaceName = None
125 
127  return int(QtGui.QDialogButtonBox.Ok) | int(QtGui.QDialogButtonBox.Apply) | int(QtGui.QDialogButtonBox.Cancel)
128 
129  def clicked(self, button):
130  if button == int(QtGui.QDialogButtonBox.Apply):
131  self.accept(button)
132 
133  def getSelectedFace(self):
134  getSelectedFace(self)
135  normal = facenormalDirection()
136  if not round(normal.z) in {1, -1}:
137  self.form.topCoverLabel.setText(translate("RebarAddon", "Left Cover"))
138  self.form.bottomCoverLabel.setText(translate("RebarAddon", "Right Cover"))
139  else:
140  self.form.topCoverLabel.setText(translate("RebarAddon", "Top Cover"))
141  self.form.bottomCoverLabel.setText(translate("RebarAddon", "Bottom Cover"))
142 
143 
144  def accept(self, signal = None):
145  b_cover = self.form.bottomCover.text()
146  b_cover = FreeCAD.Units.Quantity(b_cover).Value
147  s_cover = self.form.sideCover.text()
148  s_cover = FreeCAD.Units.Quantity(s_cover).Value
149  t_cover = self.form.topCover.text()
150  t_cover = FreeCAD.Units.Quantity(t_cover).Value
151  pitch = self.form.pitch.text()
152  pitch = FreeCAD.Units.Quantity(pitch).Value
153  diameter = self.form.diameter.text()
154  diameter = FreeCAD.Units.Quantity(diameter).Value
155  if not self.Rebar:
156  rebar = makeHelicalRebar(s_cover, b_cover, diameter, t_cover, pitch, self.SelectedObj, self.FaceName)
157  else:
158  rebar = editHelicalRebar(self.Rebar, s_cover, b_cover, diameter, t_cover, pitch, self.SelectedObj, self.FaceName)
159  self.Rebar = rebar
160  if signal == int(QtGui.QDialogButtonBox.Apply):
161  pass
162  else:
163  FreeCADGui.Control.closeDialog(self)
164 
165 def makeHelicalRebar(s_cover, b_cover, diameter, t_cover, pitch, structure = None, facename = None):
166  """ makeHelicalRebar(SideCover, BottomCover, Diameter, TopCover, Pitch, Structure, Facename):
167  Adds the Helical reinforcement bar to the selected structural object."""
168  if not structure and not facename:
169  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
170  structure = selected_obj.Object
171  facename = selected_obj.SubElementNames[0]
172  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
173  #StructurePRM = getTrueParametersOfStructure(structure)
174  FacePRM = getParametersOfFace(structure, facename, False)
175  if not FacePRM:
176  FreeCAD.Console.PrintError("Cannot identified shape or from which base object sturctural element is derived\n")
177  return
178  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
179  normal = face.normalAt(0,0)
180  #normal = face.Placement.Rotation.inverted().multVec(normal)
181  import Arch
182  helix = createHelicalWire(FacePRM, s_cover, b_cover, t_cover, pitch, size, normal)
183  helix.Support = [(structure, facename)]
184  rebar = Arch.makeRebar(structure, helix, diameter, 1, 0)
185  rebar.OffsetStart = 0
186  rebar.OffsetEnd = 0
187  FreeCAD.ActiveDocument.recompute()
188  # Adds properties to the rebar object
189  rebar.ViewObject.addProperty("App::PropertyString", "RebarShape", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Shape of rebar")).RebarShape = "HelicalRebar"
190  rebar.ViewObject.setEditorMode("RebarShape", 2)
191  rebar.addProperty("App::PropertyDistance", "SideCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Front cover of rebar")).SideCover = s_cover
192  rebar.setEditorMode("SideCover", 2)
193  rebar.addProperty("App::PropertyDistance", "Pitch", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Left Side cover of rebar")).Pitch = pitch
194  rebar.setEditorMode("Pitch", 2)
195  rebar.addProperty("App::PropertyDistance", "BottomCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Bottom cover of rebar")).BottomCover = b_cover
196  rebar.setEditorMode("BottomCover", 2)
197  rebar.addProperty("App::PropertyDistance", "TopCover", "RebarDialog", QT_TRANSLATE_NOOP("App::Property", "Top cover of rebar")).TopCover = t_cover
198  rebar.setEditorMode("TopCover", 2)
199  rebar.Label = "HelicalRebar"
200  FreeCAD.ActiveDocument.recompute()
201  return rebar
202 
203 def editHelicalRebar(Rebar, s_cover, b_cover, diameter, t_cover, pitch, structure = None, facename = None):
204  sketch = Rebar.Base
205  if structure and facename:
206  sketch.Support = [(structure, facename)]
207  # Check if sketch support is empty.
208  if not sketch.Support:
209  showWarning("You have checked remove external geometry of base sketchs when needed.\nTo unchecked Edit->Preferences->Arch.")
210  return
211  # Assigned values
212  facename = sketch.Support[0][1][0]
213  structure = sketch.Support[0][0]
214  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
215  #StructurePRM = getTrueParametersOfStructure(structure)
216  # Get parameters of the face where sketch of rebar is drawn
217  FacePRM = getParametersOfFace(structure, facename, False)
218  size = (ArchCommands.projectToVector(structure.Shape.copy(), face.normalAt(0, 0))).Length
219  normal = face.normalAt(0,0)
220  #normal = face.Placement.Rotation.inverted().multVec(normal)
221  helix = createHelicalWire(FacePRM, s_cover, b_cover, t_cover, pitch, size, normal, Rebar.Base)
222  FreeCAD.ActiveDocument.recompute()
223  Rebar.Diameter = diameter
224  Rebar.SideCover = s_cover
225  Rebar.BottomCover = b_cover
226  Rebar.TopCover = t_cover
227  Rebar.Pitch = pitch
228  FreeCAD.ActiveDocument.recompute()
229  return Rebar
230 
231 def editDialog(vobj):
232  FreeCADGui.Control.closeDialog()
233  obj = _HelicalRebarTaskPanel(vobj.Object)
234  obj.form.sideCover.setText(str(vobj.Object.SideCover))
235  obj.form.bottomCover.setText(str(vobj.Object.BottomCover))
236  obj.form.diameter.setText(str(vobj.Object.Diameter))
237  obj.form.topCover.setText(str(vobj.Object.TopCover))
238  obj.form.pitch.setText(str(vobj.Object.Pitch))
239  FreeCADGui.Control.showDialog(obj)
240 
242  selected_obj = check_selected_face()
243  if selected_obj:
244  FreeCADGui.Control.showDialog(_HelicalRebarTaskPanel())
def check_selected_face()
Definition: Rebarfunc.py:255
def CommandHelicalRebar()
def accept(self, signal=None)
def __init__(self, Rebar=None)
def getFaceNumber(s)
Definition: Rebarfunc.py:72
def editDialog(vobj)
def editHelicalRebar(Rebar, s_cover, b_cover, diameter, t_cover, pitch, structure=None, facename=None)
def showPopUpImageDialog(img)
Definition: PopUpImage.py:43
def showWarning(message)
Definition: Rebarfunc.py:293
def translate(context, text, disambig=None)
Definition: Rebarfunc.py:303
def getParametersOfFace(structure, facename, sketch=True)
Definition: Rebarfunc.py:126
def facenormalDirection(structure=None, facename=None)
Definition: Rebarfunc.py:81
def makeHelicalRebar(s_cover, b_cover, diameter, t_cover, pitch, structure=None, facename=None)
def getpointsOfHelicalRebar(FacePRM, s_cover, b_cover, t_cover, pitch, edges, diameter, size, direction)
Definition: HelicalRebar.py:39
def createHelicalWire(FacePRM, s_cover, b_cover, t_cover, pitch, size, direction, helix=None)
Definition: HelicalRebar.py:75