チュートリアル データは、[Help] メニュー → [Download Tutorials and Examples…] を選択し、[CityEngine Tutorial] からダウンロードできます。
このチュートリアルでは、建物のファサード イメージを解析し、ファサード コンポーネントを CGA に変換する方法を学習します。以下の実世界の画像から建物を再作成するための CGA ルールのセットを作成する方法を学習します。
演習 |
---|
・Part 1: 建物の探索 |
・Part 2: ファサードのレイアウトを定義 |
・Part 3: CGA で建物ボリュームを作成 |
・Part 4: フロアの追加 |
・Part 5: タイルの追加 |
・Part 6: 窓の追加 |
・Part 7: 材質の追加 |
・Part 8: 詳細の追加 |
・Part 9: スタイルの追加 |
・Part 10: キャンドラー ビルディング |
・Part 11: パルテノン神殿 |
この例では、タイルと窓のレイアウトが複雑なパターンになっていることに気づきます。また、建物を作成するために、入れ子式の繰り返し分割やパラメーターの受け渡しなど、いくつかの高度な CGA メカニズムが使用されています。
CGA シェープ グラマーの詳細については、Rule-based modeling tutorial、および Rule-based modeling と CGA modeling ヘルプ トピックを参照してください。
まず、上記のファサード イメージの CGA バージョンでシーンを開き、以下の手順を実行します。
新しい CGA ルールを計画するときは、ルールの作成を始める前に、大まかなレイアウトをスケッチし、いくつかのシェープ名の定義を行うと便利です。
まず、ファサードを解析すると、ファサードが主に最上階 (Top Floor)、地上階 (Ground Floor)、中間階 (Upper Floor) の 3 つのフロア タイプで構成されていることがわかります。下層階は窓を含むタイルでできていますが、最上階には窓要素のみが含まれています。その他の下層階は全て同じため、特定の階の正しい外観 (タイルと窓の配置) を作成するために、インデックス (FloorIndex) パラメーターを Floor シェープとともに渡します。タイルのパターンのため、2 つの Tile シェープを含む中間 DoubleTile シェープを定義します。これは、フロア パターンをエンコードした後で役に立ちます。
次に、タイル内の詳細なサブ シェープを定義します。これは、MilkGlass (すりガラス) シェープと Window シェープという 2 つの主要な部分で構成されます。Window シェープには、上部の Blind と埋め込まれた Subwindow (小窓) シェープが含まれています。これらの要素の位置はタイルの水平方向の位置に依存します。サブ シェープ構造を正しく配置できるようにするために、この位置インデックス (tileIndex) を Tile シェープのパラメーターとして保存する必要があります。
ファサード レイアウトを定義したので、CGA で建物の作成を開始できます。
最初のステップとして、新しいルールを作成し、ルール ファイルの先頭に属性を定義していきます。これらの属性はルール セット全体で使用され、[Inspector] ウィンドウを使用して属性とパラメーターを調整することで、シーン内に変更できます。ルールの作成を開始するには、以下の手順を実行します。
// User Attribute
@Group("Building", 1) @Range(min=5, max=40, restricted=false) @Distance
attr buildingH = 27 // building height
@Group("Facade", 2) @Range(min=3, max=6, restricted=false) @Distance
attr floorH = 3.5 // floor height
@Range(min=3, max=6, restricted=false) @Distance
attr groundfloorH = floorH+1 // groundfloor height
@Range(min=1, max=4, stepsize=1, restricted=false)
attr nSymmetries = 2
@Range(min=0.1, max=1, restricted=false) @Distance
attr borderwallW = 0.3 // width of border wall stripe
@Range(min=0.1, max=0.8, restricted=false) @Distance
attr ledgeH = 0.3 // ledge height
@Group("Window",3) @Range(min=1, max=5, restricted=false) @Distance
attr windowW = 2.5 // window width
@Range(min=1, max=5, restricted=false) @Distance
attr milkGlassW = windowW/2 // milkglass blend width
@Range(min=0.1, max=2.5, restricted=false) @Distance
attr blindH = 0.8 // blind height
@Range(min=0.01, max=0.5, restricted=false) @Distance
attr frameW = 0.07 // frame width
@Group("Balcony",4) @Range(min=3, max=6, restricted=false) @Distance
attr balconyDepth = 2
@Group("Colors",5)
@Color
attr brightblue = "#86b1c7"
@Color
attr darkblue = "#33556c"
@Color
attr red = "#5c3f40"
@Color
attr grey ="#6b7785"
@Color
attr white = "#ffffff"
@StartRule
Lot --> BuildingVolume
tileW = windowW + milkGlassW // total tile width
const barDiameter = 0.04
// assets
const cyl_v = "primitives/cylinder.vert.8.notop.tex.obj"
const cyl_h = "primitives/cylinder.hor.8.notop.tex.obj"
const window_tex = "facade/windows/1_glass_2_blue.tif"
const milkGlass_tex = "facade/windows/blend_tex.png"
これから実際の建物の作成が始まります。建物を押し出すために、以下の手順を実行します。
BuildingVolume -->
extrude(buildingH)
split(y) { ~1 : MainPart
| floorH : UpperPart }
UpperPart -->
split(z) { ~1 : TopFloor
| balconyDepth : Balcony }
MainPart -->
comp(f) { front : Facade
| side : Wall
| top : Roof. }
TopFloor -->
comp(f) { front : Floor(-1)
| side : Wall
| top : Roof. }
Balcony -->
s(scope.sx-2*borderwallW, 1.1, scope.sz-borderwallW)
center(x)
comp(f) { front : Railing
| left : Railing
| right : Railing }
バルコニーの寸法が決まりました。次に、建物に手すりを追加します。
ルール ファイルを保存します。
[3D View] で建物が選択されていることを確認します。
Generate models of selected shapes (Ctrl + G キー) クリックして建物を生成します。
正面ファサードをさらに細分化するには、以下の手順を実行します。
Facade -->
split(y) { ~groundfloorH : Floor( split.index )
| { ~floorH : Floor( split.index ) }* }
最初の分割では、繰り返し分割 {…} * を使用して、ファサードを地上階部分と上層階に再分割します。~groundfloorH のように、分割サイズの高さの前にチルダ記号 (~) を使用すると、高さを柔軟に変更でき、ファサードに穴がなくてもフロアを一致させることができます。split.index (フロア インデックスを表す) をパラメーターとして渡すことで、後で特定のフロア フィーチャをトリガーできます。
Floor(floorIndex) -->
split(x) { borderwallW : Wall
| ~1 : FloorSub(floorIndex)
| borderwallW : Wall }
FloorSub(floorIndex) -->
case floorIndex == 0:
split(y) { 1 : Wall
| ~1 : TileRow(floorIndex)
| ledgeH : Wall }
case floorIndex > 0:
split(y) { ~1 : TileRow(floorIndex)
| ledgeH : Ledge }
else:
TileRow(floorIndex)
次に、フロアをタイル分割します。最上階は特別なパターンはなく窓要素が繰り返されているだけです。これらのタイルを後で指定するには、タイルに -1 パラメーターを設定します。
TileRow(floorIndex) -->
case floorIndex == -1:
split(x) { ~windowW : Tile(-1) }*
else:
split(x) { ~tileW*nSymmetries : DoubleTile(floorIndex, split.index) }*
後の手順で窓要素を正しく配置するために、パラメーターとして渡すフロア インデックスとタイル インデックス (split.index) が必要になります。
フロア インデックスとタイル インデックスの組み合わせによって、Double Tile 内の窓の配置が決まります。
DoubleTile(floorIndex, tileIndex) -->
case tileIndex%2 + floorIndex%2 == 1:
split(x) { ~milkGlassW : MilkGlass
| ~windowW : Tile(tileIndex) }*
else:
split(x) { ~windowW : Tile(tileIndex)
| ~milkGlassW : MilkGlass }*
フロアとタイルインデックスの組み合わせが Double Tile 内の窓の配置を決定します。
Tile(tileIndex) -->
setupProjection(0, scope.xy, scope.sx, scope.sy)
split(x) { frameW : Frame Bracing
| ~1 : split(y) { frameW : Frame
| ~1 : Window(tileIndex)
| frameW : Frame
| blindH : Blind
| frameW : Frame }
| frameW : Frame Bracing }
次に、Tile シェープ全体を水平方向に窓枠と中央部分に分割します。 中央部分が再び垂直に分割され、枠、窓、枠、ブラインド、およびフレームのコンポーネントに分割されます。
建物に窓を追加するために、以下の手順を実行します。
Window(tileIndex) -->
case tileIndex%nSymmetries >= 1:
split(x) { ~1 : Subwindow("right")
| frameW : Frame
| ~1 : Glass }
case tileIndex%nSymmetries >= 0:
split(x) { ~1 : Glass
| frameW : Frame
| ~1 : Subwindow("left") }
else:
split(x) { ~1 : Glass
| frameW : Frame
| ~1 : Glass }
Subwindow(align) -->
case align == "left":
split(x) { ~3 : RedWindow
| ~2 : Glass }
else:
split(x) { ~2 : Glass
| ~3 : RedWindow }
RedWindow -->
split(x) { frameW : RedFrame
| ~1 : split(y) { frameW : RedFrame
| ~1 : RedGlass
| frameW : RedFrame }
| frameW : RedFrame }
RedGlass -->
split(y) { ~1 : Glass
| frameW/2 : t(0,0,-frameW) Frame
| ~1 : t(0,0,-frameW) Glass }
建物に色とテクスチャを適用するには、以下の手順を実行します。
Wall -->
color(darkblue)
Blind -->
color(grey)
Frame -->
extrude(frameW)
color(white)
RedFrame -->
t(0, 0, -frameW)
extrude(frameW*4)
color(red)
Glass -->
projectUV(0)
texture(window_tex)
color(white)
set(material.specular.r, 0.4)
set(material.specular.g, 0.4)
set(material.specular.b, 0.4)
set(material.shininess, 4)
set(material.reflectivity, 0.3)
MilkGlass -->
s('1, '1, frameW*1.2)
primitiveCube
color(brightblue)
setupProjection(0, scope.xy, scope.sx, scope.sy, 0, 0, 0)
texture(milkGlass_tex)
projectUV(0)
set(material.specular.r, 0.7)
set(material.specular.g, 0.7)
set(material.specular.b, 0.7)
set(material.shininess, 20)
set(material.reflectivity, 0.05)
最後に要素に詳細を追加するには、以下の手順を実行します。
Ledge -->
Wall
[ s('1, '0.9, 0.2) primitiveCube Wall ]
t(0, -0.1, 0.2)
s('1, scope.sy+0.1, 0.03)
primitiveCube
Wall
Railing -->
[ t(0,scope.sy-barDiameter/2,0) HBar ]
set(trim.vertical, false)
split(x) { ~tileW/3 : VBar }*
水平バーは、手すりの水平部分を作成するために挿入します。垂直トリミングを無効にすると、垂直コーナーのバーがカットされるのを防ぎます。
VBar -->
s(barDiameter, '1, barDiameter)
t(0, 0, -barDiameter)
i(cyl_v)
color(white)
HBar -->
s('1, barDiameter, barDiameter)
t(0, 0, -barDiameter)
i(cyl_h)
color(white)
Bracing -->
s(barDiameter, '1, 0.15)
center(x)
primitiveCube
split(y) { 0.01 : Wall
| ~1 : t(0, 0, 0.15) VBar
| 0.01 : Wall }
最終的なモデルには、レッジ、窓のブレース、手すりなどの詳細要素が追加され表示されます。 最終モデルが完成したので、様々な lot シェープにルールを適用するか、[Inspector] ウィンドウでユーザー属性を試してファサード デザインを変更します。
スタイル キーワードを使用して、一部の属性を再定義する新しいスタイルを定義できます。
@Description("A Variation in Red")
style Red_Color_Theme
attr brightblue = "#FF8080"
attr darkblue = "#D20000"
attr grey = "#ECCACA"
attr red = "#361B1B"
Red_Color_Theme スタイルが適用されました。
最終的なルールファイルを確認するには、complexpatterns_01.cga ルールを開きます。
キャンドラー ビルディングは、CGA がどのようにしてリアルな建物をプロシージャルに作成できるかを示す良い例です。CGA を調べるには、以下の手順を実行します。
最後に、パルテノン神殿を探索するために、以下の手順を実行します。
このチュートリアルでは、以下の方法を学習しました。