[039] Procedural Modeling Practice in Esri CityEngine: Split, Comp, and Extrude
Combine split, comp, and extrude commands to reinforce core CGA concepts through a practical exercise.
This tutorial provides a hands-on exercise to practice the core procedural modeling commands in Esri CityEngine. By constructing a specific architectural form step-by-step, you will learn how local coordinate systems shift during extrusion and how to use the Model Hierarchy to track your progress accurately.
We have concluded our basic lessons on the split command in the previous sessions.
The initial shape for this exercise is a rectangle 30m wide and 10m deep. The bottom edge is designated as the first edge.
We will now tackle the challenge of creating the shape shown below using CGA code. Since we haven't covered scale, translations, or coloring yet, we will focus purely on completing the form.
Target Form Breakdown
If you look at the image above:
1st, extrude the initial shape by 20m.
2nd, divide the left side of the extruded cube into two 10m vertical segments
and extrude the top segment 10m to the left.
3rd, split the top face of the newly extruded volume and extrude the left half
10m upwards.
4th, split the right face of the volume into 5m front and back segments.
5th, further divide the back face into 5m vertical segments.
6th, extrude the top face 10m to the right.
Does it look too simple? While it looks easy, the form often doesn't turn out as expected when you start coding. This shape can be completed using only split, comp, and extrude, so give it a try yourself!
Video: Good music to listen to while coding
Understanding Local Coordinate Changes
I found some music on YouTube that is great for coding; it's quite calming. Were you able to create the suggested form? When I used terms like 'top', 'left', 'right', and 'front' in the step-by-step explanation, applying those literal terms directly in CGA code might result in a completely different shape. This is because these directions are evaluated in the local coordinate system, which are continuously redefined during split and extrude operations.
Let's start by looking at the code.
Lot --> extrude(20) A1
# Extrude the initial shape by 20m and send to A1.
A1 --> comp(f){left : A2 | all : X.}
# Isolate the left face of the cube as A2, leave others as is.
A2 --> split(y){'0.5 : X. | '0.5 : A3}
# Split face vertically 50/50, send top segment to A3.
A3 --> extrude(10) A4
# Extrude by 10m and send the volume to A4.
A4 --> comp(f){back : A5 | all : X.}
# Send the top face (back selector) to A5.
A5 --> split(y){'0.5 : X. | '0.5 : A6}
# Divide face into two halves; send the left segment to A6.
A6 --> extrude(10) A7
# Extrude by 10m and send volume to A7.
A7 --> comp(f){front : A8 | all : X.}
# Send the right face (front selector) to A8.
A8 --> split(x){'0.5 : X. | '0.5 : A9}
# Split face front-to-back; send rear segment to A9.
A9 --> split(y){'0.5 : X. | '0.5 : A10}
# Split face vertically; send top segment to A10.
A10 --> extrude(10) X.
# Extrude final segment by 10m. End.
Step-by-Step Rule Analysis
Let's examine the results of the rules one by one. The output from the Lot is shown below. If an axis is not specified in the extrude command, the face normal determines the extrusion direction.
Phase 1: Initial Extrusion and Face Selection
A1: Let's rotate the view slightly. Using comp(f), we isolate the
left face relative to the first edge as A2.
Let's check this face in the Model Hierarchy. If you activate the three highlighted items in the panel, only the selected face will appear opaque, and its axes will be displayed. You can see that 'left' specified in the comp selector has become A2. Take note of the current face axes; they are X and Y.
Right-Hand Coordinate System
As a reminder, CityEngine uses a right-hand coordinate system.
Essentially, the thumb, index, and middle fingers represent the X, Y, and Z axes, shown in the viewport as R (Red), G (Green), and B (Blue) respectively.
A2: We split A2 vertically. When we checked the A2 face in the Model
Hierarchy, the vertical axis was the Y-axis. This is why we use
split(y) to divide it.
Looking at the Model Hierarchy, we are positioned on the upper split face. The axes are the same as A2, and the first edge is located at the bottom.
A3: Now, we extrude the upper split face by 10m and designate it as A4.
Let's check the extruded volume in the Model Hierarchy. You can see that A4 is a volume, but the axes have changed. The vertical axis for A3 was Y, but after extrusion, the Z-axis is now pointing vertically downwards.
Phase 2: Secondary Extrusion and Top Face Logic
A4: Now it's time to process the top face of A4. To do this, we must know which selector targets the top face. It's easy to mistakenly assume it is 'top' because it looks like it's on the top. This is because front, back, right, and left are determined based on the first edge of the shape used to create the volume.
A4 was created based on A3. As you can see, the bottom edge is the first edge.
Therefore, to select the top-most face in A4, we must use the
back selector. This is because face directions (front, back,
left, right) are defined relative to the first edge of the shape used during
extrusion, not the global up direction. In other words, A4 uses selectors as
follows:
Once you understand this, your coding will become 3.7% easier. A5: Next, we divide the top face left-to-right. First, check the axes of A5 in the Model Hierarchy.
Looking at the axes, we see that we must use the Y-axis for a left-to-right
split. In A2, split(y) was used for vertical division, but as the
axes have changed, the Y-axis is now used for horizontal division. Here is the
result of the split:
Let's confirm if it was divided correctly.
This confirms the split was applied correctly. The axes are the same as before. A6: We extrude the target face by 10m. Let's rotate the view. Now, let's check the axes. The axes have changed again compared to A5, and the Y-axis is once more the vertical axis.
Phase 3: Final Face Operations
A7: Now we need to select the right-hand face relative to the initial shape.
Following the same principle explained for A4, the
front direction relative to A6's first edge targets the face seen
on the right of the screen.
The code would look like this:
Let's confirm if the desired face was correctly isolated.
Success. The correct face has been isolated. Note the axes: X is horizontal, and Y is vertical. A8: Next, we divide this face front-to-back relative to our initial view. The axis used for this split will be... yes, the X-axis.
Let's check the result.
Correct, and the axes are maintained. A9: Now we divide the face vertically once more. The axis for vertical division is Y. You're starting to get the hang of it, right?
Let's check it.
Yes, that's it. A10: Final step. Extrude the target face by 10m.
Key Takeaways
That's it. It's difficult, isn't it? Modelers often say programming is hard, while programmers say coordinate systems are hard. But what can you do? If you want to use it, you have to work hard. This example is actually very, very easy. If we start moving or rotating the axis and scope, things get truly dizzying. Always keep the Model Hierarchy panel open when coding; you must check the pivot and scope at every single step.
Next, we'll cover an example that adds indices and color to today's comp and split techniques. Since indices require case-else statements, I'll explain those briefly as we go.
- Learn street selectors in [038] How to Select Street-Facing Faces with Comp() in CityEngine
- Continue learning with [040] Understanding Object Coordinate Selectors in CityEngine
Comments
Post a Comment
Feel free to leave a comment if you have any questions about Global Mapper or CityEngine. I will get back to you with a sincere response as soon as possible. (Please note that all comments are moderated and manually approved to maintain a high-quality community. Promotional or spam content will not be published.)