Merge pull request #5008 from Russ4262/fix/childless_job

[Path] Fixes #4645
This commit is contained in:
sliptonic
2022-01-03 10:37:27 -06:00
committed by GitHub
2 changed files with 100 additions and 26 deletions

View File

@@ -20,8 +20,6 @@
# * *
# ***************************************************************************
from PathScripts.PathPostProcessor import PostProcessor
from PySide import QtCore
import FreeCAD
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
@@ -31,6 +29,8 @@ import PathScripts.PathToolController as PathToolController
import PathScripts.PathUtil as PathUtil
import json
import time
from PathScripts.PathPostProcessor import PostProcessor
from PySide import QtCore
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -75,7 +75,6 @@ def isResourceClone(obj, propLink, resourceName):
def createResourceClone(obj, orig, name, icon):
clone = Draft.clone(orig)
clone.Label = "%s-%s" % (name, orig.Label)
clone.addProperty("App::PropertyString", "PathResource")
@@ -102,9 +101,12 @@ Notification = NotificationClass()
class ObjectJob:
def __init__(self, obj, models, templateFile=None):
self.obj = obj
self.tooltip = None
self.tooltipArgs = None
obj.Proxy = self
obj.addProperty(
"App::PropertyFile",
"PostProcessorOutputFile",
@@ -217,6 +219,15 @@ class ObjectJob:
obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs()
obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance()
self.setupOperations(obj)
self.setupSetupSheet(obj)
self.setupBaseModel(obj, models)
self.setupToolTable(obj)
self.setFromTemplateFile(obj, templateFile)
self.setupStock(obj)
def setupOperations(self, obj):
"""setupOperations(obj)... setup the Operations group for the Job object."""
ops = FreeCAD.ActiveDocument.addObject(
"Path::FeatureCompoundPython", "Operations"
)
@@ -228,25 +239,6 @@ class ObjectJob:
obj.setEditorMode("Operations", 2) # hide
obj.setEditorMode("Placement", 2)
self.setupSetupSheet(obj)
self.setupBaseModel(obj, models)
self.setupToolTable(obj)
self.tooltip = None
self.tooltipArgs = None
obj.Proxy = self
self.setFromTemplateFile(obj, templateFile)
if not obj.Stock:
stockTemplate = PathPreferences.defaultStockTemplate()
if stockTemplate:
obj.Stock = PathStock.CreateFromTemplate(obj, json.loads(stockTemplate))
if not obj.Stock:
obj.Stock = PathStock.CreateFromBase(obj)
if obj.Stock.ViewObject:
obj.Stock.ViewObject.Visibility = False
def setupSetupSheet(self, obj):
if not getattr(obj, "SetupSheet", None):
obj.addProperty(
@@ -264,10 +256,13 @@ class ObjectJob:
PathScripts.PathIconViewProvider.Attach(
obj.SetupSheet.ViewObject, "SetupSheet"
)
obj.SetupSheet.Label = "SetupSheet"
self.setupSheet = obj.SetupSheet.Proxy
def setupBaseModel(self, obj, models=None):
PathLog.track(obj.Label, models)
addModels = False
if not hasattr(obj, "Model"):
obj.addProperty(
"App::PropertyLink",
@@ -277,6 +272,11 @@ class ObjectJob:
"PathJob", "The base objects for all operations"
),
)
addModels = True
elif obj.Model is None:
addModels = True
if addModels:
model = FreeCAD.ActiveDocument.addObject(
"App::DocumentObjectGroup", "Model"
)
@@ -287,6 +287,7 @@ class ObjectJob:
[createModelResourceClone(obj, base) for base in models]
)
obj.Model = model
obj.Model.Label = "Model"
if hasattr(obj, "Base"):
PathLog.info(
@@ -297,6 +298,7 @@ class ObjectJob:
obj.removeProperty("Base")
def setupToolTable(self, obj):
addTable = False
if not hasattr(obj, "Tools"):
obj.addProperty(
"App::PropertyLink",
@@ -306,6 +308,11 @@ class ObjectJob:
"PathJob", "Collection of all tool controllers for the job"
),
)
addTable = True
elif obj.Tools is None:
addTable = True
if addTable:
toolTable = FreeCAD.ActiveDocument.addObject(
"App::DocumentObjectGroup", "Tools"
)
@@ -317,6 +324,17 @@ class ObjectJob:
obj.removeProperty("ToolController")
obj.Tools = toolTable
def setupStock(self, obj):
"""setupStock(obj)... setup the Stock for the Job object."""
if not obj.Stock:
stockTemplate = PathPreferences.defaultStockTemplate()
if stockTemplate:
obj.Stock = PathStock.CreateFromTemplate(obj, json.loads(stockTemplate))
if not obj.Stock:
obj.Stock = PathStock.CreateFromBase(obj)
if obj.Stock.ViewObject:
obj.Stock.ViewObject.Visibility = False
def removeBase(self, obj, base, removeFromModel):
if isResourceClone(obj, base, None):
PathUtil.clearExpressionEngine(base)
@@ -403,13 +421,17 @@ class ObjectJob:
obj.Operations.Group = []
obj.Operations = ops
FreeCAD.ActiveDocument.removeObject(name)
ops.Label = label
if label == "Unnamed":
ops.Label = "Operations"
else:
ops.Label = label
def onDocumentRestored(self, obj):
self.setupBaseModel(obj)
self.fixupOperations(obj)
self.setupSetupSheet(obj)
self.setupToolTable(obj)
self.integrityCheck(obj)
obj.setEditorMode("Operations", 2) # hide
obj.setEditorMode("Placement", 2)
@@ -624,7 +646,10 @@ class ObjectJob:
def nextToolNumber(self):
# returns the next available toolnumber in the job
group = self.obj.Tools.Group
return sorted([t.ToolNumber for t in group])[-1] + 1
if len(group) > 0:
return sorted([t.ToolNumber for t in group])[-1] + 1
else:
return 1
def addToolController(self, tc):
group = self.obj.Tools.Group
@@ -680,6 +705,49 @@ class ObjectJob:
for op in self.allOperations():
op.Path.Center = center
def integrityCheck(self, job):
"""integrityCheck(job)... Return True if job has all expected children objects. Attempts to restore any missing children."""
suffix = ""
if len(job.Name) > 3:
suffix = job.Name[3:]
def errorMessage(grp, job):
PathLog.error(
translate("PathJobGui", "{} corrupt in {} job.".format(grp, job.Name))
)
if not job.Operations:
self.setupOperations(job)
job.Operations.Label = "Operations" + suffix
if not job.Operations:
errorMessage("Operations", job)
return False
if not job.SetupSheet:
self.setupSetupSheet(job)
job.SetupSheet.Label = "SetupSheet" + suffix
if not job.SetupSheet:
errorMessage("SetupSheet", job)
return False
if not job.Model:
self.setupBaseModel(job)
job.Model.Label = "Model" + suffix
if not job.Model:
errorMessage("Model", job)
return False
if not job.Stock:
self.setupStock(job)
job.Stock.Label = "Stock" + suffix
if not job.Stock:
errorMessage("Stock", job)
return False
if not job.Tools:
self.setupToolTable(job)
job.Tools.Label = "Tools" + suffix
if not job.Tools:
errorMessage("Tools", job)
return False
return True
@classmethod
def baseCandidates(cls):
"""Answer all objects in the current document which could serve as a Base for a job."""

View File

@@ -167,6 +167,9 @@ class ViewProvider:
def setEdit(self, vobj=None, mode=0):
PathLog.track(mode)
if 0 == mode:
job = self.vobj.Object
if not job.Proxy.integrityCheck(job):
return False
self.openTaskPanel()
return True
@@ -1413,7 +1416,10 @@ class TaskPanel:
def setupUi(self, activate):
self.setupGlobal.setupUi()
self.setupOps.setupUi()
try:
self.setupOps.setupUi()
except Exception as ee:
PathLog.error(str(ee))
self.updateStockEditor(-1, False)
self.setFields()