Plans & Interfaces#
Placing several designs in a room, and the component interface that makes one placeable
Names: plan site room run place fill interface wall edge opening feature obstacle footprint mount attach abut needs stretch expose design swing hinge against at left_of right_of centre_on align gap facing elevation pin
When to use#
A plan lays out several parametric designs (a bed, a wardrobe, a run of kitchen
cabinets) in a room and compiles them as one project. A design becomes placeable by
adding an interface block to its root assembly; nothing else about the design
changes, and it still builds alone. This is Stream 1 of ADR-0060 (#463): the grammar and
the static checks (ww::plan::*) are implemented and type-check; the positioning verbs
(against, centre_on, fill, ...) parse and have their references checked, but have
no geometric effect yet — nothing is placed into world space, so status: partial.
Lowering a Plan into a built, pooled scene is ADR-0061 (a later stream).
Syntax#
project ... {
plan <Name> { ... } // or `site <Name>`, an exact alias for outdoor work
}
Inside a plan/site:
room <Name> [height=<expr>] [floor=<expr>] {
start x=<expr> y=<expr>
wall <Name> x=<expr> y=<expr> // or `edge` (bounds the room, is not a wall)
opening <Name> wall=<Name> at=<expr> width=<expr> height=<expr> [sill=<expr>]
kind=door|window|opening [swing=in|out] [hinge=left|right]
feature <Name> wall=<Name> at=<expr> kind=<word> [z=<expr>]
obstacle <Name> x=<expr> y=<expr> w=<expr> d=<expr> [h=<expr>]
}
run <Name> wall=<Name> [from=left|right] [offset=<expr>] [elevation=<expr>] {
place <Id> <Design> [overrides...] [label=] [finish=] [mirror=] [role=reference] { <verbs> }
fill <Design> [<Id>]
}
place <Id> <Design> ... { <verbs> } // also legal directly inside a plan
clearance <RefA> <RefB> min=<expr> [label=] // plan-level, check-only
Positioning verbs inside a place body (ADR-0060 §4.5; parsed and reference-checked, no
geometric effect in this stream): against <Ref>, at <len>, left_of <Ref> [gap=],
right_of <Ref> [gap=], centre_on <Ref> [with=], align <face> with=<Ref>,
gap <Ref> <len>, facing <word>, elevation <len>, pin x= y= [rot=],
clearance <Ref> min=<len>.
Inside a top-level assembly, the interface that makes it placeable:
assembly <Name> export=<Name> {
interface [kind=<word>] [front=pos_x|neg_x|pos_y|neg_y|pos_z|neg_z] {
expose <param>... [{ standard <len>... }]
footprint [x=] [y=] [z=] w=<expr> d=<expr> h=<expr>
mount floor|free|wall [z=<expr>]
attach <face>... // default: back
abut <face>... // default: none (not abuttable)
clearance <face> depth=<expr> [width=] [kind=walk|use|swing] [hinge=left|right] [label=]
needs <role> design=<Name> at=exposed_end|wall_end [min=<expr>]
stretch <param>...
mark <Name> [x=] [y=] [z=] [normal=pos_x|neg_x|pos_y|neg_y|pos_z|neg_z]
}
...
}
Face words (attach/abut/clearance <face>/align <face>, and what a mark may not
be named): front back left right top bottom. expose names either a param of this
assembly or a project param of this file (ADR-0060 Q4) — most catalogue designs keep their
envelope dimensions (width, bench_length, ...) at project scope, not assembly scope.
Example#
materials {
material Oak type=hardwood
}
assembly Board export=Board {
params {
w 100.0 min=50.0 max=200.0 label="Width"
}
interface kind=panel {
expose w
footprint w=w d=10.0 h=10.0
mount floor
attach back
abut left right
clearance front depth=600.0 kind=walk label="Walkway"
}
part Panel {
stock Oak w 10.0 10.0
by top_sw
pos x=0.0 y=0.0 z=0.0
}
}
plan Room {
room Main height=2400.0 {
start x=0.0 y=0.0
wall S x=4000.0 y=0.0
wall E x=4000.0 y=3000.0
wall N x=0.0 y=3000.0
wall W x=0.0 y=0.0
}
place B1 Board w=120.0 label="Board" {
against S
centre_on S
}
}
Pitfalls and diagnostics#
ww::plan::duplicate_plan— at most oneplan/siteper project (ADR-0060 Q2).ww::plan::plan_in_import— plans are not importable (Q15); an imported file declaring one is refused at theimportline.ww::plan::no_footprint/duplicate_interface— aninterfaceneeds exactly onefootprint.ww::plan::reserved_param—exposemay not namelabel,finish,mirrororrole: those are reservedplaceoverrides.ww::plan::mark_shadows_face— an interfacemarkmay not be namedfront,back,left,right,toporbottom.ww::plan::room_not_closed/room_self_intersecting/opening_off_wall— pure 2D geometry over literal room coordinates; a room whose walls depend on an unresolved CEL expression is checked at Stage 2 instead (not yet implemented).ww::plan::unknown_design/no_interface—place/fill/needs design=names a top-level assembly of this file or an import, and that design has aninterface.ww::plan::not_exposed— aplaceoverride must name a param the design'sinterfaceexposes.ww::plan::standard_out_of_range— anexpose ... { standard ... }size must lie inside the param's ownmin..max.ww::plan::fill_without_stretch—fill <Design>needs a design with astretchparam.ww::plan::not_abuttable— a design with noabutfaces (and noneeds, which the compiler would otherwise add fillers/end panels for) cannot sit mid-run.ww::plan::duplicate_name/unknown_ref/ambiguous_ref— walls, openings, features, obstacles, runs and places share one namespace per plan.ww::plan::mount_needs_wall— amount walldesign placed outside arunneeds an explicitagainst <Wall>.- A
place's overrides are evaluated like a--seton the design's own file (ADR-0060 §5.3): this stream checks the override resolves and lies in range, but does not yet build a specialised instance — that is ADR-0061's lowering.
See also#
parts-and-assemblies (an assembly's own params and part/instance=),
reuse-and-collections (import/export=, the mechanism place's design names resolve
through), project-and-params (expose's project-scope half, ADR-0060 Q4).
Names#
Every name this page declares, how the example library uses it, and the shortest real use.
plan#
project-level node; not used by any example yet.
site#
project-level node; not used by any example yet.
room#
word-valued property; not used by any example yet.
run#
node in 2 of 116 examples (2 uses).
Shortest real use, from postmodern_broken_pediment_cabinet.kdl:
run "w / 2.0 - gap_w / 2.0"
place#
not used by any example yet.
fill#
property; property in 10 of 116 examples (10 uses).
Shortest real use, from deco_side_chair.kdl:
material Stuffing type=fabric weave=velvet color="#1f4d3c" fill="'webbing, springs and horsehair under a velvet cover (one solid stands for all of it)'"
interface#
not used by any example yet.
wall#
word-valued property; not used by any example yet.
edge#
property; property in 23 of 116 examples (45 uses).
Shortest real use, from tall_white_cutout_cabinet.kdl:
rabbet face=pos_x edge=pos_y width=back_th depth=rd
opening#
word-valued property; not used by any example yet.
feature#
not used by any example yet.
obstacle#
not used by any example yet.
footprint#
not used by any example yet.
mount#
not used by any example yet.
attach#
not used by any example yet.
abut#
not used by any example yet.
needs#
not used by any example yet.
stretch#
not used by any example yet.
expose#
not used by any example yet.
design#
word-valued property; not used by any example yet.
swing#
word-valued property; not used by any example yet.
hinge#
word-valued property; value in 1 of 116 examples (2 uses).
Shortest real use, from ebonised_incised_cabinet.kdl:
component StrapR role=hinge {
stock Brass hinge_len 3.0 22.0
cut_path depth=0.0 face=neg_y keep="inside" {
polyline {
point x=hinge_len y=0.0
point x=18.0 y=0.0
point x=0.0 y=11.0
point x=18.0 y=22.0
point x=hinge_len y=22.0
}
}
}
against#
not used by any example yet.
at#
property; node in 47 of 116 examples (1024 uses); property in 10 of 116 examples (18 uses).
Shortest real use, from windsor_round_stool.kdl:
at z=-4.0 { circle r=rf }
left_of#
not used by any example yet.
right_of#
not used by any example yet.
centre_on#
not used by any example yet.
align#
not used by any example yet.
gap#
node in 1 of 116 examples (1 uses).
Shortest real use, from drawer_stack.kdl:
gap 10.0 min=4.0 max=30.0 step=1.0 label="Gap between drawers"
facing#
not used by any example yet.
elevation#
not used by any example yet.
pin#
node in 19 of 116 examples (35 uses).
Shortest real use, from appalachian_ladder_back_side_chair.kdl:
pin shape=round size=3.0