CAM: Remove colons from labels, fix lint, and update imports

Removed explicit colons from all form labels.
Fixed lint warnings and replaced wildcard imports with explicit
imports for clarity and maintainability.

src/Mod/CAM/Path/Machine/ui/editor/machine_editor.py:
- Removed ':' from all form labels
- Fixed lint warnings (missing docstrings, empty except, etc.)
- Replaced wildcard imports with explicit imports

src/Mod/CAM/Path/Machine/models/__init__.py:
- Updated __all__ and imports for explicit API

src/Mod/CAM/Path/Tool/assets/ui/preferences.py:
- Updated imports to use package-level import

src/Mod/CAM/Path/Machine/models/machine.py:
- Added explanatory comments to empty except blocks
- Fixed duplicate variable assignment
- Added missing class docstrings

src/Mod/CAM/CAMTests/TestMachine.py:
- Fixed unused variable warning by using returned filepath
This commit is contained in:
Billy Huddleston
2025-12-31 13:21:14 -05:00
parent dc7991bd9d
commit a71fef6f13
5 changed files with 77 additions and 54 deletions

View File

@@ -11,10 +11,8 @@
# ***************************************************************************
import FreeCAD
import unittest
import tempfile
import pathlib
import json
import CAMTests.PathTestUtils as PathTestUtils
from Path.Machine.models.machine import (
Machine,
@@ -406,7 +404,7 @@ class TestMachineFactory(PathTestUtils.PathTestBase):
# Save and load
filepath = MachineFactory.save_configuration(machine, "complex.fcm")
loaded = MachineFactory.load_configuration("complex.fcm")
loaded = MachineFactory.load_configuration(filepath)
# Verify all components
self.assertEqual(loaded.name, machine.name)

View File

@@ -20,3 +20,31 @@
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
from .machine import (
Machine,
MachineFactory,
LinearAxis,
RotaryAxis,
Spindle,
MachineUnits,
MotionMode,
OutputUnits,
OutputOptions,
GCodeBlocks,
ProcessingOptions,
)
__all__ = [
"Machine",
"MachineFactory",
"LinearAxis",
"RotaryAxis",
"Spindle",
"MachineUnits",
"MotionMode",
"OutputUnits",
"OutputOptions",
"GCodeBlocks",
"ProcessingOptions",
]

View File

@@ -349,6 +349,14 @@ class Spindle:
@dataclass
class Machine:
"""Represents a CNC machine configuration with axes, spindles, and output settings.
This class encapsulates all machine parameters including linear and rotary axes,
spindles, post-processor settings, and G-code generation options. It provides
methods for serialization to/from JSON and various factory methods for common
machine configurations (3-axis, 4-axis, 5-axis).
"""
def __init__(
self, name: str = "Default Machine", configuration_units: str = "metric", **kwargs
):
@@ -947,22 +955,6 @@ class Machine:
return data
def _initialize_3axis_config(self) -> None:
"""Initialize as a standard 3-axis XYZ configuration (no rotary axes)"""
self.name = self.name or "3-Axis XYZ Configuration"
self.linear_axes = {
"X": LinearAxis("X", FreeCAD.Vector(1, 0, 0)),
"Y": LinearAxis("Y", FreeCAD.Vector(0, 1, 0)),
"Z": LinearAxis("Z", FreeCAD.Vector(0, 0, 1)),
}
@classmethod
def create_3axis_config(cls) -> "Machine":
"""Create standard 3-axis XYZ configuration (no rotary axes)"""
config = cls("3-Axis XYZ Configuration")
config._initialize_3axis_config()
return config
def _initialize_3axis_config(self) -> None:
"""Initialize as a standard 3-axis XYZ configuration (no rotary axes)"""
self.linear_axes = {
@@ -975,6 +967,13 @@ class Machine:
self.secondary_rotary_axis = None
self.compound_moves = True
@classmethod
def create_3axis_config(cls) -> "Machine":
"""Create standard 3-axis XYZ configuration (no rotary axes)"""
config = cls("3-Axis XYZ Configuration")
config._initialize_3axis_config()
return config
def _initialize_4axis_A_config(self, a_limits=(-120, 120)) -> None:
"""Initialize as a 4-axis XYZA configuration (rotary table around X)"""
self._initialize_3axis_config()
@@ -1320,6 +1319,7 @@ class MachineFactory:
name = cls.get_machine_display_name(p.name)
machines.append((name, p.name))
except Exception:
# Failed to access machine directory or read files, return default list only
pass
return machines

View File

@@ -22,11 +22,12 @@
# ***************************************************************************
from PySide import QtGui, QtCore
import FreeCAD
import Path
import json
from typing import Optional, Dict, Any, get_type_hints, get_origin, get_args
from dataclasses import fields, is_dataclass
from typing import Optional, Dict, Any, get_origin, get_args
from dataclasses import fields
from enum import Enum
from ...models.machine import *
from ...models import Machine, MachineFactory, LinearAxis, RotaryAxis, Spindle
from ....Main.Gui.Editor import CodeEditor
from Path.Post.Processor import PostProcessorFactory
import re
@@ -241,7 +242,7 @@ class DataclassGUIGenerator:
)
label = DataclassGUIGenerator.get_field_label(field.name)
layout.addRow(label + ":", widget)
layout.addRow(label, widget)
widgets[field.name] = widget
return group, widgets
@@ -615,34 +616,34 @@ class MachineEditorDialog(QtGui.QDialog):
self.name_edit = QtGui.QLineEdit()
self.name_edit.textChanged.connect(self._on_name_changed)
layout.addRow(translate("CAM_MachineEditor", "Name:"), self.name_edit)
layout.addRow(translate("CAM_MachineEditor", "Name"), self.name_edit)
self.manufacturer_edit = QtGui.QLineEdit()
self.manufacturer_edit.textChanged.connect(self._on_manufacturer_changed)
layout.addRow(translate("CAM_MachineEditor", "Manufacturer:"), self.manufacturer_edit)
layout.addRow(translate("CAM_MachineEditor", "Manufacturer"), self.manufacturer_edit)
self.description_edit = QtGui.QLineEdit()
self.description_edit.textChanged.connect(self._on_description_changed)
layout.addRow(translate("CAM_MachineEditor", "Description:"), self.description_edit)
layout.addRow(translate("CAM_MachineEditor", "Description"), self.description_edit)
self.units_combo = QtGui.QComboBox()
self.units_combo.addItem(translate("CAM_MachineEditor", "Metric"), "metric")
self.units_combo.addItem(translate("CAM_MachineEditor", "Imperial"), "imperial")
self.units_combo.currentIndexChanged.connect(self._on_units_changed)
layout.addRow(translate("CAM_MachineEditor", "Units:"), self.units_combo)
layout.addRow(translate("CAM_MachineEditor", "Units"), self.units_combo)
self.type_combo = QtGui.QComboBox()
for key, value in self.MACHINE_TYPES.items():
self.type_combo.addItem(value["name"], key)
self.type_combo.currentIndexChanged.connect(self._on_type_changed)
layout.addRow(translate("CAM_MachineEditor", "Type:"), self.type_combo)
layout.addRow(translate("CAM_MachineEditor", "Type"), self.type_combo)
self.spindle_count_combo = QtGui.QComboBox()
for i in range(1, 10): # 1 to 9 spindles
self.spindle_count_combo.addItem(str(i), i)
self.spindle_count_combo.currentIndexChanged.connect(self.update_spindles)
layout.addRow(
translate("CAM_MachineEditor", "Number of Spindles:"), self.spindle_count_combo
translate("CAM_MachineEditor", "Number of Spindles"), self.spindle_count_combo
)
# Axes group
@@ -743,14 +744,14 @@ class MachineEditorDialog(QtGui.QDialog):
)
axis_layout = QtGui.QHBoxLayout()
axis_layout.addWidget(QtGui.QLabel("Min:"))
axis_layout.addWidget(QtGui.QLabel("Min"))
axis_layout.addWidget(min_edit)
axis_layout.addWidget(QtGui.QLabel("Max:"))
axis_layout.addWidget(QtGui.QLabel("Max"))
axis_layout.addWidget(max_edit)
axis_layout.addWidget(QtGui.QLabel("Max Vel:"))
axis_layout.addWidget(QtGui.QLabel("Max Vel"))
axis_layout.addWidget(vel_edit)
linear_layout.addRow(f"{axis}:", axis_layout)
linear_layout.addRow(f"{axis}", axis_layout)
self.axis_edits[axis] = {
"min": min_edit,
"max": max_edit,
@@ -832,22 +833,22 @@ class MachineEditorDialog(QtGui.QDialog):
axis_grid = QtGui.QGridLayout()
# Row 0: Min, Max, Vel
axis_grid.addWidget(QtGui.QLabel("Min:"), 0, 0, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Min"), 0, 0, QtCore.Qt.AlignRight)
axis_grid.addWidget(min_edit, 0, 1)
axis_grid.addWidget(QtGui.QLabel("Max:"), 0, 2, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Max"), 0, 2, QtCore.Qt.AlignRight)
axis_grid.addWidget(max_edit, 0, 3)
axis_grid.addWidget(QtGui.QLabel("Max Vel:"), 0, 4, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Max Vel"), 0, 4, QtCore.Qt.AlignRight)
axis_grid.addWidget(vel_edit, 0, 5)
# Row 1: Sequence, Joint, Prefer+
axis_grid.addWidget(QtGui.QLabel("Sequence:"), 1, 0, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Sequence"), 1, 0, QtCore.Qt.AlignRight)
axis_grid.addWidget(sequence_spin, 1, 1)
axis_grid.addWidget(QtGui.QLabel("Joint:"), 1, 2, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Joint"), 1, 2, QtCore.Qt.AlignRight)
axis_grid.addWidget(joint_combo, 1, 3)
axis_grid.addWidget(QtGui.QLabel("Prefer+:"), 1, 4, QtCore.Qt.AlignRight)
axis_grid.addWidget(QtGui.QLabel("Prefer+"), 1, 4, QtCore.Qt.AlignRight)
axis_grid.addWidget(prefer_positive, 1, 5)
rotary_layout.addRow(f"{axis}:", axis_grid)
rotary_layout.addRow(f"{axis}", axis_grid)
self.axis_edits[axis] = {
"min": min_edit,
"max": max_edit,
@@ -926,14 +927,14 @@ class MachineEditorDialog(QtGui.QDialog):
name_edit.textChanged.connect(
lambda text, idx=i: self._on_spindle_field_changed(idx, "name", text)
)
layout.addRow("Name:", name_edit)
layout.addRow("Name", name_edit)
id_edit = QtGui.QLineEdit()
id_edit.setText(spindle.id if spindle and spindle.id else f"spindle{i+1}")
id_edit.textChanged.connect(
lambda text, idx=i: self._on_spindle_field_changed(idx, "id", text)
)
layout.addRow("ID:", id_edit)
layout.addRow("ID", id_edit)
max_power_edit = QtGui.QDoubleSpinBox()
max_power_edit.setRange(0, 100)
@@ -941,7 +942,7 @@ class MachineEditorDialog(QtGui.QDialog):
max_power_edit.valueChanged.connect(
lambda value, idx=i: self._on_spindle_field_changed(idx, "max_power_kw", value)
)
layout.addRow("Max Power (kW):", max_power_edit)
layout.addRow("Max Power (kW)", max_power_edit)
max_rpm_edit = QtGui.QSpinBox()
max_rpm_edit.setRange(0, 100000)
@@ -949,7 +950,7 @@ class MachineEditorDialog(QtGui.QDialog):
max_rpm_edit.valueChanged.connect(
lambda value, idx=i: self._on_spindle_field_changed(idx, "max_rpm", value)
)
layout.addRow("Max RPM:", max_rpm_edit)
layout.addRow("Max RPM", max_rpm_edit)
min_rpm_edit = QtGui.QSpinBox()
min_rpm_edit.setRange(0, 100000)
@@ -957,7 +958,7 @@ class MachineEditorDialog(QtGui.QDialog):
min_rpm_edit.valueChanged.connect(
lambda value, idx=i: self._on_spindle_field_changed(idx, "min_rpm", value)
)
layout.addRow("Min RPM:", min_rpm_edit)
layout.addRow("Min RPM", min_rpm_edit)
tool_change_combo = QtGui.QComboBox()
tool_change_combo.addItem("Manual", "manual")
@@ -1016,7 +1017,7 @@ class MachineEditorDialog(QtGui.QDialog):
)
self.postProcessorDefaultTooltip = translate("CAM_MachineEditor", "Select a post processor")
self.post_processor_combo.setToolTip(self.postProcessorDefaultTooltip)
pp_layout.addRow("Post Processor:", self.post_processor_combo)
pp_layout.addRow("Post Processor", self.post_processor_combo)
self.post_widgets["postprocessor_file_name"] = self.post_processor_combo
self.post_processor_args_edit = QtGui.QLineEdit()
@@ -1027,7 +1028,7 @@ class MachineEditorDialog(QtGui.QDialog):
"CAM_MachineEditor", "Additional arguments"
)
self.post_processor_args_edit.setToolTip(self.postProcessorArgsDefaultTooltip)
pp_layout.addRow("Arguments:", self.post_processor_args_edit)
pp_layout.addRow("Arguments", self.post_processor_args_edit)
self.post_widgets["postprocessor_args"] = self.post_processor_args_edit
layout.addWidget(pp_group)
@@ -1301,10 +1302,6 @@ class MachineEditorDialog(QtGui.QDialog):
# Get units for suffixes in populate
units = self.units_combo.itemData(self.units_combo.currentIndex())
length_suffix = " mm" if units == "metric" else " in"
vel_suffix = " mm/min" if units == "metric" else " in/min"
angle_suffix = " deg"
angle_vel_suffix = " deg/min"
# Update axes UI after loading machine data
self.update_axes()
@@ -1432,7 +1429,8 @@ class MachineEditorDialog(QtGui.QDialog):
current_name = current_machine.name.lower()
if machine_name_lower == current_name:
current_name_allowed = True
except:
except Exception:
# Failed to load current machine configuration, assume name is not allowed
pass
if machine_name_lower in existing_names_lower and not current_name_allowed:

View File

@@ -25,10 +25,9 @@ import pathlib
import tempfile
import FreeCAD
import Path
import json
from PySide import QtGui, QtCore
from ....Machine.ui.editor import MachineEditorDialog
from ....Machine.models.machine import MachineFactory
from ....Machine.models import MachineFactory
translate = FreeCAD.Qt.translate