Add tool controller support with inplace editing.

This commit is contained in:
Markus Lampert
2017-08-26 14:08:16 -07:00
committed by wmayer
parent c0d1fa49a6
commit a440dabf5d
5 changed files with 204 additions and 64 deletions

View File

@@ -35,7 +35,7 @@ from PySide import QtCore
if True:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule()
PathLog.trackModule(PathLog.thisModule())
else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
@@ -94,6 +94,7 @@ class ObjectJob:
self.assignTemplate(obj, template)
def onDelete(self, obj, arg2=None):
PathLog.track(obj, arg2)
for tc in obj.ToolController:
FreeCAD.ActiveDocument.removeObject(tc.Name)
obj.ToolController = []
@@ -129,9 +130,9 @@ class ObjectJob:
if job.get(JobTemplate.Description):
obj.Description = job.get(JobTemplate.Description)
for tc in tree.getroot().iter(JobTemplate.ToolController):
tcs.append(PathToolController.CommandPathToolController.FromTemplate(tc))
tcs.append(PathToolController.FromTemplate(tc))
else:
tcs.append(PathToolController.CommandPathToolController.Create(obj.Name))
tcs.append(PathToolController.Create(obj.Name))
PathLog.debug("setting tool controllers (%d)" % len(tcs))
obj.ToolController = tcs
@@ -167,6 +168,14 @@ class ObjectJob:
group.append(op)
self.obj.Operations.Group = group
def addToolController(self, tc):
group = self.obj.ToolController
PathLog.info("addToolController(%s): %s" % (tc.Label, [t.Label for t in group]))
if tc.Name not in [str(t.Name) for t in group]:
group.append(tc)
self.obj.ToolController = group
@classmethod
def baseCandidates(cls):
'''Answer all objects in the current document which could serve as a Base for a job.'''

View File

@@ -27,6 +27,7 @@ import FreeCADGui
import PathScripts.PathJob as PathJob
import PathScripts.PathLog as PathLog
import PathScripts.PathToolController as PathToolController
import PathScripts.PathToolLibraryManager as PathToolLibraryManager
import sys
from PathScripts.PathPreferences import PathPreferences
@@ -86,6 +87,7 @@ class ViewProvider:
class TaskPanel:
DataObject = QtCore.Qt.ItemDataRole.UserRole
DataProperty = QtCore.Qt.ItemDataRole.UserRole + 1
def __init__(self, vobj, deleteOnReject):
FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Edit Job"))
@@ -94,6 +96,9 @@ class TaskPanel:
self.deleteOnReject = deleteOnReject
self.form = FreeCADGui.PySideUic.loadUi(":/panels/PathEdit.ui")
self.form.toolControllerList.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch)
self.form.toolControllerList.resizeColumnsToContents()
currentPostProcessor = self.obj.PostProcessor
postProcessors = PathPreferences.allEnabledPostProcessors(['', currentPostProcessor])
for post in postProcessors:
@@ -168,6 +173,58 @@ class TaskPanel:
widget.setCurrentIndex(index)
widget.blockSignals(False)
def updateToolController(self):
self.form.toolControllerList.blockSignals(True)
self.form.toolControllerList.clearContents()
self.form.toolControllerList.setRowCount(0)
self.form.activeToolController.blockSignals(True)
index = self.form.activeToolController.currentIndex()
select = None if index == -1 else self.form.activeToolController.itemData(index)
self.form.activeToolController.clear()
for row,tc in enumerate(sorted(self.obj.ToolController, key=lambda tc: tc.Label)):
self.form.activeToolController.addItem(tc.Label, tc)
if tc == select:
index = row
self.form.toolControllerList.insertRow(row)
item = QtGui.QTableWidgetItem(tc.Label)
item.setData(self.DataObject, tc)
item.setData(self.DataProperty, 'Label')
self.form.toolControllerList.setItem(row, 0, item)
item = QtGui.QTableWidgetItem("%d" % tc.ToolNumber)
item.setTextAlignment(QtCore.Qt.AlignRight)
item.setData(self.DataObject, tc)
item.setData(self.DataProperty, 'Number')
self.form.toolControllerList.setItem(row, 1, item)
item = QtGui.QTableWidgetItem("%g" % tc.HorizFeed)
item.setTextAlignment(QtCore.Qt.AlignRight)
item.setData(self.DataObject, tc)
item.setData(self.DataProperty, 'HorizFeed')
self.form.toolControllerList.setItem(row, 2, item)
item = QtGui.QTableWidgetItem("%g" % tc.VertFeed)
item.setTextAlignment(QtCore.Qt.AlignRight)
item.setData(self.DataObject, tc)
item.setData(self.DataProperty, 'VertFeed')
self.form.toolControllerList.setItem(row, 3, item)
item = QtGui.QTableWidgetItem("%s%g" % ('+' if tc.SpindleDir == 'Forward' else '-', tc.SpindleSpeed))
item.setTextAlignment(QtCore.Qt.AlignRight)
item.setData(self.DataObject, tc)
item.setData(self.DataProperty, 'Spindle')
self.form.toolControllerList.setItem(row, 4, item)
if index != -1:
self.form.activeToolController.setCurrentIndex(index)
self.form.activeToolController.blockSignals(False)
self.form.toolControllerList.blockSignals(False)
def setFields(self):
'''sets fields in the form to match the object'''
@@ -194,6 +251,7 @@ class TaskPanel:
if baseindex >= 0:
self.form.infoModel.setCurrentIndex(baseindex)
self.updateToolController()
def setPostProcessorOutputFile(self):
filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Job", "Select Output File"), None, translate("Path_Job", "All Files (*.*)"))
@@ -207,14 +265,80 @@ class TaskPanel:
else:
self.form.operationModify.setEnabled(False)
def operationDelete(self):
for item in self.form.operationsList.selectedItems():
def objectDelete(self, widget):
for item in widget.selectedItems():
obj = item.data(self.DataObject)
if obj.ViewObject and hasattr(obj.ViewObject, 'Proxy') and hasattr(obj.ViewObject.Proxy, 'onDelete'):
obj.ViewObject.Proxy.onDelete(obj.ViewObject, None)
FreeCAD.ActiveDocument.removeObject(obj.Name)
self.setFields()
def operationDelete(self):
self.objectDelete(self.form.operationsList)
def toolControllerSelect(self):
def canDeleteTC(tc):
# if the TC is referenced anywhere but the job we don't want to delete it
return len(tc.InList) == 1
# if anything is selected it can be edited
edit = True if self.form.toolControllerList.selectedItems() else False
self.form.toolControllerEdit.setEnabled(edit)
# can only delete what is selected
delete = edit
# ... but we want to make sure there's at least one TC left
if len(self.obj.ToolController) == len(self.form.toolControllerList.selectedItems()):
delete = False
# ... also don't want to delete any TCs that are already used
if delete:
for item in self.form.toolControllerList.selectedItems():
if not canDeleteTC(item.data(self.DataObject)):
delete = False
break
self.form.toolControllerDelete.setEnabled(delete)
def toolControllerEdit(self):
pass
def toolControllerAdd(self):
PathToolLibraryManager.CommandToolLibraryEdit().edit(self.obj, self.updateToolController)
def toolControllerDelete(self):
self.objectDelete(self.form.toolControllerList)
def toolControllerChanged(self, item):
tc = item.data(self.DataObject)
prop = item.data(self.DataProperty)
if 'Label' == prop:
tc.Label = item.text()
item.setText(tc.Label)
elif 'Number' == prop:
try:
tc.ToolNumber = int(item.text())
except:
pass
item.setText("%d" % tc.ToolNumber)
elif 'Spindle' == prop:
try:
speed = float(item.text())
rot = 'Forward'
if speed < 0:
rot = 'Reverse'
speed = -speed
tc.SpindleDir = rot
tc.SpindleSpeed = speed
except:
pass
item.setText("%s%g" % ('+' if tc.SpindleDir == 'Forward' else '-', tc.SpindleSpeed))
else:
try:
val = FreeCAD.Units.Quantity(item.text())
setattr(tc, prop, val)
except:
pass
item.setText("%g" % getattr(tc, prop).Value)
def setupUi(self):
self.setFields()
@@ -232,7 +356,14 @@ class TaskPanel:
self.form.operationsList.indexesMoved.connect(self.getFields)
self.form.operationDelete.clicked.connect(self.operationDelete)
self.form.toolControllerList.itemSelectionChanged.connect(self.toolControllerSelect)
self.form.toolControllerList.itemChanged.connect(self.toolControllerChanged)
self.form.toolControllerEdit.clicked.connect(self.toolControllerEdit)
self.form.toolControllerDelete.clicked.connect(self.toolControllerDelete)
self.form.toolControllerAdd.clicked.connect(self.toolControllerAdd)
self.operationSelect()
self.toolControllerSelect()
def Create(base, template=None):
'''Create(base, template) ... creates a job instance for the given base object

View File

@@ -150,7 +150,7 @@ class ToolController:
return obj.Tool
class _ViewProviderToolController:
class ViewProvider:
def __init__(self, vobj):
vobj.Proxy = self
@@ -203,6 +203,37 @@ class _ViewProviderToolController:
# this is executed when the user cancels or terminates edit mode
return False
def Create(name = 'Default Tool', tool=None, toolNumber=1, assignViewProvider=True):
PathLog.track(tool, toolNumber)
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
ToolController(obj)
if assignViewProvider:
ViewProvider(obj.ViewObject)
if tool is None:
tool = Path.Tool()
tool.Diameter = 5.0
tool.Name = "Default Tool"
tool.CuttingEdgeHeight = 15.0
tool.ToolType = "EndMill"
tool.Material = "HighSpeedSteel"
obj.Tool = tool
obj.ToolNumber = toolNumber
return obj
def FromTemplate(template, assignViewProvider=True):
PathLog.track()
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", template.get(ToolControllerTemplate.Label))
tc = ToolController(obj)
if assignViewProvider:
ViewProvider(obj.ViewObject)
tc.assignTemplate(obj, template)
return obj
class CommandPathToolController:
def GetResources(self):
@@ -219,41 +250,7 @@ class CommandPathToolController:
def Activated(self):
PathLog.track()
self.Create()
@staticmethod
def Create(assignViewProvider=True, tool=None, toolNumber=1):
PathLog.track("tool: {} with toolNumber: {}".format(tool, toolNumber))
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Default Tool")
PathScripts.PathToolController.ToolController(obj)
if FreeCAD.GuiUp and assignViewProvider:
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
if tool is None:
tool = Path.Tool()
tool.Diameter = 5.0
tool.Name = "Default Tool"
tool.CuttingEdgeHeight = 15.0
tool.ToolType = "EndMill"
tool.Material = "HighSpeedSteel"
obj.Tool = tool
obj.ToolNumber = toolNumber
return obj
@staticmethod
def FromTemplate(template, assignViewProvider=True):
PathLog.track()
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", template.get(ToolControllerTemplate.Label))
tc = PathScripts.PathToolController.ToolController(obj)
if assignViewProvider:
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
tc.assignTemplate(obj, template)
return obj
Create()
class TaskPanel:
def __init__(self):

View File

@@ -335,7 +335,8 @@ class ToolLibraryManager():
class EditorPanel():
def __init__(self):
def __init__(self, job, cb):
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui")
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui")
#self.editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui")
@@ -344,6 +345,8 @@ class EditorPanel():
self.loadTable()
self.form.ToolsList.resizeColumnsToContents()
self.job = job
self.cb = cb
def accept(self):
pass
@@ -545,18 +548,18 @@ class EditorPanel():
for toolnum in tools:
tool = self.TLM.getTool(currList, int(toolnum))
PathLog.debug('tool: {}, toolnum: {}'.format(tool, toolnum))
for job in FreeCAD.ActiveDocument.findObjects("Path::Feature"):
if isinstance(job.Proxy, PathScripts.PathJob.ObjectJob) and job.Label == targetlist:
label = "T{}: {}".format(toolnum, tool.Name)
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython",label)
PathScripts.PathToolController.ToolController(obj)
PathScripts.PathToolController._ViewProviderToolController(obj.ViewObject)
PathUtils.addToJob(obj, job.Name)
FreeCAD.activeDocument().recompute()
obj.Tool = tool.copy()
obj.ToolNumber = int(toolnum)
#obj.recompute()
if self.job:
label = "T{}: {}".format(toolnum, tool.Name)
tc = PathScripts.PathToolController.Create(label, tool=tool, toolNumber=int(toolnum))
self.job.Proxy.addToolController(tc)
else:
for job in FreeCAD.ActiveDocument.findObjects("Path::Feature"):
if isinstance(job.Proxy, PathScripts.PathJob.ObjectJob) and job.Label == targetlist:
label = "T{}: {}".format(toolnum, tool.Name)
tc = PathScripts.PathToolController.Create(label, tool=tool, toolNumber=int(toolnum))
job.Proxy.addToolController(tc)
if self.cb:
self.cb()
FreeCAD.ActiveDocument.recompute()
def getStandardButtons(self):
@@ -579,8 +582,8 @@ class EditorPanel():
self.setFields()
class CommandToolLibraryEdit():
def edit(self):
editor = EditorPanel()
def edit(self, job=None, cb=None):
editor = EditorPanel(job, cb)
editor.setupUi()
r = editor.form.exec_()