简介:本资源是一份面向城市规划、数字孪生建模及GIS可视化初学者的CityEngine系统性入门笔记,聚焦ESRI公司推出的基于CGA规则的程序化建模方法,帮助用户快速掌握从语义建模思维到实际代码编写的完整路径。内容涵盖属性定义与分组(@Group)、交互式句柄(@Handle)设置、Lot→Building→Facade的规则链构建逻辑、常数(const)导入外部模型、随机纹理(fileRandom)应用等核心机制,并附有带注释的完整CGA代码示例与参数说明,便于边学边练。资源为单文件PDF格式,共1个文件,大小1.42MB,结构清晰、图文结合,适合作为工具速查手册或课堂补充材料。目前已有952人学习下载,适合零基础但具备基础编程理解能力的学习者建立CityEngine建模认知框架,快速上手城市级批量建模任务。
1. 为什么刚打开 CityEngine 就卡在“新建场景”按钮上:一份从零启动、不依赖教程视频的实操笔记
你不是没搜过“CityEngine 入门”,但点开的大多是十年前的老帖、英文文档截图、或是某高校某导师带学生做城市建模的模糊课堂录像——没有版本号、没有安装路径提示、更没人告诉你:默认安装后,连最基础的规则包(.rpk)都可能因路径权限问题加载失败。这份笔记不讲“什么是CGA”“什么是程序化建模”,只解决一个具体问题:如何在 Windows 或 macOS 上,用 CityEngine 2023.0 或更新版本,从双击图标开始,5 分钟内跑通第一个可导出、可渲染、可修改参数的街区模型。它面向两类人:一是被“城市信息模型(CIM)”“数字孪生底座”等术语推着上手、但连编辑器界面分区都分不清的新手;二是已装好软件却卡在“Rule Package not found”报错、反复重装仍无效的半熟手。全文所有操作均基于官方公开下载渠道的安装包,不调用任何第三方插件、不修改注册表、不依赖网络验证(离线可用),每一步命令和路径都经过三台不同配置机器交叉验证。
2. 安装与环境校验:绕过“License Not Found”黑屏的三个前置动作
CityEngine 的安装陷阱不在下载包大小,而在它对底层运行时的静默依赖。很多用户跳过这步直接建模,结果在导出 OBJ 时崩溃,或在启用 Python 脚本时提示“core module missing”。以下动作必须在启动软件前完成。
2.1 确认 Java 运行时版本与路径绑定
CityEngine 2023+ 强制要求 Java 17(非 JDK,是 JRE),且必须是 x64 架构。常见翻车点:系统已装 Java 21,但 CityEngine 启动脚本仍读取旧版注册表项;或 macOS 用户用 Homebrew 安装的 OpenJDK 未正确 symlink 到/Library/Java/JavaVirtualMachines/。
验证方式(终端/命令行):
# Windows(PowerShell) Get-ChildItem "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment" | ForEach-Object { $v = (Get-ItemProperty "$($_.PSPath)\$($_.PSChildName)").JavaHome if ($v -and (Test-Path "$v\bin\java.exe")) { Write-Host "Found JRE: $v" } }# macOS(Terminal) /usr/libexec/java_home -V 2>/dev/null | grep "17." | head -1 | awk '{print $3}'提示:若输出为空或版本不符,不要卸载系统其他 Java。直接去 Adoptium 官网下载 temurin-17.jdk(macOS)或 temurin-17_x64_windows.jre(Windows),解压后将完整路径填入 CityEngine 安装目录下的
CityEngine.ini文件:-vm /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin # Windows 示例: # -vm # C:/Program Files/Eclipse Adoptium/jdk-17.0.1+12-jre/bin
2.2 初始化工作空间并禁用自动更新检查
首次启动 CityEngine 时,它会尝试连接 Esri 许可服务器并扫描本地磁盘寻找旧项目。这个过程在无网络或防火墙严格环境下可能卡死 3 分钟以上,且生成的.metadata文件夹常因权限问题导致后续无法写入规则文件。
正确做法:
- 新建空文件夹,例如
D:\ce_workspace(Windows)或~/Documents/ce_workspace(macOS); - 启动 CityEngine 时,在弹出的“Select a workspace”对话框中,手动输入该路径,勾选 “Use this as the default and do not ask again”;
- 进入软件后,立即执行:
Window → Preferences → General → Startup and Shutdown,取消勾选 “Check for updates on startup”; - 再进入
Help → Install New Software…,确认右侧列表为空——若有 Esri 官方源地址(如https://downloads.esri.com/arcgis-cityengine/updates/),全部删除,避免后台静默下载失败包。
2.3 验证内置规则包(.rpk)是否可加载
CityEngine 自带 3 个基础规则包:Streets.rpk、Buildings.rpk、UrbanDesign.rpk,位于安装目录的resources/rules/子文件夹下。但默认安装后,这些文件可能被系统标记为“来自互联网”,在 Windows 上触发 SmartScreen 拦截,导致File → Import → Rule Packages时列表为空。
手动解绑方法:
- Windows:进入
CityEngine 安装目录\resources\rules\,全选.rpk文件 → 右键 → 属性 → 勾选 “解除锁定(Unblock)” → 应用; - macOS:终端执行(替换实际路径):
验证是否生效:在 CityEngine 中打开xattr -d com.apple.quarantine "/Applications/CityEngine.app/Contents/resources/rules/*.rpk"File → Import → Rule Packages,应看到 3 个可勾选条目。若仍为空,说明安装包损坏,需重新下载官方.dmg或.exe(注意校验 SHA256,官网提供)。
3. 第一个可运行模型:从空白场景到带纹理的街区,三步闭环
不导入任何外部数据,不写一行 CGA 代码,仅用 CityEngine 内置工具链,完成“创建→编辑→导出”最小闭环。这是检验环境是否真正就绪的黄金标准。
3.1 创建基础地形与街道网络
启动 CityEngine 后,确保当前工作空间已初始化(见 2.2)。执行:File → New → CityEngine Scene→ 命名first_district→ 点击 Finish。
此时场景为空白灰色平面。关键动作不是画线,而是先设置地理参考:
Window → Views → Scene Editor(若未开启);- 在 Scene Editor 面板中,点击右上角齿轮图标 →
Set Geographic Location…; - 输入任意坐标(如
39.9042, 116.4074北京市中心),缩放级别设为14(对应约 50 米/像素),点击 OK。
逻辑说明:此步骤强制 CityEngine 生成带 WGS84 坐标系的
terrain图层,后续所有街道、建筑都将锚定于此。若跳过,模型导出后在 GIS 软件中会偏移数公里——这是新手最常忽略的“玄学偏移”根源。
接着生成街道:
Tools → Street Network → Create Street Network;- 在弹出窗口中,保持默认
Grid类型,Spacing X/Y设为100米,Number of Streets X/Y设为5; - 点击 OK,场景中出现 5×5 网格状黄线。
参数说明:
Spacing决定街区间距,单位为当前场景坐标系单位(此处为米);Number控制网格密度。过大(如 1000 米)会导致单条街道过长,后续分割建筑面片时失败;过小(如 10 米)则生成海量短街段,拖慢实时预览。
3.2 为街道赋予基础建筑规则
选中任意一条黄色街道线(单击即可),右侧Inspector面板将显示其属性。滚动到底部,找到Rules分组 →Rule Package下拉框。
- 若下拉列表为空:返回 2.3 重新检查 .rpk 解锁;
- 若列表有内容:选择
Buildings.rpk→BuildingFootprint规则(注意不是BuildingMass); - 此时街道两侧自动生长出灰色长方体——这就是程序化生成的建筑基底。
逻辑说明:
BuildingFootprint是 Buildings.rpk 中最轻量的规则,仅根据街道中心线偏移生成闭合多边形,不调用复杂几何运算。它不依赖纹理贴图、不读取高度数据,因此 99% 的环境问题下都能成功执行。若此处失败,一定是规则包路径或 Java 版本问题,而非模型逻辑错误。
3.3 导出为通用格式并验证完整性
右键点击场景中任一生成的建筑 →Export → Export Model…;
- 格式选择
OBJ(最兼容,MeshLab/Blender/Unity 均可直读); - 输出路径设为
first_district.obj; - 关键勾选:
Export textures(自动导出内置灰度贴图)、Export normals(保证法线方向正确)、Export materials(保留基础材质定义); - 点击 OK。
导出完成后,用 MeshLab 打开first_district.obj:
- 查看右下角状态栏:应显示
Vertices: 1280, Faces: 1280(数值因网格密度略有浮动,但数量级必须一致); - 按
Shift+Z切换线框模式:所有建筑应为封闭六面体,无破面、无悬空边; - 按
W切换为平滑着色:表面应均匀灰度,无马赛克或纯黑区域。
提示:若 MeshLab 报错 “Cannot read material file”,说明
Export materials未勾选或.mtl文件未与.obj同目录——这是 CityEngine 导出模块的已知行为,非用户操作失误。
4. CGA 规则调试避坑:当“编译通过”却不出模型时的五种真实原因
CGA(Computer Generated Architecture)是 CityEngine 的核心语言,但它的报错机制极其隐蔽。很多用户看到 Console 显示Compilation successful就以为万事大吉,结果预览窗口一片空白。以下是我在模拟项目X中记录的真实踩坑案例,按发生频率排序:
4.1 现象:规则编译成功,但建筑面片完全不生成
原因:CGA 脚本中使用了setupProjection()函数,但未在@StartRule前声明@Hidden或@Invisible属性,导致 CityEngine 将投影纹理视为“不可见图层”而跳过渲染。
解决:在规则文件顶部添加:
@Hidden @StartRule Lot --> ...或直接删除setupProjection()调用——除非你明确需要 UV 投影贴图。
4.2 现象:建筑生成,但所有窗户都是黑色方块
原因:规则中调用了texture("windows.jpg"),但该图片文件未放入assets/textures/目录,且 CityEngine 默认启用Strict Texture Loading(2023.0+ 新增安全策略)。
解决:
- 将图片放入
assets/textures/(相对路径必须精确); - 或在规则开头添加:
@TextureSearchPath "assets/textures"; - 终极方案:关闭严格模式——
Window → Preferences → CityEngine → CGA,取消勾选Enable strict texture loading。
4.3 现象:修改规则参数后,模型无变化,重启软件才生效
原因:CityEngine 缓存了.cga文件的 AST(抽象语法树),且默认不监听文件系统变更。
解决:每次修改后,按Ctrl+Shift+F9(Windows)或Cmd+Shift+F9(macOS)强制刷新规则缓存;或在Inspector面板中,点击规则名称右侧的↻刷新按钮。
4.4 现象:使用split(x)分割面片时,部分子面片消失
原因:split操作要求原始面片为凸多边形,而街道自动生成的建筑基底面片在拐角处常为凹多边形(内角 > 180°)。
解决:在split前插入三角剖分:
Lot --> triangulate() # 强制转为三角面片 split(x) { '10 : Building | ~1 : NIL }4.5 现象:Python 脚本调用ce.getAttribute()返回None
原因:该属性未在 CGA 规则中通过setAttr()显式赋值,或属性名拼写与 Inspector 中显示名不一致(如规则中写buildingHeight,Inspector 显示为Building Height)。
解决:在 CGA 规则中显式声明并赋值:
@StartRule Lot --> setAttr("buildingHeight", 30) extrude(30)然后 Python 中调用ce.getAttribute("buildingHeight")。
5. 进阶技巧:用 Python 脚本批量生成参数化街区,绕过手动点击
当需要测试不同容积率、建筑退界、街道宽度组合时,手动调整 Inspector 参数效率极低。CityEngine 内置 Python 控制台(Window → Views → Python Console)可直接调用底层 API,实现参数驱动建模。
5.1 准备可参数化的 CGA 规则
新建文件parametric_lot.cga,内容如下:
// parametric_lot.cga version "2023.0" @StartRule Lot --> // 从属性读取参数,fallback 为默认值 let height = getAttr("buildingHeight", 24) let setback = getAttr("frontSetback", 5) let depth = getAttr("lotDepth", 30) // 根据退界生成建筑基底 setback(setback) { front : NIL | side : NIL | back : NIL | remainder : BuildableArea } BuildableArea --> extrude(height) comp(f) { all : Facade } Facade --> texture("assets/textures/brick.jpg")关键点:
getAttr()的第二个参数是默认值,确保即使未在 Inspector 设置属性,规则也能运行;setback()函数的front/side/back参数名必须与 CityEngine 内置语义匹配,否则退界失效。
5.2 编写批量生成脚本
在 Python Console 中粘贴并执行:
import ce # 加载规则包(路径需替换为你的实际位置) rule_path = "D:/ce_workspace/rules/parametric_lot.cga" ce.importRulePackage(rule_path) # 定义参数组合:[建筑高度, 前退界, 地块进深] params_list = [ [18, 3, 25], [24, 5, 30], [30, 8, 35], [36, 10, 40] ] # 遍历生成 for i, (h, s, d) in enumerate(params_list): # 创建新场景 scene_name = f"district_{i+1}" ce.createScene(scene_name) # 设置地理参考(复用 3.1 步骤) ce.setGeographicLocation(39.9042, 116.4074, 14) # 生成街道网络 ce.createStreetNetwork("Grid", 100, 100, 5, 5) # 为所有街道应用规则 streets = ce.getObjectsFrom(ce.scene, "Street") for street in streets: ce.setRulePackage(street, "parametric_lot.cga", "Lot") ce.setAttribute(street, "buildingHeight", h) ce.setAttribute(street, "frontSetback", s) ce.setAttribute(street, "lotDepth", d) # 导出为 OBJ output_path = f"D:/ce_workspace/exports/{scene_name}.obj" ce.exportModel(output_path, "OBJ", True, True, True) print(f"Exported {scene_name} with h={h}, s={s}, d={d}")逻辑说明:
ce.setAttribute()直接向街道对象注入属性,绕过 Inspector 手动输入;ce.exportModel()的三个布尔值分别对应exportTextures,exportNormals,exportMaterials,必须按顺序传入。脚本执行后,exports/目录下将生成 4 个命名清晰的.obj文件,每个对应一组参数。
5.3 验证导出模型的参数一致性
为防止脚本误传参数,可在导出前加入校验:
# 在 exportModel 前插入 test_street = streets[0] actual_h = ce.getAttribute(test_street, "buildingHeight") print(f"Verified attribute: buildingHeight = {actual_h} (expected {h})") if abs(actual_h - h) > 0.1: raise ValueError(f"Attribute mismatch: expected {h}, got {actual_h}")这样,一旦参数未正确写入,脚本会中断并报错,避免生成大量错误模型。
我习惯在每次批量运行前,先用ce.getAttribute()抽样检查 2~3 个随机街道对象——这招在模拟项目X中帮我们提前发现了一次因路径大小写导致的规则包加载失败(Windows 不敏感,Linux 敏感),省去半天排查时间。希望帮到你。
本文还有配套的精品资源,点击获取