read_segments trusted any row with `points`. On a live seat an old-style
AcDb2dPolyline's Coordinates are x, y, z triples (measured on AutoCAD 2026,
2026-09-23: [200,200,0, 4200,200,0, ...]) which the backend reads two at a
time, so three closed ms.AddPolyline outlines on WALLS reported points like
[[0,0],[0,8600],[0,0],[8600,5400],...] and rooms_detect answered five faces of
2.6-6.9 m2 for two 20 m2 rooms. Headless, the same POLYLINE arrives with no
points and was dropped without a word; so were walls inside a block reference.
The reader now reads LINE and the lightweight polyline only (LWPOLYLINE, and
the live AcDbPolyline reported POLYLINE), and lists every other entity that
could bound a room in `skipped` with its handle, type and reason: arcs and
bulged edges as before, old-style polylines (2DPOLYLINE/3DPOLYLINE live, a
vertex-less POLYLINE headless), block references (INSERT / BLOCKREFERENCE)
and anything else not a line. Text, dimensions, leaders, points and hatches
bound nothing and are passed over. Re-run live on AutoCAD 2026 through the
real com_backend._entity_info rows: count 0 with the three polylines in
skipped (was 5 wrong rooms); with a lightweight pair and a block added, count
1 at 20 000 000 mm2 plus the block reference in skipped. The backend's stride
is left alone (shared file, other readers); this reader no longer trusts it.
label_room refused a reused id but not a reused face: a second label in a
labelled room (a retry after a transport timeout) wrote a second record with
the same area, which a schedule total counts twice. It is now refused before
anything is drawn, naming the record and label already there. rooms_detect
reports `labels` (every record in the face; `label` stays the first) and
`label_conflicts` for a face holding more than one.
No new ActiveX member is called.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
engineering/arch/faces.py finds the closed faces a set of straight segments
bounds: endpoints within tol merge, every segment splits where another crosses
or touches it (the T-junction a partition makes), dangling edges are pruned,
and the half-edge walk turns to the next edge clockwise so every bounded face
comes out counter-clockwise. A piece nested inside a face of another piece is
a hole in it, so a ring of walls measures its body and a room with a column
measures its floor. Areas come from engineering.measure.polygon_area_perimeter,
the arithmetic analysis_measure_entity reports.
engineering/arch/rooms.py labels a room with the area of the face its point
lies in - a 4000 x 5000 room between 200 mm walls reads 20.00 m2, never the
axis area - and writes the room record onto the name text. Opening records
close door and window gaps along the wall faces, so two rooms either side of a
door stay two rooms. rooms_detect reads any plan's lines, drops faces under
min_area and thin wall bodies (mean width under 600 mm, a declared heuristic),
reports confidence 1.0 for faces enclosed only by our wall layer and 0.6
otherwise, lists arcs as skipped rather than flattening them, and never
modifies the drawing.
Two hardenings beyond the plan text, each with a test: read_records pages the
current space once and filters to the arch layers locally (the plan paged it
once per arch layer - twelve full scans, each a cross-process call per entity
on a live seat), keeping the same layer-then-drawing order; and an opening
record whose offset falls outside its wall (a stale record) is listed in
omitted instead of raising out of the read-only detector.
No new ActiveX member is called: both tools compose entity_list,
entity_get/set_xdata, layer_list and draw_prims, whose COM paths are already
live-verified.
SECTION 25 opens on this branch with arch_room and arch_rooms_detect under
the rooms marker; until Task 9 gives arch its group they file under
entity_creation and entity_query. Alias records, a regenerated inventory, the
README snapshot at 231 tools in 25 groups and the frozen group-size snapshot
follow.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd