IECore::ConstInternedStringVectorDataPtr Set::computeSetNames( const Gaffer::Context *context, const ScenePlug *parent ) const { ConstInternedStringVectorDataPtr inNamesData = inPlug()->setNamesPlug()->getValue(); const std::string &names = namePlug()->getValue(); if( !names.size() ) { return inNamesData; } if( modePlug()->getValue() == Remove ) { return inNamesData; } vector<InternedString> tokenizedNames; StringAlgo::tokenize( names, ' ', tokenizedNames ); // specific logic if we have only one item, to avoid the more complex logic of adding two lists together if( tokenizedNames.size() == 1 ) { const std::vector<InternedString> &inNames = inNamesData->readable(); if( std::find( inNames.begin(), inNames.end(), tokenizedNames[0] ) != inNames.end() ) { return inNamesData; } InternedStringVectorDataPtr resultData = inNamesData->copy(); resultData->writable().push_back( tokenizedNames[0] ); return resultData; } // inserting the new names into the vector // while making sure we don't have duplicates InternedStringVectorDataPtr resultData = inNamesData->copy(); std::vector<InternedString> &result = resultData->writable(); result.reserve( result.size() + tokenizedNames.size() ); std::copy( tokenizedNames.begin(), tokenizedNames.end(), std::back_inserter( result ) ); std::sort( result.begin(), result.end() ); std::vector<InternedString>::iterator it; it = std::unique( result.begin(), result.end() ); result.resize( std::distance( result.begin(), it ) ); return resultData; }
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; }