mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-17 22:21:07 +00:00
The Maya plugin can interpolate a UV channel and a vertex color channel.
This commit is contained in:
parent
2587f6ea07
commit
f669e3a3d7
@ -152,6 +152,9 @@ ConvertMayaFVarBoundary(short boundaryMethod, bool propagateCorner) {
|
||||
cerr << "ERROR: " << message << "[" << status << "]" << endl; \
|
||||
}
|
||||
|
||||
#define CHANNELUV 0
|
||||
|
||||
#define CHANNELCOLOR 1
|
||||
|
||||
// ====================================
|
||||
// Constructors/Destructors
|
||||
@ -266,7 +269,6 @@ getCreaseVertices( MFnMesh const & inMeshFn, Descriptor & outDesc) {
|
||||
// Collect UVs and ColorSet info to represent them as face-varying in OpenSubdiv
|
||||
static MStatus
|
||||
getMayaFvarFieldParams(
|
||||
|
||||
MFnMesh const & inMeshFn,
|
||||
MStringArray & uvSetNames,
|
||||
MStringArray & colorSetNames,
|
||||
@ -291,7 +293,7 @@ getMayaFvarFieldParams(
|
||||
colorSetReps[i] = inMeshFn.getColorRepresentation(colorSetNames[i], &returnStatus);
|
||||
MCHECKERR(returnStatus, "Cannot get colorSet representation");
|
||||
|
||||
if (colorSetReps[i] == MFnMesh::kAlpha) {
|
||||
if (colorSetReps[i] == MFnMesh::kAlpha) {
|
||||
colorSetChannels[i] = 1;
|
||||
} else if (colorSetReps[i] == MFnMesh::kRGB) {
|
||||
colorSetChannels[i] = 3;
|
||||
@ -306,10 +308,14 @@ getMayaFvarFieldParams(
|
||||
|
||||
//! Caller is expected to delete the returned value
|
||||
static OpenSubdiv::Far::TopologyRefiner *
|
||||
gatherTopology( MFnMesh const & inMeshFn,
|
||||
gatherTopology( MFnMesh & inMeshFn,
|
||||
MItMeshPolygon & inMeshItPolygon,
|
||||
OpenSubdiv::Sdc::SchemeType type,
|
||||
OpenSubdiv::Sdc::Options options,
|
||||
bool & hasUVs, bool & hasColors,
|
||||
std::vector<MFloatArray> & uvSet_uCoords,
|
||||
std::vector<MFloatArray> & uvSet_vCoords,
|
||||
std::vector<MColorArray> & colorSet_colors,
|
||||
float * maxCreaseSharpness=0 ) {
|
||||
|
||||
MStatus returnStatus;
|
||||
@ -320,33 +326,32 @@ gatherTopology( MFnMesh const & inMeshFn,
|
||||
std::vector<int> colorSetChannels;
|
||||
std::vector<MFnMesh::MColorRepresentation> colorSetReps;
|
||||
int totalColorSetChannels = 0;
|
||||
returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels);
|
||||
returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
|
||||
colorSetChannels, colorSetReps, totalColorSetChannels);
|
||||
MWARNERR(returnStatus, "Failed to retrieve Maya face-varying parameters");
|
||||
|
||||
// Create face-varying data with independent float channels of dimension 1
|
||||
// Note: This FVarData needs to be kept around for the duration of the HBR mesh
|
||||
int totalFvarWidth = 2*uvSetNames.length() + totalColorSetChannels;
|
||||
|
||||
// temp storage for UVs and ColorSets for a face
|
||||
// Storage for UVs and ColorSets for face-vertex
|
||||
MIntArray fvArray; // face vertex array
|
||||
std::vector<MFloatArray> uvSet_uCoords(uvSetNames.length());
|
||||
std::vector<MFloatArray> uvSet_vCoords(uvSetNames.length());
|
||||
std::vector<MColorArray> colorSet_colors(colorSetNames.length());
|
||||
uvSet_uCoords.clear(); uvSet_uCoords.resize(uvSetNames.length());
|
||||
uvSet_vCoords.clear(); uvSet_vCoords.resize(uvSetNames.length());
|
||||
colorSet_colors.clear();colorSet_colors.resize(colorSetNames.length());
|
||||
|
||||
// Put the data in the format needed for OSD
|
||||
Descriptor desc;
|
||||
|
||||
int numFaceVertices = inMeshFn.numFaceVertices();
|
||||
|
||||
desc.numVertices = inMeshFn.numVertices();
|
||||
desc.numFaces = inMeshItPolygon.count();
|
||||
|
||||
int * vertsPerFace = new int[desc.numFaces],
|
||||
* vertIndices = new int[inMeshFn.numFaceVertices()];
|
||||
* vertIndices = new int[numFaceVertices];
|
||||
|
||||
desc.numVertsPerFace = vertsPerFace;
|
||||
desc.vertIndicesPerFace = vertIndices;
|
||||
|
||||
// Create Topology
|
||||
|
||||
for( inMeshItPolygon.reset(); !inMeshItPolygon.isDone(); inMeshItPolygon.next() ) {
|
||||
for (inMeshItPolygon.reset(); !inMeshItPolygon.isDone(); inMeshItPolygon.next()) {
|
||||
|
||||
inMeshItPolygon.getVertices(fvArray);
|
||||
int nverts = fvArray.length();
|
||||
@ -356,30 +361,81 @@ gatherTopology( MFnMesh const & inMeshFn,
|
||||
for (int i=0; i<nverts; ++i) {
|
||||
*vertIndices++ = fvArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Add FaceVaryingData (UVSets, ...)
|
||||
if (totalFvarWidth > 0) {
|
||||
// XXXX
|
||||
// Retrieve all UV and ColorSet topology
|
||||
for (unsigned int i=0; i < uvSetNames.length(); ++i) {
|
||||
inMeshItPolygon.getUVs(uvSet_uCoords[i], uvSet_vCoords[i], &uvSetNames[i] );
|
||||
}
|
||||
for (unsigned int i=0; i < colorSetNames.length(); ++i) {
|
||||
inMeshItPolygon.getColors(colorSet_colors[i], &colorSetNames[i]);
|
||||
// Add Face-Varying data to the descriptor
|
||||
Descriptor::FVarChannel * channels = NULL;
|
||||
hasUVs = uvSet_uCoords.size() > 0 && uvSet_vCoords.size() > 0;
|
||||
hasColors = colorSet_colors.size() > 0;
|
||||
|
||||
// Note : Only supports 1 channel of UVs and 1 channel of color
|
||||
if (hasUVs || hasColors) {
|
||||
|
||||
// Create 2 face-varying channel descriptor that will hold UVs and color
|
||||
desc.numFVarChannels = 2;
|
||||
channels = new Descriptor::FVarChannel[desc.numFVarChannels];
|
||||
desc.fvarChannels = channels;
|
||||
|
||||
int * uvIndices = new int[numFaceVertices];
|
||||
int * pUVIndex = uvIndices;
|
||||
channels[CHANNELUV].valueIndices = uvIndices;
|
||||
channels[CHANNELUV].numValues = 0;
|
||||
|
||||
int * colorIndices = new int[numFaceVertices];
|
||||
int * pColorIndex = colorIndices;
|
||||
channels[CHANNELCOLOR].valueIndices = colorIndices;
|
||||
channels[CHANNELCOLOR].numValues = 0;
|
||||
|
||||
// Obtain UV information
|
||||
if (hasUVs) {
|
||||
inMeshFn.getUVs(uvSet_uCoords[0], uvSet_vCoords[0], &uvSetNames[0]);
|
||||
assert( uvSet_uCoords[0].length() == uvSet_vCoords[0].length() );
|
||||
|
||||
int uvId = 0;
|
||||
for (int faceIndex = 0; faceIndex < inMeshFn.numPolygons(); ++faceIndex)
|
||||
{
|
||||
int numVertices = inMeshFn.polygonVertexCount(faceIndex);
|
||||
for (int v = 0; v < numVertices; v++)
|
||||
{
|
||||
inMeshFn.getPolygonUVid(faceIndex, v, uvId, &uvSetNames[0]);
|
||||
*pUVIndex ++ = uvId;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle uvSets
|
||||
for (unsigned int fvid=0; fvid < fvArray.length(); ++fvid) {
|
||||
}
|
||||
// Handle colorSets
|
||||
for( unsigned int colorSetIt=0; colorSetIt < colorSetNames.length(); ++colorSetIt ) {
|
||||
channels[CHANNELUV].numValues = uvSet_uCoords[0].length();
|
||||
}
|
||||
|
||||
// Obtain color information
|
||||
if (hasColors) {
|
||||
inMeshFn.getColors(colorSet_colors[0], &colorSetNames[0]);
|
||||
|
||||
int colorId = 0;
|
||||
bool addDefaultColor = true;
|
||||
for (int faceIndex = 0; faceIndex < inMeshFn.numPolygons(); ++faceIndex)
|
||||
{
|
||||
int numVertices = inMeshFn.polygonVertexCount(faceIndex);
|
||||
for ( int v = 0 ; v < numVertices; v++ )
|
||||
{
|
||||
inMeshFn.getColorIndex(faceIndex, v, colorId, &colorSetNames[0]);
|
||||
if (colorId == -1)
|
||||
{
|
||||
if (addDefaultColor)
|
||||
{
|
||||
addDefaultColor = false;
|
||||
colorSet_colors[0].append(MColor(1.0, 1.0, 1.0, 1.0));
|
||||
}
|
||||
colorId = colorSet_colors[0].length() - 1;
|
||||
}
|
||||
*pColorIndex ++ = colorId;
|
||||
}
|
||||
}
|
||||
|
||||
channels[CHANNELCOLOR].numValues = colorSet_colors[0].length();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Creases
|
||||
float maxEdgeCrease = getCreaseEdges( inMeshFn, desc );
|
||||
|
||||
float maxVertexCrease = getCreaseVertices( inMeshFn, desc );
|
||||
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner =
|
||||
@ -388,12 +444,18 @@ gatherTopology( MFnMesh const & inMeshFn,
|
||||
|
||||
delete [] desc.numVertsPerFace;
|
||||
delete [] desc.vertIndicesPerFace;
|
||||
|
||||
delete [] desc.creaseVertexIndexPairs;
|
||||
delete [] desc.creaseWeights;
|
||||
delete [] desc.cornerVertexIndices;
|
||||
delete [] desc.cornerWeights;
|
||||
|
||||
if (hasUVs || hasColors) {
|
||||
for(int i = 0 ; i < desc.numFVarChannels ; i ++) {
|
||||
delete [] channels[i].valueIndices;
|
||||
}
|
||||
delete [] channels;
|
||||
}
|
||||
|
||||
if (maxCreaseSharpness) {
|
||||
*maxCreaseSharpness = std::max(maxEdgeCrease, maxVertexCrease);
|
||||
}
|
||||
@ -433,8 +495,8 @@ createSmoothMesh_objectGroups( MFnMesh const & inMeshFn,
|
||||
|
||||
// get elements from inMesh objectGroupComponent
|
||||
MIntArray compElems;
|
||||
MFnSingleIndexedComponent compFn(inMeshDat.objectGroupComponent(compId), &status );
|
||||
|
||||
MFnSingleIndexedComponent compFn(
|
||||
inMeshDat.objectGroupComponent(compId), &status );
|
||||
MCHECKERR(status, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent().");
|
||||
compFn.getElements(compElems);
|
||||
|
||||
@ -487,9 +549,7 @@ createSmoothMesh_objectGroups( MFnMesh const & inMeshFn,
|
||||
return MS::kSuccess;
|
||||
}
|
||||
|
||||
//
|
||||
// Vertex container implementation.
|
||||
//
|
||||
struct Vertex {
|
||||
|
||||
Vertex() { }
|
||||
@ -515,10 +575,66 @@ struct Vertex {
|
||||
float position[3];
|
||||
};
|
||||
|
||||
// Face-varying container implementation for UVs
|
||||
struct FVarVertexUV {
|
||||
|
||||
FVarVertexUV() {
|
||||
u=v=0.0f;
|
||||
}
|
||||
|
||||
FVarVertexUV(FVarVertexUV const & src) {
|
||||
u = src.u;
|
||||
v = src.v;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
u=v=0.0f;
|
||||
}
|
||||
|
||||
void AddWithWeight(FVarVertexUV const & src, float weight) {
|
||||
u += weight * src.u;
|
||||
v += weight * src.v;
|
||||
}
|
||||
|
||||
// Basic 'uv' layout channel
|
||||
float u,v;
|
||||
};
|
||||
|
||||
// Face-varying container implementation for Color
|
||||
struct FVarVertexColor {
|
||||
|
||||
FVarVertexColor() {
|
||||
r=g=b=a=0.0f;
|
||||
}
|
||||
|
||||
FVarVertexColor(FVarVertexColor const & src) {
|
||||
r = src.r;
|
||||
g = src.g;
|
||||
b = src.b;
|
||||
a = src.a;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
r=g=b=a=0.0f;
|
||||
}
|
||||
|
||||
void AddWithWeight(FVarVertexColor const & src, float weight) {
|
||||
r += weight * src.r;
|
||||
g += weight * src.g;
|
||||
b += weight * src.b;
|
||||
a += weight * src.a;
|
||||
}
|
||||
|
||||
// Basic 'rgba' layout channel
|
||||
float r,g,b,a;
|
||||
};
|
||||
|
||||
static MStatus
|
||||
convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
std::vector<Vertex> const & vertexBuffer, MFnMesh const & inMeshFn,
|
||||
MObject newMeshDataObj) {
|
||||
std::vector<Vertex> const & refinedVerts,
|
||||
bool hasUVs, std::vector<FVarVertexUV> const & refinedUVs,
|
||||
bool hasColors, std::vector<FVarVertexColor> const & refinedColors,
|
||||
MFnMesh & inMeshFn, MObject newMeshDataObj) {
|
||||
|
||||
MStatus status;
|
||||
|
||||
@ -530,16 +646,16 @@ convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
= refiner.GetLevel(maxlevel);
|
||||
|
||||
int nfaces = refLastLevel.GetNumFaces();
|
||||
|
||||
|
||||
// Init Maya Data
|
||||
|
||||
// -- Face Counts
|
||||
// Face Counts
|
||||
MIntArray faceCounts(nfaces);
|
||||
for (int face=0; face < nfaces; ++face) {
|
||||
faceCounts[face] = 4;
|
||||
}
|
||||
|
||||
// -- Face Connects
|
||||
// Face Connects
|
||||
MIntArray faceConnects(nfaces*4);
|
||||
for (int face=0, idx=0; face < nfaces; ++face) {
|
||||
IndexArray fverts = refLastLevel.GetFaceVertices(face);
|
||||
@ -548,10 +664,9 @@ convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
}
|
||||
}
|
||||
|
||||
// -- Points
|
||||
// Points
|
||||
MFloatPointArray points(refLastLevel.GetNumVertices());
|
||||
Vertex const * v = &vertexBuffer.at(0);
|
||||
|
||||
Vertex const * v = &refinedVerts.at(0);
|
||||
for (int level=1; level<=maxlevel; ++level) {
|
||||
int nverts = refiner.GetLevel(level).GetNumVertices();
|
||||
if (level==maxlevel) {
|
||||
@ -569,27 +684,109 @@ convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
points, faceCounts, faceConnects, newMeshDataObj, &status);
|
||||
MCHECKERR(status, "Cannot create new mesh");
|
||||
|
||||
int fvarTotalWidth = 0;
|
||||
// Get face-varying set names and other info from the inMesh
|
||||
MStringArray uvSetNames;
|
||||
MStringArray colorSetNames;
|
||||
std::vector<int> colorSetChannels;
|
||||
std::vector<MFnMesh::MColorRepresentation> colorSetReps;
|
||||
int totalColorSetChannels = 0;
|
||||
status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
|
||||
colorSetChannels, colorSetReps, totalColorSetChannels);
|
||||
|
||||
if (fvarTotalWidth > 0) {
|
||||
// Add new UVs back to the mesh if needed
|
||||
if (hasUVs) {
|
||||
|
||||
// Get face-varying set names and other info from the inMesh
|
||||
MStringArray uvSetNames;
|
||||
MStringArray colorSetNames;
|
||||
std::vector<int> colorSetChannels;
|
||||
std::vector<MFnMesh::MColorRepresentation> colorSetReps;
|
||||
int totalColorSetChannels = 0;
|
||||
status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
|
||||
colorSetChannels, colorSetReps, totalColorSetChannels);
|
||||
MIntArray fvarConnects(faceConnects.length());
|
||||
int count = 0;
|
||||
for (int f = 0; f < refLastLevel.GetNumFaces(); ++f) {
|
||||
IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELUV);
|
||||
for (int index = 0 ; index < faceIndices.size() ; ++index) {
|
||||
fvarConnects[count] = faceIndices[index];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG) or defined(_DEBUG)
|
||||
int numUVSets = uvSetNames.length();
|
||||
int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels;
|
||||
assert(fvarTotalWidth == expectedFvarTotalWidth);
|
||||
#endif
|
||||
MFloatArray uCoord(refLastLevel.GetNumFVarValues(CHANNELUV));
|
||||
MFloatArray vCoord(refLastLevel.GetNumFVarValues(CHANNELUV));
|
||||
FVarVertexUV const * uv = &refinedUVs.at(0);
|
||||
|
||||
// XXXX fvar stuff here
|
||||
for (int level=1; level<=maxlevel; ++level) {
|
||||
int nuvs = refiner.GetLevel(level).GetNumFVarValues(CHANNELUV);
|
||||
if (level==maxlevel) {
|
||||
for (int uvIt=0; uvIt<nuvs; ++uvIt, ++uv) {
|
||||
uCoord[uvIt] = uv->u;
|
||||
vCoord[uvIt] = uv->v;
|
||||
}
|
||||
} else {
|
||||
uv += nuvs;
|
||||
}
|
||||
}
|
||||
|
||||
// Currently, the plugin only supports one UV set
|
||||
int uvSetIndex = 0;
|
||||
if (uvSetIndex > 0) {
|
||||
status = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] );
|
||||
MCHECKERR(status, "Cannot create UVSet");
|
||||
}
|
||||
static MString defaultUVName("map1");
|
||||
MString const * uvname = uvSetIndex==0 ?
|
||||
&defaultUVName : &uvSetNames[uvSetIndex];
|
||||
status = newMeshFn.setUVs(uCoord, vCoord, uvname);
|
||||
MCHECKERR(status, "Cannot set UVs for set : "+*uvname);
|
||||
status = newMeshFn.assignUVs(faceCounts, fvarConnects, uvname);
|
||||
MCHECKERR(status, "Cannot assign UVs");
|
||||
}
|
||||
|
||||
// Add new colors back to the mesh if needed
|
||||
if (hasColors) {
|
||||
|
||||
int count = 0;
|
||||
MIntArray fvarConnects2(faceConnects.length());
|
||||
for (int f = 0 ; f < refLastLevel.GetNumFaces(); ++f) {
|
||||
IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELCOLOR);
|
||||
for (int index = 0 ; index < faceIndices.size() ; ++index) {
|
||||
fvarConnects2[count] = faceIndices[index];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
MColorArray colorArray(refLastLevel.GetNumFVarValues(CHANNELCOLOR));
|
||||
FVarVertexColor const * c = &refinedColors.at(0);
|
||||
for (int level=1; level<=maxlevel; ++level) {
|
||||
int ncolors = refiner.GetLevel(level).GetNumFVarValues(CHANNELCOLOR);
|
||||
if (level==maxlevel) {
|
||||
for (int colorIt=0; colorIt<ncolors; ++colorIt, ++c) {
|
||||
colorArray.set(colorIt, c->r, c->g, c->b, c->a);
|
||||
}
|
||||
} else {
|
||||
c += ncolors;
|
||||
}
|
||||
}
|
||||
|
||||
// Currently, the plugin only supports one color sets
|
||||
int colorSetIndex = 0;
|
||||
|
||||
// Assign color buffer and map the ids for each face-vertex
|
||||
status = newMeshFn.createColorSetDataMesh(
|
||||
colorSetNames[colorSetIndex]);
|
||||
MCHECKERR(status, "Cannot create ColorSet");
|
||||
|
||||
bool isColorClamped = inMeshFn.isColorClamped(
|
||||
colorSetNames[colorSetIndex], &status);
|
||||
MCHECKERR(status, "Can not get Color Clamped ");
|
||||
|
||||
status = newMeshFn.setIsColorClamped(
|
||||
colorSetNames[colorSetIndex], isColorClamped);
|
||||
MCHECKERR(status, "Can not set Color Clamped : " + isColorClamped);
|
||||
|
||||
status = newMeshFn.setColors(
|
||||
colorArray, &colorSetNames[colorSetIndex],
|
||||
colorSetReps[colorSetIndex]);
|
||||
MCHECKERR(status, "Can not set Colors");
|
||||
|
||||
status = newMeshFn.assignColors(
|
||||
fvarConnects2, &colorSetNames[colorSetIndex]);
|
||||
MCHECKERR(status, "Can not assign Colors");
|
||||
}
|
||||
|
||||
return MS::kSuccess;
|
||||
@ -633,9 +830,7 @@ MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {
|
||||
// Convert attr values to OSD enums
|
||||
OpenSubdiv::Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;
|
||||
|
||||
//
|
||||
// Create Far topology
|
||||
//
|
||||
// == Create Far topology ==========================
|
||||
OpenSubdiv::Sdc::Options options;
|
||||
options.SetVtxBoundaryInterpolation(ConvertMayaVtxBoundary(vertBoundaryMethod));
|
||||
options.SetFVarLinearInterpolation(ConvertMayaFVarBoundary(fvarBoundaryMethod, fvarPropCorners));
|
||||
@ -644,27 +839,100 @@ MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {
|
||||
options.SetTriangleSubdivision(smoothTriangles ?
|
||||
OpenSubdiv::Sdc::Options::TRI_SUB_SMOOTH : OpenSubdiv::Sdc::Options::TRI_SUB_CATMARK);
|
||||
|
||||
// Storage for face-varying values (UV sets, vertex colors...)
|
||||
std::vector<MFloatArray> uvSet_uCoords;
|
||||
std::vector<MFloatArray> uvSet_vCoords;
|
||||
std::vector<MColorArray> colorSet_colors;
|
||||
|
||||
bool hasUVs = false, hasColors = false;
|
||||
float maxCreaseSharpness=0.0f;
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner =
|
||||
gatherTopology(inMeshFn, inMeshItPolygon, type, options, &maxCreaseSharpness);
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner = gatherTopology(
|
||||
inMeshFn, inMeshItPolygon, type, options, hasUVs, hasColors,
|
||||
uvSet_uCoords, uvSet_vCoords, colorSet_colors, &maxCreaseSharpness);
|
||||
|
||||
assert(refiner);
|
||||
|
||||
// Refine & Interpolate
|
||||
// == Refine & Interpolate ==========================
|
||||
refiner->RefineUniform(OpenSubdiv::Far::TopologyRefiner::UniformOptions(subdivisionLevel));
|
||||
|
||||
Vertex const * controlVerts =
|
||||
// Prepare vertex information
|
||||
Vertex const * initialVerts =
|
||||
reinterpret_cast<Vertex const *>(inMeshFn.getRawPoints(&status));
|
||||
|
||||
std::vector<Vertex> refinedVerts(
|
||||
refiner->GetNumVerticesTotal() - refiner->GetLevel(0).GetNumVertices());
|
||||
|
||||
Vertex const * srcVerts = controlVerts;
|
||||
Vertex const * srcVerts = &initialVerts[0];
|
||||
Vertex * dstVerts = &refinedVerts[0];
|
||||
|
||||
// Verify the refiner has the correct number of values
|
||||
// needed to interpolate the different channels
|
||||
int numInitialUVs = refiner->GetLevel(0).GetNumFVarValues(CHANNELUV);
|
||||
int numInitialColors = refiner->GetLevel(0).GetNumFVarValues(CHANNELCOLOR);
|
||||
|
||||
if (hasUVs && numInitialUVs <= 0) {
|
||||
hasUVs = false;
|
||||
MGlobal::displayError("Model with incorrect data, the UV channel will not be interpolated.");
|
||||
}
|
||||
|
||||
if (hasColors && numInitialColors <= 0) {
|
||||
hasColors = false;
|
||||
MGlobal::displayError("Model with incorrect data, the color channel will not be interpolated.");
|
||||
}
|
||||
|
||||
// Prepare UV information if needed
|
||||
std::vector<FVarVertexUV> initialUVs, refinedUVs;
|
||||
FVarVertexUV const * srcUV = NULL;
|
||||
FVarVertexUV * dstUV = NULL;
|
||||
if(hasUVs) {
|
||||
initialUVs.resize(numInitialUVs);
|
||||
refinedUVs.resize(refiner->GetNumFVarValuesTotal(CHANNELUV));
|
||||
for (int i=0; i<numInitialUVs; ++i) {
|
||||
initialUVs[i].u = uvSet_uCoords[0][i];
|
||||
initialUVs[i].v = uvSet_vCoords[0][i];
|
||||
}
|
||||
srcUV = &initialUVs[0];
|
||||
dstUV = &refinedUVs[0];
|
||||
}
|
||||
|
||||
// Prepare color information if needed
|
||||
std::vector<FVarVertexColor> initialColors, refinedColors;
|
||||
FVarVertexColor const * srcColor = NULL;
|
||||
FVarVertexColor * dstColor = NULL;
|
||||
if(hasColors) {
|
||||
initialColors.resize(numInitialColors);
|
||||
refinedColors.resize(refiner->GetNumFVarValuesTotal(CHANNELCOLOR));
|
||||
for (int i=0; i<numInitialColors; ++i) {
|
||||
initialColors[i].r = colorSet_colors[0][i].r;
|
||||
initialColors[i].g = colorSet_colors[0][i].g;
|
||||
initialColors[i].b = colorSet_colors[0][i].b;
|
||||
initialColors[i].a = colorSet_colors[0][i].a;
|
||||
}
|
||||
srcColor = &initialColors[0];
|
||||
dstColor = &refinedColors[0];
|
||||
}
|
||||
|
||||
// Interpolate the vertices and the different channels
|
||||
OpenSubdiv::Far::PrimvarRefiner primvarRefiner(*refiner);
|
||||
|
||||
for (int level = 1; level <= subdivisionLevel; ++level) {
|
||||
OpenSubdiv::Far::PrimvarRefiner(*refiner).Interpolate(level, srcVerts, dstVerts);
|
||||
|
||||
// Interpolate vertices
|
||||
primvarRefiner.Interpolate(level, srcVerts, dstVerts);
|
||||
srcVerts = dstVerts;
|
||||
dstVerts += refiner->GetLevel(level).GetNumVertices();
|
||||
|
||||
// Interpolate the uv set
|
||||
if(hasUVs) {
|
||||
primvarRefiner.InterpolateFaceVarying(level, srcUV, dstUV, CHANNELUV);
|
||||
srcUV = dstUV;
|
||||
dstUV += refiner->GetLevel(level).GetNumFVarValues(CHANNELUV);
|
||||
}
|
||||
|
||||
// Interpolate any color set
|
||||
if(hasColors) {
|
||||
primvarRefiner.InterpolateFaceVarying(level, srcColor, dstColor, CHANNELCOLOR);
|
||||
srcColor = dstColor;
|
||||
dstColor += refiner->GetLevel(level).GetNumFVarValues(CHANNELCOLOR);
|
||||
}
|
||||
}
|
||||
|
||||
// == Convert subdivided OpenSubdiv mesh to MFnMesh Data outputMesh =============
|
||||
@ -675,7 +943,8 @@ MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {
|
||||
MCHECKERR(status, "ERROR creating outputData");
|
||||
|
||||
// Create out mesh
|
||||
status = convertToMayaMeshData(*refiner, refinedVerts, inMeshFn, newMeshDataObj);
|
||||
status = convertToMayaMeshData(*refiner, refinedVerts, hasUVs,
|
||||
refinedUVs, hasColors, refinedColors, inMeshFn, newMeshDataObj);
|
||||
MCHECKERR(status, "ERROR convertOsdFarToMayaMesh");
|
||||
|
||||
// Propagate objectGroups from inMesh to outMesh (for per-facet shading, etc)
|
||||
@ -691,6 +960,7 @@ MayaPolySmooth::compute( const MPlug& plug, MDataBlock& data ) {
|
||||
data.outputValue(a_recommendedIsolation).set(isolation);
|
||||
|
||||
// == Cleanup OSD ============================================
|
||||
|
||||
// REVISIT: Re-add these deletes
|
||||
delete refiner;
|
||||
|
||||
@ -940,8 +1210,8 @@ MayaPolySmooth::initialize() {
|
||||
// Plugin
|
||||
// ==========================================
|
||||
|
||||
MStatus initializePlugin( MObject obj )
|
||||
{
|
||||
MStatus initializePlugin( MObject obj ) {
|
||||
|
||||
MStatus status = MS::kSuccess;
|
||||
MFnPlugin plugin( obj, "MayaPolySmooth", "1.0", "Any");
|
||||
|
||||
@ -968,8 +1238,8 @@ MStatus initializePlugin( MObject obj )
|
||||
return status;
|
||||
}
|
||||
|
||||
MStatus uninitializePlugin( MObject obj)
|
||||
{
|
||||
MStatus uninitializePlugin( MObject obj) {
|
||||
|
||||
MStatus returnStatus = MS::kSuccess;
|
||||
MFnPlugin plugin( obj );
|
||||
|
||||
@ -977,4 +1247,4 @@ MStatus uninitializePlugin( MObject obj)
|
||||
MCHECKERR(returnStatus, "deregisterNode");
|
||||
|
||||
return returnStatus;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user