Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
10.7.x.x (relative to 10.7.0.0)
========

Improvements
------------

- PathMatcher : Added `in()` and `containing()` methods.

10.7.0.0
========
Expand Down
6 changes: 6 additions & 0 deletions include/IECore/PathMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ class IECORE_API PathMatcher

/// Returns a PathMatcher for objects matching both this and the given PathMatcher
PathMatcher intersection( const PathMatcher &paths ) const;
/// Returns a PathMatcher with only the paths in this PathMatcher that match or are
/// descendants of paths in the given PathMatcher.
PathMatcher in( const PathMatcher &paths ) const;
/// Returns a PathMatcher with only the paths in this PathMatcher that match or are
/// ancestors of paths in the given PathMatcher.
PathMatcher containing( const PathMatcher &paths ) const;

/// Removes the specified path and all descendant paths.
/// Returns true if something was removed, false otherwise.
Expand Down
29 changes: 29 additions & 0 deletions src/IECore/PathMatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,35 @@ PathMatcher PathMatcher::intersection( const PathMatcher &paths ) const
return result;
}

PathMatcher PathMatcher::in( const PathMatcher &paths ) const
{
PathMatcher result = PathMatcher();
for( Iterator it = paths.begin(); it != paths.end(); ++it )
{
result.addPaths( (*this).subTree( *it ), *it );
it.prune();
}
return result;
}

PathMatcher PathMatcher::containing( const PathMatcher &paths ) const
{
PathMatcher result = PathMatcher();
for( Iterator it = (*this).begin(); it != (*this).end(); ++it )
{
RawIterator rit = paths.find( *it );
if( rit == paths.end() )
{
it.prune();
}
else
{
result.addPath( *it );
}
}
return result;
}

bool PathMatcher::prune( const std::string &path )
{
if( path.empty() )
Expand Down
2 changes: 2 additions & 0 deletions src/IECorePython/PathMatcherBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ void IECorePython::bindPathMatcher()
.def( "addPaths", (bool (PathMatcher::*)( const PathMatcher &, const std::vector<IECore::InternedString> & ))&PathMatcher::addPaths )
.def( "removePaths", &PathMatcher::removePaths )
.def( "intersection", (PathMatcher ( PathMatcher::*)( const PathMatcher & ) const)&PathMatcher::intersection )
.def( "in_", (PathMatcher ( PathMatcher::*)( const PathMatcher & ) const)&PathMatcher::in )
.def( "containing", (PathMatcher ( PathMatcher::*)( const PathMatcher & ) const)&PathMatcher::containing )
.def( "prune", (bool (PathMatcher::*)( const std::vector<IECore::InternedString> & ))&PathMatcher::prune )
.def( "prune", (bool (PathMatcher::*)( const std::string & ))&PathMatcher::prune )
.def( "subTree", (PathMatcher ( PathMatcher::*)( const std::vector<IECore::InternedString> & ) const)&PathMatcher::subTree )
Expand Down
46 changes: 46 additions & 0 deletions test/IECore/PathMatcherTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,52 @@ def testIntersection( self ) :

self.assertEqual( m3.paths(), [ "/a/b/c/d/myTest" ] )

def testIn( self ) :

m1 = IECore.PathMatcher( [ "/a/b/c/d/myTest", "/a/b/c/myTest", "/a/b/c", "/a/b/c/d", "/a/b/d" ] )
m2 = IECore.PathMatcher( [ "/a/b/c/d" ] )

self.assertEqual( m1.in_( m2 ), IECore.PathMatcher( [ "/a/b/c/d/myTest", "/a/b/c/d" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/c" ] )
self.assertEqual( m1.in_( m2 ), IECore.PathMatcher( [ "/a/b/c/d/myTest", "/a/b/c/myTest", "/a/b/c", "/a/b/c/d" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/d" ] )
self.assertEqual( m1.in_( m2 ), IECore.PathMatcher( [ "/a/b/d" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/e" ] )
self.assertEqual( m1.in_( m2 ), IECore.PathMatcher() )

m2 = IECore.PathMatcher( [ "/a" ] )
self.assertEqual( m1.in_( m2 ), m1 )

self.assertEqual( m1.in_( m1 ), m1 )

self.assertEqual( m1.in_( IECore.PathMatcher() ), IECore.PathMatcher() )

def testContaining( self ) :

m1 = IECore.PathMatcher( [ "/a/b/c/d/myTest", "/a/b/c/myTest", "/a/b/c", "/a/b/d" ] )
m2 = IECore.PathMatcher( [ "/a/b/c/d/myTest" ] )

self.assertEqual( m1.containing( m2 ), IECore.PathMatcher( [ "/a/b/c", "/a/b/c/d/myTest" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/c/d" ] )
self.assertEqual( m1.containing( m2 ), IECore.PathMatcher( [ "/a/b/c" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/d" ] )
self.assertEqual( m1.containing( m2 ), IECore.PathMatcher( [ "/a/b/d" ] ) )

m2 = IECore.PathMatcher( [ "/a/b/e" ] )
self.assertEqual( m1.containing( m2 ), IECore.PathMatcher() )

m2 = IECore.PathMatcher( [ "/a" ] )
self.assertEqual( m1.containing( m2 ), IECore.PathMatcher() )

self.assertEqual( m1.containing( m1 ), m1 )

self.assertEqual( m1.containing( IECore.PathMatcher() ), IECore.PathMatcher() )

def testSize( self ) :

m = IECore.PathMatcher()
Expand Down
Loading