Adds possibility to color marks in scatter plots
[scilab.git] / scilab / modules / graphic_objects / src / cpp / NgonPolylineData.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010 - DIGITEO - Manuel Juliachs
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 #include <iostream>
14
15 #include "NgonPolylineData.hxx"
16 #include "DataProperties.hxx"
17
18 extern "C" {
19 #include "BOOL.h"
20
21 #include <string.h>
22
23 #include "graphicObjectProperties.h"
24 }
25
26 NgonPolylineData::NgonPolylineData(void)
27 {
28     xShift = NULL;
29     yShift = NULL;
30     zShift = NULL;
31
32     xShiftSet = 0;
33     yShiftSet = 0;
34     zShiftSet = 0;
35
36     coordinatesShift = NULL;
37
38     zCoordinatesSet = 0;
39
40     display_function_data = NULL;
41     display_function_data_size = 0;
42
43     colors = NULL;
44 }
45
46 NgonPolylineData::~NgonPolylineData(void)
47 {
48     if (xShiftSet)
49     {
50         delete [] xShift;
51     }
52
53     if (yShiftSet)
54     {
55         delete [] yShift;
56     }
57
58     if (zShiftSet)
59     {
60         delete [] zShift;
61     }
62
63     if (display_function_data)
64     {
65         delete[] display_function_data;
66     }
67
68     if (colors)
69     {
70         delete [] colors;
71     }
72 }
73
74 int NgonPolylineData::getPropertyFromName(int propertyName)
75 {
76     switch (propertyName)
77     {
78         case __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__ :
79             return NUM_ELEMENTS_ARRAY;
80         case __GO_DATA_MODEL_X_COORDINATES_SHIFT__ :
81             return X_COORDINATES_SHIFT;
82         case __GO_DATA_MODEL_Y_COORDINATES_SHIFT__ :
83             return Y_COORDINATES_SHIFT;
84         case __GO_DATA_MODEL_Z_COORDINATES_SHIFT__ :
85             return Z_COORDINATES_SHIFT;
86         case __GO_DATA_MODEL_NUM_ELEMENTS__ :
87             return NUM_ELEMENTS;
88         case __GO_DATA_MODEL_X_COORDINATES_SHIFT_SET__ :
89             return X_COORDINATES_SHIFT_SET;
90         case __GO_DATA_MODEL_Y_COORDINATES_SHIFT_SET__ :
91             return Y_COORDINATES_SHIFT_SET;
92         case __GO_DATA_MODEL_Z_COORDINATES_SHIFT_SET__ :
93             return Z_COORDINATES_SHIFT_SET;
94         case __GO_DATA_MODEL_Z_COORDINATES_SET__ :
95             return Z_COORDINATES_SET;
96         case __GO_DATA_MODEL_DISPLAY_FUNCTION__ :
97             return DISPLAY_FUNCTION_DATA;
98         case __GO_DATA_MODEL_DISPLAY_FUNCTION_SIZE__ :
99             return DISPLAY_FUNCTION_DATA_SIZE;
100         case __GO_DATA_MODEL_COLORS__ :
101             return COLORS;
102         case __GO_DATA_MODEL_NUM_COLORS__ :
103             return NUM_COLORS;
104         default :
105             return NgonGeneralData::getPropertyFromName(propertyName);
106     }
107
108 }
109
110
111 int NgonPolylineData::setDataProperty(int property, void const* value, int numElements)
112 {
113     switch (property)
114     {
115         case NUM_ELEMENTS_ARRAY :
116             return setNumElementsArray((int const*) value);
117         case X_COORDINATES_SHIFT :
118             return setXCoordinatesShift((double const*) value, numElements);
119         case Y_COORDINATES_SHIFT :
120             return setYCoordinatesShift((double const*) value, numElements);
121         case Z_COORDINATES_SHIFT :
122             return setZCoordinatesShift((double const*) value, numElements);
123         case X_COORDINATES_SHIFT_SET :
124             setXCoordinatesShiftSet(*((int const*) value));
125             break;
126         case Y_COORDINATES_SHIFT_SET :
127             setYCoordinatesShiftSet(*((int const*) value));
128             break;
129         case Z_COORDINATES_SHIFT_SET :
130             setZCoordinatesShiftSet(*((int const*) value));
131             break;
132         case Z_COORDINATES_SET :
133             setZCoordinatesSet(*((int const*) value));
134             break;
135         case DISPLAY_FUNCTION_DATA :
136             setDisplayFunctionData((int const*) value, numElements);
137             break;
138         case COLORS :
139             setColors((int const*) value, numElements);
140             break;
141         default :
142             return NgonGeneralData::setDataProperty(property, value, numElements);
143     }
144 }
145
146 void NgonPolylineData::getDataProperty(int property, void **_pvData)
147 {
148     switch (property)
149     {
150         case X_COORDINATES_SHIFT :
151             *_pvData = getXCoordinatesShift();
152             break;
153         case Y_COORDINATES_SHIFT :
154             *_pvData = getYCoordinatesShift();
155             break;
156         case Z_COORDINATES_SHIFT :
157             *_pvData = getZCoordinatesShift();
158             break;
159         case NUM_ELEMENTS :
160             ((int *) *_pvData)[0] = getNumElements();
161             break;
162         case X_COORDINATES_SHIFT_SET :
163             ((int *) *_pvData)[0] = getXCoordinatesShiftSet();
164             break;
165         case Y_COORDINATES_SHIFT_SET :
166             ((int *) *_pvData)[0] = getYCoordinatesShiftSet();
167             break;
168         case Z_COORDINATES_SHIFT_SET :
169             ((int *) *_pvData)[0] = getZCoordinatesShiftSet();
170             break;
171         case Z_COORDINATES_SET :
172             ((int *) *_pvData)[0] = getZCoordinatesSet();
173             break;
174         case DISPLAY_FUNCTION_DATA :
175             *_pvData = getDisplayFunctionData();
176             break;
177         case DISPLAY_FUNCTION_DATA_SIZE :
178             ((int *) *_pvData)[0] = getDisplayFunctionDataSize();
179             break;
180         case COLORS :
181             *_pvData = getColors();
182             break;
183         case NUM_COLORS :
184             ((int *) *_pvData)[0] = getNumColors();
185             break;
186         default :
187             NgonGeneralData::getDataProperty(property, _pvData);
188     }
189 }
190
191 int NgonPolylineData::getNumElements(void)
192 {
193     return numVerticesPerGon;
194 }
195
196 void NgonPolylineData::setZCoordinatesSet(int zCoordinatesSet)
197 {
198     this->zCoordinatesSet = zCoordinatesSet;
199 }
200
201 int NgonPolylineData::getZCoordinatesSet(void)
202 {
203     return this->zCoordinatesSet;
204 }
205
206 double* NgonPolylineData::getXCoordinatesShift(void)
207 {
208     return xShift;
209 }
210
211 int NgonPolylineData::setXCoordinatesShift(double const* data, int numElements)
212 {
213     if (xShiftSet == 0)
214     {
215
216         try
217         {
218             xShift = new double[numVerticesPerGon];
219         }
220         catch (const std::exception& e)
221         {
222             e.what();
223             return 0;
224         }
225
226         xShiftSet = 1;
227     }
228
229     for (int i = 0; i < numVerticesPerGon; i++)
230     {
231         xShift[i] = data[i];
232     }
233
234     return 1;
235 }
236
237 double* NgonPolylineData::getYCoordinatesShift()
238 {
239     return yShift;
240 }
241
242 int NgonPolylineData::setYCoordinatesShift(double const* data, int numElements)
243 {
244     if (yShiftSet == 0)
245     {
246
247         try
248         {
249             yShift = new double[numVerticesPerGon];
250         }
251         catch (const std::exception& e)
252         {
253             e.what();
254             return 0;
255         }
256
257         yShiftSet = 1;
258     }
259
260     for (int i = 0; i < numVerticesPerGon; i++)
261     {
262         yShift[i] = data[i];
263     }
264
265     return 1;
266 }
267
268 double* NgonPolylineData::getZCoordinatesShift()
269 {
270     return zShift;
271 }
272
273 int NgonPolylineData::getXCoordinatesShiftSet(void)
274 {
275     return xShiftSet;
276 }
277
278 void NgonPolylineData::setXCoordinatesShiftSet(int xShiftSet)
279 {
280     if (xShiftSet == 0 && this->xShiftSet == 1)
281     {
282         delete [] xShift;
283         xShift = NULL;
284     }
285
286     this->xShiftSet = xShiftSet;
287 }
288
289 int NgonPolylineData::getYCoordinatesShiftSet(void)
290 {
291     return yShiftSet;
292 }
293
294 void NgonPolylineData::setYCoordinatesShiftSet(int yShiftSet)
295 {
296     if (yShiftSet == 0 && this->yShiftSet == 1)
297     {
298         delete [] yShift;
299         yShift = NULL;
300     }
301
302     this->yShiftSet = yShiftSet;
303 }
304
305 int NgonPolylineData::getZCoordinatesShiftSet(void)
306 {
307     return zShiftSet;
308 }
309
310 void NgonPolylineData::setZCoordinatesShiftSet(int zShiftSet)
311 {
312     if (zShiftSet == 0 && this->zShiftSet == 1)
313     {
314         delete [] zShift;
315         zShift = NULL;
316     }
317
318     this->zShiftSet = zShiftSet;
319 }
320
321 int NgonPolylineData::setZCoordinatesShift(double const* data, int numElements)
322 {
323     if (zShiftSet == 0)
324     {
325
326         try
327         {
328             zShift = new double[numVerticesPerGon];
329         }
330         catch (const std::exception& e)
331         {
332             e.what();
333             return 0;
334         }
335
336         zShiftSet = 1;
337     }
338
339     for (int i = 0; i < numVerticesPerGon; i++)
340     {
341         zShift[i] = data[i];
342     }
343
344     return 1;
345 }
346
347 int NgonPolylineData::setNumElementsArray(int const* numElementsArray)
348 {
349     int newNumElements = 0;
350     int previousNumElements = 0;
351     int result = 1;
352
353     if (numElementsArray[0] != 1)
354     {
355         return 0;
356     }
357
358     newNumElements = numElementsArray[0] * numElementsArray[1];
359     previousNumElements = numGons * numVerticesPerGon;
360
361     if (newNumElements == 0 && previousNumElements > 0)
362     {
363         numVerticesPerGon = 0;
364
365         deleteCoordinatesArrays();
366
367         return 1;
368     }
369
370     if (numGons * numVerticesPerGon != newNumElements)
371     {
372         double* newCoordinates = NULL;
373         double* xShiftNew = NULL;
374         double* yShiftNew = NULL;
375         double* zShiftNew = NULL;
376
377         result = 1;
378
379         try
380         {
381             newCoordinates = new double[3 * newNumElements];
382         }
383         catch (const std::exception& e)
384         {
385             e.what();
386             return 0;
387         }
388
389         if (xShiftSet)
390         {
391             try
392             {
393                 xShiftNew = new double[newNumElements];
394             }
395             catch (const std::exception& e)
396             {
397                 e.what();
398                 result = 0;
399             }
400         }
401
402         if (yShiftSet)
403         {
404             try
405             {
406                 yShiftNew = new double[newNumElements];
407             }
408             catch (const std::exception& e)
409             {
410                 e.what();
411                 result = 0;
412             }
413         }
414
415         if (zShiftSet)
416         {
417             try
418             {
419                 zShiftNew = new double[newNumElements];
420             }
421             catch (const std::exception& e)
422             {
423                 e.what();
424                 result = 0;
425             }
426         }
427
428         if (result)
429         {
430             if (numGons * numVerticesPerGon > 0)
431             {
432                 delete [] coordinates;
433             }
434
435             /*
436              * Initialize the new coordinates' z values to 0 in case
437              * they are not set afterwards.
438              */
439             for (int i = 0; i < newNumElements; i++)
440             {
441                 newCoordinates[2 * newNumElements + i] = 0.0;
442             }
443
444             coordinates = newCoordinates;
445
446             if (xShiftSet)
447             {
448                 copyShiftCoordinatesArray(xShiftNew, xShift, newNumElements);
449                 delete [] xShift;
450                 xShift = xShiftNew;
451             }
452
453             if (yShiftSet)
454             {
455                 copyShiftCoordinatesArray(yShiftNew, yShift, newNumElements);
456                 delete [] yShift;
457                 yShift = yShiftNew;
458             }
459
460             if (zShiftSet)
461             {
462                 copyShiftCoordinatesArray(zShiftNew, zShift, newNumElements);
463                 delete [] zShift;
464                 zShift = zShiftNew;
465             }
466
467             numGons = numElementsArray[0];
468             numVerticesPerGon = numElementsArray[1];
469         }
470         else
471         {
472             /* Delete the temporary arrays and don't set anything */
473             if (newCoordinates != NULL)
474             {
475                 delete [] newCoordinates;
476             }
477
478             if (xShiftNew != NULL)
479             {
480                 delete [] xShiftNew;
481             }
482
483             if (yShiftNew != NULL)
484             {
485                 delete [] yShiftNew;
486             }
487
488             if (zShiftNew != NULL)
489             {
490                 delete [] zShiftNew;
491             }
492
493         }
494
495     }
496
497     return result;
498 }
499
500 int NgonPolylineData::getNumColors(void)
501 {
502     return numColors;
503 }
504
505 int* NgonPolylineData::getColors(void)
506 {
507     return colors;
508 }
509
510 int NgonPolylineData::setColors(int const* newColors, int numElements)
511 {
512     int * _newColors = 0;
513
514     if (numElements == 0)
515     {
516         if (colors)
517         {
518             delete[] colors;
519         }
520         colors = NULL;
521         numColors = 0;
522
523         return 1;
524     }
525
526     try
527     {
528         _newColors = new int[numElements];
529     }
530     catch (const std::exception& e)
531     {
532         e.what();
533         return 0;
534     }
535
536     memcpy(_newColors, newColors, numElements * sizeof(int));
537     if (colors)
538     {
539         delete[] colors;
540     }
541
542     colors = _newColors;
543     numColors = numElements;
544
545     return 1;
546 }
547
548 void NgonPolylineData::copyShiftCoordinatesArray(double * newShift, double const* oldShift, int numElementsNew)
549 {
550     int numElementsCopied = 0;
551
552     if (numElementsNew < numVerticesPerGon)
553     {
554         numElementsCopied = numElementsNew;
555     }
556     else
557     {
558         numElementsCopied = numVerticesPerGon;
559     }
560
561     for (int i = 0; i < numElementsCopied; i++)
562     {
563         newShift[i] = oldShift[i];
564     }
565
566     for (int i = numElementsCopied; i < numElementsNew; i++)
567     {
568         newShift[i] = 0.0;
569     }
570 }
571
572 void NgonPolylineData::deleteCoordinatesArrays(void)
573 {
574     if (coordinates != NULL)
575     {
576         delete [] coordinates;
577         coordinates = NULL;
578     }
579
580     if (xShiftSet)
581     {
582         delete [] xShift;
583         xShift = NULL;
584         xShiftSet = 0;
585     }
586
587     if (yShiftSet)
588     {
589         delete [] yShift;
590         yShift = NULL;
591         yShiftSet = 0;
592     }
593
594     if (zShiftSet)
595     {
596         delete [] zShift;
597         zShift = NULL;
598         zShiftSet = 0;
599     }
600 }
601
602 int* NgonPolylineData::getDisplayFunctionData()
603 {
604     return display_function_data;
605 }
606
607 int NgonPolylineData::getDisplayFunctionDataSize()
608 {
609     return display_function_data_size;
610 }
611
612 int NgonPolylineData::setDisplayFunctionData(int const* data, int numElements)
613 {
614     if (display_function_data != NULL)
615     {
616         delete[] display_function_data;
617         display_function_data = NULL;
618     }
619
620     try
621     {
622         display_function_data_size = numElements;
623         display_function_data = new int[numElements];
624     }
625     catch (const std::exception& e)
626     {
627         e.what();
628         return 0;
629     }
630
631     memcpy(display_function_data, data, display_function_data_size * sizeof(int));
632     return 1;
633 }