Introduced Op-values and set expressions for all user modifyable properties - updated template support.

This commit is contained in:
Markus Lampert
2017-10-08 00:42:10 -07:00
parent dfd5dd1681
commit fb22e23981
4 changed files with 107 additions and 72 deletions

View File

@@ -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))

View File

@@ -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:

View File

@@ -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))

View File

@@ -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