1 /* EXTRAITS DE LA LICENCE
2 Copyright CEA, contributeurs : Damien
3 CALISTE, laboratoire L_Sim, (2016)
4
5 Adresse mèl :
6 BILLARD, non joignable par mèl ;
7 CALISTE, damien P caliste AT cea P fr.
8
9 Ce logiciel est un programme informatique servant à visualiser des
10 structures atomiques dans un rendu pseudo-3D.
11
12 Ce logiciel est régi par la licence CeCILL soumise au droit français et
13 respectant les principes de diffusion des logiciels libres. Vous pouvez
14 utiliser, modifier et/ou redistribuer ce programme sous les conditions
15 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
16 sur le site "http://www.cecill.info".
17
18 Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
19 pris connaissance de la licence CeCILL, et que vous en avez accepté les
20 termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
21 */
22
23 /* LICENCE SUM UP
24 Copyright CEA, contributors : Damien
25 CALISTE, laboratoire L_Sim, (2016)
26
27 E-mail address:
28 BILLARD, not reachable any more ;
29 CALISTE, damien P caliste AT cea P fr.
30
31 This software is a computer program whose purpose is to visualize atomic
32 configurations in 3D.
33
34 This software is governed by the CeCILL license under French law and
35 abiding by the rules of distribution of free software. You can use,
36 modify and/ or redistribute the software under the terms of the CeCILL
37 license as circulated by CEA, CNRS and INRIA at the following URL
38 "http://www.cecill.info".
39
40 The fact that you are presently reading this means that you have had
41 knowledge of the CeCILL license and that you accept its terms. You can
42 find a copy of this licence shipped with this software at Documentation/licence.en.txt.
43 */
44
45 #include "link.h"
46
47 #include "iface_wire.h"
48 #include "iface_cylinder.h"
49
50 #include <visu_basic.h>
51 #include <visu_configFile.h>
52
53 /**
54 * SECTION:link
55 * @short_description: An object to store rendering properties of a
56 * #VisuPair for a given distance criterion.
57 *
58 * <para>#VisuPair describes pairs between two #VisuElement. Such a
59 * pair can have several #VisuPairLink, depending on a distance
60 * criterion. Each link then has several rendering parameters, such as
61 * its color, its rendering method (wire or cylinder), if it is drawn...</para>
62 */
63
64 /* Parameters */
65 static ToolColor *defaultPairColor = NULL;
66 /* static void exportConfig(GString *data, VisuData *dataObj); */
67
68 struct _VisuPairLinkPrivate
69 {
70 gboolean dispose_has_run;
71
72 GWeakRef ele1;
73 GWeakRef ele2;
74
75 float minMax[2];
76 ToolUnits units;
77
78 gboolean drawn;
79 gboolean printLength;
80 ToolColor color;
81
82 guint width;
83 ToolShade *shade;
84 guint16 stipple;
85
86 gfloat radius;
87 VisuPairCylinderColorId colorType;
88 };
89
90 static void visu_pair_link_dispose(GObject* obj);
91 static void visu_pair_link_get_property(GObject* obj, guint property_id,
92 GValue *value, GParamSpec *pspec);
93 static void visu_pair_link_set_property(GObject* obj, guint property_id,
94 const GValue *value, GParamSpec *pspec);
95 static void visu_pair_wire_interface_init(VisuPairWireInterface *iface);
96 static void visu_pair_cylinder_interface_init(VisuPairCylinderInterface *iface);
97 static gboolean _setWidth(VisuPairWire *data, guint val);
98 static guint _getWidth(VisuPairWire *data);
99 static gboolean _setShade(VisuPairWire *data, ToolShade *shade);
100 static ToolShade* _getShade(VisuPairWire *data);
101 static gboolean _setStipple(VisuPairWire *data, guint16 stipple);
102 static guint16 _getStipple(VisuPairWire *data);
103 static gboolean _setRadius(VisuPairCylinder *data, gfloat val);
104 static gfloat _getRadius(VisuPairCylinder *data);
105 static gboolean _setColorType(VisuPairCylinder *data, VisuPairCylinderColorId val);
106 static VisuPairCylinderColorId _getColorType(VisuPairCylinder *data);
107
108 static void onEntryUnit(VisuPairLink *link, VisuConfigFileEntry *entry, VisuConfigFile *obj);
109 /* enum { */
110 /* LAST_SIGNAL */
111 /* }; */
112 /* static guint _signals[LAST_SIGNAL] = { 0 }; */
113
114 enum
115 {
116 PROP_0,
117 MIN_PROP,
118 MAX_PROP,
119 UNITS_PROP,
120
121 USE_PROP,
122 LENGTH_PROP,
123 COLOR_PROP,
124
125 WIDTH_PROP,
126 SHADE_PROP,
127 STIPPLE_PROP,
128
129 RADIUS_PROP,
130 TYPE_PROP,
131
132 N_PROP
133 };
134 static GParamSpec *_properties[N_PROP];
135
G_DEFINE_TYPE_WITH_CODE(VisuPairLink,visu_pair_link,VISU_TYPE_OBJECT,G_ADD_PRIVATE (VisuPairLink)G_IMPLEMENT_INTERFACE (VISU_TYPE_PAIR_WIRE,visu_pair_wire_interface_init)G_IMPLEMENT_INTERFACE (VISU_TYPE_PAIR_CYLINDER,visu_pair_cylinder_interface_init))136 G_DEFINE_TYPE_WITH_CODE(VisuPairLink, visu_pair_link, VISU_TYPE_OBJECT,
137 G_ADD_PRIVATE(VisuPairLink)
138 G_IMPLEMENT_INTERFACE(VISU_TYPE_PAIR_WIRE,
139 visu_pair_wire_interface_init)
140 G_IMPLEMENT_INTERFACE(VISU_TYPE_PAIR_CYLINDER,
141 visu_pair_cylinder_interface_init))
142
143 static void visu_pair_link_class_init(VisuPairLinkClass *klass)
144 {
145 float rgbOfPairs[4] = {1.0, 0.6, 0.2, 1.};
146 /* VisuConfigFileEntry *entry; */
147
148 DBG_fprintf(stderr, "Visu Pair Link: creating the class of the object.\n");
149
150 DBG_fprintf(stderr, " - adding new signals ;\n");
151
152 /* Connect the overloading methods. */
153 G_OBJECT_CLASS(klass)->dispose = visu_pair_link_dispose;
154 G_OBJECT_CLASS(klass)->set_property = visu_pair_link_set_property;
155 G_OBJECT_CLASS(klass)->get_property = visu_pair_link_get_property;
156
157 /**
158 * VisuPairLink::min:
159 *
160 * Store the link minimal distance.
161 *
162 * Since: 3.8
163 */
164 _properties[MIN_PROP] = g_param_spec_float("min", "Min",
165 "minimal distance",
166 0.f, G_MAXFLOAT, 0.f,
167 G_PARAM_READWRITE);
168 g_object_class_install_property(G_OBJECT_CLASS(klass), MIN_PROP,
169 _properties[MIN_PROP]);
170 /**
171 * VisuPairLink::max:
172 *
173 * Store the link maximal distance.
174 *
175 * Since: 3.8
176 */
177 _properties[MAX_PROP] = g_param_spec_float("max", "Max",
178 "maximal distance",
179 0.f, G_MAXFLOAT, 0.f,
180 G_PARAM_READWRITE);
181 g_object_class_install_property(G_OBJECT_CLASS(klass), MAX_PROP,
182 _properties[MAX_PROP]);
183 /**
184 * VisuPairLink::units:
185 *
186 * The units of the length dimensions.
187 *
188 * Since: 3.8
189 */
190 _properties[UNITS_PROP] = g_param_spec_uint("units", "Units",
191 "Units of dimensions",
192 TOOL_UNITS_UNDEFINED, TOOL_UNITS_N_VALUES - 1,
193 TOOL_UNITS_UNDEFINED, G_PARAM_READWRITE);
194 g_object_class_install_property(G_OBJECT_CLASS(klass), UNITS_PROP,
195 _properties[UNITS_PROP]);
196 /**
197 * VisuPairLink::drawn:
198 *
199 * If the link should be drawn or not.
200 *
201 * Since: 3.8
202 */
203 _properties[USE_PROP] = g_param_spec_boolean("drawn", "Drawn",
204 "link is displayed or not",
205 TRUE, G_PARAM_READWRITE);
206 g_object_class_install_property(G_OBJECT_CLASS(klass), USE_PROP,
207 _properties[USE_PROP]);
208 /**
209 * VisuPairLink::display-length:
210 *
211 * If the link should display its length or not.
212 *
213 * Since: 3.8
214 */
215 _properties[LENGTH_PROP] = g_param_spec_boolean("display-length", "Display length",
216 "link displays its length or not",
217 FALSE, G_PARAM_READWRITE);
218 g_object_class_install_property(G_OBJECT_CLASS(klass), LENGTH_PROP,
219 _properties[LENGTH_PROP]);
220 /**
221 * VisuPairLink::color:
222 *
223 * Store the color of the link.
224 *
225 * Since: 3.8
226 */
227 _properties[COLOR_PROP] = g_param_spec_boxed("color", "color", "rendering color",
228 TOOL_TYPE_COLOR, G_PARAM_READWRITE);
229 g_object_class_install_property(G_OBJECT_CLASS(klass), COLOR_PROP, _properties[COLOR_PROP]);
230
231 g_object_class_override_property(G_OBJECT_CLASS(klass), WIDTH_PROP, "width");
232 g_object_class_override_property(G_OBJECT_CLASS(klass), STIPPLE_PROP, "stipple");
233 g_object_class_override_property(G_OBJECT_CLASS(klass), SHADE_PROP, "shade");
234
235 g_object_class_override_property(G_OBJECT_CLASS(klass), RADIUS_PROP, "radius");
236 g_object_class_override_property(G_OBJECT_CLASS(klass), TYPE_PROP, "color-type");
237
238 /* entry = visu_config_file_addEnumEntry(VISU_CONFIG_FILE_RESOURCE, */
239 /* FLAG_PAIRS_UNIT, DESC_PAIRS_UNIT, */
240 /* &defaultUnits, _toUnit, FALSE); */
241 /* visu_config_file_entry_setVersion(entry, 3.8f); */
242 /* visu_config_file_addExportFunction(VISU_CONFIG_FILE_RESOURCE, */
243 /* exportConfig); */
244
245 defaultPairColor = tool_color_addFloatRGBA(rgbOfPairs, NULL);
246 }
visu_pair_wire_interface_init(VisuPairWireInterface * iface)247 static void visu_pair_wire_interface_init(VisuPairWireInterface *iface)
248 {
249 iface->set_width = _setWidth;
250 iface->get_width = _getWidth;
251 iface->set_stipple = _setStipple;
252 iface->get_stipple = _getStipple;
253 iface->set_shade = _setShade;
254 iface->get_shade = _getShade;
255 }
visu_pair_cylinder_interface_init(VisuPairCylinderInterface * iface)256 static void visu_pair_cylinder_interface_init(VisuPairCylinderInterface *iface)
257 {
258 iface->set_radius = _setRadius;
259 iface->get_radius = _getRadius;
260 iface->set_colorType = _setColorType;
261 iface->get_colorType = _getColorType;
262 }
visu_pair_link_init(VisuPairLink * obj)263 static void visu_pair_link_init(VisuPairLink *obj)
264 {
265 DBG_fprintf(stderr, "Visu Pair Link: initializing a new object (%p).\n",
266 (gpointer)obj);
267
268 obj->priv = visu_pair_link_get_instance_private(obj);
269 obj->priv->dispose_has_run = FALSE;
270
271 /* Private data. */
272 g_weak_ref_init(&obj->priv->ele1, (gpointer)0);
273 g_weak_ref_init(&obj->priv->ele2, (gpointer)0);
274 obj->priv->units = visu_basic_getPreferedUnit();
275 obj->priv->minMax[VISU_DISTANCE_MIN] = G_MAXFLOAT;
276 obj->priv->minMax[VISU_DISTANCE_MAX] = G_MAXFLOAT;
277 obj->priv->drawn = TRUE;
278 obj->priv->printLength = FALSE;
279 tool_color_copy(&obj->priv->color, defaultPairColor);
280
281 obj->priv->width = G_MAXUINT;
282 obj->priv->stipple = G_MAXUINT16;
283 obj->priv->shade = (ToolShade*)0;
284
285 obj->priv->radius = G_MAXFLOAT;
286 obj->priv->colorType = VISU_CYLINDER_N_COLOR;
287
288 g_signal_connect_object(VISU_CONFIG_FILE_RESOURCE, "parsed::main_unit",
289 G_CALLBACK(onEntryUnit), (gpointer)obj, G_CONNECT_SWAPPED);
290 }
visu_pair_link_dispose(GObject * obj)291 static void visu_pair_link_dispose(GObject* obj)
292 {
293 VisuPairLink *data;
294
295 DBG_fprintf(stderr, "Visu Pair Link: dispose object %p.\n", (gpointer)obj);
296
297 data = VISU_PAIR_LINK(obj);
298 if (data->priv->dispose_has_run)
299 return;
300 data->priv->dispose_has_run = TRUE;
301
302 g_weak_ref_clear(&data->priv->ele1);
303 g_weak_ref_clear(&data->priv->ele2);
304
305 /* Chain up to the parent class */
306 G_OBJECT_CLASS(visu_pair_link_parent_class)->dispose(obj);
307 }
visu_pair_link_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)308 static void visu_pair_link_get_property(GObject* obj, guint property_id,
309 GValue *value, GParamSpec *pspec)
310 {
311 VisuPairLink *self = VISU_PAIR_LINK(obj);
312
313 DBG_fprintf(stderr, "Visu Pair Link: get property '%s' -> ",
314 g_param_spec_get_name(pspec));
315 switch (property_id)
316 {
317 case COLOR_PROP:
318 g_value_set_boxed(value, &self->priv->color);
319 DBG_fprintf(stderr, "%gx%gx%g.\n", self->priv->color.rgba[0], self->priv->color.rgba[1], self->priv->color.rgba[2]);
320 break;
321 case MIN_PROP:
322 g_value_set_float(value, self->priv->minMax[0]);
323 DBG_fprintf(stderr, "%g.\n", self->priv->minMax[0]);
324 break;
325 case MAX_PROP:
326 g_value_set_float(value, self->priv->minMax[1]);
327 DBG_fprintf(stderr, "%g.\n", self->priv->minMax[1]);
328 break;
329 case UNITS_PROP:
330 g_value_set_uint(value, self->priv->units);
331 DBG_fprintf(stderr, "%d.\n", self->priv->units);
332 break;
333 case USE_PROP:
334 g_value_set_boolean(value, self->priv->drawn);
335 DBG_fprintf(stderr, "%d.\n", self->priv->drawn);
336 break;
337 case LENGTH_PROP:
338 g_value_set_boolean(value, self->priv->printLength);
339 DBG_fprintf(stderr, "%d.\n", self->priv->printLength);
340 break;
341 case WIDTH_PROP:
342 g_value_set_uint(value, _getWidth(VISU_PAIR_WIRE(obj)));
343 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
344 break;
345 case STIPPLE_PROP:
346 g_value_set_uint(value, _getStipple(VISU_PAIR_WIRE(obj)));
347 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
348 break;
349 case SHADE_PROP:
350 g_value_set_boxed(value, self->priv->shade);
351 DBG_fprintf(stderr, "%p.\n", (gpointer)self->priv->shade);
352 break;
353 case RADIUS_PROP:
354 g_value_set_float(value, _getRadius(VISU_PAIR_CYLINDER(obj)));
355 DBG_fprintf(stderr, "%g.\n", self->priv->radius);
356 break;
357 case TYPE_PROP:
358 g_value_set_uint(value, _getColorType(VISU_PAIR_CYLINDER(obj)));
359 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
360 break;
361 default:
362 /* We don't have any other property... */
363 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
364 break;
365 }
366 }
visu_pair_link_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)367 static void visu_pair_link_set_property(GObject* obj, guint property_id,
368 const GValue *value, GParamSpec *pspec)
369 {
370 VisuPairLink *self = VISU_PAIR_LINK(obj);
371
372 DBG_fprintf(stderr, "Visu Pair Link: set property '%s' -> ",
373 g_param_spec_get_name(pspec));
374 switch (property_id)
375 {
376 case COLOR_PROP:
377 visu_pair_link_setColor(self, g_value_get_boxed(value));
378 DBG_fprintf(stderr, "%gx%gx%g.\n", self->priv->color.rgba[0], self->priv->color.rgba[1], self->priv->color.rgba[2]);
379 break;
380 case MIN_PROP:
381 visu_pair_link_setDistance(self, g_value_get_float(value), VISU_DISTANCE_MIN);
382 DBG_fprintf(stderr, "%g.\n", self->priv->minMax[0]);
383 break;
384 case MAX_PROP:
385 visu_pair_link_setDistance(self, g_value_get_float(value), VISU_DISTANCE_MAX);
386 DBG_fprintf(stderr, "%g.\n", self->priv->minMax[1]);
387 break;
388 case UNITS_PROP:
389 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
390 visu_pair_link_setUnits(self, g_value_get_uint(value));
391 break;
392 case USE_PROP:
393 visu_pair_link_setDrawn(self, g_value_get_boolean(value));
394 DBG_fprintf(stderr, "%d.\n", self->priv->drawn);
395 break;
396 case LENGTH_PROP:
397 visu_pair_link_setPrintLength(self, g_value_get_boolean(value));
398 DBG_fprintf(stderr, "%d.\n", self->priv->printLength);
399 break;
400 case WIDTH_PROP:
401 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
402 visu_pair_wire_setWidth(VISU_PAIR_WIRE(obj), g_value_get_uint(value));
403 break;
404 case STIPPLE_PROP:
405 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
406 visu_pair_wire_setStipple(VISU_PAIR_WIRE(obj), (guint16)g_value_get_uint(value));
407 break;
408 case SHADE_PROP:
409 DBG_fprintf(stderr, "%p.\n", (gpointer)g_value_get_boxed(value));
410 visu_pair_wire_setShade(VISU_PAIR_WIRE(obj), (ToolShade*)g_value_dup_boxed(value));
411 break;
412 case RADIUS_PROP:
413 DBG_fprintf(stderr, "%g.\n", g_value_get_float(value));
414 visu_pair_cylinder_setRadius(VISU_PAIR_CYLINDER(obj), g_value_get_float(value));
415 break;
416 case TYPE_PROP:
417 DBG_fprintf(stderr, "%d.\n", g_value_get_uint(value));
418 visu_pair_cylinder_setColorType(VISU_PAIR_CYLINDER(obj), g_value_get_uint(value));
419 break;
420 default:
421 /* We don't have any other property... */
422 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
423 break;
424 }
425 }
426 /**
427 * visu_pair_link_new:
428 * @ele1: a #VisuElement object ;
429 * @ele2: a #VisuElement object ;
430 * @minMax: (array fixed-size=2): the two min and max distances.
431 *
432 * A link between two elements is characterized by its boundary distances.
433 *
434 * Returns: (transfer none): the #VisuPairLink object associated to the given two
435 * elements and distances. If none exists it is created. The
436 * returned value should not be freed.
437 */
visu_pair_link_new(VisuElement * ele1,VisuElement * ele2,const float minMax[2])438 VisuPairLink* visu_pair_link_new(VisuElement *ele1, VisuElement *ele2, const float minMax[2])
439 {
440 VisuPairLink *data;
441
442 data = VISU_PAIR_LINK(g_object_new(VISU_TYPE_PAIR_LINK, NULL));
443 data->priv->minMax[VISU_DISTANCE_MIN] = minMax[0];
444 data->priv->minMax[VISU_DISTANCE_MAX] = minMax[1];
445 g_weak_ref_set(&data->priv->ele1, ele1);
446 g_weak_ref_set(&data->priv->ele2, ele2);
447 DBG_fprintf(stderr, " | new %p %s-%s (%g %g).\n", (gpointer)data,
448 ele1->name, ele2->name,
449 data->priv->minMax[0], data->priv->minMax[1]);
450
451 return data;
452 }
453 /**
454 * visu_pair_link_getFirstElement:
455 * @data: a #VisuPairLink object.
456 *
457 * Retrieve one of the #VisuElement @data is linking.
458 *
459 * Since: 3.8
460 *
461 * Returns: (transfer full): a #VisuElement the link is linking.
462 **/
visu_pair_link_getFirstElement(VisuPairLink * data)463 VisuElement* visu_pair_link_getFirstElement(VisuPairLink *data)
464 {
465 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), (VisuElement*)0);
466 return g_weak_ref_get(&data->priv->ele1);
467 }
468 /**
469 * visu_pair_link_getSecondElement:
470 * @data: a #VisuPairLink object.
471 *
472 * Retrieve one of the #VisuElement @data is linking.
473 *
474 * Since: 3.8
475 *
476 * Returns: (transfer full): a #VisuElement the link is linking.
477 **/
visu_pair_link_getSecondElement(VisuPairLink * data)478 VisuElement* visu_pair_link_getSecondElement(VisuPairLink *data)
479 {
480 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), (VisuElement*)0);
481 return g_weak_ref_get(&data->priv->ele2);
482 }
483 /**
484 * visu_pair_link_setDrawn:
485 * @data: a #VisuPairLink object ;
486 * @drawn: a boolean.
487 *
488 * A pair can or cannot be drawn, use this method to tune it.
489 *
490 * Returns: TRUE if parameter has been changed.
491 */
visu_pair_link_setDrawn(VisuPairLink * data,gboolean drawn)492 gboolean visu_pair_link_setDrawn(VisuPairLink *data, gboolean drawn)
493 {
494 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
495
496 DBG_fprintf(stderr, "Visu Pairs: set drawn status %d (%d) for %p.\n",
497 (int)drawn, (int)data->priv->drawn, (gpointer)data);
498 if (data->priv->drawn == drawn)
499 return FALSE;
500
501 data->priv->drawn = drawn;
502 g_object_notify_by_pspec(G_OBJECT(data), _properties[USE_PROP]);
503 return TRUE;
504 }
505 /**
506 * visu_pair_link_setPrintLength:
507 * @data: a #VisuPairLink object ;
508 * @status: TRUE to print length near pairs.
509 *
510 * Set the attribute that controls if the length of pairs are drawn near pairs.
511 *
512 * Returns: TRUE if parameter has been changed.
513 */
visu_pair_link_setPrintLength(VisuPairLink * data,gboolean status)514 gboolean visu_pair_link_setPrintLength(VisuPairLink *data, gboolean status)
515 {
516 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
517
518 DBG_fprintf(stderr, "Visu Pairs: set print length status %d (%d) for %p.\n",
519 (int)status, (int)data->priv->printLength, (gpointer)data);
520 if (data->priv->printLength == status)
521 return FALSE;
522
523 data->priv->printLength = status;
524 g_object_notify_by_pspec(G_OBJECT(data), _properties[LENGTH_PROP]);
525 return TRUE;
526 }
527 /**
528 * visu_pair_link_getDrawn:
529 * @data: a #VisuPairLink object ;
530 *
531 * A pair can or cannot be drawn, use this method to retrieve its state.
532 *
533 * Returns: TRUE if pairs can be drawn.
534 */
visu_pair_link_getDrawn(const VisuPairLink * data)535 gboolean visu_pair_link_getDrawn(const VisuPairLink *data)
536 {
537 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
538 return data->priv->drawn;
539 }
540 /**
541 * visu_pair_link_setColor:
542 * @data: a #VisuPairLink object ;
543 * @destColor: a #ToolColor object.
544 *
545 * Set the color of the given pair.
546 *
547 * Returns: TRUE if parameter has been changed.
548 */
visu_pair_link_setColor(VisuPairLink * data,const ToolColor * destColor)549 gboolean visu_pair_link_setColor(VisuPairLink *data, const ToolColor* destColor)
550 {
551 g_return_val_if_fail(VISU_IS_PAIR_LINK(data) && destColor, FALSE);
552
553 DBG_fprintf(stderr, "Visu Pairs: set color [%g;%g;%g] for %p.\n",
554 destColor->rgba[0], destColor->rgba[1], destColor->rgba[2],
555 (gpointer)data);
556
557 if (tool_color_equal(&data->priv->color, destColor))
558 return FALSE;
559
560 /* Copy values of dest to current color. */
561 tool_color_copy(&data->priv->color, destColor);
562 g_object_notify_by_pspec(G_OBJECT(data), _properties[COLOR_PROP]);
563 return TRUE;
564 }
565 /**
566 * visu_pair_link_getColor:
567 * @data: a #VisuPairLink object.
568 *
569 * Look for the properties of the pair @data to find if a colour has
570 * been defined. If none, the default colour is returned instead.
571 *
572 * Returns: (transfer none): a colour (don't free it).
573 */
visu_pair_link_getColor(const VisuPairLink * data)574 ToolColor* visu_pair_link_getColor(const VisuPairLink *data)
575 {
576 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), defaultPairColor);
577
578 return &data->priv->color;
579 }
580 /**
581 * visu_pair_link_setDistance:
582 * @val: a floating point value ;
583 * @data: a #VisuPairLink object ;
584 * @minOrMax: #VISU_DISTANCE_MAX or #VISU_DISTANCE_MIN.
585 *
586 * Set the minimum or the maximum length for the given pair.
587 *
588 * Returns: TRUE if parameter has been changed.
589 */
visu_pair_link_setDistance(VisuPairLink * data,float val,VisuPairLinkDistances minOrMax)590 gboolean visu_pair_link_setDistance(VisuPairLink *data, float val,
591 VisuPairLinkDistances minOrMax)
592 {
593 g_return_val_if_fail(VISU_IS_PAIR_LINK(data) &&
594 (minOrMax == VISU_DISTANCE_MIN ||
595 minOrMax == VISU_DISTANCE_MAX), FALSE);
596
597 if (data->priv->minMax[minOrMax] == val)
598 return FALSE;
599
600 data->priv->minMax[minOrMax] = val;
601 g_object_notify_by_pspec(G_OBJECT(data), _properties[(minOrMax) ? MAX_PROP : MIN_PROP]);
602 return TRUE;
603 }
604 /**
605 * visu_pair_link_setUnits:
606 * @data: a #VisuPairLink object.
607 * @units: a unit.
608 *
609 * Define the unit used to store the distances.
610 *
611 * Since: 3.8
612 *
613 * Returns: TRUE if value is actually changed.
614 **/
visu_pair_link_setUnits(VisuPairLink * data,ToolUnits units)615 gboolean visu_pair_link_setUnits(VisuPairLink *data, ToolUnits units)
616 {
617 ToolUnits unit_;
618 double fact;
619
620 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
621
622 if (data->priv->units == units)
623 return FALSE;
624
625 unit_ = data->priv->units;
626 data->priv->units = units;
627 g_object_notify_by_pspec(G_OBJECT(data), _properties[UNITS_PROP]);
628
629 if (unit_ == TOOL_UNITS_UNDEFINED || units == TOOL_UNITS_UNDEFINED)
630 return TRUE;
631
632 fact = (double)tool_physic_getUnitValueInMeter(unit_) /
633 tool_physic_getUnitValueInMeter(units);
634
635 data->priv->minMax[VISU_DISTANCE_MIN] *= fact;
636 g_object_notify_by_pspec(G_OBJECT(data), _properties[MIN_PROP]);
637 data->priv->minMax[VISU_DISTANCE_MAX] *= fact;
638 g_object_notify_by_pspec(G_OBJECT(data), _properties[MAX_PROP]);
639
640 return TRUE;
641 }
642 /**
643 * visu_pair_link_getUnits:
644 * @data: a #VisuPairLink object.
645 *
646 * Get the units of distance definition of @data.
647 *
648 * Returns: TRUE if length are printed.
649 */
visu_pair_link_getUnits(const VisuPairLink * data)650 ToolUnits visu_pair_link_getUnits(const VisuPairLink *data)
651 {
652 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
653 return data->priv->units;
654 }
655 /**
656 * visu_pair_link_getPrintLength:
657 * @data: a #VisuPairLink object.
658 *
659 * Get the print length parameter of a pair. This parameter is used to tell if
660 * length should be drawn near pairs of this kind.
661 *
662 * Returns: TRUE if length are printed.
663 */
visu_pair_link_getPrintLength(const VisuPairLink * data)664 gboolean visu_pair_link_getPrintLength(const VisuPairLink *data)
665 {
666 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
667 return data->priv->printLength;
668 }
669 /**
670 * visu_pair_link_getDistance:
671 * @data: a #VisuPairLink object ;
672 * @minOrMax: #VISU_DISTANCE_MIN or #VISU_DISTANCE_MAX.
673 *
674 * A pair between @ele1 and @ele2 is drawn only if its length is between
675 * a minimum and a maximum value. This method can get these values.
676 *
677 * Returns: the minimum or the maximum value for the pair between @ele1 and @ele2.
678 */
visu_pair_link_getDistance(const VisuPairLink * data,VisuPairLinkDistances minOrMax)679 float visu_pair_link_getDistance(const VisuPairLink *data, VisuPairLinkDistances minOrMax)
680 {
681 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), 0.f);
682 g_return_val_if_fail(minOrMax == VISU_DISTANCE_MIN ||
683 minOrMax == VISU_DISTANCE_MAX, 0.);
684
685 return data->priv->minMax[minOrMax];
686 }
687 /**
688 * visu_pair_link_match:
689 * @data: a #VisuPairLink object.
690 * @minMax: (array fixed-size=2): two floats.
691 *
692 * Returns if @data is a link with distance criterions defined by @minMax.
693 *
694 * Since: 3.8
695 *
696 * Returns: %TRUE, if @data matches @minMax.
697 **/
visu_pair_link_match(const VisuPairLink * data,const float minMax[2])698 gboolean visu_pair_link_match(const VisuPairLink *data, const float minMax[2])
699 {
700 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
701 DBG_fprintf(stderr, " | test %p (%g %g).\n", (gpointer)data,
702 data->priv->minMax[0], data->priv->minMax[1]);
703 return (data->priv->minMax[0] == minMax[0] && data->priv->minMax[1] == minMax[1]);
704 }
705 /**
706 * visu_pair_link_isDrawn:
707 * @data: a #VisuPairLink object.
708 *
709 * A link is used or not depending on a distance criterion and a flag,
710 * see visu_pair_link_setDrawn() and visu_pair_link_setDistance().
711 *
712 * Since: 3.7
713 *
714 * Returns: TRUE if the @data is indeed drawn or not.
715 **/
visu_pair_link_isDrawn(const VisuPairLink * data)716 gboolean visu_pair_link_isDrawn(const VisuPairLink *data)
717 {
718 g_return_val_if_fail(VISU_IS_PAIR_LINK(data), FALSE);
719
720 return (data->priv->drawn &&
721 data->priv->minMax[VISU_DISTANCE_MAX] >
722 data->priv->minMax[VISU_DISTANCE_MIN] &&
723 data->priv->minMax[VISU_DISTANCE_MAX] > 0.f);
724 }
_setWidth(VisuPairWire * data,guint val)725 static gboolean _setWidth(VisuPairWire *data, guint val)
726 {
727 if (VISU_PAIR_LINK(data)->priv->width == val)
728 return FALSE;
729 VISU_PAIR_LINK(data)->priv->width = val;
730
731 return TRUE;
732 }
_getWidth(VisuPairWire * data)733 static guint _getWidth(VisuPairWire *data)
734 {
735 return VISU_PAIR_LINK(data)->priv->width == G_MAXUINT ? visu_pair_wire_getDefaultWidth() : VISU_PAIR_LINK(data)->priv->width;
736 }
_setShade(VisuPairWire * data,ToolShade * shade)737 static gboolean _setShade(VisuPairWire *data, ToolShade *shade)
738 {
739 if (tool_shade_compare(VISU_PAIR_LINK(data)->priv->shade, shade))
740 return FALSE;
741 VISU_PAIR_LINK(data)->priv->shade = shade;
742
743 return TRUE;
744 }
_getShade(VisuPairWire * data)745 static ToolShade* _getShade(VisuPairWire *data)
746 {
747 return VISU_PAIR_LINK(data)->priv->shade;
748 }
_setStipple(VisuPairWire * data,guint16 stipple)749 static gboolean _setStipple(VisuPairWire *data, guint16 stipple)
750 {
751 if (VISU_PAIR_LINK(data)->priv->stipple == stipple)
752 return FALSE;
753 VISU_PAIR_LINK(data)->priv->stipple = stipple;
754
755 return TRUE;
756 }
_getStipple(VisuPairWire * data)757 static guint16 _getStipple(VisuPairWire *data)
758 {
759 return VISU_PAIR_LINK(data)->priv->stipple == G_MAXUINT16 ? visu_pair_wire_getDefaultStipple() : VISU_PAIR_LINK(data)->priv->stipple;
760 }
_setRadius(VisuPairCylinder * data,gfloat val)761 static gboolean _setRadius(VisuPairCylinder *data, gfloat val)
762 {
763 if (VISU_PAIR_LINK(data)->priv->radius == val)
764 return FALSE;
765 VISU_PAIR_LINK(data)->priv->radius = val;
766
767 return TRUE;
768 }
_getRadius(VisuPairCylinder * data)769 static gfloat _getRadius(VisuPairCylinder *data)
770 {
771 return VISU_PAIR_LINK(data)->priv->radius == G_MAXFLOAT ? visu_pair_cylinder_getDefaultRadius() : VISU_PAIR_LINK(data)->priv->radius;
772 }
_setColorType(VisuPairCylinder * data,VisuPairCylinderColorId val)773 static gboolean _setColorType(VisuPairCylinder *data, VisuPairCylinderColorId val)
774 {
775 if (VISU_PAIR_LINK(data)->priv->colorType == val)
776 return FALSE;
777 VISU_PAIR_LINK(data)->priv->colorType = val;
778
779 return TRUE;
780 }
_getColorType(VisuPairCylinder * data)781 static VisuPairCylinderColorId _getColorType(VisuPairCylinder *data)
782 {
783 return VISU_PAIR_LINK(data)->priv->colorType >= VISU_CYLINDER_N_COLOR ? visu_pair_cylinder_getDefaultColorType() : VISU_PAIR_LINK(data)->priv->colorType;
784 }
785
onEntryUnit(VisuPairLink * link,VisuConfigFileEntry * entry _U_,VisuConfigFile * obj _U_)786 static void onEntryUnit(VisuPairLink *link, VisuConfigFileEntry *entry _U_, VisuConfigFile *obj _U_)
787 {
788 if (link->priv->units != TOOL_UNITS_UNDEFINED)
789 return;
790
791 visu_pair_link_setUnits(link, visu_basic_getPreferedUnit());
792 }
793 /* static void exportConfig(GString *data, VisuData *dataObj _U_) */
794 /* { */
795 /* const gchar **units; */
796
797 /* if (defaultUnits != TOOL_UNITS_UNDEFINED) */
798 /* { */
799 /* units = tool_physic_getUnitNames(); */
800
801 /* visu_config_file_exportComment(data, DESC_PAIRS_UNIT); */
802 /* visu_config_file_exportEntry(data, FLAG_PAIRS_UNIT, NULL, */
803 /* "%s", units[defaultUnits]); */
804 /* visu_config_file_exportComment(data, ""); */
805 /* } */
806 /* } */
_next1(VisuPairLinkIter * iter,gboolean restart)807 static gboolean _next1(VisuPairLinkIter *iter, gboolean restart)
808 {
809 if (!visu_element_getRendered(iter->iter1.element))
810 return FALSE;
811
812 if (restart)
813 visu_node_array_iterRestartNode(VISU_NODE_ARRAY(iter->data), &iter->iter1);
814 else
815 visu_node_array_iterNextNode(VISU_NODE_ARRAY(iter->data), &iter->iter1);
816
817 while (iter->iter1.node &&
818 !visu_node_getVisibility(iter->iter1.node))
819 visu_node_array_iterNextNode(VISU_NODE_ARRAY(iter->data), &iter->iter1);
820
821 if (iter->iter1.node)
822 visu_data_getNodePosition(iter->data, iter->iter1.node, iter->xyz1);
823
824 return (iter->iter1.node != NULL);
825 }
_next2(VisuPairLinkIter * iter,gboolean restart)826 static gboolean _next2(VisuPairLinkIter *iter, gboolean restart)
827 {
828 if (!visu_element_getRendered(iter->iter2.element))
829 return FALSE;
830
831 if (restart)
832 visu_node_array_iterRestartNode(VISU_NODE_ARRAY(iter->data), &iter->iter2);
833 else
834 visu_node_array_iterNextNode(VISU_NODE_ARRAY(iter->data), &iter->iter2);
835
836 while (iter->iter2.node)
837 {
838 if (iter->iter1.element == iter->iter2.element &&
839 iter->iter2.node >= iter->iter1.node)
840 return FALSE;
841
842 if (visu_node_getVisibility(iter->iter2.node))
843 {
844 visu_data_getNodePosition(iter->data, iter->iter2.node, iter->xyz2);
845 iter->dxyz[0] = iter->xyz2[0] - iter->xyz1[0];
846 iter->dxyz[1] = iter->xyz2[1] - iter->xyz1[1];
847 iter->dxyz[2] = iter->xyz2[2] - iter->xyz1[2];
848 if (iter->box)
849 iter->periodic = visu_box_getInside(iter->box, iter->dxyz, 0.6f);
850 iter->d2 = iter->dxyz[0] * iter->dxyz[0] +
851 iter->dxyz[1] * iter->dxyz[1] +
852 iter->dxyz[2] * iter->dxyz[2];
853 if(iter->d2 >= iter->l2_buffered[0] && iter->d2 <= iter->l2_buffered[1])
854 {
855 if (iter->d2 < iter->l2[0])
856 iter->coeff = (iter->d2 - iter->l2_buffered[0]) /
857 (iter->l2[0] - iter->l2_buffered[0]);
858 else if (iter->d2 > iter->l2[1])
859 iter->coeff = (iter->l2_buffered[1] - iter->d2) /
860 (iter->l2_buffered[1] - iter->l2[1]);
861 else
862 iter->coeff = 1.f;
863 return TRUE;
864 }
865 }
866 visu_node_array_iterNextNode(VISU_NODE_ARRAY(iter->data), &iter->iter2);
867 }
868 return FALSE;
869 }
870
871 /**
872 * VisuPairLinkIter:
873 * @parent: the #VisuPairLink this iterator is inheriting his properties.
874 * @data: the #VisuData this iterator have to work on.
875 * @iter1: a #VisuNodeArrayIter.
876 * @iter2: a second #VisuNodeArrayIter.
877 * @buffer: the length of the buffer around links, in percents.
878 * @l2: the current link length, squared.
879 * @l2_buffered: like @l2, but including the buffer.
880 * @box: (allow-none): a given box to apply periodicity if needed.
881 * @periodic: a boolean specifying if periodicity is to be taken into
882 * account when computing the vector linking two nodes.
883 * @xyz1: the current coordinates of the starting node in the link.
884 * @xyz2: the current coordinates of the ending node in the link.
885 * @dxyz: the current vector (within periodicity) linking node1 to
886 * node2.
887 * @d2: the length of the link, squared.
888 * @coeff: a value used to characterised link length with respect to
889 * buffer (1. means that length is within link characteristics, while
890 * 0. means that link is outside characteristics plus buffer).
891 *
892 * An iterator used to generate pairs with the characteristics given
893 * by @parent, over the node in @data.
894 *
895 * Since: 3.8
896 */
897
898 /**
899 * visu_pair_link_iter_new:
900 * @link: a #VisuPairLink object.
901 * @data: a #VisuData object.
902 * @iter: (out caller-allocates): a pointer to a #VisuPairLinkIter
903 * structure.
904 * @usePeriodicty: a boolean.
905 *
906 * Initialise a new #VisuPairLinkIter structure to iterate over links
907 * defined by @link in @data. If @usePeriodicty is %TRUE, all links
908 * between two nodes are kept if their smallest vector, using the
909 * periodicty, is within the @link distance criterion.
910 *
911 * Since: 3.8
912 *
913 * Returns: TRUE if there is a valid link to draw.
914 **/
visu_pair_link_iter_new(VisuPairLink * link,VisuData * data,VisuPairLinkIter * iter,gboolean usePeriodicty)915 gboolean visu_pair_link_iter_new(VisuPairLink *link, VisuData *data,
916 VisuPairLinkIter *iter, gboolean usePeriodicty)
917 {
918 float mM[2], length;
919
920 g_return_val_if_fail(VISU_IS_PAIR_LINK(link) && data && iter, FALSE);
921
922 if (!visu_pair_link_isDrawn(link))
923 return FALSE;
924
925 iter->parent = link;
926 iter->data = data;
927
928 visu_node_array_iter_new(VISU_NODE_ARRAY(data), &iter->iter1);
929 visu_node_array_iter_new(VISU_NODE_ARRAY(data), &iter->iter2);
930 iter->iter1.element = visu_pair_link_getFirstElement(link);
931 iter->iter2.element = visu_pair_link_getSecondElement(link);
932 g_object_unref(iter->iter2.element);
933 g_object_unref(iter->iter1.element);
934
935 iter->buffer = 0.15f;
936 mM[0] = visu_pair_link_getDistance(link, VISU_DISTANCE_MIN);
937 mM[1] = visu_pair_link_getDistance(link, VISU_DISTANCE_MAX);
938 iter->l2[0] = mM[0] * mM[0];
939 iter->l2[1] = mM[1] * mM[1];
940 length = mM[1] - mM[0];
941 iter->l2_buffered[0] = (mM[0] - iter->buffer * length);
942 iter->l2_buffered[0] *= iter->l2_buffered[0];
943 iter->l2_buffered[1] = (mM[1] + iter->buffer * length);
944 iter->l2_buffered[1] *= iter->l2_buffered[1];
945
946 iter->box = (usePeriodicty) ? visu_boxed_getBox(VISU_BOXED(data)) : (VisuBox*)0;
947 iter->periodic = FALSE;
948
949 if (_next1(iter, TRUE))
950 {
951 if (_next2(iter, TRUE))
952 return TRUE;
953
954 while (_next1(iter, FALSE))
955 {
956 if (_next2(iter, TRUE))
957 return TRUE;
958 };
959 }
960
961 return FALSE;
962 }
963 /**
964 * visu_pair_link_iter_next:
965 * @iter: a #VisuPairLinkIter object.
966 *
967 * Iterate to the next #VisuNode - #VisuNode pair.
968 *
969 * Since: 3.8
970 *
971 * Returns: TRUE if iterator is still valid.
972 **/
visu_pair_link_iter_next(VisuPairLinkIter * iter)973 gboolean visu_pair_link_iter_next(VisuPairLinkIter *iter)
974 {
975 if (_next2(iter, FALSE))
976 return TRUE;
977
978 while (_next1(iter, FALSE))
979 {
980 if (_next2(iter, TRUE))
981 return TRUE;
982 };
983
984 return FALSE;
985 }
986