feat(cadfs): expand selector provenance coverage
This commit is contained in:
@@ -13,6 +13,11 @@ from __future__ import annotations
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
from OCP.BRep import BRep_Tool
|
||||
from OCP.TopAbs import TopAbs_EDGE, TopAbs_VERTEX
|
||||
from OCP.TopExp import TopExp_Explorer
|
||||
from OCP.TopoDS import TopoDS
|
||||
|
||||
from .specs import canonical_plane_signature
|
||||
from .topology import TopologyRecord
|
||||
|
||||
@@ -48,6 +53,40 @@ def topology_records(body: Any, feature_id: str, body_id: str) -> list[TopologyR
|
||||
edges = list(body.edges())
|
||||
vertices = list(body.vertices())
|
||||
|
||||
# build123d may wrap a vertex extracted from a solid in a distinct OCC
|
||||
# handle. Builder FirstShape/LastShape vertex history is only comparable
|
||||
# with the final result's native explorer handles, so retain those exact
|
||||
# handles for selector records. Faces and edges keep their established
|
||||
# build123d export path.
|
||||
result_vertices: list[Any] = []
|
||||
explorer = TopExp_Explorer(body.wrapped, TopAbs_VERTEX)
|
||||
while explorer.More():
|
||||
candidate = explorer.Current()
|
||||
if not any(candidate.IsSame(existing) for existing in result_vertices):
|
||||
result_vertices.append(candidate)
|
||||
explorer.Next()
|
||||
result_edges: list[Any] = []
|
||||
explorer = TopExp_Explorer(body.wrapped, TopAbs_EDGE)
|
||||
while explorer.More():
|
||||
candidate = explorer.Current()
|
||||
if not any(candidate.IsSame(existing) for existing in result_edges):
|
||||
result_edges.append(candidate)
|
||||
explorer.Next()
|
||||
|
||||
def exact_incident_edge_count(vertex: Any) -> int:
|
||||
count = 0
|
||||
for edge in result_edges:
|
||||
edge_vertices: list[Any] = []
|
||||
edge_explorer = TopExp_Explorer(edge, TopAbs_VERTEX)
|
||||
while edge_explorer.More():
|
||||
candidate = edge_explorer.Current()
|
||||
if not any(candidate.IsSame(existing) for existing in edge_vertices):
|
||||
edge_vertices.append(candidate)
|
||||
edge_explorer.Next()
|
||||
if any(vertex.IsSame(candidate) for candidate in edge_vertices):
|
||||
count += 1
|
||||
return count
|
||||
|
||||
def index_for(shape: Any, candidates: list[Any]) -> int | None:
|
||||
"""Map a subshape returned by a face/edge back to body topology."""
|
||||
# 用 is_same 把面/边的子形状映射回主体拓扑列表的下标。
|
||||
@@ -302,10 +341,11 @@ def topology_records(body: Any, feature_id: str, body_id: str) -> list[TopologyR
|
||||
geometry=geometry,
|
||||
))
|
||||
# 5. 导出顶点记录:含坐标与关联边数。
|
||||
for index, vertex in enumerate(vertices):
|
||||
point = [vertex.X, vertex.Y, vertex.Z]
|
||||
for index, vertex in enumerate(result_vertices):
|
||||
point_value = BRep_Tool.Pnt_s(TopoDS.Vertex_s(vertex))
|
||||
point = [point_value.X(), point_value.Y(), point_value.Z()]
|
||||
records.append(TopologyRecord(
|
||||
record_id=f"{body_id}:vertex:{index}", kind="vertex", feature_id=feature_id, body_id=body_id, value=vertex,
|
||||
geometry={"center_mm": point, "incident_edge_count": len(vertex_edges[index])},
|
||||
geometry={"center_mm": point, "incident_edge_count": exact_incident_edge_count(vertex)},
|
||||
))
|
||||
return records
|
||||
|
||||
Reference in New Issue
Block a user