21 #include <grass/gis.h>
22 #include <grass/gstypes.h>
30 #define BUFFER_SIZE 1000000
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]))
46 #define FOR_0_TO_N(n, cmd) { int FOR_VAR; for (FOR_VAR = 0; FOR_VAR < n; FOR_VAR++) {cmd;} }
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
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))
103 WRITE((ndx / 256) + 1);
109 WRITE((ndx / 256) + 1);
137 ndx = (ndx - 1) * 256 + ndx2;
167 if (type == VOL_DTYPE_FLOAT) {
171 else if (type == VOL_DTYPE_DOUBLE) {
173 (
int)(z *
ResZ), &d);
187 *v = (*v) - isosurf->att[desc].constant;
190 if (isosurf->att[desc].constant)
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) {
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);
261 grad[p][0] = v[2] - v[1];
264 if (i == (
Cols - 1)) {
267 grad[p][0] = v[1] - v[0];
272 grad[p][0] = (v[2] - v[0]) / 2;
280 grad[p][1] = v[2] - v[1];
283 if (j == (
Rows - 1)) {
286 grad[p][1] = v[1] - v[0];
291 grad[p][1] = (v[2] - v[0]) / 2;
299 grad[p][2] = v[2] - v[1];
305 grad[p][2] = v[1] - v[0];
310 grad[p][2] = (v[2] - v[0]) / 2;
328 float val[MAX_ATTS][8], grad[8][3];
329 float d, d3[3], d_sum[3],
n[3], n_sum[3], tv;
332 if (isosurf->att[ATT_TOPO].changed) {
340 if (isosurf->att[ATT_MASK].att_src == MAP_ATT) {
342 (isosurf, ATT_MASK, x, y, z, val[ATT_MASK])) {
350 for (i = 0; i < 8; i++) {
351 if (val[ATT_TOPO][i] > 0)
372 if (isosurf->att[ATT_COLOR].changed &&
373 isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
378 if (isosurf->att[ATT_TRANSP].changed &&
379 isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
384 if (isosurf->att[ATT_SHINE].changed &&
385 isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
390 if (isosurf->att[ATT_EMIT].changed &&
391 isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
403 if (isosurf->att[ATT_TOPO].changed) {
420 v1 = edge_vert[crnt][0];
421 v2 = edge_vert[crnt][1];
424 d = val[ATT_TOPO][v1] / (val[ATT_TOPO][v1] -
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];
445 d3[0] = ((float)c) / 255.0;
447 d3[1] = ((float)c) / 255.0;
449 d3[2] = ((float)c) / 255.0;
453 v1 = edge_vert[crnt][0];
454 v2 = edge_vert[crnt][1];
457 d = ((float)c) / 255.0;
465 if (isosurf->att[ATT_COLOR].changed &&
466 isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
468 tv =
TINTERP(d3, val[ATT_COLOR]);
471 tv =
LINTERP(d, val[ATT_COLOR][v1], val[ATT_COLOR][v2]);
485 if (isosurf->att[ATT_COLOR].att_src == MAP_ATT) {
495 if (isosurf->att[ATT_TRANSP].changed &&
496 isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
498 tv =
TINTERP(d3, val[ATT_TRANSP]);
501 tv =
LINTERP(d, val[ATT_TRANSP][v1], val[ATT_TRANSP][v2]);
505 c = (min !=
max) ? 255 - (tv - min) / (max -
min) * 255 : 0;
512 if (isosurf->att[ATT_TRANSP].att_src == MAP_ATT) {
522 if (isosurf->att[ATT_SHINE].changed &&
523 isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
525 tv =
TINTERP(d3, val[ATT_SHINE]);
528 tv =
LINTERP(d, val[ATT_SHINE][v1], val[ATT_SHINE][v2]);
532 c = (min !=
max) ? (tv - min) / (max -
min) * 255 : 0;
539 if (isosurf->att[ATT_SHINE].att_src == MAP_ATT) {
549 if (isosurf->att[ATT_EMIT].changed &&
550 isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
552 tv =
TINTERP(d3, val[ATT_EMIT]);
555 tv =
LINTERP(d, val[ATT_EMIT][v1], val[ATT_EMIT][v2]);
559 c = (min !=
max) ? (tv - min) / (max -
min) * 255 : 0;
566 if (isosurf->att[ATT_EMIT].att_src == MAP_ATT) {
589 geovol_isosurf *isosurf;
592 int *need_update, need_update_global;
594 dbuff = G_malloc(gvol->n_isosurfs *
sizeof(
data_buffer));
595 need_update = G_malloc(gvol->n_isosurfs *
sizeof(
int));
598 need_update_global = 0;
601 for (i = 0; i < gvol->n_isosurfs; i++) {
602 isosurf = gvol->isosurf[i];
605 for (a = 1; a < MAX_ATTS; a++) {
606 if (isosurf->att[a].changed) {
609 if (isosurf->att[a].att_src == MAP_ATT) {
615 isosurf->att[a].hfile = gvol->hfile;
628 need_update_global = 1;
633 if (need_update[i]) {
635 dbuff[i].
old = isosurf->data;
644 if (need_update_global) {
646 ResX = gvol->isosurf_x_mod;
647 ResY = gvol->isosurf_y_mod;
648 ResZ = gvol->isosurf_z_mod;
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++) {
661 if (need_update[i]) {
674 for (i = 0; i < gvol->n_isosurfs; i++) {
675 isosurf = gvol->isosurf[i];
678 if (need_update[i]) {
679 if (dbuff[i].num_zero != 0)
685 isosurf->data = dbuff[i].
new;
686 isosurf->data_desc = 0;
689 for (a = 1; a < MAX_ATTS; a++) {
690 if (isosurf->att[a].changed) {
693 if (isosurf->att[a].att_src == MAP_ATT) {
699 isosurf->att[a].hfile = gvol->hfile;
710 isosurf->att[a].changed = 0;
712 else if (isosurf->att[a].att_src == MAP_ATT) {
733 *data = (
char *)G_realloc(*data,
741 "gvl_write_char(): reallocate memory for pos : %d to : %d B",
742 pos,
sizeof(
char) * ((pos / BUFFER_SIZE) + 1) * BUFFER_SIZE);
780 data = (
char *)G_realloc(data,
sizeof(
char) *
pos);
785 G_debug(3,
"gvl_align_data(): reallocate memory finally to : %d B", pos);
795 #define DISTANCE_2(x1, y1, x2, y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
797 #define SLICE_MODE_INTERP_NO 0
798 #define SLICE_MODE_INTERP_YES 1
811 static geovol_file *vf;
815 if (x < 0 || y < 0 || z < 0 || (x > gvl->cols - 1) || (y > gvl->rows - 1)
816 || (z > gvl->depths - 1))
824 if (type == VOL_DTYPE_FLOAT) {
827 else if (type == VOL_DTYPE_DOUBLE) {
849 int cols, rows, c,
r;
851 int *p_x, *p_y, *p_z;
852 float *p_ex, *p_ey, *p_ez;
854 float x,
y, z, ei, ej, ek, stepx, stepy, stepz;
855 float f_cols, f_rows, distxy, distz, modxy, modx, mody, modz;
860 slice = gvl->slice[ndx_slc];
863 if (slice->dir ==
X) {
874 else if (slice->dir ==
Y) {
898 distxy =
DISTANCE_2(slice->x2, slice->y2, slice->x1, slice->y1);
899 distz = fabsf(slice->z2 - slice->z1);
902 if (distxy == 0. || distz == 0.) {
913 DISTANCE_2((slice->x2 - slice->x1) / distxy * modx,
914 (slice->y2 - slice->y1) / distxy * mody, 0., 0.);
917 f_cols = distxy / modxy;
918 cols = f_cols > (
int)f_cols ? (
int)f_cols + 1 : (
int)f_cols;
920 f_rows = distz / modz;
921 rows = f_rows > (
int)f_rows ? (
int)f_rows + 1 : (
int)f_rows;
928 stepx = (slice->x2 - slice->x1) / f_cols;
929 stepy = (slice->y2 - slice->y1) / f_cols;
930 stepz = (slice->z2 - slice->z1) / f_rows;
936 for (c = 0; c < cols + 1; c++) {
950 for (r = 0; r < rows + 1; r++) {
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);
994 if (r + 1 > f_rows) {
995 z += stepz * (f_rows - (float)r);
1003 if (c + 1 > f_cols) {
1004 x += stepx * (f_cols - (float)c);
1005 y += stepy * (f_cols - (float)c);
1032 G_debug(5,
"gvl_slices_calc(): id=%d", gvol->gvol_id);
1035 ResX = gvol->slice_x_mod;
1036 ResY = gvol->slice_y_mod;
1037 ResZ = gvol->slice_z_mod;
1048 for (i = 0; i < gvol->n_slices; i++) {
1049 if (gvol->slice[i]->changed) {
1053 gvol->slice[i]->changed = 0;
void G_free(void *buf)
Free allocated memory.
#define BUFFER_SIZE
memory buffer for writing
int iso_r_cndx(data_buffer *dbuff)
Read cube index.
#define IS_IN_DATA(att)
check and set data descriptor
geovol_file * gvl_file_get_volfile(int id)
Get geovol_file structure for given handle.
int Gvl_unload_colors_data(void *color_data)
Unload color table.
int GS_v3norm(float *v1)
Change v1 so that it is a unit vector (2D)
int Gvl_get_color_for_value(void *color_data, float *value)
Get color for value.
int gvl_file_get_data_type(geovol_file *vf)
Get data type for given handle.
#define FOR_0_TO_N(n, cmd)
char * gvl_file_get_name(int id)
Get file name for given handle.
int mc33_process_cube(int c_ndx, float *v)
ADD.
int gvl_isosurf_calc(geovol *gvol)
Fill data structure with computed isosurfaces polygons.
void iso_get_range(geovol_isosurf *isosurf, int desc, double *min, double *max)
Get volume file values range.
void gvl_align_data(int pos, unsigned char *data)
Append data to buffer.
int Gvl_load_colors_data(void **color_data, const char *name)
Load color table.
void gvl_write_char(int pos, unsigned char **data, unsigned char c)
ADD.
unsigned char gvl_read_char(int pos, const unsigned char *data)
Read char.
void iso_calc_cube(geovol_isosurf *isosurf, int x, int y, int z, data_buffer *dbuff)
Process cube.
void iso_w_cndx(int ndx, data_buffer *dbuff)
Write cube index.
#define SLICE_MODE_INTERP_YES
#define WRITE(c)
writing and reading isosurface data
int gvl_file_start_read(geovol_file *vf)
Start read - allocate memory buffer a read first data into buffer.
int iso_get_cube_value(geovol_isosurf *isosurf, int desc, int x, int y, int z, float *v)
Get value from data input.
CELL_ENTRY cell_table[256]
int gvl_file_end_read(geovol_file *vf)
End read - free buffer memory.
int G_debug(int level, const char *msg,...)
Print debugging message.
int iso_get_cube_values(geovol_isosurf *isosurf, int desc, int x, int y, int z, float *v)
Read values for cube.
float slice_get_value(geovol *gvl, int x, int y, int z)
Get volume value.
#define DISTANCE_2(x1, y1, x2, y2)
int gvl_file_is_null_value(geovol_file *vf, void *value)
Check for null value.
void gvl_file_get_min_max(geovol_file *vf, double *min, double *max)
Get minimum and maximum value in volume file.
void iso_get_cube_grads(geovol_isosurf *isosurf, int x, int y, int z, float(*grad)[3])
Calculate cube grads.
int gvl_file_set_mode(geovol_file *vf, IFLAG mode)
Set read mode.
int slice_calc(geovol *gvl, int ndx_slc, void *colors)
Calculate slices.
int gvl_slices_calc(geovol *gvol)
Calculate slices for given volume set.
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.