Example #1
0
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;
}
Example #2
0
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 );
}
Example #3
0
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 );
}
Example #4
0
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 );
	}
}
Example #5
0
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);
}