MStatus OpHolder<B>::compute( const MPlug &plug, MDataBlock &block ) { IECore::OpPtr op = getOp(); if (op) { MFnDependencyNode fnDN( B::thisMObject() ); MPlug resultPlug( B::thisMObject(), fnDN.attribute( "result" ) ); if (plug != resultPlug) { return MS::kUnknownParameter; } IECore::ObjectPtr result; try { ParameterisedHolder<B>::setParameterisedValues( true /* lazy */ ); result = op->operate(); if (!result) { return MS::kFailure; } } catch( std::exception &e ) { MGlobal::displayError( e.what() ); return MS::kFailure; } catch( boost::python::error_already_set & ) { IECorePython::ScopedGILLock lock; PyErr_Print(); return MS::kFailure; } catch (...) { return MS::kFailure; } assert( result ); MStatus s = ParameterHandler::setValue( op->resultParameter(), resultPlug ); block.setClean( resultPlug ); return s; } return MS::kFailure; }
/// Cook the SOP! This method does all the work OP_ERROR SOP_OpHolder::cookMySop( OP_Context &context ) { IECore::MessageHandler::Scope handlerScope( getMessageHandler() ); // some defaults and useful variables Imath::Box3f bbox( Imath::V3f(-1,-1,-1), Imath::V3f(1,1,1) ); float now = context.getTime(); // force eval of our nodes parameters with our hidden parameter expression evalInt( "__evaluateParameters", 0, now ); // get our op IECore::OpPtr op = IECore::runTimeCast<IECore::Op>( getParameterised() ); // check for a valid parameterised on this SOP if ( !op ) { UT_String msg( "Op Holder has no parameterised class to operate on!" ); addError( SOP_MESSAGE, msg ); return error(); } if( lockInputs(context)>=UT_ERROR_ABORT ) { return error(); } // start our work UT_Interrupt *boss = UTgetInterrupt(); boss->opStart("Building OpHolder Geometry..."); gdp->clearAndDestroy(); setParameterisedValues( now ); try { // make our Cortex op do it's thing... op->operate(); // pass ourselves onto the GR_Cortex render hook IECoreHoudini::NodePassData data( this, IECoreHoudini::NodePassData::CORTEX_OPHOLDER ); GA_RWAttributeRef attrRef = gdp->createAttribute( GA_ATTRIB_DETAIL, GA_SCOPE_PRIVATE, "IECoreHoudiniNodePassData", NULL, NULL, "blinddata" ); GA_Attribute *attr = attrRef.getAttribute(); const GA_AIFBlindData *blindData = attr->getAIFBlindData(); blindData->setDataSize( attr, sizeof(IECoreHoudini::NodePassData), &data ); // if our result is a visible renderable then set our bounds on our output gdp const IECore::Object *result = op->resultParameter()->getValue(); IECore::ConstVisibleRenderablePtr renderable = IECore::runTimeCast<const IECore::VisibleRenderable>( result ); if ( renderable ) { Imath::Box3f bbox = renderable->bound(); gdp->cube( bbox.min.x, bbox.max.x, bbox.min.y, bbox.max.y, bbox.min.z, bbox.max.z, 0, 0, 0, 1, 1 ); } } catch( boost::python::error_already_set ) { addError( SOP_MESSAGE, "Error raised during Python evaluation!" ); IECorePython::ScopedGILLock lock; PyErr_Print(); } catch( const IECore::Exception &e ) { addError( SOP_MESSAGE, e.what() ); } catch( const std::exception &e ) { addError( SOP_MESSAGE, e.what() ); } catch( ... ) { addError( SOP_MESSAGE, "Caught unknown exception!" ); } // tidy up & go home! boss->opEnd(); unlockInputs(); return error(); }