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:
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user