#include "MayaNurbsCurveWriter.h"
#include "MayaUtility.h"
#include "MayaTransformWriter.h"
namespace
{
void collectNurbsCurves(
const MDagPath &dagPath,
bool iExcludeInvisible,
{
{
{
{
if ( !util::isIntermediate(curve) &&
(!iExcludeInvisible || util::isRenderable(curve)) )
{
}
else
{
continue;
}
if (util::isAnimated(curve, true))
{
oIsAnimated = true;
}
}
}
}
}
}
MayaNurbsCurveWriter::MayaNurbsCurveWriter(
MDagPath & iDag,
Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
bool iIsCurveGrp, const JobArgs & iArgs) :
mIsAnimated(false), mRootDagPath(iDag), mIsCurveGrp(iIsCurveGrp)
{
if (mIsCurveGrp)
{
collectNurbsCurves(mRootDagPath, iArgs.excludeInvisible,
mNurbsCurves, mIsAnimated);
if (mNurbsCurves.length() == 0)
return;
}
else
{
if (iTimeIndex != 0 && util::isAnimated(curve))
{
mIsAnimated = true;
}
else
{
iTimeIndex = 0;
}
}
name = util::stripNamespaces(name, iArgs.stripNamespace);
Alembic::AbcGeom::OCurves obj(iParent, name.asChar(), iTimeIndex);
mSchema = obj.getSchema();
Alembic::Abc::OCompoundProperty cp;
Alembic::Abc::OCompoundProperty up;
if (AttributesWriter::hasAnyAttr(fnDepNode, iArgs))
{
cp = mSchema.getArbGeomParams();
up = mSchema.getUserProperties();
}
mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, fnDepNode,
iTimeIndex, iArgs));
write();
}
unsigned int MayaNurbsCurveWriter::getNumCVs()
{
return mCVCount;
}
unsigned int MayaNurbsCurveWriter::getNumCurves()
{
if (mIsCurveGrp)
return mNurbsCurves.length();
else
return 1;
}
bool MayaNurbsCurveWriter::isAnimated() const
{
return mIsAnimated;
}
void MayaNurbsCurveWriter::write()
{
Alembic::AbcGeom::OCurvesSchema::Sample samp;
samp.setBasis(Alembic::AbcGeom::kBsplineBasis);
mCVCount = 0;
MMatrix exclusiveMatrixInv = mRootDagPath.exclusiveMatrixInverse(&stat);
std::size_t numCurves = 1;
if (mIsCurveGrp)
numCurves = mNurbsCurves.length();
std::vector<Alembic::Util::int32_t> nVertices(numCurves);
std::vector<float> points;
std::vector<float> width;
std::vector<float> knots;
std::vector<Alembic::Util::uint8_t> orders(numCurves);
bool useConstWidth = false;
MPlug constWidthPlug = dep.findPlug(
"width");
if (!constWidthPlug.isNull())
{
useConstWidth = true;
width.push_back(constWidthPlug.asFloat());
}
for (unsigned int i = 0; i < numCurves; i++)
{
if (mIsCurveGrp)
{
MMatrix inclusiveMatrix = mNurbsCurves[i].inclusiveMatrix(&stat);
transformMatrix = inclusiveMatrix*exclusiveMatrixInv;
}
else
{
}
if (i == 0)
{
{
samp.setWrap(Alembic::AbcGeom::kNonPeriodic);
}
else
{
samp.setWrap(Alembic::AbcGeom::kPeriodic);
}
{
samp.setType(Alembic::AbcGeom::kCubic);
}
{
samp.setType(Alembic::AbcGeom::kLinear);
}
else
{
samp.setType(Alembic::AbcGeom::kVariableOrder);
}
}
else
{
{
samp.setWrap(Alembic::AbcGeom::kNonPeriodic);
}
if ((samp.getType() == Alembic::AbcGeom::kCubic &&
(samp.getType() == Alembic::AbcGeom::kLinear &&
{
samp.setType(Alembic::AbcGeom::kVariableOrder);
}
}
orders[i] =
static_cast<Alembic::Util::uint8_t
>(curve.
degree() + 1);
Alembic::Util::int32_t numCVs = curve.
numCVs(&stat);
mCVCount += numCVs;
nVertices[i] = numCVs;
for (Alembic::Util::int32_t j = 0; j < numCVs; j++)
{
if (mIsCurveGrp)
{
transformdPt = cvArray[j]*transformMatrix;
}
else
{
transformdPt = cvArray[j];
}
points.push_back(static_cast<float>(transformdPt.
x));
points.push_back(static_cast<float>(transformdPt.
y));
points.push_back(static_cast<float>(transformdPt.
z));
}
knots.reserve(knotsArray.
length() + 2);
{
unsigned int knotsLength = knotsArray.
length();
if (knotsArray[0] == knotsArray[knotsLength - 1] ||
knotsArray[0] == knotsArray[1])
{
knots.push_back(knotsArray[0]);
}
else
{
knots.push_back(2 * knotsArray[0] - knotsArray[1]);
}
for (unsigned int j = 0; j < knotsLength; ++j)
{
knots.push_back(knotsArray[j]);
}
if (knotsArray[0] == knotsArray[knotsLength - 1] ||
knotsArray[knotsLength - 1] == knotsArray[knotsLength - 2])
{
knots.push_back(knotsArray[knotsLength - 1]);
}
else
{
knots.push_back(2 * knotsArray[knotsLength - 1] -
knotsArray[knotsLength - 2]);
}
}
if (!useConstWidth && !widthPlug.
isNull())
{
Alembic::Util::int32_t arraySum = doubleArrayData.
length();
if (arraySum == numCVs)
{
for (Alembic::Util::int32_t i = 0; i < arraySum; i++)
{
width.push_back(static_cast<float>(doubleArrayData[i]));
}
}
{
msg += " has incorrect size for the width vector.";
msg += "\nUsing default constant width of 0.1.";
width.clear();
width.push_back(0.1f);
useConstWidth = true;
}
else
{
width.push_back(widthPlug.
asFloat());
useConstWidth = true;
}
}
else if (!useConstWidth)
{
width.clear();
width.push_back(0.1f);
useConstWidth = true;
}
}
Alembic::AbcGeom::GeometryScope scope = Alembic::AbcGeom::kVertexScope;
if (useConstWidth)
scope = Alembic::AbcGeom::kConstantScope;
samp.setCurvesNumVertices(Alembic::Abc::Int32ArraySample(nVertices));
samp.setPositions(Alembic::Abc::V3fArraySample(
(const Imath::V3f *)&points.front(), points.size() / 3 ));
samp.setWidths(Alembic::AbcGeom::OFloatGeomParam::Sample(
Alembic::Abc::FloatArraySample(width), scope) );
if (samp.getType() == Alembic::AbcGeom::kVariableOrder)
{
samp.setOrders(Alembic::Abc::UcharArraySample(orders));
}
if (!knots.empty())
{
samp.setKnots(Alembic::Abc::FloatArraySample(knots));
}
mSchema.set(samp);
}