Skip to content

Commit

Permalink
FIX : Instancer
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldresser-ie committed Nov 1, 2024
1 parent 3c6f80c commit 38a4b77
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
11 changes: 9 additions & 2 deletions python/GafferSceneTest/InstancerTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,12 +734,16 @@ def testInactiveIds( self ) :
)
points["inactiveIdsTest64"] = IECoreScene.PrimitiveVariable(
IECoreScene.PrimitiveVariable.Interpolation.Constant,
IECore.IntVectorData( [ 4, 6 ] )
IECore.Int64VectorData( [ 4, 6 ] )
)
points["inactive"] = IECoreScene.PrimitiveVariable(
IECoreScene.PrimitiveVariable.Interpolation.Vertex,
IECore.BoolVectorData( [ 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 ] )
)
points["inactiveInt"] = IECoreScene.PrimitiveVariable(
IECoreScene.PrimitiveVariable.Interpolation.Vertex,
IECore.IntVectorData( [ 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 ] )
)
points["badInactive"] = IECoreScene.PrimitiveVariable(
IECoreScene.PrimitiveVariable.Interpolation.Constant,
IECore.IntVectorData( [ 13 ] )
Expand All @@ -762,7 +766,7 @@ def testInactiveIds( self ) :
instancer["prototypes"].setInput( sphere["out"] )
instancer["filter"].setInput( pointsFilter["out"] )

self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ "%i" % i for i in range( 10 ) ] ) )
self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ str( i ) for i in range( 10 ) ] ) )

instancer["inactiveIds"].setValue( "inactiveIdsTest" )
self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ "0", "1", "2", "4", "6", "8", "9" ] ) )
Expand All @@ -773,6 +777,9 @@ def testInactiveIds( self ) :
instancer["inactiveIds"].setValue( "inactive" )
self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ "0", "1", "3", "4", "7" ] ) )

instancer["inactiveIds"].setValue( "inactiveInt" )
self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ "0", "1", "3", "4", "7" ] ) )

instancer["inactiveIds"].setValue( "inactiveIdsTest inactiveIdsTest64" )
self.assertEqual( instancer["out"].childNames( "/object/instances/sphere" ), IECore.InternedStringVectorData( [ "0", "1", "2", "8", "9" ] ) )

Expand Down
3 changes: 3 additions & 0 deletions python/GafferSceneUI/InstancerUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,9 @@ def __init__( self, headings, toolTipOverride = "" ) :
will deactivate the instance for the corresponding vertex if the value is true.
""",

# This user default will pick up any of the standard USD ways of controlling this.
"userDefault", "inactiveIds invisibleIds",

"layout:section", "Settings.Inactive Ids",

],
Expand Down
38 changes: 28 additions & 10 deletions src/GafferScene/Instancer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,13 +495,14 @@ class Instancer::EngineData : public Data
const PrimitiveVariable *vertexInactiveVar = findVertexVariable( m_primitive.get(), inactiveIdVarName );
if( vertexInactiveVar )
{
if( IECore::size( vertexInactiveVar->data.get() ) != numPoints() )
{
throw IECore::Exception( fmt::format( "Inactive primitive variable \"{}\" has incorrect size", inactiveIdVarName ) );
}

if( const auto *vertexInactiveData = IECore::runTimeCast<BoolVectorData>( vertexInactiveVar->data.get() ) )
{
const std::vector<bool> &vertexInactive = vertexInactiveData->readable();
if( vertexInactive.size() != numPoints() )
{
throw IECore::Exception( fmt::format( "Inactive primitive variable \"{}\" has incorrect size", inactiveIdVarName ) );
}

if( !m_indicesInactive.size() )
{
Expand All @@ -515,17 +516,34 @@ class Instancer::EngineData : public Data
}
else
{
for( unsigned int i = 0; i < vertexInactive.size(); i++ )
for( size_t i = 0; i < vertexInactive.size(); i++ )
{
if( vertexInactive[i] )
{
m_indicesInactive[ i ] = true;
}
}
}
}
else if( const auto *vertexInactiveIntData = IECore::runTimeCast<IntVectorData>( vertexInactiveVar->data.get() ) )
{
const std::vector<int> &vertexInactiveInt = vertexInactiveIntData->readable();

continue;
if( !m_indicesInactive.size() )
{
m_indicesInactive.resize( numPoints(), false );
}

for( size_t i = 0; i < vertexInactiveInt.size(); i++ )
{
if( vertexInactiveInt[i] )
{
m_indicesInactive[ i ] = true;
}
}
}

continue;
}

IdData idData;
Expand Down Expand Up @@ -639,9 +657,9 @@ class Instancer::EngineData : public Data

if( m_indicesInactive.size() )
{
// If there are duplicates in the id list, then some point indices will be omitted - we
// need to check each point index to see if it got assigned an id correctly // TODO

// If this point is tagged as inactive ( could be due to a user specified inactiveIds,
// or due to an id collision when omitDuplicateIds is set ), then we return -1 for
// the prototype, which means to omit this point.
if( m_indicesInactive[pointIndex] )
{
return -1;
Expand Down Expand Up @@ -1352,7 +1370,7 @@ Instancer::Instancer( const std::string &name )
addChild( new StringPlug( "position", Plug::In, "P" ) );
addChild( new StringPlug( "orientation", Plug::In ) );
addChild( new StringPlug( "scale", Plug::In ) );
addChild( new StringPlug( "inactiveIds", Plug::In, "inactiveIds invisibleIds" ) );
addChild( new StringPlug( "inactiveIds", Plug::In, "" ) );
addChild( new StringPlug( "attributes", Plug::In ) );
addChild( new StringPlug( "attributePrefix", Plug::In ) );
addChild( new BoolPlug( "encapsulate", Plug::In ) );
Expand Down

0 comments on commit 38a4b77

Please sign in to comment.