#include "util.h"
#include "CameraHelper.h"
#include "LocatorHelper.h"
#include "MeshHelper.h"
#include "NurbsCurveHelper.h"
#include "NurbsSurfaceHelper.h"
#include "PointHelper.h"
#include "XformHelper.h"
#include "CreateSceneHelper.h"
#include <Alembic/AbcGeom/Visibility.h>
#include <maya/MString.h>
#include <maya/MStringArray.h>
#include <maya/MIntArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MPlug.h>
#include <maya/MDGModifier.h>
#include <maya/MFnCamera.h>
#include <maya/MFnDoubleArrayData.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnIntArrayData.h>
#include <maya/MFnStringData.h>
#include <maya/MFnTransform.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnSet.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MItSelectionList.h>
#include <maya/MItDependencyGraph.h>
#include <map>
#include <set>
#include <string>
#include <vector>
namespace
{
{
{
dpShape = shadedShape;
}
for( ; iterSelList.
isDone()!=
true; iterSelList.
next() )
{
if ((curDag==dpShape) && curCompObj.
isNull())
}
setList.
add( dpShape, comp );
int nSG = connSGObjs.
length();
for( int i=0; i<nSG; i++ )
{
connSGObj = connSGObjs[i];
if( connSGObj != iSet )
{
{
for( ; itSelList.
isDone()!=
true; itSelList.
next() )
{
if (!(dp==dpShape) || !compObj.
isNull())
continue;
otherSetList.
add( dpShape, compObj );
break;
}
}
xorList = otherSetList;
}
}
}
void addFaceSets(
MObject & iNode, Alembic::Abc::IObject & iObj)
{
if (status != MS::kSuccess)
return;
std::size_t numChildren = iObj.getNumChildren();
for ( std::size_t i = 0 ; i < numChildren; ++i )
{
Alembic::Abc::IObject child = iObj.getChild(i);
if (Alembic::AbcGeom::IFaceSet::matches(child.getHeader()))
{
Alembic::AbcGeom::IFaceSet faceSet(child,
Alembic::Abc::kWrapExisting);
const MString& faceSetName(faceSet.getName().c_str());
status = getObjectByName(faceSetName, shadingGroup);
{
shadingGroup = createShadingGroup(faceSetName);
}
true);
if (abcFacesetNamePlug.
isNull())
{
MString attrName(
"AbcFacesetName");
abcFacesetNamePlug = fnDepNode.
findPlug(attrObj,
true);
}
abcFacesetNamePlug.
setValue(faceSetName);
Alembic::AbcGeom::IFaceSetSchema::Sample samp;
faceSet.getSchema().get(samp);
const int* faceArray((int *)samp.getFaces()->getData());
const size_t size = samp.getFaces()->size();
MIntArray arr(faceArray, static_cast<unsigned int>(size));
copyIndicesToNode(arr, iNode, shadingGroup);
Alembic::Abc::ICompoundProperty arbProp =
faceSet.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
faceSet.getSchema().getUserProperties();
addProps(arbProp, shadingGroup, false);
addProps(userProp, shadingGroup, false);
}
}
}
{
MStatus status = deleteDagNode(dagPath);
if ( status != MS::kSuccess )
{
theError +=
MString(
" removal not successful");
printError(theError);
}
}
Alembic::Abc::IScalarProperty getVisible(Alembic::Abc::IObject & iNode,
bool isObjConstant,
std::vector<Prop> & oPropList,
std::vector<Alembic::AbcGeom::IObject> & oAnimVisStaticObj)
{
Alembic::AbcGeom::IVisibilityProperty visProp =
Alembic::AbcGeom::GetVisibilityProperty(iNode);
if (visProp && !visProp.isConstant())
{
Prop prop;
prop.mScalar = visProp;
oPropList.push_back(prop);
if (isObjConstant)
{
oAnimVisStaticObj.push_back(iNode);
}
}
return visProp;
}
void setConstantVisibility(Alembic::Abc::IScalarProperty iVisProp,
{
if (iVisProp.valid() && iVisProp.isConstant())
{
Alembic::Util::int8_t visVal;
iVisProp.get(&visVal);
{
}
}
}
bool matchesNameWithRegex (
const MString& iName,
{
unsigned int length = iPatterns.
length();
if (length == 0)
return true;
for (unsigned int i=0; i<length; ++i)
{
scriptStr.
format(
"match \"^1s\" \"^2s\";", iPatterns[i], iName);
{
return true;
}
}
return false;
}
{
}
void deleteIntermediateMesh(
MFnMesh& fn)
{
{
if (
MFnMesh(io).hasAttribute(
"AlembicIntermediateObject"))
{
}
}
}
}
CreateSceneVisitor::CreateSceneVisitor(double iFrame,
bool iUnmarkedFaceVaryingColors,
const MObject & iParent,
Action iAction,
MString iRootNodes,
mFrame(iFrame), mParent(iParent),
mUnmarkedFaceVaryingColors(iUnmarkedFaceVaryingColors), mAction(iAction)
{
mAnyRoots = false;
{
if (iRootNodes.
split(
' ', theArray) == MS::kSuccess)
{
unsigned int len = theArray.
length();
for (unsigned int i = 0; i < len; i++)
{
if ( getDagPathByName( name, dagPath ) == MS::kSuccess )
{
mRootNodes.insert(name.
asChar());
mAnyRoots = true;
}
else
{
MString theWarning(
"Could not find root: ");
theWarning += name;
theWarning += " in the scene.";
printWarning(theWarning);
}
}
}
}
else if (iRootNodes ==
MString(
"/"))
{
mAnyRoots = true;
}
mOnlyPatterns.clear();
if (iIncludeFilterString !=
MString() &&
iIncludeFilterString !=
MString(
"*"))
{
iIncludeFilterString.
split(
' ', mOnlyPatterns);
}
if (iExcludeFilterString !=
MString() &&
iExcludeFilterString !=
MString(
"*"))
{
iExcludeFilterString.
split(
' ', mExceptPatterns);
}
}
CreateSceneVisitor::~CreateSceneVisitor()
{
}
void CreateSceneVisitor::getData(WriterData & oData)
{
oData = mData;
}
bool CreateSceneVisitor::hasSampledData()
{
return (mData.mPropList.size() > 0
|| mData.mXformList.size() > 0
|| mData.mSubDList.size() > 0
|| mData.mPolyMeshList.size() > 0
|| mData.mCameraList.size() > 0
|| mData.mNurbsList.size() > 0
|| mData.mCurvesList.size() > 0
|| mData.mLocList.size() > 0);
}
void CreateSceneVisitor::applyShaderSelection()
{
std::map < MObject, MSelectionList, ltMObj >::iterator i =
mShaderMeshMap.begin();
std::map < MObject, MSelectionList, ltMObj >::iterator end =
mShaderMeshMap.end();
for (; i != end; ++i)
{
curSet.addMembers(i->second);
}
mShaderMeshMap.clear();
}
void CreateSceneVisitor::addFaceSetsAfterConnection()
{
std::map < MObject, Alembic::Abc::IObject, ltMObj >::iterator i =
mAddFaceSetsMap.begin();
std::map < MObject, Alembic::Abc::IObject, ltMObj >::iterator end =
mAddFaceSetsMap.end();
for (; i != end; ++i)
{
addFaceSets(dagNode, i->second);
}
}
void CreateSceneVisitor::addToPropList(std::size_t iFirst,
MObject & iObject)
{
std::size_t last = mData.mPropList.size();
std::vector<std::string> attrList;
for (std::size_t i = iFirst; i < last; ++i)
{
if (mData.mPropList[i].mArray.valid())
{
attrList.push_back(mData.mPropList[i].mArray.getName());
}
else
{
attrList.push_back(mData.mPropList[i].mScalar.getName());
}
}
mData.mPropObjList.push_back(SampledPair(iObject, attrList));
}
void CreateSceneVisitor::checkShaderSelection(
MFnMesh & iMesh,
unsigned int iInst)
{
unsigned int setsLength = sets.
length();
for (unsigned int i = 0; i < setsLength; ++i)
{
if (mShaderMeshMap.find(curSetObj) == mShaderMeshMap.end())
{
curSet.getMembers(curSel, true);
}
}
}
void CreateSceneVisitor::visit(AlembicObjectPtr iObject)
{
Alembic::Abc::IObject iObj = iObject->object();
if ( Alembic::AbcGeom::IXform::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::IXform xform(iObj, Alembic::Abc::kWrapExisting);
(*this)(xform, iObject);
}
else if ( Alembic::AbcGeom::ISubD::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::ISubD mesh(iObj, Alembic::Abc::kWrapExisting);
(*this)(mesh);
}
else if ( Alembic::AbcGeom::IPolyMesh::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::IPolyMesh mesh(iObj, Alembic::Abc::kWrapExisting);
(*this)(mesh);
}
else if ( Alembic::AbcGeom::ICamera::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::ICamera cam(iObj, Alembic::Abc::kWrapExisting);
(*this)(cam);
}
else if ( Alembic::AbcGeom::ICurves::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::ICurves curves(iObj, Alembic::Abc::kWrapExisting);
(*this)(curves);
}
else if ( Alembic::AbcGeom::INuPatch::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::INuPatch nurbs(iObj, Alembic::Abc::kWrapExisting);
(*this)(nurbs);
}
else if ( Alembic::AbcGeom::IPoints::matches(iObj.getHeader()) )
{
Alembic::AbcGeom::IPoints pts(iObj, Alembic::Abc::kWrapExisting);
(*this)(pts);
}
else if ( iObj.getHeader().getMetaData().get("schema") == "" )
{
createEmptyObject(iObject);
}
else
{
MString theWarning(iObj.getName().c_str());
theWarning += " is an unsupported schema, skipping: ";
theWarning += iObj.getMetaData().get("schema").c_str();
printWarning(theWarning);
}
}
AlembicObjectPtr CreateSceneVisitor::previsit(AlembicObjectPtr iParentObject)
{
Alembic::Abc::IObject parent = iParentObject->object();
const MString name = parent.getFullName().c_str();
const size_t numChildren = parent.getNumChildren();
if (mExceptPatterns.length() > 0 &&
matchesNameWithRegex(name, mExceptPatterns))
{
return AlembicObjectPtr();
}
for (size_t i = 0; i < numChildren; ++i)
{
Alembic::Abc::IObject child = parent.getChild(i);
AlembicObjectPtr childObject =
previsit(AlembicObjectPtr(new AlembicObject(child)));
if (childObject)
{
iParentObject->addChild(childObject);
}
}
if (iParentObject->getNumChildren() == 0)
{
if (!matchesNameWithRegex(name, mOnlyPatterns))
{
return AlembicObjectPtr();
}
}
return iParentObject;
}
std::string CreateSceneVisitor::searchRootNames(const std::string & iName)
{
if (mRootNodes.empty())
{
return iName;
}
std::string strippedName = stripPathAndNamespace(iName);
std::set<std::string>::iterator it = mRootNodes.begin();
std::set<std::string>::iterator itEnd = mRootNodes.end();
std::string closeMatch;
for (; it != itEnd; ++it)
{
if (*it == iName)
{
return iName;
}
if (*it == strippedName)
{
return strippedName;
}
std::string strippedRoot = stripPathAndNamespace(*it);
if (strippedName == strippedRoot)
{
closeMatch = *it;
}
}
return closeMatch;
}
MStatus CreateSceneVisitor::walk(Alembic::Abc::IArchive & iRoot)
{
if (!iRoot.valid()) return MS::kFailure;
AlembicObjectPtr topObject =
previsit(AlembicObjectPtr(new AlembicObject(iRoot.getTop())));
if (!topObject) return status;
size_t numChildren = topObject->getNumChildren();
if (numChildren == 0) return status;
if (mAction == NONE)
{
for (size_t i = 0; i < numChildren; i++)
{
this->visit(topObject->getChild(i));
mParent = saveParent;
}
return status;
}
std::string rootName;
if (mRootNodes.size() == 1)
{
rootName = *mRootNodes.begin();
std::string rootBase = stripPathAndNamespace(rootName);
bool foundRoot = false;
for (size_t i = 0; i < numChildren; ++i)
{
std::string childName =
topObject->object().getChildHeader(i).getName();
if (rootBase == stripPathAndNamespace(childName))
{
foundRoot = true;
break;
}
}
if (!foundRoot)
{
if (getDagPathByName(
MString(rootName.c_str()), dagPath)
== MS::kSuccess)
{
if (numChildDags > 0)
{
mRootNodes.clear();
}
for (unsigned int j = 0; j < numChildDags; ++j)
{
}
}
}
}
std::set<std::string> connectUpdateNodes;
std::set<std::string> connectCurNodesInFile;
std::set<std::string>::iterator fileEnd =
connectCurNodesInFile.end();
for (size_t i = 0; i < numChildren; i++)
{
AlembicObjectPtr object = topObject->getChild(i);
std::string name = object->object().getName();
connectCurNodesInFile.insert(name);
std::string rootPath = searchRootNames(name);
if (!rootPath.empty())
{
if (mAnyRoots &&
getDagPathByName(
MString(rootPath.c_str()), dagPath) ==
MS::kSuccess)
{
connectUpdateNodes.insert(name);
mConnectDagNode = dagPath;
this->visit(object);
mParent = saveParent;
}
else if (mAction != CREATE && mAction != CREATE_REMOVE)
{
MString theWarning(
"Could not find: ");
theWarning += name.c_str();
theWarning += " in the scene.";
theWarning += " Skipping it and all descendants.";
printWarning(theWarning);
}
else
{
connectUpdateNodes.insert(name);
this->visit(object);
mParent = saveParent;
}
}
else
{
MString theWarning(
"Could not find a match for: ");
theWarning += name.c_str();
if (rootName.empty())
{
theWarning += " in the scene.";
}
else
{
theWarning += " beneath parent: ";
theWarning += rootName.c_str();
}
printWarning(theWarning);
}
}
if (mRootNodes.size() > connectUpdateNodes.size() &&
(mAction == REMOVE || mAction == CREATE_REMOVE))
{
std::set<std::string>::iterator iter =
mRootNodes.begin();
const std::set<std::string>::iterator fileEndIter =
connectCurNodesInFile.end();
for ( ; iter != mRootNodes.end(); iter++)
{
std::string name = *iter;
bool existInFile =
(connectCurNodesInFile.find(name) != fileEndIter);
bool existInScene =
(getDagPathByName(
MString(name.c_str()), dagPath)
== MS::kSuccess);
if (existInScene && !existInFile)
{
removeDagNode(dagPath);
}
else if (!existInScene && !existInFile)
{
theWarning +=
" exists neither in file nor in the scene";
printWarning(theWarning);
}
}
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::ICamera & iNode)
{
bool isConstant = iNode.getSchema().isConstant();
if (!isConstant)
{
mData.mCameraList.push_back(iNode);
}
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, false);
getAnimatedProps(userProp, mData.mPropList, false);
Alembic::Abc::IScalarProperty visProp = getVisible(iNode, isConstant,
mData.mPropList, mData.mAnimVisStaticObjList);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
cameraObj = mConnectDagNode.node();
if (!isConstant)
{
mData.mCameraObjList.push_back(cameraObj);
}
}
}
if (mAction == CREATE || mAction == CREATE_REMOVE)
{
cameraObj = create(iNode, mParent);
if (!isConstant)
{
mData.mCameraObjList.push_back(cameraObj);
}
}
{
setConstantVisibility(visProp, cameraObj);
addProps(arbProp, cameraObj, false);
addProps(userProp, cameraObj, false);
}
if ( mAction >= CONNECT )
{
if ( status != MS::kSuccess )
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return status;
}
addToPropList(firstProp, cameraObj);
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::ICurves & iNode)
{
bool isConstant = iNode.getSchema().isConstant();
Alembic::AbcGeom::ICurvesSchema::Sample samp;
iNode.getSchema().get(samp);
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
Alembic::AbcGeom::IFloatGeomParam::Sample widthSamp;
if (iNode.getSchema().getWidthsParam())
{
iNode.getSchema().getWidthsParam().getExpanded(widthSamp);
}
std::size_t numCurves = samp.getNumCurves();
if (numCurves == 0)
{
MString theWarning(iNode.getName().c_str());
theWarning += " has no curves, skipping.";
printWarning(theWarning);
return MS::kFailure;
}
else if (!isConstant)
{
mData.mNumCurves.push_back(numCurves);
mData.mCurvesList.push_back(iNode);
}
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, false);
getAnimatedProps(userProp, mData.mPropList, false);
Alembic::Abc::IScalarProperty visProp = getVisible(iNode, isConstant,
mData.mPropList, mData.mAnimVisStaticObjList);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
curvesObj = mConnectDagNode.node();
if (!isConstant)
{
if (numCurves == 1)
{
mData.mNurbsCurveObjList.push_back(curvesObj);
}
else
{
unsigned int childCurves = mConnectDagNode.childCount();
for (unsigned int i = 0; i < numCurves; ++i)
{
if (i < childCurves)
{
mData.mNurbsCurveObjList.push_back(
mConnectDagNode.child(i));
}
else
{
mData.mNurbsCurveObjList.push_back(obj);
}
}
}
}
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
curvesObj = createCurves(iNode.getName(), samp, widthSamp, mParent,
mData.mNurbsCurveObjList, !isConstant);
}
{
setConstantVisibility(visProp, curvesObj);
addProps(arbProp, curvesObj, false);
addProps(userProp, curvesObj, false);
}
if (mAction >= CONNECT)
{
if (status != MS::kSuccess)
{
}
if (status != MS::kSuccess)
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return status;
}
if (!fncurve.object().isNull())
{
MPlug dstPlug = fncurve.findPlug(
"create",
true);
disconnectAllPlugsTo(dstPlug);
disconnectProps(fncurve, mData.mPropList, firstProp);
addToPropList(firstProp, curvesObj);
}
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::IPoints& iNode)
{
bool isConstant = iNode.getSchema().isConstant();
if (!isConstant)
mData.mPointsList.push_back(iNode);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
particleObj = mConnectDagNode.node();
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
status = create(mFrame, iNode, mParent, particleObj);
if (!isConstant)
{
mData.mPointsObjList.push_back(particleObj);
}
}
std::vector<Prop> fakePropList;
std::vector<Alembic::AbcGeom::IObject> fakeObjList;
{
Alembic::Abc::IScalarProperty visProp =
getVisible(iNode, false, fakePropList, fakeObjList);
setConstantVisibility(visProp, particleObj);
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
addProps(arbProp, particleObj, false);
addProps(userProp, particleObj, false);
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::ISubD& iNode)
{
SubDAndFriends subdAndFriends;
subdAndFriends.mMesh = iNode;
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
bool colorAnim = getUVandColorAttrs(arbProp, subdAndFriends.mV2s,
subdAndFriends.mC3s, subdAndFriends.mC4s,
mUnmarkedFaceVaryingColors);
bool isConstant = iNode.getSchema().isConstant();
if (!isConstant || colorAnim)
{
mData.mSubDList.push_back(subdAndFriends);
}
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, mUnmarkedFaceVaryingColors);
getAnimatedProps(userProp, mData.mPropList, mUnmarkedFaceVaryingColors);
Alembic::Abc::IScalarProperty visProp = getVisible(iNode, isConstant,
mData.mPropList, mData.mAnimVisStaticObjList);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
subDObj = mConnectDagNode.node();
if (!isConstant || colorAnim)
{
mData.mSubDObjList.push_back(subDObj);
}
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
subDObj = createSubD(mFrame, subdAndFriends, mParent);
if (!isConstant || colorAnim)
{
mData.mSubDObjList.push_back(subDObj);
mAddFaceSetsMap[subDObj] = iNode;
}
}
{
setConstantVisibility(visProp, subDObj);
addProps(arbProp, subDObj, mUnmarkedFaceVaryingColors);
addProps(userProp, subDObj, mUnmarkedFaceVaryingColors);
addFaceSets(subDObj, iNode);
}
if ( mAction >= CONNECT )
{
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return MS::kFailure;
}
if (isConstant && fn.isFromReferencedFile())
{
deleteIntermediateMesh(fn);
ioFn.
setObject(createSubD(mFrame, subdAndFriends, mParent));
}
if (mConnectDagNode.isValid())
{
checkShaderSelection(fn, mConnectDagNode.instanceNumber());
}
disconnectMesh(subDObj, mData.mPropList, firstProp);
fn.setObject(subDObj);
if (isConstant && CONNECT == mAction)
{
connectIntermediateMesh(ioFn, fn);
else
readSubD(mFrame, fn, subDObj, subdAndFriends, false);
}
addToPropList(firstProp, subDObj);
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::IPolyMesh& iNode)
{
PolyMeshAndFriends meshAndFriends;
meshAndFriends.mMesh = iNode;
bool isConstant = iNode.getSchema().isConstant();
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
bool colorAnim = getUVandColorAttrs(arbProp, meshAndFriends.mV2s,
meshAndFriends.mC3s, meshAndFriends.mC4s,
mUnmarkedFaceVaryingColors);
if (!isConstant || colorAnim)
mData.mPolyMeshList.push_back(meshAndFriends);
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, mUnmarkedFaceVaryingColors);
getAnimatedProps(userProp, mData.mPropList, mUnmarkedFaceVaryingColors);
Alembic::Abc::IScalarProperty visProp = getVisible(iNode, isConstant,
mData.mPropList, mData.mAnimVisStaticObjList);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
polyObj = mConnectDagNode.node();
if (!isConstant || colorAnim)
{
mData.mPolyMeshObjList.push_back(polyObj);
}
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
polyObj = createPoly(mFrame, meshAndFriends, mParent);
if (!isConstant || colorAnim)
{
mData.mPolyMeshObjList.push_back(polyObj);
mAddFaceSetsMap[polyObj] = iNode;
}
}
{
setConstantVisibility(visProp, polyObj);
addProps(arbProp, polyObj, mUnmarkedFaceVaryingColors);
addProps(userProp, polyObj, mUnmarkedFaceVaryingColors);
addFaceSets(polyObj, iNode);
}
if ( mAction >= CONNECT )
{
if ( status != MS::kSuccess )
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return status;
}
if (isConstant && fn.isFromReferencedFile())
{
deleteIntermediateMesh(fn);
ioFn.
setObject(createPoly(mFrame, meshAndFriends, mParent));
}
if (mConnectDagNode.isValid())
checkShaderSelection(fn, mConnectDagNode.instanceNumber());
disconnectMesh(polyObj, mData.mPropList, firstProp);
fn.setObject(polyObj);
if (isConstant && CONNECT == mAction)
{
connectIntermediateMesh(ioFn, fn);
else
readPoly(mFrame, fn, polyObj, meshAndFriends, false);
}
addToPropList(firstProp, polyObj);
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::INuPatch& iNode)
{
bool isConstant = iNode.getSchema().isConstant();
if (!isConstant)
mData.mNurbsList.push_back(iNode);
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, false);
getAnimatedProps(userProp, mData.mPropList, false);
Alembic::Abc::IScalarProperty visProp = getVisible(iNode, isConstant,
mData.mPropList, mData.mAnimVisStaticObjList);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
nurbsObj = mConnectDagNode.node();
if (!isConstant)
{
mData.mNurbsObjList.push_back(nurbsObj);
}
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
nurbsObj = createNurbs(mFrame, iNode, mParent);
if (!isConstant)
{
mData.mNurbsObjList.push_back(nurbsObj);
}
}
{
addProps(arbProp, nurbsObj, false);
addProps(userProp, nurbsObj, false);
setConstantVisibility(visProp, nurbsObj);
}
if ( mAction >= CONNECT )
{
if ( status != MS::kSuccess )
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return status;
}
MPlug dstPlug = fn.findPlug(
"create",
true);
disconnectAllPlugsTo(dstPlug);
disconnectProps(fn, mData.mPropList, firstProp);
addToPropList(firstProp, nurbsObj);
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}
MStatus CreateSceneVisitor::operator()(Alembic::AbcGeom::IXform & iNode,
AlembicObjectPtr iNodeObject)
{
Alembic::Abc::ICompoundProperty arbProp =
iNode.getSchema().getArbGeomParams();
Alembic::Abc::ICompoundProperty userProp =
iNode.getSchema().getUserProperties();
std::size_t firstProp = mData.mPropList.size();
getAnimatedProps(arbProp, mData.mPropList, false);
getAnimatedProps(userProp, mData.mPropList, false);
if (iNode.getProperties().getPropertyHeader("locator") != NULL)
{
Alembic::Abc::ICompoundProperty props = iNode.getProperties();
const Alembic::AbcCoreAbstract::PropertyHeader * locHead =
props.getPropertyHeader("locator");
if (locHead != NULL && locHead->isScalar() &&
locHead->getDataType().getPod() == Alembic::Util::kFloat64POD &&
locHead->getDataType().getExtent() == 6)
{
Alembic::Abc::IScalarProperty locProp(props, "locator");
bool isConstant = locProp.isConstant();
Alembic::Abc::IScalarProperty visProp = getVisible(iNode,
isConstant, mData.mPropList, mData.mAnimVisStaticObjList);
if (!isConstant)
mData.mLocList.push_back(iNode);
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode,
iNode.getName());
if (hasDag)
{
xformObj = mConnectDagNode.node();
if (!isConstant)
{
mData.mLocObjList.push_back(xformObj);
}
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE))
{
xformObj = create(iNode, mParent, locProp);
if (!isConstant)
{
mData.mLocObjList.push_back(xformObj);
}
}
{
addProps(arbProp, xformObj, false);
addProps(userProp, xformObj, false);
setConstantVisibility(visProp, xformObj);
}
if ( mAction >= CONNECT )
{
{
MString theError(
"No connection done for node '");
theError +=
MString(iNode.getName().c_str());
theError += mConnectDagNode.fullPathName();
printError(theError);
return status;
}
addToPropList(firstProp, xformObj);
}
if (hasDag)
{
mConnectDagNode.pop();
}
}
}
else
{
MString name(iNode.getName().c_str());
size_t numChildren = iNodeObject->getNumChildren();
bool isConstant = iNode.getSchema().isConstant();
Alembic::Abc::IScalarProperty visProp = getVisible(iNode,
isConstant, mData.mPropList, mData.mAnimVisStaticObjList);
Alembic::AbcGeom::XformSample samp;
iNode.getSchema().get(samp, 0);
if (!isConstant)
{
mData.mXformList.push_back(iNode);
mData.mIsComplexXform.push_back(isComplex(samp));
}
if (isConstant && visProp.valid() && !visProp.isConstant())
{
mData.mAnimVisStaticObjList.push_back(iNode);
}
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
xformObj = mConnectDagNode.node();
}
}
if ((mAction == REMOVE || mAction == CREATE_REMOVE) && hasDag)
{
unsigned int numDags = mConnectDagNode.childCount();
std::vector<MDagPath> dagToBeRemoved;
std::set< std::string > childNodesInFile;
for (size_t j = 0; j < numChildren; ++j)
{
Alembic::Abc::IObject child = iNodeObject->getChild(j)->object();
childNodesInFile.insert(child.getName());
}
for (unsigned int i = 0; i < numDags; i++)
{
MObject child = mConnectDagNode.child(i);
if ( status == MS::kSuccess )
{
std::string childName = fn.fullPathName().asChar();
size_t found = childName.rfind("|");
if (found != std::string::npos)
{
childName = childName.substr(
found+1, childName.length() - found);
if (childNodesInFile.find(childName)
== childNodesInFile.end())
{
getDagPathByName(fn.fullPathName(), dagPath);
dagToBeRemoved.push_back(dagPath);
}
}
}
}
if (dagToBeRemoved.size() > 0)
{
unsigned int dagSize =
static_cast<unsigned int>(dagToBeRemoved.size());
for ( unsigned int i = 0; i < dagSize; i++ )
removeDagNode(dagToBeRemoved[i]);
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE ))
{
xformObj = trans.
create(mParent, &status);
if (status != MS::kSuccess)
{
MString theError(
"Failed to create transform node ");
theError += name;
printError(theError);
return status;
}
}
{
setConstantVisibility(visProp, xformObj);
addProps(arbProp, xformObj, false);
addProps(userProp, xformObj, false);
}
if (mAction >= CONNECT)
{
{
std::vector<std::string> transopNameList;
connectToXform(samp, isConstant, xformObj, transopNameList,
mData.mPropList, firstProp);
if (!isConstant)
{
SampledPair sampPair(xformObj, transopNameList);
mData.mXformOpList.push_back(sampPair);
}
addToPropList(firstProp, xformObj);
}
{
MString theError = mConnectDagNode.partialPathName();
theError +=
MString(
" is not compatible as a transform node. ");
theError +=
MString(
"Connection failed.");
printError(theError);
return MS::kFailure;
}
}
for (size_t i = 0; i < numChildren; ++i)
{
mParent = saveParent;
this->visit(iNodeObject->getChild(i));
}
if (hasDag)
{
mConnectDagNode.pop();
}
}
return status;
}
MStatus CreateSceneVisitor::createEmptyObject(AlembicObjectPtr iNodeObject)
{
Alembic::Abc::IObject iNode = iNodeObject->object();
MString name(iNode.getName().c_str());
size_t numChildren = iNodeObject->getNumChildren();
bool hasDag = false;
if (mAction != NONE && mConnectDagNode.isValid())
{
hasDag = getDagPathByChildName(mConnectDagNode, iNode.getName());
if (hasDag)
{
xformObj = mConnectDagNode.node();
}
}
if ((mAction == REMOVE || mAction == CREATE_REMOVE) &&
mConnectDagNode.isValid())
{
unsigned int numDags = mConnectDagNode.childCount();
std::vector<MDagPath> dagToBeRemoved;
std::set< std::string > childNodesInFile;
for (size_t j = 0; j < numChildren; ++j)
{
Alembic::Abc::IObject child = iNodeObject->getChild(j)->object();
childNodesInFile.insert(child.getName());
}
for (unsigned int i = 0; i < numDags; i++)
{
MObject child = mConnectDagNode.child(i);
if ( status == MS::kSuccess )
{
std::string childName = fn.fullPathName().asChar();
size_t found = childName.rfind("|");
if (found != std::string::npos)
{
childName = childName.substr(
found+1, childName.length() - found);
if (childNodesInFile.find(childName)
== childNodesInFile.end())
{
getDagPathByName(fn.fullPathName(), dagPath);
dagToBeRemoved.push_back(dagPath);
}
}
}
}
if (dagToBeRemoved.size() > 0)
{
unsigned int dagSize =
static_cast<unsigned int>(dagToBeRemoved.size());
for ( unsigned int i = 0; i < dagSize; i++ )
removeDagNode(dagToBeRemoved[i]);
}
}
if (!hasDag && (mAction == CREATE || mAction == CREATE_REMOVE ))
{
xformObj = trans.
create(mParent, &status);
if (status != MS::kSuccess)
{
MString theError(
"Failed to create transform node ");
theError += name;
printError(theError);
return status;
}
}
for (size_t i = 0; i < numChildren; ++i)
{
mParent = saveParent;
this->visit(iNodeObject->getChild(i));
}
if (hasDag)
{
mConnectDagNode.pop();
}
return status;
}