语法
- import id : filePath
- import id ( styleId, ... , styleId ) : filePath
- import id : filePath ( attrId, ... , attrId )
- import id : filePath ( )
- import id : filePath ( attrId = expression, ... , attrId = expression )
- import id : filePath ( extensionId --> operations, ... , extensionId --> operations )
参数
(注记可以相互组合)
描述
导入并引用规则文件(语法 1 和 2)
- 可以通过 import 关键字导入规则文件。 导入规则文件可以使所导入规则文件的所有规则、属性和函数在导入以 id 为前缀的规则文件中可用。 在以下示例中,main.cga 将导入规则文件 imp.cga。 规则 Lot 使用前缀标识符 imp 引用了 imp.cga 的规则 Lot。
// main.cga import imp : "imp.cga" Lot --> imp.Lot
// imp.cga Lot --> extrude(10)
- 如果导入的规则文件包含多个样式,则默认导入所有样式并在样式管理器中进行显示。 为了限制导入规则文件中的可用样式,可通过以下方式指定导入样式集:在导入 id 后的括号中枚举导入样式。 在以下示例中,拉伸高度将为 20。
// main.cga import imp ( mystyle ) : "imp.cga" Lot --> imp.Lot
// imp.cga Lot --> extrude(10) style mystyle Lot --> extrude(20)
可对导入进行注记以控制其在检查器中的属性演示。 请参阅注记。
属性和规则覆盖
通过传播重新定义属性
- 默认情况下,导入规则文件中的属性值将传播到已导入的规则文件。 在以下示例中,imp.cga 中的拉伸高度由属性 height 指定。 如果单独使用 imp.cga,则拉伸高度将为 10。 如果导入 imp.cga,则 height 将可能具有不同的值。 在 main.cga 中定义了一个属性 height,该属性可能会覆盖已导入规则文件中的相同属性。 由于还在 imp.cga 中定义了属性 height,因此将传播该值,并且拉伸高度为 20。
// main.cga import imp : "imp.cga" attr height = 20 Lot --> imp.Lot
// imp.cga attr height = 10 // set to 20 Lot --> extrude(height)
属性保护(语法 3 和 4)
- 要禁用此默认行为(例如,由于已导入规则文件中的属性名称相同,但语义不同,因此不应进行覆盖),可通过在导入规则文件中的 filePath 后进行枚举来保护已导入规则文件中的属性。
// main.cga import imp : "imp.cga" (height) attr height = 20 Lot --> imp.Lot
// imp.cga attr height = 10 // not changed Lot --> extrude(height)
- 使用空括号可方便地保护所有已导入属性。
// main.cga import imp : "imp.cga" ( ) attr height = 20 Lot --> imp.Lot
// imp.cga attr height = 10 // not changed Lot --> extrude(height)
显式属性和规则覆盖(语法 5 和 6)
- 通过在导入语句内显式重新定义属性,导入规则文件可以为已导入的属性指定一个新值,而非使用属性传播。 右侧 expression 在导入规则文件的范围内进行评估。
// main.cga import imp : "imp.cga" ( height = 20 ) Lot --> imp.Lot
// imp.cga attr height = 10 // set to 20 Lot --> extrude(height)
- 与属性类似,可以使用一系列 operations 重新定义规则,将在导入规则文件的范围内对其进行评估。 已导入规则文件中重新定义的规则必须是扩展规则。 在以下示例中,双坡屋顶将被替换为位于已拉伸几何顶部的四坡屋顶。
// main.cga import imp : "imp.cga" ( Roof --> roofHip(30) ) Lot --> imp.Lot
// imp.cga attr height = 10 Lot --> extrude(height) comp(f) { top = Roof | side = Side. } extension Roof --> roofGable(30)
在 operations 的任何操作中,可以使用当前规则文件中的任何规则和导入规则文件的初始规则。 下面给出了另一个示例。
注:
- 属性传播和显式覆盖仅重新定义 Default 样式中的属性和规则。
- 如果在检查器中将已导入属性的属性源设置为“规则默认值”之外的值,则将禁用该属性的任何重新定义行为,并且将从指定的源获取值。
动态导入
动态属性和规则覆盖
- 属性和规则也可以在规则调用时动态地重新定义。 在以下示例中,静态导入语句不会重新定义 height。 height 的重新定义仅发生在 imp.Lot. 的调用中
// main.cga import imp : "imp.cga" Lot --> imp( height = 20 ).Lot
// imp.cga attr height = 10 // set to 20 Lot --> extrude(height) comp(f) { top = Roof | side = Side. } extension Roof --> roofGable(30)
- 对于动态导入,将考虑静态导入的任何显式属性或规则覆盖或者属性传播。 可以再次重新定义现有覆盖。 在以下示例中,拉伸 height 和 Roof 规则都将在静态导入中重新定义。 动态导入将再次重新定义 height 并接管静态导入的 Roof 覆盖。
// main.cga import imp : "imp.cga"( height = 20, Roof --> roofHip(30) ) Lot --> imp( height = 30 ).Lot
// imp.cga attr height = 10 // set to 30 Lot --> extrude(height) comp(f) { top = Roof | side = Side. } extension Roof --> roofGable(30)
- 可以使用运行时评估值来配置属性和规则覆盖。 在以下示例中,将多次使用静态导入 imp,其中将使用随机评估的值重新定义属性 height。
// main.cga import imp : "imp.cga" Lot --> split(x) { ~10 : Building(5) }* Building(h) --> imp( height = h + rand(10) ).Lot
// imp.cga attr height = 10 // set to 5+rand Lot --> extrude(height) comp(f) { top = Roof | side = Side. } Roof --> roofGable(30)
重新初始化属性
动态导入将在规则调用时重新初始化已导入规则集的所有属性。 在以下示例中,angle 的值取决于 height 的值。 在每次调用 imp.Lot 时,都会根据 height 的新值重新评估属性 angle。 下面给出了另一个示例。
// main.cga import imp : "imp.cga" Lot --> split(x) { ~10 : Building(5) }* Building(h) --> imp( height = h + rand(10) ).Lot
// imp.cga attr height = 10 attr angle = case height > 10 : 0 else : 30 Lot --> extrude(height) comp(f) { top = Roof | side = Side. } Roof --> roofGable(angle)
- 以下示例将使用“空”规则集初始化。 对于动态导入,之前对已导入属性所做的任何更改都不会生效,因为将在静态导入中重新初始化所有属性。
// main.cga import imp : "imp.cga" Lot --> set(imp.height, 20) imp( ).Lot
// imp.cga attr height = 10 // not changed Lot --> extrude(height)
注:
对于动态导入,在任何情况下都会重新定义属性,独立于 Inspector 中已导入属性的当前属性源。相关内容
示例
拉伸规则覆盖
此示例说明了如何在 import 语句中重新定义扩展规则以及如何在重新定义中使用初始规则。
简单庙宇模型
在以下规则文件 temple.cga 中,初始规则 Temple 生成一个简单的寺庙模型。 每个柱子由扩展规则 Column 生成。 屋顶由扩展规则 Roof 生成。 柱子的高度由属性 columnHeight 设置。 扩展规则和属性都可以在 import 语句中重新定义,以自定义庙宇模型。
// temple.cga
attr columnHeight = 12
start Temple --> CreateColumns
CreateRoof
extension Column --> primitiveCube
extension Roof --> roofHip(22)
const columnWidth = columnHeight/9
CreateColumns -->
offset(-columnWidth, border)
comp(f) { all :
extrude(columnHeight)
split(x) {
{ ~columnWidth : Column | ~2*columnWidth : NIL }* | ~columnWidth : NIL
}
}
CreateRoof --> t(0,columnHeight,0) Roof
生成的模型如下所示:
自定义柱子
在以下规则文件 corinthianColumn.cga 和 ionicColumn.cga 中,规则 CorinthianColumn 和 IonicColumn 以与 temple.cga 中规则 Column 定义的默认行为不同的方式生成列。 CorinthianColumn 和 IonicColumn 都被定义为初始规则,因此可以在 import 语句的规则覆盖中使用。
// corinthianColumn.cga
start CorinthianColumn --> split(y) { ~1 : Shaft | '0.1 : Base }
Base --> primitiveCube
Shaft --> s('0.8, '1,'0.8) center(xz) primitiveCube
// ionicColumn.cga
start IonicColumn --> split(y) { '0.1: Base | ~1 : Shaft | '0.1: Base }
Base --> primitiveCube
Shaft --> primitiveCylinder
自定义庙宇模型
以下规则文件 myTemple.cga 使用前缀标识符 CorinthianTemple 和前缀标识符 IonicTemple 导入规则文件 temple.cga。 在每个 import 语句中,将重新定义属性 columnHeight 和扩展规则。 Column 的重新定义分别调用了 corinthianColumn.cga 和 ionicColumn.cga 的初始规则。 Roof 规则的重新定义设置了颜色并调用了当前规则集中的规则 MyRoof(在同一个规则文件中)。 在 Init 规则中调用 temple.cga 的初始规则。 根据使用的前缀标识符,生成不同的庙宇模型。
// myTemple.cga
import CorinthianColumn : "corinthianColumn.cga"
import CorinthianTemple : "temple.cga" (
columnHeight = 8,
Column --> CorinthianColumn.start,
Roof --> color(1,0.5,0.5) MyRoof )
import IonicColumn : "ionicColumn.cga"
import IonicTemple : "temple.cga" (
columnHeight = 16,
Column --> IonicColumn.start,
Roof --> color(1,0.5,0) MyRoof )
@Enum("Corinthian", "Ionic")
attr type = "Corinthian"
Init --> case type == "Corinthian" : CorinthianTemple.start
else : IonicTemple.start
MyRoof --> roofGable(22)
生成的模型如下所示:
将 PlantLoader 与动态导入配合使用
在以下示例中,ESRI.lib 的 PlantLoader 用于随机插入 3 棵不同的树木。 属性 plant.Name 将在静态导入中重新定义。 对于 PlantLoader 的每次自定义,可以使用单独的导入语句。 树木的尺寸由属性 plant.Height 和 plant.Radius 定义,并在 Plant_Loader.cga 中根据 plant.Name 自动进行调整。
| |
可以在动态导入中重新定义属性 plant.Name,而非定义多个静态导入。 由此提供了在运行时动态设置值的灵活性。 将根据 plant.Name 重新初始化所有相关属性(例如 plant.Height 和 plant.Radius),从而产生正确的树木尺寸。
|