void SOP_CortexConverter::doConvert( const GU_DetailHandle &handle, const std::string &name, ResultType type, const std::string &attributeFilter, bool convertStandardAttributes ) { if ( handle.isNull() ) { addError( SOP_MESSAGE, ( "Could not extract the geometry named " + name ).c_str() ); return; } FromHoudiniGeometryConverterPtr fromConverter = FromHoudiniGeometryConverter::create( handle ); if ( !fromConverter ) { addError( SOP_MESSAGE, ( "Could not convert the geometry named " + name ).c_str() ); return; } IECore::ObjectPtr result = fromConverter->convert(); if ( !result ) { addError( SOP_MESSAGE, ( "Could not find Cortex Object named " + name + " on input geometry" ).c_str() ); return; } if ( IECore::ParameterisedProcedural *procedural = IECore::runTimeCast<IECore::ParameterisedProcedural>( result.get() ) ) { 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.get() ); } } result = boost::const_pointer_cast<IECore::Object>( IECore::runTimeCast<const IECore::Object>( renderer->world() ) ); } ToHoudiniGeometryConverterPtr converter = ( type == Cortex ) ? new ToHoudiniCortexObjectConverter( result.get() ) : ToHoudiniGeometryConverter::create( result.get() ); converter->nameParameter()->setTypedValue( name ); converter->attributeFilterParameter()->setTypedValue( attributeFilter ); converter->convertStandardAttributesParameter()->setTypedValue( convertStandardAttributes ); if ( !converter->convert( myGdpHandle ) ) { addError( SOP_MESSAGE, ( "Could not convert the Cortex Object named " + name + " to Houdini geometry" ).c_str() ); } }
MStatus NumericParameterHandler<T>::doUpdate( IECore::ConstParameterPtr parameter, MPlug &plug ) const { typename IECore::NumericParameter<T>::ConstPtr p = IECore::runTimeCast<const IECore::NumericParameter<T> >( parameter ); if( !p ) { return MS::kFailure; } MObject attribute = plug.attribute(); MFnNumericAttribute fnNAttr( attribute ); if( !fnNAttr.hasObj( attribute ) ) { return MS::kFailure; } if( fnNAttr.unitType() != NumericTraits<T>::dataType() ) { return MS::kFailure; } fnNAttr.setDefault( p->numericDefaultValue() ); if( p->minValue()!=Imath::limits<T>::min() ) { fnNAttr.setMin( p->minValue() ); } else { // parameter has no min value if( fnNAttr.hasMin() ) { // there is no way of unsetting a minimum value // in maya. return MS::kFailure; } } if( p->maxValue()!=Imath::limits<T>::max() ) { fnNAttr.setMax( p->maxValue() ); } else { // parameter has no max value if( fnNAttr.hasMax() ) { // there is no way of unsetting a maximum value // in maya. return MS::kFailure; } } T v; MStatus result = plug.getValue( v ); if( result ) { IECore::ObjectPtr d = new IECore::TypedData<T>( v ); if( !parameter->valueValid( d.get() ) ) { return MS::kFailure; } } bool keyable = true; bool channelBox = true; const IECore::ConstCompoundObjectPtr userData = parameter->userData(); assert( userData ); const IECore::ConstCompoundObjectPtr maya = userData->member<const IECore::CompoundObject>("maya"); if (maya) { const IECore::ConstBoolDataPtr keyableData = maya->member<const IECore::BoolData>("keyable"); if (keyableData) { keyable = keyableData->readable(); } const IECore::ConstBoolDataPtr channelBoxData = maya->member<const IECore::BoolData>("channelBox"); if (channelBoxData) { channelBox = channelBoxData->readable(); } } fnNAttr.setKeyable( keyable ); // Calling setChannelBox(true) disables keying if (!keyable) { fnNAttr.setChannelBox( channelBox ); } return finishUpdating( parameter, plug ); }