近年来, 全国很多城市都在进行数字城市建设, 推进城市信息化进程[。数字城市是运用3S、遥测、仿真-虚拟等技术,以计算机技术、多媒体技术和大规模存储技术为基础,以宽带网络为纽带,实现对城市多尺度、多时空、多分辨率以及多种类的三维描述[。城市三维描述的核心是构建建筑物三维模型,数字城市建设对城市建筑物三维建模有两方面的要求:一是模型的精细化,构建的三维建筑物模型越精细,效果越逼真; 二是建模过程的自动化,自动化程度越高,操作越简单,效率越高。
在建筑物三维建模方面,娄启业等研究了基于AutoCAD和3DS Max进行建筑物三维建模的方法[; 张习科等利用Skyline和3DS Max构建湖南城市学院校园主要建筑物三维模型[; 吴森等基于Skyline生成地形模型,并构建了西南科技大学三维数字校园[; 王新志等研究了基于SketchUp的校园三维建模方法[; 万宝林将SketchUp和3DS Max分别与ArcGIS结合,研究了一体化建模流程,并进行了对比分析[; 朱安峰等基于CityEngine实现了河南大学三维数字校园系统[; 张晖等研究了基于CityEngine的室内三维建模的方法[。
传统的三维建模软件(如3DS Max等)采用手工建模的方法,建模过程费时、费力[,且模型重用度低。作为新的三维建模软件,CityEngine支持基于CGA规则的建模方法,建模速度快,模型重用度高,既可以读取ArcGIS中的shapefile数据,也可以导出多种格式(包括ArcGIS支持的Multipatch格式)的三维模型。
本文主要介绍在CityEngine中基于CGA规则的建筑物建模方法,并介绍基于Python脚本实现建筑物自动化建模的过程。
1 创建CGA规则文件
CGA规则文件一般存放在工程文件的rules文件夹下,创建CGA规则文件的方法是:右击CityEngine工作空间中的项目工程rules文件夹,通过菜单中new下的CGA Rule File菜单命令来创建。通过CityEngine提供的编辑窗口编辑CGA文件。CGA文件通常包含如下内容:① 建筑物的属性定义; ② 建筑物的图形操作; ③ 建筑物面的纹理贴图。
1.1 建筑物的属性定义
建筑物属性值的类型包括数值型和字符串型,通常数值型属性值表示建筑物的高度、宽度等,字符串型属性值代表贴图文件的路径及文件名,表示对贴图的引用。直接用属性值编写CGA规则时,如果属性值发生改变,在规则文件中修改属性值时会存在很大的不便,另外未经定义的属性值不能在Inspector窗口的属性面板中查看和编辑建筑物属性值。为方便起见,通常为建筑物的一些属性值进行“常量”的定义,如果属性值发生变化,只需在定义处进行修改。
属性定义的格式为attr name=value,其中name表示对建筑物属性的命名,value表示属性值。如attr " alt="" />
建筑物由二维到三维的拉伸过程由extrude命令完成,其格式为:extrude(Height),其中,Height为数值型,表示拉伸长度。拉伸后二维矢量图变成三维立体图。
图 1(Figure 1)
图 1 二维矢量图Figure 1 2D Vector Graph
图 2(Figure 2)
图 2 三维立体图Figure 2 3D Stereogram
通常建筑物各个面的设计是不同的,所以在建模时需要将建筑物各个面划分出来,并对其命名,然后编写对应的规则。建筑物各个面的处理主要用comp命令,其格式为:comp(type) {id1:name1 | id2:name2...| id(n):name(n)},其中type表示划分类型,包括三种类型:f、e、v分别表示对面、边、点进行划分; id1, id2, …, id(n)表示划分对象的编号,name1, name2, …, name(n)表示对划分对象的命名。
拉伸后,模型底面和顶面对应的id分别为0和1,侧面的id从2开始,与原矢量数据的节点编号有关,对于不规则图形的矢量数据,可以根据其节点编号确定多面体侧面的id。对于四边形,拉伸后成为六面体,其6个面可用前、后、左、右、上、下表示(对应的id可以是front、back、left、right、top、bottom,也可以是2、3、4、5、6、1、0)。id为“side”时,表示侧面划分后剩余的一个或多个侧面成为一个整体。
图 3(Figure 3)
图 3 三维建筑物面的划分Figure 3 Division of Horizontal of 3D Building
建筑物一般有多个楼层,并且楼层有门、窗等部分,所以需要对建筑物的面进行切割,并对各切割部分进行贴图。面的切割过程主要用split命令。该命令格式为:split(axis){size1:name1|size2:name2|…|size(n):name(n)},其中axis为切割方向,其值为x、y或z,x为切割面第一条边对应的方向,y为在该面上x方向的正交方向,z为该切割面的法线方向; size1, size2, …, size(n)为切割长度,可以是相对长度(带前缀’)、绝对长度或浮动长度(带有前缀~); name1,name2,…,name(n)表示对切割出部分的命名。切割时,通常有循环过程,“*”表示重复执行,如split(y){3:floors}*表示以3 m为高度循环纵向切割。
图 4(Figure 4)
图 4 切割图Figure 4 Results of Splitting
1.3 建筑物面的纹理贴图
纹理是物体表面的沟纹,也包括光滑表面上的彩色图案。CityEngine中建筑物的纹理由纹理贴图完成。纹理贴图操作主要由setupProjection、texture、projectUV命令完成。setupProjection用于设置纹理图层、纹理投影面和纹理大小,其命令格式为:setupProjection (uvSet, axesSelector, texWidth, texHeight),其中uvSet为整数,取值范围为[0, 5],表示不同的贴图效果,0为颜色贴图,1为凹凸贴图,2为光影贴图,3为高光贴图,4为透明贴图,5为普通贴图; axesSelector为纹理投影面,取值为scope.xy、scope.xz、scope.yx、scope.yz、scope.zx、scope.zy和world.xy、world.xz、world.yx、world.yz、world.zx、world.zy,scope表示贴图面坐标系,world表示场景坐标系; texWidth和texHeight为纹理的宽度和长度,如果绝对的宽度和长度无法确定,可以用相对比例表示,前缀“ ' ”表示纹理与需要贴图部分的相对比例。texture用于定义贴图的路径及文件名,其格式为:texture (path),其中path为纹理贴图的路径及文件名,贴图可以是一般的图片或.obj文件格式。projectUV格式为:projectUV (uvSet),其中,uvSet与setupProjection命令的参数保持一致。
图 5(Figure 5)
图 5 建筑物门、窗及墙面贴图Figure 5 Texture Operation for Doors, Windows and Walls
2 Python脚本实现建筑物自动化建模
CityEngine内置了Python编程语言和Python脚本编辑器,并提供了一个针对CityEngine的Python模块——scripting模块,CE类是scripting模块中的一个类,它封装了读写和编辑CityEngine内部数据的API函数。CE类具有的主要属性和方法如
表 2(Table 2)
表 2 CE类的主要属性和方法Table 2 Main Attributes and Methods of CE Class
表 2 CE类的主要属性和方法Table 2 Main Attributes and Methods of CE Class
属性和方法
含义
ce.newFile(self, workspacePath, interactive)
创建一个新场景,其中workspacePath是场景路径及名称,interactive是布尔型,默认值为False。
setSceneCoordSystem (self, description)
为场景定义坐标系统,其中description是投影坐标系统以proj4、WKT或CODE格式文件的内容。
importFile (self, filesystemPath, importSettings, interactive)
导入矢量数据,其中filesystemPath为矢量数据的路径及文件名,importSettings默认值为None,interactive是布尔型,默认值为False。
ce.setStartRule (self, shapes, rule)
设置起始规则
ce.setRuleFile(self, shapes, workspacePath, hasToExist)
为矢量数据(shapes)赋予CGA规则文件(rule),其中shapes为矢量数据,workspacePath默认值为None,hasToExist是布尔型,默认值为False。
generateModels (self, shapes, synchronous, updateSeed)
对shapes矢量数据生产三维模型,其中synchronous和updateSeed是布尔型,前者默认值为True,后者默认值为False。
refreshWorkspace (self)
刷新场景
利用Python脚本实现建筑物自动化建模主要有以下6个过程:① 实例化CityEngine; ② 新建场景文件; ③ 定义坐标系统; ④ 导入二维矢量数据; ⑤ 生成CityEngine三维场景模型; ⑥ 导出三维模型。
生成CityEngine三维场景模型的过程需要调用规则文件,通过规则文件生成相应的建筑物模型。对多个模型进行自动化建模时,可以在ArcGIS中为二维矢量数据的属性表增加一个字段,用于存放对应的规则文件名,Python脚本通过循环读取各数据的记录,根据对应的规则文件生成建筑物三维模型。
3 应用实例
以华东师范大学图书馆为应用实例,基于CityEngine创建三维模型。前期已有的数据包括:记录建筑物平面形状的shapefile数据、实地拍摄的建筑物外表照片等。通过测量得到建筑物高30 m,由照片获得建筑物各部分的相对比例。
图书馆裙楼共5层,裙楼正面左侧为平面,中间为弧形面,右侧为平面,左侧为墙面,墙面上每层分布有横向和纵向排列的两排窗; 中间弧形面第一层以门为主,第二层及以上以窗户为主; 右侧平面左边为窗户,右边为墙面,墙面上有不规则分布的窗户和“图书馆”字体。在工程文件rules文件夹下新建CGA文件lib.cga,编写规则文件时,通过extrude将矢量图拉伸为三维模型,由comp命令对模型的面进行划分,并对各面进行切割操作和贴图操作。
以右侧平面为例,介绍该面的切割和贴图过程。由该平面窗户的分布可以看出需要先进行横向切割,可以切割为窗户、墙面、窗户、墙面、带有窗户和字体的墙面等5部分,各自所占比例为0.25、0.2、0.05、0.1、0.4。即
Facade-->split(x){′0.25:window_a|′0.2:wall|′0.05:window_b|′0.1:wall|′0.4:window_c}
对于第一部分window_a,表示纵向按楼层高度切割,每层按窗户宽度横向切割,切割出窗户; 对于第二部分和第四部分的墙面,直接贴图; 对于第三部分window_b,表示纵向切割出墙面、窗户、墙面3部分,相对比例为1:12:1,并对窗户再进行纵向切割,切割出窗户; 对于第五部分,需要纵向切割出每一层。
根据每一层的横向和纵向切割,切割出窗户和字体等部分,以带有“图”字和窗户的第五层为例。
FifthFloor→split(x){′0.4:split(y){~1:wall|~1:part1|~1:wall}|′0.6:part2}
part1→split(x){2:window_2}*
part2→split(y){~1:wall|3:split(x){~1:wall|3:tu_tex|1:wall}|1:wall}
其中,window_1、window_2、wall、tu_tex为窗户1、窗户2、墙面、“图”字的纹理贴图操作,以“图”字贴图为例:
tu_tex→
setupProjection(0, scope.xy, ′1, ′1)
projectUV(0)
texture(″assets/library/tu.tif″)
裙楼CGA文件编写完成后,可以通过Python脚本实现自动化建模,脚本运行时,调用CGA规则文件,运行后可以得到CityEngine场景模型以及导出的三维模型。
导出的MultiPatch格式三维模型加载到ArcScene中,同时加载矢量数据library.shp,加载后数据之间完全吻合,即导出的三维模型可以在ArcScene中与原矢量数据叠置。
图 6(Figure 6)
图 6 模型在ArcScene中显示图Figure 6 Model Display in ArcScene