//-***************************************************************************** std::size_t XformSample::addOp( const XformOp &iOp ) { if ( ! m_hasBeenRead ) { ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); m_setWithOpStack = 1; m_ops.push_back( iOp ); return m_ops.size() - 1; } else { std::size_t ret = m_opIndex; ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(), "Cannot update mismatched op-type in already-setted " << "XformSample!" ); ABCA_ASSERT( m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); m_ops[ret] = iOp; m_opIndex = ++m_opIndex % m_ops.size(); return ret; } }
//-***************************************************************************** CprImpl::CprImpl( AbcA::CompoundPropertyReaderPtr iParent, Ogawa::IGroupPtr iGroup, PropertyHeaderPtr iHeader, std::size_t iThreadId, const std::vector< AbcA::MetaData > & iIndexedMetaData ) : m_parent( iParent ) , m_header( iHeader ) { ABCA_ASSERT( m_parent, "Invalid parent in CprImpl(Compound)" ); ABCA_ASSERT( m_header, "invalid header in CprImpl(Compound)" ); AbcA::PropertyType pType = m_header->header.getPropertyType(); if ( pType != AbcA::kCompoundProperty ) { ABCA_THROW( "Tried to create compound property with the wrong " "property type: " << pType ); } // Set object. AbcA::ObjectReaderPtr optr = m_parent->getObject(); ABCA_ASSERT( optr, "Invalid object in CprImpl::CprImpl(Compound)" ); m_object = optr; m_data.reset( new CprData( iGroup, iThreadId, *( m_object->getArchive() ), iIndexedMetaData ) ); }
//-***************************************************************************** void XformSample::setZRotation( const double iAngleInDegrees ) { XformOp op( kRotateZOperation, kRotateHint ); op.setChannelValue( 0, iAngleInDegrees ); if ( ! m_hasBeenRead ) { ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2, "Cannot mix addOp() and set<Foo>() methods." ); m_setWithOpStack = 2; m_ops.push_back( op ); } else { std::size_t ret = m_opIndex; ABCA_ASSERT( m_setWithOpStack == 2, "Cannot mix addOp() and set<Foo>() methods." ); ABCA_ASSERT( op.getType() == m_ops[ret].getType(), "Cannot update mismatched op-type in already-setted " << "XformSample!" ); m_ops[ret] = op; m_opIndex = ++m_opIndex % m_ops.size(); } }
//-***************************************************************************** void XformSample::setScale( const Abc::V3d &iScale ) { XformOp op( kScaleOperation, kScaleHint ); for ( size_t i = 0 ; i < 3 ; ++i ) { op.setChannelValue( i, iScale[i] ); } if ( ! m_hasBeenRead ) { ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2, "Cannot mix addOp() and set<Foo>() methods." ); m_setWithOpStack = 2; m_ops.push_back( op ); } else { std::size_t ret = m_opIndex; ABCA_ASSERT( m_setWithOpStack == 2, "Cannot mix addOp() and set<Foo>() methods." ); ABCA_ASSERT( op.getType() == m_ops[ret].getType(), "Cannot update mismatched op-type in already-setted " << "XformSample!" ); m_ops[ret] = op; m_opIndex = ++m_opIndex % m_ops.size(); } }
//-***************************************************************************** CprImpl::CprImpl( AbcA::CompoundPropertyReaderPtr iParent, H5Node & iParentGroup, PropertyHeaderPtr iHeader ) : m_parent( iParent ) , m_header( iHeader ) { ABCA_ASSERT( m_parent, "Invalid parent in CprImpl(Compound)" ); ABCA_ASSERT( m_header, "invalid header in CprImpl(Compound)" ); AbcA::PropertyType pType = m_header->getPropertyType(); if ( pType != AbcA::kCompoundProperty ) { ABCA_THROW( "Tried to create compound property with the wrong " "property type: " << pType ); } // Set object. AbcA::ObjectReaderPtr optr = m_parent->getObject(); ABCA_ASSERT( optr, "Invalid object in CprImpl::CprImpl(Compound)" ); m_object = optr; m_data.reset( new CprData( iParentGroup, m_parent->getObject()->getArchive()->getArchiveVersion(), m_header->getName() ) ); }
//-***************************************************************************** std::size_t XformSample::addOp( XformOp iOp, const Abc::V3d &iVal ) { for ( size_t i = 0 ; i < 3 ; ++i ) { iOp.setChannelValue( i, iVal[i] ); } if ( ! m_hasBeenRead ) { ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); m_setWithOpStack = 1; m_ops.push_back( iOp ); return m_ops.size() - 1; } else { std::size_t ret = m_opIndex; ABCA_ASSERT( m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(), "Cannot update mismatched op-type in already-setted " << "XformSample!" ); m_ops[ret] = iOp; m_opIndex = ++m_opIndex % m_ops.size(); return ret; } }
//-***************************************************************************** void CopyWrittenArray( hid_t iGroup, const std::string &iName, WrittenArraySampleIDPtr iRef ) { ABCA_ASSERT( ( bool )iRef, "CopyWrittenArray() passed a bogus ref" ); hid_t fid = H5Iget_file_id(iGroup); ABCA_ASSERT( fid >= 0, "CopyWrittenArray() Could not get file ID from iGroup" ); hid_t did = H5Dopen( fid, iRef->getObjectLocation().c_str(), H5P_DEFAULT ); DsetCloser dcloser(did); // We have a reference. Create a link to it. // We are manually getting the source dataset instead of using // fid and iName because of a bug in HDF5 1.8.5 and earlier. // Files written using that approach would sometimes be corrupted. herr_t status = H5Lcreate_hard( did, ".", iGroup, iName.c_str(), H5P_DEFAULT, H5P_DEFAULT ); H5Fclose( fid ); ABCA_ASSERT( status >= 0, "H5Lcreate_hard failed!" << std::endl << "Dset obj id: " << did << std::endl << "Link loc id: " << iGroup << std::endl << "Link name: " << iName ); }
//-***************************************************************************** // Get the dimensions directly off of the dataspace on the dataset // This isn't suitable for string and wstring void ReadDataSetDimensions( hid_t iParent, const std::string &iName, hsize_t iExtent, Dimensions &oDims ) { // Open the data set. hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName ); DsetCloser dsetCloser( dsetId ); // Read the data space. hid_t dspaceId = H5Dget_space( dsetId ); ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: " << iName ); DspaceCloser dspaceCloser( dspaceId ); H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId ); if ( dspaceClass == H5S_SIMPLE ) { // Get the dimensions int rank = H5Sget_simple_extent_ndims( dspaceId ); ABCA_ASSERT( rank == 1, "H5Sget_simple_extent_ndims() must be 1." ); hsize_t hdim = 0; rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL ); oDims.setRank(1); oDims[0] = hdim / iExtent; } else { oDims.setRank(1); oDims[0] = 0; } }
void WriteStringsT( hid_t iParent, const std::string &iAttrName, size_t iNumStrings, const StringT *iStrings ) { // Validate ABCA_ASSERT( iNumStrings > 0, "Degenerate num strings in WriteStringsT" ); ABCA_ASSERT( iStrings, "Degenerate strings buffer in WriteStringsT" ); // Compact the strings. std::vector<CharT> charBuffer; CompactStrings( iStrings, iNumStrings, charBuffer ); // Create the dataspace. size_t len = charBuffer.size(); assert( len >= iNumStrings ); Dimensions dims( len ); HDimensions hdims( dims ); hid_t dspaceId = H5Screate_simple( hdims.rank(), hdims.rootPtr(), NULL ); DspaceCloser dspaceCloser( dspaceId ); ABCA_ASSERT( dspaceId >= 0, "WriteStringsT() Failed in dataspace constructor" ); // Create the attribute. WriteDataToAttr( iParent, dspaceId, iAttrName, GetFileDtype<CharT>(), GetNativeDtype<CharT>(), ( const void * )&charBuffer.front() ); // That's it! }
//-***************************************************************************** // With the compound property writer as an input. CpwImpl::CpwImpl( AbcA::CompoundPropertyWriterPtr iParent, hid_t iParentGroup, const std::string & iName, const AbcA::MetaData & iMeta ) : BaseCpwImpl( iParentGroup ) , m_parent( iParent ) , m_header( new AbcA::PropertyHeader(iName, iMeta) ) { // Check the validity of all inputs. ABCA_ASSERT( m_parent, "Invalid parent" ); ABCA_ASSERT( m_header, "Invalid property header" ); if ( m_header->getPropertyType() != AbcA::kCompoundProperty ) { ABCA_THROW( "Tried to create compound property with the wrong " "property type: " << m_header->getPropertyType() ); } // Set the object. AbcA::ObjectWriterPtr optr = m_parent->getObject(); ABCA_ASSERT( optr, "Invalid object" ); m_object = optr; // Write the property header. WritePropertyInfo( iParentGroup, m_header->getName(), m_header->getPropertyType(), m_header->getDataType(), false, 0, 0, 0, 0 ); WriteMetaData( iParentGroup, m_header->getName() + ".meta", m_header->getMetaData() ); }
//-***************************************************************************** std::size_t XformSample::addOp( XformOp iOp, const double iSingleAxisRotationInDegrees ) { iOp.setChannelValue( 0, iSingleAxisRotationInDegrees ); if ( ! m_hasBeenRead ) { ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); m_setWithOpStack = 1; m_ops.push_back( iOp ); return m_ops.size() - 1; } else { std::size_t ret = m_opIndex; ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(), "Cannot update mismatched op-type in already-setted " << "XformSample!" ); ABCA_ASSERT( m_setWithOpStack == 1, "Cannot mix addOp() and set<Foo>() methods." ); m_ops[ret] = iOp; m_opIndex = ++m_opIndex % m_ops.size(); return ret; } }
//-***************************************************************************** // With the compound property writer as an input. CpwImpl::CpwImpl( AbcA::CompoundPropertyWriterPtr iParent, hid_t iParentGroup, PropertyHeaderPtr iHeader ) : BaseCpwImpl( iParentGroup ) , m_parent( iParent ) , m_header( iHeader ) { // Check the validity of all inputs. ABCA_ASSERT( m_parent, "Invalid parent" ); ABCA_ASSERT( m_header, "Invalid property header" ); if ( m_header->getPropertyType() != AbcA::kCompoundProperty ) { ABCA_THROW( "Tried to create compound property with the wrong " "property type: " << m_header->getPropertyType() ); } // Set the object. AbcA::ObjectWriterPtr optr = m_parent->getObject(); ABCA_ASSERT( optr, "Invalid object" ); m_object = optr; // Write the property header. WritePropertyHeaderExceptTime( iParentGroup, m_header->getName(), *m_header ); }
//-***************************************************************************** CprImpl::CprImpl( AbcA::ObjectReaderPtr iObject, CprDataPtr iData ) : m_object( iObject ) , m_data( iData ) { ABCA_ASSERT( m_object, "Invalid object in CprImpl(Object)" ); ABCA_ASSERT( m_data, "Invalid data in CprImpl(Object)" ); m_header.reset( new AbcA::PropertyHeader( "", m_object->getMetaData() ) ); }
//-***************************************************************************** // SCENE CLASS //-***************************************************************************** Scene::Scene( const std::string &fileName, bool verbose ) : m_fileName( fileName ) , m_minTime( ( chrono_t )FLT_MAX ) , m_maxTime( ( chrono_t )-FLT_MAX ) { Timer playbackTimer; Alembic::AbcCoreFactory::IFactory factory; m_archive = factory.getArchive( fileName ); m_topObject = IObject( m_archive, kTop ); if ( verbose ) std::cout << "Opened archive and top object, creating drawables." << std::endl; m_drawable.reset( new IObjectDrw( m_topObject, false ) ); ABCA_ASSERT( m_drawable->valid(), "Invalid drawable for archive: " << fileName ); if ( verbose ) std::cout << "Created drawables, getting time range." << std::endl; m_minTime = m_drawable->getMinTime(); m_maxTime = m_drawable->getMaxTime(); if ( m_minTime <= m_maxTime ) { if ( verbose ) std::cout << "\nMin Time: " << m_minTime << " seconds " << std::endl << "Max Time: " << m_maxTime << " seconds " << std::endl << "\nLoading min time." << std::endl; m_drawable->setTime( m_minTime ); } else { if ( verbose ) std::cout << "\nConstant Time." << std::endl << "\nLoading constant sample." << std::endl; m_minTime = m_maxTime = 0.0; m_drawable->setTime( 0.0 ); } ABCA_ASSERT( m_drawable->valid(), "Invalid drawable after reading start time" ); if ( verbose ) std::cout << "Done opening archive. Elapsed CPU time: " << ((float)playbackTimer.elapsed()) / CLOCKS_PER_SEC << " seconds." << std::endl; // Bounds have been formed! m_bounds = m_drawable->getBounds(); if ( verbose ) std::cout << "Bounds at min time: " << m_bounds.min << " to " << m_bounds.max << std::endl; }
OwImpl::OwImpl( AbcA::ArchiveWriterPtr iArchive, OwDataPtr iData, const AbcA::MetaData & iMetaData ) : m_archive( iArchive ) , m_header( new AbcA::ObjectHeader( "ABC", "/", iMetaData ) ) , m_data( iData ) , m_index( 0 ) { ABCA_ASSERT( m_archive, "Invalid archive" ); ABCA_ASSERT( m_data, "Invalid data" ); }
//-***************************************************************************** OrData::OrData( ObjectHeaderPtr iHeader, H5Node & iParentGroup, int32_t iArchiveVersion ) : m_children( NULL ) { ABCA_ASSERT( iHeader, "Invalid header" ); ABCA_ASSERT( iParentGroup.isValidObject(), "Invalid group" ); m_group = OpenGroup( iParentGroup, iHeader->getName().c_str() ); ABCA_ASSERT( m_group.isValidObject(), "Could not open object group: " << iHeader->getFullName() ); std::vector<std::string> objNames; herr_t status = H5Literate( m_group.getObject(), H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, VisitAllLinksCB, ( void * )&objNames ); ABCA_ASSERT( status >= 0, "OrData::OrData: H5Literate failed" ); std::vector < std::string >::iterator namesIt; uint32_t i = 0; if ( !objNames.empty() ) { m_children = new Child[ objNames.size() ]; } std::string parentFullName = iHeader->getFullName(); if ( parentFullName != "/" ) { parentFullName += "/"; } for ( namesIt = objNames.begin(); namesIt != objNames.end(); ++namesIt, ++i ) { m_childrenMap[ *namesIt ] = i; m_children[i].header.reset( new AbcA::ObjectHeader( *namesIt, parentFullName + *namesIt, AbcA::MetaData() ) ); m_children[i].loadedMetaData = false; } m_oldGroup = m_group; m_data = Alembic::Util::shared_ptr<CprData>( new CprData( m_group, iArchiveVersion, ".prop" ) ); }
//-***************************************************************************** CprImpl::CprImpl( AbcA::ObjectReaderPtr iObject, CprDataPtr iData ) : m_object( iObject ) , m_data( iData ) { ABCA_ASSERT( m_object, "Invalid object in CprImpl(Object)" ); ABCA_ASSERT( m_data, "Invalid data in CprImpl(Object)" ); std::string emptyName; m_header.reset( new PropertyHeaderAndFriends( emptyName, m_object->getMetaData() ) ); }
//-***************************************************************************** ArImpl::ArImpl( const std::vector< std::istream * > & iStreams ) : m_archive( iStreams ) , m_header( new AbcA::ObjectHeader() ) , m_manager( iStreams.size() ) { ABCA_ASSERT( m_archive.isValid(), "Could not open as Ogawa file from provided streams." ); ABCA_ASSERT( m_archive.isFrozen(), "Ogawa streams not cleanly closed while being written. " ); init(); }
//-***************************************************************************** ArImpl::ArImpl( const std::string &iFileName, std::size_t iNumStreams ) : m_fileName( iFileName ) , m_archive( iFileName, iNumStreams ) , m_header( new AbcA::ObjectHeader() ) , m_manager( iNumStreams ) { ABCA_ASSERT( m_archive.isValid(), "Could not open as Ogawa file: " << m_fileName ); ABCA_ASSERT( m_archive.isFrozen(), "Ogawa file not cleanly closed while being written: " << m_fileName ); init(); }
//-***************************************************************************** void ReadTimeSamples( hid_t iParent, std::vector < AbcA::TimeSamplingPtr > & oTimeSamples ) { oTimeSamples.clear(); // add the intrinsic default sampling AbcA::TimeSamplingPtr ts( new AbcA::TimeSampling() ); oTimeSamples.push_back( ts ); uint32_t i = 1; AbcA::TimeSamplingType tst; std::string tstname = "1"; // keep trying to read till we can't find anymore while ( ReadTimeSamplingType( iParent, tstname, tst ) ) { // try to open the time samples attribute std::string timeName = tstname + ".time"; hid_t aid = H5Aopen( iParent, timeName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( aid >= 0, "Couldn't open time samples named: " << timeName ); AttrCloser attrCloser( aid ); // figure out how big it is hid_t sid = H5Aget_space( aid ); ABCA_ASSERT( sid >= 0, "Couldn't get dataspace for time samples: " << timeName ); DspaceCloser dspaceCloser( sid ); hssize_t numPoints = H5Sget_simple_extent_npoints( sid ); ABCA_ASSERT( numPoints > 0, "No time samples data: " << timeName ); std::vector < chrono_t > times(numPoints); // do the read herr_t status = H5Aread( aid, H5T_NATIVE_DOUBLE, &(times.front()) ); ABCA_ASSERT( status >= 0, "Can't read time samples: " << timeName ); // create the TimeSampling and add it to our vector ts.reset( new AbcA::TimeSampling(tst, times) ); oTimeSamples.push_back( ts ); // increment to try and read the next one i++; std::stringstream strm; strm << i; tstname = strm.str(); } }
//-***************************************************************************** AbcA::TimeSamplingPtr ArImpl::getTimeSampling( Util::uint32_t iIndex ) { ABCA_ASSERT( iIndex < m_timeSamples.size(), "Invalid index provided to getTimeSampling." ); return m_timeSamples[iIndex]; }
//-***************************************************************************** static void getDatatypeArrayDims( hid_t iDtype, Dimensions &dims ) { ABCA_ASSERT( iDtype >= 0, "Invalid datatype in getDatatypeArrayDims" ); int ndims = H5Tget_array_ndims( iDtype ); ABCA_ASSERT( ndims > 0, "getDatatypeArrayDims() H5Tget_array_ndims failed" ); HDimensions hdims( ( size_t )ndims ); ndims = H5Tget_array_dims2( iDtype, hdims.rootPtr() ); ABCA_ASSERT( ndims > 0, "getDatatypeArrayDims() H5Tget_array_dims failed" ); ABCA_ASSERT( ndims == hdims.rank(), "getDatatypeArrayDims() inconsistent ranks" ); dims = hdims; }
//-***************************************************************************** WrittenArraySampleMap & GetWrittenArraySampleMap( AbcA::ArchiveWriterPtr iVal ) { AwImpl *ptr = dynamic_cast<AwImpl*>( iVal.get() ); ABCA_ASSERT( ptr, "NULL Impl Ptr" ); return ptr->getWrittenArraySampleMap(); }
//-***************************************************************************** IFaceSet IPolyMeshSchema::getFaceSet ( const std::string &iFaceSetName ) { ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::getFaceSet()" ); boost::mutex::scoped_lock l(m_faceSetsMutex); if (!m_faceSetsLoaded) { loadFaceSetNames(); } ABCA_ASSERT( m_faceSets.find (iFaceSetName) != m_faceSets.end (), "The requested FaceSet name can't be found in PolyMesh."); if (!m_faceSets [iFaceSetName]) { // We haven't yet loaded the faceSet, so create/load it m_faceSets [iFaceSetName] = IFaceSet ( this->getParent().getObject(), iFaceSetName ); } return m_faceSets [iFaceSetName]; ALEMBIC_ABC_SAFE_CALL_END(); IFaceSet emptyFaceSet; return emptyFaceSet; }
//-***************************************************************************** IFaceSet ISubDSchema::getFaceSet( const std::string &iFaceSetName ) { ALEMBIC_ABC_SAFE_CALL_BEGIN( "ISubDSchema::getFaceSet()" ); Alembic::Util::scoped_lock l(m_faceSetsMutex); if (!m_faceSetsLoaded) { loadFaceSetNames(); } ABCA_ASSERT( m_faceSets.find (iFaceSetName) != m_faceSets.end (), "The requested FaceSet name can't be found in SubD."); if (!m_faceSets [iFaceSetName]) { // We haven't yet loaded the faceSet, so create/load it m_faceSets [iFaceSetName] = IFaceSet ( getObject(), iFaceSetName ); } return m_faceSets [iFaceSetName]; ALEMBIC_ABC_SAFE_CALL_END(); IFaceSet empty; return empty; }
//-***************************************************************************** void XformOp::setTranslate( const Abc::V3d &iTrans ) { ABCA_ASSERT( m_type == kTranslateOperation, "Meaningless to set translate on non-translate op." ); this->setVector( iTrans ); }
//-***************************************************************************** void XformOp::setScale( const Abc::V3d &iScale ) { ABCA_ASSERT( m_type == kScaleOperation, "Meaningless to set scale on non-scale op." ); this->setVector( iScale ); }
//-***************************************************************************** Abc::V3d XformOp::getVector() const { ABCA_ASSERT( m_type != kMatrixOperation, "Meaningless to get Abc::V3d from matrix op" ); return Abc::V3d( m_channels[0], m_channels[1], m_channels[2] ); }
//-***************************************************************************** Abc::V3d XformOp::getTranslate() const { ABCA_ASSERT( m_type == kTranslateOperation, "Meaningless to get translate vector from non-translate op." ); return this->getVector(); }
//-***************************************************************************** Abc::V3d XformOp::getScale() const { ABCA_ASSERT( m_type == kScaleOperation, "Meaningless to get scaling vector from non-scale op." ); return this->getVector(); }