feat: 完善 STEP 一级参数化编辑识别与关系式建模

This commit is contained in:
2026-08-14 18:42:39 +08:00
parent 70b59c1de6
commit a633b5a338
26 changed files with 4676 additions and 77 deletions
+54 -1
View File
@@ -9,14 +9,16 @@ import tempfile
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
from PySide6.QtCore import QEvent, QObject
from PySide6.QtCore import QEvent, QObject, QStringListModel
from PySide6.QtWidgets import (
QApplication,
QCheckBox,
QCompleter,
QFrame,
QHBoxLayout,
QLabel,
QLineEdit,
QListWidget,
QPushButton,
QScrollArea,
QTableWidget,
@@ -62,6 +64,8 @@ class _PropertyTableProbe(QWidget, WindowStateMixin):
self.property_command_active_key = ""
self.property_command_buttons = {}
self.property_editor_specs = []
self.relation_formula_items = []
self.relation_formula_next_id = 1
self.selected_kind = "feature"
self.selected_part_id = None
self.selected_solid_id = None
@@ -93,6 +97,13 @@ class _PropertyTableProbe(QWidget, WindowStateMixin):
self.current_capability_headline = QLabel()
self.apply_property_button = QPushButton()
self.export_parameters_button = QPushButton()
self.relation_formula_input = QLineEdit()
self.relation_formula_completer_model = QStringListModel(self)
self.relation_formula_completer = QCompleter(self.relation_formula_completer_model, self)
self.relation_formula_input.setCompleter(self.relation_formula_completer)
self.add_relation_formula_button = QPushButton()
self.remove_relation_formula_button = QPushButton()
self.relation_formula_list = QListWidget()
self.face_width_input = QLineEdit()
self.face_height_input = QLineEdit()
@@ -446,6 +457,34 @@ def _assert_diagnostics_stay_out_of_parameter_table(probe: _PropertyTableProbe)
_assert(diagnostic_label not in table_labels, f"{diagnostic_label} should not be shown as a feature parameter")
def _assert_relation_formula_editor() -> None:
probe = _PropertyTableProbe()
probe._refresh_property_editor()
completions = set(probe.relation_formula_completer_model.stringList())
_assert("Face0.面内长度" in completions, f"relation formula completion missing face length: {completions}")
_assert("Face0.面内宽度" in completions, f"relation formula completion missing face width: {completions}")
probe.relation_formula_input.setText("Face0.面内宽度 = Face0.面内长度 * 1.2")
probe.add_relation_formula()
_assert(len(probe.relation_formula_items) == 1, f"formula was not stored: {probe.relation_formula_items}")
_assert(probe.relation_formula_list.count() == 1, "formula list should display the stored formula")
probe._update_property_apply_state()
_assert(probe.apply_property_button.isEnabled(), "formula targeting current table should enable parametric modeling")
probe.apply_current_property_edit()
for _index in range(6):
QApplication.processEvents()
if not getattr(probe, "property_batch_active", False):
break
_assert(
probe.executed_property_actions == [("resize_face_height_local", "12")],
f"formula should fill target value and execute the existing row action: {probe.executed_property_actions}",
)
width_row = _row_by_label(probe, "面内宽度")
width_widget = probe.property_table.cellWidget(width_row, PROPERTY_TARGET_COLUMN)
_assert(isinstance(width_widget, QLineEdit), "formula target row should still have a target editor")
_assert(width_widget.text().strip() == "12", "formula result should be written back to the target value cell")
_assert(str(probe.relation_formula_items[0].get("status")) == "applied", "formula should be marked as applied")
def _assert_mouse_selection_guards() -> None:
mouse_probe = _MouseSelectionProbe()
mouse_probe._handle_left_button_press(20, 20)
@@ -502,6 +541,7 @@ def _assert_quick_blind_depth_spec() -> None:
"radius": 2.0,
"axis_point": (0.0, 0.0, 0.0),
"axis": (0.0, 0.0, 1.0),
"axis_center": (0.0, 0.0, 3.0),
"angular_span": math.tau,
"feature_guess": "hole/groove candidate",
"feature_type": "圆柱孔候选",
@@ -513,6 +553,18 @@ def _assert_quick_blind_depth_spec() -> None:
}
blind_specs, _blind_used = blind_probe._editable_property_specs(quick_blind_info)
blind_feature_specs = blind_probe._feature_property_specs(blind_specs, quick_blind_info)
blind_axis_specs = [
spec for spec in blind_feature_specs if str(spec.get("key", "")) == "hole_axis_center"
]
_assert(blind_axis_specs, "quick blind hole axis center should be visible in feature parameters")
blind_axis_spec = blind_axis_specs[0]
_assert(str(blind_axis_spec.get("value_type", "")) == "vector3", "hole axis center should accept X/Y/Z")
blind_axis_effective = blind_probe._effective_property_spec(blind_axis_spec)
_assert(bool(blind_axis_effective.get("enabled")), "quick blind hole axis center should be editable")
_assert(
str(blind_axis_effective.get("action", "")) == "move_cylindrical_hole_axis",
f"quick blind hole axis center should move the hole itself: {blind_axis_effective}",
)
blind_depth_specs = [
spec for spec in blind_feature_specs if str(spec.get("key", "")) == "hole_depth_estimate"
]
@@ -671,6 +723,7 @@ def main() -> int:
)
_assert_diagnostics_stay_out_of_parameter_table(probe)
_assert_relation_formula_editor()
_assert_mouse_selection_guards()
_assert_quick_blind_depth_spec()
_assert_user_facing_failure_messages()