IECore::ConstCompoundDataPtr CopyImageMetadata::computeProcessedMetadata( const Gaffer::Context *context, const IECore::CompoundData *inputMetadata ) const { ConstCompoundDataPtr copyFrom = copyFromPlug()->metadataPlug()->getValue(); if( copyFrom->readable().empty() ) { return inputMetadata; } const std::string names = namesPlug()->getValue(); const bool invert = invertNamesPlug()->getValue(); if ( !invert && !names.size() ) { return inputMetadata; } IECore::CompoundDataPtr result = inputMetadata->copy(); for( IECore::CompoundData::ValueType::const_iterator it = copyFrom->readable().begin(), eIt = copyFrom->readable().end(); it != eIt; ++it ) { if( StringAlgo::matchMultiple( it->first.c_str(), names.c_str() ) != invert ) { result->writable()[it->first] = it->second; } } return result; }
ImageDisplayDriver::ImageDisplayDriver( const Box2i &displayWindow, const Box2i &dataWindow, const vector<string> &channelNames, ConstCompoundDataPtr parameters ) : DisplayDriver( displayWindow, dataWindow, channelNames, parameters ), m_image( new ImagePrimitive( dataWindow, displayWindow ) ) { for ( vector<string>::const_iterator it = channelNames.begin(); it != channelNames.end(); it++ ) { m_image->createChannel<float>( *it ); } if( parameters ) { CompoundDataMap &xData = m_image->blindData()->writable(); const CompoundDataMap &yData = parameters->readable(); CompoundDataMap::const_iterator iterY = yData.begin(); for ( ; iterY != yData.end(); iterY++ ) { xData[iterY->first] = iterY->second->copy(); } ConstStringDataPtr handle = parameters->member<StringData>( "handle" ); if( handle ) { tbb::mutex::scoped_lock lock( g_poolMutex ); g_pool[handle->readable()] = m_image; } } }
IECore::ConstStringVectorDataPtr OSLImage::computeChannelNames( const Gaffer::Context *context, const GafferImage::ImagePlug *parent ) const { ConstStringVectorDataPtr channelNamesData = inPlug()->channelNamesPlug()->getValue(); set<string> result( channelNamesData->readable().begin(), channelNamesData->readable().end() ); 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() ); ConstCompoundDataPtr shading = runTimeCast<const CompoundData>( shadingPlug()->getValue() ); for( CompoundDataMap::const_iterator it = shading->readable().begin(), eIt = shading->readable().end(); it != eIt; ++it ) { result.insert( it->first ); } } return new StringVectorData( vector<string>( result.begin(), result.end() ) ); }
GafferScene::ConstPathMatcherDataPtr BranchCreator::computeSet( const IECore::InternedString &setName, const Gaffer::Context *context, const ScenePlug *parent ) const { ConstPathMatcherDataPtr inputSetData = inPlug()->set( setName ); ConstCompoundDataPtr mapping = boost::static_pointer_cast<const CompoundData>( mappingPlug()->getValue() ); if( !mapping->readable().size() ) { return inputSetData; } ScenePlug::ScenePath parentPath = mapping->member<InternedStringVectorData>( g_parentKey )->readable(); ConstPathMatcherDataPtr branchSetData = computeBranchSet( parentPath, setName, context ); if( !branchSetData ) { return inputSetData; } const PathMatcher &branchSet = branchSetData->readable(); if( branchSet.isEmpty() ) { return inputSetData; } const CompoundData *forwardMapping = mapping->member<CompoundData>( g_forwardMappingKey ); PathMatcherDataPtr outputSetData = inputSetData->copy(); PathMatcher &outputSet = outputSetData->writable(); vector<InternedString> outputPrefix( parentPath ); for( PathMatcher::RawIterator pIt = branchSet.begin(), peIt = branchSet.end(); pIt != peIt; ++pIt ) { const ScenePlug::ScenePath &branchPath = *pIt; if( !branchPath.size() ) { continue; // Skip root } assert( branchPath.size() == 1 ); const InternedStringData *outputName = forwardMapping->member<InternedStringData>( branchPath[0], /* throwExceptions = */ true ); outputPrefix.resize( parentPath.size() + 1 ); outputPrefix.back() = outputName->readable(); outputSet.addPaths( branchSet.subTree( *pIt ), outputPrefix ); pIt.prune(); // We only want to visit the first level } return outputSetData; }
void BranchCreator::hashSetNames( const Gaffer::Context *context, const ScenePlug *parent, IECore::MurmurHash &h ) const { ConstCompoundDataPtr mapping = boost::static_pointer_cast<const CompoundData>( mappingPlug()->getValue() ); if( !mapping->readable().size() ) { h = inPlug()->setNamesPlug()->hash(); return; } MurmurHash branchSetNamesHash; hashBranchSetNames( mapping->member<InternedStringVectorData>( g_parentKey )->readable(), context, branchSetNamesHash ); if( branchSetNamesHash == MurmurHash() ) { h = inPlug()->setNamesPlug()->hash(); return; } SceneProcessor::hashSetNames( context, parent, h ); inPlug()->setNamesPlug()->hash( h ); h.append( branchSetNamesHash ); }
IECore::ConstInternedStringVectorDataPtr BranchCreator::computeSetNames( const Gaffer::Context *context, const ScenePlug *parent ) const { ConstInternedStringVectorDataPtr inputSetNamesData = inPlug()->setNamesPlug()->getValue(); ConstCompoundDataPtr mapping = boost::static_pointer_cast<const CompoundData>( mappingPlug()->getValue() ); if( !mapping->readable().size() ) { return inputSetNamesData; } ConstInternedStringVectorDataPtr branchSetNamesData = computeBranchSetNames( mapping->member<InternedStringVectorData>( g_parentKey )->readable(), context ); if( !branchSetNamesData ) { return inputSetNamesData; } const vector<InternedString> &branchSetNames = branchSetNamesData->readable(); if( !branchSetNames.size() ) { return inputSetNamesData; } InternedStringVectorDataPtr resultData = inputSetNamesData->copy(); vector<InternedString> &result = resultData->writable(); // This naive approach to merging set names preserves the order of the incoming names, // but at the expense of using linear search. We assume that the number of sets is small // enough and the InternedString comparison fast enough that this is OK. for( vector<InternedString>::const_iterator it = branchSetNames.begin(), eIt = branchSetNames.end(); it != eIt; ++it ) { if( std::find( result.begin(), result.end(), *it ) == result.end() ) { result.push_back( *it ); } } return resultData; }
IECore::ConstCompoundObjectPtr BranchCreator::computeGlobals( const Gaffer::Context *context, const ScenePlug *parent ) const { ConstCompoundObjectPtr inputGlobals = inPlug()->globalsPlug()->getValue(); ConstCompoundDataPtr mapping = boost::static_pointer_cast<const CompoundData>( mappingPlug()->getValue() ); if( !mapping->readable().size() ) { return inputGlobals; } const CompoundData *branchSets = NULL; ConstCompoundObjectPtr branchGlobals = computeBranchGlobals( mapping->member<InternedStringVectorData>( g_parentKey )->readable(), context ); if( branchGlobals ) { branchSets = branchGlobals->member<CompoundData>( "gaffer:sets", /* throwExceptions = */ false ); } if( !branchSets ) { return inputGlobals; } IECore::CompoundObjectPtr outputGlobals = new CompoundObject; // Shallow copy of the input, because most of it will remain unchanged. outputGlobals->members() = inputGlobals->members(); // Deep copy of the input sets, because we'll be modifying them. const CompoundData *inputSets = inputGlobals->member<CompoundData>( "gaffer:sets", /* throwExeptions = */ false ); CompoundDataPtr outputSets = inputSets ? inputSets->copy() : new CompoundData; outputGlobals->members()["gaffer:sets"] = outputSets; const CompoundData *forwardMapping = mapping->member<CompoundData>( g_forwardMappingKey ); string parentString; ScenePlug::pathToString( mapping->member<InternedStringVectorData>( g_parentKey )->readable(), parentString ); if( !boost::ends_with( parentString, "/" ) ) { parentString += "/"; } for( CompoundDataMap::const_iterator it = branchSets->readable().begin(), eIt = branchSets->readable().end(); it != eIt; ++it ) { const PathMatcher &branchSet = static_cast<const PathMatcherData *>( it->second.get() )->readable(); PathMatcher &outputSet = outputSets->member<PathMatcherData>( it->first, /* throwExceptions = */ false, /* createIfMissing = */ true )->writable(); /// \todo If PathMatcher allowed us to rename nodes and merge in other PathMatchers, this could /// be much more efficient. vector<string> branchPaths; branchSet.paths( branchPaths ); for( vector<string>::const_iterator pIt = branchPaths.begin(), peIt = branchPaths.end(); pIt != peIt; ++pIt ) { const string &branchPath = *pIt; const size_t secondSlashPos = branchPath.find( '/', 1 ); const std::string branchName( branchPath, 1, secondSlashPos - 1 ); const InternedStringData *outputName = forwardMapping->member<InternedStringData>( branchName ); if( !outputName ) { // See comments in Group::computeGlobals(). continue; } std::string outputPath = parentString + outputName->readable().string(); if( secondSlashPos != string::npos ) { outputPath += branchPath.substr( secondSlashPos ); } outputSet.addPath( outputPath ); } } return outputGlobals; }