MStatus ObjectParameterHandler::doSetValue( const MPlug &plug, IECore::ParameterPtr parameter ) const { IECore::ObjectParameterPtr p = IECore::runTimeCast<IECore::ObjectParameter>( parameter ); if( !p ) { return MS::kFailure; } /// Keep trying all the available handlers until we find one that works for (IECore::ObjectParameter::TypeIdSet::const_iterator it = p->validTypes().begin(); it != p->validTypes().end(); ++it) { ConstParameterHandlerPtr h = ParameterHandler::create( *it ); if (h) { if ( h->doSetValue( plug, parameter ) ) { return MS::kSuccess; } } } MStatus s; MObject plugData; s = plug.getValue( plugData ); if (!s) { // We might be here as the attribute isn't storable, // in that case we set the parameter to its default value. // If it is storable, then something has gone awry. MFnAttribute fnA( plug.attribute() ); bool isStorable = fnA.isStorable( &s ); if( s && !isStorable ) { parameter->setValue( parameter->defaultValue()->copy() ); return MS::kSuccess; } else { return MS::kFailure; } } MFnPluginData fnData( plugData, &s ); if (!s) { return MS::kFailure; } ObjectData *data = dynamic_cast<ObjectData *>( fnData.data( &s ) ); if (!data || !s) { return MS::kFailure; } parameter->setValue( data->getObject() ); return MS::kSuccess; }
MStatus ClassParameterHandler::doSetValue( const MPlug &plug, IECore::ParameterPtr parameter ) const { if( !parameter || !parameter->isInstanceOf( IECore::ClassParameterTypeId ) ) { return MS::kFailure; } return MS::kSuccess; }
MStatus TransformationMatrixParameterHandler<T>::doSetValue( const MPlug &plug, IECore::ParameterPtr parameter ) const { typename IECore::TypedParameter<IECore::TransformationMatrix<T> >::Ptr p = IECore::runTimeCast<IECore::TypedParameter<IECore::TransformationMatrix<T> > >( parameter ); if( !p ) { return MS::kFailure; } IECore::TransformationMatrix<T> tMatrix = p->getTypedValue(); if( tMatrix.rotate.order() != Imath::Euler<T>::XYZ ) { IECore::msg( IECore::Msg::Error, "TransformationMatrixParameterHandler::doSetValue", "The rotation order of the parameter '"+parameter->name()+"' is not XYZ, unable to set value." ); return MS::kFailure; } std::vector<Imath::Vec3<T> > v; v.resize(8); for( unsigned int i=0; i<8; i++ ) { if( !getVecValues( plug.child(i), v[i] ) ) return MS::kFailure; } tMatrix.translate = v[ TRANSLATE_INDEX ]; tMatrix.rotate = Imath::Euler<T>(v[ ROTATE_INDEX ]); tMatrix.scale = v[ SCALE_INDEX ]; tMatrix.shear = v[ SHEAR_INDEX ]; tMatrix.scalePivot = v[ SCALEPIVOT_INDEX ]; tMatrix.scalePivotTranslation = v[ SCALEPIVOTTRANS_INDEX ]; tMatrix.rotatePivot = v[ ROTATEPIVOT_INDEX ]; tMatrix.rotatePivotTranslation = v[ ROTATEPIVOTTRANS_INDEX ]; p->setTypedValue( tMatrix ); return MS::kSuccess; }
MStatus ParameterisedHolder<B>::createOrUpdateAttribute( IECore::ParameterPtr parameter, const MString &attributeName, bool callRestore ) { MObject node = B::thisMObject(); MFnDependencyNode fnDN( node ); MPlugArray connectionsFromMe, connectionsToMe; // try to reuse an old plug if we can MPlug plug = fnDN.findPlug( attributeName, false /* no networked plugs please */ ); if( !plug.isNull() ) { MStatus s = MS::kSuccess; if( callRestore ) { ParameterHandler::restore( plug, parameter ); } if( s ) { s = IECoreMaya::ParameterHandler::update( parameter, plug ); if( s ) { return MS::kSuccess; } } // failed to restore and/or update (parameter type probably changed). // remove the current attribute and fall through to the create // code // remember connections so we can remake them for the new // attribute. we have to be careful to only store non-networked plugs as // networked plugs are invalidated by the removal of the attribute. nonNetworkedConnections( plug, connectionsFromMe, connectionsToMe ); fnDN.removeAttribute( plug.attribute() ); } // reuse failed - create a new attribute /// \todo: update ParameterisedHolder to accept null plugs when the todo in ParameterHandler::create is addressed plug = IECoreMaya::ParameterHandler::create( parameter, attributeName, node ); if( plug.isNull() ) { msg( Msg::Error, "ParameterisedHolder::createOrUpdateAttribute", boost::format( "Failed to create attribute to represent parameter \"%s\" of type \"%s\"" ) % parameter->name() % parameter->typeName() ); return MS::kFailure; } // restore any existing connections if( connectionsFromMe.length() || connectionsToMe.length() ) { MDGModifier dgMod; for (unsigned i = 0; i < connectionsFromMe.length(); i++) { dgMod.connect( plug, connectionsFromMe[i] ); } for (unsigned i = 0; i < connectionsToMe.length(); i++) { dgMod.connect( connectionsToMe[i], plug ); } dgMod.doIt(); } /// and set the value of the attribute, in case it differs from the default return IECoreMaya::ParameterHandler::setValue( parameter, plug ); }
bool ParameterisedHolder<B>::setParameterisedValuesWalk( bool lazy, IECore::ParameterPtr parameter, MStatus &status ) { MFnDependencyNode fnDN( B::thisMObject() ); // traverse child parameters if we have them bool childParametersWereSet = false; if( parameter->isInstanceOf( CompoundParameter::staticTypeId() ) ) { CompoundParameterPtr compoundParameter = boost::static_pointer_cast<CompoundParameter>( parameter ); const CompoundParameter::ParameterVector &childParameters = compoundParameter->orderedParameters(); for( CompoundParameter::ParameterVector::const_iterator cIt=childParameters.begin(); cIt!=childParameters.end(); cIt++ ) { bool b = setParameterisedValuesWalk( lazy, *cIt, status ); childParametersWereSet = childParametersWereSet || b; } } // then set this parameter if necessary bool thisParameterWasSet = false; if( parameter->name()!="" && (!lazy || m_dirtyParameters.find( parameter )!=m_dirtyParameters.end()) ) { ParameterToAttributeNameMap::const_iterator nIt = m_parametersToAttributeNames.find( parameter ); if( nIt==m_parametersToAttributeNames.end() ) { msg( Msg::Error, "ParameterisedHolder::setParameterisedValues", boost::format( "Unable to find plug name for parameter %s" ) % parameter->name() ); status = MS::kFailure; } else { MPlug p = fnDN.findPlug( nIt->second ); if( p.isNull() ) { msg( Msg::Error, "ParameterisedHolder::setParameterisedValues", boost::format( "Unable to find plug for parameter %s" ) % parameter->name() ); status = MS::kFailure; } else { try { MStatus s = ParameterHandler::setValue( p, parameter ); if( !s ) { msg( Msg::Error, "ParameterisedHolder::setParameterisedValues", boost::format( "Failed to set parameter value from %s" ) % p.name().asChar() ); status = s; } else { m_dirtyParameters.erase( parameter ); thisParameterWasSet = true; } } catch( std::exception &e ) { msg( Msg::Error, "ParameterisedHolder::setParameterisedValues", boost::format( "Caught exception while setting parameter value from %s : %s" ) % p.name().asChar() % e.what()); status = MS::kFailure; } catch( ... ) { msg( Msg::Error, "ParameterisedHolder::setParameterisedValues", boost::format( "Caught unknown exception while setting parameter value from %s" ) % p.name().asChar() ); status = MS::kFailure; } } } } // increment the updateCount if necessary if( thisParameterWasSet || childParametersWereSet ) { CompoundObjectPtr userData = parameter->userData(); IntDataPtr updateCount = userData->member<IntData>( "updateCount" ); if( !updateCount ) { updateCount = new IntData( 0 ); userData->members()["updateCount"] = updateCount; } else { updateCount->writable()++; } } return childParametersWereSet || thisParameterWasSet; }
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() ); } } } }