diff --git a/src/Mod/Path/App/Tooltable.cpp b/src/Mod/Path/App/Tooltable.cpp
index b7774d0609..53a72d5d53 100644
--- a/src/Mod/Path/App/Tooltable.cpp
+++ b/src/Mod/Path/App/Tooltable.cpp
@@ -65,7 +65,7 @@ Tool::Tool()
LengthOffset = 0;
FlatRadius = 0;
CornerRadius = 0;
- CuttingEdgeAngle = 0;
+ CuttingEdgeAngle = 180;
CuttingEdgeHeight = 0;
}
@@ -103,7 +103,7 @@ void Tool::Restore(XMLReader &reader)
LengthOffset = reader.hasAttribute("length") ? (double) reader.getAttributeAsFloat("length") : 0.0;
FlatRadius = reader.hasAttribute("flat") ? (double) reader.getAttributeAsFloat("flat") : 0.0;
CornerRadius = reader.hasAttribute("corner") ? (double) reader.getAttributeAsFloat("corner") : 0.0;
- CuttingEdgeAngle = reader.hasAttribute("angle") ? (double) reader.getAttributeAsFloat("angle") : 0.0;
+ CuttingEdgeAngle = reader.hasAttribute("angle") ? (double) reader.getAttributeAsFloat("angle") : 180.0;
CuttingEdgeHeight = reader.hasAttribute("height") ? (double) reader.getAttributeAsFloat("height") : 0.0;
std::string type = reader.hasAttribute("type") ? reader.getAttribute("type") : "";
std::string mat = reader.hasAttribute("mat") ? reader.getAttribute("mat") : "";
diff --git a/src/Mod/Path/App/TooltablePyImp.cpp b/src/Mod/Path/App/TooltablePyImp.cpp
index 17cb3fe59e..756ef0a23a 100644
--- a/src/Mod/Path/App/TooltablePyImp.cpp
+++ b/src/Mod/Path/App/TooltablePyImp.cpp
@@ -104,7 +104,7 @@ int ToolPy::PyInit(PyObject* args, PyObject* kwd)
getToolPtr()->LengthOffset = len ? PyFloat_AsDouble(len) : 0.0;
getToolPtr()->FlatRadius = fla ? PyFloat_AsDouble(fla) : 0.0;
getToolPtr()->CornerRadius = cor ? PyFloat_AsDouble(cor) : 0.0;
- getToolPtr()->CuttingEdgeAngle = ang ? PyFloat_AsDouble(ang) : 0.0;
+ getToolPtr()->CuttingEdgeAngle = ang ? PyFloat_AsDouble(ang) : 180.0;
getToolPtr()->CuttingEdgeHeight = hei ? PyFloat_AsDouble(hei) : 0.0;
return 0;
diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt
index 3f17f149df..6c8890b9c6 100644
--- a/src/Mod/Path/CMakeLists.txt
+++ b/src/Mod/Path/CMakeLists.txt
@@ -85,6 +85,7 @@ SET(PathScripts_SRCS
PathScripts/PathSurface.py
PathScripts/PathSurfaceGui.py
PathScripts/PathToolController.py
+ PathScripts/PathToolEdit.py
PathScripts/PathToolLibraryManager.py
PathScripts/PathUtil.py
PathScripts/PathUtils.py
@@ -131,9 +132,16 @@ SET(PathTests_SRCS
PathTests/TestPathUtil.py
)
+SET(Path_Images
+ Images/Tools/drill.svg
+ Images/Tools/endmill.svg
+ Images/Tools/v-bit.svg
+)
+
SET(all_files
${PathScripts_SRCS}
${PathScripts_post_SRCS}
+ ${Path_Images}
)
ADD_CUSTOM_TARGET(PathScripts ALL
@@ -172,3 +180,11 @@ INSTALL(
DESTINATION
Mod/Path/PathScripts/post
)
+
+INSTALL(
+ FILES
+ ${Path_Images}
+ DESTINATION
+ Mod/Path/Images
+)
+
diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc
index 59af5b9efe..0c16b73f9e 100644
--- a/src/Mod/Path/Gui/Resources/Path.qrc
+++ b/src/Mod/Path/Gui/Resources/Path.qrc
@@ -66,6 +66,7 @@
panels/DlgSelectPostProcessor.ui
panels/DlgToolControllerEdit.ui
panels/DlgToolCopy.ui
+ panels/DlgToolEdit.ui
panels/DlgTCChooser.ui
panels/DogboneEdit.ui
panels/HoldingTagsEdit.ui
@@ -83,7 +84,7 @@
panels/PageOpSurfaceEdit.ui
panels/PathEdit.ui
panels/PointEdit.ui
- panels/ToolEdit.ui
+ panels/ToolEditor.ui
panels/ToolLibraryEditor.ui
panels/TaskPathSimulator.ui
preferences/PathDressupHoldingTags.ui
diff --git a/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui b/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
index f0b836c3af..232354fec8 100644
--- a/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/DlgToolControllerEdit.ui
@@ -6,8 +6,8 @@
0
0
- 386
- 554
+ 561
+ 739
@@ -21,8 +21,8 @@
0
0
- 368
- 445
+ 543
+ 593
@@ -75,15 +75,15 @@
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- mm/s
-
0.000000000000000
9999999.000000000000000
+
+ mm/s
+
-
@@ -104,15 +104,15 @@
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- mm/s
-
0.000000000000000
9999999.000000000000000
+
+ mm/s
+
-
@@ -133,15 +133,15 @@
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- mm/s
-
0.000000000000000
9999999.000000000000000
+
+ mm/s
+
-
@@ -162,15 +162,15 @@
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- mm/s
-
0.000000000000000
9999999.000000000000000
+
+ mm/s
+
@@ -232,8 +232,8 @@
0
0
- 368
- 445
+ 543
+ 593
@@ -241,355 +241,36 @@
-
-
-
- Tool Properties
+
+
+
+ 0
+ 0
+
-
-
- QFormLayout::AllNonFixedFieldsGrow
+
+
+ 0
+
+
+ 0
-
-
-
-
- Name
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 50
-
-
- Display Name
-
-
-
- -
-
-
- Type
-
-
-
- -
-
-
- 6
-
-
-
-
- Drill
-
-
- -
-
- CenterDrill
-
-
- -
-
- CounterSink
-
-
- -
-
- CounterBore
-
-
- -
-
- Reamer
-
-
- -
-
- Tap
-
-
- -
-
- EndMill
-
-
- -
-
- SlotCutter
-
-
- -
-
- BallEndMill
-
-
- -
-
- ChamferMill
-
-
- -
-
- CornerRound
-
-
- -
-
- Engraver
-
-
-
-
- -
-
-
- Material
-
-
-
- -
-
-
-
-
- HighSpeedSteel
-
-
- -
-
- HighCarbonSteel
-
-
- -
-
- CastAlloy
-
-
- -
-
- Carbide
-
-
- -
-
- Ceramics
-
-
- -
-
- Diamond
-
-
- -
-
- Sialon
-
-
-
-
- -
-
-
- Diameter
-
-
-
- -
-
-
- Length Offset
-
-
-
- -
-
-
- Flat Radius
-
-
-
- -
-
-
- Corner Radius
-
-
-
- -
-
-
- Point/Tip Angle
-
-
-
- -
-
-
- Cutting Edge Height
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0 mm
-
-
- mm
-
-
- 0.000000000000000
-
-
- 100.000000000000000
-
-
- 0.125000000000000
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0 mm
-
-
- mm
-
-
- 0.000000000000000
-
-
- 100.000000000000000
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0 mm
-
-
- mm
-
-
- 0.000000000000000
-
-
- 100.000000000000000
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0 mm
-
-
- mm
-
-
- 0.000000000000000
-
-
- 100.000000000000000
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 0 mm
-
-
- mm
-
-
- 0.000000000000000
-
-
- 100.000000000000000
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- °
-
-
- 180 °
-
-
- 0.000000000000000
-
-
- 180.000000000000000
-
-
-
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
-
@@ -625,7 +306,7 @@
Gui::QuantitySpinBox
- QWidget
+ QDoubleSpinBox
@@ -639,15 +320,6 @@
spindleSpeed
spindleDirection
buttonBox
- toolName
- toolType
- toolMaterial
- toolDiameter
- toolLengthOffset
- toolFlatRadius
- toolCornerRadius
- toolCuttingEdgeAngle
- toolCuttingEdgeHeight
diff --git a/src/Mod/Path/Gui/Resources/panels/DlgToolEdit.ui b/src/Mod/Path/Gui/Resources/panels/DlgToolEdit.ui
new file mode 100644
index 0000000000..ac0eae95c2
--- /dev/null
+++ b/src/Mod/Path/Gui/Resources/panels/DlgToolEdit.ui
@@ -0,0 +1,85 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 600
+ 584
+
+
+
+ Tool Editor
+
+
+
-
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+ buttonBox
+
+
+
+
+ buttonBox
+ accepted()
+ Dialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ Dialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui b/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui
deleted file mode 100644
index b5ffde3a92..0000000000
--- a/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui
+++ /dev/null
@@ -1,277 +0,0 @@
-
-
- Dialog
-
-
-
- 0
- 0
- 422
- 498
-
-
-
- Dialog
-
-
- -
-
-
- Tool Properties
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
-
-
-
-
-
- Name
-
-
-
- -
-
-
- 50
-
-
- Display Name
-
-
-
- -
-
-
- Type
-
-
-
- -
-
-
- 0
-
-
-
- -
-
-
- Material
-
-
-
- -
-
-
- -
-
-
- Diameter
-
-
-
- -
-
-
- Length Offset
-
-
-
- -
-
-
- Flat Radius
-
-
-
- -
-
-
- Corner Radius
-
-
-
- -
-
-
- Point/Tip Angle
-
-
-
- -
-
-
- Cutting Edge Height
-
-
-
- -
-
-
- 0 mm
-
-
- 0.125000000000000
-
-
- 100.000000000000000
-
-
- 0.000000000000000
-
-
- mm
-
-
-
- -
-
-
- 0 mm
-
-
- 100.000000000000000
-
-
- 0.000000000000000
-
-
- mm
-
-
-
- -
-
-
- 0 mm
-
-
- 100.000000000000000
-
-
- 0.000000000000000
-
-
- mm
-
-
-
- -
-
-
- 0 mm
-
-
- 100.000000000000000
-
-
- 0.000000000000000
-
-
- mm
-
-
-
- -
-
-
- 0 mm
-
-
- 100.000000000000000
-
-
- 0.000000000000000
-
-
- mm
-
-
-
- -
-
-
- 180 °
-
-
- 180.000000000000000
-
-
- 0.000000000000000
-
-
- °
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
-
-
-
-
- Gui::InputField
- QLineEdit
-
-
-
-
- NameField
- TypeField
- MaterialField
- DiameterField
- LengthOffsetField
- FlatRadiusField
- CornerRadiusField
- CuttingEdgeAngleField
- CuttingEdgeHeightField
- buttonBox
-
-
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
-
diff --git a/src/Mod/Path/Gui/Resources/panels/ToolEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolEditor.ui
new file mode 100644
index 0000000000..3b73c884c7
--- /dev/null
+++ b/src/Mod/Path/Gui/Resources/panels/ToolEditor.ui
@@ -0,0 +1,317 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 560
+ 766
+
+
+
+ Form
+
+
+ -
+
+
+ Tool
+
+
+
-
+
+
+ Name
+
+
+
+ -
+
+
+ 50
+
+
+ Display Name
+
+
+
+ -
+
+
+ Type
+
+
+
+ -
+
+
+ -1
+
+
+
+ -
+
+
+ Material
+
+
+
+ -
+
+
+ -
+
+
+ Length Offset
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+
+
+
+ -
+
+
+ Tool Parameter
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Diameter
+
+
+
+ -
+
+
+ Flat Radius
+
+
+
+ -
+
+
+ Corner Radius
+
+
+
+ -
+
+
+ Point/Tip Angle
+
+
+
+ -
+
+
+ Cutting Edge Height
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 180°
+
+
+ °
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+
+
+
+ -
+
+
+ Tool Parameter
+
+
+
-
+
+
+
-
+
+
+ D =
+
+
+
+ -
+
+
+ d =
+
+
+
+ -
+
+
+ H =
+
+
+
+ -
+
+
+ α =
+
+
+
+ -
+
+
+ false
+
+
+ S =
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 0.00
+
+
+ mm
+
+
+
+ -
+
+
+ 180°
+
+
+ °
+
+
+
+ -
+
+
+ false
+
+
+ 0.00
+
+
+ mm
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Image
+
+
+ true
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+ Gui::InputField
+ QLineEdit
+
+
+
+
+
+
diff --git a/src/Mod/Path/Images/Tools/drill.svg b/src/Mod/Path/Images/Tools/drill.svg
new file mode 100644
index 0000000000..1eb08e786e
--- /dev/null
+++ b/src/Mod/Path/Images/Tools/drill.svg
@@ -0,0 +1,280 @@
+
+
+
+
diff --git a/src/Mod/Path/Images/Tools/endmill.svg b/src/Mod/Path/Images/Tools/endmill.svg
new file mode 100644
index 0000000000..dbf3e746fc
--- /dev/null
+++ b/src/Mod/Path/Images/Tools/endmill.svg
@@ -0,0 +1,529 @@
+
+
+
+
diff --git a/src/Mod/Path/Images/Tools/v-bit.svg b/src/Mod/Path/Images/Tools/v-bit.svg
new file mode 100644
index 0000000000..f3ef915529
--- /dev/null
+++ b/src/Mod/Path/Images/Tools/v-bit.svg
@@ -0,0 +1,596 @@
+
+
+
+
diff --git a/src/Mod/Path/PathScripts/PathToolController.py b/src/Mod/Path/PathScripts/PathToolController.py
index 3e4f4fd3b8..ccb54ca243 100644
--- a/src/Mod/Path/PathScripts/PathToolController.py
+++ b/src/Mod/Path/PathScripts/PathToolController.py
@@ -28,6 +28,7 @@ import Part
import Path
import PathScripts
import PathScripts.PathLog as PathLog
+import PathScripts.PathToolEdit as PathToolEdit
import PathScripts.PathUtil as PathUtil
from FreeCAD import Units
@@ -280,37 +281,7 @@ class ToolControllerEditor:
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj, 'VertRapid')
self.horizRapid = PathGui.QuantitySpinBox(self.form.horizRapid, obj, 'HorizRapid')
- self.toolDiameter = PathGui.QuantitySpinBox(self.form.toolDiameter, obj, 'Tool.Diameter')
- self.toolLengthOffset = PathGui.QuantitySpinBox(self.form.toolLengthOffset, obj, 'Tool.LengthOffset')
- self.toolFlatRadius = PathGui.QuantitySpinBox(self.form.toolFlatRadius, obj, 'Tool.FlatRadius')
- self.toolCornerRadius = PathGui.QuantitySpinBox(self.form.toolCornerRadius, obj, 'Tool.CornerRadius')
- self.toolCuttingEdgeAngle = PathGui.QuantitySpinBox(self.form.toolCuttingEdgeAngle, obj, 'Tool.CuttingEdgeAngle')
- self.toolCuttingEdgeHeight = PathGui.QuantitySpinBox(self.form.toolCuttingEdgeHeight, obj, 'Tool.CuttingEdgeHeight')
-
- def getType(self, tooltype):
- "gets a combobox index number for a given type or viceversa"
- toolslist = ["Drill", "CenterDrill", "CounterSink", "CounterBore",
- "Reamer", "Tap", "EndMill", "SlotCutter", "BallEndMill",
- "ChamferMill", "CornerRound", "Engraver"]
- if isinstance(tooltype, str):
- if tooltype in toolslist:
- return toolslist.index(tooltype)
- else:
- return 0
- else:
- return toolslist[tooltype]
-
- def getMaterial(self, material):
- "gets a combobox index number for a given material or viceversa"
- matslist = ["HighSpeedSteel", "HighCarbonToolSteel", "CastAlloy",
- "Carbide", "Ceramics", "Diamond", "Sialon"]
- if isinstance(material, str):
- if material in matslist:
- return matslist.index(material)
- else:
- return 0
- else:
- return matslist[material]
+ self.editor = PathToolEdit.ToolEditor(obj.Tool, self.form.toolEditor)
def updateUi(self):
tc = self.obj
@@ -325,15 +296,7 @@ class ToolControllerEditor:
if index >= 0:
self.form.spindleDirection.setCurrentIndex(index)
- self.form.toolName.setText(tc.Tool.Name)
- self.form.toolType.setCurrentIndex(self.getType(tc.Tool.ToolType))
- self.form.toolMaterial.setCurrentIndex(self.getMaterial(tc.Tool.Material))
- self.toolDiameter.updateSpinBox()
- self.toolLengthOffset.updateSpinBox()
- self.toolFlatRadius.updateSpinBox()
- self.toolCornerRadius.updateSpinBox()
- self.toolCuttingEdgeAngle.updateSpinBox()
- self.toolCuttingEdgeHeight.updateSpinBox()
+ self.editor.updateUI()
def updateToolController(self):
tc = self.obj
@@ -347,15 +310,9 @@ class ToolControllerEditor:
tc.SpindleSpeed = self.form.spindleSpeed.value()
tc.SpindleDir = self.form.spindleDirection.currentText()
- tc.Tool.Name = str(self.form.toolName.text())
- tc.Tool.ToolType = self.getType(self.form.toolType.currentIndex())
- tc.Tool.Material = self.getMaterial(self.form.toolMaterial.currentIndex())
- self.toolDiameter.updateProperty()
- self.toolLengthOffset.updateProperty()
- self.toolFlatRadius.updateProperty()
- self.toolCornerRadius.updateProperty()
- self.toolCuttingEdgeAngle.updateProperty()
- self.toolCuttingEdgeHeight.updateProperty()
+ self.editor.updateTool()
+ tc.Tool = self.editor.tool
+
except Exception as e:
PathLog.error(translate("PathToolController", "Error updating TC: %s") % e)
@@ -367,19 +324,14 @@ class ToolControllerEditor:
self.form.blockSignals(False)
def setupUi(self):
+ self.editor.setupUI()
+
self.form.tcName.editingFinished.connect(self.refresh)
self.form.horizFeed.editingFinished.connect(self.refresh)
self.form.vertFeed.editingFinished.connect(self.refresh)
self.form.horizRapid.editingFinished.connect(self.refresh)
self.form.vertRapid.editingFinished.connect(self.refresh)
- self.form.toolName.editingFinished.connect(self.refresh)
- self.form.toolDiameter.editingFinished.connect(self.refresh)
- self.form.toolLengthOffset.editingFinished.connect(self.refresh)
- self.form.toolFlatRadius.editingFinished.connect(self.refresh)
- self.form.toolCornerRadius.editingFinished.connect(self.refresh)
- self.form.toolCuttingEdgeAngle.editingFinished.connect(self.refresh)
- self.form.toolCuttingEdgeHeight.editingFinished.connect(self.refresh)
class TaskPanel:
diff --git a/src/Mod/Path/PathScripts/PathToolEdit.py b/src/Mod/Path/PathScripts/PathToolEdit.py
new file mode 100644
index 0000000000..6ca60bd907
--- /dev/null
+++ b/src/Mod/Path/PathScripts/PathToolEdit.py
@@ -0,0 +1,288 @@
+# -*- coding: utf-8 -*-
+
+# ***************************************************************************
+# * *
+# * Copyright (c) 2018 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 math
+
+from PySide import QtCore, QtGui
+
+PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+#PathLog.trackModule(PathLog.thisModule())
+
+class ToolEditorDefault:
+ '''Generic Tool parameter editor for all Tools that don't have a customized edit function.
+ Let's the user enter the raw internal data. Not the best approach but this is the starting point.'''
+ def __init__(self, editor):
+ self.editor = editor
+ self.form = editor.form
+
+ def setupUI(self):
+ self.form.paramImage.hide()
+ self.form.paramGeneric.show()
+
+ def updateUI(self):
+ self.form.toolDiameter.setText(FreeCAD.Units.Quantity(self.editor.tool.Diameter, FreeCAD.Units.Length).UserString)
+ self.form.toolFlatRadius.setText(FreeCAD.Units.Quantity(self.editor.tool.FlatRadius, FreeCAD.Units.Length).UserString)
+ self.form.toolCornerRadius.setText(FreeCAD.Units.Quantity(self.editor.tool.CornerRadius, FreeCAD.Units.Length).UserString)
+ self.form.toolCuttingEdgeHeight.setText(FreeCAD.Units.Quantity(self.editor.tool.CuttingEdgeHeight, FreeCAD.Units.Length).UserString)
+ self.form.toolCuttingEdgeAngle.setText(FreeCAD.Units.Quantity(self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle).UserString)
+
+ def updateTool(self):
+ self.editor.tool.Diameter = FreeCAD.Units.parseQuantity(self.form.toolDiameter.text())
+ self.editor.tool.FlatRadius = FreeCAD.Units.parseQuantity(self.form.toolFlatRadius.text())
+ self.editor.tool.CornerRadius = FreeCAD.Units.parseQuantity(self.form.toolCornerRadius.text())
+ self.editor.tool.CuttingEdgeAngle = FreeCAD.Units.Quantity(self.form.toolCuttingEdgeAngle.text())
+ self.editor.tool.CuttingEdgeHeight = FreeCAD.Units.parseQuantity(self.form.toolCuttingEdgeHeight.text())
+
+class ToolEditorImage(object):
+ '''Base implementation for all customized Tool parameter editors.
+ While not required it is simplest to subclass specific editors.'''
+ def __init__(self, editor, imageFile, hide='', disable=''):
+ self.editor = editor
+ self.form = editor.form
+ self.imagePath = "{}Mod/Path/Images/Tools/{}".format(FreeCAD.getHomePath(), imageFile)
+ self.image = QtGui.QPixmap(self.imagePath)
+ self.hide = hide
+ self.disable = disable
+
+ form = editor.form
+ self.widgets = {
+ 'D' : (form.label_D, form.value_D),
+ 'd' : (form.label_d, form.value_d),
+ 'H' : (form.label_H, form.value_H),
+ 'a' : (form.label_a, form.value_a),
+ 'S' : (form.label_S, form.value_S)
+ }
+
+ def setupUI(self):
+ PathLog.track()
+ self.form.paramGeneric.hide()
+ self.form.paramImage.show()
+
+ for key, widgets in self.widgets.items():
+ hide = key in self.hide
+ disable = key in self.disable
+ for w in widgets:
+ w.setHidden(hide)
+ w.setDisabled(disable)
+ if not hide and not disable:
+ widgets[1].editingFinished.connect(self.editor.refresh)
+
+ self.form.image.setPixmap(self.image)
+
+ def updateUI(self):
+ PathLog.track()
+ self.form.value_D.setText(self.quantityDiameter(True).UserString)
+ self.form.value_d.setText(self.quantityFlatRadius(True).UserString)
+ self.form.value_a.setText(self.quantityCuttingEdgeAngle(True).UserString)
+ self.form.value_H.setText(self.quantityCuttingEdgeHeight(True).UserString)
+
+ def updateTool(self):
+ PathLog.track()
+ toolDefault = Path.Tool()
+ if 'D' in self.hide:
+ self.editor.tool.Diameter = toolDefault.Diameter
+ else:
+ self.editor.tool.Diameter = self.quantityDiameter(False)
+
+ if 'd' in self.hide:
+ self.editor.tool.FlatRadius = toolDefault.FlatRadius
+ else:
+ self.editor.tool.FlatRadius = self.quantityFlatRadius(False)
+
+ if 'a' in self.hide:
+ self.editor.tool.CuttingEdgeAngle = toolDefault.CuttingEdgeAngle
+ else:
+ self.editor.tool.CuttingEdgeAngle = self.quantityCuttingEdgeAngle(False)
+
+ if 'H' in self.hide:
+ self.editor.tool.CuttingEdgeHeight = toolDefault.CuttingEdgeHeight
+ else:
+ self.editor.tool.CuttingEdgeHeight = self.quantityCuttingEdgeHeight(False)
+
+ self.editor.tool.CornerRadius = toolDefault.CornerRadius
+
+ def quantityDiameter(self, propertyToDisplay):
+ if propertyToDisplay:
+ return FreeCAD.Units.Quantity(self.editor.tool.Diameter, FreeCAD.Units.Length)
+ return FreeCAD.Units.parseQuantity(self.form.value_D.text())
+
+ def quantityFlatRadius(self, propertyToDisplay):
+ if propertyToDisplay:
+ return FreeCAD.Units.Quantity(self.editor.tool.FlatRadius, FreeCAD.Units.Length) * 2
+ return FreeCAD.Units.parseQuantity(self.form.value_d.text()) / 2
+
+ def quantityCuttingEdgeAngle(self, propertyToDisplay):
+ if propertyToDisplay:
+ return FreeCAD.Units.Quantity(self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle) / 2
+ return FreeCAD.Units.parseQuantity(self.form.value_a.text()) * 2
+
+ def quantityCuttingEdgeHeight(self, propertyToDisplay):
+ if propertyToDisplay:
+ return FreeCAD.Units.Quantity(self.editor.tool.CuttingEdgeHeight, FreeCAD.Units.Length)
+ return FreeCAD.Units.parseQuantity(self.form.value_H.text())
+
+class ToolEditorEndmill(ToolEditorImage):
+ '''Tool parameter editor for endmills.'''
+ def __init__(self, editor):
+ super(self.__class__, self).__init__(editor, 'endmill.svg', 'da', 'S')
+
+class ToolEditorDrill(ToolEditorImage):
+ '''Tool parameter editor for drills.'''
+ def __init__(self, editor):
+ super(self.__class__, self).__init__(editor, 'drill.svg', 'dS', '')
+
+ def quantityCuttingEdgeAngle(self, propertyToDisplay):
+ if propertyToDisplay:
+ return FreeCAD.Units.Quantity(self.editor.tool.CuttingEdgeAngle, FreeCAD.Units.Angle)
+ return FreeCAD.Units.parseQuantity(self.form.value_a.text())
+
+class ToolEditorEngrave(ToolEditorImage):
+ '''Tool parameter editor for v-bits.'''
+ def __init__(self, editor):
+ super(self.__class__, self).__init__(editor, 'v-bit.svg', '', 'HS')
+
+ def quantityCuttingEdgeHeight(self, propertyToDisplay):
+ PathLog.track()
+ dr = (self.quantityDiameter(False) - self.quantityFlatRadius(False)) / 2
+ da = self.quantityCuttingEdgeAngle(False).Value
+ return dr / math.tan(math.radians(da) / 2)
+
+class ToolEditor:
+ '''UI and controller for editing a Tool.
+ The controller embeds the UI to the parentWidget which has to have a layout attached to it.
+ The editor maintains two Tools, self.tool and self.Tool. The former is the one being edited
+ and always reflects the current state. self.Tool on the other hand is the "official" Tool
+ which should be used externally. The state is transferred between the two with accept and
+ reject.
+
+ The editor uses instances of ToolEditorDefault and ToolEditorImage to deal with the changes
+ of the actual parameters. For any ToolType not mapped in ToolTypeImage the editor uses
+ an instance of ToolEditorDefault.
+ '''
+
+ ToolTypeImage = {
+ 'EndMill': ToolEditorEndmill,
+ 'Drill': ToolEditorDrill,
+ 'Engraver': ToolEditorEngrave }
+
+ def __init__(self, tool, parentWidget, parent=None):
+ self.Parent = parent
+ self.Tool = tool
+ self.tool = tool.copy()
+ self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolEditor.ui")
+
+ self.form.setParent(parentWidget)
+ parentWidget.layout().addWidget(self.form)
+
+ for tooltype in Path.Tool.getToolTypes(tool):
+ self.form.toolType.addItem(tooltype)
+ for material in Path.Tool.getToolMaterials(tool):
+ self.form.toolMaterial.addItem(material)
+
+ self.setupToolType(self.tool.ToolType)
+
+ def accept(self):
+ self.Tool = self.tool
+
+ def reject(self):
+ self.tool = self.Tool
+
+ def getType(self, tooltype):
+ "gets a combobox index number for a given type or viceversa"
+ toolslist = Path.Tool.getToolTypes(Path.Tool())
+ if isinstance(tooltype, str):
+ if tooltype in toolslist:
+ return toolslist.index(tooltype)
+ else:
+ return 0
+ return toolslist[tooltype]
+
+ def getMaterial(self, material):
+ "gets a combobox index number for a given material or viceversa"
+ matslist = Path.Tool.getToolMaterials(Path.Tool())
+ if isinstance(material, str):
+ if material in matslist:
+ return matslist.index(material)
+ else:
+ return 0
+ return matslist[material]
+
+ def updateUI(self):
+ PathLog.track()
+ self.form.toolName.setText(self.tool.Name)
+ self.form.toolType.setCurrentIndex(self.getType(self.tool.ToolType))
+ self.form.toolMaterial.setCurrentIndex(self.getMaterial(self.tool.Material))
+ self.form.toolLengthOffset.setText(FreeCAD.Units.Quantity(self.tool.LengthOffset, FreeCAD.Units.Length).UserString)
+
+ self.editor.updateUI()
+
+ def updateToolName(self):
+ self.tool.Name = str(self.form.toolName.text())
+
+ def updateToolType(self):
+ PathLog.track()
+ self.form.blockSignals(True)
+ self.tool.ToolType = self.getType(self.form.toolType.currentIndex())
+ self.setupToolType(self.tool.ToolType)
+ self.updateUI()
+ self.form.blockSignals(False)
+
+ def setupToolType(self, tt):
+ PathLog.track()
+ if 'Undefined' == tt:
+ tt = Path.Tool.getToolTypes(Path.Tool())[0]
+ if tt in self.ToolTypeImage:
+ self.editor = self.ToolTypeImage[tt](self)
+ else:
+ PathLog.debug("weak supported ToolType = %s" % (tt))
+ self.editor = ToolEditorDefault(self)
+ self.editor.setupUI()
+
+ def updateTool(self):
+ PathLog.track()
+ self.tool.Material = self.getMaterial(self.form.toolMaterial.currentIndex())
+ self.tool.LengthOffset = FreeCAD.Units.parseQuantity(self.form.toolLengthOffset.text())
+ self.editor.updateTool()
+
+ 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.updateToolName)
+ self.form.toolType.currentIndexChanged.connect(self.updateToolType)
+ self.form.toolMaterial.currentIndexChanged.connect(self.refresh)
+ self.form.toolLengthOffset.valueChanged.connect(self.refresh)
+
diff --git a/src/Mod/Path/PathScripts/PathToolLibraryManager.py b/src/Mod/Path/PathScripts/PathToolLibraryManager.py
index 59ca60d198..f48cf23fba 100644
--- a/src/Mod/Path/PathScripts/PathToolLibraryManager.py
+++ b/src/Mod/Path/PathScripts/PathToolLibraryManager.py
@@ -29,6 +29,7 @@ import FreeCADGui
import Path
import PathScripts
import PathScripts.PathLog as PathLog
+import PathScripts.PathToolEdit as PathToolEdit
import PathScripts.PathUtil as PathUtil
import PathScripts.PathUtils as PathUtils
import json
@@ -37,10 +38,8 @@ import xml.sax
from PySide import QtCore, QtGui
-
-LOG_MODULE = 'PathToolLibraryManager'
-PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
-#PathLog.trackModule('PathToolLibraryManager')
+PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+#PathLog.trackModule(PathLog.thisModule())
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
@@ -392,10 +391,7 @@ class ToolLibraryManager():
class EditorPanel():
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")
- self.editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui")
self.TLM = ToolLibraryManager()
self.loadTable()
@@ -403,6 +399,12 @@ class EditorPanel():
self.job = job
self.cb = cb
+ def toolEditor(self, tool):
+ dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolEdit.ui")
+ editor = PathToolEdit.ToolEditor(tool, dialog.toolEditor, dialog)
+ editor.setupUI()
+ return editor
+
def accept(self):
pass
@@ -436,32 +438,14 @@ class EditorPanel():
return matslist[material]
def addTool(self):
- t = Path.Tool()
- editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui")
- editform.TypeField.clear()
- for tooltype in Path.Tool.getToolTypes(t):
- editform.TypeField.addItem(tooltype)
+ tool = Path.Tool()
+ editor = self.toolEditor(tool)
- editform.MaterialField.clear()
- for material in Path.Tool.getToolMaterials(t):
- editform.MaterialField.addItem(material)
-
- r = editform.exec_()
+ r = editor.Parent.exec_()
if r:
- if editform.NameField.text():
- t.Name = str(editform.NameField.text()) #FIXME: not unicode safe!
- t.ToolType = self.getType(editform.TypeField.currentIndex())
- t.Material = self.getMaterial(editform.MaterialField.currentIndex())
- t.Diameter = FreeCAD.Units.parseQuantity(editform.DiameterField.text())
- t.LengthOffset = FreeCAD.Units.parseQuantity(editform.LengthOffsetField.text())
- t.FlatRadius = FreeCAD.Units.parseQuantity(editform.FlatRadiusField.text())
- t.CornerRadius = FreeCAD.Units.parseQuantity(editform.CornerRadiusField.text())
- t.CuttingEdgeAngle = FreeCAD.Units.Quantity(editform.CuttingEdgeAngleField.text())
- t.CuttingEdgeHeight = FreeCAD.Units.parseQuantity(editform.CuttingEdgeHeightField.text())
-
+ editor.accept()
listname = ""
-
- if self.TLM.addnew(listname, t) is True:
+ if self.TLM.addnew(listname, editor.Tool) is True:
self.loadTable()
def setFields(self):
@@ -515,40 +499,12 @@ class EditorPanel():
listname = ""
toolnum = int(value)
tool = self.TLM.getTool(listname, toolnum)
- editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui")
+ editor = self.toolEditor(tool)
- editform.TypeField.clear()
- for tooltype in Path.Tool.getToolTypes(tool):
- editform.TypeField.addItem(tooltype)
-
- editform.MaterialField.clear()
- for material in Path.Tool.getToolMaterials(tool):
- editform.MaterialField.addItem(material)
-
- editform.NameField.setText(tool.Name)
- editform.TypeField.setCurrentIndex(self.getType(tool.ToolType))
- editform.MaterialField.setCurrentIndex(self.getMaterial(tool.Material))
- editform.DiameterField.setText(FreeCAD.Units.Quantity(tool.Diameter, FreeCAD.Units.Length).UserString)
- editform.LengthOffsetField.setText(FreeCAD.Units.Quantity(tool.LengthOffset, FreeCAD.Units.Length).UserString)
- editform.FlatRadiusField.setText(FreeCAD.Units.Quantity(tool.FlatRadius, FreeCAD.Units.Length).UserString)
- editform.CornerRadiusField.setText(FreeCAD.Units.Quantity(tool.CornerRadius, FreeCAD.Units.Length).UserString)
- editform.CuttingEdgeAngleField.setText(FreeCAD.Units.Quantity(tool.CuttingEdgeAngle, FreeCAD.Units.Angle).UserString)
- editform.CuttingEdgeHeightField.setText(FreeCAD.Units.Quantity(tool.CuttingEdgeHeight, FreeCAD.Units.Length).UserString)
-
- r = editform.exec_()
+ r = editor.Parent.exec_()
if r:
- if editform.NameField.text():
- tool.Name = str(editform.NameField.text()) #FIXME: not unicode safe!
- tool.ToolType = self.getType(editform.TypeField.currentIndex())
- tool.Material = self.getMaterial(editform.MaterialField.currentIndex())
- tool.Diameter = FreeCAD.Units.parseQuantity(editform.DiameterField.text())
- tool.LengthOffset = FreeCAD.Units.parseQuantity(editform.LengthOffsetField.text())
- tool.FlatRadius = FreeCAD.Units.parseQuantity(editform.FlatRadiusField.text())
- tool.CornerRadius = FreeCAD.Units.parseQuantity(editform.CornerRadiusField.text())
- tool.CuttingEdgeAngle = FreeCAD.Units.Quantity(editform.CuttingEdgeAngleField.text())
- tool.CuttingEdgeHeight = FreeCAD.Units.parseQuantity(editform.CuttingEdgeHeightField.text())
-
- if self.TLM.updateTool(listname, toolnum, tool) is True:
+ editor.accept()
+ if self.TLM.updateTool(listname, toolnum, editor.Tool) is True:
self.loadTable()
def importFile(self):