How to set 'inputs' for the Merge (AiMerge) node with an array of operators in python api

How to set 'inputs' for the Merge (AiMerge) node with an array of operators in python api

markus.ng
Participant Participant
1,119 Views
3 Replies
Message 1 of 4

How to set 'inputs' for the Merge (AiMerge) node with an array of operators in python api

markus.ng
Participant
Participant
I'm trying to set the 'operators' attribute on a procedural node that i'm setting in Arnold Python api.

The following code will return the error:  
============================
# Error: : parameter inputs is an array of type NODE, not STRING # 
============================

My attempt was to create an array of strings and then set the 'inputs' Merge node to the array of strings (list of the names of the operator nodes) 

I can't find any clear docs or examples on how to create an Array of nodes or how to set the 'inputs' for the Merge node.

Thanks!

#================== code starts =======================

from arnold import *

AiBegin()
AiLoadPlugins(os.getenv('ARNOLD_PLUGIN_PATH'))

#ctx = arnoldUtils.AiContext()`
geo_filename = "c:/test/chr_test.ass"
asset_name = "chr_test"
node_name = asset_name

cur_node = AiNode('procedural')
AiNodeSetStr(cur_node, 'name', node_name)
AiNodeSetStr(cur_node, 'filename', geo_filename)
string_replace_win_name = '%s_string_replace_windows'%(node_name)
n_replace_win = AiNode("string_replace")

AiNodeSetStr(n_replace_win, 'name', string_replace_win_name )
AiNodeSetStr(n_replace_win, 'selection', "*")
AiNodeSetStr(n_replace_win, 'match', "/n/")
AiNodeSetStr(n_replace_win, 'replace', "n:/")
AiNodeSetStr(n_replace_win, 'os', "windows")

print "=============== create string_replace lin"
string_replace_linux_name = '%s_string_replace_linux'%(asset_name)
n_replace_linux = AiNode("string_replace")
AiNodeSetStr(n_replace_linux, 'name', string_replace_linux_name )
AiNodeSetStr(n_replace_linux, 'selection', "*")
AiNodeSetStr(n_replace_linux, 'match', "n:/")
AiNodeSetStr(n_replace_linux, 'replace', "/n/")
AiNodeSetStr(n_replace_linux, 'os', "linux")

print "-------------- setup array string"
l_op_str = [string_replace_linux_name,
            string_replace_win_name  ]
num_ops = len(l_op_str)
print "======================AiArrayAllocat:"
# create String object with predetermined size
#operator_AiArray= AiArrayAllocate(num_ops, 1, AI_TYPE_STRING)
operator_AiArray= AiArrayAllocate(num_ops, 1, AI_TYPE_STRING)
cur_index = 0
# populate list
print "before loop"
for cur_op in l_op_str:
    print "adding to aiArray:%s"%cur_op
    AiArraySetStr(operator_AiArray,cur_index,cur_op)
    cur_index +=1
print "=================create AiMerge"

asset_aiMerge_name = "%s_aiMerge"%asset_name
node_aiMerge = AiNode('merge')
AiNodeSetStr(node_aiMerge, 'name', asset_aiMerge_name)
#
AiNodeSetArray(node_aiMerge,"inputs",operator_AiArray)

#============== end code =====================


'''
#Example .ass merge with operators, output as exported MtoA

procedural
{
 name /aiStandIn/aiStandInShape
 visibility 255
 matrix
 1 0 0 0
 0 1 0 0
 0 0 1 0
 0 0 0 1
 override_nodes off
 operator "/aiStandIn/aiStandInShape/input_merge_op"
 filename "N:/render-caches/arnold/grimm/gm01/seq_00999/shot_0555/depts/lgt/geometry/chr_king_c/chr_king_c.0004.ass"
 auto_instancing on
 declare dcc_name constant STRING
 dcc_name "aiStandInShape"
}

string_replace
{
 name fixpath_aiStringReplace1
 selection "*"
 match "/n/"
 replace "n:/"
}

string_replace
{
 name fixpath_aiStringReplace2
 selection "*"
 match "/N/"
 replace "N:/"
}


merge
{
 name chr_test_aimerge
 inputs 2 1 NODE
"fixpath_aiStringReplace1" "fixpath_aiStringReplace2" 
}
0 Likes
1,120 Views
3 Replies
Replies (3)
Message 2 of 4

Stephen.Blair
Community Manager
Community Manager

Here's how I do it for polymesh.shaders, you should be able to do something similar for merge.inputs:

n = AiNode( "polymesh" )

s1 = AiNode( "standard" )
AiNodeSetStr( s1, "name", "aiStandard1" )


s2 = AiNode( "standard" )
AiNodeSetStr( s2, "name", "aiStandard2" )

s3 = AiNode( "standard" )
AiNodeSetStr( s3, "name", "aiStandard3" )


shaders = AiArrayAllocate(3, 1, AI_TYPE_POINTER)
AiArraySetPtr(shaders, 0, s1)
AiArraySetPtr(shaders, 1, s2)
AiArraySetPtr(shaders, 2, s3)

AiNodeSetArray(n, 'shader', shaders)




// Stephen Blair
// Arnold Renderer Support
0 Likes
Message 3 of 4

Stephen.Blair
Community Manager
Community Manager

The C++ code for MtoA uses a AI_TYPE_NODE array, so maybe that's the way.
I haven't tried it yet...



// Stephen Blair
// Arnold Renderer Support
0 Likes
Message 4 of 4

markus.ng
Participant
Participant

Excellent, thx. It's using a combination of

AI_TYPE_POINTER and AiArraySetPtr with the node object to be added.

Thanks for your help!


Here's the working code:

======================

asset_name = "chr_test"
node_name = asset_name

cur_node = AiNode('procedural')
AiNodeSetStr(cur_node, 'name', node_name)
AiNodeSetStr(cur_node, 'filename', geo_filename)
string_replace_win_name = '%s_string_replace_windows'%(node_name)

n_replace_win = AiNode("string_replace")
AiNodeSetStr(n_replace_win, 'name', string_replace_win_name )
AiNodeSetStr(n_replace_win, 'selection', "*")
AiNodeSetStr(n_replace_win, 'match', "/n/")
AiNodeSetStr(n_replace_win, 'replace', "n:/")
AiNodeSetStr(n_replace_win, 'os', "windows")

string_replace_linux_name = '%s_string_replace_linux'%(asset_name)
n_replace_linux = AiNode("string_replace")
AiNodeSetStr(n_replace_linux, 'name', string_replace_linux_name )
AiNodeSetStr(n_replace_linux, 'selection', "*")
AiNodeSetStr(n_replace_linux, 'match', "n:/")
AiNodeSetStr(n_replace_linux, 'replace', "/n/")
AiNodeSetStr(n_replace_linux, 'os', "linux")

l_op_nodes = [n_replace_win,n_replace_linux]
num_ops = len(l_op_str)
operator_AiArray= AiArrayAllocate(num_ops, 1, AI_TYPE_POINTER)
cur_index = 0

for cur_op in l_op_nodes:
	AiArraySetPtr(operator_AiArray,cur_index,cur_op)
	cur_index +=1

my_aiMerge = AiNode('merge')
AiNodeSetStr(my_aiMerge, 'name', "my_aiMerge")
AiNodeSetArray(node_aiMerge,"inputs",operator_AiArray)

AiNodeSetPtr(cur_node, 'operator',my_aiMerge )

======================


0 Likes