feat: 完善 STEP/B-Rep 一级关系参数化编辑
This commit is contained in:
+432
-120
@@ -77,6 +77,13 @@ def _compact_plan_value(value: object) -> str:
|
||||
return text if len(text) <= 120 else text[:117] + "..."
|
||||
|
||||
|
||||
def _compact_user_message(value: object, limit: int = 360) -> str:
|
||||
text = " ".join(str(value or "").replace("\r", "\n").split())
|
||||
if len(text) <= limit:
|
||||
return text
|
||||
return f"{text[: max(0, limit - 1)].rstrip()}..."
|
||||
|
||||
|
||||
class WindowActionMixin:
|
||||
def export_all(self) -> None:
|
||||
if self.model is None:
|
||||
@@ -356,8 +363,7 @@ class WindowActionMixin:
|
||||
plan = self._push_pull_plan_for_action(face_id, distance)
|
||||
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能拉伸/切除平面", str(plan["message"]))
|
||||
self.statusBar().showMessage("拉伸/切除平面已阻止")
|
||||
self._show_blocked_plan_message("拉伸/切除平面", plan, "拉伸/切除平面已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -742,8 +748,7 @@ class WindowActionMixin:
|
||||
if plan is None:
|
||||
plan = self.model.shell_thickness_plan(face_id, target_thickness)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能调整壳体厚度", str(plan["message"]))
|
||||
self.statusBar().showMessage("壳体厚度调整已阻止")
|
||||
self._show_blocked_plan_message("调整壳体厚度", plan, "壳体厚度调整已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -1073,7 +1078,7 @@ class WindowActionMixin:
|
||||
delta = target_size - current_size if current_size is not None else None
|
||||
ratio = abs(delta) / current_size if current_size is not None and current_size > 1e-9 else None
|
||||
scale = target_size / current_size if current_size is not None and current_size > 1e-9 else None
|
||||
axis_label = "V向尺寸" if axis_key == "height" else "U向尺寸"
|
||||
axis_label = "面内宽度" if axis_key == "height" else "面内长度"
|
||||
return self._quick_blocked_local_face_plan(
|
||||
face_id,
|
||||
blocker,
|
||||
@@ -1153,7 +1158,7 @@ class WindowActionMixin:
|
||||
face_id,
|
||||
blocker,
|
||||
resize_strategy="local-face-plane-offset-deform",
|
||||
edit_strategy_label="偏移变换(局部重建)",
|
||||
edit_strategy_label="偏移(局部重建)",
|
||||
edit_semantics="按当前面垂直方向移动 Face 边界顶点并重建一级相邻面;复杂内孔/多边界 Face 当前不放行。",
|
||||
info=info,
|
||||
extra={
|
||||
@@ -1377,8 +1382,7 @@ class WindowActionMixin:
|
||||
cancelled_status: str,
|
||||
) -> bool:
|
||||
if plan.get("status") == "blocked":
|
||||
QMessageBox.information(self, f"不能{title}", str(plan.get("message", "")))
|
||||
self.statusBar().showMessage(blocked_status)
|
||||
self._show_blocked_plan_message(title, plan, blocked_status)
|
||||
return False
|
||||
if (
|
||||
not self._quick_edit_title_supports_isolation(title)
|
||||
@@ -1428,11 +1432,11 @@ class WindowActionMixin:
|
||||
"壳体厚度(缩放特征)缩放所属对象",
|
||||
"面积(局部重建)",
|
||||
"面面积(缩放特征)",
|
||||
"U向尺寸(局部重建)",
|
||||
"V向尺寸(局部重建)",
|
||||
"U向尺寸(缩放特征)",
|
||||
"V向尺寸(缩放特征)",
|
||||
"偏移变换(局部重建)",
|
||||
"面内长度(局部重建)",
|
||||
"面内宽度(局部重建)",
|
||||
"面内长度(缩放特征)",
|
||||
"面内宽度(缩放特征)",
|
||||
"偏移(局部重建)",
|
||||
"中心(局部重建)",
|
||||
"圆柱高度调整",
|
||||
"高度(缩放特征)缩放所属对象",
|
||||
@@ -1601,6 +1605,280 @@ class WindowActionMixin:
|
||||
return ""
|
||||
return "\n\n诊断信息:\n" + "\n".join(f"- {line}" for line in lines)
|
||||
|
||||
def _edit_blocker_type(self, reason: str) -> tuple[str, str]:
|
||||
text = str(reason or "")
|
||||
unsupported_markers = (
|
||||
"暂不支持",
|
||||
"当前版本",
|
||||
"还没有实现",
|
||||
"未实现",
|
||||
"不支持",
|
||||
"受限能力",
|
||||
"复杂链式",
|
||||
"二级",
|
||||
"三级",
|
||||
"原 CAD",
|
||||
"deferred",
|
||||
"unsupported",
|
||||
"not implemented",
|
||||
)
|
||||
risk_markers = (
|
||||
"风险过高",
|
||||
"风险太高",
|
||||
"高风险",
|
||||
"危险",
|
||||
"长时间卡死",
|
||||
"卡死",
|
||||
"超时",
|
||||
"timeout",
|
||||
"too risky",
|
||||
"high risk",
|
||||
)
|
||||
recognition_markers = (
|
||||
"识别不足",
|
||||
"识别不到",
|
||||
"没有识别",
|
||||
"未识别",
|
||||
"识别不稳",
|
||||
"不稳定",
|
||||
"不明确",
|
||||
"无法确认",
|
||||
"不能确认",
|
||||
"缺少稳定",
|
||||
"置信度",
|
||||
"not recognized",
|
||||
"not recognise",
|
||||
"ambiguous",
|
||||
"unclear",
|
||||
"unstable",
|
||||
)
|
||||
illegal_markers = (
|
||||
"无效",
|
||||
"非法",
|
||||
"必须",
|
||||
"不能",
|
||||
"不存在",
|
||||
"相同",
|
||||
"超过",
|
||||
"小于",
|
||||
"大于",
|
||||
"切空",
|
||||
"退化",
|
||||
"invalid",
|
||||
"requires",
|
||||
"must",
|
||||
"cannot",
|
||||
"missing",
|
||||
"empty",
|
||||
"greater than",
|
||||
"less than",
|
||||
"too small",
|
||||
"too large",
|
||||
"not recognized",
|
||||
"not a",
|
||||
"does not have",
|
||||
)
|
||||
lower = text.lower()
|
||||
if any(marker.lower() in lower for marker in unsupported_markers):
|
||||
return "暂未实现", "当前版本暂未实现这类稳定修改。"
|
||||
if any(marker.lower() in lower for marker in risk_markers):
|
||||
return "风险过高", "当前修改容易破坏 B-Rep 或让几何计算长时间失败,已在执行前阻止。"
|
||||
if any(marker.lower() in lower for marker in recognition_markers):
|
||||
return "识别不足", "程序还没有把当前对象识别成足够稳定的 CAD 特征或一级关系。"
|
||||
if any(marker.lower() in lower for marker in illegal_markers):
|
||||
return "当前操作不合法", "当前输入或选中对象不满足这个操作的基本条件。"
|
||||
return "不能稳定修改", "几何内核没有给出可验证的有效 B-Rep 结果。"
|
||||
|
||||
def _edit_blocker_reason_from_parameters(self, parameters: dict[str, object], prefix: str = "") -> str:
|
||||
candidate_keys: list[str] = []
|
||||
if prefix:
|
||||
candidate_keys.extend((f"{prefix}_blockers", f"{prefix}_message", f"{prefix}_warnings"))
|
||||
candidate_keys.extend(
|
||||
(
|
||||
"blockers",
|
||||
"message",
|
||||
"resize_blockers",
|
||||
"resize_message",
|
||||
"depth_blockers",
|
||||
"depth_message",
|
||||
"move_axis_blockers",
|
||||
"move_axis_message",
|
||||
"boss_resize_blockers",
|
||||
"boss_height_blockers",
|
||||
"existing_fillet_blockers",
|
||||
"fillet_blockers",
|
||||
"chamfer_blockers",
|
||||
"push_pull_message",
|
||||
)
|
||||
)
|
||||
for key in candidate_keys:
|
||||
text = str(parameters.get(key) or "").strip()
|
||||
if text:
|
||||
return text
|
||||
return ""
|
||||
|
||||
def _plan_preflight_blocker(self, plan: dict[str, object]) -> tuple[str, str, str] | None:
|
||||
status = str(plan.get("status") or "").strip().lower()
|
||||
risk = str(plan.get("risk") or "").strip().lower()
|
||||
if status != "blocked" and risk != "blocked":
|
||||
return None
|
||||
reason = self._edit_blocker_reason_from_parameters(plan) or "计划阶段已判断该操作不可执行。"
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
return blocker_type, reason, detail
|
||||
|
||||
def _show_blocked_plan_message(
|
||||
self,
|
||||
title: str,
|
||||
plan: dict[str, object],
|
||||
blocked_status: str,
|
||||
) -> None:
|
||||
blocker = self._plan_preflight_blocker(plan)
|
||||
if blocker is None:
|
||||
blocker = ("不能稳定修改", str(plan.get("message") or "计划阶段已阻止。"), "模型未修改。")
|
||||
blocker_type, reason, detail = blocker
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"不能修改",
|
||||
(
|
||||
"不能修改。\n\n"
|
||||
f"类型:{blocker_type}\n"
|
||||
f"操作:{title}\n\n"
|
||||
f"原因:{_compact_user_message(reason)}\n\n"
|
||||
f"{detail}\n\n"
|
||||
"模型未修改。"
|
||||
),
|
||||
)
|
||||
self.statusBar().showMessage(f"{blocked_status}:{blocker_type}")
|
||||
|
||||
def _show_immediate_cannot_edit_message(
|
||||
self,
|
||||
title: str,
|
||||
reason: str,
|
||||
blocked_status: str,
|
||||
) -> None:
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"不能修改",
|
||||
(
|
||||
"不能修改。\n\n"
|
||||
f"类型:{blocker_type}\n"
|
||||
f"操作:{title}\n\n"
|
||||
f"原因:{_compact_user_message(reason)}\n\n"
|
||||
f"{detail}\n\n"
|
||||
"模型未修改。"
|
||||
),
|
||||
)
|
||||
self.statusBar().showMessage(f"{blocked_status}:{blocker_type}")
|
||||
|
||||
def _edit_preflight_blocker(self, context: dict[str, object]) -> tuple[str, str, str] | None:
|
||||
parameters = context.get("parameters")
|
||||
if not isinstance(parameters, dict):
|
||||
return None
|
||||
if bool(parameters.get("ui_deferred_model_plan")) or bool(parameters.get("ui_deferred_shell_thickness_plan")):
|
||||
if bool(parameters.get("ui_deferred_shell_thickness_plan")):
|
||||
reason = "当前复杂壳体厚度修改还没有快速、稳定的一级关系判断路径。"
|
||||
else:
|
||||
reason = "当前复杂 Face 修改还没有快速、稳定的一级关系判断路径。"
|
||||
detail = (
|
||||
"属于当前版本暂未实现的稳定编辑能力。请改用更明确的孔/槽/凸台/Edge 专门入口,"
|
||||
"或先选择更简单的局部面。"
|
||||
)
|
||||
return ("暂未实现", reason, detail)
|
||||
for key, value in parameters.items():
|
||||
if str(key).startswith("ui_quick_blocked") and bool(value):
|
||||
reason = self._edit_blocker_reason_from_parameters(parameters) or "快速预检已判断该操作不可稳定执行。"
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
return (blocker_type, reason, detail)
|
||||
for key, value in parameters.items():
|
||||
key_text = str(key)
|
||||
if not key_text.endswith("_status"):
|
||||
continue
|
||||
if key_text in {"quick_plan_status", "topology_relation_status", "slot_status", "quality_status"}:
|
||||
continue
|
||||
if str(value or "").strip().lower() != "blocked":
|
||||
continue
|
||||
prefix = key_text[: -len("_status")]
|
||||
reason = self._edit_blocker_reason_from_parameters(parameters, prefix) or "计划阶段已判断该操作不可执行。"
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
return (blocker_type, reason, detail)
|
||||
for key, value in parameters.items():
|
||||
key_text = str(key)
|
||||
if not key_text.endswith("_blockers") and key_text != "blockers":
|
||||
continue
|
||||
reason = str(value or "").strip()
|
||||
if not reason:
|
||||
continue
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
return (blocker_type, reason, detail)
|
||||
return None
|
||||
|
||||
def _show_edit_preflight_blocker(self, blocker: tuple[str, str, str], context: dict[str, object]) -> None:
|
||||
blocker_type, reason, detail = blocker
|
||||
operation_name = str(context.get("operation_name") or "当前操作")
|
||||
target = str(context.get("target") or "当前对象")
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"不能修改",
|
||||
(
|
||||
"不能修改。\n\n"
|
||||
f"类型:{blocker_type}\n"
|
||||
f"对象:{target}\n"
|
||||
f"操作:{operation_name}\n\n"
|
||||
f"原因:{_compact_user_message(reason)}\n\n"
|
||||
f"{detail}\n\n"
|
||||
"模型未修改。"
|
||||
),
|
||||
)
|
||||
self.statusBar().showMessage(f"不能修改:{blocker_type}")
|
||||
|
||||
def _user_facing_edit_failure_message(
|
||||
self,
|
||||
message: str,
|
||||
context: dict[str, object] | None,
|
||||
) -> tuple[str, str]:
|
||||
raw_message = str(message or "").strip()
|
||||
reason = raw_message
|
||||
for marker in ("诊断信息:", "璇婃柇淇℃伅:"):
|
||||
index = reason.find(marker)
|
||||
if index >= 0:
|
||||
reason = reason[:index].strip()
|
||||
replacements = (
|
||||
("隔离子进程执行失败;主程序没有崩溃,原模型保持不变。", ""),
|
||||
("隔离子进程执行超时,已终止危险计算;主程序和原模型保持不变。", ""),
|
||||
("隔离子进程", "后台几何计算"),
|
||||
("子进程", "后台计算"),
|
||||
("isolated worker", "后台几何计算"),
|
||||
("isolated", "后台"),
|
||||
)
|
||||
for old, new in replacements:
|
||||
reason = reason.replace(old, new)
|
||||
reason = _compact_user_message(reason)
|
||||
if not reason:
|
||||
reason = "后台几何计算没有返回可用结果。"
|
||||
|
||||
blocker_type, detail = self._edit_blocker_type(reason)
|
||||
lower_raw = raw_message.lower()
|
||||
if "超时" in raw_message or "timeout" in lower_raw:
|
||||
blocker_type = "暂未实现"
|
||||
detail = "当前版本还不能稳定处理这类复杂拓扑,已停止继续等待。"
|
||||
if "returned an invalid b-rep" in lower_raw or "无效 b-rep" in lower_raw:
|
||||
blocker_type = "几何结果无效"
|
||||
detail = "几何内核生成的结果没有通过 B-Rep 校验,已回滚。"
|
||||
|
||||
operation_name = ""
|
||||
target = ""
|
||||
if isinstance(context, dict):
|
||||
operation_name = str(context.get("operation_name") or "")
|
||||
target = str(context.get("target") or "")
|
||||
lines = ["不能修改。", "", f"类型:{blocker_type}"]
|
||||
if target:
|
||||
lines.append(f"对象:{target}")
|
||||
if operation_name:
|
||||
lines.append(f"操作:{operation_name}")
|
||||
lines.extend(["", f"原因:{reason or '几何计算失败。'}", "", detail, "", "模型未修改。"])
|
||||
return "不能修改", "\n".join(lines)
|
||||
|
||||
def resize_hole(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
@@ -1992,7 +2270,11 @@ class WindowActionMixin:
|
||||
if angular_span is None:
|
||||
angular_span = _float_or_none(info.get("angular_span"))
|
||||
if angular_span is None or angular_span <= 1e-6 or angular_span >= math.tau * 0.92:
|
||||
QMessageBox.information(self, f"不能整体修改{label}", "当前候选没有稳定的部分圆柱角度,不能换算为目标圆柱直径。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
f"整体修改{label}",
|
||||
"当前候选没有稳定的部分圆柱角度,不能换算为目标圆柱直径。",
|
||||
f"整体修改{label}已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
span = min(max(float(angular_span), 1e-6), math.tau - 1e-6)
|
||||
@@ -2000,12 +2282,20 @@ class WindowActionMixin:
|
||||
sagitta_factor = 1.0 - math.cos(min(span, math.pi) * 0.5)
|
||||
if mode == "width":
|
||||
if abs(sin_half_span) <= 1e-6:
|
||||
QMessageBox.information(self, "不能整体修改槽宽", "当前槽圆弧角度过小,不能可靠换算槽宽。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"整体修改槽宽",
|
||||
"当前槽圆弧角度过小,不能可靠换算槽宽。",
|
||||
"整体修改槽宽已阻止",
|
||||
)
|
||||
return
|
||||
target_diameter = target_value / sin_half_span
|
||||
elif mode == "depth":
|
||||
if sagitta_factor <= 1e-6:
|
||||
QMessageBox.information(self, "不能整体修改槽深", "当前槽圆弧角度过小,不能可靠换算槽深。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"整体修改槽深",
|
||||
"当前槽圆弧角度过小,不能可靠换算槽深。",
|
||||
"整体修改槽深已阻止",
|
||||
)
|
||||
return
|
||||
target_diameter = 2.0 * target_value / sagitta_factor
|
||||
else:
|
||||
@@ -2122,11 +2412,19 @@ class WindowActionMixin:
|
||||
if angular_span is None:
|
||||
angular_span = _float_or_none(info.get("angular_span"))
|
||||
if angular_span is None or angular_span <= 1e-6 or angular_span >= math.tau * 0.92:
|
||||
QMessageBox.information(self, "不能调整槽宽", "当前候选没有稳定的部分圆柱角度,不能换算槽宽。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整槽宽",
|
||||
"当前候选没有稳定的部分圆柱角度,不能换算槽宽。",
|
||||
"槽/半孔宽度调整已阻止",
|
||||
)
|
||||
return
|
||||
sin_half_span = math.sin(min(max(angular_span, 1e-6), math.tau - 1e-6) / 2.0)
|
||||
if abs(sin_half_span) <= 1e-6:
|
||||
QMessageBox.information(self, "不能调整槽宽", "当前槽圆弧角度过小,不能可靠换算为圆柱直径。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整槽宽",
|
||||
"当前槽圆弧角度过小,不能可靠换算为圆柱直径。",
|
||||
"槽/半孔宽度调整已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
target_diameter = target_width / sin_half_span
|
||||
@@ -2244,12 +2542,20 @@ class WindowActionMixin:
|
||||
if angular_span is None:
|
||||
angular_span = _float_or_none(info.get("angular_span"))
|
||||
if angular_span is None or angular_span <= 1e-6 or angular_span >= math.tau * 0.92:
|
||||
QMessageBox.information(self, "不能调整槽深", "当前候选没有稳定的部分圆柱角度,不能换算槽深。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整槽深",
|
||||
"当前候选没有稳定的部分圆柱角度,不能换算槽深。",
|
||||
"槽/半孔深度调整已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
sagitta_factor = 1.0 - math.cos(min(max(angular_span, 1e-6), math.pi) / 2.0)
|
||||
if sagitta_factor <= 1e-6:
|
||||
QMessageBox.information(self, "不能调整槽深", "当前槽圆弧角度过小,不能可靠换算为圆柱直径。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整槽深",
|
||||
"当前槽圆弧角度过小,不能可靠换算为圆柱直径。",
|
||||
"槽/半孔深度调整已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
target_diameter = 2.0 * target_depth / sagitta_factor
|
||||
@@ -2371,7 +2677,11 @@ class WindowActionMixin:
|
||||
if angular_span is None:
|
||||
angular_span = _float_or_none(info.get("angular_span"))
|
||||
if angular_span is None or angular_span <= 1e-6 or angular_span >= math.tau * 0.92:
|
||||
QMessageBox.information(self, "不能调整圆弧长度", "当前候选没有稳定的部分圆柱角度,不能换算圆弧长度。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整圆弧长度",
|
||||
"当前候选没有稳定的部分圆柱角度,不能换算圆弧长度。",
|
||||
"槽/半孔圆弧长度调整已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
target_diameter = 2.0 * target_arc_length / angular_span
|
||||
@@ -2509,7 +2819,11 @@ class WindowActionMixin:
|
||||
if current_angular_span is None:
|
||||
current_angular_span = _float_or_none(info.get("angular_span"))
|
||||
if current_angular_span is None or current_angular_span <= 1e-6 or current_angular_span >= math.tau * 0.92:
|
||||
QMessageBox.information(self, "不能调整圆弧角度", "当前候选没有稳定的部分圆柱角度。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"调整圆弧角度",
|
||||
"当前候选没有稳定的部分圆柱角度。",
|
||||
"槽/半孔圆弧角度调整已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
plan = self.model.cylindrical_slot_angular_span_plan(face_id, target_angular_span)
|
||||
@@ -2626,8 +2940,7 @@ class WindowActionMixin:
|
||||
pair_face_id=pair_face_id,
|
||||
)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能调整槽孔总长度", str(plan["message"]))
|
||||
self.statusBar().showMessage("槽孔总长度调整已阻止")
|
||||
self._show_blocked_plan_message("调整槽孔总长度", plan, "槽孔总长度调整已阻止")
|
||||
return
|
||||
lines = [
|
||||
f"Face: {face_id}",
|
||||
@@ -2725,8 +3038,7 @@ class WindowActionMixin:
|
||||
pair_face_id=pair_face_id,
|
||||
)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能调整槽孔中心距", str(plan["message"]))
|
||||
self.statusBar().showMessage("槽孔中心距调整已阻止")
|
||||
self._show_blocked_plan_message("调整槽孔中心距", plan, "槽孔中心距调整已阻止")
|
||||
return
|
||||
lines = [
|
||||
f"Face: {face_id}",
|
||||
@@ -2817,8 +3129,7 @@ class WindowActionMixin:
|
||||
return
|
||||
plan = self.model.cylindrical_boss_resize_plan(self.selected_face_id, diameter)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能调整凸台直径", str(plan["message"]))
|
||||
self.statusBar().showMessage("圆柱凸台直径调整已阻止")
|
||||
self._show_blocked_plan_message("调整凸台直径", plan, "圆柱凸台直径调整已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
target_to_height_ratio = plan.get("target_to_height_ratio", "")
|
||||
@@ -3013,8 +3324,7 @@ class WindowActionMixin:
|
||||
face_id = self.selected_face_id
|
||||
plan = self.model.cylindrical_boss_height_plan(face_id, target_height)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能调整凸台高度", str(plan["message"]))
|
||||
self.statusBar().showMessage("圆柱凸台高度调整已阻止")
|
||||
self._show_blocked_plan_message("调整凸台高度", plan, "圆柱凸台高度调整已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -3280,8 +3590,7 @@ class WindowActionMixin:
|
||||
return
|
||||
plan = self.model.cylindrical_suppress_plan(self.selected_face_id)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能封堵圆柱孔", str(plan["message"]))
|
||||
self.statusBar().showMessage("封堵圆柱孔已阻止")
|
||||
self._show_blocked_plan_message("封堵圆柱孔", plan, "封堵圆柱孔已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -3717,8 +4026,7 @@ class WindowActionMixin:
|
||||
plan = self.model.existing_fillet_resize_plan(face_id, target_radius)
|
||||
isolation = self._isolation_for_plan(plan, "resize_existing_fillet", [face_id, target_radius])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改已有圆角", str(plan["message"]))
|
||||
self.statusBar().showMessage("已有圆角半径修改已阻止")
|
||||
self._show_blocked_plan_message("修改已有圆角", plan, "已有圆角半径修改已阻止")
|
||||
return
|
||||
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -3811,8 +4119,7 @@ class WindowActionMixin:
|
||||
plan = self.model.edge_fillet_plan(edge_id, radius)
|
||||
isolation = self._isolation_for_plan(plan, "fillet_edge", [edge_id, radius])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能添加圆角", str(plan["message"]))
|
||||
self.statusBar().showMessage("添加圆角已阻止")
|
||||
self._show_blocked_plan_message("添加圆角", plan, "添加圆角已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -3893,8 +4200,7 @@ class WindowActionMixin:
|
||||
plan = self.model.edge_chamfer_plan(edge_id, distance)
|
||||
isolation = self._isolation_for_plan(plan, "chamfer_edge", [edge_id, distance])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能添加倒角", str(plan["message"]))
|
||||
self.statusBar().showMessage("添加倒角已阻止")
|
||||
self._show_blocked_plan_message("添加倒角", plan, "添加倒角已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -4159,8 +4465,7 @@ class WindowActionMixin:
|
||||
[edge_id, target_length, anchor_mode, strategy_mode],
|
||||
)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改Edge长度", str(plan["message"]))
|
||||
self.statusBar().showMessage("Edge长度修改已阻止")
|
||||
self._show_blocked_plan_message("修改Edge长度", plan, "Edge长度修改已阻止")
|
||||
return
|
||||
|
||||
if plan["risk"] != "low":
|
||||
@@ -4325,8 +4630,7 @@ class WindowActionMixin:
|
||||
[edge_id, target_length, anchor_mode, strategy_mode],
|
||||
)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改Edge长度", str(plan["message"]))
|
||||
self.statusBar().showMessage("Edge长度修改已阻止")
|
||||
self._show_blocked_plan_message("修改Edge长度", plan, "Edge长度修改已阻止")
|
||||
return
|
||||
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -4498,8 +4802,7 @@ class WindowActionMixin:
|
||||
[edge_id, target_radius, axis_kind],
|
||||
)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, f"不能修改椭圆Edge{axis_label}", str(plan["message"]))
|
||||
self.statusBar().showMessage(f"椭圆Edge{axis_label}修改已阻止")
|
||||
self._show_blocked_plan_message(f"修改椭圆Edge{axis_label}", plan, f"椭圆Edge{axis_label}修改已阻止")
|
||||
return
|
||||
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -4861,8 +5164,7 @@ class WindowActionMixin:
|
||||
plan = self.model.conical_reference_radius_plan(face_id, target_radius)
|
||||
isolation = self._isolation_for_plan(plan, "resize_cone_reference_radius", [face_id, target_radius])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改圆锥面参数", str(plan["message"]))
|
||||
self.statusBar().showMessage("圆锥面参数修改已阻止")
|
||||
self._show_blocked_plan_message("修改圆锥面参数", plan, "圆锥面参数修改已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -4960,8 +5262,7 @@ class WindowActionMixin:
|
||||
plan = self.model.conical_semi_angle_plan(face_id, target_angle_degrees)
|
||||
isolation = self._isolation_for_plan(plan, "resize_cone_semi_angle", [face_id, target_angle_degrees])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改圆锥半角", str(plan["message"]))
|
||||
self.statusBar().showMessage("圆锥半角修改已阻止")
|
||||
self._show_blocked_plan_message("修改圆锥半角", plan, "圆锥半角修改已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -5057,8 +5358,7 @@ class WindowActionMixin:
|
||||
plan = self.model.spherical_radius_plan(face_id, target_radius)
|
||||
isolation = self._isolation_for_plan(plan, "resize_sphere_radius", [face_id, target_radius])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改球面(缩放特征)", str(plan["message"]))
|
||||
self.statusBar().showMessage("球面(缩放特征)修改已阻止")
|
||||
self._show_blocked_plan_message("修改球面(缩放特征)", plan, "球面(缩放特征)修改已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -5160,8 +5460,7 @@ class WindowActionMixin:
|
||||
plan = self.model.toroidal_radius_plan(face_id, target_radius, mode_key)
|
||||
isolation = self._isolation_for_plan(plan, "resize_torus_radius", [face_id, target_radius, mode_key])
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改环面(缩放特征)", str(plan["message"]))
|
||||
self.statusBar().showMessage("环面(缩放特征)修改已阻止")
|
||||
self._show_blocked_plan_message("修改环面(缩放特征)", plan, "环面(缩放特征)修改已阻止")
|
||||
return
|
||||
if plan["risk"] != "low":
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
@@ -5260,8 +5559,7 @@ class WindowActionMixin:
|
||||
face_id = self.selected_face_id
|
||||
plan = self.model.face_area_scale_plan(face_id, target_area)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能修改面面积", str(plan["message"]))
|
||||
self.statusBar().showMessage("面面积修改已阻止")
|
||||
self._show_blocked_plan_message("修改面面积", plan, "面面积修改已阻止")
|
||||
return
|
||||
warnings = str(plan.get("warnings", ""))
|
||||
warnings_line = f"警告: {warnings}\n\n" if warnings else ""
|
||||
@@ -5428,7 +5726,7 @@ class WindowActionMixin:
|
||||
if self.model is None:
|
||||
return
|
||||
axis_key = "height" if str(axis).lower() == "height" else "width"
|
||||
axis_label = "V向尺寸" if axis_key == "height" else "U向尺寸"
|
||||
axis_label = "面内宽度" if axis_key == "height" else "面内长度"
|
||||
if self._edit_busy(f"请等待当前编辑完成后再修改{axis_label}(局部重建)。"):
|
||||
return
|
||||
if self.selected_face_id is None:
|
||||
@@ -5450,10 +5748,10 @@ class WindowActionMixin:
|
||||
lines = [
|
||||
f"Face: {face_id}",
|
||||
f"修改对象: {axis_label}(局部重建)",
|
||||
f"当前U向尺寸: {_format_value(plan.get('current_face_width'))}",
|
||||
f"目标U向尺寸: {_format_value(plan.get('target_face_width'))}",
|
||||
f"当前V向尺寸: {_format_value(plan.get('current_face_height'))}",
|
||||
f"目标V向尺寸: {_format_value(plan.get('target_face_height'))}",
|
||||
f"当前面内长度: {_format_value(plan.get('current_face_width'))}",
|
||||
f"目标面内长度: {_format_value(plan.get('target_face_width'))}",
|
||||
f"当前面内宽度: {_format_value(plan.get('current_face_height'))}",
|
||||
f"目标面内宽度: {_format_value(plan.get('target_face_height'))}",
|
||||
f"变化量: {_format_value(plan.get('face_size_delta'))}",
|
||||
f"变化比例: {_format_percent(plan.get('face_size_delta_ratio'))}",
|
||||
f"缩放比例: {_format_value(plan.get('face_size_scale'))}",
|
||||
@@ -5522,7 +5820,7 @@ class WindowActionMixin:
|
||||
if self.model is None:
|
||||
return
|
||||
axis_key = "height" if str(axis).lower() == "height" else "width"
|
||||
axis_label = "V向尺寸" if axis_key == "height" else "U向尺寸"
|
||||
axis_label = "面内宽度" if axis_key == "height" else "面内长度"
|
||||
if self._edit_busy(f"请等待当前编辑完成后再修改{axis_label}(缩放特征)。"):
|
||||
return
|
||||
if self.selected_face_id is None:
|
||||
@@ -5542,10 +5840,10 @@ class WindowActionMixin:
|
||||
lines = [
|
||||
f"Face: {face_id}",
|
||||
f"修改对象: {axis_label}(缩放特征)",
|
||||
f"当前U向尺寸: {_format_value(plan.get('current_face_width'))}",
|
||||
f"目标U向尺寸: {_format_value(plan.get('target_face_width'))}",
|
||||
f"当前V向尺寸: {_format_value(plan.get('current_face_height'))}",
|
||||
f"目标V向尺寸: {_format_value(plan.get('target_face_height'))}",
|
||||
f"当前面内长度: {_format_value(plan.get('current_face_width'))}",
|
||||
f"目标面内长度: {_format_value(plan.get('target_face_width'))}",
|
||||
f"当前面内宽度: {_format_value(plan.get('current_face_height'))}",
|
||||
f"目标面内宽度: {_format_value(plan.get('target_face_height'))}",
|
||||
f"变化量: {_format_value(plan.get('face_size_delta'))}",
|
||||
f"变化比例: {_format_percent(plan.get('face_size_delta_ratio'))}",
|
||||
f"缩放比例: {_format_value(plan.get('face_size_scale'))}",
|
||||
@@ -5625,7 +5923,7 @@ class WindowActionMixin:
|
||||
def move_selected_face_plane_position_by_translation(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
if self._edit_busy("请等待当前编辑完成后再按偏移变换平移所属对象。"):
|
||||
if self._edit_busy("请等待当前编辑完成后再按偏移平移所属对象。"):
|
||||
return
|
||||
if self.selected_face_id is None:
|
||||
QMessageBox.information(self, "未选择Face", "请先选择一个平面 Face。")
|
||||
@@ -5633,14 +5931,13 @@ class WindowActionMixin:
|
||||
try:
|
||||
distance = float(self.offset_input.text())
|
||||
except (AttributeError, ValueError):
|
||||
QMessageBox.critical(self, "偏移变换无效", "请输入数字形式的目标偏移变换位置。")
|
||||
QMessageBox.critical(self, "偏移无效", "请输入数字形式的目标偏移位置。")
|
||||
return
|
||||
face_id = self.selected_face_id
|
||||
plan = self.model.face_plane_offset_owning_translation_plan(face_id, distance)
|
||||
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能按偏移变换平移", str(plan["message"]))
|
||||
self.statusBar().showMessage("偏移变换整体平移已阻止")
|
||||
self._show_blocked_plan_message("按偏移平移", plan, "偏移整体平移已阻止")
|
||||
return
|
||||
current_position = float(plan.get("current_plane_position", 0.0) or 0.0)
|
||||
target_position = float(plan.get("target_plane_position", current_position) or current_position)
|
||||
@@ -5652,7 +5949,7 @@ class WindowActionMixin:
|
||||
target_position,
|
||||
plane_direction,
|
||||
):
|
||||
self.statusBar().showMessage("已取消偏移变换整体平移")
|
||||
self.statusBar().showMessage("已取消偏移整体平移")
|
||||
return
|
||||
self.clear_edit_preview(render=False)
|
||||
|
||||
@@ -5663,7 +5960,7 @@ class WindowActionMixin:
|
||||
moved_id = plan.get("solid_id") if moved_kind == "solid" else plan.get("part_id")
|
||||
self._run_edit_action(
|
||||
action,
|
||||
operation_name="偏移变换(移动特征)",
|
||||
operation_name="偏移(移动特征)",
|
||||
target=f"Face {face_id}",
|
||||
parameters={
|
||||
"face_id": face_id,
|
||||
@@ -5684,8 +5981,8 @@ class WindowActionMixin:
|
||||
"translate_warnings": plan.get("warnings"),
|
||||
"translate_blockers": plan.get("blockers"),
|
||||
"resize_strategy": "translate-owning-shape-from-plane-offset",
|
||||
"edit_strategy_label": "按偏移变换平移所属对象",
|
||||
"edit_semantics": "把目标偏移变换位置换算成沿当前面垂直方向的平移量,并平移所属特征或 Solid;不拉伸/切除,不切削,也不补料。",
|
||||
"edit_strategy_label": "按偏移平移所属对象",
|
||||
"edit_semantics": "把目标偏移位置换算成沿当前面垂直方向的平移量,并平移所属特征或 Solid;不拉伸/切除,不切削,也不补料。",
|
||||
},
|
||||
target_kind="face",
|
||||
target_id=face_id,
|
||||
@@ -5694,7 +5991,7 @@ class WindowActionMixin:
|
||||
def move_selected_face_plane_position_local(self) -> None:
|
||||
if self.model is None:
|
||||
return
|
||||
if self._edit_busy("请等待当前编辑完成后再执行偏移变换(局部重建)。"):
|
||||
if self._edit_busy("请等待当前编辑完成后再执行偏移(局部重建)。"):
|
||||
return
|
||||
if self.selected_face_id is None:
|
||||
QMessageBox.information(self, "未选择Face", "请先选择一个平面 Face。")
|
||||
@@ -5702,7 +5999,7 @@ class WindowActionMixin:
|
||||
try:
|
||||
distance = float(self.offset_input.text())
|
||||
except (AttributeError, ValueError):
|
||||
QMessageBox.critical(self, "偏移变换无效", "请输入数字形式的目标偏移变换位置。")
|
||||
QMessageBox.critical(self, "偏移无效", "请输入数字形式的目标偏移位置。")
|
||||
return
|
||||
|
||||
face_id = self.selected_face_id
|
||||
@@ -5711,8 +6008,8 @@ class WindowActionMixin:
|
||||
plan = self.model.face_plane_offset_local_plan(face_id, distance)
|
||||
lines = [
|
||||
f"Face: {face_id}",
|
||||
f"当前偏移变换位置: {_format_value(plan.get('current_plane_position'))}",
|
||||
f"目标偏移变换位置: {_format_value(plan.get('target_plane_position'))}",
|
||||
f"当前偏移位置: {_format_value(plan.get('current_plane_position'))}",
|
||||
f"目标偏移位置: {_format_value(plan.get('target_plane_position'))}",
|
||||
f"平面方向: {_format_value(plan.get('plane_direction'))}",
|
||||
f"移动向量: {_format_value(plan.get('face_center_move_vector'))}",
|
||||
f"移动距离: {_format_value(plan.get('face_center_move_distance'))}",
|
||||
@@ -5722,11 +6019,11 @@ class WindowActionMixin:
|
||||
f"影响目标: {_format_value(plan.get('local_face_deform_target_kind'))}",
|
||||
]
|
||||
if not self._confirm_quick_edit_plan(
|
||||
"偏移变换(局部重建)",
|
||||
"偏移(局部重建)",
|
||||
plan,
|
||||
lines,
|
||||
"偏移变换(局部重建)已阻止",
|
||||
"已取消偏移变换(局部重建)",
|
||||
"偏移(局部重建)已阻止",
|
||||
"已取消偏移(局部重建)",
|
||||
):
|
||||
return
|
||||
self.clear_edit_preview(render=False)
|
||||
@@ -5736,7 +6033,7 @@ class WindowActionMixin:
|
||||
|
||||
self._run_edit_action(
|
||||
action,
|
||||
operation_name="偏移变换(局部重建)",
|
||||
operation_name="偏移(局部重建)",
|
||||
target=f"Face {face_id}",
|
||||
parameters={
|
||||
"face_id": face_id,
|
||||
@@ -5758,9 +6055,9 @@ class WindowActionMixin:
|
||||
"local_face_deform_face_count": plan.get("local_face_deform_face_count"),
|
||||
"local_face_deform_moved_point_count": plan.get("local_face_deform_moved_point_count"),
|
||||
"resize_strategy": "local-face-plane-offset-deform",
|
||||
"edit_strategy_label": "偏移变换(局部重建)",
|
||||
"edit_strategy_label": "偏移(局部重建)",
|
||||
"edit_semantics": (
|
||||
"把目标偏移变换位置换算成沿当前面垂直方向的移动量,移动当前 Face 的顶点并重建相邻平面;"
|
||||
"把目标偏移位置换算成沿当前面垂直方向的移动量,移动当前 Face 的顶点并重建相邻平面;"
|
||||
"不拉伸/切除加料/切削,也不平移所属对象。"
|
||||
),
|
||||
"resize_status": plan.get("status"),
|
||||
@@ -5813,12 +6110,15 @@ class WindowActionMixin:
|
||||
return self.model.move_face_center_owning(face_id, target_center)
|
||||
|
||||
else:
|
||||
QMessageBox.information(self, "不能移动Face中心", "当前 Face 没有关联到稳定的所属对象。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"移动Face中心",
|
||||
"当前 Face 没有关联到稳定的所属对象。",
|
||||
"Face中心移动已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能移动Face中心", str(plan["message"]))
|
||||
self.statusBar().showMessage("Face中心移动已阻止")
|
||||
self._show_blocked_plan_message("移动Face中心", plan, "Face中心移动已阻止")
|
||||
return
|
||||
if not self._confirm_face_center_move_plan(plan, face_id, current_center, target_center):
|
||||
self.statusBar().showMessage("已取消Face中心移动")
|
||||
@@ -5868,7 +6168,11 @@ class WindowActionMixin:
|
||||
face_id = self.selected_face_id
|
||||
current_center = self._selected_face_center_for_translation(face_id)
|
||||
if current_center is None:
|
||||
QMessageBox.information(self, "不能执行中心(局部重建)", "当前 Face 缺少稳定中心坐标。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"中心(局部重建)",
|
||||
"当前 Face 缺少稳定中心坐标。",
|
||||
"中心(局部重建)已阻止",
|
||||
)
|
||||
return
|
||||
target_center = (
|
||||
current_center[0] + vector[0],
|
||||
@@ -5953,7 +6257,11 @@ class WindowActionMixin:
|
||||
info = self._selected_face_info_snapshot()
|
||||
current_center = self._selected_axis_center_for_translation(info)
|
||||
if current_center is None:
|
||||
QMessageBox.information(self, "不能按轴心平移", "当前对象缺少稳定轴心坐标。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"按轴心平移",
|
||||
"当前对象缺少稳定轴心坐标。",
|
||||
"按轴心平移所属对象已阻止",
|
||||
)
|
||||
return
|
||||
target_center = (
|
||||
current_center[0] + vector[0],
|
||||
@@ -5977,12 +6285,15 @@ class WindowActionMixin:
|
||||
return self.model.translate_part(moved_id, vector)
|
||||
|
||||
else:
|
||||
QMessageBox.information(self, "不能按轴心平移", "当前对象没有关联到稳定的所属特征或 Solid。")
|
||||
self._show_immediate_cannot_edit_message(
|
||||
"按轴心平移",
|
||||
"当前对象没有关联到稳定的所属特征或 Solid。",
|
||||
"按轴心平移所属对象已阻止",
|
||||
)
|
||||
return
|
||||
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能按轴心平移", str(plan["message"]))
|
||||
self.statusBar().showMessage("按轴心平移所属对象已阻止")
|
||||
self._show_blocked_plan_message("按轴心平移", plan, "按轴心平移所属对象已阻止")
|
||||
return
|
||||
if not self._confirm_axis_center_translation_plan(plan, face_id, current_center, target_center):
|
||||
self.statusBar().showMessage("已取消按轴心平移所属对象")
|
||||
@@ -6184,23 +6495,23 @@ class WindowActionMixin:
|
||||
warnings_line = f"警告: {warnings}\n\n" if warnings else ""
|
||||
result = QMessageBox.question(
|
||||
self,
|
||||
"确认偏移变换整体平移",
|
||||
"确认偏移整体平移",
|
||||
(
|
||||
f"Face: {face_id}\n"
|
||||
f"移动对象: {_format_value(plan.get('target_kind', ''))}\n"
|
||||
f"零件: {_format_value(plan.get('part_id', ''))}\n"
|
||||
f"Solid: {_format_value(plan.get('solid_id', ''))}\n"
|
||||
f"当前偏移变换位置: {_format_value(current_position)}\n"
|
||||
f"目标偏移变换位置: {_format_value(target_position)}\n"
|
||||
f"当前偏移位置: {_format_value(current_position)}\n"
|
||||
f"目标偏移位置: {_format_value(target_position)}\n"
|
||||
f"平面方向: {_format_value(plane_direction)}\n"
|
||||
f"平移向量: {_format_value(plan['translation_vector'])}\n"
|
||||
f"平移距离: {_format_value(plan['translation_distance'])}\n"
|
||||
f"执行策略: 按偏移变换平移所属对象\n"
|
||||
f"执行策略: 按偏移平移所属对象\n"
|
||||
f"建模意图: 沿当前面垂直方向平移所属特征或 Solid;不拉伸/切除,不切削,也不补料。\n"
|
||||
f"风险: {plan['risk']}\n\n"
|
||||
f"{warnings_line}"
|
||||
f"{plan['message']}\n\n"
|
||||
"如果你想改变厚度或把这个面推出/切入,请在“偏移变换”这一行把建模意图选为“拉伸/切除”。确定继续吗?"
|
||||
"如果你想改变厚度或把这个面推出/切入,请在“偏移”这一行把建模意图选为“拉伸/切除”。确定继续吗?"
|
||||
),
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
@@ -6223,8 +6534,7 @@ class WindowActionMixin:
|
||||
part_id = self.selected_part_id
|
||||
plan = self.model.translate_part_plan(part_id, vector)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能平移零件", str(plan["message"]))
|
||||
self.statusBar().showMessage("平移零件已阻止")
|
||||
self._show_blocked_plan_message("平移零件", plan, "平移零件已阻止")
|
||||
return
|
||||
if not self._confirm_translation_plan("确认平移零件", plan):
|
||||
self.statusBar().showMessage("已取消平移零件")
|
||||
@@ -6268,8 +6578,7 @@ class WindowActionMixin:
|
||||
solid_id = self.selected_solid_id
|
||||
plan = self.model.translate_solid_plan(solid_id, vector)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能平移Solid", str(plan["message"]))
|
||||
self.statusBar().showMessage("平移Solid已阻止")
|
||||
self._show_blocked_plan_message("平移Solid", plan, "平移Solid已阻止")
|
||||
return
|
||||
if not self._confirm_translation_plan("确认平移Solid", plan):
|
||||
self.statusBar().showMessage("已取消平移Solid")
|
||||
@@ -6351,8 +6660,7 @@ class WindowActionMixin:
|
||||
part_id = self.selected_part_id
|
||||
plan = self.model.rotate_part_plan(part_id, axis, angle)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能旋转零件", str(plan["message"]))
|
||||
self.statusBar().showMessage("旋转零件已阻止")
|
||||
self._show_blocked_plan_message("旋转零件", plan, "旋转零件已阻止")
|
||||
return
|
||||
if not self._confirm_rotation_plan("确认旋转零件", plan):
|
||||
self.statusBar().showMessage("已取消旋转零件")
|
||||
@@ -6397,8 +6705,7 @@ class WindowActionMixin:
|
||||
solid_id = self.selected_solid_id
|
||||
plan = self.model.rotate_solid_plan(solid_id, axis, angle)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能旋转Solid", str(plan["message"]))
|
||||
self.statusBar().showMessage("旋转Solid已阻止")
|
||||
self._show_blocked_plan_message("旋转Solid", plan, "旋转Solid已阻止")
|
||||
return
|
||||
if not self._confirm_rotation_plan("确认旋转Solid", plan):
|
||||
self.statusBar().showMessage("已取消旋转Solid")
|
||||
@@ -6445,8 +6752,7 @@ class WindowActionMixin:
|
||||
part_id = self.selected_part_id
|
||||
plan = self.model.scale_part_plan(part_id, target_diagonal)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能缩放零件", str(plan["message"]))
|
||||
self.statusBar().showMessage("缩放零件已阻止")
|
||||
self._show_blocked_plan_message("缩放零件", plan, "缩放零件已阻止")
|
||||
return
|
||||
if not self._confirm_scale_plan("确认缩放零件", plan):
|
||||
self.statusBar().showMessage("已取消缩放零件")
|
||||
@@ -6493,8 +6799,7 @@ class WindowActionMixin:
|
||||
solid_id = self.selected_solid_id
|
||||
plan = self.model.scale_solid_plan(solid_id, target_diagonal)
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能缩放Solid", str(plan["message"]))
|
||||
self.statusBar().showMessage("缩放Solid已阻止")
|
||||
self._show_blocked_plan_message("缩放Solid", plan, "缩放Solid已阻止")
|
||||
return
|
||||
if not self._confirm_scale_plan("确认缩放Solid", plan):
|
||||
self.statusBar().showMessage("已取消缩放Solid")
|
||||
@@ -6594,8 +6899,7 @@ class WindowActionMixin:
|
||||
run_target_kind = "solid"
|
||||
|
||||
if plan["status"] == "blocked":
|
||||
QMessageBox.information(self, "不能按轴缩放", str(plan["message"]))
|
||||
self.statusBar().showMessage("按轴缩放已阻止")
|
||||
self._show_blocked_plan_message("按轴缩放", plan, "按轴缩放已阻止")
|
||||
return
|
||||
if not self._confirm_axis_scale_plan(title, plan):
|
||||
self.statusBar().showMessage("已取消按轴缩放")
|
||||
@@ -7075,6 +7379,10 @@ class WindowActionMixin:
|
||||
"edit_result_deflection": result_deflection,
|
||||
"isolation": dict(isolation or {}),
|
||||
}
|
||||
blocker = self._edit_preflight_blocker(context)
|
||||
if blocker is not None:
|
||||
self._show_edit_preflight_blocker(blocker, context)
|
||||
return
|
||||
|
||||
self._begin_edit_task(operation_name)
|
||||
self.pending_edit_context = context
|
||||
@@ -7563,7 +7871,7 @@ class WindowActionMixin:
|
||||
target_width = _float_or_none(parameters.get("target_face_width"))
|
||||
target_height = _float_or_none(parameters.get("target_face_height"))
|
||||
if target_width is not None or target_height is not None:
|
||||
checks.append(("U向尺寸/V向尺寸", self._face_target_size_matches(model, face_ids, target_width, target_height)))
|
||||
checks.append(("面内长度/面内宽度", self._face_target_size_matches(model, face_ids, target_width, target_height)))
|
||||
|
||||
target_center = _triple_or_none(parameters.get("target_face_center"))
|
||||
if target_center is not None:
|
||||
@@ -7577,7 +7885,7 @@ class WindowActionMixin:
|
||||
if target_position is not None and plane_direction is not None:
|
||||
checks.append(
|
||||
(
|
||||
"偏移变换",
|
||||
"偏移",
|
||||
self._face_target_plane_position_matches(
|
||||
model,
|
||||
face_ids,
|
||||
@@ -8005,9 +8313,9 @@ class WindowActionMixin:
|
||||
"面",
|
||||
"面积",
|
||||
"中心",
|
||||
"U向尺寸",
|
||||
"V向尺寸",
|
||||
"偏移变换",
|
||||
"面内长度",
|
||||
"面内宽度",
|
||||
"偏移",
|
||||
"壳体",
|
||||
"拉伸/切除",
|
||||
"圆锥",
|
||||
@@ -8058,13 +8366,13 @@ class WindowActionMixin:
|
||||
progress_text = f"{operation_name} 正在后台计算,预览表示局部边形变、端面拉伸/切除或后备策略后的目标范围。"
|
||||
elif "面积(局部重建)" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会在面内移动所选 Face 顶点并重建相邻平面。"
|
||||
elif "U向尺寸(缩放特征)" in operation_name or "V向尺寸(缩放特征)" in operation_name:
|
||||
elif "面内长度(缩放特征)" in operation_name or "面内宽度(缩放特征)" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会沿选中 Face 的平面内方向缩放所属特征或 Solid,其它几何会跟随变化。"
|
||||
elif "U向尺寸(局部重建)" in operation_name or "V向尺寸(局部重建)" in operation_name:
|
||||
elif "面内长度(局部重建)" in operation_name or "面内宽度(局部重建)" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会只沿选中 Face 的一个平面内方向缩放顶点并重建相邻平面。"
|
||||
elif "偏移变换(局部重建)" in operation_name:
|
||||
elif "偏移(局部重建)" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会沿当前面垂直方向移动所选 Face 顶点并重建相邻平面。"
|
||||
elif "偏移变换(移动特征)" in operation_name:
|
||||
elif "偏移(移动特征)" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会沿当前面垂直方向平移所属特征或 Solid,不拉伸/切除。"
|
||||
elif "Face中心" in operation_name:
|
||||
progress_text = f"{operation_name} 正在后台计算;当前会平移所属特征或 Solid,不做单面局部扭曲。"
|
||||
@@ -8199,15 +8507,19 @@ class WindowActionMixin:
|
||||
if hasattr(self, "_is_ui_thread") and not self._is_ui_thread():
|
||||
self._invoke_on_ui_thread(lambda message=message: self._fail_edit_action(message))
|
||||
return
|
||||
context = self.pending_edit_context
|
||||
close_after_cancel = bool(getattr(self, "close_after_edit_cancel", False))
|
||||
if close_after_cancel:
|
||||
self.close_after_edit_cancel = False
|
||||
self._end_edit_task(clear_preview=True)
|
||||
if not close_after_cancel:
|
||||
QMessageBox.critical(self, "操作失败", message)
|
||||
title, user_message = self._user_facing_edit_failure_message(message, context)
|
||||
QMessageBox.information(self, title, user_message)
|
||||
self._clear_editable_candidates()
|
||||
self._clear_cylinder_candidates()
|
||||
self.statusBar().showMessage("后台编辑已取消,模型已保持在编辑前状态" if close_after_cancel else "操作失败,模型已保持在编辑前状态")
|
||||
self.statusBar().showMessage(
|
||||
"后台编辑已取消,模型已保持在编辑前状态" if close_after_cancel else "不能修改,模型未修改"
|
||||
)
|
||||
if close_after_cancel:
|
||||
if self.edit_thread is not None and self.edit_thread.isRunning():
|
||||
self.edit_thread.quit()
|
||||
|
||||
Reference in New Issue
Block a user