//-***************************************************************************** void readDeepHierarchy( IObject parent, const int level, const IObject& orig ) { if ( level > DEPTH ) { ICompoundProperty p = parent.getProperties(); IInt32ArrayProperty iap( p, "intArrayProp" ); std::string fullName = const_cast<std::string&>( iap.getObject().getFullName() ); PATH_PAIR ret = PATHS.insert( fullName ); Int32ArraySamplePtr sampPtr = iap.getValue(); TESTING_ASSERT( sampPtr->get()[5] == 5 ); TESTING_ASSERT( sampPtr->get()[99] == 99 ); TESTING_ASSERT( sampPtr->size() == ( size_t ) HIGHVAL ); TESTING_ASSERT( ret.second ); TESTING_ASSERT( fullName == parent.getFullName() ); // walk back up the tree until you find the first child object // under the top object, and check that it's the one we started // with. IObject _p = parent; while ( _p.getParent().getParent() ) { _p = _p.getParent(); } TESTING_ASSERT( _p.getFullName() == orig.getFullName() ); return; } std::ostringstream strm; strm << level; std::string levelName = strm.str(); readDeepHierarchy( IObject( parent, levelName ), level + 1, orig ); }
//-***************************************************************************** void ProcessSubD( ISubD &subd, ProcArgs &args, const std::string & facesetName ) { ISubDSchema &ss = subd.getSchema(); TimeSamplingPtr ts = ss.getTimeSampling(); SampleTimeSet sampleTimes; GetRelevantSampleTimes( args, ts, ss.getNumSamples(), sampleTimes ); bool multiSample = sampleTimes.size() > 1; //include this code path for future expansion bool isHierarchicalSubD = false; bool hasLocalResources = false; std::vector<IFaceSet> faceSets; std::vector<std::string> faceSetResourceNames; if ( facesetName.empty() ) { std::vector <std::string> childFaceSetNames; ss.getFaceSetNames(childFaceSetNames); faceSets.reserve(childFaceSetNames.size()); faceSetResourceNames.reserve(childFaceSetNames.size()); for (size_t i = 0; i < childFaceSetNames.size(); ++i) { faceSets.push_back(ss.getFaceSet(childFaceSetNames[i])); IFaceSet & faceSet = faceSets.back(); std::string resourceName = args.getResource( faceSet.getFullName() ); if ( resourceName.empty() ) { resourceName = args.getResource( faceSet.getName() ); } #ifdef PRMAN_USE_ABCMATERIAL Mat::MaterialFlatten mafla(faceSet); if (!mafla.empty()) { if (!hasLocalResources) { RiResourceBegin(); hasLocalResources = true; } RiAttributeBegin(); if ( !resourceName.empty() ) { //restore existing resource state here RestoreResource( resourceName ); } WriteMaterial( mafla, args ); resourceName = faceSet.getFullName(); SaveResource( resourceName ); RiAttributeEnd(); } #endif faceSetResourceNames.push_back(resourceName); } } #ifdef PRMAN_USE_ABCMATERIAL else { //handle single faceset material directly if ( ss.hasFaceSet( facesetName ) ) { IFaceSet faceSet = ss.getFaceSet( facesetName ); ApplyObjectMaterial(faceSet, args); } } #endif if ( multiSample ) { WriteMotionBegin( args, sampleTimes ); } for ( SampleTimeSet::iterator iter = sampleTimes.begin(); iter != sampleTimes.end(); ++iter ) { ISampleSelector sampleSelector( *iter ); ISubDSchema::Sample sample = ss.getValue( sampleSelector ); RtInt npolys = (RtInt) sample.getFaceCounts()->size(); ParamListBuilder paramListBuilder; paramListBuilder.add( "P", (RtPointer)sample.getPositions()->get() ); IV2fGeomParam uvParam = ss.getUVsParam(); if ( uvParam.valid() ) { ICompoundProperty parent = uvParam.getParent(); if ( !args.flipv ) { AddGeomParamToParamListBuilder<IV2fGeomParam>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, 2, "st"); } else if ( std::vector<float> * values = AddGeomParamToParamListBuilderAsFloat<IV2fGeomParam, float>( parent, uvParam.getHeader(), sampleSelector, "float", paramListBuilder, "st") ) { for ( size_t i = 1, e = values->size(); i < e; i += 2 ) { (*values)[i] = 1.0 - (*values)[i]; } } } ICompoundProperty arbGeomParams = ss.getArbGeomParams(); AddArbitraryGeomParams( arbGeomParams, sampleSelector, paramListBuilder ); std::string subdScheme = sample.getSubdivisionScheme(); SubDTagBuilder tags; ProcessFacevaryingInterpolateBoundry( tags, sample ); ProcessInterpolateBoundry( tags, sample ); ProcessFacevaryingPropagateCorners( tags, sample ); ProcessHoles( tags, sample ); ProcessCreases( tags, sample ); ProcessCorners( tags, sample ); if ( !facesetName.empty() ) { if ( ss.hasFaceSet( facesetName ) ) { IFaceSet faceSet = ss.getFaceSet( facesetName ); ApplyResources( faceSet, args ); // TODO, move the hold test outside of MotionBegin // as it's not meaningful to change per sample IFaceSetSchema::Sample faceSetSample = faceSet.getSchema().getValue( sampleSelector ); std::set<int> facesToKeep; facesToKeep.insert( faceSetSample.getFaces()->get(), faceSetSample.getFaces()->get() + faceSetSample.getFaces()->size() ); for ( int i = 0; i < npolys; ++i ) { if ( facesToKeep.find( i ) == facesToKeep.end() ) { tags.add( "hole" ); tags.addIntArg( i ); } } } } else { //loop through the facesets and determine whether there are any //resources assigned to each for (size_t i = 0; i < faceSetResourceNames.size(); ++i) { const std::string & resourceName = faceSetResourceNames[i]; //TODO, visibility? if ( !resourceName.empty() ) { IFaceSet & faceSet = faceSets[i]; isHierarchicalSubD = true; tags.add("faceedit"); Int32ArraySamplePtr faces = faceSet.getSchema().getValue( sampleSelector ).getFaces(); for (size_t j = 0, e = faces->size(); j < e; ++j) { tags.addIntArg(1); //yep, every face gets a 1 in front of it too tags.addIntArg( (int) faces->get()[j]); } tags.addStringArg( "attributes" ); tags.addStringArg( resourceName ); tags.addStringArg( "shading" ); } } } if ( isHierarchicalSubD ) { RiHierarchicalSubdivisionMeshV( const_cast<RtToken>( subdScheme.c_str() ), npolys, (RtInt*) sample.getFaceCounts()->get(), (RtInt*) sample.getFaceIndices()->get(), tags.nt(), tags.tags(), tags.nargs( true ), tags.intargs(), tags.floatargs(), tags.stringargs(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } else { RiSubdivisionMeshV( const_cast<RtToken>(subdScheme.c_str() ), npolys, (RtInt*) sample.getFaceCounts()->get(), (RtInt*) sample.getFaceIndices()->get(), tags.nt(), tags.tags(), tags.nargs( false ), tags.intargs(), tags.floatargs(), paramListBuilder.n(), paramListBuilder.nms(), paramListBuilder.vals() ); } } if ( multiSample ) { RiMotionEnd(); } if ( hasLocalResources ) { RiResourceEnd(); } }
//-***************************************************************************** void StupidData() { std::string archiveName( "stupiddata.abc" ); // out { OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), archiveName ); OObject myobject( archive.getTop(), "myobject" ); // a compound property to use as the parent for data-containing properties OCompoundProperty props = myobject.getProperties(); OInt32ArrayProperty intArrayProp( props, "intArrayProp" ); for ( Alembic::Util::int32_t i = 0 ; i < 10 ; ++i ) { std::vector<Alembic::Util::int32_t> v( i, i ); intArrayProp.set( v ); TESTING_ASSERT( intArrayProp.getNumSamples() == ( size_t ) ( i + 1 ) ); } std::cout << std::endl << "Writing " << archiveName << std::endl; } // in { std::cout << std::endl << "Reading " << archiveName << std::endl; IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), archiveName ); IObject myobject( archive.getTop(), "myobject" ); // a compound property to use as the parent for data-containing properties ICompoundProperty props = myobject.getProperties(); IInt32ArrayProperty intArrayProp( props, "intArrayProp" ); TESTING_ASSERT( intArrayProp.getNumSamples() == 10 ); // try to create a non-existent property IFloatArrayProperty nonProp( props, "doesntexist", ErrorHandler::kQuietNoopPolicy ); if ( nonProp ) { std::cout << "this should not be printed" << std::endl; } else { std::cout << "non-existent Property doesn't exist." << std::endl; } for ( size_t i = 0 ; i < 10 ; ++i ) { std::vector<Alembic::Util::int32_t> v( i, i ); Int32ArraySamplePtr samp = intArrayProp.getValue( i ); size_t numpoints = samp->size(); TESTING_ASSERT( numpoints == i ); std::cout << "sample " << i << ": "; for ( size_t j = 0 ; j < numpoints ; ++j ) { std::cout << (*samp)[j]; if ( numpoints > 0 && j < numpoints - 1 ) { std::cout << ", "; } } std::cout << std::endl; } } }
void emptyAndValueTest(const std::string &archiveName, bool useOgawa) { std::vector<std::string> strVec; strVec.push_back( "potato" ); std::vector<C3f> colorVec; colorVec.push_back( C3f( 0.0, 0.5, 0.75 ) ); std::vector<Alembic::Util::int32_t> intVec; intVec.push_back(42); StringArraySample strSamp( strVec ); C3fArraySample colorSamp( colorVec ); Int32ArraySample intSamp( intVec ); StringArraySample emptyStrSamp = StringArraySample::emptySample(); C3fArraySample emptyColorSamp = C3fArraySample::emptySample(); Int32ArraySample emptyIntSamp = Int32ArraySample::emptySample(); { OArchive archive; if (useOgawa) { archive = OArchive( Alembic::AbcCoreOgawa::WriteArchive(), archiveName ); } else { archive = OArchive( Alembic::AbcCoreHDF5::WriteArchive(), archiveName ); } OCompoundProperty root = archive.getTop().getProperties(); OC3fArrayProperty colorProp( root, "colors" ); OInt32ArrayProperty numProp( root, "numbers" ); AbcA::MetaData md; SetReference( md ); OStringArrayProperty strProp( root, "strings", md ); TESTING_ASSERT( isReference( strProp.getHeader() ) ); colorProp.set( emptyColorSamp ); colorProp.set( colorSamp ); colorProp.set( emptyColorSamp ); colorProp.set( colorSamp ); numProp.set( emptyIntSamp ); numProp.set( intSamp ); numProp.set( emptyIntSamp ); numProp.set( intSamp ); strProp.set( emptyStrSamp ); strProp.set( strSamp ); strProp.set( emptyStrSamp ); strProp.set( strSamp ); } { StringArraySamplePtr strSampPtr; C3fArraySamplePtr colorSampPtr; Int32ArraySamplePtr intSampPtr; AbcF::IFactory factory; factory.setPolicy( ErrorHandler::kThrowPolicy ); AbcF::IFactory::CoreType coreType; IArchive archive = factory.getArchive(archiveName, coreType); TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) || (!useOgawa && coreType == AbcF::IFactory::kHDF5) ); ICompoundProperty root = archive.getTop().getProperties(); IC3fArrayProperty colorProp( root, "colors" ); IInt32ArrayProperty numProp( root, "numbers" ); IStringArrayProperty strProp( root, "strings" ); TESTING_ASSERT( isReference( strProp.getHeader() ) ); TESTING_ASSERT( colorProp.getNumSamples() == 4 ); TESTING_ASSERT( strProp.getNumSamples() == 4 ); TESTING_ASSERT( numProp.getNumSamples() == 4 ); colorProp.get( colorSampPtr, 0 ); strProp.get( strSampPtr, 0 ); numProp.get( intSampPtr, 0 ); TESTING_ASSERT( colorSampPtr->size() == 0 ); TESTING_ASSERT( strSampPtr->size() == 0 ); TESTING_ASSERT( intSampPtr->size() == 0 ); colorProp.get( colorSampPtr, 2 ); strProp.get( strSampPtr, 2 ); numProp.get( intSampPtr, 2 ); TESTING_ASSERT( colorSampPtr->size() == 0 ); TESTING_ASSERT( strSampPtr->size() == 0 ); TESTING_ASSERT( intSampPtr->size() == 0 ); colorProp.get( colorSampPtr, 1 ); strProp.get( strSampPtr, 1 ); numProp.get( intSampPtr, 1 ); TESTING_ASSERT( colorSampPtr->size() == 1 && colorSamp[0] == ( *colorSampPtr )[0] ); TESTING_ASSERT( strSampPtr->size() == 1 && strSamp[0] == ( *strSampPtr )[0] ); TESTING_ASSERT( intSampPtr->size() == 1 && intSamp[0] == ( *intSampPtr )[0] ); colorProp.get( colorSampPtr, 3 ); strProp.get( strSampPtr, 3 ); numProp.get( intSampPtr, 3 ); TESTING_ASSERT( colorSampPtr->size() == 1 && colorSamp[0] == ( *colorSampPtr )[0] ); TESTING_ASSERT( strSampPtr->size() == 1 && strSamp[0] == ( *strSampPtr )[0] ); TESTING_ASSERT( intSampPtr->size() == 1 && intSamp[0] == ( *intSampPtr )[0] ); } }
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; } } }