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 "floatProp.h" 44 45 #include <math.h> 46 47 /** 48 * SECTION:floatProp 49 * @short_description: define a #VisuNodeValues object to handle any 50 * array of floats. 51 * 52 * <para>Defines a #VisuNodeValues object to store floating point 53 * arrays on every nodes and get notification for them.</para> 54 */ 55 56 struct _VisuNodeValuesFarrayPrivate 57 { 58 gboolean dispose_has_run; 59 60 gboolean dirty; 61 gfloat min, max, nrm2; 62 gfloat *zeros; 63 64 GArray *readMinMax; /* Values min and max read for each column. */ 65 66 gchar *file; 67 }; 68 69 enum 70 { 71 PROP_0, 72 MIN_PROP, 73 MAX_PROP, 74 NRM2_PROP, 75 READ_MM_PROP, 76 FILE_PROP, 77 N_PROP 78 }; 79 static GParamSpec *_properties[N_PROP]; 80 81 static void visu_node_values_farray_finalize (GObject* obj); 82 static void visu_node_values_farray_get_property(GObject* obj, guint property_id, 83 GValue *value, GParamSpec *pspec); 84 static gboolean _setAt(VisuNodeValues *vals, const VisuNode *node, 85 GValue *value); 86 static gfloat _nrm2(const VisuNodeValuesFarray *vect, const GValue *value); 87 static void _compute(VisuNodeValuesFarray *vect); 88 static void onDimensionSet(VisuNodeValuesFarray *vect, const GParamSpec *pspec, gpointer data); 89 90 G_DEFINE_TYPE_WITH_CODE(VisuNodeValuesFarray, visu_node_values_farray, VISU_TYPE_NODE_VALUES, 91 G_ADD_PRIVATE(VisuNodeValuesFarray)) 92 93 static void visu_node_values_farray_class_init(VisuNodeValuesFarrayClass *klass) 94 { 95 /* Connect the overloading methods. */ 96 G_OBJECT_CLASS(klass)->finalize = visu_node_values_farray_finalize; 97 /* G_OBJECT_CLASS(klass)->set_property = visu_node_values_farray_set_property; */ 98 G_OBJECT_CLASS(klass)->get_property = visu_node_values_farray_get_property; 99 VISU_NODE_VALUES_CLASS(klass)->setAt = _setAt; 100 klass->nrm2 = _nrm2; 101 102 /** 103 * VisuNodeValuesFarray::minimum: 104 * 105 * Holds the norm of the minimum value. 106 * 107 * Since: 3.8 108 */ 109 _properties[MIN_PROP] = 110 g_param_spec_float("minimum", "Minimum", "minimum norm", 111 0.f, G_MAXFLOAT, 0.f, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); 112 /** 113 * VisuNodeValuesFarray::maximum: 114 * 115 * Holds the norm of the maximum value. 116 * 117 * Since: 3.8 118 */ 119 _properties[MAX_PROP] = 120 g_param_spec_float("maximum", "Maximum", "maximum norm", 121 0.f, G_MAXFLOAT, 0.f, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); 122 /** 123 * VisuNodeValuesFarray::square-norm: 124 * 125 * Holds the square norm of the values. 126 * 127 * Since: 3.8 128 */ 129 _properties[NRM2_PROP] = 130 g_param_spec_float("square-norm", "Square-norm", "Square norm", 131 0.f, G_MAXFLOAT, 0.f, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); 132 /** 133 * VisuNodeValuesFarray::data-min-max: 134 * 135 * Min / max values per dimension of the stored data. 136 * 137 * Since: 3.8 138 */ 139 _properties[READ_MM_PROP] = 140 g_param_spec_boxed("data-min-max", "Data min/max", 141 "min / max values of data", 142 G_TYPE_ARRAY, 143 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); 144 /** 145 * VisuNodeValuesFarray::source-file: 146 * 147 * Name of the source file the data come from. 148 * 149 * Since: 3.8 150 */ 151 _properties[FILE_PROP] = g_param_spec_string("source-file", "Source file", 152 "Source file if any", 153 (const gchar*)0, 154 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); 155 156 g_object_class_install_properties(G_OBJECT_CLASS(klass), N_PROP, _properties); 157 } 158 159 static void visu_node_values_farray_init(VisuNodeValuesFarray *self) 160 { 161 DBG_fprintf(stderr, "Node Values Float : initialise %p.\n", (gpointer)self); 162 163 self->priv = visu_node_values_farray_get_instance_private(self); 164 165 self->priv->readMinMax = g_array_new(FALSE, FALSE, sizeof(float) * 2); 166 self->priv->file = (gchar*)0; 167 self->priv->dirty = TRUE; 168 169 g_signal_connect(G_OBJECT(self), "notify::n-elements", 170 G_CALLBACK(onDimensionSet), (gpointer)0); 171 } 172 static void onDimensionSet(VisuNodeValuesFarray *vect, 173 const GParamSpec *pspec _U_, gpointer data _U_) 174 { 175 vect->priv->zeros = g_malloc0(sizeof(float) * visu_node_values_getDimension(VISU_NODE_VALUES(vect))); 176 } 177 178 /* This method is called once only. */ 179 static void visu_node_values_farray_finalize(GObject* obj) 180 { 181 VisuNodeValuesFarray *self; 182 183 DBG_fprintf(stderr, "Node Values Float : finalize %p.\n", (gpointer)obj); 184 185 g_return_if_fail(obj); 186 187 self = VISU_NODE_VALUES_FARRAY(obj); 188 g_free(self->priv->zeros); 189 g_array_unref(self->priv->readMinMax); 190 g_free(self->priv->file); 191 192 /* Chain up to the parent class */ 193 G_OBJECT_CLASS(visu_node_values_farray_parent_class)->finalize(obj); 194 } 195 static void visu_node_values_farray_get_property(GObject* obj, guint property_id, 196 GValue *value, GParamSpec *pspec) 197 { 198 VisuNodeValuesFarray *self = VISU_NODE_VALUES_FARRAY(obj); 199 200 switch (property_id) 201 { 202 case MIN_PROP: 203 g_value_set_float(value, visu_node_values_farray_min(self)); 204 break; 205 case MAX_PROP: 206 g_value_set_float(value, visu_node_values_farray_max(self)); 207 break; 208 case NRM2_PROP: 209 g_value_set_float(value, visu_node_values_farray_nrm2(self)); 210 break; 211 case READ_MM_PROP: 212 _compute(self); 213 g_value_set_boxed(value, self->priv->readMinMax); 214 break; 215 case FILE_PROP: 216 g_value_set_static_string(value, self->priv->file); 217 break; 218 default: 219 /* We don't have any other property... */ 220 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec); 221 break; 222 } 223 } 224 static gfloat _nrm2(const VisuNodeValuesFarray *vect, const GValue *value) 225 { 226 gfloat *diff, nrm2; 227 guint i, ln; 228 229 diff = (gfloat*)g_value_get_pointer(value); 230 if (diff) 231 { 232 ln = visu_node_values_getDimension(VISU_NODE_VALUES(vect)); 233 nrm2 = 0.f; 234 for (i = 0; i < ln; i++) 235 nrm2 += diff[i] * diff[i]; 236 return nrm2; 237 } 238 else 239 return 0.f; 240 } 241 242 /** 243 * visu_node_values_farray_new: 244 * @arr: a #VisuNodeArray object. 245 * @label: a translatable label. 246 * @dimension: a integer value. 247 * 248 * Create a new farray field located on nodes, storing @dimension 249 * floats per node. 250 * 251 * Since: 3.8 252 * 253 * Returns: (transfer full): a newly created #VisuNodeValuesFarray object. 254 **/ 255 VisuNodeValuesFarray* visu_node_values_farray_new(VisuNodeArray *arr, 256 const gchar *label, 257 guint dimension) 258 { 259 VisuNodeValuesFarray *vals; 260 261 vals = VISU_NODE_VALUES_FARRAY(g_object_new(VISU_TYPE_NODE_VALUES_FARRAY, 262 "nodes", arr, "label", label, 263 "type", G_TYPE_FLOAT, 264 "n-elements", dimension, NULL)); 265 return vals; 266 } 267 /** 268 * visu_node_values_farray_new_fromFile: 269 * @arr: a #VisuNodeArray object. 270 * @label: a label. 271 * @filename: a filename. 272 * @error: an error location. 273 * 274 * Parse @filename to read floating point values and creates a new 275 * #VisuNodeValuesFarray object based on @arr. If an error occurs, an 276 * empty #VisuNodeValuesFarray object is created. 277 * 278 * Since: 3.8 279 * 280 * Returns: (transfer full): a newly created #VisuNodeValuesFarray object. 281 **/ 282 VisuNodeValuesFarray* visu_node_values_farray_new_fromFile(VisuNodeArray *arr, 283 const gchar *label, 284 const gchar *filename, 285 GError **error) 286 { 287 guint nColumns, nbNodes; 288 GArray *data; 289 VisuNodeValuesFarray *vals; 290 291 nbNodes = visu_node_array_getNNodes(arr); 292 data = tool_array_sizedFromFile(filename, nbNodes, &nColumns, error); 293 if (!data) 294 return visu_node_values_farray_new(arr, label, 1); 295 296 vals = visu_node_values_farray_new(arr, label, nColumns); 297 visu_node_values_farray_set(vals, data); 298 vals->priv->file = g_strdup(filename); 299 300 g_array_free(data, TRUE); 301 302 return vals; 303 } 304 305 /** 306 * visu_node_values_farray_min: 307 * @vect: a #VisuNodeValuesFarray object. 308 * 309 * Computes and returns the smallest farray in the field. 310 * 311 * Since: 3.8 312 * 313 * Returns: the minimum farray norm. 314 **/ 315 gfloat visu_node_values_farray_min(VisuNodeValuesFarray *vect) 316 { 317 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), G_MAXFLOAT); 318 _compute(vect); 319 return vect->priv->min; 320 } 321 /** 322 * visu_node_values_farray_max: 323 * @vect: a #VisuNodeValuesFarray object. 324 * 325 * Computes and returns the longest farray in the field. 326 * 327 * Since: 3.8 328 * 329 * Returns: the maximum farray norm. 330 **/ 331 gfloat visu_node_values_farray_max(VisuNodeValuesFarray *vect) 332 { 333 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), -1.f); 334 _compute(vect); 335 return vect->priv->max; 336 } 337 /** 338 * visu_node_values_farray_nrm2: 339 * @vect: a #VisuNodeValuesFarray object. 340 * 341 * Computes and returns the sum of square norm all farrays in the field. 342 * 343 * Since: 3.8 344 * 345 * Returns: the square norm of the farray field. 346 **/ 347 gfloat visu_node_values_farray_nrm2(VisuNodeValuesFarray *vect) 348 { 349 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), -1.f); 350 _compute(vect); 351 return vect->priv->nrm2; 352 } 353 /** 354 * visu_node_values_farray_getColumnMinMax: 355 * @vect: the #VisuNodeValuesFarray object. 356 * @minMax: (array fixed-size=2) (out): an allocated array of two 357 * floating point values ; 358 * @column: an integer. 359 * 360 * This method is used to retrieve the minimum and the maximum 361 * values of the column designed by the @column argument. Column 362 * are numbered beginning at 0. 363 * 364 * Returns: FALSE if @column < 0 or if @column is greater than the number 365 * of read column or if no file has been set. 366 */ 367 gboolean visu_node_values_farray_getColumnMinMax(VisuNodeValuesFarray *vect, 368 float minMax[2], guint column) 369 { 370 float *minmax; 371 372 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), FALSE); 373 374 _compute(vect); 375 g_return_val_if_fail(column < vect->priv->readMinMax->len, FALSE); 376 377 minmax = &g_array_index(vect->priv->readMinMax, float, column * 2); 378 minMax[0] = minmax[0]; 379 minMax[1] = minmax[1]; 380 return TRUE; 381 } 382 static void _compute(VisuNodeValuesFarray *vect) 383 { 384 float nrm2; 385 gboolean valid; 386 guint i, ln; 387 VisuNodeValuesIter iter; 388 VisuNodeValuesFarrayClass *klass = VISU_NODE_VALUES_FARRAY_GET_CLASS(vect); 389 float init[2] = {G_MAXFLOAT, -G_MAXFLOAT}; 390 float *data, *minmax; 391 392 DBG_fprintf(stderr, "Node Values Float (%p): recompute %d.\n", 393 (gpointer)vect, vect->priv->dirty); 394 if (!vect->priv->dirty) 395 return; 396 vect->priv->dirty = FALSE; 397 398 vect->priv->nrm2 = 0.f; 399 vect->priv->min = G_MAXFLOAT; 400 vect->priv->max = 0.f; 401 402 valid = visu_node_values_iter_new(&iter, ITER_NODES_BY_TYPE, 403 VISU_NODE_VALUES(vect)); 404 while (valid) 405 { 406 nrm2 = klass->nrm2(vect, &iter.value); 407 if (nrm2 >= 0.f) 408 { 409 vect->priv->nrm2 += nrm2; 410 vect->priv->min = MIN(vect->priv->min, nrm2); 411 vect->priv->max = MAX(vect->priv->max, nrm2); 412 } 413 valid = visu_node_values_iter_next(&iter); 414 } 415 vect->priv->min = sqrt(vect->priv->min); 416 vect->priv->max = sqrt(vect->priv->max); 417 418 ln = visu_node_values_getDimension(VISU_NODE_VALUES(vect)); 419 g_array_set_size(vect->priv->readMinMax, ln); 420 /* Check for minMax values for each column. */ 421 for (i = 0; i < ln; i++) 422 g_array_insert_vals(vect->priv->readMinMax, i, init, 1); 423 for (visu_node_values_iter_new(&iter, ITER_NODES_BY_TYPE, 424 VISU_NODE_VALUES(vect)); 425 iter.iter.node; visu_node_values_iter_next(&iter)) 426 { 427 data = (float*)g_value_get_pointer(&iter.value); 428 if (!data) 429 continue; 430 for (i = 0; i < ln; i++) 431 { 432 minmax = &g_array_index(vect->priv->readMinMax, float, i * 2); 433 if (data[i] < minmax[0]) 434 minmax[0] = data[i]; 435 if (data[i] > minmax[1]) 436 minmax[1] = data[i]; 437 } 438 } 439 } 440 /** 441 * visu_node_values_farray_getAt: 442 * @vect: a #VisuNodeValuesFarray object. 443 * @node: a #VisuNode object. 444 * 445 * Retrieves the float array hosted on @node. 446 * 447 * Since: 3.8 448 * 449 * Returns: (transfer none): the coordinates of 450 * float array for @node. 451 **/ 452 const gfloat* visu_node_values_farray_getAt(VisuNodeValuesFarray *vect, 453 const VisuNode *node) 454 { 455 GValue diffValue = G_VALUE_INIT; 456 const gfloat *diff; 457 458 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), NULL); 459 460 visu_node_values_getAt(VISU_NODE_VALUES(vect), node, &diffValue); 461 diff = (const gfloat*)g_value_get_pointer(&diffValue); 462 return diff; /* ? diff : vect->priv->zeros; */ 463 } 464 465 /** 466 * visu_node_values_farray_getAtIter: 467 * @vect: a #VisuNodeValuesFarray object. 468 * @iter: an iterator on @vect. 469 * 470 * Provide the floats stored in @vect at @iter. 471 * 472 * Since: 3.8 473 * 474 * Returns: a pointer to the float array. 475 **/ 476 const gfloat* visu_node_values_farray_getAtIter(const VisuNodeValuesFarray *vect, 477 const VisuNodeValuesIter *iter) 478 { 479 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), NULL); 480 g_return_val_if_fail(iter, NULL); 481 482 return (const gfloat*)g_value_get_pointer(&iter->value); 483 } 484 485 /** 486 * visu_node_values_farray_getFloatAt: 487 * @vect: a #VisuNodeValuesFarray object. 488 * @node: a #VisuNode pointer. 489 * @column: a column id. 490 * 491 * Retrieves the float value stored for @node at @column, if any. 492 * 493 * Since: 3.8 494 * 495 * Returns: a float value. 496 **/ 497 gfloat visu_node_values_farray_getFloatAt(const VisuNodeValuesFarray *vect, 498 const VisuNode *node, 499 guint column) 500 { 501 GValue diffValue = G_VALUE_INIT; 502 const gfloat *vals; 503 504 g_return_val_if_fail(column < visu_node_values_getDimension(VISU_NODE_VALUES(vect)), 0.f); 505 506 visu_node_values_getAt(VISU_NODE_VALUES(vect), node, &diffValue); 507 vals = (const gfloat*)g_value_get_pointer(&diffValue); 508 509 return vals ? vals[column] : 0.f; 510 } 511 512 /** 513 * visu_node_values_farray_getFloatAtIter: 514 * @vect: a #VisuNodeValuesFarray object. 515 * @iter: a #VisuNodeValuesIter object. 516 * @column: a column id. 517 * 518 * Retrieves the float value stored for the current iteration of @iter 519 * for the column @column. @iter must be running on @vect. 520 * 521 * Since: 3.8 522 * 523 * Returns: a float value. 524 **/ 525 gfloat visu_node_values_farray_getFloatAtIter(const VisuNodeValuesFarray *vect, 526 const VisuNodeValuesIter *iter, 527 guint column) 528 { 529 const gfloat *vals; 530 531 g_return_val_if_fail(iter && iter->vals == VISU_NODE_VALUES(vect), 0.f); 532 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), 0.f); 533 g_return_val_if_fail(column < visu_node_values_getDimension(VISU_NODE_VALUES(vect)), 0.f); 534 535 vals = (const gfloat*)g_value_get_pointer(&iter->value); 536 537 return vals ? vals[column] : 0.f; 538 } 539 540 static gboolean _setAt(VisuNodeValues *vect, const VisuNode *node, 541 GValue *value) 542 { 543 gboolean res; 544 545 VISU_NODE_VALUES_FARRAY(vect)->priv->dirty = TRUE; 546 547 /* Chain up to parent. */ 548 res = VISU_NODE_VALUES_CLASS(visu_node_values_farray_parent_class)->setAt(vect, node, value); 549 550 if (res) 551 { 552 g_object_notify_by_pspec(G_OBJECT(vect), _properties[READ_MM_PROP]); 553 g_object_notify_by_pspec(G_OBJECT(vect), _properties[MIN_PROP]); 554 g_object_notify_by_pspec(G_OBJECT(vect), _properties[MAX_PROP]); 555 g_object_notify_by_pspec(G_OBJECT(vect), _properties[NRM2_PROP]); 556 } 557 558 return res; 559 } 560 /** 561 * visu_node_values_farray_setAt: 562 * @vect: a #VisuNodeValuesFarray object. 563 * @node: a #VisuNode object. 564 * @vals: (array length=ln): farray coordinates. 565 * @ln: a length. 566 * 567 * Changes the float array hosted at @node for one of values defined 568 * by @vals. 569 * 570 * Since: 3.8 571 * 572 * Returns: TRUE if farray for @node is indeed changed. 573 **/ 574 gboolean visu_node_values_farray_setAt(VisuNodeValuesFarray *vect, 575 const VisuNode *node, 576 const gfloat *vals, 577 guint ln) 578 { 579 gfloat *old; 580 guint i; 581 gboolean changed; 582 GValue value = {0, {{0}, {0}}}; 583 584 g_return_val_if_fail(visu_node_values_getDimension(VISU_NODE_VALUES(vect)) == ln, FALSE); 585 586 visu_node_values_getAt(VISU_NODE_VALUES(vect), node, &value); 587 old = (gfloat*)g_value_get_pointer(&value); 588 if (old) 589 { 590 changed = FALSE; 591 for (i = 0; i < ln && !changed; i++) 592 changed = (old[i] != vals[i]); 593 if (!changed) 594 return FALSE; 595 } 596 597 g_value_set_pointer(&value, (gpointer)vals); 598 return visu_node_values_setAt(VISU_NODE_VALUES(vect), node, &value); 599 } 600 /** 601 * visu_node_values_farray_setAtDbl: 602 * @vect: a #VisuNodeValuesFarray object. 603 * @node: a #VisuNode object. 604 * @vals: (array fixed-size=3): farray coordinates. 605 * @ln: a length. 606 * 607 * Same as visu_node_values_farray_setAt() but for double values. 608 * 609 * Since: 3.8 610 * 611 * Returns: TRUE if farray for @node is indeed changed. 612 **/ 613 gboolean visu_node_values_farray_setAtDbl(VisuNodeValuesFarray *vect, 614 const VisuNode *node, 615 const double *vals, 616 guint ln) 617 { 618 guint i; 619 gfloat *farr; 620 gboolean ret; 621 622 g_return_val_if_fail(visu_node_values_getDimension(VISU_NODE_VALUES(vect)) == ln, FALSE); 623 624 farr = g_malloc(sizeof(gfloat) * ln); 625 for (i = 0; i < ln; i++) 626 farr[i] = vals[i]; 627 ret = visu_node_values_farray_setAt(vect, node, farr, ln); 628 g_free(farr); 629 return ret; 630 } 631 /** 632 * visu_node_values_farray_set: 633 * @vect: a #VisuNodeValuesFarray object. 634 * @data: (element-type float): some farray coordinates. 635 * 636 * Assigns the coordinates stored in @data to each nodes in @vect. 637 * 638 * Since: 3.8 639 * 640 * Returns: TRUE if @data has the same size as @vect. 641 **/ 642 gboolean visu_node_values_farray_set(VisuNodeValuesFarray *vect, 643 const GArray *data) 644 { 645 guint i, ln; 646 gboolean valid; 647 VisuNodeValuesIter iter; 648 649 ln = visu_node_values_getDimension(VISU_NODE_VALUES(vect)); 650 g_return_val_if_fail(data && data->len % ln == 0, FALSE); 651 652 g_object_freeze_notify(G_OBJECT(vect)); 653 654 i = 0; 655 valid = visu_node_values_iter_new(&iter, ITER_NODES_BY_NUMBER, 656 VISU_NODE_VALUES(vect)); 657 while (valid && i + ln <= data->len) 658 { 659 visu_node_values_farray_setAt(vect, iter.iter.node, 660 &g_array_index(data, float, i), 661 ln); 662 i += ln; 663 valid = visu_node_values_iter_next(&iter); 664 } 665 666 g_object_thaw_notify(G_OBJECT(vect)); 667 668 return (i == data->len); 669 } 670 671 /** 672 * visu_node_values_farray_getFile: 673 * @vect: a #VisuNodeValuesFarray object. 674 * 675 * Retrieve the filename from which the values have been read, if any. 676 * 677 * Since: 3.8 678 * 679 * Returns: a filename. 680 **/ 681 const gchar* visu_node_values_farray_getFile(const VisuNodeValuesFarray *vect) 682 { 683 g_return_val_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect), (const gchar*)0); 684 685 return vect->priv->file; 686 } 687 688 /** 689 * visu_node_values_farray_scale: 690 * @vect: a #VisuNodeValuesFarray object. 691 * @factor: a factor. 692 * 693 * Multiply every element of @vect by @factor. 694 * 695 * Since: 3.8 696 **/ 697 void visu_node_values_farray_scale(VisuNodeValuesFarray *vect, gfloat factor) 698 { 699 guint i, ln; 700 VisuNodeValuesIter iter; 701 gfloat *data; 702 703 g_return_if_fail(VISU_IS_NODE_VALUES_FARRAY(vect)); 704 705 if (factor == 1.f) 706 return; 707 708 vect->priv->dirty = TRUE; 709 710 ln = visu_node_values_getDimension(VISU_NODE_VALUES(vect)); 711 for (visu_node_values_iter_new(&iter, ITER_NODES_BY_TYPE, 712 VISU_NODE_VALUES(vect)); 713 iter.iter.node; visu_node_values_iter_next(&iter)) 714 { 715 data = (gfloat*)g_value_get_pointer(&iter.value); 716 if (!data) 717 continue; 718 for (i = 0; i < ln; i++) 719 data[i] *= factor; 720 } 721 } 722