EAbcIObjectType GetEIObjectType( Alembic::Abc::IObject& in_object ) { AbcA::MetaData l_md = in_object.getMetaData(); if ( IPolyMesh::matches( l_md ) ) return EIObject_Polymesh; else if ( ISubD::matches( l_md ) ) return EIObject_Subd; else if ( IPoints::matches( l_md ) ) return EIObject_Points; else if ( IMaterial::matches( l_md ) ) return EIObject_Material; else if ( ICamera::matches( l_md ) ) return EIObject_Camera; else if ( IXform::matches( l_md ) ) return EIObject_Xform; else if ( ICurves::matches( l_md ) ) return EIObject_Curves; else if ( INuPatch::matches( l_md ) ) return EIObject_NuPatch; else if ( IFaceSet::matches( l_md ) ) return EIObject_FaceSet; else return EIObject_Unknown; }
bool getBasicSchemaDataFromObject(Alembic::Abc::IObject &object, BasicSchemaData &bsd) { ESS_PROFILE_SCOPE("getBasicSchemaDataFromObject"); const Alembic::Abc::MetaData &md = object.getMetaData(); if(Alembic::AbcGeom::IXform::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__XFORM, Alembic::AbcGeom::IXform(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::IPolyMesh::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__POLYMESH, Alembic::AbcGeom::IPolyMesh(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::ICurves::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__CURVES, Alembic::AbcGeom::ICurves(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::INuPatch::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__NUPATCH, Alembic::AbcGeom::INuPatch(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::IPoints::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__POINTS, Alembic::AbcGeom::IPoints(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::ISubD::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__SUBDIV, Alembic::AbcGeom::ISubD(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::ICamera::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__CAMERA, Alembic::AbcGeom::ICamera(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); else if(Alembic::AbcGeom::IFaceSet::matches(md)) return __getBasicSchemaDataFromObject(BasicSchemaData::__FACESET, Alembic::AbcGeom::IFaceSet(object,Alembic::Abc::kWrapExisting).getSchema(), bsd); return false; };
void copyObject(Alembic::Abc::IObject & iIn, Alembic::Abc::OObject & iOut) { std::size_t numChildren = iIn.getNumChildren(); Alembic::Abc::ICompoundProperty inProps = iIn.getProperties(); Alembic::Abc::OCompoundProperty outProps = iOut.getProperties(); copyProps(inProps, outProps); for (std::size_t i = 0; i < numChildren; ++i) { Alembic::Abc::IObject childIn(iIn.getChild(i)); Alembic::Abc::OObject childOut(iOut, childIn.getName(), childIn.getMetaData()); copyObject(childIn, childOut); } }
void getABCCameras(Alembic::Abc::IObject & iObj, std::vector<Alembic::AbcGeom::ICamera> & _objs) { unsigned int numChildren = iObj.getNumChildren(); for (unsigned i=0; i<numChildren; ++i) { IObject child( iObj.getChild( i )); if ( Alembic::AbcGeom::ICamera::matches(child.getHeader()) ) { ICamera cam(child, Alembic::Abc::kWrapExisting); _objs.push_back(cam); } if (child.getNumChildren() > 0) { getABCCameras(child, _objs); } } }
void getABCGeos(Alembic::Abc::IObject & iObj, std::vector<Alembic::AbcGeom::IObject> & _objs) { unsigned int numChildren = iObj.getNumChildren(); for (unsigned i=0; i<numChildren; ++i) { IObject child( iObj.getChild( i )); if ( Alembic::AbcGeom::IPolyMesh::matches(child.getHeader()) || Alembic::AbcGeom::ISubD::matches(child.getHeader())) { _objs.push_back(child); } if (child.getNumChildren() > 0) { getABCGeos(child, _objs); } } }
void traverse(Abc::IObject object, bool includeSelf) { if (includeSelf) { std::cout << "---------------------------------" << std::endl; std::cout << object.getFullName() << std::endl; if (Mat::IMaterial::matches(object.getHeader())) { std::cout << "(is material, local data shown)\n"; Mat::IMaterial mat(object, Abc::kWrapExisting); printMaterialSchema(mat.getSchema()); TESTING_ASSERT(object.getName() == "materialA" || object.getName() == "materialB"); } else { Mat::MaterialFlatten mafla(object); std::string name = object.getName(); std::cout << name << " " << mafla.empty() << std::endl; TESTING_ASSERT( (!mafla.empty() && (name == "geoA" || name == "geoB" || name == "geoC")) || (mafla.empty() && (name == "geometry" || name == "materials"))); if (!mafla.empty()) { std::cout << "(flattened material via has and/or assigned)\n"; printFlattenedMafla(mafla); } else { std::cout << "(neither is, has or is assigned)\n"; } } } for (size_t i = 0; i < object.getNumChildren(); ++i) { traverse(object.getChild(i), true); } }
Alembic::Abc::TimeSamplingPtr getTimeSamplingFromObject( Alembic::Abc::IObject& object) { ESS_PROFILE_SCOPE("getTimeSamplingFromObject"); const Alembic::Abc::MetaData& md = object.getMetaData(); if (Alembic::AbcGeom::IXform::matches(md)) { return Alembic::AbcGeom::IXform(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::IPolyMesh::matches(md)) { return Alembic::AbcGeom::IPolyMesh(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::ICurves::matches(md)) { return Alembic::AbcGeom::ICurves(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::INuPatch::matches(md)) { return Alembic::AbcGeom::INuPatch(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::IPoints::matches(md)) { return Alembic::AbcGeom::IPoints(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::ISubD::matches(md)) { return Alembic::AbcGeom::ISubD(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::ICamera::matches(md)) { return Alembic::AbcGeom::ICamera(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } else if (Alembic::AbcGeom::IFaceSet::matches(md)) { return Alembic::AbcGeom::IFaceSet(object, Alembic::Abc::kWrapExisting) .getSchema() .getTimeSampling(); } return Alembic::Abc::TimeSamplingPtr(); }
bool isObjectConstant(Alembic::Abc::IObject& object) { ESS_PROFILE_SCOPE("isObjectConstant"); const Alembic::Abc::MetaData& md = object.getMetaData(); if (Alembic::AbcGeom::IXform::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::IXform(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::IPolyMesh::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::IPolyMesh(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::ICurves::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::ICurves(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::INuPatch::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::INuPatch(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::IPoints::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::IPoints(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::ISubD::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::ISubD(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::ICamera::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::ICamera(object, Alembic::Abc::kWrapExisting) .getSchema()); } else if (Alembic::AbcGeom::IFaceSet::matches(md)) { return isObjectSchemaConstant( Alembic::AbcGeom::IFaceSet(object, Alembic::Abc::kWrapExisting) .getSchema()); } return true; }
AbcObjectCache::AbcObjectCache( Alembic::Abc::IObject & objToCache ) : obj( objToCache ), isMeshTopoDynamic(false), isMeshPointCache(false), fullName(objToCache.getFullName()) { ESS_PROFILE_SCOPE("AbcObjectCache::AbcObjectCache"); BasicSchemaData bsd; getBasicSchemaDataFromObject(objToCache, bsd); isConstant = bsd.isConstant; numSamples = bsd.nbSamples; bool isMesh = true; if ( bsd.type == bsd.__POLYMESH || !( isMesh = (bsd.type != bsd.__SUBDIV) ) ) { bool isTopoDyn = false; extractMeshInfo(&objToCache, isMesh, isMeshPointCache, isTopoDyn); if (!isConstant) isMeshTopoDynamic = isTopoDyn; } }
//-***************************************************************************** bool is_leaf( AbcG::IObject iObj ) { if ( !iObj.getParent().valid() ) { return true; } Abc::IObject parent = iObj.getParent(); int numChildren = parent.getNumChildren(); Abc::IObject test = parent.getChild(numChildren - 1); if ( test.valid() && test.getName() != iObj.getName() ) { return false; } return true; }
// returns the number of nodes int prescanAlembicHierarchy(AbcArchiveCache* pArchiveCache, AbcObjectCache* pRootObjectCache, std::vector<std::string>& nodes, std::map<std::string, bool>& map, bool bIncludeChildren) { for (int i = 0; i < nodes.size(); i++) { boost::to_upper(nodes[i]); } std::list<AlembicSelectionStackElement> sceneStack; for (size_t j = 0; j < pRootObjectCache->childIdentifiers.size(); j++) { AbcObjectCache* pChildObjectCache = &(pArchiveCache->find(pRootObjectCache->childIdentifiers[j])->second); sceneStack.push_back( AlembicSelectionStackElement(pChildObjectCache, false)); } int nNumNodes = 0; while (!sceneStack.empty()) { AlembicSelectionStackElement sElement = sceneStack.back(); Alembic::Abc::IObject iObj = sElement.pObjectCache->obj; bool bSelected = sElement.bSelected; sceneStack.pop_back(); nNumNodes++; bool bCreateNullNode = false; int nMergedGeomNodeIndex = -1; AbcObjectCache* pMergedChildObjectCache = NULL; getMergeInfo(pArchiveCache, sElement.pObjectCache, bCreateNullNode, nMergedGeomNodeIndex, &pMergedChildObjectCache); std::string name; std::string fullname; if (nMergedGeomNodeIndex != -1) { // we are merging Alembic::AbcGeom::IObject mergedGeomChild = pMergedChildObjectCache->obj; name = mergedGeomChild.getName(); fullname = mergedGeomChild.getFullName(); } else { // geometry node(s) under a dummy node (in pParentMaxNode) name = iObj.getName(); fullname = iObj.getFullName(); } bool bSelectChildren = false; if (bSelected) { map[fullname] = true; bSelectChildren = true; } else { boost::to_upper(name); for (int i = 0; i < nodes.size(); i++) { const char* cstrName = name.c_str(); const char* cstrNode = nodes[i].c_str(); if (name.find(nodes[i]) != std::string::npos) { if (bIncludeChildren) { bSelectChildren = true; } std::vector<std::string> parts; boost::split(parts, fullname, boost::is_any_of("/")); std::string nodeName; for (int j = 1; j < parts.size(); j++) { nodeName += "/"; nodeName += parts[j]; map[nodeName] = true; } } } } // push the children as the last step, since we need to who the parent is // first (we may have merged) for (size_t j = 0; j < sElement.pObjectCache->childIdentifiers.size(); j++) { AbcObjectCache* pChildObjectCache = &(pArchiveCache->find(sElement.pObjectCache->childIdentifiers[j]) ->second); Alembic::AbcGeom::IObject childObj = pChildObjectCache->obj; NodeCategory::type childCat = NodeCategory::get(childObj); if (childCat == NodeCategory::UNSUPPORTED) continue; // skip over unsupported types // I assume that geometry nodes are always leaf nodes. Thus, if we merged // a geometry node will its parent transform, we don't // need to push that geometry node to the stack. // A geometry node can't be combined with its transform node, the // transform node has other tranform nodes as children. These // nodes must be pushed. if (nMergedGeomNodeIndex != j) { sceneStack.push_back( AlembicSelectionStackElement(pChildObjectCache, bSelectChildren)); } } } return nNumNodes; }
int main(int argc, char *argv[]) { std::string toType; std::string inFile; std::string outFile; std::string forceStr; if (argc == 4) { toType = argv[1]; inFile = argv[2]; outFile = argv[3]; } else if (argc == 5) { forceStr = argv[1]; toType = argv[2]; inFile = argv[3]; outFile = argv[4]; } if ((argc == 4 || argc == 5) && (forceStr.empty() || forceStr == "-force")) { if (inFile == outFile) { printf("Error: inFile and outFile must not be the same!\n"); return 1; } if (toType != "-toHDF" && toType != "-toOgawa") { printf("Error: Unknown conversion type specified %s\n", toType.c_str()); printf("Currently only -toHDF and -toOgawa are supported.\n"); return 1; } Alembic::AbcCoreFactory::IFactory factory; Alembic::AbcCoreFactory::IFactory::CoreType coreType; Alembic::Abc::IArchive archive = factory.getArchive(inFile, coreType); if (!archive.valid()) { printf("Error: Invalid Alembic file specified: %s\n", inFile.c_str()); return 1; } else if ( forceStr != "-force" && ( (coreType == Alembic::AbcCoreFactory::IFactory::kHDF5 && toType == "-toHDF") || (coreType == Alembic::AbcCoreFactory::IFactory::kOgawa && toType == "-toOgawa")) ) { printf("Warning: Alembic file specified: %s\n",inFile.c_str()); printf("is already of the type you want to convert to.\n"); printf("Please specify -force if you want to do this anyway.\n"); return 1; } Alembic::Abc::IObject inTop = archive.getTop(); Alembic::Abc::OArchive outArchive; if (toType == "-toHDF") { outArchive = Alembic::Abc::OArchive( Alembic::AbcCoreHDF5::WriteArchive(), outFile, inTop.getMetaData(), Alembic::Abc::ErrorHandler::kThrowPolicy); } else if (toType == "-toOgawa") { outArchive = Alembic::Abc::OArchive( Alembic::AbcCoreOgawa::WriteArchive(), outFile, inTop.getMetaData(), Alembic::Abc::ErrorHandler::kThrowPolicy); } // start at 1, we don't need to worry about intrinsic default case for (Alembic::Util::uint32_t i = 1; i < archive.getNumTimeSamplings(); ++i) { outArchive.addTimeSampling(*archive.getTimeSampling(i)); } Alembic::Abc::OObject outTop = outArchive.getTop(); copyObject(inTop, outTop); return 0; } printf ("Usage: abcconvert [-force] OPTION inFile outFile\n"); printf ("Used to convert an Alembic file from one type to another.\n\n"); printf ("If -force is not provided and inFile happens to be the same\n"); printf ("type as OPTION no conversion will be done and a message will\n"); printf ("be printed out.\n"); printf ("OPTION has to be one of these:\n\n"); printf (" -toHDF Convert to HDF.\n"); printf (" -toOgawa Convert to Ogawa.\n"); return 1; }
AtNode *createInstanceNode(nodeData &nodata, userData * ud, int i) { Alembic::AbcGeom::IPoints typedObject(ud->gIObjects[i].abc, Alembic::Abc::kWrapExisting); instanceCloudInfo * info = ud->gIObjects[i].instanceCloud; // check that we have the masternode size_t id = (size_t)ud->gIObjects[i].ID; size_t instanceID = (size_t)ud->gIObjects[i].instanceID; if(instanceID >= info->groupInfos.size()) { AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceID . Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id); return NULL; } size_t groupID = (size_t)ud->gIObjects[i].instanceGroupID; if(groupID >= info->groupInfos[instanceID].identifiers.size()) { AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceGroupID. Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id); return NULL; } instanceGroupInfo * group = &info->groupInfos[instanceID]; // get the right centroidTime float centroidTime = ud->gCentroidTime; if(info->time.size() > 0) { centroidTime = info->time[0]->get()[id < info->time[0]->size() ? id : info->time[0]->size() - 1]; if(info->time.size() > 1) centroidTime = (1.0f - info->timeAlpha) * centroidTime + info->timeAlpha * info->time[1]->get()[id < info->time[1]->size() ? id : info->time[1]->size() - 1]; centroidTime = roundCentroid(centroidTime); } std::map<float,AtNode*>::iterator it = group->nodes[groupID].find(centroidTime); if(it == group->nodes[groupID].end()) { AiMsgError("[ExocortexAlembicArnold] Cannot find masterNode '%s' for centroidTime '%f'. Aborting.",group->identifiers[groupID].c_str(),centroidTime); return NULL; } AtNode *usedMasterNode = it->second; AtNode *shapeNode = AiNode("ginstance"); // setup name, id and the master node AiNodeSetStr(shapeNode, "name", getNameFromIdentifier(ud->gIObjects[i].abc.getFullName(),ud->gIObjects[i].ID,(long)groupID).c_str()); AiNodeSetInt(shapeNode, "id", ud->gIObjects[i].instanceID); AiNodeSetPtr(shapeNode, "node", usedMasterNode); // declare color on the ginstance if(info->color.size() > 0 && AiNodeDeclare(shapeNode, "Color", "constant RGBA")) { Alembic::Abc::C4f color = info->color[0]->get()[id < info->color[0]->size() ? id : info->color[0]->size() - 1]; AiNodeSetRGBA(shapeNode, "Color", color.r, color.g, color.b, color.a); } // now let's take care of the transform AtArray * matrices = AiArrayAllocate(1,(AtInt)ud->gMbKeys.size(),AI_TYPE_MATRIX); for(size_t j=0;j<ud->gMbKeys.size(); ++j) { SampleInfo sampleInfo = getSampleInfo( ud->gMbKeys[j], typedObject.getSchema().getTimeSampling(), typedObject.getSchema().getNumSamples() ); Alembic::Abc::M44f matrixAbc; matrixAbc.makeIdentity(); const size_t floorIndex = j << 1; const size_t ceilIndex = floorIndex + 1; // apply translation if(info->pos[floorIndex]->size() == info->pos[ceilIndex]->size()) { matrixAbc.setTranslation(float(1.0 - sampleInfo.alpha) * info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + float(sampleInfo.alpha) * info->pos[ceilIndex]->get()[id < info->pos[ceilIndex]->size() ? id : info->pos[ceilIndex]->size() - 1]); } else { const float timeAlpha = getTimeOffsetFromObject( typedObject, sampleInfo ); matrixAbc.setTranslation(info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + info->vel[floorIndex]->get()[id < info->vel[floorIndex]->size() ? id : info->vel[floorIndex]->size() - 1] * timeAlpha); } // now take care of rotation if(info->rot.size() == ud->gMbKeys.size()) { Alembic::Abc::Quatf rotAbc = info->rot[j]->get()[id < info->rot[j]->size() ? id : info->rot[j]->size() - 1]; if(info->ang.size() == ud->gMbKeys.size() && sampleInfo.alpha > 0.0) { Alembic::Abc::Quatf angAbc = info->ang[j]->get()[id < info->ang[j]->size() ? id : info->ang[j]->size() -1] * (float)sampleInfo.alpha; if(angAbc.axis().length2() != 0.0f && angAbc.r != 0.0f) { rotAbc = angAbc * rotAbc; rotAbc.normalize(); } } Alembic::Abc::M44f matrixAbcRot; matrixAbcRot.setAxisAngle(rotAbc.axis(),rotAbc.angle()); matrixAbc = matrixAbcRot * matrixAbc; } // and finally scaling if(info->scale.size() == ud->gMbKeys.size() * 2) { const Alembic::Abc::V3f scalingAbc = info->scale[floorIndex]->get()[id < info->scale[floorIndex]->size() ? id : info->scale[floorIndex]->size() - 1] * info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + info->scale[ceilIndex]->get()[id < info->scale[ceilIndex]->size() ? id : info->scale[ceilIndex]->size() - 1] * info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha); matrixAbc.scale(scalingAbc); } else { const float width = info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha); matrixAbc.scale(Alembic::Abc::V3f(width,width,width)); } // if we have offset matrices if(group->parents.size() > groupID && group->matrices.size() > groupID) { if(group->objects[groupID].valid() && group->parents[groupID].valid()) { // we have a matrix map and a parent. // now we need to check if we already exported the matrices std::map<float,std::vector<Alembic::Abc::M44f> >::iterator it; std::vector<Alembic::Abc::M44f> offsets; it = group->matrices[groupID].find(centroidTime); if(it == group->matrices[groupID].end()) { std::vector<float> samples(ud->gMbKeys.size()); offsets.resize(ud->gMbKeys.size()); for(AtInt sampleIndex=0;sampleIndex<(AtInt)ud->gMbKeys.size(); ++sampleIndex) { offsets[sampleIndex].makeIdentity(); // centralize the time once more samples[sampleIndex] = centroidTime + ud->gMbKeys[sampleIndex] - ud->gCentroidTime; } // if the transform differs, we need to compute the offset matrices // get the parent, which should be a transform Alembic::Abc::IObject parent = group->parents[groupID]; Alembic::Abc::IObject xform = group->objects[groupID].getParent(); while(Alembic::AbcGeom::IXform::matches(xform.getMetaData()) && xform.getFullName() != parent.getFullName()) { // cast to a xform Alembic::AbcGeom::IXform parentXform(xform,Alembic::Abc::kWrapExisting); if(parentXform.getSchema().getNumSamples() == 0) break; // loop over all samples for(size_t sampleIndex=0;sampleIndex<ud->gMbKeys.size(); ++sampleIndex) { SampleInfo sampleInfo = getSampleInfo( samples[sampleIndex], parentXform.getSchema().getTimeSampling(), parentXform.getSchema().getNumSamples() ); // get the data and blend it if necessary Alembic::AbcGeom::XformSample sample; parentXform.getSchema().get(sample,sampleInfo.floorIndex); Alembic::Abc::M44f abcMatrix; Alembic::Abc::M44d abcMatrixd = sample.getMatrix(); for(int x=0;x<4;x++) for(int y=0;y<4;y++) abcMatrix[x][y] = (float)abcMatrixd[x][y]; if(sampleInfo.alpha >= sampleTolerance) { parentXform.getSchema().get(sample,sampleInfo.ceilIndex); Alembic::Abc::M44d ceilAbcMatrixd = sample.getMatrix(); Alembic::Abc::M44f ceilAbcMatrix; for(int x=0;x<4;x++) for(int y=0;y<4;y++) ceilAbcMatrix[x][y] = (float)ceilAbcMatrixd[x][y]; abcMatrix = float(1.0 - sampleInfo.alpha) * abcMatrix + float(sampleInfo.alpha) * ceilAbcMatrix; } offsets[sampleIndex] = abcMatrix * offsets[sampleIndex]; } // go upwards xform = xform.getParent(); } group->matrices[groupID].insert(std::pair<float,std::vector<Alembic::Abc::M44f> >(centroidTime,offsets)); } else offsets = it->second; // this means we have the right amount of matrices to blend against if(offsets.size() > j) matrixAbc = offsets[j] * matrixAbc; } } // store it to the array AiArraySetMtx(matrices,(AtULong)j,matrixAbc.x); } AiNodeSetArray(shapeNode,"matrix",matrices); AiNodeSetBool(shapeNode, "inherit_xform", FALSE); return shapeNode; }
int main(int argc, char *argv[]) { ConversionOptions options; bool doConversion = false; if (parseArgs( argc, argv, options, doConversion ) == false) return 1; if (doConversion) { for( std::vector<std::string>::const_iterator inFile = options.inFiles.begin(); inFile != options.inFiles.end(); inFile++ ) { if (*inFile == options.outFile) { printf("Error: inFile and outFile must not be the same!\n"); return 1; } } if (options.toType != IFactoryNS::kHDF5 && options.toType != IFactoryNS::kOgawa) { printf("Currently only -toHDF and -toOgawa are supported.\n"); return 1; } Alembic::AbcCoreFactory::IFactory factory; Alembic::AbcCoreFactory::IFactory::CoreType coreType; Alembic::Abc::IArchive archive; if(options.inFiles.size() == 1) { archive = factory.getArchive(*options.inFiles.begin(), coreType); if (!archive.valid()) { printf("Error: Invalid Alembic file specified: %s\n", options.inFiles.begin()->c_str()); return 1; } else if ( !options.force && ( (coreType == IFactoryNS::kHDF5 && options.toType == IFactoryNS::kHDF5) || (coreType == IFactoryNS::kOgawa && options.toType == IFactoryNS::kOgawa)) ) { printf("Warning: Alembic file specified: %s\n", options.inFiles.begin()->c_str()); printf("is already of the type you want to convert to.\n"); printf("Please specify -force if you want to do this anyway.\n"); return 1; } } else { archive = factory.getArchive(options.inFiles, coreType); } Alembic::Abc::IObject inTop = archive.getTop(); Alembic::Abc::OArchive outArchive; if (options.toType == IFactoryNS::kHDF5) { outArchive = Alembic::Abc::OArchive( Alembic::AbcCoreHDF5::WriteArchive(), options.outFile, inTop.getMetaData(), Alembic::Abc::ErrorHandler::kThrowPolicy); } else if (options.toType == IFactoryNS::kOgawa) { outArchive = Alembic::Abc::OArchive( Alembic::AbcCoreOgawa::WriteArchive(), options.outFile, inTop.getMetaData(), Alembic::Abc::ErrorHandler::kThrowPolicy); } // start at 1, we don't need to worry about intrinsic default case for (Alembic::Util::uint32_t i = 1; i < archive.getNumTimeSamplings(); ++i) { outArchive.addTimeSampling(*archive.getTimeSampling(i)); } Alembic::Abc::OObject outTop = outArchive.getTop(); copyObject(inTop, outTop); } return 0; }