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;
}
Ejemplo n.º 2
0
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 );
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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() );
			}
		}
	}
}