1 /* EXTRAITS DE LA LICENCE
2 Copyright CEA, contributeurs : Damien
3 CALISTE, laboratoire L_Sim, (2016)
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, (2016)
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 "visu_dataatomic.h"
44
45 #include "visu_basic.h"
46
47 #include "loaders/atomic_ascii.h"
48 #include "loaders/atomic_d3.h"
49 #include "loaders/atomic_xyz.h"
50 #include "loaders/atomic_yaml.h"
51
52 /**
53 * SECTION: visu_dataatomic
54 * @short_description: a class of nodes representing atomic data and
55 * providing associated loading methods.
56 *
57 * <para>This class provides #VisuDataLoader for atomic data representation.</para>
58 */
59
60 enum
61 {
62 PROP_0,
63 PROP_FILE,
64 PROP_FORMAT,
65 N_PROP,
66 PROP_LABEL
67 };
68 static GParamSpec *_properties[N_PROP];
69
70 struct _VisuDataAtomicPrivate
71 {
72 gchar *file;
73 VisuDataLoader *format;
74 };
75
76 static GList *_atomicFormats = NULL;
_initAtomicFormats(void)77 static void _initAtomicFormats(void)
78 {
79 visu_data_atomic_class_addLoader(visu_data_loader_ascii_getStatic());
80 visu_data_atomic_class_addLoader(visu_data_loader_d3_getStatic());
81 visu_data_atomic_class_addLoader(visu_data_loader_xyz_getStatic());
82 if (visu_data_loader_yaml_getStatic())
83 visu_data_atomic_class_addLoader(visu_data_loader_yaml_getStatic());
84 }
85
86 static void visu_data_atomic_finalize (GObject* obj);
87 static void visu_data_atomic_get_property(GObject* obj, guint property_id,
88 GValue *value, GParamSpec *pspec);
89 static void visu_data_atomic_set_property(GObject* obj, guint property_id,
90 const GValue *value, GParamSpec *pspec);
91 static gboolean visu_data_atomic_load(VisuDataLoadable *self, guint iSet,
92 GCancellable *cancel, GError **error);
93 static const gchar* visu_data_atomic_getFilename(const VisuDataLoadable *self,
94 guint fileType);
95
G_DEFINE_TYPE_WITH_CODE(VisuDataAtomic,visu_data_atomic,VISU_TYPE_DATA_LOADABLE,G_ADD_PRIVATE (VisuDataAtomic))96 G_DEFINE_TYPE_WITH_CODE(VisuDataAtomic, visu_data_atomic, VISU_TYPE_DATA_LOADABLE,
97 G_ADD_PRIVATE(VisuDataAtomic))
98
99 static void visu_data_atomic_class_init(VisuDataAtomicClass *klass)
100 {
101 /* Connect the overloading methods. */
102 G_OBJECT_CLASS(klass)->finalize = visu_data_atomic_finalize;
103 G_OBJECT_CLASS(klass)->get_property = visu_data_atomic_get_property;
104 G_OBJECT_CLASS(klass)->set_property = visu_data_atomic_set_property;
105 VISU_DATA_LOADABLE_CLASS(klass)->load = visu_data_atomic_load;
106 VISU_DATA_LOADABLE_CLASS(klass)->getFilename = visu_data_atomic_getFilename;
107
108 g_object_class_override_property(G_OBJECT_CLASS(klass), PROP_LABEL, "label");
109
110 /**
111 * VisuDataAtomic::atomic-filename:
112 *
113 * The path to the source filename.
114 *
115 * Since: 3.8
116 */
117 _properties[PROP_FILE] =
118 g_param_spec_string("atomic-filename", "Atomic filename", "source filename",
119 (gchar*)0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
120 /**
121 * VisuDataAtomic::atomic-format:
122 *
123 * The format of the source filename, if known.
124 *
125 * Since: 3.8
126 */
127 _properties[PROP_FORMAT] =
128 g_param_spec_object("atomic-format", "Atomic format", "source format",
129 VISU_TYPE_DATA_LOADER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
130 g_object_class_install_properties(G_OBJECT_CLASS(klass), N_PROP, _properties);
131
132 _initAtomicFormats();
133 }
visu_data_atomic_init(VisuDataAtomic * obj)134 static void visu_data_atomic_init(VisuDataAtomic *obj)
135 {
136 obj->priv = visu_data_atomic_get_instance_private(obj);
137
138 /* Private data. */
139 obj->priv->file = (gchar*)0;
140 obj->priv->format = (VisuDataLoader*)0;
141 }
visu_data_atomic_finalize(GObject * obj)142 static void visu_data_atomic_finalize(GObject* obj)
143 {
144 VisuDataAtomic *data;
145
146 data = VISU_DATA_ATOMIC(obj);
147
148 g_free(data->priv->file);
149
150 /* Chain up to the parent class */
151 G_OBJECT_CLASS(visu_data_atomic_parent_class)->finalize(obj);
152 }
visu_data_atomic_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)153 static void visu_data_atomic_get_property(GObject* obj, guint property_id,
154 GValue *value, GParamSpec *pspec)
155 {
156 VisuDataAtomic *self = VISU_DATA_ATOMIC(obj);
157
158 switch (property_id)
159 {
160 case PROP_LABEL:
161 g_value_take_string(value, g_path_get_basename(self->priv->file));
162 break;
163 case PROP_FILE:
164 g_value_set_string(value, self->priv->file);
165 break;
166 case PROP_FORMAT:
167 g_value_set_object(value, self->priv->format);
168 break;
169 default:
170 /* We don't have any other property... */
171 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
172 break;
173 }
174 }
visu_data_atomic_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)175 static void visu_data_atomic_set_property(GObject* obj, guint property_id,
176 const GValue *value, GParamSpec *pspec)
177 {
178 VisuDataAtomic *self = VISU_DATA_ATOMIC(obj);
179
180 switch (property_id)
181 {
182 case PROP_FILE:
183 self->priv->file = tool_path_normalize(g_value_get_string(value));
184 break;
185 case PROP_FORMAT:
186 self->priv->format = g_value_get_object(value);
187 break;
188 default:
189 /* We don't have any other property... */
190 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
191 break;
192 }
193 }
194
195 /**
196 * visu_data_atomic_new:
197 * @file: a filename.
198 * @format: (allow-none): a #VisuDataLoader format, if known.
199 *
200 * Creates a #VisuDataAtomic object and set @file to it.
201 *
202 * Since: 3.8
203 *
204 * Returns: a newly allocated #VisuDataAtomic object.
205 **/
visu_data_atomic_new(const gchar * file,VisuDataLoader * format)206 VisuDataAtomic* visu_data_atomic_new(const gchar *file, VisuDataLoader *format)
207 {
208 return g_object_new(VISU_TYPE_DATA_ATOMIC, "n-files", 1,
209 "atomic-filename", file, "atomic-format", format, NULL);
210 }
211
212 /**
213 * visu_data_atomic_class_addLoader:
214 * @loader: (transfer full): a #VisuDataLoader object.
215 *
216 * Add @loader to the list of #VisuDataLoader to be used when
217 * visu_data_loadable_load() is called.
218 *
219 * Since: 3.8
220 **/
visu_data_atomic_class_addLoader(VisuDataLoader * loader)221 void visu_data_atomic_class_addLoader(VisuDataLoader *loader)
222 {
223 if (g_list_find(_atomicFormats, loader))
224 return;
225
226 g_return_if_fail(VISU_IS_DATA_LOADER(loader));
227 DBG_fprintf(stderr, "Data Atomic: adding a new loader '%s'.\n",
228 tool_file_format_getName(TOOL_FILE_FORMAT(loader)));
229 tool_file_format_setPropertiesFromCLI(TOOL_FILE_FORMAT(loader));
230 _atomicFormats = g_list_prepend(_atomicFormats, loader);
231 _atomicFormats = g_list_sort(_atomicFormats,
232 (GCompareFunc)visu_data_loader_comparePriority);
233 }
234
235 /**
236 * visu_data_atomic_class_getLoaders:
237 *
238 * Returns a list of available #VisuDataLoader.
239 *
240 * Since: 3.8
241 *
242 * Returns: (transfer none) (element-type VisuDataLoader): a list of
243 * #VisuDataLoader owned by V_Sim.
244 **/
visu_data_atomic_class_getLoaders(void)245 GList* visu_data_atomic_class_getLoaders(void)
246 {
247 return _atomicFormats;
248 }
249 /**
250 * visu_data_atomic_class_getFileDescription:
251 *
252 * Returns a translated string describing what is files loaded by
253 * #VisuDataAtomic objects.
254 *
255 * Since: 3.8
256 *
257 * Returns: a string owned by V_Sim.
258 **/
visu_data_atomic_class_getFileDescription(void)259 const gchar* visu_data_atomic_class_getFileDescription(void)
260 {
261 return _("Position files");
262 }
263 /**
264 * visu_data_atomic_class_finalize:
265 *
266 * Empty the list of known loaders.
267 *
268 * Since: 3.8
269 **/
visu_data_atomic_class_finalize(void)270 void visu_data_atomic_class_finalize(void)
271 {
272 g_list_free_full(_atomicFormats, (GDestroyNotify)g_object_unref);
273 _atomicFormats = (GList*)0;
274 }
275
276 /**
277 * visu_data_atomic_getFile:
278 * @data: a #VisuDataAtomic object.
279 * @format: (out caller-allocates): a location to store a
280 * #VisuDataLoader object.
281 *
282 * Returns the file defined in @data and its associated @format, if any.
283 *
284 * Since: 3.8
285 *
286 * Returns: a string owned by V_Sim.
287 **/
visu_data_atomic_getFile(VisuDataAtomic * data,VisuDataLoader ** format)288 const gchar* visu_data_atomic_getFile(VisuDataAtomic *data, VisuDataLoader **format)
289 {
290 g_return_val_if_fail(VISU_IS_DATA_ATOMIC(data), (const gchar*)0);
291
292 if (format)
293 *format = data->priv->format;
294 return data->priv->file;
295 }
visu_data_atomic_getFilename(const VisuDataLoadable * self,guint fileType)296 static const gchar* visu_data_atomic_getFilename(const VisuDataLoadable *self,
297 guint fileType)
298 {
299 g_return_val_if_fail(fileType == 0, (const gchar*)0);
300
301 return visu_data_atomic_getFile(VISU_DATA_ATOMIC(self), (VisuDataLoader**)0);
302 }
303
_finalize(VisuDataAtomic * data,VisuDataLoader * loader)304 static gboolean _finalize(VisuDataAtomic *data, VisuDataLoader *loader)
305 {
306 VisuNodeArrayIter iter;
307 ToolUnits unit, preferedUnit;
308 VisuBox *box;
309
310 /* We do a last check on population... in case. */
311 visu_node_array_iter_new(VISU_NODE_ARRAY(data), &iter);
312 g_return_val_if_fail(iter.nAllStoredNodes, FALSE);
313 DBG_fprintf(stderr, "Data Atomic: loading OK (%d nodes).\n", iter.nAllStoredNodes);
314
315 /* Setup additional infos. */
316 box = visu_boxed_getBox(VISU_BOXED(data));
317 unit = visu_box_getUnit(box);
318 preferedUnit = visu_basic_getPreferedUnit();
319 if (preferedUnit != TOOL_UNITS_UNDEFINED &&
320 unit != TOOL_UNITS_UNDEFINED &&
321 unit != preferedUnit)
322 visu_box_setUnit(box, preferedUnit);
323
324 visu_node_array_completeAdding(VISU_NODE_ARRAY(data));
325
326 data->priv->format = loader;
327
328 return TRUE;
329 }
330
_abort(VisuDataAtomic * data)331 static gboolean _abort(VisuDataAtomic *data)
332 {
333 visu_node_array_completeAdding(VISU_NODE_ARRAY(data));
334
335 return FALSE;
336 }
337
visu_data_atomic_load(VisuDataLoadable * self,guint iSet,GCancellable * cancel,GError ** error)338 static gboolean visu_data_atomic_load(VisuDataLoadable *self, guint iSet,
339 GCancellable *cancel, GError **error)
340 {
341 VisuDataAtomic *data;
342 GList *lst;
343 VisuDataLoader *loader;
344
345 g_return_val_if_fail(VISU_IS_DATA_ATOMIC(self), FALSE);
346
347 data = VISU_DATA_ATOMIC(self);
348
349 if (!visu_data_loadable_checkFile(self, 0, error))
350 return FALSE;
351
352 visu_node_array_startAdding(VISU_NODE_ARRAY(self));
353 for (lst = _atomicFormats; lst; lst = g_list_next(lst))
354 {
355 loader = VISU_DATA_LOADER(lst->data);
356
357 /* Each load may set error even if the format is not recognise
358 and loadOK is FALSE, then we need to free the error. */
359 g_clear_error(error);
360
361 if (!data->priv->format || loader == data->priv->format)
362 {
363 DBG_fprintf(stderr,"Data Atomic: testing '%s' with format: %s.\n",
364 data->priv->file, tool_file_format_getName(TOOL_FILE_FORMAT(loader)));
365 if (visu_data_loader_load(loader, self, 0, iSet, cancel, error))
366 return (*error) ? _abort(data) : _finalize(data, loader);
367 if (*error && (*error)->domain == G_FILE_ERROR)
368 return _abort(data);
369 if (*error && data->priv->format)
370 return _abort(data);
371 }
372 }
373 g_clear_error(error);
374 g_set_error(error, VISU_DATA_LOADABLE_ERROR, DATA_LOADABLE_ERROR_UNKNOWN,
375 _("Impossible to load '%s', unrecognised format.\n"), data->priv->file);
376 return _abort(data);
377 }
378
379 /**
380 * visu_data_atomic_loadAt:
381 * @data: a #VisuDataAtomic object.
382 * @filename: a filename.
383 * @iSet: an id.
384 * @cancel: a #GCancellable object.
385 * @error: an error location.
386 *
387 * Specific routine to load an atomic file that is not stored in the
388 * location declared at construction. This is only used for archive plug-in.
389 *
390 * Since: 3.8
391 *
392 * Returns: TRUE on success.
393 **/
visu_data_atomic_loadAt(VisuDataAtomic * data,const gchar * filename,guint iSet,GCancellable * cancel,GError ** error)394 gboolean visu_data_atomic_loadAt(VisuDataAtomic *data, const gchar *filename, guint iSet, GCancellable *cancel, GError **error)
395 {
396 gchar *old;
397 gboolean res;
398
399 g_return_val_if_fail(VISU_IS_DATA_ATOMIC(data), FALSE);
400 old = data->priv->file;
401 data->priv->file = (gchar*)filename;
402 res = visu_data_atomic_load(VISU_DATA_LOADABLE(data), iSet, cancel, error);
403 data->priv->file = old;
404 return res;
405 }
406
407 /**
408 * visu_data_atomic_getForces:
409 * @dataObj: a #VisuDataAtomic object.
410 * @create: a boolean.
411 *
412 * Retrieves the #VisuNodeValuesVector used to store forces for
413 * @dataObj, create it depending on @create if not exists.
414 *
415 * Since: 3.8
416 *
417 * Returns: (transfer none): a #VisuNodeValuesVector object, owned by V_Sim.
418 **/
visu_data_atomic_getForces(VisuDataAtomic * dataObj,gboolean create)419 VisuNodeValuesVector* visu_data_atomic_getForces(VisuDataAtomic *dataObj,
420 gboolean create)
421 {
422 VisuNodeValuesVector *vect;
423
424 if (!dataObj)
425 return (VisuNodeValuesVector*)0;
426
427 vect = (VisuNodeValuesVector*)visu_data_getNodeProperties(VISU_DATA(dataObj),
428 _("Forces"));
429 if (!vect && create)
430 {
431 vect = visu_node_values_vector_new(VISU_NODE_ARRAY(dataObj),
432 _("Forces"));
433 visu_node_values_setEditable(VISU_NODE_VALUES(vect), FALSE);
434 visu_data_addNodeProperties(VISU_DATA(dataObj), VISU_NODE_VALUES(vect));
435 }
436 return vect;
437 }
438