#include <maya/MStatus.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnMesh.h>
#include <maya/MIntArray.h>
#include <maya/MFloatVectorArray.h>
#include <maya/MPxPrimitiveGenerator.h>
#include <maya/MPxVertexBufferGenerator.h>
#include <maya/MHWGeometry.h>
#include <maya/MDrawRegistry.h>
#include <maya/MApiVersion.h>
#include <list>
#include <algorithm>
{
public:
MyCustomPrimitiveGenerator() {}
~MyCustomPrimitiveGenerator() override {}
unsigned int computeIndexCount(
const MObject&
object,
const MObject& component)
const override
{
if (!status) return 0;
}
int& primitiveStride) const override
{
for (
int x = 0; x < targetIndexing.
length(); ++x)
{
if (target->
componentType() == MComponentDataIndexing::kFaceVertex)
{
unsigned int numTriVerts = triVertIDs.
length();
unsigned int customNumTriVerts = numTriVerts * 2;
void* indexData = indexBuffer.
acquire(customNumTriVerts,
true );
if (indexData == NULL)
unsigned int nextNewVertexIndex = 0;
for(
unsigned int idx = 0; idx < sharedIndices.
length(); ++idx)
nextNewVertexIndex = std::max(nextNewVertexIndex, sharedIndices[idx]);
++nextNewVertexIndex;
unsigned int newTriId = 0;
for(unsigned int triId = 0; triId < numTriVerts; )
{
unsigned int vertexId0 = sharedIndices[triVertIDs[triId++]];
unsigned int vertexId1 = sharedIndices[triVertIDs[triId++]];
unsigned int vertexId2 = sharedIndices[triVertIDs[triId++]];
unsigned int newVertexIndex = nextNewVertexIndex++;
((unsigned int*)indexData)[newTriId++] = vertexId0;
((unsigned int*)indexData)[newTriId++] = vertexId1;
((unsigned int*)indexData)[newTriId++] = newVertexIndex;
((unsigned int*)indexData)[newTriId++] = vertexId0;
((unsigned int*)indexData)[newTriId++] = newVertexIndex;
((unsigned int*)indexData)[newTriId++] = vertexId2;
}
((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId0;
((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId1;
((unsigned short*)indexData)[newTriId++] = (unsigned short)newVertexIndex;
((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId0;
((unsigned short*)indexData)[newTriId++] = (unsigned short)newVertexIndex;
((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId2;
}
}
indexBuffer.
commit(indexData);
primitiveStride = 3;
}
}
}
};
{
return new MyCustomPrimitiveGenerator();
}
{
public:
MyCustomPositionBufferGenerator() {}
~MyCustomPositionBufferGenerator() override {}
bool getSourceIndexing(
const MObject&
object,
{
if (!status) return false;
mesh.getVertices(vertexCount, vertexList);
unsigned int vertCount = vertexList.
length();
for(unsigned int i = 0; i < vertCount; ++i)
vertices[i] = (unsigned int)vertexList[i];
return true;
}
bool getSourceStreams(
const MObject&
object,
{
return false;
}
void createVertexStream(
const MObject&
object,
{
return;
if (dimension != 3)
return;
return;
if (!status) return;
unsigned int vertexCount = indices.
length();
if (vertexCount <= 0)
return;
typedef std::list< std::pair< unsigned int, unsigned int > > ExtraVerticesList;
ExtraVerticesList extraVertices;
{
mesh.getTriangleOffsets(triCounts, triVertIDs);
unsigned int numTriVerts = triVertIDs.
length();
for(unsigned int triId = 0; triId < numTriVerts; )
{
triId++;
unsigned int vertexId1 = sharedIndices[triVertIDs[triId++]];
unsigned int vertexId2 = sharedIndices[triVertIDs[triId++]];
extraVertices.push_back( std::make_pair(vertexId1, vertexId2) );
}
}
unsigned int newVertexCount = vertexCount + (unsigned int)extraVertices.size();
float* customBuffer = (
float*)vertexBuffer.
acquire(newVertexCount,
true );
if(customBuffer)
{
float* customBufferStart = customBuffer;
unsigned int vertId = 0;
for(; vertId < vertexCount; ++vertId)
{
unsigned int vertexId = indices[vertId];
mesh.getPoint(vertexId, point);
customBuffer[vertId * dimension] = (float)point.
x;
customBuffer[vertId * dimension + 1] = (
float)point.
y;
customBuffer[vertId * dimension + 2] = (float)point.
z;
}
ExtraVerticesList::const_iterator it = extraVertices.begin();
ExtraVerticesList::const_iterator itEnd = extraVertices.end();
for(; it != itEnd; ++it, ++vertId)
{
unsigned int vertexId1 = indices[it->first];
unsigned int vertexId2 = indices[it->second];
mesh.getPoint(vertexId1, point1);
mesh.getPoint(vertexId2, point2);
MPoint point = (point1 + point2) / 2.0f;
customBuffer[vertId * dimension] = (float)point.
x;
customBuffer[vertId * dimension + 1] = (
float)point.
y;
customBuffer[vertId * dimension + 2] = (float)point.
z;
}
vertexBuffer.
commit(customBufferStart);
}
}
};
{
return new MyCustomPositionBufferGenerator();
}
{
public:
MyCustomNormalBufferGenerator() {}
~MyCustomNormalBufferGenerator() override {}
bool getSourceIndexing(
const MObject&
object,
{
if (!status) return false;
mesh.getVertices(vertexCount, vertexList);
unsigned int vertCount = vertexList.
length();
for(unsigned int i = 0; i < vertCount; ++i)
vertices[i] = (unsigned int)vertexList[i];
return true;
}
bool getSourceStreams(
const MObject&
object,
{
return false;
}
void createVertexStream(
const MObject&
object,
{
return;
if (dimension != 3)
return;
return;
if (!status) return;
unsigned int vertexCount = indices.
length();
if (vertexCount <= 0)
return;
typedef std::list< std::pair< unsigned int, unsigned int > > ExtraVerticesList;
ExtraVerticesList extraVertices;
{
mesh.getTriangleOffsets(triCounts, triVertIDs);
unsigned int numTriVerts = triVertIDs.
length();
for(unsigned int triId = 0; triId < numTriVerts;)
{
triId++;
unsigned int vertexId1 = sharedIndices[triVertIDs[triId++]];
unsigned int vertexId2 = sharedIndices[triVertIDs[triId++]];
extraVertices.push_back( std::make_pair(vertexId1, vertexId2) );
}
}
unsigned int newVertexCount = vertexCount + (unsigned int)extraVertices.size();
float* customBuffer = (
float*)vertexBuffer.
acquire(newVertexCount,
true );
if(customBuffer)
{
float* customBufferStart = customBuffer;
mesh.getNormals(normals);
unsigned int vertId = 0;
for(; vertId < vertexCount; ++vertId)
{
customBuffer[vertId * dimension] = normal.
x;
customBuffer[vertId * dimension + 1] = normal.
y;
customBuffer[vertId * dimension + 2] = normal.
z;
}
ExtraVerticesList::const_iterator it = extraVertices.begin();
ExtraVerticesList::const_iterator itEnd = extraVertices.end();
for(; it != itEnd; ++it, ++vertId)
{
unsigned int vertexId1 = it->first;
unsigned int vertexId2 = it->second;
customBuffer[vertId * dimension] = normal.
x;
customBuffer[vertId * dimension + 1] = normal.
y;
customBuffer[vertId * dimension + 2] = normal.
z;
}
vertexBuffer.
commit(customBufferStart);
}
}
};
{
return new MyCustomNormalBufferGenerator();
}
{
return MS::kSuccess;
}
{
return MS::kSuccess;
}