feat: 完善一级关系编辑 UI 与视图体验

This commit is contained in:
2026-08-06 18:15:14 +08:00
parent 57d75541c3
commit eef9efcc1e
29 changed files with 3907 additions and 178 deletions
+25
View File
@@ -108,6 +108,22 @@ def _first_existing_fillet_face(model: StepModel, radius: float, tolerance: floa
raise SystemExit(f"no existing fillet candidate near radius {radius:g}; loose matches: {detail or '<none>'}")
def _assert_existing_fillet_plan_topology(plan: dict[str, object]) -> None:
if plan.get("topology_relation_depth") != 1:
raise SystemExit(f"existing fillet plan should expose first-level depth: {plan}")
if plan.get("topology_relation_status") != "ready":
raise SystemExit(f"existing fillet plan topology should be ready: {plan}")
if plan.get("first_level_topology_status") != "ready":
raise SystemExit(f"existing fillet first-level guard should be ready: {plan}")
if int(plan.get("cylindrical_feature_boundary_edge_count", 0) or 0) < 1:
raise SystemExit(f"existing fillet plan should expose boundary Edges: {plan}")
if int(plan.get("cylindrical_feature_adjacent_face_count", 0) or 0) < 2:
raise SystemExit(f"existing fillet plan should expose direct support Faces: {plan}")
ignored = tuple(plan.get("topology_ignored_relation_depths", ()) or ())
if "second-level" not in ignored or "third-level" not in ignored:
raise SystemExit(f"existing fillet plan should document ignored deeper topology: {plan}")
def _run_fillet_case(radius: float, tolerance: float) -> None:
with tempfile.TemporaryDirectory(prefix="geom_param_edge_fillet_") as temp_dir:
model_path = Path(temp_dir) / "box.step"
@@ -121,6 +137,8 @@ def _run_fillet_case(radius: float, tolerance: float) -> None:
result = model.fillet_edge(edge_id, radius)
after = model.stats()
matches = _cylindrical_faces_near_radius(model, radius, tolerance)
if "Edge blend result check" not in result:
raise SystemExit(f"fillet result did not report execution-layer result check: {result}")
if after.solids != before.solids:
raise SystemExit(f"fillet changed solid count: before={before.solids}, after={after.solids}")
if not matches:
@@ -144,6 +162,8 @@ def _verify_chamfer_topology(
result: str,
extra_lines: list[str],
) -> None:
if "Edge blend result check" not in result:
raise SystemExit(f"{mode} result did not report execution-layer result check: {result}")
if after.solids != before.solids:
raise SystemExit(f"{mode} changed solid count: before={before.solids}, after={after.solids}")
if after.faces <= before.faces:
@@ -250,6 +270,7 @@ def _run_existing_fillet_case(source_radius: float, target_radius: float, tolera
plan = model.existing_fillet_resize_plan(face_id, target_radius)
if plan["status"] == "blocked":
raise SystemExit(f"existing fillet plan was blocked: {plan['message']}")
_assert_existing_fillet_plan_topology(plan)
support_face_ids = tuple(plan.get("feature_existing_fillet_support_face_ids", ()))
if len(support_face_ids) < 2:
raise SystemExit(f"existing fillet should expose at least two support Faces, got {support_face_ids}")
@@ -263,6 +284,10 @@ def _run_existing_fillet_case(source_radius: float, target_radius: float, tolera
raise SystemExit(f"existing fillet verification failed: no cylindrical face near radius {target_radius:g}")
if old_matches and abs(source_radius - target_radius) > tolerance:
raise SystemExit(f"existing fillet still has old radius matches: {old_matches}")
if "Existing fillet result check" not in result:
raise SystemExit(f"existing fillet result did not report result check: {result}")
if "first_level_topology_matched=True" not in result:
raise SystemExit(f"existing fillet result did not verify first-level topology: {result}")
print("mode=existing_fillet")
print(f"face_id={face_id}")
print(f"strategy={plan.get('resize_strategy')}")