| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from lazy_loader.lazy_loader import LazyLoader |
| from PySide import QtCore, QtGui |
| from PySide.QtCore import QT_TRANSLATE_NOOP |
| import FreeCAD |
| import FreeCADGui |
| import Path |
| import Path.Base.Gui.Util as PathGuiUtil |
| import Path.Base.Util as PathUtil |
| import Path.Tool.Controller as PathToolController |
| from Path.Tool.toolbit.ui.selector import ToolBitSelector |
|
|
| Part = LazyLoader("Part", globals(), "Part") |
|
|
|
|
| if False: |
| Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule()) |
| Path.Log.trackModule(Path.Log.thisModule()) |
| else: |
| Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule()) |
|
|
| translate = FreeCAD.Qt.translate |
|
|
|
|
| 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("ShapeAppearance", mode) |
| vobj.setEditorMode("Transparency", mode) |
| vobj.setEditorMode("Visibility", mode) |
| self.vobj = vobj |
|
|
| def dumps(self): |
| return None |
|
|
| def loads(self, state): |
| return None |
|
|
| def getIcon(self): |
| return ":/icons/CAM_ToolController.svg" |
|
|
| def onChanged(self, vobj, prop): |
| 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) |
|
|
| def onDelete(self, vobj, args=None): |
| PathUtil.clearExpressionEngine(vobj.Object) |
| self.vobj.Object.Proxy.onDelete(vobj.Object, args) |
| return True |
|
|
| def updateData(self, vobj, prop): |
| |
| pass |
|
|
| def setEdit(self, vobj=None, mode=0): |
| if 0 == mode: |
| if vobj is None: |
| vobj = self.vobj |
| FreeCADGui.Control.closeDialog() |
| taskd = TaskPanel(vobj.Object) |
| FreeCADGui.Control.showDialog(taskd) |
| taskd.setupUi() |
|
|
| FreeCAD.ActiveDocument.recompute() |
|
|
| return True |
| return False |
|
|
| def unsetEdit(self, vobj, mode): |
| |
| return False |
|
|
| def setupContextMenu(self, vobj, menu): |
| Path.Log.track() |
| for action in menu.actions(): |
| menu.removeAction(action) |
| action = QtGui.QAction(translate("CAM", "Edit"), menu) |
| action.triggered.connect(self._editInContextMenuTriggered) |
| menu.addAction(action) |
|
|
| def _editInContextMenuTriggered(self, checked): |
| self.setEdit() |
|
|
| def claimChildren(self): |
| obj = self.vobj.Object |
| if obj and obj.Proxy and obj.Tool: |
| return [obj.Tool] |
| return [] |
|
|
|
|
| def Create(name="Default Tool", tool=None, toolNumber=1): |
| Path.Log.track(tool, toolNumber) |
|
|
| obj = PathToolController.Create(name, tool, toolNumber) |
| ViewProvider(obj.ViewObject) |
| |
| if tool and tool.ViewObject and tool.ViewObject.Visibility: |
| tool.ViewObject.Visibility = False |
| return obj |
|
|
|
|
| class CommandPathToolController(object): |
| def GetResources(self): |
| return { |
| "Pixmap": "CAM_LengthOffset", |
| "MenuText": QT_TRANSLATE_NOOP("CAM_ToolController", "Tool Controller"), |
| "ToolTip": QT_TRANSLATE_NOOP( |
| "CAM_ToolController", "Adds a new tool controller to the active job" |
| ), |
| } |
|
|
| def selectedJob(self): |
| if FreeCAD.ActiveDocument: |
| sel = FreeCADGui.Selection.getSelectionEx() |
| 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"] |
| if 1 == len(jobs): |
| return jobs[0] |
| return None |
|
|
| def IsActive(self): |
| return self.selectedJob() is not None |
|
|
| def Activated(self): |
| Path.Log.track() |
| job = self.selectedJob() |
| if not job: |
| return |
|
|
| |
| selector = ToolBitSelector() |
| if not selector.exec_(): |
| return |
| tool = selector.get_selected_tool() |
| if not tool: |
| return |
|
|
| |
| toolNr = None |
| for tc in job.Tools.Group: |
| if tc.Tool == tool: |
| toolNr = tc.ToolNumber |
| break |
| if not toolNr: |
| toolNr = max([tc.ToolNumber for tc in job.Tools.Group]) + 1 |
|
|
| |
| tc = Create("TC: {}".format(tool.Label), tool, toolNr) |
| job.Proxy.addToolController(tc) |
| FreeCAD.ActiveDocument.recompute() |
|
|
|
|
| class BlockScrollWheel(QtCore.QObject): |
| def eventFilter(self, obj, event): |
| if event.type() == QtCore.QEvent.Type.Wheel: |
| if not obj.hasFocus(): |
| return True |
| return super().eventFilter(obj, event) |
|
|
|
|
| class ToolControllerEditor(object): |
|
|
| def __init__( |
| self, obj, asDialog, notifyChanged=None, showCountLabel=False, disableToolNumber=False |
| ): |
| self.notifyChanged = notifyChanged |
| self.form = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolControllerEdit.ui") |
| self.controller = FreeCADGui.PySideUic.loadUi(":/panels/ToolControllerEdit.ui") |
| self.form.tc_layout.addWidget(self.controller) |
| if not asDialog: |
| self.form.buttonBox.hide() |
| if not showCountLabel: |
| self.controller.tcOperationCountLabel.hide() |
| self.obj = obj |
|
|
| comboToPropertyMap = [("spindleDirection", "SpindleDir")] |
| enumTups = PathToolController.ToolController.propertyEnumerations(dataType="raw") |
|
|
| PathGuiUtil.populateCombobox(self.controller, enumTups, comboToPropertyMap) |
| self.vertFeed = PathGuiUtil.QuantitySpinBox(self.controller.vertFeed, obj, "VertFeed") |
| self.horizFeed = PathGuiUtil.QuantitySpinBox(self.controller.horizFeed, obj, "HorizFeed") |
| self.leadInFeed = PathGuiUtil.QuantitySpinBox(self.controller.leadInFeed, obj, "LeadInFeed") |
| self.leadOutFeed = PathGuiUtil.QuantitySpinBox( |
| self.controller.leadOutFeed, obj, "LeadOutFeed" |
| ) |
| self.rampFeed = PathGuiUtil.QuantitySpinBox(self.controller.rampFeed, obj, "RampFeed") |
| self.vertRapid = PathGuiUtil.QuantitySpinBox(self.controller.vertRapid, obj, "VertRapid") |
| self.horizRapid = PathGuiUtil.QuantitySpinBox(self.controller.horizRapid, obj, "HorizRapid") |
|
|
| self.blockScrollWheel = BlockScrollWheel() |
| self.controller.tcNumber.installEventFilter(self.blockScrollWheel) |
| self.controller.spindleDirection.installEventFilter(self.blockScrollWheel) |
| self.controller.tcNumber.setReadOnly(disableToolNumber) |
|
|
| self.editor = None |
|
|
| def selectInComboBox(self, name, combo): |
| """selectInComboBox(name, combo) ... |
| helper function to select a specific value in a combo box.""" |
| try: |
| combo.blockSignals(True) |
| index = combo.currentIndex() |
|
|
| |
| newindex = combo.findData(name) |
| if newindex >= 0: |
| combo.setCurrentIndex(newindex) |
| return |
|
|
| |
| newindex = combo.findText(name, QtCore.Qt.MatchFixedString) |
| if newindex >= 0: |
| combo.setCurrentIndex(newindex) |
| return |
|
|
| |
| combo.setCurrentIndex(index) |
| finally: |
| combo.blockSignals(False) |
|
|
| def updateUi(self): |
| tc = self.obj |
|
|
| blockObjects = [ |
| self.controller.tcName, |
| self.controller.tcNumber, |
| self.horizFeed.widget, |
| self.horizRapid.widget, |
| self.leadInFeed.widget, |
| self.leadOutFeed.widget, |
| self.rampFeed.widget, |
| self.vertFeed.widget, |
| self.vertRapid.widget, |
| self.controller.spindleSpeed, |
| self.controller.spindleDirection, |
| ] |
| try: |
| for obj in blockObjects: |
| obj.blockSignals(True) |
|
|
| self.controller.tcName.setText(tc.Label) |
| self.controller.tcNumber.setValue(tc.ToolNumber) |
| self.horizFeed.updateWidget() |
| self.horizRapid.updateWidget() |
| self.leadInFeed.updateWidget() |
| self.leadOutFeed.updateWidget() |
| self.rampFeed.updateWidget() |
| self.vertFeed.updateWidget() |
| self.vertRapid.updateWidget() |
| self.controller.spindleSpeed.setValue(tc.SpindleSpeed) |
|
|
| self.selectInComboBox(tc.SpindleDir, self.controller.spindleDirection) |
|
|
| if self.editor: |
| self.editor.updateUI() |
| finally: |
| for obj in blockObjects: |
| obj.blockSignals(False) |
|
|
| def updateToolController(self): |
| tc = self.obj |
| try: |
| tc.Label = self.controller.tcName.text() |
| tc.ToolNumber = self.controller.tcNumber.value() |
| self.horizFeed.updateProperty() |
| self.vertFeed.updateProperty() |
| self.leadInFeed.updateProperty() |
| self.leadOutFeed.updateProperty() |
| self.rampFeed.updateProperty() |
| self.horizRapid.updateProperty() |
| self.vertRapid.updateProperty() |
| tc.SpindleSpeed = self.controller.spindleSpeed.value() |
| tc.SpindleDir = self.controller.spindleDirection.currentData() |
|
|
| if self.editor: |
| self.editor.updateTool() |
| tc.Tool = self.editor.tool |
|
|
| except Exception as e: |
| Path.Log.error("Error updating TC: {}".format(e)) |
|
|
| def changed(self): |
| self.form.blockSignals(True) |
| self.controller.blockSignals(True) |
| self.updateToolController() |
| self.updateUi() |
| self.controller.blockSignals(False) |
| self.form.blockSignals(False) |
|
|
| if self.notifyChanged: |
| self.notifyChanged() |
|
|
| def setupUi(self): |
| if self.editor: |
| self.editor.setupUI() |
|
|
| self.controller.tcName.textChanged.connect(self.changed) |
| self.controller.tcNumber.editingFinished.connect(self.changed) |
| self.vertFeed.widget.textChanged.connect(self.changed) |
| self.horizFeed.widget.textChanged.connect(self.changed) |
| self.leadInFeed.widget.textChanged.connect(self.changed) |
| self.leadOutFeed.widget.textChanged.connect(self.changed) |
| self.rampFeed.widget.textChanged.connect(self.changed) |
| self.vertRapid.widget.textChanged.connect(self.changed) |
| self.horizRapid.widget.textChanged.connect(self.changed) |
| self.controller.spindleSpeed.editingFinished.connect(self.changed) |
| self.controller.spindleDirection.currentIndexChanged.connect(self.changed) |
|
|
|
|
| class TaskPanel: |
| def __init__(self, obj): |
| self.editor = ToolControllerEditor(obj, False) |
| self.form = self.editor.form |
| self.updating = False |
| self.toolrep = None |
| self.obj = obj |
|
|
| def accept(self): |
| self.getFields() |
|
|
| FreeCADGui.ActiveDocument.resetEdit() |
| FreeCADGui.Control.closeDialog() |
| if self.toolrep: |
| FreeCAD.ActiveDocument.removeObject(self.toolrep.Name) |
| FreeCAD.ActiveDocument.recompute() |
|
|
| def reject(self): |
| FreeCADGui.Control.closeDialog() |
| if self.toolrep: |
| FreeCAD.ActiveDocument.removeObject(self.toolrep.Name) |
| FreeCAD.ActiveDocument.recompute() |
|
|
| def getFields(self): |
| self.editor.updateToolController() |
| self.obj.Proxy.execute(self.obj) |
|
|
| def setFields(self): |
| self.editor.updateUi() |
|
|
| if self.toolrep: |
| tool = self.obj.Tool |
| radius = float(tool.Diameter) / 2 |
| length = tool.CuttingEdgeHeight |
| t = Part.makeCylinder(radius, length) |
| self.toolrep.Shape = t |
|
|
| def edit(self, item, column): |
| if not self.updating: |
| self.resetObject() |
|
|
| def resetObject(self, remove=None): |
| "transfers the values from the widget to the object" |
| FreeCAD.ActiveDocument.recompute() |
|
|
| def setupUi(self): |
| if self.editor.editor: |
| t = Part.makeCylinder(1, 1) |
| self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature", "tool") |
| self.toolrep.Shape = t |
|
|
| self.setFields() |
| self.editor.setupUi() |
|
|
|
|
| class DlgToolControllerEdit: |
| def __init__(self, obj): |
| self.editor = ToolControllerEditor(obj, True) |
| self.editor.updateUi() |
| self.editor.setupUi() |
| self.obj = obj |
|
|
| def exec_(self): |
| restoreTC = self.obj.Proxy.templateAttrs(self.obj) |
|
|
| rc = False |
| if not self.editor.form.exec_(): |
| Path.Log.info("revert") |
| self.obj.Proxy.setFromTemplate(self.obj, restoreTC) |
| rc = True |
| else: |
| self.editor.updateToolController() |
| self.obj.Proxy.execute(self.obj) |
| return rc |
|
|
|
|
| if FreeCAD.GuiUp: |
| |
| FreeCADGui.addCommand("CAM_ToolController", CommandPathToolController()) |
|
|
| FreeCAD.Console.PrintLog("Loading PathToolControllerGui… done\n") |
|
|