OpenSCAD Module: bugfixes and improvements
if more than 14 digits are given don round in general, but test for <eps only. refine before extrusion support polyhedron faces which replaces polyhedron faces importCSG round rotations don't call Draft.makecircle and makeprism as they trigger a recompute use group placholder for objects with no children move removesubtree to OpenSCADUtils add resize and offset keywords add OpenSCAD_ExplodeGroup command add OpenSCAD_IncreaseToleranceFeature change refine shape logo
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
#* *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
__title__="FreeCAD OpenSCAD Workbench - CSG importer Version 0.06a"
|
||||
__title__="FreeCAD OpenSCAD Workbench - CSG importer"
|
||||
__author__ = "Keith Sloan <keith@sloan-home.co.uk>"
|
||||
__url__ = ["http://www.sloan-home.co.uk/ImportCSG"]
|
||||
|
||||
@@ -47,9 +47,7 @@ import ply.yacc as yacc
|
||||
import Part
|
||||
|
||||
from OpenSCADFeatures import *
|
||||
#from OpenSCAD2Dgeom import *
|
||||
from OpenSCADUtils import *
|
||||
isspecialorthogonaldeterminant = isspecialorthogonalpython
|
||||
|
||||
if open.__module__ == '__builtin__':
|
||||
pythonopen = open # to distinguish python built-in open function from the one declared here
|
||||
@@ -370,6 +368,25 @@ def CGALFeatureObj(name,children,arguments=[]):
|
||||
myobj.ViewObject.Proxy = 0
|
||||
return myobj
|
||||
|
||||
#def p_offset_action(p):
|
||||
# 'offset_action : offset LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'
|
||||
# if len(p[5]) == 0:
|
||||
# mycut = placeholder('group',[],'{}')
|
||||
# elif (len(p[5]) == 1 ): #single object
|
||||
# subobj = p[5]
|
||||
# else:
|
||||
# subobj = fuse(p[6],"Offset Union")
|
||||
# newobj=doc.addObject("Part::FeaturePython",'offset')
|
||||
# OffsetShape(newobj,subobj,p[3]['delta'])
|
||||
# if gui:
|
||||
# if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||
# GetBool('useViewProviderTree'):
|
||||
# from OpenSCADFeatures import ViewProviderTree
|
||||
# ViewProviderTree(newobj.ViewObject)
|
||||
# else:
|
||||
# newobj.ViewObject.Proxy = 0
|
||||
# return [newobj]
|
||||
|
||||
def p_hull_action(p):
|
||||
'hull_action : hull LPAREN RPAREN OBRACE block_list EBRACE'
|
||||
p[0] = [ CGALFeatureObj(p[1],p[5]) ]
|
||||
@@ -382,6 +399,8 @@ def p_minkowski_action(p):
|
||||
def p_not_supported(p):
|
||||
'''
|
||||
not_supported : glide LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE
|
||||
| offset LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE
|
||||
| resize LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE
|
||||
'''
|
||||
if gui and not FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||
GetBool('usePlaceholderForUnsupported'):
|
||||
@@ -439,8 +458,7 @@ def fuse(lst,name):
|
||||
if printverbose: print "Fuse"
|
||||
if printverbose: print lst
|
||||
if len(lst) == 0:
|
||||
myfuse = doc.addObject("Part::Feature","emptyfuse")
|
||||
myfuse.Shape = Part.Compound([])
|
||||
myfuse = placeholder('group',[],'{}')
|
||||
elif len(lst) == 1:
|
||||
return lst[0]
|
||||
# Is this Multi Fuse
|
||||
@@ -476,8 +494,7 @@ def p_difference_action(p):
|
||||
if printverbose: print len(p[5])
|
||||
if printverbose: print p[5]
|
||||
if (len(p[5]) == 0 ): #nochild
|
||||
mycut = doc.addObject("Part::Feature","emptycut")
|
||||
mycut.Shape = Part.Compound([])
|
||||
mycut = placeholder('group',[],'{}')
|
||||
elif (len(p[5]) == 1 ): #single object
|
||||
p[0] = p[5]
|
||||
else:
|
||||
@@ -520,22 +537,13 @@ def p_intersection_action(p):
|
||||
elif (len(p[5]) == 1):
|
||||
mycommon = p[5][0]
|
||||
else : # 1 child
|
||||
mycommon = doc.addObject("Part::Feature","emptyintersection")
|
||||
mycommon.Shape = Part.Compound([])
|
||||
mycommon = placeholder('group',[],'{}')
|
||||
p[0] = [mycommon]
|
||||
if printverbose: print "End Intersection"
|
||||
|
||||
def process_rotate_extrude(obj):
|
||||
myrev = doc.addObject("Part::Revolution","RotateExtrude")
|
||||
myrev.Source = obj
|
||||
myrev.Axis = (0.00,1.00,0.00)
|
||||
myrev.Base = (0.00,0.00,0.00)
|
||||
myrev.Angle = 360.00
|
||||
myrev.Placement=FreeCAD.Placement(FreeCAD.Vector(),FreeCAD.Rotation(0,0,90))
|
||||
if gui:
|
||||
obj.ViewObject.hide()
|
||||
newobj=doc.addObject("Part::FeaturePython",'RefineRotateExtrude')
|
||||
RefineShape(newobj,myrev)
|
||||
RefineShape(newobj,obj)
|
||||
if gui:
|
||||
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||
GetBool('useViewProviderTree'):
|
||||
@@ -543,8 +551,16 @@ def process_rotate_extrude(obj):
|
||||
ViewProviderTree(newobj.ViewObject)
|
||||
else:
|
||||
newobj.ViewObject.Proxy = 0
|
||||
myrev.ViewObject.hide()
|
||||
return(newobj)
|
||||
obj.ViewObject.hide()
|
||||
myrev = doc.addObject("Part::Revolution","RotateExtrude")
|
||||
myrev.Source = newobj
|
||||
myrev.Axis = (0.00,1.00,0.00)
|
||||
myrev.Base = (0.00,0.00,0.00)
|
||||
myrev.Angle = 360.00
|
||||
myrev.Placement=FreeCAD.Placement(FreeCAD.Vector(),FreeCAD.Rotation(0,0,90))
|
||||
if gui:
|
||||
newobj.ViewObject.hide()
|
||||
return(myrev)
|
||||
|
||||
def p_rotate_extrude_action(p):
|
||||
'rotate_extrude_action : rotate_extrude LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'
|
||||
@@ -565,18 +581,9 @@ def p_rotate_extrude_file(p):
|
||||
if printverbose: print "End Rotate Extrude File"
|
||||
|
||||
def process_linear_extrude(obj,h) :
|
||||
mylinear = doc.addObject("Part::Extrusion","LinearExtrude")
|
||||
mylinear.Base = obj
|
||||
mylinear.Dir = (0,0,h)
|
||||
mylinear.Placement=FreeCAD.Placement()
|
||||
try:
|
||||
mylinear.Solid = True
|
||||
except:
|
||||
a = 1 # Any old null statement
|
||||
if gui:
|
||||
obj.ViewObject.hide()
|
||||
#if gui:
|
||||
newobj=doc.addObject("Part::FeaturePython",'RefineLinearExtrude')
|
||||
RefineShape(newobj,mylinear)
|
||||
RefineShape(newobj,obj)#mylinear)
|
||||
if gui:
|
||||
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||
GetBool('useViewProviderTree'):
|
||||
@@ -584,8 +591,19 @@ def process_linear_extrude(obj,h) :
|
||||
ViewProviderTree(newobj.ViewObject)
|
||||
else:
|
||||
newobj.ViewObject.Proxy = 0
|
||||
mylinear.ViewObject.hide()
|
||||
return(newobj)
|
||||
obj.ViewObject.hide()
|
||||
#mylinear.ViewObject.hide()
|
||||
mylinear = doc.addObject("Part::Extrusion","LinearExtrude")
|
||||
mylinear.Base = newobj #obj
|
||||
mylinear.Dir = (0,0,h)
|
||||
mylinear.Placement=FreeCAD.Placement()
|
||||
try:
|
||||
mylinear.Solid = True
|
||||
except:
|
||||
pass
|
||||
if gui:
|
||||
newobj.ViewObject.hide()
|
||||
return(mylinear)
|
||||
|
||||
def process_linear_extrude_with_twist(base,height,twist) :
|
||||
newobj=doc.addObject("Part::FeaturePython",'twist_extrude')
|
||||
@@ -715,38 +733,50 @@ def p_multmatrix_action(p):
|
||||
transform_matrix = FreeCAD.Matrix()
|
||||
if printverbose: print "Multmatrix"
|
||||
if printverbose: print p[3]
|
||||
transform_matrix.A11 = round(float(p[3][0][0]),12)
|
||||
transform_matrix.A12 = round(float(p[3][0][1]),12)
|
||||
transform_matrix.A13 = round(float(p[3][0][2]),12)
|
||||
transform_matrix.A14 = round(float(p[3][0][3]),12)
|
||||
transform_matrix.A21 = round(float(p[3][1][0]),12)
|
||||
transform_matrix.A22 = round(float(p[3][1][1]),12)
|
||||
transform_matrix.A23 = round(float(p[3][1][2]),12)
|
||||
transform_matrix.A24 = round(float(p[3][1][3]),12)
|
||||
transform_matrix.A31 = round(float(p[3][2][0]),12)
|
||||
transform_matrix.A32 = round(float(p[3][2][1]),12)
|
||||
transform_matrix.A33 = round(float(p[3][2][2]),12)
|
||||
transform_matrix.A34 = round(float(p[3][2][3]),12)
|
||||
m1l=sum(p[3],[])
|
||||
if any('x' in me for me in m1l): #hexfloats
|
||||
m1l=[float.fromhex(me) for me in m1l]
|
||||
matrixisrounded=False
|
||||
elif max((len(me) for me in m1l)) >= 14: #might have double precision
|
||||
m1l=[float(me) for me in m1l] # assume precise output
|
||||
m1l=[(0 if (abs(me) < 1e-15) else me) for me in m1l]
|
||||
matrixisrounded=False
|
||||
else: #trucanted numbers
|
||||
m1l=[round(float(me),12) for me in m1l] #round
|
||||
matrixisrounded=True
|
||||
transform_matrix = FreeCAD.Matrix(*tuple(m1l))
|
||||
if printverbose: print transform_matrix
|
||||
if printverbose: print "Apply Multmatrix"
|
||||
# If more than one object on the stack for multmatrix fuse first
|
||||
if (len(p[6]) > 1) :
|
||||
if (len(p[6]) == 0) :
|
||||
part = placeholder('group',[],'{}')
|
||||
elif (len(p[6]) > 1) :
|
||||
part = fuse(p[6],"Matrix Union")
|
||||
else :
|
||||
else :
|
||||
part = p[6][0]
|
||||
# part = new_part.transformGeometry(transform_matrix)
|
||||
# part = new_part.copy()
|
||||
# part.transformShape(transform_matrix)
|
||||
if (isspecialorthogonaldeterminant(fcsubmatrix(transform_matrix))) :
|
||||
if printverbose: print "Orthogonal"
|
||||
part.Placement=FreeCAD.Placement(transform_matrix).multiply(part.Placement)
|
||||
new_part = part
|
||||
if (isspecialorthogonalpython(fcsubmatrix(transform_matrix))) :
|
||||
if printverbose: print "special orthogonal"
|
||||
if matrixisrounded:
|
||||
if printverbose: print "rotation rounded"
|
||||
plm=FreeCAD.Placement(transform_matrix)
|
||||
plm=FreeCAD.Placement(plm.Base,roundrotation(plm.Rotation))
|
||||
part.Placement=plm.multiply(part.Placement)
|
||||
else:
|
||||
part.Placement=FreeCAD.Placement(transform_matrix).multiply(\
|
||||
part.Placement)
|
||||
new_part = part
|
||||
elif isrotoinversionpython(fcsubmatrix(transform_matrix)):
|
||||
if printverbose: print "orthogonal and inversion"
|
||||
cmat,axisvec = decomposerotoinversion(transform_matrix)
|
||||
new_part=doc.addObject("Part::Mirroring",'mirr_%s'%part.Name)
|
||||
new_part.Source=part
|
||||
new_part.Normal=axisvec
|
||||
new_part.Placement=FreeCAD.Placement(cmat)
|
||||
if matrixisrounded:
|
||||
if printverbose: print "rotation rounded"
|
||||
plm=FreeCAD.Placement(cmat)
|
||||
new_part.Placement=FreeCAD.Placement(plm.Base,roundrotation(plm.Rotation))
|
||||
else:
|
||||
new_part.Placement=FreeCAD.Placement(cmat)
|
||||
new_part.Label="mirrored %s" % part.Label
|
||||
if gui:
|
||||
part.ViewObject.hide()
|
||||
@@ -922,12 +952,12 @@ def p_cube_action(p):
|
||||
l,w,h = [float(str1) for str1 in p[3]['size']]
|
||||
if (l > 0 and w > 0 and h >0):
|
||||
if printverbose: print "cube : ",p[3]
|
||||
mycube=doc.addObject('Part::Box',p[1])
|
||||
mycube.Length=l
|
||||
mycube.Width=w
|
||||
mycube.Height=h
|
||||
mycube=doc.addObject('Part::Box',p[1])
|
||||
mycube.Length=l
|
||||
mycube.Width=w
|
||||
mycube.Height=h
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning('cube with radius zero\n')
|
||||
FreeCAD.Console.PrintWarning('cube with radius zero\n')
|
||||
mycube=doc.addObject("Part::Feature","emptycube")
|
||||
mycube.Shape = Part.Compound([])
|
||||
if p[3]['center']=='true' :
|
||||
@@ -947,11 +977,21 @@ def p_circle_action(p) :
|
||||
# in the modules preferences
|
||||
import Draft
|
||||
if n == 0 or fnmax != 0 and n >= fnmax:
|
||||
mycircle = Draft.makeCircle(r)
|
||||
#mycircle = doc.addObject('Part::Circle',p[1])
|
||||
#mycircle.Radius = r
|
||||
mycircle = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",'circle')
|
||||
Draft._Circle(mycircle)
|
||||
mycircle.Radius = r
|
||||
#mycircle = Draft.makeCircle(r) # would call doc.recompute
|
||||
#mycircle = doc.addObject('Part::Circle',p[1]) #would not create a face
|
||||
#mycircle.Radius = r
|
||||
else :
|
||||
mycircle = Draft.makePolygon(n,r)
|
||||
#mycircle = Draft.makePolygon(n,r) # would call doc.recompute
|
||||
mycircle = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",'polygon')
|
||||
Draft._Polygon(mycricle)
|
||||
mycircle.FacesNumber = n
|
||||
mycircle.Radius = r
|
||||
mycircle.DrawMode = "inscribed"
|
||||
if gui:
|
||||
Draft._ViewProviderDraft(mycircle.ViewObject)
|
||||
if printverbose: print "Push Circle"
|
||||
p[0] = [mycircle]
|
||||
|
||||
@@ -1021,7 +1061,8 @@ def make_face(v1,v2,v3):
|
||||
return face
|
||||
|
||||
def p_polyhedron_action(p) :
|
||||
'polyhedron_action : polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA triangles EQ OSQUARE points_list_3d ESQUARE COMMA keywordargument_list RPAREN SEMICOL'
|
||||
'''polyhedron_action : polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA faces EQ OSQUARE points_list_3d ESQUARE COMMA keywordargument_list RPAREN SEMICOL
|
||||
| polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA triangles EQ OSQUARE points_list_3d ESQUARE COMMA keywordargument_list RPAREN SEMICOL'''
|
||||
if printverbose: print "Polyhedron Points"
|
||||
v = []
|
||||
for i in p[6] :
|
||||
|
||||
Reference in New Issue
Block a user