We have a script that runs in Maya whenever a file is opened to redirect shader paths to the correct location. Originally this was run as a script job.
The problem I am having is the output that appears in the script editor. With the script job, we might see something like this:
// Error: Effect file “c:/pathSavedInFile/Shaders/cool_shader_dx11.fx” not found. //
Shader: cool_mat - Redirecting shader path from: “c:/pathSavedInFile/Shaders/cool_shader_dx11.fx” to: “d:\pathOnLocalMachine\Shaders”
That is the correct output. The file found a nonexistent path. Then it redirected to an existing path. After converting the scriptJob to a callback, the order is switched:
Shader: cool_mat - Redirecting shader path from: “c:/pathSavedInFile/Shaders/cool_shader_dx11.fx” to: “d:\pathOnLocalMachine\Shaders”
// Error: Effect file “c:/pathSavedInFile/Shaders/cool_shader_dx11.fx” not found. //
This is confusing because it looks like it tried to redirect and failed. But if I look at the shader node, I can see that it is pointing at the new correct path. For some reason the output is just in the wrong order.
Any advice on how to make it print out the results in the correct order? Or just explain why it is doing that in the first place?
Here is another bit of information that may be relevant. The Maya file is referencing another Maya file, and the shader is located in the referenced file.
Is the write order affected if the references in the scene are imported?
My guess would be that a scriptJob is called after a scene is completely opened, and that the API callback for kAfterOpen is called a little earlier than the script job–early enough that its print statements come before Maya’s scene checking output. What happens if you have a script job and an API callback on the same scene? Which prints first?
EDIT:
With the API callback do you see each Callback output paired with an error? Or does all the callback output happen and then all related errors are printed?
Finally figured it out. The hint was in the documentation for the “scriptJob” command: “They are run during idle events.” So my co-worker wondered if I could get my callback to be run during an idle event. And, in fact, there is a way. Just route the call through maya.utils.executeDeferred. Here is the new code:
Another interesting note. The solution with maya.utils.executeDeferred only works because we are running a QtGui.QAplication.instance(). Every now and then, like whenever a file is opened, we call “QtGui.QApplication.processEvents()”. I tried taking out all the calls to “processEvents()”, and the callback no longer fired.