[028] How to Select Specific Segments Using split.index in CityEngine

Learn how to use the split.index function to identify and control specific segments within a procedural split operation for precise architectural logic.

This tutorial covers the sequential nature of CGA split operations and demonstrates how to target specific segments using zero-based indexing, allowing for more dynamic and efficient rule writing compared to manual segment definition.

What is split.index in CityEngine CGA?

split.index is a value used to identify the position of each segment generated during a split operation.

Sequential Indexing in Procedural Splits

In our previous sessions, we explored the three types of split(~, *, ') operations.

Today, I intended to cover splitting by rows and columns, but I felt it would be better to pause and discuss the index at this point.

Although we haven't officially learned about axis or scope yet, the split operation works by dividing an area one by one along a designated axis direction.

Having a direction means it starts from a reference point and divides outward in a specific orientation, which implies there is a sequence. It is similar to how you might set a reference point and have people "call out their numbers" to the left or right when lining up at school or in the military.

By referencing this sequence, you can select a specific area that has been split at a particular order.

Take a look at the following diagram. We have divided 100m into 20m segments and colored the fourth split area green.

Dividing 100m into 20m segments
img 1 : Dividing 100m into 20m segments

If we were coding this using only what we have learned so far, it would look something like the following:


Lot1 -->
    split(x){ 20: A | 20: A | 20: A | 20: B | 20: A }

A --> color(1,0,0) X. # Red
B --> color(0,1,0) X. # Green

While splitting by a fixed 20m, pass the fourth segment to the B rule to change its color.

However, you can achieve the same result using split.index. You can think of split.index as a way for the system to internally remember the sequence of the split. Take a look at the code below.

The code syntax is not important at this stage; focus on how split.index is applied in the rule flow.


# Just as all programming languages start counting from 0, split.index starts at 0 and increments sequentially along the split direction.
# The 20m split areas are passed to a rule called BD.
Lot1 --> split(x){ 20: BD }*
# In the BD rule, a case...else statement is used to set a condition on the split order.
# The fourth split area (index == 3) proceeds to the B rule, while the others proceed to the A rule.
BD -->
    case split.index == 3:
        B
    else:
        A

If you look at the result, it is identical.

Identical result using split.index
img 2 : Identical result using split.index

Using split.index with Repeating Splits

How Repeating Splits Generate Multiple Segments

Now, let's implement the above result using a repeating split.


/* Perform a fixed-value repeating split of 20m, then proceed to the BD rule. Since we are repeating a 20m split over a 100m length, there will be a total of 5 divisions. */
Lot2 --> split(x){ 20: BD }*

/* If the split.index value is 3, proceed to rule B; otherwise, proceed to rule A.*/
BD -->
    case split.index == 3:
        B
    else:
        A

The result is—yes, it's the same. Since repeating splits also progress along a designated axis direction anyway, it is possible to code by referencing the split.index value.

Debugging split.index Using print() Function

To verify this visually, let's modify the code.


/* Use the print() command to write the split.index value and the name of the next rule, then check it in the console.*/
BD -->
    case split.index == 3:
        print(split.index + ": B")
        B
    else:
        print(split.index + ": A")
        A
Console output verification
img 3 : Console output verification

You can confirm that it proceeds to B when the split.index value is 3.

Creating Patterns Using Modulo with split.index

Odd and Even Index Control in CGA

Next, let's try making the odd-numbered spaces red and the even-numbered spaces green.


/* If split.index % 2 == 1, the index is odd (1, 3, 5...).
# If split.index % 2 == 0, the index is even (0, 2, 4...).
BD -->
    case split.index % 2 == 1:
        B
    else:
        A

The result is shown below. It's very easy, right?

Odd and Even indexing result
img 4 : Alternating colors using modulo and split.index

Things like the following would also be possible: while using repeating splits, you could color the 5th and 8th floors red, and the 9th and 12th floors yellow. Or, you could paint the 2nd window on the 3rd floor and the 4th window on the 4th floor red, and windows 2 through 8 on the 7th floor blue, and so on.

By using index, case~else, and the Model Hierarchy panel, you can target any specific generated segment or polygon, no matter how complex the split is.

In the next session, we will cover splitting by rows and columns.

"A place for everything, and everything in its place."
— Traditional Proverb
Continue Learning
Explore complete tutorial collections for CityEngine and Global Mapper.

Comments

Popular posts from this blog

029] How to Split Polygon Areas with Intersecting Lines in Global Mapper

[008] How to Understand CGA Rule Structure in CityEngine (Beginner Guide)

046] How to Create Parallel Offset Lines in Global Mapper