Fix memleaks and slightly improve perfs
[scilab.git] / scilab / modules / graphics / src / c / BuildObjects.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2001-2002 - INRIA - Mathieu Philippe
4  * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
5  * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
6  * Copyright (C) 2005 - INRIA - Jean-Baptiste Silvy
7  * Copyright (C) 2007 - INRIA - Vincent Couvert
8  * Copyright (C) 2010 - DIGITEO - Bruno JOFRET
9  * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
10  *
11  * This file must be used under the terms of the CeCILL.
12  * This source file is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution.  The terms
14  * are also available at
15  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
16  *
17  */
18
19 /*------------------------------------------------------------------------
20  *    Graphic library
21  *    newGraph Library header
22  *    Comment:
23  *    This file contains all functions used to BUILD new objects :
24  - allocating memory
25  - setting default value
26  - binding the newly created object tyo the entire existing hierarchy
27  --------------------------------------------------------------------------*/
28 #include <string.h>
29 #include <stdio.h>
30
31 #include "BuildObjects.h"
32 #include "GetProperty.h"
33 #include "InitObjects.h"
34 #include "DestroyObjects.h"
35 #include "SetProperty.h"
36 #include "CloneObjects.h"
37 #include "StringMatrix.h"
38 #include "Scierror.h"
39 #include "CurrentFigure.h"
40 #include "FigureList.h"
41 #include "localization.h"
42 #include "Interaction.h"
43 #include "get_ticks_utils.h"
44 #include "HandleManagement.h"
45 #include "loadTextRenderingAPI.h"
46
47 #include "MALLOC.h"             /* MALLOC */
48 #include "Scierror.h"
49
50 #include "Format.h"             // computeDefaultTicsLabels
51
52 #include "createGraphicObject.h"
53 #include "deleteGraphicObject.h"
54 #include "returnType.h"
55 #include "getGraphicObjectProperty.h"
56 #include "setGraphicObjectProperty.h"
57 #include "graphicObjectProperties.h"
58 #include "CurrentFigure.h"
59 #include "CurrentSubwin.h"
60 #include "CurrentObject.h"
61 #include "FigureModel.h"
62 #include "AxesModel.h"
63
64 /**
65  * If a current figure exists : return it
66  * Otherwise create a new one.
67  *
68  * This method also alocate an axe object.
69  *
70  * After this call: the current figure the current axes and the current subwin
71  * are set to the appropriate values.
72  *
73  * @return a reference to the current figure.
74  */
75 GRAPHICS_IMPEXP char * createNewFigureWithAxes()
76 {
77     int iID = 0;
78     char *pFigureUID = NULL;
79     int* axesSize = NULL;
80
81     pFigureUID = cloneGraphicObject(getFigureModel());
82
83     /*
84      * Clone the default menus
85      */
86     cloneMenus((char*)getFigureModel(), pFigureUID);
87
88     setGraphicObjectProperty(pFigureUID, __GO_ID__, &iID, jni_int, 1);
89
90     /*
91      * Clone the default axes
92      */
93     cloneAxesModel(pFigureUID);
94     setCurrentFigure(pFigureUID);
95     /*
96      * Force axes size after window creation ( Java )
97      */
98     getGraphicObjectProperty(getFigureModel(), __GO_AXES_SIZE__, jni_int_vector, (void **)&axesSize);
99     setGraphicObjectProperty(pFigureUID, __GO_AXES_SIZE__, axesSize, jni_int_vector, 2);
100
101     // return the reference to the current figure
102     releaseGraphicObjectProperty(__GO_PARENT__, pFigureUID, jni_string, 1);
103     return (char*)getCurrentFigure();
104 }
105
106 /**
107  * Clone a new Axes object using the Axes model which is then
108  * attached to the newly created Figure.
109  *
110  * After this call: tthe current axes and the current subwin are set to the
111  * appropriate values.
112  */
113 GRAPHICS_IMPEXP void cloneAxesModel(char const* pstFigureUID)
114 {
115     char *pAxesUID = cloneGraphicObject(getAxesModel());
116
117     /* Clone the Axes model's labels and attach them to the newly created Axes */
118     ConstructLabel(pAxesUID, "", 1);
119     ConstructLabel(pAxesUID, "", 2);
120     ConstructLabel(pAxesUID, "", 3);
121     ConstructLabel(pAxesUID, "", 4);
122
123     /* Sets the parent-child relationship within the MVC */
124     setGraphicObjectRelationship(pstFigureUID, pAxesUID);
125
126     /* Sets the newly created Axes as the Figure's current selected child */
127     setGraphicObjectProperty(pstFigureUID, __GO_SELECTED_CHILD__, pAxesUID, jni_string, 1);
128
129     // Set new axes as default too.
130     setCurrentObject(pAxesUID);
131     setCurrentSubWin(pAxesUID);
132
133     releaseGraphicObjectProperty(__GO_PARENT__, pAxesUID, jni_string, 1);
134 }
135
136 GRAPHICS_IMPEXP void cloneMenus(char * pModelUID, char * pCloneUID)
137 {
138     int iNbChildren = 0;
139     int *piNbChildren = &iNbChildren;
140     int iChild = 0;
141     char *pChildUID = NULL;
142     char **pChildren = NULL;
143     int iChildType = -1;
144     int *piChildType = &iChildType;
145
146     getGraphicObjectProperty(pModelUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&piNbChildren);
147     getGraphicObjectProperty(pModelUID, __GO_CHILDREN__, jni_string_vector, (void **)&pChildren);
148     for (iChild = iNbChildren - 1; iChild >= 0; iChild--)
149     {
150         getGraphicObjectProperty(pChildren[iChild], __GO_TYPE__, jni_int, (void **)&piChildType);
151         if (iChildType == __GO_UIMENU__)
152         {
153             pChildUID = cloneGraphicObject(pChildren[iChild]);
154
155             setGraphicObjectRelationship(pCloneUID, pChildUID);
156             cloneMenus(pChildren[iChild], pChildUID);
157
158             releaseGraphicObjectProperty(__GO_PARENT__, pChildUID, jni_string, 1);
159         }
160     }
161     releaseGraphicObjectProperty(__GO_CHILDREN__, pChildren, jni_string_vector, iNbChildren);
162 }
163
164 /**
165  * If a current subwin exists: return it
166  * Otherwise create a new figure with JoGLView.
167  **/
168 GRAPHICS_IMPEXP char const* getOrCreateDefaultSubwin(void)
169 {
170     char const* pSubWinUID = getCurrentSubWin();
171
172     if (pSubWinUID == NULL)
173     {
174         createNewFigureWithAxes();
175         // the current figure,
176         pSubWinUID = getCurrentSubWin();
177     }
178
179     return pSubWinUID;
180 }
181
182 /*-----------------------------------------------------------------------------*/
183
184 /**ConstructSubWin
185  * This function creates the Subwindow (the Axes) and the elementary structures.
186  * The update of color properties (foreground, background, etc.)
187  * according to the assigned parent Figure's colormap is not implemented yet.
188  * To be implemented.
189  *
190  * @return a reference to the current object (will be invalidated on current object modification)
191  */
192 char const* ConstructSubWin(char const* pparentfigureUID)
193 {
194     int parentType = -1;
195     int *piParentType = &parentType;
196     char *pCloneUID = NULL;
197     char const* paxesmdlUID = getAxesModel();
198
199     getGraphicObjectProperty(pparentfigureUID, __GO_TYPE__, jni_int, (void**) &piParentType);
200
201     if (parentType != __GO_FIGURE__)
202     {
203         Scierror(999, _("The parent has to be a FIGURE\n"));
204         return (char *)NULL;
205     }
206
207     pCloneUID = cloneGraphicObject(paxesmdlUID);
208
209     /* Clone the Axes model's labels and attach them to the newly created Axes */
210     ConstructLabel(pCloneUID, "", 1);
211     ConstructLabel(pCloneUID, "", 2);
212     ConstructLabel(pCloneUID, "", 3);
213     ConstructLabel(pCloneUID, "", 4);
214
215     setGraphicObjectRelationship(pparentfigureUID, pCloneUID);
216
217     setCurrentObject(pCloneUID);
218     sciSetSelectedSubWin(pCloneUID);
219     setCurrentSubWin(pCloneUID);
220
221     releaseGraphicObjectProperty(__GO_PARENT__, pCloneUID, jni_string, 1);
222
223     return getCurrentObject();
224 }
225
226 /**
227  * Creates a new text object. However the object is not added in the handle list.
228  * Its graphic and font contexts are initialized.
229  * This function is to be used with objects including a text object.
230  */
231 char * allocateText(char * pparentsubwinUID,
232                     char * * text,
233                     int nbRow,
234                     int nbCol,
235                     double x,
236                     double y,
237                     BOOL autoSize,
238                     double userSize[2],
239                     int centerPos, int *foreground, int *background, BOOL isboxed, BOOL isline, BOOL isfilled, sciTextAlignment align)
240 {
241     char * pobjUID = NULL;
242     int textDimensions[2];
243     int visible = 0;
244     int *piVisible = &visible;
245     int clipRegionSet;
246     int *piClipRegionSet = &clipRegionSet;
247     int clipState = 0;
248     int *piClipState = &clipState;
249
250     double *clipRegion = NULL;
251     double position[3];
252     double setUserSize[2];
253
254     pobjUID = (char *)createGraphicObject(__GO_TEXT__);
255
256     /* Required to initialize the default contour properties */
257     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
258
259     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
260     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, piVisible, jni_bool, 1);
261
262     /* Clipping: to be checked for consistency */
263     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
264     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
265     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
266
267     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
268     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, piClipRegionSet, jni_bool, 1);
269
270     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
271     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, piClipState, jni_int, 1);
272
273     /* Check if we should load LaTex / MathML Java libraries */
274     loadTextRenderingAPI(text, nbRow, nbCol);
275
276     /* Allocates the String array */
277     textDimensions[0] = nbRow;
278     textDimensions[1] = nbCol;
279
280     setGraphicObjectProperty(pobjUID, __GO_TEXT_ARRAY_DIMENSIONS__, textDimensions, jni_int_vector, 2);
281
282     setGraphicObjectProperty(pobjUID, __GO_TEXT_STRINGS__, text, jni_string_vector, nbRow * nbCol);
283
284     position[0] = x;
285     position[1] = y;
286     position[2] = 0.0;
287
288     setGraphicObjectProperty(pobjUID, __GO_POSITION__, position, jni_double_vector, 3);
289
290     setGraphicObjectProperty(pobjUID, __GO_TEXT_BOX_MODE__, &centerPos, jni_int, 1);
291     setGraphicObjectProperty(pobjUID, __GO_AUTO_DIMENSIONING__, &autoSize, jni_bool, 1);
292
293     /* userSize must be specified if the size is given by the user */
294     /* or the user specified a rectangle */
295     if (!autoSize || centerPos)
296     {
297         setUserSize[0] = userSize[0];
298         setUserSize[1] = userSize[1];
299     }
300     else
301     {
302         setUserSize[0] = 0.0;
303         setUserSize[1] = 0.0;
304     }
305
306     setGraphicObjectProperty(pobjUID, __GO_TEXT_BOX__, setUserSize, jni_double_vector, 2);
307
308     /* Required to get the correct MVC value from the sciTextAlignment enum */
309     align = align - 1;
310
311     /* Set alignment to left if its value is incorrect */
312     if (align < 0 || align > 2)
313     {
314         align = 0;
315     }
316
317     setGraphicObjectProperty(pobjUID, __GO_ALIGNMENT__, &align, jni_int, 1);
318
319     cloneGraphicContext(pparentsubwinUID, pobjUID);
320
321     cloneFontContext(pparentsubwinUID, pobjUID);
322
323     setGraphicObjectProperty(pobjUID, __GO_BOX__, &isboxed, jni_bool, 1);
324     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
325     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
326
327     if (foreground != NULL)
328     {
329         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
330     }
331
332     if (background != NULL)
333     {
334         setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, foreground, jni_int, 1);
335     }
336
337     /* Parent reset to the null object */
338     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
339
340     return pobjUID;
341 }
342
343 /**ConstructText
344  * This function creates the parents window (manager) and the elementaries structures
345  * @param  char *pparentsubwinUID : parent subwin UID
346  * @param  char * text[] : intial text matrix string.
347  * @param  int nbCol : the number column of the text
348  * @param  int nbRow : the number of row of the text
349  * @return  : object UID if ok , NULL if not
350  */
351 char * ConstructText(char * pparentsubwinUID, char **text, int nbRow, int nbCol, double x,
352                      double y, BOOL autoSize, double userSize[2], BOOL centerPos, int *foreground, int *background,
353                      BOOL isboxed, BOOL isline, BOOL isfilled, sciTextAlignment align)
354 {
355     int parentType = -1;
356     int *piParentType = &parentType;
357     char *pobjUID = NULL;
358
359     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
360
361     if (parentType != __GO_AXES__)
362     {
363         Scierror(999, _("The parent has to be a SUBWIN\n"));
364         return (char *)NULL;
365     }
366
367     pobjUID = allocateText(pparentsubwinUID, text, nbRow, nbCol, x, y,
368                            autoSize, userSize, centerPos, foreground, background, isboxed, isline, isfilled, align);
369
370     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
371     setCurrentObject(pobjUID);
372     releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
373
374     return (char*)getCurrentObject();
375 }
376
377 /**ConstructLegend
378  * This function creates a Legend structure
379  * @param  char *pparentsubwinUID : parent subwin UID
380  * @param  char ** text : initial text matrix string array
381  * @param long long tabofhandles[] : the array of polyline handles
382  * @param int nblegends : the number of legend items
383  * @return : object UID if ok , NULL if not
384  */
385 char * ConstructLegend(char * pparentsubwinUID, char **text, long long tabofhandles[], int nblegends)
386 {
387     char *pobjUID = NULL;
388
389     int i = 0;
390     int iLegendPresent = 0;
391     int *piLegendPresent = &iLegendPresent;
392     int iVisible = 0;
393     int *piVisible = &iVisible;
394     int textDimensions[2];
395     int fillMode = 0;
396     int legendLocation = 0;
397
398     int clipRegionSet = 0;
399     int clipState = 0;
400
401     double *clipRegion = NULL;
402     double position[2];
403
404     char **lineIDS = NULL;
405     int parentType = -1;
406     int *piParentType = &parentType;
407
408     /* Check beforehand whether a Legend object is already present */
409     getGraphicObjectProperty(pparentsubwinUID, __GO_HAS_LEGEND_CHILD__, jni_bool, (void **)&piLegendPresent);
410
411     if (iLegendPresent)
412     {
413         /* Delete it (one Legend object allowed at most) */
414         char *legendChildID;
415
416         getGraphicObjectProperty(pparentsubwinUID, __GO_LEGEND_CHILD__, jni_string, (void **)&legendChildID);
417
418         deleteGraphicObject(legendChildID);
419         releaseGraphicObjectProperty(__GO_LEGEND_CHILD__, legendChildID, jni_string, 1);
420     }
421
422     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
423
424     if (parentType != __GO_AXES__)
425     {
426         Scierror(999, _("The parent has to be a SUBWIN\n"));
427         return (char *)NULL;
428     }
429
430     pobjUID = (char *)createGraphicObject(__GO_LEGEND__);
431
432     /* Required to initialize the default contour and font properties */
433     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
434
435     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
436
437     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &iVisible, jni_bool, 1);
438
439     lineIDS = (char **)MALLOC(nblegends * sizeof(char *));
440     if (lineIDS == NULL)
441     {
442         Scierror(999, _("%s: No more memory.\n"), "ConstructLegend");
443         deleteGraphicObject(pobjUID);
444         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
445         return (char *)NULL;
446     }
447
448     textDimensions[0] = nblegends;
449     textDimensions[1] = 1;
450
451     setGraphicObjectProperty(pobjUID, __GO_TEXT_ARRAY_DIMENSIONS__, textDimensions, jni_int_vector, 2);
452     setGraphicObjectProperty(pobjUID, __GO_TEXT_STRINGS__, text, jni_string_vector, nblegends);
453
454     for (i = 0; i < nblegends; i++)
455     {
456         char * tmpObjUID;
457
458         tmpObjUID = (char*)getObjectFromHandle((long)tabofhandles[i]);
459
460         /*
461          * Links are ordered from most recent to least recent,
462          * as their referred-to Polylines in the latter's parent Compound object.
463          */
464         lineIDS[nblegends - i - 1] = tmpObjUID;
465     }
466
467     setGraphicObjectProperty(pobjUID, __GO_LINKS__, lineIDS, jni_string_vector, nblegends);
468
469     /*
470      * Do not release tmpObjUIDs (eg lineIDS content) as getObjectFromHandle pass data by reference.
471      */
472     FREE(lineIDS);
473
474     position[0] = 0.0;
475     position[1] = 0.0;
476     setGraphicObjectProperty(pobjUID, __GO_POSITION__, position, jni_double_vector, 2);
477
478     /* 9: LOWER_CAPTION */
479     legendLocation = 9;
480     setGraphicObjectProperty(pobjUID, __GO_LEGEND_LOCATION__, &legendLocation, jni_int, 1);
481
482     /* Clipping: to be checked for consistency */
483     clipRegionSet = 0;
484     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
485
486     /* 0: OFF */
487     clipState = 0;
488     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
489
490     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
491     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
492     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
493
494     /* NEW :  used to draw the line and marks of the curve F.Leray 21.01.05 */
495     cloneGraphicContext(pparentsubwinUID, pobjUID);
496
497     cloneFontContext(pparentsubwinUID, pobjUID);
498
499     fillMode = TRUE;
500     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &fillMode, jni_bool, 1);
501
502     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
503
504     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
505     setCurrentObject(pobjUID);
506     releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
507
508     return (char*)getCurrentObject();
509 }
510
511 /*---------------------------------------------------------------------------------*/
512 /**
513  * Create a polyline but does not add it to Scilab hierarchy
514  */
515 char * allocatePolyline(char * pparentsubwinUID, double *pvecx, double *pvecy, double *pvecz,
516                         int closed, int n1, int plot, int *foreground, int *background,
517                         int *mark_style, int *mark_foreground, int *mark_background, BOOL isline, BOOL isfilled, BOOL ismark, BOOL isinterpshaded)
518 {
519     char *pobjUID = NULL;
520     int i = 0;
521     BOOL result = FALSE;
522     char *type = NULL;
523     char *polylineID = NULL;
524     double barWidth = 0.;
525     double arrowSizeFactor = 0.;
526     double *clipRegion = NULL;
527     double *dataVector = NULL;
528     int clipState = 0;
529     int *piClipState = &clipState;
530     int lineClosed = 0;
531     int numElementsArray[2];
532     int visible = 0;
533     int *piVisible = &visible;
534     int zCoordinatesSet = 0;
535     int clipRegionSet = 0;
536     int *piClipRegionSet = &clipRegionSet;
537
538     pobjUID = (char *) createGraphicObject(__GO_POLYLINE__);
539     polylineID = (char *) createDataObject(pobjUID, __GO_POLYLINE__);
540
541     if (polylineID == NULL)
542     {
543         deleteGraphicObject(pobjUID);
544         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
545         return NULL;
546     }
547
548     barWidth = 0.0;
549     setGraphicObjectProperty(pobjUID, __GO_BAR_WIDTH__, &barWidth, jni_double, 1);
550
551     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
552
553     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
554
555     /* Clip state and region */
556     /* To be checked for consistency */
557
558     /*
559      * releaseGraphicObjectProperty for any property passed by reference only
560      */
561
562     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
563     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
564     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
565
566     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
567     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
568
569     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
570     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
571
572     arrowSizeFactor = 1.0;
573     setGraphicObjectProperty(pobjUID, __GO_ARROW_SIZE_FACTOR__, &arrowSizeFactor, jni_double, 1);
574
575     /*
576      * First element: number of gons (always 1 for a Polyline)
577      * Second one: number of vertices composing the Polyline
578      */
579     numElementsArray[0] = 1;
580     numElementsArray[1] = n1;
581
582     /* Data */
583     if (n1 != 0)
584     {
585         /*
586          * Sets the number of elements (vertices composing the polyline) and allocates the coordinates array
587          * The FALSE value is used to identify a failed memory allocation for now.
588          */
589         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, numElementsArray, jni_int_vector, 2);
590
591         if (result == FALSE)
592         {
593             deleteGraphicObject(pobjUID);
594             deleteDataObject(pobjUID);
595             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
596             return NULL;
597         }
598
599         dataVector = MALLOC(3 * n1 * sizeof(double));
600
601         if (dataVector == NULL)
602         {
603             deleteGraphicObject(pobjUID);
604             deleteDataObject(pobjUID);
605             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
606             return NULL;
607         }
608
609         if ((pvecx != (double *)NULL) && (pvecy != (double *)NULL))
610         {
611             for (i = 0; i < n1; i++)
612             {
613                 dataVector[i] = pvecx[i];
614                 dataVector[n1 + i] = pvecy[i];
615             }
616         }
617         else
618         {
619             for (i = 0; i < n1; i++)
620             {
621                 dataVector[i] = 0.0;
622                 dataVector[n1 + i] = 0.0;
623             }
624         }
625
626         /**DJ.Abdemouche 2003**/
627         if (pvecz == NULL)
628         {
629             for (i = 0; i < n1; i++)
630             {
631                 dataVector[2 * n1 + i] = 0.0;
632             }
633
634             zCoordinatesSet = 0;
635         }
636         else
637         {
638             for (i = 0; i < n1; i++)
639             {
640                 dataVector[2 * n1 + i] = pvecz[i];
641             }
642
643             zCoordinatesSet = 1;
644         }
645
646         /*
647          * We could probably do without the dataVector copy by individually setting
648          * x, y or z coordinates, and initializing coordinates to 0 during allocation
649          * to ensure consistency
650          */
651         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_COORDINATES__, dataVector, jni_double, n1);
652
653         FREE(dataVector);
654
655         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z_COORDINATES_SET__, &zCoordinatesSet, jni_double, n1);
656     }
657     else
658     {
659         /* 0 points */
660         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, numElementsArray, jni_int_vector, 2);
661
662         if (result == FALSE)
663         {
664             deleteGraphicObject(pobjUID);
665             deleteDataObject(pobjUID);
666             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
667             return NULL;
668         }
669     }
670
671     if (closed > 0)
672     {
673         lineClosed = 1;
674     }
675     else
676     {
677         lineClosed = 0;
678     }
679
680     setGraphicObjectProperty(pobjUID, __GO_CLOSED__, &lineClosed, jni_bool, 1);
681     setGraphicObjectProperty(pobjUID, __GO_POLYLINE_STYLE__, &plot, jni_int, 1);
682
683     /*
684      * Initializes the contour properties (background, foreground, etc)
685      * to the default values (those of the parent Axes).
686      */
687     cloneGraphicContext(pparentsubwinUID, pobjUID);
688
689     /* colors and marks setting */
690     setGraphicObjectProperty(pobjUID, __GO_MARK_MODE__, &ismark, jni_bool, 1);
691     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
692     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
693
694     /* shading interpolation vector and mode */
695     setGraphicObjectProperty(pobjUID, __GO_INTERP_COLOR_MODE__, &isinterpshaded, jni_bool, 1);
696
697     if (foreground != NULL)
698     {
699         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
700     }
701
702     if (background != NULL)
703     {
704         if (isinterpshaded == TRUE)
705         {
706             /* 3 or 4 values to store */
707
708             setGraphicObjectProperty(pobjUID, __GO_INTERP_COLOR_VECTOR__, background, jni_int_vector, n1);
709         }
710         else
711         {
712             setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
713         }
714     }
715
716     if (mark_style != NULL)
717     {
718         /* This does use the MVC */
719         setGraphicObjectProperty(pobjUID, __GO_MARK_STYLE__, mark_style, jni_int, 1);
720     }
721
722     if (mark_foreground != NULL)
723     {
724         setGraphicObjectProperty(pobjUID, __GO_MARK_FOREGROUND__, mark_foreground, jni_int, 1);
725     }
726
727     if (mark_background != NULL)
728     {
729         setGraphicObjectProperty(pobjUID, __GO_MARK_BACKGROUND__, mark_background, jni_int, 1);
730     }
731
732     visible = 1;
733     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
734
735     return pobjUID;
736 }
737
738 /*---------------------------------------------------------------------------------*/
739 /**ConstructPolyline
740  * This function creates  Polyline 2d structure
741  */
742 char * ConstructPolyline(char * pparentsubwinUID, double *pvecx, double *pvecy, double *pvecz,
743                          int closed, int n1, int plot, int *foreground, int *background,
744                          int *mark_style, int *mark_foreground, int *mark_background, BOOL isline, BOOL isfilled, BOOL ismark, BOOL isinterpshaded)
745 {
746     char * pobjUID = allocatePolyline(pparentsubwinUID, pvecx, pvecy, pvecz, closed, n1, plot,
747                                       foreground, background, mark_style, mark_foreground, mark_background,
748                                       isline, isfilled, ismark, isinterpshaded);
749     return pobjUID;
750 }
751
752 /**ConstructArc
753  * This function creates an Arc structure
754  */
755 char * ConstructArc(char * pparentsubwinUID, double x, double y,
756                     double height, double width, double alphabegin, double alphaend, int *foreground, int *background, BOOL isfilled, BOOL isline)
757 {
758     char *pobjUID = NULL;
759     int type = -1;
760     int *piType = &type;
761     double upperLeftPoint[3];
762     double *clipRegion = NULL;
763     int visible = 0;
764     int *piVisible = &visible;
765     int arcDrawingMethod = 0;
766     int *piArcDrawingMethod = &arcDrawingMethod;
767     int clipRegionSet = 0;
768     int *piClipRegionSet = &clipRegionSet;
769     int clipState = 0;
770     int *piClipState = &clipState;
771
772     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piType);
773
774     if (type != __GO_AXES__)
775     {
776         Scierror(999, _("The parent has to be a SUBWIN\n"));
777         return (char *)NULL;
778     }
779
780     pobjUID = (char *)createGraphicObject(__GO_ARC__);
781
782     /*
783      * Sets the arc's parent in order to initialize the former's Contoured properties
784      * with the latter's values (cloneGraphicContext call below)
785      */
786     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
787
788     upperLeftPoint[0] = x;
789     upperLeftPoint[1] = y;
790     upperLeftPoint[2] = 0.0;
791
792     setGraphicObjectProperty(pobjUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
793
794     setGraphicObjectProperty(pobjUID, __GO_HEIGHT__, &height, jni_double, 1);
795     setGraphicObjectProperty(pobjUID, __GO_WIDTH__, &width, jni_double, 1);
796
797     setGraphicObjectProperty(pobjUID, __GO_START_ANGLE__, &alphabegin, jni_double, 1);
798     setGraphicObjectProperty(pobjUID, __GO_END_ANGLE__, &alphaend, jni_double, 1);
799
800     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
801
802     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
803
804     getGraphicObjectProperty(pparentsubwinUID, __GO_ARC_DRAWING_METHOD__, jni_int, (void **)&piArcDrawingMethod);
805
806     setGraphicObjectProperty(pobjUID, __GO_ARC_DRAWING_METHOD__, &arcDrawingMethod, jni_int, 1);
807
808     /*
809      * Clip state and region
810      * To be checked for consistency
811      */
812     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
813     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
814     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
815
816     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
817     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
818
819     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
820     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
821
822     /*
823      * Initializes the contour properties (background, foreground, etc)
824      * to the parent Axes' values.
825      */
826     cloneGraphicContext(pparentsubwinUID, pobjUID);
827
828     /* Contour settings */
829     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
830     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
831
832     if (foreground != NULL)
833     {
834         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
835     }
836
837     if (background != NULL)
838     {
839         setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
840     }
841
842     /* Parent reset to the null object */
843     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
844
845     /*
846      * Sets the Axes as the arc's parent and adds the arc to
847      * its parent's list of children.
848      */
849     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
850
851     return pobjUID;
852 }
853
854 /**ConstructRectangle
855  * This function creates Rectangle structure and only this to destroy all sons use DelGraphicsSon
856  */
857 char * ConstructRectangle(char * pparentsubwinUID, double x, double y,
858                           double height, double width, int *foreground, int *background, int isfilled, int isline)
859 {
860     char *pobjUID = NULL;
861     char *type = NULL;
862     double upperLeftPoint[3];
863     double *clipRegion = NULL;
864     int visible = 0;
865     int *piVisible = &visible;
866     int clipRegionSet = 0;
867     int *piClipRegionSet = &clipRegionSet;
868     int clipState = 0;
869     int *piClipState = &clipState;
870     int iMarkMode = 0;
871     int *piMarkMode = &iMarkMode;
872
873     if (height < 0.0 || width < 0.0)
874     {
875         Scierror(999, _("Width and height must be positive.\n"));
876         return NULL;
877     }
878
879     pobjUID = (char *)createGraphicObject(__GO_RECTANGLE__);
880
881     /*
882      * Sets the rectangle's parent in order to initialize the former's Contoured properties
883      * with the latter's values (cloneGraphicContext call below)
884      */
885     //setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
886
887     upperLeftPoint[0] = x;
888     upperLeftPoint[1] = y;
889     upperLeftPoint[2] = 0.0;
890
891     setGraphicObjectProperty(pobjUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
892
893     setGraphicObjectProperty(pobjUID, __GO_HEIGHT__, &height, jni_double, 1);
894     setGraphicObjectProperty(pobjUID, __GO_WIDTH__, &width, jni_double, 1);
895
896     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
897     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
898
899     /* Clip state and region */
900     /* To be checked for consistency */
901
902     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
903     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
904     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
905
906     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
907     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
908
909     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
910     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
911
912     getGraphicObjectProperty(pparentsubwinUID, __GO_MARK_MODE__, jni_bool, (void **)&piMarkMode);
913     setGraphicObjectProperty(pobjUID, __GO_MARK_MODE__, &iMarkMode, jni_bool, 1);
914
915     /*
916      * Initializes the contour properties (background, foreground, etc)
917      * to the default values (those of the parent Axes).
918      */
919     cloneGraphicContext(pparentsubwinUID, pobjUID);
920
921     /* Contour settings */
922     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
923     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
924
925     if (foreground != NULL)
926     {
927         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
928     }
929
930     if (background != NULL)
931     {
932         setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
933     }
934
935     /* Parent reset to the null object */
936     //setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
937
938     /*
939      * Sets the Axes as the rectangle's parent and adds the rectangle to
940      * its parent's list of children.
941      */
942     //setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
943
944     return pobjUID;
945 }
946
947 /**ConstructSurface
948  * This function creates Surface Structure
949  */
950 char *ConstructSurface(char *pparentsubwinUID, sciTypeOf3D typeof3d,
951                        double *pvecx, double *pvecy, double *pvecz, double *zcol,
952                        int izcol, int dimzx, int dimzy,
953                        int *flag, double *ebox, int flagcolor, int *isfac, int *m1, int *n1, int *m2, int *n2, int *m3, int *n3, int *m3n, int *n3n)
954 {
955     char *pobjUID = NULL;
956     int parentType = -1;
957     int *piParentType = &parentType;
958     int const surfaceTypes[2] = { __GO_PLOT3D__, __GO_FAC3D__ };
959
960     double *clipRegion = NULL;
961
962     int nx = 0, ny = 0, nz = 0, nc = 0;
963     int result = 0;
964     int clipRegionSet = 0;
965     int *piClipRegionSet = &clipRegionSet;
966     int clipState = 0;
967     int *piClipState = &clipState;
968     int visible = 0;
969     int *piVisible = &visible;
970     int cdataMapping = 0;
971     int hiddenColor = 0;
972     int *piHiddenColor = &hiddenColor;
973     int surfaceMode = 0;
974
975     /* To be modified: the MVC does not allow Plot3d objects with color data yet */
976     if (typeof3d == SCI_PLOT3D)
977     {
978         nx = dimzx;
979         ny = dimzy;
980         nz = dimzx * dimzy;
981         if (flagcolor == 2)
982         {
983             /* one color per facet: nc = dimzx * dimzy */
984             nc = nz;
985         }
986         else if (flagcolor == 3)
987         {
988             /*
989              * one color per edge: nc = 4* dimzx * dimzy ??????
990              * 3 or 4 vertices are needed: I think we take 4 to have enough allocated memory
991              */
992             nc = nz * 4;
993         }
994         /* made by Djalel : comes from the genfac3d case */
995         else
996         {
997             nc = 0;
998         }
999     }
1000     /* DJ.A 2003 */
1001     else
1002     {
1003         /* case SCI_FAC3D */
1004         nx = dimzx * dimzy;
1005         ny = dimzx * dimzy;
1006         nz = dimzx * dimzy;
1007         if (flagcolor == 2)
1008         {
1009             /* one color per facet: nc = dimzy */
1010             nc = dimzy;
1011         }
1012         else if (flagcolor == 3)
1013         {
1014             /* one color per edge: nc = dimzx * dimzy */
1015             nc = nz;
1016         }
1017         else
1018         {
1019             nc = 0;
1020         }
1021     }
1022
1023     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1024
1025     /* test using sciGetEntityType replaced by a test on the type string */
1026     if (parentType != __GO_AXES__)
1027     {
1028         Scierror(999, _("The parent has to be a SUBWIN\n"));
1029         return NULL;
1030     }
1031
1032     pobjUID = (char *)createGraphicObject(surfaceTypes[*isfac]);
1033     createDataObject(pobjUID, surfaceTypes[*isfac]);
1034
1035     /* Clip state and region */
1036     /* To be checked for consistency */
1037
1038     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1039     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1040     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1041
1042     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1043     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1044
1045     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1046     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1047
1048     /* Visibility */
1049     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1050
1051     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1052
1053     setGraphicObjectProperty(pobjUID, __GO_COLOR_FLAG__, &flagcolor, jni_int, 1);
1054
1055     /* Direct mode enabled as default */
1056     cdataMapping = 1;
1057
1058     /* Only for Fac3D */
1059     setGraphicObjectProperty(pobjUID, __GO_DATA_MAPPING__, &cdataMapping, jni_int, 1);
1060
1061     setGraphicObjectProperty(pobjUID, __GO_COLOR_MODE__, &flag[0], jni_int, 1);
1062
1063     /* Plot3d case */
1064     if (!*isfac)
1065     {
1066         int gridSize[4];
1067
1068         gridSize[0] = *m1;
1069         gridSize[1] = *n1;
1070         gridSize[2] = *m2;
1071         gridSize[3] = *n2;
1072
1073         /* Allocates the coordinates arrays */
1074         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
1075     }
1076     /* Fac3d case */
1077     else
1078     {
1079         int numElementsArray[3];
1080
1081         /*
1082          * First element: number of n-gons
1083          * Second element: number of vertices per n-gon
1084          * Third element: number of input colors
1085          */
1086         numElementsArray[0] = dimzy;
1087         numElementsArray[1] = dimzx;
1088         numElementsArray[2] = nc;
1089
1090         /* Allocates the coordinates and color arrays */
1091         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, numElementsArray, jni_int_vector, 3);
1092     }
1093
1094     if (result == 0)
1095     {
1096         deleteGraphicObject(pobjUID);
1097         deleteDataObject(pobjUID);
1098         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1099         return NULL;
1100     }
1101
1102     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, nx);
1103     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, ny);
1104     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z__, pvecz, jni_double_vector, nz);
1105
1106     /* Add the color matrix dimensions as a property ? */
1107     if (nc > 0)
1108     {
1109         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_COLORS__, zcol, jni_double_vector, nc);
1110     }
1111
1112     /*-------END Replaced by: --------*/
1113
1114     getGraphicObjectProperty(pparentsubwinUID, __GO_HIDDEN_COLOR__, jni_int, (void **)&piHiddenColor);
1115     setGraphicObjectProperty(pobjUID, __GO_HIDDEN_COLOR__, &hiddenColor, jni_int, 1);
1116
1117     /*
1118      * surfaceMode set to "on", was previously done by InitGraphicContext, by setting
1119      * the graphic context's line_mode to on, which stood for the surface_mode.
1120      */
1121     surfaceMode = 1;
1122
1123     setGraphicObjectProperty(pobjUID, __GO_SURFACE_MODE__, &surfaceMode, jni_bool, 1);
1124
1125     /*
1126      * Adding a new handle and setting the parent-child relationship is now
1127      * done after data initialization in order to avoid additional
1128      * clean-up.
1129      */
1130     // Here we init old 'graphicContext' by cloning it from parent.
1131     cloneGraphicContext(pparentsubwinUID, pobjUID);
1132     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1133
1134     return pobjUID;
1135 }
1136
1137 /********************** 14/05/2002 *****
1138  **ConstructGrayplot
1139  * This function is used to build Grayplot and Matplot objects.
1140  * It would probably be better to put the code related to Matplot objects
1141  * in a separate build function, as it would avoid having to perform several tests
1142  * on the type parameter. This is done so because Matplot objects were previously
1143  * internally represented by sciGrayplot structures.
1144  */
1145 char *ConstructGrayplot(char *pparentsubwinUID, double *pvecx, double *pvecy, double *pvecz, int n1, int n2, int type)
1146 {
1147     char *pobjUID = NULL;
1148
1149     int const objectTypes[3] = { __GO_GRAYPLOT__, __GO_MATPLOT__, __GO_MATPLOT__ };
1150
1151     int typeParent = -1;
1152     int *piTypeParent = &typeParent;
1153
1154     char *grayplotID = NULL;
1155     int result = 0;
1156     int dataMapping = 0;
1157     int gridSize[4];
1158
1159     int parentVisible = 0;
1160     int *piParentVisible = &parentVisible;
1161     double *clipRegion = NULL;
1162     int clipRegionSet = 0;
1163     int *piClipRegionSet = &clipRegionSet;
1164     int clipState = 0;
1165     int *piClipState = &clipState;
1166     int numElements = 0;
1167
1168     double pdblScale[2];
1169
1170     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piTypeParent);
1171
1172     if (typeParent != __GO_AXES__)
1173     {
1174         Scierror(999, _("The parent has to be a SUBWIN\n"));
1175         return (char *)NULL;
1176     }
1177
1178     pobjUID = (char *)createGraphicObject(objectTypes[type]);
1179     grayplotID = (char *)createDataObject(pobjUID, objectTypes[type]);
1180
1181     if (grayplotID == NULL)
1182     {
1183         deleteGraphicObject(pobjUID);
1184         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1185         return NULL;
1186     }
1187
1188     /* 0: scaled; only used for Grayplot */
1189     if (type == 0)
1190     {
1191         dataMapping = 0;
1192         setGraphicObjectProperty(pobjUID, __GO_DATA_MAPPING__, &dataMapping, jni_int, 1);
1193     }
1194
1195     /* The x and y vectors are column ones */
1196
1197     /*
1198      * For the Grayplot object, the number of rows and columns respectively
1199      * correspond to the grid's x and y dimensions whereas for Matplot objects,
1200      * they respectively correspond to the grid's y and x dimensions.
1201      */
1202     if (type == 0)
1203     {
1204         gridSize[0] = n1;
1205         gridSize[1] = 1;
1206         gridSize[2] = n2;
1207         gridSize[3] = 1;
1208     }
1209     else
1210     {
1211         gridSize[0] = n2;
1212         gridSize[1] = 1;
1213         gridSize[2] = n1;
1214         gridSize[3] = 1;
1215     }
1216
1217     /* Only for Matplot1 objects */
1218     if (type == 2)
1219     {
1220         setGraphicObjectProperty(pobjUID, __GO_MATPLOT_TRANSLATE__, pvecx, jni_double_vector, 2);
1221         pdblScale[0] = (pvecx[2] - pvecx[0]) / (n2 - 1.0);
1222         pdblScale[1] = (pvecx[3] - pvecx[1]) / (n1 - 1.0);
1223         setGraphicObjectProperty(pobjUID, __GO_MATPLOT_SCALE__, pdblScale, jni_double_vector, 2);
1224     }
1225
1226     /* Allocates the coordinates arrays */
1227     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
1228
1229     if (result == 0)
1230     {
1231         deleteGraphicObject(pobjUID);
1232         deleteDataObject(pobjUID);
1233         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1234         return NULL;
1235     }
1236
1237     /* Only for Grayplot objects, for Matplot objects, x and y coordinates are automatically computed */
1238     if (type == 0)
1239     {
1240         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, n1);
1241         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, n2);
1242     }
1243
1244     if (type == 0)
1245     {
1246         numElements = n1 * n2;
1247     }
1248     else
1249     {
1250         numElements = (n1 - 1) * (n2 - 1);
1251     }
1252
1253     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z__, pvecz, jni_double_vector, numElements);
1254
1255     /*
1256      * Adding a new handle and setting the parent-child relationship is now
1257      * done after data initialization in order to avoid additional
1258      * clean-up.
1259      */
1260
1261     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1262
1263     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1264     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1265
1266     /*
1267      * Clip state and region
1268      * To be checked for consistency
1269      */
1270     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1271     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1272     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1273
1274     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1275     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1276
1277     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1278     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1279
1280     /* Initializes the default Contour values */
1281     cloneGraphicContext(pparentsubwinUID, pobjUID);
1282
1283     return pobjUID;
1284 }
1285
1286 /**ConstructAxis
1287  * This function creates an Axis object
1288  * @author Djalel ABDEMOUCHE
1289  * @see sciSetCurrentObj
1290  *
1291  */
1292 char *ConstructAxis(char *pparentsubwinUID, char dir, char tics, double *vx,
1293                     int nx, double *vy, int ny, char **str, int subint, char *format,
1294                     int fontsize, int textcolor, int ticscolor, char logscale, int seg, int nb_tics_labels)
1295 {
1296     int parentType = -1;
1297     int *piParentType = &parentType;
1298     char *pobjUID = NULL;
1299     int i = 0;
1300     int clipRegionSet = 0;
1301     int clipState = 0;
1302     int ticksDirection = 0;
1303     int ticksStyle = 0;
1304     double *clipRegion = NULL;
1305     double doubleFontSize = 0.;
1306
1307     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1308
1309     if (parentType != __GO_AXES__)
1310     {
1311         Scierror(999, _("The parent has to be a SUBWIN\n"));
1312         return (char *)NULL;
1313     }
1314
1315     pobjUID = (char *)createGraphicObject(__GO_AXIS__);
1316
1317     /* Required to initialize the default contour properties */
1318     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
1319
1320     /* Clipping: to be checked for consistency */
1321     clipRegionSet = 0;
1322     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1323
1324     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1325     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1326     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1327
1328     /* 0: OFF */
1329     clipState = 0;
1330     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1331
1332     /* The ticks style and direction MVC properties are Integers */
1333     if (dir == 'u')
1334     {
1335         ticksDirection = 0;
1336     }
1337     else if (dir == 'd')
1338     {
1339         ticksDirection = 1;
1340     }
1341     else if (dir == 'l')
1342     {
1343         ticksDirection = 2;
1344     }
1345     else if (dir == 'r')
1346     {
1347         ticksDirection = 3;
1348     }
1349     else
1350     {
1351         ticksDirection = 0;
1352     }
1353
1354     if (tics == 'v')
1355     {
1356         ticksStyle = 0;
1357     }
1358     else if (tics == 'r')
1359     {
1360         ticksStyle = 1;
1361     }
1362     else if (tics == 'i')
1363     {
1364         ticksStyle = 2;
1365     }
1366     else
1367     {
1368         ticksStyle = 0;
1369     }
1370
1371     setGraphicObjectProperty(pobjUID, __GO_TICKS_DIRECTION__, &ticksDirection, jni_int, 1);
1372     setGraphicObjectProperty(pobjUID, __GO_TICKS_STYLE__, &ticksStyle, jni_int, 1);
1373
1374     setGraphicObjectProperty(pobjUID, __GO_X_TICKS_COORDS__, vx, jni_double_vector, nx);
1375     setGraphicObjectProperty(pobjUID, __GO_Y_TICKS_COORDS__, vy, jni_double_vector, ny);
1376
1377     /* FORMATN must be set before Labels are computed. */
1378     if (format != NULL)
1379     {
1380         setGraphicObjectProperty(pobjUID, __GO_FORMATN__, format, jni_string, 1);
1381     }
1382
1383     /*
1384      * Labels are computed automatically depending on the ticks coordinates.
1385      * The computation is performed by a C function which has been adapted
1386      * to the MVC (property get calls) and was previously done in the
1387      * tics labels property get C function.
1388      * It should be done (or called) directly in the Java part of the model
1389      * for the sake of efficiency.
1390      * To be modified
1391      */
1392     if (str == NULL)
1393     {
1394         char **matData;
1395         StringMatrix *tics_labels;
1396
1397         tics_labels = computeDefaultTicsLabels(pobjUID);
1398
1399         if (tics_labels == NULL)
1400         {
1401             deleteGraphicObject(pobjUID);
1402             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1403             return (char *)NULL;
1404         }
1405
1406         matData = getStrMatData(tics_labels);
1407
1408         /*
1409          * The labels vector size must be computed using the matrix's dimensions.
1410          * To be modified when the labels computation is moved to the Model.
1411          */
1412         setGraphicObjectProperty(pobjUID, __GO_TICKS_LABELS__, matData, jni_string_vector, tics_labels->nbCol * tics_labels->nbRow);
1413
1414         deleteMatrix(tics_labels);
1415     }
1416     else
1417     {
1418         /*
1419          * Labels are set using the str argument; the previous code tested whether each element of the
1420          * str array was null and set the corresponding Axis' element to NULL, though there was no
1421          * apparent reason to do so. This is still checked, but now aborts building the Axis.
1422          */
1423
1424         if (nb_tics_labels == -1)
1425         {
1426             Scierror(999, _("Impossible case when building axis\n"));
1427             deleteGraphicObject(pobjUID);
1428             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1429             return NULL;
1430         }
1431
1432         for (i = 0; i < nb_tics_labels; i++)
1433         {
1434             if (str[i] == NULL)
1435             {
1436                 deleteGraphicObject(pobjUID);
1437                 releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1438                 return NULL;
1439             }
1440         }
1441
1442         setGraphicObjectProperty(pobjUID, __GO_TICKS_LABELS__, str, jni_string_vector, nb_tics_labels);
1443     }
1444
1445     setGraphicObjectProperty(pobjUID, __GO_SUBTICKS__, &subint, jni_int, 1);
1446     setGraphicObjectProperty(pobjUID, __GO_TICKS_SEGMENT__, &seg, jni_bool, 1);
1447
1448     /* Initializes the default Contour values */
1449     cloneGraphicContext(pparentsubwinUID, pobjUID);
1450
1451     /* Initializes the default Font values */
1452     cloneFontContext(pparentsubwinUID, pobjUID);
1453
1454     /* Parent reset to the null object */
1455     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
1456
1457     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1458
1459     doubleFontSize = (double)fontsize;
1460
1461     setGraphicObjectProperty(pobjUID, __GO_FONT_SIZE__, &doubleFontSize, jni_double, 1);
1462     setGraphicObjectProperty(pobjUID, __GO_FONT_COLOR__, &textcolor, jni_int, 1);
1463     setGraphicObjectProperty(pobjUID, __GO_TICKS_COLOR__, &ticscolor, jni_int, 1);
1464
1465     return pobjUID;
1466 }
1467
1468 /********************** 21/05/2002 *****
1469  **ConstructFec
1470  * This function creates Fec
1471  * @author Djalel.ABDEMOUCHE
1472  * @see sciSetCurrentObj
1473  */
1474 char *ConstructFec(char *pparentsubwinUID, double *pvecx, double *pvecy, double *pnoeud,
1475                    double *pfun, int Nnode, int Ntr, double *zminmax, int *colminmax, int *colout, BOOL with_mesh)
1476 {
1477     char *pobjUID = NULL;
1478     char *fecId = NULL;
1479     int result = 0;
1480
1481     int parentType = -1;
1482     int *piParentType = &parentType;
1483
1484     int parentVisible = 0;
1485     int *piParentVisible = &parentVisible;
1486
1487     double *clipRegion = NULL;
1488     int clipRegionSet = 0;
1489     int *piClipRegionSet = &clipRegionSet;
1490     int iClipState = 0;
1491     int *piClipState = &iClipState;
1492
1493     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1494
1495     /* test using sciGetEntityType replaced by a test on the type string */
1496     if (parentType != __GO_AXES__)
1497     {
1498         Scierror(999, _("The parent has to be a SUBWIN\n"));
1499         return (char *)NULL;
1500     }
1501
1502     pobjUID = createGraphicObject(__GO_FEC__);
1503     fecId = (char *)createDataObject(pobjUID, __GO_FEC__);
1504
1505     if (fecId == NULL)
1506     {
1507         deleteGraphicObject(pobjUID);
1508         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1509         return (char *)NULL;
1510     }
1511
1512     /* Allocates the coordinates array */
1513     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_VERTICES__, &Nnode, jni_int, 1);
1514
1515     if (result == 0)
1516     {
1517         deleteGraphicObject(pobjUID);
1518         deleteDataObject(pobjUID);
1519         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1520         return (char *)NULL;
1521     }
1522
1523     /* Allocates the triangle indices and values array */
1524     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_INDICES__, &Ntr, jni_int, 1);
1525
1526     if (result == 0)
1527     {
1528         deleteGraphicObject(pobjUID);
1529         deleteDataObject(pobjUID);
1530         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1531         return (char *)NULL;
1532     }
1533
1534     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, Nnode);
1535     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, Nnode);
1536
1537     /* Fec-specific property: triangle indices plus special values (triangle number and flag) */
1538     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_FEC_TRIANGLES__, pnoeud, jni_double_vector, Ntr);
1539
1540     /* Function values */
1541     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_VALUES__, pfun, jni_double_vector, Nnode);
1542
1543     setGraphicObjectProperty(pobjUID, __GO_Z_BOUNDS__, zminmax, jni_double_vector, 2);
1544     setGraphicObjectProperty(pobjUID, __GO_COLOR_RANGE__, colminmax, jni_int_vector, 2);
1545     setGraphicObjectProperty(pobjUID, __GO_OUTSIDE_COLOR__, colout, jni_int_vector, 2);
1546
1547     /*
1548      * Adding a new handle and setting the parent-child relationship is now
1549      * done after data initialization in order to avoid additional
1550      * clean-up.
1551      */
1552     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1553
1554     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1555     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1556
1557     /*
1558      * Clip state and region
1559      * To be checked for consistency
1560      */
1561     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1562     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1563     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1564
1565     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1566     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1567
1568     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1569     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &iClipState, jni_int, 1);
1570
1571     /* Initializes the default Contour values */
1572     cloneGraphicContext(pparentsubwinUID, pobjUID);
1573
1574     /* line mode is set using with_mesh */
1575     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &with_mesh, jni_bool, 1);
1576
1577     return pobjUID;
1578 }
1579
1580 /**ConstructSegs
1581  * This function creates Segments
1582  * It is used to create and initialize the data of both the Champ and Segs MVC objects.
1583  * @author Djalel.ABDEMOUCHE
1584  * @version 0.1
1585  * @see sciSetCurrentObj
1586  */
1587 char *ConstructSegs(char *pparentsubwinUID, int type,
1588                     double *vx, double *vy, double *vz,
1589                     int Nbr1, int Nbr2, int Nbr3, double *vfx, double *vfy, int flag, int *style, double arsize, int colored, int typeofchamp)
1590 {
1591     char *pobjUID = NULL;
1592
1593     int visible = 0;
1594     int *piVisible = &visible;
1595     int clipRegionSet = 0;
1596     int *piClipRegionSet = &clipRegionSet;
1597     int clipState = 0;
1598     int *piClipState = &clipState;
1599     int numberArrows = 0;
1600     int dimensions[2];
1601     int i = 0;
1602
1603     double *clipRegion = NULL;
1604     double *arrowCoords = NULL;
1605
1606     if (type == 0)
1607     {
1608         pobjUID = createGraphicObject(__GO_SEGS__);
1609     }
1610     else if (type == 1)
1611     {
1612         pobjUID = createGraphicObject(__GO_CHAMP__);
1613     }
1614     else
1615     {
1616         return (char *)NULL;
1617     }
1618
1619     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1620
1621     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1622
1623     /* this must be done prior to the call of Set Clipping property to know */
1624     /* if the clip_state has been set */
1625
1626     /*
1627      * Clip state and region
1628      * To be checked for consistency
1629      */
1630     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1631     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1632     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1633
1634     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1635     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1636
1637     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1638     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1639
1640     if (type == 1)
1641     {
1642         numberArrows = Nbr1 * Nbr2;
1643     }
1644     else
1645     {
1646         /* Segs: Nbr1/2 arrows, Nbr1 is the number of endpoints */
1647         numberArrows = Nbr1 / 2;
1648     }
1649
1650     /* Triggers the creation of the Arrow objects part of Champ or Segs */
1651     setGraphicObjectProperty(pobjUID, __GO_NUMBER_ARROWS__, &numberArrows, jni_int, 1);
1652
1653     /* Champ property only */
1654     if (type == 1)
1655     {
1656         dimensions[0] = Nbr1;
1657         dimensions[1] = Nbr2;
1658
1659         setGraphicObjectProperty(pobjUID, __GO_CHAMP_DIMENSIONS__, dimensions, jni_int_vector, 2);
1660     }
1661
1662     arrowCoords = (double *)MALLOC(3 * numberArrows * sizeof(double));
1663
1664     if (arrowCoords == NULL)
1665     {
1666         deleteGraphicObject(pobjUID);
1667         releaseGraphicObjectProperty(__GO_SEGS__, pobjUID, jni_string, 1);
1668         return (char *)NULL;
1669     }
1670
1671     setGraphicObjectProperty(pobjUID, __GO_ARROW_SIZE__, &arsize, jni_double, 1);
1672
1673     /* Type 0 corresponds to a SEGS object */
1674     if (type == 0)
1675     {
1676         for (i = 0; i < numberArrows; i++)
1677         {
1678             arrowCoords[3 * i] = vx[2 * i];
1679             arrowCoords[3 * i + 1] = vy[2 * i];
1680
1681             if (vz != NULL)
1682             {
1683                 arrowCoords[3 * i + 2] = vz[2 * i];
1684             }
1685             else
1686             {
1687                 arrowCoords[3 * i + 2] = 0.0;
1688             }
1689         }
1690
1691         setGraphicObjectProperty(pobjUID, __GO_BASE__, arrowCoords, jni_double_vector, 3 * numberArrows);
1692
1693         for (i = 0; i < numberArrows; i++)
1694         {
1695             arrowCoords[3 * i] = vx[2 * i + 1];
1696             arrowCoords[3 * i + 1] = vy[2 * i + 1];
1697
1698             if (vz != NULL)
1699             {
1700                 arrowCoords[3 * i + 2] = vz[2 * i + 1];
1701             }
1702             else
1703             {
1704                 arrowCoords[3 * i + 2] = 0.0;
1705             }
1706         }
1707
1708         setGraphicObjectProperty(pobjUID, __GO_DIRECTION__, arrowCoords, jni_double_vector, 3 * numberArrows);
1709
1710         if (flag == 1)
1711         {
1712             /* Style is an array of numberArrows elements */
1713             setGraphicObjectProperty(pobjUID, __GO_SEGS_COLORS__, style, jni_int_vector, numberArrows);
1714         }
1715         else
1716         {
1717             /* Style is a scalar */
1718             setGraphicObjectProperty(pobjUID, __GO_SEGS_COLORS__, style, jni_int_vector, 1);
1719         }
1720
1721     }
1722     else
1723     {
1724         /*
1725          * Type 1 corresponds to a CHAMP object
1726          * so building comes from champg
1727          */
1728         setGraphicObjectProperty(pobjUID, __GO_BASE_X__, vx, jni_double_vector, Nbr1);
1729         setGraphicObjectProperty(pobjUID, __GO_BASE_Y__, vy, jni_double_vector, Nbr2);
1730
1731         for (i = 0; i < numberArrows; i++)
1732         {
1733             arrowCoords[3 * i] = vfx[i];
1734             arrowCoords[3 * i + 1] = vfy[i];
1735             arrowCoords[3 * i + 2] = 0.0;
1736         }
1737
1738         setGraphicObjectProperty(pobjUID, __GO_DIRECTION__, arrowCoords, jni_double_vector, 3 * numberArrows);
1739
1740         /* typeofchamp corresponds to COLORED (0: false, 1: true) */
1741         setGraphicObjectProperty(pobjUID, __GO_COLORED__, &typeofchamp, jni_bool, 1);
1742     }
1743
1744     /* Required to initialize the default contour properties */
1745     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
1746
1747     /* Initializes the default Contour values */
1748     cloneGraphicContext(pparentsubwinUID, pobjUID);
1749
1750     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
1751
1752     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1753
1754     FREE(arrowCoords);
1755
1756     return pobjUID;
1757 }
1758
1759 /**sciConstructCompound
1760  * constructs a Compound of entities
1761  * do only an association with a parent and a handle reservation !
1762  * check for valid handle can be done using CheckForCompound
1763  */
1764 char *ConstructCompound(long *handelsvalue, int number) /* Conflicting types with definition */
1765 {
1766     char *compoundUID = NULL;
1767     char *parentAxesUID = NULL;
1768     char *firstMovedObjectUID = NULL;
1769
1770     int i = 0;
1771     int parentVisible = 0;
1772     int *piParentVisible = &parentVisible;
1773
1774     compoundUID = createGraphicObject(__GO_COMPOUND__);
1775
1776     /* Add the Compound's handle */
1777     /* The Compound's parent Axes is considered to be the Compound's first child's own parent */
1778     firstMovedObjectUID = (char*)getObjectFromHandle((long)handelsvalue[0]);
1779     getGraphicObjectProperty(firstMovedObjectUID, __GO_PARENT__, jni_string, (void **)&parentAxesUID);
1780
1781     /* Set the parent-child relationship between the Compound and each aggregated object */
1782     for (i = 0; i < number; i++)
1783     {
1784         char *movedObjectUID = (char*)getObjectFromHandle((long)handelsvalue[i]);
1785
1786         setGraphicObjectRelationship(compoundUID, movedObjectUID);
1787     }
1788
1789     /* Sets the parent-child relationship for the Compound */
1790     setGraphicObjectRelationship(parentAxesUID, compoundUID);
1791
1792     getGraphicObjectProperty(parentAxesUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1793     setGraphicObjectProperty(compoundUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1794
1795     releaseGraphicObjectProperty(__GO_PARENT__, parentAxesUID, jni_string, 1);
1796
1797     return (char *)compoundUID;
1798 }
1799
1800 /**ConstructCompoundSeq
1801  * constructs a Compound of with the last n entities created in the current subwindow
1802  on entry the subwin children list is
1803  s1->s2->...->sn->sn+1->...->sN
1804  with sn the least recent of the last n entities created and s1 the most recent one
1805  (that is, the last entity created), and N the subwin's initial number of children
1806  on exit it is
1807  A->sn+1->sn+2->...->sN
1808  with A a Compound object whose children list is:
1809  s1->s2->...->sn-1->sn
1810 */
1811 char *ConstructCompoundSeq(int number)
1812 {
1813     char **children = NULL;
1814     char *parentFigure = NULL;
1815     int numberChildren = 0;
1816     int *piNumberChildren = &numberChildren;
1817     int i = 0;
1818     int visible = 0;
1819     int *piVisible = &visible;
1820
1821     char *pobjUID = NULL;
1822     char const* psubwinUID = getCurrentSubWin();
1823
1824     /* Creates the Compound object A */
1825     pobjUID = createGraphicObject(__GO_COMPOUND__);
1826
1827     /* Add the Compound's handle */
1828     getGraphicObjectProperty(psubwinUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&piNumberChildren);
1829
1830     getGraphicObjectProperty(psubwinUID, __GO_CHILDREN__, jni_string_vector, (void **)&children);
1831
1832     /*
1833      * Remove the last "number" created objects (located at the children list's head)
1834      * and add them to the compound in the same order
1835      */
1836     for (i = 0; i < number; i++)
1837     {
1838         /*
1839          * Set the parent-child relationship between the Compound and each aggregated object.
1840          * Children are added to the Compound from the least recent to the most recent, to
1841          * preserve their former ordering.
1842          */
1843         setGraphicObjectRelationship(pobjUID, children[number - i - 1]);
1844     }
1845     releaseGraphicObjectProperty(__GO_CHILDREN__, children, jni_string_vector, numberChildren);
1846
1847     /* Sets the parent-child relationship for the Compound */
1848     setGraphicObjectRelationship(psubwinUID, pobjUID);
1849
1850     /*
1851      * visibility is obtained from the parent Figure, whereas it is retrieved from the
1852      * parent Axes in ConstructCompound.
1853      * To be made consistent.
1854      */
1855     getGraphicObjectProperty(pobjUID, __GO_PARENT_FIGURE__, jni_string, (void **)&parentFigure);
1856     getGraphicObjectProperty(parentFigure, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1857     releaseGraphicObjectProperty(__GO_PARENT_FIGURE__, parentFigure, jni_string, 1);
1858
1859     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1860
1861     return (char *)pobjUID;
1862 }
1863
1864 /**ConstructLabel
1865  * This function creates the Label structure used for x,y,z labels and for the Title.
1866  * On the contrary to the other Construct functions, it clones the Axes model's relevant
1867  * label instead of creating a new Label object and performing property sets using
1868  * the values of the Axes model's label, which is done instead by the clone call.
1869  * @param  char *pparentsubwinUID: the parent Axes' identifier.
1870  * @param  char text[] : initial text string, unused.
1871  * @param  int type to get info. on the type of label.
1872  */
1873 void ConstructLabel(char * pparentsubwinUID, char const* text, int type)
1874 {
1875     int const labelProperties[] = { __GO_X_AXIS_LABEL__, __GO_Y_AXIS_LABEL__, __GO_Z_AXIS_LABEL__, __GO_TITLE__ };
1876     int parentType = -1;
1877     int *piParentType = &parentType;
1878     int labelType = 0;
1879     char *modelLabelUID = NULL;
1880     char *pobjUID = NULL;
1881     int autoPosition = 0;
1882     int *piAutoPosition = &autoPosition;
1883     double position[3] = { 1.0, 1.0, 1.0 };
1884
1885     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void**)&piParentType);
1886
1887     if (parentType != __GO_AXES__)
1888     {
1889         Scierror(999, _("The parent has to be a SUBWIN\n"));
1890         return;
1891     }
1892
1893     if (type < 1 || type > 4)
1894     {
1895         return;
1896     }
1897
1898     labelType = labelProperties[type - 1];
1899
1900     getGraphicObjectProperty(getAxesModel(), labelType, jni_string, (void **)&modelLabelUID);
1901
1902     /* Creates a new Label object with the same properties as the Axes model's corresponding label */
1903     pobjUID = cloneGraphicObject(modelLabelUID);
1904
1905     /* Position set to {1, 1, 1} as a default to take into account logarithmic coordinates */
1906     setGraphicObjectProperty(pobjUID, __GO_POSITION__, position, jni_double_vector, 3);
1907
1908     /* Auto position must be reset as setting the position has set it to false */
1909     getGraphicObjectProperty(modelLabelUID, __GO_AUTO_POSITION__, jni_bool, (void **)&piAutoPosition);
1910     setGraphicObjectProperty(pobjUID, __GO_AUTO_POSITION__, &autoPosition, jni_bool, 1);
1911
1912     /* Attach the cloned label to its parent Axes and set the latter as the label's parent */
1913     setGraphicObjectProperty(pparentsubwinUID, labelType, pobjUID, jni_string, 1);
1914     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1915
1916     releaseGraphicObjectProperty(labelType, modelLabelUID, jni_string, 1);
1917     releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1918 }