question

Markus Ng avatar image
Markus Ng asked

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

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" 
}
pythonapi
10 |600 characters needed characters left characters exceeded

Up to 5 attachments (including images) can be used with a maximum of 2.0 MiB each and 9.8 MiB total.

Stephen Blair avatar image
Stephen Blair answered

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)


1 comment
10 |600 characters needed characters left characters exceeded

Up to 5 attachments (including images) can be used with a maximum of 2.0 MiB each and 9.8 MiB total.

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

0 Likes 0 ·
Markus Ng avatar image
Markus Ng answered

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 )

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


10 |600 characters needed characters left characters exceeded

Up to 5 attachments (including images) can be used with a maximum of 2.0 MiB each and 9.8 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 5 attachments (including images) can be used with a maximum of 2.0 MiB each and 9.8 MiB total.

Welcome to the Arnold Answers community.

This is the place for Arnold renderer users everywhere to ask and answer rendering questions, and share knowledge about using Arnold, Arnold plugins, workflows and developing tools with Arnold.

If you are a new user to Arnold Answers, please first check out our FAQ and User Guide for more information.

When posting questions, please be sure to select the appropriate Space for your Arnold plugin and include the plugin version you are using.

Please include images, scene and log files whenever possible as this helps the community answer your questions.

Instructions for generating full verbosity log files are available for MtoA, MaxtoA, C4DtoA, HtoA, KtoA, and Kick.

If you are looking for Arnold Documentation and Support please visit the Arnold Support site.

To try Arnold please visit the Arnold Trial page.

Bottom No panel present for this section.