Skip to content

Commit

Permalink
Added a UnionFilter node to GafferScene.
Browse files Browse the repository at this point in the history
Also moved the bindings for all filters into a separate file to further improve GafferSceneModule.cpp compilation times.

Fixes GafferHQ#594.
  • Loading branch information
johnhaddon committed Nov 5, 2013
1 parent bca54f8 commit 9bbcf3d
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 15 deletions.
1 change: 1 addition & 0 deletions include/GafferScene/TypeIds.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ enum TypeId
IsolateTypeId = 110559,
AttributeProcessorTypeId = 110560,
DeleteAttributesTypeId = 110561,
UnionFilterTypeId = 110562,

LastTypeId = 110650
};
Expand Down
81 changes: 81 additions & 0 deletions include/GafferScene/UnionFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above
// copyright notice, this list of conditions and the following
// disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided with
// the distribution.
//
// * Neither the name of John Haddon nor the names of
// any other contributors to this software may be used to endorse or
// promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#ifndef GAFFERSCENE_UNIONFILTER_H
#define GAFFERSCENE_UNIONFILTER_H

#include "GafferScene/Filter.h"

namespace Gaffer
{

IE_CORE_FORWARDDECLARE( ArrayPlug )

} // namespace Gaffer

namespace GafferScene
{

/// \todo Investigate whether or not caching is actually beneficial for this node
class UnionFilter : public Filter
{

public :

IE_CORE_DECLARERUNTIMETYPEDEXTENSION( GafferScene::UnionFilter, UnionFilterTypeId, Filter );

UnionFilter( const std::string &name=defaultName<UnionFilter>() );
virtual ~UnionFilter();

Gaffer::ArrayPlug *inPlug();
const Gaffer::ArrayPlug *inPlug() const;

virtual void affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const;

protected :

virtual bool acceptsInput( const Gaffer::Plug *plug, const Gaffer::Plug *inputPlug ) const;

virtual void hashMatch( const Gaffer::Context *context, IECore::MurmurHash &h ) const;
virtual unsigned computeMatch( const Gaffer::Context *context ) const;

static size_t g_firstPlugIndex;

};

} // namespace GafferScene

#endif // GAFFERSCENE_UNIONFILTER_H
47 changes: 47 additions & 0 deletions include/GafferSceneBindings/FilterBinding.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above
// copyright notice, this list of conditions and the following
// disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided with
// the distribution.
//
// * Neither the name of John Haddon nor the names of
// any other contributors to this software may be used to endorse or
// promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#ifndef GAFFERSCENEBINDINGS_FILTERBINDING_H
#define GAFFERSCENEBINDINGS_FILTERBINDING_H

namespace GafferSceneBindings
{

void bindFilter();

} // namespace GafferSceneBindings

#endif // GAFFERSCENEBINDINGS_FILTERBINDING_H
132 changes: 132 additions & 0 deletions python/GafferSceneTest/UnionFilterTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
##########################################################################
#
# Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided with
# the distribution.
#
# * Neither the name of John Haddon nor the names of
# any other contributors to this software may be used to endorse or
# promote products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import unittest

import IECore

import Gaffer
import GafferTest
import GafferScene
import GafferSceneTest

class UnionFilterTest( GafferSceneTest.SceneTestCase ) :

def test( self ) :

f1 = GafferScene.PathFilter()
f1["paths"].setValue( IECore.StringVectorData( [
"/a/b/c",
] ) )

f2 = GafferScene.PathFilter()
f2["paths"].setValue( IECore.StringVectorData( [
"/a/b/c/e/f/g",
] ) )

u = GafferScene.UnionFilter()
self.assertEqual( u["match"].getValue(), GafferScene.Filter.Result.NoMatch )

h1 = u["match"].hash()

u["in"][0].setInput( f1["match"] )
h2 = u["match"].hash()
self.assertNotEqual( h1, h2 )

for path in [
"/a",
"/b",
"/a/b",
"/a/b/c",
"/a/b/c/d",
] :
with Gaffer.Context() as c :
c["scene:path"] = IECore.InternedStringVectorData( path[1:].split( "/" ) )
self.assertEqual( u["match"].getValue(), f1["match"].getValue() )

u["in"][1].setInput( f2["match"] )
h3 = u["match"].hash()
self.assertNotEqual( h2, h3 )

for path, result in [
( "/a", u.Result.DescendantMatch ),
( "/b", u.Result.NoMatch ),
( "/a/b", u.Result.DescendantMatch ),
( "/a/b/c", u.Result.DescendantMatch | u.Result.ExactMatch ),
( "/a/b/c/d", u.Result.AncestorMatch ),
( "/a/b/c/e", u.Result.AncestorMatch | u.Result.DescendantMatch ),
( "/a/b/c/e/f/g", u.Result.AncestorMatch | u.Result.ExactMatch ),
( "/a/b/c/e/f/g/h", u.Result.AncestorMatch ),
] :
with Gaffer.Context() as c :
c["scene:path"] = IECore.InternedStringVectorData( path[1:].split( "/" ) )
self.assertEqual( u["match"].getValue(), int( result ) )

f2["paths"].setValue( IECore.StringVectorData( [
"/a/b",
] ) )

h4 = u["match"].hash()
self.assertNotEqual( h3, h4 )

def testDirtiedSignal( self ) :

u = GafferScene.UnionFilter( "u" )
f1 = GafferScene.PathFilter( "f" )

cs = GafferTest.CapturingSlot( u.plugDirtiedSignal() )

u["in"][0].setInput( f1["match"] )

self.assertEqual( [ x[0].fullName() for x in cs if x[0].direction() == x[0].Direction.Out ], [ "u.match" ] )

del cs[:]

f1["paths"].setValue( IECore.StringVectorData( [ "/a" ] ) )

self.assertEqual( [ x[0].fullName() for x in cs if x[0].direction() == x[0].Direction.Out ], [ "u.match" ] )

def testAcceptsInput( self ) :

f = GafferScene.PathFilter()
n = Gaffer.Node()
n["match"] = f["match"].createCounterpart( "match", Gaffer.Plug.Direction.Out )

u = GafferScene.UnionFilter()
self.assertFalse( u["in"][0].acceptsInput( n["match"] ) )

if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions python/GafferSceneTest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
from SceneReaderTest import SceneReaderTest
from IsolateTest import IsolateTest
from DeleteAttributesTest import DeleteAttributesTest
from UnionFilterTest import UnionFilterTest

if __name__ == "__main__":
import unittest
Expand Down
14 changes: 14 additions & 0 deletions python/GafferSceneUI/SceneNodeUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,17 @@ def __pathsPlugWidgetCreator( plug ) :
"paths",
__pathsPlugWidgetCreator,
)

# UnionFilter

GafferUI.PlugValueWidget.registerCreator(
GafferScene.UnionFilter.staticTypeId(),
"in",
None,
)

GafferUI.Nodule.registerNodule(
GafferScene.UnionFilter.staticTypeId(),
"in",
GafferUI.CompoundNodule
)
Loading

0 comments on commit 9bbcf3d

Please sign in to comment.