Introduced Op-values and set expressions for all user modifyable properties - updated template support.
This commit is contained in:
@@ -51,19 +51,16 @@ def translate(context, text, disambig=None):
|
||||
|
||||
class JobTemplate:
|
||||
'''Attribute and sub element strings for template export/import.'''
|
||||
Description = 'Desc'
|
||||
GeometryTolerance = 'Tolerance'
|
||||
Job = 'Job'
|
||||
PostProcessor = 'Post'
|
||||
PostProcessorArgs = 'PostArgs'
|
||||
PostProcessorOutputFile = 'Output'
|
||||
GeometryTolerance = 'Tolerance'
|
||||
Description = 'Desc'
|
||||
ToolController = 'ToolController'
|
||||
Settings = 'Settings'
|
||||
Stock = 'Stock'
|
||||
ToolController = 'ToolController'
|
||||
Version = 'Version'
|
||||
DefaultVertRapid = 'DefaultVertRapid'
|
||||
DefaultHorizRapid = 'DefaultHorizRapid'
|
||||
DefaultSafeHeight = 'DefaultSafeHeight'
|
||||
DefaultClearanceHeight = 'DefaultClearanceHeight'
|
||||
|
||||
def isArchPanelSheet(obj):
|
||||
return hasattr(obj, 'Proxy') and isinstance(obj.Proxy, ArchPanel.PanelSheet)
|
||||
@@ -209,14 +206,8 @@ class ObjectJob:
|
||||
attrs = json.load(fp)
|
||||
|
||||
if attrs.get(JobTemplate.Version) and 1 == int(attrs[JobTemplate.Version]):
|
||||
if attrs.get(JobTemplate.DefaultVertRapid):
|
||||
self.settings.updateSetting(PathSettings.Default.VertRapid, attrs[JobTemplate.DefaultVertRapid])
|
||||
if attrs.get(JobTemplate.DefaultHorizRapid):
|
||||
self.settings.updateSetting(PathSettings.Default.HorizRapid, attrs[JobTemplate.DefaultHorizRapid])
|
||||
if attrs.get(JobTemplate.DefaultSafeHeight):
|
||||
self.settings.updateSetting(PathSettings.Default.SafeHeight, attrs[JobTemplate.DefaultSafeHeight])
|
||||
if attrs.get(JobTemplate.DefaultClearanceHeight):
|
||||
self.settings.updateSetting(PathSettings.Default.ClearanceHeight, attrs[JobTemplate.DefaultClearanceHeight])
|
||||
if attrs.get(JobTemplate.Settings):
|
||||
self.settings.setFromTemplate(attrs[JobTemplate.Settings])
|
||||
|
||||
if attrs.get(JobTemplate.GeometryTolerance):
|
||||
obj.GeometryTolerance = float(attrs.get(JobTemplate.GeometryTolerance))
|
||||
@@ -236,13 +227,13 @@ class ObjectJob:
|
||||
tcs.append(PathToolController.FromTemplate(tc))
|
||||
if attrs.get(JobTemplate.Stock):
|
||||
obj.Stock = PathStock.CreateFromTemplate(obj, attrs.get(JobTemplate.Stock))
|
||||
|
||||
PathLog.debug("setting tool controllers (%d)" % len(tcs))
|
||||
obj.ToolController = tcs
|
||||
else:
|
||||
PathLog.error(translate('PathJob', "Unsupported PathJob template version %s") % attrs.get(JobTemplate.Version))
|
||||
tcs.append(PathToolController.Create())
|
||||
if not tcs:
|
||||
tcs.append(PathToolController.Create())
|
||||
PathLog.debug("setting tool controllers (%d)" % len(tcs))
|
||||
obj.ToolController = 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.'''
|
||||
@@ -256,10 +247,6 @@ class ObjectJob:
|
||||
attrs[JobTemplate.GeometryTolerance] = str(obj.GeometryTolerance.Value)
|
||||
if obj.Description:
|
||||
attrs[JobTemplate.Description] = obj.Description
|
||||
attrs[JobTemplate.DefaultVertRapid] = obj.Settings.DefaultVertRapid
|
||||
attrs[JobTemplate.DefaultHorizRapid] = obj.Settings.DefaultHorizRapid
|
||||
attrs[JobTemplate.DefaultSafeHeight] = obj.Settings.DefaultSafeHeight
|
||||
attrs[JobTemplate.DefaultClearanceHeight] = obj.Settings.DefaultClearanceHeight
|
||||
return attrs
|
||||
|
||||
def __getstate__(self):
|
||||
@@ -283,7 +270,7 @@ class ObjectJob:
|
||||
|
||||
def addToolController(self, tc):
|
||||
group = self.obj.ToolController
|
||||
PathLog.info("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.obj.Settings.Name, PathSettings.Default.VertRapid))
|
||||
tc.setExpression('HorizRapid', "%s.%s" % (self.obj.Settings.Name, PathSettings.Default.HorizRapid))
|
||||
|
||||
@@ -251,13 +251,14 @@ class CommandJobTemplateExport:
|
||||
if stockAttrs:
|
||||
attrs[PathJob.JobTemplate.Stock] = stockAttrs
|
||||
|
||||
# defaults settings
|
||||
if dialog and not (dialog.includeDefaults() and dialog.includeDefaultToolRapid()):
|
||||
attrs.pop(PathJob.JobTemplate.DefaultVertRapid, None)
|
||||
attrs.pop(PathJob.JobTemplate.DefaultHorizRapid, None)
|
||||
if dialog and not (dialog.includeDefaults() and dialog.includeDefaultOperationHeights()):
|
||||
attrs.pop(PathJob.JobTemplate.DefaultSafeHeight, None)
|
||||
attrs.pop(PathJob.JobTemplate.DefaultClearanceHeight, None)
|
||||
# settings
|
||||
settingsAttrs = None
|
||||
if dialog:
|
||||
settingsAttrs = job.Proxy.settings.templateAttributes(dialog.includeDefaultToolRapid(), dialog.includeDefaultOperationHeights())
|
||||
else:
|
||||
settingsAttrs = job.Proxy.settings.templateAttributes(True, True)
|
||||
if settingsAttrs:
|
||||
attrs[PathJob.JobTemplate.Settings] = settingsAttrs
|
||||
|
||||
# write template
|
||||
with open(unicode(path), 'wb') as fp:
|
||||
|
||||
@@ -94,15 +94,25 @@ class ObjectOp(object):
|
||||
'''
|
||||
|
||||
def addBaseProperty(self, obj):
|
||||
obj.addProperty("App::PropertyLinkSubListGlobal", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "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
|
||||
|
||||
def __init__(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "Make False, to prevent operation from generating code"))
|
||||
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional comment for this Operation"))
|
||||
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "User Assigned Label"))
|
||||
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"))
|
||||
|
||||
features = self.opFeatures(obj)
|
||||
|
||||
@@ -110,32 +120,38 @@ class ObjectOp(object):
|
||||
self.addBaseProperty(obj)
|
||||
|
||||
if FeatureLocations & features:
|
||||
obj.addProperty("App::PropertyVectorList", "Locations", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "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("App::Property", "The tool controller that will be used to calculate the path"))
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "The tool controller that will be used to calculate the path"))
|
||||
|
||||
if FeatureDepths & features:
|
||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Starting Depth of Tool- first cut depth in Z"))
|
||||
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Final Depth of Tool- lowest value in Z"))
|
||||
obj.addProperty("App::PropertyBool", "StartDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "If enabled Start Depth will not be automatically updated when geometry changes"))
|
||||
obj.addProperty("App::PropertyBool", "FinalDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "If enabled Final Depth will not be automatically updated when geometry changes"))
|
||||
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::PropertyBool", "StartDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "If enabled Start Depth will not be automatically updated when geometry changes"))
|
||||
obj.addProperty("App::PropertyBool", "FinalDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "If enabled Final Depth will not be automatically updated when geometry changes"))
|
||||
values = ['start']
|
||||
if FeatureNoFinalDepth & features:
|
||||
obj.setEditorMode('FinalDepth', 2) # hide
|
||||
obj.setEditorMode('FinalDepthLock', 2) # hide
|
||||
else:
|
||||
values.append('final')
|
||||
self.addOpValues(obj, values)
|
||||
|
||||
if FeatureStepDown & features:
|
||||
obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Incremental Step Down of Tool"))
|
||||
obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "Incremental Step Down of Tool"))
|
||||
self.addOpValues(obj, ['tooldia'])
|
||||
|
||||
if FeatureFinishDepth & features:
|
||||
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "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("App::Property", "The height needed to clear clamps and obstructions"))
|
||||
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "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::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The start point of this path"))
|
||||
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying a Start Point"))
|
||||
obj.addProperty("App::PropertyVector", "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"))
|
||||
|
||||
self.initOperation(obj)
|
||||
|
||||
@@ -153,11 +169,23 @@ class ObjectOp(object):
|
||||
obj.Document.recompute()
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
if not hasattr(obj, 'StartDepthLock'):
|
||||
obj.addProperty("App::PropertyBool", "StartDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "If enabled Start Depth will not be automatically updated when geometry changes"))
|
||||
obj.addProperty("App::PropertyBool", "StartDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "If enabled Start Depth will not be automatically updated when geometry changes"))
|
||||
obj.StartDepthLock = False
|
||||
if not hasattr(obj, 'FinalDepthLock'):
|
||||
obj.addProperty("App::PropertyBool", "FinalDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "If enabled Final Depth will not be automatically updated when geometry changes"))
|
||||
obj.addProperty("App::PropertyBool", "FinalDepthLock", "Depth", QtCore.QT_TRANSLATE_NOOP("PathOp", "If enabled Final Depth will not be automatically updated when geometry changes"))
|
||||
obj.FinalDepthLock = False
|
||||
if not hasattr(obj, 'OpStartDepth'):
|
||||
self.addOpValues(obj, ['start', 'final'])
|
||||
if not obj.StartDepthLock:
|
||||
obj.setExpression('StartDepth', 'OpStartDepth')
|
||||
if FeatureNoFinalDepth & features:
|
||||
obj.setEditorMode('OpFinalDepth', 2)
|
||||
elif not obj.FinalDepthLock:
|
||||
obj.setExpression('FinalDepth', 'OpFinalDepth')
|
||||
if PatGeom.isRoughly(obj.StepDown.Value, 1):
|
||||
obj.setExpression('StepDown', 'OpToolDiameter')
|
||||
if FeatureStepDown & self.opFeatures(obj) and not hasattr(obj, 'OpToolDiameter'):
|
||||
self.addOpValues(['tooldia'])
|
||||
|
||||
def __getstate__(self):
|
||||
'''__getstat__(self) ... called when receiver is saved.
|
||||
@@ -227,13 +255,16 @@ class ObjectOp(object):
|
||||
obj.ToolController = PathUtils.findToolController(obj)
|
||||
|
||||
if FeatureDepths & features:
|
||||
obj.StartDepth = 1.0
|
||||
obj.setExpression('StartDepth', 'OpStartDepth')
|
||||
obj.setExpression('FinalDepth', 'OpFinalDepth')
|
||||
obj.OpStartDepth = 1.0
|
||||
obj.StartDepthLock = False
|
||||
obj.FinalDepth = 0.0
|
||||
obj.OpFinalDepth = 0.0
|
||||
obj.FinalDepthLock = False
|
||||
|
||||
if FeatureStepDown & features:
|
||||
obj.StepDown = 1.0
|
||||
obj.OpToolDiameter = 1.0
|
||||
obj.setExpression('StepDown', 'OpToolDiameter')
|
||||
|
||||
if FeatureHeights & features:
|
||||
obj.setExpression('SafeHeight', "%s.%s+StartDepth" % (job.Settings.Name, PathSettings.Default.SafeHeight))
|
||||
@@ -268,7 +299,7 @@ class ObjectOp(object):
|
||||
|
||||
def updateDepths(self, obj, ignoreErrors=False):
|
||||
'''updateDepths(obj) ... base implementation calculating depths depending on base geometry.
|
||||
Can safely be overwritten.'''
|
||||
Should not be overwritten.'''
|
||||
|
||||
def faceZmin(bb, fbb):
|
||||
if fbb.ZMax == fbb.ZMin and fbb.ZMax == bb.ZMax: # top face
|
||||
@@ -303,13 +334,13 @@ class ObjectOp(object):
|
||||
safeDepths = True
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
# first set update final depth, it's value is not negotiable
|
||||
if not PathGeom.isRoughly(obj.FinalDepth.Value, zmin):
|
||||
if not PathGeom.isRoughly(obj.OpFinalDepth.Value, zmin):
|
||||
if not hasattr(obj, 'FinalDepthLock') or not obj.FinalDepthLock:
|
||||
obj.FinalDepth = zmin
|
||||
obj.OpFinalDepth = zmin
|
||||
else:
|
||||
if obj.FinalDepth.Value < zmin:
|
||||
if obj.OpFinalDepth.Value < zmin:
|
||||
safeDepths = False
|
||||
zmin = obj.FinalDepth.Value
|
||||
zmin = obj.OpFinalDepth.Value
|
||||
|
||||
def minZmax(z):
|
||||
if hasattr(obj, 'StepDown') and not PathGeom.isRoughly(obj.StepDown.Value, 0):
|
||||
@@ -322,22 +353,15 @@ class ObjectOp(object):
|
||||
zmax = minZmax(zmin)
|
||||
|
||||
# update start depth if requested and required
|
||||
if not PathGeom.isRoughly(obj.StartDepth.Value, zmax):
|
||||
if not PathGeom.isRoughly(obj.OpStartDepth.Value, zmax):
|
||||
if not hasattr(obj, 'StartDepthLock') or not obj.StartDepthLock:
|
||||
obj.StartDepth = zmax
|
||||
elif (obj.StartDepth.Value - 0.0001) <= obj.FinalDepth.Value:
|
||||
obj.StartDepth = minZmax(obj.FinalDepth.Value)
|
||||
obj.OpStartDepth = zmax
|
||||
elif (obj.OpStartDepth.Value - 0.0001) <= obj.OpFinalDepth.Value:
|
||||
obj.OpStartDepth = minZmax(obj.OpFinalDepth.Value)
|
||||
else:
|
||||
if obj.StartDepth.Value < zmax:
|
||||
if obj.OpStartDepth.Value < zmax:
|
||||
safeDepths = False
|
||||
|
||||
#clearance = obj.StartDepth.Value + self.job.Settings.DefaultClearanceHeight.Value
|
||||
#safe = obj.StartDepth.Value + self.job.Settings.DefaultSafeHeight.Value
|
||||
#if hasattr(obj, 'ClearanceHeight') and not PathGeom.isRoughly(clearance, obj.ClearanceHeight.Value):
|
||||
# obj.ClearanceHeight = clearance
|
||||
#if hasattr(obj, 'SafeHeight') and not PathGeom.isRoughly(safe, obj.SafeHeight.Value):
|
||||
# obj.SafeHeight = safe
|
||||
|
||||
return safeDepths
|
||||
|
||||
@waiting_effects
|
||||
@@ -387,11 +411,14 @@ class ObjectOp(object):
|
||||
if not tool or tool.Diameter == 0:
|
||||
FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
|
||||
return
|
||||
else:
|
||||
self.radius = tool.Diameter/2
|
||||
self.tool = tool
|
||||
self.radius = tool.Diameter/2
|
||||
self.tool = tool
|
||||
obj.OpToolDiameter = tool.Diameter
|
||||
|
||||
self.updateDepths(obj)
|
||||
# now that all op values are set make sure the user properties get updated accordingly,
|
||||
# in case they still have an expression referencing any op values
|
||||
obj.recompute()
|
||||
|
||||
self.commandlist = []
|
||||
self.commandlist.append(Path.Command("(%s)" % obj.Label))
|
||||
|
||||
@@ -76,3 +76,23 @@ class Settings:
|
||||
self.obj.Settings.setAlias(valueCell, name)
|
||||
self.obj.Settings.set(descCell, desc)
|
||||
|
||||
def setFromTemplate(self, attrs):
|
||||
if attrs.get(Default.VertRapid):
|
||||
self.updateSetting(Default.VertRapid, attrs[Default.VertRapid])
|
||||
if attrs.get(Default.HorizRapid):
|
||||
self.updateSetting(Default.HorizRapid, attrs[Default.HorizRapid])
|
||||
if attrs.get(Default.SafeHeight):
|
||||
self.updateSetting(Default.SafeHeight, attrs[Default.SafeHeight])
|
||||
if attrs.get(Default.ClearanceHeight):
|
||||
self.updateSetting(Default.ClearanceHeight, attrs[Default.ClearanceHeight])
|
||||
|
||||
def templateAttributes(self, includeRapids, includeHeights):
|
||||
attrs = {}
|
||||
if includeRapids:
|
||||
attrs[Default.VertRapid] = self.obj.Settings.DefaultVertRapid.UserString
|
||||
attrs[Default.HorizRapid] = self.obj.Settings.DefaultHorizRapid.UserString
|
||||
if includeHeights:
|
||||
attrs[Default.SafeHeight] = self.obj.Settings.DefaultSafeHeight.UserString
|
||||
attrs[Default.ClearanceHeight] = self.obj.Settings.DefaultClearanceHeight.UserString
|
||||
return attrs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user