增加了thread几何基础操作

This commit is contained in:
2026-09-03 19:39:06 +08:00
parent ef9626f936
commit bb9e8a8720
6 changed files with 130 additions and 7 deletions
+22 -1
View File
@@ -11,7 +11,8 @@ from typing import Any, Callable, Protocol
from .build123d_adapter import Build123dGeometryAdapter
from .capabilities import CapabilityAnalyzer, pattern_transform_blocker, sketch_ids_required_by_contract
from .runtime_types import (
AxisSpec, CapabilityResult, FeaturePlanNode, FeatureResult, HoleSpec, PlaneSpec, Vector3,
AxisSpec, CapabilityResult, FeaturePlanNode, FeatureResult, HoleSpec, PlaneSpec,
ThreadSpec, Vector3,
RuntimeDiagnostic, SelectorResolution, TopologyRecord, TopologyRegistry,
vector_add, vector_cross, vector_dot, vector_scale, vector_subtract, vector_unit,
)
@@ -23,6 +24,7 @@ ALL_ATOMIC_IDS = frozenset({
"revolve_add", "revolve_cut", "hole_blind", "hole_countersink",
"hole_counterbore", "sphere_add", "reference_plane", "reference_axis",
"hole_wizard", "fillet", "chamfer", "pattern_linear", "pattern_mirror",
"thread_add",
})
@@ -83,6 +85,7 @@ class GeometryAdapter(Protocol):
def fuse(self, body: Any | None, solid: Any) -> Any: ...
def cut(self, body: Any, tool: Any) -> Any: ...
def sphere(self, radius_mm: float, center_mm: Vector3) -> Any: ...
def thread_solid(self, spec: ThreadSpec) -> Any: ...
def hole_tool(self, spec: HoleSpec, starts: list[Vector3], inward: Vector3, through_depth_mm: float) -> Any: ...
def body_center(self, body: Any) -> Vector3: ...
def body_span(self, body: Any, direction: Vector3) -> float: ...
@@ -510,6 +513,23 @@ def _execute_sphere(node: FeaturePlanNode, session: ExecutionSession) -> Feature
return session.result(node)
def _execute_thread(node: FeaturePlanNode, session: ExecutionSession) -> FeatureResult:
# 螺纹特征(thread_add)执行入口:按规格生成参数化螺纹段并并入当前主体。
# 1. 解析并校验尺寸/牙距/轴,非法输入抛出带具体原因的 ValueError。
spec = ThreadSpec.from_feature(node.atomic_id, node.params)
# 2. 由适配器门面生成沿 spec.axis 放置的外螺纹实心段。
solid = session.adapter.thread_solid(spec)
# 3. 与当前主体做布尔并(fuse)后登记为新主体,并返回该特征的结果对象。
session.register_body(node.feature_id, session.adapter.fuse(session.body, solid), replay_node=node)
return session.result(node)
def _thread_executor(node: FeaturePlanNode, session: ExecutionSession, sketch: dict[str, Any] | None) -> FeatureResult:
# 螺纹不需要草图平面,丢弃该参数后执行。
del sketch
return _execute_thread(node, session)
def _host_plane(resolution: SelectorResolution) -> PlaneSpec:
if resolution.record is None:
raise ValueError(resolution.diagnostic.message if resolution.diagnostic else "host face was not resolved")
@@ -1021,6 +1041,7 @@ EXECUTORS: dict[str, ExecutorFunction] = {
"reference_plane": _reference_plane_executor,
"reference_axis": _reference_axis_executor,
"sphere_add": _sphere_executor,
"thread_add": _thread_executor,
"extrude_add_blind": _primary_executor,
"extrude_add_two_sided": _primary_executor,
"extrude_cut_blind": _primary_executor,