Expand description
§Persistent, editable space topology (DCEL)
This is the Rust core of the Room tool’s interactive room layout. It does
what the one-shot TS auto-space-detect pipeline does — turn a set of
2D wall-axis segments into the enclosed room faces of a floor plate —
but instead of building a half-edge graph, walking it once, and
throwing it away (returning bare Vec<[f64;2]> outlines), it keeps
the SpacePlate alive as the authoritative topology and exposes
local, O(degree) edit operations on it:
SpacePlate::drag_vertex— move a vertex; every incident face follows in the same call because a shared wall is one edge whose endpoints are shared vertices. This is the whole “pull one room, the neighbour follows” trick, and it falls out of the structure for free.SpacePlate::split_face— insert a partition between two vertices of a face (subdivide a room). O(1) surgery; both children valid immediately.SpacePlate::merge_faces— remove a shared edge, unioning the two rooms it separated. O(1) surgery.
Every edit returns the FaceIds it touched (with recomputed outline
- area) so the TS mirror can re-render only what changed.
§What this adds over the TS detector
- Persistence. The DCEL survives across edits; ids are stable (tombstoned, never reused) so a TS-side hit-test mirror can reference a face/edge across frames.
- Source-element provenance. Each input segment carries the IFC
element id it came from; that id is propagated through snapping,
T-junction resolution and intersection-splitting onto every bounding
half-edge. This is what makes
IfcRelSpaceBoundaryemission and the leak-repair affordance possible at bake — the TS detector drops it. prevpointers + the outer face as a real face, so split/merge are pure pointer surgery with no re-walk of the whole plate.
§Conventions
- Interior (room) faces wind CCW (signed area > 0). The unbounded
exterior winds CW and is flagged [
Face::is_outer]. A plate with several disconnected wall clusters has one outer face per component. - A half-edge’s [
HalfEdge::face] is the face on its left. - Holes / nested faces (a room enclosing a courtyard) are out of scope for this prototype: every CW cycle is treated as exterior, matching the TS detector. See the module TODO at the bottom.
Structs§
- Build
Options - Tuning for the arrangement pass. Distances are in the same units as the
input segments (the caller is expected to pre-scale to metres, exactly
as
extract-wallsdoes on the TS side). - FaceId
- Stable handle to a face (a room, or the unbounded exterior).
- Face
Patch - A face touched by an edit, with enough geometry for the caller to re-render it without re-querying the whole plate.
- Half
Edge Id - Stable handle to a directed half-edge.
- Input
Segment - An input wall-axis segment tagged with the IFC element it came from.
- Space
Plate - The persistent floor-plate topology. See the module docs.
- Vertex
Id - Stable handle to a vertex. Survives edits; never reused after tombstoning.
Enums§
- Edit
Error - Errors an edit op can reject with. Build never fails — a malformed input just yields fewer (or zero) interior faces, matching the TS detector.