要访问教程CityEngine中,单击 帮助>下载教程和例子…。选择教程或示例后,项目会自动下载并添加到您的工作区。
L 形和 U 形
教程设置
本教程展示了如何使用形状语法创建建筑物的体量模型。将创建典型的建筑体积形状,例如 L 和 U 体量。
- 将Tutorial_08_Mass_Modeling项目导入 CityEngine 工作区。
- 打开MassModeling_01.cej场景。
创建规则文件
- 单击文件>新建> CityEngine > CGA 规则文件。
- 确保容器设置正确(Tutorial_08_Mass_Modeling/rules),将文件命名为myMass_01.cga,然后单击Finish。
创建一个新的 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 形拉伸到其高度。
LotInner 应用 OpenSpace,保持地块形状不变。
笔记:
属性可以有可选的注释,例如@Group 或@Range,它们控制属性在检查器中的显示。有关 CGA 注释的详细信息,请参阅 CGA 参考。
现在您将规则应用于批次。
- 在场景编辑器中选择Lots 图层。
- 单击 形状>分配规则文件。
- 从规则目录中选择myMass_01.cga规则文件,然后单击确定。
生成建筑物
-
- 在 3D 视口中选择一些批次。
- 单击形状>生成或Ctrl+G以生成建筑物。
L 形质量模型工作;然而,它们看起来不太有说服力。你需要更多的变化。
变化的L形
当前 L 形的侧翼始终位于主体的左侧。使用rotateScope,您也可以将L 形更改为位于右侧。
使用概率运算符 % 更改 LShape 规则中的红线,以改进 L 形状,使其侧翼位于左侧或右侧。
LShape -->
50% : shapeL(wingWidth, wingWidth) { shape : LFootprint }
else : rotateScope(0, 90, 0)
shapeL(wingWidth, wingWidth) { shape : LFootprint }
使用convexify 命令,您可以将L 形拆分为其翅膀,并更改两个翅膀的高度。您将再次使用随机概率来添加变化。
LFootprint -->
75% : extrude(height) Mass
else : convexify comp(f) { 0 : extrude(height) Mass |
all : extrude(height * 0.7) Mass }
侧翼现在出现在左右两侧并且高度不同。现在您需要其他形状。
U形
您将添加一个 U 形。在起始批次规则中调用 UShape 而不是 LShape。
Lot --> UShape
同样,您将使用 shapeU 命令。
UShape -->
shapeU(wingWidth, wingWidth * 0.7, wingWidth * 0.7)
{ shape : UFootprint }
UFootprint --> extrude(height) Mass
也添加一些变化。
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 形并非适用于所有批次。您将在下一节中更正此问题。
L 形和 U 形组合
高度分布并不令人信服。为了更好地控制建筑物的高度,您将向高度属性添加一个条件。只应允许大面积地块建造高层建筑。
attr height =
case geometry.area < 1000: rand(20, 50)
else: rand(50, 150)
您将添加一个新规则 LUShapes,以控制在哪些批次上创建什么形状。
U 形在宽度大于深度的地块上效果最佳。或者在 CGA 语言中,scope.sx 大于 scope.sz。在任何其他情况下,您只会触发 L 形。
Lot --> LUShapes
LUShapes -->
case scope.sx > scope.sz :
60% : UShape
else : LShape
else: LShape
L 形和 U 形都不适用于非矩形地块。下一个 case 语句确保 UShape 和 LShape 仅在近似矩形的批次上创建(公差为 15 度)。否则,您将调用新的封装规则。
LUShapes -->
case geometry.isRectangular(15):
case scope.sx > scope.sz :
60% :UShape
else : LShape
else: LShape
else: BasicFootprint
与 L 形和 U 形相比,挤出的批量形状将太大。因此,您将向 BasicFootprint 添加负偏移量。这也将允许各个建筑物之间有更多空间。
BasicFootprint --> offset(-5,inside) extrude(height) Mass
在下一节中,您将学习如何在 Shape Grammar 中使用递归进行质量建模。
使用递归进行批量建模
教程设置
本教程展示了如何使用递归 Shape Grammar 调用对重复的建筑元素进行建模。
打开 MassModeling_01.cej现场,如果它不是已经打开。
创建规则文件
- 单击新建> CityEngine > CGA 语法文件。
- 确保容器设置正确(Tutorial_08_Mass_Modeling/rules),将文件命名为myMass_02.cga,然后单击Finish。
塔形
属性 height 为建筑物高度创建一个随机值。起始规则 Lot 调用 Envelope,它将覆盖区拉伸到塔的封套。信封调用递归规则。
height =
case geometry.area > 1000: rand(50, 200)
else: rand(20, 50)
Lot --> Tower
Tower --> extrude(height) Envelope
Envelope --> RecursiveSetbacks
对于后续的递归规则,您需要两个额外的变量:lowHeight 和 scale。对于建筑物,后者需要保持不变,因此您将其定义为属性。
// switching between these two values creates visually appealing setbacks:
lowHeight = 50%: 0.4 else: 0.6
// has to be constant:
attr scale = rand(0.75, 0.9)
RecursiveSetbacks 规则将质量(只要它高于两层楼)拆分为相对高度为 lowHeight 的较低部分质量。上部剩余部分生成形状 Setback。
如果 RecursiveSetbacks 形状小于两层楼,则其余部分的高度设置为楼层高度,并生成质量形状。
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
现在将规则应用于批次。
- 选择大量的在场景编辑器中很多层。
- 单击形状>分配规则文件。
- 从规则目录中选择myMass_02.cga规则文件,然后单击OK。
生成建筑物
-
- 在 3D 视口中选择一些批次。
- 单击“形状” >“生成”或按Ctrl+G以生成建筑物。
圆形
使用外部圆柱资产,您可以创建递归塔的圆形版本。修改 Tower 规则如下:
Tower --> extrude(height) Envelope
Envelope -->
case geometry.isRectangular(20):
20% : i("cyl.obj") RecursiveSetbacks
else: RecursiveSetbacks
else: RecursiveSetbacks
在 20% 的塔中,您将插入圆柱体资产,而不是使用隐式立方体作为基础形状。
在下一部分中,您将修改带有挫折的地块。
适应挫折的包裹
教程设置
在本节中,您将对地块形状应用退缩。
打开MassModeling_01.cej现场,如果它不是已经打开。
创建规则文件
- 单击新建> CityEngine > CGA 语法文件。
- 确保容器设置正确(Tutorial_08_Mass_Modeling/rules),将文件命名为myMass_03.cga,然后单击Finish。
街头挫折
Parcel 规则在该地块的所有街道两侧应用后退,并将该区域转发给 OpenSpace 规则。内部部分,远离街道两侧。被转发到 Footprint,它挤压到一个随机高度。
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
| remainder: Footprint }
Footprint --> extrude(height)
OpenSpace --> color("#77ff77")
笔记:
street.front 选择器评估形状 streetWidth 对象属性,该属性是为从块创建的地块自动设置的,但可能不会出现在手动创建的形状上。
-
- 在场景编辑器中选择批次图层。
- 单击 形状>分配规则文件。
- 从规则目录中选择 myMass_03.cga规则文件,然后单击确定。
- 在 3D 视口中选择很多。
- 单击“形状” >“生成”或按Ctrl+G以生成建筑物。
建筑物距离
您现在将添加一个类似的挫折来控制建筑物之间的距离。添加 attr distanceBuildings,修改 Parcel 规则,并添加一个新的 SubParcel 规则,如下所示:
attr distanceBuildings =
30%: 0
else: rand(4, 8)
Parcel -->
setback(distanceStreet)
{ streetSide: OpenSpace
| remainder: SubParcel }
SubParcel -->
setback(distanceBuildings / 2)
{ noStreetSide: OpenSpace
| remainder: Footprint }
SubParcel 将再次应用挫折,但这次是在非街道边缘。
-
- 保存 .cga 文件。
- 在 3D 视口中选择一些批次。
- 单击“形状” >“生成”或按Ctrl+G以生成建筑物。
- 选择生成的模型并试验 distanceBuildings 和 distanceStreet 规则参数。您可以在单个选定模型上设置值或同时选择多个模型。
- 要将用户定义的值重置回来自规则文件的随机值,请将源从用户更改回规则。
在下一节中,您将结合前几节中的体量模型与后退地块,并添加纹理立面。
结合质量和挫折包裹
教程设置
打开 MassModeling_01.cej现场,如果它不是已经打开。
创建规则文件
打开 massmodeling_03.cej规则文件,并将其保存为myMass_04.cga。
导入 LU 形状和塔体质量规则
-
- 添加以下两个导入命令:
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
- 保存规则文件。
- 选择大量的在场景编辑器中很多层。
- 单击 形状>分配规则文件。
- 从规则目录中选择myMass_04.cga规则文件,然后单击确定。
生成建筑物:
生成建筑物
- 在 3D 视口中选择一些批次。
- 单击“形状” >“生成”或按Ctrl+G以生成建筑物。
在下一部分中,您将向体量模型添加带纹理的外墙。
添加纹理外墙
教程设置
打开 MassModeling_01.cej现场,如果它不是已经打开。
创建规则文件
打开 massmodeling_04.cej规则文件,并将其保存为 myMass_05.cej。
要将简单的纹理立面添加到体量模型中,您需要一个函数来随机选择 12 个立面纹理图块中的一个。
const randomFacadeTexture = fileRandom("*facade_textures/f*.tif")
要将纹理瓷砖正确映射到您的立面,您将定义两个函数来计算实际地板高度和瓷砖宽度。使用这些功能,您将确保不会在立面的边缘切断纹理瓷砖。
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. }
指示导入的规则使用此质量规则。
towers.Mass --> Mass
lushapes.Mass --> Mass
最后,在立面上设置 UV 坐标,使用randomFacadeTexture函数定义纹理文件,并投影 UV。
Facade -->
setupProjection(0, scope.xy, 8*actualTileWidth, 8*actualFloorHeight)
texture(randomFacadeTexture)
projectUV(0)
- 保存规则文件。
- 选择大量的在场景编辑器中很多层。
- 单击 形状>分配规则文件。
- 从规则目录中选择myMass_05.cga规则文件,然后单击确定。
并生成建筑物:
生成建筑物
- 在 3D 视口中选择一些批次。
- 单击“形状” >“生成”或按Ctrl+G以生成建筑物。