Material Definition Language API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
argument_editor.h
Go to the documentation of this file.
1 /***************************************************************************************************
2  * Copyright 2020 NVIDIA Corporation. All rights reserved.
3  **************************************************************************************************/
6 
7 #ifndef MI_NEURAYLIB_ARGUMENT_EDITOR_H
8 #define MI_NEURAYLIB_ARGUMENT_EDITOR_H
9 
10 #include <mi/base/handle.h>
11 #include <mi/neuraylib/assert.h>
18 #include <mi/neuraylib/itype.h>
19 #include <mi/neuraylib/ivalue.h>
20 
21 #include <string>
22 
23 namespace mi {
24 
25 namespace neuraylib {
26 
27 class IMdl_execution_context;
28 
33 class Argument_editor
53 {
54 public:
55 
57 
58 
65  Argument_editor( ITransaction* transaction, const char* name, IMdl_factory* mdl_factory);
66 
72  bool is_valid() const;
73 
82  bool is_valid_instance(IMdl_execution_context* context) const;
83 
92  mi::Sint32 repair(mi::Uint32 flags, IMdl_execution_context* context);
93 
99  Element_type get_type() const;
100 
102  const char* get_definition() const;
103 
105  const char* get_mdl_definition() const;
106 
111  bool is_array_constructor() const;
112 
116  const IType* get_return_type() const;
117 
119  Size get_parameter_count() const;
120 
125  const char* get_parameter_name( Size index) const;
126 
131  Size get_parameter_index( const char* name) const;
132 
134  const IType_list* get_parameter_types() const;
135 
142  bool is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const;
143 
145  const IExpression_list* get_arguments() const;
146 
152  IExpression::Kind get_argument_kind( Size parameter_index) const;
153 
159  IExpression::Kind get_argument_kind( const char* parameter_name) const;
160 
162 
164 
178  template<class T>
179  Sint32 get_value( Size parameter_index, T& value) const;
180 
191  template <class T>
192  Sint32 get_value( const char* parameter_name, T& value) const;
193 
209  template<class T>
210  Sint32 get_value( Size parameter_index, Size component_index, T& value) const;
211 
224  template <class T>
225  Sint32 get_value( const char* parameter_name, Size component_index, T& value) const;
226 
242  template<class T>
243  Sint32 get_value( Size parameter_index, const char* field_name, T& value) const;
244 
257  template <class T>
258  Sint32 get_value( const char* parameter_name, const char* field_name, T& value) const;
259 
274  template<class T>
275  Sint32 set_value( Size parameter_index, const T& value);
276 
288  template <class T>
289  Sint32 set_value( const char* parameter_name, const T& value);
290 
310  template<class T>
311  Sint32 set_value( Size parameter_index, Size component_index, const T& value);
312 
329  template <class T>
330  Sint32 set_value( const char* parameter_name, Size component_index, const T& value);
331 
348  template<class T>
349  Sint32 set_value( Size parameter_index, const char* field_name, const T& value);
350 
364  template <class T>
365  Sint32 set_value( const char* parameter_name, const char* field_name, const T& value);
366 
380  Sint32 get_array_length( Uint32 parameter_index, Size& size) const;
381 
392  Sint32 get_array_length( const char* parameter_name, Size& size) const;
393 
408  Sint32 set_array_size( Uint32 parameter_index, Size size);
409 
421  Sint32 set_array_size( const char* parameter_name, Size size);
422 
424 
426 
435  const char* get_call( Size parameter_index) const;
436 
442  const char* get_call( const char* parameter_name) const;
443 
461  Sint32 set_call( Size parameter_index, const char* call_name);
462 
477  Sint32 set_call( const char* parameter_name, const char* call_name);
478 
480 
482 
484  ITransaction* get_transaction() const;
485 
487  IMdl_factory* get_mdl_factory() const;
488 
490  IValue_factory* get_value_factory() const;
491 
493  IExpression_factory* get_expression_factory() const;
494 
496  const IScene_element* get_scene_element() const;
497 
499  IScene_element* get_scene_element();
500 
503 
505  const std::string& get_name() const;
506 
508 
509 private:
510  void promote_to_edit_if_needed();
511 
512  base::Handle<ITransaction> m_transaction;
513  base::Handle<IMdl_factory> m_mdl_factory;
514  base::Handle<IValue_factory> m_value_factory;
515  base::Handle<IExpression_factory> m_expression_factory;
516  base::Handle<const IScene_element> m_access;
517  base::Handle<const IScene_element> m_old_access;
518  base::Handle<IScene_element> m_edit;
519  Element_type m_type;
520  std::string m_name;
521 };
522  // end group mi_neuray_mdl_elements
524 
526  ITransaction* transaction, const char* name, IMdl_factory* mdl_factory)
527 {
528  mi_neuray_assert( transaction);
529  mi_neuray_assert( name);
530 
531  m_transaction = make_handle_dup( transaction);
532  m_name = name;
533  m_mdl_factory = make_handle_dup( mdl_factory);
534  m_value_factory
535  = m_mdl_factory ? m_mdl_factory->create_value_factory( m_transaction.get()) : 0;
536  m_expression_factory
537  = m_mdl_factory ? m_mdl_factory->create_expression_factory( m_transaction.get()) : 0;
538  m_access = transaction->access<IScene_element>( name);
539  m_type = m_access ? m_access->get_element_type() : static_cast<Element_type>( 0);
540 }
541 
542 inline bool Argument_editor::is_valid() const
543 {
544  return m_access
546 }
547 
549 {
550  if (m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
551 
552  base::Handle<const IMaterial_instance> mi(m_access->get_interface<IMaterial_instance>());
553  return mi->is_valid(context);
554  }
555  else if (m_type == ELEMENT_TYPE_FUNCTION_CALL) {
556 
557  base::Handle<const IFunction_call> fc(m_access->get_interface<IFunction_call>());
558  return fc->is_valid(context);
559  }
560  else
561  return false;
562 }
563 
565 {
566  promote_to_edit_if_needed();
567  if (m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
568  base::Handle<IMaterial_instance> mi(m_edit->get_interface<IMaterial_instance>());
569  return mi->repair(flags, context);
570  }
571  else if (m_type == ELEMENT_TYPE_FUNCTION_CALL) {
572 
573  base::Handle<IFunction_call> fc(m_edit->get_interface<IFunction_call>());
574  return fc->repair(flags, context);
575  }
576  else
577  return -1;
578 }
579 
581 {
582  return m_type;
583 }
584 
585 inline const char* Argument_editor::get_definition() const
586 {
587  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
588 
589  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
590  return mi->get_material_definition();
591 
592  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
593 
594  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
595  return fc->get_function_definition();
596 
597  } else
598  return 0;
599 }
600 
601 inline const char* Argument_editor::get_mdl_definition() const
602 {
603  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
604 
605  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
606  return mi->get_mdl_material_definition();
607 
608  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
609 
610  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
611  return fc->get_mdl_function_definition();
612 
613  } else
614  return 0;
615 }
616 
618 {
619  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
620 
621  return false;
622 
623  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
624 
625  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
626  return fc->is_array_constructor();
627 
628  } else
629  return false;
630 }
631 
633 {
634  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
635 
636  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
637  return mi->get_parameter_count();
638 
639  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
640 
641  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
642  return fc->get_parameter_count();
643 
644  } else
645  return 0;
646 }
647 
648 inline const char* Argument_editor::get_parameter_name( Size parameter_index) const
649 {
650  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
651 
652  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
653  return mi->get_parameter_name( parameter_index);
654 
655  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
656 
657  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
658  return fc->get_parameter_name( parameter_index);
659 
660  } else
661  return 0;
662 }
663 
664 inline Size Argument_editor::get_parameter_index( const char* name) const
665 {
666  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
667 
668  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
669  return mi->get_parameter_index( name);
670 
671  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
672 
673  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
674  return fc->get_parameter_index( name);
675 
676  } else
677  return 0;
678 }
679 
681 {
682  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
683 
684  return 0;
685 
686  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
687 
688  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
689  return fc->get_return_type();
690 
691  } else
692  return 0;
693 }
694 
696 {
697  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
698 
699  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
700  return mi->get_parameter_types();
701 
702  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
703 
704  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
705  return fc->get_parameter_types();
706 
707  } else
708  return 0;
709 }
710 
711 inline bool Argument_editor::is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const
712 {
713  if( !evaluator)
714  return true;
715 
716  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
717 
718  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
720  m_transaction.get(), m_value_factory.get(), mi.get(), index, /*error*/ NULL));
721  if (!b)
722  return true;
723  return b->get_value();
724 
725  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
726 
727  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
729  m_transaction.get(), m_value_factory.get(), fc.get(), index, /*error*/ NULL));
730  if (!b)
731  return true;
732  return b->get_value();
733 
734  } else
735  return true;
736 }
737 
738 
740 {
741  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
742 
743  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
744  return mi->get_arguments();
745 
746  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
747 
748  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
749  return fc->get_arguments();
750 
751  } else
752  return 0;
753 }
754 
756 {
757  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
758 
759  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
760  base::Handle<const IExpression_list> arguments( mi->get_arguments());
761  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
762  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
763 
764  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
765 
766  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
767  base::Handle<const IExpression_list> arguments( fc->get_arguments());
768  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
769  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
770 
771  } else
772  return static_cast<IExpression::Kind>( 0);
773 }
774 
775 inline IExpression::Kind Argument_editor::get_argument_kind( const char* parameter_name) const
776 {
777  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
778 
779  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
780  base::Handle<const IExpression_list> arguments( mi->get_arguments());
781  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
782  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
783 
784  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
785 
786  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
787  base::Handle<const IExpression_list> arguments( fc->get_arguments());
788  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
789  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
790 
791  } else
792  return static_cast<IExpression::Kind>( 0);
793 }
794 
795 template <class T>
796 Sint32 Argument_editor::get_value( Size parameter_index, T& value) const
797 {
798  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
799 
800  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
801  base::Handle<const IExpression_list> arguments( mi->get_arguments());
802  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
803  if( !argument)
804  return -2;
806  argument->get_interface<IExpression_constant>());
807  if( !argument_constant)
808  return -4;
809  base::Handle<const IValue> argument_value( argument_constant->get_value());
810  Sint32 result = neuraylib::get_value( argument_value.get(), value);
811  return result == 0 ? 0 : -5;
812 
813  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
814 
815  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
816  base::Handle<const IExpression_list> arguments( fc->get_arguments());
817  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
818  if( !argument)
819  return -2;
821  argument->get_interface<IExpression_constant>());
822  if( !argument_constant)
823  return -4;
824  base::Handle<const IValue> argument_value( argument_constant->get_value());
825  Sint32 result = neuraylib::get_value( argument_value.get(), value);
826  return result == 0 ? 0 : -5;
827 
828  } else
829  return -1;
830 }
831 
832 template <class T>
833 Sint32 Argument_editor::get_value( const char* name, T& value) const
834 {
835  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
836 
837  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
838  base::Handle<const IExpression_list> arguments( mi->get_arguments());
839  base::Handle<const IExpression> argument_( arguments->get_expression( name));
840  if( !argument_)
841  return -2;
843  argument_->get_interface<IExpression_constant>());
844  if( !argument_constant)
845  return -4;
846  base::Handle<const IValue> argument_value( argument_constant->get_value());
847  Sint32 result = neuraylib::get_value( argument_value.get(), value);
848  return result == 0 ? 0 : -5;
849 
850  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
851 
853  m_access->get_interface<IFunction_call>());
854  base::Handle<const IExpression_list> arguments( fc->get_arguments());
855  base::Handle<const IExpression> argument_( arguments->get_expression( name));
856  if( !argument_)
857  return -2;
859  argument_->get_interface<IExpression_constant>());
860  if( !argument_constant)
861  return -4;
862  base::Handle<const IValue> argument_value( argument_constant->get_value());
863  Sint32 result = neuraylib::get_value( argument_value.get(), value);
864  return result == 0 ? 0 : -5;
865 
866  } else
867  return -1;
868 }
869 
870 template <class T>
871 Sint32 Argument_editor::get_value( Size parameter_index, Size component_index, T& value) const
872 {
873  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
874 
875  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
876  base::Handle<const IExpression_list> arguments( mi->get_arguments());
877  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
878  if( !argument)
879  return -2;
881  argument->get_interface<IExpression_constant>());
882  if( !argument_constant)
883  return -4;
884  base::Handle<const IValue> argument_value( argument_constant->get_value());
885  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
886  return result == 0 ? 0 : (result == -3 ? -3 : -5);
887 
888  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
889 
890  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
891  base::Handle<const IExpression_list> arguments( fc->get_arguments());
892  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
893  if( !argument)
894  return -2;
896  argument->get_interface<IExpression_constant>());
897  if( !argument_constant)
898  return -4;
899  base::Handle<const IValue> argument_value( argument_constant->get_value());
900  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
901  return result == 0 ? 0 : (result == -3 ? -3 : -5);
902 
903  } else
904  return -1;
905 }
906 
907 template <class T>
908 Sint32 Argument_editor::get_value( const char* parameter_name, Size component_index, T& value) const
909 {
910  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
911 
912  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
913  base::Handle<const IExpression_list> arguments( mi->get_arguments());
914  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
915  if( !argument)
916  return -2;
918  argument->get_interface<IExpression_constant>());
919  if( !argument_constant)
920  return -4;
921  base::Handle<const IValue> argument_value( argument_constant->get_value());
922  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
923  return result == 0 ? 0 : (result == -3 ? -3 : -5);
924 
925  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
926 
927  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
928  base::Handle<const IExpression_list> arguments( fc->get_arguments());
929  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
930  if( !argument)
931  return -2;
933  argument->get_interface<IExpression_constant>());
934  if( !argument_constant)
935  return -4;
936  base::Handle<const IValue> argument_value( argument_constant->get_value());
937  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
938  return result == 0 ? 0 : (result == -3 ? -3 : -5);
939 
940  } else
941  return -1;
942 }
943 
944 template <class T>
946  Size parameter_index, const char* field_name, T& value) const
947 {
948  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
949 
950  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
951  base::Handle<const IExpression_list> arguments( mi->get_arguments());
952  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
953  if( !argument)
954  return -2;
956  argument->get_interface<IExpression_constant>());
957  if( !argument_constant)
958  return -4;
959  base::Handle<const IValue> argument_value( argument_constant->get_value());
960  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
961  return result == 0 ? 0 : (result == -3 ? -3 : -5);
962 
963  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
964 
965  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
966  base::Handle<const IExpression_list> arguments( fc->get_arguments());
967  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
968  if( !argument)
969  return -2;
971  argument->get_interface<IExpression_constant>());
972  if( !argument_constant)
973  return -4;
974  base::Handle<const IValue> argument_value( argument_constant->get_value());
975  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
976  return result == 0 ? 0 : (result == -3 ? -3 : -5);
977 
978  } else
979  return -1;
980 }
981 
982 template <class T>
984  const char* parameter_name, const char* field_name, T& value) const
985 {
986  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
987 
988  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
989  base::Handle<const IExpression_list> arguments( mi->get_arguments());
990  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
991  if( !argument)
992  return -2;
994  argument->get_interface<IExpression_constant>());
995  if( !argument_constant)
996  return -4;
997  base::Handle<const IValue> argument_value( argument_constant->get_value());
998  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
999  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1000 
1001  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1002 
1003  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1004  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1005  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1006  if( !argument)
1007  return -2;
1008  base::Handle<const IExpression_constant> argument_constant(
1009  argument->get_interface<IExpression_constant>());
1010  if( !argument_constant)
1011  return -4;
1012  base::Handle<const IValue> argument_value( argument_constant->get_value());
1013  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
1014  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1015 
1016  } else
1017  return -1;
1018 }
1019 
1020 template <class T>
1021 Sint32 Argument_editor::set_value( Size parameter_index, const T& value)
1022 {
1023  promote_to_edit_if_needed();
1024 
1025  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1026 
1027  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1028  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1029  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1030  if( !argument)
1031  return -2;
1032  base::Handle<const IType> type( argument->get_type());
1033  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1034  Sint32 result = neuraylib::set_value( new_value.get(), value);
1035  if( result != 0)
1036  return -5;
1037  base::Handle<IExpression> new_expression(
1038  m_expression_factory->create_constant( new_value.get()));
1039  result = mi->set_argument( parameter_index, new_expression.get());
1040  mi_neuray_assert( result == 0);
1041  return 0;
1042 
1043  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1044 
1045  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1046  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1047  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1048  if( !argument)
1049  return -2;
1050  base::Handle<const IType> type( argument->get_type());
1051  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1052  Sint32 result = neuraylib::set_value( new_value.get(), value);
1053  if( result != 0)
1054  return -5;
1055  base::Handle<IExpression> new_expression(
1056  m_expression_factory->create_constant( new_value.get()));
1057  result = fc->set_argument( parameter_index, new_expression.get());
1058  mi_neuray_assert( result == 0);
1059  return 0;
1060 
1061  } else
1062  return -1;
1063 }
1064 
1065 template <class T>
1066 Sint32 Argument_editor::set_value( const char* parameter_name, const T& value)
1067 {
1068  promote_to_edit_if_needed();
1069 
1070  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1071 
1072  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1073  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1074  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1075  if( !argument)
1076  return -2;
1077  base::Handle<const IType> type( argument->get_type());
1078  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1079  Sint32 result = neuraylib::set_value( new_value.get(), value);
1080  if( result != 0)
1081  return -5;
1082  base::Handle<IExpression> new_expression(
1083  m_expression_factory->create_constant( new_value.get()));
1084  result = mi->set_argument( parameter_name, new_expression.get());
1085  mi_neuray_assert( result == 0);
1086  return 0;
1087 
1088  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1089 
1090  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1091  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1092  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1093  if( !argument)
1094  return -2;
1095  base::Handle<const IType> type( argument->get_type());
1096  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1097  Sint32 result = neuraylib::set_value( new_value.get(), value);
1098  if( result != 0)
1099  return -5;
1100  base::Handle<IExpression> new_expression(
1101  m_expression_factory->create_constant( new_value.get()));
1102  result = fc->set_argument( parameter_name, new_expression.get());
1103  mi_neuray_assert( result == 0);
1104  return 0;
1105 
1106  } else
1107  return -1;
1108 }
1109 
1110 template <class T>
1111 Sint32 Argument_editor::set_value( Size parameter_index, Size component_index, const T& value)
1112 {
1113  promote_to_edit_if_needed();
1114 
1115  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1116 
1117  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1118  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1119  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1120  if( !argument)
1121  return -2;
1122  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1123  // reuse existing constant expression
1124  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1125  base::Handle<IExpression_constant> new_argument_constant(
1126  new_argument->get_interface<IExpression_constant>());
1127  base::Handle<IValue> new_value( new_argument_constant->get_value());
1128  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1129  if( result != 0)
1130  return result == -3 ? -3 : -5;
1131  result = mi->set_argument( parameter_index, new_argument.get());
1132  mi_neuray_assert( result == 0);
1133  return 0;
1134  } else {
1135  // create new constant expression
1136  base::Handle<const IType> type( argument->get_type());
1137  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1138  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1139  if( result != 0)
1140  return result == -3 ? -3 : -5;
1141  base::Handle<IExpression> new_expression(
1142  m_expression_factory->create_constant( new_value.get()));
1143  result = mi->set_argument( parameter_index, new_expression.get());
1144  mi_neuray_assert( result == 0);
1145  return 0;
1146  }
1147 
1148  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1149 
1150  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1151  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1152  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1153  if( !argument)
1154  return -2;
1155  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1156  // reuse existing constant expression
1157  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1158  base::Handle<IExpression_constant> new_argument_constant(
1159  new_argument->get_interface<IExpression_constant>());
1160  base::Handle<IValue> new_value( new_argument_constant->get_value());
1161  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1162  if( result != 0)
1163  return result == -3 ? -3 : -5;
1164  result = fc->set_argument( parameter_index, new_argument.get());
1165  mi_neuray_assert( result == 0);
1166  return 0;
1167  } else {
1168  // create new constant expression
1169  base::Handle<const IType> type( argument->get_type());
1170  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1171  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1172  if( result != 0)
1173  return result == -3 ? -3 : -5;
1174  base::Handle<IExpression> new_expression(
1175  m_expression_factory->create_constant( new_value.get()));
1176  result = fc->set_argument( parameter_index, new_expression.get());
1177  mi_neuray_assert( result == 0);
1178  return 0;
1179  }
1180 
1181  } else
1182  return -1;
1183 }
1184 
1185 template <class T>
1186 Sint32 Argument_editor::set_value( const char* parameter_name, Size component_index, const T& value)
1187 {
1188  promote_to_edit_if_needed();
1189 
1190  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1191 
1192  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1193  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1194  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1195  if( !argument)
1196  return -2;
1197  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1198  // reuse existing constant expression
1199  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1200  base::Handle<IExpression_constant> new_argument_constant(
1201  new_argument->get_interface<IExpression_constant>());
1202  base::Handle<IValue> new_value( new_argument_constant->get_value());
1203  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1204  if( result != 0)
1205  return result == -3 ? -3 : -5;
1206  result = mi->set_argument( parameter_name, new_argument.get());
1207  mi_neuray_assert( result == 0);
1208  return 0;
1209  } else {
1210  // create new constant expression
1211  base::Handle<const IType> type( argument->get_type());
1212  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1213  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1214  if( result != 0)
1215  return result == -3 ? -3 : -5;
1216  base::Handle<IExpression> new_expression(
1217  m_expression_factory->create_constant( new_value.get()));
1218  result = mi->set_argument( parameter_name, new_expression.get());
1219  mi_neuray_assert( result == 0);
1220  return 0;
1221  }
1222 
1223  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1224 
1225  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1226  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1227  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1228  if( !argument)
1229  return -2;
1230  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1231  // reuse existing constant expression
1232  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1233  base::Handle<IExpression_constant> new_argument_constant(
1234  new_argument->get_interface<IExpression_constant>());
1235  base::Handle<IValue> new_value( new_argument_constant->get_value());
1236  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1237  if( result != 0)
1238  return result == -3 ? -3 : -5;
1239  result = fc->set_argument( parameter_name, new_argument.get());
1240  mi_neuray_assert( result == 0);
1241  return 0;
1242  } else {
1243  // create new constant expression
1244  base::Handle<const IType> type( argument->get_type());
1245  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1246  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1247  if( result != 0)
1248  return result == -3 ? -3 : -5;
1249  base::Handle<IExpression> new_expression(
1250  m_expression_factory->create_constant( new_value.get()));
1251  result = fc->set_argument( parameter_name, new_expression.get());
1252  mi_neuray_assert( result == 0);
1253  return 0;
1254  }
1255 
1256  } else
1257  return -1;
1258 }
1259 
1260 template <class T>
1262  Size parameter_index, const char* field_name, const T& value)
1263 {
1264  promote_to_edit_if_needed();
1265 
1266  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1267 
1268  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1269  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1270  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1271  if( !argument)
1272  return -2;
1273  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1274  // reuse existing constant expression
1275  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1276  base::Handle<IExpression_constant> new_argument_constant(
1277  new_argument->get_interface<IExpression_constant>());
1278  base::Handle<IValue> new_value( new_argument_constant->get_value());
1279  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1280  if( result != 0)
1281  return result == -3 ? -3 : -5;
1282  result = mi->set_argument( parameter_index, new_argument.get());
1283  mi_neuray_assert( result == 0);
1284  return 0;
1285  } else {
1286  // create new constant expression
1287  base::Handle<const IType> type( argument->get_type());
1288  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1289  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1290  if( result != 0)
1291  return result == -3 ? -3 : -5;
1292  base::Handle<IExpression> new_expression(
1293  m_expression_factory->create_constant( new_value.get()));
1294  result = mi->set_argument( parameter_index, new_expression.get());
1295  mi_neuray_assert( result == 0);
1296  return 0;
1297  }
1298 
1299  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1300 
1301  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1302  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1303  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1304  if( !argument)
1305  return -2;
1306  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1307  // reuse existing constant expression
1308  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1309  base::Handle<IExpression_constant> new_argument_constant(
1310  new_argument->get_interface<IExpression_constant>());
1311  base::Handle<IValue> new_value( new_argument_constant->get_value());
1312  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1313  if( result != 0)
1314  return result == -3 ? -3 : -5;
1315  result = fc->set_argument( parameter_index, new_argument.get());
1316  mi_neuray_assert( result == 0);
1317  return 0;
1318  } else {
1319  // create new constant expression
1320  base::Handle<const IType> type( argument->get_type());
1321  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1322  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1323  if( result != 0)
1324  return result == -3 ? -3 : -5;
1325  base::Handle<IExpression> new_expression(
1326  m_expression_factory->create_constant( new_value.get()));
1327  result = fc->set_argument( parameter_index, new_expression.get());
1328  mi_neuray_assert( result == 0);
1329  return 0;
1330  }
1331 
1332  } else
1333  return -1;
1334 }
1335 
1336 template <class T>
1338  const char* parameter_name, const char* field_name, const T& value)
1339 {
1340  promote_to_edit_if_needed();
1341 
1342  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1343 
1344  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1345  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1346  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1347  if( !argument)
1348  return -2;
1349  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1350  // reuse existing constant expression
1351  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1352  base::Handle<IExpression_constant> new_argument_constant(
1353  new_argument->get_interface<IExpression_constant>());
1354  base::Handle<IValue> new_value( new_argument_constant->get_value());
1355  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1356  if( result != 0)
1357  return result == -3 ? -3 : -5;
1358  result = mi->set_argument( parameter_name, new_argument.get());
1359  mi_neuray_assert( result == 0);
1360  return 0;
1361  } else {
1362  // create new constant expression
1363  base::Handle<const IType> type( argument->get_type());
1364  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1365  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1366  if( result != 0)
1367  return result == -3 ? -3 : -5;
1368  base::Handle<IExpression> new_expression(
1369  m_expression_factory->create_constant( new_value.get()));
1370  result = mi->set_argument( parameter_name, new_expression.get());
1371  mi_neuray_assert( result == 0);
1372  return 0;
1373  }
1374 
1375  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1376 
1377  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1378  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1379  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1380  if( !argument)
1381  return -2;
1382  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1383  // reuse existing constant expression
1384  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1385  base::Handle<IExpression_constant> new_argument_constant(
1386  new_argument->get_interface<IExpression_constant>());
1387  base::Handle<IValue> new_value( new_argument_constant->get_value());
1388  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1389  if( result != 0)
1390  return result == -3 ? -3 : -5;
1391  result = fc->set_argument( parameter_name, new_argument.get());
1392  mi_neuray_assert( result == 0);
1393  return 0;
1394  } else {
1395  // create new constant expression
1396  base::Handle<const IType> type( argument->get_type());
1397  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1398  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1399  if( result != 0)
1400  return result == -3 ? -3 : -5;
1401  base::Handle<IExpression> new_expression(
1402  m_expression_factory->create_constant( new_value.get()));
1403  result = fc->set_argument( parameter_name, new_expression.get());
1404  mi_neuray_assert( result == 0);
1405  return 0;
1406  }
1407 
1408  } else
1409  return -1;
1410 }
1411 
1412 inline Sint32 Argument_editor::get_array_length( Uint32 parameter_index, Size& size) const
1413 {
1414  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1415 
1416  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1417  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1418  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1419  if( !argument)
1420  return -2;
1421  base::Handle<const IExpression_constant> argument_constant(
1422  argument->get_interface<IExpression_constant>());
1423  if( !argument_constant)
1424  return -4;
1425  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1426  if( !value)
1427  return -5;
1428  size = value->get_size();
1429  return 0;
1430 
1431  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1432 
1433  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1434  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1435  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1436  if( !argument)
1437  return -2;
1438  base::Handle<const IExpression_constant> argument_constant(
1439  argument->get_interface<IExpression_constant>());
1440  if( !argument_constant)
1441  return -4;
1442  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1443  if( !value)
1444  return -5;
1445  size = value->get_size();
1446  return 0;
1447 
1448  } else
1449  return -1;
1450 }
1451 
1452 inline Sint32 Argument_editor::get_array_length( const char* parameter_name, Size& size) const
1453 {
1454  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1455 
1456  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1457  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1458  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1459  if( !argument)
1460  return -2;
1461  base::Handle<const IExpression_constant> argument_constant(
1462  argument->get_interface<IExpression_constant>());
1463  if( !argument_constant)
1464  return -4;
1465  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1466  if( !value)
1467  return -5;
1468  size = value->get_size();
1469  return 0;
1470 
1471  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1472 
1473  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1474  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1475  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1476  if( !argument)
1477  return -2;
1478  base::Handle<const IExpression_constant> argument_constant(
1479  argument->get_interface<IExpression_constant>());
1480  if( !argument_constant)
1481  return -4;
1482  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1483  if( !value)
1484  return -5;
1485  size = value->get_size();
1486  return 0;
1487 
1488  } else
1489  return -1;
1490 }
1491 
1492 inline Sint32 Argument_editor::set_array_size( Uint32 parameter_index, Size size)
1493 {
1494  promote_to_edit_if_needed();
1495 
1496  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1497 
1498  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1499  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1500  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1501  if( !argument)
1502  return -2;
1503  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1504  // reuse existing constant expression
1505  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1506  base::Handle<IExpression_constant> new_argument_constant(
1507  new_argument->get_interface<IExpression_constant>());
1508  base::Handle<IValue_array> new_value(
1509  new_argument_constant->get_value<IValue_array>());
1510  if( !new_value)
1511  return -5;
1512  Sint32 result = new_value->set_size( size);
1513  if( result != 0)
1514  return -5;
1515  result = mi->set_argument( parameter_index, new_argument.get());
1516  mi_neuray_assert( result == 0);
1517  return 0;
1518  } else {
1519  // create new constant expression
1520  base::Handle<const IType> type( argument->get_type());
1521  base::Handle<IValue_array> new_value(
1522  m_value_factory->create<IValue_array>( type.get()));
1523  if( !new_value)
1524  return -5;
1525  Sint32 result = new_value->set_size( size);
1526  if( result != 0)
1527  return -5;
1528  base::Handle<IExpression> new_expression(
1529  m_expression_factory->create_constant( new_value.get()));
1530  result = mi->set_argument( parameter_index, new_expression.get());
1531  mi_neuray_assert( result == 0);
1532  return 0;
1533  }
1534 
1535  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1536 
1537  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1538  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1539  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1540  if( !argument)
1541  return -2;
1542  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1543  // reuse existing constant expression
1544  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1545  base::Handle<IExpression_constant> new_argument_constant(
1546  new_argument->get_interface<IExpression_constant>());
1547  base::Handle<IValue_array> new_value(
1548  new_argument_constant->get_value<IValue_array>());
1549  if( !new_value)
1550  return -5;
1551  Sint32 result = new_value->set_size( size);
1552  if( result != 0)
1553  return -5;
1554  result = fc->set_argument( parameter_index, new_argument.get());
1555  mi_neuray_assert( result == 0);
1556  return 0;
1557  } else {
1558  // create new constant expression
1559  base::Handle<const IType> type( argument->get_type());
1560  base::Handle<IValue_array> new_value(
1561  m_value_factory->create<IValue_array>( type.get()));
1562  if( !new_value)
1563  return -5;
1564  Sint32 result = new_value->set_size( size);
1565  if( result != 0)
1566  return -5;
1567  base::Handle<IExpression> new_expression(
1568  m_expression_factory->create_constant( new_value.get()));
1569  result = fc->set_argument( parameter_index, new_expression.get());
1570  mi_neuray_assert( result == 0);
1571  return 0;
1572  }
1573 
1574  } else
1575  return -1;
1576 }
1577 
1578 inline Sint32 Argument_editor::set_array_size( const char* parameter_name, Size size)
1579 {
1580  promote_to_edit_if_needed();
1581 
1582  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1583 
1584  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1585  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1586  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1587  if( !argument)
1588  return -2;
1589  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1590  // reuse existing constant expression
1591  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1592  base::Handle<IExpression_constant> new_argument_constant(
1593  new_argument->get_interface<IExpression_constant>());
1594  base::Handle<IValue_array> new_value(
1595  new_argument_constant->get_value<IValue_array>());
1596  if( !new_value)
1597  return -5;
1598  Sint32 result = new_value->set_size( size);
1599  if( result != 0)
1600  return -5;
1601  result = mi->set_argument( parameter_name, new_argument.get());
1602  mi_neuray_assert( result == 0);
1603  return 0;
1604  } else {
1605  // create new constant expression
1606  base::Handle<const IType> type( argument->get_type());
1607  base::Handle<IValue_array> new_value(
1608  m_value_factory->create<IValue_array>( type.get()));
1609  if( !new_value)
1610  return -5;
1611  Sint32 result = new_value->set_size( size);
1612  if( result != 0)
1613  return -5;
1614  base::Handle<IExpression> new_expression(
1615  m_expression_factory->create_constant( new_value.get()));
1616  result = mi->set_argument( parameter_name, new_expression.get());
1617  mi_neuray_assert( result == 0);
1618  return 0;
1619  }
1620 
1621  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1622 
1623  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1624  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1625  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1626  if( !argument)
1627  return -2;
1628  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1629  // reuse existing constant expression
1630  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1631  base::Handle<IExpression_constant> new_argument_constant(
1632  new_argument->get_interface<IExpression_constant>());
1633  base::Handle<IValue_array> new_value(
1634  new_argument_constant->get_value<IValue_array>());
1635  if( !new_value)
1636  return -5;
1637  Sint32 result = new_value->set_size( size);
1638  if( result != 0)
1639  return -5;
1640  result = fc->set_argument( parameter_name, new_argument.get());
1641  mi_neuray_assert( result == 0);
1642  return 0;
1643  } else {
1644  // create new constant expression
1645  base::Handle<const IType> type( argument->get_type());
1646  base::Handle<IValue_array> new_value(
1647  m_value_factory->create<IValue_array>( type.get()));
1648  if( !new_value)
1649  return -5;
1650  Sint32 result = new_value->set_size( size);
1651  if( result != 0)
1652  return -5;
1653  base::Handle<IExpression> new_expression(
1654  m_expression_factory->create_constant( new_value.get()));
1655  result = fc->set_argument( parameter_name, new_expression.get());
1656  mi_neuray_assert( result == 0);
1657  return 0;
1658  }
1659 
1660  } else
1661  return -1;
1662 }
1663 
1664 inline const char* Argument_editor::get_call( Size parameter_index) const
1665 {
1666  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1667 
1668  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1669  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1671  arguments->get_expression<IExpression_call>( parameter_index));
1672  if( !argument)
1673  return 0;
1674  return argument->get_call();
1675 
1676  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1677 
1678  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1679  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1681  arguments->get_expression<IExpression_call>( parameter_index));
1682  if( !argument)
1683  return 0;
1684  return argument->get_call();
1685 
1686  } else
1687  return 0;
1688 }
1689 
1690 inline const char* Argument_editor::get_call( const char* parameter_name) const
1691 {
1692  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1693 
1694  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1695  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1697  arguments->get_expression<IExpression_call>( parameter_name));
1698  if( !argument)
1699  return 0;
1700  return argument->get_call();
1701 
1702  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1703 
1704  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1705  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1707  arguments->get_expression<IExpression_call>( parameter_name));
1708  if( !argument)
1709  return 0;
1710  return argument->get_call();
1711 
1712  } else
1713  return 0;
1714 }
1715 
1716 inline Sint32 Argument_editor::set_call( Size parameter_index, const char* call_name)
1717 {
1718  promote_to_edit_if_needed();
1719 
1720  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1721 
1722  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1723  if( !new_argument)
1724  return -6;
1725  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1726  return mi->set_argument( parameter_index, new_argument.get());
1727 
1728  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1729 
1730  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1731  if( !new_argument)
1732  return -6;
1733  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1734  return fc->set_argument( parameter_index, new_argument.get());
1735 
1736  } else
1737  return -1;
1738 }
1739 
1740 inline Sint32 Argument_editor::set_call( const char* parameter_name, const char* call_name)
1741 {
1742  promote_to_edit_if_needed();
1743 
1744  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1745 
1746  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1747  if( !new_argument)
1748  return -6;
1749  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1750  return mi->set_argument( parameter_name, new_argument.get());
1751 
1752  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1753 
1754  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1755  if( !new_argument)
1756  return -6;
1757  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1758  return fc->set_argument( parameter_name, new_argument.get());
1759 
1760  } else
1761  return -1;
1762 }
1763 
1765 {
1766  m_transaction->retain();
1767  return m_transaction.get();
1768 }
1769 
1771 {
1772  m_mdl_factory->retain();
1773  return m_mdl_factory.get();
1774 }
1775 
1777 {
1778  m_value_factory->retain();
1779  return m_value_factory.get();
1780 }
1781 
1783 {
1784  m_expression_factory->retain();
1785  return m_expression_factory.get();
1786 }
1787 
1789 {
1790  m_access->retain();
1791  return m_access.get();
1792 }
1793 
1795 {
1796  promote_to_edit_if_needed();
1797 
1798  m_edit->retain();
1799  return m_edit.get();
1800 }
1801 
1803 {
1804  return m_type;
1805 }
1806 
1807 inline const std::string& Argument_editor::get_name() const
1808 {
1809  return m_name;
1810 }
1811 
1812 inline void Argument_editor::promote_to_edit_if_needed()
1813 {
1814  if( m_edit)
1815  return;
1816  m_edit = m_transaction->edit<IScene_element>( m_name.c_str());
1817  mi_neuray_assert( m_edit);
1818  m_old_access = m_access;
1819  m_access = m_edit;
1820 }
1821 
1822 } // namespace neuraylib
1823 
1824 } // namespace mi
1825 
1826 #endif // MI_NEURAYLIB_ARGUMENT_EDITOR_H