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