Community
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" }
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)
The C++ code for MtoA uses a AI_TYPE_NODE array, so maybe that's the way.
I haven't tried it yet...
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 )
======================