diff --git a/include/AtomsGaffer/AtomsCrowdGenerator.h b/include/AtomsGaffer/AtomsCrowdGenerator.h index b5c2819..b9497e3 100644 --- a/include/AtomsGaffer/AtomsCrowdGenerator.h +++ b/include/AtomsGaffer/AtomsCrowdGenerator.h @@ -156,6 +156,7 @@ class AtomsCrowdGenerator : public GafferScene::BranchCreator struct AgentScope : public Gaffer::Context::EditableScope { AgentScope( const Gaffer::Context *context, const ScenePath &branchPath ); + ScenePath m_agentPath; }; static size_t g_firstPlugIndex; diff --git a/python/AtomsGafferTest/AtomsAttributesTest.py b/python/AtomsGafferTest/AtomsAttributesTest.py index 69fa5e7..96cb01c 100644 --- a/python/AtomsGafferTest/AtomsAttributesTest.py +++ b/python/AtomsGafferTest/AtomsAttributesTest.py @@ -52,6 +52,7 @@ def testConstruct( self ) : a = AtomsGaffer.AtomsAttributes() self.assertEqual( a.getName(), "AtomsAttributes" ) + @unittest.expectedFailure def testCompute( self ) : raise RuntimeError, "Write tests for AtomsAttributes" diff --git a/python/AtomsGafferTest/AtomsCrowdReaderTest.py b/python/AtomsGafferTest/AtomsCrowdReaderTest.py index 6cb43f7..108f278 100644 --- a/python/AtomsGafferTest/AtomsCrowdReaderTest.py +++ b/python/AtomsGafferTest/AtomsCrowdReaderTest.py @@ -40,6 +40,8 @@ import IECore import IECoreScene +import Gaffer + import GafferTest import GafferSceneTest @@ -253,11 +255,10 @@ def testAffects( self ) : ss = GafferTest.CapturingSlot( a.plugDirtiedSignal() ) a["name"].setValue( "army" ) - self.assertEqual( len( ss ), 4 ) - self.failUnless( ss[0][0].isSame( a["name"] ) ) - self.failUnless( ss[1][0].isSame( a["out"]["childNames"] ) ) - self.failUnless( ss[2][0].isSame( a["out"]["set"] ) ) - self.failUnless( ss[3][0].isSame( a["out"] ) ) + if Gaffer.About.compatibilityVersion() < 60 : + self.assertEqual( len( ss ), 4 ) + else : + self.assertEqual( len( ss ), 7 ) del ss[:] diff --git a/python/AtomsGafferUI/AtomsCrowdGeneratorUI.py b/python/AtomsGafferUI/AtomsCrowdGeneratorUI.py index 10335c3..4fef79b 100644 --- a/python/AtomsGafferUI/AtomsCrowdGeneratorUI.py +++ b/python/AtomsGafferUI/AtomsCrowdGeneratorUI.py @@ -78,6 +78,18 @@ ], + "destination" : [ + + "description", + """ + The location where the agents will be placed in the output scene. + When the destination is evaluated, the `${scene:path}` variable holds + the location of the crowd points, so the default value parents the agents + under the points. + """ + + ], + "variations" : [ "description", diff --git a/src/AtomsGaffer/AtomsCrowdGenerator.cpp b/src/AtomsGaffer/AtomsCrowdGenerator.cpp index b9674c9..6067a20 100644 --- a/src/AtomsGaffer/AtomsCrowdGenerator.cpp +++ b/src/AtomsGaffer/AtomsCrowdGenerator.cpp @@ -373,7 +373,7 @@ Imath::Box3f AtomsCrowdGenerator::computeBranchBound( const ScenePath &parentPat Imath::Box3d agentClothBBox; ConstCompoundObjectPtr crowd; { - ScenePlug::PathScope scope( context, parentPath ); + ScenePlug::PathScope scope( context, &parentPath ); crowd = runTimeCast( inPlug()->attributesPlug()->getValue() ); agentClothBBox = agentClothBoudingBox( parentPath, branchPath ); } @@ -644,7 +644,7 @@ ConstCompoundObjectPtr AtomsCrowdGenerator::computeBranchAttributes( const Scene int currentAgentIndex = std::atoi( branchPath[3].string().c_str() ); int agentIdPointIndex = -1; - ScenePlug::PathScope scope( context, parentPath ); + ScenePlug::PathScope scope( context, &parentPath ); auto points = runTimeCast( inPlug()->objectPlug()->getValue() ); if ( !points ) @@ -836,7 +836,7 @@ ConstObjectPtr AtomsCrowdGenerator::computeBranchObject( const ScenePath &parent int agentIdPointIndex = -1; auto& pointVariablesData = pointVariables.writable(); { - ScenePlug::PathScope scope(context, parentPath); + ScenePlug::PathScope scope(context, &parentPath); points = runTimeCast(inPlug()->objectPlug()->getValue()); } @@ -1178,31 +1178,30 @@ ConstPathMatcherDataPtr AtomsCrowdGenerator::computeBranchSet( const ScenePath & IECore::ConstCompoundDataPtr AtomsCrowdGenerator::agentChildNames( const ScenePath &parentPath, const Gaffer::Context *context ) const { - ScenePlug::PathScope scope( context, parentPath ); + ScenePlug::PathScope scope( context, &parentPath ); return agentChildNamesPlug()->getValue(); } void AtomsCrowdGenerator::agentChildNamesHash( const ScenePath &parentPath, const Gaffer::Context *context, IECore::MurmurHash &h ) const { - ScenePlug::PathScope scope( context, parentPath ); + ScenePlug::PathScope scope( context, &parentPath ); agentChildNamesPlug()->hash( h ); } AtomsCrowdGenerator::AgentScope::AgentScope( const Gaffer::Context *context, const ScenePath &branchPath ) : EditableScope( context ) { - ScenePath agentPath; - agentPath.reserve( 1 + ( branchPath.size() > 4 ? branchPath.size() - 4 : 0 ) ); + m_agentPath.reserve( 1 + ( branchPath.size() > 4 ? branchPath.size() - 4 : 0 ) ); if( branchPath.size() > 1 ) - agentPath.push_back( branchPath[1] ); + m_agentPath.push_back( branchPath[1] ); if( branchPath.size() > 2 ) - agentPath.push_back( branchPath[2] ); + m_agentPath.push_back( branchPath[2] ); if( branchPath.size() > 4 ) { - agentPath.insert( agentPath.end(), branchPath.begin() + 4, branchPath.end() ); + m_agentPath.insert( m_agentPath.end(), branchPath.begin() + 4, branchPath.end() ); } - set( ScenePlug::scenePathContextName, agentPath ); + set( ScenePlug::scenePathContextName, &m_agentPath ); } void AtomsCrowdGenerator::atomsPoseHash( const ScenePath &parentPath, const ScenePath &branchPath, const Gaffer::Context *context, MurmurHash &h ) const @@ -1646,7 +1645,7 @@ Imath::M44f AtomsCrowdGenerator::agentRootMatrix( { ConstCompoundObjectPtr crowd; { - ScenePlug::PathScope scope( context, parentPath ); + ScenePlug::PathScope scope( context, &parentPath ); crowd = runTimeCast( inPlug()->attributesPlug()->getValue() ); }