renderViewRenderRegionCmd/renderViewRenderRegionCmd.cpp

renderViewRenderRegionCmd/renderViewRenderRegionCmd.cpp
//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+
// DESCRIPTION:
//
// Produces the MEL command "renderViewRenderRegion".
//
// This example demonstrates how to use the MRenderView class to update
// the currently selected Render Region in Maya's Render View.
// The command takes no arguments and always updates the Render Region
// with a blue and white circular pattern. The command assumes that the Render
// View is currently displaying a 640x480 image (such as the one generated by
// the renderViewRender example command).
//
#include <maya/MSimple.h>
#include <maya/MIOStream.h>
#include <maya/MRenderView.h>
#include <maya/M3dView.h>
#include <math.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
//
// renderViewRenderRegion command declaration
//
class renderViewRenderRegion : public MPxCommand
{
public:
renderViewRenderRegion() {};
~renderViewRenderRegion() {};
virtual MStatus doIt ( const MArgList& );
static void* creator();
static MSyntax newSyntax();
MStatus parseSyntax (MArgDatabase &argData);
static const char * cmdName;
private:
bool doNotClearBackground;
};
static const char * kDoNotClearBackground = "-b";
static const char * kDoNotClearBackgroundLong = "-background";
const char * renderViewRenderRegion::cmdName = "renderViewRenderRegion";
void* renderViewRenderRegion::creator()
{
return new renderViewRenderRegion;
}
MSyntax renderViewRenderRegion::newSyntax()
{
MStatus status;
MSyntax syntax;
syntax.addFlag( kDoNotClearBackground, kDoNotClearBackgroundLong );
CHECK_MSTATUS_AND_RETURN(status, syntax);
return syntax;
}
//
// Description:
// Read the values of the additionnal flags for this command.
//
MStatus renderViewRenderRegion::parseSyntax (MArgDatabase &argData)
{
// Get the flag values, otherwise the default values are used.
doNotClearBackground = argData.isFlagSet( kDoNotClearBackground );
return MS::kSuccess;
}
//
// Description:
// register the command
//
MStatus initializePlugin( MObject obj )
{
MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5" );
MStatus stat;
stat = plugin.registerCommand( renderViewRenderRegion::cmdName,
renderViewRenderRegion::creator,
renderViewRenderRegion::newSyntax);
if ( !stat )
stat.perror( "registerCommand" );
return stat;
}
//
// Description:
// unregister the command
//
MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
MStatus stat;
stat = plugin.deregisterCommand( renderViewRenderRegion::cmdName );
if ( !stat )
stat.perror( "deregisterCommand" );
return stat;
}
RV_PIXEL evaluate(int x, int y)
//
// Description:
// Generates a simple procedural circular pattern to be sent to the
// Render View.
//
// Arguments:
// x, y - coordinates in the current tile (the pattern is centred
// around (0,0) ).
//
// Return Value:
// An RV_PIXEL structure containing the colour of pixel (x,y).
//
{
unsigned int distance = (unsigned int) sqrt(double((x*x) + (y*y)));
RV_PIXEL pixel;
// Always fully blue.
pixel.b = 255.0f;
// Green and red varies according to the distance.
pixel.g = pixel.r = 155.0f + (distance % 20) * 5;
pixel.a = 255.0f;
return pixel;
}
MStatus renderViewRenderRegion::doIt( const MArgList& args )
//
// Description:
// Implements the MEL renderViewRenderRegion command. This command
// fills the currently selected Render Region with a circular blue
// and white pattern. It assumes that the Render View is currently
// displaying a 640x480 image (if it isn't, then this command will
// resize the Render View to 640x480).
//
// Arguments:
// args - the argument list that was passes to the command from MEL.
// -background/-b renders the pattern without clearing the region
//
// Return Value:
// MS::kSuccess - command succeeded
// MS::kFailure - command failed (returning this value will cause the
// MEL script that is being run to terminate unless the
// error is caught using a "catch" statement.
//
{
unsigned int resX = 640;
unsigned int resY = 480;
// Check if the render view exists. It should always exist, unless
// Maya is running in batch mode.
//
{
setResult( "Cannot renderViewRenderRegion in batch render mode. "
"Please run in interactive mode, "
"so that the render editor exists." );
return MS::kFailure;
}
// get optional flags
MArgDatabase argData( syntax(), args );
parseSyntax( argData );
// Pick a camera, and tell the Render View that we will be rendering
// from its point of view. Just use the camera for the active
// modelling view.
//
MDagPath camDagPath;
curView.getCamera( camDagPath );
cout<<"Region rendering camera"<<camDagPath.fullPathName().asChar()<<endl;
{
setResult( "renderViewRenderRegion: error occurred in setCurrentCamera." );
return MS::kFailure;
}
// Retrieve the dimensions of the currently selected Render Region.
//
unsigned int regionLeft, regionRight, regionBottom, regionTop;
stat = MRenderView::getRenderRegion( regionLeft, regionRight,
regionBottom, regionTop );
if( stat != MS::kSuccess )
{
setResult( "renderViewRenderRegion: error occurred in getRenderRegion." );
return MS::kFailure;
}
// Assume that the full rendered image is 640x480, and tell the
// Render View that we're about to start rendering the given region.
//
stat = MRenderView::startRegionRender( resX, resY,
regionLeft, regionRight,
regionBottom, regionTop,
doNotClearBackground );
if( stat == MS::kSuccess )
{
cout<<"Rendering Region ("<<regionLeft<<","<<regionBottom
<<") -> ("<<regionRight<<","<<regionTop<<")"<<endl;
unsigned int width = regionRight - regionLeft + 1;
unsigned int height = regionTop - regionBottom + 1;
unsigned int numPixels = width * height;
unsigned int middleX = width / 2;
unsigned int middleY = height / 2;
// Allocate buffer to store the region
//
RV_PIXEL* pixels = new RV_PIXEL[numPixels];
// Fill the region buffer with a circular blue/white pattern centred on
// the middle of the region
//
for( unsigned int x = 0; x < width; x++ )
{
for( unsigned int y = 0; y < height; y++ )
{
int index = y*width + x;
int xCoord = x - middleX;
int yCoord = y - middleY;
pixels[index] = evaluate( xCoord, yCoord );
}
}
// Send the pixel data to the Render View.
//
stat = MRenderView::updatePixels( regionLeft, regionRight,
regionBottom, regionTop,
pixels );
if( stat != MS::kSuccess )
{
setResult( "renderViewRenderRegion: error occurred in updatePixels." );
return MS::kFailure;
}
// Force a refresh of the region in the Render View window.
//
stat = MRenderView::refresh( regionLeft, regionRight,
regionBottom, regionTop );
if( stat != MS::kSuccess )
{
setResult( "renderViewRenderRegion: error occurred in refresh." );
return MS::kFailure;
}
}
else
{
setResult( "renderViewRenderRegion: error occurred in startRegionRender." );
return MS::kFailure;
}
// Notify the Render View that we are done rendering the region.
//
if( stat != MS::kSuccess )
{
setResult( "renderViewRenderRegion: error occurred in endRender." );
return MS::kFailure;
}
setResult( "renderViewRenderRegion completed." );
return stat;
}