feat: 扩展Face保持关系编辑语义

This commit is contained in:
2026-08-10 17:50:50 +08:00
parent 61f0b76e59
commit 3a851d0967
8 changed files with 382 additions and 41 deletions
+21 -7
View File
@@ -15,12 +15,15 @@ DEFAULT_MODEL = PROJECT_ROOT / "assets" / "models" / "cube_10mm.step"
FACE_CASES = (
("size", "local", "width"),
("size", "keep_relations", "width"),
("size", "owning", "width"),
("size", "local", "height"),
("size", "keep_relations", "height"),
("size", "owning", "height"),
("area", "local", "width"),
("area", "owning", "width"),
("center", "local", "width"),
("center", "keep_relations", "width"),
("center", "owning", "width"),
("offset", "local", "width"),
("offset", "owning", "width"),
@@ -183,13 +186,19 @@ def main() -> int:
before = model.stats()
current_info = model.face_info(face_id)
if args.strategy in {"push_pull", "keep_relations"} and args.property != "offset":
raise SystemExit("--strategy push_pull/keep_relations is only valid with --property offset")
if args.strategy == "push_pull" and args.property != "offset":
raise SystemExit("--strategy push_pull is only valid with --property offset")
if args.strategy == "keep_relations" and args.property not in {"size", "center", "offset"}:
raise SystemExit("--strategy keep_relations is only valid with --property size/center/offset")
if args.property == "size" and args.strategy == "local":
plan = model.face_size_local_resize_plan(face_id, args.target_size, args.axis)
result = model.resize_face_size_local(face_id, args.target_size, args.axis)
expected_strategy = f"local-face-{args.axis}-only-deform"
elif args.property == "size" and args.strategy == "keep_relations":
plan = model.face_size_local_resize_keep_relations_plan(face_id, args.target_size, args.axis)
result = model.resize_face_size_local_keep_relations(face_id, args.target_size, args.axis)
expected_strategy = f"axis-scale-owning-shape-from-face-{args.axis}"
elif args.property == "size":
plan = model.face_size_owning_scale_plan(face_id, args.target_size, args.axis)
result = model.resize_face_size_owning_scale(face_id, args.target_size, args.axis)
@@ -202,7 +211,7 @@ def main() -> int:
plan = model.face_area_scale_plan(face_id, args.target_area)
result = model.resize_face_area(face_id, args.target_area)
expected_strategy = "uniform-scale-face-area-fallback"
elif args.property == "center" and args.strategy == "local":
elif args.property == "center" and args.strategy in {"local", "keep_relations"}:
current_center = current_info.get("area_center") or current_info.get("bbox_center")
if not isinstance(current_center, tuple) or len(current_center) != 3:
raise SystemExit("selected Face does not have a stable center")
@@ -212,9 +221,14 @@ def main() -> int:
float(current_center[1]) + offset[1],
float(current_center[2]) + offset[2],
)
plan = model.face_center_local_move_plan(face_id, target_center)
result = model.move_face_center_local(face_id, target_center)
expected_strategy = "local-face-only-deform"
if args.strategy == "keep_relations":
plan = model.face_center_local_move_keep_relations_plan(face_id, target_center)
result = model.move_face_center_local_keep_relations(face_id, target_center)
expected_strategy = "translate-owning-shape-from-face-center"
else:
plan = model.face_center_local_move_plan(face_id, target_center)
result = model.move_face_center_local(face_id, target_center)
expected_strategy = "local-face-only-deform"
elif args.property == "center":
current_center = current_info.get("area_center") or current_info.get("bbox_center")
if not isinstance(current_center, tuple) or len(current_center) != 3:
@@ -298,7 +312,7 @@ def main() -> int:
resolved_strategy = "push-pull-planar-face"
if resolved_strategy != expected_strategy:
raise SystemExit(f"expected {expected_strategy}, got {resolved_strategy or '<none>'}")
if args.property == "offset" and args.strategy == "keep_relations":
if args.strategy == "keep_relations":
if plan.get("face_push_pull_planar_relation_constraint_requested") is not True:
raise SystemExit(f"keep-relations plan should record requested relation constraint: {plan}")
if plan.get("face_push_pull_planar_constraint_status") != "ready":