news 2026/5/24 19:20:07

城市仿真软件: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/5/22 12:56:57

12-22 关于顺FENG在数字化转型方向上的思考

很多企业在“数字化转型”这个词上是高度一致的,认为是公司的第二曲线,是讲故事的重要砝码,类似树根互联、卡奥斯以及类似石化盈科、昆仑数智等数科公司比比皆是,但在认知深度与行动方式上,却存在明显分层。在交流中&a…

作者头像 李华
网站建设 2026/4/30 10:57:36

[模式识别-从入门到入土] 组合分类器

[模式识别-从入门到入土] 组合分类器 知乎:https://www.zhihu.com/people/byzh_rc CSDN:https://blog.csdn.net/qq_54636039 注:本文仅对所述内容做了框架性引导,具体细节可查询其余相关资料or源码 参考文章:各方资…

作者头像 李华
网站建设 2026/5/13 18:16:20

记录一个二级Map构建处理赋值简洁写法

//查到数据集合 List<OldpcZzjcqkVo> allData dataWorkParameterMapper.selectAllStatisticsByUnion(dto);// 构建二级Map: workType -> (companyId -> count)Map<String, Map<Long, Integer>> workTypeCompanyCountMap allData.stream…

作者头像 李华
网站建设 2026/5/16 5:20:27

智能体:谷歌A2A协议详解

摘要A2A&#xff08;Agent-to-Agent&#xff09;协议是一种用于智能体&#xff08;Agent&#xff09;之间通信、协作与互操作的标准化协议。随着人工智能技术的发展&#xff0c;尤其是多智能体系统&#xff08;Multi-Agent Systems, MAS&#xff09;在自动驾驶、智能制造、金融…

作者头像 李华
网站建设 2026/5/24 14:02:15

《概率的朋友》,为您的交易系统注入理性基因

引言&#xff1a;量化交易时代的股民梦想在当今数字化、智能化的时代&#xff0c;量化交易已经成为了股票市场的发展方向。股民们都怀揣着一个梦想&#xff0c;那就是在量化交易的领域中取得成功&#xff0c;实现自己的财富自由。《概率的朋友》这本书就像是一座灯塔&#xff0…

作者头像 李华