Files
cdsl-cad/backend/engine/cdsl_engine/executors/extrude.py
T
ganjihong 5ffb106f36 refactor(cdsl_engine): executor registry + per-family executor package
Phase 3 of the decoupling refactor (behavior-preserving):
- registry.py: atomic_executor decorator, ALL_ATOMIC_IDS with
  fail-fast registration validation, execute_node dispatcher
- executors/: one module per family (extrude, revolve, surfaces,
  loft_sweep, bodies, context, primitives, parametric, holes,
  dressup, patterns) + shared helpers in executors/common
- executors/__init__: explicit aggregation + completeness check
  (registry must cover every declared atomic id at import time)
- runtime.py: slimmed to entry points (analyze_cdsl/rebuild_cdsl)
  plus full historical re-exports incl. test-referenced privates

Adding an atomic operation now touches only one executor module and
its schema contract; the shared registry never changes. Verified
against baseline: zero new failures.
2026-09-09 13:33:06 +08:00

43 lines
1.8 KiB
Python

"""Extrusion executors (blind / two-sided / cut / through / from-face)."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from ..registry import atomic_executor
from ..topology import FeaturePlanNode, FeatureResult
from .common import _apply_primary_tool, _extruded_tool, _shape_from_primary
if TYPE_CHECKING: # pragma: no cover - import for type checkers only
from ..session import ExecutionSession
@atomic_executor(
"extrude_add_blind",
"extrude_add_blind_with_hole",
"extrude_add_two_sided",
"extrude_cut_blind",
"extrude_cut_two_sided",
"extrude_cut_through",
)
def _primary_executor(node: FeaturePlanNode, session: "ExecutionSession", sketch: dict[str, Any] | None) -> FeatureResult:
return _shape_from_primary(node, session, sketch=sketch)
def _execute_extrude_from_face(node: FeaturePlanNode, session: "ExecutionSession") -> FeatureResult:
resolved = [session.resolve(selector) for selector in node.selectors]
failed = next((item for item in resolved if item.status != "resolved"), None)
if failed or len(resolved) != 1 or resolved[0].record is None or resolved[0].record.kind != "face":
raise ValueError(failed.diagnostic.message if failed and failed.diagnostic else "derived profile face is unresolved")
face = resolved[0].record.value
tool, topology_delta = _extruded_tool(node, [face], session.adapter.face_normal(face), session)
return _apply_primary_tool(
node, session, tool, cutting=node.params.get("operation") == "cut", topology_delta=topology_delta,
)
@atomic_executor("extrude_from_face")
def _extrude_from_face_executor(node: FeaturePlanNode, session: "ExecutionSession", sketch: dict[str, Any] | None) -> FeatureResult:
del sketch
return _execute_extrude_from_face(node, session)