purge archpanel support
This commit is contained in:
@@ -24,17 +24,18 @@ import time
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
from PathScripts.PathUtils import waiting_effects
|
||||
import Path
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
from PathScripts.PathUtils import waiting_effects
|
||||
|
||||
# lazily loaded modules
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
Part = LazyLoader('Part', globals(), 'Part')
|
||||
|
||||
Part = LazyLoader("Part", globals(), "Part")
|
||||
|
||||
__title__ = "Base class for all operations."
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
@@ -65,11 +66,11 @@ FeatureLocations = 0x1000 # Locations
|
||||
FeatureCoolant = 0x2000 # Coolant
|
||||
FeatureDiameters = 0x4000 # Turning Diameters
|
||||
|
||||
FeatureBaseGeometry = FeatureBaseVertexes | FeatureBaseFaces | FeatureBaseEdges | FeatureBasePanels
|
||||
FeatureBaseGeometry = FeatureBaseVertexes | FeatureBaseFaces | FeatureBaseEdges
|
||||
|
||||
|
||||
class ObjectOp(object):
|
||||
'''
|
||||
"""
|
||||
Base class for proxy objects of all Path operations.
|
||||
|
||||
Use this class as a base class for new operations. It provides properties
|
||||
@@ -88,7 +89,6 @@ class ObjectOp(object):
|
||||
FeatureBaseVertexes ... Base geometry support for vertexes
|
||||
FeatureBaseEdges ... Base geometry support for edges
|
||||
FeatureBaseFaces ... Base geometry support for faces
|
||||
FeatureBasePanels ... Base geometry support for Arch.Panels
|
||||
FeatureLocations ... Base location support
|
||||
FeatureCoolant ... Support for operation coolant
|
||||
FeatureDiameters ... Support for turning operation diameters
|
||||
@@ -98,35 +98,93 @@ class ObjectOp(object):
|
||||
but implement the function opOnChanged().
|
||||
If a base class overwrites a base API function it should call the super's
|
||||
implementation - otherwise the base functionality might be broken.
|
||||
'''
|
||||
"""
|
||||
|
||||
def addBaseProperty(self, obj):
|
||||
obj.addProperty("App::PropertyLinkSubListGlobal", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "The base geometry for this operation"))
|
||||
obj.addProperty(
|
||||
"App::PropertyLinkSubListGlobal",
|
||||
"Base",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "The base geometry for this operation"),
|
||||
)
|
||||
|
||||
def addOpValues(self, obj, values):
|
||||
if 'start' in values:
|
||||
obj.addProperty("App::PropertyDistance", "OpStartDepth", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the calculated value for the StartDepth"))
|
||||
obj.setEditorMode('OpStartDepth', 1) # read-only
|
||||
if 'final' in values:
|
||||
obj.addProperty("App::PropertyDistance", "OpFinalDepth", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the calculated value for the FinalDepth"))
|
||||
obj.setEditorMode('OpFinalDepth', 1) # read-only
|
||||
if 'tooldia' in values:
|
||||
obj.addProperty("App::PropertyDistance", "OpToolDiameter", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the diameter of the tool"))
|
||||
obj.setEditorMode('OpToolDiameter', 1) # read-only
|
||||
if 'stockz' in values:
|
||||
obj.addProperty("App::PropertyDistance", "OpStockZMax", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the max Z value of Stock"))
|
||||
obj.setEditorMode('OpStockZMax', 1) # read-only
|
||||
obj.addProperty("App::PropertyDistance", "OpStockZMin", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the min Z value of Stock"))
|
||||
obj.setEditorMode('OpStockZMin', 1) # read-only
|
||||
if "start" in values:
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"OpStartDepth",
|
||||
"Op Values",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Holds the calculated value for the StartDepth"
|
||||
),
|
||||
)
|
||||
obj.setEditorMode("OpStartDepth", 1) # read-only
|
||||
if "final" in values:
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"OpFinalDepth",
|
||||
"Op Values",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Holds the calculated value for the FinalDepth"
|
||||
),
|
||||
)
|
||||
obj.setEditorMode("OpFinalDepth", 1) # read-only
|
||||
if "tooldia" in values:
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"OpToolDiameter",
|
||||
"Op Values",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the diameter of the tool"),
|
||||
)
|
||||
obj.setEditorMode("OpToolDiameter", 1) # read-only
|
||||
if "stockz" in values:
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"OpStockZMax",
|
||||
"Op Values",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the max Z value of Stock"),
|
||||
)
|
||||
obj.setEditorMode("OpStockZMax", 1) # read-only
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"OpStockZMin",
|
||||
"Op Values",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the min Z value of Stock"),
|
||||
)
|
||||
obj.setEditorMode("OpStockZMin", 1) # read-only
|
||||
|
||||
def __init__(self, obj, name, parentJob=None):
|
||||
PathLog.track()
|
||||
|
||||
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Make False, to prevent operation from generating code"))
|
||||
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "An optional comment for this Operation"))
|
||||
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "User Assigned Label"))
|
||||
obj.addProperty("App::PropertyString", "CycleTime", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"))
|
||||
obj.setEditorMode('CycleTime', 1) # read-only
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"Active",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Make False, to prevent operation from generating code"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"Comment",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "An optional comment for this Operation"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"UserLabel",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "User Assigned Label"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CycleTime",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"),
|
||||
)
|
||||
obj.setEditorMode("CycleTime", 1) # read-only
|
||||
|
||||
features = self.opFeatures(obj)
|
||||
|
||||
@@ -134,45 +192,136 @@ class ObjectOp(object):
|
||||
self.addBaseProperty(obj)
|
||||
|
||||
if FeatureLocations & features:
|
||||
obj.addProperty("App::PropertyVectorList", "Locations", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Base locations for this operation"))
|
||||
obj.addProperty(
|
||||
"App::PropertyVectorList",
|
||||
"Locations",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Base locations for this operation"),
|
||||
)
|
||||
|
||||
if FeatureTool & features:
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "The tool controller that will be used to calculate the path"))
|
||||
self.addOpValues(obj, ['tooldia'])
|
||||
obj.addProperty(
|
||||
"App::PropertyLink",
|
||||
"ToolController",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp",
|
||||
"The tool controller that will be used to calculate the path",
|
||||
),
|
||||
)
|
||||
self.addOpValues(obj, ["tooldia"])
|
||||
|
||||
if FeatureCoolant & features:
|
||||
obj.addProperty("App::PropertyString", "CoolantMode", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Coolant mode for this operation"))
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CoolantMode",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Coolant mode for this operation"),
|
||||
)
|
||||
|
||||
if FeatureDepths & features:
|
||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Starting Depth of Tool- first cut depth in Z"))
|
||||
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Final Depth of Tool- lowest value in Z"))
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"StartDepth",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Starting Depth of Tool- first cut depth in Z"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"FinalDepth",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Final Depth of Tool- lowest value in Z"
|
||||
),
|
||||
)
|
||||
if FeatureNoFinalDepth & features:
|
||||
obj.setEditorMode('FinalDepth', 2) # hide
|
||||
self.addOpValues(obj, ['start', 'final'])
|
||||
obj.setEditorMode("FinalDepth", 2) # hide
|
||||
self.addOpValues(obj, ["start", "final"])
|
||||
else:
|
||||
# StartDepth has become necessary for expressions on other properties
|
||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Starting Depth internal use only for derived values"))
|
||||
obj.setEditorMode('StartDepth', 1) # read-only
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"StartDepth",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Starting Depth internal use only for derived values"
|
||||
),
|
||||
)
|
||||
obj.setEditorMode("StartDepth", 1) # read-only
|
||||
|
||||
self.addOpValues(obj, ['stockz'])
|
||||
self.addOpValues(obj, ["stockz"])
|
||||
|
||||
if FeatureStepDown & features:
|
||||
obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Incremental Step Down of Tool"))
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"StepDown",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Incremental Step Down of Tool"),
|
||||
)
|
||||
|
||||
if FeatureFinishDepth & features:
|
||||
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Maximum material removed on final pass."))
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"FinishDepth",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Maximum material removed on final pass."
|
||||
),
|
||||
)
|
||||
|
||||
if FeatureHeights & features:
|
||||
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "The height needed to clear clamps and obstructions"))
|
||||
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Rapid Safety Height between locations."))
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"ClearanceHeight",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "The height needed to clear clamps and obstructions"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"SafeHeight",
|
||||
"Depth",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Rapid Safety Height between locations."
|
||||
),
|
||||
)
|
||||
|
||||
if FeatureStartPoint & features:
|
||||
obj.addProperty("App::PropertyVectorDistance", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("PathOp", "The start point of this path"))
|
||||
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("PathOp", "Make True, if specifying a Start Point"))
|
||||
obj.addProperty(
|
||||
"App::PropertyVectorDistance",
|
||||
"StartPoint",
|
||||
"Start Point",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "The start point of this path"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"UseStartPoint",
|
||||
"Start Point",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Make True, if specifying a Start Point"
|
||||
),
|
||||
)
|
||||
|
||||
if FeatureDiameters & features:
|
||||
obj.addProperty("App::PropertyDistance", "MinDiameter", "Diameter", QtCore.QT_TRANSLATE_NOOP("PathOp", "Lower limit of the turning diameter"))
|
||||
obj.addProperty("App::PropertyDistance", "MaxDiameter", "Diameter", QtCore.QT_TRANSLATE_NOOP("PathOp", "Upper limit of the turning diameter."))
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"MinDiameter",
|
||||
"Diameter",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Lower limit of the turning diameter"
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyDistance",
|
||||
"MaxDiameter",
|
||||
"Diameter",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"PathOp", "Upper limit of the turning diameter."
|
||||
),
|
||||
)
|
||||
|
||||
# members being set later
|
||||
self.commandlist = None
|
||||
@@ -199,135 +348,153 @@ class ObjectOp(object):
|
||||
obj.Proxy = self
|
||||
|
||||
def setEditorModes(self, obj, features):
|
||||
'''Editor modes are not preserved during document store/restore, set editor modes for all properties'''
|
||||
"""Editor modes are not preserved during document store/restore, set editor modes for all properties"""
|
||||
|
||||
for op in ['OpStartDepth', 'OpFinalDepth', 'OpToolDiameter', 'CycleTime']:
|
||||
for op in ["OpStartDepth", "OpFinalDepth", "OpToolDiameter", "CycleTime"]:
|
||||
if hasattr(obj, op):
|
||||
obj.setEditorMode(op, 1) # read-only
|
||||
|
||||
if FeatureDepths & features:
|
||||
if FeatureNoFinalDepth & features:
|
||||
obj.setEditorMode('OpFinalDepth', 2)
|
||||
obj.setEditorMode("OpFinalDepth", 2)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
features = self.opFeatures(obj)
|
||||
if FeatureBaseGeometry & features and 'App::PropertyLinkSubList' == obj.getTypeIdOfProperty('Base'):
|
||||
if (
|
||||
FeatureBaseGeometry & features
|
||||
and "App::PropertyLinkSubList" == obj.getTypeIdOfProperty("Base")
|
||||
):
|
||||
PathLog.info("Replacing link property with global link (%s)." % obj.State)
|
||||
base = obj.Base
|
||||
obj.removeProperty('Base')
|
||||
obj.removeProperty("Base")
|
||||
self.addBaseProperty(obj)
|
||||
obj.Base = base
|
||||
obj.touch()
|
||||
obj.Document.recompute()
|
||||
|
||||
if FeatureTool & features and not hasattr(obj, 'OpToolDiameter'):
|
||||
self.addOpValues(obj, ['tooldia'])
|
||||
if FeatureTool & features and not hasattr(obj, "OpToolDiameter"):
|
||||
self.addOpValues(obj, ["tooldia"])
|
||||
|
||||
if FeatureCoolant & features and not hasattr(obj, 'CoolantMode'):
|
||||
obj.addProperty("App::PropertyString", "CoolantMode", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Coolant option for this operation"))
|
||||
if FeatureCoolant & features and not hasattr(obj, "CoolantMode"):
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CoolantMode",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Coolant option for this operation"),
|
||||
)
|
||||
|
||||
if FeatureDepths & features and not hasattr(obj, 'OpStartDepth'):
|
||||
self.addOpValues(obj, ['start', 'final'])
|
||||
if FeatureDepths & features and not hasattr(obj, "OpStartDepth"):
|
||||
self.addOpValues(obj, ["start", "final"])
|
||||
if FeatureNoFinalDepth & features:
|
||||
obj.setEditorMode('OpFinalDepth', 2)
|
||||
obj.setEditorMode("OpFinalDepth", 2)
|
||||
|
||||
if not hasattr(obj, 'OpStockZMax'):
|
||||
self.addOpValues(obj, ['stockz'])
|
||||
if not hasattr(obj, "OpStockZMax"):
|
||||
self.addOpValues(obj, ["stockz"])
|
||||
|
||||
if not hasattr(obj, 'CycleTime'):
|
||||
obj.addProperty("App::PropertyString", "CycleTime", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"))
|
||||
if not hasattr(obj, "CycleTime"):
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"CycleTime",
|
||||
"Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation"),
|
||||
)
|
||||
|
||||
self.setEditorModes(obj, features)
|
||||
self.opOnDocumentRestored(obj)
|
||||
|
||||
def __getstate__(self):
|
||||
'''__getstat__(self) ... called when receiver is saved.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
"""__getstat__(self) ... called when receiver is saved.
|
||||
Can safely be overwritten by subclasses."""
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
'''__getstat__(self) ... called when receiver is restored.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
"""__getstat__(self) ... called when receiver is restored.
|
||||
Can safely be overwritten by subclasses."""
|
||||
return None
|
||||
|
||||
def opFeatures(self, obj):
|
||||
'''opFeatures(obj) ... returns the OR'ed list of features used and supported by the operation.
|
||||
"""opFeatures(obj) ... returns the OR'ed list of features used and supported by the operation.
|
||||
The default implementation returns "FeatureTool | FeatureDepths | FeatureHeights | FeatureStartPoint"
|
||||
Should be overwritten by subclasses.'''
|
||||
Should be overwritten by subclasses."""
|
||||
# pylint: disable=unused-argument
|
||||
return FeatureTool | FeatureDepths | FeatureHeights | FeatureStartPoint | FeatureBaseGeometry | FeatureFinishDepth | FeatureCoolant
|
||||
return (
|
||||
FeatureTool
|
||||
| FeatureDepths
|
||||
| FeatureHeights
|
||||
| FeatureStartPoint
|
||||
| FeatureBaseGeometry
|
||||
| FeatureFinishDepth
|
||||
| FeatureCoolant
|
||||
)
|
||||
|
||||
def initOperation(self, obj):
|
||||
'''initOperation(obj) ... implement to create additional properties.
|
||||
Should be overwritten by subclasses.'''
|
||||
"""initOperation(obj) ... implement to create additional properties.
|
||||
Should be overwritten by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opOnDocumentRestored(self, obj):
|
||||
'''opOnDocumentRestored(obj) ... implement if an op needs special handling like migrating the data model.
|
||||
Should be overwritten by subclasses.'''
|
||||
"""opOnDocumentRestored(obj) ... implement if an op needs special handling like migrating the data model.
|
||||
Should be overwritten by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opOnChanged(self, obj, prop):
|
||||
'''opOnChanged(obj, prop) ... overwrite to process property changes.
|
||||
"""opOnChanged(obj, prop) ... overwrite to process property changes.
|
||||
This is a callback function that is invoked each time a property of the
|
||||
receiver is assigned a value. Note that the FC framework does not
|
||||
distinguish between assigning a different value and assigning the same
|
||||
value again.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
Can safely be overwritten by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opSetDefaultValues(self, obj, job):
|
||||
'''opSetDefaultValues(obj, job) ... overwrite to set initial default values.
|
||||
"""opSetDefaultValues(obj, job) ... overwrite to set initial default values.
|
||||
Called after the receiver has been fully created with all properties.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
Can safely be overwritten by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opUpdateDepths(self, obj):
|
||||
'''opUpdateDepths(obj) ... overwrite to implement special depths calculation.
|
||||
Can safely be overwritten by subclass.'''
|
||||
"""opUpdateDepths(obj) ... overwrite to implement special depths calculation.
|
||||
Can safely be overwritten by subclass."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opExecute(self, obj):
|
||||
'''opExecute(obj) ... called whenever the receiver needs to be recalculated.
|
||||
"""opExecute(obj) ... called whenever the receiver needs to be recalculated.
|
||||
See documentation of execute() for a list of base functionality provided.
|
||||
Should be overwritten by subclasses.'''
|
||||
Should be overwritten by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def opRejectAddBase(self, obj, base, sub):
|
||||
'''opRejectAddBase(base, sub) ... if op returns True the addition of the feature is prevented.
|
||||
Should be overwritten by subclasses.'''
|
||||
"""opRejectAddBase(base, sub) ... if op returns True the addition of the feature is prevented.
|
||||
Should be overwritten by subclasses."""
|
||||
# pylint: disable=unused-argument
|
||||
return False
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
'''onChanged(obj, prop) ... base implementation of the FC notification framework.
|
||||
Do not overwrite, overwrite opOnChanged() instead.'''
|
||||
"""onChanged(obj, prop) ... base implementation of the FC notification framework.
|
||||
Do not overwrite, overwrite opOnChanged() instead."""
|
||||
|
||||
# there's a bit of cycle going on here, if sanitizeBase causes the transaction to
|
||||
# be cancelled we end right here again with the unsainitized Base - if that is the
|
||||
# case, stop the cycle and return immediately
|
||||
if prop == 'Base' and self.sanitizeBase(obj):
|
||||
if prop == "Base" and self.sanitizeBase(obj):
|
||||
return
|
||||
|
||||
if 'Restore' not in obj.State and prop in ['Base', 'StartDepth', 'FinalDepth']:
|
||||
if "Restore" not in obj.State and prop in ["Base", "StartDepth", "FinalDepth"]:
|
||||
self.updateDepths(obj, True)
|
||||
|
||||
self.opOnChanged(obj, prop)
|
||||
|
||||
def applyExpression(self, obj, prop, expr):
|
||||
'''applyExpression(obj, prop, expr) ... set expression expr on obj.prop if expr is set'''
|
||||
"""applyExpression(obj, prop, expr) ... set expression expr on obj.prop if expr is set"""
|
||||
if expr:
|
||||
obj.setExpression(prop, expr)
|
||||
return True
|
||||
return False
|
||||
|
||||
def setDefaultValues(self, obj):
|
||||
'''setDefaultValues(obj) ... base implementation.
|
||||
Do not overwrite, overwrite opSetDefaultValues() instead.'''
|
||||
if self.job:
|
||||
job = self.job
|
||||
else:
|
||||
job = PathUtils.addToJob(obj)
|
||||
"""setDefaultValues(obj) ... base implementation.
|
||||
Do not overwrite, overwrite opSetDefaultValues() instead."""
|
||||
job = PathUtils.addToJob(obj)
|
||||
|
||||
obj.Active = True
|
||||
|
||||
@@ -335,7 +502,9 @@ class ObjectOp(object):
|
||||
|
||||
if FeatureTool & features:
|
||||
if 1 < len(job.Operations.Group):
|
||||
obj.ToolController = PathUtil.toolControllerForOp(job.Operations.Group[-2])
|
||||
obj.ToolController = PathUtil.toolControllerForOp(
|
||||
job.Operations.Group[-2]
|
||||
)
|
||||
else:
|
||||
obj.ToolController = PathUtils.findToolController(obj, self)
|
||||
if not obj.ToolController:
|
||||
@@ -346,11 +515,15 @@ class ObjectOp(object):
|
||||
obj.CoolantMode = job.SetupSheet.CoolantMode
|
||||
|
||||
if FeatureDepths & features:
|
||||
if self.applyExpression(obj, 'StartDepth', job.SetupSheet.StartDepthExpression):
|
||||
if self.applyExpression(
|
||||
obj, "StartDepth", job.SetupSheet.StartDepthExpression
|
||||
):
|
||||
obj.OpStartDepth = 1.0
|
||||
else:
|
||||
obj.StartDepth = 1.0
|
||||
if self.applyExpression(obj, 'FinalDepth', job.SetupSheet.FinalDepthExpression):
|
||||
if self.applyExpression(
|
||||
obj, "FinalDepth", job.SetupSheet.FinalDepthExpression
|
||||
):
|
||||
obj.OpFinalDepth = 0.0
|
||||
else:
|
||||
obj.FinalDepth = 0.0
|
||||
@@ -358,20 +531,26 @@ class ObjectOp(object):
|
||||
obj.StartDepth = 1.0
|
||||
|
||||
if FeatureStepDown & features:
|
||||
if not self.applyExpression(obj, 'StepDown', job.SetupSheet.StepDownExpression):
|
||||
obj.StepDown = '1 mm'
|
||||
if not self.applyExpression(
|
||||
obj, "StepDown", job.SetupSheet.StepDownExpression
|
||||
):
|
||||
obj.StepDown = "1 mm"
|
||||
|
||||
if FeatureHeights & features:
|
||||
if job.SetupSheet.SafeHeightExpression:
|
||||
if not self.applyExpression(obj, 'SafeHeight', job.SetupSheet.SafeHeightExpression):
|
||||
obj.SafeHeight = '3 mm'
|
||||
if not self.applyExpression(
|
||||
obj, "SafeHeight", job.SetupSheet.SafeHeightExpression
|
||||
):
|
||||
obj.SafeHeight = "3 mm"
|
||||
if job.SetupSheet.ClearanceHeightExpression:
|
||||
if not self.applyExpression(obj, 'ClearanceHeight', job.SetupSheet.ClearanceHeightExpression):
|
||||
obj.ClearanceHeight = '5 mm'
|
||||
if not self.applyExpression(
|
||||
obj, "ClearanceHeight", job.SetupSheet.ClearanceHeightExpression
|
||||
):
|
||||
obj.ClearanceHeight = "5 mm"
|
||||
|
||||
if FeatureDiameters & features:
|
||||
obj.MinDiameter = '0 mm'
|
||||
obj.MaxDiameter = '0 mm'
|
||||
obj.MinDiameter = "0 mm"
|
||||
obj.MaxDiameter = "0 mm"
|
||||
if job.Stock:
|
||||
obj.MaxDiameter = job.Stock.Shape.BoundBox.XLength
|
||||
|
||||
@@ -389,7 +568,10 @@ class ObjectOp(object):
|
||||
return False
|
||||
if not job.Model.Group:
|
||||
if not ignoreErrors:
|
||||
PathLog.error(translate("Path", "Parent job %s doesn't have a base object") % job.Label)
|
||||
PathLog.error(
|
||||
translate("Path", "Parent job %s doesn't have a base object")
|
||||
% job.Label
|
||||
)
|
||||
return False
|
||||
self.job = job
|
||||
self.model = job.Model.Group
|
||||
@@ -397,15 +579,15 @@ class ObjectOp(object):
|
||||
return True
|
||||
|
||||
def getJob(self, obj):
|
||||
'''getJob(obj) ... return the job this operation is part of.'''
|
||||
if not hasattr(self, 'job') or self.job is None:
|
||||
"""getJob(obj) ... return the job this operation is part of."""
|
||||
if not hasattr(self, "job") or self.job is None:
|
||||
if not self._setBaseAndStock(obj):
|
||||
return None
|
||||
return self.job
|
||||
|
||||
def updateDepths(self, obj, ignoreErrors=False):
|
||||
'''updateDepths(obj) ... base implementation calculating depths depending on base geometry.
|
||||
Should not be overwritten.'''
|
||||
"""updateDepths(obj) ... base implementation calculating depths depending on base geometry.
|
||||
Should not be overwritten."""
|
||||
|
||||
def faceZmin(bb, fbb):
|
||||
if fbb.ZMax == fbb.ZMin and fbb.ZMax == bb.ZMax: # top face
|
||||
@@ -428,7 +610,7 @@ class ObjectOp(object):
|
||||
obj.OpStockZMin = zmin
|
||||
obj.OpStockZMax = zmax
|
||||
|
||||
if hasattr(obj, 'Base') and obj.Base:
|
||||
if hasattr(obj, "Base") and obj.Base:
|
||||
for base, sublist in obj.Base:
|
||||
bb = base.Shape.BoundBox
|
||||
zmax = max(zmax, bb.ZMax)
|
||||
@@ -456,7 +638,9 @@ class ObjectOp(object):
|
||||
zmin = obj.OpFinalDepth.Value
|
||||
|
||||
def minZmax(z):
|
||||
if hasattr(obj, 'StepDown') and not PathGeom.isRoughly(obj.StepDown.Value, 0):
|
||||
if hasattr(obj, "StepDown") and not PathGeom.isRoughly(
|
||||
obj.StepDown.Value, 0
|
||||
):
|
||||
return z + obj.StepDown.Value
|
||||
else:
|
||||
return z + 1
|
||||
@@ -476,21 +660,23 @@ class ObjectOp(object):
|
||||
self.opUpdateDepths(obj)
|
||||
|
||||
def sanitizeBase(self, obj):
|
||||
'''sanitizeBase(obj) ... check if Base is valid and clear on errors.'''
|
||||
if hasattr(obj, 'Base'):
|
||||
"""sanitizeBase(obj) ... check if Base is valid and clear on errors."""
|
||||
if hasattr(obj, "Base"):
|
||||
try:
|
||||
for (o, sublist) in obj.Base:
|
||||
for sub in sublist:
|
||||
e = o.Shape.getElement(sub)
|
||||
except Part.OCCError as e:
|
||||
PathLog.error("{} - stale base geometry detected - clearing.".format(obj.Label))
|
||||
o.Shape.getElement(sub)
|
||||
except Part.OCCError:
|
||||
PathLog.error(
|
||||
"{} - stale base geometry detected - clearing.".format(obj.Label)
|
||||
)
|
||||
obj.Base = []
|
||||
return True
|
||||
return False
|
||||
|
||||
@waiting_effects
|
||||
def execute(self, obj):
|
||||
'''execute(obj) ... base implementation - do not overwrite!
|
||||
"""execute(obj) ... base implementation - do not overwrite!
|
||||
Verifies that the operation is assigned to a job and that the job also has a valid Base.
|
||||
It also sets the following instance variables that can and should be safely be used by
|
||||
implementation of opExecute():
|
||||
@@ -508,7 +694,7 @@ class ObjectOp(object):
|
||||
opExecute(obj) - which is expected to add the generated commands to self.commandlist
|
||||
Finally the base implementation adds a rapid move to clearance height and assigns
|
||||
the receiver's Path property from the command list.
|
||||
'''
|
||||
"""
|
||||
PathLog.track()
|
||||
|
||||
if not obj.Active:
|
||||
@@ -523,13 +709,22 @@ class ObjectOp(object):
|
||||
self.sanitizeBase(obj)
|
||||
|
||||
if FeatureCoolant & self.opFeatures(obj):
|
||||
if not hasattr(obj, 'CoolantMode'):
|
||||
PathLog.error(translate("Path", "No coolant property found. Please recreate operation."))
|
||||
if not hasattr(obj, "CoolantMode"):
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path", "No coolant property found. Please recreate operation."
|
||||
)
|
||||
)
|
||||
|
||||
if FeatureTool & self.opFeatures(obj):
|
||||
tc = obj.ToolController
|
||||
if tc is None or tc.ToolNumber == 0:
|
||||
PathLog.error(translate("Path", "No Tool Controller is selected. We need a tool to build a Path."))
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path",
|
||||
"No Tool Controller is selected. We need a tool to build a Path.",
|
||||
)
|
||||
)
|
||||
return
|
||||
else:
|
||||
self.vertFeed = tc.VertFeed.Value
|
||||
@@ -538,7 +733,12 @@ class ObjectOp(object):
|
||||
self.horizRapid = tc.HorizRapid.Value
|
||||
tool = tc.Proxy.getTool(tc)
|
||||
if not tool or float(tool.Diameter) == 0:
|
||||
PathLog.error(translate("Path", "No Tool found or diameter is zero. We need a tool to build a Path."))
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path",
|
||||
"No Tool found or diameter is zero. We need a tool to build a Path.",
|
||||
)
|
||||
)
|
||||
return
|
||||
self.radius = float(tool.Diameter) / 2.0
|
||||
self.tool = tool
|
||||
@@ -558,7 +758,9 @@ class ObjectOp(object):
|
||||
|
||||
if self.commandlist and (FeatureHeights & self.opFeatures(obj)):
|
||||
# Let's finish by rapid to clearance...just for safety
|
||||
self.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
|
||||
self.commandlist.append(
|
||||
Path.Command("G0", {"Z": obj.ClearanceHeight.Value})
|
||||
)
|
||||
|
||||
path = Path.Path(self.commandlist)
|
||||
obj.Path = path
|
||||
@@ -572,25 +774,39 @@ class ObjectOp(object):
|
||||
|
||||
if tc is None or tc.ToolNumber == 0:
|
||||
PathLog.error(translate("Path", "No Tool Controller selected."))
|
||||
return translate('Path', 'Tool Error')
|
||||
return translate("Path", "Tool Error")
|
||||
|
||||
hFeedrate = tc.HorizFeed.Value
|
||||
vFeedrate = tc.VertFeed.Value
|
||||
hRapidrate = tc.HorizRapid.Value
|
||||
vRapidrate = tc.VertRapid.Value
|
||||
|
||||
if (hFeedrate == 0 or vFeedrate == 0) and not PathPreferences.suppressAllSpeedsWarning():
|
||||
PathLog.warning(translate("Path", "Tool Controller feedrates required to calculate the cycle time."))
|
||||
return translate('Path', 'Feedrate Error')
|
||||
if (
|
||||
hFeedrate == 0 or vFeedrate == 0
|
||||
) and not PathPreferences.suppressAllSpeedsWarning():
|
||||
PathLog.warning(
|
||||
translate(
|
||||
"Path",
|
||||
"Tool Controller feedrates required to calculate the cycle time.",
|
||||
)
|
||||
)
|
||||
return translate("Path", "Feedrate Error")
|
||||
|
||||
if (hRapidrate == 0 or vRapidrate == 0) and not PathPreferences.suppressRapidSpeedsWarning():
|
||||
PathLog.warning(translate("Path", "Add Tool Controller Rapid Speeds on the SetupSheet for more accurate cycle times."))
|
||||
if (
|
||||
hRapidrate == 0 or vRapidrate == 0
|
||||
) and not PathPreferences.suppressRapidSpeedsWarning():
|
||||
PathLog.warning(
|
||||
translate(
|
||||
"Path",
|
||||
"Add Tool Controller Rapid Speeds on the SetupSheet for more accurate cycle times.",
|
||||
)
|
||||
)
|
||||
|
||||
# Get the cycle time in seconds
|
||||
seconds = obj.Path.getCycleTime(hFeedrate, vFeedrate, hRapidrate, vRapidrate)
|
||||
|
||||
if not seconds:
|
||||
return translate('Path', 'Cycletime Error')
|
||||
return translate("Path", "Cycletime Error")
|
||||
|
||||
# Convert the cycle time to a HH:MM:SS format
|
||||
cycleTime = time.strftime("%H:%M:%S", time.gmtime(seconds))
|
||||
@@ -613,17 +829,29 @@ class ObjectOp(object):
|
||||
|
||||
for p, el in baselist:
|
||||
if p == base and sub in el:
|
||||
PathLog.notice((translate("Path", "Base object %s.%s already in the list") + "\n") % (base.Label, sub))
|
||||
PathLog.notice(
|
||||
(
|
||||
translate("Path", "Base object %s.%s already in the list")
|
||||
+ "\n"
|
||||
)
|
||||
% (base.Label, sub)
|
||||
)
|
||||
return
|
||||
|
||||
if not self.opRejectAddBase(obj, base, sub):
|
||||
baselist.append((base, sub))
|
||||
obj.Base = baselist
|
||||
else:
|
||||
PathLog.notice((translate("Path", "Base object %s.%s rejected by operation") + "\n") % (base.Label, sub))
|
||||
PathLog.notice(
|
||||
(
|
||||
translate("Path", "Base object %s.%s rejected by operation")
|
||||
+ "\n"
|
||||
)
|
||||
% (base.Label, sub)
|
||||
)
|
||||
|
||||
def isToolSupported(self, obj, tool):
|
||||
'''toolSupported(obj, tool) ... Returns true if the op supports the given tool.
|
||||
This function can safely be overwritten by subclasses.'''
|
||||
"""toolSupported(obj, tool) ... Returns true if the op supports the given tool.
|
||||
This function can safely be overwritten by subclasses."""
|
||||
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user