neuray API Programmer's Manual

argument_editor.h File Reference

Description

Utility class for MDL material instances and function calls.

Code Example

argument_editor.h

‎/***************************************************************************************************
 * Copyright 2024 NVIDIA Corporation. All rights reserved.
 **************************************************************************************************/

#ifndef MI_NEURAYLIB_ARGUMENT_EDITOR_H
#define MI_NEURAYLIB_ARGUMENT_EDITOR_H

#include <mi/base/handle.h>
#include <mi/neuraylib/assert.h>
#include <mi/neuraylib/iexpression.h>
#include <mi/neuraylib/ifunction_call.h>
#include <mi/neuraylib/imaterial_instance.h>
#include <mi/neuraylib/imdl_factory.h>
#include <mi/neuraylib/imdl_evaluator_api.h>
#include <mi/neuraylib/itransaction.h>
#include <mi/neuraylib/itype.h>
#include <mi/neuraylib/ivalue.h>

#include <string>

namespace mi {

namespace neuraylib {

class IMdl_execution_context;
























class Argument_editor
{
public:



    Argument_editor(
        ITransaction* transaction,
        const char* name,
        IMdl_factory* mdl_factory,
        bool intent_to_edit = false);

    bool is_valid() const;

    bool is_valid_instance( IMdl_execution_context* context) const;

    mi::Sint32 
               repair( mi::Uint32 flags, IMdl_execution_context* context);

    Element_type 
               get_type() const;

    const char* get_definition() const;

    const char* get_mdl_definition() const;

    bool is_array_constructor() const;

    bool is_declarative() const;

    bool is_material() const;

    const IType* get_return_type() const;

    Size 
               get_parameter_count() const;

    const char* get_parameter_name( Size index) const;

    Size 
               get_parameter_index( const char* name) const;

    const IType_list* get_parameter_types() const;

    bool is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const;

    const IExpression_list* get_arguments() const;

    IExpression::Kind 
               get_argument_kind( Size parameter_index) const;

    IExpression::Kind 
               get_argument_kind( const char* parameter_name) const;




    Sint32 
               reset_argument( Size index);

    Sint32 
               reset_argument( const char* name);




    template<class T>
    Sint32 
               get_value( Size parameter_index, T& value) const;

    template <class T>
    Sint32 
               get_value( const char* parameter_name, T& value) const;




    template<class T>
    Sint32 
               get_value( Size parameter_index, T* value, Size n) const;

    template <class T>
    Sint32 
               get_value( const char* parameter_name, T* value, Size n) const;




    template<class T>
    Sint32 
               get_value( Size parameter_index, Size component_index, T& value) const;

    template<class T>
    Sint32 
               get_value( const char* parameter_name, Size component_index, T& value) const;

    template<class T>
    Sint32 
               get_value( Size parameter_index, const char* field_name, T& value) const;

    template <class T>
    Sint32 
               get_value( const char* parameter_name, const char* field_name, T& value) const;




    template<class T>
    Sint32 
               set_value( Size parameter_index, const T& value);

    template <class T>
    Sint32 
               set_value( const char* parameter_name, const T& value);




    template<class T>
    Sint32 
               set_value( Size parameter_index, const T* value, Size n);

    template <class T>
    Sint32 
               set_value( const char* parameter_name, const T* value, Size n);




    template<class T>
    Sint32 
               set_value( Size parameter_index, Size component_index, const T& value);

    template <class T>
    Sint32 
               set_value( const char* parameter_name, Size component_index, const T& value);

    template<class T>
    Sint32 
               set_value( Size parameter_index, const char* field_name, const T& value);

    template <class T>
    Sint32 
               set_value( const char* parameter_name, const char* field_name, const T& value);




    Sint32 
               get_array_length( Uint32 parameter_index, Size& size) const;

    Sint32 
               get_array_length( const char* parameter_name, Size& size) const;

    Sint32 
               set_array_size( Uint32 parameter_index, Size size);

    Sint32 
               set_array_size( const char* parameter_name, Size size);




    const char* get_call( Size parameter_index) const;

    const char* get_call( const char* parameter_name) const;

    Sint32 
               set_call( Size parameter_index, const char* call_name);

    Sint32 
               set_call( const char* parameter_name, const char* call_name);




    ITransaction* get_transaction() const;

    IMdl_factory* get_mdl_factory() const;

    IValue_factory* get_value_factory() const;

    IExpression_factory* get_expression_factory() const;

    const IFunction_call* get_scene_element() const;

    IFunction_call* get_scene_element();

    Element_type 
               get_element_type() const;

    const std::string& get_name() const;


private:
    void promote_to_edit_if_needed();

    base::Handle< ITransaction> m_transaction;
    base::Handle< IMdl_factory> m_mdl_factory;
    base::Handle< IValue_factory> m_value_factory;
    base::Handle< IExpression_factory> m_expression_factory;
    base::Handle< const IFunction_call> m_access;
    base::Handle< const IFunction_call> m_old_access;
    base::Handle< IFunction_call> m_edit;
    Element_type m_type;
    std::string m_name;
};
 // end group mi_neuray_mdl_elements

inline Argument_editor::Argument_editor(
    ITransaction* transaction, const char* name, IMdl_factory* mdl_factory, bool intent_to_edit)
{
    mi_neuray_assert( transaction);
    mi_neuray_assert( name);

    m_transaction = make_handle_dup( transaction);
    m_name = name;
    m_mdl_factory = make_handle_dup( mdl_factory);
    m_value_factory
        = m_mdl_factory ? m_mdl_factory->create_value_factory( m_transaction.get()) : 0;
    m_expression_factory
        = m_mdl_factory ? m_mdl_factory->create_expression_factory( m_transaction.get()) : 0;

    if( intent_to_edit) {
        m_edit = transaction->edit<IFunction_call>( name);
        m_access = m_edit;
        m_old_access = m_edit;
        m_type = m_access ? m_access->get_element_type() : static_cast<Element_type>( 0);
    } else {
        m_access = transaction->access<IFunction_call>( name);
        m_type = m_access ? m_access->get_element_type() : static_cast<Element_type>( 0);
    }
}

inline bool Argument_editor::is_valid() const
{
    return m_access.is_valid_interface();
}

inline bool Argument_editor::is_valid_instance( IMdl_execution_context* context) const
{
    if( !is_valid())
        return false;

    return m_access->is_valid( context);
}

inline mi::Sint32 
               Argument_editor::repair( mi::Uint32 flags, IMdl_execution_context* context)
{
    if( !is_valid())
        return false;

    promote_to_edit_if_needed();

    return m_edit->repair( flags, context);
}

inline Element_type 
               Argument_editor::get_type() const
{
    return m_type;
}

inline const char* Argument_editor::get_definition() const
{
    if( !is_valid())
        return 0;

    return m_access->get_function_definition();
}

inline const char* Argument_editor::get_mdl_definition() const
{
    if( !is_valid())
        return 0;

    return m_access->get_mdl_function_definition();
}

inline bool Argument_editor::is_array_constructor() const
{
    if( !is_valid())
        return false;

    return m_access->is_array_constructor();
}

inline bool Argument_editor::is_declarative() const
{
    if( !is_valid())
        return false;

    return m_access->is_declarative();
}

inline bool Argument_editor::is_material() const
{
    if( !is_valid())
        return false;

    return m_access->is_material();
}

inline Size 
               Argument_editor::get_parameter_count() const
{
    if( !is_valid())
        return 0;

    return m_access->get_parameter_count();
}

inline const char* Argument_editor::get_parameter_name( Size parameter_index) const
{
    if( !is_valid())
        return 0;

    return m_access->get_parameter_name( parameter_index);
}

inline Size 
               Argument_editor::get_parameter_index( const char* name) const
{
    if( !is_valid())
        return 0;

    return m_access->get_parameter_index( name);
}

inline const IType* Argument_editor::get_return_type() const
{
    if( !is_valid())
        return 0;

    return m_access->get_return_type();
}

inline const IType_list* Argument_editor::get_parameter_types() const
{
    if( !is_valid())
        return 0;

    return m_access->get_parameter_types();
}

inline bool Argument_editor::is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const
{
    if( !evaluator)
        return true;

    if( !is_valid())
        return true;

    base::Handle< const IValue_bool> b( evaluator->is_function_parameter_enabled(
        m_transaction.get(), m_value_factory.get(), m_access.get(), index, /*errors*/ 0));
    if( !b)
        return true;
    return b->get_value();
}

inline Sint32 
               Argument_editor::reset_argument( Size index)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    return m_edit->reset_argument( index);
}

inline Sint32 
               Argument_editor::reset_argument( const char* name)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    return m_edit->reset_argument( name);
}


inline const IExpression_list* Argument_editor::get_arguments() const
{
    if( !is_valid())
        return 0;

    return m_access->get_arguments();
}

inline IExpression::Kind 
               Argument_editor::get_argument_kind( Size parameter_index) const
{
    if( !is_valid())
        return static_cast<IExpression::Kind>( 0);

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
}

inline IExpression::Kind 
               Argument_editor::get_argument_kind( const char* parameter_name) const
{
    if( !is_valid())
        return static_cast<IExpression::Kind>( 0);

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
}

template <class T>
Sint32 
               Argument_editor::get_value( Size parameter_index, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), value);
    return result == 0 ? 0 : -5;
}

template <class T>
Sint32 
               Argument_editor::get_value( const char* name, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument_( arguments->get_expression( name));
    if( !argument_)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument_->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), value);
    return result == 0 ? 0 : -5;
}

template <class T>
Sint32 
               Argument_editor::get_value( Size parameter_index, T* value, Size n) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), value, n);
    return result == 0 ? 0 : -5;
}

template <class T>
Sint32 
               Argument_editor::get_value( const char* name, T* value, Size n) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument_( arguments->get_expression( name));
    if( !argument_)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument_->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), value, n);
    return result == 0 ? 0 : -5;
}

template <class T>
Sint32 
               Argument_editor::get_value( Size parameter_index, Size component_index, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
    return result == 0 ? 0 : (result == -3 ? -3 : -5);
}

template <class T>
Sint32 
               Argument_editor::get_value( const char* parameter_name, Size component_index, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
    return result == 0 ? 0 : (result == -3 ? -3 : -5);
}

template <class T>
Sint32 
               Argument_editor::get_value(
    Size parameter_index, const char* field_name, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
    return result == 0 ? 0 : (result == -3 ? -3 : -5);
}

template <class T>
Sint32 
               Argument_editor::get_value(
    const char* parameter_name, const char* field_name, T& value) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue> argument_value( argument_constant->get_value());
    Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
    return result == 0 ? 0 : (result == -3 ? -3 : -5);
}

template <class T>
Sint32 
               Argument_editor::set_value( Size parameter_index, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IType> type( argument->get_type());
    base::Handle< IValue> new_value( m_value_factory->create( type.get()));
    Sint32 result = neuraylib::set_value( new_value.get(), value);
    if( result != 0)
        return -5;
    base::Handle< IExpression> new_expression(
        m_expression_factory->create_constant( new_value.get()));
    result = m_edit->set_argument( parameter_index, new_expression.get());
    mi_neuray_assert( result == 0);
    return result;
}

template <class T>
Sint32 
               Argument_editor::set_value( const char* parameter_name, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    base::Handle< const IType> type( argument->get_type());
    base::Handle< IValue> new_value( m_value_factory->create( type.get()));
    Sint32 result = neuraylib::set_value( new_value.get(), value);
    if( result != 0)
        return -5;
    base::Handle< IExpression> new_expression(
        m_expression_factory->create_constant( new_value.get()));
    result = m_edit->set_argument( parameter_name, new_expression.get());
    mi_neuray_assert( result == 0);
    return result;
}

template <class T>
Sint32 
               Argument_editor::set_value( Size parameter_index, const T* value, Size n)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IType_array> type( argument->get_type<IType_array>());
    base::Handle< IValue_array> new_value( m_value_factory->create_array( type.get()));
    if( !new_value)
        return -5;
    if( !type->is_immediate_sized())
        new_value->set_size( n);
    Sint32 result = neuraylib::set_value( new_value.get(), value, n);
    if( result != 0)
        return -5;
    base::Handle< IExpression> new_expression(
        m_expression_factory->create_constant( new_value.get()));
    result = m_edit->set_argument( parameter_index, new_expression.get());
    mi_neuray_assert( result == 0);
    return result;
}

template <class T>
Sint32 
               Argument_editor::set_value( const char* parameter_name, const T* value, Size n)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    base::Handle< const IType_array> type( argument->get_type<IType_array>());
    base::Handle< IValue_array> new_value( m_value_factory->create_array( type.get()));
    if( !new_value)
        return -5;
    if( !type->is_immediate_sized())
        new_value->set_size( n);
    Sint32 result = neuraylib::set_value( new_value.get(), value, n);
    if( result != 0)
        return -5;
    base::Handle< IExpression> new_expression(
        m_expression_factory->create_constant( new_value.get()));
    result = m_edit->set_argument( parameter_name, new_expression.get());
    mi_neuray_assert( result == 0);
    return result;
}

template <class T>
Sint32 
               Argument_editor::set_value( Size parameter_index, Size component_index, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue> new_value( new_argument_constant->get_value());
        Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        result = m_edit->set_argument( parameter_index, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue> new_value( m_value_factory->create( type.get()));
        Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_index, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

template <class T>
Sint32 
               Argument_editor::set_value( const char* parameter_name, Size component_index, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue> new_value( new_argument_constant->get_value());
        Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        result = m_edit->set_argument( parameter_name, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue> new_value( m_value_factory->create( type.get()));
        Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_name, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

template <class T>
Sint32 
               Argument_editor::set_value(
    Size parameter_index, const char* field_name, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue> new_value( new_argument_constant->get_value());
        Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        result = m_edit->set_argument( parameter_index, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue> new_value( m_value_factory->create( type.get()));
        Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_index, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

template <class T>
Sint32 
               Argument_editor::set_value(
    const char* parameter_name, const char* field_name, const T& value)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue> new_value( new_argument_constant->get_value());
        Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        result = m_edit->set_argument( parameter_name, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue> new_value( m_value_factory->create( type.get()));
        Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
        if( result != 0)
            return result == -3 ? -3 : -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_name, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

inline Sint32 
               Argument_editor::get_array_length( Uint32 parameter_index, Size& size) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue_array> value( argument_constant->get_value<IValue_array>());
    if( !value)
        return -5;
    size = value->get_size();
    return 0;
}

inline Sint32 
               Argument_editor::get_array_length( const char* parameter_name, Size& size) const
{
    if( !is_valid())
        return -1;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    base::Handle< const IExpression_constant> argument_constant(
        argument->get_interface<IExpression_constant>());
    if( !argument_constant)
        return -4;
    base::Handle< const IValue_array> value( argument_constant->get_value<IValue_array>());
    if( !value)
        return -5;
    size = value->get_size();
    return 0;
}

inline Sint32 
               Argument_editor::set_array_size( Uint32 parameter_index, Size size)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_index));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue_array> new_value(
            new_argument_constant->get_value<IValue_array>());
        if( !new_value)
            return -5;
        Sint32 result = new_value->set_size( size);
        if( result != 0)
            return -5;
        result = m_edit->set_argument( parameter_index, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue_array> new_value(
            m_value_factory->create<IValue_array>( type.get()));
        if( !new_value)
            return -5;
        Sint32 result = new_value->set_size( size);
        if( result != 0)
            return -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_index, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

inline Sint32 
               Argument_editor::set_array_size( const char* parameter_name, Size size)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    if( m_edit->is_default())
        return -4;
    base::Handle< const IExpression_list> arguments( m_edit->get_arguments());
    base::Handle< const IExpression> argument( arguments->get_expression( parameter_name));
    if( !argument)
        return -2;
    if( argument->get_kind() == IExpression::EK_CONSTANT) {
        // reuse existing constant expression
        base::Handle< IExpression> new_argument( m_expression_factory->clone( argument.get()));
        base::Handle< IExpression_constant> new_argument_constant(
            new_argument->get_interface<IExpression_constant>());
        base::Handle< IValue_array> new_value(
            new_argument_constant->get_value<IValue_array>());
        if( !new_value)
            return -5;
        Sint32 result = new_value->set_size( size);
        if( result != 0)
            return -5;
        result = m_edit->set_argument( parameter_name, new_argument.get());
        mi_neuray_assert( result == 0);
        return result;
    } else {
        // create new constant expression
        base::Handle< const IType> type( argument->get_type());
        base::Handle< IValue_array> new_value(
            m_value_factory->create<IValue_array>( type.get()));
        if( !new_value)
            return -5;
        Sint32 result = new_value->set_size( size);
        if( result != 0)
            return -5;
        base::Handle< IExpression> new_expression(
            m_expression_factory->create_constant( new_value.get()));
        result = m_edit->set_argument( parameter_name, new_expression.get());
        mi_neuray_assert( result == 0);
        return result;
    }
}

inline const char* Argument_editor::get_call( Size parameter_index) const
{
    if( !is_valid())
        return 0;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression_call> argument(
        arguments->get_expression<IExpression_call>( parameter_index));
    if( !argument)
        return 0;
    return argument->get_call();
}

inline const char* Argument_editor::get_call( const char* parameter_name) const
{
    if( !is_valid())
        return 0;

    base::Handle< const IExpression_list> arguments( m_access->get_arguments());
    base::Handle< const IExpression_call> argument(
        arguments->get_expression<IExpression_call>( parameter_name));
    if( !argument)
        return 0;
    return argument->get_call();
}

inline Sint32 
               Argument_editor::set_call( Size parameter_index, const char* call_name)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    base::Handle< IExpression_call> new_argument( m_expression_factory->create_call( call_name));
    if( !new_argument)
        return -6;
    return m_edit->set_argument( parameter_index, new_argument.get());
}

inline Sint32 
               Argument_editor::set_call( const char* parameter_name, const char* call_name)
{
    if( !is_valid())
        return -1;

    promote_to_edit_if_needed();

    base::Handle< IExpression_call> new_argument( m_expression_factory->create_call( call_name));
    if( !new_argument)
        return -6;
    return m_edit->set_argument( parameter_name, new_argument.get());
}

inline ITransaction* Argument_editor::get_transaction() const
{
    m_transaction->retain();
    return m_transaction.get();
}

inline IMdl_factory* Argument_editor::get_mdl_factory() const
{
    m_mdl_factory->retain();
    return m_mdl_factory.get();
}

inline IValue_factory* Argument_editor::get_value_factory() const
{
    m_value_factory->retain();
    return m_value_factory.get();
}

inline IExpression_factory* Argument_editor::get_expression_factory() const
{
    m_expression_factory->retain();
    return m_expression_factory.get();
}

inline const IFunction_call* Argument_editor::get_scene_element() const
{
    m_access->retain();
    return m_access.get();
}

inline IFunction_call* Argument_editor::get_scene_element() //-V659 PVS
{
    promote_to_edit_if_needed();

    m_edit->retain();
    return m_edit.get();
}

inline Element_type 
               Argument_editor::get_element_type() const
{
    return m_type;
}

inline const std::string& Argument_editor::get_name() const
{
    return m_name;
}

inline void Argument_editor::promote_to_edit_if_needed()
{
    if( m_edit)
        return;

    m_edit = m_transaction->edit<IFunction_call>( m_name.c_str());
    mi_neuray_assert( m_edit);
    m_old_access = m_access;
    m_access = m_edit;
}

} // namespace neuraylib

} // namespace mi

#endif // MI_NEURAYLIB_ARGUMENT_EDITOR_H

Namespaces

namespace 
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
namespace 
Namespace for the neuray API. More...

Classes

class 
A wrapper around the interface for MDL material instances and function calls. More...