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-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(char* 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 */
50 if (polylineStyle == 1)
55 else if (polylineStyle == 2)
66 /* Vertical segments plus segments */
67 else if (polylineStyle == 3)
71 /* Segments with arrow heads */
72 else if (polylineStyle == 4)
75 /* The numbers of arrow head vertices and indices are exactly the same */
76 nArrowVertices = PolylineDecomposer::getArrowTriangleIndicesSize(nPoints, closed);
78 return nPoints + nArrowVertices;
81 else if (polylineStyle == 5)
85 /* Vertical bars plus segments */
86 else if (polylineStyle == 6)
90 /* Horizontal bars plus segments */
91 else if (polylineStyle == 7)
95 /* To be done: remaining styles */
103 void PolylineDecomposer::fillVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask)
106 double* xshift = NULL;
107 double* yshift = NULL;
108 double* zshift = NULL;
110 int polylineStyle = 0;
111 int* piPolylineStyle = &polylineStyle;
114 int *piNPoints = &nPoints;
116 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &t);
117 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
119 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
120 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
121 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
123 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
125 if (polylineStyle == 1)
127 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
129 else if (polylineStyle == 2)
131 fillStairDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
133 else if (polylineStyle == 3)
135 fillVerticalLinesDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
137 else if (polylineStyle == 4)
139 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
141 else if (polylineStyle == 5)
143 fillSegmentsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
145 else if (polylineStyle == 6)
147 fillVerticalBarsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
149 else if (polylineStyle == 7)
151 fillHorizontalBarsDecompositionVertices(id, buffer, bufferLength, elementsSize, coordinateMask, scale, translation, logMask, t, nPoints, xshift, yshift, zshift);
156 void PolylineDecomposer::fillSegmentsDecompositionVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
157 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
160 int componentIndices[3];
162 // TODO Optimize ? (test if s = 1 and t = 0, coordinateMask = 0 ...)
163 for (int i = 0; i < nPoints; i++)
165 /* Offset of a polyline vertex */
166 int v0 = elementsSize*i;
168 componentIndices[0] = i;
169 componentIndices[1] = i;
170 componentIndices[2] = i;
172 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize,
173 xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
178 void PolylineDecomposer::getAndWriteVertexToBuffer(float* buffer, int offset, double* coordinates, int* vertexIndices, int nPoints, int elementsSize,
179 double* xshift, double* yshift, double* zshift, int coordinateMask, double* scale, double* translation, int logMask)
181 double coordinate = 0.;
183 if (coordinateMask & 0x01)
185 coordinate = coordinates[vertexIndices[0]];
189 coordinate += xshift[vertexIndices[0]];
194 coordinate = DecompositionUtils::getLog10Value(coordinate);
197 buffer[offset +0] = (float)(coordinate * scale[0] + translation[0]);
200 if (coordinateMask & 0x02)
202 coordinate = coordinates[vertexIndices[1] + nPoints];
206 coordinate += yshift[vertexIndices[1]];
211 coordinate = DecompositionUtils::getLog10Value(coordinate);
214 buffer[offset +1] = (float)(coordinate * scale[1] + translation[1]);
217 if (coordinateMask & 0x04)
219 coordinate = coordinates[vertexIndices[2] + 2*nPoints];
223 coordinate += zshift[vertexIndices[2]];
228 coordinate = DecompositionUtils::getLog10Value(coordinate);
231 buffer[offset +2] = (float)(coordinate * scale[2] + translation[2]);
234 if((elementsSize == 4) && (coordinateMask & 0x08))
236 buffer[offset +3] = 1.0;
241 void PolylineDecomposer::fillStairDecompositionVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
242 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
245 int* piClosed = &closed;
247 /* Offsets of the left and right vertices (respectively) */
251 int componentIndices[3];
258 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
260 for (int i = 0; i < nPoints-1; i++)
262 v0 = elementsSize*2*i;
263 v1 = elementsSize*(2*i+1);
265 componentIndices[0] = i;
266 componentIndices[1] = i;
267 componentIndices[2] = i;
269 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
271 componentIndices[0] = i+1;
272 componentIndices[1] = i;
273 componentIndices[2] = i;
275 /* To be optimized: the y and z components are fetched and transformed twice */
276 getAndWriteVertexToBuffer(buffer, v1, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
280 v0 = elementsSize*2*(nPoints-1);
282 componentIndices[0] = nPoints-1;
283 componentIndices[1] = nPoints-1;
284 componentIndices[2] = nPoints-1;
286 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
289 * One additional vertex if closed
290 * Its x-coordinate is equal to the one of the polyline's first point
291 * whereas its y and z coordinates are equal to those of the last point.
295 v0 = elementsSize*(2*nPoints-1);
297 componentIndices[0] = 0;
298 componentIndices[1] = nPoints-1;
299 componentIndices[2] = nPoints-1;
301 getAndWriteVertexToBuffer(buffer, v0, coordinates, componentIndices, nPoints, elementsSize, xshift, yshift, zshift, coordinateMask, scale, translation, logMask);
306 void PolylineDecomposer::fillVerticalLinesDecompositionVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
307 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
309 for (int i = 0; i < nPoints; i++)
311 /* Offsets of the lower and upper vertices (respectively) */
315 /* Coordinates of the lower and upper vertices (respectively) */
319 v0 = elementsSize*2*i;
320 v1 = elementsSize*(2*i+1);
322 /* Lower and upper endpoints x coordinates */
323 if (coordinateMask & 0x01)
325 coord0 = coordinates[i];
326 coord1 = coordinates[i];
336 coord0 = DecompositionUtils::getLog10Value(coord0);
337 coord1 = DecompositionUtils::getLog10Value(coord1);
340 buffer[v0 +0] = (float)(coord0 * scale[0] + translation[0]);
341 buffer[v1 +0] = (float)(coord1 * scale[0] + translation[0]);
344 /* Lower and upper endpoints y coordinates */
345 if (coordinateMask & 0x02)
348 coord1 = coordinates[i + nPoints];
353 * Only the upper vertex's y coordinate is shifted,
354 * the lower vertex's one remains unchanged.
361 /* The lower endpoint's y coordinate is unchanged (it amounts to log10(1), which is 0) */
362 coord1 = DecompositionUtils::getLog10Value(coord1);
365 buffer[v0 +1] = (float)(coord0 * scale[1] + translation[1]);
366 buffer[v1 +1] = (float)(coord1 * scale[1] + translation[1]);
369 /* Lower and upper endpoints z coordinates */
370 if (coordinateMask & 0x04)
372 coord0 = coordinates[2*nPoints+i];
373 coord1 = coordinates[2*nPoints+i];
383 coord0 = DecompositionUtils::getLog10Value(coord0);
384 coord1 = DecompositionUtils::getLog10Value(coord1);
387 buffer[v0 +2] = (float)(coord0 * scale[2] + translation[2]);
388 buffer[v1 +2] = (float)(coord1 * scale[2] + translation[2]);
391 if((elementsSize == 4) && (coordinateMask & 0x08))
401 void PolylineDecomposer::writeBarVerticesToBuffer(float* buffer, int* offsets, int componentOffset, double* coordinates, double shift, int shiftUsed,
402 double scale, double translation, int logUsed)
406 coordinates[0] += shift;
407 coordinates[1] += shift;
408 coordinates[2] += shift;
409 coordinates[3] += shift;
411 coordinates[4] += shift;
416 coordinates[0] = DecompositionUtils::getLog10Value(coordinates[0]);
417 coordinates[1] = DecompositionUtils::getLog10Value(coordinates[1]);
418 coordinates[2] = DecompositionUtils::getLog10Value(coordinates[2]);
419 coordinates[3] = DecompositionUtils::getLog10Value(coordinates[3]);
421 coordinates[4] = DecompositionUtils::getLog10Value(coordinates[4]);
424 buffer[offsets[0] +componentOffset] = (float)(coordinates[0] * scale + translation);
425 buffer[offsets[1] +componentOffset] = (float)(coordinates[1] * scale + translation);
426 buffer[offsets[2] +componentOffset] = (float)(coordinates[2] * scale + translation);
427 buffer[offsets[3] +componentOffset] = (float)(coordinates[3] * scale + translation);
429 buffer[offsets[4] +componentOffset] = (float)(coordinates[4] * scale + translation);
432 void PolylineDecomposer::fillVerticalBarsDecompositionVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
433 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
435 double barWidth = 0.0;
436 double* pdBarWidth = &barWidth;
439 int *piShiftUsed = NULL;
442 * Offsets of the lower-left, lower-right, upper-right and upper-left bar vertices (respectively)
443 * and of the polyline vertex proper
448 * {x,y or z}-component values of a bar's 4 vertices (same ordering as the offsets)
449 * and of the polyline vertex proper.
456 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
458 piShiftUsed = &shiftUsed[0];
459 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
460 piShiftUsed = &shiftUsed[1];
461 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
462 piShiftUsed = &shiftUsed[2];
463 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
466 for (int i = 0; i < nPoints; i++)
468 offsets[0] = elementsSize*4*i;
469 offsets[1] = elementsSize*(4*i+1);
470 offsets[2] = elementsSize*(4*i+2);
471 offsets[3] = elementsSize*(4*i+3);
473 offsets[4] = elementsSize*(4*nPoints+i);
475 if (coordinateMask & 0x01)
477 coords[0] = coordinates[i] - 0.5*barWidth;
478 coords[1] = coordinates[i] + 0.5*barWidth;
479 coords[2] = coordinates[i] + 0.5*barWidth;
480 coords[3] = coordinates[i] - 0.5*barWidth;
482 coords[4] = coordinates[i];
489 writeBarVerticesToBuffer(buffer, offsets, 0, coords, shift, shiftUsed[0], scale[0], translation[0], logMask & 0x01);
492 if (coordinateMask & 0x02)
496 coords[2] = coordinates[i + nPoints];
497 coords[3] = coordinates[i + nPoints];
499 coords[4] = coordinates[i + nPoints];
509 * The two lower endpoints' y coordinates must be set to 1
510 * since writeBarVerticesToBuffer applies the logarithmic transformation.
516 writeBarVerticesToBuffer(buffer, offsets, 1, coords, shift, shiftUsed[1], scale[1], translation[1], logMask & 0x02);
519 if (coordinateMask & 0x04)
521 coords[0] = coordinates[i + 2 * nPoints];
522 coords[1] = coordinates[i + 2 * nPoints];
523 coords[2] = coordinates[i + 2 * nPoints];
524 coords[3] = coordinates[i + 2 * nPoints];
526 coords[4] = coordinates[i + 2* nPoints];
533 writeBarVerticesToBuffer(buffer, offsets, 2, coords, shift, shiftUsed[2], scale[2], translation[2], logMask & 0x04);
536 if((elementsSize == 4) && (coordinateMask & 0x08))
538 buffer[offsets[0] +3] = 1.0;
539 buffer[offsets[1] +3] = 1.0;
540 buffer[offsets[2] +3] = 1.0;
541 buffer[offsets[3] +3] = 1.0;
543 buffer[offsets[4] +3] = 1.0;
551 * To do: -refactor with fillVerticalBarsDecompositionVertices as these two functions are very similar, possibly by implementing
552 a PolylineBarDecomposer class.
554 void PolylineDecomposer::fillHorizontalBarsDecompositionVertices(char* id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation,
555 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
557 double barWidth = 0.0;
558 double* pdBarWidth = &barWidth;
561 int *piShiftUsed = NULL;
564 * Offsets of the lower-left, lower-right, upper-right and upper-left bar vertices (respectively)
565 * and of the polyline vertex proper
570 * {x,y or z}-component values of a bar's 4 vertices (same ordering as the offsets)
571 * and of the polyline vertex proper.
578 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
580 piShiftUsed = &shiftUsed[0];
581 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
582 piShiftUsed = &shiftUsed[1];
583 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
584 piShiftUsed = &shiftUsed[2];
585 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT_SET__, jni_double_vector, (void**) &piShiftUsed);
587 for (int i = 0; i < nPoints; i++)
589 offsets[0] = elementsSize*4*i;
590 offsets[1] = elementsSize*(4*i+1);
591 offsets[2] = elementsSize*(4*i+2);
592 offsets[3] = elementsSize*(4*i+3);
594 offsets[4] = elementsSize*(4*nPoints+i);
596 /* The actual x coordinates correspond to the polyline's y coordinates. */
597 if (coordinateMask & 0x01)
601 coords[2] = coordinates[i + nPoints];
602 coords[3] = coordinates[i + nPoints];
604 coords[4] = coordinates[i];
611 writeBarVerticesToBuffer(buffer, offsets, 0, coords, shift, shiftUsed[1], scale[0], translation[0], logMask & 0x01);
614 /* The actual y coordinates correspond to the polyline's x coordinates. */
615 if (coordinateMask & 0x02)
617 coords[0] = coordinates[i] - 0.5*barWidth;
618 coords[1] = coordinates[i] + 0.5*barWidth;
619 coords[2] = coordinates[i] + 0.5*barWidth;
620 coords[3] = coordinates[i] - 0.5*barWidth;
622 coords[4] = coordinates[i + nPoints];
632 * The two lower endpoints' y coordinates must be set to 1
633 * since writeBarVerticesToBuffer applies the logarithmic transformation.
639 writeBarVerticesToBuffer(buffer, offsets, 1, coords, shift, shiftUsed[0], scale[1], translation[1], logMask & 0x02);
642 if (coordinateMask & 0x04)
644 coords[0] = coordinates[i + 2 * nPoints];
645 coords[1] = coordinates[i + 2 * nPoints];
646 coords[2] = coordinates[i + 2 * nPoints];
647 coords[3] = coordinates[i + 2 * nPoints];
649 coords[4] = coordinates[i + 2* nPoints];
656 writeBarVerticesToBuffer(buffer, offsets, 2, coords, shift, shiftUsed[2], scale[2], translation[2], logMask & 0x04);
659 if((elementsSize == 4) && (coordinateMask & 0x08))
661 buffer[offsets[0] +3] = 1.0;
662 buffer[offsets[1] +3] = 1.0;
663 buffer[offsets[2] +3] = 1.0;
664 buffer[offsets[3] +3] = 1.0;
666 buffer[offsets[4] +3] = 1.0;
675 * -implement for the other relevant polyline style values.
676 * -fix the no colors written problem (related to polyline C build functions, see below).
678 void PolylineDecomposer::fillColors(char* id, float* buffer, int bufferLength, int elementsSize)
681 char* parentFigure = NULL;
683 int interpColorMode = 0;
684 int* piInterpColorMode = &interpColorMode;
685 int polylineStyle = 0;
686 int* piPolylineStyle = &polylineStyle;
688 int *piNPoints = &nPoints;
689 int colormapSize = 0;
690 int* piColormapSize = &colormapSize;
691 int bufferOffset = 0;
692 int* interpColorVector = NULL;
694 double* colormap = NULL;
696 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
698 if (interpColorMode == 0)
703 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
705 if (polylineStyle != 1)
710 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
711 getGraphicObjectProperty(id, __GO_PARENT__, jni_string, (void**) &parent);
713 /* Temporary: to avoid getting a null parent_figure property when the object is built */
714 if (strcmp(parent, "") == 0)
719 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_string, (void**) &parentFigure);
722 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
723 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
724 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
725 * black-filled polygons, as no colors are written.
726 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
727 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
728 * hence possibly caused by a race condition.
731 if (strcmp(parentFigure, "") == 0)
737 * The interpolated color vector is a 3- or 4-element vector.
738 * However, if nPoints is greater than 4, we choose to output
739 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
746 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
747 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
748 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
755 for (int i = 0; i < nPoints; i++)
757 ColorComputer::getDirectColor((double) interpColorVector[i] - 1.0, colormap, colormapSize, &buffer[bufferOffset]);
759 if (elementsSize == 4)
761 buffer[bufferOffset+3] = 1.0;
764 bufferOffset += elementsSize;
767 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
768 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
771 void PolylineDecomposer::fillTextureCoordinates(char* id, float* buffer, int bufferLength)
774 char* parentFigure = NULL;
776 int interpColorMode = 0;
777 int* piInterpColorMode = &interpColorMode;
778 int polylineStyle = 0;
779 int* piPolylineStyle = &polylineStyle;
781 int *piNPoints = &nPoints;
782 int colormapSize = 0;
783 int* piColormapSize = &colormapSize;
784 int bufferOffset = 0;
785 int* interpColorVector = NULL;
787 double* colormap = NULL;
789 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
791 if (interpColorMode == 0)
796 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
798 if (polylineStyle != 1)
803 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
804 getGraphicObjectProperty(id, __GO_PARENT__, jni_string, (void**) &parent);
806 /* Temporary: to avoid getting a null parent_figure property when the object is built */
807 if (strcmp(parent, "") == 0)
812 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_string, (void**) &parentFigure);
815 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
816 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
817 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
818 * black-filled polygons, as no colors are written.
819 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
820 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
821 * hence possibly caused by a race condition.
824 if (strcmp(parentFigure, "") == 0)
830 * The interpolated color vector is a 3- or 4-element vector.
831 * However, if nPoints is greater than 4, we choose to output
832 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
839 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
840 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
841 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
848 for (int i = 0; i < nPoints; i++)
850 double index = (ColorComputer::getDirectIndex((double) interpColorVector[i] - 1.0, colormapSize) + 2.0 + COLOR_TEXTURE_OFFSET) / (double) (colormapSize + 2);
852 buffer[bufferOffset] = (float)index;
853 buffer[bufferOffset+1] = 0.0;
854 buffer[bufferOffset+2] = 0.0;
855 buffer[bufferOffset+3] = 1.0;
860 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
861 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
865 * To do: see fillIndices
866 * -take into account polyline_style.
868 int PolylineDecomposer::getIndicesSize(char* id)
871 int *piNPoints = &nPoints;
872 int polylineStyle = 0;
873 int* piPolylineStyle = &polylineStyle;
875 int* piClosed = &closed;
879 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
880 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
881 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
883 /* No facets if 0 points */
890 if (polylineStyle == 1)
897 /* Maximum number of triangles output by the triangulator */
898 nIndices = 3*(nPoints-2);
900 /* Arrowed segments */
901 else if (polylineStyle == 4)
903 nIndices = PolylineDecomposer::getArrowTriangleIndicesSize(nPoints, closed);
906 else if (polylineStyle == 5)
913 /* Maximum number of triangles output by the triangulator */
914 nIndices = 3*(nPoints-2);
916 /* Vertical bars plus segments */
917 else if (polylineStyle == 6)
919 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
921 /* Horizontal bars plus segments */
922 else if (polylineStyle == 7)
924 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
930 int PolylineDecomposer::getArrowTriangleIndicesSize(int nPoints, int closed)
940 nIndices = 3*(nPoints-1);
951 int PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(int nPoints)
958 * -take into account the polyline style property (note: vertical bars -style 6- are filled
959 * whatever fill_mode's value), by implementing the relevant functions (see fillTriangleIndices),
960 * as the curve must be filled if fill_mode set to on, whatever its polyline style value.
962 int PolylineDecomposer::fillIndices(char* id, int* buffer, int bufferLength, int logMask)
964 double* coordinates = NULL;
965 double* xshift = NULL;
966 double* yshift = NULL;
967 double* zshift = NULL;
970 int* piNPoints = &nPoints;
971 int polylineStyle = 0;
972 int* piPolylineStyle = &polylineStyle;
974 int* piFillMode = &fillMode;
976 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
977 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
978 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
979 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
980 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
981 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
983 getGraphicObjectProperty(id, __GO_FILL_MODE__, jni_bool, (void**) &piFillMode);
985 /* 0 triangles if 0 points */
991 if (polylineStyle == 1)
993 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, fillMode, polylineStyle);
995 else if (polylineStyle == 4)
997 return fillArrowTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
999 else if (polylineStyle == 5)
1001 /* Set fill mode to on, since patches are always filled whatever fill mode's value */
1002 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, 1, polylineStyle);
1004 else if (polylineStyle == 6)
1006 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
1008 else if (polylineStyle == 7)
1010 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
1016 int PolylineDecomposer::fillTriangleIndices(char* id, int* buffer, int bufferLength,
1017 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int fillMode, int polylineStyle)
1019 double coords[4][3];
1021 int interpColorMode = 0;
1022 int* piInterpColorMode = &interpColorMode;
1023 int triangulate = 0;
1029 /* At least 3 points needed */
1040 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
1043 * Do not triangulate if the interpolated color mode is set to 'on' and the polyline style is filled patch (5).
1044 * The quadrilateral facet decomposition function is used instead, if nPoints == 4,
1045 * for compatibility reasons, although triangulation could be used.
1047 if (interpColorMode && polylineStyle != 5)
1051 else if (nPoints > 3)
1053 /* Perform triangulation only if more than 3 points */
1059 Triangulator triangulator;
1065 for (int i = 0; i < nPoints; i++)
1067 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coords[0][0], &coords[0][1], &coords[0][2]);
1069 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1073 tmpValid &= DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1077 coords[0][0] = DecompositionUtils::getLog10Value(coords[0][0]);
1082 coords[0][1] = DecompositionUtils::getLog10Value(coords[0][1]);
1087 coords[0][2] = DecompositionUtils::getLog10Value(coords[0][2]);
1091 isValid &= tmpValid;
1098 triangulator.addPoint(coords[0][0], coords[0][1], coords[0][2]);
1107 triangulator.initialize();
1108 triangulator.triangulate();
1110 numTriangles = triangulator.getNumberTriangles();
1111 indices = triangulator.getIndices();
1113 for (int i = 0; i < numTriangles; i++)
1115 buffer[3*i] = indices[3*i];
1116 buffer[3*i+1] = indices[3*i+1];
1117 buffer[3*i+2] = indices[3*i+2];
1121 triangulator.clear();
1127 /* Do not triangulate: either the interpolation color mode is set to on or it is not and there are only 3 points. */
1129 /* 3 points: only one triangle output */
1132 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1133 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1134 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1136 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1137 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1138 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1144 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1145 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1146 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1147 isValid &= tmpValid;
1159 else if (nPoints >= 4)
1162 * 4 points: the quadrilateral facet decomposition algorithm is used.
1163 * If the Polyline has more than 4 points, we still output two triangles
1164 * corresponding to the first 4 points. This behaviour is kept for compatibility.
1165 * Possible correction: do not output indices if there are more than 4 points and
1166 * the interpolation color mode is set to on.
1168 int facetVertexIndices[4] = {0, 1, 2, 3};
1170 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1171 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1172 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1173 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 3, &coords[3][0], &coords[3][1], &coords[3][2]);
1175 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1176 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1177 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1178 tmpValid &= DecompositionUtils::isValid(coords[3][0], coords[3][1], coords[3][2]);
1184 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1185 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1186 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1187 tmpValid &= DecompositionUtils::isLogValid(coords[3][0], coords[3][1], coords[3][2], logMask);
1188 isValid &= tmpValid;
1193 DecompositionUtils::getDecomposedQuadTriangleIndices(coords, facetVertexIndices, buffer);
1203 int PolylineDecomposer::fillArrowTriangleIndices(char* id, int* buffer, int bufferLength,
1204 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1209 int* piClosed = &closed;
1211 int currentValid = 0;
1214 int firstArrowVertex = 0;
1218 int numberValidIndices = 0;
1220 /* At least 2 points needed to form segments */
1226 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1228 /* If closed, an additional segment is present */
1235 nArrows = nPoints-1;
1239 * Arrow head vertices are stored consecutively after all the line vertices.
1240 * Hence the offset to the first arrow vertex.
1242 firstArrowVertex = nPoints;
1244 for (int i = 0; i < nArrows; i++)
1246 /* Indices of the tip, left and right vertices */
1248 buffer[n] = firstArrowVertex + n;
1249 buffer[n + 1] = buffer[n] + 1;
1250 buffer[n + 2] = buffer[n] + 2;
1257 * Only bars are filled at the present moment, the curve is not.
1258 * See fillTriangleIndices for more information.
1260 int PolylineDecomposer::fillBarsDecompositionTriangleIndices(char* id, int* buffer, int bufferLength,
1261 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1263 double barWidth = 0.0;
1264 double* pdBarWidth = &barWidth;
1267 int triangleIndices[6];
1269 int numberValidIndices = 0;
1276 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1278 /* 0 indices if the bar width is invalid, as it is the same for all bars. */
1279 if (!DecompositionUtils::isValid(barWidth))
1285 * Gets the indices corresponding to a rectangle decomposed into 2 triangles.
1286 * All the bars are decomposed the same way.
1288 DecompositionUtils::getDecomposedRectangleTriangleIndices(triangleIndices);
1291 for (int i = 0; i < nPoints; i++)
1293 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1295 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1297 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1302 buffer[6*offset] = 4*i + triangleIndices[0];
1303 buffer[6*offset+1] = 4*i + triangleIndices[1];
1304 buffer[6*offset+2] = 4*i + triangleIndices[2];
1305 buffer[6*offset+3] = 4*i + triangleIndices[3];
1306 buffer[6*offset+4] = 4*i + triangleIndices[4];
1307 buffer[6*offset+5] = 4*i + triangleIndices[5];
1309 numberValidIndices += 6;
1315 return numberValidIndices;
1318 int PolylineDecomposer::getWireIndicesSize(char* id)
1321 int *piNPoints = &nPoints;
1322 int polylineStyle = 0;
1323 int* piPolylineStyle = &polylineStyle;
1326 int* piLineMode = &lineMode;
1329 int* piClosed = &closed;
1331 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1332 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1333 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1334 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1336 /* No segments if 0 points */
1343 if (polylineStyle == 1)
1345 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1348 else if (polylineStyle == 2)
1350 return getStairDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1352 /* Vertical segments plus segments */
1353 else if (polylineStyle == 3)
1355 return getVerticalLinesDecompositionSegmentIndicesSize(nPoints, lineMode);
1357 /* Segments with arrow heads */
1358 else if (polylineStyle == 4)
1360 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1363 else if (polylineStyle == 5)
1365 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1367 /* Vertical bars plus segments */
1368 else if (polylineStyle == 6)
1370 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1372 /* Horizontal bars plus segments */
1373 else if (polylineStyle == 7)
1375 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1384 int PolylineDecomposer::getSegmentsDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1408 int PolylineDecomposer::getStairDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1419 return 2 * nPoints + 1;
1423 return 2 * nPoints - 1;
1432 int PolylineDecomposer::getVerticalLinesDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1441 return 2*(nPoints) + 2*(nPoints-1);
1449 int PolylineDecomposer::getBarsDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1458 return 2*4*(nPoints) + 2*(nPoints-1);
1462 return 2*4*(nPoints);
1466 int PolylineDecomposer::fillWireIndices(char* id, int* buffer, int bufferLength, int logMask)
1468 double* coordinates = NULL;
1469 double* xshift = NULL;
1470 double* yshift = NULL;
1471 double* zshift = NULL;
1473 int polylineStyle = 0;
1474 int* piPolylineStyle = &polylineStyle;
1476 int* piNPoints = &nPoints;
1478 int* piClosed = &closed;
1480 int* piLineMode = &lineMode;
1482 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1484 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
1485 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1486 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
1487 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
1488 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
1490 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1491 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1493 if (polylineStyle == 1)
1495 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1497 else if (polylineStyle == 2)
1499 return fillStairDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1501 else if (polylineStyle == 3)
1503 return fillVerticalLinesDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1505 else if (polylineStyle == 4)
1507 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1509 else if (polylineStyle == 5)
1511 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1513 else if (polylineStyle == 6)
1515 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1517 else if (polylineStyle == 7)
1519 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1525 int PolylineDecomposer::fillSegmentsDecompositionSegmentIndices(char* id, int* buffer, int bufferLength,
1526 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1528 /* If less than 2 points, no segments */
1539 for (int i = 0; i < nPoints; i++)
1546 buffer[nPoints] = 0;
1549 return closed ? (nPoints + 1) : nPoints;
1552 int PolylineDecomposer::fillStairDecompositionSegmentIndices(char* id, int* buffer, int bufferLength,
1553 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1556 double coordsip1[3];
1558 int currentValid = 0;
1559 int middleVertexValid = 0;
1563 int numberValidIndices = 0;
1565 /* If less than 2 points, no segments */
1576 for (int i = 0; i < 2 * nPoints - 1; i++)
1583 buffer[2 * nPoints - 1] = 2 * nPoints - 1;
1584 buffer[2 * nPoints] = 0;
1587 return closed ? (2 * nPoints + 1) : (2 * nPoints - 1);
1590 int PolylineDecomposer::fillVerticalLinesDecompositionSegmentIndices(char* id, int* buffer, int bufferLength,
1591 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1596 int numberValidIndices = 0;
1603 /* Vertical lines */
1604 for (int i = 0; i < nPoints; i++)
1606 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1608 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1610 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1615 buffer[2*offset] = 2*i;
1616 buffer[2*offset+1] = 2*i+1;
1618 numberValidIndices += 2;
1629 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1631 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1635 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1638 for (int i = 0; i < nPoints-1; i++)
1640 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i+1, &coordsi[0], &coordsi[1], &coordsi[2]);
1642 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1646 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1649 if (currentValid && nextValid)
1651 buffer[2*offset] = 2*i+1;
1652 buffer[2*offset+1] = 2*(i+1)+1;
1654 numberValidIndices += 2;
1658 currentValid = nextValid;
1662 return numberValidIndices;
1666 int PolylineDecomposer::fillBarsDecompositionSegmentIndices(char* id, int* buffer, int bufferLength,
1667 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1669 double barWidth = 0.0;
1670 double* pdBarWidth = &barWidth;
1673 int barWidthValid = 0;
1675 int numberValidIndices = 0;
1682 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1684 barWidthValid = DecompositionUtils::isValid(barWidth);
1686 /* 0 bar segment indices if the bar width is invalid, as it is the same for all bars. */
1690 for (int i = 0; i < nPoints; i++)
1692 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1694 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1696 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1701 buffer[8*offset] = 4*i;
1702 buffer[8*offset+1] = 4*i+1;
1703 buffer[8*offset+2] = 4*i+1;
1704 buffer[8*offset+3] = 4*i+2;
1705 buffer[8*offset+4] = 4*i+2;
1706 buffer[8*offset+5] = 4*i+3;
1707 buffer[8*offset+6] = 4*i+3;
1708 buffer[8*offset+7] = 4*i;
1710 numberValidIndices += 8;
1726 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1728 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1732 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1735 for (int i = 0; i < nPoints-1; i++)
1737 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i+1, &coordsi[0], &coordsi[1], &coordsi[2]);
1739 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1743 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1746 if (currentValid && nextValid)
1748 buffer[8*offset+2*loffset] = 4*nPoints +i;
1749 buffer[8*offset+2*loffset+1] = 4*nPoints +i+1;
1751 numberValidIndices += 2;
1755 currentValid = nextValid;
1759 return numberValidIndices;
1762 void PolylineDecomposer::getShiftedPolylinePoint(double* coordinates, double* xshift, double* yshift, double* zshift, int nPoints, int index,
1763 double* x, double* y, double* z)
1765 *x = coordinates[index];
1769 *x += xshift[index];
1772 *y = coordinates[index + nPoints];
1776 *y += yshift[index];
1779 *z = coordinates[index + 2*nPoints];
1783 *z += zshift[index];