// A test useful for assessing the performance // of the Context class. void GafferTest::testManyContexts() { // our typical context doesn't have a huge number of keys - we'll // use a working set of 20 for this test. ContextPtr base = new Context(); const int numKeys = 20; vector<InternedString> keys; for( int i = 0; i < numKeys; ++i ) { InternedString key = string( "testKey" ) + lexical_cast<string>( i ); keys.push_back( key ); base->set( key, i ); } // then typically we create new temporary contexts based on that one, // change a value or two, and then continue. Timer t; for( int i = 0; i < 100000; ++i ) { ContextPtr tmp = new Context( *base, Context::Borrowed ); tmp->set( keys[i%numKeys], i ); GAFFERTEST_ASSERT( tmp->get<int>( keys[i%numKeys] ) == i ); } // uncomment to get timing information //std::cerr << t.stop() << std::endl; }
IECore::MurmurHash ImagePlug::imageHash() const { const Box2i dataWindow = dataWindowPlug()->getValue(); ConstStringVectorDataPtr channelNamesData = channelNamesPlug()->getValue(); const vector<string> &channelNames = channelNamesData->readable(); MurmurHash result = formatPlug()->hash(); result.append( dataWindowPlug()->hash() ); result.append( metadataPlug()->hash() ); result.append( channelNamesPlug()->hash() ); V2i minTileOrigin = tileOrigin( dataWindow.min ); V2i maxTileOrigin = tileOrigin( dataWindow.max ); ContextPtr context = new Context( *Context::current(), Context::Borrowed ); Context::Scope scope( context.get() ); for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it!=eIt; it++ ) { context->set( ImagePlug::channelNameContextName, *it ); for( int tileOriginY = minTileOrigin.y; tileOriginY<=maxTileOrigin.y; tileOriginY += tileSize() ) { for( int tileOriginX = minTileOrigin.x; tileOriginX<=maxTileOrigin.x; tileOriginX += tileSize() ) { context->set( ImagePlug::tileOriginContextName, V2i( tileOriginX, tileOriginY ) ); channelDataPlug()->hash( result ); } } } return result; }
void operator()( const blocked_range2d<size_t>& r ) const { ContextPtr context = new Context( *m_parentContext ); const Box2i operationWindow( V2i( r.rows().begin()+m_dataWindow.min.x, r.cols().begin()+m_dataWindow.min.y ), V2i( r.rows().end()+m_dataWindow.min.x-1, r.cols().end()+m_dataWindow.min.y-1 ) ); V2i minTileOrigin = ImagePlug::tileOrigin( operationWindow.min ); V2i maxTileOrigin = ImagePlug::tileOrigin( operationWindow.max ); size_t imageStride = m_dataWindow.size().x + 1; for( int tileOriginY = minTileOrigin.y; tileOriginY <= maxTileOrigin.y; tileOriginY += m_tileSize ) { for( int tileOriginX = minTileOrigin.x; tileOriginX <= maxTileOrigin.x; tileOriginX += m_tileSize ) { for( vector<string>::const_iterator it = m_channelNames.begin(), eIt = m_channelNames.end(); it != eIt; it++ ) { context->set( ImagePlug::channelNameContextName, *it ); context->set( ImagePlug::tileOriginContextName, V2i( tileOriginX, tileOriginY ) ); Context::Scope scope( context.get() ); Box2i tileBound( V2i( tileOriginX, tileOriginY ), V2i( tileOriginX + m_tileSize - 1, tileOriginY + m_tileSize - 1 ) ); Box2i b = boxIntersection( tileBound, operationWindow ); ConstFloatVectorDataPtr tileData = m_channelDataPlug->getValue(); for( int y = b.min.y; y<=b.max.y; y++ ) { const float *tilePtr = &(tileData->readable()[0]) + (y - tileOriginY) * m_tileSize + (b.min.x - tileOriginX); float *channelPtr = m_imageChannelData[it-m_channelNames.begin()] + ( m_dataWindow.size().y - ( y - m_dataWindow.min.y ) ) * imageStride + (b.min.x - m_dataWindow.min.x); for( int x = b.min.x; x <= b.max.x; x++ ) { *channelPtr++ = *tilePtr++; } } } } } }
void ColorProcessor::compute( Gaffer::ValuePlug *output, const Gaffer::Context *context ) const { if( output == colorDataPlug() ) { FloatVectorDataPtr r, g, b; { ContextPtr tmpContext = new Context( *context, Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); tmpContext->set( ImagePlug::channelNameContextName, string( "R" ) ); r = inPlug()->channelDataPlug()->getValue()->copy(); tmpContext->set( ImagePlug::channelNameContextName, string( "G" ) ); g = inPlug()->channelDataPlug()->getValue()->copy(); tmpContext->set( ImagePlug::channelNameContextName, string( "B" ) ); b = inPlug()->channelDataPlug()->getValue()->copy(); } processColorData( context, r.get(), g.get(), b.get() ); ObjectVectorPtr result = new ObjectVector(); result->members().push_back( r ); result->members().push_back( g ); result->members().push_back( b ); static_cast<ObjectPlug *>( output )->setValue( result ); return; } ImageProcessor::compute( output, context ); }
IECore::MurmurHash ImagePlug::channelDataHash( const std::string &channelName, const Imath::V2i &tile ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( ImagePlug::channelNameContextName, channelName ); tmpContext->set( ImagePlug::tileOriginContextName, tile ); Context::Scope scopedContext( tmpContext.get() ); return channelDataPlug()->hash(); }
void ColorProcessor::hashColorData( const Gaffer::Context *context, IECore::MurmurHash &h ) const { ContextPtr tmpContext = new Context( *context, Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); tmpContext->set( ImagePlug::channelNameContextName, string( "R" ) ); inPlug()->channelDataPlug()->hash( h ); tmpContext->set( ImagePlug::channelNameContextName, string( "G" ) ); inPlug()->channelDataPlug()->hash( h ); tmpContext->set( ImagePlug::channelNameContextName, string( "B" ) ); inPlug()->channelDataPlug()->hash( h ); }
IECore::ConstFloatVectorDataPtr ImagePlug::channelData( const std::string &channelName, const Imath::V2i &tile ) const { if( direction()==In && !getInput<Plug>() ) { return channelDataPlug()->defaultValue(); } ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( ImagePlug::channelNameContextName, channelName ); tmpContext->set( ImagePlug::tileOriginContextName, tile ); Context::Scope scopedContext( tmpContext.get() ); return channelDataPlug()->getValue(); }
Imath::Box3f ScenePlug::bound( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current() ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext ); return boundPlug()->getValue(); }
IECore::MurmurHash ScenePlug::childNamesHash( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext.get() ); return childNamesPlug()->hash(); }
IECore::ConstInternedStringVectorDataPtr ScenePlug::childNames( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext.get() ); return childNamesPlug()->getValue(); }
IECore::ConstObjectPtr ScenePlug::object( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext.get() ); return objectPlug()->getValue(); }
Imath::M44f ScenePlug::transform( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext.get() ); return transformPlug()->getValue(); }
Imath::Box3f SceneNode::unionOfTransformedChildBounds( const ScenePath &path, const ScenePlug *out, const IECore::InternedStringVectorData *childNamesData ) const { ConstInternedStringVectorDataPtr computedChildNames; if( !childNamesData ) { computedChildNames = out->childNames( path ); childNamesData = computedChildNames.get(); } const vector<InternedString> &childNames = childNamesData->readable(); Box3f result; if( childNames.size() ) { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); ScenePath childPath( path ); childPath.push_back( InternedString() ); // room for the child name for( vector<InternedString>::const_iterator it = childNames.begin(); it != childNames.end(); it++ ) { childPath[path.size()] = *it; tmpContext->set( ScenePlug::scenePathContextName, childPath ); Box3f childBound = out->boundPlug()->getValue(); childBound = transform( childBound, out->transformPlug()->getValue() ); result.extendBy( childBound ); } } return result; }
IECore::MurmurHash SceneNode::hashOfTransformedChildBounds( const ScenePath &path, const ScenePlug *out, const IECore::InternedStringVectorData *childNamesData ) const { ConstInternedStringVectorDataPtr computedChildNames; if( !childNamesData ) { computedChildNames = out->childNames( path ); childNamesData = computedChildNames.get(); } const vector<InternedString> &childNames = childNamesData->readable(); IECore::MurmurHash result; if( childNames.size() ) { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); ScenePath childPath( path ); childPath.push_back( InternedString() ); // room for the child name for( vector<InternedString>::const_iterator it = childNames.begin(); it != childNames.end(); it++ ) { childPath[path.size()] = *it; tmpContext->set( ScenePlug::scenePathContextName, childPath ); out->boundPlug()->hash( result ); out->transformPlug()->hash( result ); } } else { result.append( typeId() ); result.append( "emptyBound" ); } return result; }
IECore::MurmurHash ScenePlug::attributesHash( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current() ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext ); return attributesPlug()->hash(); }
IECore::ConstCompoundObjectPtr ScenePlug::attributes( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current() ); tmpContext->set( scenePathContextName, scenePath ); Context::Scope scopedContext( tmpContext ); return attributesPlug()->getValue(); }
void Unpremultiply::processChannelData( const Gaffer::Context *context, const ImagePlug *parent, const std::string &channel, FloatVectorDataPtr outData ) const { std::string alphaChannel = alphaChannelPlug()->getValue(); if ( channel == alphaChannel ) { return; } ConstStringVectorDataPtr inChannelNamesPtr = inPlug()->channelNamesPlug()->getValue(); const std::vector<std::string> &inChannelNames = inChannelNamesPtr->readable(); if ( std::find( inChannelNames.begin(), inChannelNames.end(), alphaChannel ) == inChannelNames.end() ) { std::ostringstream channelError; channelError << "Channel '" << alphaChannel << "' does not exist"; throw( IECore::Exception( channelError.str() ) ); } ContextPtr tmpContext = new Context( *context, Context::Borrowed ); tmpContext->set( ImagePlug::channelNameContextName, alphaChannel ); Context::Scope scopedContext( tmpContext.get() ); const std::vector<float> &a = inPlug()->channelDataPlug()->getValue()->readable(); std::vector<float> &out = outData->writable(); std::vector<float>::const_iterator aIt = a.begin(); for ( std::vector<float>::iterator outIt = out.begin(), outItEnd = out.end(); outIt != outItEnd; ++outIt, ++aIt ) { if ( *aIt != 0.0f ) { *outIt /= *aIt; } } }
IECore::CompoundObjectPtr ScenePlug::fullAttributes( const ScenePath &scenePath ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); Context::Scope scopedContext( tmpContext.get() ); IECore::CompoundObjectPtr result = new IECore::CompoundObject; IECore::CompoundObject::ObjectMap &resultMembers = result->members(); ScenePath path( scenePath ); while( path.size() ) { tmpContext->set( scenePathContextName, path ); IECore::ConstCompoundObjectPtr a = attributesPlug()->getValue(); const IECore::CompoundObject::ObjectMap &aMembers = a->members(); for( IECore::CompoundObject::ObjectMap::const_iterator it = aMembers.begin(), eIt = aMembers.end(); it != eIt; it++ ) { if( resultMembers.find( it->first ) == resultMembers.end() ) { resultMembers.insert( *it ); } } path.pop_back(); } return result; }
virtual task *execute() { ContextPtr context = new Context( *m_context ); context->set( ScenePlug::scenePathContextName, m_scenePath ); Context::Scope scopedContext( context ); m_scenePlug->transformPlug()->getValue(); m_scenePlug->boundPlug()->getValue(); m_scenePlug->attributesPlug()->getValue(); m_scenePlug->objectPlug()->getValue(); ConstInternedStringVectorDataPtr childNamesData = m_scenePlug->childNamesPlug()->getValue(); const vector<InternedString> &childNames = childNamesData->readable(); set_ref_count( 1 + childNames.size() ); ScenePlug::ScenePath childPath = m_scenePath; childPath.push_back( InternedString() ); // space for the child name for( vector<InternedString>::const_iterator it = childNames.begin(), eIt = childNames.end(); it != eIt; it++ ) { childPath[m_scenePath.size()] = *it; SceneTraversalTask *t = new( allocate_child() ) SceneTraversalTask( m_scenePlug, m_context, childPath ); spawn( *t ); } wait_for_all(); return 0; }
IECore::ConstInternedStringVectorDataPtr Isolate::computeChildNames( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const { ContextPtr tmpContext = filterContext( context ); Context::Scope scopedContext( tmpContext.get() ); if( mayPruneChildren( path, filterPlug()->getValue() ) ) { // we may need to delete one or more of our children ConstInternedStringVectorDataPtr inputChildNamesData = inPlug()->childNamesPlug()->getValue(); const vector<InternedString> &inputChildNames = inputChildNamesData->readable(); InternedStringVectorDataPtr outputChildNamesData = new InternedStringVectorData; vector<InternedString> &outputChildNames = outputChildNamesData->writable(); ScenePath childPath = path; childPath.push_back( InternedString() ); // for the child name for( vector<InternedString>::const_iterator it = inputChildNames.begin(), eIt = inputChildNames.end(); it != eIt; it++ ) { childPath[path.size()] = *it; tmpContext->set( ScenePlug::scenePathContextName, childPath ); if( filterPlug()->getValue() != Filter::NoMatch ) { outputChildNames.push_back( *it ); } } return outputChildNamesData; } else { // pass through return inPlug()->childNamesPlug()->getValue(); } }
void Group::hashBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { if( path.size() == 0 ) // "/" { SceneProcessor::hashBound( path, context, parent, h ); for( vector<ScenePlugPtr>::const_iterator it = m_inPlugs.inputs().begin(), eIt = m_inPlugs.inputs().end(); it!=eIt; it++ ) { (*it)->boundPlug()->hash( h ); } transformPlug()->hash( h ); } else if( path.size() == 1 ) // "/group" { SceneProcessor::hashBound( path, context, parent, h ); ContextPtr tmpContext = new Context( *Context::current() ); tmpContext->set( ScenePlug::scenePathContextName, ScenePath() ); Context::Scope scopedContext( tmpContext ); for( vector<ScenePlugPtr>::const_iterator it = m_inPlugs.inputs().begin(), eIt = m_inPlugs.inputs().end(); it!=eIt; it++ ) { (*it)->boundPlug()->hash( h ); } } else // "/group/..." { // pass through ScenePlug *sourcePlug = 0; ScenePath source = sourcePath( path, namePlug()->getValue(), &sourcePlug ); h = sourcePlug->boundHash( source ); } }
void Group::hashBound( const ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { if( path.size() == 0 ) // "/" { SceneProcessor::hashBound( path, context, parent, h ); for( ScenePlugIterator it( inPlugs() ); it != it.end(); ++it ) { (*it)->boundPlug()->hash( h ); } transformPlug()->hash( h ); } else if( path.size() == 1 ) // "/group" { SceneProcessor::hashBound( path, context, parent, h ); ContextPtr tmpContext = new Context( *context, Context::Borrowed ); tmpContext->set( ScenePlug::scenePathContextName, ScenePath() ); Context::Scope scopedContext( tmpContext.get() ); for( ScenePlugIterator it( inPlugs() ); it != it.end(); ++it ) { (*it)->boundPlug()->hash( h ); } } else // "/group/..." { // pass through const ScenePlug *sourcePlug = 0; ScenePath source = sourcePath( path, namePlug()->getValue(), &sourcePlug ); h = sourcePlug->boundHash( source ); } }
ConstPathMatcherDataPtr ScenePlug::set( const IECore::InternedString &setName ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( setNameContextName, setName ); removeNonGlobalContextVariables( tmpContext.get() ); Context::Scope scopedContext( tmpContext.get() ); return setPlug()->getValue(); }
Gaffer::ContextPtr Instancer::instanceContext( const Gaffer::Context *parentContext, const ScenePath &branchPath ) const { if( branchPath.size() == 0 ) { return 0; } ContextPtr result = new Context( *parentContext ); InternedStringVectorDataPtr instancePath = new InternedStringVectorData; instancePath->writable().insert( instancePath->writable().end(), branchPath.begin() + 1, branchPath.end() ); result->set( ScenePlug::scenePathContextName, instancePath.get() ); result->set( "instancer:id", instanceIndex( branchPath ) ); return result; }
IECore::MurmurHash ScenePlug::setHash( const IECore::InternedString &setName ) const { ContextPtr tmpContext = new Context( *Context::current(), Context::Borrowed ); tmpContext->set( setNameContextName, setName ); removeNonGlobalContextVariables( tmpContext.get() ); Context::Scope scopedContext( tmpContext.get() ); return setPlug()->hash(); }
// Useful for assessing the performance of substitutions. void GafferTest::testManySubstitutions() { ContextPtr context = new Context(); context->set( "foodType", std::string( "kipper" ) ); context->set( "cookingMethod", std::string( "smoke" ) ); const std::string phrase( "${cookingMethod} me a ${foodType}" ); const std::string expectedResult( "smoke me a kipper" ); Timer t; for( int i = 0; i < 100000; ++i ) { const std::string s = context->substitute( phrase ); GAFFERTEST_ASSERT( s == expectedResult ); } // uncomment to get timing information //std::cerr << t.stop() << std::endl; }
void operator()( const blocked_range3d<size_t>& r ) const { ContextPtr context = new Context( *m_parentContext, Context::Borrowed ); Context::Scope scope( context.get() ); const Box2i operationWindow( V2i( r.rows().begin()+m_dataWindow.min.x, r.cols().begin()+m_dataWindow.min.y ), V2i( r.rows().end()+m_dataWindow.min.x-1, r.cols().end()+m_dataWindow.min.y-1 ) ); V2i minTileOrigin = ImagePlug::tileOrigin( operationWindow.min ); V2i maxTileOrigin = ImagePlug::tileOrigin( operationWindow.max ); size_t imageStride = m_dataWindow.size().x + 1; for( size_t channelIndex = r.pages().begin(); channelIndex < r.pages().end(); ++channelIndex ) { context->set( ImagePlug::channelNameContextName, m_channelNames[channelIndex] ); float *channelBegin = m_imageChannelData[channelIndex]; for( int tileOriginY = minTileOrigin.y; tileOriginY <= maxTileOrigin.y; tileOriginY += m_tileSize ) { for( int tileOriginX = minTileOrigin.x; tileOriginX <= maxTileOrigin.x; tileOriginX += m_tileSize ) { context->set( ImagePlug::tileOriginContextName, V2i( tileOriginX, tileOriginY ) ); Box2i tileBound( V2i( tileOriginX, tileOriginY ), V2i( tileOriginX + m_tileSize - 1, tileOriginY + m_tileSize - 1 ) ); Box2i b = boxIntersection( tileBound, operationWindow ); size_t tileStrideSize = sizeof(float) * ( b.size().x + 1 ); ConstFloatVectorDataPtr tileData = m_channelDataPlug->getValue(); const float *tileDataBegin = &(tileData->readable()[0]); for( int y = b.min.y; y<=b.max.y; y++ ) { const float *tilePtr = tileDataBegin + (y - tileOriginY) * m_tileSize + (b.min.x - tileOriginX); float *channelPtr = channelBegin + ( m_dataWindow.size().y - ( y - m_dataWindow.min.y ) ) * imageStride + (b.min.x - m_dataWindow.min.x); std::memcpy( channelPtr, tilePtr, tileStrideSize ); } } } } }
void OSLImage::hashChannelNames( const GafferImage::ImagePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const { ImageProcessor::hashChannelNames( output, context, h ); inPlug()->channelNamesPlug()->hash( h ); const Box2i dataWindow = inPlug()->dataWindowPlug()->getValue(); if( !dataWindow.isEmpty() ) { ContextPtr c = new Context( *context, Context::Borrowed ); c->set( ImagePlug::tileOriginContextName, ImagePlug::tileOrigin( dataWindow.min ) ); Context::Scope s( c.get() ); shadingPlug()->hash( h ); } }
void Unpremultiply::hashChannelData( const GafferImage::ImagePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const { std::string alphaChannel = alphaChannelPlug()->getValue(); ChannelDataProcessor::hashChannelData( output, context, h ); inPlug()->channelDataPlug()->hash( h ); ContextPtr tmpContext = new Context( *context, Context::Borrowed ); tmpContext->set( ImagePlug::channelNameContextName, alphaChannel ); Context::Scope scopedContext( tmpContext.get() ); inPlug()->channelDataPlug()->hash( h ); }
void Group::hash( const Gaffer::ValuePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const { SceneProcessor::hash( output, context, h ); if( output == mappingPlug() ) { ContextPtr tmpContext = new Context( *context, Context::Borrowed ); tmpContext->set( ScenePlug::scenePathContextName, ScenePath() ); Context::Scope scopedContext( tmpContext.get() ); for( ScenePlugIterator it( inPlugs() ); it != it.end(); ++it ) { (*it)->childNamesPlug()->hash( h ); } } }