//-***************************************************************************** void visit( Abc::ICompoundProperty iProp, bool all = false, bool long_list = false, bool meta = false, bool recursive = false, bool first = false, bool values = false ) { // header if ( recursive && iProp.getNumProperties() > 0 ) { printParent( iProp, all, long_list, recursive, first ); } // children for( size_t c = 0; c < iProp.getNumProperties(); ++c ) { printChild( iProp, iProp.getPropertyHeader( c ), all, long_list, meta, values ); } // visit children if ( recursive && all && iProp.getNumProperties() > 0 ) { for( size_t p = 0; p < iProp.getNumProperties(); ++p ) { Abc::PropertyHeader header = iProp.getPropertyHeader( p ); if ( header.isCompound() ) visit( Abc::ICompoundProperty( iProp, header.getName() ), all, long_list, meta, recursive, false, values ); } } }
//-***************************************************************************** void visit( AbcG::IObject iObj, bool all = false, bool long_list = false, bool meta = false, bool recursive = false, bool first = false, bool values = false ) { Abc::ICompoundProperty props = iObj.getProperties(); // header if ( recursive && ( iObj.getNumChildren() > 0 || ( all && props.getNumProperties() > 0 ) ) ) { printParent( iObj, all, long_list, recursive, first ); } // children for( size_t c = 0; c < iObj.getNumChildren(); ++c ) { printChild( iObj, iObj.getChild( c ), all, long_list, meta, values ); } // properties if ( all ) { for( size_t h = 0; h < props.getNumProperties(); ++h ) { printChild( props, props.getPropertyHeader( h ), all, long_list, meta, values ); } } // visit property children if ( recursive && all && props.getNumProperties() > 0 ) { for( size_t p = 0; p < props.getNumProperties(); ++p ) { Abc::PropertyHeader header = props.getPropertyHeader( p ); if ( header.isCompound() ) { if ( !long_list ) std::cout << std::endl; visit( Abc::ICompoundProperty( props, header.getName() ), all, long_list, meta, recursive, false, values ); } } } // visit object children if ( recursive && iObj.getNumChildren() > 0 ) { for( size_t c = 0; c < iObj.getNumChildren(); ++c ) { visit( iObj.getChild( c ), all, long_list, meta, recursive, false, values ); } } }
//-***************************************************************************** int index( Abc::ICompoundProperty iProp, Abc::PropertyHeader iHeader ) { for ( size_t i = 0 ; i < iProp.getNumProperties() ; i++ ) { Abc::PropertyHeader header = iProp.getPropertyHeader( i ); if ( header.getName() == iHeader.getName() ) { return i; } } return -1; }
//-***************************************************************************** bool is_leaf( Abc::ICompoundProperty iProp, Abc::PropertyHeader iHeader ) { if ( !iProp.valid() ) { return true; } int last = iProp.getNumProperties() - 1; Abc::PropertyHeader header = iProp.getPropertyHeader( last ); if ( header.getName() == iHeader.getName() ) return true; return false; }
//-***************************************************************************** void tree( AbcG::IObject iObj, bool showProps = false, std::string prefix = "" ) { std::string path = iObj.getFullName(); if ( path == "/" ) { prefix = ""; } else { if ( iObj.getParent().getFullName() != "/" ) { prefix = prefix + " "; } if ( is_leaf( iObj ) ) { std::cout << prefix << " `--"; prefix = prefix + " "; } else { std::cout << prefix << " |--"; prefix = prefix + " |"; } }; if ( showProps ) std::cout << GREENCOLOR; std::cout << iObj.getName(); if ( showProps ) std::cout << RESETCOLOR; std::cout << "\r" << std::endl; // property tree if ( showProps ) { Abc::ICompoundProperty props = iObj.getProperties(); for ( size_t i = 0 ; i < props.getNumProperties() ; i++ ) { Abc::PropertyHeader header = props.getPropertyHeader( i ); if ( header.isScalar() ) { tree( Abc::IScalarProperty( props, header.getName() ), prefix ); } else if ( header.isArray() ) { tree( Abc::IArrayProperty( props, header.getName() ), prefix ); } else { tree( Abc::ICompoundProperty( props, header.getName() ), prefix ); } } } // object tree for ( size_t i = 0 ; i < iObj.getNumChildren() ; i++ ) { tree( AbcG::IObject( iObj, iObj.getChildHeader(i).getName() ), showProps, prefix ); }; }
//-***************************************************************************** void tree( Abc::ICompoundProperty iProp, std::string prefix = "" ) { if ( iProp.getObject().getFullName() != "/" ) { prefix = prefix + " "; } if ( is_leaf( iProp.getParent(), iProp.getHeader() ) && iProp.getObject().getNumChildren() == 0 ) { std::cout << prefix << " `--"; prefix = prefix + " "; } else { if ( is_leaf( iProp.getParent(), iProp.getHeader() ) ) { std::cout << prefix << " | `--"; prefix = prefix + " |"; } else if ( iProp.getObject().getNumChildren() == 0 ) { std::cout << prefix << " :--"; prefix = prefix + " :"; } else if ( is_leaf( iProp, iProp.getHeader() ) ) { std::cout << prefix << " | `--"; prefix = prefix + " |"; } else { std::cout << prefix << " | :--"; prefix = prefix + " | :"; } } std::cout << iProp.getName() << "\r" << std::endl; for ( size_t i = 0 ; i < iProp.getNumProperties() ; i++ ) { Abc::PropertyHeader header = iProp.getPropertyHeader( i ); if ( header.isScalar() ) { tree( Abc::IScalarProperty( iProp, header.getName() ), prefix ); } else if ( header.isArray() ) { tree( Abc::IArrayProperty( iProp, header.getName() ), prefix ); } else { tree( Abc::ICompoundProperty( iProp, header.getName() ), prefix ); } } }
//-***************************************************************************** int main( int argc, char *argv[] ) { //float opt_fps = 24.0; bool opt_all = false; // show all option bool opt_long = false; // long listing option bool opt_meta = false; // metadata option bool opt_recursive = false; // recursive option bool opt_size = false; // array sample size option bool opt_time = false; // time info option bool opt_values = false; // show all 0th values int index = -1; // sample number, at tail of path std::string desc( "abcls [OPTION] FILE[/NAME] \n" " -a include property listings\n" " -f show time sampling as 24 fps\n" " -h, --help show this help message\n" " -l long listing format\n" " -m show archive metadata\n" " -r list entries recursively\n" " -s show the size of a data property sample\n" " -t show time sampling information\n" " -v show 0th value for all properties\n" ); /* sigaction if available */ #if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) // seg fault handler struct sigaction act; sigemptyset(&act.sa_mask); act.sa_handler = segfault_sigaction; act.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &act, NULL); /* signal if available */ #elif defined(_POSIX_VERSION) || defined(_MSC_VER) signal(SIGSEGV, segfault_sigaction); #else #error No signal interface available #endif //_POSIX_VERSION // check for min args if ( argc < 2 ) { std::cout << desc << std::endl; return 0; }; // parse args std::vector<std::string> arguments(argv, argv + argc); std::vector<std::string> options; std::vector<std::string> files; // separate file args from option args for ( std::size_t i = 1; i < arguments.size(); i++ ) { if ( arguments[ i ].substr( 0, 1 ) == "-" ) options.push_back( arguments[ i ] ); else files.push_back( arguments[ i ] ); } // help if ( argc < 2 || optionExists( options, "h" ) || optionExists( options, "help" ) ) { std::cout << desc << std::endl; return 0; }; // set some flags double fps = 1.0; opt_all = optionExists( options, "a" ); opt_long = optionExists( options, "l" ); opt_meta = optionExists( options, "m" ); opt_recursive = optionExists( options, "r" ); opt_size = optionExists( options, "s" ); opt_time = optionExists( options, "t" ); opt_values = optionExists( options, "v" ); if ( optionExists( options, "f" ) ) { fps = 24.0; opt_time = true; } // open each file for ( std::size_t i = 0; i < files.size(); i++ ) { if ( files.size() > 1 ) std::cout << BOLD << files[i] << ':' << RESETCOLOR << std::endl; std::stringstream ss( files[i] ); std::stringstream fp; std::string segment; std::vector<std::string> seglist; /* * separate file and object paths, e.g. * * ../dir1/foo.abc/bar/baz/index * \_____________/\______/\____/ * file obj sample */ int j = 0; while ( std::getline( ss, segment, '/' ) ) { if ( !isFile ( fp.str() ) ) { if ( j != 0 ) fp << "/"; fp << segment; } else { seglist.push_back( segment ); } ++j; } bool lastIsIndex = false; if (!seglist.empty() && is_digit( seglist.back() ) ) { index = atoi( seglist.back().c_str() ); lastIsIndex = true; } // open the iarchive Abc::IArchive archive; AbcF::IFactory factory; factory.setPolicy(Abc::ErrorHandler::kQuietNoopPolicy); AbcF::IFactory::CoreType coreType; archive = factory.getArchive(std::string( fp.str() ), coreType); // display file metadata if ( opt_meta && seglist.size() == 0 ) { std::cout << "Using " << Alembic::AbcCoreAbstract::GetLibraryVersion() << std::endl;; std::string appName; std::string libraryVersionString; Alembic::Util::uint32_t libraryVersion; std::string whenWritten; std::string userDescription; std::string coreName; GetArchiveInfo (archive, appName, libraryVersionString, libraryVersion, whenWritten, userDescription); if ( coreType == AbcF::IFactory::kOgawa ) { coreName = "Ogawa"; } else if ( coreType == AbcF::IFactory::kHDF5 ) { coreName = "HDF5"; } else { coreName = "Unknown"; }; if ( appName != "" ) { std::cout << " file written by: " << appName << std::endl; std::cout << " using Alembic : " << libraryVersionString << std::endl; std::cout << " written on : " << whenWritten << std::endl; std::cout << " user description : " << userDescription << std::endl; } else { std::cout << " (file doesn't have any ArchiveInfo)" << std::endl; } std::cout << " core type : " << coreName << std::endl; }; if ( opt_time && seglist.size() == 0 ) { uint32_t numTimes = archive.getNumTimeSamplings(); std::cout << std::endl << "Time Samplings: " << std::endl; for ( uint32_t k = 0; k < numTimes; ++k ) { AbcA::TimeSamplingPtr ts = archive.getTimeSampling( k ); index_t maxSample = archive.getMaxNumSamplesForTimeSamplingIndex( k ); std::cout << k << " "; printTimeSampling( ts, maxSample, fps ); } std::cout << std::endl; } // walk object hierarchy and find valid objects AbcG::IObject test = archive.getTop(); AbcG::IObject iObj = test; while ( test.valid() && seglist.size() > 0 ) { test = test.getChild( seglist.front() ); if ( test.valid() ) { iObj = test; seglist.erase( seglist.begin() ); } } // walk property hierarchy for most recent object Abc::ICompoundProperty props = iObj.getProperties(); const Abc::PropertyHeader* header; bool found = false; bool shouldPrintValue = false; for ( std::size_t i = 0; i < seglist.size(); ++i ) { header = props.getPropertyHeader( seglist[i] ); if ( header && header->isCompound() ) { Abc::ICompoundProperty ptest( props, header->getName() ); if ( ptest.valid() ) { props = ptest; found = true; } } else if ( header && header->isSimple() ) { found = true; // if the last value happens to be an index, and we are a // property then dont bother checking the last item in seglist if (lastIsIndex && i == seglist.size() - 2) { shouldPrintValue = true; break; } } else { std::cout << seglist[i] << ": Invalid object or property" << std::endl; return 1; } } // do stuff if ( shouldPrintValue ) { printValue( props, *header, index, opt_size, opt_time, fps ); } else { if ( found && header->isCompound() ) visit( props, opt_all, opt_long, opt_meta, opt_recursive, true, opt_values ); else if ( found && header->isSimple() ) printChild( props, *header, opt_all, opt_long, opt_values ); else visit( iObj, opt_all, opt_long, opt_meta, opt_recursive, true, opt_values ); std::cout << RESETCOLOR; if ( !opt_long ) std::cout << std::endl; } } return 0; }
void copyProps(Alembic::Abc::ICompoundProperty & iRead, Alembic::Abc::OCompoundProperty & iWrite) { std::size_t numChildren = iRead.getNumProperties(); for (std::size_t i = 0; i < numChildren; ++i) { Alembic::AbcCoreAbstract::PropertyHeader header = iRead.getPropertyHeader(i); if (header.isArray()) { Alembic::Abc::IArrayProperty inProp(iRead, header.getName()); Alembic::Abc::OArrayProperty outProp(iWrite, header.getName(), header.getDataType(), header.getMetaData(), header.getTimeSampling()); std::size_t numSamples = inProp.getNumSamples(); for (std::size_t j = 0; j < numSamples; ++j) { Alembic::AbcCoreAbstract::ArraySamplePtr samp; Alembic::Abc::ISampleSelector sel( (Alembic::Abc::index_t) j); inProp.get(samp, sel); outProp.set(*samp); } } else if (header.isScalar()) { Alembic::Abc::IScalarProperty inProp(iRead, header.getName()); Alembic::Abc::OScalarProperty outProp(iWrite, header.getName(), header.getDataType(), header.getMetaData(), header.getTimeSampling()); std::size_t numSamples = inProp.getNumSamples(); std::vector<std::string> sampStrVec; std::vector<std::wstring> sampWStrVec; if (header.getDataType().getPod() == Alembic::AbcCoreAbstract::kStringPOD) { sampStrVec.resize(header.getDataType().getExtent()); } else if (header.getDataType().getPod() == Alembic::AbcCoreAbstract::kWstringPOD) { sampWStrVec.resize(header.getDataType().getExtent()); } char samp[4096]; for (std::size_t j = 0; j < numSamples; ++j) { Alembic::Abc::ISampleSelector sel( (Alembic::Abc::index_t) j); if (header.getDataType().getPod() == Alembic::AbcCoreAbstract::kStringPOD) { inProp.get(&sampStrVec.front(), sel); outProp.set(&sampStrVec.front()); } else if (header.getDataType().getPod() == Alembic::AbcCoreAbstract::kWstringPOD) { inProp.get(&sampWStrVec.front(), sel); outProp.set(&sampWStrVec.front()); } else { inProp.get(samp, sel); outProp.set(samp); } } } else if (header.isCompound()) { Alembic::Abc::OCompoundProperty outProp(iWrite, header.getName(), header.getMetaData()); Alembic::Abc::ICompoundProperty inProp(iRead, header.getName()); copyProps(inProp, outProp); } } }
void read() { Abc::IArchive archive(Alembic::AbcCoreHDF5::ReadArchive(), "MaterialNetworkNodes.abc"); Abc::IObject materialsObject(archive.getTop(), "materials"); Mat::IMaterial matObj(materialsObject, "material1"); std::cout << "----" << std::endl; std::cout << "NODES" << std::endl; std::cout << matObj.getSchema().getNumNetworkNodes() << std::endl; TESTING_ASSERT(matObj.getSchema().getNumNetworkNodes() == 2); for (size_t i = 0, e = matObj.getSchema().getNumNetworkNodes(); i < e; ++i) { Mat::IMaterialSchema::NetworkNode node = matObj.getSchema().getNetworkNode(i); TESTING_ASSERT(node.valid()); std::cout << " ----" << std::endl; std::string target = "<undefined>"; node.getTarget(target); TESTING_ASSERT(target == "abc"); std::string nodeType = "<undefined>"; node.getNodeType(nodeType); std::cout << " NODE: " << node.getName() << ", TARGET: " << target << ", TYPE: " << nodeType << std::endl; TESTING_ASSERT((nodeType == "blinn" && node.getName() == "mainshader")|| (nodeType == "texture_read" && node.getName() == "colormap")); Abc::ICompoundProperty parameters = node.getParameters(); TESTING_ASSERT(parameters.valid()); TESTING_ASSERT(parameters.getNumProperties() == 1); if (parameters.valid()) { std::cout << " PARAMETERS:" << std::endl; TESTING_ASSERT( (node.getName() == "mainshader" && parameters.getPropertyHeader(0).getName() == "Kd") || (node.getName() == "colormap" && parameters.getPropertyHeader(0).getName() == "map_name") ); for (size_t i = 0, e = parameters.getNumProperties(); i < e; ++i) { const Abc::PropertyHeader & header = parameters.getPropertyHeader(i); std::cout << " " << header.getName() << std::endl; } } size_t numConnections = node.getNumConnections(); TESTING_ASSERT( (node.getName() == "mainshader" && numConnections == 1) || (node.getName() == "colormap" && numConnections == 0) ); if (numConnections) { std::string inputName, connectedNodeName, connectedOutputName; std::cout << " CONNNECTIONS:" << std::endl; for (size_t i = 0; i < numConnections; ++i) { if (node.getConnection(i, inputName, connectedNodeName, connectedOutputName)) { TESTING_ASSERT( inputName == "Cs" && connectedNodeName == "colormap" && connectedOutputName == "color_out" ); std::cout << " " << inputName << " -> NODE: " << connectedNodeName; if (!connectedOutputName.empty()) { std::cout << ", PORT: " << connectedOutputName; } std::cout << std::endl; } } } } std::cout << "TERMINALS" << std::endl; std::vector<std::string> targetNames; matObj.getSchema().getNetworkTerminalTargetNames(targetNames); TESTING_ASSERT(targetNames.size() == 1); for (std::vector<std::string>::iterator I = targetNames.begin(); I != targetNames.end(); ++I) { const std::string & targetName = (*I); std::cout << " TARGET: " << targetName << std::endl; std::vector<std::string> shaderTypeNames; matObj.getSchema().getNetworkTerminalShaderTypesForTarget( targetName, shaderTypeNames); for (std::vector<std::string>::iterator I = shaderTypeNames.begin(); I != shaderTypeNames.end(); ++I) { const std::string & shaderType = (*I); std::cout << " SHADERTYPE: " << shaderType; std::string connectedNodeName = "<undefined>"; std::string connectedOutputName = "<undefined>"; if (matObj.getSchema().getNetworkTerminal( targetName, shaderType, connectedNodeName, connectedOutputName)) { TESTING_ASSERT(targetName == "abc" && shaderType == "surface" && connectedNodeName == "mainshader" && connectedOutputName == "out"); std::cout << ", NODE: " << connectedNodeName; if (!connectedOutputName.empty()) { std::cout << ", PORT: " << connectedOutputName; } } std::cout << std::endl; } } std::vector<std::string> mappingNames; matObj.getSchema().getNetworkInterfaceParameterMappingNames(mappingNames); std::cout << "INTERFACE MAPPINGS" << std::endl; TESTING_ASSERT(mappingNames.size() == 1); for (std::vector<std::string>::iterator I = mappingNames.begin(); I != mappingNames.end(); ++I) { std::string mapToNodeName; std::string mapToParamName; if (matObj.getSchema().getNetworkInterfaceParameterMapping( (*I), mapToNodeName, mapToParamName)) { TESTING_ASSERT(mapToNodeName == "colormap" && mapToParamName == "map_name"); std::cout << " PARAM NAME: " << (*I) << ", MAPTONODE: " << mapToNodeName << ", MAPTOPARAMNAME: " << mapToParamName; std::cout << std::endl; } } std::cerr << "\n\n\nFROM FLATTENED MATERIAL" << std::endl; Mat::MaterialFlatten mafla(matObj); printFlattenedMafla(mafla); }
void PrimitiveReader::readArbGeomParams( const Alembic::Abc::ICompoundProperty ¶ms, const Alembic::Abc::ISampleSelector &sampleSelector, IECoreScene::Primitive *primitive ) const { if( !params.valid() ) { return; } for( size_t i = 0; i < params.getNumProperties(); ++i ) { const PropertyHeader &header = params.getPropertyHeader( i ); if( IFloatGeomParam::matches( header ) ) { IFloatGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IDoubleGeomParam::matches( header ) ) { IDoubleGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IV3dGeomParam::matches( header ) ) { IV3dGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IInt32GeomParam::matches( header ) ) { IInt32GeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IStringGeomParam::matches( header ) ) { IStringGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IV2fGeomParam::matches( header ) ) { IV2fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IV3fGeomParam::matches( header ) ) { IV3fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IC3fGeomParam::matches( header ) ) { IC3fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IC4fGeomParam::matches( header ) ) { IC4fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IN3fGeomParam::matches( header ) ) { IN3fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IP3fGeomParam::matches( header ) ) { IP3fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IM44fGeomParam::matches( header ) ) { IM44fGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IBoolGeomParam::matches( header ) ) { IBoolGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if( IQuatfGeomParam::matches( header) ) { IQuatfGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else if ( IQuatdGeomParam::matches( header ) ) { IQuatdGeomParam p( params, header.getName() ); readGeomParam( p, sampleSelector, primitive ); } else { msg( Msg::Warning, "FromAlembicGeomBaseConverter::convertArbGeomParams", boost::format( "Param \"%s\" has unsupported type" ) % header.getName() ); } } }
void MeshDrwHelper::updateArbs(Alembic::Abc::ICompoundProperty & iParent, Int32ArraySamplePtr iIndices, Int32ArraySamplePtr iCounts ) { // early exit! if (m_colors.size()==m_meshP->size()) { return; } Alembic::AbcCoreAbstract::ArraySamplePtr CsSamp; Alembic::AbcCoreAbstract::ArraySamplePtr OsSamp; size_t numProps = iParent.getNumProperties(); for (size_t i = 0; i < numProps; ++i) { const Alembic::Abc::PropertyHeader & propHeader = iParent.getPropertyHeader(i); const std::string & propName = propHeader.getName(); if (propName == "Cs") { Alembic::Abc::IArrayProperty prop(iParent, propName); if (prop.isArray() && prop.getNumSamples()>0) // only if array not empty { Alembic::AbcCoreAbstract::DataType dtype = prop.getDataType(); Alembic::Util::uint8_t extent = dtype.getExtent(); std::string interp = prop.getMetaData().get("interpretation"); if (dtype.getPod() == Alembic::Util::kFloat32POD && extent==3 && interp == "rgb") { prop.get(CsSamp, 0);// only static data } } } else if (propName == "Os") { Alembic::Abc::IArrayProperty prop(iParent, propName); if (prop.isArray() && prop.getNumSamples()>0) // only if array not empty { Alembic::AbcCoreAbstract::DataType dtype = prop.getDataType(); Alembic::Util::uint8_t extent = dtype.getExtent(); std::string interp = prop.getMetaData().get("interpretation"); if (dtype.getPod() == Alembic::Util::kFloat32POD && extent==3 && interp == "rgb") { prop.get(OsSamp, 0);// only static data } } } } if (CsSamp && !OsSamp) { m_colors.resize(m_meshP->size()); float * CsData = (float *) CsSamp->getData(); int csid=0; for (int idx=0; idx<int(iIndices->size()); idx++) { if (csid<int(CsSamp->size()*3)) { m_colors[(*iIndices)[idx]] = C4f(CsData[csid],CsData[csid+1],CsData[csid+2],1); } csid+=3; } } else if (CsSamp && OsSamp) { m_colors.resize(m_meshP->size()); float * CsData = (float *) CsSamp->getData(); float * OsData = (float *) OsSamp->getData(); int csid=0; for (int idx=0; idx<int(iIndices->size()); idx++) { if (csid<int(CsSamp->size()*3)) { m_colors[(*iIndices)[idx]] = C4f(CsData[csid],CsData[csid+1],CsData[csid+2],OsData[csid]); } csid+=3; } } }
//-***************************************************************************** int main( int argc, char *argv[] ) { bool opt_all = false; bool opt_meta = false; std::string desc( "abctree [OPTION] FILE[/NAME]\n" " -a include properties listings\n" " -h, --help prints this help message\n" " -m print metadata\n" ); // check for min args if ( argc < 2 ) { std::cout << desc << std::endl; return 0; }; // parse args std::vector<std::string> arguments(argv, argv + argc); std::vector<std::string> options; std::vector<std::string> files; // separate file args from option args for ( std::size_t i = 1; i < arguments.size(); i++ ) { if ( arguments[ i ].substr( 0, 1 ) == "-" ) options.push_back( arguments[ i ] ); else files.push_back( arguments[ i ] ); } // help if ( argc < 2 || optionExists( options, "h" ) || optionExists( options, "help" ) ) { std::cout << desc << std::endl; return 0; }; // set some flags opt_all = optionExists( options, "a"); opt_meta = optionExists( options, "m"); // open each file size_t count = 0; for ( std::size_t i = 0; i < files.size(); i++ ) { if ( files.size() > 1 ) std::cout << BOLD << files[i] << ':' << RESETCOLOR << std::endl; std::stringstream ss( files[i] ); std::stringstream fp; std::string segment; std::vector<std::string> seglist; /* * separate file and object paths, e.g. * * ../dir1/foo.abc/bar/baz * \_____________/\______/ * file obj */ int j = 0; while ( std::getline( ss, segment, '/' ) ) { if ( !isFile ( fp.str() ) ) { if ( j != 0 ) fp << "/"; fp << segment; } else { seglist.push_back( segment ); } ++j; } // open the iarchive Abc::IArchive archive; AbcF::IFactory factory; factory.setPolicy(Abc::ErrorHandler::kQuietNoopPolicy); AbcF::IFactory::CoreType coreType; archive = factory.getArchive(std::string( fp.str() ), coreType); // display file metadata if ( opt_meta ) { std::cout << "Using " << Alembic::AbcCoreAbstract::GetLibraryVersion () << std::endl;; std::string appName; std::string libraryVersionString; Alembic::Util::uint32_t libraryVersion; std::string whenWritten; std::string userDescription; std::string coreName; GetArchiveInfo (archive, appName, libraryVersionString, libraryVersion, whenWritten, userDescription); if ( coreType == AbcF::IFactory::kOgawa ) { coreName = "Ogawa"; } else if ( coreType == AbcF::IFactory::kHDF5 ) { coreName = "HDF5"; } else { coreName = "Unknown"; }; if ( appName != "" ) { std::cout << " file written by: " << appName << std::endl; std::cout << " using Alembic : " << libraryVersionString << std::endl; std::cout << " written on : " << whenWritten << std::endl; std::cout << " user description : " << userDescription << std::endl; } else { std::cout << " (file doesn't have any ArchiveInfo)" << std::endl; } std::cout << " core type : " << coreName << std::endl; }; // walk object hierarchy and find valid objects AbcG::IObject test = archive.getTop(); AbcG::IObject iObj = test; while ( test.valid() && seglist.size() > 0 ) { test = test.getChild( seglist.front() ); if ( test.valid() ) { iObj = test; seglist.erase( seglist.begin() ); } } // walk property hierarchy for most recent valid object Abc::ICompoundProperty props = iObj.getProperties(); const Abc::PropertyHeader* header; bool found = false; for ( std::size_t i = 0; i < seglist.size(); ++i ) { header = props.getPropertyHeader( seglist[i] ); if ( header && header->isCompound() ) { Abc::ICompoundProperty ptest( props, header->getName() ); if ( ptest.valid() ) { props = ptest; found = true; } } else if ( header && header->isSimple() ) { found = true; } else { std::cout << seglist[i] << ": Invalid object or property" << std::endl; return 1; } } // walk the archive tree if ( found ) if ( header->isCompound() ) tree( props ); else tree( Abc::IScalarProperty( props, header->getName() ) ); else tree( iObj, opt_all ); ++count; } return 0; }