feat: 完善 STEP/B-Rep 一级关系参数化编辑
This commit is contained in:
+104
-3
@@ -135,6 +135,18 @@ class WindowCoreMixin:
|
||||
def _should_suppress_transient_tooltip(self, watched) -> bool:
|
||||
if not isinstance(watched, QWidget):
|
||||
return False
|
||||
property_table = getattr(self, "property_table", None)
|
||||
if isinstance(property_table, QWidget):
|
||||
widget = watched
|
||||
while widget is not None:
|
||||
if widget is property_table:
|
||||
return False
|
||||
widget = widget.parentWidget()
|
||||
try:
|
||||
if watched is property_table.viewport():
|
||||
return False
|
||||
except Exception:
|
||||
pass
|
||||
suppressed_roots = (
|
||||
getattr(self, "vtk_widget", None),
|
||||
getattr(self, "object_edit_box", None),
|
||||
@@ -1791,6 +1803,8 @@ class WindowCoreMixin:
|
||||
self.pointer_button_down = True
|
||||
self.left_button_press_position = (int(x), int(y))
|
||||
self.left_button_dragged = False
|
||||
self.left_button_press_camera_state = self._camera_state_signature()
|
||||
self.left_button_press_target = self._selection_target_at_position(x, y)
|
||||
self.pending_hover_position = None
|
||||
self.last_hover_pick_position = None
|
||||
self.hover_timer.stop()
|
||||
@@ -1812,16 +1826,55 @@ class WindowCoreMixin:
|
||||
def _handle_left_button_release(self, x: int, y: int) -> None:
|
||||
self._update_left_button_drag_state(x, y)
|
||||
was_dragged = bool(getattr(self, "left_button_dragged", False))
|
||||
camera_changed = self._left_button_camera_changed()
|
||||
self.pointer_button_down = False
|
||||
press_target = getattr(self, "left_button_press_target", None)
|
||||
self.left_button_press_position = None
|
||||
self.left_button_dragged = False
|
||||
self.left_button_press_camera_state = None
|
||||
self.left_button_press_target = None
|
||||
self.pending_hover_position = None
|
||||
self.last_hover_pick_position = None
|
||||
if getattr(self, "camera_interaction_active", False):
|
||||
self._end_camera_interaction()
|
||||
if was_dragged:
|
||||
if was_dragged or camera_changed or self._selection_target_signature(press_target) is None:
|
||||
return
|
||||
self._handle_left_click(x, y)
|
||||
self._handle_left_click(x, y, required_press_target=press_target)
|
||||
|
||||
def _camera_state_signature(self) -> tuple[float, ...] | None:
|
||||
renderer = getattr(self, "renderer", None)
|
||||
if renderer is None:
|
||||
return None
|
||||
try:
|
||||
camera = renderer.GetActiveCamera()
|
||||
except Exception:
|
||||
return None
|
||||
if camera is None:
|
||||
return None
|
||||
values: list[float] = []
|
||||
for getter in (
|
||||
"GetPosition",
|
||||
"GetFocalPoint",
|
||||
"GetViewUp",
|
||||
):
|
||||
try:
|
||||
values.extend(float(item) for item in getattr(camera, getter)())
|
||||
except Exception:
|
||||
return None
|
||||
for getter in ("GetParallelScale", "GetDistance", "GetViewAngle"):
|
||||
try:
|
||||
values.append(float(getattr(camera, getter)()))
|
||||
except Exception:
|
||||
pass
|
||||
return tuple(values)
|
||||
|
||||
def _left_button_camera_changed(self) -> bool:
|
||||
before = getattr(self, "left_button_press_camera_state", None)
|
||||
after = self._camera_state_signature()
|
||||
if before is None or after is None or len(before) != len(after):
|
||||
return False
|
||||
tolerance = float(getattr(self, "left_click_camera_tolerance", 1e-7) or 1e-7)
|
||||
return any(abs(float(a) - float(b)) > tolerance for a, b in zip(before, after))
|
||||
|
||||
def _update_left_button_drag_state(self, x: int, y: int) -> None:
|
||||
press_position = getattr(self, "left_button_press_position", None)
|
||||
@@ -1833,7 +1886,33 @@ class WindowCoreMixin:
|
||||
if max(dx, dy) > threshold:
|
||||
self.left_button_dragged = True
|
||||
|
||||
def _handle_left_click(self, x: int, y: int) -> None:
|
||||
def _selection_target_signature(self, target: dict[str, object] | None) -> tuple[str, int] | None:
|
||||
if not isinstance(target, dict):
|
||||
return None
|
||||
try:
|
||||
return str(target["kind"]), int(target["target_id"])
|
||||
except (KeyError, TypeError, ValueError):
|
||||
return None
|
||||
|
||||
def _selection_target_at_position(self, x: int, y: int) -> dict[str, object] | None:
|
||||
if (
|
||||
getattr(self, "load_in_progress", False)
|
||||
or getattr(self, "operation_in_progress", False)
|
||||
or getattr(self, "scan_in_progress", False)
|
||||
or getattr(self, "model", None) is None
|
||||
):
|
||||
return None
|
||||
try:
|
||||
return self._pick_selection_target(self._current_selection_mode(), int(x), int(y))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _handle_left_click(
|
||||
self,
|
||||
x: int,
|
||||
y: int,
|
||||
required_press_target: dict[str, object] | None = None,
|
||||
) -> None:
|
||||
self.pending_hover_position = None
|
||||
self.last_hover_pick_position = None
|
||||
self.hover_timer.stop()
|
||||
@@ -1850,6 +1929,16 @@ class WindowCoreMixin:
|
||||
return
|
||||
mode = self._current_selection_mode()
|
||||
target = self._pick_selection_target(mode, x, y)
|
||||
if required_press_target is not None:
|
||||
press_signature = self._selection_target_signature(required_press_target)
|
||||
release_signature = self._selection_target_signature(target)
|
||||
if press_signature is None or release_signature != press_signature:
|
||||
self._cancel_hover_tracking(render=False)
|
||||
if hasattr(self, "render_window"):
|
||||
self.render_window.Render()
|
||||
if self.selected_kind is not None:
|
||||
self.statusBar().showMessage("左键按下和松开未命中同一对象,已保持当前选择")
|
||||
return
|
||||
if target is None:
|
||||
self._cancel_hover_tracking(render=False)
|
||||
if hasattr(self, "render_window"):
|
||||
@@ -1871,6 +1960,7 @@ class WindowCoreMixin:
|
||||
|
||||
def _handle_pointer_button_press(self) -> None:
|
||||
self.pointer_button_down = True
|
||||
self.left_button_press_target = None
|
||||
self.pending_hover_position = None
|
||||
self.last_hover_pick_position = None
|
||||
self.hover_timer.stop()
|
||||
@@ -1884,6 +1974,7 @@ class WindowCoreMixin:
|
||||
|
||||
def _handle_pointer_button_release(self) -> None:
|
||||
self.pointer_button_down = False
|
||||
self.left_button_press_target = None
|
||||
self.pending_hover_position = None
|
||||
self.last_hover_pick_position = None
|
||||
self._end_camera_interaction()
|
||||
@@ -2279,6 +2370,14 @@ class WindowCoreMixin:
|
||||
self._set_selection_mode("Edge")
|
||||
self.select_edge(int(target_id))
|
||||
self.statusBar().showMessage(f"已选择可尝试调整长度的Edge {target_id}")
|
||||
elif action == "resize_ellipse_edge_major_radius":
|
||||
self._set_selection_mode("Edge")
|
||||
self.select_edge(int(target_id))
|
||||
self.statusBar().showMessage(f"已选择可调整椭圆主半径的Edge {target_id}")
|
||||
elif action == "resize_ellipse_edge_minor_radius":
|
||||
self._set_selection_mode("Edge")
|
||||
self.select_edge(int(target_id))
|
||||
self.statusBar().showMessage(f"已选择可调整椭圆小半径的Edge {target_id}")
|
||||
elif target_kind == "edge":
|
||||
self._set_selection_mode("Edge")
|
||||
self.select_edge(int(target_id))
|
||||
@@ -2439,6 +2538,8 @@ class WindowCoreMixin:
|
||||
self._sync_id_picker("Feature", logical_id)
|
||||
self.set_info(self._with_pick_info(info, pick_position))
|
||||
feature_type = str(info.get("feature_type", "特征候选"))
|
||||
if hasattr(self, "_feature_display_label"):
|
||||
feature_type = self._feature_display_label(feature_type)
|
||||
self._update_action_states()
|
||||
raw_note = f"(当前拓扑 Face {face_id})" if logical_id != face_id else ""
|
||||
self.statusBar().showMessage(self._selection_status(f"已选择 {feature_type},来源 Face {logical_id}{raw_note}", pick_position))
|
||||
|
||||
Reference in New Issue
Block a user