背景

最近遇到一个有趣的问题,如何在CityEgnine中判断有接触或相交关系的模型,从而自动进行建模?

这个问题有点抽象,我们来看个实例,了解下问题的背景:

以往绝大多数情况下,我们拿到的2D建筑物底面(FootPrint)都是一个建筑对应一个面,也就是这样的:

实际生活中的的建筑物可能是更复杂的,例如商场、大型会议中心、复杂居民楼等参差不齐的多栋联合建筑,我们可以采集多个底面来表示建筑物,例如这样:

使用多个底面表示一栋复杂建筑物的做法可以很大程度上简化建模的工作,因此无可厚非。 但是问题来了,因为是彼此独立的Footprint,建模时若不加判断,就会出现如下图所示的情况,好像“空中地下室”。这样的房子既不美观也不实际。


解决方法

CityEngine的真正魅力在于“动态”建模,这是CE的创作者一直想要传播的理念。 CityEgnine提供很多内置函数解决这些问题,其中有一组为:Occlusion Functions,包含:insideoverlapstouches 三个函数。 我们可以利用 touches() 来实现判断。

先写段简单的来了解下函数用法:

1
2
3
4
5
6
7
Init --> 
extrude(40) Mass
Mass -->
comp(f){top:NIL| side:Side}
Side -->
case touches(): color(1,0,0) ShareSide
else: Walls

针对前面“空中地下室”的问题,可以在楼层切割到窗户和墙体的时候做个判断,楼层不touch其他楼层时,再进行分割。

可以实现这个样子:

全部 CGA 代码共享给大家:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* File: TestTouches.cga
* Created: 1 Apr 2016 13:00:24 GMT
* Author: kikita
*/

version "2015.2"

# Define Attributes
attr AVG_HEIGHT = 0
attr WindowsWidth = 8
attr WallWidth = 2.5

# Building Schmetic
Init -->
extrude(AVG_HEIGHT) Mass
Mass -->
comp(f){top:Top|side:Walls}
Walls -->
split(y) { 15 : GroundFloor | {~10 : UpperFloors } * }

# Ground Floor
GroundFloor -->
setupProjection(0, scope.xy, '1, '1)
projectUV(0)
texture("GroundFloor.jpg")

# All Upper Floors
UpperFloors -->

# Use touches() function
case touches():
setupProjection(0, scope.xy, 10, 10)
projectUV(0)
texture("Wall/wall_grey.jpg")
else:
split(x){ ~WallWidth : AllWalls |
{ ~WindowsWidth : WindowTiles |
~WallWidth : AllWalls } * }
WindowTiles -->
split(y){ ~WallWidth/2: AllWalls |
~WindowsWidth : Windows|
~WallWidth/2 :AllWalls }

# Wall Texture
AllWalls -->
setupProjection(0, scope.xy, 10, 10)
projectUV(0)
texture("Wall/wall_grey.jpg")

# Windows
Windows -->
color("DAFAF3")
i("Windows/sash_window.obj")
s('1,'1,'2)

# Roofs
Top -->
offset(-0.5)
comp(f){ border : RoofEdge | inside : RoofFlat }
RoofFlat -->
setupProjection(0, scope.xy, '1, '1)
projectUV(0)
texture("flatroof6.bw.jpg")
RoofEdge -->
extrude(1)

明天就放假了

节日愉快

我说的是愚人节