// general cortex render function, takes a gu_detail and uses the NodePassData attribute // to call the required render method void GR_Cortex::render( GU_Detail *gdp, const IECoreGL::State *displayState ) { // gl scene from a parameterised procedural const GA_ROAttributeRef attrRef = gdp->findAttribute( GA_ATTRIB_DETAIL, GA_SCOPE_PRIVATE, "IECoreHoudiniNodePassData" ); if ( attrRef.isInvalid() ) { return; } const GA_Attribute *attr = attrRef.getAttribute(); const GA_AIFBlindData *blindData = attr->getAIFBlindData(); const NodePassData passData = blindData->getValue<NodePassData>( attr, 0 ); switch( passData.type() ) { case IECoreHoudini::NodePassData::CORTEX_OPHOLDER : { SOP_OpHolder *sop = dynamic_cast<SOP_OpHolder*>( const_cast<OP_Node*>( passData.nodePtr() ) ); if ( !sop ) { return; } IECore::OpPtr op = IECore::runTimeCast<IECore::Op>( sop->getParameterised() ); if ( !op ) { return; } const IECore::Parameter *result_parameter = op->resultParameter(); const IECore::Object *result_object = result_parameter->getValue(); renderObject( result_object, displayState ); break; } case IECoreHoudini::NodePassData::CORTEX_PROCEDURALHOLDER : { SOP_ProceduralHolder *sop = dynamic_cast<SOP_ProceduralHolder*>( const_cast<OP_Node*>( passData.nodePtr() ) ); if ( !sop ) { return; } IECoreGL::ConstScenePtr scene = sop->scene(); if ( !scene ) { return; } scene->render( const_cast<IECoreGL::State *>( displayState ) ); break; } default : { break; } } }
void SOP_ParameterisedHolder::setInputParameterValues( float now ) { for ( unsigned int i=0; i < m_inputParameters.size(); i++ ) { useInputSource( i, m_dirty, false ); IECore::ParameterPtr inputParameter = m_inputParameters[i]; GU_DetailHandle inputHandle = inputGeoHandle( i ); GU_DetailHandleAutoReadLock readHandle( inputHandle ); const GU_Detail *inputGdp = readHandle.getGdp(); if ( !inputGdp ) { continue; } const GA_ROAttributeRef attrRef = inputGdp->findAttribute( GA_ATTRIB_DETAIL, GA_SCOPE_PRIVATE, "IECoreHoudiniNodePassData" ); if ( attrRef.isValid() ) { // looks like data passed from another ParameterisedHolder const GA_Attribute *attr = attrRef.getAttribute(); const GA_AIFBlindData *blindData = attr->getAIFBlindData(); const NodePassData passData = blindData->getValue<NodePassData>( attr, 0 ); SOP_ParameterisedHolder *sop = dynamic_cast<SOP_ParameterisedHolder*>( const_cast<OP_Node*>( passData.nodePtr() ) ); IECore::ConstObjectPtr result = 0; if ( passData.type() == IECoreHoudini::NodePassData::CORTEX_OPHOLDER ) { IECore::OpPtr op = IECore::runTimeCast<IECore::Op>( sop->getParameterised() ); result = op->resultParameter()->getValue(); } else if ( passData.type() == IECoreHoudini::NodePassData::CORTEX_PROCEDURALHOLDER ) { IECore::ParameterisedProcedural *procedural = IECore::runTimeCast<IECore::ParameterisedProcedural>( sop->getParameterised() ); IECore::CapturingRendererPtr renderer = new IECore::CapturingRenderer(); // We are acquiring and releasing the GIL here to ensure that it is released when we render. This has // to be done because a procedural might jump between c++ and python a few times (i.e. if it spawns // subprocedurals that are implemented in python). In a normal call to cookMySop, this wouldn't be an // issue, but if cookMySop was called from HOM, hou.Node.cook appears to be holding onto the GIL. IECorePython::ScopedGILLock gilLock; { IECorePython::ScopedGILRelease gilRelease; { IECore::WorldBlock worldBlock( renderer ); procedural->render( renderer ); } } result = IECore::runTimeCast<const IECore::Object>( renderer->world() ); } else { continue; } try { inputParameter->setValidatedValue( IECore::constPointerCast<IECore::Object>( result ) ); } catch ( const IECore::Exception &e ) { addError( SOP_MESSAGE, e.what() ); } } else { // looks like a regular Houdini detail IECore::ObjectParameterPtr objectParameter = IECore::runTimeCast<IECore::ObjectParameter>( inputParameter ); if ( !objectParameter ) { continue; } FromHoudiniGeometryConverterPtr converter = FromHoudiniGeometryConverter::create( inputHandle, objectParameter->validTypes() ); if ( !converter ) { continue; } // set converter parameters from the node values const CompoundParameter::ParameterVector &converterParameters = converter->parameters()->orderedParameters(); for ( CompoundParameter::ParameterVector::const_iterator it=converterParameters.begin(); it != converterParameters.end(); ++it ) { updateParameter( *it, now, "parm_" + inputParameter->name() + "_" ); } try { IECore::ObjectPtr converted = converter->convert(); if ( converted ) { inputParameter->setValidatedValue( converted ); } } catch ( const IECore::Exception &e ) { addError( SOP_MESSAGE, e.what() ); } catch ( std::runtime_error &e ) { addError( SOP_MESSAGE, e.what() ); } } } }