black reformat (setupsheet)

This commit is contained in:
sliptonic
2022-01-04 14:26:52 -06:00
parent 09d1e31b73
commit ddd680e932
5 changed files with 439 additions and 207 deletions

View File

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

View File

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

View File

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

View File

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

View File

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