Maya API How-To #12

Back · Previous · Next Maya

How do I determine when to use MDGContext over MGlobal::viewFrame()?

If you read Maya's DevKit FAQ you'll find the nice little hint in there like so:

You can ... perform a viewframe, to set the time, then query the
attributes ... you are interested in via the getValue methods of the MPlug
class. As you point out however, this is somewhat slow, since viewframe
changes the global time.

[or] You can create an instance of the MDGContext class initialized to the
time you are interested in. This can be passed to the getValue method of
the MPlug class... As much or as little of the dependencies as necessary
will be reevaluated... Lots of dependencies on other nodes will make the
evaluation slow. Otherwise it should be fast.

The way I had interpreted this was:

MGlobal::viewFrame() will always be slow because it has to reevaluate the entire DG. Under some cases MDGContext will be as slow as ::viewFrame() but typically it should be faster.

Whoa back tho'. Not so much! Take a gander at this real-life example:

#if MAYA_VIEW_FRAME

  MGlobal::viewFrame( obTime );

  MFnMesh                      fnMesh( obDagPath, &status );

#else

  MFnDependencyNode            fnDependNode( obDagPath.node(), &status );

  MPlug                        plugMesh;
  MObject                      meshData;

  plugMesh = fnDependNode.findPlug( MString( "outMesh" ), &status );

  status = plugMesh.getValue( meshData, MDGContext( obTime ) );

  MFnMesh                      fnMesh( meshData, &status );

#endif

  status = fnMesh.getPoints( aobPoints, MSpace::kObject );

Now lets look at the performance of these:

If MAYA_VIEW_FRAME is not defined - in other words I use the "optimal" MDGContext method, I get the results:

%%                   TIME adding to ANIM: 399.03 seconds
%%       --> time consumed by MDGContext: 395.994 seconds

Now a run through the exact same object using ::viewFrame():

%%                        TIME adding to ANIM: 41.58 seconds
%%  --> time consumed by MGlobal::viewFrame(): 16.003 seconds

This is exponentially more significant than I'd ever have imagined. And now I can see why many suggest ::viewFrame() over MDGContext.

Putting The Results In Context

There is one important consideration to these results: In both cases I shuffled Maya's UI to the background and monitored the Output Window. By doing so, Maya skipped all redraw operations because none of its viewports were visible.

If Maya's UI is visible (or, specifically, any panels that must be redrawn when Time changes) then a call to ::viewFrame() will force a redraw within these panels. This is what generates the performance penalty of the ::viewFrame() call. Had I been watching Maya's main window in the above time trials then they would both have generated similar results.

Conclusions

If you expect Maya's UI to remain in front of other windows while you modify time values, MGlobal::viewFrame() may actually take more time to execute.

However, you will always pay a penalty in performance by using MDGContext as it seems to force Maya to perform a "mental" redraw regardless. You can avoid all unnecessary evaluation by using MGlobal::viewFrame() and shuffling Maya's UI to the background during the processing.

Monday, May 21, 2001