CityEngine建模示例教程6:Basic Shape Grammar之Part 1:簡單建築物


    本着從示例中學習使用規則建模的目的,學習一下CityEngine中的教程。前幾個教程是熟悉軟件以及如何使用規則的,第六個教程是開始使用規則建模,並給建築物貼紋理的。因此一邊學習教程6中的步驟,一邊查看其中創建規則的CGA具體語法,希望我們都能從教程中有很多收獲。前提要了解如何創建規則和應用規則。

    本次學習的教程為Tutorial_06_Basic_Shape_Grammar__2011_1,其中包含四部分,分別為:1.構建簡單建築物;2.為簡單建築物貼紋理;3.添加LOD;4.建築物屬性隨機變化。本節學習該教程中的第一部分。

    本節學習最終要構建一個如下圖的建築物,該建築物有地面一樓和其他樓層,一樓的正面有一個入口的門,其他窗口都使用的是一個提前做好的OBJ模型。

     

                 

    下面開始創建規則進行建模:

    為了更好的理解規則,我們自己創建一個新的規則,按照教程中的語句進行規則的書寫。

1.    在規則文件的最開始處定義建築的屬性(也可以放在規則文件的其他位置)。在CGA文件中,這些屬性將對整個規則文件產生作用。這些屬性將顯示在屬性查看器(Inspector)中,可通過屬性查看器修改這些屬性。

attr groundfloor_height     = 4          //地面一樓的高度

attr floor_height           = 3.5        //其他樓層的高度

attr tile_width          = 3         //將樓面按塊划分的寬度

attr height                               = 11      //樓高

attr wallColor              = "#fefefe"     //牆面顏色

 

2.    教程中構建的窗戶是使用的一個已經建好的窗戶模型window.obj,這個文件存放在assets文件夾中,使用之前也要先定義出來。

window_asset = "facades/window.obj"     //指定obj文件

 

3.    下面我們定義第一條規則為Lot. 在屬性檢查器中,該規則被指定為開始規則。大量的模型是使用拉伸操作創建而來的:

//對shape使用height中定義的高度進行拉伸,並命名為Building
Lot -->
   extrude(height) Building    

拉伸之后如下圖:

   

4.    可以通過應用comp()將Building分解為多個面, 生成了正面(FrontFacade)、多個側面(SideFacade)和一個頂面(Roof)

Building-->
  comp(f){ front : FrontFacade | side : SideFacade | top: Roof}

5.    分解完成之后,就開始開始對這些面進行外觀造型。典型的外觀造型流程如下:1,將面分解為樓層Floors)。2,將樓層分解為Tile),每一塊通常由牆面和窗口構成。這樣的細分過程在CGA要素語法的實現過程如下圖:

 

//下面的FrontFacade規則將正面沿y軸方向,分割為兩大部分,第一部分高度為groundfloor_height的地面一層Groundfloor,剩余的以floor_height高度進行重復分割(以*符號標記),分割為多個Floor。
FrontFacade --> split(y){ groundfloor_height : Groundfloor | { ~floor_height: Floor }* }

 

正面分割之后如下圖:

 

6.     細分側面:
SideFacade -->     
 split(y){ groundfloor_height: Floor | { ~floor_height: Floor }* }
  SideFacade規則將側面沿y軸方向分割也分為兩大部分,這兩部分使用的都是是相同的Floor對象,因此側面這兩大部分看起來都應該是一樣的。只有高度不一樣,高度不一樣主要是為了與正前面的樓層高度保持一致。

側面分割之后如下圖,三個側面都是一致的:

 7.     繼續對Floor對象進行細化:

//先給每層樓在x軸方向的兩端畫出寬度為1的牆面(Wall),剩余的部分以tile_width為寬度重復分割(Tile)
Floor --> split(x){ 1: Wall | { ~tile_width: Tile }* | 1 : Wall }

如下圖:

 

8.     最后對正面的地面一樓進行細化:

//同樣先在x軸方向的兩端畫出寬度為1的牆面(Wall),按照tile_width划分為多個Tile,並按照tile_width划分出一個入口EntranceTile。
Groundfloor -->split(x){ 1: Wall                
|{ ~tile_width: Tile }*
| ~ tile_width: EntranceTile | 1: Wall }

結果如下圖:

 

9.     下面對Tile進行定義:

//先對Tile在x軸方向中間划分出寬度為2的一部分(對這部分再按y軸方向先划分一個高度為分別為1和1.5的wall和window,剩余的高度也定為wall),然后兩邊分別划分為寬度大概為1的wall
Tile -->
split(x){ ~1 : Wall
| 2 : split(y){ 1: Wall | 1.5: Window | ~1: Wall }
| ~1 : Wall }

結果如下:

 

10.  EntranceTile進行定義:

EntranceTile -->    
split(x){ ~1 : SolidWall
| 2 : split(y){ 2.5: Door | ~2: SolidWall }
| ~1 : SolidWall }

先對入口在x軸方向划分寬度為2的一部分(這部分在y軸方向先划分2.5高度的Door,剩余的大約高度2定為SolidWall.),然后兩邊各為大約1米的Solidwall。

 

11.  最后對前面定義的WindowDoorWallSolidWall寫具體的規則。

Window -->
s('1,'1,0.4)
t(0,0,-0.25)
i(window_asset)
Door -->
s('1,'1,0.1)
t(0,0,-0.5)
i("builtin:cube")
Wall -->
color(wallColor)

SolidWall -->
color(wallColor)
s('1,'1,0.4)
t(0,0,-0.4)
i("builtin:cube:notex")

這里解釋一下上面出現的幾個命令:

    s('1,'1,0.4)

命令:s(float xSize, float ySize, float zSize)

作用設置形狀的尺寸。

eg1:   s(5,5,5)   表示將三個方向的值設為絕對值5

eg2:   s('0.5,'1,'1.5)  等同於  s(0.5*scope.sx,scope.sy,1.5*scope.sz),如果加上'符號,括號內的值在0-1之間,表示設置xyz的值為原先的多少倍。

   ②t(0,0,-0.25)

平移:t(tx, ty, tz)

   ③i(window_asset)或者i("builtin:cube:notex")

對象替換:i(geometryPath)

CityEngine有內置的素材可以直接使用,分為Geometry Assets和Textures。

Geometry Assets

       builtin:cube—有節點的單位立方體,帶有紋理圖層的紋理坐標系

       builtin:cube:notex—單位立方體,不帶有紋理坐標系

Textures:

       builtin:default—表示16×16黑白方格相間的紋理

       builtin:uvtest.png—使用CE標准的測試紋理

最終效果:

 

到此我們完成了簡單建築物的構建,學習了構建流程,如何拉伸、分解面、分割Tile等。規則可以一步步嘗試,也可以替換成其他顏色或將obj替換為其他模型。如下圖:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM