feat(cadfs): expand selector provenance coverage
This commit is contained in:
@@ -8,6 +8,7 @@ selector resolution, never on executors.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .runtime_base import ExtentVector, FeatureExecutionError
|
||||
@@ -44,12 +45,29 @@ def _targeted_extent_vector(
|
||||
end_condition: dict[str, Any] | None = None,
|
||||
offset_mm: float | None = None,
|
||||
) -> ExtentVector:
|
||||
if session.body is None:
|
||||
reference = _extent_reference(node, end_condition) if condition != "through_next" else None
|
||||
source_vertex_point: Vector3 | None = None
|
||||
if condition == "up_to_vertex" and isinstance(reference, dict) and reference.get("kind") == "source_vertex":
|
||||
raw_point = reference.get("point_mm")
|
||||
if not (
|
||||
isinstance(raw_point, list)
|
||||
and len(raw_point) == 3
|
||||
and all(isinstance(value, (int, float)) and math.isfinite(float(value)) for value in raw_point)
|
||||
):
|
||||
raise FeatureExecutionError(
|
||||
"invalid_source_vertex_extent",
|
||||
"The source-vertex extent datum must contain one finite 3D point",
|
||||
extent=condition,
|
||||
)
|
||||
source_vertex_point = (float(raw_point[0]), float(raw_point[1]), float(raw_point[2]))
|
||||
elif session.body is None:
|
||||
raise FeatureExecutionError("missing_extent_body", "Selector-dependent extent requires an existing body", extent=condition)
|
||||
if condition == "through_next":
|
||||
target = session.body
|
||||
elif source_vertex_point is not None:
|
||||
target = None
|
||||
else:
|
||||
reference = _extent_reference(node, end_condition)
|
||||
assert isinstance(reference, dict)
|
||||
resolution = session.resolve(reference)
|
||||
if resolution.status != "resolved" or resolution.record is None:
|
||||
raise ValueError(resolution.diagnostic.message if resolution.diagnostic else "extent target was not resolved")
|
||||
@@ -62,7 +80,7 @@ def _targeted_extent_vector(
|
||||
)
|
||||
target = resolution.record.value
|
||||
if condition == "up_to_vertex":
|
||||
target_point = session.adapter.vertex_coordinates(target)
|
||||
target_point = source_vertex_point or session.adapter.vertex_coordinates(target)
|
||||
projections = [
|
||||
vector_dot(vector_subtract(target_point, point), direction)
|
||||
for face in faces
|
||||
@@ -89,6 +107,19 @@ def _targeted_extent_vector(
|
||||
distance = session.adapter.uniform_intersection_distance(target, faces, direction)
|
||||
except ValueError as error:
|
||||
message = str(error)
|
||||
if condition == "up_to_surface" and message == "extent target is not reached by every profile ray":
|
||||
# Do not reinterpret a partially hit finite face: that path
|
||||
# has explicit trimmed-solid semantics below. Only a wholly
|
||||
# unreachable planar face may terminate on its supporting
|
||||
# plane, and the adapter proves one positive, uniform
|
||||
# profile-to-plane distance before returning it.
|
||||
if not session.adapter.target_has_forward_intersection(target, faces, direction):
|
||||
try:
|
||||
distance = session.adapter.uniform_planar_supporting_surface_distance(target, faces, direction)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return ExtentVector(vector_scale(direction, distance))
|
||||
code = "non_uniform_extent_target" if "non-uniform" in message else "extent_target_not_reached"
|
||||
if condition in {"up_to_surface", "through_next"}:
|
||||
# #5 高级终止条件:profile 与目标面非均匀相交(部分采样点未
|
||||
|
||||
Reference in New Issue
Block a user