OpenSCAD use PythonFeatures for hull and minkowski

This commit is contained in:
Sebastian Hoogen 2014-02-15 12:25:36 +01:00 committed by Yorik van Havre
parent de038b327f
commit 0e6b7a629d
3 changed files with 76 additions and 38 deletions

View File

@ -448,6 +448,30 @@ class OffsetShape:
if fp.Base and fp.Offset:
fp.Shape=fp.Base.Shape.makeOffsetShape(fp.Offset,1e-6)
class CGALFeature:
def __init__(self,obj,opname=None,children=None,arguments=None):
obj.addProperty("App::PropertyLinkList",'Children','OpenSCAD',"Base Objects")
obj.addProperty("App::PropertyString",'Arguments','OpenSCAD',"Arguments")
obj.addProperty("App::PropertyString",'Operation','OpenSCAD',"Operation")
obj.Proxy = self
if opname:
obj.Operation = opname
if children:
obj.Children = children
if arguments:
obj.Arguments = arguments
def execute(self,fp):
#arguments are ignored
maxmeshpoints = None #TBD: add as property
import Part,OpenSCADUtils
shape = OpenSCADUtils.process_ObjectsViaOpenSCADShape(fp.Document,fp.Children,\
fp.Operation, maxmeshpoints=maxmeshpoints)
if shape:
fp.Shape = shape
else:
raise ValueError
def makeSurfaceVolume(filename):
import FreeCAD,Part
f1=open(filename)

View File

@ -110,7 +110,7 @@ def callopenscad(inputfilename,outputfilename=None,outputext='csg',keepname=Fals
raise OpenSCADError('%s\n' % stdoutd.strip())
#raise Exception,'stdout %s\n stderr%s' %(stdoutd,stderrd)
if stdoutd.strip():
FreeCAD.Console.PrintWarning(stdoutd+u'\n')
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
return stdoutd
osfilename = FreeCAD.ParamGet(\
@ -280,46 +280,43 @@ def meshoponobjs(opname,inobjs):
else:
return (None,[])
def process2D_ObjectsViaOpenSCAD(ObjList,Operation,doc=None):
def process2D_ObjectsViaOpenSCADShape(ObjList,Operation,doc):
import FreeCAD,importDXF
import os,tempfile
#print "process2D"
doc = doc or FreeCAD.activeDocument()
dir1=tempfile.gettempdir()
filenames = []
#print "Export DXF"
for item in ObjList :
outputfilename=os.path.join(dir1,'%s.dxf' % tempfilenamegen.next())
#print "Call Export : "+outputfilename
importDXF.export([item],outputfilename,True,True)
#print "File Exported"
filenames.append(outputfilename)
dxfimports = ' '.join("import(file = \"%s\");" % \
#filename \
os.path.split(filename)[1] for filename in filenames)
#print "Call OpenSCAD : "+dxfimports
tmpfilename = callopenscadstring('%s(){%s}' % (Operation,dxfimports),'dxf')
#from importCSG import processDXF #import the result
#obj = processDXF(tmpfilename,None)
from OpenSCAD2Dgeom import importDXFface
#print "Import DXF"
# TBD: assure the given doc is active
face = importDXFface(tmpfilename,None,None)
#print "Add Hull"
obj=doc.addObject('Part::Feature',Operation)
obj.Shape=face
# Hide Children
if FreeCAD.GuiUp:
for index in ObjList :
index.ViewObject.hide()
#clean up
filenames.append(tmpfilename) #delete the ouptut file as well
try:
os.unlink(tmpfilename)
except OSError:
pass
return face
def process2D_ObjectsViaOpenSCAD(ObjList,Operation,doc=None):
import FreeCAD
doc = doc or FreeCAD.activeDocument()
face=process2D_ObjectsViaOpenSCADShape(ObjList,Operation,doc)
obj=doc.addObject('Part::Feature',Operation)
obj.Shape=face
# Hide Children
if FreeCAD.GuiUp:
for index in ObjList :
index.ViewObject.hide()
return(obj)
def process3D_ObjectsViaOpenSCAD(doc,ObjList,Operation):
def process3D_ObjectsViaOpenSCADShape(ObjList,Operation,maxmeshpoints=None):
import FreeCAD,Mesh,Part
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD")
if False: # disabled due to issue 1292
@ -332,25 +329,42 @@ def process3D_ObjectsViaOpenSCAD(doc,ObjList,Operation):
meshes = [Mesh.Mesh(obj.Shape.tessellate(params.GetFloat(\
'meshmaxlength',1.0))) for obj in ObjList]
if max(mesh.CountPoints for mesh in meshes) < \
params.GetInt('tempmeshmaxpoints',5000):
(maxmeshpoints or params.GetInt('tempmeshmaxpoints',5000)):
stlmesh = meshoptempfile(Operation,meshes)
sh=Part.Shape()
sh.makeShapeFromMesh(stlmesh.Topology,0.1)
solid = Part.Solid(sh)
obj=doc.addObject('Part::Feature',Operation) #non parametric objec
solid=solid.removeSplitter()
if solid.Volume < 0:
solid.complement()
return solid
def process3D_ObjectsViaOpenSCAD(doc,ObjList,Operation):
solid = process3D_ObjectsViaOpenSCADShape(ObjList,Operation)
if solid is not None:
obj=doc.addObject('Part::Feature',Operation) #non parametric objec
obj.Shape=solid#.removeSplitter()
if FreeCAD.GuiUp:
for index in ObjList :
index.ViewObject.hide()
return(obj)
def process_ObjectsViaOpenSCADShape(doc,children,name,maxmeshpoints=None):
if all((not obj.Shape.isNull() and obj.Shape.Volume == 0) \
for obj in children):
return process2D_ObjectsViaOpenSCADShape(children,name,doc)
elif all((not obj.Shape.isNull() and obj.Shape.Volume > 0) \
for obj in children):
return process3D_ObjectsViaOpenSCADShape(children,name,maxmeshpoints)
else:
import FreeCAD
FreeCAD.Console.PrintError( unicode(translate('OpenSCAD',\
"Error all shapes must be either 2D or both must be 3D"))+u'\n')
def process_ObjectsViaOpenSCAD(doc,children,name):
if all((not obj.Shape.isNull() and obj.Shape.Volume == 0) \
for obj in children):
return process2D_ObjectsViaOpenSCAD(children,name)
return process2D_ObjectsViaOpenSCAD(children,name,doc)
elif all((not obj.Shape.isNull() and obj.Shape.Volume > 0) \
for obj in children):
return process3D_ObjectsViaOpenSCAD(doc,children,name)

View File

@ -46,12 +46,10 @@ import ply.lex as lex
import ply.yacc as yacc
import Part
from OpenSCADFeatures import RefineShape
from OpenSCADFeatures import Frustum
from OpenSCADFeatures import *
#from OpenSCAD2Dgeom import *
from OpenSCADUtils import *
isspecialorthogonaldeterminant = isspecialorthogonalpython
from OpenSCADFeatures import Twist
if open.__module__ == '__builtin__':
pythonopen = open # to distinguish python built-in open function from the one declared here
@ -357,26 +355,28 @@ def placeholder(name,children,arguments):
#don't hide the children
return newobj
def CGALorPlaceholder(name,children,arguments=[]):
'''Tries to perform a CGAL opertion by calling scad
if it fails it creates a placeholder object to continue parsing
'''
if any(obj.Shape.isNull() for obj in children):
doc.recompute() #we need valid shapes
newobj = process_ObjectsViaOpenSCAD(doc,children,name)
if newobj is not None :
return newobj
else:
return placeholder(name,children,arguments)
def CGALFeatureObj(name,children,arguments=[]):
myobj=doc.addObject("Part::FeaturePython",name)
CGALFeature(myobj,name,children,str(arguments))
if gui:
for subobj in children:
subobj.ViewObject.hide()
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
GetBool('useViewProviderTree'):
from OpenSCADFeatures import ViewProviderTree
ViewProviderTree(myobj.ViewObject)
else:
myobj.ViewObject.Proxy = 0
return myobj
def p_hull_action(p):
'hull_action : hull LPAREN RPAREN OBRACE block_list EBRACE'
p[0] = [ CGALorPlaceholder(p[1],p[5]) ]
p[0] = [ CGALFeatureObj(p[1],p[5]) ]
def p_minkowski_action(p):
'''
minkowski_action : minkowski LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'''
p[0] = [ CGALorPlaceholder(p[1],p[6],p[3]) ]
p[0] = [ CGALFeatureObj(p[1],p[6],p[3]) ]
def p_not_supported(p):
'''