feat: 增加Face偏移保持一级关系策略
This commit is contained in:
@@ -25,6 +25,7 @@ FACE_CASES = (
|
||||
("offset", "local", "width"),
|
||||
("offset", "owning", "width"),
|
||||
("offset", "push_pull", "width"),
|
||||
("offset", "keep_relations", "width"),
|
||||
)
|
||||
|
||||
|
||||
@@ -170,7 +171,7 @@ def main() -> int:
|
||||
parser.add_argument("--target-area", type=float, default=144.0)
|
||||
parser.add_argument("--center-offset", default="2,0,3")
|
||||
parser.add_argument("--offset-distance", type=float, default=1.0)
|
||||
parser.add_argument("--strategy", default="local", choices=["local", "owning", "push_pull"])
|
||||
parser.add_argument("--strategy", default="local", choices=["local", "owning", "push_pull", "keep_relations"])
|
||||
parser.add_argument("--tolerance", type=float, default=1e-5)
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -182,8 +183,8 @@ def main() -> int:
|
||||
before = model.stats()
|
||||
current_info = model.face_info(face_id)
|
||||
|
||||
if args.strategy == "push_pull" and args.property != "offset":
|
||||
raise SystemExit("--strategy push_pull is only valid with --property offset")
|
||||
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.property == "size" and args.strategy == "local":
|
||||
plan = model.face_size_local_resize_plan(face_id, args.target_size, args.axis)
|
||||
@@ -259,7 +260,7 @@ def main() -> int:
|
||||
plan = model.face_plane_offset_owning_translation_plan(face_id, args.offset_distance)
|
||||
result = model.translate_face_plane_offset_owning(face_id, args.offset_distance)
|
||||
expected_strategy = "translate-owning-shape-from-plane-offset"
|
||||
else:
|
||||
elif args.property == "offset" and args.strategy == "push_pull":
|
||||
frame = model.face_plane_offset_frame(face_id)
|
||||
if frame is None:
|
||||
raise SystemExit("selected Face does not have a stable plane offset frame")
|
||||
@@ -275,12 +276,35 @@ def main() -> int:
|
||||
plan = model.push_pull_plan(face_id, args.offset_distance)
|
||||
result = model.push_pull_face(face_id, args.offset_distance)
|
||||
expected_strategy = "push-pull-planar-face"
|
||||
else:
|
||||
frame = model.face_plane_offset_frame(face_id)
|
||||
if frame is None:
|
||||
raise SystemExit("selected Face does not have a stable plane offset frame")
|
||||
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")
|
||||
_origin, direction, _position = frame
|
||||
target_center = (
|
||||
float(current_center[0]) + direction[0] * args.offset_distance,
|
||||
float(current_center[1]) + direction[1] * args.offset_distance,
|
||||
float(current_center[2]) + direction[2] * args.offset_distance,
|
||||
)
|
||||
plan = model.push_pull_keep_relations_plan(face_id, args.offset_distance)
|
||||
result = model.push_pull_face_keep_relations(face_id, args.offset_distance)
|
||||
expected_strategy = "push-pull-planar-face-keep-relations"
|
||||
|
||||
resolved_strategy = str(plan.get("resize_strategy", ""))
|
||||
if args.property == "offset" and args.strategy == "push_pull":
|
||||
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 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":
|
||||
raise SystemExit(f"keep-relations plan should be ready on cube Face: {plan}")
|
||||
if "Planar relation check: ok" not in result:
|
||||
raise SystemExit(f"keep-relations result should include planar relation check, got: {result}")
|
||||
if "Face result check:" not in result:
|
||||
raise SystemExit(f"Face edit result message should include a result check, got: {result}")
|
||||
if "First-level check:" not in result:
|
||||
|
||||
@@ -14,6 +14,7 @@ if str(PROJECT_ROOT) not in sys.path:
|
||||
|
||||
EXPECTED_FACE_ISOLATED_OPERATIONS = {
|
||||
"push_pull_face",
|
||||
"push_pull_face_keep_relations",
|
||||
"move_face_plane_offset_local",
|
||||
"resize_face_area_local",
|
||||
"resize_face_area",
|
||||
@@ -122,6 +123,7 @@ def _assert_same(label: str, actual: set[str], expected: set[str]) -> None:
|
||||
|
||||
PROPERTY_FACE_ACTION_TO_ISOLATED_OPERATION = {
|
||||
"push_pull_face": "push_pull_face",
|
||||
"push_pull_face_keep_relations": "push_pull_face_keep_relations",
|
||||
"move_selected_face_plane_position_local": "move_face_plane_offset_local",
|
||||
"resize_face_width_local": "resize_face_size_local",
|
||||
"resize_face_height_local": "resize_face_size_local",
|
||||
@@ -151,6 +153,8 @@ PROPERTY_FACE_ACTIONS_ALLOWED_IN_MAIN_THREAD = {
|
||||
|
||||
|
||||
ACTION_IMPLEMENTATION_METHOD = {
|
||||
"push_pull_face": "_push_pull_face_action",
|
||||
"push_pull_face_keep_relations": "_push_pull_face_action",
|
||||
"resize_face_width_local": "_resize_face_size_local",
|
||||
"resize_face_height_local": "_resize_face_size_local",
|
||||
"resize_face_width_owning_scale": "_resize_face_size_owning_scale",
|
||||
|
||||
@@ -491,6 +491,19 @@ def main() -> int:
|
||||
_assert_label(plane_specs, "local_face_width", "面内长度")
|
||||
_assert_label(plane_specs, "local_face_height", "面内宽度")
|
||||
_assert_label(plane_specs, "face_target_normal_position", "偏移")
|
||||
offset_keep_relations = _scope_mode(plane_specs, "face_target_normal_position", "keep_relations")
|
||||
if str(offset_keep_relations.get("label") or "") != "保持关系":
|
||||
raise SystemExit(f"Face plane-offset keep-relations scope should be labelled clearly: {offset_keep_relations}")
|
||||
if str(offset_keep_relations.get("action") or "") != "push_pull_face_keep_relations":
|
||||
raise SystemExit(f"Face plane-offset keep-relations scope should use its own action: {offset_keep_relations}")
|
||||
if not bool(offset_keep_relations.get("enabled", False)):
|
||||
raise SystemExit(f"Face plane-offset keep-relations scope should be available on simple planar Face: {offset_keep_relations}")
|
||||
_assert_scoped_hint_fragments(
|
||||
plane_specs,
|
||||
"face_target_normal_position",
|
||||
"keep_relations",
|
||||
("一级", "平行/垂直", "会直接阻止"),
|
||||
)
|
||||
_assert_actionable_rows_first(
|
||||
plane_info,
|
||||
(
|
||||
@@ -575,7 +588,7 @@ def main() -> int:
|
||||
mode,
|
||||
("5%", "5 倍", "会被阻止"),
|
||||
)
|
||||
for mode in ("push_pull", "local", "owning"):
|
||||
for mode in ("push_pull", "keep_relations", "local", "owning"):
|
||||
_assert_scoped_hint_fragments(
|
||||
plane_specs,
|
||||
"face_target_normal_position",
|
||||
|
||||
Reference in New Issue
Block a user