7f2525382774eda30ee04dd9c17a58d10f908bbb
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_plot3d.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * Copyright (C) 2008 - INRIA - Sylvestre LEDRU (nicer default plot3d)
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 /*------------------------------------------------------------------------*/
19 /* file: sci_plot3d.c                                                     */
20 /* desc : interface for plot3d (and plot3d1) routine                      */
21 /*------------------------------------------------------------------------*/
22
23 #include <stdio.h>
24 #include <string.h>
25 #include "gw_graphics.h"
26 #include "api_scilab.h"
27 #include "BuildObjects.h"
28 #include "GetCommandArg.h"
29 #include "sci_malloc.h"
30 #include "sciCall.h"
31 #include "localization.h"
32 #include "Scierror.h"
33
34 /*--------------------------------------------------------------------------*/
35 int sci_plot3d(char * fname, void *pvApiCtx)
36 {
37     SciErr sciErr;
38     static double  ebox_def [6] = { 0, 1, 0, 1, 0, 1};
39     double *ebox = ebox_def;
40     static int iflag_def[3] = {2, 2, 4};
41     int *iflag = iflag_def;
42     double  alpha_def = 35.0 , theta_def = 45.0;
43     double *alpha = &alpha_def, *theta = &theta_def;
44     int m1 = 0, n1 = 0,  m2 = 0, n2 = 0, m3 = 0, n3 = 0;
45     int m3n = 0, n3n = 0, m3l = 0;
46
47     int izcol = 0,  isfac = 0;
48     double *zcol = NULL;
49     int mustFree = 0;
50
51     static rhs_opts opts[] =
52     {
53         { -1, "alpha", -1, 0, 0, NULL},
54         { -1, "ebox", -1, 0, 0, NULL},
55         { -1, "flag", -1, 0, 0, NULL},
56         { -1, "leg", -1, 0, 0, NULL},
57         { -1, "theta", -1, 0, 0, NULL},
58         { -1, NULL, -1, 0, 0, NULL}
59     };
60
61     char * legend = NULL;
62
63     int* piAddr1  = NULL;
64     int* piAddr2  = NULL;
65     int* piAddr3  = NULL;
66     int* piAddr31 = NULL;
67     int* piAddr32 = NULL;
68
69     double* l1  = NULL;
70     double* l2  = NULL;
71     double* l3  = NULL;
72     double* l3n = NULL;
73
74     /*
75     ** This overload the function to call demo script
76     ** the demo script is called %_<fname>
77     */
78     if (nbInputArgument(pvApiCtx) <= 0)
79     {
80         sci_demo(fname, pvApiCtx);
81         return 0;
82     }
83
84     if (nbInputArgument(pvApiCtx) == 2)
85     {
86         Scierror(77, _("%s: Wrong number of input argument(s).\n"), fname);
87         return -1;
88     }
89
90     CheckInputArgument(pvApiCtx, 1, 8);
91
92     if (getOptionals(pvApiCtx, fname, opts) == 0)
93     {
94         ReturnArguments(pvApiCtx);
95         return 0;
96     }
97
98     if (nbInputArgument(pvApiCtx) != 1 && FirstOpt(pvApiCtx) < 4)
99     {
100         Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"), fname, 1, 4);
101         return -1;
102     }
103
104     //get variable address
105     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
106     if (sciErr.iErr)
107     {
108         printError(&sciErr, 0);
109         return 1;
110     }
111
112     // Retrieve a matrix of double at position 1.
113     sciErr = getMatrixOfDouble(pvApiCtx, piAddr1, &m1, &n1, &l1);
114     if (sciErr.iErr)
115     {
116         Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 1);
117         printError(&sciErr, 0);
118         return 1;
119     }
120
121     if (nbInputArgument(pvApiCtx) == 1)
122     {
123         int i;
124
125         if (m1 * n1 == 0)
126         {
127             AssignOutputVariable(pvApiCtx, 1) = 0;
128             ReturnArguments(pvApiCtx);
129             return 0;
130         }
131
132         if (m1 == 1 || n1 == 1)
133         {
134             Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 1);
135             return 1;
136         }
137
138         l3 = l1;
139         m3 = m1;
140         n3 = n1;
141         m1 = 1;
142         n1 = m3;
143         m2 = 1;
144         n2 = n3;
145         l1 = (double *)MALLOC(sizeof(double) * n1);
146         for (i = 0; i < n1; ++i)
147         {
148             l1[i] = i + 1;
149         }
150         l2 = (double *)MALLOC(sizeof(double) * n2);
151         for (i = 0; i < n2; ++i)
152         {
153             l2[i] = i + 1;
154         }
155
156         mustFree = 1;
157     }
158
159     if (nbInputArgument(pvApiCtx) >= 3)
160     {
161         //get variable address
162         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
163         if (sciErr.iErr)
164         {
165             printError(&sciErr, 0);
166             return 1;
167         }
168
169         // Retrieve a matrix of double at position 2.
170         sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &m2, &n2, &l2);
171         if (sciErr.iErr)
172         {
173             Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 2);
174             printError(&sciErr, 0);
175             return 1;
176         }
177
178         if (m1 * n1 == 0)
179         {
180             AssignOutputVariable(pvApiCtx, 1) = 0;
181             ReturnArguments(pvApiCtx);
182             return 0;
183         }
184
185         /*     third argument can be a matrix z or a list list(z,zcol) */
186         sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
187         if (sciErr.iErr)
188         {
189             printError(&sciErr, 0);
190             return 1;
191         }
192
193         switch (getInputArgumentType(pvApiCtx, 3))
194         {
195             case sci_matrix :
196                 //get variable address
197                 sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
198                 if (sciErr.iErr)
199                 {
200                     printError(&sciErr, 0);
201                     return 1;
202                 }
203
204                 // Retrieve a matrix of double at position 3.
205                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &m3, &n3, &l3);
206                 if (sciErr.iErr)
207                 {
208                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
209                     printError(&sciErr, 0);
210                     return 1;
211                 }
212
213                 izcol = 0;
214                 break;
215             case sci_list :
216                 izcol = 1;
217                 /* z = list(z,colors) */
218                 sciErr = getListItemNumber(pvApiCtx, piAddr3, &m3l);
219                 if (sciErr.iErr)
220                 {
221                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
222                     printError(&sciErr, 0);
223                     return 1;
224                 }
225
226                 if (m3l != 2)
227                 {
228                     Scierror(999, _("%s: Wrong size for input argument #%d: List of size %d expected.\n"),
229                              fname, 2, m3l, 2);
230                     return 1;
231                 }
232
233                 sciErr = getListItemAddress(pvApiCtx, piAddr3, 1, &piAddr31);
234                 if (sciErr.iErr)
235                 {
236                     printError(&sciErr, 0);
237                     return 1;
238                 }
239
240                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr31, &m3, &n3, &l3); /* z */
241                 if (sciErr.iErr)
242                 {
243                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
244                     printError(&sciErr, 0);
245                     return 1;
246                 }
247
248                 sciErr = getListItemAddress(pvApiCtx, piAddr3, 2, &piAddr32);
249                 if (sciErr.iErr)
250                 {
251                     printError(&sciErr, 0);
252                     return 1;
253                 }
254
255                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr32, &m3n, &n3n, &l3n); /* z */
256                 if (sciErr.iErr)
257                 {
258                     Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 3);
259                     printError(&sciErr, 0);
260                     return 1;
261                 }
262
263                 zcol  = (l3n);
264                 if (m3n * n3n != n3 &&  m3n * n3n != m3 * n3)
265                 {
266                     Scierror(999, _("%s: Wrong size for input argument #%d: %d or %d expected.\n"), fname, 3, n3, m3 * n3);
267                     return 1;
268                 }
269                 /*
270                  *   Added by E Segre 4/5/2000. In the case where zcol is a
271                  *   matrix of the same size as z, we set izcol to 2. This
272                  *   value is later transmitted to the C2F(fac3dg) routine,
273                  *   which has been modified to do the interpolated shading
274                  *    (see the file SCI/modules/graphics/src/c/Plo3d.c
275                  */
276                 if (m3n * n3n == m3 * n3)
277                 {
278                     izcol = 2 ;
279                 }
280                 break;
281             default :
282                 OverLoad(3);
283                 return 0;
284         }
285     }
286
287     if (m1 * n1 == m3 * n3 && m1 * n1 == m2 * n2 && m1 * n1 != 1)
288     {
289         if (! (m1 == m2 && m2 == m3 && n1 == n2 && n2 == n3))
290         {
291             Scierror(999, _("%s: Wrong value for input arguments #%d, #%d and #%d: Incompatible length.\n"), fname, 1, 2, 3);
292             return 1;
293         }
294     }
295     else
296     {
297         if (m2 * n2 != n3)
298         {
299             Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Incompatible length.\n"), fname, 2, 3);
300             return 1;
301         }
302
303         if (m1 * n1 != m3)
304         {
305             Scierror(999, _("%s: Wrong value for input arguments #%d and #%d: Incompatible length.\n"), fname, 1, 3);
306             return 1;
307         }
308
309         if (m1 * n1 <= 1 || m2 * n2 <= 1)
310         {
311             Scierror(999, _("%s: Wrong size for input arguments #%d and #%d: %s expected.\n"), fname, 2, 3, ">= 2");
312             return 1;
313         }
314     }
315
316     if (m1 * n1 == 0 || m2 * n2 == 0 || m3 * n3 == 0)
317     {
318         AssignOutputVariable(pvApiCtx, 1) = 0;
319         ReturnArguments(pvApiCtx);
320         return 0;
321     }
322
323     iflag_def[1] = 8;
324
325     if (get_optional_double_arg(pvApiCtx, fname, 4, "theta", &theta, 1, opts) == 0)
326     {
327         return 0;
328     }
329     if (get_optional_double_arg(pvApiCtx, fname, 5, "alpha", &alpha, 1, opts) == 0)
330     {
331         return 0;
332     }
333     if (get_labels_arg(pvApiCtx, fname, 6, opts, &legend) == 0)
334     {
335         return 0;
336     }
337     if (get_optional_int_arg(pvApiCtx, fname, 7, "flag", &iflag, 3, opts) == 0)
338     {
339         return 0;
340     }
341     if (get_optional_double_arg(pvApiCtx, fname, 8, "ebox", &ebox, 6, opts) == 0)
342     {
343         return 0;
344     }
345
346
347     getOrCreateDefaultSubwin();
348
349     /******************** 24/05/2002 ********************/
350     if (m1 * n1 == m3 * n3 && m1 * n1 == m2 * n2 && m1 * n1 != 1) /* NG beg */
351     {
352         isfac = 1;
353     }
354     else
355     {
356         isfac = 0;
357     }
358
359
360     Objplot3d (fname, &isfac, &izcol, (l1), (l2), (l3), zcol, &m3, &n3, theta, alpha, legend, iflag, ebox, &m1, &n1, &m2, &n2, &m3, &n3, &m3n, &n3n); /*Adding F.Leray 12.03.04 and 19.03.04*/
361
362     if (mustFree)
363     {
364         FREE(l1);
365         FREE(l2);
366     }
367
368     AssignOutputVariable(pvApiCtx, 1) = 0;
369     ReturnArguments(pvApiCtx);
370     return 0;
371
372 }
373 /*--------------------------------------------------------------------------*/