diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt
index 6c9d692156..bcfa177d88 100644
--- a/src/Mod/Path/CMakeLists.txt
+++ b/src/Mod/Path/CMakeLists.txt
@@ -176,6 +176,7 @@ SET(Tools_Shape_SRCS
Tools/Shape/endmill.fcstd
Tools/Shape/probe.fcstd
Tools/Shape/slittingsaw.fcstd
+ Tools/Shape/thread-mill.fcstd
Tools/Shape/v-bit.fcstd
)
diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui
index f67744b714..8de86b656a 100644
--- a/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/PageOpThreadMillingEdit.ui
@@ -6,7 +6,7 @@
0
0
- 482
+ 318
756
@@ -157,37 +157,10 @@
Tool Controller
-
- -
-
-
- Tool
-
-
-
- -
+
+
-
- -
-
-
- false
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- false
-
-
- Crest
-
-
-
diff --git a/src/Mod/Path/PathScripts/PathThreadMilling.py b/src/Mod/Path/PathScripts/PathThreadMilling.py
index 2804de0daf..3005e7d326 100644
--- a/src/Mod/Path/PathScripts/PathThreadMilling.py
+++ b/src/Mod/Path/PathScripts/PathThreadMilling.py
@@ -40,8 +40,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "Path thread milling operation."
-PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
-PathLog.trackModule(PathLog.thisModule())
+PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+#PathLog.trackModule(PathLog.thisModule())
# Qt translation handling
def translate(context, text, disambig=None):
@@ -196,6 +196,12 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp):
obj.addProperty("App::PropertyLink", "ClearanceOp", "Operation", QtCore.QT_TRANSLATE_NOOP("PathThreadMilling", "Operation to clear the inside of the thread"))
obj.Direction = self.Directions
+ # Rotation related properties
+ if not hasattr(obj, 'EnableRotation'):
+ obj.addProperty("App::PropertyEnumeration", "EnableRotation", "Rotation", QtCore.QT_TRANSLATE_NOOP("App::Property", "Enable rotation to gain access to pockets/areas not normal to Z axis."))
+ obj.EnableRotation = ['Off', 'A(x)', 'B(y)', 'A & B']
+
+
def threadStartDepth(self, obj):
if obj.ThreadOrientation == self.RightHand:
if obj.Direction == self.DirectionClimb:
@@ -264,7 +270,7 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp):
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
- for radius in threadPasses(obj.Passes, radiiInternal, obj.MajorDiameter.Value, obj.MinorDiameter.Value, self.tool.Diameter, 0):
+ for radius in threadPasses(obj.Passes, radiiInternal, obj.MajorDiameter.Value, obj.MinorDiameter.Value, float(self.tool.Diameter), float(self.tool.Crest)):
commands = internalThreadCommands(loc, gcode, zStart, zFinal, pitch, radius, obj.LeadInOut)
for cmd in commands:
p = cmd.Parameters
@@ -279,20 +285,22 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp):
def circularHoleExecute(self, obj, holes):
PathLog.track()
+ if self.isToolSupported(obj, self.tool):
+ self.commandlist.append(Path.Command("(Begin Thread Milling)"))
- self.commandlist.append(Path.Command("(Begin Thread Milling)"))
+ (cmd, zStart, zFinal) = self.threadSetup(obj)
+ pitch = obj.Pitch.Value
+ if obj.TPI > 0:
+ pitch = 25.4 / obj.TPI
+ if pitch <= 0:
+ PathLog.error("Cannot create thread with pitch {}".format(pitch))
+ return
- (cmd, zStart, zFinal) = self.threadSetup(obj)
- pitch = obj.Pitch.Value
- if obj.TPI > 0:
- pitch = 25.4 / obj.TPI
- if pitch <= 0:
- PathLog.error("Cannot create thread with pitch {}".format(pitch))
- return
-
- # rapid to clearance height
- for loc in holes:
- self.executeThreadMill(obj, FreeCAD.Vector(loc['x'], loc['y'], 0), cmd, zStart, zFinal, pitch)
+ # rapid to clearance height
+ for loc in holes:
+ self.executeThreadMill(obj, FreeCAD.Vector(loc['x'], loc['y'], 0), cmd, zStart, zFinal, pitch)
+ else:
+ PathLog.error("No suitable Tool found for thread milling operation")
def opSetDefaultValues(self, obj, job):
@@ -305,6 +313,10 @@ class ObjectThreadMilling(PathCircularHoleBase.ObjectOp):
obj.Direction = self.DirectionClimb
obj.LeadInOut = True
+ def isToolSupported(self, obj, tool):
+ '''Thread milling only supports thread milling cutters.'''
+ return hasattr(tool, 'Diameter') and hasattr(tool, 'Crest')
+
def SetupProperties():
setup = []
diff --git a/src/Mod/Path/PathScripts/PathThreadMillingGui.py b/src/Mod/Path/PathScripts/PathThreadMillingGui.py
index 9a3e55930e..61eecbeec7 100644
--- a/src/Mod/Path/PathScripts/PathThreadMillingGui.py
+++ b/src/Mod/Path/PathScripts/PathThreadMillingGui.py
@@ -38,8 +38,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "UI and Command for Path Thread Milling Operation."
-PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
-PathLog.trackModule(PathLog.thisModule())
+PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+#PathLog.trackModule(PathLog.thisModule())
def setupCombo(combo, selections):
combo.clear()
diff --git a/src/Mod/Path/Tools/Shape/thread-mill.fcstd b/src/Mod/Path/Tools/Shape/thread-mill.fcstd
new file mode 100644
index 0000000000..ba9294fe6f
Binary files /dev/null and b/src/Mod/Path/Tools/Shape/thread-mill.fcstd differ