GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvl_calc.c
Go to the documentation of this file.
1 
19 #include <math.h>
20 
21 #include <grass/gis.h>
22 #include <grass/gstypes.h>
23 
24 #include "rgbpack.h"
25 #include "mc33_table.h"
26 
30 #define BUFFER_SIZE 1000000
31 
32 /* USEFUL MACROS */
33 
34 /* interp. */
35 #define LINTERP(d,a,b) (a + d * (b - a))
36 #define TINTERP(d,v) ((v[0]*(1.-d[0])*(1.-d[1])*(1.-d[2])) +\
37  (v[1]*d[0]*(1.-d[1])*(1.-d[2])) + \
38  (v[2]*d[0]*d[1]*(1.-d[2])) + \
39  (v[3]*(1.-d[0])*d[1]*(1.-d[2])) + \
40  (v[4]*(1.-d[0])*(1.-d[1])*d[2]) + \
41  (v[5]*d[0]*(1.-d[1])*d[2]) + \
42  (v[6]*d[0]*d[1]*d[2]) + \
43  (v[7]*(1.-d[0])*d[1]*d[2]))
44 
45 #define FOR_VAR i_for
46 #define FOR_0_TO_N(n, cmd) { int FOR_VAR; for (FOR_VAR = 0; FOR_VAR < n; FOR_VAR++) {cmd;} }
47 
51 #define WRITE(c) gvl_write_char(dbuff->ndx_new++, &(dbuff->new), c)
52 #define READ() gvl_read_char(dbuff->ndx_old++, dbuff->old)
53 #define SKIP(n) dbuff->ndx_old = dbuff->ndx_old + n
54 
58 #define IS_IN_DATA(att) ((isosurf->data_desc >> att) & 1)
59 #define SET_IN_DATA(att) isosurf->data_desc = (isosurf->data_desc | (1 << att))
60 
61 typedef struct
62 {
63  unsigned char *old;
64  unsigned char *new;
65  int ndx_old;
66  int ndx_new;
67  int num_zero;
68 } data_buffer;
69 
70 int mc33_process_cube(int c_ndx, float *v);
71 
72 /* global variables */
74 double ResX, ResY, ResZ;
75 
76 /************************************************************************/
77 /* ISOSURFACES */
78 
85 void iso_w_cndx(int ndx, data_buffer * dbuff)
86 {
87  /* cube don't contains polys */
88  if (ndx == -1) {
89  if (dbuff->num_zero == 0) {
90  WRITE(0);
91  dbuff->num_zero++;
92  }
93  else if (dbuff->num_zero == 254) {
94  WRITE(dbuff->num_zero + 1);
95  dbuff->num_zero = 0;
96  }
97  else {
98  dbuff->num_zero++;
99  }
100  }
101  else { /* isosurface cube */
102  if (dbuff->num_zero == 0) {
103  WRITE((ndx / 256) + 1);
104  WRITE(ndx % 256);
105  }
106  else {
107  WRITE(dbuff->num_zero);
108  dbuff->num_zero = 0;
109  WRITE((ndx / 256) + 1);
110  WRITE(ndx % 256);
111  }
112  }
113 }
114 
121 {
122  int ndx, ndx2;
123 
124  if (dbuff->num_zero != 0) {
125  dbuff->num_zero--;
126  ndx = -1;
127  }
128  else {
129  WRITE(ndx = READ());
130  if (ndx == 0) {
131  WRITE(dbuff->num_zero = READ());
132  dbuff->num_zero--;
133  ndx = -1;
134  }
135  else {
136  WRITE(ndx2 = READ());
137  ndx = (ndx - 1) * 256 + ndx2;
138  }
139  }
140 
141  return ndx;
142 }
143 
155 int iso_get_cube_value(geovol_isosurf * isosurf, int desc, int x, int y,
156  int z, float *v)
157 {
158  double d;
159  geovol_file *vf;
160  int type, ret = 1;
161 
162  /* get volume file from attribute handle */
163  vf = gvl_file_get_volfile(isosurf->att[desc].hfile);
164  type = gvl_file_get_data_type(vf);
165 
166  /* get value from volume file */
167  if (type == VOL_DTYPE_FLOAT) {
168  gvl_file_get_value(vf, (int)(x * ResX), (int)(y * ResY),
169  (int)(z * ResZ), v);
170  }
171  else if (type == VOL_DTYPE_DOUBLE) {
172  gvl_file_get_value(vf, (int)(x * ResX), (int)(y * ResY),
173  (int)(z * ResZ), &d);
174  *v = (float)d;
175  }
176  else {
177  return 0;
178  }
179 
180  /* null check */
181  if (gvl_file_is_null_value(vf, v))
182  ret = 0;
183 
184  /* adjust data */
185  switch (desc) {
186  case (ATT_TOPO):
187  *v = (*v) - isosurf->att[desc].constant;
188  break;
189  case (ATT_MASK):
190  if (isosurf->att[desc].constant)
191  ret = !ret;
192  break;
193  }
194 
195  return ret;
196 }
197 
206 void iso_get_range(geovol_isosurf * isosurf, int desc, double *min,
207  double *max)
208 {
209  gvl_file_get_min_max(gvl_file_get_volfile(isosurf->att[desc].hfile), min,
210  max);
211 }
212 
223 int iso_get_cube_values(geovol_isosurf * isosurf, int desc, int x, int y,
224  int z, float *v)
225 {
226  int p, ret = 1;
227 
228  for (p = 0; p < 8; ++p) {
230  (isosurf, desc, x + ((p ^ (p >> 1)) & 1), y + ((p >> 1) & 1),
231  z + ((p >> 2) & 1), &v[p]) == 0) {
232  ret = 0;
233  }
234  }
235 
236  return ret;
237 }
238 
246 void iso_get_cube_grads(geovol_isosurf * isosurf, int x, int y, int z,
247  float (*grad)[3])
248 {
249  float v[3];
250  int i, j, k, p;
251 
252  for (p = 0; p < 8; ++p) {
253  i = x + ((p ^ (p >> 1)) & 1);
254  j = y + ((p >> 1) & 1);
255  k = z + ((p >> 2) & 1);
256 
257  /* x */
258  if (i == 0) {
259  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
260  iso_get_cube_value(isosurf, ATT_TOPO, i + 1, j, k, &v[2]);
261  grad[p][0] = v[2] - v[1];
262  }
263  else {
264  if (i == (Cols - 1)) {
265  iso_get_cube_value(isosurf, ATT_TOPO, i - 1, j, k, &v[0]);
266  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
267  grad[p][0] = v[1] - v[0];
268  }
269  else {
270  iso_get_cube_value(isosurf, ATT_TOPO, i - 1, j, k, &v[0]);
271  iso_get_cube_value(isosurf, ATT_TOPO, i + 1, j, k, &v[2]);
272  grad[p][0] = (v[2] - v[0]) / 2;
273  }
274  }
275 
276  /* y */
277  if (j == 0) {
278  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
279  iso_get_cube_value(isosurf, ATT_TOPO, i, j + 1, k, &v[2]);
280  grad[p][1] = v[2] - v[1];
281  }
282  else {
283  if (j == (Rows - 1)) {
284  iso_get_cube_value(isosurf, ATT_TOPO, i, j - 1, k, &v[0]);
285  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
286  grad[p][1] = v[1] - v[0];
287  }
288  else {
289  iso_get_cube_value(isosurf, ATT_TOPO, i, j - 1, k, &v[0]);
290  iso_get_cube_value(isosurf, ATT_TOPO, i, j + 1, k, &v[2]);
291  grad[p][1] = (v[2] - v[0]) / 2;
292  }
293  }
294 
295  /* z */
296  if (k == 0) {
297  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
298  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k + 1, &v[2]);
299  grad[p][2] = v[2] - v[1];
300  }
301  else {
302  if (k == (Depths - 1)) {
303  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k - 1, &v[0]);
304  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k, &v[1]);
305  grad[p][2] = v[1] - v[0];
306  }
307  else {
308  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k - 1, &v[0]);
309  iso_get_cube_value(isosurf, ATT_TOPO, i, j, k + 1, &v[2]);
310  grad[p][2] = (v[2] - v[0]) / 2;
311  }
312  }
313  }
314 }
315 
323 void iso_calc_cube(geovol_isosurf * isosurf, int x, int y, int z,
324  data_buffer * dbuff)
325 {
326  int i, c_ndx;
327  int crnt, v1, v2, c;
328  float val[MAX_ATTS][8], grad[8][3];
329  float d, d3[3], d_sum[3], n[3], n_sum[3], tv;
330  double min, max;
331 
332  if (isosurf->att[ATT_TOPO].changed) {
333  /* read topo values, if there are NULL values then return */
334  if (!iso_get_cube_values(isosurf, ATT_TOPO, x, y, z, val[ATT_TOPO])) {
335  iso_w_cndx(-1, dbuff);
336  return;
337  }
338 
339  /* mask */
340  if (isosurf->att[ATT_MASK].att_src == MAP_ATT) {
342  (isosurf, ATT_MASK, x, y, z, val[ATT_MASK])) {
343  iso_w_cndx(-1, dbuff);
344  return;
345  }
346  }
347 
348  /* index to precalculated table */
349  c_ndx = 0;
350  for (i = 0; i < 8; i++) {
351  if (val[ATT_TOPO][i] > 0)
352  c_ndx |= 1 << i;
353  }
354  c_ndx = mc33_process_cube(c_ndx, val[ATT_TOPO]);
355 
356  iso_w_cndx(c_ndx, dbuff);
357 
358  if (c_ndx == -1)
359  return;
360 
361  /* calc cube grads */
362  iso_get_cube_grads(isosurf, x, y, z, grad);
363 
364  }
365  else {
366  /* read cube index */
367  if ((c_ndx = iso_r_cndx(dbuff)) == -1)
368  return;
369  }
370 
371  /* get color values */
372  if (isosurf->att[ATT_COLOR].changed &&
373  isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
374  iso_get_cube_values(isosurf, ATT_COLOR, x, y, z, val[ATT_COLOR]);
375  }
376 
377  /* get transparency values */
378  if (isosurf->att[ATT_TRANSP].changed &&
379  isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
380  iso_get_cube_values(isosurf, ATT_TRANSP, x, y, z, val[ATT_TRANSP]);
381  }
382 
383  /* get shine values */
384  if (isosurf->att[ATT_SHINE].changed &&
385  isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
386  iso_get_cube_values(isosurf, ATT_SHINE, x, y, z, val[ATT_SHINE]);
387  }
388 
389  /* get emit values */
390  if (isosurf->att[ATT_EMIT].changed &&
391  isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
392  iso_get_cube_values(isosurf, ATT_EMIT, x, y, z, val[ATT_EMIT]);
393  }
394 
395  FOR_0_TO_N(3, d_sum[FOR_VAR] = 0.; n_sum[FOR_VAR] = 0.);
396 
397  /* loop in edges */
398  for (i = 0; i < cell_table[c_ndx].nedges; i++) {
399  /* get edge number */
400  crnt = cell_table[c_ndx].edges[i];
401 
402  /* set topo */
403  if (isosurf->att[ATT_TOPO].changed) {
404  /* interior vertex */
405  if (crnt == 12) {
406  FOR_0_TO_N(3,
407  WRITE((d3[FOR_VAR] =
408  d_sum[FOR_VAR] /
409  ((float)(cell_table[c_ndx].nedges))) *
410  255));
411  GS_v3norm(n_sum);
412  FOR_0_TO_N(3,
413  WRITE((n_sum[FOR_VAR] /
414  ((float)(cell_table[c_ndx].nedges)) +
415  1.) * 127));
416  /* edge vertex */
417  }
418  else {
419  /* set egdes verts */
420  v1 = edge_vert[crnt][0];
421  v2 = edge_vert[crnt][1];
422 
423  /* calc intersection point - edge and isosurf */
424  d = val[ATT_TOPO][v1] / (val[ATT_TOPO][v1] -
425  val[ATT_TOPO][v2]);
426 
427  d_sum[edge_vert_pos[crnt][0]] += d;
428  d_sum[edge_vert_pos[crnt][1]] += edge_vert_pos[crnt][2];
429  d_sum[edge_vert_pos[crnt][3]] += edge_vert_pos[crnt][4];
430 
431  WRITE(d * 255);
432 
433  /* set normal for intersect. point */
434  FOR_0_TO_N(3, n[FOR_VAR] =
435  LINTERP(d, grad[v1][FOR_VAR], grad[v2][FOR_VAR]));
436  GS_v3norm(n);
437  FOR_0_TO_N(3, n_sum[FOR_VAR] += n[FOR_VAR]);
438  FOR_0_TO_N(3, WRITE((n[FOR_VAR] + 1.) * 127));
439  }
440  }
441  else {
442  /* read x,y,z of intersection point in cube coords */
443  if (crnt == 12) {
444  WRITE(c = READ());
445  d3[0] = ((float)c) / 255.0;
446  WRITE(c = READ());
447  d3[1] = ((float)c) / 255.0;
448  WRITE(c = READ());
449  d3[2] = ((float)c) / 255.0;
450  }
451  else {
452  /* set egdes verts */
453  v1 = edge_vert[crnt][0];
454  v2 = edge_vert[crnt][1];
455 
456  WRITE(c = READ());
457  d = ((float)c) / 255.0;
458  }
459 
460  /* set normals */
461  FOR_0_TO_N(3, WRITE(READ()));
462  }
463 
464  /* set color */
465  if (isosurf->att[ATT_COLOR].changed &&
466  isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
467  if (crnt == 12) {
468  tv = TINTERP(d3, val[ATT_COLOR]);
469  }
470  else {
471  tv = LINTERP(d, val[ATT_COLOR][v1], val[ATT_COLOR][v2]);
472  }
473 
474  c = Gvl_get_color_for_value(isosurf->att[ATT_COLOR].att_data,
475  &tv);
476 
477  WRITE(c & RED_MASK);
478  WRITE((c & GRN_MASK) >> 8);
479  WRITE((c & BLU_MASK) >> 16);
480 
481  if (IS_IN_DATA(ATT_COLOR))
482  SKIP(3);
483  }
484  else {
485  if (isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
486  FOR_0_TO_N(3, WRITE(READ()));
487  }
488  else {
489  if (IS_IN_DATA(ATT_COLOR))
490  SKIP(3);
491  }
492  }
493 
494  /* set transparency */
495  if (isosurf->att[ATT_TRANSP].changed &&
496  isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
497  if (crnt == 12) {
498  tv = TINTERP(d3, val[ATT_TRANSP]);
499  }
500  else {
501  tv = LINTERP(d, val[ATT_TRANSP][v1], val[ATT_TRANSP][v2]);
502  }
503 
504  iso_get_range(isosurf, ATT_TRANSP, &min, &max);
505  c = (min != max) ? 255 - (tv - min) / (max - min) * 255 : 0;
506 
507  WRITE(c);
508  if (IS_IN_DATA(ATT_TRANSP))
509  SKIP(1);
510  }
511  else {
512  if (isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
513  WRITE(READ());
514  }
515  else {
516  if (IS_IN_DATA(ATT_TRANSP))
517  SKIP(1);
518  }
519  }
520 
521  /* set shin */
522  if (isosurf->att[ATT_SHINE].changed &&
523  isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
524  if (crnt == 12) {
525  tv = TINTERP(d3, val[ATT_SHINE]);
526  }
527  else {
528  tv = LINTERP(d, val[ATT_SHINE][v1], val[ATT_SHINE][v2]);
529  }
530 
531  iso_get_range(isosurf, ATT_SHINE, &min, &max);
532  c = (min != max) ? (tv - min) / (max - min) * 255 : 0;
533 
534  WRITE(c);
535  if (IS_IN_DATA(ATT_SHINE))
536  SKIP(1);
537  }
538  else {
539  if (isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
540  WRITE(READ());
541  }
542  else {
543  if (IS_IN_DATA(ATT_SHINE))
544  SKIP(1);
545  }
546  }
547 
548  /* set emit */
549  if (isosurf->att[ATT_EMIT].changed &&
550  isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
551  if (crnt == 12) {
552  tv = TINTERP(d3, val[ATT_EMIT]);
553  }
554  else {
555  tv = LINTERP(d, val[ATT_EMIT][v1], val[ATT_EMIT][v2]);
556  }
557 
558  iso_get_range(isosurf, ATT_EMIT, &min, &max);
559  c = (min != max) ? (tv - min) / (max - min) * 255 : 0;
560 
561  WRITE(c);
562  if (IS_IN_DATA(ATT_SHINE))
563  SKIP(1);
564  }
565  else {
566  if (isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
567  WRITE(READ());
568  }
569  else {
570  if (IS_IN_DATA(ATT_EMIT))
571  SKIP(1);
572  }
573  }
574  }
575 }
576 
584 int gvl_isosurf_calc(geovol * gvol)
585 {
586  int x, y, z;
587  int i, a, read;
588  geovol_file *vf;
589  geovol_isosurf *isosurf;
590 
591  data_buffer *dbuff;
592  int *need_update, need_update_global;
593 
594  dbuff = G_malloc(gvol->n_isosurfs * sizeof(data_buffer));
595  need_update = G_malloc(gvol->n_isosurfs * sizeof(int));
596 
597  /* flag - changed any isosurface */
598  need_update_global = 0;
599 
600  /* initialize */
601  for (i = 0; i < gvol->n_isosurfs; i++) {
602  isosurf = gvol->isosurf[i];
603 
604  need_update[i] = 0;
605  for (a = 1; a < MAX_ATTS; a++) {
606  if (isosurf->att[a].changed) {
607  read = 0;
608  /* changed to map attribute */
609  if (isosurf->att[a].att_src == MAP_ATT) {
610  vf = gvl_file_get_volfile(isosurf->att[a].hfile);
611  read = 1;
612  }
613  /* changed threshold value */
614  if (a == ATT_TOPO) {
615  isosurf->att[a].hfile = gvol->hfile;
616  vf = gvl_file_get_volfile(gvol->hfile);
617  read = 1;
618  }
619  /* initialize reading in selected mode */
620  if (read) {
621  gvl_file_set_mode(vf, 3);
623  }
624 
625  /* set update flag - isosurface will be calc */
626  if (read || IS_IN_DATA(a)) {
627  need_update[i] = 1;
628  need_update_global = 1;
629  }
630  }
631  }
632 
633  if (need_update[i]) {
634  /* initialize read/write buffers */
635  dbuff[i].old = isosurf->data;
636  dbuff[i].new = NULL;
637  dbuff[i].ndx_old = 0;
638  dbuff[i].ndx_new = 0;
639  dbuff[i].num_zero = 0;
640  }
641  }
642 
643  /* calculate if only some isosurface changed */
644  if (need_update_global) {
645 
646  ResX = gvol->isosurf_x_mod;
647  ResY = gvol->isosurf_y_mod;
648  ResZ = gvol->isosurf_z_mod;
649 
650  Cols = gvol->cols / ResX;
651  Rows = gvol->rows / ResY;
652  Depths = gvol->depths / ResZ;
653 
654  /* calc isosurface - marching cubes - start */
655 
656  for (z = 0; z < Depths - 1; z++) {
657  for (y = 0; y < Rows - 1; y++) {
658  for (x = 0; x < Cols - 1; x++) {
659  for (i = 0; i < gvol->n_isosurfs; i++) {
660  /* recalculate only changed isosurfaces */
661  if (need_update[i]) {
662  iso_calc_cube(gvol->isosurf[i], x, y, z,
663  &dbuff[i]);
664  }
665  }
666  }
667  }
668  }
669 
670  }
671  /* end */
672 
673  /* deinitialize */
674  for (i = 0; i < gvol->n_isosurfs; i++) {
675  isosurf = gvol->isosurf[i];
676 
677  /* set new isosurface data */
678  if (need_update[i]) {
679  if (dbuff[i].num_zero != 0)
680  gvl_write_char(dbuff[i].ndx_new++, &(dbuff[i].new),
681  dbuff[i].num_zero);
682 
683  G_free(isosurf->data);
684  /* gvl_align_data(dbuff[i].ndx_new, dbuff[i].new); */
685  isosurf->data = dbuff[i].new;
686  isosurf->data_desc = 0;
687  }
688 
689  for (a = 1; a < MAX_ATTS; a++) {
690  if (isosurf->att[a].changed) {
691  read = 0;
692  /* changed map attribute */
693  if (isosurf->att[a].att_src == MAP_ATT) {
694  vf = gvl_file_get_volfile(isosurf->att[a].hfile);
695  read = 1;
696  }
697  /* changed threshold value */
698  if (a == ATT_TOPO) {
699  isosurf->att[a].hfile = gvol->hfile;
700  vf = gvl_file_get_volfile(gvol->hfile);
701  read = 1;
702  }
703  /* deinitialize reading */
704  if (read) {
705  gvl_file_end_read(vf);
706 
707  /* set data description */
708  SET_IN_DATA(a);
709  }
710  isosurf->att[a].changed = 0;
711  }
712  else if (isosurf->att[a].att_src == MAP_ATT) {
713  /* set data description */
714  SET_IN_DATA(a);
715  }
716  }
717  }
718 
719  return (1);
720 }
721 
729 void gvl_write_char(int pos, unsigned char **data, unsigned char c)
730 {
731  /* check to need allocation memory */
732  if ((pos % BUFFER_SIZE) == 0) {
733  *data = (char *)G_realloc(*data,
734  sizeof(char) * ((pos / BUFFER_SIZE) +
735  1) * BUFFER_SIZE);
736  if (!(*data)) {
737  return;
738  }
739 
740  G_debug(3,
741  "gvl_write_char(): reallocate memory for pos : %d to : %d B",
742  pos, sizeof(char) * ((pos / BUFFER_SIZE) + 1) * BUFFER_SIZE);
743  }
744 
745  (*data)[pos] = c;
746 }
747 
757 unsigned char gvl_read_char(int pos, const unsigned char *data)
758 {
759  if (!data)
760  return '\0';
761 
762  return data[pos];
763 }
764 
771 void gvl_align_data(int pos, unsigned char *data)
772 {
773  /* WARNING: wrong pointer usage
774  * this function needs **data, not *data,
775  * and if pos == 0, data must be set to NULL,
776  * thus: */
777  return;
778 
779  /* realloc memory to fit in data length */
780  data = (char *)G_realloc(data, sizeof(char) * pos); /* G_fatal_error */
781  if (!data) {
782  return;
783  }
784 
785  G_debug(3, "gvl_align_data(): reallocate memory finally to : %d B", pos);
786 
787  return;
788 }
789 
790 /************************************************************************/
791 /* SLICES */
792 
793 /************************************************************************/
794 
795 #define DISTANCE_2(x1, y1, x2, y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
796 
797 #define SLICE_MODE_INTERP_NO 0
798 #define SLICE_MODE_INTERP_YES 1
799 
808 float slice_get_value(geovol * gvl, int x, int y, int z)
809 {
810  static double d;
811  static geovol_file *vf;
812  static int type;
813  static float value;
814 
815  if (x < 0 || y < 0 || z < 0 || (x > gvl->cols - 1) || (y > gvl->rows - 1)
816  || (z > gvl->depths - 1))
817  return 0.;
818 
819  /* get volume file from attribute handle */
820  vf = gvl_file_get_volfile(gvl->hfile);
821  type = gvl_file_get_data_type(vf);
822 
823  /* get value from volume file */
824  if (type == VOL_DTYPE_FLOAT) {
825  gvl_file_get_value(vf, x, y, z, &value);
826  }
827  else if (type == VOL_DTYPE_DOUBLE) {
828  gvl_file_get_value(vf, x, y, z, &d);
829  value = (float)d;
830  }
831  else {
832  return 0.;
833  }
834 
835  return value;
836 }
837 
847 int slice_calc(geovol * gvl, int ndx_slc, void *colors)
848 {
849  int cols, rows, c, r;
850  int i, j, k, pos, color;
851  int *p_x, *p_y, *p_z;
852  float *p_ex, *p_ey, *p_ez;
853  float value, v[8];
854  float x, y, z, ei, ej, ek, stepx, stepy, stepz;
855  float f_cols, f_rows, distxy, distz, modxy, modx, mody, modz;
856 
857  geovol_slice *slice;
858  geovol_file *vf;
859 
860  slice = gvl->slice[ndx_slc];
861 
862  /* set mods, pointer to x, y, z step value */
863  if (slice->dir == X) {
864  modx = ResY;
865  mody = ResZ;
866  modz = ResX;
867  p_x = &k;
868  p_y = &i;
869  p_z = &j;
870  p_ex = &ek;
871  p_ey = &ei;
872  p_ez = &ej;
873  }
874  else if (slice->dir == Y) {
875  modx = ResX;
876  mody = ResZ;
877  modz = ResY;
878  p_x = &i;
879  p_y = &k;
880  p_z = &j;
881  p_ex = &ei;
882  p_ey = &ek;
883  p_ez = &ej;
884  }
885  else {
886  modx = ResX;
887  mody = ResY;
888  modz = ResZ;
889  p_x = &i;
890  p_y = &j;
891  p_z = &k;
892  p_ex = &ei;
893  p_ey = &ej;
894  p_ez = &ek;
895  }
896 
897  /* distance between slice def. points */
898  distxy = DISTANCE_2(slice->x2, slice->y2, slice->x1, slice->y1);
899  distz = fabsf(slice->z2 - slice->z1);
900 
901  /* distance between slice def points is zero - nothing to do */
902  if (distxy == 0. || distz == 0.) {
903  return (1);
904  }
905 
906  /* start reading volume file */
907  vf = gvl_file_get_volfile(gvl->hfile);
908  gvl_file_set_mode(vf, 3);
910 
911  /* set xy resolution */
912  modxy =
913  DISTANCE_2((slice->x2 - slice->x1) / distxy * modx,
914  (slice->y2 - slice->y1) / distxy * mody, 0., 0.);
915 
916  /* cols/rows of slice */
917  f_cols = distxy / modxy;
918  cols = f_cols > (int)f_cols ? (int)f_cols + 1 : (int)f_cols;
919 
920  f_rows = distz / modz;
921  rows = f_rows > (int)f_rows ? (int)f_rows + 1 : (int)f_rows;
922 
923  /* set x,y intially to first slice point */
924  x = slice->x1;
925  y = slice->y1;
926 
927  /* set x,y step */
928  stepx = (slice->x2 - slice->x1) / f_cols;
929  stepy = (slice->y2 - slice->y1) / f_cols;
930  stepz = (slice->z2 - slice->z1) / f_rows;
931 
932  /* set position in slice data */
933  pos = 0;
934 
935  /* loop in slice cols */
936  for (c = 0; c < cols + 1; c++) {
937 
938  /* convert x, y to integer - index in grid */
939  i = (int)x;
940  j = (int)y;
941 
942  /* distance between index and real position */
943  ei = x - (float)i;
944  ej = y - (float)j;
945 
946  /* set z to slice z1 point */
947  z = slice->z1;
948 
949  /* loop in slice rows */
950  for (r = 0; r < rows + 1; r++) {
951 
952  /* distance between index and real position */
953  k = (int)z;
954  ek = z - (float)k;
955 
956  /* get interpolated value */
957  if (slice->mode == SLICE_MODE_INTERP_YES) {
958  /* get grid values */
959  v[0] = slice_get_value(gvl, *p_x, *p_y, *p_z);
960  v[1] = slice_get_value(gvl, *p_x + 1, *p_y, *p_z);
961  v[2] = slice_get_value(gvl, *p_x, *p_y + 1, *p_z);
962  v[3] = slice_get_value(gvl, *p_x + 1, *p_y + 1, *p_z);
963 
964  v[4] = slice_get_value(gvl, *p_x, *p_y, *p_z + 1);
965  v[5] = slice_get_value(gvl, *p_x + 1, *p_y, *p_z + 1);
966  v[6] = slice_get_value(gvl, *p_x, *p_y + 1, *p_z + 1);
967  v[7] = slice_get_value(gvl, *p_x + 1, *p_y + 1, *p_z + 1);
968 
969  /* get interpolated value */
970  value = v[0] * (1. - *p_ex) * (1. - *p_ey) * (1. - *p_ez)
971  + v[1] * (*p_ex) * (1. - *p_ey) * (1. - *p_ez)
972  + v[2] * (1. - *p_ex) * (*p_ey) * (1. - *p_ez)
973  + v[3] * (*p_ex) * (*p_ey) * (1. - *p_ez)
974  + v[4] * (1. - *p_ex) * (1. - *p_ey) * (*p_ez)
975  + v[5] * (*p_ex) * (1. - *p_ey) * (*p_ez)
976  + v[6] * (1. - *p_ex) * (*p_ey) * (*p_ez)
977  + v[7] * (*p_ex) * (*p_ey) * (*p_ez);
978 
979  /* no interp value */
980  }
981  else {
982  value = slice_get_value(gvl, *p_x, *p_y, *p_z);
983  }
984 
985  /* translate value to color */
986  color = Gvl_get_color_for_value(colors, &value);
987 
988  /* write color to slice data */
989  gvl_write_char(pos++, &(slice->data), color & RED_MASK);
990  gvl_write_char(pos++, &(slice->data), (color & GRN_MASK) >> 8);
991  gvl_write_char(pos++, &(slice->data), (color & BLU_MASK) >> 16);
992 
993  /* step in z */
994  if (r + 1 > f_rows) {
995  z += stepz * (f_rows - (float)r);
996  }
997  else {
998  z += stepz;
999  }
1000  }
1001 
1002  /* step in x,y */
1003  if (c + 1 > f_cols) {
1004  x += stepx * (f_cols - (float)c);
1005  y += stepy * (f_cols - (float)c);
1006  }
1007  else {
1008  x += stepx;
1009  y += stepy;
1010  }
1011  }
1012 
1013  /* end reading volume file */
1014  gvl_file_end_read(vf);
1015  /* gvl_align_data(pos, slice->data); */
1016 
1017  return (1);
1018 }
1019 
1027 int gvl_slices_calc(geovol *gvol)
1028 {
1029  int i;
1030  void *colors;
1031 
1032  G_debug(5, "gvl_slices_calc(): id=%d", gvol->gvol_id);
1033 
1034  /* set current resolution */
1035  ResX = gvol->slice_x_mod;
1036  ResY = gvol->slice_y_mod;
1037  ResZ = gvol->slice_z_mod;
1038 
1039  /* set current num of cols, rows, depths */
1040  Cols = gvol->cols / ResX;
1041  Rows = gvol->rows / ResY;
1042  Depths = gvol->depths / ResZ;
1043 
1044  /* load colors for geovol file */
1045  Gvl_load_colors_data(&colors, gvl_file_get_name(gvol->hfile));
1046 
1047  /* calc changed slices */
1048  for (i = 0; i < gvol->n_slices; i++) {
1049  if (gvol->slice[i]->changed) {
1050  slice_calc(gvol, i, colors);
1051 
1052  /* set changed flag */
1053  gvol->slice[i]->changed = 0;
1054  }
1055  }
1056 
1057  /* free color */
1058  Gvl_unload_colors_data(colors);
1059 
1060  return (1);
1061 }
int Rows
Definition: gvl_calc.c:73
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
#define RED_MASK
Definition: gsd_prim.c:38
#define BUFFER_SIZE
memory buffer for writing
Definition: gvl_calc.c:30
int iso_r_cndx(data_buffer *dbuff)
Read cube index.
Definition: gvl_calc.c:120
int ndx_old
Definition: gvl_calc.c:65
#define IS_IN_DATA(att)
check and set data descriptor
Definition: gvl_calc.c:58
geovol_file * gvl_file_get_volfile(int id)
Get geovol_file structure for given handle.
Definition: gvl_file.c:118
#define LINTERP(d, a, b)
Definition: gvl_calc.c:35
#define min(x, y)
Definition: draw2.c:68
int Gvl_unload_colors_data(void *color_data)
Unload color table.
Definition: Gvl3.c:64
int GS_v3norm(float *v1)
Change v1 so that it is a unit vector (2D)
Definition: GS_util.c:246
int Gvl_get_color_for_value(void *color_data, float *value)
Get color for value.
Definition: Gvl3.c:82
float r
Definition: named_colr.c:8
unsigned char * old
Definition: gvl_calc.c:63
double ResX
Definition: gvl_calc.c:74
#define Y(x)
Definition: display/draw.c:246
tuple pos
Definition: tools.py:1367
int gvl_file_get_data_type(geovol_file *vf)
Get data type for given handle.
Definition: gvl_file.c:203
int ndx_new
Definition: gvl_calc.c:66
#define FOR_0_TO_N(n, cmd)
Definition: gvl_calc.c:46
#define BLU_MASK
Definition: gsd_prim.c:40
#define X(y)
Definition: display/draw.c:248
#define GRN_MASK
Definition: gsd_prim.c:39
char * gvl_file_get_name(int id)
Get file name for given handle.
Definition: gvl_file.c:166
int mc33_process_cube(int c_ndx, float *v)
ADD.
Definition: gvl_calc2.c:307
int y
Definition: plot.c:34
#define max(x, y)
Definition: draw2.c:69
int num_zero
Definition: gvl_calc.c:67
int gvl_isosurf_calc(geovol *gvol)
Fill data structure with computed isosurfaces polygons.
Definition: gvl_calc.c:584
double ResY
Definition: gvl_calc.c:74
#define TINTERP(d, v)
Definition: gvl_calc.c:36
#define SET_IN_DATA(att)
Definition: gvl_calc.c:59
void iso_get_range(geovol_isosurf *isosurf, int desc, double *min, double *max)
Get volume file values range.
Definition: gvl_calc.c:206
void gvl_align_data(int pos, unsigned char *data)
Append data to buffer.
Definition: gvl_calc.c:771
unsigned char * new
Definition: gvl_calc.c:64
int edges[12]
Definition: viz.h:76
int Gvl_load_colors_data(void **color_data, const char *name)
Load color table.
Definition: Gvl3.c:33
tuple data
void gvl_write_char(int pos, unsigned char **data, unsigned char c)
ADD.
Definition: gvl_calc.c:729
tuple color
Definition: tools.py:1703
int nedges
Definition: viz.h:75
unsigned char gvl_read_char(int pos, const unsigned char *data)
Read char.
Definition: gvl_calc.c:757
#define SKIP(n)
Definition: gvl_calc.c:53
void iso_calc_cube(geovol_isosurf *isosurf, int x, int y, int z, data_buffer *dbuff)
Process cube.
Definition: gvl_calc.c:323
int
Definition: g3dcolor.c:48
void iso_w_cndx(int ndx, data_buffer *dbuff)
Write cube index.
Definition: gvl_calc.c:85
char * value
Definition: env.c:30
#define SLICE_MODE_INTERP_YES
Definition: gvl_calc.c:798
#define WRITE(c)
writing and reading isosurface data
Definition: gvl_calc.c:51
int gvl_file_start_read(geovol_file *vf)
Start read - allocate memory buffer a read first data into buffer.
Definition: gvl_file.c:968
int iso_get_cube_value(geovol_isosurf *isosurf, int desc, int x, int y, int z, float *v)
Get value from data input.
Definition: gvl_calc.c:155
CELL_ENTRY cell_table[256]
return NULL
Definition: dbfopen.c:1394
int gvl_file_end_read(geovol_file *vf)
End read - free buffer memory.
Definition: gvl_file.c:1019
tuple cols
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int iso_get_cube_values(geovol_isosurf *isosurf, int desc, int x, int y, int z, float *v)
Read values for cube.
Definition: gvl_calc.c:223
float slice_get_value(geovol *gvl, int x, int y, int z)
Get volume value.
Definition: gvl_calc.c:808
#define DISTANCE_2(x1, y1, x2, y2)
Definition: gvl_calc.c:795
int gvl_file_is_null_value(geovol_file *vf, void *value)
Check for null value.
Definition: gvl_file.c:1088
void gvl_file_get_min_max(geovol_file *vf, double *min, double *max)
Get minimum and maximum value in volume file.
Definition: gvl_file.c:215
void iso_get_cube_grads(geovol_isosurf *isosurf, int x, int y, int z, float(*grad)[3])
Calculate cube grads.
Definition: gvl_calc.c:246
int Cols
Definition: gvl_calc.c:73
int gvl_file_set_mode(geovol_file *vf, IFLAG mode)
Set read mode.
Definition: gvl_file.c:1117
int slice_calc(geovol *gvl, int ndx_slc, void *colors)
Calculate slices.
Definition: gvl_calc.c:847
int n
Definition: dataquad.c:291
int gvl_slices_calc(geovol *gvol)
Calculate slices for given volume set.
Definition: gvl_calc.c:1027
#define READ()
Definition: gvl_calc.c:52
int gvl_file_get_value(geovol_file *vf, int x, int y, int z, void *value)
Get value for volume file at x, y, z.
Definition: gvl_file.c:1051
#define FOR_VAR
Definition: gvl_calc.c:45
double ResZ
Definition: gvl_calc.c:74
int Depths
Definition: gvl_calc.c:73