Skip to main content
Skip table of contents

Workspace Volumes

Volumes contain data that is used by a channel such as 3D models and other content. Most channels implement 'Package Volumes” which are tightly coupled to the package architecture. These volumes are defined in the package.yml file and data for them is uploaded via the SDK or anamount utility by the channel developer.

Users can also create their own volumes that are not tied to packages. This allows them to add custom content to their graphs without having to be channel developers. This type of volume is referred to as a “Workspace Volume” because instead of defining it in a package and uploading data via the SDK, it is managed by the user via the GUI where it is associated with a workspace rather than a package. Uploading data to a workspace volume is done by the user via the GUI so SDK access is not required. To learn more about how this is done, refer to our Creating and Using Volumes tutorial.

VolumeFile Node

Support for workspace volumes must be explicitly built into a channel. To do this, the channel developer must do two things: 1) Add a VolumeFile node to the channel and 2) add VolumeFile support to any node that will accept input from a VolumeFile node.

The “VolumeFile” node is located in the anatools package. This can be included in your channel by adding it to the “add_nodes” section of the channel definition file as shown below:

CODE
channel:
  type: blender

add_setup:
  - example.lib.setup

add_packages:
  - example

add_nodes:
  - package: anatools
    name: VolumeFile

Note that although the node class is VolumeFile, in the GUI the title of the VolumeFile node will be the name of the file that was selected. Here is an example of the GUI which includes a VolumeFIle node titled “NewCube”:

And here is a portion of the graph file that this produces:

CODE
nodes:
  NewCube.blend_0:
    links: {}
    name: NewCube.blend_0
    nodeClass: VolumeFile
    values:
      File: b604ba3b-455a-404c-9330-55cce373861b:/NewCube.blend
  Color Variation_8:
    links:
      Generators:
        - outputPort: File
          sourceNode: NewCube.blend_0
    name: Color Variation_8
    nodeClass: Color Variation
    values:
      Color: Orange

The VolumeFile node has one input called File. The GUI automatically fills this input with the name of the file you selected, prefixed with the volumeId for the volume. The VolumeFile node converts this into an absolute file path and passes it on as an output called “File”. The output is an instance of a class called “FileObject” which has a single attribute called “filename” which contains the absolute file path.

VolumeFile support must be added to any node that will accept input from it. In the above example, the “Color Variation” node must be modified to recognize and process the FileObject sent to it from the VolumeFile node. This processing is channel specific, however there are some helper functions provided by anatools that handle common use cases. The rest of this document describes how this is done in the Example channel.

In the above example, the “Color Variation” node is a modifier that is applied to a generator that it takes as input. Normally this input would come from an object generator node that has been built into the channel. In order to process input from the VolumeFile node, the “Color Variation” node must wrap any FileObjects in an object generator. To do this we use a helper function called “file_to_objgen”.

Here is the code for the “Color Variation” node which includes the call to “file_to_objgen”.

CODE
from example.nodes.object_generators import ExampleChannelObject
from anatools.lib.file_handlers import file_to_objgen
import logging

logger = logging.getLogger(__name__)

class ColorVariationModifier(Node):
    """
    A class to represent the ColorVariationModifier node, a node that can modify the color of an object.
    """

    def exec(self):
        logger.info("Executing {}".format(self.name))

        # wrap any file objects in an object generator
        generators = file_to_objgen(self.inputs["Generators"], ExampleChannelObject)
 
        # add modifier to the generator tree
        try:
            generator = ObjectModifier(
                method="color",  # the object method to use
                children=generators,  # the set of objects to choose from
                color_type=self.inputs["Color"][0])
        except Exception as e:
            logger.error("{} in \"{}\": \"{}\"".format(type(e).__name__, type(self).__name__, e).replace("\n", ""))
            raise

        return {"Generator": generator}

The file_to_objgen function takes two inputs - a list of ObjectGenerators and FileObjects, and a class. The function processes the list, wrapping any FileObjects on the list in an ObjectGenerator. The class parameter is the object class that will be returned by wrapped object generators. The class must be a subclass of AnaObject.

Every node in the channel that can take input from a VolumeFile is modified in a similar manner. In the Example channel this includes all modifiers including the Weight modifier as well as the “Drop Object” node.

If custom FileObject processing is required in your node, you should look at the source code in anatools.lib.file_handlers and implement something similar.

VolumeDirectory Node

Workspace volumes also support adding a full directory to the graph. This is supported by the VolumeDirectory node. Like the VolumeFile node, it must be explicitly supported by the channel. The node must be added to the “add_nodes” section of the channel definition file and any node that could accept input from the VolumeDirectory node must be modified to support it.

Note that if you use the “file_to_objgen” helper function, VolumeDirectory support is built in. In this case, a generator is created for each file in the directory. All of these generators have a weight of 1.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.