Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

small SceneReader/writer updates, + a branch in SceneProcedural that renders VisibleRenderables #71

Merged
merged 6 commits into from
Apr 1, 2013
Merged
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
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* SceneProcedural now renders general VisibleRenderables too...

* Added base classes Executable and Despatcher and two derived Node classes: ExecutableNode and ExecutableOpHolder.

* Added an enabled/disabled plug to all SceneNodes. Nodes with no inputs output an empty scene when disabled, and SceneProcessors output the first input unchanged. The enabled/disabled state can be toggled using the node right click menu or the "d" hotkey in the Graph Editor.
Expand Down
2 changes: 2 additions & 0 deletions include/GafferScene/SceneReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class SceneReader : public FileSource
virtual ~SceneReader();

IE_CORE_DECLARERUNTIMETYPEDEXTENSION( SceneReader, SceneReaderTypeId, FileSource )


protected :

Expand All @@ -72,6 +73,7 @@ class SceneReader : public FileSource
class Cache;
static Cache &cache();

static const double g_frameRate;
};

} // namespace GafferScene
Expand Down
3 changes: 2 additions & 1 deletion include/GafferScene/SceneWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class SceneWriter : public Gaffer::Node
void writeLocation( GafferScene::ScenePlug *scenePlug, const ScenePlug::ScenePath &scenePath, IECore::SceneInterface *output );

static size_t g_firstPlugIndex;


static const double g_frameRate;
};

} // namespace GafferScene
Expand Down
18 changes: 9 additions & 9 deletions python/GafferSceneTest/SceneReadWriteTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,18 @@ def writeAnimatedSCC( self ) :
sc3.writeObject( mesh, time )
sc3.writeTransform( IECore.M44dData(), time )

for time in [ 0.5, 1, 1.5, 2, 5, 10 ] :
for frame in [ 0.5, 1, 1.5, 2, 5, 10 ] :

matrix = IECore.M44d.createTranslated( IECore.V3d( 1, time, 0 ) )
sc1.writeTransform( IECore.M44dData( matrix ), time )
matrix = IECore.M44d.createTranslated( IECore.V3d( 1, frame, 0 ) )
sc1.writeTransform( IECore.M44dData( matrix ), float( frame ) / 24 )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little confusing - perhaps the time variable should be renamed to frame to avoid the confusion?

mesh["Cd"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Uniform, IECore.V3fVectorData( [ IECore.V3f( time, 1, 0 ) ] * 6 ) )
sc2.writeObject( mesh, time )
matrix = IECore.M44d.createTranslated( IECore.V3d( 2, time, 0 ) )
sc2.writeTransform( IECore.M44dData( matrix ), time )
mesh["Cd"] = IECore.PrimitiveVariable( IECore.PrimitiveVariable.Interpolation.Uniform, IECore.V3fVectorData( [ IECore.V3f( frame, 1, 0 ) ] * 6 ) )
sc2.writeObject( mesh, float( frame ) / 24 )
matrix = IECore.M44d.createTranslated( IECore.V3d( 2, frame, 0 ) )
sc2.writeTransform( IECore.M44dData( matrix ), float( frame ) / 24 )

matrix = IECore.M44d.createTranslated( IECore.V3d( 3, time, 0 ) )
sc3.writeTransform( IECore.M44dData( matrix ), time )
matrix = IECore.M44d.createTranslated( IECore.V3d( 3, frame, 0 ) )
sc3.writeTransform( IECore.M44dData( matrix ), float( frame ) / 24 )

def testAnimatedScene( self ) :

Expand Down
5 changes: 5 additions & 0 deletions src/GafferScene/SceneProcedural.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ void SceneProcedural::render( RendererPtr renderer ) const
}
break; // no motion blur for these chappies.
}
else if( const VisibleRenderable* renderable = runTimeCast< const VisibleRenderable >( object.get() ) )
{
renderable->render( renderer );
break; // no motion blur for these chappies.
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems totally unrelated to the rest of this pull request - in the future we should make sure we deal with individual topics separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup - looks like this was a stowaway...

}
}
Expand Down
144 changes: 38 additions & 106 deletions src/GafferScene/SceneReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
#include "IECore/FileIndexedIO.h"
#include "IECore/LRUCache.h"
#include "IECore/SceneInterface.h"
#include "IECore/SharedSceneInterfaces.h"
#include "IECore/InternedString.h"
#include "IECore/SceneCache.h"

#include "Gaffer/Context.h"
#include "GafferScene/SceneReader.h"
Expand All @@ -53,96 +55,13 @@ using namespace GafferScene;

IE_CORE_DEFINERUNTIMETYPED( SceneReader );

//////////////////////////////////////////////////////////////////////////
// SceneReader::Cache Implementation
//////////////////////////////////////////////////////////////////////////

class SceneReader::Cache
{

private :

IE_CORE_FORWARDDECLARE( FileAndMutex )

public :

Cache()
: m_fileCache( fileCacheGetter, 200 )
{
};

/// This class provides access to a particular location within
/// the SceneInterface, and ensures that access is threadsafe by holding
/// a mutex on the file.
class Entry : public IECore::RefCounted
{

public :

SceneInterface *sceneInterface()
{
return m_entry;
}

private :

Entry( FileAndMutexPtr fileAndMutex )
: m_fileAndMutex( fileAndMutex ), m_lock( m_fileAndMutex->mutex )
{
}

FileAndMutexPtr m_fileAndMutex;
tbb::mutex::scoped_lock m_lock;
SceneInterfacePtr m_entry;

friend class Cache;

};

IE_CORE_DECLAREPTR( Entry )

EntryPtr entry( const std::string &fileName, const ScenePath &scenePath )
{
FileAndMutexPtr f = m_fileCache.get( fileName );
EntryPtr result = new Entry( f ); // this locks the mutex for us
result->m_entry = result->m_fileAndMutex->file->scene( scenePath );
return result;
}

void clear()
{
m_fileCache.clear();
}

private :

class FileAndMutex : public IECore::RefCounted
{
public :

typedef tbb::mutex Mutex;
Mutex mutex;
SceneInterfacePtr file;

};

static FileAndMutexPtr fileCacheGetter( const std::string &fileName, size_t &cost )
{
FileAndMutexPtr result = new FileAndMutex;
result->file = SceneInterface::create( fileName, IndexedIO::Read );
cost = 1;
return result;
}

typedef LRUCache<std::string, FileAndMutexPtr> FileCache;
FileCache m_fileCache;

};

//////////////////////////////////////////////////////////////////////////
// SceneReader implementation
//////////////////////////////////////////////////////////////////////////

/// \todo hard coded framerate should be replaced with a getTime() method on Gaffer::Context or something
const double SceneReader::g_frameRate( 24 );

SceneReader::SceneReader( const std::string &name )
: FileSource( name )
{
Expand All @@ -161,8 +80,10 @@ Imath::Box3f SceneReader::computeBound( const ScenePath &path, const Gaffer::Con
return Box3f();
}

Cache::EntryPtr entry = cache().entry( fileName, path );
Box3d b = entry->sceneInterface()->readBound( context->getFrame() );
ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
s = s->scene( path );

Box3d b = s->readBound( context->getFrame() / g_frameRate );

if( b.isEmpty() )
{
Expand All @@ -180,8 +101,10 @@ Imath::M44f SceneReader::computeTransform( const ScenePath &path, const Gaffer::
return M44f();
}

Cache::EntryPtr entry = cache().entry( fileName, path );
M44d t = entry->sceneInterface()->readTransformAsMatrix( context->getFrame() );
ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
s = s->scene( path );

M44d t = s->readTransformAsMatrix( context->getFrame() / g_frameRate );

return M44f(
t[0][0], t[0][1], t[0][2], t[0][3],
Expand All @@ -199,16 +122,28 @@ IECore::ConstCompoundObjectPtr SceneReader::computeAttributes( const ScenePath &
return parent->attributesPlug()->defaultValue();
}

Cache::EntryPtr entry = cache().entry( fileName, path );

ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
s = s->scene( path );

SceneInterface::NameList nameList;
entry->sceneInterface()->readAttributeNames( nameList );
s->readAttributeNames( nameList );

CompoundObjectPtr result = new CompoundObject;

for( SceneInterface::NameList::iterator it = nameList.begin(); it != nameList.end(); ++it )
{
result->members()[ std::string( *it ) ] = entry->sceneInterface()->readAttribute( *it, context->getFrame() );
// these internal attributes should be ignored:
if( *it == SceneCache::animatedObjectTopologyAttribute )
{
continue;
}
if( *it == SceneCache::animatedObjectPrimVarsAttribute )
{
continue;
}

result->members()[ std::string( *it ) ] = s->readAttribute( *it, context->getFrame() / g_frameRate );
}

return result;
Expand All @@ -222,12 +157,14 @@ IECore::ConstObjectPtr SceneReader::computeObject( const ScenePath &path, const
return parent->objectPlug()->defaultValue();
}

Cache::EntryPtr entry = cache().entry( fileName, path );
ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
s = s->scene( path );

ObjectPtr o;

if( entry->sceneInterface()->hasObject() )
if( s->hasObject() )
{
ObjectPtr o = entry->sceneInterface()->readObject( context->getFrame() );
ObjectPtr o = s->readObject( context->getFrame() / g_frameRate );

return o? o : parent->objectPlug()->defaultValue();
}
Expand All @@ -243,10 +180,11 @@ IECore::ConstInternedStringVectorDataPtr SceneReader::computeChildNames( const S
return parent->childNamesPlug()->defaultValue();
}

Cache::EntryPtr entry = cache().entry( fileName, path );
ConstSceneInterfacePtr s = SharedSceneInterfaces::get( fileName );
s = s->scene( path );

InternedStringVectorDataPtr result = new InternedStringVectorData;
entry->sceneInterface()->childNames( result->writable() );
s->childNames( result->writable() );

return result;
}
Expand All @@ -256,12 +194,6 @@ IECore::ConstCompoundObjectPtr SceneReader::computeGlobals( const Gaffer::Contex
return parent->globalsPlug()->defaultValue();
}

SceneReader::Cache &SceneReader::cache()
{
static Cache c;
return c;
}

void SceneReader::plugSet( Gaffer::Plug *plug )
{
// this clears the cache every time the refresh count is updated, so you don't get entries
Expand All @@ -270,13 +202,13 @@ void SceneReader::plugSet( Gaffer::Plug *plug )
// way of doing this!
if( plug == refreshCountPlug() )
{
cache().clear();
SharedSceneInterfaces::clear();
}
}

/// \todo this hash needs to be smarter - it should detect if the scene cache is animated or not
void SceneReader::hash( const Gaffer::ValuePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
FileSource::hash( output, context, h );
h.append( context->getFrame() );
h.append( context->getFrame() / g_frameRate );
}
14 changes: 9 additions & 5 deletions src/GafferScene/SceneWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
//////////////////////////////////////////////////////////////////////////

#include "GafferScene/SceneWriter.h"
#include "GafferScene/SceneReader.h"
#include "Gaffer/Context.h"
#include "Gaffer/ScriptNode.h"

Expand All @@ -48,6 +49,9 @@ using namespace GafferScene;

IE_CORE_DEFINERUNTIMETYPED( SceneWriter );

/// \todo hard coded framerate should be replaced with a getTime() method on Gaffer::Context or something
const double SceneWriter::g_frameRate( 24 );

size_t SceneWriter::g_firstPlugIndex = 0;

SceneWriter::SceneWriter( const std::string &name )
Expand Down Expand Up @@ -101,25 +105,25 @@ void SceneWriter::writeLocation( GafferScene::ScenePlug *scenePlug, const SceneP
ConstCompoundObjectPtr attributes = scenePlug->attributesPlug()->getValue();
for( CompoundObject::ObjectMap::const_iterator it = attributes->members().begin(), eIt = attributes->members().end(); it != eIt; it++ )
{
output->writeAttribute( it->first, it->second.get(), script->context()->getFrame() );
output->writeAttribute( it->first, it->second.get(), script->context()->getFrame() / g_frameRate );
}

if( scenePath.empty() )
{
ConstCompoundObjectPtr globals = scenePlug->globalsPlug()->getValue();
output->writeAttribute( "gaffer:globals", globals, script->context()->getFrame() );
output->writeAttribute( "gaffer:globals", globals, script->context()->getFrame() / g_frameRate );
}

ConstObjectPtr object = scenePlug->objectPlug()->getValue();

if( object->typeId() != IECore::NullObjectTypeId && scenePath.size() > 0 )
{
output->writeObject( object, script->context()->getFrame() );
output->writeObject( object, script->context()->getFrame() / g_frameRate );
}

Imath::Box3f b = scenePlug->boundPlug()->getValue();

output->writeBound( Imath::Box3d( Imath::V3f( b.min ), Imath::V3f( b.max ) ), script->context()->getFrame() );
output->writeBound( Imath::Box3d( Imath::V3f( b.min ), Imath::V3f( b.max ) ), script->context()->getFrame() / g_frameRate );

if( scenePath.size() )
{
Expand All @@ -131,7 +135,7 @@ void SceneWriter::writeLocation( GafferScene::ScenePlug *scenePlug, const SceneP
t[3][0], t[3][1], t[3][2], t[3][3]
);

output->writeTransform( new IECore::M44dData( transform ), script->context()->getFrame() );
output->writeTransform( new IECore::M44dData( transform ), script->context()->getFrame() / g_frameRate );
}

ConstInternedStringVectorDataPtr childNames = scenePlug->childNamesPlug()->getValue();
Expand Down