Fixed issues with BaseGeometry UI processing and extended interface to support multiple shapes.

This commit is contained in:
Markus Lampert
2017-08-04 21:00:26 -07:00
committed by Yorik van Havre
parent 83e5c8098b
commit d07319e4d2
4 changed files with 85 additions and 90 deletions

View File

@@ -111,6 +111,7 @@ class ObjectOp(object):
pass
def onChanged(self, obj, prop):
#PathLog.track(obj.Label, prop)
if prop in ['AreaParams', 'PathParams', 'removalshape']:
obj.setEditorMode(prop, 2)
self.opOnChanged(obj, prop)
@@ -174,8 +175,10 @@ class ObjectOp(object):
PathLog.debug("Area with params: {}".format(area.getParams()))
sections = area.makeSections(mode=0, project=True, heights=heights)
sections = area.makeSections(mode=0, project=self.opUseProjection(obj), heights=heights)
PathLog.debug("sections = %s" % sections)
shapelist = [sec.getShape() for sec in sections]
PathLog.debug("shapelist = %s" % shapelist)
pathParams = self.opPathParams(obj)
pathParams['shapes'] = shapelist
@@ -192,6 +195,7 @@ class ObjectOp(object):
pathParams['start'] = obj.StartPoint
obj.PathParams = str({key: value for key, value in pathParams.items() if key != 'shapes'})
PathLog.debug("Path with params: {}".format(obj.PathParams))
(pp, end_vector) = Path.fromShapes(**pathParams)
PathLog.debug('pp: {}, end vector: {}'.format(pp, end_vector))
@@ -244,23 +248,25 @@ class ObjectOp(object):
else:
self.radius = tool.Diameter/2
commandlist = []
commandlist.append(Path.Command("(" + obj.Label + ")"))
shape = self.opShape(obj, commandlist)
if FeatureStartPoint and obj.UseStartPoint:
start = obj.StartPoint
else:
start = FreeCAD.Vector()
try:
(pp, sim) = self._buildPathArea(obj, shape, start, getsim)
commandlist.extend(pp.Commands)
except Exception as e:
FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Check project and tool config.")
sim = None
commandlist = []
commandlist.append(Path.Command("(" + obj.Label + ")"))
shapes = self.opShapes(obj, commandlist)
sims = []
for shape in shapes:
try:
(pp, sim) = self._buildPathArea(obj, shape, start, getsim)
commandlist.extend(pp.Commands)
sims.append(sim)
except Exception as e:
FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Check project and tool config.")
# Let's finish by rapid to clearance...just for safety
@@ -269,7 +275,7 @@ class ObjectOp(object):
PathLog.track()
path = Path.Path(commandlist)
obj.Path = path
return sim
return sims
def addBase(self, obj, base, sub=""):
PathLog.track()

View File

@@ -39,6 +39,10 @@ from PySide import QtCore, QtGui
# 2 ... multi panel layout
TaskPanelLayout = 2
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
@@ -49,6 +53,9 @@ class ViewProvider(object):
PathLog.track()
vobj.Proxy = self
#for sel in FreeCADGui.Selection.getSelectionEx():
# if sel[0].HasSubObjects:
def attach(self, vobj):
PathLog.track()
self.Object = vobj.Object
@@ -180,9 +187,9 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
#FreeCADGui.updateGui()
def supportsEdges(self):
return self.support & PathAreaOp.FeatureBaseEdges
return self.supports & PathAreaOp.FeatureBaseEdges
def supportsFaces(self):
return self.support & PathAreaOp.FeatureBaseFaces
return self.supports & PathAreaOp.FeatureBaseFaces
def featureName(self):
if self.supportsEdges() and self.supportsFaces():
return 'features'
@@ -192,38 +199,36 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
return 'edges'
return 'nothing'
def addBase(self):
selection = FreeCADGui.Selection.getSelectionEx()
def addBaseGeometry(self, selection):
if len(selection) != 1:
PahtLog.error(translate("PathProject", "Please select %s from a single solid" % self.featureName()))
return
PathLog.error(translate("PathProject", "Please select %s from a single solid" % self.featureName()))
return False
sel = selection[0]
if not sel.HasSubObjects:
PahtLog.error(translate("PathProject", "Please select %s of a solid" % self.featureName()))
return
PathLog.error(translate("PathProject", "Please select %s of a solid" % self.featureName()))
return False
if not self.supportsEdges() and selection[0].SubObjects[0].ShapeType == "Edge":
PahtLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
return
PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
return False
if not self.supportsFaces() and selection[0].SubObjects[0].ShapeType == "Face":
PahtLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
return
for i in sel.SubElementNames:
self.obj.Proxy.addBase(self.obj, sel.Object, i)
PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
return False
self.obj.Proxy.execute(self.obj)
self.setFields()
for sub in sel.SubElementNames:
self.obj.Proxy.addBase(self.obj, sel.Object, sub)
return True
def addBase(self):
if self.addBaseGeometry(FreeCADGui.Selection.getSelectionEx()):
#self.obj.Proxy.execute(self.obj)
self.setFields(self.obj)
def deleteBase(self):
newlist = []
for item in self.form.baseList.selectedItems():
obj = item.data(self.DataObject)
sub = itme.data(self.DataObjectSub)
for base in self.obj.Base:
if base[0].Name != obj.Name and base[1] != sub:
newlist.append(base)
PathLog.track()
selected = self.form.baseList.selectedItems()
for item in selected:
self.form.baseList.takeItem(self.form.baseList.row(item))
self.obj.Base = newlist
self.updateBase()
#self.obj.Proxy.execute(self.obj)
#FreeCAD.ActiveDocument.recompute()
@@ -232,8 +237,10 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
for i in range(self.form.baseList.count()):
item = self.form.baseList.item(i)
obj = item.data(self.DataObject)
sub = item.data(self.DataObjectSub)
newlist.append((obj, sub))
sub = str(item.data(self.DataObjectSub))
base = (obj, sub)
newlist.append(base)
PathLog.debug("Setting new base: %s -> %s" % (self.obj.Base, newlist))
self.obj.Base = newlist
#self.obj.Proxy.execute(self.obj)
@@ -305,6 +312,7 @@ class TaskPanelDepthsPage(TaskPanelDepthsWoFinishPage):
class TaskPanel(object):
def __init__(self, obj, deleteOnReject, opPage, selectionFactory):
PathLog.track(obj.Label, deleteOnReject, opPage, selectionFactory)
FreeCAD.ActiveDocument.openTransaction(translate("Path_AreaOp", "AreaOp Operation"))
self.deleteOnReject = deleteOnReject
self.featurePages = []
@@ -363,8 +371,7 @@ class TaskPanel(object):
FreeCADGui.ActiveDocument.resetEdit()
FreeCAD.ActiveDocument.commitTransaction()
FreeCADGui.Selection.removeObserver(self.s)
if self.isDirty():
FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.recompute()
def reject(self):
FreeCADGui.Control.closeDialog()
@@ -380,8 +387,8 @@ class TaskPanel(object):
def clicked(self, button):
if button == QtGui.QDialogButtonBox.Apply:
self.panelGetFields()
FreeCAD.ActiveDocument.recompute()
self.setClean()
FreeCAD.ActiveDocument.recompute()
def panelGetFields(self):
PathLog.track()
@@ -403,6 +410,14 @@ class TaskPanel(object):
def setupUi(self):
PathLog.track()
if self.deleteOnReject and PathAreaOp.FeatureBaseGeometry & self.obj.Proxy.opFeatures(self.obj):
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) == 1 and sel[0].Object != self.obj:
for page in self.featurePages:
if hasattr(page, 'addBase'):
page.addBaseGeometry(sel)
self.panelSetFields()
for page in self.featurePages:
page.pageRegisterSignalHandlers()

View File

@@ -58,6 +58,9 @@ class ObjectContour(PathAreaOp.ObjectOp):
def opFeatures(self, obj):
return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint
def opUseProjection(self, obj):
return True
def initOperation(self, obj):
PathLog.track()
@@ -97,7 +100,7 @@ class ObjectContour(PathAreaOp.ObjectOp):
obj.MiterLimit = 0.1
def opShape(self, obj, commandlist):
def opShapes(self, obj, commandlist):
if obj.UseComp:
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
else:
@@ -120,10 +123,10 @@ class ObjectContour(PathAreaOp.ObjectOp):
for shape in shapes:
f = Part.makeFace([shape], 'Part::FaceMakerSimple')
thickness = baseobject.Group[0].Source.Thickness
return f.extrude(FreeCAD.Vector(0, 0, thickness))
return [f.extrude(FreeCAD.Vector(0, 0, thickness))]
if hasattr(baseobject, "Shape") and not isPanel:
return PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams)
return [PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams)]
def opAreaParams(self, obj):
params = {'Fill': 0, 'Coplanar': 2}

View File

@@ -33,7 +33,7 @@ from PySide import QtCore
"""Path Pocket object and FreeCAD command"""
if False:
if True:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
else:
@@ -64,6 +64,9 @@ class ObjectPocket(PathAreaOp.ObjectOp):
def opFeatures(self, obj):
return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint | PathAreaOp.FeatureBaseFaces | PathAreaOp.FeatureFinishDepth
def opUseProjection(self, obj):
return False
def opShapeForDepths(self, obj):
job = PathUtils.findParentJob(obj)
if job and job.Base:
@@ -72,44 +75,6 @@ class ObjectPocket(PathAreaOp.ObjectOp):
PathLog.warning("No job object found (%s), or job has no Base." % job)
return None
def addpocketbase(self, obj, ss, sub=""):
PathLog.track()
baselist = obj.Base
if baselist is None:
baselist = []
if len(baselist) == 0: # When adding the first base object, guess at heights
try:
bb = ss.Shape.BoundBox # parent boundbox
subobj = ss.Shape.getElement(sub)
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
obj.SafeHeight = bb.ZMax + 3.0
if fbb.ZMax == fbb.ZMin and fbb.ZMax == bb.ZMax: # top face
obj.FinalDepth = bb.ZMin
elif fbb.ZMax > fbb.ZMin and fbb.ZMax == bb.ZMax: # vertical face, full cut
obj.FinalDepth = fbb.ZMin
elif fbb.ZMax > fbb.ZMin and fbb.ZMin > bb.ZMin: # internal vertical wall
obj.FinalDepth = fbb.ZMin
elif fbb.ZMax == fbb.ZMin and fbb.ZMax > bb.ZMin: # face/shelf
obj.FinalDepth = fbb.ZMin
else: # catch all
obj.FinalDepth = bb.ZMin
except:
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
item = (ss, sub)
if item in baselist:
PathLog.warning(translate("Path", "this object already in the list" + "\n"))
else:
baselist.append(item)
obj.Base = baselist
self.execute(obj)
def opAreaParams(self, obj):
params = {}
params['Fill'] = 0
@@ -136,7 +101,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
params['sort_mode'] = 2
return params
def opShape(self, obj, commandlist):
def opShapes(self, obj, commandlist):
PathLog.track()
job = PathUtils.findParentJob(obj)
@@ -146,6 +111,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
if obj.Base:
PathLog.debug("base items exist. Processing...")
removalshapes = []
for b in obj.Base:
PathLog.debug("Base item: {}".format(b))
for sub in b[1]:
@@ -157,22 +123,26 @@ class ObjectPocket(PathAreaOp.ObjectOp):
env = PathUtils.getEnvelope(baseobject.Shape, subshape=shape, depthparams=self.depthparams)
obj.removalshape = env.cut(baseobject.Shape)
removalshapes.append(obj.removalshape)
else: # process the job base object as a whole
PathLog.debug("processing the whole job base object")
env = PathUtils.getEnvelope(baseobject.Shape, subshape=None, depthparams=self.depthparams)
obj.removalshape = env.cut(baseobject.Shape)
return obj.removalshape
removalshapes = [obj.removalshape]
return removalshapes
def opSetDefaultValues(self, obj):
obj.StepOver = 100
obj.ZigZagAngle = 45
def opOnChanged(self, obj, prop):
#PathLog.track(obj.Label, prop)
if prop == 'Base' and len(obj.Base) == 1:
try:
(base, sub) = obj.Base[0]
bb = base.Shape.BoundBox # parent boundbox
subobj = base.Shape.getElement(sub)
subobj = base.Shape.getElement(sub[0])
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
@@ -188,7 +158,8 @@ class ObjectPocket(PathAreaOp.ObjectOp):
obj.FinalDepth = fbb.ZMin
else: # catch all
obj.FinalDepth = bb.ZMin
except:
except Exception as e:
PathLog.error(translate("PathPocket", "Error in calculating depths: %s" % e))
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0