[MtoA] mtoa missing from Plug-in Manager


If mtoa.mll is not listed in the Plug-in Manager, that means that Maya did not find the MtoA module file (mtoa.mod). And if you try to manually load mtoa.mll, you’ll get errors like this:

// Error: file: C:/Program Files/Autodesk/Maya2016/scripts/others/pluginWin.mel line 781: Unable to dynamically load : C:/solidangle/mtoadeploy/2016/plug-ins/mtoa.mll
The specified module could not be found. // 
// Error: file: C:/Program Files/Autodesk/Maya2016/scripts/others/pluginWin.mel line 781: The specified module could not be found. (mtoa) //

To load MtoA, you need to make sure that Maya finds the MtoA module file.

By default, the MtoA installer puts the mtoa.mod file in the user’s modules folder. For example:

C:\Users\StephenBlair\Documents\maya\2016\modules

If you installed MtoA using one user account, and try to run Maya with a different user account, Maya will not find the module file.

The module file has to be in the MAYA_MODULE_PATH. For example, for the user account “StephenBlair”, here are the default places where Maya looks for modules:

  • C:/Program Files/Autodesk/Maya2016/modules
  • C:/Users/StephenBlair/Documents/maya/2016/modules
  • C:/Users/StephenBlair/Documents/maya/modules
  • C:/Program Files/Common Files/Alias Shared/Modules/maya/2016
  • C:/Program Files/Common Files/Alias Shared/Modules/maya
  • C:/Program Files/Common Files/Autodesk Shared/Modules/maya/2016

If you want MtoA to available to all users, then you could copy mtoa.mod to one of the common locations.

[MtoA] Adding per-face and per-vertex user data


With Maya and MtoA, there’s no easy way to add per-face and per-vertex user data attributes to objects. You’ve got to do it with scripting: add an array attribute with addAttr and then provide the values. For example, here’s how to add per-face and per-vertex attributes, which MtoA will translate to UNIFORM (per-face) and VARYING (per-vertex) user data on the shape.

import maya.cmds as cmds
# Add UNIFORM (per-face) user data
cmds.addAttr("pPlaneShape1", dataType="vectorArray", longName="mtoa_uniform_myPerPolyColor")
cmds.setAttr("pPlaneShape1.mtoa_uniform_myPerPolyColor", 4,(0.48, 0.39, 0.35), (0.62, 0.63, 0.44), (0.47, 0.69, 0.33), (0.70, 0.38, 0.29), type="vectorArray")

# Add VARYING (per-face vertex) user data
cmds.addAttr("pPlaneShape2", dataType="vectorArray", longName="mtoa_varying_myPerPointColor")
cmds.setAttr("pPlaneShape2.mtoa_varying_myPerPointColor", 9, (0.46, 0.55, 0.66), (0.29, 0.40, 0.38), (0.69, 0.43, 0.68), (0.36, 0.58, 0.55), (0.59, 0.48, 0.27), (0.55, 0.52, 0.70), (0.48, 0.35, 0.26), (0.46, 0.46, 0.47), (0.34, 0.55, 0.31), type="vectorArray" )

After you run the script to add the attributes, you can use the aiUserData shaders to get the user data values and use them in your shader trees.

aiUserDataColor

For example, here’s the per-face and per-vertex user data colors on a simple grid:

uniform_varying_user_data

The case of the blue render view


Reason #35 why you should check the Arnold log

In this case, a scene that used to render yesterday, now just resulted in a blue render view, like this:

blue_render_view

Anytime the render view doesn’t update when your render, you can be fairly sure there’s some ERROR in the Arnold log.

In this case, the problem was a broken path to the IES file used by a photometric light. In the Arnold log, there was this ERROR:

00:00:04 870MB ERROR | [photometric] can't open C:/Assets/IES/example.ies

It’s easy to say “check the log”, but where do you find the log? It’s not like there’s a nice, color-coded button (red for error) on the render view UI that will pop up the log for you.

  • On Windows, you should see the Arnold log in the Output Windows. However, I find that this happens only when I start Maya from the command line. If I start Maya from the Windows Start menu, the Arnold log messages don’t show up in the Output Window. So I have to enable file logging, and check the log file.
  • On OSX and Linux, you’ll also have to enable file logging, unless you start Maya from a terminal.

Update: For Google:

  • Arnold renders a black screen
  • Arnold renders a blue screen

 

[MtoA] MayaFile node uses a default color for missing textures


Here’s something important to remember when you’re debugging a scene…

By default, the MayaFile node uses a default color if a texture is missing.

MayaFile_Use_Default_Color

This means the render won’t abort because of missing textures, and you won’t see ERRORs like these in the Arnold log for missing texture files:

ERROR   |   [texturesys] OpenImageIO could not open "sourceimages/noicon.tx" as tx: Could not open file "sourceimages/noicon.tx"
ERROR   |   [texturesys] Invalid image file "sourceimages/noicon.tx"

So missing textures can easily go unnoticed.

If you need to disable Use Default Color for testing, an easy way is to export an ASS file and then render it with kick -set MayaFile.useDefaultColor false.

I suppose you could also modify the Maya scene file directly:

import maya.cmds as cmds
import os

def set_useDefaultColor(b):
    filenodes=cmds.ls(type="file")
    for item in filenodes:
        cmds.setAttr( "%s.aiUseDefaultColor" % item, b )

set_useDefaultColor( False )

And finally, you can change the default value of the Use Default Color parameter by adding this to shaders/mtoa_shaders.mtd:

[node MayaFile]
	[attr useDefaultColor]
		default		BOOL	false

[MtoA] Instancing lights


If you want to instance lights in Maya, use Duplicate Special. MtoA will correctly translate those instances to Arnold (as copies, not instances, because Arnold itself doesn’t support light instances).

MtoA doesn’t support the particle instancer for lights.

PS I don’t think Maya supports instancing lights with the particle instancer. The Maya docs say “Do not instance lights; they’ll have no effect in rendering.”, and that’s the behavior I’ve observed with mental ray and the Maya Software renderer. Also, if I leave the viewport set to Viewport 2.0, Maya crashes when I try to use the particle instancer with point or spot lights (and that’s without MtoA loaded).

[MtoA] Finding your Arnold log file


When you enable file logging, it can seem a bit of a mystery where the .log files end up. You may find log files in different folders of your project, like the scenes folder, or the sourceimages folder.
mtoa_file_logging
Here’s how it works.

  • If the MTOA_LOG_PATH environment variable is set, the log files are saved to the folder specified by MTOA_LOG_PATH.
  • If MTOA_LOG_PATH is not set, the log files are saved in the current workspace directory (in MEL, that’s workspace -q -directory). In other words, the log files are saved to last place you went with the Maya file browser. If you haven’t used the file browser yet, the log file is saved in the root folder of the project.
  • If you click the folder icon beside the Filename text box, you can choose where the log files are saved.

Note that the log files will always include the frame number, so you’ll get arnold.1.log, arnold.2.log, and so on.

[MtoA] Setting defaults for options and drivers


If you want to set default rendering options, or change the defaults for AOVs, you can use the hook functions provided by mtoadeploy/2015/scripts/mtoa/hooks.py.

hooks.py provides a number of setup functions that MtoA calls during initialization. You can override the default hook functions to do your own custom setup. For example, you could put this Python in your userSetup.py:

import mtoa.hooks

#
# Set some defaults for the defaultArnoldRenderOptions node
#
def setupOptions(options):
    options.AASamples.set(2)
    options.display_gamma.set(1)
    options.light_gamma.set(2.2)
    options.shader_gamma.set(2.2)
    options.texture_gamma.set(2.2)
    options.GITotalDepth.set(6)    
mtoa.hooks.setupOptions = setupOptions    

#
# Enable Merge AOVs for the defaultArnoldDriver and
# any other drivers created later by the user 
#
def setupDriver(driver, aovName=None):
    driver.mergeAOVs.set(1)
mtoa.hooks.setupDriver = setupDriver    

The setupOptions() function gets a pymel.PyNode object that holds the defaultArnoldRenderOptions. setupDriver() gets an aiAOVDriver pynode and the name of the AOV as a string.

Here’s a snippet that shows how to work with the pynode for an aiAOVDriver node.

import pymel.core as pm
driver = pm.PyNode('defaultArnoldDriver')

print driver
print driver.aiTranslator.get()
print driver.mergeAOVs.get()

The case of the disappearing particles


In this case, nParticles (render type = point) weren’t visible behind a refractive plane:
particles_not_visible

For the points render type, you get an Arnold points shape (with mode “disk”), so I exported an ASS file to see the parameter settings on the points node. I noticed the visibility 243 right away (the default visibility is 255, which is visible to all rays). And sure enough, in the Render Stats for the particle shape, some rays were turned off (and the check boxes were disabled too).
particles_render_stats

I used the User Options to force the visibility to 255
particles_useroptions
and the particles behind the refractive surface appeared:
particles_visible

This is a Maya thing. For most particle render types, the particles are not visible in reflections or refractions. It says so in the docs:

You can turn on reflections, refractions, and shadows when you software render Clouds, Tubes, and Blobby Surfaces

I’m not sure where the default values are set, but I did find the AEtemplate code that disables the render stats for all particle render types except the “s/w” type:

// C:\Program Files\Autodesk\Maya2015\scripts\AETemplates\AEparticleLayout.mel
		if( $value == 7 || $value == 8 || $value == 9 ) {
			// software particle type
			editorTemplate -dimControl $nodeName "visibleInReflections" false;
			editorTemplate -dimControl $nodeName "visibleInRefractions" false;
			editorTemplate -dimControl $nodeName "castsShadows"    		false;
			editorTemplate -dimControl $nodeName "receiveShadows" 		false;
			editorTemplate -dimControl $nodeName "primaryVisibility" 	false;
		} else {
			// hardware particle type
			editorTemplate -dimControl $nodeName "visibleInReflections" true;
			editorTemplate -dimControl $nodeName "visibleInRefractions" true;
			editorTemplate -dimControl $nodeName "castsShadows"			true;
			editorTemplate -dimControl $nodeName "receiveShadows" 		true;
			editorTemplate -dimControl $nodeName "primaryVisibility" 	true;
		}

So, since that AE template code just enables and disables UI controls, but doesn’t change the actual values, another way to enable Visible in Refractions (or Visible in Reflections) is to do this:

  1. Change the Particle Render Type to one of the “s/w” types, like Blobby Surface.
  2. Now the Visible in Refractions check box is enabled.
  3. Select the check box.
  4. Go back and change the Particle Render Type to points.

Now when you render, the points are visible to refraction rays, so they show up behind the glass.

[MacOSX] Troubleshooting with dtruss


In a previous post, I looked at how things could go wrong in the file ~/pymel.log wasn’t accessible. On Windows, this was fairly easy to track down using Process Monitor:
pymel.log

On Mac OS X, I had to use dtruss. For example, I ran this command to trace the syscalls of the Maya Render command:

sudo dtruss -f -t open_nocancel -n Render 2> /var/tmp/mtoarender.log

When the render job failed, I checked the log file, and found this line:

11668/0x35deb: open_nocancel("/Users/stephenblair/pymel.log\0", 0x601, 0x1B6) = -1 Err#13

One important gotcha: if you repeat the render, you won’t find any mention of pymel error in the dtruss output. My guess is that at that point, the Render command ends up going through the file system cache, so dtruss doesn’t see the attempt to find pymel.log.

Here’s a quick summary of the dtruss command I showed above:

  • Use sudo to run dtruss, because it needs additional privileges.
  • -f tells dtruss to follow any child processes (like mayabatch) launched by Render
  • -t filters the trace for open_nocancel system calls
  • -n tells dtruss to trace the process named “Render”
  • 2> /var/tmp/mtoarender.log redirects the dtruss output to a file

The case of the “cannot remove alias” RuntimeError


In this case, mayabatch reported some runtime errors when loading a certain scene:

# Traceback (most recent call last):
#   File "C:\solidangle\mtoadeploy\2015\scripts\mtoa\callbacks.py", line 415, in deferredCallback
#     func(*args, **kwargs)
#   File "C:\solidangle\mtoadeploy\2015\scripts\mtoa\aovs.py", line 471, in createAliases
#     pm.aliasAttr(sg + '.ai_aov_' + name, remove=True)
#   File "C:\Program Files\Autodesk\maya2015\Python\lib\site-packages\pymel\internal\pmcmds.py", line 134, in wrappedCmd
#     res = new_cmd(*new_args, **new_kwargs)
# # RuntimeError: 'aiStandardSG.ai_aov_direct_specular' is not a unique name.  Cannot remove alias.

Now, even though I have the advantage of access to the MtoA source code, the problem remained: how do I fix the scene and stop these errors? To find a solution (and understand the problem) I had to resort to examining the Maya ASCII version of the scene.

The “fix” was to clear the AOV names on the shadingEngine node:

setAttr "aiStandardSG.aovs[0].aov_name" -type "string" ""; 
setAttr "aiStandardSG.aovs[1].aov_name" -type "string" ""; 
setAttr "aiStandardSG.aovs[2].aov_name" -type "string" ""; 

The problem is that the shadingEngine node has some named custom AOVs, but no corresponding “attribute alias” list. So the AOV name couldn’t be found in the alias list, which in the error message came out as “not a unique name”.

In the Maya ASCII version of the problem scene, I saw this:

createNode shadingEngine -n "aiStandardSG"; 
	addAttr -ci true -h true -sn "aal" -ln "attributeAliasList" -dt "attributeAlias"; 
	setAttr -s 4 ".aovs"; 
	setAttr ".aovs[0].aov_name" -type "string" "direct_diffuse";
	setAttr ".aovs[1].aov_name" -type "string" "direct_specular";
	setAttr ".aovs[2].aov_name" -type "string" "indirect_diffuse";
	setAttr ".aovs[3].aov_name" -type "string" "indirect_specular";

instead of this:

createNode shadingEngine -n "aiStandard1SG";
	addAttr -ci true -h true -sn "aal" -ln "attributeAliasList" -dt "attributeAlias";
	setAttr ".ihi" 0;
	setAttr ".ro" yes;
	setAttr -s 4 ".aovs";
	setAttr ".aovs[0].aov_name" -type "string" "direct_diffuse";
	setAttr ".aovs[1].aov_name" -type "string" "direct_specular";
	setAttr ".aovs[2].aov_name" -type "string" "indirect_diffuse";
	setAttr ".aovs[3].aov_name" -type "string" "indirect_specular";
	setAttr ".aal" -type "attributeAlias" {"ai_aov_direct_diffuse","aiCustomAOVs[0]",
			"ai_aov_direct_specular","aiCustomAOVs[1]",
			"ai_aov_indirect_diffuse","aiCustomAOVs[2]",
			"ai_aov_indirect_specular","aiCustomAOVs[3]"} ;

I don’t know how the user managed to get the scene into that state 😉