MDL SDK 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 2022 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
49 {
50 public:
51 
53 
54 
70  ITransaction* transaction,
71  const char* name,
72  IMdl_factory* mdl_factory,
73  bool intent_to_edit = false);
74 
80  bool is_valid() const;
81 
90  bool is_valid_instance( IMdl_execution_context* context) const;
91 
100  mi::Sint32 repair(mi::Uint32 flags, IMdl_execution_context* context);
101 
109  Element_type get_type() const;
110 
112  const char* get_definition() const;
113 
115  const char* get_mdl_definition() const;
116 
121  bool is_array_constructor() const;
122 
124  bool is_material() const;
125 
127  const IType* get_return_type() const;
128 
130  Size get_parameter_count() const;
131 
136  const char* get_parameter_name( Size index) const;
137 
142  Size get_parameter_index( const char* name) const;
143 
145  const IType_list* get_parameter_types() const;
146 
153  bool is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const;
154 
156  const IExpression_list* get_arguments() const;
157 
163  IExpression::Kind get_argument_kind( Size parameter_index) const;
164 
170  IExpression::Kind get_argument_kind( const char* parameter_name) const;
171 
173 
175 
191  Sint32 reset_argument( Size index);
192 
209  Sint32 reset_argument( const char* name);
210 
212 
214 
228  template<class T>
229  Sint32 get_value( Size parameter_index, T& value) const;
230 
241  template <class T>
242  Sint32 get_value( const char* parameter_name, T& value) const;
243 
259  template<class T>
260  Sint32 get_value( Size parameter_index, Size component_index, T& value) const;
261 
274  template <class T>
275  Sint32 get_value( const char* parameter_name, Size component_index, T& value) const;
276 
292  template<class T>
293  Sint32 get_value( Size parameter_index, const char* field_name, T& value) const;
294 
307  template <class T>
308  Sint32 get_value( const char* parameter_name, const char* field_name, T& value) const;
309 
325  template<class T>
326  Sint32 set_value( Size parameter_index, const T& value);
327 
340  template <class T>
341  Sint32 set_value( const char* parameter_name, const T& value);
342 
363  template<class T>
364  Sint32 set_value( Size parameter_index, Size component_index, const T& value);
365 
383  template <class T>
384  Sint32 set_value( const char* parameter_name, Size component_index, const T& value);
385 
403  template<class T>
404  Sint32 set_value( Size parameter_index, const char* field_name, const T& value);
405 
420  template <class T>
421  Sint32 set_value( const char* parameter_name, const char* field_name, const T& value);
422 
436  Sint32 get_array_length( Uint32 parameter_index, Size& size) const;
437 
448  Sint32 get_array_length( const char* parameter_name, Size& size) const;
449 
465  Sint32 set_array_size( Uint32 parameter_index, Size size);
466 
479  Sint32 set_array_size( const char* parameter_name, Size size);
480 
482 
484 
493  const char* get_call( Size parameter_index) const;
494 
500  const char* get_call( const char* parameter_name) const;
501 
519  Sint32 set_call( Size parameter_index, const char* call_name);
520 
535  Sint32 set_call( const char* parameter_name, const char* call_name);
536 
538 
540 
542  ITransaction* get_transaction() const;
543 
545  IMdl_factory* get_mdl_factory() const;
546 
548  IValue_factory* get_value_factory() const;
549 
551  IExpression_factory* get_expression_factory() const;
552 
554  const IScene_element* get_scene_element() const;
555 
557  IScene_element* get_scene_element();
558 
561 
563  const std::string& get_name() const;
564 
566 
567 private:
568  void promote_to_edit_if_needed();
569 
570  base::Handle<ITransaction> m_transaction;
571  base::Handle<IMdl_factory> m_mdl_factory;
572  base::Handle<IValue_factory> m_value_factory;
573  base::Handle<IExpression_factory> m_expression_factory;
574  base::Handle<const IScene_element> m_access;
575  base::Handle<const IScene_element> m_old_access;
576  base::Handle<IScene_element> m_edit;
577  Element_type m_type;
578  std::string m_name;
579 };
580  // end group mi_neuray_mdl_elements
582 
584  ITransaction* transaction, const char* name, IMdl_factory* mdl_factory, bool intent_to_edit)
585 {
586  mi_neuray_assert( transaction);
587  mi_neuray_assert( name);
588 
589  m_transaction = make_handle_dup( transaction);
590  m_name = name;
591  m_mdl_factory = make_handle_dup( mdl_factory);
592  m_value_factory
593  = m_mdl_factory ? m_mdl_factory->create_value_factory( m_transaction.get()) : 0;
594  m_expression_factory
595  = m_mdl_factory ? m_mdl_factory->create_expression_factory( m_transaction.get()) : 0;
596 
597  if( intent_to_edit) {
598  m_edit = transaction->edit<IScene_element>( name);
599  m_access = m_edit;
600  m_old_access = m_edit;
601  m_type = m_access ? m_access->get_element_type() : static_cast<Element_type>( 0);
602  } else {
603  m_access = transaction->access<IScene_element>( name);
604  m_type = m_access ? m_access->get_element_type() : static_cast<Element_type>( 0);
605  }
606 }
607 
608 inline bool Argument_editor::is_valid() const
609 {
610  return m_access
612 }
613 
615 {
616  if (m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
617 
618  base::Handle<const IMaterial_instance> mi(m_access->get_interface<IMaterial_instance>());
619  return mi->is_valid(context);
620  }
621  else if (m_type == ELEMENT_TYPE_FUNCTION_CALL) {
622 
623  base::Handle<const IFunction_call> fc(m_access->get_interface<IFunction_call>());
624  return fc->is_valid(context);
625  }
626  else
627  return false;
628 }
629 
631 {
632  promote_to_edit_if_needed();
633  if (m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
634  base::Handle<IMaterial_instance> mi(m_edit->get_interface<IMaterial_instance>());
635  return mi->repair(flags, context);
636  }
637  else if (m_type == ELEMENT_TYPE_FUNCTION_CALL) {
638 
639  base::Handle<IFunction_call> fc(m_edit->get_interface<IFunction_call>());
640  return fc->repair(flags, context);
641  }
642  else
643  return -1;
644 }
645 
647 {
648  return m_type;
649 }
650 
651 inline const char* Argument_editor::get_definition() const
652 {
653  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
654 
655  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
656  return mi->get_material_definition();
657 
658  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
659 
660  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
661  return fc->get_function_definition();
662 
663  } else
664  return 0;
665 }
666 
667 inline const char* Argument_editor::get_mdl_definition() const
668 {
669  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
670 
671  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
672  return mi->get_mdl_material_definition();
673 
674  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
675 
676  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
677  return fc->get_mdl_function_definition();
678 
679  } else
680  return 0;
681 }
682 
684 {
685  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
686 
687  return false;
688 
689  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
690 
691  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
692  return fc->is_array_constructor();
693 
694  } else
695  return false;
696 }
697 
698 inline bool Argument_editor::is_material() const
699 {
700  if( !m_access)
701  return false;
702 
703  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
704  return mi.is_valid_interface();
705 }
706 
708 {
709  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
710 
711  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
712  return mi->get_parameter_count();
713 
714  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
715 
716  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
717  return fc->get_parameter_count();
718 
719  } else
720  return 0;
721 }
722 
723 inline const char* Argument_editor::get_parameter_name( Size parameter_index) const
724 {
725  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
726 
727  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
728  return mi->get_parameter_name( parameter_index);
729 
730  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
731 
732  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
733  return fc->get_parameter_name( parameter_index);
734 
735  } else
736  return 0;
737 }
738 
739 inline Size Argument_editor::get_parameter_index( const char* name) const
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_parameter_index( name);
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_parameter_index( name);
750 
751  } else
752  return 0;
753 }
754 
756 {
757  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
758 
759  return 0;
760 
761  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
762 
763  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
764  return fc->get_return_type();
765 
766  } else
767  return 0;
768 }
769 
771 {
772  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
773 
774  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
775  return mi->get_parameter_types();
776 
777  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
778 
779  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
780  return fc->get_parameter_types();
781 
782  } else
783  return 0;
784 }
785 
786 inline bool Argument_editor::is_parameter_enabled( Size index, IMdl_evaluator_api* evaluator) const
787 {
788  if( !evaluator)
789  return true;
790 
791  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
792 
793  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
795  m_transaction.get(), m_value_factory.get(), mi.get(), index, /*error*/ NULL));
796  if (!b)
797  return true;
798  return b->get_value();
799 
800  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
801 
802  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
804  m_transaction.get(), m_value_factory.get(), fc.get(), index, /*error*/ NULL));
805  if (!b)
806  return true;
807  return b->get_value();
808 
809  } else
810  return true;
811 }
812 
814 {
815  promote_to_edit_if_needed();
816 
817  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
818 
819  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
820  return mi->reset_argument( index);
821 
822  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
823 
824  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
825  return fc->reset_argument( index);
826 
827  } else
828  return -1;
829 }
830 
831 inline Sint32 Argument_editor::reset_argument( const char* name)
832 {
833  promote_to_edit_if_needed();
834 
835  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
836 
837  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
838  return mi->reset_argument( name);
839 
840  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
841 
842  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
843  return fc->reset_argument( name);
844 
845  } else
846  return -1;
847 }
848 
849 
851 {
852  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
853 
854  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
855  return mi->get_arguments();
856 
857  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
858 
859  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
860  return fc->get_arguments();
861 
862  } else
863  return 0;
864 }
865 
867 {
868  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
869 
870  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
871  base::Handle<const IExpression_list> arguments( mi->get_arguments());
872  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
873  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
874 
875  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
876 
877  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
878  base::Handle<const IExpression_list> arguments( fc->get_arguments());
879  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
880  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
881 
882  } else
883  return static_cast<IExpression::Kind>( 0);
884 }
885 
886 inline IExpression::Kind Argument_editor::get_argument_kind( const char* parameter_name) const
887 {
888  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
889 
890  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
891  base::Handle<const IExpression_list> arguments( mi->get_arguments());
892  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
893  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
894 
895  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
896 
897  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
898  base::Handle<const IExpression_list> arguments( fc->get_arguments());
899  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
900  return argument ? argument->get_kind() : static_cast<IExpression::Kind>( 0);
901 
902  } else
903  return static_cast<IExpression::Kind>( 0);
904 }
905 
906 template <class T>
907 Sint32 Argument_editor::get_value( Size parameter_index, T& value) const
908 {
909  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
910 
911  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
912  base::Handle<const IExpression_list> arguments( mi->get_arguments());
913  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
914  if( !argument)
915  return -2;
917  argument->get_interface<IExpression_constant>());
918  if( !argument_constant)
919  return -4;
920  base::Handle<const IValue> argument_value( argument_constant->get_value());
921  Sint32 result = neuraylib::get_value( argument_value.get(), value);
922  return result == 0 ? 0 : -5;
923 
924  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
925 
926  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
927  base::Handle<const IExpression_list> arguments( fc->get_arguments());
928  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
929  if( !argument)
930  return -2;
932  argument->get_interface<IExpression_constant>());
933  if( !argument_constant)
934  return -4;
935  base::Handle<const IValue> argument_value( argument_constant->get_value());
936  Sint32 result = neuraylib::get_value( argument_value.get(), value);
937  return result == 0 ? 0 : -5;
938 
939  } else
940  return -1;
941 }
942 
943 template <class T>
944 Sint32 Argument_editor::get_value( const char* name, T& value) const
945 {
946  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
947 
948  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
949  base::Handle<const IExpression_list> arguments( mi->get_arguments());
950  base::Handle<const IExpression> argument_( arguments->get_expression( name));
951  if( !argument_)
952  return -2;
954  argument_->get_interface<IExpression_constant>());
955  if( !argument_constant)
956  return -4;
957  base::Handle<const IValue> argument_value( argument_constant->get_value());
958  Sint32 result = neuraylib::get_value( argument_value.get(), value);
959  return result == 0 ? 0 : -5;
960 
961  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
962 
964  m_access->get_interface<IFunction_call>());
965  base::Handle<const IExpression_list> arguments( fc->get_arguments());
966  base::Handle<const IExpression> argument_( arguments->get_expression( name));
967  if( !argument_)
968  return -2;
970  argument_->get_interface<IExpression_constant>());
971  if( !argument_constant)
972  return -4;
973  base::Handle<const IValue> argument_value( argument_constant->get_value());
974  Sint32 result = neuraylib::get_value( argument_value.get(), value);
975  return result == 0 ? 0 : -5;
976 
977  } else
978  return -1;
979 }
980 
981 template <class T>
982 Sint32 Argument_editor::get_value( Size parameter_index, Size component_index, T& value) const
983 {
984  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
985 
986  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
987  base::Handle<const IExpression_list> arguments( mi->get_arguments());
988  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
989  if( !argument)
990  return -2;
992  argument->get_interface<IExpression_constant>());
993  if( !argument_constant)
994  return -4;
995  base::Handle<const IValue> argument_value( argument_constant->get_value());
996  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
997  return result == 0 ? 0 : (result == -3 ? -3 : -5);
998 
999  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1000 
1001  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1002  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1003  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1004  if( !argument)
1005  return -2;
1006  base::Handle<const IExpression_constant> argument_constant(
1007  argument->get_interface<IExpression_constant>());
1008  if( !argument_constant)
1009  return -4;
1010  base::Handle<const IValue> argument_value( argument_constant->get_value());
1011  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
1012  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1013 
1014  } else
1015  return -1;
1016 }
1017 
1018 template <class T>
1019 Sint32 Argument_editor::get_value( const char* parameter_name, Size component_index, T& value) const
1020 {
1021  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1022 
1023  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1024  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1025  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1026  if( !argument)
1027  return -2;
1028  base::Handle<const IExpression_constant> argument_constant(
1029  argument->get_interface<IExpression_constant>());
1030  if( !argument_constant)
1031  return -4;
1032  base::Handle<const IValue> argument_value( argument_constant->get_value());
1033  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
1034  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1035 
1036  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1037 
1038  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1039  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1040  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1041  if( !argument)
1042  return -2;
1043  base::Handle<const IExpression_constant> argument_constant(
1044  argument->get_interface<IExpression_constant>());
1045  if( !argument_constant)
1046  return -4;
1047  base::Handle<const IValue> argument_value( argument_constant->get_value());
1048  Sint32 result = neuraylib::get_value( argument_value.get(), component_index, value);
1049  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1050 
1051  } else
1052  return -1;
1053 }
1054 
1055 template <class T>
1057  Size parameter_index, const char* field_name, T& value) const
1058 {
1059  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1060 
1061  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1062  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1063  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1064  if( !argument)
1065  return -2;
1066  base::Handle<const IExpression_constant> argument_constant(
1067  argument->get_interface<IExpression_constant>());
1068  if( !argument_constant)
1069  return -4;
1070  base::Handle<const IValue> argument_value( argument_constant->get_value());
1071  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
1072  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1073 
1074  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1075 
1076  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1077  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1078  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1079  if( !argument)
1080  return -2;
1081  base::Handle<const IExpression_constant> argument_constant(
1082  argument->get_interface<IExpression_constant>());
1083  if( !argument_constant)
1084  return -4;
1085  base::Handle<const IValue> argument_value( argument_constant->get_value());
1086  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
1087  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1088 
1089  } else
1090  return -1;
1091 }
1092 
1093 template <class T>
1095  const char* parameter_name, const char* field_name, T& value) const
1096 {
1097  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1098 
1099  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1100  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1101  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1102  if( !argument)
1103  return -2;
1104  base::Handle<const IExpression_constant> argument_constant(
1105  argument->get_interface<IExpression_constant>());
1106  if( !argument_constant)
1107  return -4;
1108  base::Handle<const IValue> argument_value( argument_constant->get_value());
1109  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
1110  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1111 
1112  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1113 
1114  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1115  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1116  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1117  if( !argument)
1118  return -2;
1119  base::Handle<const IExpression_constant> argument_constant(
1120  argument->get_interface<IExpression_constant>());
1121  if( !argument_constant)
1122  return -4;
1123  base::Handle<const IValue> argument_value( argument_constant->get_value());
1124  Sint32 result = neuraylib::get_value( argument_value.get(), field_name, value);
1125  return result == 0 ? 0 : (result == -3 ? -3 : -5);
1126 
1127  } else
1128  return -1;
1129 }
1130 
1131 template <class T>
1132 Sint32 Argument_editor::set_value( Size parameter_index, const T& value)
1133 {
1134  promote_to_edit_if_needed();
1135 
1136  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1137 
1138  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1139  if( mi->is_default())
1140  return -4;
1141  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1142  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1143  if( !argument)
1144  return -2;
1145  base::Handle<const IType> type( argument->get_type());
1146  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1147  Sint32 result = neuraylib::set_value( new_value.get(), value);
1148  if( result != 0)
1149  return -5;
1150  base::Handle<IExpression> new_expression(
1151  m_expression_factory->create_constant( new_value.get()));
1152  result = mi->set_argument( parameter_index, new_expression.get());
1153  mi_neuray_assert( result == 0);
1154  return result;
1155 
1156  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1157 
1158  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1159  if( fc->is_default())
1160  return -4;
1161  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1162  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1163  if( !argument)
1164  return -2;
1165  base::Handle<const IType> type( argument->get_type());
1166  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1167  Sint32 result = neuraylib::set_value( new_value.get(), value);
1168  if( result != 0)
1169  return -5;
1170  base::Handle<IExpression> new_expression(
1171  m_expression_factory->create_constant( new_value.get()));
1172  result = fc->set_argument( parameter_index, new_expression.get());
1173  mi_neuray_assert( result == 0);
1174  return result;
1175 
1176  } else
1177  return -1;
1178 }
1179 
1180 template <class T>
1181 Sint32 Argument_editor::set_value( const char* parameter_name, const T& value)
1182 {
1183  promote_to_edit_if_needed();
1184 
1185  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1186 
1187  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1188  if( mi->is_default())
1189  return -4;
1190  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1191  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1192  if( !argument)
1193  return -2;
1194  base::Handle<const IType> type( argument->get_type());
1195  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1196  Sint32 result = neuraylib::set_value( new_value.get(), value);
1197  if( result != 0)
1198  return -5;
1199  base::Handle<IExpression> new_expression(
1200  m_expression_factory->create_constant( new_value.get()));
1201  result = mi->set_argument( parameter_name, new_expression.get());
1202  mi_neuray_assert( result == 0);
1203  return result;
1204 
1205  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1206 
1207  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1208  if( fc->is_default())
1209  return -4;
1210  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1211  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1212  if( !argument)
1213  return -2;
1214  base::Handle<const IType> type( argument->get_type());
1215  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1216  Sint32 result = neuraylib::set_value( new_value.get(), value);
1217  if( result != 0)
1218  return -5;
1219  base::Handle<IExpression> new_expression(
1220  m_expression_factory->create_constant( new_value.get()));
1221  result = fc->set_argument( parameter_name, new_expression.get());
1222  mi_neuray_assert( result == 0);
1223  return result;
1224 
1225  } else
1226  return -1;
1227 }
1228 
1229 template <class T>
1230 Sint32 Argument_editor::set_value( Size parameter_index, Size component_index, const T& value)
1231 {
1232  promote_to_edit_if_needed();
1233 
1234  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1235 
1236  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1237  if( mi->is_default())
1238  return -4;
1239  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1240  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1241  if( !argument)
1242  return -2;
1243  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1244  // reuse existing constant expression
1245  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1246  base::Handle<IExpression_constant> new_argument_constant(
1247  new_argument->get_interface<IExpression_constant>());
1248  base::Handle<IValue> new_value( new_argument_constant->get_value());
1249  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1250  if( result != 0)
1251  return result == -3 ? -3 : -5;
1252  result = mi->set_argument( parameter_index, new_argument.get());
1253  mi_neuray_assert( result == 0);
1254  return result;
1255  } else {
1256  // create new constant expression
1257  base::Handle<const IType> type( argument->get_type());
1258  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1259  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1260  if( result != 0)
1261  return result == -3 ? -3 : -5;
1262  base::Handle<IExpression> new_expression(
1263  m_expression_factory->create_constant( new_value.get()));
1264  result = mi->set_argument( parameter_index, new_expression.get());
1265  mi_neuray_assert( result == 0);
1266  return result;
1267  }
1268 
1269  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1270 
1271  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1272  if( fc->is_default())
1273  return -4;
1274  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1275  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1276  if( !argument)
1277  return -2;
1278  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1279  // reuse existing constant expression
1280  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1281  base::Handle<IExpression_constant> new_argument_constant(
1282  new_argument->get_interface<IExpression_constant>());
1283  base::Handle<IValue> new_value( new_argument_constant->get_value());
1284  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1285  if( result != 0)
1286  return result == -3 ? -3 : -5;
1287  result = fc->set_argument( parameter_index, new_argument.get());
1288  mi_neuray_assert( result == 0);
1289  return result;
1290  } else {
1291  // create new constant expression
1292  base::Handle<const IType> type( argument->get_type());
1293  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1294  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1295  if( result != 0)
1296  return result == -3 ? -3 : -5;
1297  base::Handle<IExpression> new_expression(
1298  m_expression_factory->create_constant( new_value.get()));
1299  result = fc->set_argument( parameter_index, new_expression.get());
1300  mi_neuray_assert( result == 0);
1301  return result;
1302  }
1303 
1304  } else
1305  return -1;
1306 }
1307 
1308 template <class T>
1309 Sint32 Argument_editor::set_value( const char* parameter_name, Size component_index, const T& value)
1310 {
1311  promote_to_edit_if_needed();
1312 
1313  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1314 
1315  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1316  if( mi->is_default())
1317  return -4;
1318  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1319  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1320  if( !argument)
1321  return -2;
1322  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1323  // reuse existing constant expression
1324  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1325  base::Handle<IExpression_constant> new_argument_constant(
1326  new_argument->get_interface<IExpression_constant>());
1327  base::Handle<IValue> new_value( new_argument_constant->get_value());
1328  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1329  if( result != 0)
1330  return result == -3 ? -3 : -5;
1331  result = mi->set_argument( parameter_name, new_argument.get());
1332  mi_neuray_assert( result == 0);
1333  return result;
1334  } else {
1335  // create new constant expression
1336  base::Handle<const IType> type( argument->get_type());
1337  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1338  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1339  if( result != 0)
1340  return result == -3 ? -3 : -5;
1341  base::Handle<IExpression> new_expression(
1342  m_expression_factory->create_constant( new_value.get()));
1343  result = mi->set_argument( parameter_name, new_expression.get());
1344  mi_neuray_assert( result == 0);
1345  return result;
1346  }
1347 
1348  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1349 
1350  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1351  if( fc->is_default())
1352  return -4;
1353  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1354  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1355  if( !argument)
1356  return -2;
1357  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1358  // reuse existing constant expression
1359  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1360  base::Handle<IExpression_constant> new_argument_constant(
1361  new_argument->get_interface<IExpression_constant>());
1362  base::Handle<IValue> new_value( new_argument_constant->get_value());
1363  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1364  if( result != 0)
1365  return result == -3 ? -3 : -5;
1366  result = fc->set_argument( parameter_name, new_argument.get());
1367  mi_neuray_assert( result == 0);
1368  return result;
1369  } else {
1370  // create new constant expression
1371  base::Handle<const IType> type( argument->get_type());
1372  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1373  Sint32 result = neuraylib::set_value( new_value.get(), component_index, value);
1374  if( result != 0)
1375  return result == -3 ? -3 : -5;
1376  base::Handle<IExpression> new_expression(
1377  m_expression_factory->create_constant( new_value.get()));
1378  result = fc->set_argument( parameter_name, new_expression.get());
1379  mi_neuray_assert( result == 0);
1380  return result;
1381  }
1382 
1383  } else
1384  return -1;
1385 }
1386 
1387 template <class T>
1389  Size parameter_index, const char* field_name, const T& value)
1390 {
1391  promote_to_edit_if_needed();
1392 
1393  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1394 
1395  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1396  if( mi->is_default())
1397  return -4;
1398  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1399  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1400  if( !argument)
1401  return -2;
1402  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1403  // reuse existing constant expression
1404  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1405  base::Handle<IExpression_constant> new_argument_constant(
1406  new_argument->get_interface<IExpression_constant>());
1407  base::Handle<IValue> new_value( new_argument_constant->get_value());
1408  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1409  if( result != 0)
1410  return result == -3 ? -3 : -5;
1411  result = mi->set_argument( parameter_index, new_argument.get());
1412  mi_neuray_assert( result == 0);
1413  return result;
1414  } else {
1415  // create new constant expression
1416  base::Handle<const IType> type( argument->get_type());
1417  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1418  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1419  if( result != 0)
1420  return result == -3 ? -3 : -5;
1421  base::Handle<IExpression> new_expression(
1422  m_expression_factory->create_constant( new_value.get()));
1423  result = mi->set_argument( parameter_index, new_expression.get());
1424  mi_neuray_assert( result == 0);
1425  return result;
1426  }
1427 
1428  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1429 
1430  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1431  if( fc->is_default())
1432  return -4;
1433  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1434  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1435  if( !argument)
1436  return -2;
1437  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1438  // reuse existing constant expression
1439  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1440  base::Handle<IExpression_constant> new_argument_constant(
1441  new_argument->get_interface<IExpression_constant>());
1442  base::Handle<IValue> new_value( new_argument_constant->get_value());
1443  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1444  if( result != 0)
1445  return result == -3 ? -3 : -5;
1446  result = fc->set_argument( parameter_index, new_argument.get());
1447  mi_neuray_assert( result == 0);
1448  return result;
1449  } else {
1450  // create new constant expression
1451  base::Handle<const IType> type( argument->get_type());
1452  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1453  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1454  if( result != 0)
1455  return result == -3 ? -3 : -5;
1456  base::Handle<IExpression> new_expression(
1457  m_expression_factory->create_constant( new_value.get()));
1458  result = fc->set_argument( parameter_index, new_expression.get());
1459  mi_neuray_assert( result == 0);
1460  return result;
1461  }
1462 
1463  } else
1464  return -1;
1465 }
1466 
1467 template <class T>
1469  const char* parameter_name, const char* field_name, const T& value)
1470 {
1471  promote_to_edit_if_needed();
1472 
1473  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1474 
1475  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1476  if( mi->is_default())
1477  return -4;
1478  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1479  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1480  if( !argument)
1481  return -2;
1482  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1483  // reuse existing constant expression
1484  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1485  base::Handle<IExpression_constant> new_argument_constant(
1486  new_argument->get_interface<IExpression_constant>());
1487  base::Handle<IValue> new_value( new_argument_constant->get_value());
1488  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1489  if( result != 0)
1490  return result == -3 ? -3 : -5;
1491  result = mi->set_argument( parameter_name, new_argument.get());
1492  mi_neuray_assert( result == 0);
1493  return result;
1494  } else {
1495  // create new constant expression
1496  base::Handle<const IType> type( argument->get_type());
1497  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1498  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1499  if( result != 0)
1500  return result == -3 ? -3 : -5;
1501  base::Handle<IExpression> new_expression(
1502  m_expression_factory->create_constant( new_value.get()));
1503  result = mi->set_argument( parameter_name, new_expression.get());
1504  mi_neuray_assert( result == 0);
1505  return result;
1506  }
1507 
1508  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1509 
1510  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1511  if( fc->is_default())
1512  return -4;
1513  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1514  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1515  if( !argument)
1516  return -2;
1517  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1518  // reuse existing constant expression
1519  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1520  base::Handle<IExpression_constant> new_argument_constant(
1521  new_argument->get_interface<IExpression_constant>());
1522  base::Handle<IValue> new_value( new_argument_constant->get_value());
1523  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1524  if( result != 0)
1525  return result == -3 ? -3 : -5;
1526  result = fc->set_argument( parameter_name, new_argument.get());
1527  mi_neuray_assert( result == 0);
1528  return result;
1529  } else {
1530  // create new constant expression
1531  base::Handle<const IType> type( argument->get_type());
1532  base::Handle<IValue> new_value( m_value_factory->create( type.get()));
1533  Sint32 result = neuraylib::set_value( new_value.get(), field_name, value);
1534  if( result != 0)
1535  return result == -3 ? -3 : -5;
1536  base::Handle<IExpression> new_expression(
1537  m_expression_factory->create_constant( new_value.get()));
1538  result = fc->set_argument( parameter_name, new_expression.get());
1539  mi_neuray_assert( result == 0);
1540  return result;
1541  }
1542 
1543  } else
1544  return -1;
1545 }
1546 
1547 inline Sint32 Argument_editor::get_array_length( Uint32 parameter_index, Size& size) const
1548 {
1549  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1550 
1551  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1552  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1553  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1554  if( !argument)
1555  return -2;
1556  base::Handle<const IExpression_constant> argument_constant(
1557  argument->get_interface<IExpression_constant>());
1558  if( !argument_constant)
1559  return -4;
1560  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1561  if( !value)
1562  return -5;
1563  size = value->get_size();
1564  return 0;
1565 
1566  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1567 
1568  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1569  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1570  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1571  if( !argument)
1572  return -2;
1573  base::Handle<const IExpression_constant> argument_constant(
1574  argument->get_interface<IExpression_constant>());
1575  if( !argument_constant)
1576  return -4;
1577  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1578  if( !value)
1579  return -5;
1580  size = value->get_size();
1581  return 0;
1582 
1583  } else
1584  return -1;
1585 }
1586 
1587 inline Sint32 Argument_editor::get_array_length( const char* parameter_name, Size& size) const
1588 {
1589  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1590 
1591  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1592  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1593  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1594  if( !argument)
1595  return -2;
1596  base::Handle<const IExpression_constant> argument_constant(
1597  argument->get_interface<IExpression_constant>());
1598  if( !argument_constant)
1599  return -4;
1600  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1601  if( !value)
1602  return -5;
1603  size = value->get_size();
1604  return 0;
1605 
1606  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1607 
1608  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1609  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1610  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1611  if( !argument)
1612  return -2;
1613  base::Handle<const IExpression_constant> argument_constant(
1614  argument->get_interface<IExpression_constant>());
1615  if( !argument_constant)
1616  return -4;
1617  base::Handle<const IValue_array> value( argument_constant->get_value<IValue_array>());
1618  if( !value)
1619  return -5;
1620  size = value->get_size();
1621  return 0;
1622 
1623  } else
1624  return -1;
1625 }
1626 
1627 inline Sint32 Argument_editor::set_array_size( Uint32 parameter_index, Size size)
1628 {
1629  promote_to_edit_if_needed();
1630 
1631  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1632 
1633  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1634  if( mi->is_default())
1635  return -4;
1636  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1637  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1638  if( !argument)
1639  return -2;
1640  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1641  // reuse existing constant expression
1642  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1643  base::Handle<IExpression_constant> new_argument_constant(
1644  new_argument->get_interface<IExpression_constant>());
1645  base::Handle<IValue_array> new_value(
1646  new_argument_constant->get_value<IValue_array>());
1647  if( !new_value)
1648  return -5;
1649  Sint32 result = new_value->set_size( size);
1650  if( result != 0)
1651  return -5;
1652  result = mi->set_argument( parameter_index, new_argument.get());
1653  mi_neuray_assert( result == 0);
1654  return result;
1655  } else {
1656  // create new constant expression
1657  base::Handle<const IType> type( argument->get_type());
1658  base::Handle<IValue_array> new_value(
1659  m_value_factory->create<IValue_array>( type.get()));
1660  if( !new_value)
1661  return -5;
1662  Sint32 result = new_value->set_size( size);
1663  if( result != 0)
1664  return -5;
1665  base::Handle<IExpression> new_expression(
1666  m_expression_factory->create_constant( new_value.get()));
1667  result = mi->set_argument( parameter_index, new_expression.get());
1668  mi_neuray_assert( result == 0);
1669  return result;
1670  }
1671 
1672  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1673 
1674  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1675  if( fc->is_default())
1676  return -4;
1677  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1678  base::Handle<const IExpression> argument( arguments->get_expression( parameter_index));
1679  if( !argument)
1680  return -2;
1681  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1682  // reuse existing constant expression
1683  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1684  base::Handle<IExpression_constant> new_argument_constant(
1685  new_argument->get_interface<IExpression_constant>());
1686  base::Handle<IValue_array> new_value(
1687  new_argument_constant->get_value<IValue_array>());
1688  if( !new_value)
1689  return -5;
1690  Sint32 result = new_value->set_size( size);
1691  if( result != 0)
1692  return -5;
1693  result = fc->set_argument( parameter_index, new_argument.get());
1694  mi_neuray_assert( result == 0);
1695  return result;
1696  } else {
1697  // create new constant expression
1698  base::Handle<const IType> type( argument->get_type());
1699  base::Handle<IValue_array> new_value(
1700  m_value_factory->create<IValue_array>( type.get()));
1701  if( !new_value)
1702  return -5;
1703  Sint32 result = new_value->set_size( size);
1704  if( result != 0)
1705  return -5;
1706  base::Handle<IExpression> new_expression(
1707  m_expression_factory->create_constant( new_value.get()));
1708  result = fc->set_argument( parameter_index, new_expression.get());
1709  mi_neuray_assert( result == 0);
1710  return result;
1711  }
1712 
1713  } else
1714  return -1;
1715 }
1716 
1717 inline Sint32 Argument_editor::set_array_size( const char* parameter_name, Size size)
1718 {
1719  promote_to_edit_if_needed();
1720 
1721  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1722 
1723  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1724  if( mi->is_default())
1725  return -4;
1726  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1727  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1728  if( !argument)
1729  return -2;
1730  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1731  // reuse existing constant expression
1732  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1733  base::Handle<IExpression_constant> new_argument_constant(
1734  new_argument->get_interface<IExpression_constant>());
1735  base::Handle<IValue_array> new_value(
1736  new_argument_constant->get_value<IValue_array>());
1737  if( !new_value)
1738  return -5;
1739  Sint32 result = new_value->set_size( size);
1740  if( result != 0)
1741  return -5;
1742  result = mi->set_argument( parameter_name, new_argument.get());
1743  mi_neuray_assert( result == 0);
1744  return result;
1745  } else {
1746  // create new constant expression
1747  base::Handle<const IType> type( argument->get_type());
1748  base::Handle<IValue_array> new_value(
1749  m_value_factory->create<IValue_array>( type.get()));
1750  if( !new_value)
1751  return -5;
1752  Sint32 result = new_value->set_size( size);
1753  if( result != 0)
1754  return -5;
1755  base::Handle<IExpression> new_expression(
1756  m_expression_factory->create_constant( new_value.get()));
1757  result = mi->set_argument( parameter_name, new_expression.get());
1758  mi_neuray_assert( result == 0);
1759  return result;
1760  }
1761 
1762  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1763 
1764  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1765  if( fc->is_default())
1766  return -4;
1767  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1768  base::Handle<const IExpression> argument( arguments->get_expression( parameter_name));
1769  if( !argument)
1770  return -2;
1771  if( argument->get_kind() == IExpression::EK_CONSTANT) {
1772  // reuse existing constant expression
1773  base::Handle<IExpression> new_argument( m_expression_factory->clone( argument.get()));
1774  base::Handle<IExpression_constant> new_argument_constant(
1775  new_argument->get_interface<IExpression_constant>());
1776  base::Handle<IValue_array> new_value(
1777  new_argument_constant->get_value<IValue_array>());
1778  if( !new_value)
1779  return -5;
1780  Sint32 result = new_value->set_size( size);
1781  if( result != 0)
1782  return -5;
1783  result = fc->set_argument( parameter_name, new_argument.get());
1784  mi_neuray_assert( result == 0);
1785  return result;
1786  } else {
1787  // create new constant expression
1788  base::Handle<const IType> type( argument->get_type());
1789  base::Handle<IValue_array> new_value(
1790  m_value_factory->create<IValue_array>( type.get()));
1791  if( !new_value)
1792  return -5;
1793  Sint32 result = new_value->set_size( size);
1794  if( result != 0)
1795  return -5;
1796  base::Handle<IExpression> new_expression(
1797  m_expression_factory->create_constant( new_value.get()));
1798  result = fc->set_argument( parameter_name, new_expression.get());
1799  mi_neuray_assert( result == 0);
1800  return result;
1801  }
1802 
1803  } else
1804  return -1;
1805 }
1806 
1807 inline const char* Argument_editor::get_call( Size parameter_index) const
1808 {
1809  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1810 
1811  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1812  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1814  arguments->get_expression<IExpression_call>( parameter_index));
1815  if( !argument)
1816  return 0;
1817  return argument->get_call();
1818 
1819  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1820 
1821  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1822  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1824  arguments->get_expression<IExpression_call>( parameter_index));
1825  if( !argument)
1826  return 0;
1827  return argument->get_call();
1828 
1829  } else
1830  return 0;
1831 }
1832 
1833 inline const char* Argument_editor::get_call( const char* parameter_name) const
1834 {
1835  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1836 
1837  base::Handle<const IMaterial_instance> mi( m_access->get_interface<IMaterial_instance>());
1838  base::Handle<const IExpression_list> arguments( mi->get_arguments());
1840  arguments->get_expression<IExpression_call>( parameter_name));
1841  if( !argument)
1842  return 0;
1843  return argument->get_call();
1844 
1845  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1846 
1847  base::Handle<const IFunction_call> fc( m_access->get_interface<IFunction_call>());
1848  base::Handle<const IExpression_list> arguments( fc->get_arguments());
1850  arguments->get_expression<IExpression_call>( parameter_name));
1851  if( !argument)
1852  return 0;
1853  return argument->get_call();
1854 
1855  } else
1856  return 0;
1857 }
1858 
1859 inline Sint32 Argument_editor::set_call( Size parameter_index, const char* call_name)
1860 {
1861  promote_to_edit_if_needed();
1862 
1863  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1864 
1865  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1866  if( !new_argument)
1867  return -6;
1868  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1869  return mi->set_argument( parameter_index, new_argument.get());
1870 
1871  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1872 
1873  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1874  if( !new_argument)
1875  return -6;
1876  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1877  return fc->set_argument( parameter_index, new_argument.get());
1878 
1879  } else
1880  return -1;
1881 }
1882 
1883 inline Sint32 Argument_editor::set_call( const char* parameter_name, const char* call_name)
1884 {
1885  promote_to_edit_if_needed();
1886 
1887  if( m_type == ELEMENT_TYPE_MATERIAL_INSTANCE) {
1888 
1889  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1890  if( !new_argument)
1891  return -6;
1892  base::Handle<IMaterial_instance> mi( m_edit->get_interface<IMaterial_instance>());
1893  return mi->set_argument( parameter_name, new_argument.get());
1894 
1895  } else if( m_type == ELEMENT_TYPE_FUNCTION_CALL) {
1896 
1897  base::Handle<IExpression_call> new_argument( m_expression_factory->create_call( call_name));
1898  if( !new_argument)
1899  return -6;
1900  base::Handle<IFunction_call> fc( m_edit->get_interface<IFunction_call>());
1901  return fc->set_argument( parameter_name, new_argument.get());
1902 
1903  } else
1904  return -1;
1905 }
1906 
1908 {
1909  m_transaction->retain();
1910  return m_transaction.get();
1911 }
1912 
1914 {
1915  m_mdl_factory->retain();
1916  return m_mdl_factory.get();
1917 }
1918 
1920 {
1921  m_value_factory->retain();
1922  return m_value_factory.get();
1923 }
1924 
1926 {
1927  m_expression_factory->retain();
1928  return m_expression_factory.get();
1929 }
1930 
1932 {
1933  m_access->retain();
1934  return m_access.get();
1935 }
1936 
1938 {
1939  promote_to_edit_if_needed();
1940 
1941  m_edit->retain();
1942  return m_edit.get();
1943 }
1944 
1946 {
1947  return m_type;
1948 }
1949 
1950 inline const std::string& Argument_editor::get_name() const
1951 {
1952  return m_name;
1953 }
1954 
1955 inline void Argument_editor::promote_to_edit_if_needed()
1956 {
1957  if( m_edit)
1958  return;
1959  m_edit = m_transaction->edit<IScene_element>( m_name.c_str());
1960  mi_neuray_assert( m_edit);
1961  m_old_access = m_access;
1962  m_access = m_edit;
1963 }
1964 
1965 } // namespace neuraylib
1966 
1967 } // namespace mi
1968 
1969 #endif // MI_NEURAYLIB_ARGUMENT_EDITOR_H