简介:这份资源是面向Cityengine用户的城市规划规则库工具包,适合从事三维城市建模、景观设计及规划方案推演的设计师与学习者使用,可帮助快速扩展或定制城市生成规则,降低从零编写CGA脚本的门槛。压缩包共8个文件,约36KB,包含cgb规则二进制文件、cga规则脚本、xml配置、project工程文件及pydevproject开发配置等,覆盖规则定义、工程组织与脚本开发等环节,导入后即可在Cityengine中调用并调整参数。目前已有1109人学习下载,具备一定参考价值。借助其中的规则集与工程结构,读者可研究地形、建筑、道路等规则的编写思路,结合CGA语言与Python API进行二次开发,实时预览不同规划方案的城市景观效果,并集成GIS数据开展光照、视线与密度分析,为城市规划、交通规划及虚拟场景制作提供可复用的规则基础。
1. 拆开这个 Cityengine 城市规划规则库:它到底能省掉哪几步重复劳动
如果你做过三维城市建模,大概率经历过这种循环:拿到一块地形和路网,手动拉体块、切立面、调高度,改一版方案就要重来一遍。Cityengine 的城市规划02规则库,本质就是把这套重复劳动打包成一套可复用的 CGA 规则集,配合 assets、data、scenes、rules、scripts 这些目录,让你导入后直接跑出成片的城市肌理。它面向的是做城市规划、景观设计、影视场景预演的从业者,尤其是需要快速出多方案对比的人。压缩包里带 .project、.pydevproject、.resolvemap.xml 这些工程文件,说明它不是零散脚本,而是一个能直接在 Cityengine 里打开的完整工程。下面我按自己拆包和跑通的顺序,把规则库的结构、参数、坑点讲清楚。
2. 规则库目录结构与 CGA 规则驱动逻辑
2.1 从压缩包目录看工程组织方式
拿到城市规划02.rar解压后,目录大致是这样分布的,先认清每个目录的职责,后面改参数才不会找错地方:
| 目录/文件 | 作用 | 是否要动 |
|---|---|---|
rules | 存放 CGA 规则文件,城市生成的核心逻辑 | 主要修改对象 |
assets | 模型、纹理等素材资源 | 一般不动 |
data | GIS 数据、地形、路网等输入数据 | 按项目替换 |
scenes | 场景文件,保存相机、图层、规则分配 | 打开入口 |
scripts | Python 脚本,做批量处理或数据转换 | 进阶用 |
models | 生成后的模型输出 | 只读 |
maps/images | 贴图与参考图 | 一般不动 |
.project/.pydevproject | 工程配置,标识项目根 | 不要删 |
.resolvemap.xml | 资源解析映射,指向素材路径 | 路径变了要改 |
.resolvemap.xml这个文件容易被忽略,它记录的是资源相对路径的解析规则。如果你把工程挪到别的盘符或目录层级,Cityengine 找不到纹理和模型,多半就是这里没对上。常见做法是保持解压后的目录层级不变,或者用 Cityengine 的工程重定位功能重新指一遍。
2.2 CGA 规则是怎么把地块变成建筑的
Cityengine 的核心是规则驱动,CGA(Computer Generated Architecture)是它专用的脚本语言。规则库里的每条规则,本质是一组「形状 → 操作 → 新形状」的推导。举个最简化的建筑体块规则,帮你理解规则库里那些文件在干什么:
// 建筑体块生成规则示例 attr height = 30 // 建筑高度,可外部传入 attr floors = 10 // 楼层数 Lot --> // 从地块形状开始 extrude(height) // 按高度拉伸成体块 Comp(f) { top: Roof | // 顶面交给 Roof 规则 side: Facade } // 侧面交给 Facade 规则 Roof --> color(0.6, 0.6, 0.6) // 屋顶赋灰色 setback(2) { all: NIL } // 内缩 2 米 Facade --> split(y) { ~floors: Floor } // 沿高度按楼层切分 Floor --> split(x) { ~1: Window | ~1: Wall } // 每层切窗户和墙逻辑说明:Lot是入口规则,对应地块。extrude把平面拉成三维体块,Comp(f)把体块拆成顶面和侧面分别处理。split(y)沿垂直方向按楼层切,~表示按比例自适应。参数说明:height和floors用attr声明,意味着可以在 Cityengine 的检查器面板里实时改,改完场景立刻重算,这就是规则驱动比手动建模快的地方。规则库里的文件比这个复杂得多,但拆开看都是这类推导的组合。
2.3 导入规则库并跑通第一个场景
步骤不复杂,但顺序错了会白折腾:
- 解压后不要直接双击场景文件,先在 Cityengine 里用
File > Import > Cityengine Project把整个工程目录导入,让.project被识别。 - 打开
scenes目录下的场景文件,检查图层里地块是否正常显示。 - 选中地块图层,在 Inspector 面板的 Rules 栏里指定
rules目录下的规则文件。 - 如果规则没自动分配,右键地块图层选
Assign Rules,手动指到对应.cga。 - 改几个
attr参数,看场景是否实时更新。
# 如果 scripts 目录下有批量处理脚本,常见调用方式 # 注意:路径按你实际解压位置替换 cd 城市规划02/scripts python batch_assign.py --scene ../scenes/city_02.cej --rules ../rules/building.cga这段脚本调用是常见做法,具体脚本名和参数以你包里的为准。逻辑是批量给场景里的图层分配规则,省去一个个手点。参数--scene指场景文件,--rules指规则文件。跑之前先确认 Python 环境里装了 Cityengine 对应的模块,否则会报导入错误。
3. 参数调优:让规则库输出符合你规划意图的城市
3.1 建筑高度与密度参数怎么设
规则库默认参数跑出来的城市,往往和你项目的控规指标对不上。这时候要动的是规则里的attr变量。常见做法是先在 Inspector 面板里试,试出合适的值再回写进 CGA 文件固化下来。
以建筑高度为例,规则库里通常会有类似attr maxHeight、attr minHeight、attr density这样的参数。maxHeight控制天际线峰值,density控制地块内建筑覆盖率。调density的时候注意,它影响的是体块占地比例,不是容积率,别直接拿它当 FAR 用。容积率要靠高度和覆盖率一起算。
// 按控规指标约束建筑生成 attr FAR = 2.5 // 容积率目标 attr siteArea = 1000 // 地块面积,可由 GIS 数据带入 attr coverage = 0.4 // 建筑覆盖率 Building --> // 根据容积率和覆盖率反推高度 let h = (FAR * siteArea) / (siteArea * coverage) extrude(h) Comp(f) { top: Roof | side: Facade }逻辑说明:这里用let做了一次计算,把容积率换算成高度。参数说明:FAR、siteArea、coverage都可以从 GIS 属性表里读,Cityengine 支持把地块属性直接映射成规则参数。这样改规划指标时,不用手动改每个建筑,改属性表就行。
3.2 道路与地块的衔接参数
道路规则负责街道宽度、交叉口形态。规则库里道路部分通常和地块是分开的两套规则,衔接靠的是地块边界和道路中心线的对齐。常见坑是地块和道路之间有缝隙或重叠,导致建筑压到路面上。
处理办法是在道路规则里设attr sidewalkWidth(人行道宽度),在地块规则里设attr setback(退线距离),让两者相加等于道路红线到建筑的实际距离。如果跑出来建筑还是压线,检查地块多边形是不是从道路中心线偏移生成的,偏移量要和sidewalkWidth对上。
提示:改道路参数后,地块不会自动重算边界,需要重新生成一次地块图层,否则退线还是按旧边界算。
3.3 用 Python 脚本批量改参数
项目多了以后,一个个在面板里点不现实。scripts目录下的 Python 脚本就是干这个的。Cityengine 提供 Python API,可以遍历场景里的图层和规则参数。
# 批量修改场景中所有地块的建筑高度上限 from scripting import * cityEngine = getCityEngine() # 获取当前场景 scene = cityEngine.getCurrentScene() # 遍历所有地块图层 for layer in scene.getLayers(): if layer.getName().startswith("Lot"): # 读取规则参数并修改 ruleParams = layer.getRuleParameters() if "maxHeight" in ruleParams: ruleParams["maxHeight"] = 60 # 统一改成 60 米 layer.setRuleParameters(ruleParams) print("参数批量更新完成")逻辑说明:先拿到当前场景,再遍历名字以Lot开头的图层,找到maxHeight参数统一赋值。参数说明:maxHeight这个名字要和你规则文件里attr声明的一致,不一致就找不到。跑之前建议先备份场景,批量改参数没有后悔药。
4. 避坑与常见问题排查
4.1 导入后场景一片空白
现象:打开场景文件,视图里什么都没有,图层列表也是空的。 原因:多半是.resolvemap.xml里的资源路径和你实际解压路径对不上,Cityengine 解析不到数据。 解决:用File > Project > Relocate重新指定工程根目录,或者手动编辑.resolvemap.xml把路径改成相对路径。保持解压后的目录层级不变是最省事的做法。
4.2 规则分配了但建筑不生成
现象:规则文件指定了,地块也在,但场景里就是不出体块。 原因:地块图层的几何类型不对。CGA 规则入口通常要求是面(polygon),如果地块是线或点,extrude直接失败。 解决:检查地块图层的几何类型,在图层属性里确认是 Polygon。如果是线,先用Cleanup > Polygonize转成面。
4.3 纹理丢失显示为纯色
现象:建筑体块出来了,但表面是灰的或纯色,没有贴图。 原因:assets目录里的纹理路径在规则里写的是绝对路径,换机器后失效。 解决:把 CGA 里的纹理引用改成相对路径,或者用texture()函数时配合.resolvemap.xml的映射规则。常见做法是统一用相对工程根的路径。
4.4 参数改了场景不更新
现象:在 Inspector 里改了attr值,场景没反应。 原因:规则没有真正绑定到图层,或者改的是规则文件但没重新加载。 解决:确认图层 Inspector 的 Rules 栏里有规则文件路径。如果改的是.cga文件本身,需要右键规则文件选Reload,或者重启场景。Cityengine 不会自动监听文件外部修改。
4.5 生成速度慢到卡死
现象:地块一多,改一个参数要等好几分钟。 原因:规则里用了递归或大范围split,每次重算都全量跑。 解决:把不参与实时调整的部分用NIL或Comp提前终止,减少推导层级。另外可以在 Inspector 里把预览精度调低,出图时再调高。血泪经验是别在几万个地块的场景里实时拖参数,先在小范围试好再全量跑。
5. 进阶:把规则库接进 GIS 数据流与批量出图
规则库真正好用的地方,是它能和 GIS 数据联动。data目录里放的就是这类输入。常见做法是把地块属性表里的容积率、用地性质、限高这些字段,直接映射成 CGA 的attr,这样改规划指标不用碰规则文件,改属性表就行。
# 从 GIS 属性表读取指标并写入规则参数 import csv from scripting import * cityEngine = getCityEngine() scene = cityEngine.getCurrentScene() # 读取外部指标表 with open("../data/parcels_metrics.csv", "r", encoding="utf-8") as f: reader = csv.DictReader(f) for row in reader: parcelId = row["parcel_id"] far = float(row["FAR"]) heightLimit = float(row["height_limit"]) # 按地块 ID 找到对应图层并写入参数 layer = scene.getLayer(parcelId) if layer: params = layer.getRuleParameters() params["FAR"] = far params["maxHeight"] = heightLimit layer.setRuleParameters(params)逻辑说明:用 CSV 做中间格式,把 GIS 导出的指标读进来,按地块 ID 匹配图层写参数。参数说明:parcel_id要和场景里图层命名规则一致,FAR和height_limit要和 CGA 里的attr名字对上。这套流程跑通后,一个片区的方案调整就是改 CSV 再跑一遍脚本的事。
批量出图也是类似思路,用 Python API 遍历相机视角,逐个渲染导出。我一般会先固定几个关键视角,比如鸟瞰、人视、沿街,然后写个循环批量出图,避免手动一张张调。
从那以后我每次拿到新的规则库,都强制先跑一遍最小场景验证路径和规则绑定,再往大项目上套。希望帮到你。
本文还有配套的精品资源,点击获取