Tuesday, June 16, 2009

Bugs in the node soup

Yet another day wasted (and by day I mean 14 hours) trying to work around yet another fucking Maya bug.

Today, I tried to trace the source of this message:

Warning: line 1: Node 'test_JR02004_layout:shot04_v07_pCubeShape12.instObjGroups[0]': cannot make assignment to 'initialShadingGroup' shader.

This warning is misleading. It's actually hiding a more serious error: shader assignments don't stick. When a Maya scene gets into this state, changes you make to shader assignments are not persistent. Why this isn't an error is beyond me.

So, a lighter creates a bunch of shading nodes, assigns them to holdout objects from animation, saves the scene, and launches a render. But when the scene is opened and RIB is generated, no shaders are attached to the objects -- they render in plasticene grey. The lighter comes back the next morning, re-opens their scene, and BAM! Why aren't the shaders attached? Damn, must have forgot. Re-attach, re-launch. Still bad frames.

How does a Maya scene get into this state? I have no idea. Maya adds crap to a scene every time you export or import, and lighting is where all the crap comes together. If anything is going to break, it's going to break in lighting.

Why is this so hard to track down? I blame Maya's complete lack of encapsulation. Any Maya node can (and will) connect to any other Maya node. There is no abstraction or protection. It's a bit like the old days of DOS and Windows 3.1, where any application could corrupt any other application's memory space. Compare that to Windows XP, where each application is isolated in its own space, preventing a single badly behaved program from taking down the whole system.

Maya is the Windows 3.1 of 3D applications.

And worse than that, the problem is essentially that Maya cannot correctly read files it itself generated! Unacceptable.

And how are we going to solve this problem? By working around it. This is production -- we can't afford to wait 6 months for Autodesk to fix a bug. So, we're doing a complete end-run around shader attachment and exporting compiled shaders. Thank fuck we have that option -- if we were using Mental Ray we'd be truly buggered.

So now I have to write a tool to export and manage individual shaders. Those tools will inevitably have bugs, too, so we're stuck supporting a hack around something that software celebrating its 10th anniversary should have figured out long ago.

Wednesday, June 10, 2009

A few words on global namespaces

Stupid. Stupid stupid stupid stupid stupid.

That is all.

Monday, June 8, 2009

FAIL of the day

Since Maya's asset management is so piss-poor, studios end up building scripts and plug-ins to do the job. Let me backtrack a bit and describe how Maya's asset management works.

A Maya scene is a collection of nodes, attributes on nodes, and connections between attributes. There are a few other little details, such as plug-ins, DAG paths, references and namespaces, but that's essentially it.

There are two ways to split work between two scene files. The first is to just import the scene into your scene. This loads all the nodes (and connections and attributes) and prepends a namespace in front of all the node names to prevent name clashes. The second is called a reference. It does the same thing as an import, but links all of the nodes to a reference node as well. A reference node is a special node that tells Maya to load a bunch of nodes from another file. That way, you can refresh the reference. But, since Maya allows connections between any node, referenced nor not, provision must be made for changes to referenced nodes. It handles this by adding another, invisible blob of data called reference edits. These store changes to referenced nodes. References can be nested as well, so you can imagine how complex reference edits can get.

But I digress.

This morning I'm trying to build a scene that is basically a collection of references to other scenes. I'm using a simple MEL script to references a bunch of textured models, apply some geocached animation to them, and load the camera and set from layout. Seems simple enough. But, but, but... it fails. It spits out the usual screenfuls of dubious warnings, then segfaults.

Thinking that maybe some of our custom plug-ins were responsible, I ran the same process through gdb. Nope:

Saving Generated Scene: /dfs1/net/prod/pipeline/working/markv/clean2/projects/dot/shots/test/JR02003/light/synch/test_JR02003_light_synch.ma

[crap omitted]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 47512146590080 (LWP 14527)]
0x0000000018ed0d10 in ?? ()
(gdb) where
#0 0x0000000018ed0d10 in ?? ()
#1 0x00002b363f6833ff in TDGtypeFilter::matches ()
from /usr/autodesk/maya2009-x64/lib/libDependEngine.so
#2 0x00002b363f685af4 in TDGanyFilter::matches ()
from /usr/autodesk/maya2009-x64/lib/libDependEngine.so
#3 0x00002b3642806c03 in TglobalTranslator::callNodeCallbacks ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#4 0x00002b3642806e27 in TglobalTranslator::callNodeCallbacks ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#5 0x00002b3642806ea8 in TglobalTranslator::callNodeCallbacks ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#6 0x00002b36428048cb in Tscene::saveScene ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#7 0x00002b3642804aa4 in Tscene::doSave ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#8 0x00002b36427d68d1 in TsceneOperator::saveScene ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#9 0x00002b36427d0647 in TfileCmd::handleFileSaveFlag ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#10 0x00002b36427d3e60 in TfileCmd::handleFlags ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
#11 0x00002b36427d61dd in TfileCmd::doCommand ()
from /usr/autodesk/maya2009-x64/lib/libShared.so
---Type to continue, or q to quit---
#12 0x00002b363f3b3406 in Mel_Command_Dispatch ()
from /usr/autodesk/maya2009-x64/lib/libCommandEngine.so
#13 0x00002b363f3d8152 in node_exec ()
from /usr/autodesk/maya2009-x64/lib/libCommandEngine.so
#14 0x00002b363f3d832f in sophia_call_executable ()
from /usr/autodesk/maya2009-x64/lib/libCommandEngine.so
#15 0x00002b363f3f4f2e in SophiaExecutable::evaluate ()
from /usr/autodesk/maya2009-x64/lib/libCommandEngine.so
#16 0x00002b363f3b9e42 in TcommandEngine::sourceFile ()
from /usr/autodesk/maya2009-x64/lib/libCommandEngine.so
#17 0x000000000040f4a1 in TmayaApp::initAfter ()
#18 0x000000000040d9c9 in TmayaApp::initBatch ()
#19 0x00002b36401fe43c in Tapplication::start ()
from /usr/autodesk/maya2009-x64/lib/libExtensionLayer.so
#20 0x000000000041060b in appmain ()
#21 0x000000000041e93b in main ()
(gdb) quit

Here's the kicker: the same script, run from interactive Maya does not crash.

How in the hell does a piece of software that's 10 years old still have a bug that causes it to segfault?

FAIL.

Saturday, June 6, 2009

Maya=FAIL

I've been working in the 3D visual effects industry for over 10 years now. In the beginning, the industry had forbiddingly high startup costs. SGI workstations were the norm (Octanes, a few Indigo2s, and an O2). Frames were transferred from D-Beta with a networked hardware frame buffer called an Acom. Most studios used a mix of proprietary and commercial software, usually Alias Poweranimator or Softimage.

Not us, though. We used Side Effects software's Houdini, the successor to the lovingly obfuscated Action animation tools and ICE compositor.

I spent those halcyon days writing plugins for fur, dynamics, feathers, and lots of other studio tools.

For all the flack Houdini has taken -- complicated, artist-unfriendly, horrible UI -- it was remarkably powerful. We enjoyed a very close relationship with the small development team at Side Effects, and I became used to the idea that my input mattered, and that software should be cleanly written above all, and that forward progress -- not backwards-compatibility -- should be the ultimate goal.

To be fair, most of the shows we worked on were small in scope, and generally a single artist/TD (there was little distinction at this point) crafted a shot from plate to final comp. You could do pretty much anything in Houdini, yet still be able to backtrack and find out what was going on by looking through the object and SOP networks.

Houdini slowly progressed, improving on both the inside and the outside. APIs were refactored, or even thrown away completely (e.g. COPs vs. COPS2). UI became progressively cleaner.

Suddenly, my bliss was interruped by a momentous event. SoftImage had foundered while Microsoft tried to make it work under Windows, and Alias|Wavefront's Maya had slipped into the gap. And they had DROPPED THE PRICE. Maya Complete, formerly priced at $7,500 would now sell for $1,999 and Maya Unlimited, which formerly sold for $16,000 would be priced at $6,999. This was significantly less than Houdini's $18,000 price tag.

The economic climate at the time was difficult. Strikes and 9/11 had reduced the amount of available work, and the high margins formerly associated with VFX work were thinning. Maya's new price made it a very attractive option for the low-budget cartoon we had managed to snag. So, the studio made the leap. We put down our trusty Houdini 5, picked up Maya 4.5, and went to work.

In many ways, Maya turned out to be a breath of fresh air. Artists loved its clever UI, and since most visible parts were written in MEL (its home-grown scripting language) it was customizable beyond belief. We wrote a rudimentary asset-management system, hooked it into our proprietary distributed rendering system, added custom animation tools to seamlessly import lipsync data -- it felt like the sky was the limit.

But the bugs. Oh my, the bugs. Daily crashes, corrupt scenes, inexplicable errors and failures...

6 years has now passed. I'm still working in this industry, and Maya is still the industry standard. The bugs haven't gone away. They've multiplied and festered. New features seem to solve problems, until up close one realises they do little more than fulfill a marketing check-list. Maya is still wildly popular, partially due to its use by large studios (who have rewritten large swathes of it to work around its inherent problems) and partially due to Autodesk's relentless marketing and sales force.

After 4 years of using it, I can say without a doubt that I hate Maya. I hate it with a passion. I hate its lack of encapsulation, I hate its mickey-mouse toy scripting language, and I hate Autodesk's creeping influence. Most of all, I hate how bloated and buggy and slow it has become.

This blog is a way for me to let off steam and a diary of the bugs and general stupidities I uncover in my day-to-day work. It's about how Maya=FAIL.