Example #1
0
unsigned SetFilter::computeMatch( const ScenePlug *scene, const Gaffer::Context *context ) const
{
	if( !scene )
	{
		return NoMatch;
	}

	const ScenePlug::ScenePath &path = context->get<ScenePlug::ScenePath>( ScenePlug::scenePathContextName );

	// See explanatory comments in hashMatch().
	ContextPtr tmpContext = new Context( *context, Context::Borrowed );
	tmpContext->remove( Filter::inputSceneContextName );
	tmpContext->remove( ScenePlug::scenePathContextName );
	Context::Scope scopedContext( tmpContext.get() );

	ConstPathMatcherDataPtr set = scene->set( setPlug()->getValue() );

	return set->readable().match( path );
}
Example #2
0
void SetFilter::hashMatch( const ScenePlug *scene, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	if( !scene )
	{
		return;
	}

	/// \todo It would be preferable to throw an exception if the scene path isn't
	/// available, as we really do require it for computing a match. Currently we
	/// can't do that because the Isolate and Prune must include the filter hash when
	/// hashing their sets, because they will use the filter to remap the sets as
	/// a global operation. In this case, we're lucky that the hash (minus the scene path)
	/// of the SetFilter is sufficient to uniquely identify the remapping that will occur - filters
	/// which access scene data using the path would not have a valid hash in this scenario,
	/// which is the reason we don't yet have AttributeFilter etc. If we had a hierarchyHash for
	/// the scene then we would be able to use that in these situations and have a broader range
	/// of filters. If we manage that, then we should go back to throwing an exception here if
	/// the context doesn't contain a path. We should then do the same in the PathFilter.
	typedef IECore::TypedData<ScenePlug::ScenePath> ScenePathData;
	const ScenePathData *pathData = context->get<ScenePathData>( ScenePlug::scenePathContextName, 0 );
	if( pathData )
	{
		const ScenePlug::ScenePath &path = pathData->readable();
		h.append( &(path[0]), path.size() );
	}

	// Remove unnecessary but frequently changed context entries. This
	// makes us friendlier to the hash caching mechanism in ValuePlug,
	// since it'll see fewer unnecessarily different contexts, and will
	// therefore get more cache hits. We do the same in computeMatch().
	ContextPtr tmpContext = new Context( *context, Context::Borrowed );
	tmpContext->remove( Filter::inputSceneContextName );
	tmpContext->remove( ScenePlug::scenePathContextName );
	Context::Scope scopedContext( tmpContext.get() );

	h.append( scene->setHash( setPlug()->getValue() ) );
}
Example #3
0
void Isolate::hashSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const
{
	FilteredSceneProcessor::hashSet( setName, context, parent, h );
	inPlug()->setPlug()->hash( h );
	fromPlug()->hash( h );

	// The sets themselves do not depend on the "scene:path"
	// context entry - the whole point is that they're global.
	// However, the PathFilter is dependent on scene:path, so
	// we must remove the path before hashing in the filter in
	// case we're computed from multiple contexts with different
	// paths (from a SetFilter for instance). If we didn't do this,
	// our different hashes would lead to huge numbers of redundant
	// calls to computeSet() and a huge overhead in recomputing
	// the same sets repeatedly.
	//
	// See further comments in FilteredSceneProcessor::affects().
	ContextPtr c = filterContext( context );
	c->remove( ScenePlug::scenePathContextName );
	Context::Scope s( c.get() );
	filterPlug()->hash( h );
}