compositingShader/compositingShader.cpp
 
 
 
compositingShader/compositingShader.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/MFnPlugin.h>
#include <maya/MIOStream.h>
#include <maya/MPxNode.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h> 
#include <maya/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>

class myComp : public MPxNode
{
        public:
                 myComp();
        virtual ~myComp();

        virtual MStatus compute( const MPlug&, MDataBlock& );
        virtual void    postConstructor();

        static  void *  creator();
        static  MStatus initialize();

        //  Id tag for use with binary file format
    static  MTypeId id;

        private:

        // Input attributes

        static MObject aForegroundColor;
        static MObject aBackgroundColor;
        static MObject aBackColor;
        static MObject aMask;

        // Output attributes
        static MObject aOutColor;
        static MObject aOutAlpha;
};

// Static data
MTypeId myComp::id( 0x8100c );

// Attributes
MObject         myComp::aForegroundColor;
MObject         myComp::aBackgroundColor;
MObject         myComp::aBackColor;
MObject         myComp::aMask;
 
MObject         myComp::aOutColor;
MObject         myComp::aOutAlpha;

#define MAKE_INPUT(attr)                        \
    CHECK_MSTATUS( attr.setKeyable(true));              \
        CHECK_MSTATUS( attr.setStorable(true));         \
    CHECK_MSTATUS( attr.setReadable(true));     \
        CHECK_MSTATUS( attr.setWritable(true));

#define MAKE_OUTPUT(attr)                       \
    CHECK_MSTATUS( attr.setKeyable(false));     \
        CHECK_MSTATUS( attr.setStorable(false));        \
    CHECK_MSTATUS( attr.setReadable(true));     \
        CHECK_MSTATUS( attr.setWritable(false));

void myComp::postConstructor( )
{
        setMPSafe(true);
}

myComp::myComp()
{
}

myComp::~myComp()
{
}

// creates an instance of the node
void * myComp::creator()
{
    return new myComp();
}

// initializes attribute information
MStatus myComp::initialize()
{
    MFnNumericAttribute nAttr; 

    // Create input attributes

    aForegroundColor = nAttr.createColor("foreground", "fg");
    MAKE_INPUT(nAttr);

    aBackgroundColor = nAttr.createColor("background", "bg");
    MAKE_INPUT(nAttr);
    CHECK_MSTATUS( nAttr.setDefault(1., 1., 1.));

    aBackColor = nAttr.createColor("backColor", "bk");
    MAKE_INPUT(nAttr);
    CHECK_MSTATUS( nAttr.setDefault(1., 1., 1.));

    aMask = nAttr.create( "mask", "ms", MFnNumericData::kFloat);
    CHECK_MSTATUS( nAttr.setMin(0.f));
    CHECK_MSTATUS( nAttr.setMax(1.f));
    MAKE_INPUT(nAttr);

        // Create output attributes here
    aOutColor = nAttr.createColor("outColor", "oc");
        MAKE_OUTPUT(nAttr);

    aOutAlpha = nAttr.create( "outAlpha", "oa", MFnNumericData::kFloat);
        MAKE_OUTPUT(nAttr);

    // Add the attributes here
    CHECK_MSTATUS( addAttribute(aForegroundColor) );
    CHECK_MSTATUS( addAttribute(aBackgroundColor) );
    CHECK_MSTATUS( addAttribute(aBackColor) );
    CHECK_MSTATUS( addAttribute(aMask) );

    CHECK_MSTATUS( addAttribute(aOutColor) );
    CHECK_MSTATUS( addAttribute(aOutAlpha) );

    // all input affect the output color and alpha
    CHECK_MSTATUS( attributeAffects(aForegroundColor, aOutColor) );
    CHECK_MSTATUS( attributeAffects(aForegroundColor, aOutAlpha) );

    CHECK_MSTATUS( attributeAffects(aBackgroundColor, aOutColor) );
    CHECK_MSTATUS( attributeAffects(aBackgroundColor, aOutAlpha) );

    CHECK_MSTATUS( attributeAffects(aBackColor, aOutColor) );
    CHECK_MSTATUS( attributeAffects(aBackColor, aOutAlpha) );

    CHECK_MSTATUS( attributeAffects(aMask, aOutColor) );
    CHECK_MSTATUS( attributeAffects(aMask, aOutAlpha) );

    return MS::kSuccess;
}


//
// This function gets called by Maya to evaluate the texture.

MStatus myComp::compute(const MPlug& plug, MDataBlock& block)
{
        // outColor or individial R, G, B channel
    if((plug != aOutColor) && (plug.parent() != aOutColor) &&
           (plug != aOutAlpha))
                return MS::kUnknownParameter;

        MFloatVector resultColor;
        MFloatVector& fore = block.inputValue( aForegroundColor ).asFloatVector();
        MFloatVector& back = block.inputValue( aBackgroundColor ).asFloatVector();
        MFloatVector& bclr = block.inputValue( aBackColor ).asFloatVector();
        float& alpha = block.inputValue( aMask ).asFloat();

        if ( alpha > 0.99999f ) alpha = 1.f;
        else if ( alpha < 0.00001 )  alpha = 0.f;
        
        resultColor = fore + ((bclr - back) * (1.0f - alpha));

        // normalize output color
        if (resultColor[0] < 0.f )      resultColor[0] = 0.f;
        if (resultColor[1] < 0.f )      resultColor[1] = 0.f;
        if (resultColor[2] < 0.f )      resultColor[2] = 0.f;
        
        if (resultColor[0] > 1.f )      resultColor[0] = 1.f;
        if (resultColor[1] > 1.f )      resultColor[1] = 1.f;
        if (resultColor[2] > 1.f )      resultColor[2] = 1.f;

        // set ouput color attribute
        MDataHandle outColorHandle = block.outputValue( aOutColor );
        MFloatVector& outColor = outColorHandle.asFloatVector();
        outColor = resultColor;
        outColorHandle.setClean();
        
        MDataHandle outAlphaHandle = block.outputValue( aOutAlpha );
        float& outAlpha = outAlphaHandle.asFloat();
        outAlpha = ( resultColor.x + resultColor.y + resultColor.z ) / 3.0f;
        outAlphaHandle.setClean();

        return MS::kSuccess;
}

MStatus initializePlugin( MObject obj )
{ 
        const MString UserClassify( "utility/color" );

        MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
        CHECK_MSTATUS( plugin.registerNode( "composite", myComp::id, 
                                                 &myComp::creator, &myComp::initialize,
                                                 MPxNode::kDependNode, &UserClassify ) );

        return MS::kSuccess;
}

MStatus uninitializePlugin( MObject obj )
{
        MFnPlugin plugin( obj );
        CHECK_MSTATUS( plugin.deregisterNode( myComp::id ) );

        return MS::kSuccess;
}