diff --git a/src/Mod/OpenSCAD/OpenSCADFeatures.py b/src/Mod/OpenSCAD/OpenSCADFeatures.py index ec71a1425..977c30225 100644 --- a/src/Mod/OpenSCAD/OpenSCADFeatures.py +++ b/src/Mod/OpenSCAD/OpenSCADFeatures.py @@ -306,6 +306,7 @@ class GetWire: def execute(self, fp): if fp.Base: + import Part #fp.Shape=fp.Base.Shape.Wires[0] fp.Shape=Part.Wire(fp.Base.Shape.Wires[0]) # works with 0.13 stable #sh = fp.Base.Shape.Wires[0].copy; sh.transformSahpe(fp.Base.Shape.Placement.toMatrix()); fp.Shape = sh #untested @@ -348,6 +349,8 @@ class Frustum: pts.append(pts[0]) shape = Part.makePolygon(pts) face = Part.Face(shape) + if ir==1: #top face + face.reverse() wires.append(shape) faces.append(face) #shellperi=Part.makeRuledSurface(*wires) @@ -438,12 +441,12 @@ class OffsetShape: def onChanged(self, fp, prop): pass - #if prop in ["Offset"]: - # self.createGeometry(fp) + if prop in ["Offset"]: + self.createGeometry(fp) def createGeometry(self,fp): if fp.Base and fp.Offset: - fp.Shape=fp.Base.Shape.makeOffsetShape(self.Offset,1e-6) + fp.Shape=fp.Base.Shape.makeOffsetShape(fp.Offset,1e-6) def makeSurfaceVolume(filename): import FreeCAD,Part diff --git a/src/Mod/OpenSCAD/OpenSCADUtils.py b/src/Mod/OpenSCAD/OpenSCADUtils.py index d9e7c63a9..646cfb69a 100644 --- a/src/Mod/OpenSCAD/OpenSCADUtils.py +++ b/src/Mod/OpenSCAD/OpenSCADUtils.py @@ -29,6 +29,12 @@ This Script includes various pyhton helper functions that are shared across the module ''' +def translate(context,text): + "convenience function for Qt translator" + from PySide import QtGui + return QtGui.QApplication.translate(context, text, None, \ + QtGui.QApplication.UnicodeUTF8) + class OpenSCADError(Exception): def __init__(self,value): self.value= value @@ -342,10 +348,13 @@ def process3D_ObjectsViaOpenSCAD(doc,ObjList,Operation): return(obj) def process_ObjectsViaOpenSCAD(doc,children,name): - if all(obj.Shape.Volume == 0 for obj in children): + if all((not obj.Shape.isNull() and obj.Shape.Volume == 0) \ + for obj in children): return process2D_ObjectsViaOpenSCAD(children,name) - elif all(obj.Shape.Volume > 0 for obj in children): + elif all((not obj.Shape.isNull() and obj.Shape.Volume > 0) \ + for obj in children): return process3D_ObjectsViaOpenSCAD(doc,children,name) else: + import FreeCAD FreeCAD.Console.PrintError( unicode(translate('OpenSCAD',\ - "Error Both shapes must be either 2D or both must be 3D"))+u'\n') + "Error all shapes must be either 2D or both must be 3D"))+u'\n') diff --git a/src/Mod/OpenSCAD/importCSG.py b/src/Mod/OpenSCAD/importCSG.py index 8118fb301..caf062a1c 100644 --- a/src/Mod/OpenSCAD/importCSG.py +++ b/src/Mod/OpenSCAD/importCSG.py @@ -47,6 +47,7 @@ import ply.yacc as yacc import Part from OpenSCADFeatures import RefineShape +from OpenSCADFeatures import Frustum #from OpenSCAD2Dgeom import * from OpenSCADUtils import * isspecialorthogonaldeterminant = isspecialorthogonalpython @@ -360,6 +361,8 @@ 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 @@ -434,7 +437,10 @@ def fuse(lst,name): global doc if printverbose: print "Fuse" if printverbose: print lst - if len(lst) == 1: + if len(lst) == 0: + myfuse = doc.addObject("Part::Feature","emptyfuse") + myfuse.Shape = Part.Compound([]) + elif len(lst) == 1: return lst[0] # Is this Multi Fuse elif len(lst) > 2: @@ -468,7 +474,10 @@ def p_difference_action(p): if printverbose: print "difference" if printverbose: print len(p[5]) if printverbose: print p[5] - if (len(p[5]) == 1 ): #single object + if (len(p[5]) == 0 ): #nochild + mycut = doc.addObject("Part::Feature","emptycut") + mycut.Shape = Part.Compound([]) + elif (len(p[5]) == 1 ): #single object p[0] = p[5] else: # Cut using Fuse @@ -499,7 +508,7 @@ def p_intersection_action(p): if gui: for subobj in mycommon.Shapes: subobj.ViewObject.hide() - else : + elif (len(p[5]) == 2): if printverbose: print "Single Common" mycommon = doc.addObject('Part::Common',p[1]) mycommon.Base = p[5][0] @@ -507,7 +516,11 @@ def p_intersection_action(p): if gui: mycommon.Base.ViewObject.hide() mycommon.Tool.ViewObject.hide() - + elif (len(p[5]) == 1): + mycommon = p[5][0] + else : # 1 child + mycommon = doc.addObject("Part::Feature","emptyintersection") + mycommon.Shape = Part.Compound([]) p[0] = [mycommon] if printverbose: print "End Intersection" @@ -792,13 +805,13 @@ def p_cylinder_action(p): r1 = float(p[3]['r1']) r2 = float(p[3]['r2']) n = int(p[3]['$fn']) + fnmax = FreeCAD.ParamGet(\ + "User parameter:BaseApp/Preferences/Mod/OpenSCAD").\ + GetInt('useMaxFN') if printverbose: print p[3] if ( r1 == r2 and r1 > 0): if printverbose: print "Make Cylinder" - fnmax = FreeCAD.ParamGet(\ - "User parameter:BaseApp/Preferences/Mod/OpenSCAD").\ - GetInt('useMaxFN') - if n < 3 or fnmax != 0 and n >= fnmax: + if n < 3 or fnmax != 0 and n > fnmax: mycyl=doc.addObject("Part::Cylinder",p[1]) mycyl.Height = h mycyl.Radius = r1 @@ -829,13 +842,25 @@ def p_cylinder_action(p): mycyl.Height = h elif (r1 != r2): - if printverbose: print "Make Cone" - mycyl=doc.addObject("Part::Cone",p[1]) - mycyl.Height = h - mycyl.Radius1 = r1 - mycyl.Radius2 = r2 + if n < 3 or fnmax != 0 and n > fnmax: + if printverbose: print "Make Cone" + mycyl=doc.addObject("Part::Cone",p[1]) + mycyl.Height = h + mycyl.Radius1 = r1 + mycyl.Radius2 = r2 + else: + if printverbose: print "Make Frustum" + mycyl=doc.addObject("Part::FeaturePython",'frustum') + Frustum(mycyl,r1,r2,n,h) + if gui: + if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\ + GetBool('useViewProviderTree'): + from OpenSCADFeatures import ViewProviderTree + ViewProviderTree(mycyl.ViewObject) + else: + mycyl.ViewObject.Proxy = 0 else: # r1 == r2 == 0 - FreeCAD.Console.PrintWarning('cylinder with radius zero\n') + FreeCAD.Console.PrintWarning('cylinder with radius zero\n') mycyl=doc.addObject("Part::Feature","emptycyl") mycyl.Shape = Part.Compound([]) if printverbose: print "Center = ",tocenter diff --git a/src/Mod/OpenSCAD/prototype.py b/src/Mod/OpenSCAD/prototype.py index 86c49d6d7..a73cabe1c 100644 --- a/src/Mod/OpenSCAD/prototype.py +++ b/src/Mod/OpenSCAD/prototype.py @@ -140,8 +140,8 @@ class Node: obj.Height = h if self.arguments['center']: center(obj,0,0,h) - base.ViewObject.hide() - elif True: #use Frustum Feature with makeRuledSurface + #base.ViewObject.hide() + elif False: #use Frustum Feature with makeRuledSurface obj=doc.addObject("Part::FeaturePython",'frustum') Frustum(obj,r1,r2,int(self.arguments['$fn']),h) ViewProviderTree(obj.ViewObject)