Bug 12232 fixed: fix several memleaks in various filler
[scilab.git] / scilab / modules / graphic_objects / src / cpp / Plot3DDecomposer.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2012 - DIGITEO - Manuel Juliachs
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include <cstring>
14
15 #include "ColorComputer.hxx"
16 #include "DecompositionUtils.hxx"
17 #include "Plot3DDecomposer.hxx"
18
19 extern "C"
20 {
21 #include "getGraphicObjectProperty.h"
22 #include "graphicObjectProperties.h"
23 }
24
25 Plot3DDecomposer* Plot3DDecomposer::decomposer = NULL;
26
27 void Plot3DDecomposer::fillVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask)
28 {
29     double* x = NULL;
30     double* y = NULL;
31     double* z = NULL;
32
33     int numX = 0;
34     int* piNumX = &numX;
35     int numY = 0;
36     int* piNumY = &numY;
37
38     Plot3DDecomposer* decomposer = get();
39
40     getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x);
41     getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y);
42     getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
43
44     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX);
45     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY);
46
47     decomposer->fillGridVertices(buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, x, y, z, numX, numY);
48 }
49
50 double Plot3DDecomposer::getZCoordinate(double* z, int numX, int numY, int i, int j)
51 {
52     double zij = 0.;
53
54     zij = z[numX*j+i];
55
56     return zij;
57 }
58
59 double Plot3DDecomposer::getZCoordinate(double* z, int numX, int numY, int i, int j, int logUsed)
60 {
61     double zij = 0.;
62
63     zij = z[numX*j+i];
64
65     if (logUsed)
66     {
67         zij = DecompositionUtils::getLog10Value(zij);
68     }
69
70     return zij;
71 }
72
73 void Plot3DDecomposer::getFacetTriangles(double* x, double* y, double* z, int numX, int numY, int i, int j,
74                                          int* facetVertexIndices, int* triangleVertexIndices)
75 {
76     double vertices[4][3];
77
78     /* Gets the facet's vertices: (i,j), (i+1,j), (i+1,j+1), (i,j+1) */
79     getFacetCoordinates(x, y, z, numX, numY, i, j, vertices);
80
81     /* Decomposes the facet into two triangles and outputs their indices */
82     DecompositionUtils::getDecomposedQuadTriangleIndices(vertices, facetVertexIndices, triangleVertexIndices);
83 }
84
85 /*
86  * To do: compute and return color indices instead of directly looking
87  * up colors from the colormap.
88  */
89 void Plot3DDecomposer::fillColors(char* id, float* buffer, int bufferLength, int elementsSize)
90 {
91     char* parentFigure = NULL;
92     char* parent = NULL;
93
94     double* z = NULL;
95     double* colormap = NULL;
96
97
98     int numX = 0;
99     int* piNumX = &numX;
100     int numY = 0;
101     int* piNumY = &numY;
102     int colormapSize = 0;
103     int* piColormapSize = &colormapSize;
104
105     Plot3DDecomposer* decomposer = get();
106
107     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX);
108     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY);
109
110     getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
111
112     getGraphicObjectProperty(id, __GO_PARENT__, jni_string, (void**) &parent);
113
114     /* Temporary: to avoid getting a null parent_figure property when the object is built */
115     if (strcmp(parent, "") == 0)
116     {
117         return;
118     }
119
120     getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_string, (void**) &parentFigure);
121
122     if (parentFigure == NULL)
123     {
124         return;
125     }
126
127     getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
128     getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
129
130     decomposer->fillNormalizedZGridColors(buffer, bufferLength, elementsSize, colormap, colormapSize, z, numX, numY);
131
132     releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
133 }
134
135 int Plot3DDecomposer::fillIndices(char* id, int* buffer, int bufferLength, int logMask)
136 {
137     double* x = NULL;
138     double* y = NULL;
139     double* z = NULL;
140
141     int numX = 0;
142     int* piNumX = &numX;
143     int numY = 0;
144     int* piNumY = &numY;
145
146     int numberIndices = 0;
147
148     Plot3DDecomposer* decomposer = get();
149
150     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX);
151     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY);
152
153     /* 0 indices if 0 points */
154     if (numX == 0 || numY == 0)
155     {
156         return 0;
157     }
158
159     getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x);
160     getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y);
161     getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
162
163     /* The per-node value flag is set to 1, as grid values amount to z coordinates and are not relevant anyway. */
164     numberIndices = decomposer->fillTriangleIndices(buffer, bufferLength, logMask, x, y, z, z, 1, numX, numY);
165
166     return numberIndices;
167 }
168
169 int Plot3DDecomposer::getWireIndicesSize(char* id)
170 {
171     int numX = 0;
172     int* piNumX = &numX;
173     int numY = 0;
174     int* piNumY = &numY;
175
176     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX);
177     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY);
178
179     if (numX == 0 || numY == 0)
180     {
181         return 0;
182     }
183
184     return 2*2*(numX-1)*(numY-1) + 2*(numX-1) + 2*(numY-1);
185 }
186
187 /*
188  * To be optimized:
189  * -a lot of work performed redundantly with NgonGridDataDecomposer::fillIndices, ought to be merged
190  *  with it.
191  */
192 int Plot3DDecomposer::fillWireIndices(char* id, int* buffer, int bufferLength, int logMask)
193 {
194     double* x = NULL;
195     double* y = NULL;
196     double* z = NULL;
197
198     int numX = 0;
199     int* piNumX = &numX;
200     int numY = 0;
201     int* piNumY = &numY;
202
203     int previousRowValid = 0;
204     int currentRowValid = 0;
205     int nextRowValid = 0;
206
207     int previousColumnValid = 0;
208     int currentColumnValid = 0;
209     int nextColumnValid = 0;
210
211     int lowerLeftZValid = 0;
212     int lowerRightZValid = 0;
213     int upperLeftZValid = 0;
214     int upperRightZValid = 0;
215
216     int jm1HorizontalEdgeZValid = 0;
217     int im1VerticalEdgeZValid = 0;
218     int jHorizontalEdgeZValid = 0;
219     int iVerticalEdgeZValid = 0;
220     int jp1HorizontalEdgeZValid = 0;
221     int ip1VerticalEdgeZValid = 0;
222
223     int ij = 0;
224     int ip1j = 0;
225     int ijp1 = 0;
226     int ip1jp1 = 0;
227     int ijm1 = 0;
228     int ip1jm1 = 0;
229
230     int firstVertexIndex = 0;
231
232     int bufferOffset = 0;
233
234     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_X__, jni_int, (void**) &piNumX);
235     getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**) &piNumY);
236
237     /* 0 indices if less than 2 points along either dimension */
238     if (numX < 2 || numY < 2)
239     {
240         return 0;
241     }
242
243     getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x);
244     getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y);
245     getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
246
247     /* First row */
248     previousRowValid = 0;
249     currentRowValid = DecompositionUtils::isValid(y[0]);
250
251     if (logMask & 0x2)
252     {
253         currentRowValid &= DecompositionUtils::isLogValid(y[0]);
254     }
255
256     /* Set to 0 as it is not relevant for the first row iteration */
257     jm1HorizontalEdgeZValid = 0;
258
259     /* x-axis and y-axis indices (respectively) */
260     for (int j = 0; j < numY-1; j++)
261     {
262         nextRowValid = DecompositionUtils::isValid(y[j+1]);
263
264         if (logMask & 0x2)
265         {
266             nextRowValid &= DecompositionUtils::isLogValid(y[j+1]);
267         }
268
269         if (!currentRowValid)
270         {
271             previousRowValid = currentRowValid;
272             currentRowValid = nextRowValid;
273             continue;
274         }
275
276         previousColumnValid = 0;
277         currentColumnValid = DecompositionUtils::isValid(x[0]);
278
279         if (logMask & 0x1)
280         {
281             currentColumnValid &= DecompositionUtils::isLogValid(x[0]);
282         }
283
284         ij = getPointIndex(numX, numY, 0, j);
285         ijp1 = getPointIndex(numX, numY, 0, j+1);
286
287         lowerLeftZValid = DecompositionUtils::isValid(z[ij]);
288         upperLeftZValid = DecompositionUtils::isValid(z[ijp1]);
289
290         if (logMask & 0x4)
291         {
292             lowerLeftZValid &= DecompositionUtils::isLogValid(z[ij]);
293             upperLeftZValid &= DecompositionUtils::isLogValid(z[ijp1]);
294         }
295
296         iVerticalEdgeZValid = lowerLeftZValid && upperLeftZValid;
297
298         /* Set to 0 as not relevant for the first column iteration */
299         im1VerticalEdgeZValid = 0;
300
301         for (int i = 0; i < numX-1; i++)
302         {
303 #if !PER_VERTEX_VALUES
304             firstVertexIndex = getFirstVertexIndex(numX, numY, i, j);
305 #endif
306
307             ip1j = getPointIndex(numX, numY, i+1, j);
308             ip1jp1 = getPointIndex(numX, numY, i+1, j+1);
309
310             nextColumnValid = DecompositionUtils::isValid(x[i+1]);
311
312             if (logMask & 0x1)
313             {
314                 nextColumnValid &= DecompositionUtils::isLogValid(x[i+1]);
315             }
316
317             lowerRightZValid = DecompositionUtils::isValid(z[ip1j]);
318             upperRightZValid = DecompositionUtils::isValid(z[ip1jp1]);
319
320             if (logMask & 0x4)
321             {
322                 lowerRightZValid &= DecompositionUtils::isLogValid(z[ip1j]);
323                 upperRightZValid &= DecompositionUtils::isLogValid(z[ip1jp1]);
324             }
325
326             if (j > 0)
327             {
328                 ijm1 = getPointIndex(numX, numY, i, j-1);
329                 ip1jm1 = getPointIndex(numX, numY, i+1, j-1);
330
331                 jm1HorizontalEdgeZValid = DecompositionUtils::isValid(z[ijm1]) && DecompositionUtils::isValid(z[ip1jm1]);
332
333                 if (logMask & 0x4)
334                 {
335                     jm1HorizontalEdgeZValid &= (DecompositionUtils::isLogValid(z[ijm1]) && DecompositionUtils::isLogValid(z[ip1jm1]));
336                 }
337             }
338
339             jHorizontalEdgeZValid = lowerLeftZValid && lowerRightZValid;
340
341             jp1HorizontalEdgeZValid = upperLeftZValid && upperRightZValid;
342             ip1VerticalEdgeZValid = lowerRightZValid && upperRightZValid;
343
344             /*
345              * Two segments: between points (i,j) and (i+1,j)
346              * and points (i,j) and (i,j+1) .
347              */
348             if ((currentColumnValid && nextColumnValid) && jHorizontalEdgeZValid && ((previousRowValid && jm1HorizontalEdgeZValid) || (nextRowValid && jp1HorizontalEdgeZValid)))
349             {
350 #if PER_VERTEX_VALUES
351                 buffer[bufferOffset] = ij;
352                 buffer[bufferOffset+1] = ip1j;
353 #else
354                 buffer[bufferOffset] = firstVertexIndex;
355                 buffer[bufferOffset+1] = firstVertexIndex +1;
356 #endif
357
358                 bufferOffset += 2;
359             }
360
361             if (currentColumnValid && nextRowValid && iVerticalEdgeZValid && ((previousColumnValid && im1VerticalEdgeZValid) || (nextColumnValid && ip1VerticalEdgeZValid)))
362             {
363 #if PER_VERTEX_VALUES
364                 buffer[bufferOffset] = ij;
365                 buffer[bufferOffset+1] = ijp1;
366 #else
367                 buffer[bufferOffset] = firstVertexIndex;
368                 buffer[bufferOffset+1] = firstVertexIndex +2;
369 #endif
370
371                 bufferOffset += 2;
372             }
373
374             previousColumnValid = currentColumnValid;
375             currentColumnValid = nextColumnValid;
376             lowerLeftZValid = lowerRightZValid;
377             upperLeftZValid = upperRightZValid;
378
379             im1VerticalEdgeZValid = iVerticalEdgeZValid;
380             iVerticalEdgeZValid = ip1VerticalEdgeZValid;
381
382             ij = ip1j;
383             ijp1 = ip1jp1;
384         }
385
386         /* Rightmost vertical line */
387         if (currentColumnValid && nextRowValid && iVerticalEdgeZValid && (previousColumnValid && im1VerticalEdgeZValid))
388         {
389 #if PER_VERTEX_VALUES
390             buffer[bufferOffset] = ij;
391             buffer[bufferOffset+1] = ijp1;
392 #else
393             firstVertexIndex = getFirstVertexIndex(numX, numY, numX-2, j);
394
395             buffer[bufferOffset] = firstVertexIndex +1;
396             buffer[bufferOffset+1] = firstVertexIndex +3;
397 #endif
398
399             bufferOffset += 2;
400         }
401
402         previousRowValid = currentRowValid;
403         currentRowValid = nextRowValid;
404     }
405
406     /* Topmost horizontal lines */
407     currentRowValid = DecompositionUtils::isValid(y[numY-1]);
408
409     if (logMask & 0x2)
410     {
411         currentRowValid &= DecompositionUtils::isLogValid(y[numY-1]);
412     }
413
414     currentColumnValid = DecompositionUtils::isValid(x[0]);
415
416     if (logMask & 0x1)
417     {
418         currentColumnValid = DecompositionUtils::isValid(x[0]);
419     }
420
421     ij = getPointIndex(numX, numY, 0, numY-1);
422
423     lowerLeftZValid = DecompositionUtils::isValid(z[ij]);
424
425     if (logMask & 0x4)
426     {
427         lowerLeftZValid &= DecompositionUtils::isValid(z[ij]);
428     }
429
430     ij = getPointIndex(numX, numY, 0, numY-1);
431
432     for (int i = 0; i < numX-1; i++)
433     {
434         nextColumnValid = DecompositionUtils::isValid(x[i+1]);
435
436         if (logMask & 0x1)
437         {
438             nextColumnValid &= DecompositionUtils::isLogValid(x[i+1]);
439         }
440
441         ip1j = getPointIndex(numX, numY, i+1, numY-1);
442
443         lowerRightZValid = DecompositionUtils::isValid(z[ip1j]);
444
445         if (logMask & 0x4)
446         {
447             lowerRightZValid &= DecompositionUtils::isLogValid(z[ip1j]);
448         }
449
450         ijm1 = getPointIndex(numX, numY, i, numY-2);
451         ip1jm1 = getPointIndex(numX, numY, i+1, numY-2);
452
453         jm1HorizontalEdgeZValid = DecompositionUtils::isValid(z[ijm1]) && DecompositionUtils::isValid(z[ip1jm1]);
454
455         if (logMask & 0x4)
456         {
457             jm1HorizontalEdgeZValid &= (DecompositionUtils::isLogValid(z[ijm1]) && DecompositionUtils::isLogValid(z[ip1jm1]));
458         }
459
460         jHorizontalEdgeZValid = lowerLeftZValid && lowerRightZValid;
461
462         if (currentRowValid && (currentColumnValid && nextColumnValid) && jHorizontalEdgeZValid && (previousRowValid && jm1HorizontalEdgeZValid))
463         {
464 #if PER_VERTEX_VALUES
465             buffer[bufferOffset] = ij;
466             buffer[bufferOffset+1] = ip1j;
467 #else
468             firstVertexIndex = getFirstVertexIndex(numX, numY, i, numY-2);
469
470             buffer[bufferOffset] = firstVertexIndex +2;
471             buffer[bufferOffset+1] = firstVertexIndex +3;
472 #endif
473
474             bufferOffset += 2;
475         }
476
477         currentColumnValid = nextColumnValid;
478         lowerLeftZValid = lowerRightZValid;
479
480         ij = ip1j;
481     }
482
483     return bufferOffset;
484 }
485