Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
SHM: addWall tool
# -*- 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