#include "util.h"
#include "AlembicNode.h"
#include "CreateSceneHelper.h"
#include "NodeIteratorVisitorHelper.h"
#include "AbcImportStrings.h"
#include <Alembic/AbcCoreFactory/IFactory.h>
#include <maya/MDoubleArray.h>
#include <maya/MFloatArray.h>
#include <maya/MIntArray.h>
#include <maya/MFnIntArrayData.h>
#include <maya/MPlug.h>
#include <maya/MPointArray.h>
#include <maya/MUint64Array.h>
#include <maya/MStringArray.h>
#include <maya/MFnData.h>
#include <maya/MFnDoubleArrayData.h>
#include <maya/MFnFloatArrayData.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnNumericData.h>
#include <maya/MFnStringData.h>
#include <maya/MFnStringArrayData.h>
#include <maya/MFnPointArrayData.h>
#include <maya/MFnVectorArrayData.h>
#include <maya/MFnMesh.h>
#include <maya/MFnTransform.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MObjectArray.h>
#include <maya/MDGModifier.h>
#include <maya/MSelectionList.h>
#include <maya/MFnLight.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnCamera.h>
#include <maya/MTime.h>
#include <maya/MFileObject.h>
template <class T>
void unsupportedWarning(T & iProp)
{
MString warn = AbcImportStrings::getString(AbcImportStrings::kWarningUnsupportedAttr) ;
warn += iProp.getName().c_str();
warn += " ";
warn += PODName(iProp.getDataType().getPod());
warn += "[";
warn += iProp.getDataType().getExtent();
warn += "]";
printWarning(warn);
}
void addString(
MObject & iParent,
const std::string & iAttrName,
const std::string & iValue)
{
MString attrName(iAttrName.c_str());
strAttrObject);
parentFn.addAttribute(attrObj);
MPlug plug = parentFn.findPlug(attrName,
true);
{
}
}
void addArbAttrAndScope(
MObject & iParent,
const std::string & iAttrName,
const std::string & iScope, const std::string & iInterp,
Alembic::Util::uint8_t iExtent)
{
std::string attrStr;
if (iInterp == "rgb" && iScope != "" && iScope != "con")
{
attrStr = "rgb";
}
else if (iInterp == "rgba" && iScope != "" && iScope != "con")
{
attrStr = "rgba";
}
else if (iInterp == "vector")
{
if (iExtent == 2)
attrStr = "vector2";
}
else if (iInterp == "point")
{
if (iExtent == 2)
attrStr = "point2";
}
else if (iInterp == "normal")
{
if (iExtent == 2)
attrStr = "normal2";
else if (iExtent == 3)
attrStr = "normal3";
}
if (attrStr != "")
{
std::string attrName = iAttrName + "_AbcType";
addString(iParent, attrName, attrStr);
}
if (iScope != "" && iScope != "con")
{
std::string attrName = iAttrName + "_AbcGeomScope";
addString(iParent, attrName, iScope);
}
}
bool addArrayProp(Alembic::Abc::IArrayProperty & iProp,
MObject & iParent)
{
MString attrName(iProp.getName().c_str());
MPlug plug = parentFn.findPlug(attrName,
true);
Alembic::AbcCoreAbstract::DataType dtype = iProp.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
std::string interp = iProp.getMetaData().get("interpretation");
bool isScalarLike = iProp.isScalarLike() &&
iProp.getMetaData().get("isArray") != "1";
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
{
if (extent != 1 || !isScalarLike)
{
return false;
}
bool bval = 0;
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr val;
iProp.get(val);
bval =
((Alembic::Util::bool_t *)(val->getData()))[0] != false;
}
if (plug.isNull())
{
attrObj = numAttr.
create(attrName, attrName,
}
else
{
plug.setValue(bval);
return true;
}
}
break;
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
if (extent != 1 || !isScalarLike)
{
return false;
}
Alembic::Util::int8_t val = 1;
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
val = ((Alembic::Util::int8_t *) samp->getData())[0];
}
if (plug.isNull())
{
attrObj = numAttr.
create(attrName, attrName,
}
else
{
plug.setValue(val);
}
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
if (extent > 3 || !isScalarLike)
{
return false;
}
Alembic::Util::int16_t val[3] = {0, 0, 0};
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
const Alembic::Util::int16_t * sampData =
(const Alembic::Util::int16_t *) samp->getData();
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = sampData[i];
}
}
if (!plug.isNull())
{
unsigned int numChildren = plug.numChildren();
if (numChildren == 0)
{
plug.setValue(val[0]);
}
else
{
if (numChildren > extent)
numChildren = extent;
for (unsigned int i = 0; i < numChildren; ++i)
{
plug.child(i).setValue(val[i]);
}
}
return true;
}
else if (extent == 1)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 3)
{
attrObj = numAttr.
create(attrName, attrName,
}
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
{
if (!isScalarLike)
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
static_cast<unsigned int>(samp->size()));
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else
{
if (extent > 3)
{
return false;
}
Alembic::Util::int32_t val[3] = {0, 0, 0};
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
const Alembic::Util::int32_t * sampData =
(const Alembic::Util::int32_t *)samp->getData();
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = sampData[i];
}
}
if (!plug.isNull())
{
unsigned int numChildren = plug.numChildren();
if (numChildren == 0)
{
plug.setValue(val[0]);
}
else
{
if (numChildren > extent)
numChildren = extent;
for (unsigned int i = 0; i < numChildren; ++i)
{
plug.child(i).setValue(val[i]);
}
}
return true;
}
else if (extent == 1)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 3)
{
attrObj = numAttr.
create(attrName, attrName,
}
}
}
break;
case Alembic::Util::kFloat32POD:
{
if (!isScalarLike)
{
if ((extent == 2 || extent == 3) && (interp == "normal" ||
interp == "vector" || interp == "rgb"))
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
const Alembic::Util::float32_t * sampData =
(const Alembic::Util::float32_t *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
x = sampData[extent*i];
vec.
y = sampData[extent*i+1];
if (extent == 3)
{
vec.
z = sampData[extent*i+2];
}
arr[i] = vec;
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else if (interp == "point" && (extent == 2 || extent == 3))
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
const Alembic::Util::float32_t * sampData =
(const Alembic::Util::float32_t *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
pt.
x = sampData[extent*i];
pt.
y = sampData[extent*i+1];
if (extent == 3)
{
pt.
z = sampData[extent*i+2];
}
arr[i] = pt;
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
static_cast<unsigned int>(samp->size()));
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
}
else
{
if (extent > 3)
{
return false;
}
float val[3] = {0, 0, 0};
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
const float * sampData = (const float *) samp->getData();
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = sampData[i];
}
}
if (!plug.isNull())
{
unsigned int numChildren = plug.numChildren();
if (numChildren == 0)
{
plug.setValue(val[0]);
}
else
{
if (numChildren > extent)
numChildren = extent;
for (unsigned int i = 0; i < numChildren; ++i)
{
plug.child(i).setValue(val[i]);
}
}
return true;
}
else if (extent == 1)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 3)
{
if (interp == "rgb")
{
}
else if (interp == "point")
{
}
else
{
attrObj = numAttr.
create(attrName, attrName,
}
}
}
}
break;
case Alembic::Util::kFloat64POD:
{
if (!isScalarLike)
{
if ((extent == 2 || extent == 3) && (interp == "normal" ||
interp == "vector" || interp == "rgb"))
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
const Alembic::Util::float64_t * sampData =
(const Alembic::Util::float64_t *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
x = sampData[extent*i];
vec.
y = sampData[extent*i+1];
if (extent == 3)
{
vec.
z = sampData[extent*i+2];
}
arr[i] = vec;
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else if (interp == "point" && (extent == 2 || extent == 3))
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
const Alembic::Util::float64_t * sampData =
(const Alembic::Util::float64_t *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
pt.
x = sampData[extent*i];
pt.
y = sampData[extent*i+1];
if (extent == 3)
{
pt.
z = sampData[extent*i+2];
}
arr[i] = pt;
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
static_cast<unsigned int>(samp->size()));
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
}
else
{
if (extent > 4)
{
return false;
}
double val[4] = {0, 0, 0, 0};
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
const double * sampData = (const double *) samp->getData();
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = sampData[i];
}
}
if (!plug.isNull())
{
unsigned int numChildren = plug.numChildren();
if (numChildren == 0)
{
plug.setValue(val[0]);
}
else
{
if (numChildren > extent)
numChildren = extent;
for (unsigned int i = 0; i < numChildren; ++i)
{
plug.child(i).setValue(val[i]);
}
}
return true;
}
else if (extent == 1)
{
if (plug.isNull())
{
attrObj = numAttr.
create(attrName, attrName,
}
else
{
plug.setValue(val[0]);
return true;
}
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 3)
{
attrObj = numAttr.
create(attrName, attrName,
}
else if (extent == 4)
{
attrObj = numAttr.
create(attrName, attrName,
numAttr.
setDefault(val[0], val[1], val[2], val[3]);
}
}
}
break;
case Alembic::Util::kStringPOD:
{
if (!isScalarLike)
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
Alembic::Util::string * strData =
(Alembic::Util::string *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = strData[i].c_str();
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else
{
if (extent != 1)
{
return false;
}
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
((Alembic::Util::string *) samp->getData())[0].c_str());
strAttrObject = fnStringData.
create(attrValue);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
return true;
}
}
else
{
strAttrObject = fnStringData.
create(attrValue);
}
parentFn.addAttribute(attrObj);
plug = parentFn.findPlug(attrName, true);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
}
}
}
break;
case Alembic::Util::kWstringPOD:
{
if (!isScalarLike)
{
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
unsigned int sampSize = (unsigned int)samp->size();
Alembic::Util::wstring * strData =
(Alembic::Util::wstring *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = (wchar_t *)(strData[i].c_str());
}
if (!plug.isNull())
{
plug.setValue(arrObj);
return true;
}
}
else
{
}
attrObj = typedAttr.
create(attrName, attrName,
}
else
{
if (extent != 1)
{
return false;
}
if (iProp.isConstant())
{
Alembic::AbcCoreAbstract::ArraySamplePtr samp;
iProp.get(samp);
((Alembic::Util::wstring *)samp->getData())[0].c_str());
strAttrObject = fnStringData.
create(attrValue);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
return true;
}
}
else
{
strAttrObject = fnStringData.
create(attrValue);
}
parentFn.addAttribute(attrObj);
plug = parentFn.findPlug(attrName, true);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
}
}
}
break;
default:
{
return false;
}
break;
}
if (isScalarLike && interp == "rgb")
{
}
if ( ! parentFn.hasAttribute( attrName ) )
{
parentFn.addAttribute(attrObj);
}
addArbAttrAndScope(iParent, iProp.getName(),
iProp.getMetaData().get("geoScope"), interp, extent);
return true;
}
template <class PODTYPE>
AddPropResult
addScalarExtentOneProp(Alembic::Abc::IScalarProperty& iProp,
Alembic::Util::uint8_t extent,
PODTYPE defaultVal,
{
if (extent != 1)
return INVALID;
static const Alembic::Abc::ISampleSelector iss((Alembic::Abc::index_t)0);
PODTYPE val = defaultVal;
if (iProp.isConstant())
iProp.get(&val, iss);
{
attrObj = numAttr.
create(attrName, attrName, type, val);
}
else
{
return VALID_DONE;
}
return VALID_NOTDONE;
}
template <class PODTYPE>
AddPropResult
addScalarExtentThreeProp(Alembic::Abc::IScalarProperty& iProp,
Alembic::Util::uint8_t extent,
PODTYPE defaultVal,
{
if (extent > 3)
return INVALID;
static const Alembic::Abc::ISampleSelector iss((Alembic::Abc::index_t)0);
PODTYPE val[3] = {defaultVal, defaultVal, defaultVal};
if (iProp.isConstant())
iProp.get(&val, iss);
{
if (numChildren == 0)
{
}
else
{
if (numChildren > extent)
numChildren = extent;
if (numChildren > 3)
numChildren = 3;
for (unsigned int i = 0; i < numChildren; ++i)
}
return VALID_DONE;
}
else if (extent == 1)
{
attrObj = numAttr.
create(attrName, attrName, type1);
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName, type2);
}
else if (extent == 3)
{
attrObj = numAttr.
create(attrName, attrName, type3);
}
return VALID_NOTDONE;
}
template <class PODTYPE>
AddPropResult
addScalarExtentFourProp(Alembic::Abc::IScalarProperty& iProp,
Alembic::Util::uint8_t extent,
PODTYPE defaultVal,
{
if (extent > 4)
return INVALID;
static const Alembic::Abc::ISampleSelector iss((Alembic::Abc::index_t)0);
PODTYPE val[4] = {defaultVal, defaultVal, defaultVal, defaultVal};
if (iProp.isConstant())
iProp.get(&val, iss);
{
if (numChildren == 0)
{
}
else
{
if (numChildren > extent)
numChildren = extent;
for (unsigned int i = 0; i < numChildren; ++i)
{
}
}
return VALID_DONE;
}
else if (extent == 1)
{
attrObj = numAttr.
create(attrName, attrName, type1);
}
else if (extent == 2)
{
attrObj = numAttr.
create(attrName, attrName, type2);
}
else if (extent == 3)
{
attrObj = numAttr.
create(attrName, attrName, type3);
}
else if (extent == 4)
{
attrObj = numAttr.
create(attrName, attrName, type4);
numAttr.
setDefault(val[0], val[1], val[2], val[3]);
}
return VALID_NOTDONE;
}
bool addScalarProp(Alembic::Abc::IScalarProperty & iProp,
MObject & iParent)
{
MString attrName(iProp.getName().c_str());
MPlug plug = parentFn.findPlug(attrName,
true);
Alembic::AbcCoreAbstract::DataType dtype = iProp.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
std::string interp = iProp.getMetaData().get("interpretation");
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
{
AddPropResult result = addScalarExtentOneProp<bool>
(iProp, extent, false, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
AddPropResult result = addScalarExtentOneProp<Alembic::Util::int8_t>
(iProp, extent, 1, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
AddPropResult result = addScalarExtentThreeProp<Alembic::Util::int16_t>
(iProp, extent, 0, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
{
AddPropResult result = addScalarExtentThreeProp<Alembic::Util::int32_t>
(iProp, extent, 0, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kFloat32POD:
{
AddPropResult result = addScalarExtentThreeProp<float>
(iProp, extent, 0.f, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kFloat64POD:
{
AddPropResult result = addScalarExtentFourProp<double>
(iProp, extent, 0.f, plug, attrName, numAttr, attrObj,
if (result == INVALID)
return false;
else if (result == VALID_DONE)
return true;
}
break;
case Alembic::Util::kStringPOD:
{
if (extent != 1)
return false;
if (iProp.isConstant())
{
Alembic::Abc::IStringProperty strProp( iProp.getPtr(),
Alembic::Abc::kWrapExisting );
if (!strProp.valid())
return false;
if (strProp.getNumSamples() == 0)
return false;
static const Alembic::Abc::ISampleSelector iss((Alembic::Abc::index_t)0);
std::string val = strProp.getValue(iss);
strAttrObject = fnStringData.
create(attrValue);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
return true;
}
}
parentFn.addAttribute(attrObj);
plug = parentFn.findPlug(attrName, true);
if (!plug.isNull())
{
plug.setValue(strAttrObject);
}
}
break;
default:
std::cout << "Type not yet supported.\n";
break;
}
numAttr.setKeyable(true);
if (interp == "rgb")
{
numAttr.setUsedAsColor(true);
}
if ( ! parentFn.hasAttribute( attrName ) )
{
parentFn.addAttribute(attrObj);
}
addArbAttrAndScope(iParent, iProp.getName(),
iProp.getMetaData().get("geoScope"), interp, extent);
return true;
}
void addProps(Alembic::Abc::ICompoundProperty & iParent,
MObject & iObject,
bool iUnmarkedFaceVaryingColors)
{
if (!iParent)
return;
std::size_t numProps = iParent.getNumProperties();
for (std::size_t i = 0; i < numProps; ++i)
{
const Alembic::Abc::PropertyHeader & propHeader =
iParent.getPropertyHeader(i);
const std::string & propName = propHeader.getName();
iUnmarkedFaceVaryingColors) )
{
continue;
}
else if (propName.empty() || propName[0] == '.' ||
propName.find('[') != std::string::npos)
{
MString warn = AbcImportStrings::getString(AbcImportStrings::kWarningSkipOddlyNamed) ;
warn += propName.c_str();
printWarning(warn);
}
else
{
if (propHeader.isArray())
{
Alembic::Abc::IArrayProperty prop(iParent, propName);
if (prop.getNumSamples() == 0)
{
MString warn = AbcImportStrings::getString(AbcImportStrings::kWarningSkipNoSamples) ;
warn += propName.c_str();
printWarning(warn);
}
if (!addArrayProp(prop, iObject))
{
unsupportedWarning<Alembic::Abc::IArrayProperty>(prop);
}
}
else if (propHeader.isScalar())
{
Alembic::Abc::IScalarProperty prop(iParent, propName);
if (prop.getNumSamples() == 0)
{
MString warn =
"Skipping property with no samples: ";
warn += propName.c_str();
printWarning(warn);
}
if (!addScalarProp(prop, iObject))
{
unsupportedWarning<Alembic::Abc::IScalarProperty>(prop);
}
}
}
}
}
void getAnimatedArrayProp(Alembic::Abc::IArrayProperty prop,
std::vector<Prop> & oPropList)
{
Alembic::AbcCoreAbstract::DataType dtype = prop.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
if (extent != 1 || !prop.isScalarLike())
return;
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
if (extent > 3 || !prop.isScalarLike())
return;
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
case Alembic::Util::kFloat32POD:
{
if (prop.isScalarLike() && extent > 3)
return;
}
break;
case Alembic::Util::kFloat64POD:
{
if (prop.isScalarLike() && extent > 4)
return;
}
break;
case Alembic::Util::kStringPOD:
case Alembic::Util::kWstringPOD:
{
if (prop.isScalarLike() && extent > 1)
return;
}
break;
default:
{
return;
}
break;
}
Prop animProp;
animProp.mArray = prop;
oPropList.push_back(animProp);
}
void getAnimatedScalarProp(Alembic::Abc::IScalarProperty prop,
std::vector<Prop> & oPropList)
{
Alembic::AbcCoreAbstract::DataType dtype = prop.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
if (extent != 1)
return;
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
if (extent > 3)
return;
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
case Alembic::Util::kFloat32POD:
{
if (extent > 3)
return;
}
break;
case Alembic::Util::kFloat64POD:
{
if (extent > 4)
return;
}
break;
case Alembic::Util::kStringPOD:
case Alembic::Util::kWstringPOD:
{
if (extent > 1)
return;
}
break;
default:
{
return;
}
break;
}
Prop animProp;
animProp.mScalar = prop;
oPropList.push_back(animProp);
}
void getAnimatedProps(Alembic::Abc::ICompoundProperty & iParent,
std::vector<Prop> & oPropList,
bool iUnmarkedFaceVaryingColors)
{
if (!iParent)
return;
std::size_t numProps = iParent.getNumProperties();
for (std::size_t i = 0; i < numProps; ++i)
{
const Alembic::Abc::PropertyHeader & propHeader =
iParent.getPropertyHeader(i);
const std::string & propName = propHeader.getName();
if ( isColorSet(propHeader, iUnmarkedFaceVaryingColors) )
{
continue;
}
else if (propName.empty() || propName[0] == '.' ||
propName.find('[') != std::string::npos)
{
continue;
}
else if (propHeader.isArray())
{
Alembic::Abc::IArrayProperty prop(iParent, propName);
if (prop.getNumSamples() == 0 || prop.isConstant())
{
continue;
}
getAnimatedArrayProp(prop, oPropList);
}
else if (propHeader.isScalar())
{
Alembic::Abc::IScalarProperty prop(iParent, propName);
if (prop.getNumSamples() == 0 || prop.isConstant())
{
continue;
}
getAnimatedScalarProp(prop, oPropList);
}
}
}
void readProp(double iFrame,
Alembic::Abc::IArrayProperty & iProp,
{
Alembic::AbcCoreAbstract::DataType dtype = iProp.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
Alembic::AbcCoreAbstract::ArraySamplePtr samp, ceilSamp;
Alembic::AbcCoreAbstract::index_t index, ceilIndex;
double alpha = getWeightAndIndex(iFrame, iProp.getTimeSampling(),
iProp.getNumSamples(), index, ceilIndex);
bool isScalarLike = iProp.isScalarLike() &&
iProp.getMetaData().get("isArray") != "1";
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
{
if (!isScalarLike || extent != 1)
{
return;
}
iProp.get(samp, index);
Alembic::Util::bool_t val =
((Alembic::Util::bool_t *) samp->getData())[0];
}
break;
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
if (!isScalarLike || extent != 1)
{
return;
}
Alembic::Util::int8_t val;
if (index != ceilIndex && alpha != 0.0)
{
iProp.get(samp, index);
iProp.get(ceilSamp, ceilIndex);
Alembic::Util::int8_t lo =
((Alembic::Util::int8_t *) samp->getData())[0];
Alembic::Util::int8_t hi =
((Alembic::Util::int8_t *) ceilSamp->getData())[0];
val = simpleLerp<Alembic::Util::int8_t>(alpha, lo, hi);
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
val = ((Alembic::Util::int8_t *) samp->getData())[0];
}
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
Alembic::Util::int16_t val[3];
if (index != ceilIndex && alpha != 0.0)
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
iProp.get(ceilSamp, Alembic::Abc::ISampleSelector(ceilIndex));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<Alembic::Util::int16_t>(alpha,
((Alembic::Util::int16_t *)samp->getData())[i],
((Alembic::Util::int16_t *)ceilSamp->getData())[i]);
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = ((Alembic::Util::int16_t *)samp->getData())[i];
}
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Short);
}
else if (extent == 3)
{
}
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
{
if (isScalarLike && extent < 4)
{
Alembic::Util::int32_t val[3];
if (index != ceilIndex && alpha != 0.0)
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<Alembic::Util::int32_t>(alpha,
((Alembic::Util::int32_t *)samp->getData())[i],
((Alembic::Util::int32_t *)ceilSamp->getData())[i]);
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] =
((Alembic::Util::int32_t *) samp->getData())[i];
}
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Int);
}
else if (extent == 3)
{
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
if (alpha != 0.0 && index != ceilIndex)
{
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
static_cast<unsigned int>(samp->size()));
std::size_t sampSize = samp->size();
if (sampSize != ceilSamp->size())
{
}
else
{
int * hi = (int *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = simpleLerp<int>(alpha, arr[i], hi[i]);
}
}
}
else
{
static_cast<unsigned int>(samp->size()));
}
}
}
break;
case Alembic::Util::kFloat32POD:
{
if (isScalarLike && extent < 4)
{
float val[3];
if (index != ceilIndex && alpha != 0.0)
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<float>(alpha,
((float *)samp->getData())[i],
((float *)ceilSamp->getData())[i]);
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = ((float *)samp->getData())[i];
}
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Float);
}
else if (extent == 3)
{
}
}
else
{
std::string interp = iProp.getMetaData().get("interpretation");
if ((extent == 2 || extent == 3) && (interp == "normal" ||
interp == "vector" || interp == "rgb"))
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
if (alpha != 0.0 && index != ceilIndex)
{
Alembic::Abc::ISampleSelector(ceilIndex));
if (sampSize != ceilSamp->size())
{
float * vals = (float *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
y = vals[extent*i+1];
if (extent == 3)
{
vec.
z = vals[extent*i+2];
}
arr[i] = vec;
}
}
else
{
float * lo = (float *) samp->getData();
float * hi = (float *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
x = simpleLerp<double>(alpha,
lo[extent*i], hi[extent*i]);
vec.
y = simpleLerp<double>(alpha,
lo[extent*i+1], hi[extent*i+1]);
if (extent == 3)
{
vec.
z = simpleLerp<double>(alpha,
lo[extent*i+2], hi[extent*i+2]);
}
arr[i] = vec;
}
}
}
else
{
float * vals = (float *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
y = vals[extent*i+1];
if (extent == 3)
{
vec.
z = vals[extent*i+2];
}
arr[i] = vec;
}
}
}
else if (interp == "point" && (extent == 2 || extent == 3))
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
if (alpha != 0.0 && index != ceilIndex)
{
Alembic::Abc::ISampleSelector(ceilIndex));
if (sampSize != ceilSamp->size())
{
float * vals = (float *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
if (extent == 3)
{
}
arr[i] = pt;
}
}
else
{
float * lo = (float *) samp->getData();
float * hi = (float *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
pt.
x = simpleLerp<double>(alpha,
lo[extent*i], hi[extent*i]);
pt.
y = simpleLerp<double>(alpha,
lo[extent*i+1], hi[extent*i+1]);
if (extent == 3)
{
pt.
z = simpleLerp<double>(alpha,
lo[extent*i+2], hi[extent*i+2]);
}
arr[i] = pt;
}
}
}
else
{
float * vals = (float *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
if (extent == 3)
{
}
arr[i] = pt;
}
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
if (alpha != 0.0 && index != ceilIndex)
{
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
static_cast<unsigned int>(samp->size()));
std::size_t sampSize = samp->size();
if (sampSize != ceilSamp->size())
{
}
else
{
float * hi = (float *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = simpleLerp<double>(alpha, arr[i],
hi[i]);
}
}
}
else
{
static_cast<unsigned int>(samp->size()));
}
}
}
}
break;
case Alembic::Util::kFloat64POD:
{
if (isScalarLike && extent < 5)
{
double val[4];
if (index != ceilIndex && alpha != 0.0)
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<double>(alpha,
((double *)(samp->getData()))[i],
((double *)(ceilSamp->getData()))[i]);
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = ((double *)(samp->getData()))[i];
}
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Double);
}
else if (extent == 3)
{
numData.
create(MFnNumericData::k3Double);
}
else if (extent == 4)
{
}
}
else
{
std::string interp = iProp.getMetaData().get("interpretation");
if ((extent == 2 || extent == 3) && (interp == "normal" ||
interp == "vector" || interp == "rgb"))
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
if (alpha != 0.0 && index != ceilIndex)
{
Alembic::Abc::ISampleSelector(ceilIndex));
if (sampSize != ceilSamp->size())
{
double * vals = (double *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
y = vals[extent*i+1];
if (extent == 3)
{
vec.
z = vals[extent*i+2];
}
arr[i] = vec;
}
}
else
{
double * lo = (double *) samp->getData();
double * hi = (double *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
x = simpleLerp<double>(alpha,
lo[extent*i], hi[extent*i]);
vec.
y = simpleLerp<double>(alpha,
lo[extent*i+1], hi[extent*i+1]);
if (extent == 3)
{
vec.
z = simpleLerp<double>(alpha,
lo[extent*i+2], hi[extent*i+2]);
}
arr[i] = vec;
}
}
}
else
{
double * vals = (double *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
vec.
y = vals[extent*i+1];
if (extent == 3)
{
vec.
z = vals[extent*i+2];
}
arr[i] = vec;
}
}
}
else if (interp == "point" && (extent == 2 || extent == 3))
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
if (alpha != 0.0 && index != ceilIndex)
{
Alembic::Abc::ISampleSelector(ceilIndex));
if (sampSize != ceilSamp->size())
{
double * vals = (double *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
if (extent == 3)
{
}
arr[i] = pt;
}
}
else
{
double * lo = (double *) samp->getData();
double * hi = (double *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
pt.
x = simpleLerp<double>(alpha,
lo[extent*i], hi[extent*i]);
pt.
y = simpleLerp<double>(alpha,
lo[extent*i+1], hi[extent*i+1]);
if (extent == 3)
{
pt.
z = simpleLerp<double>(alpha,
lo[extent*i+2], hi[extent*i+2]);
}
arr[i] = pt;
}
}
}
else
{
double * vals = (double *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
if (extent == 3)
{
}
arr[i] = pt;
}
}
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
if (alpha != 0.0 && index != ceilIndex)
{
iProp.get(ceilSamp,
Alembic::Abc::ISampleSelector(ceilIndex));
static_cast<unsigned int>(samp->size()));
std::size_t sampSize = samp->size();
if (sampSize != ceilSamp->size())
{
}
else
{
double * hi = (double *) ceilSamp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = simpleLerp<double>(alpha, arr[i],
hi[i]);
}
}
}
else
{
static_cast<unsigned int>(samp->size()));
}
}
}
}
break;
case Alembic::Util::kStringPOD:
{
if (isScalarLike && extent == 1)
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
((Alembic::Util::string *)samp->getData())[0].c_str());
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
Alembic::Util::string * strData =
(Alembic::Util::string *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = strData[i].c_str();
}
}
}
break;
case Alembic::Util::kWstringPOD:
{
if (isScalarLike && extent == 1)
{
iProp.
get(samp, Alembic::Abc::ISampleSelector(index));
((Alembic::Util::wstring *)samp->getData())[0].c_str());
}
else
{
iProp.get(samp, Alembic::Abc::ISampleSelector(index));
unsigned int sampSize = (unsigned int)samp->size();
Alembic::Util::wstring * strData =
(Alembic::Util::wstring *) samp->getData();
for (unsigned int i = 0; i < sampSize; ++i)
{
arr[i] = (wchar_t *)strData[i].c_str();
}
}
}
break;
default:
break;
}
}
void readProp(double iFrame,
Alembic::Abc::IScalarProperty & iProp,
{
Alembic::AbcCoreAbstract::DataType dtype = iProp.getDataType();
Alembic::Util::uint8_t extent = dtype.getExtent();
Alembic::AbcCoreAbstract::index_t index, ceilIndex;
double alpha = getWeightAndIndex(iFrame, iProp.getTimeSampling(),
iProp.getNumSamples(), index, ceilIndex);
switch (dtype.getPod())
{
case Alembic::Util::kBooleanPOD:
{
if (extent != 1)
return;
Alembic::Util::bool_t val;
iProp.get(&val, index);
}
break;
case Alembic::Util::kUint8POD:
case Alembic::Util::kInt8POD:
{
if (extent != 1)
return;
Alembic::Util::int8_t val;
if (index != ceilIndex && alpha != 0.0)
{
Alembic::Util::int8_t lo;
Alembic::Util::int8_t hi;
iProp.get(&lo, index);
iProp.get(&hi, ceilIndex);
val = simpleLerp<Alembic::Util::int8_t>(alpha, lo, hi);
}
else
{
iProp.get(&val, index);
}
}
break;
case Alembic::Util::kInt16POD:
case Alembic::Util::kUint16POD:
{
Alembic::Util::int16_t val[3];
if (index != ceilIndex && alpha != 0.0)
{
Alembic::Util::int16_t lo[3];
Alembic::Util::int16_t hi[3];
iProp.get(lo, index);
iProp.get(hi, ceilIndex);
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<Alembic::Util::int16_t>(alpha,
lo[i],
hi[i]);
}
}
else
{
iProp.get(val, index);
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Short);
}
else if (extent == 3)
{
}
}
break;
case Alembic::Util::kUint32POD:
case Alembic::Util::kInt32POD:
{
if (extent < 4)
{
Alembic::Util::int32_t val[3];
if (index != ceilIndex && alpha != 0.0)
{
Alembic::Util::int32_t lo[3];
Alembic::Util::int32_t hi[3];
iProp.get(lo, index);
iProp.get(hi, ceilIndex);
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
{
val[i] = simpleLerp<Alembic::Util::int32_t>(alpha,
lo[i],
hi[i]);
}
}
else
{
iProp.get(val, index);
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Int);
}
else if (extent == 3)
{
}
}
}
break;
case Alembic::Util::kFloat32POD:
{
if (extent < 4)
{
float val[3];
if (index != ceilIndex && alpha != 0.0)
{
float lo[3];
float hi[3];
iProp.get(lo, index);
iProp.get(hi, ceilIndex);
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
val[i] = simpleLerp<float>(alpha, lo[i], hi[i]);
}
else
{
iProp.get(val, index);
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Float);
}
else if (extent == 3)
{
}
}
}
break;
case Alembic::Util::kFloat64POD:
{
if (extent < 5)
{
double val[4];
if (index != ceilIndex && alpha != 0.0)
{
double lo[4];
double hi[4];
iProp.get(lo, index);
iProp.get(hi, index);
for (Alembic::Util::uint8_t i = 0; i < extent; ++i)
val[i] = simpleLerp<double>(alpha, lo[i], hi[i]);
}
else
{
iProp.get(val, index);
}
if (extent == 1)
{
}
else if (extent == 2)
{
numData.
create(MFnNumericData::k2Double);
}
else if (extent == 3)
{
numData.
create(MFnNumericData::k3Double);
}
else if (extent == 4)
{
}
}
}
break;
case Alembic::Util::kStringPOD:
{
if (extent == 1)
{
Alembic::Abc::IStringProperty strProp( iProp.getPtr(),
Alembic::Abc::kWrapExisting );
iHandle.
setString(strProp.getValue(index).c_str());
}
}
break;
case Alembic::Util::kWstringPOD:
{
if (extent == 1)
{
Alembic::Abc::IWstringProperty strProp( iProp.getPtr(),
Alembic::Abc::kWrapExisting );
iHandle.
setString(strProp.getValue(index).c_str());
}
}
break;
default:
break;
}
}
WriterData::WriterData()
{
}
WriterData::~WriterData()
{
mPropList.clear();
}
WriterData::WriterData(const WriterData & rhs)
{
*this = rhs;
}
WriterData & WriterData::operator=(const WriterData & rhs)
{
mCameraList = rhs.mCameraList;
mCurvesList = rhs.mCurvesList;
mNurbsList = rhs.mNurbsList;
mPointsList = rhs.mPointsList;
mPolyMeshList = rhs.mPolyMeshList;
mSubDList = rhs.mSubDList;
mXformList = rhs.mXformList;
mPropList = rhs.mPropList;
mLocList = rhs.mLocList;
mAnimVisStaticObjList = rhs.mAnimVisStaticObjList;
mCameraObjList = rhs.mCameraObjList;
mNurbsCurveObjList = rhs.mNurbsCurveObjList;
mNurbsObjList = rhs.mNurbsObjList;
mPointsObjList = rhs.mPointsObjList;
mPolyMeshObjList = rhs.mPolyMeshObjList;
mSubDObjList = rhs.mSubDObjList;
mXformOpList = rhs.mXformOpList;
mPropObjList = rhs.mPropObjList;
mIsComplexXform = rhs.mIsComplexXform;
mLocObjList = rhs.mLocObjList;
mNumCurves = rhs.mNumCurves;
return *this;
}
void WriterData::getFrameRange(double & oMin, double & oMax)
{
oMin = DBL_MAX;
oMax = -DBL_MAX;
Alembic::AbcCoreAbstract::TimeSamplingPtr ts;
std::size_t i = 0;
std::size_t iEnd = mLocList.size();
for (i = 0; i < iEnd; ++i)
{
Alembic::Abc::IScalarProperty locProp(mLocList[i].getProperties(), "locator");
ts = locProp.getTimeSampling();
std::size_t numSamples = locProp.getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
iEnd = mPointsList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mPointsList[i].getSchema().getTimeSampling();
std::size_t numSamples = mPointsList[i].getSchema().getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
iEnd = mPolyMeshList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mPolyMeshList[i].mMesh.getSchema().getTimeSampling();
std::size_t numSamples =
mPolyMeshList[i].mMesh.getSchema().getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
std::vector< Alembic::AbcGeom::IV2fGeomParam >::iterator v2s, v2sEnd;
v2sEnd = mPolyMeshList[i].mV2s.end();
for (v2s = mPolyMeshList[i].mV2s.begin(); v2s != v2sEnd; ++v2s)
{
ts = v2s->getTimeSampling();
numSamples = v2s->getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
std::vector< Alembic::AbcGeom::IC3fGeomParam >::iterator c3s, c3sEnd;
c3sEnd = mPolyMeshList[i].mC3s.end();
for (c3s = mPolyMeshList[i].mC3s.begin(); c3s != c3sEnd; ++c3s)
{
ts = c3s->getTimeSampling();
numSamples = c3s->getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
std::vector< Alembic::AbcGeom::IC4fGeomParam >::iterator c4s, c4sEnd;
c4sEnd = mPolyMeshList[i].mC4s.end();
for (c4s = mPolyMeshList[i].mC4s.begin(); c4s != c4sEnd; ++c4s)
{
ts = c4s->getTimeSampling();
numSamples = c4s->getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mSubDList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mSubDList[i].mMesh.getSchema().getTimeSampling();
std::size_t numSamples = mSubDList[i].mMesh.getSchema().getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
std::vector< Alembic::AbcGeom::IC3fGeomParam >::iterator c3s, c3sEnd;
c3sEnd = mSubDList[i].mC3s.end();
for (c3s = mSubDList[i].mC3s.begin(); c3s != c3sEnd; ++c3s)
{
ts = c3s->getTimeSampling();
numSamples = c3s->getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
std::vector< Alembic::AbcGeom::IC4fGeomParam >::iterator c4s, c4sEnd;
c4sEnd = mSubDList[i].mC4s.end();
for (c4s = mSubDList[i].mC4s.begin(); c4s != c4sEnd; ++c4s)
{
ts = c4s->getTimeSampling();
numSamples = c4s->getNumSamples();
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mXformList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mXformList[i].getSchema().getTimeSampling();
std::size_t numSamples = mXformList[i].getSchema().getNumSamples();
if (numSamples > 1)
{
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mCameraList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mCameraList[i].getSchema().getTimeSampling();
std::size_t numSamples = mCameraList[i].getSchema().getNumSamples();
if (numSamples > 1)
{
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mCurvesList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mCurvesList[i].getSchema().getTimeSampling();
std::size_t numSamples = mCurvesList[i].getSchema().getNumSamples();
if (numSamples > 1)
{
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mNurbsList.size();
for (i = 0; i < iEnd; ++i)
{
ts = mNurbsList[i].getSchema().getTimeSampling();
std::size_t numSamples = mNurbsList[i].getSchema().getNumSamples();
if (numSamples > 1)
{
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
iEnd = mPropList.size();
for (i = 0; i < iEnd; ++i)
{
std::size_t numSamples = 0;
if (mPropList[i].mArray.valid())
{
ts = mPropList[i].mArray.getTimeSampling();
numSamples = mPropList[i].mArray.getNumSamples();
}
else
{
ts = mPropList[i].mScalar.getTimeSampling();
numSamples = mPropList[i].mScalar.getNumSamples();
}
if (numSamples > 1)
{
oMin = std::min(ts->getSampleTime(0), oMin);
oMax = std::max(ts->getSampleTime(numSamples-1), oMax);
}
}
}
ArgData::ArgData(std::vector<std::string>& iFileNames,
bool iDebugOn,
MObject iReparentObj,
bool iConnect,
MString iConnectRootNodes,
bool iCreateIfNotFound,
bool iRemoveIfNoUpdate,
bool iRecreateColorSets,
MString iFilterString,
mFileNames(iFileNames),
mDebugOn(iDebugOn), mReparentObj(iReparentObj),
mRecreateColorSets(iRecreateColorSets),
mConnect(iConnect),
mConnectRootNodes(iConnectRootNodes),
mCreateIfNotFound(iCreateIfNotFound),
mRemoveIfNoUpdate(iRemoveIfNoUpdate),
mIncludeFilterString(iFilterString),
mExcludeFilterString(iExcludeFilterString)
{
mSequenceStartTime = -DBL_MAX;
mSequenceEndTime = DBL_MAX;
}
ArgData::ArgData(const ArgData & rhs)
{
*this = rhs;
}
ArgData & ArgData::operator=(const ArgData & rhs)
{
mFileNames = rhs.mFileNames;
mSequenceStartTime = rhs.mSequenceStartTime;
mSequenceEndTime = rhs.mSequenceEndTime;
mDebugOn = rhs.mDebugOn;
mReparentObj = rhs.mReparentObj;
mRecreateColorSets = rhs.mRecreateColorSets;
mIncludeFilterString = rhs.mIncludeFilterString;
mExcludeFilterString = rhs.mExcludeFilterString;
mConnect = rhs.mConnect;
mConnectRootNodes = rhs.mConnectRootNodes;
mCreateIfNotFound = rhs.mCreateIfNotFound;
mRemoveIfNoUpdate = rhs.mRemoveIfNoUpdate;
mData = rhs.mData;
return *this;
}
MString createScene(ArgData & iArgData)
{
Alembic::Abc::IArchive archive;
Alembic::AbcCoreFactory::IFactory factory;
factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
archive = factory.getArchive(iArgData.mFileNames);
if (!archive.valid())
{
MString theError = (*iArgData.mFileNames.begin()).c_str();
theError +=
MString(
" " + AbcImportStrings::getString(AbcImportStrings::kErrorInvalidAlembic) );
printError(theError);
return returnName;
}
CreateSceneVisitor::Action action = CreateSceneVisitor::CREATE;
if (iArgData.mRemoveIfNoUpdate && iArgData.mCreateIfNotFound)
action = CreateSceneVisitor::CREATE_REMOVE;
else if (iArgData.mRemoveIfNoUpdate)
action = CreateSceneVisitor::REMOVE;
else if (iArgData.mCreateIfNotFound)
action = CreateSceneVisitor::CREATE;
else if (iArgData.mConnect)
action = CreateSceneVisitor::CONNECT;
CreateSceneVisitor visitor(iArgData.mSequenceStartTime,
iArgData.mRecreateColorSets, iArgData.mReparentObj, action,
iArgData.mConnectRootNodes, iArgData.mIncludeFilterString,
iArgData.mExcludeFilterString);
visitor.walk(archive);
if (visitor.hasSampledData())
{
visitor.getData(iArgData.mData);
iArgData.mData.getFrameRange(iArgData.mSequenceStartTime,
iArgData.mSequenceEndTime);
returnName = connectAttr(iArgData);
}
if (iArgData.mConnect)
{
visitor.applyShaderSelection();
}
visitor.addFaceSetsAfterConnection();
return returnName;
}
MString connectAttr(ArgData & iArgData)
{
AlembicNode *alembicNodePtr =
reinterpret_cast<AlembicNode*>(alembicNodeFn.userNode(&status));
if (status == MS::kSuccess)
{
alembicNodePtr->setReaderPtrList(iArgData.mData);
alembicNodePtr->setDebugMode(iArgData.mDebugOn);
alembicNodePtr->setIncludeFilterString(iArgData.mIncludeFilterString);
alembicNodePtr->setExcludeFilterString(iArgData.mExcludeFilterString);
}
if (iArgData.mRecreateColorSets)
{
alembicNodeFn.addAttribute(attrObj);
}
stripFileName((*iArgData.mFileNames.begin()).c_str(), fileName);
MString alembicNodeName = fileName +
"_AlembicNode";
alembicNodeFn.setName(alembicNodeName, false, &status);
MPlug plug = alembicNodeFn.findPlug(
"abc_File",
true, &status);
plug.
setValue((*iArgData.mFileNames.begin()).c_str());
MPlug layerFilesPlug = alembicNodeFn.findPlug(AlembicNode::mAbcLayerFileNamesAttr,
true, &status);
{
std::vector< std::string > &argFilenames = iArgData.mFileNames;
for( size_t i = 0; i < argFilenames.size(); i++ )
{
}
{
layerFilesPlug.
setValue( updatedFilenameData );
}
}
plug = alembicNodeFn.findPlug("startFrame", true, &status);
plug = alembicNodeFn.findPlug("endFrame", true, &status);
plug = alembicNodeFn.findPlug("connect", true, &status);
plug = alembicNodeFn.findPlug("createIfNotFound", true, &status);
plug.
setValue(iArgData.mCreateIfNotFound);
plug = alembicNodeFn.findPlug("removeIfNoUpdate", true, &status);
plug.
setValue(iArgData.mRemoveIfNoUpdate);
plug = alembicNodeFn.findPlug("connectRoot", true, &status);
plug.
setValue(iArgData.mConnectRootNodes);
dstPlug = alembicNodeFn.findPlug("time", true, &status);
status = getPlugByName("time1", "outTime", srcPlug);
status = modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
std::size_t subDSize = iArgData.mData.mSubDObjList.size();
std::size_t polySize = iArgData.mData.mPolyMeshObjList.size();
std::size_t cameraSize = iArgData.mData.mCameraObjList.size();
std::size_t particleSize = iArgData.mData.mPointsObjList.size();
std::size_t xformSize = iArgData.mData.mXformOpList.size();
std::size_t nSurfaceSize = iArgData.mData.mNurbsObjList.size();
std::size_t nCurveSize = iArgData.mData.mNurbsCurveObjList.size();
std::size_t propSize = iArgData.mData.mPropObjList.size();
std::size_t locatorSize = iArgData.mData.mLocObjList.size();
if (xformSize > 0)
{
unsigned int logicalIndex = 0;
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"transOp",
true);
for (unsigned int i = 0 ; i < xformSize; i++)
{
SampledPair & sampPair = iArgData.mData.mXformOpList[i];
MObject mObject = sampPair.getObject();
unsigned int sampleSize = sampPair.sampledChannelSize();
for (unsigned int j = 0; j < sampleSize; j ++)
{
std::string attrName = sampPair.getSampleElement(j);
dstPlug = mFn.findPlug(attrName.c_str(), true);
continue;
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
}
if (subDSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outSubDMesh",
true);
for (unsigned int i = 0; i < subDSize; i++)
{
MFnMesh mFn(iArgData.mData.mSubDObjList[i], &status);
dstPlug = mFn.findPlug("inMesh", true, &status);
status = modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
if (status != MS::kSuccess)
{
MString theError(
"AlembicNode.outSubDMesh[");
theError += i;
theError += "] --> ";
theError += mFn.name();
theError += ".inMesh " + AbcImportStrings::getString(AbcImportStrings::kErrorConnectionNotMade);
printError(theError);
}
}
}
if (polySize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outPolyMesh",
true);
for (unsigned int i = 0; i < polySize; i++)
{
MFnMesh mFn(iArgData.mData.mPolyMeshObjList[i]);
dstPlug = mFn.findPlug("inMesh", true);
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
if (locatorSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outLoc",
true);
unsigned int logicalIndex = 0;
for (unsigned int i = 0; i < locatorSize; i++)
{
MFnDagNode fnLocator(iArgData.mData.mLocObjList[i]);
dstPlug = fnLocator.findPlug("localPositionX", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnLocator.findPlug("localPositionY", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnLocator.findPlug("localPositionZ", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnLocator.findPlug("localScaleX", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnLocator.findPlug("localScaleY", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnLocator.findPlug("localScaleZ", true);
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
if (cameraSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outCamera",
true);
unsigned int logicalIndex = 0;
for (unsigned int i = 0; i < cameraSize; i++)
{
MFnCamera fnCamera(iArgData.mData.mCameraObjList[i]);
dstPlug = fnCamera.findPlug("focalLength", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("lensSqueezeRatio", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("horizontalFilmAperture", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("verticalFilmAperture", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("horizontalFilmOffset", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("verticalFilmOffset", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("overscan", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("nearClipPlane", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("farClipPlane", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("fStop", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("focusDistance", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("shutterAngle", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("filmFitOffset", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("preScale", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("filmTranslateH", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("filmTranslateV", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("postScale", true);
modifier.
connect(srcPlug, dstPlug);
dstPlug = fnCamera.findPlug("cameraScale", true);
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
if (propSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"prop",
true, &status);
unsigned int index = 0;
for (unsigned int i = 0 ; i < propSize; i++)
{
SampledPair & sampPair = iArgData.mData.mPropObjList[i];
MObject obj = sampPair.getObject();
unsigned int sampleSize = sampPair.sampledChannelSize();
for (unsigned int j = 0; j < sampleSize; j ++)
{
std::string attrName = sampPair.getSampleElement(j);
if (attrName == Alembic::AbcGeom::kVisibilityPropertyName)
dstPlug = mFn.findPlug("visibility", true, &status);
else
dstPlug = mFn.findPlug(attrName.c_str(), true, &status);
if (attrName != Alembic::AbcGeom::kVisibilityPropertyName &&
(status != MS::kSuccess ||
dstPlug.
partialName(
false,
false,
false,
false,
false,
true)
!= attrName.c_str()))
{
MString theError(attrName.c_str());
theError +=
MString(
" " + AbcImportStrings::getString(AbcImportStrings::kErrorConnectionNotFound));
printError(theError);
continue;
}
{
status = plugMod.
connect(srcPlug, dstPlug);
}
if (status != MS::kSuccess)
{
theError += dstPlug.
name();
theError +=
MString(
" " + AbcImportStrings::getString(AbcImportStrings::kErrorConnectionNotMade));
printError(theError);
}
}
}
}
if (particleSize > 0)
{
printWarning(AbcImportStrings::getString(AbcImportStrings::kWarningNoAnimatedParticleSupport));
}
if (nSurfaceSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outNSurface",
true);
for (unsigned int i = 0; i < nSurfaceSize; i++)
{
dstPlug = fnNSurface.findPlug("create", true);
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
if (nCurveSize > 0)
{
MPlug srcArrayPlug = alembicNodeFn.findPlug(
"outNCurveGrp",
true);
for (unsigned int i = 0; i < nCurveSize; i++)
{
MObject curveObj = iArgData.mData.mNurbsCurveObjList[i];
{
dstPlug = fnNCurve.findPlug("create", true);
modifier.
connect(srcPlug, dstPlug);
status = modifier.
doIt();
}
}
}
return alembicNodeFn.name();
}
bool getUVandColorAttrs(Alembic::Abc::ICompoundProperty & iParent,
std::vector< Alembic::AbcGeom::IV2fGeomParam > & ioV2s,
std::vector< Alembic::AbcGeom::IC3fGeomParam > & ioC3s,
std::vector< Alembic::AbcGeom::IC4fGeomParam > & ioC4s,
bool iUnmarkedFaceVaryingColors)
{
bool anyAnimated = false;
if (!iParent)
return anyAnimated;
std::size_t numProps = iParent.getNumProperties();
for (std::size_t i = 0; i < numProps; ++i)
{
const Alembic::Abc::PropertyHeader & propHeader =
iParent.getPropertyHeader(i);
if (Alembic::AbcGeom::IV2fGeomParam::matches(propHeader) &&
Alembic::AbcGeom::isUV(propHeader))
{
Alembic::AbcGeom::IV2fGeomParam uvGeomParam(iParent,
propHeader.getName());
if (!anyAnimated)
{
anyAnimated = !uvGeomParam.isConstant();
}
ioV2s.push_back(uvGeomParam);
continue;
}
if (!isColorSet(propHeader, iUnmarkedFaceVaryingColors))
{
continue;
}
if (Alembic::AbcGeom::IC3fGeomParam::matches(propHeader))
{
Alembic::AbcGeom::IC3fGeomParam cgp(iParent, propHeader.getName());
if (!anyAnimated)
{
anyAnimated = !cgp.isConstant();
}
ioC3s.push_back(cgp);
}
else if (Alembic::AbcGeom::IC4fGeomParam::matches(propHeader))
{
Alembic::AbcGeom::IC4fGeomParam cgp(iParent, propHeader.getName());
if (!anyAnimated)
{
anyAnimated = !cgp.isConstant();
}
ioC4s.push_back(cgp);
}
}
return anyAnimated;
}