Last active
September 17, 2019 08:34
-
-
Save VonMoustachen/b54f0afd134efd426f62 to your computer and use it in GitHub Desktop.
SHM: addWall tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# FreeCAD sheet metal workbench: addWall tool. | |
# (c) 2014 Javier Martínez García | |
#*************************************************************************** | |
#* (c) Javier Martínez García 2014 * | |
#* * | |
#* This program is free software; you can redistribute it and/or modify * | |
#* it under the terms of the GNU Lesser General Public License (LGPL) * | |
#* as published by the Free Software Foundation; either version 2 of * | |
#* the License, or (at your option) any later version. * | |
#* for detail see the LICENCE text file. * | |
#* * | |
#* This macro is distributed in the hope that it will be useful, * | |
#* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
#* GNU Lesser General Public License for more details. * | |
#* * | |
#* You should have received a copy of the GNU Library General Public * | |
#* License along with FreeCAD; if not, write to the Free Software * | |
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * | |
#* USA * | |
#* * | |
#***************************************************************************/ | |
from FreeCAD import Gui | |
import Part | |
def addWall(thk = 1.0, bendR = 3.0, alpha = 90, L1 = 0.0, L2 = 0.0 , relief = True, rlfWidth = 0.5, | |
rlfDepth = 1.0, inverted = False, create = True, sketch = False ): | |
selFace = Gui.Selection.getSelectionEx()[0].SubObjects[0] | |
selObjectName = Gui.Selection.getSelection()[0].Name | |
# get thickness direction | |
for edge in selFace.Edges: | |
if abs( edge.Length - thk ) < 0.01: | |
V_thDir = ( edge.valueAt( 0.0 ) - edge.valueAt( edge.Length ) ).normalize() | |
break | |
print V_thDir | |
# One point of the revolution axis | |
if inverted: | |
P_revAxis = selFace.CenterOfMass + V_thDir*0.5*thk + V_thDir*bendR | |
else: | |
P_revAxis = selFace.CenterOfMass - V_thDir*0.5*thk - V_thDir*bendR | |
# Direction of the revolution axis | |
for edge in selFace.Edges: | |
if abs( edge.Length - thk ) > 0.01: | |
V_revAxis = ( edge.valueAt( 0.0 ) - edge.valueAt( edge.Length) ).normalize() | |
break | |
# Auxiliar rectangle over face (L1, L2), square relief generator | |
if L1 > 0.0 and L2 > 0.0 and relief: | |
firstDone = True | |
for edge in selFace.Edges: | |
if edge.Length > thk: | |
if firstDone: | |
V_edge0 = ( edge.valueAt(edge.Length ) - edge.valueAt( 0.0 ) ).normalize() | |
p1 = Part.Vertex( edge.valueAt(0.0 ) + V_edge0*L1 ) | |
p2 = Part.Vertex( edge.valueAt( edge.Length ) - V_edge0*L2 ) | |
firstDone = False | |
if not(firstDone): | |
V_edge1 = ( edge.valueAt(edge.Length ) - edge.valueAt( 0.0 ) ).normalize() | |
p3 = Part.Vertex( edge.valueAt(0.0 ) + V_edge1*L1 ) | |
p4 = Part.Vertex( edge.valueAt( edge.Length ) - V_edge1*L2 ) | |
points = [ p1.Point, p2.Point, p4.Point, p3.Point, p1.Point ] | |
lines = [] | |
for i in range( len( points ) - 1 ): | |
l = Part.makeLine( points[i], points[i+1] ) | |
lines.append( l ) | |
Rectangle = Part.Wire( lines ) | |
RevFace = Part.Face( Rectangle ) | |
# side 1, points 1 and 3, V_edge1 | |
side1P1 = p1.Point | |
side1P2 = p1.Point - V_edge1*rlfWidth | |
side1P3 = p3.Point | |
side1P4 = p3.Point - V_edge1*rlfWidth | |
side1Points = [ side1P1, side1P2, side1P4, side1P3, side1P1 ] | |
side1Lines = [] | |
for i in range( len( side1Points ) - 1 ): | |
p0 = side1Points[i] | |
p1 = side1Points[i+1] | |
l = Part.makeLine( p0, p1 ) | |
side1Lines.append( l ) | |
side1Rectangle = Part.Wire( side1Lines ) | |
reliefSide1Face = Part.Face( side1Rectangle ) | |
relief1 = reliefSide1Face.extrude( ( ( selFace.normalAt(0,0)).normalize() )*-rlfDepth ) | |
# side 2, points 2 and 4, V_edge0 | |
side2P1 = p2.Point | |
side2P2 = p2.Point + V_edge1*rlfWidth | |
side2P3 = p4.Point + V_edge1*rlfWidth | |
side2P4 = p4.Point | |
side2Points = [ side2P1, side2P2, side2P3, side2P4, side2P1 ] | |
side2Lines = [] | |
for i in range( len( side2Points ) - 1 ): | |
p0 = side2Points[i] | |
p1 = side2Points[i+1] | |
l = Part.makeLine( p0, p1 ) | |
side2Lines.append( l ) | |
side2Rectangle = Part.Wire( side2Lines ) | |
reliefSide2Face = Part.Face( side2Rectangle ) | |
relief2 = reliefSide2Face.extrude( ( ( selFace.normalAt(0,0)).normalize() )*-rlfDepth ) | |
# Revolve selFace | |
try: | |
bend = RevFace.revolve( P_revAxis, V_revAxis, alpha) | |
except: | |
RevFace = selFace | |
bend = selFace.revolve( P_revAxis, V_revAxis, alpha) | |
# Revolution angle correction (this is needed to not intersect original shape ) | |
P_BendDirTest = RevFace.CenterOfMass + RevFace.normalAt(0,0)*0.001 | |
if not(bend.isInside( P_BendDirTest, 0.0001, False )): | |
bend = RevFace.revolve( P_revAxis, V_revAxis, -alpha) | |
# Create wall | |
# get wall base face for extrude: | |
for face in bend.Faces: | |
COM = face.CenterOfMass | |
area = face.Area | |
if area == RevFace.Area and COM != RevFace.CenterOfMass: | |
break | |
# extrusion direction | |
V_extDir = face.normalAt( 0,0 ) | |
# extrusion magnitude | |
for edge in face.Edges: | |
if edge.Length != thk: | |
extLength = edge.Length | |
break | |
# extrusion | |
wallFace = face.extrude( V_extDir*extLength ) | |
# get wallFace characteristics for sketch support | |
P_wallFaceCOM = wallFace.CenterOfMass | |
# Fusion of bend and wall | |
newWall = wallFace.fuse( bend ) | |
# Add temporal object to de document for updatable display | |
AAD = App.ActiveDocument | |
if not(create): | |
Dobj = AAD.addObject( "Part::Feature", "temporalbend" ) | |
Dobj.Shape = newWall | |
else: | |
MainObject = AAD.getObject( selObjectName ) | |
finalShape = MainObject.Shape.fuse( newWall ) | |
if L1 > 0 and L2 > 0 and relief: | |
finalShape = finalShape.cut( relief1 ) # cut square relief1 | |
finalShape = finalShape.cut( relief2 ) # cut square relief2 | |
FinalObject = AAD.addObject( "Part::Feature", "SHM_Wall" ) | |
FinalObject.Shape = finalShape | |
Gui.ActiveDocument.getObject( selObjectName ).Visibility = False | |
n=1 | |
for face in FinalObject.Shape.Faces: | |
if P_wallFaceCOM == face.CenterOfMass - face.normalAt(0,0)*0.5*thk: | |
break | |
n+=1 | |
if sketch: | |
createSketch = AAD.addObject( 'Sketcher::SketchObject', 'Wall Sketch' ) | |
sketchName = createSketch.Label | |
createSketch.Support = ( AAD.getObject( FinalObject.Label), ["Face%d"%n] ) | |
AAD.recompute() | |
Gui.updateGui() | |
Gui.ActiveDocument.setEdit( createSketch.Name ) | |
AAD.recompute() | |
Gui.updateGui() | |
# call function to use this script as copy-paste: | |
addWall( create = True, L1 = 0, L2 = 0 ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment