#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/MPointArray.h>
#include <maya/MFnPlugin.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MFnMesh.h>
#include <maya/MItMeshVertex.h>
#include <maya/MDagPath.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MRenderUtil.h>
#include <maya/MSelectionList.h>
#include <mutex>
class cvColorShader :
public MPxNode
{
public:
cvColorShader();
~cvColorShader() override;
SchedulingType
schedulingType()
const override {
return SchedulingType::kParallel; }
static void * creator();
private:
long triangleId,
);
static std::mutex fCriticalSection;
};
MTypeId cvColorShader::id( 0x8000f );
std::mutex cvColorShader::fCriticalSection;
MObject cvColorShader::aReverseAlpha;
MObject cvColorShader::aPrimitiveId;
cvColorShader::cvColorShader()
{
}
cvColorShader::~cvColorShader()
{
}
void * cvColorShader::creator()
{
return new cvColorShader();
}
MStatus cvColorShader::initialize()
{
aReverseAlpha = nAttr.
create(
"reverseAlpha",
"ra",
return MS::kSuccess;
}
inline float cvColorShader::dotProd(
{
return v1.
x*v2.
x + v1.
y*v2.
y + v1.
z*v2.
z;
}
{
if ((plug != aOutColor) && (plug.
parent() != aOutColor) &&
(plug != aOutAlpha))
return MS::kUnknownParameter;
if (objectId != NULL) {
status = getTriangleInfo(meshPath, triangleId, pos, colours);
MFloatVector pos1((
float)pos[0].x, (
float)pos[0].y, (
float)pos[0].z);
MFloatVector pos2((
float)pos[1].x, (
float)pos[1].y, (
float)pos[1].z);
MFloatVector pos3((
float)pos[2].x, (
float)pos[2].y, (
float)pos[2].z);
pointObj = pointObj - pos3;
pos1 = pos1 - pos3;
pos2 = pos2 - pos3;
float len = dotProd(norm, norm);
len = dotProd(norm, pointObj)/len;
pointObj = pointObj - (len * norm);
float aa = dotProd(pos1, pos1);
float bb = dotProd(pos2, pos2);
float ab = dotProd(pos1, pos2);
float am = dotProd(pos1, pointObj);
float bm = dotProd(pos2, pointObj);
float det = aa*bb - ab*ab;
float a = (am*bb - bm*ab) / det;
float b = (bm*aa - am*ab) / det;
float c = 1-a-b;
resultColor = (a*colours[0]) + (b*colours[1]) + (c*colours[2]);
if( rev_flag == true )
resultColor.
a = 1.0f - resultColor.
a;
}
outColor.
x = resultColor.
r;
outColor.
y = resultColor.
g;
outColor.
z = resultColor.
b;
float& outAlpha = outAlphaHandle.
asFloat();
outAlpha = resultColor.
a;
return MS::kSuccess;
}
MStatus cvColorShader::getTriangleInfo(
long triangleId,
) {
meshFn.getConnectedSetsAndMembers(
);
int polygonId = -1;
int triangleCount = 0;
for (
unsigned int s = 0; (polygonId < 0) && (s < shaders.
length()); ++s) {
bool isLocked = true;
fCriticalSection.lock();
for (; !faceIter.isDone(); faceIter.next()) {
if (faceIter.hasValidTriangulation()) {
int nTri;
faceIter.numTriangles(nTri);
if (triangleId < triangleCount + nTri) {
polygonId = faceIter.index();
st = faceIter.getTriangle(
triangleId - triangleCount,
vertPositions,
vertIndices,
);
break;
}
triangleCount += nTri;
}
if (isLocked) {
fCriticalSection.unlock();
isLocked = false;
}
}
if (isLocked) {
fCriticalSection.unlock();
}
}
if ((polygonId == -1) || !st) {
return MS::kFailure;
}
int preIndex = 0;
CHECK_MSTATUS ( vertIter.getColor( vertColours[0], polygonId ) );
CHECK_MSTATUS ( vertIter.getColor( vertColours[1], polygonId ) );
CHECK_MSTATUS ( vertIter.getColor( vertColours[2], polygonId ) );
return MS::kSuccess;
}
{
const MString UserClassify(
"utility/color" );
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"5.0",
"Any");
CHECK_MSTATUS ( plugin.registerNode(
"cvColorShader", cvColorShader::id,
cvColorShader::creator,
cvColorShader::initialize,
return MS::kSuccess;
}
{
return MS::kSuccess;
}