From 81faf7727c7fbb837dcfee2de5dd7d36b02c5667 Mon Sep 17 00:00:00 2001 From: Billy Date: Sun, 24 Aug 2025 15:42:56 -0400 Subject: [PATCH] CAM: Remove hardcoded style for Tool Number, Fix TestPathToolBitSerializer Fix issue with toolshapes Renamed fillet to radius Added Tool Type Filter to library Fix units so that they honor user preference Remove the QToolBox widget from the Shape Selector page and combine into a single page. Fix issue with PropertyBag so that CustomPropertyGroups as a string is converted to enum and enums are handled correctly. Update TestPathPropertyBag test for enum changes. Update TestPathToolBitListWidget Update TestPathToolLibrarySerializer to match new LinuxCNC output Fix LinuxCNC export too handle ALL tool types, use user preferences for units, and include all lcnc fields --- src/Mod/CAM/CAMTests/TestPathPropertyBag.py | 22 +++- .../CAM/CAMTests/TestPathToolBitListWidget.py | 2 +- .../CAM/CAMTests/TestPathToolBitSerializer.py | 2 +- .../CAMTests/TestPathToolLibrarySerializer.py | 8 +- src/Mod/CAM/CMakeLists.txt | 8 +- .../CAM/Gui/Resources/panels/ShapeSelector.ui | 24 +--- src/Mod/CAM/Path/Base/Gui/PropertyBag.py | 13 +- src/Mod/CAM/Path/Base/PropertyBag.py | 77 +++++++++--- src/Mod/CAM/Path/Base/Util.py | 6 +- .../Path/Tool/library/serializers/linuxcnc.py | 33 +++-- src/Mod/CAM/Path/Tool/library/ui/browser.py | 100 +++++++++++++++ src/Mod/CAM/Path/Tool/library/ui/dock.py | 16 ++- src/Mod/CAM/Path/Tool/shape/__init__.py | 4 +- src/Mod/CAM/Path/Tool/shape/models/custom.py | 24 +++- .../shape/models/{fillet.py => radius.py} | 19 +-- .../CAM/Path/Tool/shape/ui/shapeselector.py | 7 +- src/Mod/CAM/Path/Tool/toolbit/__init__.py | 4 +- src/Mod/CAM/Path/Tool/toolbit/models/base.py | 5 + .../CAM/Path/Tool/toolbit/models/custom.py | 29 +++++ src/Mod/CAM/Path/Tool/toolbit/models/probe.py | 29 +++++ .../toolbit/models/{fillet.py => radius.py} | 14 +-- src/Mod/CAM/Path/Tool/toolbit/ui/tablecell.py | 4 - src/Mod/CAM/Path/Tool/toolbit/util.py | 13 +- src/Mod/CAM/Tools/Shape/fillet.fcstd | Bin 17383 -> 0 bytes src/Mod/CAM/Tools/Shape/radius.fcstd | Bin 0 -> 14627 bytes .../Tools/Shape/{fillet.svg => radius.svg} | 119 +++++++++++++----- src/Mod/CAM/Tools/Shape/thread-mill.fcstd | Bin 16823 -> 15032 bytes src/Mod/CAM/Tools/Shape/v-bit.fcstd | Bin 18822 -> 13977 bytes 28 files changed, 447 insertions(+), 135 deletions(-) rename src/Mod/CAM/Path/Tool/shape/models/{fillet.py => radius.py} (86%) rename src/Mod/CAM/Path/Tool/toolbit/models/{fillet.py => radius.py} (82%) delete mode 100644 src/Mod/CAM/Tools/Shape/fillet.fcstd create mode 100644 src/Mod/CAM/Tools/Shape/radius.fcstd rename src/Mod/CAM/Tools/Shape/{fillet.svg => radius.svg} (82%) diff --git a/src/Mod/CAM/CAMTests/TestPathPropertyBag.py b/src/Mod/CAM/CAMTests/TestPathPropertyBag.py index 0cf14f129a..3cff57c1e3 100644 --- a/src/Mod/CAM/CAMTests/TestPathPropertyBag.py +++ b/src/Mod/CAM/CAMTests/TestPathPropertyBag.py @@ -25,6 +25,20 @@ import Path.Base.PropertyBag as PathPropertyBag import CAMTests.PathTestUtils as PathTestUtils +def as_group_list(groups): + """Normalize CustomPropertyGroups to a list of strings.""" + if groups is None: + return [] + if isinstance(groups, (list, tuple)): + return list(groups) + if isinstance(groups, str): + return [groups] + try: + return list(groups) + except Exception: + return [str(groups)] + + class TestPathPropertyBag(PathTestUtils.PathTestBase): def setUp(self): self.doc = FreeCAD.newDocument("test-property-bag") @@ -37,7 +51,7 @@ class TestPathPropertyBag(PathTestUtils.PathTestBase): bag = PathPropertyBag.Create() self.assertTrue(hasattr(bag, "Proxy")) self.assertEqual(bag.Proxy.getCustomProperties(), []) - self.assertEqual(bag.CustomPropertyGroups, []) + self.assertEqual(as_group_list(bag.CustomPropertyGroups), []) def test01(self): """adding properties to a PropertyBag is tracked properly""" @@ -48,7 +62,7 @@ class TestPathPropertyBag(PathTestUtils.PathTestBase): bag.Title = "Madame" self.assertEqual(bag.Title, "Madame") self.assertEqual(bag.Proxy.getCustomProperties(), ["Title"]) - self.assertEqual(bag.CustomPropertyGroups, ["Address"]) + self.assertEqual(as_group_list(bag.CustomPropertyGroups), ["Address"]) def test02(self): """refreshCustomPropertyGroups deletes empty groups""" @@ -59,7 +73,7 @@ class TestPathPropertyBag(PathTestUtils.PathTestBase): bag.removeProperty("Title") proxy.refreshCustomPropertyGroups() self.assertEqual(bag.Proxy.getCustomProperties(), []) - self.assertEqual(bag.CustomPropertyGroups, []) + self.assertEqual(as_group_list(bag.CustomPropertyGroups), []) def test03(self): """refreshCustomPropertyGroups does not delete non-empty groups""" @@ -72,4 +86,4 @@ class TestPathPropertyBag(PathTestUtils.PathTestBase): bag.removeProperty("Gender") proxy.refreshCustomPropertyGroups() self.assertEqual(bag.Proxy.getCustomProperties(), ["Title"]) - self.assertEqual(bag.CustomPropertyGroups, ["Address"]) + self.assertEqual(as_group_list(bag.CustomPropertyGroups), ["Address"]) diff --git a/src/Mod/CAM/CAMTests/TestPathToolBitListWidget.py b/src/Mod/CAM/CAMTests/TestPathToolBitListWidget.py index 2c233856ca..182695b51f 100644 --- a/src/Mod/CAM/CAMTests/TestPathToolBitListWidget.py +++ b/src/Mod/CAM/CAMTests/TestPathToolBitListWidget.py @@ -55,7 +55,7 @@ class TestToolBitListWidget(PathTestWithAssets): self.assertEqual(cell_widget.tool_no, str(tool_no)) self.assertEqual(cell_widget.upper_text, toolbit.label) # Assuming the 5mm_Endmill asset has a shape named 'Endmill' - self.assertEqual(cell_widget.lower_text, "5 mm 4-flute endmill, 30 mm cutting edge") + self.assertEqual(cell_widget.lower_text, "5.00 mm 4-flute endmill, 30.00 mm cutting edge") # Verify URI is stored in item data stored_uri = item.data(ToolBitUriRole) diff --git a/src/Mod/CAM/CAMTests/TestPathToolBitSerializer.py b/src/Mod/CAM/CAMTests/TestPathToolBitSerializer.py index 7a9ea41995..fbc8cf16fa 100644 --- a/src/Mod/CAM/CAMTests/TestPathToolBitSerializer.py +++ b/src/Mod/CAM/CAMTests/TestPathToolBitSerializer.py @@ -149,7 +149,7 @@ class TestYamlToolBitSerializer(_BaseToolBitSerializerTestCase): self.assertEqual(data.get("shape"), "endmill.fcstd") self.assertEqual(data.get("shape-type"), "Endmill") self.assertEqual(data.get("parameter", {}).get("Diameter"), "4.12 mm") - self.assertEqual(data.get("parameter", {}).get("Length"), "15.0 mm") + self.assertEqual(data.get("parameter", {}).get("Length"), "15.00 mm") def test_extract_dependencies(self): """Test dependency extraction for YAML.""" diff --git a/src/Mod/CAM/CAMTests/TestPathToolLibrarySerializer.py b/src/Mod/CAM/CAMTests/TestPathToolLibrarySerializer.py index ce578ddd27..597175c117 100644 --- a/src/Mod/CAM/CAMTests/TestPathToolLibrarySerializer.py +++ b/src/Mod/CAM/CAMTests/TestPathToolLibrarySerializer.py @@ -144,13 +144,13 @@ class TestLinuxCNCLibrarySerializer(TestPathToolLibrarySerializerBase): # Verify the content format (basic check) lines = serialized_data.decode("ascii", "ignore").strip().split("\n") self.assertEqual(len(lines), 3) - self.assertEqual(lines[0], "T1 P0 D6.000 ;Endmill 6mm") - self.assertEqual(lines[1], "T2 P0 D3.000 ;Endmill 3mm") - self.assertEqual(lines[2], "T3 P0 D5.000 ;Ballend 5mm") + self.assertEqual(lines[0], "T1 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D6.00 I0 J0 Q0 ;Endmill 6mm") + self.assertEqual(lines[1], "T2 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D3.00 I0 J0 Q0 ;Endmill 3mm") + self.assertEqual(lines[2], "T3 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D5.00 I0 J0 Q0 ;Ballend 5mm") def test_linuxcnc_deserialize_not_implemented(self): serializer = LinuxCNCSerializer - dummy_data = b"T1 D6.0 ;Endmill 6mm\n" + dummy_data = b"T1 P0 X0 Y0 Z0 A0 B0 C0 U0 V0 W0 D6.00 I0 J0 Q0 ;Endmill 6mm\n" with self.assertRaises(NotImplementedError): serializer.deserialize(dummy_data, "dummy_id", {}) diff --git a/src/Mod/CAM/CMakeLists.txt b/src/Mod/CAM/CMakeLists.txt index 88a6f3643e..5cc41ed1b3 100644 --- a/src/Mod/CAM/CMakeLists.txt +++ b/src/Mod/CAM/CMakeLists.txt @@ -183,7 +183,7 @@ SET(PathPythonToolsToolBitModels_SRCS Path/Tool/toolbit/models/dovetail.py Path/Tool/toolbit/models/drill.py Path/Tool/toolbit/models/endmill.py - Path/Tool/toolbit/models/fillet.py + Path/Tool/toolbit/models/radius.py Path/Tool/toolbit/models/probe.py Path/Tool/toolbit/models/reamer.py Path/Tool/toolbit/models/slittingsaw.py @@ -264,7 +264,7 @@ SET(PathPythonToolsShapeModels_SRCS Path/Tool/shape/models/dovetail.py Path/Tool/shape/models/drill.py Path/Tool/shape/models/endmill.py - Path/Tool/shape/models/fillet.py + Path/Tool/shape/models/radius.py Path/Tool/shape/models/icon.py Path/Tool/shape/models/probe.py Path/Tool/shape/models/reamer.py @@ -455,8 +455,8 @@ SET(Tools_Shape_SRCS Tools/Shape/drill.svg Tools/Shape/endmill.fcstd Tools/Shape/endmill.svg - Tools/Shape/fillet.fcstd - Tools/Shape/fillet.svg + Tools/Shape/radius.fcstd + Tools/Shape/radius.svg Tools/Shape/probe.fcstd Tools/Shape/probe.svg Tools/Shape/reamer.fcstd diff --git a/src/Mod/CAM/Gui/Resources/panels/ShapeSelector.ui b/src/Mod/CAM/Gui/Resources/panels/ShapeSelector.ui index da9f2dbc17..86103f5d06 100644 --- a/src/Mod/CAM/Gui/Resources/panels/ShapeSelector.ui +++ b/src/Mod/CAM/Gui/Resources/panels/ShapeSelector.ui @@ -17,11 +17,11 @@ - - - 1 + + + true - + 0 @@ -30,22 +30,6 @@ 487 - - Standard tools - - - - - - 0 - 0 - 880 - 487 - - - - My tools - diff --git a/src/Mod/CAM/Path/Base/Gui/PropertyBag.py b/src/Mod/CAM/Path/Base/Gui/PropertyBag.py index f6bd417eae..f25b11e03a 100644 --- a/src/Mod/CAM/Path/Base/Gui/PropertyBag.py +++ b/src/Mod/CAM/Path/Base/Gui/PropertyBag.py @@ -150,7 +150,6 @@ class PropertyCreate(object): self.form.propertyEnum.textChanged.connect(self.updateUI) def updateUI(self): - typeSet = True if self.propertyIsEnumeration(): self.form.labelEnum.setEnabled(True) @@ -239,7 +238,17 @@ class TaskPanel(object): pass def _setupProperty(self, i, name): - typ = PathPropertyBag.getPropertyTypeName(self.obj.getTypeIdOfProperty(name)) + if name not in self.obj.PropertiesList: + Path.Log.warning(f"Property '{name}' not found in object {self.obj.Name}") + return + prop_type_id = self.obj.getTypeIdOfProperty(name) + try: + typ = PathPropertyBag.getPropertyTypeName(prop_type_id) + except IndexError: + Path.Log.error( + f"Unknown property type id '{prop_type_id}' for property '{name}' in object {self.obj.Name}" + ) + return val = PathUtil.getPropertyValueString(self.obj, name) info = self.obj.getDocumentationOfProperty(name) diff --git a/src/Mod/CAM/Path/Base/PropertyBag.py b/src/Mod/CAM/Path/Base/PropertyBag.py index e5f2657112..2b0fd946ab 100644 --- a/src/Mod/CAM/Path/Base/PropertyBag.py +++ b/src/Mod/CAM/Path/Base/PropertyBag.py @@ -68,12 +68,14 @@ class PropertyBag(object): CustomPropertyGroupDefault = "User" def __init__(self, obj): - obj.addProperty( - "App::PropertyStringList", - self.CustomPropertyGroups, - "Base", - QT_TRANSLATE_NOOP("App::Property", "List of custom property groups"), - ) + # Always add as enumeration + if not hasattr(obj, self.CustomPropertyGroups): + obj.addProperty( + "App::PropertyEnumeration", + self.CustomPropertyGroups, + "Base", + QT_TRANSLATE_NOOP("App::Property", "List of custom property groups"), + ) self.onDocumentRestored(obj) def dumps(self): @@ -96,15 +98,39 @@ class PropertyBag(object): def onDocumentRestored(self, obj): self.obj = obj - obj.setEditorMode(self.CustomPropertyGroups, 2) # hide + cpg = getattr(obj, self.CustomPropertyGroups, None) + # If it's a string list, convert to enum + if isinstance(cpg, list): + vals = cpg + try: + obj.removeProperty(self.CustomPropertyGroups) + except Exception: + pass + obj.addProperty( + "App::PropertyEnumeration", + self.CustomPropertyGroups, + "Base", + QT_TRANSLATE_NOOP("App::Property", "List of custom property groups"), + ) + if hasattr(obj, "setEnumerationsOfProperty"): + obj.setEnumerationsOfProperty(self.CustomPropertyGroups, vals) + else: + # Fallback: set the property value directly (may not work in all FreeCAD versions) + setattr(obj, self.CustomPropertyGroups, vals) + if hasattr(obj, "setEditorMode"): + obj.setEditorMode(self.CustomPropertyGroups, 2) # hide + elif hasattr(obj, "getEnumerationsOfProperty"): + if hasattr(obj, "setEditorMode"): + obj.setEditorMode(self.CustomPropertyGroups, 2) # hide def getCustomProperties(self): - """getCustomProperties() ... Return a list of all custom properties created in this container.""" - return [ - p - for p in self.obj.PropertiesList - if self.obj.getGroupOfProperty(p) in self.obj.CustomPropertyGroups - ] + """Return a list of all custom properties created in this container.""" + groups = [] + if hasattr(self.obj, "getEnumerationsOfProperty"): + groups = list(self.obj.getEnumerationsOfProperty(self.CustomPropertyGroups)) + else: + groups = list(getattr(self.obj, self.CustomPropertyGroups, [])) + return [p for p in self.obj.PropertiesList if self.obj.getGroupOfProperty(p) in groups] def addCustomProperty(self, propertyType, name, group=None, desc=None): """addCustomProperty(propertyType, name, group=None, desc=None) ... adds a custom property and tracks its group.""" @@ -112,15 +138,23 @@ class PropertyBag(object): desc = "" if group is None: group = self.CustomPropertyGroupDefault - groups = self.obj.CustomPropertyGroups + + # Always use enum for groups + if hasattr(self.obj, "getEnumerationsOfProperty"): + groups = list(self.obj.getEnumerationsOfProperty(self.CustomPropertyGroups)) + else: + groups = list(getattr(self.obj, self.CustomPropertyGroups, [])) name = self.__sanitizePropertyName(name) if not re.match("^[A-Za-z0-9_]*$", name): raise ValueError("Property Name can only contain letters and numbers") - if not group in groups: + if group not in groups: groups.append(group) - self.obj.CustomPropertyGroups = groups + if hasattr(self.obj, "setEnumerationsOfProperty"): + self.obj.setEnumerationsOfProperty(self.CustomPropertyGroups, groups) + else: + setattr(self.obj, self.CustomPropertyGroups, groups) self.obj.addProperty(propertyType, name, group, desc) return name @@ -129,9 +163,16 @@ class PropertyBag(object): customGroups = [] for p in self.obj.PropertiesList: group = self.obj.getGroupOfProperty(p) - if group in self.obj.CustomPropertyGroups and not group in customGroups: + if hasattr(self.obj, "getEnumerationsOfProperty"): + groups = list(self.obj.getEnumerationsOfProperty(self.CustomPropertyGroups)) + else: + groups = list(getattr(self.obj, self.CustomPropertyGroups, [])) + if group in groups and group not in customGroups: customGroups.append(group) - self.obj.CustomPropertyGroups = customGroups + if hasattr(self.obj, "setEnumerationsOfProperty"): + self.obj.setEnumerationsOfProperty(self.CustomPropertyGroups, customGroups) + else: + setattr(self.obj, self.CustomPropertyGroups, customGroups) def Create(name="PropertyBag"): diff --git a/src/Mod/CAM/Path/Base/Util.py b/src/Mod/CAM/Path/Base/Util.py index 33beb423e1..4905b8abda 100644 --- a/src/Mod/CAM/Path/Base/Util.py +++ b/src/Mod/CAM/Path/Base/Util.py @@ -78,10 +78,10 @@ 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) if attr is not None and isinstance(value, str): - if isinstance(attr, int): - value = int(value, 0) - elif isinstance(attr, bool): + if isinstance(attr, bool): value = value.lower() in ["true", "1", "yes", "ok"] + elif isinstance(attr, int): + value = int(value, 0) if o and name: setattr(o, name, value) diff --git a/src/Mod/CAM/Path/Tool/library/serializers/linuxcnc.py b/src/Mod/CAM/Path/Tool/library/serializers/linuxcnc.py index 992dfe6760..1b599917fa 100644 --- a/src/Mod/CAM/Path/Tool/library/serializers/linuxcnc.py +++ b/src/Mod/CAM/Path/Tool/library/serializers/linuxcnc.py @@ -50,18 +50,29 @@ class LinuxCNCSerializer(AssetSerializer): output = io.BytesIO() for bit_no, bit in sorted(asset._bit_nos.items()): - assert isinstance(bit, ToolBit) - if not isinstance(bit, RotaryToolBitMixin): - Path.Log.warning( - f"Skipping too {bit.label} (bit.id) because it is not a rotary tool" - ) - continue - diameter = bit.get_diameter() + # Connor: assert isinstance(bit, ToolBit) + # if not isinstance(bit, RotaryToolBitMixin): + # Path.Log.warning( + # f"Skipping too {bit.label} (bit.id) because it is not a rotary tool" + # ) + # continue + # Commenting this out. Why did we skip because it is not a rotary tool? + diameter = bit.get_diameter().getUserPreferred()[0] pocket = "P0" # TODO: is there a better way? - - # Format diameter to one decimal place and remove units - diameter_value = diameter.Value if hasattr(diameter, "Value") else diameter - line = f"T{bit_no} {pocket} D{diameter_value:.3f} ;{bit.label}\n" + # TODO: Strip units by splitting at the first space if diameter is a string + # This is where we need a machine definition so we can export these out correctly + # for a metric or imperial machine + # Using user preferred for now + if hasattr(diameter, "Value"): + diameter_value = diameter.Value + elif isinstance(diameter, str): + diameter_value = diameter.split(" ")[0] + else: + diameter_value = diameter + line = ( + f"T{bit_no} {pocket} X0 Y0 Z0 A0 B0 C0 U0 V0 W0 " + f"D{diameter_value} I0 J0 Q0 ;{bit.label}\n" + ) output.write(line.encode("utf-8")) return output.getvalue() diff --git a/src/Mod/CAM/Path/Tool/library/ui/browser.py b/src/Mod/CAM/Path/Tool/library/ui/browser.py index c5527772a1..ff1f5f15ce 100644 --- a/src/Mod/CAM/Path/Tool/library/ui/browser.py +++ b/src/Mod/CAM/Path/Tool/library/ui/browser.py @@ -65,8 +65,17 @@ class LibraryBrowserWidget(ToolBitBrowserWidget): compact=compact, ) self.current_library: Optional[Library] = None + self._selected_tool_type: Optional[str] = None self.layout().setContentsMargins(0, 0, 0, 0) + # Add tool type filter combo box to the base widget + self._tool_type_combo = QtGui.QComboBox() + self._tool_type_combo.setSizePolicy( + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred + ) + self._top_layout.insertWidget(0, self._tool_type_combo, 1) + self._tool_type_combo.currentTextChanged.connect(self._on_tool_type_combo_changed) + self.restore_last_sort_order() self.load_last_library() @@ -177,6 +186,35 @@ class LibraryBrowserWidget(ToolBitBrowserWidget): if library: Path.Preferences.setLastToolLibrary(str(library.get_uri())) + def _get_available_tool_types(self): + """Get all available tool types from the current assets.""" + tool_types = set() + # Make sure we have assets to work with + if not hasattr(self, "_all_assets") or not self._all_assets: + return [] + + for asset in self._all_assets: + # Use get_shape_name() method to get the tool type + if hasattr(asset, "get_shape_name"): + tool_type = asset.get_shape_name() + if tool_type: + tool_types.add(tool_type) + + return sorted(tool_types) + + def _get_filtered_assets(self): + """Get assets filtered by tool type if a specific type is selected.""" + if not self._selected_tool_type or self._selected_tool_type == "All Tool Types": + return self._all_assets + + filtered_assets = [] + for asset in self._all_assets: + if hasattr(asset, "get_shape_name"): + tool_type = asset.get_shape_name() + if tool_type == self._selected_tool_type: + filtered_assets.append(asset) + return filtered_assets + def _update_tool_list(self): """Updates the tool list based on the current library.""" if self.current_library: @@ -187,8 +225,34 @@ class LibraryBrowserWidget(ToolBitBrowserWidget): self._all_assets = cast(List[ToolBit], all_toolbits) self._sort_assets() self._tool_list_widget.clear_list() + # Update tool type combo after assets are loaded + if hasattr(self, "_tool_type_combo"): + self._update_tool_type_combo() self._update_list() + def _update_list(self): + """Updates the list widget with filtered assets.""" + self._tool_list_widget.clear_list() + filtered_assets = self._get_filtered_assets() + + # Apply search filter if there is one + search_term = self._search_edit.text().lower() + if search_term: + search_filtered = [] + for asset in filtered_assets: + if search_term in asset.label.lower(): + search_filtered.append(asset) + continue + # Also search in tool type + if hasattr(asset, "get_shape_name"): + tool_type = asset.get_shape_name() + if tool_type and search_term in tool_type.lower(): + search_filtered.append(asset) + filtered_assets = search_filtered + + for asset in filtered_assets: + self._tool_list_widget.add_toolbit(asset) + def _add_shortcuts(self): """Adds keyboard shortcuts for common actions.""" Path.Log.debug("LibraryBrowserWidget._add_shortcuts: Called.") @@ -476,6 +540,32 @@ class LibraryBrowserWidget(ToolBitBrowserWidget): self._asset_manager.add(library) self.refresh() + def _update_tool_type_combo(self): + """Update the tool type combo box with available types.""" + current_selection = self._tool_type_combo.currentText() + self._tool_type_combo.blockSignals(True) + try: + self._tool_type_combo.clear() + self._tool_type_combo.addItem("All Tool Types") + + for tool_type in self._get_available_tool_types(): + self._tool_type_combo.addItem(tool_type) + + # Restore selection if it still exists + index = self._tool_type_combo.findText(current_selection) + if index >= 0: + self._tool_type_combo.setCurrentIndex(index) + else: + self._tool_type_combo.setCurrentIndex(0) + self._selected_tool_type = "All Tool Types" + finally: + self._tool_type_combo.blockSignals(False) + + def _on_tool_type_combo_changed(self, tool_type): + """Handle tool type filter selection change.""" + self._selected_tool_type = tool_type + self._update_list() + class LibraryBrowserWithCombo(LibraryBrowserWidget): """ @@ -502,10 +592,15 @@ class LibraryBrowserWithCombo(LibraryBrowserWidget): self._top_layout.removeWidget(self._search_edit) layout.insertWidget(1, self._search_edit, 20) + # Library selection combo box self._library_combo = QtGui.QComboBox() self._library_combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) self._top_layout.insertWidget(0, self._library_combo, 1) self._library_combo.currentIndexChanged.connect(self._on_library_combo_changed) + + self._top_layout.removeWidget(self._tool_type_combo) + self._top_layout.insertWidget(1, self._tool_type_combo, 1) + self.current_library_changed.connect(self._on_current_library_changed) self._in_refresh = False @@ -554,6 +649,11 @@ class LibraryBrowserWithCombo(LibraryBrowserWidget): if not libraries: return if not self.current_library: + first_library = self._library_combo.itemData(0) + if first_library: + uri = first_library.get_uri() + library = self._asset_manager.get(uri, store=self._store_name, depth=1) + self.set_current_library(library) self._library_combo.setCurrentIndex(0) return diff --git a/src/Mod/CAM/Path/Tool/library/ui/dock.py b/src/Mod/CAM/Path/Tool/library/ui/dock.py index 215444ebf7..ff92275ed2 100644 --- a/src/Mod/CAM/Path/Tool/library/ui/dock.py +++ b/src/Mod/CAM/Path/Tool/library/ui/dock.py @@ -36,7 +36,6 @@ from ...toolbit import ToolBit from .editor import LibraryEditor from .browser import LibraryBrowserWithCombo - if False: Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule()) Path.Log.trackModule(Path.Log.thisModule()) @@ -66,7 +65,7 @@ class ToolBitLibraryDock(object): self.form_layout.setSpacing(4) # Create the browser widget - self.browser_widget = LibraryBrowserWidget(asset_manager=cam_assets) + self.browser_widget = LibraryBrowserWithCombo(asset_manager=cam_assets) self._setup_ui() @@ -80,8 +79,6 @@ class ToolBitLibraryDock(object): main_layout.setContentsMargins(4, 4, 4, 4) main_layout.setSpacing(4) - # Create the browser widget - self.browser_widget = LibraryBrowserWithCombo(asset_manager=cam_assets) main_layout.addWidget(self.browser_widget) # Create buttons @@ -89,11 +86,19 @@ class ToolBitLibraryDock(object): translate("CAM_ToolBit", "Open Library Editor") ) self.addToolControllerButton = QtGui.QPushButton(translate("CAM_ToolBit", "Add to Job")) + self.closeButton = QtGui.QPushButton(translate("CAM_ToolBit", "Close")) - # Add buttons to a horizontal layout + button_width = 120 + self.libraryEditorOpenButton.setMinimumWidth(button_width) + self.addToolControllerButton.setMinimumWidth(button_width) + self.closeButton.setMinimumWidth(button_width) + + # Add buttons to a horizontal layout, right-align Close button_layout = QtGui.QHBoxLayout() button_layout.addWidget(self.libraryEditorOpenButton) button_layout.addWidget(self.addToolControllerButton) + button_layout.addStretch(1) + button_layout.addWidget(self.closeButton) # Add the button layout to the main layout main_layout.addLayout(button_layout) @@ -106,6 +111,7 @@ class ToolBitLibraryDock(object): self.browser_widget.itemDoubleClicked.connect(self._on_doubleclick) self.libraryEditorOpenButton.clicked.connect(self._open_editor) self.addToolControllerButton.clicked.connect(self._add_tool_controller_to_doc) + self.closeButton.clicked.connect(self.form.reject) # Update the initial state of the UI self._update_state() diff --git a/src/Mod/CAM/Path/Tool/shape/__init__.py b/src/Mod/CAM/Path/Tool/shape/__init__.py index 70aa088931..1a19b62139 100644 --- a/src/Mod/CAM/Path/Tool/shape/__init__.py +++ b/src/Mod/CAM/Path/Tool/shape/__init__.py @@ -10,7 +10,7 @@ from .models.custom import ToolBitShapeCustom from .models.dovetail import ToolBitShapeDovetail from .models.drill import ToolBitShapeDrill from .models.endmill import ToolBitShapeEndmill -from .models.fillet import ToolBitShapeFillet +from .models.radius import ToolBitShapeRadius from .models.probe import ToolBitShapeProbe from .models.reamer import ToolBitShapeReamer from .models.slittingsaw import ToolBitShapeSlittingSaw @@ -36,7 +36,7 @@ __all__ = [ "ToolBitShapeDovetail", "ToolBitShapeDrill", "ToolBitShapeEndmill", - "ToolBitShapeFillet", + "ToolBitShapeRadius", "ToolBitShapeProbe", "ToolBitShapeReamer", "ToolBitShapeSlittingSaw", diff --git a/src/Mod/CAM/Path/Tool/shape/models/custom.py b/src/Mod/CAM/Path/Tool/shape/models/custom.py index bdd1c12e8b..a64069068d 100644 --- a/src/Mod/CAM/Path/Tool/shape/models/custom.py +++ b/src/Mod/CAM/Path/Tool/shape/models/custom.py @@ -34,9 +34,31 @@ class ToolBitShapeCustom(ToolBitShape): name: str = "Custom" aliases = ("custom",) + # Connor: We're going to treat custom tools as normal endmills @classmethod def schema(cls) -> Mapping[str, Tuple[str, str]]: - return {} + 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("ToolBitToolBitShapeShapeEndMill", "Shank diameter"), + "App::PropertyLength", + ), + } @property def label(self) -> str: diff --git a/src/Mod/CAM/Path/Tool/shape/models/fillet.py b/src/Mod/CAM/Path/Tool/shape/models/radius.py similarity index 86% rename from src/Mod/CAM/Path/Tool/shape/models/fillet.py rename to src/Mod/CAM/Path/Tool/shape/models/radius.py index 0156b910ff..be99fa6024 100644 --- a/src/Mod/CAM/Path/Tool/shape/models/fillet.py +++ b/src/Mod/CAM/Path/Tool/shape/models/radius.py @@ -25,23 +25,26 @@ from typing import Tuple, Mapping from .base import ToolBitShape -class ToolBitShapeFillet(ToolBitShape): - name = "Fillet" - aliases = ("fillet",) +class ToolBitShapeRadius(ToolBitShape): + name = "Radius" + aliases = ( + "radius", + "fillet", + ) @classmethod def schema(cls) -> Mapping[str, Tuple[str, str]]: return { - "CrownHeight": ( - FreeCAD.Qt.translate("ToolBitShape", "Crown height"), + "CuttingEdgeHeight": ( + FreeCAD.Qt.translate("ToolBitShape", "Cutting edge height"), "App::PropertyLength", ), "Diameter": ( FreeCAD.Qt.translate("ToolBitShape", "Diameter"), "App::PropertyLength", ), - "FilletRadius": ( - FreeCAD.Qt.translate("ToolBitShape", "Fillet radius"), + "CuttingRadius": ( + FreeCAD.Qt.translate("ToolBitShape", "Cutting radius"), "App::PropertyLength", ), "Flutes": ( @@ -60,4 +63,4 @@ class ToolBitShapeFillet(ToolBitShape): @property def label(self) -> str: - return FreeCAD.Qt.translate("ToolBitShape", "Filleted Chamfer") + return FreeCAD.Qt.translate("ToolBitShape", "Radius Mill") diff --git a/src/Mod/CAM/Path/Tool/shape/ui/shapeselector.py b/src/Mod/CAM/Path/Tool/shape/ui/shapeselector.py index 5e4e7ce8a6..542c847bad 100644 --- a/src/Mod/CAM/Path/Tool/shape/ui/shapeselector.py +++ b/src/Mod/CAM/Path/Tool/shape/ui/shapeselector.py @@ -39,7 +39,6 @@ class ShapeSelector: self.flows = {} self.update_shapes() - self.form.toolBox.setCurrentIndex(0) def _add_shape_group(self, toolbox): if toolbox in self.flows: @@ -70,8 +69,10 @@ class ShapeSelector: custom = cam_assets.fetch(asset_type="toolbitshape", store="local") for shape in custom: builtin.pop(shape.id, None) - self._add_shapes(self.form.standardTools, builtin.values()) - self._add_shapes(self.form.customTools, custom) + + # Combine all shapes into a single list + all_shapes = list(builtin.values()) + list(custom) + self._add_shapes(self.form.toolsContainer, all_shapes) def on_shape_button_clicked(self, shape): self.shape = shape diff --git a/src/Mod/CAM/Path/Tool/toolbit/__init__.py b/src/Mod/CAM/Path/Tool/toolbit/__init__.py index 9ae1e129ad..37fa8aa694 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/__init__.py +++ b/src/Mod/CAM/Path/Tool/toolbit/__init__.py @@ -10,7 +10,7 @@ from .models.custom import ToolBitCustom from .models.dovetail import ToolBitDovetail from .models.drill import ToolBitDrill from .models.endmill import ToolBitEndmill -from .models.fillet import ToolBitFillet +from .models.radius import ToolBitRadius from .models.probe import ToolBitProbe from .models.reamer import ToolBitReamer from .models.slittingsaw import ToolBitSlittingSaw @@ -28,7 +28,7 @@ __all__ = [ "ToolBitDovetail", "ToolBitDrill", "ToolBitEndmill", - "ToolBitFillet", + "ToolBitRadius", "ToolBitProbe", "ToolBitReamer", "ToolBitSlittingSaw", diff --git a/src/Mod/CAM/Path/Tool/toolbit/models/base.py b/src/Mod/CAM/Path/Tool/toolbit/models/base.py index 692ebe71e2..9cfff72974 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/models/base.py +++ b/src/Mod/CAM/Path/Tool/toolbit/models/base.py @@ -513,6 +513,7 @@ class ToolBit(Asset, ABC): self._create_base_properties() # Transfer property values from the detached object to the real object + self._suppress_visual_update = True temp_obj.copy_to(self.obj) # Ensure label is set @@ -520,6 +521,7 @@ class ToolBit(Asset, ABC): # Update the visual representation now that it's attached self._update_tool_properties() + self._suppress_visual_update = False self._update_visual_representation() def onChanged(self, obj, prop): @@ -528,6 +530,9 @@ class ToolBit(Asset, ABC): if "Restore" in obj.State: return + if getattr(self, "_suppress_visual_update", False): + return + if hasattr(self, "_in_update") and self._in_update: Path.Log.debug(f"Skipping onChanged for {obj.Label} due to active update.") return diff --git a/src/Mod/CAM/Path/Tool/toolbit/models/custom.py b/src/Mod/CAM/Path/Tool/toolbit/models/custom.py index b32004a796..b969e515e0 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/models/custom.py +++ b/src/Mod/CAM/Path/Tool/toolbit/models/custom.py @@ -35,3 +35,32 @@ class ToolBitCustom(ToolBit): @property def summary(self) -> str: return FreeCAD.Qt.translate("CAM", "Unknown custom toolbit type") + + # Connor: Adding in getters and setters for diameter and length + def get_diameter(self) -> FreeCAD.Units.Quantity: + """ + Get the diameter of the rotary tool bit from the shape. + """ + return self.obj.Diameter + + def set_diameter(self, diameter: FreeCAD.Units.Quantity): + """ + Set the diameter of the rotary tool bit on the shape. + """ + if not isinstance(diameter, FreeCAD.Units.Quantity): + raise ValueError("Diameter must be a FreeCAD Units.Quantity") + self.obj.Diameter = diameter + + def get_length(self) -> FreeCAD.Units.Quantity: + """ + Get the length of the rotary tool bit from the shape. + """ + return self.obj.Length + + def set_length(self, length: FreeCAD.Units.Quantity): + """ + Set the length of the rotary tool bit on the shape. + """ + if not isinstance(length, FreeCAD.Units.Quantity): + raise ValueError("Length must be a FreeCAD Units.Quantity") + self.obj.Length = length diff --git a/src/Mod/CAM/Path/Tool/toolbit/models/probe.py b/src/Mod/CAM/Path/Tool/toolbit/models/probe.py index 838667ea28..c07c6b879b 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/models/probe.py +++ b/src/Mod/CAM/Path/Tool/toolbit/models/probe.py @@ -46,3 +46,32 @@ class ToolBitProbe(ToolBit): def can_rotate(self) -> bool: return False + + # Connor: Add getters and setters for Diameter and Length + def get_diameter(self) -> FreeCAD.Units.Quantity: + """ + Get the diameter of the rotary tool bit from the shape. + """ + return self.obj.Diameter + + def set_diameter(self, diameter: FreeCAD.Units.Quantity): + """ + Set the diameter of the rotary tool bit on the shape. + """ + if not isinstance(diameter, FreeCAD.Units.Quantity): + raise ValueError("Diameter must be a FreeCAD Units.Quantity") + self.obj.Diameter = diameter + + def get_length(self) -> FreeCAD.Units.Quantity: + """ + Get the length of the rotary tool bit from the shape. + """ + return self.obj.Length + + def set_length(self, length: FreeCAD.Units.Quantity): + """ + Set the length of the rotary tool bit on the shape. + """ + if not isinstance(length, FreeCAD.Units.Quantity): + raise ValueError("Length must be a FreeCAD Units.Quantity") + self.obj.Length = length diff --git a/src/Mod/CAM/Path/Tool/toolbit/models/fillet.py b/src/Mod/CAM/Path/Tool/toolbit/models/radius.py similarity index 82% rename from src/Mod/CAM/Path/Tool/toolbit/models/fillet.py rename to src/Mod/CAM/Path/Tool/toolbit/models/radius.py index 05063a710c..b289e2bad5 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/models/fillet.py +++ b/src/Mod/CAM/Path/Tool/toolbit/models/radius.py @@ -21,25 +21,25 @@ # *************************************************************************** import FreeCAD import Path -from ...shape import ToolBitShapeFillet +from ...shape import ToolBitShapeRadius from ..mixins import RotaryToolBitMixin, CuttingToolMixin from .base import ToolBit -class ToolBitFillet(ToolBit, CuttingToolMixin, RotaryToolBitMixin): - SHAPE_CLASS = ToolBitShapeFillet +class ToolBitRadius(ToolBit, CuttingToolMixin, RotaryToolBitMixin): + SHAPE_CLASS = ToolBitShapeRadius - def __init__(self, shape: ToolBitShapeFillet, id: str | None = None): - Path.Log.track(f"ToolBitFillet __init__ called with shape: {shape}, id: {id}") + def __init__(self, shape: ToolBitShapeRadius, id: str | None = None): + Path.Log.track(f"ToolBitRadius __init__ called with shape: {shape}, id: {id}") super().__init__(shape, id=id) CuttingToolMixin.__init__(self, self.obj) @property def summary(self) -> str: - radius = self.get_property_str("FilletRadius", "?", precision=3) + radius = self.get_property_str("CuttingRadius", "?", precision=3) flutes = self.get_property("Flutes") diameter = self.get_property_str("ShankDiameter", "?", precision=3) return FreeCAD.Qt.translate( - "CAM", f"R{radius} fillet bit, {diameter} shank, {flutes}-flute" + "CAM", f"R{radius} radius mill, {diameter} shank, {flutes}-flute" ) diff --git a/src/Mod/CAM/Path/Tool/toolbit/ui/tablecell.py b/src/Mod/CAM/Path/Tool/toolbit/ui/tablecell.py index 7248bc56c6..e0bed94b43 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/ui/tablecell.py +++ b/src/Mod/CAM/Path/Tool/toolbit/ui/tablecell.py @@ -66,24 +66,20 @@ class TwoLineTableCell(QtGui.QWidget): self.vbox.addWidget(self.label_upper) self.vbox.addWidget(self.label_lower) - style = "color: {}".format(fg_color.name()) self.label_left = QtGui.QLabel() self.label_left.setMinimumWidth(40) self.label_left.setTextFormat(QtCore.Qt.RichText) self.label_left.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) - self.label_left.setStyleSheet(style) self.label_left.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) ratio = self.devicePixelRatioF() self.icon_size = QtCore.QSize(50 * ratio, 60 * ratio) self.icon_widget = QtGui.QLabel() - style = "color: {}".format(fg_color.name()) self.label_right = QtGui.QLabel() self.label_right.setMinimumWidth(40) self.label_right.setTextFormat(QtCore.Qt.RichText) self.label_right.setAlignment(QtCore.Qt.AlignCenter) - self.label_right.setStyleSheet(style) self.label_right.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) self.hbox = QtGui.QHBoxLayout() diff --git a/src/Mod/CAM/Path/Tool/toolbit/util.py b/src/Mod/CAM/Path/Tool/toolbit/util.py index 705ef05783..bc21722814 100644 --- a/src/Mod/CAM/Path/Tool/toolbit/util.py +++ b/src/Mod/CAM/Path/Tool/toolbit/util.py @@ -34,9 +34,16 @@ def format_value(value: FreeCAD.Units.Quantity | int | float | None, precision: return None elif isinstance(value, FreeCAD.Units.Quantity): if precision is not None: + user_val, _, user_unit = value.getUserPreferred() + if user_unit in ("deg", "°", "degree", "degrees"): + # Remove the last character (degree symbol) and convert to float + try: + deg_val = float(str(user_val)[:-1]) + except Exception: + return value.getUserPreferred()[0] + formatted_value = f"{deg_val:.1f}".rstrip("0").rstrip(".") + return f"{formatted_value}°" # Format the value with the specified number of precision and strip trailing zeros - formatted_value = f"{value.Value:.{precision}f}".rstrip("0").rstrip(".") - unit = value.getUserPreferred()[2] - return f"{formatted_value} {unit}" + return value.getUserPreferred()[0] return value.UserString return str(value) diff --git a/src/Mod/CAM/Tools/Shape/fillet.fcstd b/src/Mod/CAM/Tools/Shape/fillet.fcstd deleted file mode 100644 index 536a57f848c404fe0ddb506e9b807b77e2bbe826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17383 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 SDjm+tPs__+vM@bc1 literal 0 HcmV?d00001 diff --git a/src/Mod/CAM/Tools/Shape/fillet.svg b/src/Mod/CAM/Tools/Shape/radius.svg similarity index 82% rename from src/Mod/CAM/Tools/Shape/fillet.svg rename to src/Mod/CAM/Tools/Shape/radius.svg index 03caccb09a..bb3f8e7e11 100644 --- a/src/Mod/CAM/Tools/Shape/fillet.svg +++ b/src/Mod/CAM/Tools/Shape/radius.svg @@ -5,9 +5,9 @@ viewBox="0 0 210 297" height="297mm" width="210mm" - sodipodi:docname="fillet.svg" + sodipodi:docname="radius.svg" xml:space="preserve" - inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" + inkscape:version="1.3.2 (091e20e, 2023-11-25)" 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,13 +26,13 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" showgrid="false" - inkscape:zoom="0.50398562" - inkscape:cx="712.32191" - inkscape:cy="915.70073" - inkscape:window-width="2311" - inkscape:window-height="1509" - inkscape:window-x="1529" - inkscape:window-y="377" + inkscape:zoom="0.41628253" + inkscape:cx="136.92624" + inkscape:cy="599.35256" + inkscape:window-width="1512" + inkscape:window-height="916" + inkscape:window-x="0" + inkscape:window-y="38" inkscape:window-maximized="0" inkscape:current-layer="svg8" />image/svg+xmlhr + 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">rd diff --git a/src/Mod/CAM/Tools/Shape/thread-mill.fcstd b/src/Mod/CAM/Tools/Shape/thread-mill.fcstd index e0eb96c9eaebeaf04007502fc60e64f367f4b815..575076c4f2812f949d3e51257fd18f5ef532683f 100644 GIT binary patch delta 12549 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 literal 16823 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 L1ccxHG35Op5};;> diff --git a/src/Mod/CAM/Tools/Shape/v-bit.fcstd b/src/Mod/CAM/Tools/Shape/v-bit.fcstd index 16cd0e630a995741888fed1be1444a4a2f104c16..be25111e2e4cb5022ecc1ce4b38f4ad8b40dc655 100644 GIT binary patch delta 11557 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 Xw=d}k|AiWH2NM$!AyMLg9O(Z556|qW