1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien
3 	CALISTE, laboratoire L_Sim, (20016)
4 
5 	Adresse mèl :
6 	CALISTE, damien P caliste AT cea P fr.
7 
8 	Ce logiciel est un programme informatique servant à visualiser des
9 	structures atomiques dans un rendu pseudo-3D.
10 
11 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
12 	respectant les principes de diffusion des logiciels libres. Vous pouvez
13 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
14 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
15 	sur le site "http://www.cecill.info".
16 
17 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
18 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
19 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
20 */
21 
22 /*   LICENCE SUM UP
23 	Copyright CEA, contributors : Damien
24 	CALISTE, laboratoire L_Sim, (20016)
25 
26 	E-mail address:
27 	CALISTE, damien P caliste AT cea P fr.
28 
29 	This software is a computer program whose purpose is to visualize atomic
30 	configurations in 3D.
31 
32 	This software is governed by the CeCILL  license under French law and
33 	abiding by the rules of distribution of free software.  You can  use,
34 	modify and/ or redistribute the software under the terms of the CeCILL
35 	license as circulated by CEA, CNRS and INRIA at the following URL
36 	"http://www.cecill.info".
37 
38 	The fact that you are presently reading this means that you have had
39 	knowledge of the CeCILL license and that you accept its terms. You can
40 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
41 */
42 #include "mapset.h"
43 
44 /**
45  * SECTION:mapset
46  * @short_description: Defines methods to draw maps that share a same #VisuScalarField.
47  *
48  * <para>Maps are coloured representation of a #VisuScalarField on a #VisuPlane.</para>
49  */
50 
51 /**
52  * VisuGlExtMapSetClass:
53  * @parent: the parent class;
54  *
55  * A short way to identify #_VisuGlExtMapSetClass structure.
56  *
57  * Since: 3.8
58  */
59 /**
60  * VisuGlExtMapSet:
61  *
62  * An opaque structure.
63  *
64  * Since: 3.8
65  */
66 /**
67  * VisuGlExtMapSetPrivate:
68  *
69  * Private fields for #VisuGlExtMapSet objects.
70  *
71  * Since: 3.8
72  */
73 struct _VisuGlExtMapSetPrivate
74 {
75   gboolean dispose_has_run;
76 
77   VisuScalarField *field;
78   gulong sig_chg;
79 
80   GHashTable *maps;
81 
82   /* General values. */
83   float prec;
84   gboolean alpha;
85   guint nLines;
86   gboolean useManualRange;
87   float manualMinMax[2];
88   float drawnMinMax[2];
89   ToolMatrixScalingFlag scale;
90   ToolShade *shade;
91   ToolColor *color;
92 
93   VisuGlExtShade *extLegend;
94 };
95 
96 struct _mapData
97 {
98   VisuMap *map;
99   gulong changed_sig;
100   VisuPlane *plane;
101   gboolean planeStatus;
102 };
103 
104 enum
105   {
106     PROP_0,
107     FIELD_PROP,
108     COLOR_PROP,
109     SHADE_PROP,
110     PRECISION_PROP,
111     ALPHA_PROP,
112     N_LINES_PROP,
113     SCALE_PROP,
114     USE_MANUAL_MM_PROP,
115     MANUAL_MM_PROP,
116     MANUAL_MIN_PROP,
117     MANUAL_MAX_PROP,
118     N_PROP
119   };
120 static GParamSpec *_properties[N_PROP];
121 
122 static void visu_gl_ext_map_set_finalize(GObject* obj);
123 static void visu_gl_ext_map_set_dispose(GObject* obj);
124 static void visu_gl_ext_map_set_get_property(GObject* obj, guint property_id,
125                                           GValue *value, GParamSpec *pspec);
126 static void visu_gl_ext_map_set_set_property(GObject* obj, guint property_id,
127                                              const GValue *value, GParamSpec *pspec);
128 static gboolean visu_gl_ext_map_set_add(VisuGlExtMaps *maps, VisuMap *map,
129                                         float prec, ToolShade *shade,
130                                         const ToolColor *color, gboolean alpha);
131 static void visu_gl_ext_map_set_added(VisuGlExtMaps *maps, VisuMap *map);
132 static void visu_gl_ext_map_set_removed(VisuGlExtMaps *maps, VisuMap *map);
133 
134 /* Local callbacks */
135 static void onMapChange(VisuMap *map, gpointer data);
136 static void onFieldChanged(VisuScalarField *field, gpointer data);
137 
138 /* Local routines. */
_newMapData(VisuGlExtMapSet * maps,VisuMap * map)139 static struct _mapData* _newMapData(VisuGlExtMapSet *maps, VisuMap *map)
140 {
141   struct _mapData *data = g_malloc(sizeof(struct _mapData));
142 
143   data->map = map;
144   data->changed_sig = g_signal_connect(G_OBJECT(map), "changed",
145                                        G_CALLBACK(onMapChange), (gpointer)maps);
146   data->plane = (VisuPlane*)0;
147   return data;
148 }
_freeMapData(struct _mapData * data)149 static void _freeMapData(struct _mapData *data)
150 {
151   DBG_fprintf(stderr, "Extension MapSet: freeing handle on map %p.\n",
152               (gpointer)data->map);
153   g_signal_handler_disconnect(G_OBJECT(data->map), data->changed_sig);
154   if (data->plane)
155     {
156       visu_plane_setRendered(data->plane, data->planeStatus);
157       g_object_unref(data->plane);
158     }
159 }
_setLeg(GBinding * bind _U_,const GValue * from,GValue * to,gpointer data)160 static gboolean _setLeg(GBinding *bind _U_, const GValue *from,
161                         GValue *to, gpointer data)
162 {
163   g_value_set_boolean(to, g_value_get_boolean(from) &&
164                       g_hash_table_size(VISU_GL_EXT_MAP_SET(data)->priv->maps) > 0);
165   return TRUE;
166 }
167 
G_DEFINE_TYPE_WITH_CODE(VisuGlExtMapSet,visu_gl_ext_map_set,VISU_TYPE_GL_EXT_MAPS,G_ADD_PRIVATE (VisuGlExtMapSet))168 G_DEFINE_TYPE_WITH_CODE(VisuGlExtMapSet, visu_gl_ext_map_set, VISU_TYPE_GL_EXT_MAPS,
169                         G_ADD_PRIVATE(VisuGlExtMapSet))
170 
171 static void visu_gl_ext_map_set_class_init(VisuGlExtMapSetClass *klass)
172 {
173   DBG_fprintf(stderr, "Extension MapSet: creating the class of the object.\n");
174   /* DBG_fprintf(stderr, "                - adding new signals ;\n"); */
175 
176   /* Connect the overloading methods. */
177   G_OBJECT_CLASS(klass)->dispose  = visu_gl_ext_map_set_dispose;
178   G_OBJECT_CLASS(klass)->finalize = visu_gl_ext_map_set_finalize;
179   G_OBJECT_CLASS(klass)->set_property = visu_gl_ext_map_set_set_property;
180   G_OBJECT_CLASS(klass)->get_property = visu_gl_ext_map_set_get_property;
181   VISU_GL_EXT_MAPS_CLASS(klass)->add = visu_gl_ext_map_set_add;
182   VISU_GL_EXT_MAPS_CLASS(klass)->added = visu_gl_ext_map_set_added;
183   VISU_GL_EXT_MAPS_CLASS(klass)->removed = visu_gl_ext_map_set_removed;
184 
185   /**
186    * VisuGlExtMapSet::field:
187    *
188    * Store the field maps are drawn from.
189    *
190    * Since: 3.8
191    */
192   _properties[FIELD_PROP] = g_param_spec_object("field", "Field",
193                                                 "field storing 3D data",
194                                                 VISU_TYPE_SCALAR_FIELD,
195                                                 G_PARAM_READWRITE);
196   g_object_class_install_property(G_OBJECT_CLASS(klass), FIELD_PROP,
197 				  _properties[FIELD_PROP]);
198   /**
199    * VisuGlExtMapSet::line-color:
200    *
201    * Store the colour used to draw isolines.
202    *
203    * Since: 3.8
204    */
205   _properties[COLOR_PROP] = g_param_spec_boxed("line-color", "Line color",
206                                                "colour used to draw isolines",
207                                                TOOL_TYPE_COLOR, G_PARAM_READWRITE);
208   g_object_class_install_property(G_OBJECT_CLASS(klass), COLOR_PROP,
209 				  _properties[COLOR_PROP]);
210   /**
211    * VisuGlExtMapSet::shade:
212    *
213    * Store the shade used to colourise the map.
214    *
215    * Since: 3.8
216    */
217   _properties[SHADE_PROP] = g_param_spec_boxed("shade", "Shade",
218                                                "shade used to colourise the map",
219                                                TOOL_TYPE_SHADE, G_PARAM_READWRITE);
220   g_object_class_install_property(G_OBJECT_CLASS(klass), SHADE_PROP,
221 				  _properties[SHADE_PROP]);
222   /**
223    * VisuGlExtMapSet::precision:
224    *
225    * Store the adaptatbility level used to render mapSet.
226    *
227    * Since: 3.8
228    */
229   _properties[PRECISION_PROP] = g_param_spec_float("precision", "Precision",
230                                                    "map degree of adaptability",
231                                                    10.f, 200.f, 100.f, G_PARAM_READWRITE);
232   g_object_class_install_property(G_OBJECT_CLASS(klass), PRECISION_PROP,
233 				  _properties[PRECISION_PROP]);
234   /**
235    * VisuGlExtMapSet::transparent:
236    *
237    * Define if field value is transfered to alpha channel also.
238    *
239    * Since: 3.8
240    */
241   _properties[ALPHA_PROP] = g_param_spec_boolean("transparent", "Transparent",
242                                                  "use alpha channel according to field values",
243                                                  FALSE, G_PARAM_READWRITE);
244   g_object_class_install_property(G_OBJECT_CLASS(klass), ALPHA_PROP,
245 				  _properties[ALPHA_PROP]);
246   /**
247    * VisuGlExtMapSet::n-lines:
248    *
249    * Define how many lines are drawn in full range.
250    *
251    * Since: 3.8
252    */
253   _properties[N_LINES_PROP] = g_param_spec_uint("n-lines", "N lines",
254                                                 "number of lines is the full range",
255                                                 0, G_MAXUINT, 0, G_PARAM_READWRITE);
256   g_object_class_install_property(G_OBJECT_CLASS(klass), N_LINES_PROP,
257 				  _properties[N_LINES_PROP]);
258   /**
259    * VisuGlExtMapSet::scale:
260    *
261    * Define how to scale input values into [0;1].
262    *
263    * Since: 3.8
264    */
265   _properties[SCALE_PROP] = g_param_spec_uint("scale", "Scale",
266                                               "scaling method",
267                                               0, TOOL_MATRIX_SCALING_N_VALUES - 1,
268                                               TOOL_MATRIX_SCALING_LINEAR,
269                                               G_PARAM_READWRITE);
270   g_object_class_install_property(G_OBJECT_CLASS(klass), SCALE_PROP,
271 				  _properties[SCALE_PROP]);
272   /**
273    * VisuGlExtMapSet::use-manual-range:
274    *
275    * True, when mapSet are scaled according to a manual range.
276    *
277    * Since: 3.8
278    */
279   _properties[USE_MANUAL_MM_PROP] = g_param_spec_boolean("use-manual-range",
280                                                          "Use manual range",
281                                                          "use manual range",
282                                                          FALSE, G_PARAM_READWRITE);
283   g_object_class_install_property(G_OBJECT_CLASS(klass), USE_MANUAL_MM_PROP,
284 				  _properties[USE_MANUAL_MM_PROP]);
285   /**
286    * VisuGlExtMapSet::manual-range:
287    *
288    * Min / max range as used to normalise data.
289    *
290    * Since: 3.8
291    */
292   _properties[MANUAL_MM_PROP] = g_param_spec_boxed("manual-range", "Manual range",
293                                                    "manual range values",
294                                                    G_TYPE_ARRAY,
295                                                    G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
296   g_object_class_install_property
297     (G_OBJECT_CLASS(klass), MANUAL_MM_PROP, _properties[MANUAL_MM_PROP]);
298   /**
299    * VisuGlExtMapSet::manual-range-min:
300    *
301    * Min range as used to normalise data.
302    *
303    * Since: 3.8
304    */
305   _properties[MANUAL_MIN_PROP] = g_param_spec_float("manual-range-min",
306                                                     "Manual range minimum",
307                                                     "manual range minimum value",
308                                                     -G_MAXFLOAT, G_MAXFLOAT, -G_MAXFLOAT,
309                                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
310   g_object_class_install_property
311     (G_OBJECT_CLASS(klass), MANUAL_MIN_PROP, _properties[MANUAL_MIN_PROP]);
312   /**
313    * VisuGlExtMapSet::manual-range-max:
314    *
315    * Max range as used to normalise data.
316    *
317    * Since: 3.8
318    */
319   _properties[MANUAL_MAX_PROP] = g_param_spec_float("manual-range-max",
320                                                     "Manual range maximum",
321                                                     "manual range maximum value",
322                                                     -G_MAXFLOAT, G_MAXFLOAT, -G_MAXFLOAT,
323                                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
324   g_object_class_install_property
325     (G_OBJECT_CLASS(klass), MANUAL_MAX_PROP, _properties[MANUAL_MAX_PROP]);
326 }
327 
visu_gl_ext_map_set_init(VisuGlExtMapSet * obj)328 static void visu_gl_ext_map_set_init(VisuGlExtMapSet *obj)
329 {
330   DBG_fprintf(stderr, "Extension MapSet: initializing a new object (%p).\n",
331 	      (gpointer)obj);
332 
333   obj->priv = visu_gl_ext_map_set_get_instance_private(obj);
334   obj->priv->dispose_has_run = FALSE;
335 
336   /* Private data. */
337   obj->priv->field           = (VisuScalarField*)0;
338   obj->priv->maps            = g_hash_table_new_full(g_direct_hash, g_direct_equal,
339                                                      NULL, (GDestroyNotify)_freeMapData);
340   obj->priv->color           = (ToolColor*)0;
341   obj->priv->shade           = (ToolShade*)0;
342   obj->priv->prec            = 100.f;
343   obj->priv->alpha           = FALSE;
344   obj->priv->nLines          = 0;
345   obj->priv->useManualRange  = FALSE;
346   obj->priv->drawnMinMax[0]  =  G_MAXFLOAT;
347   obj->priv->drawnMinMax[1]  = -G_MAXFLOAT;
348   obj->priv->manualMinMax[0] = -G_MAXFLOAT;
349   obj->priv->manualMinMax[1] =  G_MAXFLOAT;
350   obj->priv->scale           = TOOL_MATRIX_SCALING_LINEAR;
351   obj->priv->extLegend       = visu_gl_ext_shade_new("Map legend");
352   g_object_bind_property_full(G_OBJECT(obj), "active",
353                               G_OBJECT(obj->priv->extLegend), "active",
354                               G_BINDING_SYNC_CREATE, _setLeg, NULL, obj, NULL);
355   visu_gl_ext_frame_setScale(VISU_GL_EXT_FRAME(obj->priv->extLegend),
356                              visu_map_getLegendScale());
357   visu_gl_ext_frame_setPosition(VISU_GL_EXT_FRAME(obj->priv->extLegend),
358                                 visu_map_getLegendPosition(TOOL_XYZ_X),
359                                 visu_map_getLegendPosition(TOOL_XYZ_Y));
360 }
visu_gl_ext_map_set_dispose(GObject * obj)361 static void visu_gl_ext_map_set_dispose(GObject* obj)
362 {
363   VisuGlExtMapSet *mapSet = VISU_GL_EXT_MAP_SET(obj);
364 
365   DBG_fprintf(stderr, "Extension MapSet: dispose object %p.\n", (gpointer)obj);
366   if (mapSet->priv->dispose_has_run)
367     return;
368 
369   mapSet->priv->dispose_has_run = TRUE;
370   g_object_unref(mapSet->priv->extLegend);
371   visu_gl_ext_map_set_setField(mapSet, (VisuScalarField*)0);
372   g_hash_table_remove_all(mapSet->priv->maps);
373 
374   /* Chain up to the parent class */
375   G_OBJECT_CLASS(visu_gl_ext_map_set_parent_class)->dispose(obj);
376 }
visu_gl_ext_map_set_finalize(GObject * obj)377 static void visu_gl_ext_map_set_finalize(GObject* obj)
378 {
379   g_return_if_fail(obj);
380 
381   DBG_fprintf(stderr, "Extension MapSet: finalize object %p.\n", (gpointer)obj);
382   g_hash_table_destroy(VISU_GL_EXT_MAP_SET(obj)->priv->maps);
383 
384   /* Chain up to the parent class */
385   DBG_fprintf(stderr, "Extension MapSet: chain to parent.\n");
386   G_OBJECT_CLASS(visu_gl_ext_map_set_parent_class)->finalize(obj);
387   DBG_fprintf(stderr, "Extension MapSet: freeing ... OK.\n");
388 }
visu_gl_ext_map_set_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)389 static void visu_gl_ext_map_set_get_property(GObject* obj, guint property_id,
390                                          GValue *value, GParamSpec *pspec)
391 {
392   GArray *arr;
393   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(obj);
394 
395   DBG_fprintf(stderr, "Extension MapSet: get property '%s' -> ",
396 	      g_param_spec_get_name(pspec));
397   switch (property_id)
398     {
399     case FIELD_PROP:
400       g_value_set_object(value, self->priv->field);
401       DBG_fprintf(stderr, "%p.\n", (gpointer)self->priv->field);
402       break;
403     case SHADE_PROP:
404       g_value_set_boxed(value, self->priv->shade);
405       DBG_fprintf(stderr, "%p.\n", (gpointer)self->priv->shade);
406       break;
407     case COLOR_PROP:
408       g_value_set_boxed(value, self->priv->color);
409       DBG_fprintf(stderr, "%p.\n", (gpointer)self->priv->color);
410       break;
411     case PRECISION_PROP:
412       g_value_set_float(value, self->priv->prec);
413       DBG_fprintf(stderr, "%g.\n", self->priv->prec);
414       break;
415     case ALPHA_PROP:
416       g_value_set_boolean(value, self->priv->alpha);
417       DBG_fprintf(stderr, "%d.\n", self->priv->alpha);
418       break;
419     case N_LINES_PROP:
420       g_value_set_uint(value, self->priv->nLines);
421       DBG_fprintf(stderr, "%u.\n", self->priv->nLines);
422       break;
423     case SCALE_PROP:
424       g_value_set_uint(value, self->priv->scale);
425       DBG_fprintf(stderr, "%u.\n", self->priv->scale);
426       break;
427     case USE_MANUAL_MM_PROP:
428       g_value_set_boolean(value, self->priv->useManualRange);
429       DBG_fprintf(stderr, "%d.\n", self->priv->useManualRange);
430       break;
431     case MANUAL_MM_PROP:
432       arr = g_array_sized_new(FALSE, FALSE, sizeof(float) * 2, 2);
433       g_array_append_vals(arr, self->priv->manualMinMax, 2);
434       g_value_take_boxed(value, self->priv->manualMinMax);
435       DBG_fprintf(stderr, "%p.\n", (gpointer)arr);
436       break;
437     case MANUAL_MIN_PROP:
438       g_value_set_float(value, self->priv->manualMinMax[0]);
439       DBG_fprintf(stderr, "%g.\n", self->priv->manualMinMax[0]);
440       break;
441     case MANUAL_MAX_PROP:
442       g_value_set_float(value, self->priv->manualMinMax[1]);
443       DBG_fprintf(stderr, "%g.\n", self->priv->manualMinMax[1]);
444       break;
445     default:
446       /* We don't have any other property... */
447       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
448       break;
449     }
450 }
visu_gl_ext_map_set_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)451 static void visu_gl_ext_map_set_set_property(GObject* obj, guint property_id,
452                                           const GValue *value, GParamSpec *pspec)
453 {
454   GArray *arr;
455   float mm[2];
456   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(obj);
457 
458   DBG_fprintf(stderr, "Extension MapSet: set property '%s' -> ",
459 	      g_param_spec_get_name(pspec));
460   switch (property_id)
461     {
462     case FIELD_PROP:
463       DBG_fprintf(stderr, "%p.\n", g_value_get_object(value));
464       visu_gl_ext_map_set_setField(self, VISU_SCALAR_FIELD(g_value_get_object(value)));
465       break;
466     case COLOR_PROP:
467       DBG_fprintf(stderr, "%p.\n", g_value_get_boxed(value));
468       visu_gl_ext_map_set_setLineColor(self, (ToolColor*)g_value_get_boxed(value));
469       break;
470     case SHADE_PROP:
471       DBG_fprintf(stderr, "%p.\n", g_value_get_boxed(value));
472       visu_gl_ext_map_set_setShade(self, (ToolShade*)g_value_get_boxed(value));
473       break;
474     case PRECISION_PROP:
475       DBG_fprintf(stderr, "%g.\n", g_value_get_float(value));
476       visu_gl_ext_map_set_setPrecision(self, g_value_get_float(value));
477       break;
478     case ALPHA_PROP:
479       DBG_fprintf(stderr, "%d.\n", g_value_get_boolean(value));
480       visu_gl_ext_map_set_setTransparent(self, g_value_get_boolean(value));
481       break;
482     case N_LINES_PROP:
483       DBG_fprintf(stderr, "%u.\n", g_value_get_uint(value));
484       visu_gl_ext_map_set_setLines(self, g_value_get_uint(value));
485       break;
486     case SCALE_PROP:
487       DBG_fprintf(stderr, "%u.\n", g_value_get_uint(value));
488       visu_gl_ext_map_set_setScaling(self, g_value_get_uint(value));
489       break;
490     case USE_MANUAL_MM_PROP:
491       DBG_fprintf(stderr, "%d.\n", g_value_get_boolean(value));
492       visu_gl_ext_map_set_setScalingRange(self,
493                                        g_value_get_boolean(value) ?
494                                        self->priv->manualMinMax : (const float*)0);
495       break;
496     case MANUAL_MM_PROP:
497       arr = (GArray*)g_value_get_boxed(value);
498       g_return_if_fail(arr && arr->len == 2);
499       if (self->priv->useManualRange)
500         visu_gl_ext_map_set_setScalingRange(self, (float*)arr->data);
501       else
502         {
503           self->priv->manualMinMax[0] = g_array_index(arr, float, 0);
504           self->priv->manualMinMax[1] = g_array_index(arr, float, 1);
505         }
506       break;
507     case MANUAL_MIN_PROP:
508       if (self->priv->useManualRange)
509         {
510           mm[0] = g_value_get_float(value);
511           mm[1] = self->priv->manualMinMax[1];
512           visu_gl_ext_map_set_setScalingRange(self, mm);
513         }
514       else
515         self->priv->manualMinMax[0] = g_value_get_float(value);
516       break;
517     case MANUAL_MAX_PROP:
518       if (self->priv->useManualRange)
519         {
520           mm[0] = self->priv->manualMinMax[0];
521           mm[1] = g_value_get_float(value);
522           visu_gl_ext_map_set_setScalingRange(self, mm);
523         }
524       else
525         self->priv->manualMinMax[1] = g_value_get_float(value);
526       break;
527     default:
528       /* We don't have any other property... */
529       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
530       break;
531     }
532 }
533 
534 /**
535  * visu_gl_ext_map_set_new:
536  * @name: (allow-none): the name to give to the extension.
537  *
538  * Creates a new #VisuGlExt to draw mapSet.
539  *
540  * Since: 3.7
541  *
542  * Returns: a pointer to the #VisuGlExt it created or
543  * NULL otherwise.
544  */
visu_gl_ext_map_set_new(const gchar * name)545 VisuGlExtMapSet* visu_gl_ext_map_set_new(const gchar *name)
546 {
547   char *name_ = "MapSet";
548   char *description = _("Drawing extension for mapSet.");
549   VisuGlExt *extensionMapSet;
550 
551   DBG_fprintf(stderr,"Extension MapSet: new object.\n");
552 
553   extensionMapSet = VISU_GL_EXT(g_object_new(VISU_TYPE_GL_EXT_MAP_SET,
554                                            "name", (name)?name:name_, "label", _(name),
555                                            "description", description, "nGlObj", 1,
556                                            "priority", VISU_GL_EXT_PRIORITY_NORMAL - 1,
557                                            "saveState", TRUE, NULL));
558 
559   return VISU_GL_EXT_MAP_SET(extensionMapSet);
560 }
561 /**
562  * visu_gl_ext_map_set_getLegend:
563  * @mapSet: a #VisuGlExtMapSet object.
564  *
565  * Retrieve the associated #VisuGlExtShade object used to draw the legend.
566  *
567  * Since: 3.8
568  *
569  * Returns: (transfer none): the associated #VisuGlExtShade legend.
570  **/
visu_gl_ext_map_set_getLegend(VisuGlExtMapSet * mapSet)571 VisuGlExtShade* visu_gl_ext_map_set_getLegend(VisuGlExtMapSet *mapSet)
572 {
573   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), (VisuGlExtShade*)0);
574 
575   return mapSet->priv->extLegend;
576 }
577 /**
578  * visu_gl_ext_map_set_setField:
579  * @mapSet: a #VisuGlExtMapSet object.
580  * @field: (transfer none): a #VisuScalarField object.
581  *
582  * Associate @field to the @mapSet.
583  *
584  * Since: 3.8
585  **/
visu_gl_ext_map_set_setField(VisuGlExtMapSet * mapSet,VisuScalarField * field)586 void visu_gl_ext_map_set_setField(VisuGlExtMapSet *mapSet, VisuScalarField *field)
587 {
588   VisuGlExtMapsIter iter;
589 
590   g_return_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet));
591 
592   if (mapSet->priv->field)
593     {
594       g_signal_handler_disconnect(G_OBJECT(mapSet->priv->field), mapSet->priv->sig_chg);
595       g_object_unref(G_OBJECT(mapSet->priv->field));
596     }
597   mapSet->priv->field = field;
598   if (field)
599     {
600       g_object_ref(G_OBJECT(field));
601       mapSet->priv->sig_chg = g_signal_connect(G_OBJECT(field), "changed",
602                                                G_CALLBACK(onFieldChanged), mapSet);
603     }
604   g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[FIELD_PROP]);
605 
606   /* Update stored maps. */
607   for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
608        iter.valid; visu_gl_ext_maps_iter_next(&iter))
609     visu_map_setField(iter.map, field);
610   DBG_fprintf(stderr, "Extension MapSet: setting field %p.\n", (gpointer)field);
611   visu_gl_ext_setActive(VISU_GL_EXT(mapSet->priv->extLegend),
612                         visu_gl_ext_getActive(VISU_GL_EXT(mapSet)) &&
613                         g_hash_table_size(mapSet->priv->maps) > 0 &&
614                         mapSet->priv->field &&
615                         !visu_scalar_field_isEmpty(mapSet->priv->field));
616 }
617 
_legend(VisuGlExtMapSet * mapSet)618 static void _legend(VisuGlExtMapSet *mapSet)
619 {
620   float *marks, minmax[2], inputMM[2] = {G_MAXFLOAT, -G_MAXFLOAT}, factor;
621   guint i;
622   double dmm[2];
623   VisuGlExtMapsIter iter;
624 
625   if (!visu_gl_ext_getActive(VISU_GL_EXT(mapSet->priv->extLegend)))
626     return;
627 
628   if (mapSet->priv->useManualRange)
629     {
630       inputMM[0] = mapSet->priv->manualMinMax[0];
631       inputMM[1] = mapSet->priv->manualMinMax[1];
632       minmax[0] = 0.;
633       minmax[1] = 1.;
634     }
635   else
636     {
637       for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
638            iter.valid; visu_gl_ext_maps_iter_next(&iter))
639         {
640           visu_scalar_field_getMinMax(visu_map_getField(iter.map), dmm);
641           tool_minmax_fromDbl(inputMM, dmm);
642         }
643       minmax[0] = mapSet->priv->drawnMinMax[0];
644       minmax[1] = mapSet->priv->drawnMinMax[1];
645     }
646   visu_gl_ext_shade_setMinMax(mapSet->priv->extLegend, inputMM[0], inputMM[1]);
647 
648   /* Update the shade legend. */
649   marks = g_malloc(sizeof(float) * (2 + mapSet->priv->nLines));
650   factor = (minmax[1] - minmax[0]) / (float)(mapSet->priv->nLines + 1);
651   for (i = 0; i < mapSet->priv->nLines; i++)
652     marks[1 + i] = factor * (float)(i + 1) + minmax[0];
653   marks[0]                        = mapSet->priv->drawnMinMax[0];
654   marks[1 + mapSet->priv->nLines] = mapSet->priv->drawnMinMax[1];
655 
656   visu_gl_ext_shade_setMarks(mapSet->priv->extLegend, marks, 2 + mapSet->priv->nLines);
657 
658   g_free(marks);
659 }
_setLines(VisuGlExtMapSet * mapSet)660 static void _setLines(VisuGlExtMapSet *mapSet)
661 {
662   float minmax[2];
663   VisuGlExtMapsIter iter;
664 
665   if (mapSet->priv->useManualRange)
666     {
667       minmax[0] = 0.;
668       minmax[1] = 1.;
669     }
670   else
671     {
672       minmax[0] = mapSet->priv->drawnMinMax[0];
673       minmax[1] = mapSet->priv->drawnMinMax[1];
674     }
675   for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
676        iter.valid; visu_gl_ext_maps_iter_next(&iter))
677     visu_map_setLines(iter.map, mapSet->priv->nLines, minmax);
678   _legend(mapSet);
679 }
_drawnMinMax(VisuGlExtMapSet * mapSet)680 static gboolean _drawnMinMax(VisuGlExtMapSet *mapSet)
681 {
682   float drawnMinMax[2], oldMinMax[2], minMax[2];
683   VisuGlExtMapsIter iter;
684 
685   oldMinMax[0] = mapSet->priv->drawnMinMax[0];
686   oldMinMax[1] = mapSet->priv->drawnMinMax[1];
687 
688   /* We update the drawnMinMax array. */
689   drawnMinMax[0] = G_MAXFLOAT;
690   drawnMinMax[1] = -G_MAXFLOAT;
691   for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
692        iter.valid; visu_gl_ext_maps_iter_next(&iter))
693     if (visu_map_getScaledMinMax(iter.map, minMax))
694       {
695         drawnMinMax[0] = MIN(drawnMinMax[0], minMax[0]);
696         drawnMinMax[1] = MAX(drawnMinMax[1], minMax[1]);
697       }
698     else
699       return FALSE; /* No global drawn min max available yet. */
700   DBG_fprintf(stderr, "Extension MapSet: global scaled min/max: %g/%g (%g/%g).\n",
701               drawnMinMax[0], drawnMinMax[1],
702               oldMinMax[0], oldMinMax[1]);
703 
704   if (oldMinMax[0] == drawnMinMax[0] && oldMinMax[1] == drawnMinMax[1])
705     return FALSE;
706 
707   mapSet->priv->drawnMinMax[0] = drawnMinMax[0];
708   mapSet->priv->drawnMinMax[1] = drawnMinMax[1];
709   _setLines(mapSet);
710 
711   return TRUE;
712 }
713 /**
714  * visu_gl_ext_map_set_addFromPlane:
715  * @mapSet: a #VisuGlExtMapSet object.
716  * @plane: (transfer none): a #VisuPlane object.
717  *
718  * Add a new map to the list of drawn mapSet. If @color is %NULL, then
719  * iso-lines will be drawn in inverse color.
720  *
721  * Since: 3.8
722  *
723  * Returns: (transfer none): the corresponding #VisuMap.
724  **/
visu_gl_ext_map_set_addFromPlane(VisuGlExtMapSet * mapSet,VisuPlane * plane)725 VisuMap* visu_gl_ext_map_set_addFromPlane(VisuGlExtMapSet *mapSet,
726                                           VisuPlane *plane)
727 {
728   VisuMap *map;
729   float full[2] = {0.f, 1.f};
730 
731   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet) && plane, (VisuMap*)0);
732 
733   map = visu_map_new_fromPlane(plane);
734   visu_map_setField(map, mapSet->priv->field);
735   visu_map_setScaling(map, mapSet->priv->scale);
736   visu_map_setScalingRange(map, (mapSet->priv->useManualRange) ? mapSet->priv->manualMinMax : (float*)0);
737   visu_map_setLines(map, mapSet->priv->nLines, (mapSet->priv->useManualRange) ? full : mapSet->priv->drawnMinMax);
738 
739   if (!visu_gl_ext_maps_add(VISU_GL_EXT_MAPS(mapSet), map,
740                             mapSet->priv->prec, mapSet->priv->shade,
741                             mapSet->priv->color, mapSet->priv->alpha))
742     {
743       g_object_unref(map);
744       return (VisuMap*)0;
745     }
746 
747   visu_gl_ext_map_set_setPlane(mapSet, map, plane);
748   g_object_unref(map);
749 
750   return map;
751 }
752 /**
753  * visu_gl_ext_map_set_setPlane:
754  * @mapSet: a #VisuGlExtMapSet object.
755  * @map: a #VisuMap object.
756  * @plane: a #VisuPlane object.
757  *
758  * Change the plane where @map is projected on to @plane.
759  *
760  * Since: 3.8
761  **/
visu_gl_ext_map_set_setPlane(VisuGlExtMapSet * mapSet,VisuMap * map,VisuPlane * plane)762 void visu_gl_ext_map_set_setPlane(VisuGlExtMapSet *mapSet, VisuMap *map, VisuPlane *plane)
763 {
764   struct _mapData *data;
765 
766   g_return_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet));
767 
768   data = (struct _mapData*)g_hash_table_lookup(mapSet->priv->maps, map);
769   g_return_if_fail(data);
770 
771   if (data->plane == plane)
772     return;
773 
774   if (data->plane)
775     {
776       visu_plane_setRendered(data->plane, data->planeStatus);
777       g_object_unref(data->plane);
778     }
779 
780   g_object_ref(plane);
781   data->plane = plane;
782   data->planeStatus = visu_plane_getRendered(plane);
783   visu_plane_setRendered(plane, FALSE);
784 
785   visu_map_setPlane(map, plane);
786 }
787 /**
788  * visu_gl_ext_map_set_getPlane:
789  * @mapSet: a #VisuGlExtMapSet object.
790  * @map: a #VisuMap object.
791  *
792  * Retrieve the #VisuPlane @map was build from (if any).
793  *
794  * Since: 3.8
795  *
796  * Returns: (transfer none): the attached #VisuPlane if any.
797  **/
visu_gl_ext_map_set_getPlane(VisuGlExtMapSet * mapSet,VisuMap * map)798 VisuPlane* visu_gl_ext_map_set_getPlane(VisuGlExtMapSet *mapSet, VisuMap *map)
799 {
800   struct _mapData *data;
801 
802   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), (VisuPlane*)0);
803 
804   DBG_fprintf(stderr, "Extension MapSet: looking for map %p.\n", (gpointer)map);
805   data = (struct _mapData*)g_hash_table_lookup(mapSet->priv->maps, map);
806   g_return_val_if_fail(data, (VisuPlane*)0);
807   return data->plane;
808 }
809 
810 /**
811  * visu_gl_ext_map_set_setPrecision:
812  * @mapSet: a #VisuGlExtMapSet object.
813  * @prec: a floating point value (default is 100).
814  *
815  * Changes the adaptative mesh of @map. At a value of 200, there is no
816  * adaptivity and all triangles are rendered. At a level of 100, a
817  * variation of less than 3% on neighbouring triangles make them merged.
818  *
819  * Since: 3.8
820  *
821  * Returns: TRUE if @prec of @map is changed.
822  **/
visu_gl_ext_map_set_setPrecision(VisuGlExtMapSet * mapSet,float prec)823 gboolean visu_gl_ext_map_set_setPrecision(VisuGlExtMapSet *mapSet, float prec)
824 {
825   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
826   if (mapSet->priv->prec != prec)
827     {
828       mapSet->priv->prec = prec;
829       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[PRECISION_PROP]);
830     }
831   return visu_gl_ext_maps_setPrecision(VISU_GL_EXT_MAPS(mapSet), (VisuMap*)0, prec);
832 }
833 /**
834  * visu_gl_ext_map_set_setShade:
835  * @mapSet: a #VisuGlExtMapSet object.
836  * @shade: (allow-none) (transfer full): a #ToolShade object.
837  *
838  * Changes the #ToolShade used to render data variation on the @map.
839  *
840  * Since: 3.8
841  *
842  * Returns: TRUE if @shade of @map is changed.
843  **/
visu_gl_ext_map_set_setShade(VisuGlExtMapSet * mapSet,ToolShade * shade)844 gboolean visu_gl_ext_map_set_setShade(VisuGlExtMapSet *mapSet, ToolShade *shade)
845 {
846   gboolean diff;
847 
848   if (!tool_shade_compare(mapSet->priv->shade, shade))
849     {
850       if (mapSet->priv->shade)
851         g_boxed_free(TOOL_TYPE_SHADE, mapSet->priv->shade);
852       mapSet->priv->shade = (shade) ? g_boxed_copy(TOOL_TYPE_SHADE, shade) : (ToolShade*)0;
853       diff = TRUE;
854       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[SHADE_PROP]);
855     }
856   visu_gl_ext_maps_setShade(VISU_GL_EXT_MAPS(mapSet), (VisuMap*)0, shade);
857   visu_gl_ext_shade_setShade(mapSet->priv->extLegend, shade);
858   return diff;
859 }
860 /**
861  * visu_gl_ext_map_set_setLineColor:
862  * @mapSet: a #VisuGlExtMapSet object.
863  * @color: (allow-none) (transfer full): a #ToolColor object.
864  *
865  * Changes the rendered isoline color of @map to @color. If @color is
866  * %NULL, then the isolines will be color inversed to the #ToolShade
867  * of @map (see visu_gl_ext_map_set_setShade()).
868  *
869  * Since: 3.8
870  *
871  * Returns: TRUE if @color of @map is changed.
872  **/
visu_gl_ext_map_set_setLineColor(VisuGlExtMapSet * mapSet,const ToolColor * color)873 gboolean visu_gl_ext_map_set_setLineColor(VisuGlExtMapSet *mapSet,
874                                           const ToolColor *color)
875 {
876   gboolean diff;
877 
878   if (!tool_color_equal(mapSet->priv->color, color))
879     {
880       if (mapSet->priv->color)
881         g_boxed_free(TOOL_TYPE_COLOR, mapSet->priv->color);
882       mapSet->priv->color = (color) ? g_boxed_copy(TOOL_TYPE_COLOR, color) : (ToolColor*)0;
883       diff = TRUE;
884       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[COLOR_PROP]);
885     }
886   visu_gl_ext_maps_setLineColor(VISU_GL_EXT_MAPS(mapSet), (VisuMap*)0, color);
887   return diff;
888 }
889 /**
890  * visu_gl_ext_map_set_setTransparent:
891  * @mapSet: a #VisuGlExtMapSet object.
892  * @alpha: a boolean.
893  *
894  * Sets if @map is rendered with transparency or not. If @alpha is
895  * %TRUE, the lower the rendered value is, the more transparent the
896  * colour will be.
897  *
898  * Since: 3.8
899  *
900  * Returns: TRUE if transparency of @map is changed.
901  **/
visu_gl_ext_map_set_setTransparent(VisuGlExtMapSet * mapSet,gboolean alpha)902 gboolean visu_gl_ext_map_set_setTransparent(VisuGlExtMapSet *mapSet, gboolean alpha)
903 {
904   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
905   if (mapSet->priv->alpha != alpha)
906     {
907       mapSet->priv->alpha = alpha;
908       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[ALPHA_PROP]);
909     }
910   return visu_gl_ext_maps_setTransparent(VISU_GL_EXT_MAPS(mapSet), (VisuMap*)0, alpha);
911 }
912 /**
913  * visu_gl_ext_map_set_setLines:
914  * @mapSet: a #VisuGlExtMapSet object.
915  * @nLines: a number.
916  *
917  * Set the number of iso-lines that are computed for each #VisuMap in
918  * @mapSet. Contrary to visu_map_setLines(), this routine set the same
919  * number of lines for every #VisuMap and use the same bounds for all.
920  *
921  * Since: 3.8
922  *
923  * Returns: TRUE if the number of lines of @mapSet is changed.
924  **/
visu_gl_ext_map_set_setLines(VisuGlExtMapSet * mapSet,guint nLines)925 gboolean visu_gl_ext_map_set_setLines(VisuGlExtMapSet *mapSet, guint nLines)
926 {
927   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
928 
929   if (mapSet->priv->nLines == nLines)
930     return FALSE;
931 
932   mapSet->priv->nLines = nLines;
933 
934   g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[N_LINES_PROP]);
935 
936   _setLines(mapSet);
937 
938   return TRUE;
939 }
940 /**
941  * visu_gl_ext_map_set_setScaling:
942  * @mapSet: a #VisuGlExtMapSet object.
943  * @scale: a #ToolMatrixScalingFlag scaling method.
944  *
945  * Set globally the scaling method for all #VisuMap in @mapSet.
946  *
947  * Since: 3.8
948  *
949  * Returns: TRUE if scaling function is changed.
950  **/
visu_gl_ext_map_set_setScaling(VisuGlExtMapSet * mapSet,ToolMatrixScalingFlag scale)951 gboolean visu_gl_ext_map_set_setScaling(VisuGlExtMapSet *mapSet,
952                                         ToolMatrixScalingFlag scale)
953 {
954   VisuGlExtMapsIter iter;
955 
956   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
957 
958   if (mapSet->priv->scale == scale)
959     return FALSE;
960 
961   mapSet->priv->scale = scale;
962 
963   g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[SCALE_PROP]);
964 
965   visu_gl_ext_shade_setScaling(mapSet->priv->extLegend, scale);
966   for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
967        iter.valid; visu_gl_ext_maps_iter_next(&iter))
968     visu_map_setScaling(iter.map, scale);
969 
970   return TRUE;
971 }
972 /**
973  * visu_gl_ext_map_set_setScalingRange:
974  * @mapSet: a #VisuGlExtMapSet object.
975  * @minMax: (array fixed-size=2) (allow-none): a range.
976  *
977  * Set globally the scaling range for all #VisuMap in @mapSet.
978  *
979  * Since: 3.8
980  *
981  * Returns: TRUE if the range is changed of @mapSet is changed.
982  **/
visu_gl_ext_map_set_setScalingRange(VisuGlExtMapSet * mapSet,const float minMax[2])983 gboolean visu_gl_ext_map_set_setScalingRange(VisuGlExtMapSet *mapSet, const float minMax[2])
984 {
985   VisuGlExtMapsIter iter;
986 
987   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
988 
989   DBG_fprintf(stderr, "Extension MapSet: set scaling range to %p (%d).\n",
990               (gpointer)minMax, mapSet->priv->useManualRange);
991   if ((mapSet->priv->useManualRange && minMax &&
992        mapSet->priv->manualMinMax[0] == minMax[0] &&
993        mapSet->priv->manualMinMax[1] == minMax[1]) ||
994       (!mapSet->priv->useManualRange && !minMax))
995     return FALSE;
996 
997   mapSet->priv->useManualRange = (minMax != (const float*)0);
998   g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[USE_MANUAL_MM_PROP]);
999   if (minMax)
1000     {
1001       mapSet->priv->manualMinMax[0] = minMax[0];
1002       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[MANUAL_MIN_PROP]);
1003       mapSet->priv->manualMinMax[1] = minMax[1];
1004       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[MANUAL_MAX_PROP]);
1005       g_object_notify_by_pspec(G_OBJECT(mapSet), _properties[MANUAL_MM_PROP]);
1006     }
1007 
1008   for (visu_gl_ext_maps_iter_new(VISU_GL_EXT_MAPS(mapSet), &iter);
1009        iter.valid; visu_gl_ext_maps_iter_next(&iter))
1010     visu_map_setScalingRange(iter.map, minMax);
1011 
1012   /* We update the legend min and max. */
1013   _legend(mapSet);
1014 
1015   return TRUE;
1016 }
1017 /**
1018  * visu_gl_ext_map_set_getPrecision:
1019  * @mapSet: a #VisuGlExtMapSet object.
1020  *
1021  * Return the rendering adaptability of @map, or the general
1022  * adaptability value if @map is %NULL.
1023  *
1024  * Since: 3.8
1025  *
1026  * Returns: the precision value.
1027  **/
visu_gl_ext_map_set_getPrecision(const VisuGlExtMapSet * mapSet)1028 float visu_gl_ext_map_set_getPrecision(const VisuGlExtMapSet *mapSet)
1029 {
1030   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), 100.f);
1031 
1032   return mapSet->priv->prec;
1033 }
1034 /**
1035  * visu_gl_ext_map_set_getTransparent:
1036  * @mapSet: a #VisuGlExtMapSet object.
1037  *
1038  * Return if field values are also used for alpha channel for @map, or the general
1039  * setting if @map is %NULL.
1040  *
1041  * Since: 3.8
1042  *
1043  * Returns: if map is rendered with transparency or not.
1044  **/
visu_gl_ext_map_set_getTransparent(const VisuGlExtMapSet * mapSet)1045 gboolean visu_gl_ext_map_set_getTransparent(const VisuGlExtMapSet *mapSet)
1046 {
1047   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(mapSet), FALSE);
1048 
1049   return mapSet->priv->alpha;
1050 }
1051 
1052 /* Callbacks. */
visu_gl_ext_map_set_add(VisuGlExtMaps * maps,VisuMap * map,float prec,ToolShade * shade,const ToolColor * color,gboolean alpha)1053 static gboolean visu_gl_ext_map_set_add(VisuGlExtMaps *maps, VisuMap *map,
1054                                         float prec, ToolShade *shade,
1055                                         const ToolColor *color, gboolean alpha)
1056 {
1057   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(maps);
1058   g_return_val_if_fail(VISU_IS_GL_EXT_MAP_SET(maps), FALSE);
1059   g_return_val_if_fail(!visu_map_getField(map) ||
1060                        visu_map_getField(map) == self->priv->field, FALSE);
1061 
1062   g_hash_table_insert(self->priv->maps, map,
1063                       _newMapData(VISU_GL_EXT_MAP_SET(maps), map));
1064   if (!VISU_GL_EXT_MAPS_CLASS(visu_gl_ext_map_set_parent_class)->add(maps, map, prec,
1065                                                                      shade, color, alpha))
1066     {
1067       g_hash_table_remove(self->priv->maps, map);
1068       return FALSE;
1069     }
1070 
1071   return TRUE;
1072 }
visu_gl_ext_map_set_added(VisuGlExtMaps * maps,VisuMap * map _U_)1073 static void visu_gl_ext_map_set_added(VisuGlExtMaps *maps, VisuMap *map _U_)
1074 {
1075   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(maps);
1076 
1077   if (visu_gl_ext_getActive(VISU_GL_EXT(maps)) && self->priv->field &&
1078       !visu_scalar_field_isEmpty(self->priv->field))
1079     visu_gl_ext_setActive(VISU_GL_EXT(self->priv->extLegend), TRUE);
1080 }
visu_gl_ext_map_set_removed(VisuGlExtMaps * maps,VisuMap * map)1081 static void visu_gl_ext_map_set_removed(VisuGlExtMaps *maps, VisuMap *map)
1082 {
1083   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(maps);
1084 
1085   DBG_fprintf(stderr, "Extension MapSet: removing map %p.\n", (gpointer)map);
1086   g_hash_table_remove(self->priv->maps, map);
1087   if (!g_hash_table_size(self->priv->maps))
1088     visu_gl_ext_setActive(VISU_GL_EXT(self->priv->extLegend), FALSE);
1089 }
onMapChange(VisuMap * map _U_,gpointer data)1090 static void onMapChange(VisuMap *map _U_, gpointer data)
1091 {
1092   DBG_fprintf(stderr, "Extension MapSet: caught 'changed' signal for map %p.\n",
1093               (gpointer)map);
1094   _drawnMinMax(VISU_GL_EXT_MAP_SET(data));
1095 }
onFieldChanged(VisuScalarField * field _U_,gpointer data)1096 static void onFieldChanged(VisuScalarField *field _U_, gpointer data)
1097 {
1098   VisuGlExtMapSet *self = VISU_GL_EXT_MAP_SET(data);
1099 
1100   visu_gl_ext_setActive(VISU_GL_EXT(self->priv->extLegend),
1101                         visu_gl_ext_getActive(VISU_GL_EXT(self)) &&
1102                         g_hash_table_size(self->priv->maps) > 0 &&
1103                         !visu_scalar_field_isEmpty(self->priv->field));
1104 
1105   self->priv->drawnMinMax[0] = G_MAXFLOAT;
1106   self->priv->drawnMinMax[1] = -G_MAXFLOAT;
1107 }
1108 
1109 /**
1110  * visu_gl_ext_map_set_export:
1111  * @mapSet: a #VisuGlExtMapSet object.
1112  * @map: a given #VisuMap object.
1113  * @filename: a filename.
1114  * @format: a format.
1115  * @error: an error location.
1116  *
1117  * Runs visu_map_export() on @map with @mapSet shade and colour.
1118  *
1119  * Since: 3.8
1120  *
1121  * Returns: TRUE if exportation is successful.
1122  **/
visu_gl_ext_map_set_export(VisuGlExtMapSet * mapSet,VisuMap * map,const gchar * filename,VisuMapExportFormat format,GError ** error)1123 gboolean visu_gl_ext_map_set_export(VisuGlExtMapSet *mapSet, VisuMap *map,
1124                                     const gchar *filename, VisuMapExportFormat format,
1125                                     GError **error)
1126 {
1127   return visu_map_export(map, mapSet->priv->shade, (mapSet->priv->color) ? mapSet->priv->color->rgba : (float*)0, mapSet->priv->prec, filename, format, error);
1128 }
1129