Imath::Box3d HoudiniScene::readBound( double time ) const { OP_Node *node = retrieveNode( true ); Imath::Box3d bounds; UT_BoundingBox box; OP_Context context( time ); /// \todo: this doesn't account for SOPs containing multiple shapes /// if we fix it, we need to fix the condition below as well if ( node->getBoundingBox( box, context ) ) { bounds = IECore::convert<Imath::Box3d>( box ); } // paths embedded within a sop already have bounds accounted for if ( m_contentIndex ) { return bounds; } NameList children; childNames( children ); for ( NameList::iterator it=children.begin(); it != children.end(); ++it ) { ConstSceneInterfacePtr childScene = child( *it ); Imath::Box3d childBound = childScene->readBound( time ); if ( !childBound.isEmpty() ) { bounds.extendBy( Imath::transform( childBound, childScene->readTransformAsMatrix( time ) ) ); } } return bounds; }
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( path ); if( !s ) { return Box3f(); } Box3d b = s->readBound( context->getFrame() / g_frameRate ); if( b.isEmpty() ) { return Box3f(); } return Box3f( b.min, b.max ); }
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { std::string fileName = fileNamePlug()->getValue(); if( !fileName.size() ) { return Box3f(); } ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName ); s = s->scene( path ); Box3d b = s->readBound( context->getFrame() / g_frameRate ); if( b.isEmpty() ) { return Box3f(); } return Box3f( b.min, b.max ); }
Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstSceneInterfacePtr s = scene( path ); if( !s ) { return Box3f(); } if( s->hasBound() ) { const Box3d b = s->readBound( context->getTime() ); if( b.isEmpty() ) { return Box3f(); } return Box3f( b.min, b.max ); } else { return unionOfTransformedChildBounds( path, parent ); } }
void LinkedScene::writeAttribute( const Name &name, const Object *attribute, double time ) { if ( m_readOnly ) { throw Exception( "No write access to scene file!" ); } if ( name == linkAttribute ) { bool firstTime = !m_mainScene->hasAttribute( fileNameLinkAttribute ); if ( firstTime ) { // if it's the first time, we better check if this level already has objects, tags or children // and raise exceptions to prevent weird configurations... if ( m_mainScene->hasObject() ) { throw Exception( "Links to external scenes cannot be created on locations where there's already an object saved!" ); } NameList names; m_mainScene->childNames( names ); if ( names.size() ) { throw Exception( "Links to external scenes cannot be created on locations where there are already child locations!" ); } } // we are creating a link! const CompoundData *d = runTimeCast< const CompoundData >(attribute); if ( !d ) { throw Exception( "SceneInterface:link attribute must be of type CompoundData!" ); } // open the linked scene int linkDepth; ConstDoubleDataPtr timeData = d->member< const DoubleData >( g_time ); const StringData *fileName = d->member< const StringData >( g_fileName ); const InternedStringVectorData *sceneRoot = d->member< const InternedStringVectorData >( g_root ); ConstSceneInterfacePtr linkedScene = expandLink( fileName, sceneRoot, linkDepth ); if ( !linkedScene ) { throw Exception( "Trying to store a broken link!" ); } // get the bounds of the linked scene const SampledSceneInterface *sampledScene = runTimeCast< const SampledSceneInterface >(linkedScene.get()); if ( sampledScene && !timeData ) { // When there's no time remapping we get all the bounding box samples from the linked scene, using the same time. if ( firstTime ) { size_t bounds = sampledScene->numBoundSamples(); for ( size_t b = 0; b < bounds; b++ ) { m_mainScene->writeBound( sampledScene->readBoundAtSample(b), sampledScene->boundSampleTime(b) ); } } } else { /// we store just the current bounding box if ( timeData ) { m_mainScene->writeBound( linkedScene->readBound(timeData->readable()), time ); } else { m_mainScene->writeBound( linkedScene->readBound(time), time ); } } if ( firstTime ) { // save the tags from the linked file to the current location so it gets propagated to the root. NameList tags; // Check if the position of the file we are trying to link to, has ancestor tags. // This situation is undesirable, as it will make LinkedScene return inconsistent ancestor tags before and after the link location. linkedScene->readTags(tags, SceneInterface::AncestorTag ); if ( tags.size() ) { std::string pathStr; SceneInterface::pathToString( sceneRoot->readable(), pathStr ); msg( Msg::Warning, "LinkedScene::writeAttribute", ( boost::format( "Detected ancestor tags while creating link to file %s at location %s." ) % fileName->readable() % pathStr ).str() ); } tags.clear(); /// copy all descendent and local tags as descendent tags (so we can distinguish from tags added in the LinkedScene) linkedScene->readTags(tags, SceneInterface::LocalTag|SceneInterface::DescendantTag ); static_cast< SceneCache *>(m_mainScene.get())->writeTags(tags, true); m_mainScene->writeAttribute( fileNameLinkAttribute, d->member< const StringData >( g_fileName ), time ); m_mainScene->writeAttribute( rootLinkAttribute, d->member< const InternedStringVectorData >( g_root ), time ); } /// we keep the information this level has a link, so we can prevent attempts to /// create children or save objects at this level. m_atLink = true; if( timeData ) { m_mainScene->writeAttribute( timeLinkAttribute, timeData, time ); } return; } m_mainScene->writeAttribute(name,attribute,time); }