Skip to content

Loop Custom Messages

maybites edited this page Feb 7, 2021 · 10 revisions

NodeOsc has from Version 2 onwards the ability to dynamically format and loop over the data-path string.

To expand on the previous example and working with an osc message whose arguments are looking the same:

/objects/Variable/location/xyz Cube 10.0 15.2 -5.3

We can see we receive the message on /objects/Variable/location/xyz.

However, now we want to use one of the arguments and the index of the loop to format the data-path. For this we have to enable 'Format' and the new format-field appears.

Relying on Pythons string format() method, we can now take the arguments tuple to format the data-path. Its worthwhile to have a closer loop at this reference.

You can see the format-field says args[0], index, which means its first value is the first osc-argument (in our case 'Cube') and the second argument is the value of the variable 'index' - more about this one further down.

And looking at the data-path more closely: bpy.data.objects['{0}'].location[{1}], there is a {0} inside the objects-brackets and a {1} inside the location-brackets. Which means we take the first element of the arguments tuple (in our case 'Cube') and put it inside the object-bracket (like in the example before), and we take the second element (in our case the value of 'index') and put it inside the location-bracket.

But we also need to put the whole format and evaluation sequence through an additional loop, so we have to enable the 'Loop'.

The new range-field underneath the args[idx] allows us to control the loop. In this case it loops from 0 to 2 (3 minus 1) in a 1 step increment. -> see python loops with range

the following lines illustrates in python code what NodeOsc is doing behind the scene:

# it creates a variable 'args' containing the tuple from the arguments
args = ('Cube', 10.0, 15.2, -5.3)

# it creates the range tuple to be used inside the range() function
rangeTuple = (0, 3, 1)

# it starts a loop with the range values
for index in range (*rangeTuple):

    # it creates the format tuple to be used inside the format() function
    formatTuple = eval('args[0], index') # here the index value is put into the format tuple

    # it applies the format method on the datapath
    datapath = "bpy.data.objects['{0}'].location[{1}]".format(*formatTuple)
    
    # it creates the new args[idx] tuple to be used further down...
    argIndex = (index + 1) 

...

The resulting datapaths that are used further on are:

bpy.data.objects['Cube'].location[0]
bpy.data.objects['Cube'].location[1]
bpy.data.objects['Cube'].location[2]

the message contains 4 arguments and by setting args[idx] (index + 1), only one value from the osc-arguments will be applied to the datapath, resulting in:

bpy.data.objects['Cube'].location[0] = args[1] (or 10.0)
bpy.data.objects['Cube'].location[1] = args[2] (or 15.2)
bpy.data.objects['Cube'].location[2] = args[3] (or -5.3)