ルール ベースのモデリング
チュートリアル データは、[Help] メニュー → [Download Tutorials and Examples…] を選択し、[CityEngine Tutorial] からダウンロードできます。
このチュートリアルは、Houseal Lavigne Associates の Devin Lavigne 氏との共同作業で作成されました。

概要
CityEngine は「プロシージャル モデリング アプリケーション」であり、2D シェープを一連の処理 (CGA ルール ファイル) に通すことで 3D モデルを生成します。CityEngine の強みは、CGA (Computer Generated Architecture) にあります。CGA は CityEngine の建築的な 3D コンテンツを生成するために記述できる独自のプログラミング言語です。基本的に CGA ルールをシェープに割り当てたり適用したりすると、3D モデルが作成されます。3D モデルの複雑さは、CGA ルールおよびその中に記述された指示によって決まります。単純な CGA ファイルは建物のフットプリント形状を押し出して 3D のシェープ (マス) を作成するだけかもしれません。一方、より複雑な CGA ルールでは、マスのファサードにテクスチャーを適用したり、それを分割して詳細な 3D モデルを生成したりすることができます。
CGA コードを書くうえで重要なのは、ルールを段階的に作成しその都度機能を追加していくことです。最終的にどうしたいかの計画は必要ですが、いきなり 500 行のコードを書いて実行するわけではありません。どちらかというと、ルールを少しずつ構築し、その都度結果を確認しながら進めていきます。
このチュートリアルでは、単純なフットプリントから一連の 3D 建物を作成するルールを記述する方法を学びます。
シーンを開く
始めるにはプロジェクトの scenes フォルダーから BasicsOfRules.cej を開きます。
Hello, World!
コーディングには「Hello, World!」というものがあります。これは、簡単なコードを書いて簡単なメッセージを出力することで、基本的な構文を確認したり、コードが正しく動作しているか確認したりする方法です。CityEngine における「Hello, World!」の例は、ランダムな高さで形状を単純に押し出し、色を適用するという、シンプルなものです。
最初のルールを作成するために、rules フォルダーを右クリックし、[New] → [CGA Rule File] を選択し、ルール名を DetailedBuilding.cga とします。
まず、使用している CityEngine のバージョン (例: version 20XX.X) が書かれている行の下に、以下のコードを追加し、ルールを保存します。
@StartRule
Footprint -->
extrude(rand(10,100))
color(1,1,0)@StartRule アノテーションを付与すると、この Footprint ルールが利用できるようになります。次の行では、シェープを 10〜100 メートルのランダムな高さに押し出します。最後の行は、シェープを RGB の黄色に着色します。
ルールの割り当て
ルールを保存したら、形状を選択してルールを割り当てます (下図参照)。新しいルールを割り当てた後、何も起こらない場合は、[Generate Models] ツール (Ctrl+G) をクリックするか、メイン メニューの [Shapes] → [Generate Models] をクリックします。
属性の追加
ルールが動作することを確認できたので、高さを属性として追加し、ルールにいくつかの追加機能を持たせます。重要なポイントは、段階的な変更をすることです。ゼロから書き直すのではなく、すでに作成したルールに変更を追加していきます。
@Group("Building Shell")
@Range(min=0, max=100, stepsize=1)
attr building_height = rint(rand(10,100))
@StartRule
Footprint -->
extrude(building_height)
color(1,1,0)これらの変更によって、ランダムな建物の高さが building_height という属性に移されました。これにより、依然としてすべてのシェープに対して高さは生成されますが、[Inspector] ウィンドウでユーザーが操作できる属性として管理できるようになります。また、新たに乱数を最も近い整数に丸める rint という組み込み関数を追加しています。
@Group アノテーションは、[Inspector] ウィンドウに表示される属性の場所を整理するのに役立ちます。@Range アノテーションは、スライダーを制御するためのものです。建物の高さを属性にすることで、各シェープの高さを調整できるスライダーが利用可能になります。

建物をクリックすると、高さを調整してランダムに生成された数値を上書きできるようになります。また、スライダーは設定した範囲の最小値と最大値である 0 から 100 の間 だけ動くようになっています。
ハンドルの追加
ハンドルは、属性の機能を拡張し、シーン内で直感的かつインタラクティブに操作できるようにします。建物の高さを制御するハンドルをモデルに追加するために、@Handle アノテーション と Mass ルールを追加します。
@Group("Building Shell")
@Handle(shape=Mass, axis=y)
@Range(min=0, max=100, stepsize=1)
attr building_height = rint(rand(0,100))
@StartRule
Footprint -->
extrude(building_height)
color(1,1,0)
Massモデルを再生成することを忘れないでください (CTRL+G)。そうすると、建物にハンドルが表示され、高さ属性を調整できるようになります。

フロア分割の追加
ルールを段階的に変更していく流れの続きとして、建物を各フロアごとに 縦方向 (y 軸方向) に分割するコードを追加します。 新しい floor_height 属性で制御される分割処理を行う Mass ルール を作成します。なお、CityEngine のデフォルトの単位はメートルなので、以下のコードの 3.048 メートルは、コメント (# で表記) にもあるとおり 10 フィート であることを示しています。
@Group("Building Shell")
@Handle(shape=Mass, axis=y)
@Range(min=0, max=100, stepsize=1)
attr building_height = rint(rand(10,100))
@Range(min=1, max=25, stepsize=1)
attr floor_height = 3.048 # 10 feet
@StartRule
Footprint -->
extrude(building_height)
color(1,1,0)
Mass
Mass -->
split(y) { floor_height : Floor }*
建物の最上階のフロアの高さが他の階と異なっていることに気づいているかもしれません。これは、分割が下から開始され上方向に進むため、すべての分割の処理が終わった後に残ったものが最上階の高さになるためです。
この問題を修正する 1 つの方法は、floor_height の前にチルダ (~) を付けることです。これは CityEngine に浮動サイズを使用するよう指示するもので、ソフトウェアが自動的に分割を調整できるようにします。この方法では各フロアの高さが正確に 3.048 メートルになるわけではありませんが、すべてのフロアが均等な高さになり、余りの部分がなくなります。
Mass -->
split(y) { ~floor_height : Floor }*
用途別に着色する関数の構築
まず、@StartRule 内でフットプリントに色を割り当てている行をコメント アウトする必要があります。 シェープはルールごとに処理される中で複数回色を変更することもできますが、色は一度だけ設定するのが好ましいです。
次のようにコメントを追加して、#color(1,1,0) の行をコメント アウトします。
@StartRule
Footprint -->
extrude(building_height)
#color(1,1,0)
Mass関数は、ある処理を実行して値を返すために、再利用できるルーチンやコードのかたまりです。フロアを用途ごとに色付けするために、適切な色を呼び出すシンプルな関数を作成することができます。そのためには、各フロアの位置によって異なる用途を選択できるように、いくつかの属性を作成する必要があります。
@Group("Building Shell")
@Handle(shape=Mass, axis=y)
@Range(min=0, max=100, stepsize=1)
attr building_height = rint(rand(10,100))
@Range(min=1, max=25, stepsize=1)
attr floor_height = 3.048 # 10 feet
@Group("Land Use")
@Enum("Retail","Office","Multi-Family")
attr use_ground = "Retail"
@Enum("Retail","Office","Multi-Family")
attr use_upper = "Multi-Family"次に、属性と @StartRule の間に新しい関数を作成します。以下の関数は use パラメーター受け取り、ファサードに対して正しい色を返すよう評価します。もし use パラメーターが一致しない場合は、#FFFFFF (白) の色を返します。
getColor(use) = case use == "Retail" : "#FF6633"
case use == "Office" : "#6699FF"
case use == "Multi-Family" : "#A97C50"
else: "#FFFFFF"最後に、1 階と上層階を判定し、それぞれに対して関数を呼び出して色を設定することで、これまでの内容をまとめます。最上階を、ほかの上層階の分割部分と区別するために、分割を呼び出すたびに作成される split.index と split.total を使用します。これを行うために、コードを拡張して Floor ルール を追加します。
Floor ルールでは、まず case による条件分岐 を行います。split.index が 0 の場合は 1 階、それ以外の値の場合は上層階となります。階が判定された後、その階に応じて関数が呼び出され、床の色が設定されます。
Floor -->
case split.index == 0:
color(getColor(use_ground))
else:
color(getColor(use_upper))高さや土地利用の属性を工夫することで、より多様なトポロジーを実現できるようになりました。

定数の作成
定数を作成することで、計算に使用できる固定の数値を作成できるようになります。これは次のチュートリアルで扱うレポート機能などさまざまな場面で役立ちます。以下のコード行は、平方メートルから平方フィートを計算したり、建物の住戸数を計算したりするのにも役立ちます。ただし、定数はどんな用途に対しても使用でき、 コードの中のどこにでも置くことができます。とはいえ、定数をページの上部付近にまとめておくことを勧めます。なお、これらの定数は CityEngine のデフォルトのメートル法をアメリカのヤード・ポンド法に変換することに注意してください。
const unitScale = 0.3048 # convert meters to feet
const areaScale = 10.7639 # convert square meters to square feet
const acres = 43560 # there are 43,560 square feet in an acreレポートの追加
CityEngine は 3D モデルを生成することに加えて、ルール内で計算を実行し、それをレポートすることで有用なデータを取得することができます。これは、あなたが計画や開発を視覚化するだけでなく、数値レポートを生成することもできることを意味します。これにより、CityEngine はジオデザインの分野において強力なツールとなります。たとえば、延べ床面積 (GFA)、戸数、または土地利用構成などの数値を含めることができます。また、計画を変更した場合、モデルやシェープを含め、レポートは自動的に更新されます。 このルールを基に、いくつかのデータをレポートしてみます。最初は簡単に、床面積のみをレポートします。まず、Floor ルールを修正し、Plate と呼ばれるルールに続くようにします。Plate ルールでは、ジオメトリーをコンポーネント面に分解 (comp(f)) し、形状の底面を Reporting ルールに渡して、そのジオメトリーの面積を計算します。注意として、最初に底面を分割して取り出す必要があります。そうしないと、計算にすべてのシェープの表面積が含まれてしまうためです。
Floor -->
case split.index == 0:
color(getColor(use_ground))
Plate
else:
color(getColor(use_upper))
Plate
Plate -->
comp(f) { side : Wall | bottom : Reporting | top : Top }
Reporting -->
report("FloorArea", geometry.area)結果を確認するには、ルール ファイルを保存 (Ctrl+S) し、すべてのシェープを選択 (Ctrl+A) し、その後 Generate Models (Ctrl+G) をクリックします。
[Inspector] ウィンドウで [Report] セクション を展開します。

このことから、総階数は 117 階、総面積は 85,704.20 平方メートルであることがわかります。床面積を平方フィートに変換するには、geometry.area に areaScale 定数を掛けるだけで行えます。
Reporting -->
report("FloorArea", geometry.area * areaScale)
もし土地利用ごとの面積を知りたい場合や、密度や容積率といった、重要で一般的な都市計画の情報を知りたい場合には、ルールにいくつかの簡単な修正を加えて、土地利用情報をパラメーターとして渡すことができます。 Plate ルールに landUse パラメーターとして土地利用 (use_ground と use_upper) を渡すようにコードを修正すると、Reporting ルールに渡すことができるようになります。
Floor -->
case split.index == 0:
color(getColor(use_ground))
Plate (use_ground)
else:
color(getColor(use_upper))
Plate (use_upper)
Plate(landUse) -->
comp(f) { side : Wall | bottom : Reporting(landUse) | top : Top }
Reporting(landUse) -->
report("FloorArea." + landUse, geometry.area * areaScale)
容積率 (FAR) を計算するためには、土地の面積を報告または計算する必要があります。この計算を行うには、@StartRule として Footprint ルールに report オペレーションを追加します。
@StartRule
Footprint -->
report("LotArea", geometry.area * areaScale)
extrude(building_height)
#color(1,1,0)
Mass
ダッシュボードの追加
ダッシュボードは、CityEngine のレポートを拡張する素晴らしい方法です。ダッシュボードを使用すると、ルールから報告された任意の値を取得し、必要に応じて追加の計算を適用し、情報を棒グラフやチャートで表示することができます。
メイン メニューの [Window] → [Dashboard] をクリックします。

デフォルトでは、[Inspector] ウィンドウに [Dashboard] タブが表示されます。 [Add a Chart] ボタンをクリックしてウィンドウを開きます。[Pie Chart] を選択し、[Title] ボックスに Land Use と追加して、[FloorArea.*] を選択します。最後に [Add Card] をクリックし、[Dashboard] ウィンドウのキャンバスに配置して、カードを追加します。

別のカードを追加します。今回は [Key Number] を選択します。タイトルに「FAR」と名付け、レポートとして[FloorArea.*] を選択して LotArea で除算します。[Add Card] をクリックし、キャンバスに追加します。
最後のステップとして、画面上の建物の色に合わせて、チャートに色を追加することができます。これを行うには、Reporting ルールに 2 行目を追加します。これは、土地利用の色取得関数を呼び出し、チャートの属性として追加するものです。
Reporting(landUse) -->
report("FloorArea." + landUse, geometry.area * areaScale)
report("FloorArea." + landUse + "#color", getColor(landUse))
CityEngine を設計ツールとして使用した場合のダッシュボードの有用性を確認するため、建物を選択し、ハンドルで建物の高さを変更します。

ダッシュボードがリアルタイムに更新され、都市計画者やデザイナーが地域の要件や設計目標を満たすための計画を作成するのに役立ちます。
このチュートリアルでは、以下のことを学びました。
- 単純な 2D フットプリントから一連の建物を作成するルールを記述すること。
- ルール内で計算を実行し、貴重なデータを得るためにレポートすること。
- レポートの値をチャートやグラフで可視化するダッシュボードを作成すること。
また、他のエッセンシャル チュートリアルもご参照ください。
CityEngine の学習を続けるには、CityEngine チュートリアル をご参照ください。