feat: 完善 Face 参数化编辑和隔离执行

This commit is contained in:
2026-07-31 16:36:05 +08:00
parent 27e4f7236c
commit bb44e3920d
31 changed files with 5428 additions and 252 deletions
+62
View File
@@ -72,6 +72,17 @@ def _first_hole_face(model: StepModel, *, blind: bool | None = None) -> int:
return candidates[0]
def _first_circle_edge_adjacent_to_face(model: StepModel, face_id: int) -> int:
for edge_id in range(len(model.edges)):
info = model.edge_info(edge_id)
if info.get("curve") != "circle":
continue
adjacent_face_ids = tuple(int(item) for item in info.get("adjacent_face_ids", ()) or ())
if face_id in adjacent_face_ids:
return edge_id
raise SystemExit(f"no circular edge adjacent to Face {face_id} was recognized")
def _axis_center(model: StepModel, face_id: int) -> tuple[float, float, float]:
info = model.face_info(face_id)
axis_point = info.get("axis_point")
@@ -208,6 +219,52 @@ def _run_axis_center_case(offset: float, tolerance: float) -> None:
print(result.encode("ascii", "backslashreplace").decode("ascii"))
def _run_circle_edge_axis_center_case(offset: float, tolerance: float) -> None:
with tempfile.TemporaryDirectory(prefix="geom_param_circle_edge_axis_") as temp_dir:
model_path = Path(temp_dir) / "through_hole.step"
_write_through_hole_model(model_path)
model = StepModel.load(model_path)
face_id = _first_hole_face(model, blind=False)
edge_id = _first_circle_edge_adjacent_to_face(model, face_id)
before = model.stats()
current_axis_center = _axis_center(model, face_id)
current_diameter = _diameter(model, face_id)
edge_info = model.edge_info(edge_id)
edge_center = edge_info.get("center")
if not isinstance(edge_center, tuple):
raise SystemExit(f"circle edge center is missing on Edge {edge_id}")
target_edge_center = (float(edge_center[0]) + offset, float(edge_center[1]), float(edge_center[2]))
target_axis_center = (current_axis_center[0] + offset, current_axis_center[1], current_axis_center[2])
plan = model.circular_edge_axis_move_plan(edge_id, target_edge_center)
if plan["status"] == "blocked":
raise SystemExit(f"circle_edge_axis_center plan was blocked: {plan['message']}")
result = model.move_circular_edge_axis_center(edge_id, target_edge_center)
after = model.stats()
verified_face, diameter, center, _ = _nearest_hole_by_diameter(
model,
current_diameter,
target_axis_center,
blind=False,
)
center_error = _distance(center, target_axis_center)
if center_error > tolerance or abs(diameter - current_diameter) > tolerance:
raise SystemExit(
f"circle_edge_axis_center verification failed: target={target_axis_center}, center={center}, "
f"center_error={center_error:g}, diameter={diameter:g}"
)
print("mode=circle_edge_axis_center")
print(f"source_edge={edge_id}")
print(f"source_face={face_id}")
print(f"strategy={plan.get('resize_strategy')}")
print(f"delegated_mode={plan.get('circular_edge_cylinder_mode')}")
print(f"before={before}")
print(f"after={after}")
print(f"verified_face={verified_face}")
print(f"target_edge_center={target_edge_center}")
print(f"target_axis_center={target_axis_center} value={center} diameter={diameter:.6f} error={center_error:.6g}")
print(result.encode("ascii", "backslashreplace").decode("ascii"))
def _run_suppress_case(tolerance: float) -> None:
with tempfile.TemporaryDirectory(prefix="geom_param_hole_suppress_") as temp_dir:
model_path = Path(temp_dir) / "through_hole.step"
@@ -295,6 +352,7 @@ def main() -> int:
"diameter",
"diameter_shrink",
"axis_center",
"circle_edge_axis_center",
"suppress",
"blind_depth",
"blind_depth_shallow",
@@ -304,6 +362,7 @@ def main() -> int:
parser.add_argument("--diameter", type=float, default=8.0)
parser.add_argument("--diameter-shrink", type=float, default=4.0)
parser.add_argument("--axis-center", type=float, default=2.0, help="Axis-center X offset to verify.")
parser.add_argument("--circle-edge-axis-center", type=float, default=2.0, help="Circle Edge center X offset to verify.")
parser.add_argument("--blind-depth", type=float, default=8.0)
parser.add_argument("--blind-depth-shallow", type=float, default=4.0)
parser.add_argument("--tolerance", type=float, default=2e-4)
@@ -314,6 +373,7 @@ def main() -> int:
("diameter", args.diameter),
("diameter_shrink", args.diameter_shrink),
("axis_center", args.axis_center),
("circle_edge_axis_center", args.circle_edge_axis_center),
("suppress", None),
("blind_depth", args.blind_depth),
("blind_depth_shallow", args.blind_depth_shallow),
@@ -326,6 +386,8 @@ def main() -> int:
_run_diameter_case(float(target), args.tolerance)
elif mode == "axis_center":
_run_axis_center_case(float(target), args.tolerance)
elif mode == "circle_edge_axis_center":
_run_circle_edge_axis_center_case(float(target), args.tolerance)
elif mode == "suppress":
_run_suppress_case(args.tolerance)
elif mode in {"blind_depth", "blind_depth_shallow"}: