#include "util.h"
#include "NurbsSurfaceHelper.h"
#include "NodeIteratorVisitorHelper.h"
#include <maya/MString.h>
#include <maya/MDagPath.h>
#include <maya/MDoubleArray.h>
#include <maya/MPointArray.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MFnNurbsCurveData.h>
#include <maya/MGlobal.h>
#include <maya/MObjectArray.h>
#include <maya/MTrimBoundaryArray.h>
#include <maya/MFnTransform.h>
#include <maya/MCommandResult.h>
#include <maya/MDagModifier.h>
namespace
{
void trimSurface( Alembic::AbcGeom::INuPatchSchema::Sample & iSamp,
{
Alembic::Util::int32_t numLoops = iSamp.getTrimNumLoops();
if (numLoops == 0)
return;
double startU, endU, startV, endV;
double offsetV = startV + endV;
Alembic::Abc::Int32ArraySamplePtr numCurvesPerLoop =
iSamp.getTrimNumCurves();
Alembic::Abc::Int32ArraySamplePtr numCurveVerts =
iSamp.getTrimNumVertices();
Alembic::Abc::Int32ArraySamplePtr orders = iSamp.getTrimOrders();
Alembic::Abc::FloatArraySamplePtr knots = iSamp.getTrimKnots();
Alembic::Abc::FloatArraySamplePtr uVert = iSamp.getTrimU();
Alembic::Abc::FloatArraySamplePtr vVert = iSamp.getTrimV();
Alembic::Abc::FloatArraySamplePtr wVert = iSamp.getTrimW();
Alembic::Util::int32_t curCurve = 0;
Alembic::Util::int32_t curPos = 0;
Alembic::Util::int32_t curKnot = 0;
for (Alembic::Util::int32_t i = 0; i < numLoops; ++i)
{
Alembic::Util::int32_t numCurves = (*numCurvesPerLoop)[i];
for (Alembic::Util::int32_t j = 0; j < numCurves; ++j, ++curCurve)
{
unsigned int degree = (*orders)[curCurve] - 1;
Alembic::Util::int32_t numVerts = (*numCurveVerts)[curCurve];
Alembic::Util::int32_t numKnots = numVerts + degree + 1;
for (Alembic::Util::int32_t k=0 ; k<numVerts; ++k, ++curPos)
{
double x = (*uVert)[curPos];
double y = (*vVert)[curPos];
double w = (*wVert)[curPos];
cvs.
set(k, x, offsetV-y, 0.0, w);
}
++curKnot;
for (Alembic::Util::int32_t k = 1; k < numKnots - 1;
++k, ++curKnot)
{
dknots.
set((*knots)[curKnot], k - 1);
}
++curKnot;
curveData, &status);
{
{
}
}
}
trimBoundaryArray.
append(trimLoop);
}
for (
unsigned int i = 0; i < trimBoundaryArray.
length(); i++)
{
if (i > 0)
{
bool isOuterBoundary = false;
double length = loop.
length();
unsigned int segment = std::max(loop.
numCVs(), 10);
for (unsigned int j = 0; j < segment; j++)
{
}
MPoint rightMostPoint = curvePoints[0];
unsigned int rightMostIndex = 0;
for (unsigned int j = 0; j < curvePoints.length(); j++)
{
if (rightMostPoint.
x < curvePoints[j].x)
{
rightMostPoint = curvePoints[j];
rightMostIndex = j;
}
}
int beforeIndex = (rightMostIndex == 0) ? curvePoints.length() - 1 : rightMostIndex - 1;
int afterIndex = (rightMostIndex == curvePoints.length() - 1) ? 0 : rightMostIndex + 1;
for (unsigned int j = 0; j < curvePoints.length(); j++)
{
if (fabs(curvePoints[beforeIndex].x - curvePoints[rightMostIndex].x) < 1e-5)
{
beforeIndex = (beforeIndex == 0) ? curvePoints.length() - 1 : beforeIndex - 1;
}
}
for (unsigned int j = 0; j < curvePoints.length(); j++)
{
if (fabs(curvePoints[afterIndex].x - curvePoints[rightMostIndex].x) < 1e-5)
{
afterIndex = (afterIndex == (int)(curvePoints.length()) - 1) ? 0 : afterIndex + 1;
}
}
if (fabs(curvePoints[afterIndex].x - curvePoints[rightMostIndex].x) < 1e-5 &&
fabs(curvePoints[beforeIndex].x - curvePoints[rightMostIndex].x) < 1e-5)
{
continue;
}
if (beforeIndex < 0)
beforeIndex += curvePoints.length();
if (beforeIndex >= (int)(curvePoints.length()))
beforeIndex = beforeIndex & curvePoints.length();
if (afterIndex < 0)
afterIndex += curvePoints.length();
if (afterIndex >= (int)(curvePoints.length()))
afterIndex = afterIndex & curvePoints.length();
MVector vector1 = curvePoints[beforeIndex] - curvePoints[rightMostIndex];
MVector vector2 = curvePoints[afterIndex] - curvePoints[rightMostIndex];
if ((vector1 ^ vector2).z < 0)
{
isOuterBoundary = true;
}
if (isOuterBoundary)
{
#if MAYA_API_VERSION < 201300
#else
#endif
{
"Trimming Nurbs Surface outer failed.");
}
}
}
oneRegion.
append(trimBoundaryArray[i]);
}
#if MAYA_API_VERSION < 201300
#else
#endif
{
}
}
}
MObject readNurbs(
double iFrame, Alembic::AbcGeom::INuPatch & iNode,
{
Alembic::AbcGeom::INuPatchSchema schema = iNode.getSchema();
Alembic::AbcCoreAbstract::index_t index, ceilIndex;
getWeightAndIndex(iFrame, schema.getTimeSampling(),
schema.getNumSamples(), index, ceilIndex);
Alembic::AbcGeom::INuPatchSchema::Sample samp;
schema.get(samp, Alembic::Abc::ISampleSelector(index));
Alembic::Abc::P3fArraySamplePtr pos = samp.getPositions();
Alembic::Abc::FloatArraySamplePtr weights = samp.getPositionWeights();
MString surfaceName(iNode.getName().c_str());
unsigned int degreeU = samp.getUOrder() - 1;
unsigned int degreeV = samp.getVOrder() - 1;
unsigned int numCVInU = samp.getNumU();
unsigned int numCVInV = samp.getNumV();
unsigned int numCV = numCVInU*numCVInV;
unsigned int curPos = 0;
for (unsigned int v = 0; v < numCVInV; ++v)
{
for (unsigned int u = 0; u < numCVInU; ++u, ++curPos)
{
unsigned int mayaIndex = u * numCVInV + (numCVInV - v - 1);
MPoint pt((*pos)[curPos].x, (*pos)[curPos].y, (*pos)[curPos].z);
if (weights)
{
pt.w = (*weights)[curPos];
}
controlVertices.
set(pt, mayaIndex);
}
}
bool notOpen = true;
for (unsigned int v = 0; notOpen && v < numCVInV; v++) {
for (unsigned int u = 0; u < degreeU; u++) {
unsigned int firstIndex = u * numCVInV + (numCVInV - v - 1);
unsigned int lastPeriodicIndex = (numCVInU - degreeU + u) * numCVInV + (numCVInV - v - 1);
if (!controlVertices[firstIndex].isEquivalent(controlVertices[lastPeriodicIndex])) {
notOpen = false;
break;
}
}
}
for (unsigned int v = 0; v < numCVInV; v++) {
unsigned int lastUIndex = (numCVInU - 1) * numCVInV + (numCVInV - v - 1);
if (! controlVertices[numCVInV-v-1].isEquivalent(controlVertices[lastUIndex])) {
break;
}
}
}
notOpen = true;
for (unsigned int u = 0; notOpen && u < numCVInU; u++) {
for (unsigned int v = 0; v < degreeV; v++) {
unsigned int firstIndex = u * numCVInV + (numCVInV - v - 1);
unsigned int lastPeriodicIndex = u * numCVInV + (degreeV - v - 1);
if (!controlVertices[firstIndex].isEquivalent(controlVertices[lastPeriodicIndex])) {
notOpen = false;
break;
}
}
}
for (unsigned int u = 0; u < numCVInU; u++) {
if (! controlVertices[u * numCVInV + (numCVInV-1)].isEquivalent(controlVertices[u * numCVInV])) {
break;
}
}
}
Alembic::Abc::FloatArraySamplePtr uKnot = samp.getUKnot();
Alembic::Abc::FloatArraySamplePtr vKnot = samp.getVKnot();
unsigned int numKnotsInU = static_cast<unsigned int>(uKnot->size() - 2);
for (unsigned int i = 0; i < numKnotsInU; ++i)
{
uKnotSequences.
set((*uKnot)[i+1], i);
}
unsigned int numKnotsInV = static_cast<unsigned int>(vKnot->size() - 2);
for (unsigned int i = 0; i < numKnotsInV; i++)
{
vKnotSequences.
set((*vKnot)[i+1], i);
}
obj = mFn.
create(controlVertices, uKnotSequences, vKnotSequences,
degreeU, degreeV, formU, formV,
true, iObject, &status);
{
obj = mFn.
create(controlVertices, uKnotSequences, vKnotSequences,
true, iObject, &status);
}
{
}
else
{
MString errorMsg =
"Could not create Nurbs Surface: ";
errorMsg += surfaceName;
}
trimSurface(samp, mFn);
return obj;
}
MObject createNurbs(
double iFrame, Alembic::AbcGeom::INuPatch & iNode,
{
MObject obj = readNurbs(iFrame, iNode, iParent);
{
setInitialShadingGroup(fn.partialPathName());
}
return obj;
}