CGA建模教程——形状语法(建筑群)

本教程是使用CityEngine的CGA进行建筑建模的进阶教程。
原文链接:http://desktop.arcgis.com/en/cityengine/latest/tutorials/tutorial-8-mass-modeling.htm

资源下载:
初始数据
PDF教程

1、L型和U型建筑

本教程介绍使用CGA形状语法构建大量建筑群,以L型和U型建筑为例。
这里写图片描述

步骤

  1. 导入工程** Tutorial_08_Mass_Modeling**。
  2. 打开场景文件** MassModeling_01.cej ** 。

建立规则文件

  1. 在‘rule’文件夹下新建一个规则文件。
  2. 确保‘container’ 被正确设置为 (Tutorial_08_Mass_Modeling/rules),将规则文件命名为myMass_01.cga.
  3. 确认后,新的CGA文件被创建,CGA编辑器打开。

L型建筑

下面从一个L形状开始。

attr height = rand(30, 60)
attr wingWidth = rand(10, 20)

Lot --> LShape

LShape -->
    shapeL(wingWidth, wingWidth) { shape : LFootprint }

LFootprint --> extrude(height) Mass

LotInner --> OpenSpace

shapeL命令创建了一个平面的L形状,大小是10到20之间随机数。
LFootprint规则将L-shape 挤出高度height。
LotInner规则定义L形状的开放空间部分(缺口部分)。
脚本中的属性可以定义一些可选选项,如@Group、@Range等,用来控制这些属性在属性面板中的显示方式。在CGA参考文档中可以查阅更多CGA annotations相关信息。

现在可以给所有的lots应用规则了。

  1. 在场景管理器中选择Lots层(或者选中某个Block)。
  2. 点击菜单Shapes > Assign Rule File(也可在Block上点右键菜单找到该操作)。
  3. 选择myMass_01.cga规则文件,点击OK。

下面可以构建建筑了。

  1. 选中要构建建筑的lots。
  2. 点击菜单Shapes > Generate 或者直接快捷键Ctrl+G构建建筑。

在这里插入图片描述
在这里插入图片描述

大量的L-shaped建筑生成成功了。然而,他们看上去太死板,你需要对他们做更多的多样化。

多样化L shape

现在的 L shape建筑被定义在lot的左下角(即:缺口总是在右上角)。使用旋转操作可以改变建筑的朝向,从而增加多样化。

在规则文件中使用概率操作符 %,使其有一定的概率进行旋转。

LShape -->
    50% : shapeL(wingWidth, wingWidth) { shape : LFootprint }
    else : rotateScope(0, 90, 0) 
    			shapeL(wingWidth, wingWidth) { shape : LFootprint }

进一步,使用convexify命令完成凸包分解。即将L建筑分成2个子建筑,并独立设置两个部分的高度。同样的,我们使用概率操作来控制该规则。

LFootprint -->
    75% : extrude(height) Mass
    else : convexify comp(f) { 0 : extrude(height) Mass | 
    			all : extrude(height * 0.7) Mass }

此时已经拥有了旋转效果,且分割后的L建筑也有了不同的高度。下面我们需要跟多的形状。
此时已经拥有了旋转效果,且分割后的L建筑也有了不同的高度。下面我们需要跟多的形状。

U shape

下面开始创建U shape规则。在调用的时候注意把起始规则修改为UShape。

attr height = rand(30, 60)
attr wingWidth = rand(10, 20)

// LShape部分省略...

Lot --> UShape
UShape -->
    shapeU(wingWidth, wingWidth * 0.7, wingWidth * 0.7) 
    		{ shape : UFootprint }

UFootprint --> extrude(height) Mass

同样引入变化,将UShape规则修改为:

UShape -->
    80% : rotateScope(0, 180, 0) shapeU(wingWidth, wingWidth * 0.7, 
    		wingWidth * 0.7) { shape : UFootprint }
    else:  shapeU(wingWidth, wingWidth * 0.7, wingWidth * 0.7) 
    		{ shape : UFootprint }

在这里插入图片描述
很明显, U shapes在某些lot上面效果不好。接下来我们来修复这个问题。

L、 U shapes混合

建筑高度的分布并不合理。要更好的控制建筑高度,你需要一个条件属性,即只有很大的lot才允许创建很高的建筑。

attr height = 
    case geometry.area < 1000: rand(20, 50)
    else: rand(50, 150)

增加新的规则LUShapes来控制创建L shape还是U shape。

当lot的宽度比深度大的时候,更加适合创建U shapes——对应CGA中当scope.sx大于scope.sz的情况。其他情况我们创建L shapes。

Lot --> LUShapes
LUShapes -->
    case scope.sx > scope.sz : 
        60%  : UShape
        else : LShape
    else: LShape

无论L 还是 U shapes都不能很好的在非矩形lots上创建。因此,我们增加一个条件,保证lot近似矩形时才执行LUShapes规则 (可以有15度的误差)。否则,我们调用新的规则BasicFootprint,这个规则执行简单的挤出操作。

LUShapes -->
    case geometry.isRectangular(15):
        case scope.sx > scope.sz : 
            60%  :UShape
            else : LShape
        else: LShape
    else: BasicFootprint

简答的挤出不规则lot,在视觉上效果不太好——因为看上去太大了。因此,我们做一点修改,将其稍微缩小一点,即使用一个负数做offset偏移操作。这样的结果还可以保证建筑之间有一定的空间,不至于紧密的贴在一起。

BasicFootprint --> offset(-5,inside) extrude(height) Mass

在这里插入图片描述
下一节你将学习如何使用递归的方法来生成大量建筑。

2、递归生成大量建筑

步骤

本小节使用递归方法来生成重复的建筑元素。导入工程**MassModeling_01.cej **。

建立规则文件

  1. 在‘rule’文件夹下新建一个规则文件。
  2. 确保‘container’ 被正确设置为 (Tutorial_08_Mass_Modeling/rules),将规则文件命名为myMass_02.cga.
  3. 确认后,新的CGA文件被创建,CGA编辑器打开。

塔型

height属性定义的建筑的随机高度,起始规则调用Envelope来挤出塔身,Envelope规则是一个递归规则。

height = 
    case geometry.area > 1000: rand(50, 200) 
    else: rand(20, 50)

Lot --> Tower

Tower --> extrude(height) Envelope
	
Envelope --> RecursiveSetbacks

接下来的递归规则中,你需要2个变量: lowHeight,scale。
后者是个常量,因此需要定义为属性。

// 在两个值之间随机切换
lowHeight 	= 50%: 0.4 else: 0.6

// 常量
attr scale 	= rand(0.75, 0.9)

RecursiveSetbacks规则将高于2层的建筑进行切分。

如果形状RecursiveSetbacks低于2层楼高,则将其缩放为高度height,建立名为Mass 的形状。

attr floorheight = rand(4, 5) // 一层楼的高度(注意是绝对高度)

RecursiveSetbacks -->
    case scope.sy > 2 * floorheight  :// 下部比例高度固定,上部递归
        split(y){ 'lowHeight : Mass | ~1: Setback }
    else: 
        s('1, floorheight, '1) Mass // 最终顶楼的高度为一层楼

Setback规则缩放并居中形状,然后递归调用RecursiveSetbacks规则。

Setback -->
    s('scale, '1, 'scale) center(xz) RecursiveSetbacks

将规则应用于Block,可见效果如下:
在这里插入图片描述

圆形

使用一个外部的圆柱体,可以创建屋顶为圆柱形的塔。修改塔规则:

Tower --> extrude(height) Envelope

Envelope -->
    case geometry.isRectangular(20):
        20% : i("cyl.obj") RecursiveSetbacks	
        else: RecursiveSetbacks
    else: RecursiveSetbacks

这样,20%的概率下,塔会使用圆柱来替换原有的立方体。
在这里插入图片描述

下一节你将学会使用setbacks来修改大量建筑。

3、使用setbacks修改建筑群

步骤

本小节使用setbacks修改建筑群。(译者注:setbacks是一种类似前文所述进行offset偏移的操作。区别在于setbacks仅对多边形特定的边进行操作。)
导入工程**MassModeling_01.cej **。

建立规则文件

  1. 在‘rule’文件夹下新建一个规则文件。
  2. 确保‘container’ 被正确设置为 (Tutorial_08_Mass_Modeling/rules),将规则文件命名为myMass_03.cga.

街道SetBack

Parcel(译者注:不好翻译,指建筑群内的绿化带之类的土地区域。)规则将对lots所在多边形执行setback向内偏移操作 。偏移完成后,移动形成的靠近街道的部分生成Parcel,而其余部分挤出成建筑物部分。
(译者注:每指定一组参数执行一次setbacks,则多边形向内缩进形成新的多边形。一定要理解不同参数导致生成的不同多边形的位置和意义。如下图所示:)
在这里插入图片描述
在这里插入图片描述

attr height = 
    case geometry.area > 1000: rand(50, 200) 
    else: rand(20, 50)

attr distanceStreet = 
    20%: 0
    else: rand(3, 6)


Lot --> Parcel
LotInner --> OpenSpace

Parcel --> 
    setback(distanceStreet)
        { street.front: OpenSpace // 靠近街道部分,作为Parcel处理
        | remainder: Footprint }  // 其余部分生成建筑

Footprint --> extrude(height)  

OpenSpace --> color("#77ff77") // Parcel设置为绿色

注意:street.front选择子用于评估shape的streetWidth属性,如果shape是通过block建立的,则被自动设置。手动创建的shape则没有设置。
在这里插入图片描述

建筑距离

现在通过同样方式添加setback来控制建筑之间的距离。
增加一个distanceBuildings属性,修改Parcel规则,增加新规则SubParcel如下:

attr distanceBuildings =
    30%: 0
    else: rand(4, 8)

Parcel --> // 第1次缩进
    setback(distanceStreet)
        { streetSide: OpenSpace // 左右边,即除去街道的临边和对边的剩余边
        | remainder: SubParcel }// 剩余边

SubParcel --> // 第2次缩进
    setback(distanceBuildings / 2)
        { noStreetSide: OpenSpace  // 非街道的临边,缩进成绿地
        | remainder: Footprint }   // 其余部分生成建筑
Footprint --> extrude(height)        
OpenSpace --> color("#77ff77")

这次会在不靠近街道的边上执行SubParcel 。
在这里插入图片描述
在这里插入图片描述

4、 多重的setback parcels

步骤

导入工程**MassModeling_01.cej **。

建立规则文件

打开massmodeling_03.cga规则文件,另存为myMass_04.cga。用已有的LUshape和塔的规则文件:

import lushapes : "massmodeling_01.cga"
import towers : "massmodeling_02.cga"

修改其中的Footprint规则:

Footprint -->
    case geometry.isRectangular(15):
        25% : towers.Tower
        else : lushapes.LUShape
    else:
        25%: towers.Tower
        else: offset(-5, inside) lushapes.BasicFootprint

指定给一组lots,执行生成。
在这里插入图片描述
在这里插入图片描述
下一节为建筑贴纹理。

5、增加立面纹理

打开massmodeling_04.cga规则文件,另存为myMass_05.cga.
接下来,我们写一个函数,来从12个立面纹理文件中随机挑选:

const randomFacadeTexture = fileRandom("*facade_textures/f*.tif")

为了正确的实施纹理映射到建筑立面,需要再定义2个函数来计算实际的楼层高度和切片宽度。

attr floorheight = rand(4,5)

actualFloorHeight =  
   case scope.sy >= floorheight : scope.sy/rint(scope.sy/floorheight)
   else : scope.sy
   
actualTileWidth = 
   case scope.sx >= 2 : scope.sx/rint(scope.sx/4)
   else : scope.sx

接下来实施组件分割,完成立面元素的构建:

Mass --> 
	comp(f){ side: Facade | top: Roof. }

指定引入规则中的Mass使用刚才定义的Mass。

towers.Mass --> Mass
lushapes.Mass --> Mass

最后,使用函数randomFacadeTexture设置纹理 UV坐标,并投影 UVs.

Facade -->
	setupProjection(0, scope.xy, 8*actualTileWidth, 8*actualFloorHeight)
	texture(randomFacadeTexture)
 projectUV(0)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值