import

Syntax

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

Parameters

  1. id

    Unique prefix for the imported rules, attributes and functions.

  2. filePath—string
    Absolute or relative path to a CGA rule file (e.g. "file.cga"). See Asset Search for details about the supported syntax.

Description

Rules, attributes and functions from an existing rule file can be imported by a rule file by the import keyword (syntax 1). Importing a rule file makes all rules, attributes and functions of the imported rule file available prefixed by id. If the imported rule file contains multiple styles, by default all styles are imported and visible in the style manager.

In order to limit the styles available in an importing rule file, the set of imported styles can be specified by enumerating the imported styles in parenthesis after the import id (syntax 2).

By default, attribute values from an importing rule file (e.g. height in main.cga below) are propagated to the imported rule file (e.g. height in structure.cga takes its value from height in main.cga below). In order to disable this default behavior (e.g. because an attribute in an imported rule file has the same name but a different semantic and should therefore not be overwritten), the attributes in an imported rule file can be protected by enumerating them after the rule file (syntax 3).

Attributes can not only be protected but an importing rule file can additionally specify a new value for the attribute by redefining the attribute with an expression (syntax 4) where the right hand side expression is evaluated in the scope of the importing rule file.

Using empty parentheses (syntax 5) protects all imported attributes. Setting the attribute source of an imported attribute in the inspector to something else than "Rule-defined value" will disable this behavior for that attribute completely and the value will be taken from the designated source instead.

Similarly to attributes, rules can be redefined with a sequence of operations (syntax 6) where the right hand side operations is evaluated in the scope of the importing rule file. The redefined rule in the imported rule file must be an extension rule. Within operations any operation, any rule in the current rule file and start rules of imported rule files can be used. An example is given below.

Imports can be annotated to control their attribute presentation in the inspector. See Annotations.

Examples

Import and attribute propagation

This example illustrates how to import rule files, how to reference imported rules (or attributes and functions) and how attribute values are propagated.

Imported rule file

In the following rule file structure.cga the rule Lot performs an extrusion. The extrusion height is specifed by the attribute height. If this rule file is used standalone, the extrusion will be of height 10. If this rule file is imported, height will potentially have a different value.

// structure.cga

attr height = 10

Lot --> extrude(height)

Importing rule file

The following rule file main.cga imports the rule file structure.cga. The rule Init references the rule Lot of structure.cga using the prefix identifier st. Further, an attribute height is defined which potentially overrides the same attribute in imported rule files. Because an attribute height is also defined in structure.cga the value is propagated and the extrusion will be of height 20.

// main.cga

import st : "structure.cga"

attr height = 20

Init --> st.Lot

Extension rule override

This example illustrates how extension rules can be redefined in an import statement and how start rules can be used in redefinitions.

Simple temple model

In the following rule file temple.cga the start rule Temple generates a simple temple model. Each column is generated by the extension rule Column. The roof is generated by the extension rule Roof. The height of the columns is set by the attribute columnHeight. Both extension rules and attributes can be redefined in import statements in order to customize the temple model.

// 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

The resulting model looks like this:

Import temple

Customized columns

In the following rule files corinthianColumn.cga and ionicColumn.cga the rules CorinthianColumn and IonicColumn generate columns in a different manner as the default behavior defined by the rule Column in temple.cga. Both CorinthianColumn and IonicColumn are defined as a start rule and can therefore be used in rule overrides of import statements.

// 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

Customized temple model

The following rule file myTemple.cga imports the rule file temple.cga using the prefix identifier CorinthianTemple and the prefix identifier IonicTemple. In each import statement the attribute columnHeight and extension rules are redefined. The redifinitions of Column invoke the start rules of corinthianColumn.cga and ionicColumn.cga respectively. The redefinition of the Roof rule sets a color and invokes the rule MyRoof in the current ruleset (in the same rule file). Within the Init rule the start rule of temple.cga is invoked. Depending on which prefix identifier is used a different temple model is generated.

// 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)

The resulting models look like this:

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


In this topic