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
1 change: 1 addition & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Improvements
- OSLShader :
- Improved loading of spline parameters with additional duplicate endpoints.
- Added support for loading splines from RenderMan shaders.
- Rendering : Improved detection of static objects. This fixes messages from Arnold like "discarded X duplicate deformation keys", and may improve performance in some cases.

Fixes
-----
Expand Down
36 changes: 36 additions & 0 deletions python/GafferSceneTest/RendererAlgoTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,42 @@ def testObjectSamples( self ) :

self.assertEqual( [ s.radius() for s in samples ], [ 0.75, 1.25 ] )

def testObjectSamplesMatchingHash( self ) :

# If the input object has a hash that doesn't vary with time, then we just get one sample when
# we try to sample over time.
sphere = GafferScene.Sphere()
sphere["type"].setValue( sphere.Type.Primitive )

with Gaffer.Context() as c :
c["scene:path"] = IECore.InternedStringVectorData( [ "sphere" ] )
samples = GafferScene.Private.RendererAlgo.objectSamples( sphere["out"]["object"], [ 0.75, 1.25 ] )

self.assertEqual( [ s.radius() for s in samples ], [ 1.0 ] )

def testObjectSamplesMatchingResult( self ) :

# If the input object has different hashes at different times, but still produces identical objects,
# then we should still only output one sample.

frame = GafferTest.FrameNode()

# Quick hack to produce a value that doesn't vary, but has a hash that does: feed the frame
# through an integer multiply node, which will truncate the value to an integer
multiply = GafferTest.MultiplyNode()
multiply["op1"].setValue( 1 )
multiply["op2"].setInput( frame["output"] )

sphere = GafferScene.Sphere()
sphere["type"].setValue( sphere.Type.Primitive )
sphere["radius"].setInput( multiply["product"] )

with Gaffer.Context() as c :
c["scene:path"] = IECore.InternedStringVectorData( [ "sphere" ] )
samples = GafferScene.Private.RendererAlgo.objectSamples( sphere["out"]["object"], [ 1.25, 1.75 ] )

self.assertEqual( [ s.radius() for s in samples ], [ 1.0 ] )

def testNonInterpolableObjectSamples( self ) :

frame = GafferTest.FrameNode()
Expand Down
17 changes: 17 additions & 0 deletions src/GafferScene/RendererAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,9 @@ bool objectSamples( const ObjectPlug *objectPlug, const std::vector<float> &samp
const Context *frameContext = Context::current();
Context::EditableScope timeContext( frameContext );

bool actualMovement = false;
IECore::MurmurHash actualHash;

samples.reserve( sampleTimes.size() );
for( size_t i = 0; i < sampleTimes.size(); i++ )
{
Expand All @@ -568,6 +571,15 @@ bool objectSamples( const ObjectPlug *objectPlug, const std::vector<float> &samp
runTimeCast<const Camera>( object.get() )
)
{
if( i == 0 )
{
actualHash = object->hash();
}
else if( !actualMovement )
{
actualMovement = object->hash() != actualHash;
}

samples.push_back( object.get() );
}
else if(
Expand Down Expand Up @@ -608,6 +620,11 @@ bool objectSamples( const ObjectPlug *objectPlug, const std::vector<float> &samp
break;
}
}

if( !actualMovement && samples.size() > 1 )
{
samples.resize( 1 );
}
}

if( hash )
Expand Down
Loading