©Anton Podvalny

Table of Contents

"Symmetric" plugins, classes and categories API in Python and Node.js

Disclaimer: This is not a full description of the types, their methods, properties, etc. Only general concepts are described here. For full description of the concrete types and their methods, see the API Reference Guides.

Python

Container objects

Let's have a VRayRenderer instance:

import vray
renderer = vray.VRayRenderer()

Then

renderer.plugins is a container of all plugin instances inside this renderer.

renderer.classes is a container of all plugin classes (or types) loaded into and thus supported by this renderer.

renderer.categories is a container of all plugin categories to which the plugins may belong. This container is not as essential as the other two but it can be quite useful in some cases.

renderer.plugins, renderer.classes and renderer.categories are custom objects that have some dictionary-like features but they are not dictionaries:

  1. They support the mapping protocol (like dictionaries) - the keys in plugins are plugin names, the keys in classes are class names and the keys in categories are category names e.g. renderer.plugins['settingsColorMapping'], renderer.classes['SettingsColorMapping'], renderer.categories['Settings'].
  2. They are iterable but the iteration is performed over the plugin / class / category objects they contain (similar to sets) and not over their names (like dictionaries).
  3. They support access by attribute name so e.g. renderer.plugins.settingsColorMapping returns the same object as renderer.plugins['settingsColorMapping'], renderer.classes.SettingsColorMapping returns the same object as renderer.classes['SettingsColorMapping'] and renderer.categories.Settings returns the same object as renderer.categories['Settings'].
  4. The len() function returns the number of plugin / class / category objects contained in them.

Among these 3 containers (plugins, classes and categories), only plugins support deletion (removing elements). It is important to note that deleting and creating plugin instances during iteration is supported so:

for plugin in renderer.plugins: # This is preferred
  if someCondition:
    # Delete the plugin in plugins. Its reference then becomes invalid and 'plugin' is removed from renderer.plugins
    plugin.deleteThis() # plugin.isValid() will return False after this call
    # Alternative way to delete plugin instances
    # del renderer.plugins[plugin] # use the plugin name or the plugin instance as the key
  if otherCondition:
    # Create a new plugin (with an auto-generated name) inside renderer.plugins
    renderer.classes.Node()

would work exactly the same as:

for plugin in list(renderer.plugins): # This is redundant and slower
  ...

or

for plugin in vray.PluginList(source = renderer.plugins):  # This is redundant and slower 
  ...

but would be more efficient. Newly created plugin instances wouldn't be included in the loop but deleted plugins would be included as invalid references (see plugin.isValid() method).

Container objects may also include methods e.g.

renderer.categories.getInstances((renderer.categories.GeometricObject, renderer.categories.Light))

would return all geometric objects that are lights (or all lights that are also geometric objects, depending on your point of view but it's exactly the same).


Plugin objects, class objects and category objects

These 3 share similar characteristics as well (although category objects are closer to the container objects described above, see their description below).

Plugin objects

The plugin objects are references (or handles) to plugin instances inside a VRayRenderer instance. The plugin parameters are presented as both attributes and keys on the plugin objects. They are always read and written by value which means that when you read them, you get a copy of the whole value contained inside them (even if it's a complex value like a list) and when you write to them, you set a copy of their value inside the corresponding plugin parameter.

Plugin objects act both as plugin handles used to manipulate their plugin parameters (via their attributes, keys or getter/setter methods) and plugin references that can be set as values to other plugin parameters.

Plugin objects are dictionary-like custom types. Iterating over a plugin object iterates over its parameter names similar to dictionaries. Note that this behavior is different from the behavior of the renderer.plugins, renderer.classes and renderer.categories containers where iteration is performed over the values they contain (i.e. plugin, class or category objects) and not the keys.

Besides keys and attributes a plugin object also have methods to perform various actions upon the underlying plugin instance or to query some info about it.

Plugin objects may be (or become) invalid if/when/after the underlying plugin instance is deleted.

PluginRef objects

The PluginRef type is an extension of Plugin. Its whole purpose is to refer to alternative plugin outputs. Some plugins (e.g. textures), when used as inputs to other ones, generate data of a certain type (e.g. AColor) but might have additional outputs (called output parameters and designated by pluginName::outputParamName in the .vrscene files) of other types (e.g. float, int, etc.). A PluginRef object consists of a plugin object and an alternative output parameter of that plugin. While PluginRefs could be used to manipulate the parameters of the underlying plugin, their real purpose is to be used as values of other plugin input parameters.

Have in mind that even if a plugin and a pluginRef object refer to the same plugin instance inside a VRayRenderer, the comparison plugin == pluginRef will be False.
(But plugin == pluginRef.getPlugin() and plugin.getPlugin() == pluginRef.getPlugin() will be True.)

Class objects

Class objects represent the plugin types. They are mostly used to create plugin instances and query some info about the plugin and/or its parameters without creating a plugin instance.


# Create a plugin of type Node with the name 'myNode1' and assign a reference to it to variable node
node = renderer.classes.Node('myNode1')

# Create a plugin of type Node with the name 'myNode2'
renderer.classes.Node('myNode2')

# In both cases the new plugin becomes available in renderer.plugins
node1 = renderer.plugins.myNode1
node2 = renderer.plugins.myNode2

# Comparisons
node == node1 # Compare plugin instances. This would be True
node == node2 # Compare plugin instances. This would be False
node.getClass() == node2.getClass() # Compare plugin classes. This would be True
node.getClass() == renderer.classes.Node # Compare plugin classes. This would be True


Class objects are iterable over the parameter names of the plugin type they represent (similar to plugin objects). Currently accessing the class attributes or keys using the parameter names returns the same data as calling the class.getMeta(paramName) method. But you shouldn't rely on this behavior and should always call the getMeta() method explicitly because the behavior may change in the future.

Class objects also have methods to create or get plugin objects of their type or to query some info about them or their parameters.

Category objects

Category objects group similar plugin types with similar characteristics. They are contained inside renderer.categories. One plugin (instance or class) can belong to none, one or more plugin categories.

The category objects are more akin to the renderer.classes container because they group the plugin classes which belong to them.

Category objects:

  1. Support the mapping protocol (like dictionaries) - their keys are class names e.g. renderer.categories.GeometricObject['Node'].
  2. Are iterable but the iteration is performed over the class objects they contain (similar to sets) and not over the class names (like dictionaries).
  3. Support access by attribute name so e.g. renderer.categories.GeometricObject.Node returns the same object as renderer.categories.GeometricObject['Node'].
  4. Are indexable, which is similar to supporting the sequence protocol. len(category) returns the number of classes belonging to that category.
  5. Have methods to return the plugin objects belonging to them (category.getInstances()) or check if a plugin instance or a class belongs to them (category.belongs(object)).

Node.js

Container objects

Let's have a VRayRenderer instance:

const vray = require('./node/vray');
let renderer = new vray.VRayRenderer;

Then

renderer.plugins is a container of all plugin instances inside this renderer.

renderer.classes is a container of all plugin classes (or types) loaded into and thus supported by this renderer.

renderer.categories is a container of all plugin categories to which the plugins may belong. This container is not as essential as the other two but it can be quite useful in some cases.

renderer.plugins, renderer.classes and renderer.categories are custom objects:

  1. Their properties are the plugin / class / category objects contained in them.
  2. They are enumerable and support for...in loops by keys (i.e. plugin / class / category names).
  3. They are iterable and support for...of loops by values (i.e. the plugin / class / category objects they contain).
  4. They support access by property name e.g. renderer.plugins.settingsColorMapping or renderer.plugins['settingsColorMapping'], renderer.classes.SettingsColorMapping or renderer.classes['SettingsColorMapping'] and renderer.categories.Settings or renderer.categories['Settings'].
  5. Their .length property returns the number of plugin / class / category objects contained in them.
  6. They may have methods which are not included in the enumeration.

Among these 3 containers (plugins, classes and categories), only plugins support deletion (removing elements). It is important to note that deleting and creating plugin instances during iteration is supported so:

for (let plugin of renderer.plugins) { // This is preferred
  if (someCondition {
    // Delete the plugin in plugins. Its reference then becomes invalid and 'plugin' is removed from renderer.plugins
    plugin.deleteThis(); // plugin.isValid() will return false after this call
    // Alternative way to delete plugin instances
    // delete renderer.plugins[plugin]; // use the plugin name or the plugin instance as the key
  }
  if (otherCondition) {
    // Create a new plugin (with an auto-generated name) inside renderer.plugins
    renderer.classes.Node();
  }
}

would work exactly the same as e.g.:

for (let plugin of Array.from(renderer.plugins)) // This is redundant and slower
  ...

but would be more efficient. Newly created plugin instances wouldn't be included in the loop but deleted plugins would be included as invalid references (see plugin.isValid() method).

Container objects may also include methods e.g.

renderer.categories.getInstances([renderer.categories.GeometricObject, renderer.categories.Light]);

would return all geometric objects that are lights (or all lights that are also geometric objects, depending on your point of view but it's exactly the same).


Plugin objects, class objects and category objects

These 3 share similar characteristics as well (although category objects are closer to the container objects described above, see their description below).

Plugin objects

The plugin objects are references (or handles) to plugin instances inside a VRayRenderer instance. The plugin parameters are presented as properties of the plugin objects. They are always read and written by value which means that when you read them, you get a copy of the whole value contained inside them (even if it's a complex value like a list) and when you write to them, you set a copy of their value inside the corresponding plugin parameter (there is one exception, see the note below).

Plugin objects act both as plugin handles used to manipulate their plugin parameters (via their properties or getter/setter methods) and plugin references that can be set as values to other plugin parameters.

Plugin objects are enumerable custom types. for...in looping through a plugin object iterates over its parameter names. For...of loops are not supported.

A plugin object also have methods to perform various actions upon the underlying plugin instance or to query some info about it. Those are not included in the for...in loops.

Plugin objects can be compared with the operator ==. See the example below in the class objects section.

Plugin objects may be (or become) invalid if/when/after the underlying plugin instance is deleted.

Note about large typed lists:
The renderer.maxTypedListsCopyByteSize property controls whether the contents of V-Ray typed lists (currently IntList, FloatList, ColorList and VectorList) is copied to the corresponding plugin parameter. The default value is -1 which means to always copy all the data. If you set it to 0 or a positive number, the contents data won't be copied if its size in bytes is larger than the number set. Instead, it will be directly set inside the V-Ray memory and the underlying ArrayBuffer will be shared between V-Ray and your program.

PluginRef objects

The PluginRef type is an extension of Plugin. Its whole purpose is to refer to alternative plugin outputs. Some plugins (e.g. textures), when used as inputs to other ones, generate data of a certain type (e.g. AColor) but might have additional outputs (called output parameters and designated by pluginName::outputParamName in the .vrscene files) of other types (e.g. float, int, etc.). A PluginRef object consists of a plugin object and an alternative output parameter of that plugin. While PluginRefs could be used to manipulate the parameters of the underlying plugin, their real purpose is to be used as values of other plugin input parameters.

PluginRef objects can be compared with the operator == too. Have in mind that even if a plugin and a pluginRef object refer to the same plugin instance inside a VRayRenderer, the comparison plugin == pluginRef will be false. (But plugin == pluginRef.getPlugin() and plugin.getPlugin() == pluginRef.getPlugin() will be true.)

Class objects

Class objects represent the plugin types. They are mostly used to create plugin instances and query some info about the plugin and/or its parameters without creating a plugin instance.


// Create a plugin of type Node with the name 'myNode1' and assign a reference to it to variable node
var node = renderer.classes.Node('myNode1')

// Create a plugin of type Node with the name 'myNode2'
renderer.classes.Node('myNode2')

// In both cases the new plugin becomes available in renderer.plugins
var node1 = renderer.plugins.myNode1
var node2 = renderer.plugins.myNode2

// Comparisons
node == node1 // Compare plugin instances. This would be true
node == node2 // Compare plugin instances. This would be false
node.getClass() == node2.getClass() // Compare plugin classes. This would be true
node.getClass() == renderer.classes.Node // Compare plugin classes. This would be true


Class objects are enumerable custom types. for...in looping through a class object iterates over the parameter names of the plugin type they represent.

Class objects also have methods to create or get plugin objects of the plugin type they represent, to query some info about the corresponding plugin type and its parameters. Those are not included in the for...in loops.

Class objects can be compared with the operator ==. See the example above.

Currently accessing the class properties using the parameter names returns the same data as calling the class.getMeta(paramName) method. But you shouldn't rely on this behavior and should always call the getMeta() method explicitly because the behavior may change in the future.

Category objects

Category objects group similar plugin types with similar characteristics. They are contained inside renderer.categories. One plugin (instance or class) can belong to none, one or more plugin categories.

The category objects are more akin to the renderer.classes container because they group the plugin classes which belong to them.

Category objects:

  1. Properties are the plugin classes which belong to them.
  2. Are enumerable and support for...in loops by class names.
  3. Are iterable and support for...of loops over the class objects they contain.
  4. Support access by both property name (e.g. renderer.categories.GeometricObject.Node) and index (e.g. renderer.categories.GeometricObject[0], like arrays).
  5. Their .length property returns the number of class objects contained in them.
  6. Have methods to return the plugin objects belonging to them (category.getInstances()) or check if a plugin instance or a class belongs to them (category.belongs(object)).
  7. Can be compared with the operator ==.


  • No labels
Was this helpful?