Tutorial 22: Dynamic imports

To access the tutorial projects in ArcGIS CityEngine, open CityEngine and click Help > Download Tutorials and Examples in the main menu. After choosing a tutorial or example, the project is automatically downloaded and added to your CityEngine workspace.

Palm trees along a road lined with bushes

This tutorial shows you how to use dynamic imports through an example involving the ESRI.lib Plant_Loader. Imagine that you want to insert palm trees along the sides of a road. You'll learn about a common mistake that users make resulting in incorrect tree heights, a tedious way to fix the mistake, and how to fix the mistake using dynamic imports.

A common mistake made by users

When using the Plant_Loader, users often set the name of the plant without knowing that the height and radius will probably be incorrect if they are not set as well. In other words, when setting a desired attribute without knowing that the dependent attributes also need to be set, this often leads to mistakes.

Next, you'll look at this in more detail.

  1. Expand the Tutorial_22_Dynamic_Imports tutorial folder in the Navigator window.
  2. Open the dynamic_imports_01.cej file in the /scenes/ folder to open a scene in the Viewport of a street without any plants:

    Street without plants

  3. Open the dynamic_imports_01.cga rule file in the /rules/ folder to open it in the CGA Editor window.
  4. Import the Plant_Loader from ESRI.lib by adding the following line after the existing import statement:

    import Plant_Loader:"/ESRI.lib/rules/Plants/Plant_Loader.cga" (Representation="LowPoly")

  5. Modify the Tree rule using the Plant_Loader to add trees to the sides of the street:

    Tree -->
    	Plant_Loader.Generate

  6. Save the dynamic_imports_01.cga file.
  7. Select the sidewalk shapes and click Generate Generate (Ctrl+G):

    Street lined with default "Orange Tree".

    Since you did not specify a plant name, the street is lined with the default "Orange Tree". For this tutorial, you want the trees to be "Coconut Palm".

    To see what the scene and rule look like at this point, open the dynamic_imports_02.cej scene and dynamic_imports_02.cga rule file.

  8. Set the plant attribute name to "Coconut Palm" in the Tree rule:

    Tree -->
    	set(Plant_Loader.Name, "Coconut Palm")
    	Plant_Loader.Generate

  9. Save the rule and generate:

    Street lined with correct "Coconut Palm" trees but with wrong height.

    The street is lined with palm trees, but they have the incorrect height and radius because these values come from the default "Orange Tree" name.

    This is because, upon import of the Plant_Loader, the Name attribute is set to "Orange Tree" and the Height and Radius attributes are calculated based on the standard sizes for the "Orange Tree". In the Plant_Loader, the attributes depend on each other. The Height value is calculated based on the Name attribute, and the Radius value is calculated based on the Name and Height attributes.

    Therefore, when you use the set() operation to set Plant_Loader.Name to “Coconut Palm”, it only sets the Name attribute. It does not change or recalculate the values for height and radius, and these attributes still have their original values from the “Orange Tree”.

Fix the mistake the tedious way

By setting only the Name attribute of the plant, you have created palm trees that have the height of an orange tree. To fix the incorrect heights of the palm trees, you can recalculate and set the values for Height and Radius after you set the Name of the plant.

You'll explore this solution next, but keep in mind that this is a tedious method because it requires you to understand the attribute dependencies of the Plant_Loader and know how to recalculate the necessary attributes. This method is complicated and prone to mistakes.

  1. Open the dynamic_imports_03.cej scene and dynamic_imports_03.cga rule file.
  2. In dynamic_imports_03.cga, modify the Tree rule to set the Height and Radius after setting the Name of the plant:

    Tree -->
    	set(Plant_Loader.Name, "Coconut Palm")
    	set(Plant_Loader.Height, Plant_Loader.getStandardHeight)
    	set(Plant_Loader.Radius, Plant_Loader.getRadius)
    	Plant_Loader.Generate

  3. Save and generate.

    Palm trees correctly sized along a road

    Now the palm trees have the correct height and radius, but this is not an easy way to achieve this. This method is complicated because, first, you must know which attributes need to be recalculated and in which order, and second, you must know how to recalculate them.

Fix the mistake with dynamic imports

The recommended way of fixing this mistake is to use dynamic imports. Instead of setting attributes using the set() operation, set the desired attributes in a dynamic import, and any dependent attributes and constants are automatically recalculated. Here is how this works with the Plant_Loader example.

  1. Open the dynamic_imports_04.cej scene and the dynamic_imports_04.cga rule file.
  2. Modify the Tree rule to use a dynamic import that sets the Name attribute to “Coconut Palm”:

    Tree -->
    	Plant_Loader(Name="Coconut Palm").Generate

    The Height and Radius attributes are automatically updated without having to think about it.

  3. Save and generate.

    Palm trees sized correctly using dynamic imports

    The scene is exactly as it was before. The coconut palm trees line the sides of the street and have the correct height and radius. The difference is in the code. With dynamic imports, you set only the attributes you want, and you don’t need to think about attribute dependencies.

  4. Modify the Bush rule to insert rhododendrons along the sidewalks using a dynamic import of the Plant_Loader:

    Bush -->
    	Plant_Loader(Name="Rhododendron Azaleas").Generate

  5. Save and generate.

    Palm trees and bushes along the side of a road

    The same imported Plant_Loader is used to insert palm trees and rhododendron bushes by setting the Name attribute to different values in dynamic imports at different points in the shape tree.

    You can open the dynamic_imports_05.cej scene and dynamic_imports_05.cga file to see the final scene and rule file.

In this tutorial, you learned the following:

  • How a common mistake in which only the plant names are set, causes the plants to be inserted with incorrect heights.
  • How to fix the mistake the tedious way by setting all dependent attributes.
  • How to fix the mistake the recommended way by using dynamic imports to set desired attributes. With this method, dependent attributes are recalculated automatically.

To continue your learning with CityEngine, see the complete CityEngine tutorial catalog.