Rebar Addon for FreeCAD
Rebarfunc.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__ = "GenericRebarFuctions"
25 __author__ = "Amritpal Singh"
26 __url__ = "https://www.freecadweb.org"
27 
28 from PySide import QtCore, QtGui
29 from DraftGeomUtils import vec, isCubic
30 import FreeCAD
31 import FreeCADGui
32 import math
33 
34 # --------------------------------------------------------------------------
35 # Generic functions
36 # --------------------------------------------------------------------------
37 
38 def getEdgesAngle(edge1, edge2):
39  """ getEdgesAngle(edge1, edge2): returns a angle between two edges."""
40  vec1 = vec(edge1)
41  vec2 = vec(edge2)
42  angle = vec1.getAngle(vec2)
43  angle = math.degrees(angle)
44  return angle
45 
46 def checkRectangle(edges):
47  """ checkRectangle(edges=[]): This function checks whether the given form rectangle
48  or not. It will return True when edges form rectangular shape or return False
49  when edges not form a rectangular."""
50  angles = [round(getEdgesAngle(edges[0], edges[1])), round(getEdgesAngle(edges[0], edges[2])),
51  round(getEdgesAngle(edges[0], edges[3]))]
52  if angles.count(90) == 2 and (angles.count(180) == 1 or angles.count(0) == 1):
53  return True
54  else:
55  return False
56 
58  """ getBaseStructuralObject(obj): This function will return last base
59  structural object."""
60  if not obj.Base:
61  return obj
62  else:
63  return getBaseStructuralObject(obj.Base)
64 
65 def getBaseObject(obj):
66  """ getBaseObject(obj): This function will return last base object."""
67  if hasattr(obj, "Base"):
68  return getBaseObject(obj.Base)
69  else:
70  return obj
71 
73  """ getFaceNumber(facename): This will return a face number from face name.
74  For eg.:
75  Input: "Face12"
76  Output: 12"""
77  head = s.rstrip('0123456789')
78  tail = s[len(head):]
79  return int(tail)
80 
81 def facenormalDirection(structure = None, facename = None):
82  if not structure and not facename:
83  selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
84  structure = selected_obj.Object
85  facename = selected_obj.SubElementNames[0]
86  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
87  normal = face.normalAt(0,0)
88  normal = face.Placement.Rotation.inverted().multVec(normal)
89  return normal
90 
91 # --------------------------------------------------------------------------
92 # Main functions which is use while creating any rebar.
93 # --------------------------------------------------------------------------
94 
96  """ getTrueParametersOfStructure(obj): This function return actual length,
97  width and height of the structural element in the form of array like
98  [Length, Width, Height]"""
99  baseObject = getBaseObject(obj)
100  # If selected_obj is not derived from any base object
101  if baseObject:
102  # If selected_obj is derived from SketchObject
103  if baseObject.isDerivedFrom("Sketcher::SketchObject"):
104  edges = baseObject.Shape.Edges
105  if checkRectangle(edges):
106  for edge in edges:
107  # Representation vector of edge
108  rep_vector = edge.Vertexes[1].Point.sub(edge.Vertexes[0].Point)
109  rep_vector_angle = round(math.degrees(rep_vector.getAngle(FreeCAD.Vector(1,0,0))))
110  if rep_vector_angle in {0, 180}:
111  length = edge.Length
112  else:
113  width = edge.Length
114  else:
115  return None
116  else:
117  return None
118  height = obj.Height.Value
119  else:
120  structuralBaseObject = getBaseStructuralObject(obj)
121  length = structuralBaseObject.Length.Value
122  width = structuralBaseObject.Width.Value
123  height = structuralBaseObject.Height.Value
124  return [length, width, height]
125 
126 def getParametersOfFace(structure, facename, sketch = True):
127  """ getParametersOfFace(structure, facename, sketch = True): This function will return
128  length, width and points of center of mass of a given face according to the sketch
129  value in the form of list.
130 
131  For eg.:
132  Case 1: When sketch is True: We use True when we want to create rebars from sketch
133  (planar rebars) and the sketch is strictly based on 2D so we neglected the normal
134  axis of the face.
135  Output: [(FaceLength, FaceWidth), (CenterOfMassX, CenterOfMassY)]
136 
137  Case 2: When sketch is False: When we want to create non-planar rebars(like stirrup)
138  or we want to create rebar from a wire. Also for creating rebar from wire
139  we will require three coordinates (x, y, z).
140  Output: [(FaceLength, FaceWidth), (CenterOfMassX, CenterOfMassY, CenterOfMassZ)]"""
141  face = structure.Shape.Faces[getFaceNumber(facename) - 1]
142  center_of_mass = face.CenterOfMass
143  #center_of_mass = center_of_mass.sub(getBaseStructuralObject(structure).Placement.Base)
144  center_of_mass = center_of_mass.sub(structure.Placement.Base)
145  Edges = []
146  facePRM = []
147  # When structure is cubic. It support all structure is derived from
148  # any other object (like a sketch, wire etc).
149  if isCubic(structure.Shape):
150  print 423
151  for edge in face.Edges:
152  if not Edges:
153  Edges.append(edge)
154  else:
155  # Checks whether similar edges is already present in Edges list
156  # or not.
157  if round((vec(edge)).Length) not in [round((vec(x)).Length) for x in Edges]:
158  Edges.append(edge)
159  if len(Edges) == 1:
160  Edges.append(edge)
161  # facePRM holds length of a edges.
162  facePRM = [(vec(edge)).Length for edge in Edges]
163  # Find the orientation of the face. Also eliminating normal axes
164  # to the edge/face.
165  # When edge is parallel to x-axis
166  if round(Edges[0].tangentAt(0)[0]) in {1,-1}:
167  x = center_of_mass[0]
168  if round(Edges[1].tangentAt(0)[1]) in {1, -1}:
169  y = center_of_mass[1]
170  else:
171  y = center_of_mass[2]
172  # When edge is parallel to y-axis
173  elif round(Edges[0].tangentAt(0)[1]) in {1,-1}:
174  x = center_of_mass[1]
175  if round(Edges[1].tangentAt(0)[0]) in {1, -1}:
176  # Change order when edge along x-axis is at second place.
177  facePRM.reverse()
178  y = center_of_mass[1]
179  else:
180  y = center_of_mass[2]
181  elif round(Edges[0].tangentAt(0)[2]) in {1,-1}:
182  y = center_of_mass[2]
183  if round(Edges[1].tangentAt(0)[0]) in {1, -1}:
184  x = center_of_mass[0]
185  else:
186  x = center_of_mass[1]
187  facePRM.reverse()
188  facelength = facePRM[0]
189  facewidth = facePRM[1]
190  # When structure is not cubic. For founding parameters of given face
191  # I have used bounding box.
192  else:
193  boundbox = face.BoundBox
194  # Check that one length of bounding box is zero. Here bounding box
195  # looks like a plane.
196  if 0 in {round(boundbox.XLength), round(boundbox.YLength), round(boundbox.ZLength)}:
197  normal = face.normalAt(0,0)
198  normal = face.Placement.Rotation.inverted().multVec(normal)
199  #print "x: ", boundbox.XLength
200  #print "y: ", boundbox.YLength
201  #print "z: ", boundbox.ZLength
202  # Set length and width of user selected face of structural element
203  flag = True
204  # FIXME: Improve below logic.
205  for i in range(len(normal)):
206  if round(normal[i]) == 0:
207  if flag and i == 0:
208  x = center_of_mass[i]
209  facelength = boundbox.XLength
210  flag = False
211  elif flag and i == 1:
212  x = center_of_mass[i]
213  facelength = boundbox.YLength
214  flag = False
215  if i == 1:
216  y = center_of_mass[i]
217  facewidth = boundbox.YLength
218  elif i == 2:
219  y = center_of_mass[i]
220  facewidth = boundbox.ZLength
221  #print [(facelength, facewidth), (x, y)]
222  # Return parameter of the face when rebar is not created from the sketch.
223  # For eg. non-planar rebars like stirrup etc.
224  if not sketch:
225  center_of_mass = face.CenterOfMass
226  return [(facelength, facewidth), center_of_mass]
227  #TODO: Add support when bounding box have depth. Here bounding box looks
228  # like cuboid. If we given curved face.
229  return [(facelength, facewidth), (x, y)]
230 
231 # -------------------------------------------------------------------------
232 # Functions which is mainly used while creating stirrup.
233 # -------------------------------------------------------------------------
234 
235 def extendedTangentPartLength(rounding, diameter, angle):
236  """ extendedTangentPartLength(rounding, diameter, angle): Get a extended
237  length of rounding on corners."""
238  radius = rounding * diameter
239  x1 = radius / math.tan(math.radians(angle))
240  x2 = radius / math.cos(math.radians(90 - angle)) - radius
241  return x1 + x2
242 
243 def extendedTangentLength(rounding, diameter, angle):
244  """ extendedTangentLength(rounding, diameter, angle): Get a extended
245  length of rounding at the end of Stirrup for bent."""
246  radius = rounding * diameter
247  x1 = radius / math.sin(math.radians(angle))
248  x2 = radius * math.tan(math.radians(90 - angle))
249  return x1 + x2
250 
251 # -------------------------------------------------------------------------
252 # Warning / Alert functions when user do something wrong.
253 #--------------------------------------------------------------------------
254 
256  """ check_selected_face(): This function checks whether user have selected
257  any face or not."""
258  selected_objs = FreeCADGui.Selection.getSelectionEx()
259  if not selected_objs:
260  showWarning("Select any face of the structural element.")
261  selected_obj = None
262  else:
263  selected_face_names = selected_objs[0].SubElementNames
264  if not selected_face_names:
265  selected_obj = None
266  showWarning("Select any face of the structural element.")
267  elif "Face" in selected_face_names[0]:
268  if len(selected_face_names) > 1:
269  showWarning("You have selected more than one face of the structural element.")
270  selected_obj = None
271  elif len(selected_face_names) == 1:
272  selected_obj = selected_objs[0]
273  else:
274  showWarning("Select any face of the selected the face.")
275  selected_obj = None
276  return selected_obj
277 
278 def getSelectedFace(self):
279  selected_objs = FreeCADGui.Selection.getSelectionEx()
280  if selected_objs:
281  if len(selected_objs[0].SubObjects) == 1:
282  if "Face" in selected_objs[0].SubElementNames[0]:
283  self.SelectedObj = selected_objs[0].Object
284  self.FaceName = selected_objs[0].SubElementNames[0]
285  self.form.PickSelectedFaceLabel.setText("Selected face is " + self.FaceName)
286  else:
287  showWarning("Select any face of the structural element.")
288  else:
289  showWarning("Select only one face of the structural element.")
290  else:
291  showWarning("Select any face of the structural element.")
292 
293 def showWarning(message):
294  """ showWarning(message): This function is used to produce warning
295  message for the user."""
296  msg = QtGui.QMessageBox()
297  msg.setIcon(QtGui.QMessageBox.Warning)
298  msg.setText(translate("RebarAddon", message))
299  msg.setStandardButtons(QtGui.QMessageBox.Ok)
300  msg.exec_()
301 
302 # Qt tanslation handling
303 def translate(context, text, disambig=None):
304  return QtCore.QCoreApplication.translate(context, text, disambig)
def getTrueParametersOfStructure(obj)
Definition: Rebarfunc.py:95
def check_selected_face()
Definition: Rebarfunc.py:255
def getBaseObject(obj)
Definition: Rebarfunc.py:65
def extendedTangentLength(rounding, diameter, angle)
Definition: Rebarfunc.py:243
def getBaseStructuralObject(obj)
Definition: Rebarfunc.py:57
def getEdgesAngle(edge1, edge2)
Definition: Rebarfunc.py:38
def getSelectedFace(self)
Definition: Rebarfunc.py:278
def getFaceNumber(s)
Definition: Rebarfunc.py:72
def showWarning(message)
Definition: Rebarfunc.py:293
def translate(context, text, disambig=None)
Definition: Rebarfunc.py:303
def checkRectangle(edges)
Definition: Rebarfunc.py:46
def getParametersOfFace(structure, facename, sketch=True)
Definition: Rebarfunc.py:126
def facenormalDirection(structure=None, facename=None)
Definition: Rebarfunc.py:81
def extendedTangentPartLength(rounding, diameter, angle)
Definition: Rebarfunc.py:235