black reformat (setupsheet)
This commit is contained in:
@@ -45,21 +45,32 @@ def translate(context, text, disambig=None):
|
||||
class Template:
|
||||
# pylint: disable=no-init
|
||||
|
||||
HorizRapid = 'HorizRapid'
|
||||
VertRapid = 'VertRapid'
|
||||
CoolantMode = 'CoolantMode'
|
||||
SafeHeightOffset = 'SafeHeightOffset'
|
||||
SafeHeightExpression = 'SafeHeightExpression'
|
||||
ClearanceHeightOffset = 'ClearanceHeightOffset'
|
||||
ClearanceHeightExpression = 'ClearanceHeightExpression'
|
||||
StartDepthExpression = 'StartDepthExpression'
|
||||
FinalDepthExpression = 'FinalDepthExpression'
|
||||
StepDownExpression = 'StepDownExpression'
|
||||
Fixtures = 'Fixtures'
|
||||
OrderOutputBy = 'OrderOutputBy'
|
||||
SplitOutput = 'SplitOutput'
|
||||
HorizRapid = "HorizRapid"
|
||||
VertRapid = "VertRapid"
|
||||
CoolantMode = "CoolantMode"
|
||||
SafeHeightOffset = "SafeHeightOffset"
|
||||
SafeHeightExpression = "SafeHeightExpression"
|
||||
ClearanceHeightOffset = "ClearanceHeightOffset"
|
||||
ClearanceHeightExpression = "ClearanceHeightExpression"
|
||||
StartDepthExpression = "StartDepthExpression"
|
||||
FinalDepthExpression = "FinalDepthExpression"
|
||||
StepDownExpression = "StepDownExpression"
|
||||
Fixtures = "Fixtures"
|
||||
OrderOutputBy = "OrderOutputBy"
|
||||
SplitOutput = "SplitOutput"
|
||||
|
||||
All = [HorizRapid, VertRapid, CoolantMode, SafeHeightOffset, SafeHeightExpression, ClearanceHeightOffset, ClearanceHeightExpression, StartDepthExpression, FinalDepthExpression, StepDownExpression]
|
||||
All = [
|
||||
HorizRapid,
|
||||
VertRapid,
|
||||
CoolantMode,
|
||||
SafeHeightOffset,
|
||||
SafeHeightExpression,
|
||||
ClearanceHeightOffset,
|
||||
ClearanceHeightExpression,
|
||||
StartDepthExpression,
|
||||
FinalDepthExpression,
|
||||
StepDownExpression,
|
||||
]
|
||||
|
||||
|
||||
def _traverseTemplateAttributes(attrs, codec):
|
||||
@@ -82,46 +93,130 @@ def _traverseTemplateAttributes(attrs, codec):
|
||||
|
||||
|
||||
class SetupSheet:
|
||||
'''Property container object used by a Job to hold global reference values. '''
|
||||
"""Property container object used by a Job to hold global reference values."""
|
||||
|
||||
TemplateReference = '${SetupSheet}'
|
||||
TemplateReference = "${SetupSheet}"
|
||||
|
||||
DefaultSafeHeightOffset = '3 mm'
|
||||
DefaultClearanceHeightOffset = '5 mm'
|
||||
DefaultSafeHeightExpression = "OpStockZMax+${SetupSheet}.SafeHeightOffset"
|
||||
DefaultSafeHeightOffset = "3 mm"
|
||||
DefaultClearanceHeightOffset = "5 mm"
|
||||
DefaultSafeHeightExpression = "OpStockZMax+${SetupSheet}.SafeHeightOffset"
|
||||
DefaultClearanceHeightExpression = "OpStockZMax+${SetupSheet}.ClearanceHeightOffset"
|
||||
|
||||
DefaultStartDepthExpression = 'OpStartDepth'
|
||||
DefaultFinalDepthExpression = 'OpFinalDepth'
|
||||
DefaultStepDownExpression = 'OpToolDiameter'
|
||||
DefaultStartDepthExpression = "OpStartDepth"
|
||||
DefaultFinalDepthExpression = "OpFinalDepth"
|
||||
DefaultStepDownExpression = "OpToolDiameter"
|
||||
|
||||
DefaultCoolantModes = ['None', 'Flood', 'Mist']
|
||||
DefaultCoolantModes = ["None", "Flood", "Mist"]
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
obj.addProperty('App::PropertySpeed', 'VertRapid', 'ToolController', translate('PathSetupSheet', 'Default speed for horizontal rapid moves.'))
|
||||
obj.addProperty('App::PropertySpeed', 'HorizRapid', 'ToolController', translate('PathSetupSheet', 'Default speed for vertical rapid moves.'))
|
||||
obj.addProperty(
|
||||
"App::PropertySpeed",
|
||||
"VertRapid",
|
||||
"ToolController",
|
||||
translate("PathSetupSheet", "Default speed for horizontal rapid moves."),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertySpeed",
|
||||
"HorizRapid",
|
||||
"ToolController",
|
||||
translate("PathSetupSheet", "Default speed for vertical rapid moves."),
|
||||
)
|
||||
|
||||
obj.addProperty('App::PropertyStringList', 'CoolantModes', 'CoolantMode', translate('PathSetupSheet', 'Coolant Modes'))
|
||||
obj.addProperty('App::PropertyEnumeration', 'CoolantMode', 'CoolantMode', translate('PathSetupSheet', 'Default coolant mode.'))
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"CoolantModes",
|
||||
"CoolantMode",
|
||||
translate("PathSetupSheet", "Coolant Modes"),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"CoolantMode",
|
||||
"CoolantMode",
|
||||
translate("PathSetupSheet", "Default coolant mode."),
|
||||
)
|
||||
|
||||
obj.addProperty('App::PropertyLength', 'SafeHeightOffset', 'OperationHeights', translate('PathSetupSheet', 'The usage of this field depends on SafeHeightExpression - by default its value is added to StartDepth and used for SafeHeight of an operation.'))
|
||||
obj.addProperty('App::PropertyString', 'SafeHeightExpression', 'OperationHeights', translate('PathSetupSheet', 'Expression set for the SafeHeight of new operations.'))
|
||||
obj.addProperty('App::PropertyLength', 'ClearanceHeightOffset', 'OperationHeights', translate('PathSetupSheet', 'The usage of this field depends on ClearanceHeightExpression - by default is value is added to StartDepth and used for ClearanceHeight of an operation.'))
|
||||
obj.addProperty('App::PropertyString', 'ClearanceHeightExpression', 'OperationHeights', translate('PathSetupSheet', 'Expression set for the ClearanceHeight of new operations.'))
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"SafeHeightOffset",
|
||||
"OperationHeights",
|
||||
translate(
|
||||
"PathSetupSheet",
|
||||
"The usage of this field depends on SafeHeightExpression - by default its value is added to StartDepth and used for SafeHeight of an operation.",
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"SafeHeightExpression",
|
||||
"OperationHeights",
|
||||
translate(
|
||||
"PathSetupSheet", "Expression set for the SafeHeight of new operations."
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"ClearanceHeightOffset",
|
||||
"OperationHeights",
|
||||
translate(
|
||||
"PathSetupSheet",
|
||||
"The usage of this field depends on ClearanceHeightExpression - by default is value is added to StartDepth and used for ClearanceHeight of an operation.",
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"ClearanceHeightExpression",
|
||||
"OperationHeights",
|
||||
translate(
|
||||
"PathSetupSheet",
|
||||
"Expression set for the ClearanceHeight of new operations.",
|
||||
),
|
||||
)
|
||||
|
||||
obj.addProperty('App::PropertyString', 'StartDepthExpression', 'OperationDepths', translate('PathSetupSheet', 'Expression used for StartDepth of new operations.'))
|
||||
obj.addProperty('App::PropertyString', 'FinalDepthExpression', 'OperationDepths', translate('PathSetupSheet', 'Expression used for FinalDepth of new operations.'))
|
||||
obj.addProperty('App::PropertyString', 'StepDownExpression', 'OperationDepths', translate('PathSetupSheet', 'Expression used for StepDown of new operations.'))
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"StartDepthExpression",
|
||||
"OperationDepths",
|
||||
translate(
|
||||
"PathSetupSheet", "Expression used for StartDepth of new operations."
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"FinalDepthExpression",
|
||||
"OperationDepths",
|
||||
translate(
|
||||
"PathSetupSheet", "Expression used for FinalDepth of new operations."
|
||||
),
|
||||
)
|
||||
obj.addProperty(
|
||||
"App::PropertyString",
|
||||
"StepDownExpression",
|
||||
"OperationDepths",
|
||||
translate(
|
||||
"PathSetupSheet", "Expression used for StepDown of new operations."
|
||||
),
|
||||
)
|
||||
|
||||
obj.SafeHeightOffset = self.decodeAttributeString(self.DefaultSafeHeightOffset)
|
||||
obj.ClearanceHeightOffset = self.decodeAttributeString(self.DefaultClearanceHeightOffset)
|
||||
obj.SafeHeightExpression = self.decodeAttributeString(self.DefaultSafeHeightExpression)
|
||||
obj.ClearanceHeightExpression = self.decodeAttributeString(self.DefaultClearanceHeightExpression)
|
||||
obj.SafeHeightOffset = self.decodeAttributeString(self.DefaultSafeHeightOffset)
|
||||
obj.ClearanceHeightOffset = self.decodeAttributeString(
|
||||
self.DefaultClearanceHeightOffset
|
||||
)
|
||||
obj.SafeHeightExpression = self.decodeAttributeString(
|
||||
self.DefaultSafeHeightExpression
|
||||
)
|
||||
obj.ClearanceHeightExpression = self.decodeAttributeString(
|
||||
self.DefaultClearanceHeightExpression
|
||||
)
|
||||
|
||||
obj.StartDepthExpression = self.decodeAttributeString(self.DefaultStartDepthExpression)
|
||||
obj.FinalDepthExpression = self.decodeAttributeString(self.DefaultFinalDepthExpression)
|
||||
obj.StepDownExpression = self.decodeAttributeString(self.DefaultStepDownExpression)
|
||||
obj.StartDepthExpression = self.decodeAttributeString(
|
||||
self.DefaultStartDepthExpression
|
||||
)
|
||||
obj.FinalDepthExpression = self.decodeAttributeString(
|
||||
self.DefaultFinalDepthExpression
|
||||
)
|
||||
obj.StepDownExpression = self.decodeAttributeString(
|
||||
self.DefaultStepDownExpression
|
||||
)
|
||||
|
||||
obj.CoolantModes = self.DefaultCoolantModes
|
||||
obj.CoolantMode = self.DefaultCoolantModes
|
||||
@@ -133,22 +228,34 @@ class SetupSheet:
|
||||
|
||||
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 hasDefaultToolRapids(self):
|
||||
return PathGeom.isRoughly(self.obj.VertRapid.Value, 0) and PathGeom.isRoughly(self.obj.HorizRapid.Value, 0)
|
||||
return PathGeom.isRoughly(self.obj.VertRapid.Value, 0) and PathGeom.isRoughly(
|
||||
self.obj.HorizRapid.Value, 0
|
||||
)
|
||||
|
||||
def hasDefaultOperationHeights(self):
|
||||
if self.obj.SafeHeightOffset.UserString != FreeCAD.Units.Quantity(self.DefaultSafeHeightOffset).UserString:
|
||||
if (
|
||||
self.obj.SafeHeightOffset.UserString
|
||||
!= FreeCAD.Units.Quantity(self.DefaultSafeHeightOffset).UserString
|
||||
):
|
||||
return False
|
||||
if self.obj.ClearanceHeightOffset.UserString != FreeCAD.Units.Quantity(self.DefaultClearanceHeightOffset).UserString:
|
||||
if (
|
||||
self.obj.ClearanceHeightOffset.UserString
|
||||
!= FreeCAD.Units.Quantity(self.DefaultClearanceHeightOffset).UserString
|
||||
):
|
||||
return False
|
||||
if self.obj.SafeHeightExpression != self.decodeAttributeString(self.DefaultSafeHeightExpression):
|
||||
if self.obj.SafeHeightExpression != self.decodeAttributeString(
|
||||
self.DefaultSafeHeightExpression
|
||||
):
|
||||
return False
|
||||
if self.obj.ClearanceHeightExpression != self.decodeAttributeString(self.DefaultClearanceHeightExpression):
|
||||
if self.obj.ClearanceHeightExpression != self.decodeAttributeString(
|
||||
self.DefaultClearanceHeightExpression
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -165,7 +272,7 @@ class SetupSheet:
|
||||
return self.obj.CoolantMode == "None"
|
||||
|
||||
def setFromTemplate(self, attrs):
|
||||
'''setFromTemplate(attrs) ... sets the default values from the given dictionary.'''
|
||||
"""setFromTemplate(attrs) ... sets the default values from the given dictionary."""
|
||||
for name in Template.All:
|
||||
if attrs.get(name) is not None:
|
||||
setattr(self.obj, name, attrs[name])
|
||||
@@ -180,15 +287,22 @@ class SetupSheet:
|
||||
prop = prototype.getProperty(propName)
|
||||
propertyName = OpPropertyName(opName, propName)
|
||||
propertyGroup = OpPropertyGroup(opName)
|
||||
prop.setupProperty(self.obj, propertyName, propertyGroup, prop.valueFromString(value))
|
||||
prop.setupProperty(
|
||||
self.obj,
|
||||
propertyName,
|
||||
propertyGroup,
|
||||
prop.valueFromString(value),
|
||||
)
|
||||
|
||||
def templateAttributes(self,
|
||||
includeRapids=True,
|
||||
includeCoolantMode=True,
|
||||
includeHeights=True,
|
||||
includeDepths=True,
|
||||
includeOps=None):
|
||||
'''templateAttributes(includeRapids, includeHeights, includeDepths) ... answers a dictionary with the default values.'''
|
||||
def templateAttributes(
|
||||
self,
|
||||
includeRapids=True,
|
||||
includeCoolantMode=True,
|
||||
includeHeights=True,
|
||||
includeDepths=True,
|
||||
includeOps=None,
|
||||
):
|
||||
"""templateAttributes(includeRapids, includeHeights, includeDepths) ... answers a dictionary with the default values."""
|
||||
attrs = {}
|
||||
|
||||
if includeRapids:
|
||||
@@ -199,15 +313,19 @@ class SetupSheet:
|
||||
attrs[Template.CoolantMode] = self.obj.CoolantMode
|
||||
|
||||
if includeHeights:
|
||||
attrs[Template.SafeHeightOffset] = self.obj.SafeHeightOffset.UserString
|
||||
attrs[Template.SafeHeightExpression] = self.obj.SafeHeightExpression
|
||||
attrs[Template.ClearanceHeightOffset] = self.obj.ClearanceHeightOffset.UserString
|
||||
attrs[Template.ClearanceHeightExpression] = self.obj.ClearanceHeightExpression
|
||||
attrs[Template.SafeHeightOffset] = self.obj.SafeHeightOffset.UserString
|
||||
attrs[Template.SafeHeightExpression] = self.obj.SafeHeightExpression
|
||||
attrs[
|
||||
Template.ClearanceHeightOffset
|
||||
] = self.obj.ClearanceHeightOffset.UserString
|
||||
attrs[
|
||||
Template.ClearanceHeightExpression
|
||||
] = self.obj.ClearanceHeightExpression
|
||||
|
||||
if includeDepths:
|
||||
attrs[Template.StartDepthExpression] = self.obj.StartDepthExpression
|
||||
attrs[Template.FinalDepthExpression] = self.obj.FinalDepthExpression
|
||||
attrs[Template.StepDownExpression] = self.obj.StepDownExpression
|
||||
attrs[Template.StepDownExpression] = self.obj.StepDownExpression
|
||||
|
||||
if includeOps:
|
||||
for opName in includeOps:
|
||||
@@ -216,13 +334,15 @@ class SetupSheet:
|
||||
for propName in op.properties():
|
||||
prop = OpPropertyName(opName, propName)
|
||||
if hasattr(self.obj, prop):
|
||||
settings[propName] = PathUtil.getPropertyValueString(self.obj, prop)
|
||||
settings[propName] = PathUtil.getPropertyValueString(
|
||||
self.obj, prop
|
||||
)
|
||||
attrs[opName] = settings
|
||||
|
||||
return attrs
|
||||
|
||||
def expressionReference(self):
|
||||
'''expressionReference() ... returns the string to be used in expressions'''
|
||||
"""expressionReference() ... returns the string to be used in expressions"""
|
||||
# Using the Name here and not the Label (both would be valid) because the Name 'fails early'.
|
||||
#
|
||||
# If there is a Name/Label conflict and an expression is bound to the Name we'll get an error
|
||||
@@ -244,23 +364,27 @@ class SetupSheet:
|
||||
return self.obj.Name
|
||||
|
||||
def encodeAttributeString(self, attr):
|
||||
'''encodeAttributeString(attr) ... return the encoded string of a template attribute.'''
|
||||
return PathUtil.toUnicode(attr.replace(self.expressionReference(), self.TemplateReference))
|
||||
"""encodeAttributeString(attr) ... return the encoded string of a template attribute."""
|
||||
return PathUtil.toUnicode(
|
||||
attr.replace(self.expressionReference(), self.TemplateReference)
|
||||
)
|
||||
|
||||
def decodeAttributeString(self, attr):
|
||||
'''decodeAttributeString(attr) ... return the decoded string of a template attribute.'''
|
||||
return PathUtil.toUnicode(attr.replace(self.TemplateReference, self.expressionReference()))
|
||||
"""decodeAttributeString(attr) ... return the decoded string of a template attribute."""
|
||||
return PathUtil.toUnicode(
|
||||
attr.replace(self.TemplateReference, self.expressionReference())
|
||||
)
|
||||
|
||||
def encodeTemplateAttributes(self, attrs):
|
||||
'''encodeTemplateAttributes(attrs) ... return a dictionary with all values encoded.'''
|
||||
"""encodeTemplateAttributes(attrs) ... return a dictionary with all values encoded."""
|
||||
return _traverseTemplateAttributes(attrs, self.encodeAttributeString)
|
||||
|
||||
def decodeTemplateAttributes(self, attrs):
|
||||
'''decodeTemplateAttributes(attrs) ... expand template attributes to reference the receiver where applicable.'''
|
||||
"""decodeTemplateAttributes(attrs) ... expand template attributes to reference the receiver where applicable."""
|
||||
return _traverseTemplateAttributes(attrs, self.decodeAttributeString)
|
||||
|
||||
def operationsWithSettings(self):
|
||||
'''operationsWithSettings() ... returns a list of operations which currently have some settings defined.'''
|
||||
"""operationsWithSettings() ... returns a list of operations which currently have some settings defined."""
|
||||
ops = []
|
||||
for name, value in PathUtil.keyValueIter(_RegisteredOps):
|
||||
for prop in value.registeredPropertyNames(name):
|
||||
@@ -283,23 +407,32 @@ class SetupSheet:
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
|
||||
if not hasattr(obj, 'CoolantModes'):
|
||||
obj.addProperty('App::PropertyStringList', 'CoolantModes', 'CoolantMode', translate('PathSetupSheet', 'Coolant Modes'))
|
||||
if not hasattr(obj, "CoolantModes"):
|
||||
obj.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"CoolantModes",
|
||||
"CoolantMode",
|
||||
translate("PathSetupSheet", "Coolant Modes"),
|
||||
)
|
||||
obj.CoolantModes = self.DefaultCoolantModes
|
||||
|
||||
if not hasattr(obj, 'CoolantMode'):
|
||||
obj.addProperty('App::PropertyEnumeration', 'CoolantMode', 'CoolantMode', translate('PathSetupSheet', 'Default coolant mode.'))
|
||||
if not hasattr(obj, "CoolantMode"):
|
||||
obj.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"CoolantMode",
|
||||
"CoolantMode",
|
||||
translate("PathSetupSheet", "Default coolant mode."),
|
||||
)
|
||||
obj.CoolantMode = self.DefaultCoolantModes
|
||||
|
||||
|
||||
def Create(name='SetupSheet'):
|
||||
obj = FreeCAD.ActiveDocument.addObject('App::FeaturePython', name)
|
||||
def Create(name="SetupSheet"):
|
||||
obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython", name)
|
||||
obj.Proxy = SetupSheet(obj)
|
||||
return obj
|
||||
|
||||
|
||||
class _RegisteredOp(object):
|
||||
|
||||
def __init__(self, factory, properties):
|
||||
self.factory = factory
|
||||
self.properties = properties
|
||||
@@ -319,7 +452,7 @@ def RegisterOperation(name, objFactory, setupProperties):
|
||||
|
||||
|
||||
def OpNamePrefix(name):
|
||||
return name.replace('Path', '').replace(' ', '').replace('_', '')
|
||||
return name.replace("Path", "").replace(" ", "").replace("_", "")
|
||||
|
||||
|
||||
def OpPropertyName(opName, propName):
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathScripts.PathGui as PathGui
|
||||
import PathScripts.PathIconViewProvider as PathIconViewProvider
|
||||
import PathScripts.PathLog as PathLog
|
||||
@@ -54,8 +54,8 @@ else:
|
||||
|
||||
|
||||
class ViewProvider:
|
||||
'''ViewProvider for a SetupSheet.
|
||||
It's sole job is to provide an icon and invoke the TaskPanel on edit.'''
|
||||
"""ViewProvider for a SetupSheet.
|
||||
It's sole job is to provide an icon and invoke the TaskPanel on edit."""
|
||||
|
||||
def __init__(self, vobj, name):
|
||||
PathLog.track(name)
|
||||
@@ -82,7 +82,7 @@ class ViewProvider:
|
||||
|
||||
def getDisplayMode(self, mode):
|
||||
# pylint: disable=unused-argument
|
||||
return 'Default'
|
||||
return "Default"
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
# pylint: disable=unused-argument
|
||||
@@ -107,7 +107,7 @@ class ViewProvider:
|
||||
|
||||
class Delegate(QtGui.QStyledItemDelegate):
|
||||
PropertyRole = QtCore.Qt.UserRole + 1
|
||||
EditorRole = QtCore.Qt.UserRole + 2
|
||||
EditorRole = QtCore.Qt.UserRole + 2
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
# pylint: disable=unused-argument
|
||||
@@ -133,7 +133,7 @@ class Delegate(QtGui.QStyledItemDelegate):
|
||||
|
||||
|
||||
class OpTaskPanel:
|
||||
'''Editor for an operation's property default values.
|
||||
"""Editor for an operation's property default values.
|
||||
The implementation is a simplified generic property editor with basically 3 fields
|
||||
- checkbox - if set a default value for the given property is set
|
||||
- name - a non-editable string with the property name
|
||||
@@ -141,7 +141,7 @@ class OpTaskPanel:
|
||||
The specific editor classes for a given property type are implemented in
|
||||
PathSetupSheetOpPrototypeGui which also provides a factory function. The properties
|
||||
are displayed in a table, each field occypying a column and each row representing
|
||||
a single property.'''
|
||||
a single property."""
|
||||
|
||||
def __init__(self, obj, name, op):
|
||||
self.name = name
|
||||
@@ -168,7 +168,7 @@ class OpTaskPanel:
|
||||
|
||||
self.delegate = Delegate(self.form)
|
||||
self.model = QtGui.QStandardItemModel(len(self.props), 3, self.form)
|
||||
self.model.setHorizontalHeaderLabels(['Set', 'Property', 'Value'])
|
||||
self.model.setHorizontalHeaderLabels(["Set", "Property", "Value"])
|
||||
|
||||
for i, name in enumerate(self.props):
|
||||
prop = self.prototype.getProperty(name)
|
||||
@@ -179,10 +179,12 @@ class OpTaskPanel:
|
||||
self.model.setData(self.model.index(i, 0), isset, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 1), name, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 2), prop, Delegate.PropertyRole)
|
||||
self.model.setData(self.model.index(i, 2), prop.displayString(), QtCore.Qt.DisplayRole)
|
||||
self.model.setData(
|
||||
self.model.index(i, 2), prop.displayString(), QtCore.Qt.DisplayRole
|
||||
)
|
||||
|
||||
self.model.item(i, 0).setCheckable(True)
|
||||
self.model.item(i, 0).setText('')
|
||||
self.model.item(i, 0).setText("")
|
||||
self.model.item(i, 1).setEditable(False)
|
||||
self.model.item(i, 1).setToolTip(prop.info)
|
||||
self.model.item(i, 2).setToolTip(prop.info)
|
||||
@@ -213,7 +215,9 @@ class OpTaskPanel:
|
||||
propName = self.propertyName(name)
|
||||
enabled = self.model.item(i, 0).checkState() == QtCore.Qt.Checked
|
||||
if enabled and not prop.getValue() is None:
|
||||
if prop.setupProperty(self.obj, propName, self.propertyGroup(), prop.getValue()):
|
||||
if prop.setupProperty(
|
||||
self.obj, propName, self.propertyGroup(), prop.getValue()
|
||||
):
|
||||
propertiesCreatedRemoved = True
|
||||
else:
|
||||
if hasattr(self.obj, propName):
|
||||
@@ -223,15 +227,21 @@ class OpTaskPanel:
|
||||
|
||||
|
||||
class OpsDefaultEditor:
|
||||
'''Class to collect and display default property editors for all registered operations.
|
||||
"""Class to collect and display default property editors for all registered operations.
|
||||
If a form is given at creation time it will integrate with that form and provide an interface to switch
|
||||
between the editors of different operations. If no form is provided the class assumes that the UI is
|
||||
taken care of somehow else and just serves as an interface to all operation editors.'''
|
||||
taken care of somehow else and just serves as an interface to all operation editors."""
|
||||
|
||||
def __init__(self, obj, form):
|
||||
self.form = form
|
||||
self.obj = obj
|
||||
self.ops = sorted([OpTaskPanel(self.obj, name, op) for name, op in PathUtil.keyValueIter(PathSetupSheet._RegisteredOps)], key=lambda op: op.name)
|
||||
self.ops = sorted(
|
||||
[
|
||||
OpTaskPanel(self.obj, name, op)
|
||||
for name, op in PathUtil.keyValueIter(PathSetupSheet._RegisteredOps)
|
||||
],
|
||||
key=lambda op: op.name,
|
||||
)
|
||||
if form:
|
||||
parent = form.tabOpDefaults
|
||||
for op in self.ops:
|
||||
@@ -281,7 +291,7 @@ class OpsDefaultEditor:
|
||||
|
||||
|
||||
class GlobalEditor(object):
|
||||
'''Editor for the global properties which affect almost every operation.'''
|
||||
"""Editor for the global properties which affect almost every operation."""
|
||||
|
||||
def __init__(self, obj, form):
|
||||
self.form = form
|
||||
@@ -306,11 +316,13 @@ class GlobalEditor(object):
|
||||
if val != value:
|
||||
PathUtil.setProperty(self.obj, name, value)
|
||||
|
||||
updateExpression('StartDepthExpression', self.form.setupStartDepthExpr)
|
||||
updateExpression('FinalDepthExpression', self.form.setupFinalDepthExpr)
|
||||
updateExpression('StepDownExpression', self.form.setupStepDownExpr)
|
||||
updateExpression('ClearanceHeightExpression', self.form.setupClearanceHeightExpr)
|
||||
updateExpression('SafeHeightExpression', self.form.setupSafeHeightExpr)
|
||||
updateExpression("StartDepthExpression", self.form.setupStartDepthExpr)
|
||||
updateExpression("FinalDepthExpression", self.form.setupFinalDepthExpr)
|
||||
updateExpression("StepDownExpression", self.form.setupStepDownExpr)
|
||||
updateExpression(
|
||||
"ClearanceHeightExpression", self.form.setupClearanceHeightExpr
|
||||
)
|
||||
updateExpression("SafeHeightExpression", self.form.setupSafeHeightExpr)
|
||||
self.clearanceHeightOffs.updateProperty()
|
||||
self.safeHeightOffs.updateProperty()
|
||||
self.rapidVertical.updateProperty()
|
||||
@@ -318,7 +330,7 @@ class GlobalEditor(object):
|
||||
self.obj.CoolantMode = self.form.setupCoolantMode.currentText()
|
||||
|
||||
def selectInComboBox(self, name, combo):
|
||||
'''selectInComboBox(name, combo) ... helper function to select a specific value in a combo box.'''
|
||||
"""selectInComboBox(name, combo) ... helper function to select a specific value in a combo box."""
|
||||
index = combo.findText(name, QtCore.Qt.MatchFixedString)
|
||||
if index >= 0:
|
||||
combo.blockSignals(True)
|
||||
@@ -349,16 +361,24 @@ class GlobalEditor(object):
|
||||
self.updateUI()
|
||||
|
||||
def setupUi(self):
|
||||
self.clearanceHeightOffs = PathGui.QuantitySpinBox(self.form.setupClearanceHeightOffs, self.obj, 'ClearanceHeightOffset')
|
||||
self.safeHeightOffs = PathGui.QuantitySpinBox(self.form.setupSafeHeightOffs, self.obj, 'SafeHeightOffset')
|
||||
self.rapidHorizontal = PathGui.QuantitySpinBox(self.form.setupRapidHorizontal, self.obj, 'HorizRapid')
|
||||
self.rapidVertical = PathGui.QuantitySpinBox(self.form.setupRapidVertical, self.obj, 'VertRapid')
|
||||
self.clearanceHeightOffs = PathGui.QuantitySpinBox(
|
||||
self.form.setupClearanceHeightOffs, self.obj, "ClearanceHeightOffset"
|
||||
)
|
||||
self.safeHeightOffs = PathGui.QuantitySpinBox(
|
||||
self.form.setupSafeHeightOffs, self.obj, "SafeHeightOffset"
|
||||
)
|
||||
self.rapidHorizontal = PathGui.QuantitySpinBox(
|
||||
self.form.setupRapidHorizontal, self.obj, "HorizRapid"
|
||||
)
|
||||
self.rapidVertical = PathGui.QuantitySpinBox(
|
||||
self.form.setupRapidVertical, self.obj, "VertRapid"
|
||||
)
|
||||
self.form.setupCoolantMode.addItems(self.obj.CoolantModes)
|
||||
self.setFields()
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
'''TaskPanel for the SetupSheet - if it is being edited directly.'''
|
||||
"""TaskPanel for the SetupSheet - if it is being edited directly."""
|
||||
|
||||
def __init__(self, vobj):
|
||||
self.vobj = vobj
|
||||
@@ -368,7 +388,9 @@ class TaskPanel:
|
||||
self.globalEditor = GlobalEditor(self.obj, self.globalForm)
|
||||
self.opsEditor = OpsDefaultEditor(self.obj, None)
|
||||
self.form = [op.form for op in self.opsEditor.ops] + [self.globalForm]
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_SetupSheet", "Edit SetupSheet"))
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
translate("Path_SetupSheet", "Edit SetupSheet")
|
||||
)
|
||||
|
||||
def reject(self):
|
||||
self.globalEditor.reject()
|
||||
@@ -408,12 +430,12 @@ class TaskPanel:
|
||||
self.opsEditor.setupUi()
|
||||
|
||||
|
||||
def Create(name='SetupSheet'):
|
||||
'''Create(name='SetupSheet') ... creates a new setup sheet'''
|
||||
def Create(name="SetupSheet"):
|
||||
"""Create(name='SetupSheet') ... creates a new setup sheet"""
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Create Job"))
|
||||
ssheet = PathSetupSheet.Create(name)
|
||||
PathIconViewProvider.Attach(ssheet, name)
|
||||
return ssheet
|
||||
|
||||
|
||||
PathIconViewProvider.RegisterViewProvider('SetupSheet', ViewProvider)
|
||||
PathIconViewProvider.RegisterViewProvider("SetupSheet", ViewProvider)
|
||||
|
||||
@@ -35,6 +35,7 @@ __doc__ = "Task panel editor for a SetupSheet"
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
LOGLEVEL = False
|
||||
|
||||
if LOGLEVEL:
|
||||
@@ -43,27 +44,32 @@ if LOGLEVEL:
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
|
||||
class _PropertyEditor(object):
|
||||
'''Base class of all property editors - just outlines the TableView delegate interface.'''
|
||||
"""Base class of all property editors - just outlines the TableView delegate interface."""
|
||||
|
||||
def __init__(self, prop):
|
||||
self.prop = prop
|
||||
|
||||
def widget(self, parent):
|
||||
'''widget(parent) ... called by the delegate to get a new editor widget.
|
||||
Must be implemented by subclasses and return the widget.'''
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
"""widget(parent) ... called by the delegate to get a new editor widget.
|
||||
Must be implemented by subclasses and return the widget."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def setEditorData(self, widget):
|
||||
'''setEditorData(widget) ... called by the delegate to initialize the editor.
|
||||
"""setEditorData(widget) ... called by the delegate to initialize the editor.
|
||||
The widget is the object returned by widget().
|
||||
Must be implemented by subclasses.'''
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
Must be implemented by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def setModelData(self, widget):
|
||||
'''setModelData(widget) ... called by the delegate to store new values.
|
||||
Must be implemented by subclasses.'''
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
"""setModelData(widget) ... called by the delegate to store new values.
|
||||
Must be implemented by subclasses."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
|
||||
class _PropertyEnumEditor(_PropertyEditor):
|
||||
'''Editor for enumeration values - uses a combo box.'''
|
||||
"""Editor for enumeration values - uses a combo box."""
|
||||
|
||||
def widget(self, parent):
|
||||
PathLog.track(self.prop.name, self.prop.getEnumValues())
|
||||
@@ -82,36 +88,38 @@ class _PropertyEnumEditor(_PropertyEditor):
|
||||
|
||||
|
||||
class _PropertyBoolEditor(_PropertyEditor):
|
||||
'''Editor for boolean values - uses a combo box.'''
|
||||
"""Editor for boolean values - uses a combo box."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QComboBox(parent)
|
||||
|
||||
def setEditorData(self, widget):
|
||||
widget.clear()
|
||||
widget.addItems(['false', 'true'])
|
||||
widget.addItems(["false", "true"])
|
||||
if not self.prop.getValue() is None:
|
||||
index = 1 if self.prop.getValue() else 0
|
||||
widget.setCurrentIndex(index)
|
||||
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.currentText() == 'true')
|
||||
self.prop.setValue(widget.currentText() == "true")
|
||||
|
||||
|
||||
class _PropertyStringEditor(_PropertyEditor):
|
||||
'''Editor for string values - uses a line edit.'''
|
||||
"""Editor for string values - uses a line edit."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QLineEdit(parent)
|
||||
|
||||
def setEditorData(self, widget):
|
||||
text = '' if self.prop.getValue() is None else self.prop.getValue()
|
||||
text = "" if self.prop.getValue() is None else self.prop.getValue()
|
||||
widget.setText(text)
|
||||
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.text())
|
||||
|
||||
|
||||
class _PropertyAngleEditor(_PropertyEditor):
|
||||
'''Editor for angle values - uses a line edit'''
|
||||
"""Editor for angle values - uses a line edit"""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QLineEdit(parent)
|
||||
@@ -125,8 +133,9 @@ class _PropertyAngleEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(FreeCAD.Units.Quantity(widget.text()))
|
||||
|
||||
|
||||
class _PropertyLengthEditor(_PropertyEditor):
|
||||
'''Editor for length values - uses a line edit.'''
|
||||
"""Editor for length values - uses a line edit."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QLineEdit(parent)
|
||||
@@ -140,8 +149,9 @@ class _PropertyLengthEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(FreeCAD.Units.Quantity(widget.text()))
|
||||
|
||||
|
||||
class _PropertyPercentEditor(_PropertyEditor):
|
||||
'''Editor for percent values - uses a spin box.'''
|
||||
"""Editor for percent values - uses a spin box."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QSpinBox(parent)
|
||||
@@ -156,8 +166,9 @@ class _PropertyPercentEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.value())
|
||||
|
||||
|
||||
class _PropertyIntegerEditor(_PropertyEditor):
|
||||
'''Editor for integer values - uses a spin box.'''
|
||||
"""Editor for integer values - uses a spin box."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QSpinBox(parent)
|
||||
@@ -171,8 +182,9 @@ class _PropertyIntegerEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.value())
|
||||
|
||||
|
||||
class _PropertyFloatEditor(_PropertyEditor):
|
||||
'''Editor for float values - uses a double spin box.'''
|
||||
"""Editor for float values - uses a double spin box."""
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QDoubleSpinBox(parent)
|
||||
@@ -186,33 +198,35 @@ class _PropertyFloatEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.value())
|
||||
|
||||
class _PropertyFileEditor(_PropertyEditor):
|
||||
|
||||
class _PropertyFileEditor(_PropertyEditor):
|
||||
def widget(self, parent):
|
||||
return QtGui.QLineEdit(parent)
|
||||
|
||||
def setEditorData(self, widget):
|
||||
text = '' if self.prop.getValue() is None else self.prop.getValue()
|
||||
text = "" if self.prop.getValue() is None else self.prop.getValue()
|
||||
widget.setText(text)
|
||||
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.text())
|
||||
|
||||
|
||||
_EditorFactory = {
|
||||
PathSetupSheetOpPrototype.Property: None,
|
||||
PathSetupSheetOpPrototype.PropertyAngle: _PropertyAngleEditor,
|
||||
PathSetupSheetOpPrototype.PropertyBool: _PropertyBoolEditor,
|
||||
PathSetupSheetOpPrototype.PropertyDistance: _PropertyLengthEditor,
|
||||
PathSetupSheetOpPrototype.PropertyEnumeration: _PropertyEnumEditor,
|
||||
PathSetupSheetOpPrototype.PropertyFloat: _PropertyFloatEditor,
|
||||
PathSetupSheetOpPrototype.PropertyInteger: _PropertyIntegerEditor,
|
||||
PathSetupSheetOpPrototype.PropertyLength: _PropertyLengthEditor,
|
||||
PathSetupSheetOpPrototype.PropertyPercent: _PropertyPercentEditor,
|
||||
PathSetupSheetOpPrototype.PropertyString: _PropertyStringEditor,
|
||||
}
|
||||
PathSetupSheetOpPrototype.Property: None,
|
||||
PathSetupSheetOpPrototype.PropertyAngle: _PropertyAngleEditor,
|
||||
PathSetupSheetOpPrototype.PropertyBool: _PropertyBoolEditor,
|
||||
PathSetupSheetOpPrototype.PropertyDistance: _PropertyLengthEditor,
|
||||
PathSetupSheetOpPrototype.PropertyEnumeration: _PropertyEnumEditor,
|
||||
PathSetupSheetOpPrototype.PropertyFloat: _PropertyFloatEditor,
|
||||
PathSetupSheetOpPrototype.PropertyInteger: _PropertyIntegerEditor,
|
||||
PathSetupSheetOpPrototype.PropertyLength: _PropertyLengthEditor,
|
||||
PathSetupSheetOpPrototype.PropertyPercent: _PropertyPercentEditor,
|
||||
PathSetupSheetOpPrototype.PropertyString: _PropertyStringEditor,
|
||||
}
|
||||
|
||||
|
||||
def Editor(prop):
|
||||
'''Returns an editor class to be used for the given property.'''
|
||||
"""Returns an editor class to be used for the given property."""
|
||||
factory = _EditorFactory[prop.__class__]
|
||||
if factory:
|
||||
return factory(prop)
|
||||
|
||||
@@ -34,11 +34,14 @@ def translate(context, text, disambig=None):
|
||||
|
||||
|
||||
class CommandPathSimpleCopy:
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_SimpleCopy',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy", "Simple Copy"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy", "Creates a non-parametric copy of another path")}
|
||||
return {
|
||||
"Pixmap": "Path_SimpleCopy",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy", "Simple Copy"),
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"Path_SimpleCopy", "Creates a non-parametric copy of another path"
|
||||
),
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
if bool(FreeCADGui.Selection.getSelection()) is False:
|
||||
@@ -46,7 +49,7 @@ class CommandPathSimpleCopy:
|
||||
try:
|
||||
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
|
||||
return isinstance(obj.Proxy, PathScripts.PathOp.ObjectOp)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
@@ -54,27 +57,38 @@ class CommandPathSimpleCopy:
|
||||
selection = FreeCADGui.Selection.getSelection()
|
||||
if len(selection) != 1:
|
||||
FreeCAD.Console.PrintError(
|
||||
translate("Path_SimpleCopy", "Please select exactly one path object")+"\n")
|
||||
translate("Path_SimpleCopy", "Please select exactly one path object")
|
||||
+ "\n"
|
||||
)
|
||||
return
|
||||
if not(selection[0].isDerivedFrom("Path::Feature")):
|
||||
if not (selection[0].isDerivedFrom("Path::Feature")):
|
||||
FreeCAD.Console.PrintError(
|
||||
translate("Path_SimpleCopy", "Please select exactly one path object")+"\n")
|
||||
translate("Path_SimpleCopy", "Please select exactly one path object")
|
||||
+ "\n"
|
||||
)
|
||||
return
|
||||
|
||||
FreeCAD.ActiveDocument.openTransaction(
|
||||
translate("Path_SimpleCopy", "Simple Copy"))
|
||||
FreeCADGui.doCommand("srcpath = FreeCADGui.Selection.getSelectionEx()[0].Object.Path\n")
|
||||
translate("Path_SimpleCopy", "Simple Copy")
|
||||
)
|
||||
FreeCADGui.doCommand(
|
||||
"srcpath = FreeCADGui.Selection.getSelectionEx()[0].Object.Path\n"
|
||||
)
|
||||
|
||||
FreeCADGui.addModule("PathScripts.PathUtils")
|
||||
FreeCADGui.addModule("PathScripts.PathCustom")
|
||||
FreeCADGui.doCommand('obj = PathScripts.PathCustom.Create("' + selection[0].Name + '_SimpleCopy")')
|
||||
FreeCADGui.doCommand('obj.ViewObject.Proxy = 0')
|
||||
FreeCADGui.doCommand('obj.Gcode = [c.toGCode() for c in srcpath.Commands]')
|
||||
FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
|
||||
FreeCADGui.doCommand(
|
||||
'obj = PathScripts.PathCustom.Create("'
|
||||
+ selection[0].Name
|
||||
+ '_SimpleCopy")'
|
||||
)
|
||||
FreeCADGui.doCommand("obj.ViewObject.Proxy = 0")
|
||||
FreeCADGui.doCommand("obj.Gcode = [c.toGCode() for c in srcpath.Commands]")
|
||||
FreeCADGui.doCommand("PathScripts.PathUtils.addToJob(obj)")
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_SimpleCopy', CommandPathSimpleCopy())
|
||||
FreeCADGui.addCommand("Path_SimpleCopy", CommandPathSimpleCopy())
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
import FreeCAD
|
||||
import Path
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathGui as PGui # ensure Path/Gui/Resources are loaded
|
||||
import PathScripts.PathDressup as PathDressup
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
@@ -36,8 +36,9 @@ from FreeCAD import Vector, Base
|
||||
|
||||
# lazily loaded modules
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
Mesh = LazyLoader('Mesh', globals(), 'Mesh')
|
||||
Part = LazyLoader('Part', globals(), 'Part')
|
||||
|
||||
Mesh = LazyLoader("Mesh", globals(), "Mesh")
|
||||
Part = LazyLoader("Part", globals(), "Part")
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
@@ -83,7 +84,9 @@ class PathSimulation:
|
||||
|
||||
def UpdateProgress(self):
|
||||
if self.numCommands > 0:
|
||||
self.taskForm.form.progressBar.setValue(self.iprogress * 100 / self.numCommands)
|
||||
self.taskForm.form.progressBar.setValue(
|
||||
self.iprogress * 100 / self.numCommands
|
||||
)
|
||||
|
||||
def Activate(self):
|
||||
self.initdone = False
|
||||
@@ -112,7 +115,7 @@ class PathSimulation:
|
||||
def _populateJobSelection(self, form):
|
||||
# Make Job selection combobox
|
||||
setJobIdx = 0
|
||||
jobName = ''
|
||||
jobName = ""
|
||||
jIdx = 0
|
||||
# Get list of Job objects in active document
|
||||
jobList = FreeCAD.ActiveDocument.findObjects("Path::FeaturePython", "Job.*")
|
||||
@@ -122,10 +125,12 @@ class PathSimulation:
|
||||
guiSelection = FreeCADGui.Selection.getSelectionEx()
|
||||
if guiSelection: # Identify job selected by user
|
||||
sel = guiSelection[0]
|
||||
if hasattr(sel.Object, "Proxy") and isinstance(sel.Object.Proxy, PathJob.ObjectJob):
|
||||
if hasattr(sel.Object, "Proxy") and isinstance(
|
||||
sel.Object.Proxy, PathJob.ObjectJob
|
||||
):
|
||||
jobName = sel.Object.Name
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
|
||||
|
||||
# populate the job selection combobox
|
||||
form.comboJobs.blockSignals(True)
|
||||
form.comboJobs.clear()
|
||||
@@ -136,7 +141,7 @@ class PathSimulation:
|
||||
if j.Name == jobName or jCnt == 1:
|
||||
setJobIdx = jIdx
|
||||
jIdx += 1
|
||||
|
||||
|
||||
# Pre-select GUI-selected job in the combobox
|
||||
if jobName or jCnt == 1:
|
||||
form.comboJobs.setCurrentIndex(setJobIdx)
|
||||
@@ -155,19 +160,22 @@ class PathSimulation:
|
||||
self.numCommands += len(self.operations[i].Path.Commands)
|
||||
|
||||
self.stock = self.job.Stock.Shape
|
||||
if (self.isVoxel):
|
||||
if self.isVoxel:
|
||||
maxlen = self.stock.BoundBox.XLength
|
||||
if (maxlen < self.stock.BoundBox.YLength):
|
||||
if maxlen < self.stock.BoundBox.YLength:
|
||||
maxlen = self.stock.BoundBox.YLength
|
||||
self.voxSim.BeginSimulation(self.stock, 0.01 * self.accuracy * maxlen)
|
||||
(self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
|
||||
(
|
||||
self.cutMaterial.Mesh,
|
||||
self.cutMaterialIn.Mesh,
|
||||
) = self.voxSim.GetResultMesh()
|
||||
else:
|
||||
self.cutMaterial.Shape = self.stock
|
||||
self.busy = False
|
||||
self.tool = None
|
||||
for i in range(len(self.activeOps)):
|
||||
self.SetupOperation(0)
|
||||
if (self.tool is not None):
|
||||
if self.tool is not None:
|
||||
break
|
||||
self.iprogress = 0
|
||||
self.UpdateProgress()
|
||||
@@ -179,18 +187,29 @@ class PathSimulation:
|
||||
except Exception:
|
||||
self.tool = None
|
||||
|
||||
if (self.tool is not None):
|
||||
if self.tool is not None:
|
||||
if isinstance(self.tool, Path.Tool):
|
||||
# handle legacy tools
|
||||
toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), float(self.tool.Diameter) / 2.0)
|
||||
self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1)))
|
||||
toolProf = self.CreateToolProfile(
|
||||
self.tool,
|
||||
Vector(0, 1, 0),
|
||||
Vector(0, 0, 0),
|
||||
float(self.tool.Diameter) / 2.0,
|
||||
)
|
||||
self.cutTool.Shape = Part.makeSolid(
|
||||
toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1))
|
||||
)
|
||||
else:
|
||||
# handle tool bits
|
||||
self.cutTool.Shape = self.tool.Shape
|
||||
|
||||
if not self.cutTool.Shape.isValid() or self.cutTool.Shape.isNull():
|
||||
self.EndSimulation()
|
||||
raise RuntimeError("Path Simulation: Error in tool geometry - {}".format(self.tool.Name))
|
||||
raise RuntimeError(
|
||||
"Path Simulation: Error in tool geometry - {}".format(
|
||||
self.tool.Name
|
||||
)
|
||||
)
|
||||
|
||||
self.cutTool.ViewObject.show()
|
||||
self.voxSim.SetToolShape(self.cutTool.Shape, 0.05 * self.accuracy)
|
||||
@@ -206,19 +225,27 @@ class PathSimulation:
|
||||
self.skipStep = False
|
||||
self.initialPos = Vector(0, 0, self.job.Stock.Shape.BoundBox.ZMax)
|
||||
# Add cut tool
|
||||
self.cutTool = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "CutTool")
|
||||
self.cutTool = FreeCAD.ActiveDocument.addObject(
|
||||
"Part::FeaturePython", "CutTool"
|
||||
)
|
||||
self.cutTool.ViewObject.Proxy = 0
|
||||
self.cutTool.ViewObject.hide()
|
||||
|
||||
# Add cut material
|
||||
if self.isVoxel:
|
||||
self.cutMaterial = FreeCAD.ActiveDocument.addObject("Mesh::FeaturePython", "CutMaterial")
|
||||
self.cutMaterialIn = FreeCAD.ActiveDocument.addObject("Mesh::FeaturePython", "CutMaterialIn")
|
||||
self.cutMaterial = FreeCAD.ActiveDocument.addObject(
|
||||
"Mesh::FeaturePython", "CutMaterial"
|
||||
)
|
||||
self.cutMaterialIn = FreeCAD.ActiveDocument.addObject(
|
||||
"Mesh::FeaturePython", "CutMaterialIn"
|
||||
)
|
||||
self.cutMaterialIn.ViewObject.Proxy = 0
|
||||
self.cutMaterialIn.ViewObject.show()
|
||||
self.cutMaterialIn.ViewObject.ShapeColor = (1.0, 0.85, 0.45, 0.0)
|
||||
else:
|
||||
self.cutMaterial = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "CutMaterial")
|
||||
self.cutMaterial = FreeCAD.ActiveDocument.addObject(
|
||||
"Part::FeaturePython", "CutMaterial"
|
||||
)
|
||||
self.cutMaterial.Shape = self.job.Stock.Shape
|
||||
self.cutMaterial.ViewObject.Proxy = 0
|
||||
self.cutMaterial.ViewObject.show()
|
||||
@@ -226,7 +253,9 @@ class PathSimulation:
|
||||
|
||||
# Add cut path solid for debug
|
||||
if self.debug:
|
||||
self.cutSolid = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "CutDebug")
|
||||
self.cutSolid = FreeCAD.ActiveDocument.addObject(
|
||||
"Part::FeaturePython", "CutDebug"
|
||||
)
|
||||
self.cutSolid.ViewObject.Proxy = 0
|
||||
self.cutSolid.ViewObject.hide()
|
||||
|
||||
@@ -246,28 +275,30 @@ class PathSimulation:
|
||||
cmd = self.operation.Path.Commands[self.icmd]
|
||||
pathSolid = None
|
||||
|
||||
if cmd.Name in ['G0']:
|
||||
if cmd.Name in ["G0"]:
|
||||
self.firstDrill = True
|
||||
self.curpos = self.RapidMove(cmd, self.curpos)
|
||||
if cmd.Name in ['G1', 'G2', 'G3']:
|
||||
if cmd.Name in ["G1", "G2", "G3"]:
|
||||
self.firstDrill = True
|
||||
if self.skipStep:
|
||||
self.curpos = self.RapidMove(cmd, self.curpos)
|
||||
else:
|
||||
(pathSolid, self.curpos) = self.GetPathSolid(self.tool, cmd, self.curpos)
|
||||
(pathSolid, self.curpos) = self.GetPathSolid(
|
||||
self.tool, cmd, self.curpos
|
||||
)
|
||||
|
||||
if cmd.Name in ['G80']:
|
||||
if cmd.Name in ["G80"]:
|
||||
self.firstDrill = True
|
||||
if cmd.Name in ['G81', 'G82', 'G83']:
|
||||
if cmd.Name in ["G81", "G82", "G83"]:
|
||||
if self.firstDrill:
|
||||
extendcommand = Path.Command('G0', {"Z": cmd.r})
|
||||
extendcommand = Path.Command("G0", {"Z": cmd.r})
|
||||
self.curpos = self.RapidMove(extendcommand, self.curpos)
|
||||
self.firstDrill = False
|
||||
extendcommand = Path.Command('G0', {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
extendcommand = Path.Command("G0", {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
self.curpos = self.RapidMove(extendcommand, self.curpos)
|
||||
extendcommand = Path.Command('G1', {"X": cmd.x, "Y": cmd.y, "Z": cmd.z})
|
||||
extendcommand = Path.Command("G1", {"X": cmd.x, "Y": cmd.y, "Z": cmd.z})
|
||||
self.curpos = self.RapidMove(extendcommand, self.curpos)
|
||||
extendcommand = Path.Command('G1', {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
extendcommand = Path.Command("G1", {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
self.curpos = self.RapidMove(extendcommand, self.curpos)
|
||||
self.skipStep = False
|
||||
if pathSolid is not None:
|
||||
@@ -307,27 +338,39 @@ class PathSimulation:
|
||||
|
||||
cmd = self.opCommands[self.icmd]
|
||||
# for cmd in job.Path.Commands:
|
||||
if cmd.Name in ['G0', 'G1', 'G2', 'G3']:
|
||||
if cmd.Name in ["G0", "G1", "G2", "G3"]:
|
||||
self.firstDrill = True
|
||||
self.curpos = self.voxSim.ApplyCommand(self.curpos, cmd)
|
||||
if not self.disableAnim:
|
||||
self.cutTool.Placement = self.curpos
|
||||
(self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
|
||||
if cmd.Name in ['G80']:
|
||||
(
|
||||
self.cutMaterial.Mesh,
|
||||
self.cutMaterialIn.Mesh,
|
||||
) = self.voxSim.GetResultMesh()
|
||||
if cmd.Name in ["G80"]:
|
||||
self.firstDrill = True
|
||||
if cmd.Name in ['G81', 'G82', 'G83']:
|
||||
if cmd.Name in ["G81", "G82", "G83"]:
|
||||
extendcommands = []
|
||||
if self.firstDrill:
|
||||
extendcommands.append(Path.Command('G0', {"Z": cmd.r}))
|
||||
extendcommands.append(Path.Command("G0", {"Z": cmd.r}))
|
||||
self.firstDrill = False
|
||||
extendcommands.append(Path.Command('G0', {"X": cmd.x, "Y": cmd.y, "Z": cmd.r}))
|
||||
extendcommands.append(Path.Command('G1', {"X": cmd.x, "Y": cmd.y, "Z": cmd.z}))
|
||||
extendcommands.append(Path.Command('G1', {"X": cmd.x, "Y": cmd.y, "Z": cmd.r}))
|
||||
extendcommands.append(
|
||||
Path.Command("G0", {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
)
|
||||
extendcommands.append(
|
||||
Path.Command("G1", {"X": cmd.x, "Y": cmd.y, "Z": cmd.z})
|
||||
)
|
||||
extendcommands.append(
|
||||
Path.Command("G1", {"X": cmd.x, "Y": cmd.y, "Z": cmd.r})
|
||||
)
|
||||
for ecmd in extendcommands:
|
||||
self.curpos = self.voxSim.ApplyCommand(self.curpos, ecmd)
|
||||
if not self.disableAnim:
|
||||
self.cutTool.Placement = self.curpos
|
||||
(self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
|
||||
(
|
||||
self.cutMaterial.Mesh,
|
||||
self.cutMaterialIn.Mesh,
|
||||
) = self.voxSim.GetResultMesh()
|
||||
self.icmd += 1
|
||||
self.iprogress += 1
|
||||
self.UpdateProgress()
|
||||
@@ -341,7 +384,7 @@ class PathSimulation:
|
||||
self.busy = False
|
||||
|
||||
def PerformCut(self):
|
||||
if (self.isVoxel):
|
||||
if self.isVoxel:
|
||||
self.PerformCutVoxel()
|
||||
else:
|
||||
self.PerformCutBoolean()
|
||||
@@ -457,7 +500,7 @@ class PathSimulation:
|
||||
form.listOperations.clear()
|
||||
self.operations = []
|
||||
for op in j.Operations.OutList:
|
||||
if PathUtil.opProperty(op, 'Active'):
|
||||
if PathUtil.opProperty(op, "Active"):
|
||||
listItem = QtGui.QListWidgetItem(op.ViewObject.Icon, op.Label)
|
||||
listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||
listItem.setCheckState(QtCore.Qt.CheckState.Checked)
|
||||
@@ -499,7 +542,7 @@ class PathSimulation:
|
||||
def InvalidOperation(self):
|
||||
if len(self.activeOps) == 0:
|
||||
return True
|
||||
if (self.tool is None):
|
||||
if self.tool is None:
|
||||
TSError("No tool assigned for the operation")
|
||||
return True
|
||||
return False
|
||||
@@ -526,7 +569,10 @@ class PathSimulation:
|
||||
|
||||
def ViewShape(self):
|
||||
if self.isVoxel:
|
||||
(self.cutMaterial.Mesh, self.cutMaterialIn.Mesh) = self.voxSim.GetResultMesh()
|
||||
(
|
||||
self.cutMaterial.Mesh,
|
||||
self.cutMaterialIn.Mesh,
|
||||
) = self.voxSim.GetResultMesh()
|
||||
else:
|
||||
self.cutMaterial.Shape = self.stock
|
||||
|
||||
@@ -570,12 +616,15 @@ class PathSimulation:
|
||||
|
||||
|
||||
class CommandPathSimulate:
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path_Simulator',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Simulator", "CAM Simulator"),
|
||||
'Accel': "P, M",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Simulator", "Simulate Path G-Code on stock")}
|
||||
return {
|
||||
"Pixmap": "Path_Simulator",
|
||||
"MenuText": QtCore.QT_TRANSLATE_NOOP("Path_Simulator", "CAM Simulator"),
|
||||
"Accel": "P, M",
|
||||
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
|
||||
"Path_Simulator", "Simulate Path G-Code on stock"
|
||||
),
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
if FreeCAD.ActiveDocument is not None:
|
||||
@@ -592,5 +641,5 @@ pathSimulation = PathSimulation()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_Simulator', CommandPathSimulate())
|
||||
FreeCADGui.addCommand("Path_Simulator", CommandPathSimulate())
|
||||
FreeCAD.Console.PrintLog("Loading PathSimulator Gui... done\n")
|
||||
|
||||
Reference in New Issue
Block a user