メインコンテンツまでスキップ

stack — 縦の境界を階に渡す

垂直に貫く空間 — 階段室・EVシャフト・吹抜け — は、階ごとに同じ関係を書き直すことになる。stack はその関係を一度書いて全階に渡す一語である。

stack <名> <レベル範囲> type:stair|shaft|void [属性...]

<名> はパスの末尾のセグメントであり、/ で始まらない。レベル範囲は L1..L11 の形で、type: は必須である。

stack st1 L1..L11 type:stair
stack st2 L1..L11 type:stair
stack ev  L1..L11 type:shaft

これは「連続するレベルの対ごとに、垂直の境界を一本ずつ張る」と書いたのと同じである。stack ev L1..L3 type:shaft は次の二行になる。

boundary /L1/ev /L2/ev type:shaft
boundary /L2/ev /L3/ev type:shaft

型はトポロジーだけを言う

垂直の隣接の既定はである。書かないかぎり、上下に重なる空間の間には床がある。stack が宣言するのはその例外であり、型は三つしかない。

意味
stair通れる。階段も斜路もエスカレーターもここに入る
shaft連続するが人は通れない (EVシャフト・ダクト)
void床が無い (吹抜け)

縦の通行可能性は stair の一語が引き受ける。階段も斜路もエスカレーターもトポロジーは同じなので、型は増やさない。装置の違いは空間の側の宣言 — stair: ramp: escalator: lift: — が形の生成規則として持つ (縦動線)。

✖ c.muro:line 13: A stack type is stair / shaft / void: undefined
✖ b.muro:line 11: A stack type is stair / shaft / void: floor

属性は全ての対に配られる

type: 以外の key:value は、生成される境界のすべてに同じ値で載る。

stack a L1..L3 type:stair spec:RC name:主階段
{
"between": ["/L1/a", "/L2/a"],
"a": "/L1/a",
"kind": "stair",
"attrs": { "name": "主階段", "spec": "RC" }
}

境界の name: と、stack の第一引数である末尾セグメントは別物である。前者は境界の表示名、後者は空間パスの一部である。

対応する空間が要る

stack は境界を作るだけで、空間は作らない。範囲のすべてのレベル/Lk/<名> の空間が無ければ、check が未定義の空間として止める。

✖ b.muro:line 11: References an undefined space: /L3/st

空間の側は スパン展開 で一行で書けるので、対になる二行はこう並ぶ。

space /L1..L3/st stair X1..X2 Y1..Y2 name:階段 use:common stair:N form:return
stack st L1..L3 type:stair

stack は残らない

stack は parse の時点で普通の boundary へ展開される。モデルにも正準JSONにも stack は残らない。一行で書いた版と、対ごとに手で書いた版は、同じ正準JSONを与える。


スパン展開

stack のレベル範囲と同じ綴りが、space zone boundary のパスの先頭セグメントでも使える。

space /L2..L9/B unit X2..X3 Y1..Y2 name:Bタイプ use:exclusive
zone /L3..L10/A name:Aタイプ use:exclusive
boundary /L2..L9/A/ldk /L2..L9/A/hall t:100 spec:LGS
  door w:800 name:D

基準階を一度だけ書くための記法である。展開されるのは先頭セグメントだけで、パスの途中に書いた .. は展開されない。

並びは z 順であって、名前の連番ではない

L1..L2 は「宣言済みのレベルのうち、z が両端の間 (両端を含む) にあるものを z の昇順に並べたもの」に展開される。名前が連番かどうかは見ない。

level L1 0  h:2000 slab:200
level M1 2200 h:2000 slab:200
level L2 4400 h:2700 slab:300
space /L1..L2/a room X1..X2 Y1..Y2 name:室

この一行は /L1/a /M1/a /L2/a三つの空間になる。中2階を範囲に入れたくなければ、範囲を分けて二行書く。

範囲の綴り

レベル名は 英字+数字 の形でなければスパンに使えない。RPH のような数字を持たない名は、範囲の端にできない。

✖ b.muro:line 11: Cannot read the level range: L1..R

範囲の端は宣言済みでなければならず、逆順は拒まれる。

✖ b.muro:line 11: The range includes an undeclared level (declare level first): L1..L9
✖ b.muro:line 11: The range runs backwards: L2..L1

一行の中の範囲は一つに揃える

boundary のように一行が二つのパスを取るとき、両方のスパンは同じでなければならない。「2階から9階までの A と、1階の B を結ぶ」のような書き方はできない。

✖ b.muro:line 12: Level ranges on one line must agree: L1..L3, L1..L2

字下げした行は全ての展開に載る

展開される行の下に字下げして書いた door / window / seg / area は、展開されたすべてに付く。扉を一度書けば全階に載る。

boundary /L1..L3/a /L1..L3/b t:100 spec:LGS
  door w:800 name:D

三階建てなら、この二行から境界が三本、扉が三枚出る。

スパンも残らない

スパン展開も parse の時点で普通の宣言に開かれる。展開後のパスが正準JSONに並び、.. の綴りは残らない。


縦を組む二行

垂直に貫く空間は、空間の列関係の列の二つが揃って初めて建物になる。片方だけでは通れない。

space /L1..L3/st stair X1..X2 Y1..Y2 name:階段 use:common stair:N form:return
space /L1..L3/ev shaft X2..X3 Y1..Y2 name:昇降機 use:common lift:1

stack st L1..L3 type:stair
stack ev L1..L3 type:shaft

空間の側の stair: lift: が形を決め、stack の側の type:stair type:shaft がトポロジーを決める。形があってもグラフが繋がっているとは限らない — 形だけを書いて stack を落とすと、koyu validaterun.disconnected で言う。

階を跨ぐ関係はどの階の層にも属さないので、ファイルを分けて書くときは entry (base層) に置くのが自然である (import)。

関連

  • 縦動線stair: ramp: escalator: lift: と、形の導出
  • boundary — 境界の宣言、水平と垂直の型
  • space — 空間の宣言とパス
  • import — 階を跨ぐ関係をどの層に置くか