import

语法

  1. import id : filePath
  2. import id ( styleId, ... , styleId ) : filePath
  3. import id : filePath ( attrId, ... , attrId )
  4. import id : filePath ( )
  5. import id : filePath ( attrId = expression, ... , attrId = expression )
  6. import id : filePath ( extensionId --> operations, ... , extensionId --> operations )

参数

  1. id
    导入的规则、属性和函数的唯一前缀。
  2. filePathstring
    CGA 规则文件(例如,"file.cga")的绝对路径或相对路径。 有关受支持语法的详细信息,请参阅资产搜索
  3. styleIdidentifier
    要导入的样式
  4. attrIdidentifier
    要保护或覆盖的属性
  5. expression—(float, string, bool, float[], string[], bool[])
    属性值。
  6. extensionIdidentifier
    要覆盖的扩展规则
  7. 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 样式中的属性和规则。
  • 如果在检查器中将已导入属性的属性源设置为“规则默认值”之外的值,则将禁用该属性的任何重新定义行为,并且将从指定的源获取值。

动态导入

动态属性和规则覆盖

  • 属性和规则也可以在规则调用时动态地重新定义。 在以下示例中,静态导入语句不会重新定义 heightheight 的重新定义仅发生在 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)
  • 对于动态导入,将考虑静态导入的任何显式属性或规则覆盖或者属性传播。 可以再次重新定义现有覆盖。 在以下示例中,拉伸 heightRoof 规则都将在静态导入中重新定义。 动态导入将再次重新定义 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.cgaionicColumn.cga 中,规则 CorinthianColumnIonicColumn 以与 temple.cga 中规则 Column 定义的默认行为不同的方式生成列。 CorinthianColumnIonicColumn 都被定义为初始规则,因此可以在 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.cgaionicColumn.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)

生成的模型如下所示:

type == "Corinthian"
type == "Corinthian"
type == "Iconic"
type == "Iconic"

将 PlantLoader 与动态导入配合使用

在以下示例中,ESRI.lib 的 PlantLoader 用于随机插入 3 棵不同的树木。 属性 plant.Name 将在静态导入中重新定义。 对于 PlantLoader 的每次自定义,可以使用单独的导入语句。 树木的尺寸由属性 plant.Heightplant.Radius 定义,并在 Plant_Loader.cga 中根据 plant.Name 自动进行调整。

import bay    : "/ESRI.lib/rules/Plants/Plant_Loader.cga"
                ( Name = "California Bay" )
				
import cedar  : "/ESRI.lib/rules/Plants/Plant_Loader.cga"
                ( Name = "California Incense Cedar" )
				
import walnut : "/ESRI.lib/rules/Plants/Plant_Loader.cga"
                ( Name = "California Walnut" )

Lot --> scatter(surface, 10, uniform) { Plant }

Plant -->  33% : bay.Generate
           33% : cedar.Generate
          else : walnut.Generate
导入植物

可以在动态导入中重新定义属性 plant.Name,而非定义多个静态导入。 由此提供了在运行时动态设置值的灵活性。 将根据 plant.Name 重新初始化所有相关属性(例如 plant.Heightplant.Radius),从而产生正确的树木尺寸。

import plant:"/ESRI.lib/rules/Plants/Plant_Loader.cga"

getName =  33% : "California Bay"
           33% : "California Incense Cedar"
          else : "California Walnut"

Lot --> scatter(surface, 10, uniform) { Plant }

Plant --> plant( Name = getName ).Generate
导入植物