1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2012 - DIGITEO - Manuel Juliachs
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 
16 #ifndef NGONGRIDDATA_DECOMPOSER_HXX
17 #define NGONGRIDDATA_DECOMPOSER_HXX
18 
19 #include <string>
20 
21 extern "C" {
22 #include <stdlib.h>
23 }
24 
25 /**
26  * NgonGridData decomposer class
27  * Determines the vertices and the segments indices to be rendered
28  * as a function of the decomposed NgonGridData object's properties.
29  *
30  * To do: being able to specify either per-facet or per-vertex colors at execution time.
31  *        Specifying per-facet colors and using flat shading at render time would reduce
32  *        the vertex and color data duplication made necessary by using smooth shading
33  *        when rendering flag-shaded facets (see the vertex and color data fill functions),
34  *        with only a few additional modifications to the aforementioned functions.
35  */
36 
37 class NgonGridDataDecomposer
38 {
39 
40 private :
41 
42     /** NgonGridData decomposer instance */
43     static NgonGridDataDecomposer* decomposer;
44 
45 protected :
46 
47     /**
48      * Fills a buffer with vertex data from a grid.
49      * @param[out] the buffer to fill.
50      * @param[in] the buffer length in number of elements.
51      * @param[in] the number of coordinates taken by one element in the buffer.
52      * @param[in] the byte mask specifying which coordinates are filled (1 for X, 2 for Y, 4 for Z).
53      * @param[in] the conversion scale factor to apply to data.
54      * @param[in] the conversion translation factor to apply to data.
55      * @param[in] the bit mask specifying whether logarithmic coordinates are used.
56      * @param[in] the grid x-coordinate array.
57      * @param[in] the grid y-coordinate array.
58      * @param[in] the grid z-coordinate array.
59      * @param[in] the grid's number of vertices along the x-axis.
60      * @param[in] the grid's number of vertices along the y-axis.
61      */
62     virtual void fillGridVertices(float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask,
63                                   double* x, double* y, double* z, int numX, int numY);
64 
65     /**
66      * Fills a buffer with color data from a grid.
67      * Colors are looked up in a color map, which is linearly mapped to the grid's normalized z values.
68      * @param[out] the buffer to fill.
69      * @param[in] the buffer length in number of elements.
70      * @param[in] the number of components taken by a color element (3 or 4).
71      * @param[in] a pointer to the colormap used.
72      * @param[in] the colormap's size.
73      * @param[in] the grid z-coordinate array.
74      * @param[in] the grid's number of vertices along the x-axis.
75      * @param[in] the grid's number of vertices along the y-axis.
76      */
77     void fillNormalizedZGridColors(float* buffer, int bufferLength, int elementsSize, double* colormap, int colormapSize,
78                                    double* z, int numX, int numY);
79 
80     /**
81      * Fills a buffer with color data from a grid.
82      * Colors are looked up in a color map, which is directly mapped to the grid's z values.
83      * @param[out] the buffer to fill.
84      * @param[in] the buffer length in number of elements.
85      * @param[in] the number of components taken by a color element (3 or 4).
86      * @param[in] a pointer to the colormap used.
87      * @param[in] the colormap's size.
88      * @param[in] the grid z-coordinate array.
89      * @param[in] the grid's number of vertices along the x-axis.
90      * @param[in] the grid's number of vertices along the y-axis.
91      */
92     void fillDirectGridColors(float* buffer, int bufferLength, int elementsSize, double* colormap, int colormapSize,
93                               double* z, int numX, int numY);
94 
95     /**
96      * Returns the coordinates of the (i,j) facet's four vertices, where (i,j) is the facet's
97      * lower-left corner. Vertices are output in the following order: (i,j), (i+1,j), (i+1,j+1) and (i,j+1).
98      * @param[in] the grid x-coordinate array.
99      * @param[in] the grid y-coordinate array.
100      * @param[in] the grid z-coordinate array.
101      * @param[in] the grid's number of vertices along the x-axis.
102      * @param[in] the grid's number of vertices along the y-axis.
103      * @param[in] the lower-left corner's x index.
104      * @param[in] the lower-left corner's y index.
105      * @param[out] the facet's vertices (4 (x,y,z) triplets).
106      */
107     void getFacetCoordinates(double* x, double* y, double* z, int numX, int numY, int i, int j,
108                              double vertices[4][3]);
109 
110     /**
111      * Returns the z-coordinate of the (i,j) grid point.
112      * It treats z as a 1-element array, hence all grid points have the same z-value.
113      * @param[in] the grid z-coordinate array.
114      * @param[in] the grid's number of points along the x-axis.
115      * @param[in] the grid's number of points along the y-axis.
116      * @param[in] the point's x index.
117      * @param[in] the point's y index.
118      * @return the (i,j) grid point's z-coordinate.
119      */
120     virtual double getZCoordinate(double* z, int numX, int numY, int i, int j);
121 
122     /**
123      * Returns the z-coordinate of the (i,j) grid point, taking
124      * into account logarithmic scaling.
125      * It treats z as a 1-element array, hence all grid points have the same z-value.
126      * @param[in] the grid z-coordinate array.
127      * @param[in] the grid's number of points along the x-axis.
128      * @param[in] the grid's number of points along the y-axis.
129      * @param[in] the point's x index.
130      * @param[in] the point's y index.
131      * @param[in] a flag specifying whether logarithmic scaling is used.
132      * @return the (i,j) grid point's z-coordinate.
133      */
134     virtual double getZCoordinate(double* z, int numX, int numY, int i, int j, int logUsed);
135 
136     /**
137      * Returns the value of the (i,j) grid point.
138      * @param[in] the grid value array.
139      * @param[in] the grid's number of points along the x-axis.
140      * @param[in] the grid's number of points along the y-axis.
141      * @param[in] the point's x index.
142      * @param[in] the point's y index.
143      * @return the (i,j) grid point's value.
144      */
145     virtual double getValue(double* values, int numX, int numY, int i, int j);
146 
147     /**
148      * Fills a buffer with triangle indices from a decomposed grid.
149      * @param[out] the buffer to fill.
150      * @param[in] the buffer length in number of elements.
151      * @param[in] the bit mask specifying whether logarithmic coordinates are used.
152      * @param[in] the grid x-coordinate array.
153      * @param[in] the grid y-coordinate array.
154      * @param[in] the grid z-coordinate array.
155      * @param[in] the grid value array.
156      * @param[in] a flag indicating whether grid values are defined per node (1) or per facet (0).
157      * @param[in] the grid's number of vertices along the x-axis.
158      * @param[in] the grid's number of vertices along the y-axis.
159      * @return the number of indices actually written.
160      */
161     int fillTriangleIndices(int* buffer, int bufferLength, int logMask, double* x, double* y, double* z, double* values, int perNodeValues,
162                             int numX, int numY);
163 
164     /**
165      * Decomposes facet (i,j) into triangles and outputs the resulting vertex indices, where (i,j) is
166      * the facet's lower-left corner. As N-gon grid objects are plane, it always decomposes facets
167      * exactly the same way. The output triangles' vertex indices are in counter-clockwise order.
168      * @param[in] the grid x-coordinate array.
169      * @param[in] the grid y-coordinate array.
170      * @param[in] the grid z-coordinate array.
171      * @param[in] the grid's number of vertices along the x-axis.
172      * @param[in] the grid's number of vertices along the y-axis.
173      * @param[in] the lower-left corner's x index.
174      * @param[in] the lower-left corner's y index.
175      * @param[in] the facet vertices' indices (4-element array: (i,j), (i+1,j), (i+1,j+1) and (i,j+1) indices).
176      * @param[out] the triangles' indices (6-element array: two consecutive triplets).
177      */
178     virtual void getFacetTriangles(double* x, double* y, double* z, int numX, int numY, int i, int j,
179                                    int* facetVertexIndices, int* triangleVertexIndices);
180 
181     /**
182      * Determines whether a facet is valid.
183      * The facet is identified by its lower left-corner (i,j). It requires a flag (computed beforehand)
184      * as an input which indicates whether the (i,j) to (i,j+1) edge is valid or not, and outputs
185      * another flag indicating whether the (i+1,j) to (i+1,j+1) edge is valid or not.
186      * @param[in] the grid z-coordinate array.
187      * @param[in] the grid value array.
188      * @param[in] a flag indicating whether grid values are defined per node (1) or per facet (0).
189      * @param[in] the grid's number of vertices along the x-axis.
190      * @param[in] the grid's number of vertices along the y-axis.
191      * @param[in] the lower-left corner's x index.
192      * @param[in] the lower-left corner's y index.
193      * @param[in] a flag specifying whether logarithmic coordinates are used.
194      * @param[in] a flag indicating whether the (i,j) to (i,j+1) edge is valid.
195      * @param[out] a pointer to the output flag indicating whether the (i+1,j) to (i+1,j+1) edge is valid.
196      * @return 1 if the facet is valid, 0 if it is not.
197      */
198     virtual int isFacetValid(double* z, double* values, int perNodeValues, int numX, int numY, int i, int j, int logUsed, int currentEdgeValid, int* nextEdgeValid);
199 
200     /**
201      * Determines whether the left edge of a facet is valid.
202      * The left edge is between the lower-left corner (i,j) and the
203      * upper-left corner (i,j+1). The edge's validity depends only
204      * on its endpoints' z coordinates.
205      * @param[in] the grid z-coordinate array.
206      * @param[in] the grid value array.
207      * @param[in] a flag indicating whether grid values are defined per node (1) or per facet (0).
208      * @param[in] the grid's number of vertices along the x-axis.
209      * @param[in] the grid's number of vertices along the y-axis.
210      * @param[in] the lower-left corner's x index.
211      * @param[in] the lower-left corner's y index.
212      * @param[in] a flag specifying whether logarithmic coordinates are used.
213      * @return 1 if the edge valid, 0 if it is not.
214      */
215     virtual int isFacetEdgeValid(double* z, double* values, int perNodeValues, int numX, int numY, int i, int j, int logUsed);
216 
217     /**
218      * Returns a 1D vertex index from its x and y indices.
219      * @param[in] the number of vertices along the x-axis.
220      * @param[in] the number of vertices along the y-axis.
221      * @param[in] the x index.
222      * @param[in] the y index.
223      * @return the 1D vertex index.
224      */
225     static int getPointIndex(int numX, int numY, int i, int j);
226 
227     /**
228      * Computes and returns the grid's minimum and maximum z values.
229      * @param[in] the grid z-coordinate array.
230      * @param[in] the grid's number of z values along the x-axis.
231      * @param[in] the grid's number of z values along the y-axis.
232      * @param[out] a pointer to the returned minimum z value.
233      * @param[out] a pointer to the returned maximum z value.
234      */
235     static void computeMinMaxZValues(double* z, int numX, int numY, double* zMin, double* zMax);
236 
237     /**
238      * Computes a facet's average z value.
239      * @param[in] the grid z-coordinate array.
240      * @param[in] the grid's number of vertices along the x-axis.
241      * @param[in] the grid's number of vertices along the y-axis.
242      * @param[in] the facet's lower-left corner x index.
243      * @param[in] the facet's lower-left corner y index.
244      * @return the facet's average z value.
245      */
246     static double computeFacetAverageZValue(double* z, int numX, int numY, int i, int j);
247 
248     /**
249      * Writes the color value of a facet's four vertices into a buffer.
250      * The color is constant across the whole facet, hence four identical
251      * color values are consecutively written.
252      * @param[out] the buffer which is written to.
253      * @param[in] the buffer offset of the first vertex's color.
254      * @param[in] the facet color (3 or 4-element array).
255      * @param[in] the number of components taken by a color element (3 or 4).
256      */
257     static void writeFacetColorToBuffer(float* buffer, int bufferOffset, float* color, int elementsSize, bool hasTransparency = false);
258 
259     /**
260      * Returns the index of a facet's first vertex (its lower-left corner).
261      * This index corresponds to the location of the facet's first vertex in an array whose elements
262      * are sets of four vertices, a set corresponding to a single grid facet, with shared vertices
263      * being duplicated. For facet (i,j), vertices are ordered as follows: (i,j), (i+1,j), (i,j+1), (i+1,j+1) .
264      * @param[in] the grid's number of vertices along the x-axis.
265      * @param[in] the grid's number of vertices along the y-axis.
266      * @param[in] the facet's lower-left corner x index.
267      * @param[in] the facet's lower-left corner y index.
268      * @return the index of the facet's first vertex.
269      */
270     static int getFirstVertexIndex(int numX, int numY, int i, int j);
271 
272 public :
273 
274     /**
275      * Returns the class' single instance.
276      * @return the class instance
277      */
get(void)278     static NgonGridDataDecomposer* get(void)
279     {
280         if (decomposer == NULL)
281         {
282             decomposer = new NgonGridDataDecomposer();
283         }
284 
285         return decomposer;
286     }
287 
288     /**
289      * Returns the number of data elements for the given object.
290      * @param[in] the given object id.
291      * @return the number of data elements.
292      */
293     static int getDataSize(int id);
294 
295     /**
296      * Fills the given buffer with vertex data from the given object.
297      * @param[in] the id of the given object.
298      * @param[out] the buffer to fill.
299      * @param[in] the buffer length in number of elements.
300      * @param[in] the number of coordinates taken by one element in the buffer.
301      * @param[in] the byte mask specifying which coordinates are filled (1 for X, 2 for Y, 4 for Z).
302      * @param[in] the conversion scale factor to apply to data.
303      * @param[in] the conversion translation factor to apply to data.
304      * @param[in] the bit mask specifying whether logarithmic coordinates are used.
305      */
306     static void fillVertices(int id, float* buffer, int bufferLength, int elementsSize, int coordinateMask, double* scale, double* translation, int logMask);
307 
308     /**
309      * Returns the number of indices for the given object.
310      * @param[in] the given object id.
311      * @return the object's number of indices.
312      */
313     static int getIndicesSize(int id);
314 
315     /**
316      * Fills the given buffer with indices data of the given object.
317      * @param[in] the given object id.
318      * @param[out] the buffer to fill.
319      * @param[in] the buffer length.
320      * @param[in] the bit mask specifying whether logarithmic coordinates are used.
321      * @return the number of indices actually written.
322      */
323     static int fillIndices(int id, int* buffer, int bufferLength, int logMask);
324 };
325 
326 /**
327  * Specifies whether per-vertex or per-facet colors are used (0 corresponds to
328  * per-facet color values, any other value to per-vertex colors) for all the
329  * Ngon grid-derived objects, by commenting out the related code blocks.
330  * Temporary since this should be specified as a parameter of the vertex,
331  * index and color fill functions, independently for each Ngon grid-derived
332  * object type.
333  */
334 #define PER_VERTEX_VALUES    0
335 
336 /**
337  * The default z-coordinate value for plane grid objects
338  * (Grayplot and Matplot) when the logarithmic scale is used.
339  * It is added to their z-shift value to obtain the actual z-coordinate.
340  */
341 #define DEFAULT_LOG_COORD_Z 1.0
342 
343 #endif
344