void Duplicate::sourcePath( const ScenePath &branchPath, ScenePath &source ) const { assert( branchPath.size() ); ScenePlug::stringToPath( targetPlug()->getValue(), source ); copy( ++branchPath.begin(), branchPath.end(), back_inserter( source ) ); }
void CompoundObjectSource::hashAttributes( const ScenePath &path, const Gaffer::Context *context, const GafferScene::ScenePlug *parent, IECore::MurmurHash &h ) const { SceneNode::hashAttributes( path, context, parent, h ); h.append( &path.front(), path.size() ); inPlug()->hash( h ); }
void Duplicate::compute( ValuePlug *output, const Context *context ) const { if( output == outParentPlug() ) { ScenePath target; ScenePlug::stringToPath( targetPlug()->getValue(), target ); string parent; for( size_t i = 0; i < target.size(); ++i ) { parent += "/"; if( i < target.size() - 1 ) { parent += target[i]; } } static_cast<StringPlug *>( output )->setValue( parent ); return; } else if( output == childNamesPlug() ) { // get the path to our target. ScenePath target; ScenePlug::stringToPath( targetPlug()->getValue(), target ); // throw if the target path doesn't exist in the input. we need to compute the input child names at the // parent for this, but it's not necessary to represent that in the hash, because it doesn't actually // affect our result (if we throw we will have no result). ScenePath parent( target ); parent.pop_back(); ConstInternedStringVectorDataPtr parentChildNamesData = inPlug()->childNames( parent ); vector<InternedString> parentChildNames = parentChildNamesData->readable(); if( find( parentChildNames.begin(), parentChildNames.end(), target.back() ) == parentChildNames.end() ) { throw Exception( boost::str( boost::format( "Target \"%s\" does not exist" ) % target.back().string() ) ); } // go ahead and generate our childnames. // these are composed of a stem and possibly // a numeric suffix. we default to deriving // these from the name of the target. std::string stem; int suffix = StringAlgo::numericSuffix( target.back(), 0, &stem ); suffix++; const int copies = copiesPlug()->getValue(); const std::string name = namePlug()->getValue(); // if a name is provided explicitly, then // it overrides the name and suffix derived // from the target. if( name.size() ) { std::string nameStem; const int nameSuffix = StringAlgo::numericSuffix( name, &nameStem ); stem = nameStem; suffix = copies == 1 ? nameSuffix : max( nameSuffix, 1 ); } InternedStringVectorDataPtr childNamesData = new InternedStringVectorData; std::vector<InternedString> &childNames = childNamesData->writable(); childNames.reserve( copies ); if( suffix == -1 ) { assert( copies == 1 ); childNames.push_back( stem ); } else { boost::format formatter( "%s%d" ); for( int i = 0; i < copies; ++i ) { childNames.push_back( boost::str( formatter % stem % suffix++ ) ); } } static_cast<InternedStringVectorDataPlug *>( output )->setValue( childNamesData ); return; } BranchCreator::compute( output, context ); }