要访问教程CityEngine中,单击 帮助>下载教程和例子…。选择教程或示例后,项目会自动下载并添加到您的工作区。

模拟一个简单的建筑

本教程介绍了 CityEngine 的 CGA 形状语法的基础知识。您将分析一个完成的规则​​文件,其中包含创建基本建筑的所有步骤。

GUID-1D604825-9396-45C5-914F-1477954BCBF6-web

 

教程设置

  1. 将 Tutorial_06_Basic_Shape_Grammar 项目导入 CityEngine 工作区。
  2. 打开Tutorial_06_Basic_Shape_Grammar/scenes/01_SimpleBuilding.cej场景。

简单的建筑

您将建造一座具有典型外观的简单建筑。此部分的结果将如下图所示:

GUID-6CA00FEB-ACEE-4214-935C-E5A5AAA3B7C5-web

 

    1. 在 3D 视口中选择批次(或模型,如果它已经生成),并在 Inspector 窗口中查看信息(如果它没有打开,点击Window > Inspector打开它)。
      GUID-425AD8F9-3F7B-4448-8178-483E69CE1DE1-web
在这里可以找到两个重要参数:

  • 规则文件 – 包含到rules/simpleBuilding.01.cga规则文件的链接。触发生成时执行此规则文件。
  • 开始规则 – 定义在规则文件中执行的第一个规则。在这种情况下,开始规则是 Lot。

  1. 通过单击检查器中的规则文件链接或双击 导航器中的rules/simpleBuilding.01.cga文件以在 CGA 编辑器中打开文件,打开 CGA 规则文件。

简单的建筑规则集

建筑属性

建筑物属性通常在规则文件的开头定义(尽管它们可以放在规则文件中的任何位置)。这些属性在整个规则集中使用,并出现在 Inspector 的 CGA 属性映射区域中,它们的值也可以在 CGA 语法编辑器之外设置和修改。

attr groundfloor_height	= 4
attr floor_height 		= 3.5
attr tile_width 		= 3
attr height 			= 11 
attr wallColor		= "#fefefe"

窗口资产

用于创建简单建筑的窗口资产在此处定义。实际资产是从导航器中项目的资产文件夹加载的。

// geometries
window_asset	 = "facades/window.obj"

批次规则

建筑的实际创建现在开始。第一条规则称为 Lot。记住检查器中分配的开始规则。质量模型是通过挤压操作创建的,如下所示:

Lot -->
    extrude(height) Building

建筑规则

通常在此步骤中,可以通过应用组件拆分将体量模型分成其外观。

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

此规则通过应用组件拆分将名为 Building 的形状(体量模型)拆分为其面。这导致了一个正面形状(通常是带有入口的主正面),几个侧面形状作为正面,以及一个屋顶形状。

现在可以对立面进行建模。典型的立面建模工作流程如下:首先,立面可以分解成楼层。接下来,地板被进一步分解为称为瓷砖的元素(地板细分)。瓷砖通常由墙壁和窗户元素组成。这种细分方案可以在 CGA 形状语法中实现如下:

GUID-F6D840F2-6C8C-4817-96AC-0BD946D095EE-web

 

FrontFacade 规则

FrontFacade 规则将正面拆分为高度为 4 的底层形状,并重复(使用重复运算符 [*])大约高度为 3.5 的上层形状。波浪号运算符 (~) 保证无论建筑物的实际高度如何,始终创建完整数量的上层。底层的外观往往与其他楼层不同,尤其是前立面。它们的不同不仅是因为入口的存在,而且通常还因为不同大小的楼层高度、窗户外观、颜色等。

FrontFacade -->
    split(y){ groundfloor_height : Groundfloor |
	{ ~floor_height: Floor }* }

SideFacade 规则

SideFacade 规则将侧立面拆分为地板形状。以相同的方式进行细分,以确保楼层高度与前立面同步。

SideFacade -->     
    split(y){ groundfloor_height: Floor | { ~floor_height: Floor }* }

楼层规则

地板规则是将地板细分为大约宽度为 3 的瓷砖的典型示例。为了使地板设计更有趣,您将在每一侧拆分宽度为 1 的墙元素。

Floor -->
    split(x){ 1: Wall 
            | { ~tile_width: Tile }* 
            | 1 : Wall }

底层规则

底层规则使用类似的细分分割细化底层形状,不同之处在于入口放置在右侧。下图首先描述了拉伸体量模型,然后描述了分解为下面的地板和瓷砖。

GUID-1957AC70-7D37-483F-9528-B5B906BBD94F-web
GUID-8867F114-19A3-4E37-AC99-0F68BD85F08F-web

 

Groundfloor -->
    split(x){ 1: Wall 
	    |{ ~tile_width: Tile }* 
	    | ~tilewidth: EntranceTile 
	    | 1: Wall }

平铺规则

在定义了初始立面结构后,可以对瓷砖进行建模。

Tile -->
    split(x){ ~1 : Wall
            |  2 : split(y){ ~1: Wall | 1.5: Window | ~1: Wall }
            | ~1 : Wall }

平铺规则通过沿 x 轴和 y 轴拆分(使用嵌套拆分)来定义平铺的外观。在此设计中,墙壁元素是浮动的(带有波浪号),并且窗口的宽度固定为 2,高度为 1.5。

EntranceTile规则

EntranceTile 规则以与瓷砖形状类似的方式定义入口形状(但显然,底部没有墙)。

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

窗、门和墙规则

最终规则用相应的资产替换窗户、门和墙壁形状的几何图形,定位它们并设置纹理。

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")

使用操作 t(x,y,z) 在 z 方向上平移当前形状 -0.25。通过这种方式,窗户和纹理被退回到立面 0.25 米处。接下来,插入操作 i(objectname) 将资产插入当前范围。如果尺寸设置与“窗”或“门”规则不同,则会自动调整尺寸——否则使用给定的尺寸。使用操作 s(x,y,z),可以在 Wall 规则中设置范围的大小。示波器的宽度和高度不受影响,因为使用了相对坐标:当前示波器的 x 和 y 维度按一 (‘1) 缩放,导致没有变化。z 尺寸设置为 -0.4,导致墙的厚度为 0.4 米(指向内)。

将所有这些规则放在一起,您将获得最终的无纹理简单建筑:

GUID-CDD92A02-481A-4745-8CC2-CAF9E246E6D5-web

 

在下一节中,您将学习如何为简单建筑添加纹理。

构造简单的建筑

在本节中,您将学习如何将纹理应用于简单建筑的窗户和墙壁元素。

教程设置

  1. 如果Tutorial_06_Basic_Shape_Grammar/scenes/01_SimpleBuilding.cej场景尚未打开,请打开它。
  2. 打开规则文件。使用您刚刚创建的规则,或在导航器中双击Tutorial_06_Basic_Shape_Grammar/rules/simpleBuilding.01.cga文件以打开 CGA 规则编辑器。

纹理声明

与资产一样,您将在规则文件的顶部定义将使用的纹理。纹理从资产文件夹加载。

    1. 将以下新行添加到 window_asset 声明下方的规则文件中。
// textures
frontdoor_tex   = "facades/textures/shopdoor.tif"
wall_tex        = "facades/textures/brickwall.jpg"
dirt_tex        = "facades/textures/dirtmap.15.tif"
roof_tex        = "roofs/roof.tif"
在项目的assets/facade文件夹中准备了九种不同的窗口纹理。步骤 2 中的函数没有将所有九个纹理名称列为单个资产,而是返回资产文件夹中的九个窗口纹理之一。
    1. 将以下行添加到规则文件中:
randomWindowTexture = fileRandom("facades/textures/window.*.tif")
    1. 将 setupProjection() 命令添加到 Frontfacade 和 Sidefacade 规则中:
Frontfacade -->
	setupProjection(0, scope.xy, 1.5, 1, 1) 
	setupProjection(2, scope.xy, scope.sx, scope.sy)
	split(y){ groundfloor_height : Groundfloor | { ~floor_height: Floor }* }

Sidefacade -->
	setupProjection(0, scope.xy, 1.5, 1, 1) 
	setupProjection(2, scope.xy, scope.sx, scope.sy)  
	split(y){ groundfloor_height: Floor | { ~floor_height: Floor }* }
setupProjection() 命令为颜色(通道 0)和污垢贴图(通道 2)准备立面上的 UV 坐标投影,投影到示波器的 xy 平面上;因此,scope.xy 被设置为第二个参数。
砖纹理(通道 0)将在 X 轴上每 1.5m 重复一次,在 Y 轴上每 1m 重复一次,而污垢贴图(通道 2)将跨越整个立面并使用 scope.sx 和 scope.sy 作为大小参数。
    1. 添加新的屋顶规则。
Roof --> 
	setupProjection(0, scope.xy, scope.sx, scope.sy)	
	texture(roof_tex)
	projectUV(0)
屋顶规则准备 UV 坐标以覆盖整个屋顶面,设置屋顶纹理,并将纹理坐标应用于几何体。
    1. 将 texture() 命令添加到后续规则中。
Window -->
	s('1,'1,0.4)
	t(0,0,-0.25)
	texture(randomWindowTexture)
	i(window_asset)  

Door -->
	s('1,'1,0.1)
	t(0,0,-0.5)
	texture(frontdoor_tex)  
	i("builtin:cube")
对于窗户和门元素,您只需将颜色图设置为所需的纹理。对于窗口,使用带有随机索引的 getWindowTex() 函数来获取九个窗口纹理之一。
    1. Wall 和 SolidWall 使用 Facade 规则中准备的 UV。除了为颜色和污垢通道选择纹理之外,您还需要在这两个通道上投影 UV。
Wall -->
	color(wallColor)
	texture(wall_tex)  
	set(material.dirtmap, dirt_tex)
	projectUV(0) projectUV(2)

SolidWall -->
	color(wallColor)
	s('1,'1,0.4) 
	t(0,0,-0.4) 
	texture(wall_tex)  
	set(material.dirtmap, dirt_tex)
	i("builtin:cube:notex")	
	projectUV(0) projectUV(2)
下图显示了最终的建筑模型:

GUID-5D082634-56C1-48A6-8ECA-60EF65894E41-web
同一型号的特写视图:

GUID-140D68F1-C2DF-40A4-AA07-E40AA6F93918-web
下图显示了应用于任意质量模型的规则集:

GUID-BEABFDA8-A67A-40BA-80B5-660AF0A7326B-web

添加详细级别

在本节中,您将为简单的建筑添加一个简单的细节级别 (LOD) 机制。您将降低模型的复杂性(多边形数量),这在创建更大面积的简单建筑物时很有帮助。

教程设置

  1. 如果Tutorial_06_Basic_Shape_Grammar/scenes/02_SimpleBuilding.cej场景尚未打开,请打开它。
  2. 打开规则文件。使用您刚刚创建的规则,或在导航器中双击Tutorial_06_Basic_Shape_Grammar/rules/simpleBuilding.02.cga文件以打开 CGA 规则编辑器。

添加详细级别属性

将新属性 LOD 添加到 .cga 文件中的现有属性。

attr LOD = 1

在此示例中,您将定义以下两个详细级别:

  • LOD 0——低细节,低复杂度
  • LOD 1——高细节、高复杂度

您已经建模的简单建筑将成为您的高分辨率模型。您现在将通过几个步骤创建低分辨率版本。

检查您当前的模型,您会发现您可以主要在窗口资产上保存多边形。您将使用带纹理的平面而不是复杂的窗口资源。

    1. 到窗口规则,添加行情况LOD> 0: 在开始和行 的质地(randomWindowTexture其他参数看起来应该如下:
Window -->
	case LOD > 0 : 
	  s('1,'1,0.4)
	  t(0,0,-0.25)
	  texture(randomWindowTexture)
	  i(window_asset)  
	else :		
	  setupProjection(0,scope.xy,scope.sx,scope.sy)	
	  texture(randomWindowTexture)	
	  projectUV(0)
您向窗口规则添加了一个条件:如果 LOD 值大于 0(您的高分辨率),则使用旧的高分辨率窗口资源。否则(LOD 为零),不加载窗口资源,而是使用来自立面的简单平面。
    1. 与门规则类似:加载一个简单的平面而不是一个立方体。
Door -->
	case LOD > 0 :
  s('1,'1,0.1)
	 t(0,0,-0.5)
  texture(frontdoor_tex)
   i("builtin:cube")
	else :
	 setupProjection(0,scope.xy,scope.sx,scope.sy)	
	 texture(frontdoor_tex) 
	 projectUV(0)
    1. 现在是 SolidWall 元素。因为您移除了门的插图,所以您不再需要实体元素。
SolidWall -->
	case LOD > 0 :
	    color(wallColor)
	    s('1,'1,0.4) 
	    t(0,0,-0.4) 
	    texture(wall_tex)  
	    set(material.dirtmap, dirt_tex)
	    i("builtin:cube:notex")	
	    projectUV(0) projectUV(2)
    else :
	    Wall
    1. 选择建筑物后,查看 Inspector 的属性字段。此处列出了新的 LOD 属性。将值更改为 0。
源字段从规则更改为值。这意味着在建筑物的下一代中,规则文件中的 LOD 值将由 Inspector 中的值 0 设置。
以下屏幕截图显示了 Inspector 中 LOD = 0 的新 LOD 属性:

GUID-787E9E5F-C08E-4F2D-A6A6-3019154352EA-web
    1. 生成建筑物以获得下图所示的低级别版本,LOD = 0:
      GUID-D2A3D8FB-8E92-48DC-87FD-742457669FA4-web
    2. 在着色(按6)和无纹理(按5)上显示带有线框的模型,差异清晰可见。按dd在包含多边形计数的视口顶部显示抬头显示。模型从 3699 个多边形减少到 475 个。
      GUID-BA285B10-1C92-420B-8019-DDA0B9C729AA-web
在下一部分中,您将为简单的建筑物添加随机变化。

建筑属性随机变化

本节展示了如何通过定义随机属性为生成的建筑物添加变化。

教程设置

  1. 如果Tutorial_06_Basic_Shape_Grammar/scenes/03_SimpleBuilding.cej场景尚未打开,请打开它。
  2. 打开规则文件。使用您刚刚创建的规则,或在导航器中双击Tutorial_06_Basic_Shape_Grammar/rules/simpleBuilding.03.cga文件以打开 CGA 规则编辑器。

添加随机属性

    1. 您将为建筑的三个属性添加变化:2.5 到 6 米之间的随机瓷砖宽度,8 到 35 米之间的随机建筑高度,以及为每个建筑随机选择的三种颜色。
attr tile_width	= rand(2.5, 6)
attr height		= rand(8, 35) 
attr wallColor	= 33%  :  "#ffffff"
                  	  33%  :  "#999999"
                      else :  "#444444"
    1. 由于您将生成大量建筑物,请将默认 LOD 值从 1 更改为 0。
attr LOD = 0
  1. 选择Lots 2 图层。
  2. 通过单击“形状” >“生成”来生成建筑物 。
    GUID-AC47ED7E-7B9A-49B9-AAA1-9572F8BB677B-web
    GUID-71581E6D-635E-40ED-BCD6-A2E63310BA97-web