Work with Metadata and Attribute Nodes

Using Lua to interact with Metadata and Attributes


Visionary Render allows user data to be stored within the scene. This data is in the form of numbers, arrays of numbers, strings and links. The Lua scripting system can be used to create, access and modify these values. These values are available to all scripts within the loaded scene and are saved as part of the scene.


The example below shows a MetaGroup assembly and its children:

-- Drag/Drop section BEGINS - Do not edit between BEGINS and ENDS.
local TableTop = __Script.dragdrop.TableTop
-- Drag/Drop section ENDS

-- print out the current number of wins, losses, and draws

-- calculate number of games
local total = TableTop.MetaData.wins + TableTop.MetaData.loses + TableTop.MetaData.draws

-- calculate percentage wins
local p_wins = TableTop.MetaData.wins / total

-- print percentage wins

-- set the metadata back on the tabletop = total
TableTop.MetaData.percentage_wins = p_wins
Access to these values in the example is through the Metadata assembly but they could be directly modified if they had been dragged and dropped into the script editor individually. They can be modified as with any other assembly property.

If the scene is saved, then these values are saved with it.

This example demonstrates how a script can dynamically create metadata nodes within the scene. It checks for the existence of a MetaData value and if that value is not present it creates it. The script gets the first child of the MetaData assembly then goes through all of its siblings looking at the assembly’s name. The script uses the function vrnode::find to look for an existing node matching the name. If the node does not exist it then calls vrCreateNode with the type of node to create, its name and the parent node. It then initialises that metadata value to 0.

-- Drag/Drop section BEGINS - Do not edit between BEGINS and ENDS.
local TableTop = __Script.dragdrop.TableTop
-- Drag/Drop section ENDS

local found = nil
local name = "goals"

-- check to see if the goals value already exists
local goals = TableTop.MetaData:find(name)

-- if it doesn't exist, create it
if not goals then
   print("Creating goals metadata")
   goals = vrCreateNode("MetaDataInt", name, TableTop.MetaData)
   goals.Value = 0

-- now increment goals by 1
goals.Value = goals.Value + 1

Attribute Tables

The new, more performant attribute tables (generated during CAD import) can also be accessed from Lua.

Values can be accessed directly by key as if it was a property of the attribute table node. Keys and values are always stored as strings, but Lua is quite good at transparently converting these to numbers where appropriate.


Dragging an assembly (e.g 048-037-16B) into the script editor allows us to access its attributes:

print(Assembly__048_037_16B.Metadata.PTC_WM_ITERATION) --prints "6"
Although not generally encouraged for imported CAD attribute data, Lua can also set these values. E.g. to increment the value we printed before:

Assembly__048_037_16B.Metadata.PTC_WM_ITERATION = Assembly__048_037_16B.Metadata.PTC_WM_ITERATION + 1
Each key/value pair in an attribute table uses two properties on the node. These can also be controlled to a limited extent by using vrNodeGetValueByIndex and vrNodeSetValueByIndex

-- count the total number of properties
local propertyCount = vrMetaNodeGetPropertyCount(Assembly__048_037_16B.Metadata:type())
local current = 0

-- print all the keys in the attribute table
while current < propertyCount do
  print(vrNodeGetValueByIndex(Assembly__048_037_16B.Metadata, current))
  current = current + 2

No Results.

Getting StartedArchitectureBest PracticesHow ToAdvanced TopicsChangelogvrtree_cppCoreForeign Function InterfaceMetanodesMigrationsObserversPropertiesTreeUtilitiesAPI DefinitionsVR ExchangePluginsLua API