From cf8c0fadd140fd42dca7ea598e3368f879eb7134 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Wed, 4 Sep 2019 22:56:28 -0700 Subject: [PATCH] Basic editor and shape update. --- src/Mod/Path/CMakeLists.txt | 1 + src/Mod/Path/Gui/Resources/Path.qrc | 1 + .../Gui/Resources/panels/ToolBitEditor.ui | 170 +++++++++++++++ src/Mod/Path/PathScripts/PathGui.py | 37 +--- src/Mod/Path/PathScripts/PathMillFace.py | 5 +- src/Mod/Path/PathScripts/PathSetupSheetGui.py | 4 +- .../PathScripts/PathSetupSheetOpPrototype.py | 41 ++-- .../PathSetupSheetOpPrototypeGui.py | 34 ++- src/Mod/Path/PathScripts/PathToolBit.py | 202 ++++++++++++++++++ src/Mod/Path/PathScripts/PathToolBitEdit.py | 127 +++++++++++ src/Mod/Path/PathScripts/PathToolBitGui.py | 153 +++++++++++++ src/Mod/Path/PathScripts/PathUtil.py | 42 +++- .../Path/Tools/Template/drill-straight.fcstd | Bin 10098 -> 10158 bytes .../Tools/Template/endmill-straight.fcstd | Bin 10496 -> 10501 bytes src/Mod/Path/Tools/Template/v-bit.fcstd | Bin 11847 -> 11989 bytes 15 files changed, 746 insertions(+), 71 deletions(-) create mode 100644 src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui create mode 100644 src/Mod/Path/PathScripts/PathToolBit.py create mode 100644 src/Mod/Path/PathScripts/PathToolBitEdit.py create mode 100644 src/Mod/Path/PathScripts/PathToolBitGui.py diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 83937b084fb5..15d65c9db1c2 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -101,6 +101,7 @@ SET(PathScripts_SRCS PathScripts/PathStop.py PathScripts/PathSurface.py PathScripts/PathSurfaceGui.py + PathScripts/PathToolBitEdit.py PathScripts/PathToolController.py PathScripts/PathToolControllerGui.py PathScripts/PathToolEdit.py diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc index 19246750dfb8..e6eae76dbc8c 100644 --- a/src/Mod/Path/Gui/Resources/Path.qrc +++ b/src/Mod/Path/Gui/Resources/Path.qrc @@ -107,6 +107,7 @@ panels/PointEdit.ui panels/SetupGlobal.ui panels/SetupOp.ui + panels/ToolBitEditor.ui panels/ToolEditor.ui panels/ToolLibraryEditor.ui panels/TaskPathSimulator.ui diff --git a/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui new file mode 100644 index 000000000000..06b0ccad458c --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/ToolBitEditor.ui @@ -0,0 +1,170 @@ + + + Form + + + + 0 + 0 + 411 + 886 + + + + Form + + + + + + Tool Bit + + + + + + Name + + + + + + + 50 + + + Display Name + + + + + + + Type + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + ... + + + + + + + + + + + + + Bit Parameter + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Point/Tip Angle + + + + + + + 180° + + + ° + + + + + + + Cutting Edge Height + + + + + + + 0.00 + + + mm + + + + + + + + + + + + + + 210 + 297 + + + + Image + + + Qt::AlignCenter + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Gui::InputField + QLineEdit +
Gui/InputField.h
+
+
+ + +
diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index ed2e9e757d2e..98cf98810618 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -25,6 +25,7 @@ import FreeCAD import PathScripts.PathGeom as PathGeom import PathScripts.PathLog as PathLog +import PathScripts.PathUtil as PathUtil import PySide @@ -44,34 +45,6 @@ def translate(context, text, disambig=None): else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -def _getProperty(obj, prop): - o = obj - attr = obj - name = None - for name in prop.split('.'): - o = attr - if not hasattr(o, name): - break - attr = getattr(o, name) - - if o == attr: - PathLog.warning(translate('PathGui', "%s has no property %s (%s))") % (obj.Label, prop, name)) - return (None, None, None) - - #PathLog.debug("found property %s of %s (%s: %s)" % (prop, obj.Label, name, attr)) - return(o, attr, name) - -def getProperty(obj, prop): - '''getProperty(obj, prop) ... answer obj's property defined by its canonical name.''' - o, attr, name = _getProperty(obj, prop) # pylint: disable=unused-variable - return attr - -def setProperty(obj, prop, value): - '''setProperty(obj, prop, value) ... set the property value of obj's property defined by its canonical name.''' - o, attr, name = _getProperty(obj, prop) # pylint: disable=unused-variable - if o and name: - setattr(o, name, value) - def updateInputField(obj, prop, widget, onBeforeChange=None): '''updateInputField(obj, prop, widget) ... update obj's property prop with the value of widget. The property's value is only assigned if the new value differs from the current value. @@ -82,13 +55,13 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): Returns True if a new value was assigned, False otherwise (new value is the same as the current). ''' value = FreeCAD.Units.Quantity(widget.text()).Value - attr = getProperty(obj, prop) + attr = PathUtil.getProperty(obj, prop) attrValue = attr.Value if hasattr(attr, 'Value') else attr if not PathGeom.isRoughly(attrValue, value): PathLog.debug("updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, attr, value)) if onBeforeChange: onBeforeChange(obj) - setProperty(obj, prop, value) + PathUtil.setProperty(obj, prop, value) return True return False @@ -107,7 +80,7 @@ def __init__(self, widget, obj, prop, onBeforeChange=None): self.widget = widget self.prop = prop self.onBeforeChange = onBeforeChange - attr = getProperty(self.obj, self.prop) + attr = PathUtil.getProperty(self.obj, self.prop) if attr is not None: if hasattr(attr, 'Value'): widget.setProperty('unit', attr.getUserPreferred()[2]) @@ -134,7 +107,7 @@ def updateSpinBox(self, quantity=None): quantity can be of type Quantity or Float.''' if self.valid: if quantity is None: - quantity = getProperty(self.obj, self.prop) + quantity = PathUtil.getProperty(self.obj, self.prop) value = quantity.Value if hasattr(quantity, 'Value') else quantity self.widget.setProperty('rawValue', value) diff --git a/src/Mod/Path/PathScripts/PathMillFace.py b/src/Mod/Path/PathScripts/PathMillFace.py index 362fd18d17fe..cb6c02f08077 100644 --- a/src/Mod/Path/PathScripts/PathMillFace.py +++ b/src/Mod/Path/PathScripts/PathMillFace.py @@ -80,7 +80,8 @@ def areaOpOnChanged(self, obj, prop): # default depths calculation not correct for facing if prop == "Base": job = PathUtils.findParentJob(obj) - obj.OpStartDepth = job.Stock.Shape.BoundBox.ZMax + if job: + obj.OpStartDepth = job.Stock.Shape.BoundBox.ZMax if len(obj.Base) >= 1: print('processing') @@ -95,7 +96,7 @@ def areaOpOnChanged(self, obj, prop): # Otherwise, top of part. obj.OpFinalDepth = Part.makeCompound(sublist).BoundBox.ZMax - else: + elif job: obj.OpFinalDepth = job.Proxy.modelBoundBox(job).ZMax def areaOpShapes(self, obj): diff --git a/src/Mod/Path/PathScripts/PathSetupSheetGui.py b/src/Mod/Path/PathScripts/PathSetupSheetGui.py index 1537f870c267..5b5a75b2d65f 100644 --- a/src/Mod/Path/PathScripts/PathSetupSheetGui.py +++ b/src/Mod/Path/PathScripts/PathSetupSheetGui.py @@ -306,9 +306,9 @@ def accept(self): def getFields(self): def updateExpression(name, widget): value = str(widget.text()) - val = PathGui.getProperty(self.obj, name) + val = PathUtil.getProperty(self.obj, name) if val != value: - PathGui.setProperty(self.obj, name, value) + PathUtil.setProperty(self.obj, name, value) updateExpression('StartDepthExpression', self.form.setupStartDepthExpr) updateExpression('FinalDepthExpression', self.form.setupFinalDepthExpr) diff --git a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py index 146d70821ab9..8c5c3e4b8d77 100644 --- a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py +++ b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototype.py @@ -106,6 +106,10 @@ def displayString(self): return Property.displayString(self) return self.value.getUserPreferred()[0] +class PropertyAngle(PropertyQuantity): + def typeString(self): + return "Angle" + class PropertyDistance(PropertyQuantity): def typeString(self): return "Distance" @@ -137,24 +141,25 @@ def typeString(self): class OpPrototype(object): PropertyType = { - 'App::PropertyBool': PropertyBool, - 'App::PropertyDistance': PropertyDistance, - 'App::PropertyEnumeration': PropertyEnumeration, - 'App::PropertyFloat': PropertyFloat, - 'App::PropertyFloatConstraint': Property, - 'App::PropertyFloatList': Property, - 'App::PropertyInteger': PropertyInteger, - 'App::PropertyIntegerList': PropertyInteger, - 'App::PropertyLength': PropertyLength, - 'App::PropertyLink': Property, - 'App::PropertyLinkList': Property, - 'App::PropertyLinkSubListGlobal': Property, - 'App::PropertyPercent': PropertyPercent, - 'App::PropertyString': PropertyString, - 'App::PropertyStringList': Property, - 'App::PropertyVectorDistance': Property, - 'App::PropertyVectorList': Property, - 'Part::PropertyPartShape': Property, + 'App::PropertyAngle': PropertyAngle, + 'App::PropertyBool': PropertyBool, + 'App::PropertyDistance': PropertyDistance, + 'App::PropertyEnumeration': PropertyEnumeration, + 'App::PropertyFloat': PropertyFloat, + 'App::PropertyFloatConstraint': Property, + 'App::PropertyFloatList': Property, + 'App::PropertyInteger': PropertyInteger, + 'App::PropertyIntegerList': PropertyInteger, + 'App::PropertyLength': PropertyLength, + 'App::PropertyLink': Property, + 'App::PropertyLinkList': Property, + 'App::PropertyLinkSubListGlobal': Property, + 'App::PropertyPercent': PropertyPercent, + 'App::PropertyString': PropertyString, + 'App::PropertyStringList': Property, + 'App::PropertyVectorDistance': Property, + 'App::PropertyVectorList': Property, + 'Part::PropertyPartShape': Property, } def __init__(self, name): diff --git a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototypeGui.py b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototypeGui.py index c215d0057d08..f89b7b40ed96 100644 --- a/src/Mod/Path/PathScripts/PathSetupSheetOpPrototypeGui.py +++ b/src/Mod/Path/PathScripts/PathSetupSheetOpPrototypeGui.py @@ -112,6 +112,21 @@ def setEditorData(self, widget): def setModelData(self, widget): self.prop.setValue(widget.text()) +class _PropertyAngleEditor(_PropertyEditor): + '''Editor for angle values - uses a line edit''' + + def widget(self, parent): + return QtGui.QLineEdit(parent) + + def setEditorData(self, widget): + quantity = self.prop.getValue() + if quantity is None: + quantity = FreeCAD.Units.Quantity(0, FreeCAD.Units.Angle) + widget.setText(quantity.getUserPreferred()[0]) + + def setModelData(self, widget): + self.prop.setValue(FreeCAD.Units.Quantity(widget.text())) + class _PropertyLengthEditor(_PropertyEditor): '''Editor for length values - uses a line edit.''' @@ -174,15 +189,16 @@ def setModelData(self, widget): self.prop.setValue(widget.value()) _EditorFactory = { - PathSetupSheetOpPrototype.Property: None, - 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): diff --git a/src/Mod/Path/PathScripts/PathToolBit.py b/src/Mod/Path/PathScripts/PathToolBit.py new file mode 100644 index 000000000000..03f400f44965 --- /dev/null +++ b/src/Mod/Path/PathScripts/PathToolBit.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2019 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import Part +import PathScripts.PathGeom as PathGeom +import PathScripts.PathLog as PathLog +import PathScripts.PathSetupSheetOpPrototype as PathSetupSheetOpPrototype +import PathScripts.PathUtil as PathUtil +import PySide +import Sketcher +import math +import zipfile + +__title__ = "Tool bits." +__author__ = "sliptonic (Brad Collette)" +__url__ = "http://www.freecadweb.org" +__doc__ = "Class to deal with and represent a tool bit." + +PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.trackModule() + +def translate(context, text, disambig=None): + return PySide.QtCore.QCoreApplication.translate(context, text, disambig) + +ParameterTypeConstraint = { + 'Angle': 'App::PropertyAngle', + 'Distance': 'App::PropertyLength', + 'DistanceX': 'App::PropertyLength', + 'DistanceY': 'App::PropertyLength', + 'Radius': 'App::PropertyLength' + } + + +def updateConstraint(sketch, name, value): + for i, constraint in enumerate(sketch.Constraints): + if constraint.Name.split(';')[0] == name: + if constraint.Type in ['DistanceX', 'DistanceY', 'Distance', 'Radius']: + if not PathGeom.isRoughly(constraint.Value, value.Value): + PathLog.track(name, constraint.Type, 'update', i) + constr = Sketcher.Constraint(constraint.Type, constraint.First, value) + sketch.delConstraint(i) + sketch.recompute() + n = sketch.addConstraint(constr) + sketch.renameConstraint(n, constraint.Name) + else: + PathLog.track(name, constraint.Type, 'unchanged') + else: + print(constraint.Name, constraint.Type) + break + +PropertyGroupBit = 'Bit' + +class ToolBit(object): + + def __init__(self, obj, templateFile): + PathLog.track(obj.Label, templateFile) + self.obj = obj + obj.addProperty('App::PropertyFile', 'BitTemplate', 'Base', translate('PathToolBit', 'Template for bit shape')) + obj.addProperty('App::PropertyLink', 'BitBody', 'Base', translate('PathToolBit', 'The parametrized body representing the tool bit')) + if templateFile is not None: + obj.BitTemplate = templateFile + self._setupBitFromTemplate(obj) + self.onDocumentRestored(obj) + + def __getstate__(self): + return None + + def __setstate__(self, state): + for obj in FreeCAD.ActiveDocument.Objects: + if hasattr(obj, 'Proxy') and obj.Proxy == self: + self.obj = obj + break + return None + + def bitPropertyNames(self, obj): + return [prop for prop in obj.PropertiesList if obj.getGroupOfProperty(prop) == PropertyGroupBit] + + def onDocumentRestored(self, obj): + obj.setEditorMode('BitTemplate', 1) + obj.setEditorMode('BitBody', 2) + obj.setEditorMode('Shape', 2) + + for prop in self.bitPropertyNames(obj): + obj.setEditorMode(prop, 1) + + def onChanged(self, obj, prop): + PathLog.track(obj.Label, prop) + if prop == 'BitTemplate' and not 'Restore' in obj.State: + self._setupBitFromTemplate(obj) + #elif obj.getGroupOfProperty(prop) == PropertyGroupBit: + # self._updateBitShape(obj, [prop]) + + def _updateBitShape(self, obj, properties=None): + if not properties: + properties = self.bitPropertyNames(obj) + for prop in properties: + for sketch in [o for o in obj.BitBody.Group if o.TypeId == 'Sketcher::SketchObject']: + PathLog.track(obj.Label, sketch.Label, prop) + updateConstraint(sketch, prop, obj.getPropertyByName(prop)) + self._copyBitShape(obj) + + def _copyBitShape(self, obj): + obj.Document.recompute() + if obj.BitBody and obj.BitBody.Shape: + obj.Shape = obj.BitBody.Shape + else: + obj.Shape = Part.Shape() + + def _loadBitBody(self, obj, path=None): + if not path: + path = obj.BitTemplate + docOpened = False + doc = None + for d in FreeCAD.listDocuments(): + if FreeCAD.getDocument(d).FileName == path: + doc = FreeCAD.getDocument(d) + break + if doc is None: + doc = FreeCAD.open(path) + docOpened = True + return (doc, docOpened) + + def _removeBitBody(self, obj): + if obj.BitBody: + obj.BitBody.removeObjectsFromDocument() + obj.Document.removeObject(obj.BitBody.Name) + obj.BitBody = None + + def _deleteBitSetup(self, obj): + PathLog.track(obj.Label) + self._removeBitBody(obj) + self._copyBitShape(obj) + for prop in self.bitPropertyNames(obj): + obj.removeProperty(prop) + + def _setupBitFromTemplate(self, obj, path=None): + (doc, docOpened) = self._loadBitBody(obj, path) + + obj.Label = doc.RootObjects[0].Label + self._deleteBitSetup(obj) + obj.BitBody = obj.Document.copyObject(doc.RootObjects[0], True) + if docOpened: + FreeCAD.closeDocument(doc.Name) + + if obj.BitBody.ViewObject: + obj.BitBody.ViewObject.Visibility = False + self._copyBitShape(obj) + + for sketch in [o for o in obj.BitBody.Group if o.TypeId == 'Sketcher::SketchObject']: + for constraint in [c for c in sketch.Constraints if c.Name != '']: + typ = ParameterTypeConstraint.get(constraint.Type) + PathLog.track(constraint, typ) + if typ is not None: + parts = [p.strip() for p in constraint.Name.split(';')] + prop = parts[0] + desc = '' + if len(parts) > 1: + desc = parts[1] + obj.addProperty(typ, prop, PropertyGroupBit, desc) + value = constraint.Value + if constraint.Type == 'Angle': + value = value * 180 / math.pi + PathUtil.setProperty(obj, prop, constraint.Value) + + def getBitThumbnail(self, obj): + if obj.BitTemplate: + with open(obj.BitTemplate, 'rb') as fd: + zf = zipfile.ZipFile(fd) + pf = zf.open('thumbnails/Thumbnail.png', 'r') + data = pf.read() + pf.close() + return data + else: + return None + + +def Create(name = 'ToolBit', templateFile=None): + obj = FreeCAD.ActiveDocument.addObject('Part::FeaturePython', name) + obj.Proxy = ToolBit(obj, templateFile) + return obj diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py new file mode 100644 index 000000000000..f2fe5525801c --- /dev/null +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2019 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +import PathScripts.PathGui as PathGui +import PathScripts.PathLog as PathLog +import PathScripts.PathToolBit as PathToolBit +import copy +import math +import re + +from PySide import QtGui + +PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.trackModule(PathLog.thisModule()) + + +ParameterTypeConstraint = { + 'Angle': 'Angle', + 'Distance': 'Length', + 'DistanceX': 'Length', + 'DistanceY': 'Length', + 'Radius': 'Length' + } + +ParameterTypeProperty = { + 'Length': 'App::PropertyLength', + 'Angle': 'App::PropertyAngle' + } + +class ToolBitEditor: + '''UI and controller for editing a ToolBit. + The controller embeds the UI to the parentWidget which has to have a layout attached to it. + ''' + + def __init__(self, tool, parentWidget=None): + self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitEditor.ui") + + if parentWidget: + self.form.setParent(parentWidget) + parentWidget.layout().addWidget(self.form) + + self.tool = tool + if not tool.BitTemplate: + self.tool.BitTemplate = 'src/Mod/Path/Tools/Template/endmill-straight.fcstd' + self.setupTool(self.tool) + + def setupTool(self, tool): + layout = self.form.bitParams.layout() + for i in range(layout.rowCount() - 1, -1, -1): + layout.removeRow(i) + editor = {} + ui = FreeCADGui.UiLoader() + for name in tool.PropertiesList: + if tool.getGroupOfProperty(name) == PathToolBit.PropertyGroupBit: + qsb = ui.createWidget('Gui::QuantitySpinBox') + editor[name] = PathGui.QuantitySpinBox(qsb, tool, name) + label = QtGui.QLabel(re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', name))) + #if parameter.get('Desc'): + # qsb.setToolTip(parameter['Desc']) + layout.addRow(label, qsb) + self.bitEditor = editor + + def accept(self): + self.refresh() + + def reject(self): + pass + + def updateUI(self): + PathLog.track() + self.form.toolName.setText(self.tool.Label) + self.form.templatePath.setText(self.tool.BitTemplate) + + for editor in self.bitEditor: + self.bitEditor[editor].updateSpinBox() + + def updateTemplate(self): + self.tool.BitTemplate = str(self.form.templatePath.text()) + self.setupTool(self.tool) + + def updateTool(self): + PathLog.track() + self.tool.Label = str(self.form.toolName.text()) + self.tool.BitTemplate = str(self.form.templatePath.text()) + + for editor in self.bitEditor: + self.bitEditor[editor].updateProperty() + + self.tool.Proxy._updateBitShape(self.tool) + + def refresh(self): + PathLog.track() + self.form.blockSignals(True) + self.updateTool() + self.updateUI() + self.form.blockSignals(False) + + def setupUI(self): + PathLog.track() + self.updateUI() + + self.form.toolName.editingFinished.connect(self.refresh) + self.form.templatePath.editingFinished.connect(self.updateTemplate) diff --git a/src/Mod/Path/PathScripts/PathToolBitGui.py b/src/Mod/Path/PathScripts/PathToolBitGui.py new file mode 100644 index 000000000000..cec2d869800a --- /dev/null +++ b/src/Mod/Path/PathScripts/PathToolBitGui.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2019 sliptonic * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import PathScripts.PathGui as PathGui +import PathScripts.PathIconViewProvider as PathIconViewProvider +import PathScripts.PathLog as PathLog +import PathScripts.PathToolBit as PathToolBit +import PathScripts.PathToolBitEdit as PathToolBitEdit +import PathScripts.PathUtil as PathUtil + +from PySide import QtCore, QtGui + +__title__ = "Tool Bit UI" +__author__ = "sliptonic (Brad Collette)" +__url__ = "http://www.freecadweb.org" +__doc__ = "Task panel editor for a ToolBit" + +# Qt translation handling +def translate(context, text, disambig=None): + return QtCore.QCoreApplication.translate(context, text, disambig) + +PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.trackModule(PathLog.thisModule()) + +class ViewProvider(object): + '''ViewProvider for a ToolBit. + It's sole job is to provide an icon and invoke the TaskPanel on edit.''' + + def __init__(self, vobj, name): + PathLog.track(name, vobj.Object) + self.icon = name + self.obj = vobj.Object + self.vobj = vobj + vobj.Proxy = self + + def attach(self, vobj): + PathLog.track(vobj.Object) + self.vobj = vobj + self.obj = vobj.Object + + def getIcon(self): + png = self.obj.Proxy.getBitThumbnail(self.obj) + if png: + pixmap = QtGui.QPixmap() + pixmap.loadFromData(png, "PNG") + return QtGui.QIcon(pixmap) + return ':/icons/Path-ToolChange.svg' + + def __getstate__(self): + return None + + def __setstate__(self, state): + # pylint: disable=unused-argument + return None + + def getDisplayMode(self, mode): + # pylint: disable=unused-argument + return 'Default' + + def setEdit(self, vobj, mode=0): + # pylint: disable=unused-argument + PathLog.track() + taskPanel = TaskPanel(vobj) + FreeCADGui.Control.closeDialog() + FreeCADGui.Control.showDialog(taskPanel) + taskPanel.setupUi() + return True + + def unsetEdit(self, vobj, mode): + # pylint: disable=unused-argument + FreeCADGui.Control.closeDialog() + return + + def claimChildren(self): + if self.obj.BitBody: + return [self.obj.BitBody] + return [] + + def doubleClicked(self, vobj): + self.setEdit(vobj) + +class TaskPanel: + '''TaskPanel for the SetupSheet - if it is being edited directly.''' + + def __init__(self, vobj): + PathLog.track(vobj.Object.Label) + self.vobj = vobj + self.obj = vobj.Object + self.editor = PathToolBitEdit.ToolBitEditor(self.obj) + self.form = self.editor.form + FreeCAD.ActiveDocument.openTransaction(translate("PathToolBit", "Edit ToolBit")) + + def reject(self): + self.editor.reject() + FreeCAD.ActiveDocument.abortTransaction() + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def accept(self): + self.editor.accept() + + FreeCAD.ActiveDocument.commitTransaction() + FreeCADGui.ActiveDocument.resetEdit() + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def getFields(self): + self.editor.getFields() + + def updateUI(self): + self.editor.updateUI() + + def updateModel(self): + self.editor.updateTool() + FreeCAD.ActiveDocument.recompute() + + def setFields(self): + self.editor.setFields() + + def setupUi(self): + self.editor.setupUI() + +def Create(name = 'ToolBit'): + '''Create(name = 'ToolBit') ... creates a new tool bit''' + FreeCAD.ActiveDocument.openTransaction(translate("PathToolBit", "Create ToolBit")) + tool = PathToolBit.Create(name) + PathIconViewProvider.Attach(tool.ViewObject, name) + return tool + +PathIconViewProvider.RegisterViewProvider('ToolBit', ViewProvider) diff --git a/src/Mod/Path/PathScripts/PathUtil.py b/src/Mod/Path/PathScripts/PathUtil.py index 3fa449106cb5..9633c6833dc8 100644 --- a/src/Mod/Path/PathScripts/PathUtil.py +++ b/src/Mod/Path/PathScripts/PathUtil.py @@ -34,14 +34,40 @@ import six import PathScripts.PathLog as PathLog - -LOGLEVEL = False - -if LOGLEVEL: - PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) - PathLog.trackModule(PathLog.thisModule()) -else: - PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +import PySide + +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + +def translate(context, text, disambig=None): + return PySide.QtCore.QCoreApplication.translate(context, text, disambig) + +def _getProperty(obj, prop): + o = obj + attr = obj + name = None + for name in prop.split('.'): + o = attr + if not hasattr(o, name): + break + attr = getattr(o, name) + + if o == attr: + PathLog.warning(translate('PathGui', "%s has no property %s (%s))") % (obj.Label, prop, name)) + return (None, None, None) + + #PathLog.debug("found property %s of %s (%s: %s)" % (prop, obj.Label, name, attr)) + return(o, attr, name) + +def getProperty(obj, prop): + '''getProperty(obj, prop) ... answer obj's property defined by its canonical name.''' + o, attr, name = _getProperty(obj, prop) # pylint: disable=unused-variable + return attr + +def setProperty(obj, prop, value): + '''setProperty(obj, prop, value) ... set the property value of obj's property defined by its canonical name.''' + o, attr, name = _getProperty(obj, prop) # pylint: disable=unused-variable + if o and name: + setattr(o, name, value) # NotValidBaseTypeIds = ['Sketcher::SketchObject'] NotValidBaseTypeIds = [] diff --git a/src/Mod/Path/Tools/Template/drill-straight.fcstd b/src/Mod/Path/Tools/Template/drill-straight.fcstd index 0e33b9a2d54061b3a11e42b369b98dd9d6c7dadf..1de5f441816c2e0cf7755070e633971d4ba8a2f0 100644 GIT binary patch delta 8019 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 delta 6478 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 F{|~dq|9}7h diff --git a/src/Mod/Path/Tools/Template/v-bit.fcstd b/src/Mod/Path/Tools/Template/v-bit.fcstd index 3fb173c4b626830a26e78f10e4300c279f9752de..b9370436666181512e652be6ceddf43b37683653 100644 GIT binary patch delta 10641 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 NlY@zyoteGs{{v5<6jcBK delta 10519 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