feat: 推进SCDM-first后端接入和大模型编辑优化

This commit is contained in:
2026-08-19 10:28:09 +08:00
parent 722256a41f
commit a3eb7e2476
28 changed files with 9666 additions and 168 deletions
+79 -1
View File
@@ -19,13 +19,19 @@ if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from step_editor.model import StepModel
from step_editor.records import OperationRecord
from step_editor.window_actions import WindowActionMixin
from step_editor.window_state import WindowStateMixin
class _WindowActionProbe(WindowActionMixin):
pass
class _WindowStateProbe(WindowStateMixin):
pass
def _wire_count(face) -> int:
count = 0
explorer = TopExp_Explorer(face, TopAbs_WIRE)
@@ -145,6 +151,9 @@ def main() -> int:
raise SystemExit(f"large stepped cap should be recognized as stepped cap: {plan}")
if plan.get("cylindrical_cap_extension_method") != "local-shell-rebuild":
raise SystemExit(f"large stepped cap should use local shell rebuild: {plan}")
stepped_isolation = _WindowActionProbe()._isolation_for_plan(plan, "push_pull_face", [face_id, 89.0])
if not stepped_isolation or stepped_isolation.get("reason") != "large-model-smooth-ui-isolated-occ-edit":
raise SystemExit(f"large stepped cap should use the smooth UI background process: {stepped_isolation}")
started = time.perf_counter()
result = model.push_pull_face(face_id, 89.0)
@@ -233,7 +242,13 @@ def main() -> int:
multi_face_id = _large_multi_boundary_cap_face(multi_model)
multi_logical_id = multi_model.face_region_logical_id(multi_face_id)
multi_before_topology = _face_topology_counts(multi_model, multi_face_id)
started = time.perf_counter()
multi_plan = multi_model.push_pull_plan(multi_face_id, 34.5)
multi_plan_elapsed = time.perf_counter() - started
if multi_plan_elapsed > 5.0:
raise SystemExit(
f"multi-boundary cap push/pull plan should be quick: {multi_plan_elapsed:.3f}s; plan={multi_plan}"
)
if abs(float(multi_plan.get("current_plane_position") or 0.0) - 57.5) > 1e-9:
raise SystemExit(f"multi-boundary cap should start at 57.5: {multi_plan}")
if abs(float(multi_plan.get("target_plane_position") or 0.0) - 92.0) > 1e-9:
@@ -242,6 +257,22 @@ def main() -> int:
raise SystemExit(f"multi-boundary cap should be recognized as planar cap: {multi_plan}")
if multi_plan.get("planar_cap_extension_method") != "boundary-shell-rebuild":
raise SystemExit(f"multi-boundary cap should use boundary shell rebuild: {multi_plan}")
multi_isolation = _WindowActionProbe()._isolation_for_plan(multi_plan, "push_pull_face", [multi_face_id, 34.5])
if not multi_isolation or multi_isolation.get("reason") != "large-model-smooth-ui-isolated-occ-edit":
raise SystemExit(f"multi-boundary cap should use the smooth UI background process: {multi_isolation}")
ui_probe = _WindowActionProbe()
ui_probe.model = multi_model
ui_probe.current_info_values = multi_model.quick_face_info(multi_face_id)
ui_plan = ui_probe._push_pull_plan_for_action(multi_face_id, 34.5)
if bool(ui_plan.get("ui_deferred_model_plan")):
raise SystemExit(f"large multi-boundary UI plan should use the fast local plan now: {ui_plan}")
if ui_plan.get("planar_cap_extension_method") != "boundary-shell-rebuild":
raise SystemExit(f"large multi-boundary UI plan should use boundary-shell rebuild: {ui_plan}")
ui_isolation = ui_probe._isolation_for_plan(ui_plan, "push_pull_face", [multi_face_id, 34.5])
if not ui_isolation or ui_isolation.get("reason") != "large-model-smooth-ui-isolated-occ-edit":
raise SystemExit(f"large multi-boundary UI plan should use the smooth UI background process: {ui_isolation}")
if ui_probe._edit_preflight_blocker({"parameters": ui_plan}) is not None:
raise SystemExit(f"large multi-boundary UI plan should not be blocked before editing: {ui_plan}")
started = time.perf_counter()
multi_inward_plan = multi_model.push_pull_plan(multi_face_id, -1.0)
multi_inward_elapsed = time.perf_counter() - started
@@ -346,6 +377,53 @@ def main() -> int:
multi_after_topology,
min_inner_wires=5,
)
locator_probe = _WindowStateProbe()
locator_probe.model = multi_model
locator_record = OperationRecord(
summary="test",
detail="test",
operation_name="拉伸/切除平面",
target=f"Face {multi_face_id}",
parameters={
"part_id": multi_plan.get("part_id"),
"solid_id": multi_plan.get("solid_id"),
"surface": "plane",
"outward_direction": multi_plan.get("outward_direction") or multi_plan.get("plane_direction"),
"target_plane_position": multi_plan.get("target_plane_position"),
"bbox_diagonal": multi_plan.get("bbox_diagonal"),
},
result_message=multi_result,
target_kind="face",
target_id=multi_face_id,
target_logical_id=multi_logical_id,
)
started = time.perf_counter()
resolved_after_edit = locator_probe._resolve_record_face_id(locator_record)
locator_elapsed = time.perf_counter() - started
if resolved_after_edit != multi_retained_ids[0] or locator_elapsed > 0.5:
raise SystemExit(
f"large multi-boundary operation history locator should use the fast result Face: "
f"resolved={resolved_after_edit}, expected={multi_retained_ids[0]}, elapsed={locator_elapsed:.3f}s"
)
no_hint_record = OperationRecord(
summary="test",
detail="test",
operation_name="拉伸/切除平面",
target=f"Face {multi_face_id}",
parameters=locator_record.parameters,
result_message="Planar face push/pull completed without result face hint.",
target_kind="face",
target_id=multi_face_id,
target_logical_id=multi_logical_id,
)
started = time.perf_counter()
fallback_after_edit = locator_probe._record_plane_position_face_id(no_hint_record)
fallback_elapsed = time.perf_counter() - started
if fallback_after_edit != multi_retained_ids[0] or fallback_elapsed > 1.0:
raise SystemExit(
f"large multi-boundary fallback locator should use lightweight plane positions: "
f"resolved={fallback_after_edit}, expected={multi_retained_ids[0]}, elapsed={fallback_elapsed:.3f}s"
)
with tempfile.TemporaryDirectory(prefix="verify_large_multi_boundary_cap_isolated_") as temp_dir:
temp_root = Path(temp_dir)
@@ -442,7 +520,7 @@ def main() -> int:
)
print(
"large multi-boundary cap push/pull ok: "
f"face_id={multi_face_id}, elapsed={multi_elapsed:.3f}s, "
f"face_id={multi_face_id}, plan_elapsed={multi_plan_elapsed:.3f}s, elapsed={multi_elapsed:.3f}s, "
f"isolated_elapsed={multi_isolated_elapsed:.3f}s, "
f"topology_before={multi_before_topology}, topology_after={multi_after_topology}, result={multi_result}"
)