This tutorial will take you through adding a new object to the example channel. We will use a Volume to store a Blender object and use an Object Generator node to define how the 3D object can be loaded from the Volume. For this tutorial we will use a Spaceship Blender file that we found on Turbosquid, but you are free to use any Blender file you’d like.

Preparing the Blender File

To ensure the Blender object is properly loaded into the scene, we need to make sure the Spaceship Blender file is structured in a way that can be interpreted by the loader. We will also want to verify properties of the object to ensure its position, scale, and physics properties are appropriate. To do this we will start by opening the file in Blender. Blender can be downloaded from https://www.blender.org/download/. In this tutorial we used Blender 2.90 to match the Example channel’s Blender version.

Collection Structure

In Blender, we need to create a Collection (white box) and Parent Object (orange triangle) that share the same name. In this case, we want to call our object Spaceship, so we name both the Collection under Scene Collection and Object Spaceship. Note that we can still have other objects in the Blender file (Camera, Plane, Plane.001) that are not part of our Collection and thus will not be loaded into the scene when the Generator node is called.

Object Properties

Next we’ll ensure that some of the Blender object properties are configured so that the object is compatible with the channel. Things to consider in this step are object placement, size, physics, and materials.


Placement - We want to ensure the object’s center of mass is centered at 0,0,0 in the X, Y and Z coordinates. For the example channel this doesn’t need to be perfect but if it is too far off, the object can fall outside of the container. If your object location is not at [0,0,0] when centered, select the object and apply the Location translation in your 3D Viewport by selecting Object > Apply > Location.


Rotation - Sometimes we care about object rotation so we know the object’s orientation when its loaded into the scene. In the example channel we randomize this parameter so it doesn’t matter so much here.

Scale - Because the example channel objects are toys, we want to scale new objects added to the channel to be toy-sized. Ensure you double-check your units (in this example we are using Metric > Centimeters), and make sure the scale of your object is configured correctly. The measure tool can be helpful. After scaling, if your object isn’t set to [1,1,1] for the scale, select the object and apply the Scale transformation in your 3D Viewport by selecting Object > Apply > Scale.

Object Physics - For this channel we use gravity to drop the objects. We’ll want to enable the Rigid Body Physics under the Physics Properties tab.


Materials - Sometimes we care about the materials for an object, for example the Color Variation node that sets the color of a material is looking for specific property names. For this example we will ignore any material modifications.

Now that we have the object file configured, we can go ahead and save it. For this tutorial, we are saving our file as Spaceship.blend to keep consistent with the object name.

Adding the Object to a Volume

Since your user has Read-Only access to the example channel’s volume, we will need to upload the Blender file to another volume that is owned by your Organization. First we need to create a volume on the Rendered.ai Platform, to learn more about Volumes, see https://dadoes.atlassian.net/wiki/spaces/DG/pages/1576796161/Ana+Software+Architecture#Volumes.

Creating the Volume

To create a volume on the platform we will use create_managed_volume() call in the anatools SDK.

(anatools) anadev@test:/workspaces/example$ python
Python 3.7.7 (default, May  7 2020, 21:25:33) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import anatools
>>> anatools.client()
Enter your credentials for the Rendered.ai Platform.
Email: test@rendered.ai
Password: ********
These are your organizations and workspaces:            
    default Organization                          fca0ef6b-1863-42f4-a2dc-ddd6c248dc95              
        Example                                   6cc85813-844c-4a98-9977-c74c047db3b4                          
Signed into Rendered.ai Platform with test@rendered.ai
The current workspace is: 6cc85813-844c-4a98-9977-c74c047db3b4
>>> client.create_managed_volume(name='custom', organizationId='fca0ef6b-1863-42f4-a2dc-ddd6c248dc95')
'3cabcc67-a398-4bee-aa1d-ecf67a72760f'
PY

The volumeId is returned from the create_managed_volume() call, we will use this value in the next step.

Mounting the Volume

To mount the volume, we’ll first want to add the volume to the example package’s package.yml file at example/packages/example/example/packages.yml. Under the volumes section we will add our new custom volume and under the objects section we will add our Spaceship Blender file.

packages.yml

volumes:
  example: 'df8ad806-223b-4d56-a932-838da835ec62'
  custom: '3cabcc67-a398-4bee-aa1d-ecf67a72760f'

objects:
  YoYo:
    filename: example:LowPoly.blend
  Spaceship:
    filename: custom:Spaceship.blend
YAML

Uploading the Object

Once we have updated the packages.yml file we can re-mount our channel using anamount.

(anatools) anadev@test:/workspaces/example$ anamount
Using channelfile found at ./example.yml.
If this is the wrong channel, specify a channelfile using the --channel argument.
Enter your credentials for the Rendered.ai Platform.
Email: test@rendered.ai
Password: ********
Mounting volume 3cabcc67-a398-4bee-aa1d-ecf67a72760f...complete!
Mounting volume df8ad806-223b-4d56-a932-838da835ec62...complete!
CODE

Notice that after mounting we see two directories under the example/data/volumes/ directory.

To add an file to this volume we can just drag and drop the file into the volume directory in the VSCode Explorer.

Adding the Generator Code

Now that we have our data in the volume, we can add the code to load and use the new object in the channel. To do this we need to add a new Generator node for the object, defining the loading code in the object_generators.py and the node schema in object_generators.yml.

object_generators.py

class Spaceship(Node):
    """
    A class to represent the Spaceship node, a node that instantiates a generator for the Spaceship object.
    """

    def exec(self):
        logger.info("Executing {}".format(self.name))
        return {"Spaceship Generator": get_blendfile_generator("example", ExampleChannelObject, "Spaceship")}
CODE


object_generators.yml

schemas:
  Spaceship:
    alias: Spaceship
    inputs: []
    outputs:
    - name: Spaceship Generator
      description: Spaceship Object
    tooltip: Generator for the Spaceship Object
    category: Objects
    subcategory: Generators
    color: "#246BB3"
YAML

Once we have updated these nodes, we can go ahead and test the implementation to ensure the changes worked as expected.

Testing Locally

To test these code changes, we’ll add the Spaceship object to our default graph and run the ana command. The changes to the example/graphs/default.yml file are shown below:

default.yml

nodes
  Spaceship:
    nodeClass: Spaceship
    
  ObjectPlacement:
    nodeClass: Random Placement
    values: {Number of Objects: 20}
    links:
      Object Generators:
      - {sourceNode: ColorToys, outputPort: Generator}
      - {sourceNode: "Rubik's Cube", outputPort: "Rubik's Cube Generator"}
      - {sourceNode: Mix Cube, outputPort: Mixed Cube Generator}
      - {sourceNode: Spaceship, outputPort: Spaceship Generator}
CODE


Running the ana command will now produce the following output:

(anatools) anadev@test:/workspaces/example$ ana --channel example --graph graphs/default.yml
BASH

After we have tested locally, we can now deploy the changes to the channel to the platform. To deploy a channel, reference the Channel Deployment documentation atDeploying a Channel. We will be deploying over the custom_channel in our default Organization in this tutorial.

Using the new Object in a Graph

After the channel has successfully deployed, we can use our Generator in custom_channel graphs. In the Nodes section on the left, we should be able to find our Spaceship Generator under the Objects > Generators category. We will add this node to our graph.

Next we will configure the inputs and outputs of this node, in this case we will connect the Spaceship node’s Spaceship Generator output to the Object Generators input of the Random Placement node.

After we are happy with the graph we can create our new dataset with the Spaceship objects. Below are some examples of the images from a dataset created with this graph.

Congratulations, you have created your first generator node for the example channel!