Files

75 lines
3.1 KiB
Python
Raw Permalink Normal View History

from __future__ import annotations
from pathlib import Path
import sys
PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from step_editor.model import StepModel
DEFAULT_MODEL = PROJECT_ROOT / "assets" / "models" / "cube_10mm.step"
def _first_plane_face(model: StepModel) -> int:
for face_id in range(len(model.faces)):
info = model.face_info(face_id)
if info.get("surface") == "plane":
return face_id
raise SystemExit("no plane Face found")
def _assert_plan(label: str, plan: dict[str, object], status: str, risk: str | None = None) -> None:
actual_status = str(plan.get("status", ""))
actual_risk = str(plan.get("risk", ""))
if actual_status != status:
raise SystemExit(f"{label} expected status={status}, got {actual_status}: {plan}")
if risk is not None and actual_risk != risk:
raise SystemExit(f"{label} expected risk={risk}, got {actual_risk}: {plan}")
def main() -> int:
model = StepModel.load(DEFAULT_MODEL)
face_id = _first_plane_face(model)
shallow = model.push_pull_plan(face_id, -1.0)
_assert_plan("shallow inward cut", shallow, "ready", "low")
if abs(float(shallow.get("push_pull_inward_material_depth") or 0.0) - 10.0) > 1e-5:
raise SystemExit(f"shallow cut should report 10mm inward material depth: {shallow}")
if abs(float(shallow.get("push_pull_inward_cut_ratio") or 0.0) - 0.1) > 1e-5:
raise SystemExit(f"shallow cut should report 0.1 inward cut ratio: {shallow}")
near_through = model.push_pull_plan(face_id, -9.0)
_assert_plan("near-through inward cut", near_through, "caution", "high")
if float(near_through.get("push_pull_inward_cut_ratio") or 0.0) < 0.85:
raise SystemExit(f"near-through cut should report a high inward cut ratio: {near_through}")
large_outward = model.push_pull_plan(face_id, 11.0)
_assert_plan("large outward push/pull", large_outward, "caution", "high")
large_message = str(large_outward.get("message") or large_outward.get("warnings") or "")
if "隔离子进程" not in large_message and "OCCT" not in large_message:
raise SystemExit(f"large outward push/pull warning should explain isolated high-risk execution: {large_outward}")
if float(large_outward.get("push_pull_distance_to_owning_axis_span_ratio") or 0.0) <= 1.0:
raise SystemExit(f"large outward push/pull should report the owning-axis span ratio: {large_outward}")
through = model.push_pull_plan(face_id, -10.0)
_assert_plan("through inward cut", through, "blocked", "blocked")
message = str(through.get("message") or through.get("blockers") or "")
if "材料厚度" not in message and "切空" not in message:
raise SystemExit(f"through cut blocker should explain material depth: {through}")
try:
model.push_pull_face(face_id, -10.0)
except ValueError:
pass
else:
raise SystemExit("push_pull_face should reject an inward cut that reaches full material depth")
print("Face push/pull limit guards ok")
return 0
if __name__ == "__main__":
raise SystemExit(main())