toolcontroller black

This commit is contained in:
sliptonic
2022-01-22 15:26:07 -06:00
parent 98d4042b29
commit beac4ad660
2 changed files with 221 additions and 119 deletions

View File

@@ -20,7 +20,7 @@
# * *
# ***************************************************************************
'''Tool Controller defines tool, spindle speed and feed rates for Path Operations'''
"""Tool Controller defines tool, spindle speed and feed rates for Path Operations"""
import FreeCAD
import Path
@@ -40,58 +40,104 @@ def translate(context, text, disambig=None):
class ToolControllerTemplate:
'''Attribute and sub element strings for template export/import.'''
"""Attribute and sub element strings for template export/import."""
Expressions = 'xengine'
ExprExpr = 'expr'
ExprProp = 'prop'
HorizFeed = 'hfeed'
HorizRapid = 'hrapid'
Label = 'label'
Name = 'name'
SpindleDir = 'dir'
SpindleSpeed = 'speed'
ToolNumber = 'nr'
Tool = 'tool'
Version = 'version'
VertFeed = 'vfeed'
VertRapid = 'vrapid'
Expressions = "xengine"
ExprExpr = "expr"
ExprProp = "prop"
HorizFeed = "hfeed"
HorizRapid = "hrapid"
Label = "label"
Name = "name"
SpindleDir = "dir"
SpindleSpeed = "speed"
ToolNumber = "nr"
Tool = "tool"
Version = "version"
VertFeed = "vfeed"
VertRapid = "vrapid"
class ToolController:
def __init__(self, obj, legacyTool=False, createTool=True):
PathLog.track('tool: {}'.format(legacyTool))
PathLog.track("tool: {}".format(legacyTool))
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The active tool"))
obj.addProperty(
"App::PropertyIntegerConstraint",
"ToolNumber",
"Tool",
QtCore.QT_TRANSLATE_NOOP("PathToolController", "The active tool"),
)
obj.ToolNumber = (0, 0, 10000, 1)
obj.addProperty("App::PropertyFloat", "SpindleSpeed", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The speed of the cutting spindle in RPM"))
obj.addProperty("App::PropertyEnumeration", "SpindleDir", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Direction of spindle rotation"))
obj.SpindleDir = ['Forward', 'Reverse']
obj.addProperty("App::PropertySpeed", "VertFeed", "Feed", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Feed rate for vertical moves in Z"))
obj.addProperty("App::PropertySpeed", "HorizFeed", "Feed", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Feed rate for horizontal moves"))
obj.addProperty("App::PropertySpeed", "VertRapid", "Rapid", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Rapid rate for vertical moves in Z"))
obj.addProperty("App::PropertySpeed", "HorizRapid", "Rapid", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Rapid rate for horizontal moves"))
obj.setEditorMode('Placement', 2)
obj.addProperty(
"App::PropertyFloat",
"SpindleSpeed",
"Tool",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "The speed of the cutting spindle in RPM"
),
)
obj.addProperty(
"App::PropertyEnumeration",
"SpindleDir",
"Tool",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "Direction of spindle rotation"
),
)
obj.SpindleDir = ["Forward", "Reverse"]
obj.addProperty(
"App::PropertySpeed",
"VertFeed",
"Feed",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "Feed rate for vertical moves in Z"
),
)
obj.addProperty(
"App::PropertySpeed",
"HorizFeed",
"Feed",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "Feed rate for horizontal moves"
),
)
obj.addProperty(
"App::PropertySpeed",
"VertRapid",
"Rapid",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "Rapid rate for vertical moves in Z"
),
)
obj.addProperty(
"App::PropertySpeed",
"HorizRapid",
"Rapid",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "Rapid rate for horizontal moves"
),
)
obj.setEditorMode("Placement", 2)
if createTool:
self.ensureUseLegacyTool(obj, legacyTool)
def onDocumentRestored(self, obj):
obj.setEditorMode('Placement', 2)
obj.setEditorMode("Placement", 2)
def onDelete(self, obj, arg2=None):
# pylint: disable=unused-argument
if not self.usesLegacyTool(obj):
if hasattr(obj.Tool, 'InList') and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, 'onDelete'):
if hasattr(obj.Tool, "InList") and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, "onDelete"):
obj.Tool.Proxy.onDelete(obj.Tool)
def setFromTemplate(self, obj, template):
'''
"""
setFromTemplate(obj, xmlItem) ... extract properties from xmlItem
and assign to receiver.
'''
"""
PathLog.track(obj.Name, template)
version = 0
if template.get(ToolControllerTemplate.Version):
@@ -108,51 +154,84 @@ class ToolController:
if template.get(ToolControllerTemplate.HorizRapid):
obj.HorizRapid = template.get(ToolControllerTemplate.HorizRapid)
if template.get(ToolControllerTemplate.SpindleSpeed):
obj.SpindleSpeed = float(template.get(ToolControllerTemplate.SpindleSpeed))
obj.SpindleSpeed = float(
template.get(ToolControllerTemplate.SpindleSpeed)
)
if template.get(ToolControllerTemplate.SpindleDir):
obj.SpindleDir = template.get(ToolControllerTemplate.SpindleDir)
if template.get(ToolControllerTemplate.ToolNumber):
obj.ToolNumber = int(template.get(ToolControllerTemplate.ToolNumber))
obj.ToolNumber = int(
template.get(ToolControllerTemplate.ToolNumber)
)
if template.get(ToolControllerTemplate.Tool):
toolVersion = template.get(ToolControllerTemplate.Tool).get(ToolControllerTemplate.Version)
toolVersion = template.get(ToolControllerTemplate.Tool).get(
ToolControllerTemplate.Version
)
if toolVersion == 1:
self.ensureUseLegacyTool(obj, True)
obj.Tool.setFromTemplate(template.get(ToolControllerTemplate.Tool))
obj.Tool.setFromTemplate(
template.get(ToolControllerTemplate.Tool)
)
else:
self.ensureUseLegacyTool(obj, False)
obj.Tool = PathToolBit.Factory.CreateFromAttrs(template.get(ToolControllerTemplate.Tool))
if obj.Tool and obj.Tool.ViewObject and obj.Tool.ViewObject.Visibility:
obj.Tool = PathToolBit.Factory.CreateFromAttrs(
template.get(ToolControllerTemplate.Tool)
)
if (
obj.Tool
and obj.Tool.ViewObject
and obj.Tool.ViewObject.Visibility
):
obj.Tool.ViewObject.Visibility = False
if template.get(ToolControllerTemplate.Expressions):
for exprDef in template.get(ToolControllerTemplate.Expressions):
if exprDef[ToolControllerTemplate.ExprExpr]:
obj.setExpression(exprDef[ToolControllerTemplate.ExprProp], exprDef[ToolControllerTemplate.ExprExpr])
obj.setExpression(
exprDef[ToolControllerTemplate.ExprProp],
exprDef[ToolControllerTemplate.ExprExpr],
)
else:
PathLog.error(translate('PathToolController', "Unsupported PathToolController template version %s") % template.get(ToolControllerTemplate.Version))
PathLog.error(
translate(
"PathToolController",
"Unsupported PathToolController template version %s",
)
% template.get(ToolControllerTemplate.Version)
)
else:
PathLog.error(translate('PathToolController', 'PathToolController template has no version - corrupted template file?'))
PathLog.error(
translate(
"PathToolController",
"PathToolController template has no version - corrupted template file?",
)
)
def templateAttrs(self, obj):
'''templateAttrs(obj) ... answer a dictionary with all properties that should be stored for a template.'''
"""templateAttrs(obj) ... answer a dictionary with all properties that should be stored for a template."""
attrs = {}
attrs[ToolControllerTemplate.Version] = 1
attrs[ToolControllerTemplate.Name] = obj.Name
attrs[ToolControllerTemplate.Label] = obj.Label
attrs[ToolControllerTemplate.ToolNumber] = obj.ToolNumber
attrs[ToolControllerTemplate.VertFeed] = ("%s" % (obj.VertFeed))
attrs[ToolControllerTemplate.HorizFeed] = ("%s" % (obj.HorizFeed))
attrs[ToolControllerTemplate.VertRapid] = ("%s" % (obj.VertRapid))
attrs[ToolControllerTemplate.HorizRapid] = ("%s" % (obj.HorizRapid))
attrs[ToolControllerTemplate.Version] = 1
attrs[ToolControllerTemplate.Name] = obj.Name
attrs[ToolControllerTemplate.Label] = obj.Label
attrs[ToolControllerTemplate.ToolNumber] = obj.ToolNumber
attrs[ToolControllerTemplate.VertFeed] = "%s" % (obj.VertFeed)
attrs[ToolControllerTemplate.HorizFeed] = "%s" % (obj.HorizFeed)
attrs[ToolControllerTemplate.VertRapid] = "%s" % (obj.VertRapid)
attrs[ToolControllerTemplate.HorizRapid] = "%s" % (obj.HorizRapid)
attrs[ToolControllerTemplate.SpindleSpeed] = obj.SpindleSpeed
attrs[ToolControllerTemplate.SpindleDir] = obj.SpindleDir
attrs[ToolControllerTemplate.SpindleDir] = obj.SpindleDir
if self.usesLegacyTool(obj):
attrs[ToolControllerTemplate.Tool] = obj.Tool.templateAttrs()
attrs[ToolControllerTemplate.Tool] = obj.Tool.templateAttrs()
else:
attrs[ToolControllerTemplate.Tool] = obj.Tool.Proxy.templateAttrs(obj.Tool)
attrs[ToolControllerTemplate.Tool] = obj.Tool.Proxy.templateAttrs(obj.Tool)
expressions = []
for expr in obj.ExpressionEngine:
PathLog.debug('%s: %s' % (expr[0], expr[1]))
expressions.append({ToolControllerTemplate.ExprProp: expr[0], ToolControllerTemplate.ExprExpr: expr[1]})
PathLog.debug("%s: %s" % (expr[0], expr[1]))
expressions.append(
{
ToolControllerTemplate.ExprProp: expr[0],
ToolControllerTemplate.ExprExpr: expr[1],
}
)
if expressions:
attrs[ToolControllerTemplate.Expressions] = expressions
return attrs
@@ -161,24 +240,23 @@ class ToolController:
PathLog.track()
commands = ""
commands += "(" + obj.Label + ")"+'\n'
commands += 'M6 T'+str(obj.ToolNumber)+'\n'
commands += "(" + obj.Label + ")" + "\n"
commands += "M6 T" + str(obj.ToolNumber) + "\n"
# If a toolbit is used, check to see if spindlepower is allowed.
# This is to prevent accidentally spinning the spindle with an
# unpowered tool like probe or dragknife
allowSpindlePower = True
if (not isinstance(obj.Tool, Path.Tool) and
hasattr(obj.Tool, "SpindlePower")):
allowSpindlePower = obj.Tool.SpindlePower
if not isinstance(obj.Tool, Path.Tool) and hasattr(obj.Tool, "SpindlePower"):
allowSpindlePower = obj.Tool.SpindlePower
if allowSpindlePower:
PathLog.debug('selected tool preventing spindle power')
if obj.SpindleDir == 'Forward':
commands += 'M3 S' + str(obj.SpindleSpeed) + '\n'
PathLog.debug("selected tool preventing spindle power")
if obj.SpindleDir == "Forward":
commands += "M3 S" + str(obj.SpindleSpeed) + "\n"
else:
commands += 'M4 S' + str(obj.SpindleSpeed) + '\n'
commands += "M4 S" + str(obj.SpindleSpeed) + "\n"
if commands == "":
commands += "(No commands processed)"
@@ -189,32 +267,56 @@ class ToolController:
obj.ViewObject.Visibility = True
def getTool(self, obj):
'''returns the tool associated with this tool controller'''
"""returns the tool associated with this tool controller"""
PathLog.track()
return obj.Tool
def usesLegacyTool(self, obj):
'''returns True if the tool being controlled is a legacy tool'''
"""returns True if the tool being controlled is a legacy tool"""
return isinstance(obj.Tool, Path.Tool)
def ensureUseLegacyTool(self, obj, legacy):
if not hasattr(obj, 'Tool') or (legacy != self.usesLegacyTool(obj)):
if legacy and hasattr(obj, 'Tool') and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, 'onDelete'):
if not hasattr(obj, "Tool") or (legacy != self.usesLegacyTool(obj)):
if legacy and hasattr(obj, "Tool") and len(obj.Tool.InList) == 1:
if hasattr(obj.Tool.Proxy, "onDelete"):
obj.Tool.Proxy.onDelete(obj.Tool)
obj.Document.removeObject(obj.Tool.Name)
if hasattr(obj, 'Tool'):
obj.removeProperty('Tool')
if hasattr(obj, "Tool"):
obj.removeProperty("Tool")
if legacy:
obj.addProperty("Path::PropertyTool", "Tool", "Base", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The tool used by this controller"))
obj.addProperty(
"Path::PropertyTool",
"Tool",
"Base",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "The tool used by this controller"
),
)
else:
obj.addProperty("App::PropertyLink", "Tool", "Base", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The tool used by this controller"))
obj.addProperty(
"App::PropertyLink",
"Tool",
"Base",
QtCore.QT_TRANSLATE_NOOP(
"PathToolController", "The tool used by this controller"
),
)
def Create(name='TC: Default Tool', tool=None, toolNumber=1, assignViewProvider=True, assignTool=True):
legacyTool = PathPreferences.toolsUseLegacyTools() if tool is None else isinstance(tool, Path.Tool)
def Create(
name="TC: Default Tool",
tool=None,
toolNumber=1,
assignViewProvider=True,
assignTool=True,
):
legacyTool = (
PathPreferences.toolsUseLegacyTools()
if tool is None
else isinstance(tool, Path.Tool)
)
PathLog.track(tool, toolNumber, legacyTool)

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
import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
@@ -34,7 +34,8 @@ from PySide import QtCore, QtGui
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader('Part', globals(), 'Part')
Part = LazyLoader("Part", globals(), "Part")
# Qt translation handling
@@ -43,22 +44,21 @@ def translate(context, text, disambig=None):
class ViewProvider:
def __init__(self, vobj):
vobj.Proxy = self
self.vobj = vobj
def attach(self, vobj):
mode = 2
vobj.setEditorMode('LineWidth', mode)
vobj.setEditorMode('MarkerColor', mode)
vobj.setEditorMode('NormalColor', mode)
vobj.setEditorMode('DisplayMode', mode)
vobj.setEditorMode('BoundingBox', mode)
vobj.setEditorMode('Selectable', mode)
vobj.setEditorMode('ShapeColor', mode)
vobj.setEditorMode('Transparency', mode)
vobj.setEditorMode('Visibility', mode)
vobj.setEditorMode("LineWidth", mode)
vobj.setEditorMode("MarkerColor", mode)
vobj.setEditorMode("NormalColor", mode)
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
vobj.setEditorMode("ShapeColor", mode)
vobj.setEditorMode("Transparency", mode)
vobj.setEditorMode("Visibility", mode)
self.vobj = vobj
def __getstate__(self):
@@ -73,12 +73,12 @@ class ViewProvider:
def onChanged(self, vobj, prop):
# pylint: disable=unused-argument
mode = 2
vobj.setEditorMode('LineWidth', mode)
vobj.setEditorMode('MarkerColor', mode)
vobj.setEditorMode('NormalColor', mode)
vobj.setEditorMode('DisplayMode', mode)
vobj.setEditorMode('BoundingBox', mode)
vobj.setEditorMode('Selectable', mode)
vobj.setEditorMode("LineWidth", mode)
vobj.setEditorMode("MarkerColor", mode)
vobj.setEditorMode("NormalColor", mode)
vobj.setEditorMode("DisplayMode", mode)
vobj.setEditorMode("BoundingBox", mode)
vobj.setEditorMode("Selectable", mode)
def onDelete(self, vobj, args=None):
# pylint: disable=unused-argument
@@ -115,7 +115,7 @@ class ViewProvider:
PathLog.track()
for action in menu.actions():
menu.removeAction(action)
action = QtGui.QAction(translate('Path', 'Edit'), menu)
action = QtGui.QAction(translate("Path", "Edit"), menu)
action.triggered.connect(self.setEdit)
menu.addAction(action)
@@ -126,7 +126,7 @@ class ViewProvider:
return []
def Create(name='Default Tool', tool=None, toolNumber=1):
def Create(name="Default Tool", tool=None, toolNumber=1):
PathLog.track(tool, toolNumber)
obj = PathScripts.PathToolController.Create(name, tool, toolNumber)
@@ -142,16 +142,22 @@ class CommandPathToolController(object):
# pylint: disable=no-init
def GetResources(self):
return {'Pixmap': 'Path_LengthOffset',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolController", "Add Tool Controller to the Job"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolController", "Add Tool Controller")}
return {
"Pixmap": "Path_LengthOffset",
"MenuText": QtCore.QT_TRANSLATE_NOOP(
"Path_ToolController", "Add Tool Controller to the Job"
),
"ToolTip": QtCore.QT_TRANSLATE_NOOP(
"Path_ToolController", "Add Tool Controller"
),
}
def selectedJob(self):
if FreeCAD.ActiveDocument:
sel = FreeCADGui.Selection.getSelectionEx()
if sel and sel[0].Object.Name[:3] == 'Job':
if sel and sel[0].Object.Name[:3] == "Job":
return sel[0].Object
jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job']
jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == "Job"]
if 1 == len(jobs):
return jobs[0]
return None
@@ -178,25 +184,21 @@ class CommandPathToolController(object):
class ToolControllerEditor(object):
def __init__(self, obj, asDialog):
self.form = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolControllerEdit.ui")
if not asDialog:
self.form.buttonBox.hide()
self.obj = obj
self.vertFeed = PathGui.QuantitySpinBox(self.form.vertFeed, obj,
'VertFeed')
self.horizFeed = PathGui.QuantitySpinBox(self.form.horizFeed, obj,
'HorizFeed')
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj,
'VertRapid')
self.horizRapid = PathGui.QuantitySpinBox(self.form.horizRapid, obj,
'HorizRapid')
self.vertFeed = PathGui.QuantitySpinBox(self.form.vertFeed, obj, "VertFeed")
self.horizFeed = PathGui.QuantitySpinBox(self.form.horizFeed, obj, "HorizFeed")
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj, "VertRapid")
self.horizRapid = PathGui.QuantitySpinBox(
self.form.horizRapid, obj, "HorizRapid"
)
if obj.Proxy.usesLegacyTool(obj):
self.editor = PathToolEdit.ToolEditor(obj.Tool,
self.form.toolEditor)
self.editor = PathToolEdit.ToolEditor(obj.Tool, self.form.toolEditor)
else:
self.editor = None
self.form.toolBox.widget(1).hide()
@@ -211,8 +213,9 @@ class ToolControllerEditor(object):
self.vertFeed.updateSpinBox()
self.vertRapid.updateSpinBox()
self.form.spindleSpeed.setValue(tc.SpindleSpeed)
index = self.form.spindleDirection.findText(tc.SpindleDir,
QtCore.Qt.MatchFixedString)
index = self.form.spindleDirection.findText(
tc.SpindleDir, QtCore.Qt.MatchFixedString
)
if index >= 0:
self.form.spindleDirection.setCurrentIndex(index)
@@ -236,8 +239,7 @@ class ToolControllerEditor(object):
tc.Tool = self.editor.tool
except Exception as e:
PathLog.error(translate("PathToolController",
"Error updating TC: %s") % e)
PathLog.error(translate("PathToolController", "Error updating TC: %s") % e)
def refresh(self):
self.form.blockSignals(True)
@@ -259,7 +261,6 @@ class ToolControllerEditor(object):
class TaskPanel:
def __init__(self, obj):
self.editor = ToolControllerEditor(obj, False)
self.form = self.editor.form
@@ -309,8 +310,7 @@ class TaskPanel:
def setupUi(self):
if self.editor.editor:
t = Part.makeCylinder(1, 1)
self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature",
"tool")
self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature", "tool")
self.toolrep.Shape = t
self.setFields()
@@ -337,6 +337,6 @@ class DlgToolControllerEdit:
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_ToolController', CommandPathToolController())
FreeCADGui.addCommand("Path_ToolController", CommandPathToolController())
FreeCAD.Console.PrintLog("Loading PathToolControllerGui... done\n")