1 /* EXTRAITS DE LA LICENCE
2 Copyright CEA, contributeurs : Damien
3 CALISTE, laboratoire L_Sim, (2018)
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, (2018)
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
43 #include "poleProp.h"
44 #include <coreTools/toolMatrix.h>
45 #include <coreTools/toolPhysic.h>
46 #include <coreTools/atoms_yaml.h>
47
48 #include <string.h>
49
50 /**
51 * SECTION:poleProp
52 * @short_description: define a #VisuNodeValues object to handle
53 * multipole node information.
54 *
55 * <para>Defines a #VisuNodeValues object to store a pole
56 * information on nodes.</para>
57 */
58
59 static gboolean _parse(VisuNodeValues *vals, VisuNode *node, const gchar *from);
60 static gchar* _serialize(const VisuNodeValues *vals, const VisuNode *node);
61
62
G_DEFINE_TYPE(VisuNodeValuesPole,visu_node_values_pole,VISU_TYPE_NODE_VALUES_FARRAY)63 G_DEFINE_TYPE(VisuNodeValuesPole, visu_node_values_pole, VISU_TYPE_NODE_VALUES_FARRAY)
64
65 static void visu_node_values_pole_class_init(VisuNodeValuesPoleClass *klass)
66 {
67 /* Connect the overloading methods. */
68 VISU_NODE_VALUES_CLASS(klass)->parse = _parse;
69 VISU_NODE_VALUES_CLASS(klass)->serialize = _serialize;
70 }
71
visu_node_values_pole_init(VisuNodeValuesPole * self _U_)72 static void visu_node_values_pole_init(VisuNodeValuesPole *self _U_)
73 {
74 }
75
_parse(VisuNodeValues * vals,VisuNode * node,const gchar * from)76 static gboolean _parse(VisuNodeValues *vals, VisuNode *node, const gchar *from)
77 {
78 gfloat data[9];
79 GValue value = G_VALUE_INIT;
80 PosinpDict *dict;
81 guint i;
82
83 g_return_val_if_fail(from, FALSE);
84
85 dict = posinp_yaml_parse_properties(from, NULL);
86 if (!dict)
87 return FALSE;
88 memset(vals, '\0', sizeof(gfloat) * 9);
89 for (i = 0; i < dict->len && dict->items[i].key; i++)
90 if (!strcmp(dict->items[i].key, "q0") &&
91 dict->items[i].type == POSINP_TYPE_DBL_ARR &&
92 dict->items[i].value.darr.len == 1)
93 data[0] = dict->items[i].value.darr.arr[0];
94 else if (!strcmp(dict->items[i].key, "q1") &&
95 dict->items[i].type == POSINP_TYPE_DBL_ARR &&
96 dict->items[i].value.darr.len == 3)
97 {
98 data[1] = dict->items[i].value.darr.arr[0];
99 data[2] = dict->items[i].value.darr.arr[1];
100 data[3] = dict->items[i].value.darr.arr[2];
101 }
102 else if (!strcmp(dict->items[i].key, "q2") &&
103 dict->items[i].type == POSINP_TYPE_DBL_ARR &&
104 dict->items[i].value.darr.len == 5)
105 {
106 data[4] = dict->items[i].value.darr.arr[0];
107 data[5] = dict->items[i].value.darr.arr[1];
108 data[6] = dict->items[i].value.darr.arr[2];
109 data[7] = dict->items[i].value.darr.arr[3];
110 data[8] = dict->items[i].value.darr.arr[4];
111 }
112 posinp_yaml_free_properties(dict);
113 g_value_set_pointer(&value, data);
114 return visu_node_values_setAt(vals, node, &value);
115 }
_serialize(const VisuNodeValues * vals,const VisuNode * node)116 static gchar* _serialize(const VisuNodeValues *vals, const VisuNode *node)
117 {
118 GValue value = G_VALUE_INIT;
119 gfloat *fvals;
120
121 if (!visu_node_values_getAt(vals, node, &value))
122 return (gchar*)0;
123
124 fvals = (float*)g_value_get_pointer(&value);
125 if (fvals)
126 return g_strdup_printf("q0: [%#.3g]\nq1: [%#.3g, %#.3g, %#.3g]\nq2: [%#.3g, %#.3g, %#.3g, %#.3g, %#.3g]", fvals[0], fvals[1], fvals[2], fvals[3], fvals[4], fvals[5], fvals[6], fvals[7], fvals[8]);
127 else
128 return (gchar*)0;
129 }
130
131 /**
132 * visu_node_values_pole_new:
133 * @arr: a #VisuNodeArray object.
134 * @label: a translatable label.
135 *
136 * Create a new pole field located on nodes.
137 *
138 * Since: 3.8
139 *
140 * Returns: (transfer full): a newly created #VisuNodeValuesPole object.
141 **/
visu_node_values_pole_new(VisuNodeArray * arr,const gchar * label)142 VisuNodeValuesPole* visu_node_values_pole_new(VisuNodeArray *arr,
143 const gchar *label)
144 {
145 VisuNodeValuesPole *vals;
146
147 vals = VISU_NODE_VALUES_POLE(g_object_new(VISU_TYPE_NODE_VALUES_POLE,
148 "nodes", arr, "label", label,
149 "type", G_TYPE_FLOAT,
150 "n-elements", 9, NULL));
151 return vals;
152 }
153
154 static const gfloat zmono[1] = {0.f};
155 static const gfloat zdi[3] = {0.f, 0.f, 0.f};
156 static const gfloat zquad[5] = {0.f, 0.f, 0.f, 0.f, 0.f};
157 /**
158 * visu_node_values_pole_getAt:
159 * @pole: a #VisuNodeValuesPole object.
160 * @node: a #VisuNode object.
161 * @order: a #VisuPoleOrder value.
162 *
163 * Retrieves the pole hosted on @node.
164 *
165 * Since: 3.8
166 *
167 * Returns: (array fixed-size=3) (transfer none): the coordinates of
168 * pole for @node.
169 **/
visu_node_values_pole_getAt(const VisuNodeValuesPole * pole,const VisuNode * node,VisuPoleOrder order)170 const gfloat* visu_node_values_pole_getAt(const VisuNodeValuesPole *pole,
171 const VisuNode *node,
172 VisuPoleOrder order)
173 {
174 GValue diffValue = G_VALUE_INIT;
175 const gfloat *diff;
176
177 diff = (const gfloat*)0;
178 if (visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &diffValue))
179 diff = (const gfloat*)g_value_get_pointer(&diffValue);
180 switch (order)
181 {
182 case VISU_MONOPOLE:
183 return (diff) ? diff : zmono;
184 case VISU_DIPOLE:
185 return (diff) ? diff + 1: zdi;
186 case VISU_QUADRUPOLE:
187 return (diff) ? diff + 4: zquad;
188 default:
189 return (const gfloat*)0;
190 }
191 }
192
193 /**
194 * visu_node_values_pole_setMonoAt:
195 * @pole: a #VisuNodeValuesPole object.
196 * @node: a #VisuNode object.
197 * @val: a mono-pole value.
198 *
199 * Changes the mono-pole hosted at @node.
200 *
201 * Since: 3.8
202 *
203 * Returns: TRUE if pole for @node is indeed changed.
204 **/
visu_node_values_pole_setMonoAt(VisuNodeValuesPole * pole,const VisuNode * node,gfloat val)205 gboolean visu_node_values_pole_setMonoAt(VisuNodeValuesPole *pole,
206 const VisuNode *node, gfloat val)
207 {
208 gfloat *vals, poles[9];
209 GValue gval = G_VALUE_INIT;
210
211 visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
212 vals = (gfloat*)g_value_get_pointer(&gval);
213 if (vals && vals[0] == val)
214 return FALSE;
215
216 if (!vals)
217 {
218 vals = poles;
219 memset(poles, '\0', sizeof(gfloat) * 9);
220 }
221 vals[0] = val;
222 g_value_set_pointer(&gval, vals);
223 return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
224 }
225 /**
226 * visu_node_values_pole_setMonoAtDbl:
227 * @pole: a #VisuNodeValuesPole object.
228 * @node: a #VisuNode object.
229 * @val: a mono-pole value.
230 *
231 * Changes the mono-pole hosted at @node.
232 *
233 * Since: 3.8
234 *
235 * Returns: TRUE if pole for @node is indeed changed.
236 **/
visu_node_values_pole_setMonoAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,gdouble val)237 gboolean visu_node_values_pole_setMonoAtDbl(VisuNodeValuesPole *pole,
238 const VisuNode *node, gdouble val)
239 {
240 return visu_node_values_pole_setMonoAt(pole, node, val);
241 }
242
243 /**
244 * visu_node_values_pole_setDiAt:
245 * @pole: a #VisuNodeValuesPole object.
246 * @node: a #VisuNode object.
247 * @val: a di-pole value.
248 *
249 * Changes the di-pole hosted at @node.
250 *
251 * Since: 3.8
252 *
253 * Returns: TRUE if pole for @node is indeed changed.
254 **/
visu_node_values_pole_setDiAt(VisuNodeValuesPole * pole,const VisuNode * node,const gfloat val[3])255 gboolean visu_node_values_pole_setDiAt(VisuNodeValuesPole *pole,
256 const VisuNode *node, const gfloat val[3])
257 {
258 gfloat *vals, poles[9];
259 GValue gval = G_VALUE_INIT;
260
261 visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
262 vals = (gfloat*)g_value_get_pointer(&gval);
263 if (vals && vals[1] == val[0] && vals[2] == val[1] && vals[3] == val[2])
264 return FALSE;
265
266 if (!vals)
267 {
268 vals = poles;
269 memset(poles, '\0', sizeof(gfloat) * 9);
270 }
271 vals[1] = val[0];
272 vals[2] = val[1];
273 vals[3] = val[2];
274 g_value_set_pointer(&gval, vals);
275 return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
276 }
277 /**
278 * visu_node_values_pole_setDiAtDbl:
279 * @pole: a #VisuNodeValuesPole object.
280 * @node: a #VisuNode object.
281 * @val: a di-pole value.
282 *
283 * Changes the di-pole hosted at @node.
284 *
285 * Since: 3.8
286 *
287 * Returns: TRUE if pole for @node is indeed changed.
288 **/
visu_node_values_pole_setDiAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,const gdouble val[3])289 gboolean visu_node_values_pole_setDiAtDbl(VisuNodeValuesPole *pole,
290 const VisuNode *node, const gdouble val[3])
291 {
292 gfloat fval[3];
293 fval[0] = val[0];
294 fval[1] = val[1];
295 fval[2] = val[2];
296 return visu_node_values_pole_setDiAt(pole, node, fval);
297 }
298
299 /**
300 * visu_node_values_pole_setQuadAt:
301 * @pole: a #VisuNodeValuesPole object.
302 * @node: a #VisuNode object.
303 * @val: a quadru-pole value.
304 *
305 * Changes the quadru-pole hosted at @node.
306 *
307 * Since: 3.8
308 *
309 * Returns: TRUE if pole for @node is indeed changed.
310 **/
visu_node_values_pole_setQuadAt(VisuNodeValuesPole * pole,const VisuNode * node,const gfloat val[5])311 gboolean visu_node_values_pole_setQuadAt(VisuNodeValuesPole *pole,
312 const VisuNode *node, const gfloat val[5])
313 {
314 gfloat *vals, poles[9];
315 GValue gval = G_VALUE_INIT;
316
317 visu_node_values_getAt(VISU_NODE_VALUES(pole), node, &gval);
318 vals = (gfloat*)g_value_get_pointer(&gval);
319 if (vals && vals[4] == val[0] && vals[5] == val[1] && vals[6] == val[2] && vals[7] == val[3] && vals[8] == val[4])
320 return FALSE;
321
322 if (!vals)
323 {
324 vals = poles;
325 memset(poles, '\0', sizeof(gfloat) * 9);
326 }
327 vals[4] = val[0];
328 vals[5] = val[1];
329 vals[6] = val[2];
330 vals[7] = val[3];
331 vals[8] = val[4];
332 g_value_set_pointer(&gval, vals);
333 return visu_node_values_setAt(VISU_NODE_VALUES(pole), node, &gval);
334 }
335 /**
336 * visu_node_values_pole_setQuadAtDbl:
337 * @pole: a #VisuNodeValuesPole object.
338 * @node: a #VisuNode object.
339 * @val: a quadru-pole value.
340 *
341 * Changes the quadru-pole hosted at @node.
342 *
343 * Since: 3.8
344 *
345 * Returns: TRUE if pole for @node is indeed changed.
346 **/
visu_node_values_pole_setQuadAtDbl(VisuNodeValuesPole * pole,const VisuNode * node,const gdouble val[5])347 gboolean visu_node_values_pole_setQuadAtDbl(VisuNodeValuesPole *pole,
348 const VisuNode *node, const gdouble val[5])
349 {
350 gfloat fval[5];
351 fval[0] = val[0];
352 fval[1] = val[1];
353 fval[2] = val[2];
354 fval[3] = val[3];
355 fval[4] = val[4];
356 return visu_node_values_pole_setQuadAt(pole, node, fval);
357 }
358