Skip to content

Commit

Permalink
[OpenSCAD] Add scale parameter to linear_extrude
Browse files Browse the repository at this point in the history
  • Loading branch information
chennes authored and wwmayer committed Mar 11, 2021
1 parent b6634e0 commit bfce108
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 29 deletions.
25 changes: 10 additions & 15 deletions src/Mod/OpenSCAD/OpenSCADFeatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,17 @@ def createGeometry(self,fp):
fp.Placement = plm

class Twist:
def __init__(self, obj,child=None,h=1.0,angle=0.0):
def __init__(self, obj,child=None,h=1.0,angle=0.0,scale=[1.0,1.0]):
obj.addProperty("App::PropertyLink","Base","Base",
"The base object that must be tranfsformed")
obj.addProperty("App::PropertyAngle","Angle","Base","Twist Angle in degrees") #degree or rad
obj.addProperty("App::PropertyDistance","Height","Base","Height of the Extrusion")
obj.addProperty("App::PropertyFloatList","Scale","Base","Scale to apply during the Extrusion")

obj.Base = child
obj.Angle = angle
obj.Height = h
obj.Scale = scale
obj.Proxy = self

def execute(self, fp):
Expand All @@ -408,8 +410,7 @@ def onChanged(self, fp, prop):

def createGeometry(self,fp):
import FreeCAD,Part,math,sys
#tangle = -twist #openscad uses degrees clockwise
if fp.Base and fp.Angle and fp.Height and \
if fp.Base and fp.Height and \
fp.Base.Shape.isValid():
#wire=fp.Base.Shape.Wires[0].transformGeometry(fp.Base.Placement.toMatrix())
solids=[]
Expand All @@ -421,32 +422,26 @@ def createGeometry(self,fp):
faceu=faceb.copy()
facetransform=FreeCAD.Matrix()
facetransform.rotateZ(math.radians(fp.Angle.Value))
facetransform.scale(fp.Scale[0],fp.Scale[1], 1.0)
facetransform.move(FreeCAD.Vector(0,0,fp.Height.Value))
faceu.transformShape(facetransform)
step = 2 + abs(int(fp.Angle.Value // 90)) #resolution in z direction
# print abs(int(fp.Angle.Value // 90)) #resolution in z direction
# print step
zinc = fp.Height.Value/(step-1.0)
angleinc = math.radians(fp.Angle.Value)/(step-1.0)
spine = Part.makePolygon([(0,0,i*zinc) \
for i in range(step)])
auxspine = Part.makePolygon([(math.cos(i*angleinc),\
math.sin(i*angleinc),i*fp.Height.Value/(step-1)) \
math.sin(i*angleinc),i*zinc) \
for i in range(step)])
faces=[faceb,faceu]
for wire in faceb.Wires:
for wire1,wire2 in zip(faceb.Wires,faceu.Wires):
pipeshell=Part.BRepOffsetAPI.MakePipeShell(spine)
pipeshell.setSpineSupport(spine)
pipeshell.add(wire)
# Was before function change
# pipeshell.setAuxiliarySpine(auxspine,True,False)
if sys.version_info.major < 3:
pipeshell.setAuxiliarySpine(auxspine,True,long(0))
else:
pipeshell.setAuxiliarySpine(auxspine,True,0)
pipeshell.add(wire1)
pipeshell.add(wire2)
pipeshell.setAuxiliarySpine(auxspine,True,0)
print(pipeshell.getStatus())
assert(pipeshell.isReady())
#fp.Shape=pipeshell.makeSolid()
pipeshell.build()
faces.extend(pipeshell.shape().Faces)
try:
Expand Down
9 changes: 8 additions & 1 deletion src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ def test_import_linear_extrude(self):

doc = self.utility_create_scad("linear_extrude(height = 20, scale = 0.2) square([20, 10], center = true);", "linear_extrude_scale")
object = doc.ActiveObject
# Not actually supported - this does not create a frustum, but a cube: scale does nothing
self.assertTrue (object is not None)
self.assertAlmostEqual (object.Shape.Volume, 1945.2745, 3)
FreeCAD.closeDocument(doc.Name)

doc = self.utility_create_scad("linear_extrude(height = 20, twist = 90) square([20, 10], center = true);", "linear_extrude_twist")
Expand All @@ -255,6 +256,12 @@ def test_import_linear_extrude(self):
self.assertAlmostEqual (object.Shape.Volume, 3999.9961, 3)
FreeCAD.closeDocument(doc.Name)

doc = self.utility_create_scad("linear_extrude(height = 40, twist = 180, scale=0.25) square([20, 10], center = true);", "linear_extrude_twist")
object = doc.ActiveObject
self.assertTrue (object is not None)
self.assertAlmostEqual (object.Shape.Volume, 4144.9071, 3)
FreeCAD.closeDocument(doc.Name)

def test_import_rotate_extrude_file(self):
# OpenSCAD doesn't seem to have this feature at this time (March 2021)
pass
Expand Down
27 changes: 14 additions & 13 deletions src/Mod/OpenSCAD/importCSG.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def p_operation(p):
| intersection_action
| union_action
| rotate_extrude_action
| linear_extrude_with_twist
| linear_extrude_with_transform
| rotate_extrude_file
| import_file1
| resize_action
Expand Down Expand Up @@ -728,9 +728,9 @@ def process_linear_extrude(obj,h) :
newobj.ViewObject.hide()
return(mylinear)

def process_linear_extrude_with_twist(base,height,twist) :
newobj=doc.addObject("Part::FeaturePython",'twist_extrude')
Twist(newobj,base,height,-twist) #base is an FreeCAD Object, height and twist are floats
def process_linear_extrude_with_transform(base,height,twist,scale) :
newobj=doc.addObject("Part::FeaturePython",'transform_extrude')
Twist(newobj,base,height,-twist,scale) #base is an FreeCAD Object, height and twist are floats, scale is a two-component vector of floats
if gui:
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
GetBool('useViewProviderTree'):
Expand All @@ -742,17 +742,18 @@ def process_linear_extrude_with_twist(base,height,twist) :
#ViewProviderTree(obj.ViewObject)
return(newobj)

def p_linear_extrude_with_twist(p):
'linear_extrude_with_twist : linear_extrude LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'
if printverbose: print("Linear Extrude With Twist")
def p_linear_extrude_with_transform(p):
'linear_extrude_with_transform : linear_extrude LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'
if printverbose: print("Linear Extrude With Transform")
h = float(p[3]['height'])
s = 1.0
t = 0.0
if printverbose: print("Twist : ",p[3])
if 'scale' in p[3]:
FreeCAD.Console.PrintWarning('WARNING: "scale" option to linear_extrude is not supported. Ignoring.\n')
s = [float(p[3]['scale'][0]), float(p[3]['scale'][1])]
print ("Scale: " + str(s))
if 'twist' in p[3]:
t = float(p[3]['twist'])
else:
t = 0
# Test if null object like from null text
if (len(p[6]) == 0) :
p[0] = []
Expand All @@ -761,14 +762,14 @@ def p_linear_extrude_with_twist(p):
obj = fuse(p[6],"Linear Extrude Union")
else :
obj = p[6][0]
if t:
newobj = process_linear_extrude_with_twist(obj,h,t)
if t != 0.0 or s != 1.0:
newobj = process_linear_extrude_with_transform(obj,h,t,s)
else:
newobj = process_linear_extrude(obj,h)
if p[3]['center']=='true' :
center(newobj,0,0,h)
p[0] = [newobj]
if printverbose: print("End Linear Extrude with twist")
if printverbose: print("End Linear Extrude with Transform")

def p_import_file1(p):
'import_file1 : import LPAREN keywordargument_list RPAREN SEMICOL'
Expand Down

0 comments on commit bfce108

Please sign in to comment.