3993585d634a7a253b9a21600d72f2e09241e465
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Scene3D / src / public / Controls / Model.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.Runtime.InteropServices;
20 using System.ComponentModel;
21 using Tizen.NUI;
22 using Tizen.NUI.Binding;
23 using Tizen.NUI.BaseComponents;
24
25 namespace Tizen.NUI.Scene3D
26 {
27     /// <summary>
28     /// Model is a Class to show 3D mesh objects.
29     /// Model supports glTF 2.0 and DLI model formats.
30     /// Physically Based Rendering with Image Based Lighting is also supported.
31     /// </summary>
32     ///
33     /// <remarks>
34     /// Since NUI uses a left-handed coordinate system, loaded models are transformed into a left-handed coordinate system with Y pointing down.
35     /// The Animations defined in the glTF or DLI are also loaded and can be retrieved by using <see cref="GetAnimation(uint)"/> and <see cref="GetAnimation(string)"/> methods.
36     /// The number of animation is also retrieved by GetAnimationCount() method.
37     ///
38     /// Model also supports Physically Based Rendering(PBR) with Image Based Lighting(IBL).
39     /// For the IBL, two cube map textures(diffuse and specular) are required.
40     /// Model supports 4 types layout for Cube Map: Vertical/Horizontal Cross layouts, and Vertical/Horizontal Array layouts.
41     /// And also, ktx format with cube map is supported.
42     ///
43     /// The model and IBL textures start to be loaded asynchronously when the Model object is on Window.
44     /// ResourcesLoaded signal notifies that the loading of the model and IBL resources have been completed.
45     /// If Model or IBL is requested to be loaded before the other loading is completed, the ResourcesLoaded signal is called after all resources are loaded.
46     /// <see cref="GetAnimation(uint)"/> and <see cref="GetAnimation(string)"/> methods can be used after the model loading is finished.
47     ///
48     /// By default, the loaded mesh has its own size and <see cref="PivotPoint"/> inferred from position of vertices.
49     /// The <see cref="PivotPoint"/> can be modified after model loading is finished.
50     /// If user set size property, the mesh will be scaled to the input size.
51     /// Default value of <see cref="ParentOrigin"/> of the Model is Center.
52     /// </remarks>
53     ///
54     /// <example>
55     /// <code>
56     /// Model model = new Model(modelUrl)
57     /// {
58     ///     Size = new Size(width, height),
59     /// };
60     /// model.ResourcesLoaded += (s, e) =>
61     /// {
62     ///     model.PivotPoint = new Vector3(0.5f, 0.5f, 0.5f); // Use center as a Pivot.
63     ///
64     ///     int animationCount = model.GetAnimationCount();
65     ///     if(animationCount > 0)
66     ///     {
67     ///         // Play an Animation of index 0.
68     ///         model.GetAnimation(0).Play();
69     ///     }
70     /// };
71     /// model.SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
72     /// window.Add(model);
73     ///
74     /// </code>
75     /// </example>
76     /// <since_tizen> 10 </since_tizen>
77     public class Model : View
78     {
79         internal Model(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
80         {
81         }
82
83         /// <summary>
84         /// Create an initialized Model.
85         /// </summary>
86         /// <param name="modelUrl">model file url.(e.g. glTF, and DLI).</param>
87         /// <param name="resourceDirectoryUrl"> The url to derectory containing resources: binary, image etc.</param>
88         /// <remarks>
89         /// If resourceDirectoryUrl is empty, the parent directory url of modelUrl is used for resource url.
90         ///
91         /// http://tizen.org/privilege/mediastorage for local files in media storage.
92         /// http://tizen.org/privilege/externalstorage for local files in external storage.
93         /// </remarks>
94         /// <since_tizen> 10 </since_tizen>
95         public Model(string modelUrl, string resourceDirectoryUrl = "") : this(Interop.Model.ModelNew(modelUrl, resourceDirectoryUrl), true)
96         {
97             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
98             this.PositionUsesAnchorPoint = true;
99         }
100
101         /// <summary>
102         /// Create an initialized Model.
103         /// </summary>
104         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
105         [EditorBrowsable(EditorBrowsableState.Never)]
106         public Model() : this(Interop.Model.ModelNew(), true)
107         {
108             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
109             this.PositionUsesAnchorPoint = true;
110         }
111
112         /// <summary>
113         /// Copy constructor.
114         /// </summary>
115         /// <param name="model">Source object to copy.</param>
116         /// <since_tizen> 10 </since_tizen>
117         public Model(Model model) : this(Interop.Model.NewModel(Model.getCPtr(model)), true)
118         {
119             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
120         }
121
122         /// <summary>
123         /// Assignment operator.
124         /// </summary>
125         /// <param name="model">Source object to be assigned.</param>
126         /// <returns>Reference to this.</returns>
127         internal Model Assign(Model model)
128         {
129             Model ret = new Model(Interop.Model.ModelAssign(SwigCPtr, Model.getCPtr(model)), false);
130             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
131             return ret;
132         }
133
134         /// <summary>
135         /// Set/Get the ImageBasedLight ScaleFactor.
136         /// Scale factor controls light source intensity in [0.0f, 1.0f]
137         /// </summary>
138         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
139         [EditorBrowsable(EditorBrowsableState.Never)]
140         public float ImageBasedLightScaleFactor
141         {
142             set
143             {
144                 SetImageBasedLightScaleFactor(value);
145             }
146             get
147             {
148                 return GetImageBasedLightScaleFactor();
149             }
150         }
151
152         /// <summary>
153         /// Adds modelNode to this Model.
154         /// </summary>
155         /// <param name="modelRoot">Root of a ModelNode tree</param>
156         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
157         [EditorBrowsable(EditorBrowsableState.Never)]
158         public void AddModelNode(ModelNode modelRoot)
159         {
160             Interop.Model.AddModelNode(SwigCPtr, ModelNode.getCPtr(modelRoot));
161             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
162         }
163
164         /// <summary>
165         /// Removes modelNode from this Model.
166         /// </summary>
167         /// <param name="modelRoot">Root of a ModelNode tree to be removed</param>
168         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
169         [EditorBrowsable(EditorBrowsableState.Never)]
170         public void RemoveModelNode(ModelNode modelRoot)
171         {
172             Interop.Model.RemoveModelNode(SwigCPtr, ModelNode.getCPtr(modelRoot));
173             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
174         }
175
176         /// <summary>
177         /// Removes Returns a child ModelNode object with a name that matches nodeName.
178         /// </summary>
179         /// <param name="nodeName">The name of the child ModelNode object you want to find.</param>
180         /// <returns>Child ModelNode that has nodeName as name.</returns>
181         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
182         [EditorBrowsable(EditorBrowsableState.Never)]
183         public ModelNode FindChildModelNodeByName(string nodeName)
184         {
185             global::System.IntPtr cPtr = Interop.Model.FindChildModelNodeByName(SwigCPtr, nodeName);
186             ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
187             if (ret == null)
188             {
189                 // Register new animatable into Registry.
190                 ret = new ModelNode(cPtr, true);
191             }
192             else
193             {
194                 // We found matched NUI animatable. Reduce cPtr reference count.
195                 HandleRef handle = new HandleRef(this, cPtr);
196                 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
197                 handle = new HandleRef(null, IntPtr.Zero);
198             }
199             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
200             return ret;
201         }
202
203         /// <summary>
204         /// Changes Image Based Light according to the given input textures.
205         /// </summary>
206         /// <param name="diffuseUrl">The path of Cube map image that will be used as a diffuse IBL source.</param>
207         /// <param name="specularUrl">The path of Cube map image that will be used as a specular IBL source.</param>
208         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
209         /// <remarks>
210         /// http://tizen.org/privilege/mediastorage for local files in media storage.
211         /// http://tizen.org/privilege/externalstorage for local files in external storage.
212         /// </remarks>
213         /// <since_tizen> 10 </since_tizen>
214         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
215         {
216             Interop.Model.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
217             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
218         }
219
220         /// <summary>
221         /// Gets number of animations that has been loaded from model file.
222         /// </summary>
223         /// <remarks>
224         /// This method should be called after Model load has been finished.
225         /// </remarks>
226         /// <returns>The number of loaded animations.</returns>
227         /// <since_tizen> 10 </since_tizen>
228         public uint GetAnimationCount()
229         {
230             uint ret = Interop.Model.GetAnimationCount(SwigCPtr);
231             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
232             return ret;
233         }
234
235         /// <summary>
236         /// Gets animation at the index.
237         /// </summary>
238         /// <remarks>
239         /// This method should be called after Model load has been finished.
240         /// </remarks>
241         /// <param name="index">Index of animation to be retrieved.</param>
242         /// <returns>Animation at the index.</returns>
243         /// <since_tizen> 10 </since_tizen>
244         public Animation GetAnimation(uint index)
245         {
246             global::System.IntPtr cPtr = Interop.Model.GetAnimation(SwigCPtr, index);
247             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
248             if (ret == null)
249             {
250                 // Register new animation into Registry.
251                 ret = new Animation(cPtr, true);
252             }
253             else
254             {
255                 // We found matched NUI animation. Reduce cPtr reference count.
256                 HandleRef handle = new HandleRef(this, cPtr);
257                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
258                 handle = new HandleRef(null, IntPtr.Zero);
259             }
260             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
261             return ret;
262         }
263
264         /// <summary>
265         /// Retrieves animation with the given name.
266         /// Note: This method should be called after Model load finished.
267         /// </summary>
268         /// <param name="name">String name of animation to be retrieved.</param>
269         /// <returns>Animation that has the given name.</returns>
270         /// <since_tizen> 10 </since_tizen>
271         public Animation GetAnimation(string name)
272         {
273             global::System.IntPtr cPtr = Interop.Model.GetAnimation(SwigCPtr, name);
274             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
275             if (ret == null)
276             {
277                 // Register new animation into Registry.
278                 ret = new Animation(cPtr, true);
279             }
280             else
281             {
282                 // We found matched NUI animation. Reduce cPtr reference count.
283                 HandleRef handle = new HandleRef(this, cPtr);
284                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
285                 handle = new HandleRef(null, IntPtr.Zero);
286             }
287             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
288             return ret;
289         }
290
291         /// <summary>
292         /// Gets number of camera parameters that has been loaded from model file.
293         /// </summary>
294         /// <remarks>
295         /// This method should be called after Model load has been finished.
296         /// </remarks>
297         /// <returns>The number of loaded camera parameters.</returns>
298         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
299         [EditorBrowsable(EditorBrowsableState.Never)]
300         public uint GetCameraCount()
301         {
302             uint ret = Interop.Model.GetCameraCount(SwigCPtr);
303             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
304             return ret;
305         }
306
307         /// <summary>
308         /// Generate Camera using camera parameters at the index.
309         /// If camera parameter is valid, create new Camera.
310         /// Else, return empty Handle.
311         /// </summary>
312         /// <remarks>
313         /// This method should be called after Model load has been finished.
314         /// </remarks>
315         /// <param name="index">Index of camera to be generated.</param>
316         /// <returns>Generated Camera by the index, or empty Handle if generation failed.</returns>
317         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
318         [EditorBrowsable(EditorBrowsableState.Never)]
319         public Camera GenerateCamera(uint index)
320         {
321             global::System.IntPtr cPtr = Interop.Model.GenerateCamera(SwigCPtr, index);
322             Camera ret = new Camera(cPtr, true); // Always create new camera.
323             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
324             return ret;
325         }
326
327         /// <summary>
328         /// Apply camera parameters at the index to inputed Camera.
329         /// If camera parameter is valid and camera is not empty, apply parameters.
330         /// It will change camera's transform and near / far / fov or orthographic size / aspect ratio (if defined)
331         /// </summary>
332         /// <remarks>
333         /// This method should be called after Model load has been finished.
334         /// </remarks>
335         /// <param name="index">Index of camera to be retrieved.</param>
336         /// <param name="camera">Camera to be applied parameter.</param>
337         /// <returns>True if Apply successed. False otherwise.</returns>
338         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
339         [EditorBrowsable(EditorBrowsableState.Never)]
340         public bool ApplyCamera(uint index, Camera camera)
341         {
342             bool ret = false;
343             if (camera?.HasBody() == true)
344             {
345                 ret = Interop.Model.ApplyCamera(SwigCPtr, index, Camera.getCPtr(camera));
346                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
347             }
348             return ret;
349         }
350
351         /// <summary>
352         /// Load bvh animation and assign to model.
353         /// Scale is additional scale factor of bvh animation. It is possible that
354         /// Model's scale may not matched with bvh animation scale.
355         /// If scale is null, default use as Vector3.ONE
356         /// </summary>
357         /// <param name="bvhFilename">Name of bvh format file.</param>
358         /// <param name="scale">Scale value of bvh animation match with model.</param>
359         /// <param name="translateRootFromModelNode">Whether we should translate the bvh root from it's ModelNode position or not.</param>
360         /// <returns>Animaion of bvh</returns>
361         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
362         [EditorBrowsable(EditorBrowsableState.Never)]
363         public Animation LoadBvhAnimation(string bvhFilename, Vector3 scale = null, bool translateRootFromModelNode = true)
364         {
365             global::System.IntPtr cPtr = Interop.Model.LoadBvhAnimation(SwigCPtr, bvhFilename, Vector3.getCPtr(scale), translateRootFromModelNode);
366             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
367             if (ret == null)
368             {
369                 // Register new animation into Registry.
370                 ret = new Animation(cPtr, true);
371             }
372             else
373             {
374                 // We found matched NUI animation. Reduce cPtr reference count.
375                 HandleRef handle = new HandleRef(this, cPtr);
376                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
377                 handle = new HandleRef(null, IntPtr.Zero);
378             }
379             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
380             return ret;
381         }
382
383         /// <summary>
384         /// Load bvh animation and assign to model.
385         /// Scale is additional scale factor of bvh animation. It is possible that
386         /// Model's scale may not matched with bvh animation scale.
387         /// If scale is null, default use as Vector3.ONE
388         /// </summary>
389         /// <param name="bvhBuffer">Contents of bvh format file.</param>
390         /// <param name="scale">Scale value of bvh animation match with model.</param>
391         /// <param name="translateRootFromModelNode">Whether we should translate the bvh root from it's ModelNode position or not.</param>
392         /// <returns>Animaion of bvh</returns>
393         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
394         [EditorBrowsable(EditorBrowsableState.Never)]
395         public Animation LoadBvhAnimationFromBuffer(string bvhBuffer, Vector3 scale = null, bool translateRootFromModelNode = true)
396         {
397             global::System.IntPtr cPtr = Interop.Model.LoadBvhAnimationFromBuffer(SwigCPtr, bvhBuffer, bvhBuffer.Length, Vector3.getCPtr(scale), translateRootFromModelNode);
398             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
399             if (ret == null)
400             {
401                 // Register new animation into Registry.
402                 ret = new Animation(cPtr, true);
403             }
404             else
405             {
406                 // We found matched NUI animation. Reduce cPtr reference count.
407                 HandleRef handle = new HandleRef(this, cPtr);
408                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
409                 handle = new HandleRef(null, IntPtr.Zero);
410             }
411             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
412             return ret;
413         }
414
415         /// <summary>
416         /// Load facial animation and assign to model.
417         /// </summary>
418         /// <param name="facialFilename">Name of json format file what we predefined.</param>
419         /// <returns>Animaion of facial</returns>
420         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
421         [EditorBrowsable(EditorBrowsableState.Never)]
422         public Animation LoadFacialAnimation(string facialFilename)
423         {
424             global::System.IntPtr cPtr = Interop.Model.LoadFacialAnimation(SwigCPtr, facialFilename);
425             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
426             if (ret == null)
427             {
428                 // Register new animation into Registry.
429                 ret = new Animation(cPtr, true);
430             }
431             else
432             {
433                 // We found matched NUI animation. Reduce cPtr reference count.
434                 HandleRef handle = new HandleRef(this, cPtr);
435                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
436                 handle = new HandleRef(null, IntPtr.Zero);
437             }
438             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
439             return ret;
440         }
441
442         /// <summary>
443         /// Load facial animation and assign to model.
444         /// </summary>
445         /// <param name="facialBuffer">Contents of json format file what we predefined.</param>
446         /// <returns>Animaion of facial</returns>
447         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
448         [EditorBrowsable(EditorBrowsableState.Never)]
449         public Animation LoadFacialAnimationFromBuffer(string facialBuffer)
450         {
451             global::System.IntPtr cPtr = Interop.Model.LoadFacialAnimationFromBuffer(SwigCPtr, facialBuffer, facialBuffer.Length);
452             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
453             if (ret == null)
454             {
455                 // Register new animation into Registry.
456                 ret = new Animation(cPtr, true);
457             }
458             else
459             {
460                 // We found matched NUI animation. Reduce cPtr reference count.
461                 HandleRef handle = new HandleRef(this, cPtr);
462                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
463                 handle = new HandleRef(null, IntPtr.Zero);
464             }
465             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
466             return ret;
467         }
468
469         /// <summary>
470         /// Retrieves model root Actor.
471         /// </summary>
472         /// <returns>Root View of the model.</returns>
473         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
474         [EditorBrowsable(EditorBrowsableState.Never)]
475         private ModelNode GetModelRoot()
476         {
477             global::System.IntPtr cPtr = Interop.Model.GetModelRoot(SwigCPtr);
478             ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
479             if (ret == null)
480             {
481                 // Register new animatable into Registry.
482                 ret = new ModelNode(cPtr, true);
483             }
484             else
485             {
486                 // We found matched NUI animatable. Reduce cPtr reference count.
487                 HandleRef handle = new HandleRef(this, cPtr);
488                 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
489                 handle = new HandleRef(null, IntPtr.Zero);
490             }
491             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
492             return ret;
493         }
494
495         /// <summary>
496         /// Set the ImageBasedLight ScaleFactor.
497         /// </summary>
498         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
499         private void SetImageBasedLightScaleFactor(float scaleFactor)
500         {
501             Interop.Model.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
502             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
503         }
504
505         /// <summary>
506         /// Get the ImageBasedLight ScaleFactor.
507         /// </summary>
508         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
509         private float GetImageBasedLightScaleFactor()
510         {
511             float scaleFactor = Interop.Model.GetImageBasedLightScaleFactor(SwigCPtr);
512             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
513             return scaleFactor;
514         }
515
516         /// <summary>
517         /// Release swigCPtr.
518         /// </summary>
519         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
520         [EditorBrowsable(EditorBrowsableState.Never)]
521         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
522         {
523             Interop.Model.DeleteModel(swigCPtr);
524         }
525     }
526 }