purge archpanel support
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
from PathScripts.PathPostProcessor import PostProcessor
|
||||
from PySide import QtCore
|
||||
import FreeCAD
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
@@ -29,13 +31,11 @@ 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
|
||||
ArchPanel = LazyLoader('ArchPanel', globals(), 'ArchPanel')
|
||||
Draft = LazyLoader('Draft', globals(), 'Draft')
|
||||
|
||||
Draft = LazyLoader("Draft", globals(), "Draft")
|
||||
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
@@ -48,45 +48,41 @@ def translate(context, text, disambig=None):
|
||||
|
||||
class JobTemplate:
|
||||
# pylint: disable=no-init
|
||||
'''Attribute and sub element strings for template export/import.'''
|
||||
Description = 'Desc'
|
||||
GeometryTolerance = 'Tolerance'
|
||||
Job = 'Job'
|
||||
PostProcessor = 'Post'
|
||||
PostProcessorArgs = 'PostArgs'
|
||||
PostProcessorOutputFile = 'Output'
|
||||
Fixtures = 'Fixtures'
|
||||
OrderOutputBy = 'OrderOutputBy'
|
||||
SplitOutput = 'SplitOutput'
|
||||
SetupSheet = 'SetupSheet'
|
||||
Stock = 'Stock'
|
||||
"""Attribute and sub element strings for template export/import."""
|
||||
Description = "Desc"
|
||||
GeometryTolerance = "Tolerance"
|
||||
Job = "Job"
|
||||
PostProcessor = "Post"
|
||||
PostProcessorArgs = "PostArgs"
|
||||
PostProcessorOutputFile = "Output"
|
||||
Fixtures = "Fixtures"
|
||||
OrderOutputBy = "OrderOutputBy"
|
||||
SplitOutput = "SplitOutput"
|
||||
SetupSheet = "SetupSheet"
|
||||
Stock = "Stock"
|
||||
# TCs are grouped under Tools in a job, the template refers to them directly though
|
||||
ToolController = 'ToolController'
|
||||
Version = 'Version'
|
||||
|
||||
|
||||
def isArchPanelSheet(obj):
|
||||
return hasattr(obj, 'Proxy') and isinstance(obj.Proxy, ArchPanel.PanelSheet)
|
||||
ToolController = "ToolController"
|
||||
Version = "Version"
|
||||
|
||||
|
||||
def isResourceClone(obj, propLink, resourceName):
|
||||
# pylint: disable=unused-argument
|
||||
if hasattr(propLink, 'PathResource') and (resourceName is None or resourceName == propLink.PathResource):
|
||||
if hasattr(propLink, "PathResource") and (
|
||||
resourceName is None or resourceName == propLink.PathResource
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def createResourceClone(obj, orig, name, icon):
|
||||
if isArchPanelSheet(orig):
|
||||
# can't clone panel sheets - they have to be panel sheets
|
||||
return orig
|
||||
|
||||
clone = Draft.clone(orig)
|
||||
clone.Label = "%s-%s" % (name, orig.Label)
|
||||
clone.addProperty('App::PropertyString', 'PathResource')
|
||||
clone.addProperty("App::PropertyString", "PathResource")
|
||||
clone.PathResource = name
|
||||
if clone.ViewObject:
|
||||
import PathScripts.PathIconViewProvider
|
||||
|
||||
PathScripts.PathIconViewProvider.Attach(clone.ViewObject, icon)
|
||||
clone.ViewObject.Visibility = False
|
||||
clone.ViewObject.Transparency = 80
|
||||
@@ -95,7 +91,7 @@ def createResourceClone(obj, orig, name, icon):
|
||||
|
||||
|
||||
def createModelResourceClone(obj, orig):
|
||||
return createResourceClone(obj, orig, 'Model', 'BaseGeometry')
|
||||
return createResourceClone(obj, orig, "Model", "BaseGeometry")
|
||||
|
||||
|
||||
class NotificationClass(QtCore.QObject):
|
||||
@@ -106,30 +102,108 @@ Notification = NotificationClass()
|
||||
|
||||
|
||||
class ObjectJob:
|
||||
|
||||
def __init__(self, obj, models, templateFile=None):
|
||||
self.obj = obj
|
||||
obj.addProperty("App::PropertyFile", "PostProcessorOutputFile", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "The NC output file for this project"))
|
||||
obj.addProperty("App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Select the Post Processor"))
|
||||
obj.addProperty("App::PropertyString", "PostProcessorArgs", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Arguments for the Post Processor (specific to the script)"))
|
||||
obj.addProperty("App::PropertyString", "LastPostProcessDate", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Last Time the Job was post-processed"))
|
||||
obj.setEditorMode('LastPostProcessDate', 2) # Hide
|
||||
obj.addProperty("App::PropertyString", "LastPostProcessOutput", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Last Time the Job was post-processed"))
|
||||
obj.setEditorMode('LastPostProcessOutput', 2) # Hide
|
||||
obj.addProperty(
|
||||
"App::PropertyFile",
|
||||
"PostProcessorOutputFile",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "The NC output file for this project"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"PostProcessor",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "Select the Post Processor"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"PostProcessorArgs",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "Arguments for the Post Processor (specific to the script)"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"LastPostProcessDate",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "Last Time the Job was post-processed"),
|
||||
)
|
||||
obj.setEditorMode("LastPostProcessDate", 2) # Hide
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"LastPostProcessOutput",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "Last Time the Job was post-processed"),
|
||||
)
|
||||
obj.setEditorMode("LastPostProcessOutput", 2) # Hide
|
||||
|
||||
obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("PathJob", "An optional description for this job"))
|
||||
obj.addProperty("App::PropertyString", "CycleTime", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Job Cycle Time Estimation"))
|
||||
obj.setEditorMode('CycleTime', 1) # read-only
|
||||
obj.addProperty("App::PropertyDistance", "GeometryTolerance", "Geometry", QtCore.QT_TRANSLATE_NOOP("PathJob", "For computing Paths; smaller increases accuracy, but slows down computation"))
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"Description",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "An optional description for this job"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CycleTime",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Job Cycle Time Estimation"),
|
||||
)
|
||||
obj.setEditorMode("CycleTime", 1) # read-only
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"GeometryTolerance",
|
||||
"Geometry",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob",
|
||||
"For computing Paths; smaller increases accuracy, but slows down computation",
|
||||
),
|
||||
)
|
||||
|
||||
obj.addProperty("App::PropertyLink", "Stock", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Solid object to be used as stock."))
|
||||
obj.addProperty("App::PropertyLink", "Operations", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Compound path of all operations in the order they are processed."))
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Stock",
|
||||
"Base",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathJob", "Solid object to be used as stock."),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Operations",
|
||||
"Base",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob",
|
||||
"Compound path of all operations in the order they are processed.",
|
||||
),
|
||||
)
|
||||
|
||||
obj.addProperty("App::PropertyBool", "SplitOutput", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Split output into multiple gcode files"))
|
||||
obj.addProperty("App::PropertyEnumeration", "OrderOutputBy", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "If multiple WCS, order the output this way"))
|
||||
obj.addProperty("App::PropertyStringList", "Fixtures", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "The Work Coordinate Systems for the Job"))
|
||||
obj.OrderOutputBy = ['Fixture', 'Tool', 'Operation']
|
||||
obj.Fixtures = ['G54']
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"SplitOutput",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "Split output into multiple gcode files"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"OrderOutputBy",
|
||||
"WCS",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "If multiple WCS, order the output this way"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"Fixtures",
|
||||
"WCS",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "The Work Coordinate Systems for the Job"
|
||||
),
|
||||
)
|
||||
obj.OrderOutputBy = ["Fixture", "Tool", "Operation"]
|
||||
obj.Fixtures = ["G54"]
|
||||
|
||||
obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile()
|
||||
obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors()
|
||||
@@ -142,14 +216,16 @@ class ObjectJob:
|
||||
obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs()
|
||||
obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance()
|
||||
|
||||
ops = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Operations")
|
||||
ops = FreeCAD.ActiveDocument.addObject(
|
||||
"Path::FeatureCompoundPython", "Operations"
|
||||
)
|
||||
if ops.ViewObject:
|
||||
ops.ViewObject.Proxy = 0
|
||||
ops.ViewObject.Visibility = False
|
||||
|
||||
obj.Operations = ops
|
||||
obj.setEditorMode('Operations', 2) # hide
|
||||
obj.setEditorMode('Placement', 2)
|
||||
obj.setEditorMode("Operations", 2) # hide
|
||||
obj.setEditorMode("Placement", 2)
|
||||
|
||||
self.setupSetupSheet(obj)
|
||||
self.setupBaseModel(obj, models)
|
||||
@@ -171,41 +247,73 @@ class ObjectJob:
|
||||
obj.Stock.ViewObject.Visibility = False
|
||||
|
||||
def setupSetupSheet(self, obj):
|
||||
if not getattr(obj, 'SetupSheet', None):
|
||||
obj.addProperty('App::PropertyLink', 'SetupSheet', 'Base', QtCore.QT_TRANSLATE_NOOP('PathJob', 'SetupSheet holding the settings for this job'))
|
||||
if not getattr(obj, "SetupSheet", None):
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"SetupSheet",
|
||||
"Base",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "SetupSheet holding the settings for this job"
|
||||
),
|
||||
)
|
||||
obj.SetupSheet = PathSetupSheet.Create()
|
||||
if obj.SetupSheet.ViewObject:
|
||||
import PathScripts.PathIconViewProvider
|
||||
PathScripts.PathIconViewProvider.Attach(obj.SetupSheet.ViewObject, 'SetupSheet')
|
||||
|
||||
PathScripts.PathIconViewProvider.Attach(
|
||||
obj.SetupSheet.ViewObject, "SetupSheet"
|
||||
)
|
||||
self.setupSheet = obj.SetupSheet.Proxy
|
||||
|
||||
def setupBaseModel(self, obj, models=None):
|
||||
PathLog.track(obj.Label, models)
|
||||
if not hasattr(obj, 'Model'):
|
||||
obj.addProperty("App::PropertyLink", "Model", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "The base objects for all operations"))
|
||||
model = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", "Model")
|
||||
if not hasattr(obj, "Model"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Model",
|
||||
"Base",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "The base objects for all operations"
|
||||
),
|
||||
)
|
||||
model = FreeCAD.ActiveDocument.addObject(
|
||||
"App::DocumentObjectGroup", "Model"
|
||||
)
|
||||
if model.ViewObject:
|
||||
model.ViewObject.Visibility = False
|
||||
if models:
|
||||
model.addObjects([createModelResourceClone(obj, base) for base in models])
|
||||
model.addObjects(
|
||||
[createModelResourceClone(obj, base) for base in models]
|
||||
)
|
||||
obj.Model = model
|
||||
|
||||
if hasattr(obj, 'Base'):
|
||||
PathLog.info("Converting Job.Base to new Job.Model for {}".format(obj.Label))
|
||||
if hasattr(obj, "Base"):
|
||||
PathLog.info(
|
||||
"Converting Job.Base to new Job.Model for {}".format(obj.Label)
|
||||
)
|
||||
obj.Model.addObject(obj.Base)
|
||||
obj.Base = None
|
||||
obj.removeProperty('Base')
|
||||
obj.removeProperty("Base")
|
||||
|
||||
def setupToolTable(self, obj):
|
||||
if not hasattr(obj, 'Tools'):
|
||||
obj.addProperty("App::PropertyLink", "Tools", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Collection of all tool controllers for the job"))
|
||||
toolTable = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", "Tools")
|
||||
toolTable.Label = 'Tools'
|
||||
if not hasattr(obj, "Tools"):
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"Tools",
|
||||
"Base",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "Collection of all tool controllers for the job"
|
||||
),
|
||||
)
|
||||
toolTable = FreeCAD.ActiveDocument.addObject(
|
||||
"App::DocumentObjectGroup", "Tools"
|
||||
)
|
||||
toolTable.Label = "Tools"
|
||||
if toolTable.ViewObject:
|
||||
toolTable.ViewObject.Visibility = False
|
||||
if hasattr(obj, 'ToolController'):
|
||||
if hasattr(obj, "ToolController"):
|
||||
toolTable.addObjects(obj.ToolController)
|
||||
obj.removeProperty('ToolController')
|
||||
obj.removeProperty("ToolController")
|
||||
obj.Tools = toolTable
|
||||
|
||||
def removeBase(self, obj, base, removeFromModel):
|
||||
@@ -219,16 +327,22 @@ class ObjectJob:
|
||||
return PathStock.shapeBoundBox(obj.Model.Group)
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
'''Called by the view provider, there doesn't seem to be a callback on the obj itself.'''
|
||||
"""Called by the view provider, there doesn't seem to be a callback on the obj itself."""
|
||||
PathLog.track(obj.Label, arg2)
|
||||
doc = obj.Document
|
||||
|
||||
if getattr(obj, 'Operations', None):
|
||||
if getattr(obj, "Operations", None):
|
||||
# the first to tear down are the ops, they depend on other resources
|
||||
PathLog.debug('taking down ops: %s' % [o.Name for o in self.allOperations()])
|
||||
PathLog.debug(
|
||||
"taking down ops: %s" % [o.Name for o in self.allOperations()]
|
||||
)
|
||||
while obj.Operations.Group:
|
||||
op = obj.Operations.Group[0]
|
||||
if not op.ViewObject or not hasattr(op.ViewObject.Proxy, 'onDelete') or op.ViewObject.Proxy.onDelete(op.ViewObject, ()):
|
||||
if (
|
||||
not op.ViewObject
|
||||
or not hasattr(op.ViewObject.Proxy, "onDelete")
|
||||
or op.ViewObject.Proxy.onDelete(op.ViewObject, ())
|
||||
):
|
||||
PathUtil.clearExpressionEngine(op)
|
||||
doc.removeObject(op.Name)
|
||||
obj.Operations.Group = []
|
||||
@@ -236,14 +350,14 @@ class ObjectJob:
|
||||
obj.Operations = None
|
||||
|
||||
# stock could depend on Model, so delete it first
|
||||
if getattr(obj, 'Stock', None):
|
||||
PathLog.debug('taking down stock')
|
||||
if getattr(obj, "Stock", None):
|
||||
PathLog.debug("taking down stock")
|
||||
PathUtil.clearExpressionEngine(obj.Stock)
|
||||
doc.removeObject(obj.Stock.Name)
|
||||
obj.Stock = None
|
||||
|
||||
# base doesn't depend on anything inside job
|
||||
if getattr(obj, 'Model', None):
|
||||
if getattr(obj, "Model", None):
|
||||
for base in obj.Model.Group:
|
||||
PathLog.debug("taking down base %s" % base.Label)
|
||||
self.removeBase(obj, base, False)
|
||||
@@ -252,8 +366,8 @@ class ObjectJob:
|
||||
obj.Model = None
|
||||
|
||||
# Tool controllers might refer to either legacy tool or toolbit
|
||||
if getattr(obj, 'Tools', None):
|
||||
PathLog.debug('taking down tool controller')
|
||||
if getattr(obj, "Tools", None):
|
||||
PathLog.debug("taking down tool controller")
|
||||
for tc in obj.Tools.Group:
|
||||
if hasattr(tc.Tool, "Proxy"):
|
||||
PathUtil.clearExpressionEngine(tc.Tool)
|
||||
@@ -266,7 +380,7 @@ class ObjectJob:
|
||||
obj.Tools = None
|
||||
|
||||
# SetupSheet
|
||||
if getattr(obj, 'SetupSheet', None):
|
||||
if getattr(obj, "SetupSheet", None):
|
||||
PathUtil.clearExpressionEngine(obj.SetupSheet)
|
||||
doc.removeObject(obj.SetupSheet.Name)
|
||||
obj.SetupSheet = None
|
||||
@@ -274,13 +388,15 @@ class ObjectJob:
|
||||
return True
|
||||
|
||||
def fixupOperations(self, obj):
|
||||
if getattr(obj.Operations, 'ViewObject', None):
|
||||
if getattr(obj.Operations, "ViewObject", None):
|
||||
try:
|
||||
obj.Operations.ViewObject.DisplayMode
|
||||
except Exception: # pylint: disable=broad-except
|
||||
name = obj.Operations.Name
|
||||
label = obj.Operations.Label
|
||||
ops = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Operations")
|
||||
ops = FreeCAD.ActiveDocument.addObject(
|
||||
"Path::FeatureCompoundPython", "Operations"
|
||||
)
|
||||
ops.ViewObject.Proxy = 0
|
||||
ops.Group = obj.Operations.Group
|
||||
obj.Operations.Group = []
|
||||
@@ -294,23 +410,49 @@ class ObjectJob:
|
||||
self.setupSetupSheet(obj)
|
||||
self.setupToolTable(obj)
|
||||
|
||||
obj.setEditorMode('Operations', 2) # hide
|
||||
obj.setEditorMode('Placement', 2)
|
||||
obj.setEditorMode("Operations", 2) # hide
|
||||
obj.setEditorMode("Placement", 2)
|
||||
|
||||
if not hasattr(obj, 'CycleTime'):
|
||||
obj.addProperty("App::PropertyString", "CycleTime", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"))
|
||||
obj.setEditorMode('CycleTime', 1) # read-only
|
||||
if not hasattr(obj, "CycleTime"):
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CycleTime",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"),
|
||||
)
|
||||
obj.setEditorMode("CycleTime", 1) # read-only
|
||||
|
||||
if not hasattr(obj, "Fixtures"):
|
||||
obj.addProperty("App::PropertyStringList", "Fixtures", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "The Work Coordinate Systems for the Job"))
|
||||
obj.Fixtures = ['G54']
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"Fixtures",
|
||||
"WCS",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "The Work Coordinate Systems for the Job"
|
||||
),
|
||||
)
|
||||
obj.Fixtures = ["G54"]
|
||||
|
||||
if not hasattr(obj, "OrderOutputBy"):
|
||||
obj.addProperty("App::PropertyEnumeration", "OrderOutputBy", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "If multiple WCS, order the output this way"))
|
||||
obj.OrderOutputBy = ['Fixture', 'Tool', 'Operation']
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"OrderOutputBy",
|
||||
"WCS",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "If multiple WCS, order the output this way"
|
||||
),
|
||||
)
|
||||
obj.OrderOutputBy = ["Fixture", "Tool", "Operation"]
|
||||
|
||||
if not hasattr(obj, "SplitOutput"):
|
||||
obj.addProperty("App::PropertyBool", "SplitOutput", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Split output into multiple gcode files"))
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"SplitOutput",
|
||||
"Output",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathJob", "Split output into multiple gcode files"
|
||||
),
|
||||
)
|
||||
obj.SplitOutput = False
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
@@ -320,17 +462,17 @@ class ObjectJob:
|
||||
self.tooltipArgs = processor.tooltipArgs
|
||||
|
||||
def baseObject(self, obj, base):
|
||||
'''Return the base object, not its clone.'''
|
||||
if isResourceClone(obj, base, 'Model') or isResourceClone(obj, base, 'Base'):
|
||||
"""Return the base object, not its clone."""
|
||||
if isResourceClone(obj, base, "Model") or isResourceClone(obj, base, "Base"):
|
||||
return base.Objects[0]
|
||||
return base
|
||||
|
||||
def baseObjects(self, obj):
|
||||
'''Return the base objects, not their clones.'''
|
||||
"""Return the base objects, not their clones."""
|
||||
return [self.baseObject(obj, base) for base in obj.Model.Group]
|
||||
|
||||
def resourceClone(self, obj, base):
|
||||
'''resourceClone(obj, base) ... Return the resource clone for base if it exists.'''
|
||||
"""resourceClone(obj, base) ... Return the resource clone for base if it exists."""
|
||||
if isResourceClone(obj, base, None):
|
||||
return base
|
||||
for b in obj.Model.Group:
|
||||
@@ -339,11 +481,11 @@ class ObjectJob:
|
||||
return None
|
||||
|
||||
def setFromTemplateFile(self, obj, template):
|
||||
'''setFromTemplateFile(obj, template) ... extract the properties from the given template file and assign to receiver.
|
||||
This will also create any TCs stored in the template.'''
|
||||
"""setFromTemplateFile(obj, template) ... extract the properties from the given template file and assign to receiver.
|
||||
This will also create any TCs stored in the template."""
|
||||
tcs = []
|
||||
if template:
|
||||
with open(PathUtil.toUnicode(template), 'rb') as fp:
|
||||
with open(PathUtil.toUnicode(template), "rb") as fp:
|
||||
attrs = json.load(fp)
|
||||
|
||||
if attrs.get(JobTemplate.Version) and 1 == int(attrs[JobTemplate.Version]):
|
||||
@@ -352,15 +494,19 @@ class ObjectJob:
|
||||
self.setupSheet.setFromTemplate(attrs[JobTemplate.SetupSheet])
|
||||
|
||||
if attrs.get(JobTemplate.GeometryTolerance):
|
||||
obj.GeometryTolerance = float(attrs.get(JobTemplate.GeometryTolerance))
|
||||
obj.GeometryTolerance = float(
|
||||
attrs.get(JobTemplate.GeometryTolerance)
|
||||
)
|
||||
if attrs.get(JobTemplate.PostProcessor):
|
||||
obj.PostProcessor = attrs.get(JobTemplate.PostProcessor)
|
||||
if attrs.get(JobTemplate.PostProcessorArgs):
|
||||
obj.PostProcessorArgs = attrs.get(JobTemplate.PostProcessorArgs)
|
||||
else:
|
||||
obj.PostProcessorArgs = ''
|
||||
obj.PostProcessorArgs = ""
|
||||
if attrs.get(JobTemplate.PostProcessorOutputFile):
|
||||
obj.PostProcessorOutputFile = attrs.get(JobTemplate.PostProcessorOutputFile)
|
||||
obj.PostProcessorOutputFile = attrs.get(
|
||||
JobTemplate.PostProcessorOutputFile
|
||||
)
|
||||
if attrs.get(JobTemplate.Description):
|
||||
obj.Description = attrs.get(JobTemplate.Description)
|
||||
|
||||
@@ -368,10 +514,14 @@ class ObjectJob:
|
||||
for tc in attrs.get(JobTemplate.ToolController):
|
||||
tcs.append(PathToolController.FromTemplate(tc))
|
||||
if attrs.get(JobTemplate.Stock):
|
||||
obj.Stock = PathStock.CreateFromTemplate(obj, attrs.get(JobTemplate.Stock))
|
||||
obj.Stock = PathStock.CreateFromTemplate(
|
||||
obj, attrs.get(JobTemplate.Stock)
|
||||
)
|
||||
|
||||
if attrs.get(JobTemplate.Fixtures):
|
||||
obj.Fixtures = [x for y in attrs.get(JobTemplate.Fixtures) for x in y]
|
||||
obj.Fixtures = [
|
||||
x for y in attrs.get(JobTemplate.Fixtures) for x in y
|
||||
]
|
||||
|
||||
if attrs.get(JobTemplate.OrderOutputBy):
|
||||
obj.OrderOutputBy = attrs.get(JobTemplate.OrderOutputBy)
|
||||
@@ -382,12 +532,15 @@ class ObjectJob:
|
||||
PathLog.debug("setting tool controllers (%d)" % len(tcs))
|
||||
obj.Tools.Group = tcs
|
||||
else:
|
||||
PathLog.error(translate('PathJob', "Unsupported PathJob template version %s") % attrs.get(JobTemplate.Version))
|
||||
PathLog.error(
|
||||
translate("PathJob", "Unsupported PathJob template version %s")
|
||||
% attrs.get(JobTemplate.Version)
|
||||
)
|
||||
if not tcs:
|
||||
self.addToolController(PathToolController.Create())
|
||||
|
||||
def templateAttrs(self, obj):
|
||||
'''templateAttrs(obj) ... answer a dictionary with all properties of the receiver that should be stored in a template file.'''
|
||||
"""templateAttrs(obj) ... answer a dictionary with all properties of the receiver that should be stored in a template file."""
|
||||
attrs = {}
|
||||
attrs[JobTemplate.Version] = 1
|
||||
if obj.PostProcessor:
|
||||
@@ -408,13 +561,13 @@ class ObjectJob:
|
||||
|
||||
def __setstate__(self, state):
|
||||
for obj in FreeCAD.ActiveDocument.Objects:
|
||||
if hasattr(obj, 'Proxy') and obj.Proxy == self:
|
||||
if hasattr(obj, "Proxy") and obj.Proxy == self:
|
||||
self.obj = obj
|
||||
break
|
||||
return None
|
||||
|
||||
def execute(self, obj):
|
||||
if getattr(obj, 'Operations', None):
|
||||
if getattr(obj, "Operations", None):
|
||||
obj.Path = obj.Operations.Path
|
||||
self.getCycleTime()
|
||||
|
||||
@@ -425,18 +578,23 @@ class ObjectJob:
|
||||
for op in self.obj.Operations.Group:
|
||||
|
||||
# Skip inactive operations
|
||||
if PathUtil.opProperty(op, 'Active') is False:
|
||||
if PathUtil.opProperty(op, "Active") is False:
|
||||
continue
|
||||
|
||||
# Skip operations that don't have a cycletime attribute
|
||||
if PathUtil.opProperty(op, 'CycleTime') is None:
|
||||
if PathUtil.opProperty(op, "CycleTime") is None:
|
||||
continue
|
||||
|
||||
formattedCycleTime = PathUtil.opProperty(op, 'CycleTime')
|
||||
formattedCycleTime = PathUtil.opProperty(op, "CycleTime")
|
||||
opCycleTime = 0
|
||||
try:
|
||||
# Convert the formatted time from HH:MM:SS to just seconds
|
||||
opCycleTime = sum(x * int(t) for x, t in zip([1, 60, 3600], reversed(formattedCycleTime.split(":"))))
|
||||
opCycleTime = sum(
|
||||
x * int(t)
|
||||
for x, t in zip(
|
||||
[1, 60, 3600], reversed(formattedCycleTime.split(":"))
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
@@ -469,10 +627,26 @@ class ObjectJob:
|
||||
|
||||
def addToolController(self, tc):
|
||||
group = self.obj.Tools.Group
|
||||
PathLog.debug("addToolController(%s): %s" % (tc.Label, [t.Label for t in group]))
|
||||
PathLog.debug(
|
||||
"addToolController(%s): %s" % (tc.Label, [t.Label for t in group])
|
||||
)
|
||||
if tc.Name not in [str(t.Name) for t in group]:
|
||||
tc.setExpression('VertRapid', "%s.%s" % (self.setupSheet.expressionReference(), PathSetupSheet.Template.VertRapid))
|
||||
tc.setExpression('HorizRapid', "%s.%s" % (self.setupSheet.expressionReference(), PathSetupSheet.Template.HorizRapid))
|
||||
tc.setExpression(
|
||||
"VertRapid",
|
||||
"%s.%s"
|
||||
% (
|
||||
self.setupSheet.expressionReference(),
|
||||
PathSetupSheet.Template.VertRapid,
|
||||
),
|
||||
)
|
||||
tc.setExpression(
|
||||
"HorizRapid",
|
||||
"%s.%s"
|
||||
% (
|
||||
self.setupSheet.expressionReference(),
|
||||
PathSetupSheet.Template.HorizRapid,
|
||||
),
|
||||
)
|
||||
self.obj.Tools.addObject(tc)
|
||||
Notification.updateTC.emit(self.obj, tc)
|
||||
|
||||
@@ -480,17 +654,19 @@ class ObjectJob:
|
||||
ops = []
|
||||
|
||||
def collectBaseOps(op):
|
||||
if hasattr(op, 'TypeId'):
|
||||
if op.TypeId == 'Path::FeaturePython':
|
||||
if hasattr(op, "TypeId"):
|
||||
if op.TypeId == "Path::FeaturePython":
|
||||
ops.append(op)
|
||||
if hasattr(op, 'Base'):
|
||||
if hasattr(op, "Base"):
|
||||
collectBaseOps(op.Base)
|
||||
if op.TypeId == 'Path::FeatureCompoundPython':
|
||||
if op.TypeId == "Path::FeatureCompoundPython":
|
||||
ops.append(op)
|
||||
for sub in op.Group:
|
||||
collectBaseOps(sub)
|
||||
|
||||
if getattr(self.obj, 'Operations', None) and getattr(self.obj.Operations, 'Group', None):
|
||||
if getattr(self.obj, "Operations", None) and getattr(
|
||||
self.obj.Operations, "Group", None
|
||||
):
|
||||
for op in self.obj.Operations.Group:
|
||||
collectBaseOps(op)
|
||||
|
||||
@@ -505,25 +681,32 @@ class ObjectJob:
|
||||
|
||||
@classmethod
|
||||
def baseCandidates(cls):
|
||||
'''Answer all objects in the current document which could serve as a Base for a job.'''
|
||||
return sorted([obj for obj in FreeCAD.ActiveDocument.Objects if cls.isBaseCandidate(obj)], key=lambda o: o.Label)
|
||||
"""Answer all objects in the current document which could serve as a Base for a job."""
|
||||
return sorted(
|
||||
[obj for obj in FreeCAD.ActiveDocument.Objects if cls.isBaseCandidate(obj)],
|
||||
key=lambda o: o.Label,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def isBaseCandidate(cls, obj):
|
||||
'''Answer true if the given object can be used as a Base for a job.'''
|
||||
return PathUtil.isValidBaseObject(obj) or isArchPanelSheet(obj)
|
||||
"""Answer true if the given object can be used as a Base for a job."""
|
||||
return PathUtil.isValidBaseObject(obj)
|
||||
|
||||
|
||||
def Instances():
|
||||
'''Instances() ... Return all Jobs in the current active document.'''
|
||||
"""Instances() ... Return all Jobs in the current active document."""
|
||||
if FreeCAD.ActiveDocument:
|
||||
return [job for job in FreeCAD.ActiveDocument.Objects if hasattr(job, 'Proxy') and isinstance(job.Proxy, ObjectJob)]
|
||||
return [
|
||||
job
|
||||
for job in FreeCAD.ActiveDocument.Objects
|
||||
if hasattr(job, "Proxy") and isinstance(job.Proxy, ObjectJob)
|
||||
]
|
||||
return []
|
||||
|
||||
|
||||
def Create(name, base, templateFile=None):
|
||||
'''Create(name, base, templateFile=None) ... creates a new job and all it's resources.
|
||||
If a template file is specified the new job is initialized with the values from the template.'''
|
||||
"""Create(name, base, templateFile=None) ... creates a new job and all it's resources.
|
||||
If a template file is specified the new job is initialized with the values from the template."""
|
||||
if isinstance(base[0], str):
|
||||
models = []
|
||||
for baseName in base:
|
||||
|
||||
Reference in New Issue
Block a user