feat: 增强一级关系识别与保持关系策略
This commit is contained in:
+155
-20
@@ -1487,6 +1487,7 @@ class WindowActionMixin:
|
||||
"move_circular_edge_axis_center",
|
||||
"resize_ellipse_edge_axis_radius",
|
||||
"resize_existing_fillet",
|
||||
"resize_existing_chamfer",
|
||||
"fillet_edge",
|
||||
"chamfer_edge",
|
||||
"chamfer_edge_asymmetric",
|
||||
@@ -4101,6 +4102,92 @@ class WindowActionMixin:
|
||||
isolation=isolation,
|
||||
)
|
||||
|
||||
def resize_existing_chamfer(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
if self._edit_busy("请等待当前编辑完成后再修改已有倒角。"):
|
||||
return
|
||||
if self.selected_face_id is None:
|
||||
QMessageBox.information(self, "未选择已有倒角", "请先选择一个已有倒角斜面 Face。")
|
||||
return
|
||||
try:
|
||||
target_distance = float(self.edge_chamfer_distance_input.text())
|
||||
except ValueError:
|
||||
QMessageBox.critical(self, "距离无效", "请输入数字形式的目标倒角距离。")
|
||||
return
|
||||
|
||||
face_id = self.selected_face_id
|
||||
plan = self.model.existing_chamfer_resize_plan(face_id, target_distance)
|
||||
isolation = self._isolation_for_plan(plan, "resize_existing_chamfer", [face_id, target_distance])
|
||||
if plan["status"] == "blocked":
|
||||
self._show_blocked_plan_message("修改已有倒角", plan, "已有倒角距离修改已阻止")
|
||||
return
|
||||
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
warnings_line = f"警告: {warnings}\n\n" if warnings else ""
|
||||
result = QMessageBox.question(
|
||||
self,
|
||||
"确认修改已有倒角距离",
|
||||
(
|
||||
f"Face: {plan['face_id']}\n"
|
||||
f"当前估算距离: {_format_value(plan['current_distance'])}\n"
|
||||
f"目标距离: {_format_value(plan['target_distance'])}\n"
|
||||
f"距离变化量: {_format_value(plan['delta_distance'])}\n"
|
||||
f"距离变化比例: {_format_percent(plan['distance_delta_ratio'])}\n"
|
||||
f"支撑 Face: {_format_value(plan.get('feature_existing_chamfer_support_face_ids', ''))}\n"
|
||||
f"长边 Edge: {_format_value(plan.get('feature_existing_chamfer_long_edge_ids', ''))}\n"
|
||||
f"策略: {plan['resize_strategy']}\n"
|
||||
f"执行策略: {_format_value(plan.get('edit_strategy_label'))}\n"
|
||||
f"建模意图: {_format_value(plan.get('edit_semantics'))}\n"
|
||||
f"风险: {plan['risk']}\n\n"
|
||||
f"{warnings_line}"
|
||||
f"{plan['message']}\n\n"
|
||||
"继续操作会先尝试移除当前倒角斜面,再对恢复出的锐边重新倒角。\n"
|
||||
"这不是 CAD 历史特征参数编辑,复杂倒角可能失败。\n\n"
|
||||
"确定继续吗?"
|
||||
),
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
if result != QMessageBox.StandardButton.Yes:
|
||||
self.statusBar().showMessage("已取消修改已有倒角距离")
|
||||
return
|
||||
|
||||
def action():
|
||||
return self.model.resize_existing_chamfer(face_id, target_distance)
|
||||
|
||||
self._run_edit_action(
|
||||
action,
|
||||
operation_name="修改已有倒角距离",
|
||||
target=f"Face {face_id}",
|
||||
parameters={
|
||||
"part_id": plan.get("part_id"),
|
||||
"solid_id": plan.get("solid_id"),
|
||||
"old_distance": plan.get("current_distance"),
|
||||
"new_distance": target_distance,
|
||||
"delta_distance": plan.get("delta_distance"),
|
||||
"distance_delta_ratio": plan.get("distance_delta_ratio"),
|
||||
"feature_type": plan.get("feature_type"),
|
||||
"feature_guess": plan.get("feature_guess"),
|
||||
"confidence": plan.get("confidence"),
|
||||
"existing_chamfer_status": plan.get("status"),
|
||||
"existing_chamfer_risk": plan.get("risk"),
|
||||
"existing_chamfer_message": plan.get("message"),
|
||||
"existing_chamfer_warnings": plan.get("warnings"),
|
||||
"existing_chamfer_blockers": plan.get("blockers"),
|
||||
"feature_existing_chamfer_support_face_ids": plan.get("feature_existing_chamfer_support_face_ids"),
|
||||
"feature_existing_chamfer_long_edge_ids": plan.get("feature_existing_chamfer_long_edge_ids"),
|
||||
"resize_strategy": plan.get("resize_strategy"),
|
||||
"edit_strategy_label": plan.get("edit_strategy_label"),
|
||||
"edit_semantics": plan.get("edit_semantics"),
|
||||
"resize_note": plan.get("resize_note"),
|
||||
"ui_preview": "skipped-for-existing-chamfer",
|
||||
},
|
||||
target_kind="face",
|
||||
target_id=face_id,
|
||||
isolation=isolation,
|
||||
)
|
||||
|
||||
def fillet_edge(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
@@ -4483,6 +4570,7 @@ class WindowActionMixin:
|
||||
f"建模意图: {_format_value(plan.get('edge_length_strategy_label', ''))}\n"
|
||||
f"固定约束: {_format_value(plan.get('edge_length_constraint_summary', ''))}\n"
|
||||
f"执行影响: {_format_value(plan.get('edge_length_impact_summary', ''))}\n"
|
||||
f"平面关系约束: {_format_value(plan.get('edge_length_planar_constraint_summary', ''))}\n"
|
||||
f"策略: {_format_value(plan.get('resize_strategy', ''))}\n"
|
||||
f"局部形变目标: {_format_value(plan.get('local_edge_deform_target_kind', ''))}\n"
|
||||
f"局部形变: {_format_value(plan.get('local_edge_deform_anchor', ''))}\n"
|
||||
@@ -4539,6 +4627,26 @@ class WindowActionMixin:
|
||||
"edge_length_strategy_label": plan.get("edge_length_strategy_label"),
|
||||
"edge_length_constraint_summary": plan.get("edge_length_constraint_summary"),
|
||||
"edge_length_impact_summary": plan.get("edge_length_impact_summary"),
|
||||
"edge_length_planar_relation_constraint_requested": plan.get(
|
||||
"edge_length_planar_relation_constraint_requested"
|
||||
),
|
||||
"edge_length_planar_relation_constraint_label": plan.get(
|
||||
"edge_length_planar_relation_constraint_label"
|
||||
),
|
||||
"edge_length_planar_constraint_status": plan.get("edge_length_planar_constraint_status"),
|
||||
"edge_length_planar_constraint_summary": plan.get("edge_length_planar_constraint_summary"),
|
||||
"edge_length_planar_constraint_side_face_count": plan.get(
|
||||
"edge_length_planar_constraint_side_face_count"
|
||||
),
|
||||
"edge_length_planar_constraint_parallel_count": plan.get(
|
||||
"edge_length_planar_constraint_parallel_count"
|
||||
),
|
||||
"edge_length_planar_constraint_perpendicular_count": plan.get(
|
||||
"edge_length_planar_constraint_perpendicular_count"
|
||||
),
|
||||
"edge_length_planar_constraint_angled_count": plan.get("edge_length_planar_constraint_angled_count"),
|
||||
"edge_length_planar_constraint_blockers": plan.get("edge_length_planar_constraint_blockers"),
|
||||
"edge_length_planar_constraint_warnings": plan.get("edge_length_planar_constraint_warnings"),
|
||||
"edit_strategy_label": plan.get("edit_strategy_label"),
|
||||
"edit_semantics": plan.get("edit_semantics"),
|
||||
"local_edge_deform_target_kind": plan.get("local_edge_deform_target_kind"),
|
||||
@@ -4650,6 +4758,7 @@ class WindowActionMixin:
|
||||
f"建模意图: {_format_value(plan.get('edge_length_strategy_label', ''))}\n"
|
||||
f"固定约束: {_format_value(plan.get('edge_length_constraint_summary', ''))}\n"
|
||||
f"执行影响: {_format_value(plan.get('edge_length_impact_summary', ''))}\n"
|
||||
f"平面关系约束: {_format_value(plan.get('edge_length_planar_constraint_summary', ''))}\n"
|
||||
f"策略: {_format_value(strategy)}\n"
|
||||
f"局部形变目标: {_format_value(plan.get('local_edge_deform_target_kind', ''))}\n"
|
||||
f"局部形变: {_format_value(plan.get('local_edge_deform_anchor', ''))}\n"
|
||||
@@ -4707,6 +4816,26 @@ class WindowActionMixin:
|
||||
"edge_length_strategy_label": plan.get("edge_length_strategy_label"),
|
||||
"edge_length_constraint_summary": plan.get("edge_length_constraint_summary"),
|
||||
"edge_length_impact_summary": plan.get("edge_length_impact_summary"),
|
||||
"edge_length_planar_relation_constraint_requested": plan.get(
|
||||
"edge_length_planar_relation_constraint_requested"
|
||||
),
|
||||
"edge_length_planar_relation_constraint_label": plan.get(
|
||||
"edge_length_planar_relation_constraint_label"
|
||||
),
|
||||
"edge_length_planar_constraint_status": plan.get("edge_length_planar_constraint_status"),
|
||||
"edge_length_planar_constraint_summary": plan.get("edge_length_planar_constraint_summary"),
|
||||
"edge_length_planar_constraint_side_face_count": plan.get(
|
||||
"edge_length_planar_constraint_side_face_count"
|
||||
),
|
||||
"edge_length_planar_constraint_parallel_count": plan.get(
|
||||
"edge_length_planar_constraint_parallel_count"
|
||||
),
|
||||
"edge_length_planar_constraint_perpendicular_count": plan.get(
|
||||
"edge_length_planar_constraint_perpendicular_count"
|
||||
),
|
||||
"edge_length_planar_constraint_angled_count": plan.get("edge_length_planar_constraint_angled_count"),
|
||||
"edge_length_planar_constraint_blockers": plan.get("edge_length_planar_constraint_blockers"),
|
||||
"edge_length_planar_constraint_warnings": plan.get("edge_length_planar_constraint_warnings"),
|
||||
"edit_strategy_label": plan.get("edit_strategy_label"),
|
||||
"edit_semantics": plan.get("edit_semantics"),
|
||||
"local_edge_deform_target_kind": plan.get("local_edge_deform_target_kind"),
|
||||
@@ -4894,7 +5023,7 @@ class WindowActionMixin:
|
||||
float(getattr(self, f"{prefix}_z_input").text()),
|
||||
)
|
||||
except (AttributeError, ValueError):
|
||||
QMessageBox.critical(self, "Edge endpoint coordinate invalid", "Please enter numeric X, Y and Z values.")
|
||||
QMessageBox.critical(self, "Edge端点坐标无效", "请输入数字形式的 X、Y、Z 目标坐标。")
|
||||
return None
|
||||
|
||||
def move_edge_start_point(self) -> None:
|
||||
@@ -4992,10 +5121,10 @@ class WindowActionMixin:
|
||||
def move_edge_center_point(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
if self._edit_busy("Please wait for the current edit to finish before moving an Edge center."):
|
||||
if self._edit_busy("请等待当前编辑完成后再移动 Edge 中心。"):
|
||||
return
|
||||
if self.selected_edge_id is None:
|
||||
QMessageBox.information(self, "No Edge selected", "Please select an Edge first.")
|
||||
QMessageBox.information(self, "未选择Edge", "请先选择一条 Edge。")
|
||||
return
|
||||
try:
|
||||
target_center = (
|
||||
@@ -5004,7 +5133,7 @@ class WindowActionMixin:
|
||||
float(self.edge_center_z_input.text()),
|
||||
)
|
||||
except (AttributeError, ValueError):
|
||||
QMessageBox.critical(self, "Edge center coordinate invalid", "Please enter numeric X, Y and Z values.")
|
||||
QMessageBox.critical(self, "Edge中心坐标无效", "请输入数字形式的 X、Y、Z 目标坐标。")
|
||||
return
|
||||
|
||||
edge_id = self.selected_edge_id
|
||||
@@ -5012,12 +5141,13 @@ class WindowActionMixin:
|
||||
isolation = self._isolation_for_plan(plan, "move_edge_center", [edge_id, target_center])
|
||||
lines = [
|
||||
f"Edge: {edge_id}",
|
||||
f"Current center: {_format_value(plan.get('current_edge_center'))}",
|
||||
f"Target center: {_format_value(plan.get('target_edge_center'))}",
|
||||
f"Move vector: {_format_value(plan.get('moved_edge_center_delta'))}",
|
||||
f"Edge length: {_format_value(plan.get('current_length'))}",
|
||||
f"Strategy: {_format_value(plan.get('resize_strategy'))}",
|
||||
f"Rebuilt faces: {_format_value(plan.get('local_edge_deform_face_count'))}",
|
||||
f"当前中心: {_format_value(plan.get('current_edge_center'))}",
|
||||
f"目标中心: {_format_value(plan.get('target_edge_center'))}",
|
||||
f"移动量: {_format_value(plan.get('moved_edge_center_delta'))}",
|
||||
f"Edge长度: {_format_value(plan.get('current_length'))}",
|
||||
f"建模语义: {_format_value(plan.get('edit_strategy_label'))}",
|
||||
f"影响范围: {_format_value(plan.get('edit_semantics'))}",
|
||||
f"重建Face数: {_format_value(plan.get('local_edge_deform_face_count'))}",
|
||||
]
|
||||
if not self._confirm_quick_edit_plan(
|
||||
"移动Edge中心",
|
||||
@@ -5054,6 +5184,8 @@ class WindowActionMixin:
|
||||
"local_edge_deform_start_move": plan.get("local_edge_deform_start_move"),
|
||||
"local_edge_deform_end_move": plan.get("local_edge_deform_end_move"),
|
||||
"resize_strategy": plan.get("resize_strategy"),
|
||||
"edit_strategy_label": plan.get("edit_strategy_label"),
|
||||
"edit_semantics": plan.get("edit_semantics"),
|
||||
"resize_status": plan.get("status"),
|
||||
"resize_risk": plan.get("risk"),
|
||||
"resize_message": plan.get("message"),
|
||||
@@ -5068,10 +5200,10 @@ class WindowActionMixin:
|
||||
def _move_edge_endpoint(self, endpoint_role: str) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
if self._edit_busy("Please wait for the current edit to finish before moving an Edge endpoint."):
|
||||
if self._edit_busy("请等待当前编辑完成后再移动 Edge 端点。"):
|
||||
return
|
||||
if self.selected_edge_id is None:
|
||||
QMessageBox.information(self, "No Edge selected", "Please select an Edge first.")
|
||||
QMessageBox.information(self, "未选择Edge", "请先选择一条 Edge。")
|
||||
return
|
||||
|
||||
target_point = self._edge_endpoint_target_from_inputs(endpoint_role)
|
||||
@@ -5084,14 +5216,15 @@ class WindowActionMixin:
|
||||
title = "移动Edge起点" if endpoint_role == "start" else "移动Edge终点"
|
||||
lines = [
|
||||
f"Edge: {edge_id}",
|
||||
f"Endpoint: {_format_value(plan.get('edge_endpoint_label'))}",
|
||||
f"Current endpoint: {_format_value(plan.get('current_endpoint_point'))}",
|
||||
f"Target endpoint: {_format_value(plan.get('target_endpoint_point'))}",
|
||||
f"Move vector: {_format_value(plan.get('moved_endpoint_delta'))}",
|
||||
f"Current Edge length: {_format_value(plan.get('current_length'))}",
|
||||
f"Result Edge length: {_format_value(plan.get('target_length'))}",
|
||||
f"Strategy: {_format_value(plan.get('resize_strategy'))}",
|
||||
f"Rebuilt faces: {_format_value(plan.get('local_edge_deform_face_count'))}",
|
||||
f"端点: {_format_value(plan.get('edge_endpoint_label'))}",
|
||||
f"当前端点: {_format_value(plan.get('current_endpoint_point'))}",
|
||||
f"目标端点: {_format_value(plan.get('target_endpoint_point'))}",
|
||||
f"移动量: {_format_value(plan.get('moved_endpoint_delta'))}",
|
||||
f"当前Edge长度: {_format_value(plan.get('current_length'))}",
|
||||
f"结果Edge长度: {_format_value(plan.get('target_length'))}",
|
||||
f"建模语义: {_format_value(plan.get('edit_strategy_label'))}",
|
||||
f"影响范围: {_format_value(plan.get('edit_semantics'))}",
|
||||
f"重建Face数: {_format_value(plan.get('local_edge_deform_face_count'))}",
|
||||
]
|
||||
if not self._confirm_quick_edit_plan(
|
||||
title,
|
||||
@@ -5133,6 +5266,8 @@ class WindowActionMixin:
|
||||
"local_edge_deform_start_move": plan.get("local_edge_deform_start_move"),
|
||||
"local_edge_deform_end_move": plan.get("local_edge_deform_end_move"),
|
||||
"resize_strategy": plan.get("resize_strategy"),
|
||||
"edit_strategy_label": plan.get("edit_strategy_label"),
|
||||
"edit_semantics": plan.get("edit_semantics"),
|
||||
"resize_status": plan.get("status"),
|
||||
"resize_risk": plan.get("risk"),
|
||||
"resize_message": plan.get("message"),
|
||||
|
||||
Reference in New Issue
Block a user