Skip to main content

Video: Create a Flow with Blocks

R
Written by Rob Asher
Updated this week

This second video in the three-part series builds on the foundation established in Part 1, guiding you through the development of the flow algorithm. By the end of this video, you'll be equipped to seamlessly integrate your own apartment types into the system.

Creating Dynamic Apartment Layouts with Flows: A Step-by-Step Guide

The YouTube video this article is based on demonstrates a powerful technique for dynamically generating apartment layouts using a flow-based system. This allows for flexible and customizable arrangements of apartment units based on a simple text-based input. This guide breaks down the process, explaining each step and highlighting the key concepts involved in creating this dynamic layout generator.

Keywords: apartment layout, dynamic layout, generative design, flow-based system, instance groups, procedural modeling, JavaScript, parametric design, giraffe

1. Setting the Stage: Blocks and Flows

The foundation of this system lies in pre-defined blocks representing different apartment unit types (e.g., "Unit 1," "Unit 2," "Unit 1C"). These blocks serve as the building blocks for our final layout. The first step is to create a line, using the L key to draw the line. This line acts as the base path along which the apartments will be placed.

Next, a "Flow Editor" is used to create a flow. In this example, the flow is named "Apartment Mixup." The flow is the engine that drives the dynamic layout process, connecting different operations and manipulating the data to achieve the desired arrangement. The flow is attached to the slime.

### 2. Defining Unit Types and Their Widths: The Dictionary

A crucial component is the "dictionary" of unit types. This dictionary maps each unit type (e.g., "1," "2," "1C") to its corresponding width. This mapping enables the system to accurately space and arrange the units along the line. The dictionary is created using a text panel containing a JavaScript object.

Example Dictionary:

```

{

"1": 7.2,

"2": 10.2,

"1C": 7.2

}

```

This dictionary is then passed to a "pass" which converts the text panel into a JavaScript object.

3. Shorthand Input String and String Splitting

The user interacts with the system by providing a shorthand string representing the desired sequence of apartment units. For example, the string "1 2 2 1C" represents an apartment arrangement starting with "Unit 1," followed by two "Unit 2" units, and ending with "Unit 1C."

This string is then converted into a list (or array) using the `string split` command in JavaScript. This split operation breaks the string at each space, resulting in a list of unit type keys.

4. Mapping Unit Keys to Widths: Reading Properties

The next step involves mapping the unit type keys in the list to their corresponding widths from the dictionary. This is achieved using the `map` function. The `map` function iterates over each item (unit key) in the list and performs the same operation on it.

For each unit key, the system reads the corresponding width from the dictionary using the "Read Property" function. The unit key acts as the "property name," and the dictionary is the "object" from which the property is read. This process generates a new list containing the widths of each unit, in the order specified by the input string.

5. Calculating Cumulative Distances: The Power of "Reduce"

To correctly position the apartment units along the line, we need to calculate the cumulative distances. This means determining the starting position of each unit based on the combined widths of all the preceding units. This is where the `reduce` function comes in handy.

The `reduce` function takes a list and reduces it down to a single value. In this case, we're using it to create a new list where each element is the sum of all the preceding widths. This is a more complex application of `reduce` and requires a bit more explanation.

Accumulator: The `reduce` function uses an "accumulator" to store the intermediate results. In this case, the accumulator is an empty array `[]`.

Pop and Push: The process involves popping the last element off the accumulator (the current cumulative distance), adding the next unit width to it, and then pushing the updated distance back into the accumulator. This effectively builds up a list of cumulative distances.

Example:

Input widths: `[7.2, 10.2, 10.2, 7.2]`

Output cumulative distances: `[7.2, 17.4, 27.6, 34.8]`

6. Positioning Units Along the Line: Along Point Transform

With the cumulative distances calculated, we can now position the apartment units along the line. The "Along Point Transform" node is used for this purpose. This node takes a curve (the line) and a percentage along the curve to determine the position and orientation of a point.

Since the "Along Point Transform" requires percentages, the cumulative distances need to be normalized. This is done by dividing each distance by the total length of the curve. This results in a list of percentages representing the position of each unit along the line. This division puts the percentage as a decimal, to represent it as a percentage, it is multiplied by 100.

The calculated percentages are then fed into the "parameters dot percent along" property of the "Along Point Transform" node. This creates points along the curve at the desired locations.

7. Instancing Apartment Units: Instance Group Transform

The final step is to replace the points with the actual apartment unit blocks. This is accomplished using the "Instance Group Transform" node. This node places an instance of a specified group (the apartment unit block) at the location and orientation of a given transform (the points created by the "Along Point Transform").

To ensure the correct apartment unit is instanced at each point, the system needs to map the correct group ID to each point. This is done using a "List Item" node, which retrieves the corresponding group ID from the master list of unit types based on the index of the map function. This ensures that "Unit 1" is placed at the first point, "Unit 2" at the second, and so on. The "parameters dot group ID" property is used to specify the group ID for each instance.

8. Baking and Grouping for Correct Display

After setting up the flow and assigning group IDs, it may be necessary to "bake" certain elements. This involves transferring the flow's effects to the actual geometry. Also the units need to be grouped for easier manipulation.

9. Customization and Fine-Tuning

The system allows for further customization through adjustments to parameters like:

Floor-to-floor height: Modifying the vertical spacing between apartment levels.

Facade: Adjusting properties like "no facads verticals" to control the appearance of the building's facade.

Slab thickness: Modifying the thickness of the floor slabs.

10. Creating Corridors: Offset Polygons

In the final part of the video, the creator offsets the original curve to create a second line parallel to the original, representing a corridor. This offset line is then used to create an additional row of apartments. The "Offset Polygon Transform" node is used to create a polygon representing the corridor's shape.

Did this answer your question?