feat: 完善 SCDM-first 参数化编辑交付版

This commit is contained in:
2026-08-20 17:12:01 +08:00
parent 4e7877e05c
commit b4feab24d2
21 changed files with 3015 additions and 1729 deletions
+99
View File
@@ -543,6 +543,80 @@ def main() -> int:
pattern_segment_mismatch.get("ok") is False and pattern_segment_mismatch.get("reason") == "target-mismatch",
f"pattern.segment_spacing mismatch should fail from the applied edit result: {pattern_segment_mismatch}",
)
single_left_signature = dict(before_pattern_segment["objects"][0]["geometrySignature"]) # type: ignore[index]
single_left_signature["movingSide"] = "single_left"
single_left_ok = validate_scdm_edit_result(
{
"ok": True,
"output_step": str(output_step),
"applied": {"segmentSpacing": 6.5, "segmentIndex": 1, "spacingMode": "segment_single_left"},
},
before_signature=single_left_signature,
before_cache=before_pattern_segment,
after_cache=after_pattern_segment,
capability_key="pattern.segment_spacing",
expected_target=6.5,
edited_object_id="pattern:holes",
)
_assert(
single_left_ok.get("ok") is True
and single_left_ok.get("targetCheck", {}).get("spacingMode") == "segment_single_left",
f"pattern.segment_spacing should validate move-only-left-instance mode: {single_left_ok}",
)
single_right_signature = dict(before_pattern_segment["objects"][0]["geometrySignature"]) # type: ignore[index]
single_right_signature["movingSide"] = "single_right"
single_right_ok = validate_scdm_edit_result(
{
"ok": True,
"output_step": str(output_step),
"applied": {"segmentSpacing": 6.5, "segmentIndex": 1, "spacingMode": "segment_single_right"},
},
before_signature=single_right_signature,
before_cache=before_pattern_segment,
after_cache=after_pattern_segment,
capability_key="pattern.segment_spacing",
expected_target=6.5,
edited_object_id="pattern:holes",
)
_assert(
single_right_ok.get("ok") is True
and single_right_ok.get("targetCheck", {}).get("spacingMode") == "segment_single_right",
f"pattern.segment_spacing should validate move-only-right-instance mode: {single_right_ok}",
)
wrong_mode = validate_scdm_edit_result(
{
"ok": True,
"output_step": str(output_step),
"applied": {"segmentSpacing": 6.5, "segmentIndex": 1, "spacingMode": "segment_after"},
},
before_signature=single_right_signature,
before_cache=before_pattern_segment,
after_cache=after_pattern_segment,
capability_key="pattern.segment_spacing",
expected_target=6.5,
edited_object_id="pattern:holes",
)
_assert(
wrong_mode.get("ok") is False and wrong_mode.get("reason") == "pattern-segment-spacing-mode-mismatch",
f"pattern.segment_spacing should fail when SCDM reports a different modeling intent: {wrong_mode}",
)
missing_mode = validate_scdm_edit_result(
{
"ok": True,
"output_step": str(output_step),
"applied": {"segmentSpacing": 6.5, "segmentIndex": 1},
},
before_signature=single_right_signature,
before_cache=before_pattern_segment,
after_cache=after_pattern_segment,
capability_key="pattern.segment_spacing",
expected_target=6.5,
edited_object_id="pattern:holes",
)
_assert(
missing_mode.get("ok") is False and missing_mode.get("reason") == "pattern-segment-spacing-mode-missing",
f"pattern.segment_spacing should require SCDM to report a known modeling intent: {missing_mode}",
)
shell_thickness_ok = check_scdm_target(
{
"objectType": "thin_wall",
@@ -574,6 +648,31 @@ def main() -> int:
)
summary_ok = check_scdm_summary_delta(summary_before, summary_after_ok, capability_key="hole.diameter")
_assert(summary_ok.get("ok") is True, f"small summary changes should pass: {summary_ok}")
summary_after_repartition = _cache_with_summary(
{"bodyCount": 9, "objectCount": 548, "faceCount": 157, "edgeCount": 390},
_hole("hole:90", 90, diameter=0.9, center=(0.5, 1.0, 9.5)),
)
summary_repartition = check_scdm_summary_delta(summary_before, summary_after_repartition, capability_key="hole.diameter")
_assert(
summary_repartition.get("ok") is None and summary_repartition.get("reason") == "body-count-repartitioned",
f"SCDM body repartition should be a warning, not a hard failure: {summary_repartition}",
)
repartition_ok = validate_scdm_edit_result(
{"ok": True, "output_step": str(output_step)},
before_signature=summary_before["objects"][0]["geometrySignature"], # type: ignore[index]
before_cache=summary_before,
after_cache=summary_after_repartition,
capability_key="hole.diameter",
expected_target=0.9,
edited_object_id="hole:85",
brep_validator=lambda path: {"ok": path.is_file(), "reason": "ok"},
)
_assert(
repartition_ok.get("ok") is True
and repartition_ok.get("summaryCheck", {}).get("reason") == "body-count-repartitioned"
and repartition_ok.get("validationWarnings"),
f"target-verified SCDM hole diameter edit should survive body repartition warnings: {repartition_ok}",
)
summary_after_bad = _cache_with_summary(
{"bodyCount": 13, "objectCount": 80, "faceCount": 20, "edgeCount": 45},
_hole("hole:90", 90, diameter=0.75, center=(0.5, 1.0, 9.5)),