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