engineering/arch/catalogue.py is the standard-parts pattern of track B for an
architectural plan: twenty authored plan symbols in two families - thirteen
furniture items (single and double bed, wardrobe, three-seat sofa, armchair,
chair, dining table with four chairs, desk, kitchen counter run, fridge,
bookshelf, nightstand, coffee table) and seven sanitary items (WC, bidet, wall
basin, shower tray, bathtub, kitchen sink, washing machine). Every size is a
nominal catalogue dimension and says so in SIZE_BASIS, in each row and in both
tool docstrings; no standard is cited because none fixes these sizes.
Each item is typed block_define primitives on layer 0 inside [0, w] x [0, d],
origin at the back-left corner with the wall side along +X - a test holds all
twenty to their footprint. catalogue() searches name, family and the English
and Turkish labels, ignoring case and Turkish diacritics (buzdolabi finds
buzdolabı). insert_item() defines ARCH_<NAME> once, creates the furniture or
sanitary layer from its ARCH_LAYERS row when missing (live ActiveX refuses a
missing layer), inserts with an invisible ITEM attribute, and refuses an
unknown name with the nearest catalogue names before any write.
SECTION 25 opens on this branch with the two tools, alias records (INSERT,
ADCENTER, TOOLPALETTES and English/Turkish synonyms), a regenerated inventory,
the README snapshot at 231 tools, and the branch-local group snapshot
(entity_query 10, entity_creation 19) that the track F merge recomputes.
No new ActiveX call: insert_item composes the existing layer_list,
layer_create, block_list, block_define and block_insert members. Run once live
through ComBackend on AutoCAD 2026 (scratch document, closed after): all
twenty items defined and inserted, a second double_bed insert reported
defined=false, ITEM read back as double_bed, 20 ARCH_* blocks, 21 INSERTs on
A-FURN-E-N / A-SANR-E-N, both layers created at ACI 5 / 0.18 mm.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
Track F starts here; the three group branches are cut from this commit.
- engineering/arch/model.py: Wall, Opening, Stair and Room as frozen
dataclasses, and every refusal of spec 4 before anything is drawn, by path
(walls[2].thickness): finite positive numbers, an axis of at least two
distinct points with no zero-length segment, an arc segment refused by name
rather than approximated, an opening on an unknown wall, past its wall,
across an axis vertex or overlapping another (both ids named), an unknown
material, and a typed room area - areas are measured, never typed. The
plan travels as ACADMCP_ARCH XDATA; an opening's door/window kind and a
stair's straight/l/u kind ride beside the payload kind as opening_kind /
stair_kind, because one key cannot hold both.
- engineering/arch/layers.py: the arch set - thirteen ISO 13567-style layers
with ISO 128 lineweights only (0.05 mm on the construction scratch layer,
as every set in this repository) - and ARCH_ROLE_LAYER, the one place a
role becomes a layer. Registered in engineering/layers.py last, which is
what keeps the engineering.layers <-> engineering.arch import cycle closed.
- engineering/arch/materials.py: eight wall materials, one pattern each,
every row citing its source: ANSI31 for brick (ISO 128-50 general hatching,
acadiso.pat's own "Iron, Brick, Stone masonry"), AAC as ANSI31 at twice the
spacing (a repository convention, and it says so), AR-CONC / AR-SAND as
AutoCAD patterns, and the JIS A 0150 RC / stone / wood symbols. Reinforced
concrete cannot be ANSI31 and AR-CONC in one HATCH, so it takes the one
symbol that names it. Periods on a 1:50 sheet are recomputed from ezdxf's
own pattern definitions by the tests. normalise_material is the one reading
of a material name, shared by the model and wall_hatch, so the model never
refuses "Reinforced Concrete" that the hatch table resolves.
- engineering/arch/lang.py: EN / TR vocabulary, D/W and K/P tag prefixes, and
the decimal comma for lang="tr" (24,50 m2).
- draw_prims(role_layer=) and the XDATA codec's app_id= / kinds=: both
generalised with the mechanical defaults, and the mechanical suite passes
unchanged against them - that is the regression gate.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd