IECore::ConstObjectPtr OSLObject::computeProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::ConstObjectPtr inputObject ) const { const Primitive *inputPrimitive = runTimeCast<const Primitive>( inputObject.get() ); if( !inputPrimitive ) { return inputObject; } if( !inputPrimitive->variableData<V3fVectorData>( "P", PrimitiveVariable::Vertex ) ) { return inputObject; } ConstOSLShaderPtr shader = runTimeCast<const OSLShader>( shaderPlug()->source<Plug>()->node() ); ConstShadingEnginePtr shadingEngine = shader ? shader->shadingEngine() : NULL; if( !shadingEngine ) { return inputObject; } CompoundDataPtr shadingPoints = new CompoundData; for( PrimitiveVariableMap::const_iterator it = inputPrimitive->variables.begin(), eIt = inputPrimitive->variables.end(); it != eIt; ++it ) { if( it->second.interpolation == PrimitiveVariable::Vertex ) { // cast is ok - we're only using it to be able to reference the data from the shadingPoints, // but nothing will modify the data itself. shadingPoints->writable()[it->first] = boost::const_pointer_cast<Data>( it->second.data ); } } PrimitivePtr outputPrimitive = inputPrimitive->copy(); ShadingEngine::Transforms transforms; transforms[ g_world ] = ShadingEngine::Transform( inPlug()->fullTransform( path )); CompoundDataPtr shadedPoints = shadingEngine->shade( shadingPoints.get(), transforms ); for( CompoundDataMap::const_iterator it = shadedPoints->readable().begin(), eIt = shadedPoints->readable().end(); it != eIt; ++it ) { if( it->first != "Ci" ) { outputPrimitive->variables[it->first] = PrimitiveVariable( PrimitiveVariable::Vertex, it->second ); } } return outputPrimitive; }
void OSLObject::hashProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::MurmurHash &h ) const { const OSLShader *shader = runTimeCast<const OSLShader>( shaderPlug()->source()->node() ); ConstShadingEnginePtr shadingEngine = shader ? shader->shadingEngine() : nullptr; if( !shadingEngine ) { return; } shadingEngine->hash( h ); interpolationPlug()->hash( h ); h.append( inPlug()->fullTransformHash( path ) ); h.append( resampledInPlug()->objectPlug()->hash() ); }
IECore::ConstObjectPtr OSLObject::computeProcessedObject( const ScenePath &path, const Gaffer::Context *context, IECore::ConstObjectPtr inputObject ) const { const Primitive *inputPrimitive = runTimeCast<const Primitive>( inputObject.get() ); if( !inputPrimitive ) { return inputObject; } const OSLShader *shader = runTimeCast<const OSLShader>( shaderPlug()->source()->node() ); ConstShadingEnginePtr shadingEngine = shader ? shader->shadingEngine() : nullptr; if( !shadingEngine ) { return inputObject; } PrimitiveVariable::Interpolation interpolation = static_cast<PrimitiveVariable::Interpolation>( interpolationPlug()->getValue() ); IECoreScene::ConstPrimitivePtr resampledObject = IECore::runTimeCast<const IECoreScene::Primitive>( resampledInPlug()->objectPlug()->getValue() ); CompoundDataPtr shadingPoints = prepareShadingPoints( resampledObject.get(), shadingEngine.get() ); PrimitivePtr outputPrimitive = inputPrimitive->copy(); ShadingEngine::Transforms transforms; transforms[ g_world ] = ShadingEngine::Transform( inPlug()->fullTransform( path )); CompoundDataPtr shadedPoints = shadingEngine->shade( shadingPoints.get(), transforms ); for( CompoundDataMap::const_iterator it = shadedPoints->readable().begin(), eIt = shadedPoints->readable().end(); it != eIt; ++it ) { // Ignore the output color closure as the debug closures are used to define what is 'exported' from the shader if( it->first != "Ci" ) { outputPrimitive->variables[it->first] = PrimitiveVariable( interpolation, it->second ); } } return outputPrimitive; }
void OSLObject::compute( Gaffer::ValuePlug *output, const Gaffer::Context *context ) const { if( output == resampledNamesPlug() ) { ConstPrimitivePtr prim = runTimeCast<const IECoreScene::Primitive>( inPlug()->objectPlug()->getValue() ); if (!prim) { static_cast<StringPlug *>( output )->setToDefault(); return; } std::string primitiveVariablesToResample; const OSLShader *shader = runTimeCast<const OSLShader>( shaderPlug()->source()->node() ); ConstShadingEnginePtr shadingEngine = shader ? shader->shadingEngine() : nullptr; for( PrimitiveVariableMap::const_iterator it = prim->variables.begin(); it != prim->variables.end(); ++it ) { if( it->second.interpolation == PrimitiveVariable::Constant ) { continue; } if( shadingEngine && !shadingEngine->needsAttribute( it->first ) ) { continue; } primitiveVariablesToResample += " " + it->first; } static_cast<StringPlug *>( output )->setValue( primitiveVariablesToResample ); return; } SceneElementProcessor::compute( output, context ); }
IECore::ConstCompoundDataPtr OSLImage::computeShading( const Gaffer::Context *context ) const { ConstShadingEnginePtr shadingEngine; if( const OSLShader *shader = runTimeCast<const OSLShader>( shaderPlug()->source<Plug>()->node() ) ) { shadingEngine = shader->shadingEngine(); } if( !shadingEngine ) { return static_cast<const CompoundData *>( shadingPlug()->defaultValue() ); } const V2i tileOrigin = context->get<V2i>( ImagePlug::tileOriginContextName ); const Format format = inPlug()->formatPlug()->getValue(); CompoundDataPtr shadingPoints = new CompoundData(); V3fVectorDataPtr pData = new V3fVectorData; FloatVectorDataPtr uData = new FloatVectorData; FloatVectorDataPtr vData = new FloatVectorData; vector<V3f> &pWritable = pData->writable(); vector<float> &uWritable = uData->writable(); vector<float> &vWritable = vData->writable(); const size_t tileSize = ImagePlug::tileSize(); pWritable.reserve( tileSize * tileSize ); uWritable.reserve( tileSize * tileSize ); vWritable.reserve( tileSize * tileSize ); /// \todo Non-zero display window origins - do we have those? const float uStep = 1.0f / format.width(); const float uMin = 0.5f * uStep; const float vStep = 1.0f / format.height(); const float vMin = 0.5f * vStep; const size_t xMax = tileOrigin.x + tileSize; const size_t yMax = tileOrigin.y + tileSize; for( size_t y = tileOrigin.y; y < yMax; ++y ) { const float v = vMin + y * vStep; for( size_t x = tileOrigin.x; x < xMax; ++x ) { uWritable.push_back( uMin + x * uStep ); vWritable.push_back( v ); pWritable.push_back( V3f( x, y, 0.0f ) ); } } shadingPoints->writable()["P"] = pData; shadingPoints->writable()["u"] = uData; shadingPoints->writable()["v"] = vData; ConstStringVectorDataPtr channelNamesData = inPlug()->channelNamesPlug()->getValue(); const vector<string> &channelNames = channelNamesData->readable(); for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it != eIt; ++it ) { shadingPoints->writable()[*it] = boost::const_pointer_cast<FloatVectorData>( inPlug()->channelData( *it, tileOrigin ) ); } CompoundDataPtr result = shadingEngine->shade( shadingPoints.get() ); // remove results that aren't suitable to become channels for( CompoundDataMap::iterator it = result->writable().begin(); it != result->writable().end(); ) { CompoundDataMap::iterator nextIt = it; nextIt++; if( !runTimeCast<FloatVectorData>( it->second ) ) { result->writable().erase( it ); } it = nextIt; } return result; }