194 lines
6.2 KiB
Python
194 lines
6.2 KiB
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
|
SCRIPT_DIR = PROJECT_ROOT / "scripts"
|
|
|
|
|
|
CASES: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
(
|
|
"face width, current face only",
|
|
("verify_face_resize_semantics.py", "--strategy", "local", "--axis", "width", "--target-size", "15"),
|
|
),
|
|
(
|
|
"Face first-level shared-edge topology",
|
|
("verify_face_first_level_topology.py",),
|
|
),
|
|
(
|
|
"cylindrical Face first-level topology for holes and slots",
|
|
("verify_cylindrical_first_level_topology.py",),
|
|
),
|
|
(
|
|
"face width, owning feature",
|
|
("verify_face_resize_semantics.py", "--strategy", "owning", "--axis", "width", "--target-size", "15"),
|
|
),
|
|
(
|
|
"face height, current face only",
|
|
("verify_face_resize_semantics.py", "--strategy", "local", "--axis", "height", "--target-size", "15"),
|
|
),
|
|
(
|
|
"face height, owning feature",
|
|
("verify_face_resize_semantics.py", "--strategy", "owning", "--axis", "height", "--target-size", "15"),
|
|
),
|
|
(
|
|
"rectangular face width and height axes stay separate",
|
|
("verify_face_rectangular_axes.py",),
|
|
),
|
|
(
|
|
"face area, current face only",
|
|
("verify_face_resize_semantics.py", "--property", "area", "--strategy", "local", "--target-area", "144"),
|
|
),
|
|
(
|
|
"face area, owning feature",
|
|
("verify_face_resize_semantics.py", "--property", "area", "--strategy", "owning", "--target-area", "144"),
|
|
),
|
|
(
|
|
"face center, current face only",
|
|
("verify_face_resize_semantics.py", "--property", "center", "--strategy", "local", "--center-offset", "2,0,3"),
|
|
),
|
|
(
|
|
"face center, owning feature",
|
|
("verify_face_resize_semantics.py", "--property", "center", "--strategy", "owning", "--center-offset", "2,0,3"),
|
|
),
|
|
(
|
|
"face offset, push pull",
|
|
("verify_face_resize_semantics.py", "--property", "offset", "--strategy", "push_pull", "--offset-distance", "1"),
|
|
),
|
|
(
|
|
"face offset, keep first-level planar relations",
|
|
("verify_face_resize_semantics.py", "--property", "offset", "--strategy", "keep_relations", "--offset-distance", "1"),
|
|
),
|
|
(
|
|
"face offset, push pull inward cut",
|
|
("verify_face_resize_semantics.py", "--property", "offset", "--strategy", "push_pull", "--offset-distance", "-1"),
|
|
),
|
|
(
|
|
"face offset, inward cut limits",
|
|
("verify_face_push_pull_limits.py",),
|
|
),
|
|
(
|
|
"face offset, current face only",
|
|
("verify_face_resize_semantics.py", "--property", "offset", "--strategy", "local", "--offset-distance", "1"),
|
|
),
|
|
(
|
|
"face offset, owning feature",
|
|
("verify_face_resize_semantics.py", "--property", "offset", "--strategy", "owning", "--offset-distance", "1"),
|
|
),
|
|
(
|
|
"coplanar split faces, push pull as one region",
|
|
("verify_face_coplanar_push_pull.py",),
|
|
),
|
|
(
|
|
"coplanar split faces, inward cut as one region",
|
|
("verify_face_coplanar_push_pull.py", "--distance", "-1"),
|
|
),
|
|
(
|
|
"holed planar Face disables local-only deformation",
|
|
("verify_face_complex_boundary_guard.py",),
|
|
),
|
|
(
|
|
"planar Face on curved Solid disables local-only deformation",
|
|
("verify_face_mixed_surface_guard.py",),
|
|
),
|
|
(
|
|
"freeform Face stays read-only with a clear blocker",
|
|
("verify_face_freeform_guard.py",),
|
|
),
|
|
(
|
|
"analytic curved Face radius and angle edits",
|
|
("verify_analytic_surface_resize.py",),
|
|
),
|
|
(
|
|
"cylindrical side Face height edits are checked",
|
|
("verify_cylindrical_height_resize.py",),
|
|
),
|
|
(
|
|
"large stepped cylindrical cap push pull stays local",
|
|
("verify_large_stepped_cap_push_pull.py",),
|
|
),
|
|
(
|
|
"non-rectangular planar Face local edits",
|
|
("verify_face_nonrectangular_local_edit.py",),
|
|
),
|
|
(
|
|
"thin wall thickness, current face and owning feature",
|
|
("verify_shell_thickness_resize.py",),
|
|
),
|
|
(
|
|
"thin wall thickness decrease, current face and owning feature",
|
|
("verify_shell_thickness_resize.py", "--target-thickness", "1"),
|
|
),
|
|
(
|
|
"property editor keeps generic Face edits out of cylindrical features",
|
|
("verify_property_editor_specs.py",),
|
|
),
|
|
(
|
|
"Face UI isolation contract",
|
|
("verify_face_ui_isolation_contract.py",),
|
|
),
|
|
(
|
|
"first-level fact graph is exposed",
|
|
("verify_first_level_fact_graph.py",),
|
|
),
|
|
(
|
|
"feature recognition summary is exposed",
|
|
("verify_feature_recognition_summary.py",),
|
|
),
|
|
(
|
|
"Face edited values read back into property rows",
|
|
("verify_face_property_readback.py",),
|
|
),
|
|
(
|
|
"Face logical selection stays on the edited face",
|
|
("verify_face_logical_selection_retention.py",),
|
|
),
|
|
(
|
|
"Face selection identity UI prefers logical IDs",
|
|
("verify_selection_identity_ui.py",),
|
|
),
|
|
(
|
|
"Face feature parameters stay stable after full recognition cache",
|
|
("verify_face_feature_parameter_consistency.py",),
|
|
),
|
|
(
|
|
"Face invalid positive targets are blocked",
|
|
("verify_face_invalid_target_guards.py",),
|
|
),
|
|
(
|
|
"Face extreme positive targets are blocked",
|
|
("verify_face_extreme_target_guards.py",),
|
|
),
|
|
(
|
|
"Face no-op plans are blocked",
|
|
("verify_face_noop_guards.py",),
|
|
),
|
|
(
|
|
"Face edit integrity guards reject broken results",
|
|
("verify_face_edit_integrity_guards.py",),
|
|
),
|
|
(
|
|
"cone semi-angle high-risk edit is isolated and rebuilt analytically",
|
|
("verify_cone_semi_angle_isolation.py",),
|
|
),
|
|
)
|
|
|
|
|
|
def main() -> int:
|
|
for index, (label, command) in enumerate(CASES, start=1):
|
|
print(f"\n[{index}/{len(CASES)}] {label}", flush=True)
|
|
subprocess.run(
|
|
(sys.executable, str(SCRIPT_DIR / command[0]), *command[1:]),
|
|
cwd=PROJECT_ROOT,
|
|
check=True,
|
|
)
|
|
print("\nFace edit suite passed.", flush=True)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|