2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Pierre Lando
4 * Copyright (C) 2011-2012 - DIGITEO - Manuel Juliachs
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
16 #include "DecompositionUtils.hxx"
17 #include "PolylineDecomposer.hxx"
18 #include "Triangulator.hxx"
19 #include "ColorComputer.hxx"
26 #include "getGraphicObjectProperty.h"
27 #include "graphicObjectProperties.h"
30 int PolylineDecomposer::getDataSize(int id)
33 int *piNPoints = &nPoints;
34 int polylineStyle = 0;
35 int* piPolylineStyle = &polylineStyle;
37 int* piClosed = &closed;
39 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
40 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
41 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
43 /* If 0 points, 0 elements */
49 switch (polylineStyle)
62 return (2 * nPoints) - 1;
65 /* Vertical segments plus segments */
68 /* Segments with arrow heads */
71 /* The numbers of arrow head vertices and indices are exactly the same */
72 nArrowVertices = PolylineDecomposer::getArrowTriangleIndicesSize(nPoints, closed);
74 return nPoints + nArrowVertices;
80 /* Vertical bars plus segments */
83 /* Horizontal bars plus segments */
86 /* To be done: remaining styles */
91 void PolylineDecomposer::fillVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask)
94 double* xshift = NULL;
95 double* yshift = NULL;
96 double* zshift = NULL;
98 int polylineStyle = 0;
99 int* piPolylineStyle = &polylineStyle;
102 int *piNPoints = &nPoints;
104 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &t);
105 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
107 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
108 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
109 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
111 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
113 switch (polylineStyle)
116 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
119 fillStairDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
122 fillVerticalLinesDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
125 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
128 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
131 fillVerticalBarsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
134 fillHorizontalBarsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
139 void PolylineDecomposer::fillSegmentsDecompositionVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
140 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
143 int componentIndices[3];
145 // TODO Optimize ? (test if s = 1 and t = 0, coordinateMask = 0 ...)
146 for (int i = 0; i < nPoints; i++)
148 /* Offset of a polyline vertex */
149 int v0 = elementsSize * i;
151 componentIndices[0] = i;
152 componentIndices[1] = i;
153 componentIndices[2] = i;
155 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize,
156 xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
161 void PolylineDecomposer::getAndWriteVertexToBuffer(float* buffer, int offset, double* coordinates, int* vertexIndices, int nPoints, int elementsSize,
162 double* xshift, double* yshift, double* zshift, int coordinateMask, double* scale, double* translation, int logMask)
164 double coordinate = 0.;
166 if (coordinateMask & 0x01)
168 coordinate = coordinates[vertexIndices[0]];
172 coordinate += xshift[vertexIndices[0]];
177 coordinate = DecompositionUtils::getLog10Value(coordinate);
180 buffer[offset + 0] = (float)(coordinate * scale[0] + translation[0]);
183 if (coordinateMask & 0x02)
185 coordinate = coordinates[vertexIndices[1] + nPoints];
189 coordinate += yshift[vertexIndices[1]];
194 coordinate = DecompositionUtils::getLog10Value(coordinate);
197 buffer[offset + 1] = (float)(coordinate * scale[1] + translation[1]);
200 if (coordinateMask & 0x04)
202 coordinate = coordinates[vertexIndices[2] + 2 * nPoints];
206 coordinate += zshift[vertexIndices[2]];
211 coordinate = DecompositionUtils::getLog10Value(coordinate);
214 buffer[offset + 2] = (float)(coordinate * scale[2] + translation[2]);
217 if ((elementsSize == 4) && (coordinateMask & 0x08))
219 buffer[offset + 3] = 1.0;
224 void PolylineDecomposer::fillStairDecompositionVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
225 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
228 int* piClosed = &closed;
230 /* Offsets of the left and right vertices (respectively) */
234 int componentIndices[3];
241 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
243 for (int i = 0; i < nPoints - 1; i++)
245 v0 = elementsSize * 2 * i;
246 v1 = elementsSize * (2 * i + 1);
248 componentIndices[0] = i;
249 componentIndices[1] = i;
250 componentIndices[2] = i;
252 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
254 componentIndices[0] = i + 1;
255 componentIndices[1] = i;
256 componentIndices[2] = i;
258 /* To be optimized: the y and z components are fetched and transformed twice */
259 getAndWriteVertexToBuffer(buffer, v1, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
263 v0 = elementsSize * 2 * (nPoints - 1);
265 componentIndices[0] = nPoints - 1;
266 componentIndices[1] = nPoints - 1;
267 componentIndices[2] = nPoints - 1;
269 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
272 * One additional vertex if closed
273 * Its x-coordinate is equal to the one of the polyline's first point
274 * whereas its y and z coordinates are equal to those of the last point.
278 v0 = elementsSize * (2 * nPoints - 1);
280 componentIndices[0] = 0;
281 componentIndices[1] = nPoints - 1;
282 componentIndices[2] = nPoints - 1;
284 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
289 void PolylineDecomposer::fillVerticalLinesDecompositionVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
290 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
292 for (int i = 0; i < nPoints; i++)
294 /* Offsets of the lower and upper vertices (respectively) */
298 /* Coordinates of the lower and upper vertices (respectively) */
302 v0 = elementsSize * 2 * i;
303 v1 = elementsSize * (2 * i + 1);
305 /* Lower and upper endpoints x coordinates */
306 if (coordinateMask & 0x01)
308 coord0 = coordinates[i];
309 coord1 = coordinates[i];
319 coord0 = DecompositionUtils::getLog10Value(coord0);
320 coord1 = DecompositionUtils::getLog10Value(coord1);
323 buffer[v0 + 0] = (float)(coord0 * scale[0] + translation[0]);
324 buffer[v1 + 0] = (float)(coord1 * scale[0] + translation[0]);
327 /* Lower and upper endpoints y coordinates */
328 if (coordinateMask & 0x02)
331 coord1 = coordinates[i + nPoints];
336 * Only the upper vertex's y coordinate is shifted,
337 * the lower vertex's one remains unchanged.
344 /* The lower endpoint's y coordinate is unchanged (it amounts to log10(1), which is 0) */
345 coord1 = DecompositionUtils::getLog10Value(coord1);
348 buffer[v0 + 1] = (float)(coord0 * scale[1] + translation[1]);
349 buffer[v1 + 1] = (float)(coord1 * scale[1] + translation[1]);
352 /* Lower and upper endpoints z coordinates */
353 if (coordinateMask & 0x04)
355 coord0 = coordinates[2 * nPoints + i];
356 coord1 = coordinates[2 * nPoints + i];
366 coord0 = DecompositionUtils::getLog10Value(coord0);
367 coord1 = DecompositionUtils::getLog10Value(coord1);
370 buffer[v0 + 2] = (float)(coord0 * scale[2] + translation[2]);
371 buffer[v1 + 2] = (float)(coord1 * scale[2] + translation[2]);
374 if ((elementsSize == 4) && (coordinateMask & 0x08))
376 buffer[v0 + 3] = 1.0;
377 buffer[v1 + 3] = 1.0;
384 void PolylineDecomposer::writeBarVerticesToBuffer(float* buffer, int* offsets, int componentOffset, double* coordinates, double shift, int shiftUsed,
385 double scale, double translation, int logUsed)
389 coordinates[0] += shift;
390 coordinates[1] += shift;
391 coordinates[2] += shift;
392 coordinates[3] += shift;
394 coordinates[4] += shift;
399 coordinates[0] = DecompositionUtils::getLog10Value(coordinates[0]);
400 coordinates[1] = DecompositionUtils::getLog10Value(coordinates[1]);
401 coordinates[2] = DecompositionUtils::getLog10Value(coordinates[2]);
402 coordinates[3] = DecompositionUtils::getLog10Value(coordinates[3]);
404 coordinates[4] = DecompositionUtils::getLog10Value(coordinates[4]);
407 buffer[offsets[0] + componentOffset] = (float)(coordinates[0] * scale + translation);
408 buffer[offsets[1] + componentOffset] = (float)(coordinates[1] * scale + translation);
409 buffer[offsets[2] + componentOffset] = (float)(coordinates[2] * scale + translation);
410 buffer[offsets[3] + componentOffset] = (float)(coordinates[3] * scale + translation);
412 buffer[offsets[4] + componentOffset] = (float)(coordinates[4] * scale + translation);
415 void PolylineDecomposer::fillVerticalBarsDecompositionVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
416 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
418 double barWidth = 0.0;
419 double* pdBarWidth = &barWidth;
422 int *piShiftUsed = NULL;
425 * Offsets of the lower-left, lower-right, upper-right and upper-left bar vertices (respectively)
426 * and of the polyline vertex proper
431 * {x,y or z}-component values of a bar's 4 vertices (same ordering as the offsets)
432 * and of the polyline vertex proper.
439 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
441 piShiftUsed = &shiftUsed[0];
442 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
443 piShiftUsed = &shiftUsed[1];
444 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
445 piShiftUsed = &shiftUsed[2];
446 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
449 for (int i = 0; i < nPoints; i++)
451 offsets[0] = elementsSize * 4 * i;
452 offsets[1] = elementsSize * (4 * i + 1);
453 offsets[2] = elementsSize * (4 * i + 2);
454 offsets[3] = elementsSize * (4 * i + 3);
456 offsets[4] = elementsSize * (4 * nPoints + i);
458 if (coordinateMask & 0x01)
460 coords[0] = coordinates[i] - 0.5 * barWidth;
461 coords[1] = coordinates[i] + 0.5 * barWidth;
462 coords[2] = coordinates[i] + 0.5 * barWidth;
463 coords[3] = coordinates[i] - 0.5 * barWidth;
465 coords[4] = coordinates[i];
472 writeBarVerticesToBuffer(buffer, offsets, 0, coords, shift, shiftUsed[0], scale[0], translation[0], logMask & 0x01);
475 if (coordinateMask & 0x02)
479 coords[2] = coordinates[i + nPoints];
480 coords[3] = coordinates[i + nPoints];
482 coords[4] = coordinates[i + nPoints];
492 * The two lower endpoints' y coordinates must be set to 1
493 * since writeBarVerticesToBuffer applies the logarithmic transformation.
499 writeBarVerticesToBuffer(buffer, offsets, 1, coords, shift, shiftUsed[1], scale[1], translation[1], logMask & 0x02);
502 if (coordinateMask & 0x04)
504 coords[0] = coordinates[i + 2 * nPoints];
505 coords[1] = coordinates[i + 2 * nPoints];
506 coords[2] = coordinates[i + 2 * nPoints];
507 coords[3] = coordinates[i + 2 * nPoints];
509 coords[4] = coordinates[i + 2 * nPoints];
516 writeBarVerticesToBuffer(buffer, offsets, 2, coords, shift, shiftUsed[2], scale[2], translation[2], logMask & 0x04);
519 if ((elementsSize == 4) && (coordinateMask & 0x08))
521 buffer[offsets[0] + 3] = 1.0;
522 buffer[offsets[1] + 3] = 1.0;
523 buffer[offsets[2] + 3] = 1.0;
524 buffer[offsets[3] + 3] = 1.0;
526 buffer[offsets[4] + 3] = 1.0;
534 * To do: -refactor with fillVerticalBarsDecompositionVertices as these two functions are very similar, possibly by implementing
535 a PolylineBarDecomposer class.
537 void PolylineDecomposer::fillHorizontalBarsDecompositionVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
538 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
540 double barWidth = 0.0;
541 double* pdBarWidth = &barWidth;
544 int *piShiftUsed = NULL;
547 * Offsets of the lower-left, lower-right, upper-right and upper-left bar vertices (respectively)
548 * and of the polyline vertex proper
553 * {x,y or z}-component values of a bar's 4 vertices (same ordering as the offsets)
554 * and of the polyline vertex proper.
561 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
563 piShiftUsed = &shiftUsed[0];
564 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
565 piShiftUsed = &shiftUsed[1];
566 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
567 piShiftUsed = &shiftUsed[2];
568 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
570 for (int i = 0; i < nPoints; i++)
572 offsets[0] = elementsSize * 4 * i;
573 offsets[1] = elementsSize * (4 * i + 1);
574 offsets[2] = elementsSize * (4 * i + 2);
575 offsets[3] = elementsSize * (4 * i + 3);
577 offsets[4] = elementsSize * (4 * nPoints + i);
579 /* The actual x coordinates correspond to the polyline's y coordinates. */
580 if (coordinateMask & 0x01)
584 coords[2] = coordinates[i + nPoints];
585 coords[3] = coordinates[i + nPoints];
587 coords[4] = coordinates[i];
594 writeBarVerticesToBuffer(buffer, offsets, 0, coords, shift, shiftUsed[1], scale[0], translation[0], logMask & 0x01);
597 /* The actual y coordinates correspond to the polyline's x coordinates. */
598 if (coordinateMask & 0x02)
600 coords[0] = coordinates[i] - 0.5 * barWidth;
601 coords[1] = coordinates[i] + 0.5 * barWidth;
602 coords[2] = coordinates[i] + 0.5 * barWidth;
603 coords[3] = coordinates[i] - 0.5 * barWidth;
605 coords[4] = coordinates[i + nPoints];
615 * The two lower endpoints' y coordinates must be set to 1
616 * since writeBarVerticesToBuffer applies the logarithmic transformation.
622 writeBarVerticesToBuffer(buffer, offsets, 1, coords, shift, shiftUsed[0], scale[1], translation[1], logMask & 0x02);
625 if (coordinateMask & 0x04)
627 coords[0] = coordinates[i + 2 * nPoints];
628 coords[1] = coordinates[i + 2 * nPoints];
629 coords[2] = coordinates[i + 2 * nPoints];
630 coords[3] = coordinates[i + 2 * nPoints];
632 coords[4] = coordinates[i + 2 * nPoints];
639 writeBarVerticesToBuffer(buffer, offsets, 2, coords, shift, shiftUsed[2], scale[2], translation[2], logMask & 0x04);
642 if ((elementsSize == 4) && (coordinateMask & 0x08))
644 buffer[offsets[0] + 3] = 1.0;
645 buffer[offsets[1] + 3] = 1.0;
646 buffer[offsets[2] + 3] = 1.0;
647 buffer[offsets[3] + 3] = 1.0;
649 buffer[offsets[4] + 3] = 1.0;
658 * -implement for the other relevant polyline style values.
659 * -fix the no colors written problem (related to polyline C build functions, see below).
661 void PolylineDecomposer::fillColors(int id, float* buffer, int bufferLength, int elementsSize)
664 int* pparent = &parent;
665 int parentFigure = 0;
666 int* pparentFigure = &parentFigure;
668 int interpColorMode = 0;
669 int* piInterpColorMode = &interpColorMode;
670 int polylineStyle = 0;
671 int* piPolylineStyle = &polylineStyle;
673 int *piNPoints = &nPoints;
674 int colormapSize = 0;
675 int* piColormapSize = &colormapSize;
676 int bufferOffset = 0;
677 int* interpColorVector = NULL;
679 double* colormap = NULL;
681 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
683 if (interpColorMode == 0)
688 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
690 if (polylineStyle != 1)
695 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
696 parent = getParentObject(id);
698 /* Temporary: to avoid getting a null parent_figure property when the object is built */
704 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_int, (void**) &pparentFigure);
707 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
708 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
709 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
710 * black-filled polygons, as no colors are written.
711 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
712 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
713 * hence possibly caused by a race condition.
716 if (parentFigure == 0)
722 * The interpolated color vector is a 3- or 4-element vector.
723 * However, if nPoints is greater than 4, we choose to output
724 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
731 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
732 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
733 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
740 for (int i = 0; i < nPoints; i++)
742 ColorComputer::getDirectColor((double) interpColorVector[i] - 1.0, colormap, colormapSize, &buffer[bufferOffset]);
744 if (elementsSize == 4)
746 buffer[bufferOffset + 3] = 1.0;
749 bufferOffset += elementsSize;
752 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
753 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
756 void PolylineDecomposer::fillTextureCoordinates(int id, float* buffer, int bufferLength)
759 int* pparent = &parent;
760 int parentFigure = 0;
761 int* pparentFigure = &parentFigure;
763 int interpColorMode = 0;
764 int* piInterpColorMode = &interpColorMode;
765 int polylineStyle = 0;
766 int* piPolylineStyle = &polylineStyle;
768 int *piNPoints = &nPoints;
769 int colormapSize = 0;
770 int* piColormapSize = &colormapSize;
771 int bufferOffset = 0;
772 int* interpColorVector = NULL;
774 double* colormap = NULL;
776 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
778 if (interpColorMode == 0)
783 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
785 if (polylineStyle != 1)
790 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
791 parent = getParentObject(id);
793 /* Temporary: to avoid getting a null parent_figure property when the object is built */
799 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_int, (void**) &pparentFigure);
802 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
803 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
804 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
805 * black-filled polygons, as no colors are written.
806 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
807 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
808 * hence possibly caused by a race condition.
811 if (parentFigure == 0)
817 * The interpolated color vector is a 3- or 4-element vector.
818 * However, if nPoints is greater than 4, we choose to output
819 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
826 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
827 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
828 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
835 for (int i = 0; i < nPoints; i++)
837 double index = (ColorComputer::getDirectIndex((double) interpColorVector[i] - 1.0, colormapSize) + 2.0 + COLOR_TEXTURE_OFFSET) / (double) (colormapSize + 2);
839 buffer[bufferOffset] = (float)index;
840 buffer[bufferOffset + 1] = 0.0;
841 buffer[bufferOffset + 2] = 0.0;
842 buffer[bufferOffset + 3] = 1.0;
847 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
848 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
852 * To do: see fillIndices
853 * -take into account polyline_style.
855 int PolylineDecomposer::getIndicesSize(int id)
858 int *piNPoints = &nPoints;
859 int polylineStyle = 0;
860 int* piPolylineStyle = &polylineStyle;
862 int* piClosed = &closed;
866 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
867 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
868 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
870 /* No facets if 0 points */
877 if (polylineStyle == 1)
884 /* Maximum number of triangles output by the triangulator */
885 nIndices = 3 * (nPoints - 2);
887 /* Arrowed segments */
888 else if (polylineStyle == 4)
890 nIndices = PolylineDecomposer::getArrowTriangleIndicesSize(nPoints, closed);
893 else if (polylineStyle == 5)
900 /* Maximum number of triangles output by the triangulator */
901 nIndices = 3 * (nPoints - 2);
903 /* Vertical bars plus segments */
904 else if (polylineStyle == 6)
906 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
908 /* Horizontal bars plus segments */
909 else if (polylineStyle == 7)
911 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
917 int PolylineDecomposer::getArrowTriangleIndicesSize(int nPoints, int closed)
927 nIndices = 3 * (nPoints - 1);
938 int PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(int nPoints)
940 return 2 * 3 * nPoints;
945 * -take into account the polyline style property (note: vertical bars -style 6- are filled
946 * whatever fill_mode's value), by implementing the relevant functions (see fillTriangleIndices),
947 * as the curve must be filled if fill_mode set to on, whatever its polyline style value.
949 int PolylineDecomposer::fillIndices(int id, int* buffer, int bufferLength, int logMask)
951 double* coordinates = NULL;
952 double* xshift = NULL;
953 double* yshift = NULL;
954 double* zshift = NULL;
957 int* piNPoints = &nPoints;
958 int polylineStyle = 0;
959 int* piPolylineStyle = &polylineStyle;
961 int* piFillMode = &fillMode;
963 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
964 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
965 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
966 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
967 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
968 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
970 getGraphicObjectProperty(id, __GO_FILL_MODE__, jni_bool, (void**) &piFillMode);
972 /* 0 triangles if 0 points */
978 switch (polylineStyle)
981 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, fillMode, polylineStyle);
983 return fillArrowTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
985 /* Set fill mode to on, since patches are always filled whatever fill mode's value */
986 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, 1, polylineStyle);
988 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
990 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
996 int PolylineDecomposer::fillTriangleIndices(int id, int* buffer, int bufferLength,
997 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int fillMode, int polylineStyle)
1001 int interpColorMode = 0;
1002 int* piInterpColorMode = &interpColorMode;
1003 int triangulate = 0;
1009 /* At least 3 points needed */
1020 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
1023 * Do not triangulate if the interpolated color mode is set to 'on' and the polyline style is filled patch (5).
1024 * The quadrilateral facet decomposition function is used instead, if nPoints == 4,
1025 * for compatibility reasons, although triangulation could be used.
1027 if (interpColorMode && polylineStyle != 5)
1031 else if (nPoints > 3)
1033 /* Perform triangulation only if more than 3 points */
1039 Triangulator triangulator;
1045 for (int i = 0; i < nPoints; i++)
1047 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coords[0][0], &coords[0][1], &coords[0][2]);
1049 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1053 tmpValid &= DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1057 coords[0][0] = DecompositionUtils::getLog10Value(coords[0][0]);
1062 coords[0][1] = DecompositionUtils::getLog10Value(coords[0][1]);
1067 coords[0][2] = DecompositionUtils::getLog10Value(coords[0][2]);
1071 isValid &= tmpValid;
1078 triangulator.addPoint(coords[0][0], coords[0][1], coords[0][2]);
1087 triangulator.initialize();
1088 triangulator.triangulate();
1090 numTriangles = triangulator.getNumberTriangles();
1091 indices = triangulator.getIndices();
1093 for (int i = 0; i < numTriangles; i++)
1095 buffer[3 * i] = indices[3 * i];
1096 buffer[3 * i + 1] = indices[3 * i + 1];
1097 buffer[3 * i + 2] = indices[3 * i + 2];
1101 triangulator.clear();
1107 /* Do not triangulate: either the interpolation color mode is set to on or it is not and there are only 3 points. */
1109 /* 3 points: only one triangle output */
1112 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1113 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1114 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1116 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1117 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1118 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1124 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1125 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1126 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1127 isValid &= tmpValid;
1139 else if (nPoints >= 4)
1142 * 4 points: the quadrilateral facet decomposition algorithm is used.
1143 * If the Polyline has more than 4 points, we still output two triangles
1144 * corresponding to the first 4 points. This behaviour is kept for compatibility.
1145 * Possible correction: do not output indices if there are more than 4 points and
1146 * the interpolation color mode is set to on.
1148 int facetVertexIndices[4] = {0, 1, 2, 3};
1150 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1151 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1152 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1153 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 3, &coords[3][0], &coords[3][1], &coords[3][2]);
1155 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1156 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1157 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1158 tmpValid &= DecompositionUtils::isValid(coords[3][0], coords[3][1], coords[3][2]);
1164 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1165 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1166 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1167 tmpValid &= DecompositionUtils::isLogValid(coords[3][0], coords[3][1], coords[3][2], logMask);
1168 isValid &= tmpValid;
1173 DecompositionUtils::getDecomposedQuadTriangleIndices(coords, facetVertexIndices, buffer);
1183 int PolylineDecomposer::fillArrowTriangleIndices(int id, int* buffer, int bufferLength,
1184 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1187 int* piClosed = &closed;
1189 int currentValid = 0;
1192 int firstArrowVertex = 0;
1196 int numberValidIndices = 0;
1198 /* At least 2 points needed to form segments */
1204 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1206 /* If closed, an additional segment is present */
1213 nArrows = nPoints - 1;
1217 * Arrow head vertices are stored consecutively after all the line vertices.
1218 * Hence the offset to the first arrow vertex.
1220 firstArrowVertex = nPoints;
1222 for (int i = 0; i < nArrows; i++)
1224 /* Indices of the tip, left and right vertices */
1226 buffer[n] = firstArrowVertex + n;
1227 buffer[n + 1] = buffer[n] + 1;
1228 buffer[n + 2] = buffer[n] + 2;
1235 * Only bars are filled at the present moment, the curve is not.
1236 * See fillTriangleIndices for more information.
1238 int PolylineDecomposer::fillBarsDecompositionTriangleIndices(int id, int* buffer, int bufferLength,
1239 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1241 double barWidth = 0.0;
1242 double* pdBarWidth = &barWidth;
1245 int triangleIndices[6];
1247 int numberValidIndices = 0;
1254 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1256 /* 0 indices if the bar width is invalid, as it is the same for all bars. */
1257 if (!DecompositionUtils::isValid(barWidth))
1263 * Gets the indices corresponding to a rectangle decomposed into 2 triangles.
1264 * All the bars are decomposed the same way.
1266 DecompositionUtils::getDecomposedRectangleTriangleIndices(triangleIndices);
1269 for (int i = 0; i < nPoints; i++)
1271 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1273 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1275 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1280 buffer[6 * offset] = 4 * i + triangleIndices[0];
1281 buffer[6 * offset + 1] = 4 * i + triangleIndices[1];
1282 buffer[6 * offset + 2] = 4 * i + triangleIndices[2];
1283 buffer[6 * offset + 3] = 4 * i + triangleIndices[3];
1284 buffer[6 * offset + 4] = 4 * i + triangleIndices[4];
1285 buffer[6 * offset + 5] = 4 * i + triangleIndices[5];
1287 numberValidIndices += 6;
1293 return numberValidIndices;
1296 int PolylineDecomposer::getWireIndicesSize(int id)
1299 int *piNPoints = &nPoints;
1300 int polylineStyle = 0;
1301 int* piPolylineStyle = &polylineStyle;
1304 int* piLineMode = &lineMode;
1307 int* piClosed = &closed;
1309 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1310 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1311 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1312 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1314 /* No segments if 0 points */
1320 switch (polylineStyle)
1324 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1327 return getStairDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1329 /* Vertical segments plus segments */
1330 return getVerticalLinesDecompositionSegmentIndicesSize(nPoints, lineMode);
1332 /* Segments with arrow heads */
1333 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1336 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1338 /* Vertical bars plus segments */
1339 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1341 /* Horizontal bars plus segments */
1342 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1348 int PolylineDecomposer::getSegmentsDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1372 int PolylineDecomposer::getStairDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1383 return 2 * nPoints + 1;
1387 return 2 * nPoints - 1;
1396 int PolylineDecomposer::getVerticalLinesDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1405 return 2 * (nPoints) + 2 * (nPoints - 1);
1409 return 2 * (nPoints);
1413 int PolylineDecomposer::getBarsDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1422 return 2 * 4 * (nPoints) + 2 * (nPoints - 1);
1426 return 2 * 4 * (nPoints);
1430 int PolylineDecomposer::fillWireIndices(int id, int* buffer, int bufferLength, int logMask)
1432 double* coordinates = NULL;
1433 double* xshift = NULL;
1434 double* yshift = NULL;
1435 double* zshift = NULL;
1437 int polylineStyle = 0;
1438 int* piPolylineStyle = &polylineStyle;
1440 int* piNPoints = &nPoints;
1442 int* piClosed = &closed;
1444 int* piLineMode = &lineMode;
1446 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1448 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
1449 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1450 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
1451 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
1452 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
1454 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1455 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1457 switch (polylineStyle)
1460 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1462 return fillStairDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1464 return fillVerticalLinesDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1466 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1468 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1470 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1472 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1478 int PolylineDecomposer::fillSegmentsDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1479 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1481 /* If less than 2 points, no segments */
1492 for (int i = 0; i < nPoints; i++)
1499 buffer[nPoints] = 0;
1502 return closed ? (nPoints + 1) : nPoints;
1505 int PolylineDecomposer::fillStairDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1506 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1508 int currentValid = 0;
1509 int middleVertexValid = 0;
1513 int numberValidIndices = 0;
1515 /* If less than 2 points, no segments */
1526 for (int i = 0; i < 2 * nPoints - 1; i++)
1533 buffer[2 * nPoints - 1] = 2 * nPoints - 1;
1534 buffer[2 * nPoints] = 0;
1537 return closed ? (2 * nPoints + 1) : (2 * nPoints - 1);
1540 int PolylineDecomposer::fillVerticalLinesDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1541 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1546 int numberValidIndices = 0;
1553 /* Vertical lines */
1554 for (int i = 0; i < nPoints; i++)
1556 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1558 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1560 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1565 buffer[2 * offset] = 2 * i;
1566 buffer[2 * offset + 1] = 2 * i + 1;
1568 numberValidIndices += 2;
1579 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1581 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1585 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1588 for (int i = 0; i < nPoints - 1; i++)
1590 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i + 1, &coordsi[0], &coordsi[1], &coordsi[2]);
1592 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1596 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1599 if (currentValid && nextValid)
1601 buffer[2 * offset] = 2 * i + 1;
1602 buffer[2 * offset + 1] = 2 * (i + 1) + 1;
1604 numberValidIndices += 2;
1608 currentValid = nextValid;
1612 return numberValidIndices;
1616 int PolylineDecomposer::fillBarsDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1617 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1619 double barWidth = 0.0;
1620 double* pdBarWidth = &barWidth;
1623 int barWidthValid = 0;
1625 int numberValidIndices = 0;
1632 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1634 barWidthValid = DecompositionUtils::isValid(barWidth);
1636 /* 0 bar segment indices if the bar width is invalid, as it is the same for all bars. */
1640 for (int i = 0; i < nPoints; i++)
1642 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1644 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1646 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1651 buffer[8 * offset] = 4 * i;
1652 buffer[8 * offset + 1] = 4 * i + 1;
1653 buffer[8 * offset + 2] = 4 * i + 1;
1654 buffer[8 * offset + 3] = 4 * i + 2;
1655 buffer[8 * offset + 4] = 4 * i + 2;
1656 buffer[8 * offset + 5] = 4 * i + 3;
1657 buffer[8 * offset + 6] = 4 * i + 3;
1658 buffer[8 * offset + 7] = 4 * i;
1660 numberValidIndices += 8;
1676 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1678 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1682 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1685 for (int i = 0; i < nPoints - 1; i++)
1687 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i + 1, &coordsi[0], &coordsi[1], &coordsi[2]);
1689 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1693 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1696 if (currentValid && nextValid)
1698 buffer[8 * offset + 2 * loffset] = 4 * nPoints + i;
1699 buffer[8 * offset + 2 * loffset + 1] = 4 * nPoints + i + 1;
1701 numberValidIndices += 2;
1705 currentValid = nextValid;
1709 return numberValidIndices;
1712 void PolylineDecomposer::getShiftedPolylinePoint(double* coordinates, double* xshift, double* yshift, double* zshift, int nPoints, int index,
1713 double* x, double* y, double* z)
1715 *x = coordinates[index];
1719 *x += xshift[index];
1722 *y = coordinates[index + nPoints];
1726 *y += yshift[index];
1729 *z = coordinates[index + 2 * nPoints];
1733 *z += zshift[index];