news 2026/7/2 0:15:05

城市仿真软件:CityEngine_(5).规则文件编写

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
城市仿真软件:CityEngine_(5).规则文件编写

规则文件编写

在CityEngine中,规则文件是定义城市模型生成逻辑的核心文件。规则文件使用CityEngine的规则语言(CGA),这是一种基于形状的操作语言,用于描述如何从简单的几何形状生成复杂的三维模型。通过编写规则文件,用户可以控制建筑物、道路、植被等城市元素的生成过程,从而实现高度自定义的城市仿真。

CGA语言基础

语法结构

CGA语言的基本语法结构非常直观。每个规则文件由一个或多个规则(rule)组成,每个规则定义了一组操作,这些操作将应用于特定的形状(shape)。规则文件的扩展名为.cga。以下是一个简单的CGA规则文件示例:

// 定义一个规则文件 @StartRule createBuilding() { // 操作 extrude(10) // 拉伸形状 color("#FF0000") // 设置颜色 split(y) { 0.5 : roof() // 分割形状并应用规则 0.5 : wall() // 分割形状并应用规则 } } roof() { extrude(2) color("#00FF00") } wall() { extrude(8) color("#0000FF") }

基本操作

CGA语言提供了多种基本操作,用于形状的变换和生成。以下是一些常用的操作:

  • extrude(height):将形状沿垂直方向拉伸指定的高度。

  • color(colorCode):设置形状的颜色。

  • split(axis):将形状沿指定轴分割成多个部分。

  • translate(axis, distance):将形状沿指定轴移动指定的距离。

  • scale(axis, factor):将形状沿指定轴缩放指定的比例。

规则应用

规则文件中的规则可以通过以下几种方式应用:

  • @StartRule:指定规则文件的入口规则,当模型生成开始时,这个规则会被首先调用。

  • apply ruleName:在形状上应用指定的规则。

  • call ruleName:调用另一个规则,但不会改变当前形状。

形状属性

形状在CGA语言中可以具有多种属性,这些属性可以在规则中访问和修改。常见的属性包括:

  • attr:自定义属性,用于存储和传递数据。

  • height:形状的高度。

  • width:形状的宽度。

  • depth:形状的深度。

  • center:形状的中心点。

变量和参数

CGA语言支持变量和参数的使用,这使得规则更加灵活和可复用。变量可以在规则中定义和使用,参数可以在规则调用时传递。

变量
// 定义变量 height = 10 createBuilding() { extrude(height) // 使用变量 color("#FF0000") }
参数
createBuilding(height, color) { extrude(height) // 使用参数 color(color) // 使用参数 }

条件判断

CGA语言支持条件判断,可以用于根据特定条件选择不同的操作。

createBuilding(height) { extrude(height) if (height > 10) { color("#FF0000") } else { color("#0000FF") } }

循环

CGA语言支持循环操作,可以用于重复执行一系列操作。

createBuilding(height) { extrude(height) for (i; 0; 5) { translate(y, i * 2) extrude(2) color("#FF0000") } }

高级规则编写

嵌套规则

嵌套规则是指在一个规则中调用另一个规则,从而实现更复杂的模型生成逻辑。

@StartRule createBuilding() { extrude(10) color("#FF0000") split(y) { 0.5 : roof() 0.5 : createWalls() } } createWalls() { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } } roof() { extrude(2) color("#00FF00") } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") }

形状分割

形状分割是CGA语言中非常强大的功能,可以将一个形状沿特定轴分割成多个部分,并对每个部分应用不同的规则。

@StartRule createBuilding() { extrude(10) split(y) { 0.5 : createRoof() 0.5 : createWalls() } } createRoof() { split(x) { 0.5 : roofLeft() 0.5 : roofRight() } } createWalls() { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } } roofLeft() { extrude(2) color("#00FF00") } roofRight() { extrude(2) color("#00FF00") } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") }

形状操作

CGA语言提供了多种形状操作,用于形状的变换和生成。以下是一些高级操作示例:

旋转
rotate(axis, angle) { rotateX(angle) // 沿X轴旋转 rotateY(angle) // 沿Y轴旋转 rotateZ(angle) // 沿Z轴旋转 }
布尔操作

CGA语言支持布尔操作,如并集、差集和交集,用于形状的组合和裁剪。

@StartRule createBuilding() { extrude(10) color("#FF0000") split(y) { 0.5 : createRoof() 0.5 : createWalls() } } createRoof() { extrude(2) color("#00FF00") difference() { extrude(2) // 基础形状 translate(y, -1) extrude(1) // 裁剪形状 } } createWalls() { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") }

形状脚本

形状脚本是CGA语言中的一种高级功能,允许用户编写更复杂的逻辑。形状脚本使用Python语言编写,可以在规则中调用。

定义形状脚本

创建一个Python脚本文件,例如building_script.py,定义一些辅助函数:

# building_script.pydefget_building_height(building_type):ifbuilding_type=="residential":return10elifbuilding_type=="commercial":return20else:return30defget_building_color(building_type):ifbuilding_type=="residential":return"#FF0000"elifbuilding_type=="commercial":return"#00FF00"else:return"#0000FF"
在CGA规则中调用形状脚本
@StartRule createBuilding(building_type) { // 调用Python脚本中的函数 call building_script.get_building_height(building_type) -> height call building_script.get_building_color(building_type) -> color extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls() } } createRoof() { extrude(2) color("#00FF00") } createWalls() { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") }

形状属性的高级用法

形状属性可以用于存储和传递更复杂的数据,例如建筑物的层数、窗户的数量等。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } for (i; 0; num_floors) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"

形状继承

形状继承允许一个规则继承另一个规则的属性和操作,从而减少重复代码。

baseBuilding(height, color) { extrude(height) color(color) } @StartRule createResidentialBuilding() { // 继承baseBuilding规则 call baseBuilding(10, "#FF0000") split(y) { 0.5 : createRoof() 0.5 : createWalls(3) } } createCommercialBuilding() { // 继承baseBuilding规则 call baseBuilding(20, "#00FF00") split(y) { 0.5 : createRoof() 0.5 : createWalls(5) } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } for (i; 0; num_floors) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") }

形状引用

形状引用允许在规则中引用其他形状,从而实现更复杂的模型组合和复用。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } // 引用其他形状 ref building2 = createBuilding("commercial", 4) translate(x, 10) ref building2 } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } for (i; 0; num_floors) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"

形状层次结构

在复杂的城市模型生成过程中,形状层次结构可以帮助组织和管理模型的生成逻辑。通过使用嵌套规则和形状引用,可以创建多层级的形状结构。

@StartRule createCity() { // 创建多个建筑物 ref building1 = createBuilding("residential", 3) translate(x, 10) ref building2 = createBuilding("commercial", 4) translate(x, 10) ref building3 = createBuilding("industrial", 5) } createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } // 创建周围环境 split(x) { 0.5 : createPark() 0.5 : createRoad() } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } for (i; 0; num_floors) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 创建公园 createPark() { extrude(1) color("#008000") } // 创建道路 createRoad() { extrude(1) color("#808080") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"

形状参数化

参数化是CGA语言的一个重要特性,通过参数化可以创建高度灵活的模型生成规则。以下是一个参数化建筑物生成的示例:

@StartRule createBuilding(building_type, num_floors, window_spacing) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors, window_spacing) } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors, window_spacing) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } for (i; 0; num_floors) { translate(y, i * 3) split(x) { 0.25 : createWindow(window_spacing) 0.5 : createWindow(window_spacing) 0.25 : createWindow(window_spacing) } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow(window_spacing) { for (j; 0; 4) { translate(x, j * window_spacing) extrude(1) color("#FFFFFF") } } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"

形状生成的优化

在生成大量形状时,优化规则文件的性能是非常重要的。以下是一些优化技巧:

  • 减少不必要的形状分割:避免在每个形状上进行不必要的分割操作,可以通过参数化和条件判断减少分割次数。

  • 使用缓存:对于重复生成的形状,可以使用缓存来提高生成效率。

  • 优化循环:合理使用循环和条件判断,避免不必要的重复操作。

  • 简化操作:尽量使用简单的操作来实现复杂的效果,减少计算量。

减少不必要的形状分割

在生成复杂模型时,形状分割是常用的手段。然而,过多的分割操作会显著增加计算时间和内存消耗。可以通过参数化和条件判断来减少不必要的分割。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } if (num_floors > 1) { for (i; 0; num_floors - 1) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"
使用缓存

缓存可以用于存储已经生成的形状,避免在后续生成过程中重复计算。CityEngine提供了内置的缓存机制,可以通过cache关键字来使用。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } // 引用缓存的其他形状 ref building2 = cache createBuilding("commercial", 4) translate(x, 10) ref building2 } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } if (num_floors > 1) { for (i; 0; num_floors - 1) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"
优化循环

合理使用循环和条件判断可以显著提高生成效率。避免在循环中进行不必要的操作,可以通过条件判断减少循环次数。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } if (num_floors > 1) { for (i; 0; num_floors - 1) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"
简化操作

尽量使用简单的操作来实现复杂的效果,减少计算量。例如,可以通过组合基本形状来生成复杂的模型,而不是使用大量的布尔操作。

@StartRule createBuilding(building_type, num_floors) { attr height = num_floors * 3 attr color = get_building_color(building_type) extrude(height) color(color) split(y) { 0.5 : createRoof() 0.5 : createWalls(num_floors) } // 创建周围环境 split(x) { 0.5 : createPark() 0.5 : createRoad() } } createRoof() { extrude(2) color("#00FF00") } createWalls(num_floors) { split(x) { 0.25 : wall() 0.5 : door() 0.25 : wall() } if (num_floors > 1) { for (i; 0; num_floors - 1) { translate(y, i * 3) split(x) { 0.25 : createWindow() 0.5 : createWindow() 0.25 : createWindow() } } } } wall() { extrude(8) color("#0000FF") } door() { extrude(2) color("#000000") } createWindow() { extrude(1) color("#FFFFFF") } // 创建公园 createPark() { extrude(1) color("#008000") } // 创建道路 createRoad() { extrude(1) color("#808080") } // 定义一个Python函数 def get_building_color(building_type): if building_type == "residential": return "#FF0000" elif building_type == "commercial": return "#00FF00" else: return "#0000FF"

通过以上优化技巧,可以显著提高CityEngine中规则文件的性能,从而更高效地生成复杂的城市模型。希望这些内容能够帮助你在CityEngine中编写更高效、更灵活的规则文件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 12:10:47

城市仿真软件:CityEngine_(10).建筑物与环境细节优化

建筑物与环境细节优化 在城市仿真软件中,建筑物与环境的细节优化是至关重要的一步,它直接影响到最终场景的真实感和用户体验。本节将详细介绍如何在CityEngine中进行建筑物与环境的细节优化,包括纹理优化、模型优化、光照优化以及环境效果的添…

作者头像 李华
网站建设 2026/6/26 4:49:02

城市仿真软件:CityEngine_(11).城市仿真案例分析

城市仿真案例分析 在前一节中,我们介绍了CityEngine的基本功能和使用方法。接下来,我们将通过具体的案例分析,进一步探讨如何利用CityEngine进行城市仿真。本节将涵盖以下几个方面:案例背景介绍数据准备模型构建规则文件编写仿真运…

作者头像 李华
网站建设 2026/7/1 4:45:36

Python RPA解放Excel生产力

一、环境准备:3行代码搭建自动化工具箱1. 核心库安装必装3件套:pandas:数据处理“瑞士军刀”,1行代码完成数据清洗;openpyxl:轻量级Excel写入工具,适合生成基础报表;xlwings&#xf…

作者头像 李华
网站建设 2026/6/30 6:20:42

Java毕设选题推荐:基于springboot的物流管理系统基于Springboot+Vue智能物流管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/26 8:04:30

基于MATLAB的图像处理实践:当工业零件遇上非均匀光照

标题:基于matlab的图像处理实践 关键词:otsu 非均匀照度 光照补偿 log函数和gamma函数 Dice和Hausdorff测度 工件有孔,无孔进行分类 中心点标记 描述:主要是使用图像处理算法处理非均匀光照图像,进行光照模型补偿&…

作者头像 李华
网站建设 2026/7/1 0:46:27

腾讯地图TMap标记反显,新增标记

功能: 1. 根据省市区获取对于的经纬度,设置为地图的center 2. 如果传入了经纬度,则在地图中反显 3. 根据输入内容,调用接口,获取关联关键字的地址列表,点击列表项后,根据地址经纬度,…

作者头像 李华