Units / topology
topology.shell partial
- Layer
- 36
- Upstream lines
- 750
- Functions
- 37
- Rust module
topology::shell
Source: crates/solidcore/src/topology/shell.rs
Upstream: source/SMLib/inc/SmRegion.h, source/SMLib/inc/SmShell.h, source/SMLib/src/SmRegion.cpp, source/SMLib/src/SmShell.cpp
Notes
PARTIAL (port by @0xlillith in PR #80, finished in PR #154): difftest 911 cases, 892 pass bit-identical, 0 failed, 19 deferred (query.brep 11: SmBrep::CalculateBoundingBox, and the 8 ray_closed_* cases whose boundary-face shape needs the cached B-rep (harness-limited, below); query.face_p1 4: SmFace::CalculateBoundingBox; topology.face_p3 4: SmFace::CreateUVTrimCurves reached through SmTopologyTraverser::IsInnerShell (was topology.face_p1 CalculateUVDomainFromUVTrimCurves before PR #148 wired it)), max_rel_err 0, no absolute floors; --perturb SENSITIVE 892/892; probe (--seeds 3000) 3895 cases, 0 failed, no crash. PR #80: RegionRef/RegionLookup resolve native region identities against the live arenas (geom.attribute green, geom.a_object region propagation compared), ordered wire traversal, child transfer with literal face-use sibling links, RayFire, degeneracy, OrderShells. PR #154 (after merging main): the shell calls its owners on main (topology::edge::{vertices, edgeuses, is_wire}, topology::vertex::edges, topology_traverser::is_inner_shell, so Shell::is_inner_shell / order_region_shells take &mut Kernel); wired UNPORTED(topology.shell) in mass::integrator (SmRegion::IsVoid) and topology_traverser (RemoveShell -> transfer_children, FaceuseShellReplacement -> shell::move_faceuse: 7 traverser cases now compared); the topology.vertexuse-style difftest importers (vertexuse, vertex, edge, face_p2, and through them traverser, trimming_tools, heal.gap, heal.heal_data_p2) now read the shared version-3 shell state block (sc_topology_fixture::append_shell_state, appended by every export: infinite region, region void flags, wire/vertex shell heads, vertex-use lists, face-use next/last links) instead of inferring those fields; the walks register SmBrep::GetEdges and the vertex-use lists first. Stubs left: UNPORTED(query.face_p1) SmFace::CalculateBoundingBox, UNPORTED(query.brep) SmBrep::CalculateBoundingBox, UNPORTED(topology.brep_p2) SmBrep::LocalCurveSector. CO-PORTED: SmOwningTopology::Remove/PostInsert of a face use on the typed face-use list (topology::shell::move_faceuse; the topology.proto_topology_p1 version works on ObjectKey records), SmBrep::GetEdges (no filter) as topology::shell::brep_get_edges = the B-rep edge arena in insertion order (topology.brep_p1; valid for importers that register GetEdges first, as every fixture walk now does), minimum default-tight CalculateBoundingBox branches (query.face_p1). Plan notes: 37 fns; largest: SmShell::RayFire, SmShell::TransferChildrenTo, SmShell::GetWireEdges, SmRegion::OrderShells; cycle back-edges (call into later units; stub or co-port): topology.edge(5), query.face_p1(2), topology.brep_p1(2), query.brep(1), topology.brep_p2(1), topology.topology_traverser(1), topology.vertex(1), topology.vertexuse(1); unit-SCC #22 (220 units); 319 upstream test entry points reach this unit; CO-PORTED in topology.edgeuse_p1 (PR #55): SmRegion (m_pListOwner != NULL only) -> topology::Region, SmShell::m_pListOwner -> topology::Shell::region; SmShell::GetRegion, GetBrep -> topology::edgeuse::p1::{shell_region, shell_brep}. Review round (PR #154): the generator now draws random operations over vertex/face/network/.smb/mixed fixtures (TransferChildrenTo with any shell pair, NULL/duplicate candidates and preceding transfers, arbitrary SM_TYPE codes, ray, degeneracy, ordering, filtering); a new native fixture kind mixed (a face plus N wire networks in one B-rep) and pre transfers reach face->wire, wire->face, mixed->empty and wire->wire; the transfer shim rejects exactly the inputs that crash C++ (NULL candidate on a reading branch, GetWireEdges on a wire shell without head) and both sides then return rejected_input. RayFire is compared only on the empty-shape branch (EmptyRayWorld): solution selection, parameter filtering, LoadFromIntersection and line segments need a real TopologyObjects world over the imported B-rep (topology::brep_cache::BrepObjects over a built BrepCache = query.brep, plus SmBrep::LocalCurveSector = topology.brep_p2). The 8 ray_closed_* cases are recorded as harness-limited: EmptyRayWorld::shell_ray_shape defers any non-empty boundary-face shape as UNPORTED(query.brep), so they stay deferred (never FAIL) when query.face_p1 lands; swap in BrepObjects when query.brep and topology.brep_p2 are ported. Review round 2 (PR #154): GetWireEdges, GetMatedShells and RayFire now claim and lock a context mark like SmNewMarkAndLock (geom::context::with_mark_lock, ALL_MARKS) and mark through topology_traverser::Marks (new Entity::Shell), so wire_edges / Shell::mated_shells / ray_fire / transfer_children / remove_shell / the degeneracy functions take &mut Kernel; the difftest compares per call how far each of the 5 context mark counters advanced and that none stays locked (topology.shell wires, query, transfer and ray outputs, shim MarkSnap). The ray shim guard rejects non-finite start/direction/tolerance/radius only when a shell has boundary faces (it reaches the solver there); empty-shape runs compare them (generator draws nan/inf). SmRegion::Remove is not used by merge_p1 any more (see boolean.merge_p1); region_remove_shell stays as the CO-PORT of SmOwningTopology::Remove (also recorded in topology.proto_topology_p1). Missing region context in the geom.attribute / geom.a_object handlers is Unported(topology.shell), not InvalidInput. Face-use sibling links, once Some, win over Shell::members (documented in shell.rs).
Difftest
- Cases
- 911
- Passed
- 892
- Deferred
- 19
- Failed
- 0
- Both errored
- 9
- Max rel. error
- 0.0
- Tolerance
- 1e-09 rel.
- Seeds
- 16
Blocked by
| Unported unit | Deferred cases |
|---|---|
query.brep claimed | 11 |
query.face_p1 claimed | 4 |
topology.face_p3 claimed | 4 |
Report JSON (per-case results)
Dependencies
Depends on: geom.extent3d green geom.object partial geom.solution_array partial geom.vector3d green topology.edgeuse_p1 partial topology.proto_topology_p1 partial topology.topology green
Soft dependencies: geom.context green geom.tol green intersect.point_class partial intersect.topology_solver_p2 partial nurbs.b_spline_curve_p1 green
Dependents: blend.fillet_executive_p1 todo boolean.merge_p1 partial boolean.merge_p4 todo offset.offset_executive_p2 claimed query.face_p1 claimed sweep.topology_sweep claimed topology.brep_p1 claimed topology.brep_p10 claimed topology.brep_p2 claimed topology.brep_p3 claimed topology.brep_p4 claimed topology.brep_p5 claimed topology.brep_p6 claimed topology.brep_p7 claimed topology.brep_p9 claimed
Soft dependents: blend.fillet_geom_p1 claimed blend.fillet_solver_p1 claimed blend.hcr claimed boolean.merge_p2 todo boolean.merge_p3 todo boolean.merge_p5 partial heal.heal_data_p1 partial heal.heal_data_p3 partial mass.integrator partial primitive.primitive_creation_p1 claimed primitive.primitive_creation_p2 todo primitive.primitive_creation_p3 todo query.api_queries partial topology.edge partial topology.face_p4 claimed topology.loopuse partial topology.topology_traverser partial topology.trimming_tools partial topology.vertex partial topology.vertexuse partial
Upstream functions
| Upstream function | Defined at | Lines | Rust (from the file header) |
|---|---|---|---|
SmRegion::SmRegion | SmRegion.h:43 | 6 | |
SmRegion::~SmRegion | SmRegion.h:50 | 5 | |
SmRegion::IsVoid | SmRegion.h:119 | 1 | [Region::get_shells], [Region::is_void], [Region::set_is_void] |
SmRegion::GetClassString | SmRegion.h:146 | 1 | |
SmRegion::GetType | SmRegion.h:146 | 1 | |
SmRegion::GetTypeString | SmRegion.h:146 | 1 | |
SmRegion::GetShells | SmRegion.h:157 | 9 | [Region::get_shells], [Region::is_void], [Region::set_is_void] |
SmRegion::GetBrep | SmRegion.h:172 | 5 | [shell_region], [shell_brep] |
SmShell::GetClassString | SmShell.h:137 | 1 | |
SmShell::GetType | SmShell.h:137 | 1 | |
SmShell::GetTypeString | SmShell.h:137 | 1 | |
SmRegion::IsDegenerate | SmRegion.cpp:273 | 16 | [shell_is_degenerate], [region_is_degenerate] |
SmRegion::IsInfiniteRegion | SmRegion.cpp:296 | 6 | [Region::is_infinite_region] |
SmRegion::SetIsVoid | SmRegion.cpp:308 | 6 | [Region::get_shells], [Region::is_void], [Region::set_is_void] |
SmRegion::OrderShells | SmRegion.cpp:324 | 63 | [Shell::is_inner_shell], [order_region_shells] |
SmRegion::IsKindOf | SmRegion.cpp:520 | 4 | |
SmShell::SmShell | SmShell.cpp:33 | 8 | |
SmShell::~SmShell | SmShell.cpp:47 | 13 | |
SmShell::GetWireEdges | SmShell.cpp:130 | 100 | [wire_edges] |
SmShell::TransferChildrenTo | SmShell.cpp:364 | 160 | [transfer_children] |
SmShell::GetMatedShells | SmShell.cpp:536 | 44 | [Shell::is_closed], [Shell::mated_shells] |
SmShell::RayFire | SmShell.cpp:592 | 183 | [ray_fire] |
SmShell::IsInnerShell | SmShell.cpp:793 | 11 | [Shell::is_inner_shell], [order_region_shells] |
SmShell::IsDegenerate | SmShell.cpp:1168 | 20 | [shell_is_degenerate], [region_is_degenerate] |
SmShell::IsClosed | SmShell.cpp:1200 | 22 | [Shell::is_closed], [Shell::mated_shells] |
SmShell::GetWireEdge | SmShell.cpp:1379 | 11 | [Shell::wire_edge], [Shell::vertex] |
SmShell::GetRegion | SmShell.cpp:1409 | 4 | [shell_region], [shell_brep] |
SmShell::GetBrep | SmShell.cpp:1419 | 4 | [shell_region], [shell_brep] |
SmShell::GetFaceuses | SmShell.cpp:1429 | 9 | [Shell::get_faceuses], [Shell::first_faceuse] |
SmShell::IsVertexShell | SmShell.cpp:1444 | 2 | |
SmShell::IsWireShell | SmShell.cpp:1452 | 2 | |
SmShell::IsFaceuseShell | SmShell.cpp:1460 | 2 | |
SmShell::IsUnknownShell | SmShell.cpp:1468 | 2 | |
SmShell::SetShellType | SmShell.cpp:1476 | 2 | |
SmShell::GetVertex | SmShell.cpp:1484 | 11 | [Shell::wire_edge], [Shell::vertex] |
SmShell::GetFirstFaceuse | SmShell.cpp:1501 | 9 | [Shell::get_faceuses], [Shell::first_faceuse] |
SmShell::IsKindOf | SmShell.cpp:1884 | 4 |
Module file-header table (20 rows)
| Rust | Upstream |
|---|---|
[ShellType], [ShellMembers] | m_tShellType, typed m_pList contents |
[Shell::new], [Region::new], implicit Drop | constructors, destructors |
[Shell::type_string], [Shell::class_string], [Shell::is_kind_of], [Region::type_string], [Region::class_string], [Region::is_kind_of] | SM_COMMON names and full base-class chain |
[Shell::get_faceuses], [Shell::first_faceuse] | GetFaceuses, GetFirstFaceuse |
[Shell::wire_edge], [Shell::vertex] | GetWireEdge, GetVertex |
[Shell::is_closed], [Shell::mated_shells] | IsClosed, GetMatedShells |
[shell_region], [shell_brep] | GetRegion, GetBrep |
[RegionLookup], [RegionRef] | caller-supplied resolution of implicit native region pointers |
[wire_edges] | SmShell::GetWireEdges |
[ray_fire] | SmShell::RayFire (partial output state retained) |
[transfer_children] | SmShell::TransferChildrenTo |
[move_faceuse] | SmOwningTopology::Remove + PostInsert of a face use (typed list) |
[shell_is_degenerate], [region_is_degenerate] | IsDegenerate (native default tolerance) |
shell_bounds_for_degeneracy, region_bounds_for_degeneracy | minimum default-tight CalculateBoundingBox branches (query.face_p1) |
[faceuse_sibling_links] | typed SmTopology::GetNext / GetLast for face uses |
topology::edge::{vertices, edgeuses, is_wire}, topology::vertex::edges | SmEdge::GetVertices, GetEdgeuses, IsWire, SmVertex::GetEdges (callees, no filters) |
[Region::get_shells], [Region::is_void], [Region::set_is_void] | GetShells, IsVoid, SetIsVoid |
[Region::is_infinite_region] | IsInfiniteRegion |
[Shell::is_inner_shell], [order_region_shells] | IsInnerShell, OrderShells |
[region_remove_shell] | SmOwningTopology::Remove of a shell from its region |
Upstream tests reaching this unit
prog_test:my_test_extent3d, prog_test:my_test_vector2d, prog_test:my_test_surface_closest_point, prog_test:my_test_drop_point, prog_test:my_test_matrix, prog_test:my_test_reversed_line_join