- Main Page
- Related Pages
- Modules
- Classes
- Examples

# 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.
    // ==========================================================================
    //+

    #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.
    //
    {
        MStatus stat = MS::kSuccess;

        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.
        //
        if (!MRenderView::doesRenderEditorExist())
        {
            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.
        //
        M3dView curView = M3dView::active3dView();
        MDagPath camDagPath;
        curView.getCamera( camDagPath );
        cout<<"Region rendering camera"<<camDagPath.fullPathName().asChar()<<endl;

        if( MRenderView::setCurrentCamera( camDagPath ) != MS::kSuccess )
        {
            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.
        //
        stat = MRenderView::endRender();
        if( stat != MS::kSuccess )
        {
            setResult( "renderViewRenderRegion: error occurred in endRender." );
            return MS::kFailure;
        }

        setResult( "renderViewRenderRegion completed." );
        return stat;
    }