[Arnold] Standins and the ASS file cache


Did you ever notice the ASS file cache stats in the Arnold log? It’s a breakdown of how many unique ASS files were loaded, and how many were reused:

03:11:33 8868MB | -----------------------------------------------------------------------------------------
03:11:33 8868MB | .ass file cache:
03:11:33 8868MB | unique (loaded from disk)     10 ( 1.00%)
03:11:33 8868MB | reused (found in cache)      990 ( 99.00%)
03:11:33 8868MB | total referenced .ass files 1000 (100.00%)
03:11:33 8868MB | -----------------------------------------------------------------------------------------

Roughly speaking, this caching of standins means that if you have 100 standins that all load the same ASS file, you’ll get one set of geometry and 99 instances of that geometry. That saves memory and I/O time and is just more efficient.

More here…

[Arnold] Loading plugins when you edit ASS files


If you’re using the Arnold API to update ASS files (for example, to change paths), you need to load all the plugins (aka shaders) that are referenced by the ASS file. Otherwise, the unknown nodes are skipped on load, and therefore won’t be in any ASS file you write.

For example, if you set ARNOLD_PLUGIN_PATH to point to the locations of the MtoA shaders and any custom shaders you use, then you could do something like this:

from arnold import *
import os

AiBegin()
AiMsgSetConsoleFlags(AI_LOG_ALL)
AiLoadPlugins( os.getenv( 'ARNOLD_PLUGIN_PATH' ) )
AiASSLoad("original.1001.ass", AI_NODE_ALL)

#
# Do your edits here
#

AiASSWrite("edited.1001.ass", AI_NODE_ALL, False)
AiEnd()

[kick] Combining ASS files on the command line


One way to avoid exporting the same static geometry for every frame is to export it just once, and then export the rest of the scene (the cameras, lights, and any animated objects) as a regular sequence. kick can combine multiple ASS files and then render the result. For example:

kick environment.ass lights.ass character.0001.ass camera.0001.ass -o scene.0001.exr
  • environment.ass is all the static geometry and the applied shaders.
  • camera.####.ass is the camera, driver, filter, and options.
  • character.####.ass is an animated character with its shaders.

Texture search paths


With Arnold there are two things in an ASS file that specify the location of a texture file:

  • The texture filename, which can be an absolute or relative path.
  • The texture_searchpath in the render options. The texture_searchpath is used only if the texture filename is a relative path (for example: “sourceimages/example.tiff”.
  • For example, if the texture filename was a relative path, you might have something like this in an ASS file:

    options
    {
     ...
     texture_searchpath "//server/projects/test"
     ...
    }
    
    MayaFile
    {
     ...
     filename "sourceimages/noicon.png"
     ...
    }
    

    [MtoA] Using standins to load animation sequences


     

    To load an animated sequence into a standin:

    • In the Attribute editor for the StandInShape, under File/Frame, your Path should be something like example.####.ass (you must use four # symbols for the frame number pattern)
    • Enable Use Frame Extension
    • In the Frame box, type “= frame” without the quotation marks, and press ENTER. That creates an expression that uses the current frame number to specify which ASS file to load.

    [SItoA] Expressions for standins of animated sequences


    A standin can load an animation sequence, such as circling_cubes.[1..25].ass.
    For example, if you open an Arnold_Standin property, click Browse, and select a sequence, Softimage automatically inserts a [Frame] token into the file name:

    standin-path

    By default, that [Frame] token resolved to the current frame, but you can override that and use an expression to drive the sequence.

    For example, if you have a 25-frame sequence of ASS files, you may want to play the 25 frames and then stop. To do that, you could use this expression:

     
    MIN(Fc,25)
     
    

    If you wanted to continuously loop the 25 frame sequence, you could use an fmod (modulo) expression like this:

     
    cond( fmod( Fc, 25 ) == 0, 25, fmod(Fc,25) )
     
    

    And if you wanted to show just frames 10 to 25, you could use this expression:

     
    cond( Fc<10 , 10 , MIN(Fc,25) )
     
    

    If you’re not sure about these expressions, try playing with them in the Expression Editor. As you move through the timeline, watch the Current Value update in the Expression Editor.
    fmod_expression

    Just for kicks: Printing out shading trees


    kick -tree prints the shading network for a shader node. For example, given this:

    polymesh
    {
     ...
     shader "Sources.Materials.DefaultLib.Material.standard.SItoA.41000.1" 
     ...
    }
    
    standard
    {
     name Sources.Materials.DefaultLib.Material.standard.SItoA.41000.1
     
    }
    

    You can print out the shader tree for the standard shader like this:

    set ASS_FILE=//Projects/Support/Arnold_Scenes/example.ass
    set NODE=Sources.Materials.DefaultLib.Material.standard.SItoA.41000.1
    set SHADER_PATH=%SITOA_BIN%
    %KICK_PATH%\kick.exe -tree %NODE%  -i %ASS_FILE% -l %SHADER_PATH%
    

    For a [simple] shading tree that looks like this:
    SimpleTree
    You would get this:

    standard:Sources.Materials.DefaultLib.Material.standard.SItoA.41000.1
      |
      +-Kd_color = txt2d_image_explicit:Sources.Materials.DefaultLib.Material.Image.SItoA.41000.2
      |   |
      |   +-tex = sib_image_clip:Sources.Materials.DefaultLib.Material.noIcon_pic.SItoA.41000.3
      |
      +-opacity = txt2d_image_explicit:Sources.Materials.DefaultLib.Material.Image.SItoA.41000.2
          |
          +-tex = sib_image_clip:Sources.Materials.DefaultLib.Material.noIcon_pic.SItoA.41000.3
    
    max depth:       2
    total shaders:   5
    cycles detected: 0
    
    shader counts:
      2 txt2d_image_explicit
      2 sib_image_clip
      1 standard
    
    one-to-many connections:
      2 txt2d_image_explicit:Sources.Materials.DefaultLib.Material.Image.SItoA.41000.2
      2 sib_image_clip:Sources.Materials.DefaultLib.Material.noIcon_pic.SItoA.41000.3
    

    Notice that txt2d_image_explicit and sib_image_clip are counted twice, because those branches are plugged into two different ports on the standard shader.

    Using the attr token in the texture file name attribute of a File node


    In this blog post, I’ll quickly step through an example of how to use the <attr> token in the Maya File node.

    Add a "mtoa_constant_" attribute to the shape node.
    attr_AddAttribute

    Put the name of the texture file in the extra attribute:
    attr_ExtraAttributes

    Use the token in the Image Name. Note that I have a relative path, so I have to make sure that I’ve set a project.
    attr_ImageName

    Now I’ve got something that will render in Maya. If I want to export this to an ASS file and render it with kick, I need to add a Texture Search Path (and optionally, a shader search path if I don’t want to use kick -l).
    attr_SearchPaths

    Here’s the texture-related parts of the exported ASS file:

    options
    {
     ...
     texture_searchpath "[MY_PROJECT_PATH]"
     ...
    }
    
    polymesh
    {
     name pPlaneShape1
     ...
     declare myFileName constant STRING
     myFileName "noicon.png"
    }
    
    standard
    {
     name aiStandard1
     Kd_color file1
    }
    
    MayaFile
    {
     name file1
     filename "/sourceimages/<attr:myFileName>"
    }
    

    Notice how MtoA exported a relative path instead of an absolute. This happens only if you have a token in the filename; otherwise, you always get an absolute path.

    And here’s a screenshot to show all this working, both in Maya and in Arnold:
    attr_Render

    Exporting user data parameters to Arnold from Maya


    You can add attributes to shape nodes in Maya, and MTOA will export those extra attributes as user data in Arnold shape nodes. For example, you use this mechanism to add user data to a procedural node.

    Add some extra attributes to a shape node, using the naming convention mtoa_constant_parameter-name. That is, the attribute name must always start with “mtoa_constant_”.
    AddAttribute

    Export to ASS. In the .ass file, your extra attributes will be declared as user parameters:

    procedural
    {
     name ArnoldStandInShape
     dso "C:/Users/SOLIDANGLE/Dev/MyProcedural.dll"
     min -9.63329697 0 0.861843109
     max -6.73797035 3.62841082 9.87797546
     matrix 
      1 0 0 0
      0 1 0 0
      0 0 1 0
      0 0 0 1 
     declare MyVector constant VECTOR
     MyVector 0 0 0
     declare MyFloat constant FLOAT
     MyFloat 0
     declare MyInteger constant INT
     MyInteger 0
     declare MyBoolean constant BOOL
     MyBoolean off
     declare MyString constant STRING
     MyString ""
    }