feat: 完善参数化关系式与SCDM模型修改验证
This commit is contained in:
+20
-3
@@ -287,6 +287,16 @@ class StepEditorWindow(WindowCoreMixin, WindowStateMixin, WindowActionMixin, Inf
|
||||
self.property_command_buttons: dict[str, QPushButton] = {}
|
||||
self.relation_formula_items: list[dict[str, object]] = []
|
||||
self.relation_formula_next_id = 1
|
||||
self.relation_formula_base_snapshot: dict[object, object] | None = None
|
||||
self.relation_formula_replay_queue: list[dict[str, object]] = []
|
||||
self.relation_formula_replay_total = 0
|
||||
self.relation_formula_replay_done = 0
|
||||
self.relation_formula_replay_active = False
|
||||
self.relation_formula_replay_current_id: int | None = None
|
||||
self.relation_formula_replay_callback_seen = False
|
||||
self._relation_formula_replay_running_action = False
|
||||
self._relation_formula_object_label_cache_key: object = None
|
||||
self._relation_formula_object_label_cache: dict[str, object] = {}
|
||||
|
||||
self._build_ui()
|
||||
self._build_vtk()
|
||||
@@ -1292,7 +1302,7 @@ class StepEditorWindow(WindowCoreMixin, WindowStateMixin, WindowActionMixin, Inf
|
||||
self.relation_formula_box.setObjectName("relationFormulaBox")
|
||||
help_tip(
|
||||
self.relation_formula_box,
|
||||
"用 FaceID.参数 = 表达式 的形式建立关系式。第一版会先计算公式并回填当前参数表目标值,再执行参数化建模。",
|
||||
"用 FaceID.参数 = 表达式 的形式建立关系式。添加后会立即按当前公式组重新计算并修改模型。",
|
||||
)
|
||||
relation_layout = QVBoxLayout(self.relation_formula_box)
|
||||
relation_layout.setContentsMargins(6, 8, 6, 6)
|
||||
@@ -1305,13 +1315,20 @@ class StepEditorWindow(WindowCoreMixin, WindowStateMixin, WindowActionMixin, Inf
|
||||
self.relation_formula_input.setPlaceholderText("Face87.直径 = Face85.直径")
|
||||
help_tip(
|
||||
self.relation_formula_input,
|
||||
"示例:Face87.直径 = Face85.直径,或 Face87.位置 = Face85.位置 + (0, 0, -3.5)。输入 Face87. 后会提示当前可用参数。",
|
||||
"示例:Face87.直径 = Face85.直径,或 Face87.位置 = Face85.位置 + (0, 0, -3.5)。输入 Face87. 后会提示可用参数。",
|
||||
)
|
||||
self.relation_formula_completer_model = QStringListModel(self)
|
||||
self.relation_formula_completer = QCompleter(self.relation_formula_completer_model, self)
|
||||
self.relation_formula_completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
|
||||
self.relation_formula_completer.setFilterMode(Qt.MatchFlag.MatchStartsWith)
|
||||
self.relation_formula_completer.setCompletionMode(QCompleter.CompletionMode.PopupCompletion)
|
||||
self.relation_formula_input.setCompleter(self.relation_formula_completer)
|
||||
self.relation_formula_completer.setMaxVisibleItems(12)
|
||||
self.relation_formula_completer.activated[str].connect(self._on_relation_formula_completion_activated)
|
||||
relation_popup = self.relation_formula_completer.popup()
|
||||
if relation_popup is not None:
|
||||
relation_popup.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
||||
relation_popup.installEventFilter(self)
|
||||
self.relation_formula_completer.setWidget(self.relation_formula_input)
|
||||
self.relation_formula_input.installEventFilter(self)
|
||||
self.relation_formula_input.textChanged.connect(self._on_relation_formula_input_changed)
|
||||
self.relation_formula_input.returnPressed.connect(self.add_relation_formula)
|
||||
|
||||
@@ -4808,6 +4808,24 @@ class StepModel(FeatureMixin, ExportMixin, TransformMixin, OperationMixin, Polyd
|
||||
self._editable_feature_candidates_cache.clear()
|
||||
self._cylindrical_feature_candidates_cache.clear()
|
||||
|
||||
def mark_external_recognition_stale(self, reason: str = "modified-topology") -> None:
|
||||
self._topology_refresh_generation = max(int(getattr(self, "_topology_refresh_generation", 0) or 0), 2)
|
||||
self._asitus_hole_regions_attempted = False
|
||||
self._asitus_hole_regions_loading = False
|
||||
self._asitus_hole_region_cache.clear()
|
||||
self._asitus_face_relation_cache.clear()
|
||||
self._asitus_adjacency_relation_cache.clear()
|
||||
self._asitus_geometric_relation_cache.clear()
|
||||
self._asitus_hole_recognition_info.clear()
|
||||
self._asitus_hole_recognition_info.update(
|
||||
{
|
||||
"ok": False,
|
||||
"reason": str(reason or "modified-topology"),
|
||||
"message": "Analysis Situs result ignored because the model topology has changed.",
|
||||
}
|
||||
)
|
||||
self._clear_same_domain_dependent_caches()
|
||||
|
||||
def _install_asitus_relation_summary(self, result: dict[str, object]) -> None:
|
||||
faces = result.get("faces", ())
|
||||
if isinstance(faces, (tuple, list)):
|
||||
|
||||
@@ -8257,6 +8257,10 @@ class WindowActionMixin:
|
||||
new_model.filename = self.step_path
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
new_model.mark_external_recognition_stale("isolated-edit-result")
|
||||
except Exception:
|
||||
pass
|
||||
child_message = str(response.get("message") or "隔离子进程编辑完成。")
|
||||
self._preserve_isolated_face_logical_id(new_model, context, child_message)
|
||||
started = time.perf_counter()
|
||||
@@ -9186,8 +9190,11 @@ class WindowActionMixin:
|
||||
timings["finish_ui"] = time.perf_counter() - finish_started
|
||||
locator_note = self._locate_operation_record(record)
|
||||
relation_note = ""
|
||||
relation_dependency_ids: list[int] = []
|
||||
relation_replay_active = bool(getattr(self, "relation_formula_replay_active", False))
|
||||
if hasattr(self, "_refresh_relation_formulas_after_model_edit"):
|
||||
relation_note = self._refresh_relation_formulas_after_model_edit()
|
||||
relation_note = self._refresh_relation_formulas_after_model_edit(context=context)
|
||||
relation_dependency_ids = list(getattr(self, "_last_relation_formula_refresh_affected_ids", []) or [])
|
||||
if relation_note:
|
||||
locator_note = f"{locator_note}\n{relation_note}" if locator_note else relation_note
|
||||
except Exception as exc:
|
||||
@@ -9220,6 +9227,15 @@ class WindowActionMixin:
|
||||
self.set_plain_info(f"{record.detail}{timing_detail}\n\n{locator_note}")
|
||||
if hasattr(self, "_after_property_edit_finished"):
|
||||
self._after_property_edit_finished(success=True)
|
||||
if (
|
||||
relation_dependency_ids
|
||||
and not relation_replay_active
|
||||
and hasattr(self, "_queue_relation_formula_dependency_reapply")
|
||||
and hasattr(self, "_run_pending_relation_formula_dependency_reapply")
|
||||
):
|
||||
self._queue_relation_formula_dependency_reapply(relation_dependency_ids)
|
||||
if not bool(getattr(self, "property_batch_active", False)):
|
||||
self._run_pending_relation_formula_dependency_reapply()
|
||||
|
||||
@Slot(str)
|
||||
def _fail_edit_action(self, message: str) -> None:
|
||||
|
||||
@@ -179,12 +179,48 @@ class WindowCoreMixin:
|
||||
elif watched is getattr(self, "property_table", None):
|
||||
if event.type() == QEvent.Type.Resize and hasattr(self, "_resize_property_table_columns"):
|
||||
QTimer.singleShot(0, self._resize_property_table_columns)
|
||||
elif watched is self._relation_formula_popup_widget():
|
||||
if event.type() == QEvent.Type.KeyPress and event.key() == Qt.Key.Key_Backspace:
|
||||
editor = getattr(self, "relation_formula_input", None)
|
||||
popup = self._relation_formula_popup_widget()
|
||||
if editor is not None and hasattr(editor, "backspace"):
|
||||
if popup is not None and hasattr(popup, "hide"):
|
||||
popup.hide()
|
||||
if hasattr(editor, "setFocus"):
|
||||
editor.setFocus(Qt.FocusReason.OtherFocusReason)
|
||||
editor.backspace()
|
||||
if hasattr(self, "_update_relation_formula_completions"):
|
||||
QTimer.singleShot(0, self._update_relation_formula_completions)
|
||||
event.accept()
|
||||
return True
|
||||
elif watched is getattr(self, "relation_formula_input", None):
|
||||
if event.type() == QEvent.Type.KeyPress and event.key() == Qt.Key.Key_Tab:
|
||||
if event.type() == QEvent.Type.MouseButtonPress:
|
||||
if hasattr(self, "_hide_relation_formula_completion_popup"):
|
||||
self._hide_relation_formula_completion_popup()
|
||||
if hasattr(watched, "setFocus"):
|
||||
watched.setFocus(Qt.FocusReason.MouseFocusReason)
|
||||
if event.type() in {QEvent.Type.ShortcutOverride, QEvent.Type.KeyPress} and event.key() == Qt.Key.Key_Tab:
|
||||
if bool(getattr(self, "_relation_formula_tab_completion_accepted", False)):
|
||||
self._relation_formula_tab_completion_accepted = False
|
||||
event.accept()
|
||||
return True
|
||||
if hasattr(self, "_accept_relation_formula_completion") and self._accept_relation_formula_completion():
|
||||
self._relation_formula_tab_completion_accepted = event.type() == QEvent.Type.ShortcutOverride
|
||||
if self._relation_formula_tab_completion_accepted:
|
||||
QTimer.singleShot(0, lambda: setattr(self, "_relation_formula_tab_completion_accepted", False))
|
||||
event.accept()
|
||||
return True
|
||||
return super().eventFilter(watched, event)
|
||||
|
||||
def _relation_formula_popup_widget(self):
|
||||
completer = getattr(self, "relation_formula_completer", None)
|
||||
if completer is None or not hasattr(completer, "popup"):
|
||||
return None
|
||||
try:
|
||||
return completer.popup()
|
||||
except RuntimeError:
|
||||
return None
|
||||
|
||||
def _should_suppress_transient_tooltip(self, watched) -> bool:
|
||||
if not isinstance(watched, QWidget):
|
||||
return False
|
||||
@@ -1274,6 +1310,8 @@ class WindowCoreMixin:
|
||||
self.load_in_progress = False
|
||||
self.pending_load_path = None
|
||||
self._update_action_states()
|
||||
if hasattr(self, "_update_relation_formula_buttons"):
|
||||
self._update_relation_formula_buttons()
|
||||
if float(getattr(self, "preview_load_deflection", 0.0) or 0.0) > float(
|
||||
getattr(self, "initial_load_deflection", 0.0) or 0.0
|
||||
):
|
||||
@@ -1337,6 +1375,8 @@ class WindowCoreMixin:
|
||||
self.load_in_progress = False
|
||||
self.pending_load_path = None
|
||||
self._update_action_states()
|
||||
if hasattr(self, "_update_relation_formula_buttons"):
|
||||
self._update_relation_formula_buttons()
|
||||
self._request_thread_quit(self.load_thread)
|
||||
self._request_thread_quit(self.load_refine_thread)
|
||||
|
||||
@@ -1387,6 +1427,8 @@ class WindowCoreMixin:
|
||||
self.redo_stack.clear()
|
||||
self.operation_history.clear()
|
||||
self.redo_history.clear()
|
||||
if hasattr(self, "_clear_relation_formula_runtime_state"):
|
||||
self._clear_relation_formula_runtime_state(clear_items=True)
|
||||
self.clear_diff_preview(render=False)
|
||||
if hasattr(self, "history_list"):
|
||||
self.history_list.clear()
|
||||
|
||||
+937
-71
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user