e26d489979fd249d45902b91d3d795962652842f
[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             return NULL;
596         }
597
598         dataVector = MALLOC(3 * n1 * sizeof(double));
599
600         if (dataVector == NULL)
601         {
602             deleteGraphicObject(pobjUID);
603             deleteDataObject(pobjUID);
604             return NULL;
605         }
606
607         if ((pvecx != (double *)NULL) && (pvecy != (double *)NULL))
608         {
609             for (i = 0; i < n1; i++)
610             {
611                 dataVector[i] = pvecx[i];
612                 dataVector[n1 + i] = pvecy[i];
613             }
614         }
615         else
616         {
617             for (i = 0; i < n1; i++)
618             {
619                 dataVector[i] = 0.0;
620                 dataVector[n1 + i] = 0.0;
621             }
622         }
623
624         /**DJ.Abdemouche 2003**/
625         if (pvecz == NULL)
626         {
627             for (i = 0; i < n1; i++)
628             {
629                 dataVector[2 * n1 + i] = 0.0;
630             }
631
632             zCoordinatesSet = 0;
633         }
634         else
635         {
636             for (i = 0; i < n1; i++)
637             {
638                 dataVector[2 * n1 + i] = pvecz[i];
639             }
640
641             zCoordinatesSet = 1;
642         }
643
644         /*
645          * We could probably do without the dataVector copy by individually setting
646          * x, y or z coordinates, and initializing coordinates to 0 during allocation
647          * to ensure consistency
648          */
649         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_COORDINATES__, dataVector, jni_double, n1);
650
651         FREE(dataVector);
652
653         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z_COORDINATES_SET__, &zCoordinatesSet, jni_double, n1);
654     }
655     else
656     {
657         /* 0 points */
658         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, numElementsArray, jni_int_vector, 2);
659
660         if (result == FALSE)
661         {
662             deleteGraphicObject(pobjUID);
663             deleteDataObject(pobjUID);
664             return NULL;
665         }
666     }
667
668     if (closed > 0)
669     {
670         lineClosed = 1;
671     }
672     else
673     {
674         lineClosed = 0;
675     }
676
677     setGraphicObjectProperty(pobjUID, __GO_CLOSED__, &lineClosed, jni_bool, 1);
678     setGraphicObjectProperty(pobjUID, __GO_POLYLINE_STYLE__, &plot, jni_int, 1);
679
680     /*
681      * Initializes the contour properties (background, foreground, etc)
682      * to the default values (those of the parent Axes).
683      */
684     cloneGraphicContext(pparentsubwinUID, pobjUID);
685
686     /* colors and marks setting */
687     setGraphicObjectProperty(pobjUID, __GO_MARK_MODE__, &ismark, jni_bool, 1);
688     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
689     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
690
691     /* shading interpolation vector and mode */
692     setGraphicObjectProperty(pobjUID, __GO_INTERP_COLOR_MODE__, &isinterpshaded, jni_bool, 1);
693
694     if (foreground != NULL)
695     {
696         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
697     }
698
699     if (background != NULL)
700     {
701         if (isinterpshaded == TRUE)
702         {
703             /* 3 or 4 values to store */
704
705             setGraphicObjectProperty(pobjUID, __GO_INTERP_COLOR_VECTOR__, background, jni_int_vector, n1);
706         }
707         else
708         {
709             setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
710         }
711     }
712
713     if (mark_style != NULL)
714     {
715         /* This does use the MVC */
716         setGraphicObjectProperty(pobjUID, __GO_MARK_STYLE__, mark_style, jni_int, 1);
717     }
718
719     if (mark_foreground != NULL)
720     {
721         setGraphicObjectProperty(pobjUID, __GO_MARK_FOREGROUND__, mark_foreground, jni_int, 1);
722     }
723
724     if (mark_background != NULL)
725     {
726         setGraphicObjectProperty(pobjUID, __GO_MARK_BACKGROUND__, mark_background, jni_int, 1);
727     }
728
729     visible = 1;
730     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
731
732     return pobjUID;
733 }
734
735 /*---------------------------------------------------------------------------------*/
736 /**ConstructPolyline
737  * This function creates  Polyline 2d structure
738  */
739 char * ConstructPolyline(char * pparentsubwinUID, double *pvecx, double *pvecy, double *pvecz,
740                          int closed, int n1, int plot, int *foreground, int *background,
741                          int *mark_style, int *mark_foreground, int *mark_background, BOOL isline, BOOL isfilled, BOOL ismark, BOOL isinterpshaded)
742 {
743     char * pobjUID = allocatePolyline(pparentsubwinUID, pvecx, pvecy, pvecz, closed, n1, plot,
744                                       foreground, background, mark_style, mark_foreground, mark_background,
745                                       isline, isfilled, ismark, isinterpshaded);
746     return pobjUID;
747 }
748
749 /**ConstructArc
750  * This function creates an Arc structure
751  */
752 char * ConstructArc(char * pparentsubwinUID, double x, double y,
753                     double height, double width, double alphabegin, double alphaend, int *foreground, int *background, BOOL isfilled, BOOL isline)
754 {
755     char *pobjUID = NULL;
756     int type = -1;
757     int *piType = &type;
758     double upperLeftPoint[3];
759     double *clipRegion = NULL;
760     int visible = 0;
761     int *piVisible = &visible;
762     int arcDrawingMethod = 0;
763     int *piArcDrawingMethod = &arcDrawingMethod;
764     int clipRegionSet = 0;
765     int *piClipRegionSet = &clipRegionSet;
766     int clipState = 0;
767     int *piClipState = &clipState;
768
769     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piType);
770
771     if (type != __GO_AXES__)
772     {
773         Scierror(999, _("The parent has to be a SUBWIN\n"));
774         return (char *)NULL;
775     }
776
777     pobjUID = (char *)createGraphicObject(__GO_ARC__);
778
779     /*
780      * Sets the arc's parent in order to initialize the former's Contoured properties
781      * with the latter's values (cloneGraphicContext call below)
782      */
783     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
784
785     upperLeftPoint[0] = x;
786     upperLeftPoint[1] = y;
787     upperLeftPoint[2] = 0.0;
788
789     setGraphicObjectProperty(pobjUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
790
791     setGraphicObjectProperty(pobjUID, __GO_HEIGHT__, &height, jni_double, 1);
792     setGraphicObjectProperty(pobjUID, __GO_WIDTH__, &width, jni_double, 1);
793
794     setGraphicObjectProperty(pobjUID, __GO_START_ANGLE__, &alphabegin, jni_double, 1);
795     setGraphicObjectProperty(pobjUID, __GO_END_ANGLE__, &alphaend, jni_double, 1);
796
797     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
798
799     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
800
801     getGraphicObjectProperty(pparentsubwinUID, __GO_ARC_DRAWING_METHOD__, jni_int, (void **)&piArcDrawingMethod);
802
803     setGraphicObjectProperty(pobjUID, __GO_ARC_DRAWING_METHOD__, &arcDrawingMethod, jni_int, 1);
804
805     /*
806      * Clip state and region
807      * To be checked for consistency
808      */
809     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
810     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
811     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
812
813     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
814     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
815
816     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
817     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
818
819     /*
820      * Initializes the contour properties (background, foreground, etc)
821      * to the parent Axes' values.
822      */
823     cloneGraphicContext(pparentsubwinUID, pobjUID);
824
825     /* Contour settings */
826     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
827     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
828
829     if (foreground != NULL)
830     {
831         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
832     }
833
834     if (background != NULL)
835     {
836         setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
837     }
838
839     /* Parent reset to the null object */
840     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
841
842     /*
843      * Sets the Axes as the arc's parent and adds the arc to
844      * its parent's list of children.
845      */
846     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
847
848     return pobjUID;
849 }
850
851 /**ConstructRectangle
852  * This function creates Rectangle structure and only this to destroy all sons use DelGraphicsSon
853  */
854 char * ConstructRectangle(char * pparentsubwinUID, double x, double y,
855                           double height, double width, int *foreground, int *background, int isfilled, int isline)
856 {
857     char *pobjUID = NULL;
858     char *type = NULL;
859     double upperLeftPoint[3];
860     double *clipRegion = NULL;
861     int visible = 0;
862     int *piVisible = &visible;
863     int clipRegionSet = 0;
864     int *piClipRegionSet = &clipRegionSet;
865     int clipState = 0;
866     int *piClipState = &clipState;
867     int iMarkMode = 0;
868     int *piMarkMode = &iMarkMode;
869
870     if (height < 0.0 || width < 0.0)
871     {
872         Scierror(999, _("Width and height must be positive.\n"));
873         return NULL;
874     }
875
876     pobjUID = (char *)createGraphicObject(__GO_RECTANGLE__);
877
878     /*
879      * Sets the rectangle's parent in order to initialize the former's Contoured properties
880      * with the latter's values (cloneGraphicContext call below)
881      */
882     //setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
883
884     upperLeftPoint[0] = x;
885     upperLeftPoint[1] = y;
886     upperLeftPoint[2] = 0.0;
887
888     setGraphicObjectProperty(pobjUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
889
890     setGraphicObjectProperty(pobjUID, __GO_HEIGHT__, &height, jni_double, 1);
891     setGraphicObjectProperty(pobjUID, __GO_WIDTH__, &width, jni_double, 1);
892
893     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
894     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
895
896     /* Clip state and region */
897     /* To be checked for consistency */
898
899     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
900     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
901     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
902
903     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
904     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
905
906     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
907     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
908
909     getGraphicObjectProperty(pparentsubwinUID, __GO_MARK_MODE__, jni_bool, (void **)&piMarkMode);
910     setGraphicObjectProperty(pobjUID, __GO_MARK_MODE__, &iMarkMode, jni_bool, 1);
911
912     /*
913      * Initializes the contour properties (background, foreground, etc)
914      * to the default values (those of the parent Axes).
915      */
916     cloneGraphicContext(pparentsubwinUID, pobjUID);
917
918     /* Contour settings */
919     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &isline, jni_bool, 1);
920     setGraphicObjectProperty(pobjUID, __GO_FILL_MODE__, &isfilled, jni_bool, 1);
921
922     if (foreground != NULL)
923     {
924         setGraphicObjectProperty(pobjUID, __GO_LINE_COLOR__, foreground, jni_int, 1);
925     }
926
927     if (background != NULL)
928     {
929         setGraphicObjectProperty(pobjUID, __GO_BACKGROUND__, background, jni_int, 1);
930     }
931
932     /* Parent reset to the null object */
933     //setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
934
935     /*
936      * Sets the Axes as the rectangle's parent and adds the rectangle to
937      * its parent's list of children.
938      */
939     //setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
940
941     return pobjUID;
942 }
943
944 /**ConstructSurface
945  * This function creates Surface Structure
946  */
947 char *ConstructSurface(char *pparentsubwinUID, sciTypeOf3D typeof3d,
948                        double *pvecx, double *pvecy, double *pvecz, double *zcol,
949                        int izcol, int dimzx, int dimzy,
950                        int *flag, double *ebox, int flagcolor, int *isfac, int *m1, int *n1, int *m2, int *n2, int *m3, int *n3, int *m3n, int *n3n)
951 {
952     char *pobjUID = NULL;
953     int parentType = -1;
954     int *piParentType = &parentType;
955     int const surfaceTypes[2] = { __GO_PLOT3D__, __GO_FAC3D__ };
956
957     double *clipRegion = NULL;
958
959     int nx = 0, ny = 0, nz = 0, nc = 0;
960     int result = 0;
961     int clipRegionSet = 0;
962     int *piClipRegionSet = &clipRegionSet;
963     int clipState = 0;
964     int *piClipState = &clipState;
965     int visible = 0;
966     int *piVisible = &visible;
967     int cdataMapping = 0;
968     int hiddenColor = 0;
969     int *piHiddenColor = &hiddenColor;
970     int surfaceMode = 0;
971
972     /* To be modified: the MVC does not allow Plot3d objects with color data yet */
973     if (typeof3d == SCI_PLOT3D)
974     {
975         nx = dimzx;
976         ny = dimzy;
977         nz = dimzx * dimzy;
978         if (flagcolor == 2)
979         {
980             /* one color per facet: nc = dimzx * dimzy */
981             nc = nz;
982         }
983         else if (flagcolor == 3)
984         {
985             /*
986              * one color per edge: nc = 4* dimzx * dimzy ??????
987              * 3 or 4 vertices are needed: I think we take 4 to have enough allocated memory
988              */
989             nc = nz * 4;
990         }
991         /* made by Djalel : comes from the genfac3d case */
992         else
993         {
994             nc = 0;
995         }
996     }
997     /* DJ.A 2003 */
998     else
999     {
1000         /* case SCI_FAC3D */
1001         nx = dimzx * dimzy;
1002         ny = dimzx * dimzy;
1003         nz = dimzx * dimzy;
1004         if (flagcolor == 2)
1005         {
1006             /* one color per facet: nc = dimzy */
1007             nc = dimzy;
1008         }
1009         else if (flagcolor == 3)
1010         {
1011             /* one color per edge: nc = dimzx * dimzy */
1012             nc = nz;
1013         }
1014         else
1015         {
1016             nc = 0;
1017         }
1018     }
1019
1020     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1021
1022     /* test using sciGetEntityType replaced by a test on the type string */
1023     if (parentType != __GO_AXES__)
1024     {
1025         Scierror(999, _("The parent has to be a SUBWIN\n"));
1026         return NULL;
1027     }
1028
1029     pobjUID = (char *)createGraphicObject(surfaceTypes[*isfac]);
1030     createDataObject(pobjUID, surfaceTypes[*isfac]);
1031
1032     /* Clip state and region */
1033     /* To be checked for consistency */
1034
1035     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1036     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1037     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1038
1039     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1040     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1041
1042     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1043     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1044
1045     /* Visibility */
1046     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1047
1048     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1049
1050     setGraphicObjectProperty(pobjUID, __GO_COLOR_FLAG__, &flagcolor, jni_int, 1);
1051
1052     /* Direct mode enabled as default */
1053     cdataMapping = 1;
1054
1055     /* Only for Fac3D */
1056     setGraphicObjectProperty(pobjUID, __GO_DATA_MAPPING__, &cdataMapping, jni_int, 1);
1057
1058     setGraphicObjectProperty(pobjUID, __GO_COLOR_MODE__, &flag[0], jni_int, 1);
1059
1060     /* Plot3d case */
1061     if (!*isfac)
1062     {
1063         int gridSize[4];
1064
1065         gridSize[0] = *m1;
1066         gridSize[1] = *n1;
1067         gridSize[2] = *m2;
1068         gridSize[3] = *n2;
1069
1070         /* Allocates the coordinates arrays */
1071         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
1072     }
1073     /* Fac3d case */
1074     else
1075     {
1076         int numElementsArray[3];
1077
1078         /*
1079          * First element: number of n-gons
1080          * Second element: number of vertices per n-gon
1081          * Third element: number of input colors
1082          */
1083         numElementsArray[0] = dimzy;
1084         numElementsArray[1] = dimzx;
1085         numElementsArray[2] = nc;
1086
1087         /* Allocates the coordinates and color arrays */
1088         result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_ELEMENTS_ARRAY__, numElementsArray, jni_int_vector, 3);
1089     }
1090
1091     if (result == 0)
1092     {
1093         deleteGraphicObject(pobjUID);
1094         deleteDataObject(pobjUID);
1095         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1096         return NULL;
1097     }
1098
1099     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, nx);
1100     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, ny);
1101     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z__, pvecz, jni_double_vector, nz);
1102
1103     /* Add the color matrix dimensions as a property ? */
1104     if (nc > 0)
1105     {
1106         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_COLORS__, zcol, jni_double_vector, nc);
1107     }
1108
1109     /*-------END Replaced by: --------*/
1110
1111     getGraphicObjectProperty(pparentsubwinUID, __GO_HIDDEN_COLOR__, jni_int, (void **)&piHiddenColor);
1112     setGraphicObjectProperty(pobjUID, __GO_HIDDEN_COLOR__, &hiddenColor, jni_int, 1);
1113
1114     /*
1115      * surfaceMode set to "on", was previously done by InitGraphicContext, by setting
1116      * the graphic context's line_mode to on, which stood for the surface_mode.
1117      */
1118     surfaceMode = 1;
1119
1120     setGraphicObjectProperty(pobjUID, __GO_SURFACE_MODE__, &surfaceMode, jni_bool, 1);
1121
1122     /*
1123      * Adding a new handle and setting the parent-child relationship is now
1124      * done after data initialization in order to avoid additional
1125      * clean-up.
1126      */
1127     // Here we init old 'graphicContext' by cloning it from parent.
1128     cloneGraphicContext(pparentsubwinUID, pobjUID);
1129     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1130
1131     return pobjUID;
1132 }
1133
1134 /********************** 14/05/2002 *****
1135  **ConstructGrayplot
1136  * This function is used to build Grayplot and Matplot objects.
1137  * It would probably be better to put the code related to Matplot objects
1138  * in a separate build function, as it would avoid having to perform several tests
1139  * on the type parameter. This is done so because Matplot objects were previously
1140  * internally represented by sciGrayplot structures.
1141  */
1142 char *ConstructGrayplot(char *pparentsubwinUID, double *pvecx, double *pvecy, double *pvecz, int n1, int n2, int type)
1143 {
1144     char *pobjUID = NULL;
1145
1146     int const objectTypes[3] = { __GO_GRAYPLOT__, __GO_MATPLOT__, __GO_MATPLOT__ };
1147
1148     int typeParent = -1;
1149     int *piTypeParent = &typeParent;
1150
1151     char *grayplotID = NULL;
1152     int result = 0;
1153     int dataMapping = 0;
1154     int gridSize[4];
1155
1156     int parentVisible = 0;
1157     int *piParentVisible = &parentVisible;
1158     double *clipRegion = NULL;
1159     int clipRegionSet = 0;
1160     int *piClipRegionSet = &clipRegionSet;
1161     int clipState = 0;
1162     int *piClipState = &clipState;
1163     int numElements = 0;
1164
1165     double pdblScale[2];
1166
1167     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piTypeParent);
1168
1169     if (typeParent != __GO_AXES__)
1170     {
1171         Scierror(999, _("The parent has to be a SUBWIN\n"));
1172         return (char *)NULL;
1173     }
1174
1175     pobjUID = (char *)createGraphicObject(objectTypes[type]);
1176     grayplotID = (char *)createDataObject(pobjUID, objectTypes[type]);
1177
1178     if (grayplotID == NULL)
1179     {
1180         deleteGraphicObject(pobjUID);
1181         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1182         return NULL;
1183     }
1184
1185     /* 0: scaled; only used for Grayplot */
1186     if (type == 0)
1187     {
1188         dataMapping = 0;
1189         setGraphicObjectProperty(pobjUID, __GO_DATA_MAPPING__, &dataMapping, jni_int, 1);
1190     }
1191
1192     /* The x and y vectors are column ones */
1193
1194     /*
1195      * For the Grayplot object, the number of rows and columns respectively
1196      * correspond to the grid's x and y dimensions whereas for Matplot objects,
1197      * they respectively correspond to the grid's y and x dimensions.
1198      */
1199     if (type == 0)
1200     {
1201         gridSize[0] = n1;
1202         gridSize[1] = 1;
1203         gridSize[2] = n2;
1204         gridSize[3] = 1;
1205     }
1206     else
1207     {
1208         gridSize[0] = n2;
1209         gridSize[1] = 1;
1210         gridSize[2] = n1;
1211         gridSize[3] = 1;
1212     }
1213
1214     /* Only for Matplot1 objects */
1215     if (type == 2)
1216     {
1217         setGraphicObjectProperty(pobjUID, __GO_MATPLOT_TRANSLATE__, pvecx, jni_double_vector, 2);
1218         pdblScale[0] = (pvecx[2] - pvecx[0]) / (n2 - 1.0);
1219         pdblScale[1] = (pvecx[3] - pvecx[1]) / (n1 - 1.0);
1220         setGraphicObjectProperty(pobjUID, __GO_MATPLOT_SCALE__, pdblScale, jni_double_vector, 2);
1221     }
1222
1223     /* Allocates the coordinates arrays */
1224     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_GRID_SIZE__, gridSize, jni_int_vector, 4);
1225
1226     if (result == 0)
1227     {
1228         deleteGraphicObject(pobjUID);
1229         deleteDataObject(pobjUID);
1230         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1231         return NULL;
1232     }
1233
1234     /* Only for Grayplot objects, for Matplot objects, x and y coordinates are automatically computed */
1235     if (type == 0)
1236     {
1237         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, n1);
1238         setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, n2);
1239     }
1240
1241     if (type == 0)
1242     {
1243         numElements = n1 * n2;
1244     }
1245     else
1246     {
1247         numElements = (n1 - 1) * (n2 - 1);
1248     }
1249
1250     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Z__, pvecz, jni_double_vector, numElements);
1251
1252     /*
1253      * Adding a new handle and setting the parent-child relationship is now
1254      * done after data initialization in order to avoid additional
1255      * clean-up.
1256      */
1257
1258     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1259
1260     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1261     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1262
1263     /*
1264      * Clip state and region
1265      * To be checked for consistency
1266      */
1267     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1268     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1269     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1270
1271     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1272     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1273
1274     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1275     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1276
1277     /* Initializes the default Contour values */
1278     cloneGraphicContext(pparentsubwinUID, pobjUID);
1279
1280     return pobjUID;
1281 }
1282
1283 /**ConstructAxis
1284  * This function creates an Axis object
1285  * @author Djalel ABDEMOUCHE
1286  * @see sciSetCurrentObj
1287  *
1288  */
1289 char *ConstructAxis(char *pparentsubwinUID, char dir, char tics, double *vx,
1290                     int nx, double *vy, int ny, char **str, int subint, char *format,
1291                     int fontsize, int textcolor, int ticscolor, char logscale, int seg, int nb_tics_labels)
1292 {
1293     int parentType = -1;
1294     int *piParentType = &parentType;
1295     char *pobjUID = NULL;
1296     int i = 0;
1297     int clipRegionSet = 0;
1298     int clipState = 0;
1299     int ticksDirection = 0;
1300     int ticksStyle = 0;
1301     double *clipRegion = NULL;
1302     double doubleFontSize = 0.;
1303
1304     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1305
1306     if (parentType != __GO_AXES__)
1307     {
1308         Scierror(999, _("The parent has to be a SUBWIN\n"));
1309         return (char *)NULL;
1310     }
1311
1312     pobjUID = (char *)createGraphicObject(__GO_AXIS__);
1313
1314     /* Required to initialize the default contour properties */
1315     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
1316
1317     /* Clipping: to be checked for consistency */
1318     clipRegionSet = 0;
1319     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1320
1321     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1322     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1323     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1324
1325     /* 0: OFF */
1326     clipState = 0;
1327     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1328
1329     /* The ticks style and direction MVC properties are Integers */
1330     if (dir == 'u')
1331     {
1332         ticksDirection = 0;
1333     }
1334     else if (dir == 'd')
1335     {
1336         ticksDirection = 1;
1337     }
1338     else if (dir == 'l')
1339     {
1340         ticksDirection = 2;
1341     }
1342     else if (dir == 'r')
1343     {
1344         ticksDirection = 3;
1345     }
1346     else
1347     {
1348         ticksDirection = 0;
1349     }
1350
1351     if (tics == 'v')
1352     {
1353         ticksStyle = 0;
1354     }
1355     else if (tics == 'r')
1356     {
1357         ticksStyle = 1;
1358     }
1359     else if (tics == 'i')
1360     {
1361         ticksStyle = 2;
1362     }
1363     else
1364     {
1365         ticksStyle = 0;
1366     }
1367
1368     setGraphicObjectProperty(pobjUID, __GO_TICKS_DIRECTION__, &ticksDirection, jni_int, 1);
1369     setGraphicObjectProperty(pobjUID, __GO_TICKS_STYLE__, &ticksStyle, jni_int, 1);
1370
1371     setGraphicObjectProperty(pobjUID, __GO_X_TICKS_COORDS__, vx, jni_double_vector, nx);
1372     setGraphicObjectProperty(pobjUID, __GO_Y_TICKS_COORDS__, vy, jni_double_vector, ny);
1373
1374     /* FORMATN must be set before Labels are computed. */
1375     if (format != NULL)
1376     {
1377         setGraphicObjectProperty(pobjUID, __GO_FORMATN__, format, jni_string, 1);
1378     }
1379
1380     /*
1381      * Labels are computed automatically depending on the ticks coordinates.
1382      * The computation is performed by a C function which has been adapted
1383      * to the MVC (property get calls) and was previously done in the
1384      * tics labels property get C function.
1385      * It should be done (or called) directly in the Java part of the model
1386      * for the sake of efficiency.
1387      * To be modified
1388      */
1389     if (str == NULL)
1390     {
1391         char **matData;
1392         StringMatrix *tics_labels;
1393
1394         tics_labels = computeDefaultTicsLabels(pobjUID);
1395
1396         if (tics_labels == NULL)
1397         {
1398             deleteGraphicObject(pobjUID);
1399             return (char *)NULL;
1400         }
1401
1402         matData = getStrMatData(tics_labels);
1403
1404         /*
1405          * The labels vector size must be computed using the matrix's dimensions.
1406          * To be modified when the labels computation is moved to the Model.
1407          */
1408         setGraphicObjectProperty(pobjUID, __GO_TICKS_LABELS__, matData, jni_string_vector, tics_labels->nbCol * tics_labels->nbRow);
1409
1410         deleteMatrix(tics_labels);
1411     }
1412     else
1413     {
1414         /*
1415          * Labels are set using the str argument; the previous code tested whether each element of the
1416          * str array was null and set the corresponding Axis' element to NULL, though there was no
1417          * apparent reason to do so. This is still checked, but now aborts building the Axis.
1418          */
1419
1420         if (nb_tics_labels == -1)
1421         {
1422             Scierror(999, _("Impossible case when building axis\n"));
1423             deleteGraphicObject(pobjUID);
1424             releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1425             return NULL;
1426         }
1427
1428         for (i = 0; i < nb_tics_labels; i++)
1429         {
1430             if (str[i] == NULL)
1431             {
1432                 deleteGraphicObject(pobjUID);
1433                 releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1434                 return NULL;
1435             }
1436         }
1437
1438         setGraphicObjectProperty(pobjUID, __GO_TICKS_LABELS__, str, jni_string_vector, nb_tics_labels);
1439     }
1440
1441     setGraphicObjectProperty(pobjUID, __GO_SUBTICKS__, &subint, jni_int, 1);
1442     setGraphicObjectProperty(pobjUID, __GO_TICKS_SEGMENT__, &seg, jni_bool, 1);
1443
1444     /* Initializes the default Contour values */
1445     cloneGraphicContext(pparentsubwinUID, pobjUID);
1446
1447     /* Initializes the default Font values */
1448     cloneFontContext(pparentsubwinUID, pobjUID);
1449
1450     /* Parent reset to the null object */
1451     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
1452
1453     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1454
1455     doubleFontSize = (double)fontsize;
1456
1457     setGraphicObjectProperty(pobjUID, __GO_FONT_SIZE__, &doubleFontSize, jni_double, 1);
1458     setGraphicObjectProperty(pobjUID, __GO_FONT_COLOR__, &textcolor, jni_int, 1);
1459     setGraphicObjectProperty(pobjUID, __GO_TICKS_COLOR__, &ticscolor, jni_int, 1);
1460
1461     return pobjUID;
1462 }
1463
1464 /********************** 21/05/2002 *****
1465  **ConstructFec
1466  * This function creates Fec
1467  * @author Djalel.ABDEMOUCHE
1468  * @see sciSetCurrentObj
1469  */
1470 char *ConstructFec(char *pparentsubwinUID, double *pvecx, double *pvecy, double *pnoeud,
1471                    double *pfun, int Nnode, int Ntr, double *zminmax, int *colminmax, int *colout, BOOL with_mesh)
1472 {
1473     char *pobjUID = NULL;
1474     char *fecId = NULL;
1475     int result = 0;
1476
1477     int parentType = -1;
1478     int *piParentType = &parentType;
1479
1480     int parentVisible = 0;
1481     int *piParentVisible = &parentVisible;
1482
1483     double *clipRegion = NULL;
1484     int clipRegionSet = 0;
1485     int *piClipRegionSet = &clipRegionSet;
1486     int iClipState = 0;
1487     int *piClipState = &iClipState;
1488
1489     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void **)&piParentType);
1490
1491     /* test using sciGetEntityType replaced by a test on the type string */
1492     if (parentType != __GO_AXES__)
1493     {
1494         Scierror(999, _("The parent has to be a SUBWIN\n"));
1495         return (char *)NULL;
1496     }
1497
1498     pobjUID = createGraphicObject(__GO_FEC__);
1499     fecId = (char *)createDataObject(pobjUID, __GO_FEC__);
1500
1501     if (fecId == NULL)
1502     {
1503         deleteGraphicObject(pobjUID);
1504         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1505         return (char *)NULL;
1506     }
1507
1508     /* Allocates the coordinates array */
1509     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_VERTICES__, &Nnode, jni_int, 1);
1510
1511     if (result == 0)
1512     {
1513         deleteGraphicObject(pobjUID);
1514         deleteDataObject(pobjUID);
1515         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1516         return (char *)NULL;
1517     }
1518
1519     /* Allocates the triangle indices and values array */
1520     result = setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_NUM_INDICES__, &Ntr, jni_int, 1);
1521
1522     if (result == 0)
1523     {
1524         deleteGraphicObject(pobjUID);
1525         deleteDataObject(pobjUID);
1526         releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1527         return (char *)NULL;
1528     }
1529
1530     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_X__, pvecx, jni_double_vector, Nnode);
1531     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_Y__, pvecy, jni_double_vector, Nnode);
1532
1533     /* Fec-specific property: triangle indices plus special values (triangle number and flag) */
1534     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_FEC_TRIANGLES__, pnoeud, jni_double_vector, Ntr);
1535
1536     /* Function values */
1537     setGraphicObjectProperty(pobjUID, __GO_DATA_MODEL_VALUES__, pfun, jni_double_vector, Nnode);
1538
1539     setGraphicObjectProperty(pobjUID, __GO_Z_BOUNDS__, zminmax, jni_double_vector, 2);
1540     setGraphicObjectProperty(pobjUID, __GO_COLOR_RANGE__, colminmax, jni_int_vector, 2);
1541     setGraphicObjectProperty(pobjUID, __GO_OUTSIDE_COLOR__, colout, jni_int_vector, 2);
1542
1543     /*
1544      * Adding a new handle and setting the parent-child relationship is now
1545      * done after data initialization in order to avoid additional
1546      * clean-up.
1547      */
1548     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1549
1550     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1551     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1552
1553     /*
1554      * Clip state and region
1555      * To be checked for consistency
1556      */
1557     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1558     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1559     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1560
1561     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1562     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1563
1564     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1565     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &iClipState, jni_int, 1);
1566
1567     /* Initializes the default Contour values */
1568     cloneGraphicContext(pparentsubwinUID, pobjUID);
1569
1570     /* line mode is set using with_mesh */
1571     setGraphicObjectProperty(pobjUID, __GO_LINE_MODE__, &with_mesh, jni_bool, 1);
1572
1573     return pobjUID;
1574 }
1575
1576 /**ConstructSegs
1577  * This function creates Segments
1578  * It is used to create and initialize the data of both the Champ and Segs MVC objects.
1579  * @author Djalel.ABDEMOUCHE
1580  * @version 0.1
1581  * @see sciSetCurrentObj
1582  */
1583 char *ConstructSegs(char *pparentsubwinUID, int type,
1584                     double *vx, double *vy, double *vz,
1585                     int Nbr1, int Nbr2, int Nbr3, double *vfx, double *vfy, int flag, int *style, double arsize, int colored, int typeofchamp)
1586 {
1587     char *pobjUID = NULL;
1588
1589     int visible = 0;
1590     int *piVisible = &visible;
1591     int clipRegionSet = 0;
1592     int *piClipRegionSet = &clipRegionSet;
1593     int clipState = 0;
1594     int *piClipState = &clipState;
1595     int numberArrows = 0;
1596     int dimensions[2];
1597     int i = 0;
1598
1599     double *clipRegion = NULL;
1600     double *arrowCoords = NULL;
1601
1602     if (type == 0)
1603     {
1604         pobjUID = createGraphicObject(__GO_SEGS__);
1605     }
1606     else if (type == 1)
1607     {
1608         pobjUID = createGraphicObject(__GO_CHAMP__);
1609     }
1610     else
1611     {
1612         return (char *)NULL;
1613     }
1614
1615     getGraphicObjectProperty(pparentsubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1616
1617     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1618
1619     /* this must be done prior to the call of Set Clipping property to know */
1620     /* if the clip_state has been set */
1621
1622     /*
1623      * Clip state and region
1624      * To be checked for consistency
1625      */
1626     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX__, jni_double_vector, (void **)&clipRegion);
1627     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1628     releaseGraphicObjectProperty(__GO_CLIP_BOX__, clipRegion, jni_double_vector, 4);
1629
1630     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_BOX_SET__, jni_bool, (void **)&piClipRegionSet);
1631     setGraphicObjectProperty(pobjUID, __GO_CLIP_BOX_SET__, &clipRegionSet, jni_bool, 1);
1632
1633     getGraphicObjectProperty(pparentsubwinUID, __GO_CLIP_STATE__, jni_int, (void **)&piClipState);
1634     setGraphicObjectProperty(pobjUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
1635
1636     if (type == 1)
1637     {
1638         numberArrows = Nbr1 * Nbr2;
1639     }
1640     else
1641     {
1642         /* Segs: Nbr1/2 arrows, Nbr1 is the number of endpoints */
1643         numberArrows = Nbr1 / 2;
1644     }
1645
1646     /* Triggers the creation of the Arrow objects part of Champ or Segs */
1647     setGraphicObjectProperty(pobjUID, __GO_NUMBER_ARROWS__, &numberArrows, jni_int, 1);
1648
1649     /* Champ property only */
1650     if (type == 1)
1651     {
1652         dimensions[0] = Nbr1;
1653         dimensions[1] = Nbr2;
1654
1655         setGraphicObjectProperty(pobjUID, __GO_CHAMP_DIMENSIONS__, dimensions, jni_int_vector, 2);
1656     }
1657
1658     arrowCoords = (double *)MALLOC(3 * numberArrows * sizeof(double));
1659
1660     if (arrowCoords == NULL)
1661     {
1662         deleteGraphicObject(pobjUID);
1663         return (char *)NULL;
1664     }
1665
1666     setGraphicObjectProperty(pobjUID, __GO_ARROW_SIZE__, &arsize, jni_double, 1);
1667
1668     /* Type 0 corresponds to a SEGS object */
1669     if (type == 0)
1670     {
1671         for (i = 0; i < numberArrows; i++)
1672         {
1673             arrowCoords[3 * i] = vx[2 * i];
1674             arrowCoords[3 * i + 1] = vy[2 * i];
1675
1676             if (vz != NULL)
1677             {
1678                 arrowCoords[3 * i + 2] = vz[2 * i];
1679             }
1680             else
1681             {
1682                 arrowCoords[3 * i + 2] = 0.0;
1683             }
1684         }
1685
1686         setGraphicObjectProperty(pobjUID, __GO_BASE__, arrowCoords, jni_double_vector, 3 * numberArrows);
1687
1688         for (i = 0; i < numberArrows; i++)
1689         {
1690             arrowCoords[3 * i] = vx[2 * i + 1];
1691             arrowCoords[3 * i + 1] = vy[2 * i + 1];
1692
1693             if (vz != NULL)
1694             {
1695                 arrowCoords[3 * i + 2] = vz[2 * i + 1];
1696             }
1697             else
1698             {
1699                 arrowCoords[3 * i + 2] = 0.0;
1700             }
1701         }
1702
1703         setGraphicObjectProperty(pobjUID, __GO_DIRECTION__, arrowCoords, jni_double_vector, 3 * numberArrows);
1704
1705         if (flag == 1)
1706         {
1707             /* Style is an array of numberArrows elements */
1708             setGraphicObjectProperty(pobjUID, __GO_SEGS_COLORS__, style, jni_int_vector, numberArrows);
1709         }
1710         else
1711         {
1712             /* Style is a scalar */
1713             setGraphicObjectProperty(pobjUID, __GO_SEGS_COLORS__, style, jni_int_vector, 1);
1714         }
1715
1716     }
1717     else
1718     {
1719         /*
1720          * Type 1 corresponds to a CHAMP object
1721          * so building comes from champg
1722          */
1723         setGraphicObjectProperty(pobjUID, __GO_BASE_X__, vx, jni_double_vector, Nbr1);
1724         setGraphicObjectProperty(pobjUID, __GO_BASE_Y__, vy, jni_double_vector, Nbr2);
1725
1726         for (i = 0; i < numberArrows; i++)
1727         {
1728             arrowCoords[3 * i] = vfx[i];
1729             arrowCoords[3 * i + 1] = vfy[i];
1730             arrowCoords[3 * i + 2] = 0.0;
1731         }
1732
1733         setGraphicObjectProperty(pobjUID, __GO_DIRECTION__, arrowCoords, jni_double_vector, 3 * numberArrows);
1734
1735         /* typeofchamp corresponds to COLORED (0: false, 1: true) */
1736         setGraphicObjectProperty(pobjUID, __GO_COLORED__, &typeofchamp, jni_bool, 1);
1737     }
1738
1739     /* Required to initialize the default contour properties */
1740     setGraphicObjectProperty(pobjUID, __GO_PARENT__, pparentsubwinUID, jni_string, 1);
1741
1742     /* Initializes the default Contour values */
1743     cloneGraphicContext(pparentsubwinUID, pobjUID);
1744
1745     setGraphicObjectProperty(pobjUID, __GO_PARENT__, "", jni_string, 1);
1746
1747     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1748
1749     FREE(arrowCoords);
1750
1751     return pobjUID;
1752 }
1753
1754 /**sciConstructCompound
1755  * constructs a Compound of entities
1756  * do only an association with a parent and a handle reservation !
1757  * check for valid handle can be done using CheckForCompound
1758  */
1759 char *ConstructCompound(long *handelsvalue, int number) /* Conflicting types with definition */
1760 {
1761     char *compoundUID = NULL;
1762     char *parentAxesUID = NULL;
1763     char *firstMovedObjectUID = NULL;
1764
1765     int i = 0;
1766     int parentVisible = 0;
1767     int *piParentVisible = &parentVisible;
1768
1769     compoundUID = createGraphicObject(__GO_COMPOUND__);
1770
1771     /* Add the Compound's handle */
1772     /* The Compound's parent Axes is considered to be the Compound's first child's own parent */
1773     firstMovedObjectUID = (char*)getObjectFromHandle((long)handelsvalue[0]);
1774     getGraphicObjectProperty(firstMovedObjectUID, __GO_PARENT__, jni_string, (void **)&parentAxesUID);
1775
1776     /* Set the parent-child relationship between the Compound and each aggregated object */
1777     for (i = 0; i < number; i++)
1778     {
1779         char *movedObjectUID = (char*)getObjectFromHandle((long)handelsvalue[i]);
1780
1781         setGraphicObjectRelationship(compoundUID, movedObjectUID);
1782     }
1783
1784     /* Sets the parent-child relationship for the Compound */
1785     setGraphicObjectRelationship(parentAxesUID, compoundUID);
1786
1787     getGraphicObjectProperty(parentAxesUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
1788     setGraphicObjectProperty(compoundUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
1789
1790     releaseGraphicObjectProperty(__GO_PARENT__, parentAxesUID, jni_string, 1);
1791
1792     return (char *)compoundUID;
1793 }
1794
1795 /**ConstructCompoundSeq
1796  * constructs a Compound of with the last n entities created in the current subwindow
1797  on entry the subwin children list is
1798  s1->s2->...->sn->sn+1->...->sN
1799  with sn the least recent of the last n entities created and s1 the most recent one
1800  (that is, the last entity created), and N the subwin's initial number of children
1801  on exit it is
1802  A->sn+1->sn+2->...->sN
1803  with A a Compound object whose children list is:
1804  s1->s2->...->sn-1->sn
1805 */
1806 char *ConstructCompoundSeq(int number)
1807 {
1808     char **children = NULL;
1809     char *parentFigure = NULL;
1810     int numberChildren = 0;
1811     int *piNumberChildren = &numberChildren;
1812     int i = 0;
1813     int visible = 0;
1814     int *piVisible = &visible;
1815
1816     char *pobjUID = NULL;
1817     char const* psubwinUID = getCurrentSubWin();
1818
1819     /* Creates the Compound object A */
1820     pobjUID = createGraphicObject(__GO_COMPOUND__);
1821
1822     /* Add the Compound's handle */
1823     getGraphicObjectProperty(psubwinUID, __GO_CHILDREN_COUNT__, jni_int, (void **)&piNumberChildren);
1824
1825     getGraphicObjectProperty(psubwinUID, __GO_CHILDREN__, jni_string_vector, (void **)&children);
1826
1827     /*
1828      * Remove the last "number" created objects (located at the children list's head)
1829      * and add them to the compound in the same order
1830      */
1831     for (i = 0; i < number; i++)
1832     {
1833         /*
1834          * Set the parent-child relationship between the Compound and each aggregated object.
1835          * Children are added to the Compound from the least recent to the most recent, to
1836          * preserve their former ordering.
1837          */
1838         setGraphicObjectRelationship(pobjUID, children[number - i - 1]);
1839     }
1840     releaseGraphicObjectProperty(__GO_CHILDREN__, children, jni_string_vector, numberChildren);
1841
1842     /* Sets the parent-child relationship for the Compound */
1843     setGraphicObjectRelationship(psubwinUID, pobjUID);
1844
1845     /*
1846      * visibility is obtained from the parent Figure, whereas it is retrieved from the
1847      * parent Axes in ConstructCompound.
1848      * To be made consistent.
1849      */
1850     getGraphicObjectProperty(pobjUID, __GO_PARENT_FIGURE__, jni_string, (void **)&parentFigure);
1851     getGraphicObjectProperty(parentFigure, __GO_VISIBLE__, jni_bool, (void **)&piVisible);
1852     releaseGraphicObjectProperty(__GO_PARENT_FIGURE__, parentFigure, jni_string, 1);
1853
1854     setGraphicObjectProperty(pobjUID, __GO_VISIBLE__, &visible, jni_bool, 1);
1855
1856     return (char *)pobjUID;
1857 }
1858
1859 /**ConstructLabel
1860  * This function creates the Label structure used for x,y,z labels and for the Title.
1861  * On the contrary to the other Construct functions, it clones the Axes model's relevant
1862  * label instead of creating a new Label object and performing property sets using
1863  * the values of the Axes model's label, which is done instead by the clone call.
1864  * @param  char *pparentsubwinUID: the parent Axes' identifier.
1865  * @param  char text[] : initial text string, unused.
1866  * @param  int type to get info. on the type of label.
1867  */
1868 void ConstructLabel(char * pparentsubwinUID, char const* text, int type)
1869 {
1870     int const labelProperties[] = { __GO_X_AXIS_LABEL__, __GO_Y_AXIS_LABEL__, __GO_Z_AXIS_LABEL__, __GO_TITLE__ };
1871     int parentType = -1;
1872     int *piParentType = &parentType;
1873     int labelType = 0;
1874     char *modelLabelUID = NULL;
1875     char *pobjUID = NULL;
1876     int autoPosition = 0;
1877     int *piAutoPosition = &autoPosition;
1878     double position[3] = { 1.0, 1.0, 1.0 };
1879
1880     getGraphicObjectProperty(pparentsubwinUID, __GO_TYPE__, jni_int, (void**)&piParentType);
1881
1882     if (parentType != __GO_AXES__)
1883     {
1884         Scierror(999, _("The parent has to be a SUBWIN\n"));
1885         return;
1886     }
1887
1888     if (type < 1 || type > 4)
1889     {
1890         return;
1891     }
1892
1893     labelType = labelProperties[type - 1];
1894
1895     getGraphicObjectProperty(getAxesModel(), labelType, jni_string, (void **)&modelLabelUID);
1896
1897     /* Creates a new Label object with the same properties as the Axes model's corresponding label */
1898     pobjUID = cloneGraphicObject(modelLabelUID);
1899
1900     /* Position set to {1, 1, 1} as a default to take into account logarithmic coordinates */
1901     setGraphicObjectProperty(pobjUID, __GO_POSITION__, position, jni_double_vector, 3);
1902
1903     /* Auto position must be reset as setting the position has set it to false */
1904     getGraphicObjectProperty(modelLabelUID, __GO_AUTO_POSITION__, jni_bool, (void **)&piAutoPosition);
1905     setGraphicObjectProperty(pobjUID, __GO_AUTO_POSITION__, &autoPosition, jni_bool, 1);
1906
1907     /* Attach the cloned label to its parent Axes and set the latter as the label's parent */
1908     setGraphicObjectProperty(pparentsubwinUID, labelType, pobjUID, jni_string, 1);
1909     setGraphicObjectRelationship(pparentsubwinUID, pobjUID);
1910
1911     releaseGraphicObjectProperty(labelType, modelLabelUID, jni_string, 1);
1912     releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
1913 }