杰瑞科技汇

CityEngine Python如何高效建模?

核心概念:CGA 与 Python 的关系

首先要明确一个关键点:在 CityEngine 中,CGA (计算机生成建筑) 语言是用于生成 3D 模型的核心脚本语言,而 Python 在 CityEngine 中扮演着“元脚本”(Meta-Script)的角色,它不直接生成几何体,而是用来:

CityEngine Python如何高效建模?-图1
(图片来源网络,侵删)
  • 控制 CGA 脚本:动态地修改 CGA 文件中的参数、属性或规则。
  • 管理场景和文件:批量创建、删除、重命名场景中的对象,或读写文件。
  • 自动化工作流:将一系列重复的手动操作(如导入数据、生成模型、导出模型)整合成一个 Python 脚本一键执行。
  • 与外部系统交互:通过 API 获取外部数据(如数据库、Web API),并驱动 CityEngine 场景。

你可以这样理解它们的关系:

  • CGA:是“设计师”,负责根据蓝图(规则)和材料(属性)建造具体的房子(3D模型)。
  • Python:是“项目经理”,负责告诉设计师用什么蓝图、用什么材料、建多少栋房子,并管理整个建筑工地的流程。

Python 脚本的主要应用场景

1 参数化控制

这是最常用的功能,你可以在 CGA 规则中定义参数,然后在 Python 脚本中动态地修改这些参数,从而在不重新编写 CGA 代码的情况下,生成形态各异的建筑。

CGA 示例 (building.cga):

@StartRule
Lot --> extrude(height)  // 使用 height 参数进行拉伸

Python 示例:

CityEngine Python如何高效建模?-图2
(图片来源网络,侵删)
# 获取场景中选中的对象
selected = ce.getSelection()
# 遍历选中的对象
for obj in selected:
    # 获取对象关联的 CGA 规则文件
    rule_file = obj.getRuleFile()
    # 设置 CGA 参数 'height' 的值为 50.0
    ce.setRuleParameters(rule_file, {"height": 50.0})
    # 重新生成模型
    obj.generate()

2 批量处理

当你需要对成百上千个地块或建筑进行统一操作时,Python 的威力就体现出来了。

Python 示例 (批量设置地块高度):

# 获取场景中所有类型为 'Street' 的对象
streets = ce.getObjects("Street")
for street in streets:
    # 获取其关联的规则
    rule_file = street.getRuleFile()
    # 设置参数
    ce.setRuleParameters(rule_file, {"streetWidth": 10.0, "streetHeight": 2.0})
    # 重新生成
    street.generate()
print(f"已处理 {len(streets)} 条街道。")

3 场景与文件管理

Python 可以让你以编程方式管理整个 CityEngine 项目。

Python 示例 (批量导入 Shapefile):

CityEngine Python如何高效建模?-图3
(图片来源网络,侵删)
import os
# 定义要导入的文件夹路径
data_folder = r"C:\path\to\your\shapefiles"
# 遍历文件夹
for filename in os.listdir(data_folder):
    if filename.endswith(".shp"):
        shp_path = os.path.join(data_folder, filename)
        # 创建一个新的图层来导入数据
        layer_name = os.path.splitext(filename)[0]
        new_layer = ce.createLayer(layer_name)
        # 执行导入操作
        ce.importShapefile(new_layer, shp_path)
        print(f"已导入: {shp_path}")
print("所有 Shapefile 导入完成。")

4 自定义工具与 UI

你可以创建带有图形用户界面的 Python 脚本,将其作为插件嵌入到 CityEngine 中,方便非技术人员使用。

Python 示例 (创建一个简单的对话框):

from javax.swing import JOptionPane
# 弹出一个输入对话框
user_input = JOptionPane.showInputDialog(
    ce.getUI(), 
    "请输入建筑高度:", 
    "批量设置高度", 
    JOptionPane.QUESTION_MESSAGE
)
# 检查用户是否点击了“取消”
if user_input is not None:
    try:
        height = float(user_input)
        # 获取选中对象并设置参数 (同上)
        selected = ce.getSelection()
        for obj in selected:
            ce.setRuleParameters(obj.getRuleFile(), {"height": height})
            obj.generate()
        print(f"已将 {len(selected)} 个对象的高度设置为 {height}")
    except ValueError:
        JOptionPane.showMessageDialog(ce.getUI(), "请输入有效的数字!", "错误", JOptionPane.ERROR_MESSAGE)

CityEngine Python API 核心模块

CityEngine 提供了一个强大的 Python API,主要包含以下几个模块:

  • ce: 核心模块,提供最常用的功能,如场景操作、对象管理、规则控制等。90% 的日常操作都通过这个模块完成。
  • ce.gui: 图形用户界面模块,用于创建自定义对话框、按钮等。
  • ce.script: 脚本相关模块,提供一些辅助功能。
  • math, os, sys: Python 标准库,可以直接使用。

ce 模块常用函数列表:

功能类别 函数 说明
场景与图层 ce.getScene() 获取当前场景对象。
ce.createLayer(name) 创建一个新的图层。
ce.getObjects(type) 根据类型(如 "Building", "Street")获取场景中的对象列表。
对象操作 ce.getSelection() 获取当前选中的对象列表。
obj.getShape() 获取对象的几何形状。
obj.getRuleFile() 获取对象关联的 CGA 规则文件路径。
obj.generate() 重新生成对象。
规则与参数 ce.setRuleParameters(rule_file, params_dict) 设置 CGA 文件的参数。params_dict 是一个字典,如 {"height": 30, "color": "red"}
ce.getRuleParameters(rule_file) 获取 CGA 文件的当前参数。
文件与路径 ce.resolvePath(path) 将相对路径解析为绝对路径。
ce.export(filepath, obj, format) 导出对象到指定格式的文件(如 obj, objk, glb)。
UI 交互 ce.getUI() 获取 CityEngine 的主窗口对象。
ce.warning(msg), ce.info(msg) 在 CityEngine 的脚本控制台显示信息或警告。

如何编写和运行 Python 脚本

  1. 打开脚本编辑器:

    • 在 CityEngine 界面顶部菜单栏选择 Windows > Scripting
    • 或者使用快捷键 Ctrl + 6 (Windows/Linux) 或 Cmd + 6 (macOS)。
  2. 编写脚本:

    • 脚本编辑器会打开一个新的 Python 文件。
    • 将上面的示例代码粘贴进去。
  3. 运行脚本:

    • 点击脚本编辑器工具栏上的 "Run" 按钮(一个绿色的播放图标)。
    • 脚本的输出和错误信息会显示在底部的 "Console" 窗口中。

实战案例:创建一个随机城市

这个案例将结合前面提到的知识点,创建一个简单的脚本来批量生成不同高度的建筑。

步骤 1: 准备 CGA 规则 (simple_building.cga)

创建一个简单的 CGA 文件,至少包含一个 height 参数。

@StartRule
Building --> 
    # 将 height 参数赋值给局部变量 h
    h = scope.height 
    extrude(h) 
    # 可以添加一个简单的屋顶
    Roof -->
Roof -->
    primitiveCube() 
    s('1, 1, 0.1) // 缩小一点,作为屋顶
    t(0, 0, scope.sy) // 向上移动到建筑顶部

步骤 2: 在场景中创建一些地块

在 CityEngine 场景中手动创建几个 Building 类型的地块,并将 simple_building.cga 规则文件拖拽到它们上面。

步骤 3: 编写 Python 脚本

在脚本编辑器中运行以下 Python 代码:

import random
# 1. 获取场景中所有类型为 'Building' 的对象
buildings = ce.getObjects("Building")
if not buildings:
    ce.warning("场景中没有找到 'Building' 对象,请先创建一些地块。")
else:
    print(f"找到 {len(buildings)} 个建筑对象,开始处理...")
    # 2. 遍历每个建筑对象
    for i, building in enumerate(buildings):
        # 3. 生成一个随机高度 (20 到 80 米之间)
        random_height = random.uniform(20, 80)
        # 4. 获取该建筑的规则文件
        rule_file = building.getRuleFile()
        # 5. 设置 CGA 参数 'height'
        # 注意:参数名必须与 CGA 文件中的 scope.height 完全一致
        params = {"height": random_height}
        ce.setRuleParameters(rule_file, params)
        # 6. 重新生成建筑模型
        building.generate()
        print(f"建筑 {i+1}/{len(buildings)}: 高度已设置为 {random_height:.2f} 米")
    print("所有建筑随机化完成!")

运行结果: 运行脚本后,你会看到场景中的所有建筑高度都发生了变化,并且每个建筑的高度都是随机生成的,这个简单的例子展示了 Python 如何高效地控制 CGA 规则,实现复杂的批量自动化任务。


CityEngine 的 Python 脚本是连接数据、逻辑和 3D 模型的强大桥梁,它让你能够:

  • 解放生产力:将手动、重复的工作自动化。
  • 实现真正的参数化设计:不仅仅是调整几个滑块,而是通过数据驱动整个场景的生成。
  • 扩展 CityEngine 的能力:通过自定义工具和与外部系统集成,打造专属的工作流。

对于希望从 CityEngine 用户迈向高级用户或技术美术的人来说,熟练掌握 Python 是一项必备技能,建议从简单的参数控制和批量处理开始,逐步尝试更复杂的场景管理和 UI 开发。

分享:
扫描分享到社交APP
上一篇
下一篇