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