#include <math.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.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>
#include <maya/MFnPlugin.h>
class Contrast:public MPxNode
{
public:
Contrast();
virtual ~Contrast();
virtual MStatus compute( const MPlug&, MDataBlock& );
virtual void postConstructor();
static void *creator();
static MStatus initialize();
static MTypeId id;
private:
static MObject aColor;
static MObject aContrast;
static MObject aBias;
static MObject aOutColor;
};
MTypeId Contrast::id( 0x81008 );
MObject Contrast::aColor;
MObject Contrast::aContrast;
MObject Contrast::aBias;
MObject Contrast::aOutColor;
#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 Contrast::postConstructor( )
{
setMPSafe(true);
}
Contrast::Contrast()
{
}
Contrast::~Contrast()
{
}
void *Contrast::creator()
{
return new Contrast();
}
MStatus Contrast::initialize()
{
MFnNumericAttribute nAttr;
aColor = nAttr.createColor("inputColor", "ic");
MAKE_INPUT(nAttr);
aContrast = nAttr.createColor("contrast", "c");
MAKE_INPUT(nAttr);
CHECK_MSTATUS(nAttr.setDefault(1.f, 1.f, 1.f));
aBias = nAttr.createColor("bias", "b");
MAKE_INPUT(nAttr);
CHECK_MSTATUS(nAttr.setDefault(.5f, .5f, .5f));
aOutColor = nAttr.createColor("outColor", "oc");
MAKE_OUTPUT(nAttr);
CHECK_MSTATUS(addAttribute(aColor));
CHECK_MSTATUS(addAttribute(aContrast));
CHECK_MSTATUS(addAttribute(aBias));
CHECK_MSTATUS(addAttribute(aOutColor));
CHECK_MSTATUS(attributeAffects(aColor, aOutColor));
CHECK_MSTATUS(attributeAffects(aContrast, aOutColor));
CHECK_MSTATUS(attributeAffects(aBias, aOutColor));
return MS::kSuccess;
}
MStatus Contrast::compute(const MPlug& plug, MDataBlock& block)
{
if((plug != aOutColor) && (plug.parent() != aOutColor))
return MS::kUnknownParameter;
MFloatVector resultColor;
MFloatVector & col = block.inputValue(aColor).asFloatVector();
MFloatVector & cont = block.inputValue(aContrast).asFloatVector();
MFloatVector & bias = block.inputValue(aBias).asFloatVector();
float xp;
float logp5= logf(0.5F);
xp = powf(col[0], logp5/logf(bias[0]));
resultColor[0] = xp<0.5F ?
0.5F*powf(2.0F*xp, cont[0]) :
1.0F-0.5F*powf(2.0F*(1.0F-xp), cont[0]);
xp = powf(col[1], logp5/logf(bias[1]));
resultColor[1] = xp<0.5F ?
0.5F*powf(2.0F*xp, cont[1]) :
1.0F-0.5F*powf(2.0F*(1.0F-xp), cont[1]);
xp = powf(col[2], logp5/logf(bias[2]));
resultColor[2] = xp<0.5F ?
0.5F*powf(2.0F*xp, cont[2]) :
1.0F-0.5F*powf(2.0F*(1.0F-xp), cont[2]);
MDataHandle outColorHandle = block.outputValue( aOutColor );
MFloatVector& outColor = outColorHandle.asFloatVector();
outColor = resultColor;
outColorHandle.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("contrastNode", Contrast::id,
Contrast::creator, Contrast::initialize,
MPxNode::kDependNode, &UserClassify ) );
return MS::kSuccess;
}
MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
CHECK_MSTATUS( plugin.deregisterNode( Contrast::id ) );
return MS::kSuccess;
}