OpenSCAD use PythonFeatures for hull and minkowski
This commit is contained in:
parent
de038b327f
commit
0e6b7a629d
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
'''
|
||||
|
|
Loading…
Reference in New Issue
Block a user