背景
最近遇到一個有趣的問題,如何在CityEgnine中判斷有接觸或相交關係的模型,從而自動進行建模?
這個問題有點抽象,我們來看個實例,瞭解下問題的背景:
以往絕大多數情況下,我們拿到的2D建築物底面(FootPrint)都是一個建築對應一個面,也就是這樣的:
實際生活中的的建築物可能是更復雜的,例如商場、大型會議中心、複雜居民樓等參差不齊的多棟聯合建築,我們可以採集多個底面來表示建築物,例如這樣:
使用多個底面表示一棟複雜建築物的做法可以很大程度上簡化建模的工作,因此無可厚非。 但是問題來了,因爲是彼此獨立的Footprint,建模時若不加判斷,就會出現如下圖所示的情況,好像“空中地下室”。這樣的房子既不美觀也不實際。
解決方法
CityEngine的真正魅力在於“動態”建模,這是CE的創作者一直想要傳播的理念。 CityEgnine提供很多內置函數解決這些問題,其中有一組爲:Occlusion Functions,包含:inside
,overlaps
,touches
三個函數。 我們可以利用 touches()
來實現判斷。
先寫段簡單的來了解下函數用法:
Init -->
extrude(40) Mass
Mass -->
comp(f){top:NIL| side:Side}
Side -->
case touches(): color(1,0,0) ShareSide
else: Walls
針對前面“空中地下室”的問題,可以在樓層切割到窗戶和牆體的時候做個判斷,樓層不touch其他樓層時,再進行分割。
可以實現這個樣子:
全部 CGA 代碼共享給大家:
/**
* 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)
明天就放假了
節日愉快
我說的是愚人節
哈
Also available Here .