From bfce108083124d753fc960556be8d6906f708934 Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Wed, 10 Mar 2021 18:53:01 -0600 Subject: [PATCH] [OpenSCAD] Add scale parameter to linear_extrude --- src/Mod/OpenSCAD/OpenSCADFeatures.py | 25 +++++++---------- .../OpenSCADTest/app/test_importCSG.py | 9 ++++++- src/Mod/OpenSCAD/importCSG.py | 27 ++++++++++--------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/Mod/OpenSCAD/OpenSCADFeatures.py b/src/Mod/OpenSCAD/OpenSCADFeatures.py index ce4ec8d33e..108b15edb5 100644 --- a/src/Mod/OpenSCAD/OpenSCADFeatures.py +++ b/src/Mod/OpenSCAD/OpenSCADFeatures.py @@ -387,15 +387,17 @@ class Frustum: 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): @@ -408,8 +410,7 @@ class Twist: 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=[] @@ -421,32 +422,26 @@ class Twist: 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: diff --git a/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py b/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py index 1f493461d3..2a7b0b546b 100644 --- a/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py +++ b/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py @@ -246,7 +246,8 @@ polyhedron( 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") @@ -255,6 +256,12 @@ polyhedron( 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 diff --git a/src/Mod/OpenSCAD/importCSG.py b/src/Mod/OpenSCAD/importCSG.py index 26f3326797..5e0066e47a 100644 --- a/src/Mod/OpenSCAD/importCSG.py +++ b/src/Mod/OpenSCAD/importCSG.py @@ -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 @@ -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'): @@ -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] = [] @@ -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'