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:
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:
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”.
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.