IECore::ConstCompoundObjectPtr DeleteGlobals::computeProcessedGlobals( const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputGlobals ) const { if( inputGlobals->members().empty() ) { return inputGlobals; } const std::string names = namesPlug()->getValue(); const bool invert = invertNamesPlug()->getValue(); if( !invert && !names.size() ) { return inputGlobals; } const std::string prefix = namePrefix(); IECore::CompoundObjectPtr result = new IECore::CompoundObject; for( IECore::CompoundObject::ObjectMap::const_iterator it = inputGlobals->members().begin(), eIt = inputGlobals->members().end(); it != eIt; ++it ) { bool keep = true; if( boost::starts_with( it->first.c_str(), prefix ) ) { if( matchMultiple( it->first.c_str() + prefix.size(), names.c_str() ) != invert ) { keep = false; } } if( keep ) { result->members()[it->first] = it->second; } } return result; }
IECore::ConstCompoundObjectPtr AttributeProcessor::computeProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputAttributes ) const { if( inputAttributes->members().empty() ) { return inputAttributes; } const std::string names = namesPlug()->getValue(); const bool invert = invertNamesPlug()->getValue(); CompoundObjectPtr result = new CompoundObject; for( CompoundObject::ObjectMap::const_iterator it = inputAttributes->members().begin(), eIt = inputAttributes->members().end(); it != eIt; ++it ) { ConstObjectPtr attribute = it->second; if( matchMultiple( it->first, names ) != invert ) { attribute = processAttribute( path, context, it->first, attribute.get() ); } if( attribute ) { result->members().insert( CompoundObject::ObjectMap::value_type( it->first, // cast is ok - result is const immediately on // returning from this function, and attribute will // therefore not be modified. boost::const_pointer_cast<Object>( attribute ) ) ); } } return result; }
IECore::ConstCompoundObjectPtr Options::computeProcessedGlobals( const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputGlobals ) const { const CompoundDataPlug *p = optionsPlug(); if( !p->children().size() ) { return inputGlobals; } IECore::CompoundObjectPtr result = new IECore::CompoundObject; // Since we're not going to modify any existing members (only add new ones), // and our result becomes const on returning it, we can directly reference // the input members in our result without copying. Be careful not to modify // them though! result->members() = inputGlobals->members(); const std::string prefix = computePrefix( context ); std::string name; for( NameValuePlugIterator it( p ); !it.done(); ++it ) { IECore::DataPtr d = p->memberDataAndName( it->get(), name ); if( d ) { result->members()[prefix + name] = d; } } return result; }
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; }
IECore::ConstCompoundObjectPtr Set::computeProcessedGlobals( const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputGlobals ) const { std::string name = namePlug()->getValue(); if( !name.size() ) { return inputGlobals; } IECore::CompoundObjectPtr result = new IECore::CompoundObject; // Since we're not going to modify any existing members other than the sets, // and our result becomes const on returning it, we can directly reference // the input members in our result without copying. We have to be careful not // to modify the input sets though. result->members() = inputGlobals->members(); CompoundDataPtr sets = new CompoundData; if( const CompoundData *inputSets = inputGlobals->member<CompoundData>( "gaffer:sets" ) ) { sets->writable() = inputSets->readable(); } result->members()["gaffer:sets"] = sets; ConstObjectPtr set = pathMatcherPlug()->getValue(); // const cast is acceptable because we're just using it to place a const object into a // container that will be treated as const everywhere immediately after return from this method. sets->writable()[name] = const_cast<Data *>( static_cast<const Data *>( set.get() ) ); return result; }
IECore::ConstCompoundObjectPtr Attributes::computeProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputAttributes ) const { const CompoundDataPlug *ap = attributesPlug(); if( !ap->children().size() ) { return inputAttributes; } /// \todo You might think that we wouldn't have to check this again /// because the base class would have used processesAttributes() /// to avoid even calling this function. But that isn't the case for /// some reason. if( globalPlug()->getValue() ) { return inputAttributes; } CompoundObjectPtr result = new CompoundObject; // Since we're not going to modify any existing members (only add new ones), // and our result becomes const on returning it, we can directly reference // the input members in our result without copying. Be careful not to modify // them though! result->members() = inputAttributes->members(); ap->fillCompoundObject( result->members() ); return result; }
IECore::ConstCompoundObjectPtr AttributeProcessor::computeProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputAttributes ) const { if( inputAttributes->members().empty() ) { return inputAttributes; } /// \todo See todos about name matching in PrimitiveVariableProcessor. typedef boost::tokenizer<boost::char_separator<char> > Tokenizer; std::string namesValue = namesPlug()->getValue(); Tokenizer names( namesValue, boost::char_separator<char>( " " ) ); bool invert = invertNamesPlug()->getValue(); CompoundObjectPtr result = new CompoundObject; IECore::PrimitiveVariableMap::iterator next; for( CompoundObject::ObjectMap::const_iterator it = inputAttributes->members().begin(), eIt = inputAttributes->members().end(); it != eIt; ++it ) { ConstObjectPtr attribute = it->second; bool found = std::find( names.begin(), names.end(), it->first.string() ) != names.end(); if( found != invert ) { attribute = processAttribute( path, context, it->first, attribute.get() ); } if( attribute ) { result->members().insert( CompoundObject::ObjectMap::value_type( it->first, // cast is ok - result is const immediately on // returning from this function, and attribute will // therefore not be modified. constPointerCast<Object>( attribute ) ) ); } } return result; }
IECore::ConstCompoundObjectPtr Outputs::computeProcessedGlobals( const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputGlobals ) const { const CompoundPlug *dsp = outputsPlug(); if( !dsp->children().size() ) { return inputGlobals; } IECore::CompoundObjectPtr result = new IECore::CompoundObject; // Since we're not going to modify any existing members (only add new ones), // and our result becomes const on returning it, we can directly reference // the input members in our result without copying. Be careful not to modify // them though! result->members() = inputGlobals->members(); // add our outputs to the result for( InputCompoundPlugIterator it( dsp ); it != it.end(); it++ ) { const CompoundPlug *outputPlug = it->get(); if( outputPlug->getChild<BoolPlug>( "active" )->getValue() ) { // backwards compatibility with old plug layout const StringPlug *namePlug = outputPlug->getChild<StringPlug>( "label" ); if( !namePlug ) { namePlug = outputPlug->getChild<StringPlug>( "name" ); } const std::string name = namePlug->getValue(); const StringPlug *fileNamePlug = outputPlug->getChild<StringPlug>( "fileName" ); if( !fileNamePlug ) { // backwards compatibility with old plug layout fileNamePlug = outputPlug->getChild<StringPlug>( "name" ); } const std::string fileName = fileNamePlug->getValue(); const std::string type = outputPlug->getChild<StringPlug>( "type" )->getValue(); const std::string data = outputPlug->getChild<StringPlug>( "data" )->getValue(); if( name.size() && fileName.size() && type.size() && data.size() ) { DisplayPtr d = new Display( fileName, type, data ); outputPlug->getChild<CompoundDataPlug>( "parameters" )->fillCompoundData( d->parameters() ); result->members()["output:" + name] = d; } } } return result; }
IECore::ConstCompoundObjectPtr AttributeVisualiser::computeProcessedAttributes( const ScenePath &path, const Gaffer::Context *context, IECore::ConstCompoundObjectPtr inputAttributes ) const { const std::string attributeName = attributeNamePlug()->getValue(); if( !attributeName.size() ) { return inputAttributes; } const std::string shaderType = shaderTypePlug()->getValue(); if( !shaderType.size() ) { return inputAttributes; } const Object *attribute = inputAttributes->member<Object>( attributeName ); if( !attribute ) { if( !inputAttributes->member<Object>( shaderType ) ) { return inputAttributes; } } CompoundObjectPtr result = new CompoundObject; // Since we're not going to modify any existing members (only add a new one), // and our result becomes const on returning it, we can directly reference // the input members in our result without copying. Be careful not to modify // them though! result->members() = inputAttributes->members(); if( !attribute ) { result->members().erase( shaderType ); return result; } // Compute our colour. Color3f color( 0.0f ); const Mode mode = (Mode)modePlug()->getValue(); if( mode == Random ) { Rand32 r( tbb_hasher( attribute->hash() ) ); for( int i = 0; i < 3; ++i ) { color[i] = r.nextf(); } } else if( mode == ShaderNodeColor ) { const Shader *shader = runTimeCast<const Shader>( attribute ); if( !shader ) { if( const ShaderNetwork *network = runTimeCast<const ShaderNetwork>( attribute ) ) { shader = network->outputShader(); } } if( shader ) { const Color3fData *colorData = shader->blindData()->member<const Color3fData>( "gaffer:nodeColor" ); if( colorData ) { color = colorData->readable(); } } } else { // Color or FalseColor switch( attribute->typeId() ) { case FloatDataTypeId : color = Color3f( static_cast<const FloatData *>( attribute )->readable() ); break; case DoubleDataTypeId : color = Color3f( static_cast<const DoubleData *>( attribute )->readable() ); break; case IntDataTypeId : color = Color3f( static_cast<const IntData *>( attribute )->readable() ); break; case BoolDataTypeId : color = Color3f( static_cast<const BoolData *>( attribute )->readable() ); break; case Color3fDataTypeId : color = static_cast<const Color3fData *>( attribute )->readable(); break; default : throw IECore::Exception( boost::str( boost::format( "Unsupported attribute data type \"%s\"" ) % attribute->typeName() ) ); } const Color3f min( minPlug()->getValue() ); const Color3f max( maxPlug()->getValue() ); color = ( color - min ) / ( max - min ); if( mode == FalseColor ) { const SplinefColor3f ramp = rampPlug()->getValue().spline(); color = ramp( color[0] ); } } // Apply the colour using a shader. ShaderPtr shader = new Shader( shaderNamePlug()->getValue(), shaderType ); shader->parameters()[shaderParameterPlug()->getValue()] = new Color3fData( color ); ShaderNetworkPtr shaderNetwork = new ShaderNetwork; const InternedString handle = shaderNetwork->addShader( "surface", std::move( shader ) ); shaderNetwork->setOutput( handle ); result->members()[shaderType] = shaderNetwork; return result; }