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 */
50 if (polylineStyle == 1)
55 else if (polylineStyle == 2)
63 return (2 * nPoints) - 1;
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(int 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(int 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(int 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(int 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))
393 buffer[v0 + 3] = 1.0;
394 buffer[v1 + 3] = 1.0;
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(int 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(int 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(int id, float* buffer, int bufferLength, int elementsSize)
681 int* pparent = &parent;
682 int parentFigure = 0;
683 int* pparentFigure = &parentFigure;
685 int interpColorMode = 0;
686 int* piInterpColorMode = &interpColorMode;
687 int polylineStyle = 0;
688 int* piPolylineStyle = &polylineStyle;
690 int *piNPoints = &nPoints;
691 int colormapSize = 0;
692 int* piColormapSize = &colormapSize;
693 int bufferOffset = 0;
694 int* interpColorVector = NULL;
696 double* colormap = NULL;
698 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
700 if (interpColorMode == 0)
705 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
707 if (polylineStyle != 1)
712 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
713 parent = getParentObject(id);
715 /* Temporary: to avoid getting a null parent_figure property when the object is built */
721 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_int, (void**) &pparentFigure);
724 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
725 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
726 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
727 * black-filled polygons, as no colors are written.
728 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
729 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
730 * hence possibly caused by a race condition.
733 if (parentFigure == 0)
739 * The interpolated color vector is a 3- or 4-element vector.
740 * However, if nPoints is greater than 4, we choose to output
741 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
748 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
749 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
750 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
757 for (int i = 0; i < nPoints; i++)
759 ColorComputer::getDirectColor((double) interpColorVector[i] - 1.0, colormap, colormapSize, &buffer[bufferOffset]);
761 if (elementsSize == 4)
763 buffer[bufferOffset + 3] = 1.0;
766 bufferOffset += elementsSize;
769 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
770 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
773 void PolylineDecomposer::fillTextureCoordinates(int id, float* buffer, int bufferLength)
776 int* pparent = &parent;
777 int parentFigure = 0;
778 int* pparentFigure = &parentFigure;
780 int interpColorMode = 0;
781 int* piInterpColorMode = &interpColorMode;
782 int polylineStyle = 0;
783 int* piPolylineStyle = &polylineStyle;
785 int *piNPoints = &nPoints;
786 int colormapSize = 0;
787 int* piColormapSize = &colormapSize;
788 int bufferOffset = 0;
789 int* interpColorVector = NULL;
791 double* colormap = NULL;
793 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
795 if (interpColorMode == 0)
800 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
802 if (polylineStyle != 1)
807 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
808 parent = getParentObject(id);
810 /* Temporary: to avoid getting a null parent_figure property when the object is built */
816 getGraphicObjectProperty(id, __GO_PARENT_FIGURE__, jni_int, (void**) &pparentFigure);
819 * In some cases, the polyline's parent figure may be unitialized, when this point is reached from the
820 * filled polygons build C functions (xfpolys, with several polygons and a color vector for each one).
821 * This check prevents from crashing when getting the colormap. However, it results in incorrectly
822 * black-filled polygons, as no colors are written.
823 * As the sequentially built polygons are inserted within a Compound object, the latter object may be
824 * still unattached to a Figure as its Polyline children are rendered. This occurs about once in 5 to 10,
825 * hence possibly caused by a race condition.
828 if (parentFigure == 0)
834 * The interpolated color vector is a 3- or 4-element vector.
835 * However, if nPoints is greater than 4, we choose to output
836 * 4 colors (this behaviour is kept for compatibility, see fillTriangleIndices).
843 getGraphicObjectProperty(id, __GO_INTERP_COLOR_VECTOR__, jni_int_vector, (void**) &interpColorVector);
844 getGraphicObjectProperty(parentFigure, __GO_COLORMAP__, jni_double_vector, (void**) &colormap);
845 getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**) &piColormapSize);
852 for (int i = 0; i < nPoints; i++)
854 double index = (ColorComputer::getDirectIndex((double) interpColorVector[i] - 1.0, colormapSize) + 2.0 + COLOR_TEXTURE_OFFSET) / (double) (colormapSize + 2);
856 buffer[bufferOffset] = (float)index;
857 buffer[bufferOffset + 1] = 0.0;
858 buffer[bufferOffset + 2] = 0.0;
859 buffer[bufferOffset + 3] = 1.0;
864 releaseGraphicObjectProperty(__GO_COLORMAP__, colormap, jni_double_vector, colormapSize);
865 releaseGraphicObjectProperty(__GO_INTERP_COLOR_VECTOR__, interpColorVector, jni_int_vector, 0);
869 * To do: see fillIndices
870 * -take into account polyline_style.
872 int PolylineDecomposer::getIndicesSize(int id)
875 int *piNPoints = &nPoints;
876 int polylineStyle = 0;
877 int* piPolylineStyle = &polylineStyle;
879 int* piClosed = &closed;
883 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
884 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
885 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
887 /* No facets if 0 points */
894 if (polylineStyle == 1)
901 /* Maximum number of triangles output by the triangulator */
902 nIndices = 3 * (nPoints - 2);
904 /* Arrowed segments */
905 else if (polylineStyle == 4)
907 nIndices = PolylineDecomposer::getArrowTriangleIndicesSize(nPoints, closed);
910 else if (polylineStyle == 5)
917 /* Maximum number of triangles output by the triangulator */
918 nIndices = 3 * (nPoints - 2);
920 /* Vertical bars plus segments */
921 else if (polylineStyle == 6)
923 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
925 /* Horizontal bars plus segments */
926 else if (polylineStyle == 7)
928 nIndices = PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(nPoints);
934 int PolylineDecomposer::getArrowTriangleIndicesSize(int nPoints, int closed)
944 nIndices = 3 * (nPoints - 1);
955 int PolylineDecomposer::getBarsDecompositionTriangleIndicesSize(int nPoints)
957 return 2 * 3 * nPoints;
962 * -take into account the polyline style property (note: vertical bars -style 6- are filled
963 * whatever fill_mode's value), by implementing the relevant functions (see fillTriangleIndices),
964 * as the curve must be filled if fill_mode set to on, whatever its polyline style value.
966 int PolylineDecomposer::fillIndices(int id, int* buffer, int bufferLength, int logMask)
968 double* coordinates = NULL;
969 double* xshift = NULL;
970 double* yshift = NULL;
971 double* zshift = NULL;
974 int* piNPoints = &nPoints;
975 int polylineStyle = 0;
976 int* piPolylineStyle = &polylineStyle;
978 int* piFillMode = &fillMode;
980 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
981 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
982 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
983 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
984 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
985 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
987 getGraphicObjectProperty(id, __GO_FILL_MODE__, jni_bool, (void**) &piFillMode);
989 /* 0 triangles if 0 points */
995 if (polylineStyle == 1)
997 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, fillMode, polylineStyle);
999 else if (polylineStyle == 4)
1001 return fillArrowTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
1003 else if (polylineStyle == 5)
1005 /* Set fill mode to on, since patches are always filled whatever fill mode's value */
1006 return fillTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, 1, polylineStyle);
1008 else if (polylineStyle == 6)
1010 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
1012 else if (polylineStyle == 7)
1014 return fillBarsDecompositionTriangleIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift);
1020 int PolylineDecomposer::fillTriangleIndices(int id, int* buffer, int bufferLength,
1021 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int fillMode, int polylineStyle)
1023 double coords[4][3];
1025 int interpColorMode = 0;
1026 int* piInterpColorMode = &interpColorMode;
1027 int triangulate = 0;
1033 /* At least 3 points needed */
1044 getGraphicObjectProperty(id, __GO_INTERP_COLOR_MODE__, jni_bool, (void**) &piInterpColorMode);
1047 * Do not triangulate if the interpolated color mode is set to 'on' and the polyline style is filled patch (5).
1048 * The quadrilateral facet decomposition function is used instead, if nPoints == 4,
1049 * for compatibility reasons, although triangulation could be used.
1051 if (interpColorMode && polylineStyle != 5)
1055 else if (nPoints > 3)
1057 /* Perform triangulation only if more than 3 points */
1063 Triangulator triangulator;
1069 for (int i = 0; i < nPoints; i++)
1071 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coords[0][0], &coords[0][1], &coords[0][2]);
1073 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1077 tmpValid &= DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1081 coords[0][0] = DecompositionUtils::getLog10Value(coords[0][0]);
1086 coords[0][1] = DecompositionUtils::getLog10Value(coords[0][1]);
1091 coords[0][2] = DecompositionUtils::getLog10Value(coords[0][2]);
1095 isValid &= tmpValid;
1102 triangulator.addPoint(coords[0][0], coords[0][1], coords[0][2]);
1111 triangulator.initialize();
1112 triangulator.triangulate();
1114 numTriangles = triangulator.getNumberTriangles();
1115 indices = triangulator.getIndices();
1117 for (int i = 0; i < numTriangles; i++)
1119 buffer[3 * i] = indices[3 * i];
1120 buffer[3 * i + 1] = indices[3 * i + 1];
1121 buffer[3 * i + 2] = indices[3 * i + 2];
1125 triangulator.clear();
1131 /* Do not triangulate: either the interpolation color mode is set to on or it is not and there are only 3 points. */
1133 /* 3 points: only one triangle output */
1136 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1137 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1138 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1140 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1141 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1142 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1148 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1149 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1150 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1151 isValid &= tmpValid;
1163 else if (nPoints >= 4)
1166 * 4 points: the quadrilateral facet decomposition algorithm is used.
1167 * If the Polyline has more than 4 points, we still output two triangles
1168 * corresponding to the first 4 points. This behaviour is kept for compatibility.
1169 * Possible correction: do not output indices if there are more than 4 points and
1170 * the interpolation color mode is set to on.
1172 int facetVertexIndices[4] = {0, 1, 2, 3};
1174 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coords[0][0], &coords[0][1], &coords[0][2]);
1175 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 1, &coords[1][0], &coords[1][1], &coords[1][2]);
1176 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 2, &coords[2][0], &coords[2][1], &coords[2][2]);
1177 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 3, &coords[3][0], &coords[3][1], &coords[3][2]);
1179 tmpValid = DecompositionUtils::isValid(coords[0][0], coords[0][1], coords[0][2]);
1180 tmpValid &= DecompositionUtils::isValid(coords[1][0], coords[1][1], coords[1][2]);
1181 tmpValid &= DecompositionUtils::isValid(coords[2][0], coords[2][1], coords[2][2]);
1182 tmpValid &= DecompositionUtils::isValid(coords[3][0], coords[3][1], coords[3][2]);
1188 tmpValid = DecompositionUtils::isLogValid(coords[0][0], coords[0][1], coords[0][2], logMask);
1189 tmpValid &= DecompositionUtils::isLogValid(coords[1][0], coords[1][1], coords[1][2], logMask);
1190 tmpValid &= DecompositionUtils::isLogValid(coords[2][0], coords[2][1], coords[2][2], logMask);
1191 tmpValid &= DecompositionUtils::isLogValid(coords[3][0], coords[3][1], coords[3][2], logMask);
1192 isValid &= tmpValid;
1197 DecompositionUtils::getDecomposedQuadTriangleIndices(coords, facetVertexIndices, buffer);
1207 int PolylineDecomposer::fillArrowTriangleIndices(int id, int* buffer, int bufferLength,
1208 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1211 int* piClosed = &closed;
1213 int currentValid = 0;
1216 int firstArrowVertex = 0;
1220 int numberValidIndices = 0;
1222 /* At least 2 points needed to form segments */
1228 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1230 /* If closed, an additional segment is present */
1237 nArrows = nPoints - 1;
1241 * Arrow head vertices are stored consecutively after all the line vertices.
1242 * Hence the offset to the first arrow vertex.
1244 firstArrowVertex = nPoints;
1246 for (int i = 0; i < nArrows; i++)
1248 /* Indices of the tip, left and right vertices */
1250 buffer[n] = firstArrowVertex + n;
1251 buffer[n + 1] = buffer[n] + 1;
1252 buffer[n + 2] = buffer[n] + 2;
1259 * Only bars are filled at the present moment, the curve is not.
1260 * See fillTriangleIndices for more information.
1262 int PolylineDecomposer::fillBarsDecompositionTriangleIndices(int id, int* buffer, int bufferLength,
1263 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift)
1265 double barWidth = 0.0;
1266 double* pdBarWidth = &barWidth;
1269 int triangleIndices[6];
1271 int numberValidIndices = 0;
1278 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1280 /* 0 indices if the bar width is invalid, as it is the same for all bars. */
1281 if (!DecompositionUtils::isValid(barWidth))
1287 * Gets the indices corresponding to a rectangle decomposed into 2 triangles.
1288 * All the bars are decomposed the same way.
1290 DecompositionUtils::getDecomposedRectangleTriangleIndices(triangleIndices);
1293 for (int i = 0; i < nPoints; i++)
1295 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1297 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1299 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1304 buffer[6 * offset] = 4 * i + triangleIndices[0];
1305 buffer[6 * offset + 1] = 4 * i + triangleIndices[1];
1306 buffer[6 * offset + 2] = 4 * i + triangleIndices[2];
1307 buffer[6 * offset + 3] = 4 * i + triangleIndices[3];
1308 buffer[6 * offset + 4] = 4 * i + triangleIndices[4];
1309 buffer[6 * offset + 5] = 4 * i + triangleIndices[5];
1311 numberValidIndices += 6;
1317 return numberValidIndices;
1320 int PolylineDecomposer::getWireIndicesSize(int id)
1323 int *piNPoints = &nPoints;
1324 int polylineStyle = 0;
1325 int* piPolylineStyle = &polylineStyle;
1328 int* piLineMode = &lineMode;
1331 int* piClosed = &closed;
1333 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1334 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1335 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1336 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1338 /* No segments if 0 points */
1345 if (polylineStyle == 1)
1347 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1350 else if (polylineStyle == 2)
1352 return getStairDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1354 /* Vertical segments plus segments */
1355 else if (polylineStyle == 3)
1357 return getVerticalLinesDecompositionSegmentIndicesSize(nPoints, lineMode);
1359 /* Segments with arrow heads */
1360 else if (polylineStyle == 4)
1362 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1365 else if (polylineStyle == 5)
1367 return getSegmentsDecompositionSegmentIndicesSize(nPoints, lineMode, closed);
1369 /* Vertical bars plus segments */
1370 else if (polylineStyle == 6)
1372 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1374 /* Horizontal bars plus segments */
1375 else if (polylineStyle == 7)
1377 return getBarsDecompositionSegmentIndicesSize(nPoints, lineMode);
1386 int PolylineDecomposer::getSegmentsDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1410 int PolylineDecomposer::getStairDecompositionSegmentIndicesSize(int nPoints, int lineMode, int closed)
1421 return 2 * nPoints + 1;
1425 return 2 * nPoints - 1;
1434 int PolylineDecomposer::getVerticalLinesDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1443 return 2 * (nPoints) + 2 * (nPoints - 1);
1447 return 2 * (nPoints);
1451 int PolylineDecomposer::getBarsDecompositionSegmentIndicesSize(int nPoints, int lineMode)
1460 return 2 * 4 * (nPoints) + 2 * (nPoints - 1);
1464 return 2 * 4 * (nPoints);
1468 int PolylineDecomposer::fillWireIndices(int id, int* buffer, int bufferLength, int logMask)
1470 double* coordinates = NULL;
1471 double* xshift = NULL;
1472 double* yshift = NULL;
1473 double* zshift = NULL;
1475 int polylineStyle = 0;
1476 int* piPolylineStyle = &polylineStyle;
1478 int* piNPoints = &nPoints;
1480 int* piClosed = &closed;
1482 int* piLineMode = &lineMode;
1484 getGraphicObjectProperty(id, __GO_POLYLINE_STYLE__, jni_int, (void**) &piPolylineStyle);
1486 getGraphicObjectProperty(id, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void**) &coordinates);
1487 getGraphicObjectProperty(id, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**) &piNPoints);
1488 getGraphicObjectProperty(id, __GO_DATA_MODEL_X_COORDINATES_SHIFT__, jni_double_vector, (void**) &xshift);
1489 getGraphicObjectProperty(id, __GO_DATA_MODEL_Y_COORDINATES_SHIFT__, jni_double_vector, (void**) &yshift);
1490 getGraphicObjectProperty(id, __GO_DATA_MODEL_Z_COORDINATES_SHIFT__, jni_double_vector, (void**) &zshift);
1492 getGraphicObjectProperty(id, __GO_LINE_MODE__, jni_bool, (void**) &piLineMode);
1493 getGraphicObjectProperty(id, __GO_CLOSED__, jni_bool, (void**) &piClosed);
1495 if (polylineStyle == 1)
1497 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1499 else if (polylineStyle == 2)
1501 return fillStairDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1503 else if (polylineStyle == 3)
1505 return fillVerticalLinesDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1507 else if (polylineStyle == 4)
1509 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1511 else if (polylineStyle == 5)
1513 return fillSegmentsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode, closed);
1515 else if (polylineStyle == 6)
1517 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1519 else if (polylineStyle == 7)
1521 return fillBarsDecompositionSegmentIndices(id, buffer, bufferLength, logMask, coordinates, nPoints, xshift, yshift, zshift, lineMode);
1527 int PolylineDecomposer::fillSegmentsDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1528 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1530 /* If less than 2 points, no segments */
1541 for (int i = 0; i < nPoints; i++)
1548 buffer[nPoints] = 0;
1551 return closed ? (nPoints + 1) : nPoints;
1554 int PolylineDecomposer::fillStairDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1555 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode, int closed)
1557 int currentValid = 0;
1558 int middleVertexValid = 0;
1562 int numberValidIndices = 0;
1564 /* If less than 2 points, no segments */
1575 for (int i = 0; i < 2 * nPoints - 1; i++)
1582 buffer[2 * nPoints - 1] = 2 * nPoints - 1;
1583 buffer[2 * nPoints] = 0;
1586 return closed ? (2 * nPoints + 1) : (2 * nPoints - 1);
1589 int PolylineDecomposer::fillVerticalLinesDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1590 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1595 int numberValidIndices = 0;
1602 /* Vertical lines */
1603 for (int i = 0; i < nPoints; i++)
1605 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1607 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1609 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1614 buffer[2 * offset] = 2 * i;
1615 buffer[2 * offset + 1] = 2 * i + 1;
1617 numberValidIndices += 2;
1628 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1630 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1634 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1637 for (int i = 0; i < nPoints - 1; i++)
1639 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i + 1, &coordsi[0], &coordsi[1], &coordsi[2]);
1641 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1645 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1648 if (currentValid && nextValid)
1650 buffer[2 * offset] = 2 * i + 1;
1651 buffer[2 * offset + 1] = 2 * (i + 1) + 1;
1653 numberValidIndices += 2;
1657 currentValid = nextValid;
1661 return numberValidIndices;
1665 int PolylineDecomposer::fillBarsDecompositionSegmentIndices(int id, int* buffer, int bufferLength,
1666 int logMask, double* coordinates, int nPoints, double* xshift, double* yshift, double* zshift, int lineMode)
1668 double barWidth = 0.0;
1669 double* pdBarWidth = &barWidth;
1672 int barWidthValid = 0;
1674 int numberValidIndices = 0;
1681 getGraphicObjectProperty(id, __GO_BAR_WIDTH__, jni_double, (void**) &pdBarWidth);
1683 barWidthValid = DecompositionUtils::isValid(barWidth);
1685 /* 0 bar segment indices if the bar width is invalid, as it is the same for all bars. */
1689 for (int i = 0; i < nPoints; i++)
1691 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i, &coordsi[0], &coordsi[1], &coordsi[2]);
1693 if (DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]))
1695 if (logMask && !DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask))
1700 buffer[8 * offset] = 4 * i;
1701 buffer[8 * offset + 1] = 4 * i + 1;
1702 buffer[8 * offset + 2] = 4 * i + 1;
1703 buffer[8 * offset + 3] = 4 * i + 2;
1704 buffer[8 * offset + 4] = 4 * i + 2;
1705 buffer[8 * offset + 5] = 4 * i + 3;
1706 buffer[8 * offset + 6] = 4 * i + 3;
1707 buffer[8 * offset + 7] = 4 * i;
1709 numberValidIndices += 8;
1725 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, 0, &coordsi[0], &coordsi[1], &coordsi[2]);
1727 currentValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1731 currentValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1734 for (int i = 0; i < nPoints - 1; i++)
1736 getShiftedPolylinePoint(coordinates, xshift, yshift, zshift, nPoints, i + 1, &coordsi[0], &coordsi[1], &coordsi[2]);
1738 nextValid = DecompositionUtils::isValid(coordsi[0], coordsi[1], coordsi[2]);
1742 nextValid &= DecompositionUtils::isLogValid(coordsi[0], coordsi[1], coordsi[2], logMask);
1745 if (currentValid && nextValid)
1747 buffer[8 * offset + 2 * loffset] = 4 * nPoints + i;
1748 buffer[8 * offset + 2 * loffset + 1] = 4 * nPoints + i + 1;
1750 numberValidIndices += 2;
1754 currentValid = nextValid;
1758 return numberValidIndices;
1761 void PolylineDecomposer::getShiftedPolylinePoint(double* coordinates, double* xshift, double* yshift, double* zshift, int nPoints, int index,
1762 double* x, double* y, double* z)
1764 *x = coordinates[index];
1768 *x += xshift[index];
1771 *y = coordinates[index + nPoints];
1775 *y += yshift[index];
1778 *z = coordinates[index + 2 * nPoints];
1782 *z += zshift[index];