# Add a Modifier Node

This tutorial will take you through adding your first modifier node to the toybox channel. Modifiers nodes can manipulate 3D objects or other scene components and parameters to introduce variation. Variation is essential for creating large datasets with diverse imagery. Specifically, we’ll be adding a modifier node that will adjust the scale of the objects in the scene.

* [Scaling Objects in Blender](#scaling-objects-in-blender)
  * [Opening Blender](#opening-blender)
  * [Manipulating the Scale](#manipulating-the-scale)
  * [Finding the Python SDK call](#finding-the-python-sdk-call)
* [Adding the Modifier Code](#adding-the-modifier-code)
* [Testing Locally](#testing-locally)
* [Using our new Node in a Graph](#using-our-new-node-in-a-graph)

## Scaling Objects in Blender <a href="#scaling-objects-in-blender" id="scaling-objects-in-blender"></a>

The toybox channel uses Blender to build scenes. All objects are loaded into Blender and can be manipulated using Blender python calls. First we’ll look at Blender to learn what we need to implement to adjust the scale of an object.

### Opening Blender <a href="#opening-blender" id="opening-blender"></a>

For this tutorial, we’ll download Blender from [![](https://www.blender.org/wp-content/themes/bthree/assets/icons/favicon-16x16.png)Download — blender.org](https://www.blender.org/download/). For this tutorial we use Blender 2.90, the same version of Blender that is in the toybox channel environment. It is important to note that Blender python calls can change between versions of Blender. When we first open Blender, we are greeted with a screen similar to the one below:

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2F9zQUBHeXFQoENCnI9WTq%2F85d7c1f6-de94-4f66-a44d-7608ae25aa83.png?alt=media&#x26;token=85b6eac2-af60-4f47-bf53-7f303032102c" alt=""><figcaption><p>Blender Start</p></figcaption></figure>

In this starting scene we have a camera, a light and The next thing we’ll want to do is learn how to manipulate the scale of the Cube object.

### Manipulating the Scale <a href="#manipulating-the-scale" id="manipulating-the-scale"></a>

We can set scale of the Cube object by first selecting the object in the 3D Viewport then setting the Scale properties for the X,Y,Z dimensions under the Object Properties tab. In the example below we set the scale to 5 for each of the dimensions, \[5,5,5].

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FbZSjsM6RLeKPjL39uCDx%2F0cbdd9d0-0028-4469-a25d-b7270e40af1b.png?alt=media&#x26;token=e8344ab5-4c16-449b-84f1-7381a7bf5df2" alt=""><figcaption><p>Blender Scale Property</p></figcaption></figure>

### Finding the Python SDK call <a href="#finding-the-python-sdk-call" id="finding-the-python-sdk-call"></a>

In this example, we want to be able to allow a channel user to configure object scale without having to use Blender. The way to do this is to create a node that will include Blender python calls that modify an object. To figure out the python call to make that will scale an object, we use the Scripting view at the top of the 3D Viewport in Blender. This will provide us with a list of python calls made in the Blender session. The three most recent calls should be the calls we made to scale the Cube object.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FAraO6ojR7HwDpk0fVhsX%2F5fef5e6e-3733-4d6f-b6d4-acf7b4353e8b.png?alt=media&#x26;token=7b8d129c-1f03-4489-918f-b1e38dd0ccb2" alt=""><figcaption><p>Blender Scripting</p></figcaption></figure>

Blender will use the the current context to determine which object to scale, indicated with the _bpy.context.object_ prefix. In the toybox channel, we use the AnaObject class to reference the Blender object. An toybox of how we would set the scale for an AnaObject is shown below:

```python
obj.root.scale = [5,5,5]
```

## Adding the Modifier Code <a href="#adding-the-modifier-code" id="adding-the-modifier-code"></a>

To add the Scale Modifier to the toybox channel we will need to add a few files to the toybox package. The first two files we will add will be the Scale Modifier Node definition and the second will be the Scale Modifier Node schema. These will define the input and outputs of the node and what command will be called when the modifier is used. We create scale\_modifier.py and scale\_modifier.yml under the toybox/packages/toybox/toybox/nodes directory.

**scale\_modifier.py**

```python
from anatools.lib.node import Node
from anatools.lib.generator import ObjectModifier

class ScaleModifier(Node):
    """
    A class to represent the ScaleModifier node, a node that can modify the scale of an object.
    """
    def exec(self):
        generator = ObjectModifier(
            method="scale",
            children=self.inputs["Generators"],
            scale=self.inputs["Scale"][0])
        return {"Generator": generator}
```

**scale\_modifier.yml**

```python
schemas:
  ScaleModifier:
    alias: Scale
    inputs:
    - name: Scale
      description: The scale value to set the objects to.
      default: 1
    - name: Generators
      description: Object Generators to set the scale for.
    outputs:
    - name: Generator
      description: The modified Object Generators
    tooltip: Changes the scale of objects.
    category: Modifiers
    subcategory: Scale
    color: "#B32424"
```

The next file we’ll update is the existing object\_generators.py, where we will update the toybox Channel Object class to add a _scale_ method. In this method is where we will call the Blender object’s scale property, we will be scaling the objects to the same value in all three dimensions.

**object\_generators.py**

```python
class ToyboxChannelObject(AnaObject):
    """
    A class to represent the Toybox Channel AnaObjects.
    Add a 'color' method for the objects of interest.
    """

    def color(self, color_type=None):
        pass

    def scale(self, scale):
        self.root.scale = [scale,scale,scale]
```

Now that our Scale Modifier node has been implemented, we’ll want to test out our code to ensure it runs as planned and we are getting the results we want.

## Testing Locally <a href="#testing-locally" id="testing-locally"></a>

The first thing we’ll do is modify the default graph for the channel to include the scale modifier. In toybox/graphs/default.yml, we will add Scale Modifier to modify the scale of the Rubik’s Cube. We will also replace the Object Placement node’s input for the Rubik’s Cube output with the output from the Scale Modifier.

**default.yml**

```yaml
  ScaleModifier:
    nodeClass: Scale
    values: {Scale: 2}
    links:
      Generators:
        - {sourceNode: "Rubik's Cube", outputPort: "Rubik's Cube Generator"}
        
  ObjectPlacement:
    nodeClass: Random Placement
    values: {Number of Objects: 20}
    links:
      Object Generators:
      - {sourceNode: ColorToys, outputPort: Generator}
      - {sourceNode: ScaleModifier , outputPort: Generator}
      - {sourceNode: Mix Cube, outputPort: Mixed Cube Generator}
```

\
After making these changes, it's time to run Ana again to see what has changed. Note that the example is set to create Rubik’s cubes that are twice as big as the original, all other objects will remain the same size.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FTUk470onO7rIYGWKZ3wT%2F91d132da-3f64-4392-93c4-b0ecc45c4aa8.png?alt=media&#x26;token=80bef808-894d-40f1-b1e0-750eecd3797f" alt=""><figcaption><p>Running the Channel With Scale = 2</p></figcaption></figure>

Let's test again, but this time setting the Scale parameter to 0.5.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FDaM5ff2Y4gD7lsadvB9O%2F402da07f-b18b-4d1e-bf2f-cb50b859524f.png?alt=media&#x26;token=91a1ded3-331c-48f7-bf3b-56624d6ffbf0" alt=""><figcaption><p>Running the Channel With Scale = 0.5</p></figcaption></figure>

If we are happy with the results, its ready to deploy to the platform so we can use the Scale Modifier when creating new datasets.

To deploy a channel, reference the Channel Deployment documentation at[Deploying a Channel](https://dadoes.atlassian.net/wiki/spaces/DG/pages/1614676085). We will be deploying over the custom\_channel in our default Organization in this tutorial.

## Using our new Node in a Graph <a href="#using-our-new-node-in-a-graph" id="using-our-new-node-in-a-graph"></a>

After the channel has successfully deployed, we can use our Modifier in our custom\_channel graphs. In the Nodes section on the left, we should be able to find our Scale Modifier under the Modifiers > Scale category. We will add this node to our graph.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FooXPcmwqhZTRIO4hflEZ%2Fc1d7dc46-b439-40b9-b372-15ae780f52b4.png?alt=media&#x26;token=988913e4-58bd-4d05-ba6d-2dd25a895a4e" alt=""><figcaption><p>Scale Node Category</p></figcaption></figure>

Next we will configure the inputs and outputs of this node, in this case we will connect the Rubik’s Cube to the Generators input and connect the Generators output to the Drop Object node’s.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2F20YvYwl56v1xMICAm8n6%2F62485a5b-381e-4adf-b2fa-0e9921bb4f68.png?alt=media&#x26;token=72eeb802-afc3-4bae-8106-3c22100d7197" alt=""><figcaption><p>Scale Node Used in a Graph</p></figcaption></figure>

After we are happy with the graph we can create our new dataset with scaled objects. Below are some examples of the images from a dataset created with a graph that scaled Skateboards randomly from 1-3.

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2F3D7Zi06qrARFjTNmOYuH%2Fb38221c7-a855-4d0e-bc4e-c3ae29dad906.png?alt=media&#x26;token=1a9b72bc-eceb-487b-b42f-ff08ab447cef" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FpCdL99al40n1Mg3izw1S%2F386b6646-e7f9-4167-88a1-c110c801f7f5.png?alt=media&#x26;token=317a09e5-542e-4e36-9413-ae8927f338b1" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FKH3g87QojGl8QuE6Y8ol%2Fbeae3c12-feb7-44e7-8d23-bfccc4008d2c.png?alt=media&#x26;token=598bab02-abd5-412f-8b83-e62ed7127999" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3091318601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbPMRyh7BHNPMVqv2031A%2Fuploads%2FdLNplryLzxBNA7rBNhJU%2F094b97a4-e64a-490e-82ab-a817714ec219.png?alt=media&#x26;token=7b3f2d23-d2f9-4069-8b6b-7a89ee332eea" alt=""><figcaption></figcaption></figure>

Congratulations, you have created your first modifier node for the toybox channel!
