feat: 完善 Face 一级编辑与隔离计算
This commit is contained in:
@@ -19,6 +19,11 @@ if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from step_editor.model import StepModel
|
||||
from step_editor.window_actions import WindowActionMixin
|
||||
|
||||
|
||||
class _WindowActionProbe(WindowActionMixin):
|
||||
pass
|
||||
|
||||
|
||||
def _wire_count(face) -> int:
|
||||
@@ -240,17 +245,54 @@ def main() -> int:
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap inward push/pull plan should be quick: {multi_inward_elapsed:.3f}s"
|
||||
)
|
||||
if multi_inward_plan.get("status") != "blocked":
|
||||
if multi_inward_plan.get("status") == "blocked":
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap inward push/pull should be blocked until second-level propagation exists: "
|
||||
f"multi-boundary cap shallow inward push/pull should be allowed by boundary shell rebuild: "
|
||||
f"{multi_inward_plan}"
|
||||
)
|
||||
multi_inward_message = str(multi_inward_plan.get("message") or "")
|
||||
if "二级关系" not in multi_inward_message or "通用 OCCT 布尔" not in multi_inward_message:
|
||||
if multi_inward_plan.get("planar_cap_extension_method") != "boundary-shell-rebuild":
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap inward blocker should explain topology depth and slow Boolean risk: "
|
||||
f"multi-boundary cap shallow inward should use boundary shell rebuild: {multi_inward_plan}"
|
||||
)
|
||||
multi_inward_message = str(multi_inward_plan.get("message") or "")
|
||||
if "向内收缩" not in multi_inward_message and "重建侧壁" not in multi_inward_message:
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap shallow inward message should explain boundary shell semantics: "
|
||||
f"{multi_inward_plan}"
|
||||
)
|
||||
multi_inward_result_model = StepModel.load(path)
|
||||
started = time.perf_counter()
|
||||
multi_inward_result = multi_inward_result_model.push_pull_face(multi_face_id, -1.0)
|
||||
multi_inward_result_elapsed = time.perf_counter() - started
|
||||
if multi_inward_result_elapsed > 15.0:
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap shallow inward push/pull took too long: "
|
||||
f"{multi_inward_result_elapsed:.3f}s; result={multi_inward_result}"
|
||||
)
|
||||
if "boundary-shell rebuild" not in multi_inward_result or "actual=56.5" not in multi_inward_result:
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap shallow inward should move to 56.5 by boundary shell rebuild: {multi_inward_result}"
|
||||
)
|
||||
if multi_inward_result_model.stats().solids != 1:
|
||||
raise SystemExit(f"multi-boundary cap shallow inward should keep one Solid: {multi_inward_result_model.stats()}")
|
||||
inward_retained_ids = multi_inward_result_model.face_ids_for_logical_id(multi_logical_id)
|
||||
if len(inward_retained_ids) != 1:
|
||||
raise SystemExit(f"multi-boundary cap shallow inward logical Face should follow the moved cap: {inward_retained_ids}")
|
||||
inward_info = multi_inward_result_model.quick_face_info(inward_retained_ids[0])
|
||||
if int(inward_info.get("inner_boundary_wires", 0) or 0) < 5:
|
||||
raise SystemExit(f"multi-boundary cap shallow inward should keep inner wires: {inward_info}")
|
||||
|
||||
multi_deep_inward_plan = multi_model.push_pull_plan(multi_face_id, -77.5)
|
||||
if multi_deep_inward_plan.get("status") != "blocked":
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap deep inward push/pull should still be blocked: {multi_deep_inward_plan}"
|
||||
)
|
||||
multi_deep_inward_message = str(multi_deep_inward_plan.get("message") or "")
|
||||
if "材料厚度" not in multi_deep_inward_message and "二级关系" not in multi_deep_inward_message:
|
||||
raise SystemExit(
|
||||
f"multi-boundary cap deep inward blocker should explain cut-through or topology depth: "
|
||||
f"{multi_deep_inward_plan}"
|
||||
)
|
||||
|
||||
started = time.perf_counter()
|
||||
multi_result = multi_model.push_pull_face(multi_face_id, 34.5)
|
||||
@@ -351,6 +393,42 @@ def main() -> int:
|
||||
raise SystemExit(
|
||||
f"large multi-boundary cap isolated worker used the wrong path: {multi_isolated_message}"
|
||||
)
|
||||
isolated_output_model = StepModel.load(output_path)
|
||||
probe = _WindowActionProbe()
|
||||
direction = multi_plan.get("outward_direction") or multi_plan.get("plane_direction")
|
||||
context = {
|
||||
"operation_name": "拉伸/切除平面",
|
||||
"target_kind": "face",
|
||||
"target_id": multi_face_id,
|
||||
"target_logical_id": multi_face_id,
|
||||
"parameters": {
|
||||
"part_id": multi_plan.get("part_id"),
|
||||
"solid_id": multi_plan.get("solid_id"),
|
||||
"surface": "plane",
|
||||
"outward_direction": direction,
|
||||
"current_plane_position": multi_plan.get("current_plane_position"),
|
||||
"target_plane_position": multi_plan.get("target_plane_position"),
|
||||
"bbox_diagonal": multi_plan.get("bbox_diagonal"),
|
||||
"resize_strategy": multi_plan.get("resize_strategy"),
|
||||
},
|
||||
}
|
||||
blocker = probe._face_target_integrity_blocker(isolated_output_model, context)
|
||||
if blocker:
|
||||
raise SystemExit(f"window-layer isolated target check should accept the moved cap: {blocker}")
|
||||
probe._preserve_isolated_face_logical_id(isolated_output_model, context, multi_isolated_message)
|
||||
retained_after_isolation = isolated_output_model.face_ids_for_logical_id(multi_face_id)
|
||||
if not retained_after_isolation:
|
||||
raise SystemExit("window-layer isolated logical Face retention lost the moved cap")
|
||||
if not probe._face_target_plane_position_matches(
|
||||
isolated_output_model,
|
||||
retained_after_isolation,
|
||||
float(multi_plan["target_plane_position"]),
|
||||
direction,
|
||||
float(multi_plan["bbox_diagonal"]),
|
||||
):
|
||||
raise SystemExit(
|
||||
f"window-layer isolated logical Face retention points at the wrong cap: {retained_after_isolation}"
|
||||
)
|
||||
|
||||
print(
|
||||
"large stepped cap push/pull ok: "
|
||||
|
||||
Reference in New Issue
Block a user