diff --git a/src/Mod/CAM/CMakeLists.txt b/src/Mod/CAM/CMakeLists.txt
index 4b1b4d927e..f1e5af3042 100644
--- a/src/Mod/CAM/CMakeLists.txt
+++ b/src/Mod/CAM/CMakeLists.txt
@@ -211,6 +211,7 @@ SET(PathPythonToolsToolBitModels_SRCS
Path/Tool/toolbit/models/reamer.py
Path/Tool/toolbit/models/slittingsaw.py
Path/Tool/toolbit/models/tap.py
+ Path/Tool/toolbit/models/taperedballnose.py
Path/Tool/toolbit/models/threadmill.py
Path/Tool/toolbit/models/vbit.py
)
@@ -284,6 +285,7 @@ SET(PathPythonToolsShapeModels_SRCS
Path/Tool/shape/models/reamer.py
Path/Tool/shape/models/slittingsaw.py
Path/Tool/shape/models/tap.py
+ Path/Tool/shape/models/taperedballnose.py
Path/Tool/shape/models/threadmill.py
Path/Tool/shape/models/vbit.py
)
@@ -487,6 +489,8 @@ SET(Tools_Shape_SRCS
Tools/Shape/slittingsaw.svg
Tools/Shape/tap.fcstd
Tools/Shape/tap.svg
+ Tools/Shape/taperedballnose.fcstd
+ Tools/Shape/taperedballnose.svg
Tools/Shape/thread-mill.fcstd
Tools/Shape/thread-mill.svg
Tools/Shape/v-bit.fcstd
diff --git a/src/Mod/CAM/Gui/Resources/panels/ToolBitEditor.ui b/src/Mod/CAM/Gui/Resources/panels/ToolBitEditor.ui
index 12cc1b8a7a..250c5f0828 100644
--- a/src/Mod/CAM/Gui/Resources/panels/ToolBitEditor.ui
+++ b/src/Mod/CAM/Gui/Resources/panels/ToolBitEditor.ui
@@ -6,8 +6,8 @@
0
0
- 750
- 800
+ 775
+ 600
@@ -15,24 +15,9 @@
-
-
-
- true
-
-
-
-
- 0
- 0
- 980
- 849
-
-
-
-
-
-
-
-
-
+
+
-
+
0
@@ -41,14 +26,14 @@
- 650
- 850
+ 775
+ 600
- 650
- 850
+ 775
+ 600
@@ -170,10 +155,6 @@
-
-
-
-
-
diff --git a/src/Mod/CAM/Path/Main/Gui/Camotics.py b/src/Mod/CAM/Path/Main/Gui/Camotics.py
index 3eedc530ad..7d8c98c1eb 100644
--- a/src/Mod/CAM/Path/Main/Gui/Camotics.py
+++ b/src/Mod/CAM/Path/Main/Gui/Camotics.py
@@ -134,6 +134,7 @@ class CamoticsSimulation(QtCore.QObject):
SHAPEMAP = {
"ballend": "Ballnose",
"endmill": "Cylindrical",
+ "taperedballnose": "Ballnose",
"v-bit": "Conical",
"chamfer": "Snubnose",
}
diff --git a/src/Mod/CAM/Path/Op/SurfaceSupport.py b/src/Mod/CAM/Path/Op/SurfaceSupport.py
index 18169c544b..b792a37b00 100644
--- a/src/Mod/CAM/Path/Op/SurfaceSupport.py
+++ b/src/Mod/CAM/Path/Op/SurfaceSupport.py
@@ -2678,6 +2678,7 @@ class OCL_Tool:
"endmill": "CylCutter",
"ballend": "BallCutter",
"bullnose": "BullCutter",
+ "taperedballnose": "BallCutter",
"drill": "ConeCutter",
"engraver": "ConeCutter",
"v_bit": "ConeCutter",
diff --git a/src/Mod/CAM/Path/Tool/library/serializers/camotics.py b/src/Mod/CAM/Path/Tool/library/serializers/camotics.py
index 15513bad94..807b289258 100644
--- a/src/Mod/CAM/Path/Tool/library/serializers/camotics.py
+++ b/src/Mod/CAM/Path/Tool/library/serializers/camotics.py
@@ -33,11 +33,17 @@ from ..models.library import Library
SHAPEMAP = {
"ballend": "Ballnose",
"endmill": "Cylindrical",
+ "taperedballnose": "Ballnose",
"v-bit": "Conical",
"vbit": "Conical",
"chamfer": "Snubnose",
}
-SHAPEMAP_REVERSE = dict((v, k) for k, v in SHAPEMAP.items())
+SHAPEMAP_REVERSE = {
+ "Ballnose": "ballend", # Default to ballend when deserializing Ballnose
+ "Cylindrical": "endmill",
+ "Conical": "v-bit",
+ "Snubnose": "chamfer",
+}
tooltemplate = {
"units": "metric",
diff --git a/src/Mod/CAM/Path/Tool/shape/__init__.py b/src/Mod/CAM/Path/Tool/shape/__init__.py
index a6d5cf04bc..22dca5562a 100644
--- a/src/Mod/CAM/Path/Tool/shape/__init__.py
+++ b/src/Mod/CAM/Path/Tool/shape/__init__.py
@@ -16,6 +16,7 @@ from .models.probe import ToolBitShapeProbe
from .models.reamer import ToolBitShapeReamer
from .models.slittingsaw import ToolBitShapeSlittingSaw
from .models.tap import ToolBitShapeTap
+from .models.taperedballnose import ToolBitShapeTaperedBallNose
from .models.threadmill import ToolBitShapeThreadMill
from .models.vbit import ToolBitShapeVBit
from .models.icon import (
@@ -42,6 +43,7 @@ __all__ = [
"ToolBitShapeReamer",
"ToolBitShapeSlittingSaw",
"ToolBitShapeTap",
+ "ToolBitShapeTaperedBallNose",
"ToolBitShapeThreadMill",
"ToolBitShapeVBit",
"TOOL_BIT_SHAPE_NAMES",
diff --git a/src/Mod/CAM/Path/Tool/shape/models/taperedballnose.py b/src/Mod/CAM/Path/Tool/shape/models/taperedballnose.py
new file mode 100644
index 0000000000..80074e75fe
--- /dev/null
+++ b/src/Mod/CAM/Path/Tool/shape/models/taperedballnose.py
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+################################################################################
+# #
+# © 2026 Billy Huddleston #
+# #
+# FreeCAD is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Lesser General Public License as #
+# published by the Free Software Foundation, either version 2.1 #
+# of the License, or (at your option) any later version. #
+# #
+# FreeCAD 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 Lesser General Public License for more details. #
+# #
+# You should have received a copy of the GNU Lesser General Public #
+# License along with FreeCAD. If not, see https://www.gnu.org/licenses #
+# #
+################################################################################
+
+import FreeCAD
+from typing import Tuple, Mapping
+from .base import ToolBitShape
+
+
+class ToolBitShapeTaperedBallNose(ToolBitShape):
+ name: str = "TaperedBallNose"
+ aliases = ("taperedballnose",)
+
+ @classmethod
+ def schema(cls) -> Mapping[str, Tuple[str, str]]:
+ return {
+ "CuttingEdgeHeight": (
+ FreeCAD.Qt.translate("ToolBitShape", "Cutting edge height"),
+ "App::PropertyLength",
+ ),
+ "Diameter": (
+ FreeCAD.Qt.translate("ToolBitShape", "Diameter"),
+ "App::PropertyLength",
+ ),
+ "Flutes": (
+ FreeCAD.Qt.translate("ToolBitShape", "Flutes"),
+ "App::PropertyInteger",
+ ),
+ "Length": (
+ FreeCAD.Qt.translate("ToolBitShape", "Overall tool length"),
+ "App::PropertyLength",
+ ),
+ "ShankDiameter": (
+ FreeCAD.Qt.translate("ToolBitShape", "Shank diameter"),
+ "App::PropertyLength",
+ ),
+ "TaperAngle": (
+ FreeCAD.Qt.translate("ToolBitShape", "Included Taper angle"),
+ "App::PropertyAngle",
+ ),
+ "TaperDiameter": (
+ FreeCAD.Qt.translate("ToolBitShape", "Diameter at top of Taper"),
+ "App::PropertyLength",
+ ),
+ }
+
+ @property
+ def label(self) -> str:
+ return FreeCAD.Qt.translate("ToolBitShape", "Tapered Ball Nose")
diff --git a/src/Mod/CAM/Path/Tool/shape/ui/shapewidget.py b/src/Mod/CAM/Path/Tool/shape/ui/shapewidget.py
index 15470c0efc..43667192a7 100644
--- a/src/Mod/CAM/Path/Tool/shape/ui/shapewidget.py
+++ b/src/Mod/CAM/Path/Tool/shape/ui/shapewidget.py
@@ -45,7 +45,7 @@ class ShapeWidget(QtGui.QWidget):
self.layout.setAlignment(QtCore.Qt.AlignHCenter)
self.shape = shape
- self.icon_size = icon_size or QtCore.QSize(140, 165) # 200 x 235
+ self.icon_size = icon_size or QtCore.QSize(263, 372) # A4 aspect ratio
self.icon_widget = QtGui.QLabel()
self.layout.addWidget(self.icon_widget)
diff --git a/src/Mod/CAM/Path/Tool/toolbit/__init__.py b/src/Mod/CAM/Path/Tool/toolbit/__init__.py
index c1603981be..9b95591711 100644
--- a/src/Mod/CAM/Path/Tool/toolbit/__init__.py
+++ b/src/Mod/CAM/Path/Tool/toolbit/__init__.py
@@ -15,6 +15,7 @@ from .models.radius import ToolBitRadius
from .models.probe import ToolBitProbe
from .models.reamer import ToolBitReamer
from .models.slittingsaw import ToolBitSlittingSaw
+from .models.taperedballnose import ToolBitTaperedBallNose
from .models.tap import ToolBitTap
from .models.threadmill import ToolBitThreadMill
from .models.vbit import ToolBitVBit
@@ -33,6 +34,7 @@ __all__ = [
"ToolBitProbe",
"ToolBitReamer",
"ToolBitSlittingSaw",
+ "ToolBitTaperedBallNose",
"ToolBitTap",
"ToolBitThreadMill",
"ToolBitVBit",
diff --git a/src/Mod/CAM/Path/Tool/toolbit/models/taperedballnose.py b/src/Mod/CAM/Path/Tool/toolbit/models/taperedballnose.py
new file mode 100644
index 0000000000..2ab1124403
--- /dev/null
+++ b/src/Mod/CAM/Path/Tool/toolbit/models/taperedballnose.py
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+################################################################################
+# #
+# © 2026 Billy Huddleston #
+# #
+# FreeCAD is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU Lesser General Public License as #
+# published by the Free Software Foundation, either version 2.1 #
+# of the License, or (at your option) any later version. #
+# #
+# FreeCAD 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 Lesser General Public License for more details. #
+# #
+# You should have received a copy of the GNU Lesser General Public #
+# License along with FreeCAD. If not, see https://www.gnu.org/licenses #
+# #
+################################################################################
+import FreeCAD
+import Path
+from ...shape import ToolBitShapeTaperedBallNose
+from ..mixins import RotaryToolBitMixin, CuttingToolMixin
+from .base import ToolBit
+
+
+class ToolBitTaperedBallNose(ToolBit, CuttingToolMixin, RotaryToolBitMixin):
+ SHAPE_CLASS = ToolBitShapeTaperedBallNose
+
+ def __init__(self, shape: ToolBitShapeTaperedBallNose, id: str | None = None):
+ Path.Log.track(f"ToolBitTaperedBallNose __init__ called with shape: {shape}, id: {id}")
+ super().__init__(shape, id=id)
+ CuttingToolMixin.__init__(self, self.obj)
+
+ @property
+ def summary(self) -> str:
+ diameter = self.get_property_str("Diameter", "?", precision=3)
+ flutes = self.get_property("Flutes")
+ cutting_edge_height = self.get_property_str("CuttingEdgeHeight", "?", precision=3)
+ taper_angle = self.get_property_str("TaperAngle", "?", precision=1)
+
+ return FreeCAD.Qt.translate(
+ "CAM",
+ f"{diameter} tip, {taper_angle} taper, {flutes}-flute tapered ball nose, {cutting_edge_height} cutting edge",
+ )
diff --git a/src/Mod/CAM/Path/Tool/toolbit/serializers/camotics.py b/src/Mod/CAM/Path/Tool/toolbit/serializers/camotics.py
index 755cbd585b..00a9d124e2 100644
--- a/src/Mod/CAM/Path/Tool/toolbit/serializers/camotics.py
+++ b/src/Mod/CAM/Path/Tool/toolbit/serializers/camotics.py
@@ -34,11 +34,17 @@ from ...assets.asset import Asset
SHAPEMAP = {
"ballend": "Ballnose",
"endmill": "Cylindrical",
+ "taperedballnose": "Ballnose",
"v-bit": "Conical",
"vbit": "Conical",
"chamfer": "Snubnose",
}
-SHAPEMAP_REVERSE = dict((v, k) for k, v in SHAPEMAP.items())
+SHAPEMAP_REVERSE = {
+ "Ballnose": "ballend", # Default to ballend when deserializing Ballnose
+ "Cylindrical": "endmill",
+ "Conical": "v-bit",
+ "Snubnose": "chamfer",
+}
tooltemplate = {
"units": "metric",
diff --git a/src/Mod/CAM/Path/Tool/toolbit/ui/editor.py b/src/Mod/CAM/Path/Tool/toolbit/ui/editor.py
index 11ed760bf1..afa6ee9f97 100644
--- a/src/Mod/CAM/Path/Tool/toolbit/ui/editor.py
+++ b/src/Mod/CAM/Path/Tool/toolbit/ui/editor.py
@@ -99,8 +99,6 @@ class ToolBitPropertiesWidget(QtGui.QWidget):
properties_layout.setStretchFactor(self._property_editor, 1)
main_layout.addWidget(properties_group_box)
-
- # Add stretch before shape widget to push it towards the bottom
main_layout.addStretch(1)
# Layout for centering the shape widget (created later)
@@ -276,18 +274,36 @@ class ToolBitEditor(QtGui.QWidget):
)
self._tab_closed = False
- # Get first tab from the form, add the shape widget at the top.
+ # Get first tab from the form, add the shape widget to the right.
tool_tab_layout = self.form.toolTabLayout
- widget = ShapeWidget(toolbit._tool_bit_shape)
- tool_tab_layout.addWidget(widget)
- # Add tool properties editor to the same tab.
+ # Create a horizontal layout for the tab content
+ tab_content_layout = QtGui.QHBoxLayout()
+
+ # Add tool properties editor to the left with stretch
self._props = ToolBitPropertiesWidget(toolbit, tool_no, self, icon=icon)
self._last_units_value = self._get_units_value(self._props)
self._props.toolBitChanged.connect(self._on_toolbit_changed)
self._props.toolBitChanged.connect(self._update)
self._props.toolNoChanged.connect(self._on_tool_no_changed)
- tool_tab_layout.addWidget(self._props)
+
+ # Wrap properties in a scroll area for vertical scrolling
+ scroll_area = QtGui.QScrollArea()
+ scroll_area.setWidget(self._props)
+ scroll_area.setWidgetResizable(True)
+ scroll_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+ scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+ scroll_area.setMinimumHeight(550) # Set minimum height for the scroll area
+ scroll_area.setMaximumHeight(600) # Set maximum height to prevent excessive growth
+
+ tab_content_layout.addWidget(scroll_area, 1)
+
+ # Add shape widget to the right without stretch
+ widget = ShapeWidget(toolbit._tool_bit_shape)
+ tab_content_layout.addWidget(widget, 0)
+
+ # Add the horizontal layout to the tab layout
+ tool_tab_layout.addLayout(tab_content_layout)
self.form.tabWidget.setCurrentIndex(0)
self.form.tabWidget.currentChanged.connect(self._on_tab_switched)
@@ -350,19 +366,27 @@ class ToolBitEditor(QtGui.QWidget):
are in sync with the current toolbit's units, and user changes are preserved
because the ToolBit object is always up to date.
"""
- # Remove the current property editor widget
+ # Get the horizontal layout and scroll area
tool_tab_layout = self.form.toolTabLayout
- tool_tab_layout.removeWidget(self._props)
+ tab_content_layout = tool_tab_layout.itemAt(0).layout() # Get the QHBoxLayout
+ scroll_area = tab_content_layout.itemAt(0).widget() # Get the scroll area
+
+ # Remove the current property editor widget from scroll area
+ scroll_area.takeWidget()
self._props.deleteLater()
+
# Restore the original schema
FreeCAD.Units.setSchema(self._original_schema)
+
# Recreate the property editor with the current toolbit
self._props = ToolBitPropertiesWidget(self.toolbit, self.tool_no, self, icon=False)
self._last_units_value = self._get_units_value(self._props)
self._props.toolBitChanged.connect(self._on_toolbit_changed)
self._props.toolBitChanged.connect(self._update)
self._props.toolNoChanged.connect(self._on_tool_no_changed)
- tool_tab_layout.addWidget(self._props)
+
+ # Set the new widget in the scroll area
+ scroll_area.setWidget(self._props)
self.form.tabWidget.setCurrentIndex(0)
def _restore_original_schema(self):
diff --git a/src/Mod/CAM/Tools/Shape/ballend.svg b/src/Mod/CAM/Tools/Shape/ballend.svg
index a7d7e1b89a..cbb0039609 100644
--- a/src/Mod/CAM/Tools/Shape/ballend.svg
+++ b/src/Mod/CAM/Tools/Shape/ballend.svg
@@ -8,7 +8,7 @@
version="1.1"
id="svg5"
xml:space="preserve"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="ballend.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@@ -25,14 +25,14 @@
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
- inkscape:zoom="0.74991656"
- inkscape:cx="176.68632"
- inkscape:cy="308.70101"
- inkscape:window-width="2818"
- inkscape:window-height="1645"
- inkscape:window-x="1022"
- inkscape:window-y="192"
- inkscape:window-maximized="0"
+ inkscape:zoom="0.61035884"
+ inkscape:cx="409.59512"
+ inkscape:cy="577.52912"
+ inkscape:window-width="1632"
+ inkscape:window-height="1013"
+ inkscape:window-x="1728"
+ inkscape:window-y="1050"
+ inkscape:window-maximized="1"
inkscape:current-layer="g547" />LLLLDDCCh
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.2222px;font-family:'URW Bookman L';-inkscape-font-specification:'URW Bookman L, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">h
diff --git a/src/Mod/CAM/Tools/Shape/drill.svg b/src/Mod/CAM/Tools/Shape/drill.svg
index 3bdd068d0e..a8bb89b7d7 100644
--- a/src/Mod/CAM/Tools/Shape/drill.svg
+++ b/src/Mod/CAM/Tools/Shape/drill.svg
@@ -6,7 +6,7 @@
height="297mm"
width="210mm"
sodipodi:docname="drill.svg"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@@ -24,15 +24,15 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
- inkscape:window-width="2340"
- inkscape:window-height="1659"
+ inkscape:window-width="1680"
+ inkscape:window-height="1050"
id="namedview45"
showgrid="false"
inkscape:zoom="0.35355339"
- inkscape:cx="-80.610173"
- inkscape:cy="442.64885"
- inkscape:window-x="1500"
- inkscape:window-y="263"
+ inkscape:cx="-82.024387"
+ inkscape:cy="446.89149"
+ inkscape:window-x="1680"
+ inkscape:window-y="1050"
inkscape:window-maximized="0"
inkscape:current-layer="layer1"
inkscape:showpageshadow="2"
@@ -66,14 +66,14 @@
offset="1"
id="stop17" />image/svg+xmlαα
+ orient="auto"
+ viewBox="0 0 12.705841 9.5264135"
+ markerWidth="12.705841"
+ markerHeight="9.5264139"
+ preserveAspectRatio="xMidYMid">
+ orient="auto"
+ viewBox="0 0 12.705841 9.5264135"
+ markerWidth="12.705841"
+ markerHeight="9.5264139"
+ preserveAspectRatio="xMidYMid">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
L
-
+
+
+
+
+
+
+
+
+
+
+
+
+
ddd
+ id="tspan5690-9">d
diff --git a/src/Mod/CAM/Tools/Shape/reamer.svg b/src/Mod/CAM/Tools/Shape/reamer.svg
index 1707a0495b..41a874341e 100644
--- a/src/Mod/CAM/Tools/Shape/reamer.svg
+++ b/src/Mod/CAM/Tools/Shape/reamer.svg
@@ -6,7 +6,7 @@
height="297mm"
width="210mm"
sodipodi:docname="reamer.svg"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@@ -24,17 +24,17 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
- inkscape:window-width="2166"
- inkscape:window-height="1490"
+ inkscape:window-width="1680"
+ inkscape:window-height="1050"
id="namedview71"
showgrid="false"
- inkscape:zoom="0.73495371"
- inkscape:cx="523.1622"
- inkscape:cy="775.55905"
- inkscape:window-x="1674"
- inkscape:window-y="259"
+ inkscape:zoom="0.41052622"
+ inkscape:cx="187.56415"
+ inkscape:cy="777.05147"
+ inkscape:window-x="1680"
+ inkscape:window-y="1050"
inkscape:window-maximized="0"
- inkscape:current-layer="g40"
+ inkscape:current-layer="layer1"
inkscape:document-rotation="0"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="true"
@@ -166,7 +166,11 @@
id="marker1181"
refX="0"
refY="0"
- orient="auto">HddT
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/bullnose.svg b/src/Mod/CAM/Tools/Shape/svg_source/bullnose.svg
new file mode 100644
index 0000000000..a9abd57060
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/bullnose.svg
@@ -0,0 +1,408 @@
+
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/chamfer.svg b/src/Mod/CAM/Tools/Shape/svg_source/chamfer.svg
new file mode 100644
index 0000000000..b7e1e38d8f
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/chamfer.svg
@@ -0,0 +1,452 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/dovetail.svg b/src/Mod/CAM/Tools/Shape/svg_source/dovetail.svg
new file mode 100644
index 0000000000..6ee794f7b4
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/dovetail.svg
@@ -0,0 +1,668 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/drill.svg b/src/Mod/CAM/Tools/Shape/svg_source/drill.svg
new file mode 100644
index 0000000000..28df70c63a
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/drill.svg
@@ -0,0 +1,284 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/endmill.svg b/src/Mod/CAM/Tools/Shape/svg_source/endmill.svg
new file mode 100644
index 0000000000..f264d41bff
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/endmill.svg
@@ -0,0 +1,626 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/probe.svg b/src/Mod/CAM/Tools/Shape/svg_source/probe.svg
new file mode 100644
index 0000000000..d7ad0793b6
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/probe.svg
@@ -0,0 +1,476 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/radius.svg b/src/Mod/CAM/Tools/Shape/svg_source/radius.svg
new file mode 100644
index 0000000000..92151061fc
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/radius.svg
@@ -0,0 +1,508 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/reamer.svg b/src/Mod/CAM/Tools/Shape/svg_source/reamer.svg
new file mode 100644
index 0000000000..41a874341e
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/reamer.svg
@@ -0,0 +1,594 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/slittingsaw.svg b/src/Mod/CAM/Tools/Shape/svg_source/slittingsaw.svg
new file mode 100644
index 0000000000..ef14f94699
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/slittingsaw.svg
@@ -0,0 +1,512 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/tap.svg b/src/Mod/CAM/Tools/Shape/svg_source/tap.svg
new file mode 100644
index 0000000000..b6e79c120b
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/tap.svg
@@ -0,0 +1,454 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/taperedballnose.svg b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnose.svg
new file mode 100644
index 0000000000..e6e78b352b
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnose.svg
@@ -0,0 +1,371 @@
+
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev1.svg b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev1.svg
new file mode 100644
index 0000000000..41d0081ebd
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev1.svg
@@ -0,0 +1,364 @@
+
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev2.svg b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev2.svg
new file mode 100644
index 0000000000..38a0c6fa98
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/taperedballnosev2.svg
@@ -0,0 +1,363 @@
+
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/thread-mill.svg b/src/Mod/CAM/Tools/Shape/svg_source/thread-mill.svg
new file mode 100644
index 0000000000..8851e2a42f
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/thread-mill.svg
@@ -0,0 +1,610 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/svg_source/v-bit.svg b/src/Mod/CAM/Tools/Shape/svg_source/v-bit.svg
new file mode 100644
index 0000000000..e9dd988c4d
--- /dev/null
+++ b/src/Mod/CAM/Tools/Shape/svg_source/v-bit.svg
@@ -0,0 +1,467 @@
+
+
diff --git a/src/Mod/CAM/Tools/Shape/tap.svg b/src/Mod/CAM/Tools/Shape/tap.svg
index 4ef1c077e0..8b288bd86d 100644
--- a/src/Mod/CAM/Tools/Shape/tap.svg
+++ b/src/Mod/CAM/Tools/Shape/tap.svg
@@ -7,7 +7,7 @@
width="210mm"
sodipodi:docname="tap.svg"
xml:space="preserve"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
@@ -26,14 +26,14 @@
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
- inkscape:zoom="1.0986719"
- inkscape:cx="257.58372"
- inkscape:cy="643.95931"
- inkscape:window-width="2311"
- inkscape:window-height="1509"
- inkscape:window-x="1156"
- inkscape:window-y="209"
- inkscape:window-maximized="0"
+ inkscape:zoom="0.81750039"
+ inkscape:cx="299.69405"
+ inkscape:cy="489.90802"
+ inkscape:window-width="1632"
+ inkscape:window-height="1013"
+ inkscape:window-x="1728"
+ inkscape:window-y="1050"
+ inkscape:window-maximized="1"
inkscape:current-layer="svg8" />image/svg+xmlDhh
+
+
+
diff --git a/src/Mod/CAM/Tools/Shape/thread-mill.svg b/src/Mod/CAM/Tools/Shape/thread-mill.svg
index 904d1f3aa5..ae1e681f23 100644
--- a/src/Mod/CAM/Tools/Shape/thread-mill.svg
+++ b/src/Mod/CAM/Tools/Shape/thread-mill.svg
@@ -7,7 +7,7 @@
width="210mm"
sodipodi:docname="thread-mill.svg"
xml:space="preserve"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
@@ -27,13 +27,13 @@
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.71628115"
- inkscape:cx="407.66115"
- inkscape:cy="655.46888"
- inkscape:window-width="1838"
- inkscape:window-height="1205"
- inkscape:window-x="2002"
- inkscape:window-y="638"
- inkscape:window-maximized="0"
+ inkscape:cx="256.88237"
+ inkscape:cy="573.09898"
+ inkscape:window-width="1632"
+ inkscape:window-height="1013"
+ inkscape:window-x="1728"
+ inkscape:window-y="1050"
+ inkscape:window-maximized="1"
inkscape:current-layer="svg8" />DDNn
+ style="fill:none;stroke:#000000;stroke-width:0.753157;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
diff --git a/src/Mod/CAM/Tools/Shape/v-bit.svg b/src/Mod/CAM/Tools/Shape/v-bit.svg
index e6e327b813..a9517165dd 100644
--- a/src/Mod/CAM/Tools/Shape/v-bit.svg
+++ b/src/Mod/CAM/Tools/Shape/v-bit.svg
@@ -7,7 +7,7 @@
width="210mm"
sodipodi:docname="v-bit.svg"
xml:space="preserve"
- inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
@@ -26,14 +26,14 @@
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
- inkscape:zoom="0.7127433"
- inkscape:cx="623.64669"
- inkscape:cy="637.67699"
- inkscape:window-width="2860"
- inkscape:window-height="1491"
- inkscape:window-x="536"
- inkscape:window-y="363"
- inkscape:window-maximized="0"
+ inkscape:zoom="0.71907494"
+ inkscape:cx="333.76215"
+ inkscape:cy="581.99776"
+ inkscape:window-width="1632"
+ inkscape:window-height="1013"
+ inkscape:window-x="1728"
+ inkscape:window-y="1050"
+ inkscape:window-maximized="1"
inkscape:current-layer="svg8" />DDddhh