BY-GEN Structured Generators
< BY-GEN
Introduction
Starting with version 6, BY-GEN allows you to build structured generators that can be used to create randomized objects from collections of pre-made parts. There are different types of structured generators to match different use-cases.
Quick-call buttons to start the generation procedures can be found in the BY-GEN - Structured Generation panel.
Loading Templates
In versions 8+ of the BY-GEN addon, you can load templates into the active blend file to simplify the process of setting up your own structural generators using the available algorithms. Options for this can be found in the scene properties tab. These templates will load pre-made collections into your scene which you can then add your own content to.
Layered Generators
This method allows the user to design structures composed of multiple layers of parent-child hierarchies. Each layer is defined as a collection in the outliner. Parent-child hierarchies are constructed via position-reference objects. A configuration text file in the Text Editor must be passed to the generation procedure to inform BY-GEN of which collection to start the generation procedure, as well as to provide override behaviors for each child collection.
The Procedure
Create major collection for the generator.
Create child collections to specify each layer of the generator.
Create objects for each of the collections.
Create child position reference objects for each major object to describe where child objects should go.
Create config text file in the Text Editor window (JSON format).
Create a list of all major generators (usually one per-file, but more are allowed).
Write any necessary behavior overrides for each child collection (mirroring, allowing rotation, etc.)
Run the generator.
World Origin Requirement
The Layered Generator also expects an object to act as the world origin. Just create an empty object and name it 'WorldOrigin'.
Example - Mech Generator
To better explain the procedure, we can take a look at the Mech Generator example (taken from the standalone Mech Generator product available on Gumroad and Blender Market).
Step 1 - Creating Major Collection for the Generator
Notice how we have a collection 'Generator_Mech' which acts as a parent for all of the different layers of objects that compose the mech object. We will tell BY-GEN to only look at 'Generator_Mech' and use its contents during the generation procedure (see step 2).
Each of the child collections contains a variety of objects. If other child objects are intended to connect to these pieces, then position reference objects need to be made for them. Let's take a look at this in more detail.
Position Reference Objects
To tell the following objects in the structure where to go, position reference objects must be created and made children to the parent object. In this example, we can see that a torso piece for the mech has position reference objects to tell BY-GEN where to place objects from Parts_Head, Parts_UpperArmLeft, Parts_UpperArmRight and Parts_UpperLeg.
You may notice that there is only one position reference for the upper leg (unlike the upper arms which have a reference for each side). This is because whereas the upper arms are asymmetrical in thie generator, the upper legs are symmetrical and will be mirrored. Because of this, we only need to generate parts for one side - telling BY-GEN to mirror these parts is done in the config file (see step 2).
Naming Convention
Position reference objects must follow a naming convention. This is how BY-GEN will identify their purpose. The convention is as follows:
pos_CollectionName
If there is a numerical suffix to the end of the name(e.g. pos_CollectionName.123), then BY-GEN will automatically trim that section of the name and ignore it.
When BY-GEN finds each position reference object, it will add it to a temporary database and read from it when it finds a collection that matches the name.
For example, when choosing this torso piece, pos_Parts_Head will be temporarily stored for later use. When the procedure comes to picking an object for the head piece, it will notice that a position reference was already stored for this collection, and then use it to correctly place the selected head piece.
Child objects can also have position reference objects which can lead to further branches of objects. Strictly speaking, you can create a structure that goes into infinity. Imagine a gun with a scope, which has a smaller scope, which (for some reason) has 4 smaller scopes, each of which has a variety of extra scopes, and so on.
Order of Creation
The order of creation is important, from parent to child. Naturally, the torso for a mech needs to be created first because all other parts will fit onto it afterwards. It would not make sense for a foot piece to be created first, as it would end up in the wrong location. For the foot to be placed correctly, the torso must be created first, which created a pos-ref object for the upper leg, which creates a pos-ref object for the lower leg, which conseuqently creates a pos-ref object for the foot.
The order of creation is defined by the order of collections in the inspector.
See, in the example above, how the Parts_Torso collection is placed before all other child object collections.
Step 2 - Create a Config File
For the Layered Generation mode to work properly, you must create a config file in the Text Editor window that provides some information, usually called config.gen
.
Don't let this example image put you off, the minimum needed to start the generator is the following:
{ "generators":["Generator_Mech"] }
This simply tells BY-GEN to start from the 'Generator_Mech' collection and work its way through all of the child collections.
Everything else you would add to this config file would be a behavioral override.
Note: Watch our for commas! JSON requires perfect syntax - commas in incorrect places will prevent the generator from running.
Changing the Output Collection
If you want, you can specify a unique output collection for the created generator inside of the config file by using the following format:
"Generator_Mech":{ "output": "Output Collection" }
If no overriding output collection is specified, BY-GEN will put the results in the default output collection called 'Generation Result'. If this collection does not exist, it creates it for you.
Mirroring Parts
If you want BY-GEN to mirror certain parts, then you can use the following format:
"Parts_UpperLeg":{ "mirror_x": true, "mirror_y": false, "mirror_z": false, "allow_rotation": true }
Allowing Parts Rotation
As you've likely already seen in the examples above, you can allow rotation for selected parts by using the following format:
"Parts_HandRight"{ "allow_rotation": true }
Step 3 - Run the Generator
As stated at the top of this page, you can run the Layered Generation operation by pressing the appropriate button in the BY-GEN - Structured Generation panel. You can also search for it using the search function in Blender (F3).
When calling the operation, a properties window will appear in the bottom-left of the 3D View. Here, you can change the default parameters, including the name of the config file you have created.
When you are ready to begin generating, tick the 'Enable Generation' option, and the operator will begin creating content.
If nothing happens, you have made a mistake during the setup.
Developers can call the operation with: bpy.ops.object.bygen_start_layered_generation()
Branched Generators
This method allows the user to design branching structures composed of randomly selected modules defined for multiple types of three-dimensional junctions. A collection must be specified in the outliner for each type of junction. An example of the branched generator can be found in the standalone Space Station Generator, available on Gumroad and Blender Market.
Unlike the Layered Generation method, Branched Generation does not rely on an embedded configuration text file to tell BY-GEN how to generate new objects.
Instead, when you call Branched Generation, the operator properties window will appear in the bottom-left of the 3D View. In here is where you will tell BY-GEN which collections in the outliner contain the appropriate junctions. Names like Module_L and Module_Straight are chosen as default and can be seen in the example image.
Maximum Modules refers to the mamimum number of pieces that can be generated.
Branch Minimum and Maximum define how long each new branch of the structure can be.
Chance Level defines the probability (0-100) that new branches will grow from pre-existing ones. This has more of a soft influence over the probability rather than an absolute rule.
Allow Spin defines whether certain modules can be rotated 90 or 180 degrees (positive or negative).
Move Offset is the proportional size of a cell.
The Module Collections area of the properties is where you will define which collections contain the appropriate objects for those types of junctions.
Cell Structure
The procedure pretends that each module piece is a 1x1 cube, which makes it easier to connect the pieces together. Objects must be built to fit within a 1x1x1 ratio
Module Origins
The origins for each of the module objects contained in the collections must be placed in the center of the cell. Typically, this would be 0,0,0 (world origin). The default size for cells is 2x2x2 meters, equivalent to the 'Move Offset' value shown in the operator properties above.
Rotational Conventions
For the modules to be rotated correctly to fit the generated structure, a base rotation needs to be agreed for each of the parts before their orientation is altered. To see which way each of the module types should be orientated, I highly recommend downloading the free package of the standalone Space Station Generator from Gumroad.
Extension Details
The branched generation method does allow for the inclusion of modules that have details that extend past the tradition 1x1x1 ratio cell.
This would of course cause intersections issues with neighbouring parts, so an exception has been added where you can tell BY-GEN which modules intrude into neighbouring cells by providing the object name with the ext_
prefix.
For example: ext_Module_Straight
Run the Generator
As stated at the top of this page, you can run the Layered Generation operation by pressing the appropriate button in the BY-GEN - Structured Generation panel. You can also search for it using the search function in Blender (F3).
When you are ready to begin generating, tick the 'Enable Generation' option, and the operator will begin creating content.
If nothing happens, you have made a mistake during the setup.
Developers can call the operation with: bpy.ops.object.bygen_start_branched_generation()
Useful Operations
I have included a couple of operations to help you when rapidly prototyping different generator results. Inside of the BY-GEN - Tools panel, Clear Generation Result and Backup Generation Result can be used to delete all of the objects or make a copy of the 'Generation Result' collection respectively.