GafferScene::ConstPathMatcherDataPtr Set::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { const std::string allSets = " " + namePlug()->getValue() + " "; const std::string setNameToFind = " " + setName.string() + " "; if( allSets.find( setNameToFind ) == std::string::npos ) { return inPlug()->setPlug()->getValue(); } ConstPathMatcherDataPtr pathMatcher = pathMatcherPlug()->getValue(); switch( modePlug()->getValue() ) { case Add : { ConstPathMatcherDataPtr inputSet = inPlug()->setPlug()->getValue(); if( !inputSet->readable().isEmpty() ) { PathMatcherDataPtr result = inputSet->copy(); result->writable().addPaths( pathMatcher->readable() ); return result; } // Input set empty - fall through to create mode. } case Create : { return pathMatcher; } case Remove : default : { ConstPathMatcherDataPtr inputSet = inPlug()->setPlug()->getValue(); if( inputSet->readable().isEmpty() ) { return inputSet; } PathMatcherDataPtr result = inputSet->copy(); result->writable().removePaths( pathMatcher->readable() ); return result; } } }
GafferScene::ConstPathMatcherDataPtr BranchCreator::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstPathMatcherDataPtr inputSetData = inPlug()->set( setName ); ConstCompoundDataPtr mapping = boost::static_pointer_cast<const CompoundData>( mappingPlug()->getValue() ); if( !mapping->readable().size() ) { return inputSetData; } ScenePlug::ScenePath parentPath = mapping->member<InternedStringVectorData>( g_parentKey )->readable(); ConstPathMatcherDataPtr branchSetData = computeBranchSet( parentPath, setName, context ); if( !branchSetData ) { return inputSetData; } const PathMatcher &branchSet = branchSetData->readable(); if( branchSet.isEmpty() ) { return inputSetData; } const CompoundData *forwardMapping = mapping->member<CompoundData>( g_forwardMappingKey ); PathMatcherDataPtr outputSetData = inputSetData->copy(); PathMatcher &outputSet = outputSetData->writable(); vector<InternedString> outputPrefix( parentPath ); for( PathMatcher::RawIterator pIt = branchSet.begin(), peIt = branchSet.end(); pIt != peIt; ++pIt ) { const ScenePlug::ScenePath &branchPath = *pIt; if( !branchPath.size() ) { continue; // Skip root } assert( branchPath.size() == 1 ); const InternedStringData *outputName = forwardMapping->member<InternedStringData>( branchPath[0], /* throwExceptions = */ true ); outputPrefix.resize( parentPath.size() + 1 ); outputPrefix.back() = outputName->readable(); outputSet.addPaths( branchSet.subTree( *pIt ), outputPrefix ); pIt.prune(); // We only want to visit the first level } return outputSetData; }
GafferScene::ConstPathMatcherDataPtr Prune::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstPathMatcherDataPtr inputSetData = inPlug()->setPlug()->getValue(); const PathMatcher &inputSet = inputSetData->readable(); if( inputSet.isEmpty() ) { return inputSetData; } PathMatcherDataPtr outputSetData = inputSetData->copy(); PathMatcher &outputSet = outputSetData->writable(); FilterPlug::SceneScope sceneScope( context, inPlug() ); for( PathMatcher::RawIterator pIt = inputSet.begin(), peIt = inputSet.end(); pIt != peIt; ) { sceneScope.set( ScenePlug::scenePathContextName, *pIt ); const int m = filterPlug()->getValue(); if( m & ( Filter::ExactMatch | Filter::AncestorMatch ) ) { // This path and all below it are pruned, so we can // ignore it and prune the traversal to the descendant // paths. outputSet.prune( *pIt ); pIt.prune(); ++pIt; } else if( m & Filter::DescendantMatch ) { // This path isn't pruned, so we continue our traversal // as normal to find out which descendants _are_ pruned. ++pIt; } else { // This path isn't pruned, and neither is anything // below it. We can avoid retesting the filter for // all descendant paths, since we know they're not // pruned. assert( m == Filter::NoMatch ); pIt.prune(); ++pIt; } } return outputSetData; }
GafferScene::ConstPathMatcherDataPtr Isolate::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstPathMatcherDataPtr inputSetData = inPlug()->setPlug()->getValue(); if( ( setName == g_lightsSetName && keepLightsPlug()->getValue() ) || ( setName == g_camerasSetName && keepCamerasPlug()->getValue() ) ) { return inputSetData; } const PathMatcher &inputSet = inputSetData->readable(); if( inputSet.isEmpty() ) { return inputSetData; } PathMatcherDataPtr outputSetData = inputSetData->copy(); PathMatcher &outputSet = outputSetData->writable(); FilterPlug::SceneScope sceneScope( context, inPlug() ); const std::string fromString = fromPlug()->getValue(); ScenePlug::ScenePath fromPath; ScenePlug::stringToPath( fromString, fromPath ); const SetsToKeep setsToKeep( this ); for( PathMatcher::RawIterator pIt = inputSet.begin(), peIt = inputSet.end(); pIt != peIt; ) { sceneScope.set( ScenePlug::scenePathContextName, *pIt ); const int m = filterPlug()->getValue() || setsToKeep.match( *pIt ); if( m & ( Filter::ExactMatch | Filter::AncestorMatch ) ) { // We want to keep everything below this point, so // can just prune our iteration. pIt.prune(); ++pIt; } else if( m & Filter::DescendantMatch ) { // We might be removing things below here, // so just continue our iteration normally // so we can find out. ++pIt; } else { assert( m == Filter::NoMatch ); if( boost::starts_with( *pIt, fromPath ) ) { // Not going to keep anything below // here, so we can prune traversal // entirely. outputSet.prune( *pIt ); pIt.prune(); } ++pIt; } } return outputSetData; }