2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Manuel Juliachs
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
13 #include "DecompositionUtils.hxx"
14 #include "ColorComputer.hxx"
15 #include "Fac3DColorComputer.hxx"
16 #include "Fac3DDecomposer.hxx"
23 #include "getGraphicObjectProperty.h"
24 #include "graphicObjectProperties.h"
27 int Fac3DDecomposer::getDataSize(char* id)
29 int numVerticesPerGon = 0;
30 int* piNumVerticesPerGon = &numVerticesPerGon;
32 int* piNumGons = &numGons;
34 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
35 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
37 return numVerticesPerGon*numGons;
40 void Fac3DDecomposer::fillVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask)
48 int numVerticesPerGon = 0;
49 int* piNumVerticesPerGon = &numVerticesPerGon;
51 int* piNumGons = &numGons;
55 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
56 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
58 getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_int, (void**) &x);
59 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_int, (void**) &y);
60 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_int, (void**) &z);
63 for (i = 0; i < numVerticesPerGon*numGons; i++)
65 if (coordinateMask & 0x1)
70 xi = DecompositionUtils::getLog10Value(x[i]);
72 buffer[bufferOffset] = (float)(xi * scale[0] + translation[0]);
75 if (coordinateMask & 0x2)
80 yi = DecompositionUtils::getLog10Value(y[i]);
82 buffer[bufferOffset + 1] = (float)(yi * scale[1] + translation[1]);
85 if (coordinateMask & 0x4)
90 zi = DecompositionUtils::getLog10Value(z[i]);
92 buffer[bufferOffset + 2] = (float)(zi * scale[2] + translation[2]);
95 if (elementsSize == 4 && (coordinateMask & 0x8))
97 buffer[bufferOffset + 3] = 1.0;
105 void Fac3DDecomposer::fillTextureCoordinates(char* id, float* buffer, int bufferLength)
107 char* parentFigure = NULL;
110 double* colors = NULL;
111 double* colormap = NULL;
116 int numVerticesPerGon = 0;
117 int* piNumVerticesPerGon = &numVerticesPerGon;
119 int* piNumGons = &numGons;
121 int* piNumColors = &numColors;
123 int colormapSize = 0;
124 int* piColormapSize = &colormapSize;
127 int* piColorFlag = &colorFlag;
130 int* piDataMapping = &dataMapping;
135 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
136 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
138 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_COLORS__, jni_int, (void**) &piNumColors);
139 getGraphicObjectProperty(id, __GO_DATA_MODEL_COLORS__, jni_double_vector, (void**) &colors);
141 getGraphicObjectProperty(id, __GO_PARENT__, jni_string, (void**) &parent);
143 /* Temporary: to avoid getting a null parent_figure property when the object is built */
144 if (strcmp(parent, "") == 0)
149 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_string, (void**) &parentFigure);
151 if (parentFigure == NULL)
156 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
157 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
159 getGraphicObjectProperty(id, __GO_COLOR_FLAG__, jni_int, (void**) &piColorFlag);
161 getGraphicObjectProperty(id, __GO_DATA_MAPPING__, jni_int, (void**) &piDataMapping);
169 if (numColors == numGons*numVerticesPerGon)
173 else if (numColors == numGons)
179 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_int, (void**) &z);
183 fillNormalizedZColorsTextureCoordinates(buffer, bufferLength, colormap, colormapSize, z, numGons, numVerticesPerGon);
185 else if (colorFlag > 1 && numColors == 0)
188 * The color buffer must be filled with the color_mode value.
189 * To do: correctly take into account Nan and infinite values.
192 int* piColorMode = &colorMode;
194 getGraphicObjectProperty(id, __GO_COLOR_MODE__, jni_int, (void**) &piColorMode);
196 color = (double) colorMode;
197 color = DecompositionUtils::getAbsoluteValue(color);
199 fillConstantColorsTextureCoordinates(buffer, bufferLength, colormap, colormapSize,
200 color, numGons, numVerticesPerGon);
204 fillDataColorsTextureCoordinates(buffer, bufferLength, colormap, colormapSize,
205 colors, colorFlag, perVertex, dataMapping, numGons, numVerticesPerGon);
210 void Fac3DDecomposer::fillNormalizedZColorsTextureCoordinates(float* buffer, int bufferLength, double* colormap, int colormapSize,
211 double* z, int numGons, int numVerticesPerGon)
217 double minDoubleValue = 0.;
222 int bufferOffset = 0;
224 computeMinMaxValues(z, numGons*numVerticesPerGon, numGons, numVerticesPerGon, ALL_VALUES, &zMin, &zMax);
226 minDoubleValue = DecompositionUtils::getMinDoubleValue();
229 if ((zMax - zMin) < minDoubleValue)
235 zRange = zMax - zMin;
238 for (i = 0; i < numGons; i++)
240 /* Per-face average */
241 zavg = computeAverageValue(&z[i*numVerticesPerGon], numVerticesPerGon);
242 index = (float)((ColorComputer::getIndex(zavg, zMin, zRange, Z_COLOR_OFFSET, 0, colormapSize - 1) + 2.0 + COLOR_TEXTURE_OFFSET) / (float) (colormapSize + 2));
244 for (j = 0; j < numVerticesPerGon; j++)
246 buffer[bufferOffset++] = index;
247 buffer[bufferOffset++] = 0;
248 buffer[bufferOffset++] = 0;
249 buffer[bufferOffset++] = 1.0;
255 void Fac3DDecomposer::fillConstantColorsTextureCoordinates(float* buffer, int bufferLength, double* colormap, int colormapSize,
256 double colorValue, int numGons, int numVerticesPerGon)
258 int bufferOffset = 0;
260 double index = (ColorComputer::getClampedDirectIndex(colorValue - 1.0, colormapSize) + 2.0 + COLOR_TEXTURE_OFFSET) / (float) (colormapSize + 2);
262 for (int i = 0; i < numGons*numVerticesPerGon; i++)
264 buffer[bufferOffset++] = (float)index;
265 buffer[bufferOffset++] = 0;
266 buffer[bufferOffset++] = 0;
267 buffer[bufferOffset++] = 1.0;
272 void Fac3DDecomposer::fillDataColorsTextureCoordinates(float* buffer, int bufferLength, double* colormap, int colormapSize,
273 double* colors, int colorFlag, int perVertex, int dataMapping, int numGons, int numVerticesPerGon)
276 double colRange = 0.;
278 double colorTextureOffset = 0.;
281 int bufferOffset = 0;
285 Fac3DColorComputer colorComputer;
289 numColors = numGons*numVerticesPerGon;
296 colorComputer = Fac3DColorComputer(colors, numColors, colorFlag, dataMapping, numGons, numVerticesPerGon);
298 /* 0: colors are scaled */
299 if (dataMapping == 0)
301 colorComputer.getColorRangeValue(&colMin, &colRange);
305 * The color texture offset value is used to center color sub-intervals
306 * on integer index values when interpolated shading is used or to be sure
307 * to fetch the correct color value when flat shading is used.
309 colorTextureOffset = COLOR_TEXTURE_OFFSET;
311 for (int i = 0; i < numGons; i++)
313 for (int j = 0; j < numVerticesPerGon; j++)
315 color = colorComputer.getOutputFacetColor(i, j);
317 if (dataMapping == 1)
319 color = DecompositionUtils::getAbsoluteValue(color);
320 index = ColorComputer::getClampedDirectIndex(color - 1.0 , colormapSize);
322 else if (dataMapping == 0)
324 index = ColorComputer::getIndex(color, colMin, colRange, COLOR_OFFSET, 0, colormapSize-1);
327 /* The offset corresponding to the black and white colors must added to the index and the colormap size. */
328 buffer[bufferOffset++] = (float) ((index + colorTextureOffset + 2.0) / (double) (colormapSize + 2));
329 buffer[bufferOffset++] = 0;
330 buffer[bufferOffset++] = 0;
331 buffer[bufferOffset++] = 1.0;
336 double Fac3DDecomposer::computeAverageValue(double* values, int numVertices)
338 double averageValue = 0.0;
340 for (int i = 0; i < numVertices; i++)
342 averageValue += values[i];
345 averageValue /= (double) numVertices;
350 void Fac3DDecomposer::computeMinMaxValues(double* values, int numValues, int numGons, int numVerticesPerGon, int minMaxComputation,
351 double* valueMin, double* valueMax)
353 double maxDouble = DecompositionUtils::getMaxDoubleValue();
354 double tmpValueMin = maxDouble;
355 double tmpValueMax = -maxDouble;
358 int numIterations = 0;
360 if (minMaxComputation != ALL_VALUES)
362 numIterations = numGons;
366 numIterations = numValues;
369 for (int i = 0; i < numIterations; i++)
371 if (minMaxComputation == FIRST_VERTEX_VALUE)
373 value = values[i*numVerticesPerGon];
375 else if (minMaxComputation == FACE_AVERAGE)
377 value = computeAverageValue(&values[i*numVerticesPerGon], numVerticesPerGon);
384 if (DecompositionUtils::isValid(value))
386 if (value < tmpValueMin)
391 if (value > tmpValueMax)
398 *valueMin = tmpValueMin;
399 *valueMax = tmpValueMax;
402 int Fac3DDecomposer::getIndicesSize(char* id)
404 int numVerticesPerGon = 0;
405 int* piNumVerticesPerGon = &numVerticesPerGon;
407 int* piNumGons = &numGons;
409 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
410 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
412 if (numVerticesPerGon < 2)
417 return 3*(numVerticesPerGon-2)*numGons;
421 * To do: use a polygon triangulation algorithm, as the fan decomposition used may produce
422 * overlapping triangles for non-convex polygons.
424 int Fac3DDecomposer::fillIndices(char* id, int* buffer, int bufferLength, int logMask)
434 double* colors = NULL;
436 int numVerticesPerGon = 0;
437 int* piNumVerticesPerGon = &numVerticesPerGon;
439 int* piNumGons = &numGons;
442 int* piNumColors = &numColors;
445 int* piColorFlag = &colorFlag;
448 int* piDataMapping = &dataMapping;
450 int bufferOffset = 0;
451 int vertexOffset = 0;
453 Fac3DColorComputer colorComputer;
455 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
456 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
458 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_COLORS__, jni_int, (void**) &piNumColors);
459 getGraphicObjectProperty(id, __GO_DATA_MODEL_COLORS__, jni_double_vector, (void**) &colors);
461 getGraphicObjectProperty(id, __GO_COLOR_FLAG__, jni_int, (void**) &piColorFlag);
463 getGraphicObjectProperty(id, __GO_DATA_MAPPING__, jni_int, (void**) &piDataMapping);
465 /* At least 3 vertices per N-gon are required to output triangles. */
466 if (numVerticesPerGon < 3)
471 colorComputer = Fac3DColorComputer(colors, numColors, colorFlag, dataMapping, numGons, numVerticesPerGon);
473 getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x);
474 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y);
475 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
477 for (int i = 0; i < numGons; i++)
481 for (int j = 0; j < numVerticesPerGon; j++)
483 xc = x[vertexOffset+j];
484 yc = y[vertexOffset+j];
485 zc = z[vertexOffset+j];
487 if (!DecompositionUtils::isValid(xc, yc, zc) || !DecompositionUtils::isLogValid(xc, yc, zc, logMask))
494 if (isValid == 0 || colorComputer.isFacetColorValid(i) == 0)
496 vertexOffset += numVerticesPerGon;
500 /* Performs a fan decomposition, vertices are ordered counter-clockwise. */
501 for (int j = 0; j < numVerticesPerGon-2; j++)
503 buffer[bufferOffset] = vertexOffset;
504 buffer[bufferOffset +1] = vertexOffset + j+2;
505 buffer[bufferOffset +2] = vertexOffset + j+1;
510 vertexOffset += numVerticesPerGon;
516 int Fac3DDecomposer::getWireIndicesSize(char* id)
518 int numVerticesPerGon = 0;
519 int* piNumVerticesPerGon = &numVerticesPerGon;
521 int* piNumGons = &numGons;
523 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
524 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
526 return 2*numVerticesPerGon*numGons;
529 int Fac3DDecomposer::fillWireIndices(char* id, int* buffer, int bufferLength, int logMask)
539 int numVerticesPerGon = 0;
540 int* piNumVerticesPerGon = &numVerticesPerGon;
542 int* piNumGons = &numGons;
544 int bufferOffset = 0;
545 int vertexOffset = 0;
547 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_VERTICES_PER_GON__, jni_int, (void**) &piNumVerticesPerGon);
548 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_GONS__, jni_int, (void**) &piNumGons);
550 /* At least 2 vertices per N-gon are required to output segments. */
551 if (numVerticesPerGon < 2)
556 getGraphicObjectProperty(id, __GO_DATA_MODEL_X__, jni_double_vector, (void**) &x);
557 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y__, jni_double_vector, (void**) &y);
558 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z__, jni_double_vector, (void**) &z);
560 for (int i = 0; i < numGons; i++)
564 for (int j = 0; j < numVerticesPerGon; j++)
566 xc = x[vertexOffset+j];
567 yc = y[vertexOffset+j];
568 zc = z[vertexOffset+j];
570 if (!DecompositionUtils::isValid(xc, yc, zc) || !DecompositionUtils::isLogValid(xc, yc, zc, logMask))
579 vertexOffset += numVerticesPerGon;
583 for (int j = 0; j < numVerticesPerGon; j++)
585 buffer[bufferOffset] = vertexOffset + j;
586 buffer[bufferOffset+1] = vertexOffset + (j+1) % numVerticesPerGon;
591 vertexOffset += numVerticesPerGon;