1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include "hecmw_vis_ray_trace.h"
7 
8 #include "hecmw_font_texture.h"
9 #include "hecmw_malloc.h"
10 
find_color_minmax(double * var,int * empty_flag,int nx,int ny,int nz,double * mincolor,double * maxcolor)11 void find_color_minmax(double *var, int *empty_flag, int nx, int ny, int nz,
12                        double *mincolor, double *maxcolor) {
13   int i;
14   double value;
15 
16   for (i = 0; i < (nx + 1) * (ny + 1) * (nz + 1); i++) {
17     if (empty_flag[i] == 1) {
18       value                            = var[i];
19       if (value < *mincolor) *mincolor = value;
20       if (value > *maxcolor) *maxcolor = value;
21     }
22   }
23   return;
24 }
generate_histogram_graph(double tmincolor,double tmaxcolor,double * var,int * empty_flag,int nx,int ny,int nz,int mynode,int pesize,HECMW_Comm VIS_COMM,int color_system_type)25 void generate_histogram_graph(double tmincolor, double tmaxcolor, double *var,
26                               int *empty_flag, int nx, int ny, int nz,
27                               int mynode, int pesize, HECMW_Comm VIS_COMM,
28                               int color_system_type) {
29   int i, j, k, m;
30   double delta, value, color[3];
31   int count[500], t_count[500], max_number, max_length, start_x, end_x, start_y,
32       end_y;
33   FILE *fp;
34   double *graph;
35   BITMAPFILEHEADER header; /* File header */
36 
37   unsigned char r, g, b;
38   int ri, gi, bi;
39   BITMAPINFOHEADER info;
40 
41   int start_xs, start_ys;
42   char buf[128];
43   int output7[7][7];
44 
45   delta = (tmaxcolor - tmincolor) / 500.0;
46   for (i = 0; i < 500; i++) {
47     count[i]   = 0;
48     t_count[i] = 0;
49   }
50   for (i = 0; i < (nx + 1) * (ny + 1) * (nz + 1); i++) {
51     if (empty_flag[i] == 1) {
52       j              = (int)((var[i] - tmincolor) / delta);
53       if (j < 0) j   = 0;
54       if (j > 499) j = 499;
55       count[j]++;
56     }
57   }
58   if (pesize > 1)
59     HECMW_Allreduce(count, t_count, 500, HECMW_INT, HECMW_SUM, VIS_COMM);
60   else {
61     for (i = 0; i < 500; i++) t_count[i] = count[i];
62   }
63   if (mynode == 0) {
64     fp = fopen("histogram.bmp", "wb");
65     if (fp == NULL) {
66       fprintf(stderr, "Cannot generate the histogram output file\n");
67       exit(0);
68     }
69     graph = (double *)HECMW_calloc(400 * 530 * 3, sizeof(double));
70     if (graph == NULL) {
71       fprintf(stderr, "There is no enough memory for graph\n");
72       exit(0);
73     }
74     for (i = 0; i < 400 * 530 * 3; i++) graph[i] = 0.0;
75     max_number                                   = 0;
76     for (i = 0; i < 500; i++) {
77       if (t_count[i] > max_number) max_number = t_count[i];
78     }
79     if (max_number == 0) {
80       fprintf(stderr,
81               "Cannot generate histogram graph, the number of voxels is 0\n");
82       exit(0);
83     }
84     max_length = (int)(400 - 30 - 5 - 45 * 1.5);
85     start_x    = (int)(5 + 45 * 1.5 + 15);
86     start_y    = 15;
87     for (j = 0; j < 500; j++) {
88       end_x =
89           (int)((double)t_count[j] * (double)max_length / (double)max_number +
90                 start_x) +
91           2;
92       value = j / 500.0;
93       value2_to_rgb(value, color, color_system_type);
94       for (i = start_x; i < end_x; i++) {
95         graph[((j + 15) * 400 + i) * 3]     = color[0];
96         graph[((j + 15) * 400 + i) * 3 + 1] = color[1];
97         graph[((j + 15) * 400 + i) * 3 + 2] = color[2];
98       }
99     }
100     /*start mark scales */
101     start_y = 15;
102     end_y   = 515;
103     for (k = 0; k < 11; k++) {
104       value    = tmincolor + (tmaxcolor - tmincolor) / 10.0 * k;
105       start_ys = start_y + (int)((double)500.0 / 10 * k) - (int)7 / 2;
106       start_xs = 15;
107       sprintf(buf, "%3.2E", value);
108       for (m = 0; m < 9; m++) {
109         font7_generate(buf[8 - m], output7);
110         for (j = 0; j < 7; j++)
111           for (i = 0; i < 7; i++) {
112             graph[((start_ys + j) * 400 + start_xs - i) * 3] =
113                 (double)output7[6 - j][i];
114             graph[((start_ys + j) * 400 + start_xs - i) * 3 + 1] =
115                 (double)output7[6 - j][i];
116             graph[((start_ys + j) * 400 + start_xs - i) * 3 + 2] =
117                 (double)output7[6 - j][i];
118           }
119         start_xs += 7;
120         if ((value >= 0) && (m == 0)) start_xs -= 7;
121       }
122       if ((k != 0) && (k != 10)) {
123         start_ys += (int)7 / 2;
124 
125         for (i = start_x; i < start_x + 5; i++)
126           for (j = 0; j < 3; j++) graph[(start_ys * 400 + i) * 3 + j] = 1.0;
127       }
128     }
129     header.bfSize = 54 + 3 * 400 * 530;
130 #ifdef CONVERSE_ORDER
131     header.bfSize = change_unsigned_int_order(54 + 3 * 400 * 530);
132 #endif
133     header.bfReserved1 = 0;
134 #ifdef CONVERSE_ORDER
135     header.bfReserved1 = change_short_int_order(0);
136 #endif
137 
138     header.bfReserved2 = 0;
139 #ifdef CONVERSE_ORDER
140     header.bfReserved2 = change_short_int_order(0);
141 #endif
142 
143     header.bfOffBits = 54;
144 #ifdef CONVERSE_ORDER
145     header.bfOffBits = change_unsigned_int_order(54);
146 #endif
147 
148     info.biBitCount = 24;
149 #ifdef CONVERSE_ORDER
150     info.biBitCount = change_short_int_order(24);
151 #endif
152 
153     info.biSize = 40;
154 #ifdef CONVERSE_ORDER
155     info.biSize = change_unsigned_int_order(40);
156 #endif
157 
158     info.biWidth = 400;
159 #ifdef CONVERSE_ORDER
160     info.biWidth = change_int_order(400);
161 #endif
162 
163     info.biHeight = 530;
164 #ifdef CONVERSE_ORDER
165     info.biHeight = change_int_order(530);
166 #endif
167 
168     info.biSizeImage = 3 * 400 * 530;
169 #ifdef CONVERSE_ORDER
170     info.biSizeImage = change_unsigned_int_order(3 * 400 * 530);
171 #endif
172 
173     info.biClrImportant = 0;
174 #ifdef CONVERSE_ORDER
175     info.biClrImportant = change_unsigned_int_order(0);
176 #endif
177 
178     info.biClrUsed = 0;
179 #ifdef CONVERSE_ORDER
180     info.biClrUsed = change_unsigned_int_order(0);
181 #endif
182 
183     info.biCompression = 0;
184 #ifdef CONVERSE_ORDER
185     info.biCompression = change_unsigned_int_order(0);
186 #endif
187 
188     info.biPlanes = 1;
189 #ifdef CONVERSE_ORDER
190     info.biPlanes = change_short_int_order(1);
191 #endif
192 
193     info.biXPelsPerMeter = 3780;
194 #ifdef CONVERSE_ORDER
195     info.biXPelsPerMeter = change_int_order(3780);
196 #endif
197 
198     info.biYPelsPerMeter = 3780;
199 #ifdef CONVERSE_ORDER
200     info.biYPelsPerMeter = change_int_order(3780);
201 #endif
202 
203     putc('B', fp);
204     putc('M', fp);
205     fwrite(&(header.bfSize), sizeof(unsigned int), 1, fp);
206     fwrite(&header.bfReserved1, sizeof(unsigned short int), 1, fp);
207     fwrite(&header.bfReserved2, sizeof(unsigned short int), 1, fp);
208     fwrite(&header.bfOffBits, sizeof(unsigned int), 1, fp);
209     fwrite(&info, 40, 1, fp);
210     for (j = 0; j < 530; j++)
211       for (i = 400 - 1; i >= 0; i--) {
212         ri               = (int)(graph[(j * 400 + i) * 3] * 256);
213         gi               = (int)(graph[(j * 400 + i) * 3 + 1] * 256);
214         bi               = (int)(graph[(j * 400 + i) * 3 + 2] * 256);
215         if (ri < 0) ri   = 0;
216         if (ri > 255) ri = 255;
217         if (gi < 0) gi   = 0;
218         if (gi > 255) gi = 255;
219         if (bi < 0) bi   = 0;
220         if (bi > 255) bi = 255;
221         r                = ri;
222         g                = gi;
223         b                = bi;
224         putc(b, fp);
225         putc(g, fp);
226         putc(r, fp);
227       }
228 
229     fclose(fp);
230     HECMW_free(graph);
231   }
232   return;
233 }
234 
generate_interval_point(double tmincolor,double tmaxcolor,double * var,int * empty_flag,int nx,int ny,int nz,int mynode,int pesize,HECMW_Comm VIS_COMM,double * interval_point)235 void generate_interval_point(double tmincolor, double tmaxcolor, double *var,
236                              int *empty_flag, int nx, int ny, int nz,
237                              int mynode, int pesize, HECMW_Comm VIS_COMM,
238                              double *interval_point) {
239   int i, j;
240   double delta;
241   int count[500], t_count[500], tmp_count[500], sum_count, interv_count, sum,
242       current_j;
243   delta = (tmaxcolor - tmincolor) / 500.0;
244   for (i = 0; i < 500; i++) {
245     count[i]   = 0;
246     t_count[i] = 0;
247   }
248   for (i = 0; i < (nx + 1) * (ny + 1) * (nz + 1); i++) {
249     if (empty_flag[i] == 1) {
250       j              = (int)((var[i] - tmincolor) / delta);
251       if (j < 0) j   = 0;
252       if (j > 499) j = 499;
253       count[j]++;
254     }
255   }
256   if (pesize > 1)
257     HECMW_Allreduce(count, t_count, 500, HECMW_INT, HECMW_SUM, VIS_COMM);
258   else {
259     for (i = 0; i < 500; i++) t_count[i] = count[i];
260   }
261   sum_count = 0;
262   for (i = 0; i < 500; i++) {
263     sum_count += t_count[i];
264     tmp_count[i] = t_count[i];
265   }
266   interv_count      = (int)sum_count / 10;
267   current_j         = 0;
268   interval_point[0] = tmincolor;
269   interval_point[1] = 0.0;
270   for (i = 1; i < 10; i++) {
271     interval_point[i * 2 + 1] = (double)i / 10.0;
272     sum                       = 0;
273     j                         = current_j;
274     while ((j < 500) && (sum < interv_count)) {
275       sum += t_count[j];
276       j++;
277     }
278     j--;
279     interval_point[i * 2] =
280         ((double)j / 500.0 +
281          1.0 / 500.0 *
282              (1.0 - (double)(sum - interv_count) / (double)tmp_count[j])) *
283             (tmaxcolor - tmincolor) +
284         tmincolor;
285     t_count[j] = sum - interv_count;
286     current_j  = j;
287   }
288   interval_point[20] = tmaxcolor;
289   interval_point[21] = 1.0;
290   fprintf(stderr, "The automatic color mapping set is :\n");
291   for (i = 0; i < 11; i++)
292     fprintf(stderr, "%lf    %lf   \n", interval_point[i * 2],
293             interval_point[i * 2 + 1]);
294   return;
295 }
296 
output_histogram(double tmincolor,double tmaxcolor,double * var,int * empty_flag,int nx,int ny,int nz,int mynode,int pesize,HECMW_Comm VIS_COMM)297 void output_histogram(double tmincolor, double tmaxcolor, double *var,
298                       int *empty_flag, int nx, int ny, int nz, int mynode,
299                       int pesize, HECMW_Comm VIS_COMM) {
300   int i, j;
301   double delta;
302   int count[100], t_count[100];
303   FILE *fp;
304 
305   delta = (tmaxcolor - tmincolor) / 100.0;
306   for (i = 0; i < 100; i++) {
307     count[i]   = 0;
308     t_count[i] = 0;
309   }
310   for (i = 0; i < (nx + 1) * (ny + 1) * (nz + 1); i++) {
311     if (empty_flag[i] == 1) {
312       j             = (int)((var[i] - tmincolor) / delta);
313       if (j < 0) j  = 0;
314       if (j > 99) j = 99;
315       count[j]++;
316     }
317   }
318   if (pesize > 1)
319     HECMW_Allreduce(count, t_count, 100, HECMW_INT, HECMW_SUM, VIS_COMM);
320   else {
321     for (i = 0; i < 100; i++) t_count[i] = count[i];
322   }
323   if (mynode == 0) {
324     fp = fopen("histogram.file", "w");
325     if (fp == NULL) {
326       fprintf(stderr, "Cannot generate the histogram output file\n");
327       exit(0);
328     }
329     for (i = 0; i < 100; i++)
330       fprintf(fp, "%d   %d   -----(%lf --- %lf)\n", i, t_count[i],
331               tmincolor + i * delta, tmincolor + (i + 1) * delta);
332     fclose(fp);
333   }
334   return;
335 }
336 
find_minmax(double * voxel_dxyz,double * voxel_orig_xyz,int mynode,double range[6])337 void find_minmax(double *voxel_dxyz, double *voxel_orig_xyz, int mynode,
338                  double range[6]) {
339   int i;
340   for (i     = 0; i < 6; i++)
341     range[i] = voxel_orig_xyz[mynode * 3 + i / 2] +
342                (i % 2) * voxel_dxyz[mynode * 3 + i / 2];
343   return;
344 }
345 
transform_range_vertex(double range[6],double vertex[24])346 void transform_range_vertex(double range[6], double vertex[24]) {
347   vertex[0 * 3] = vertex[4 * 3] = vertex[7 * 3] = vertex[3 * 3] = range[0];
348   vertex[1 * 3] = vertex[5 * 3] = vertex[6 * 3] = vertex[2 * 3] = range[1];
349   vertex[0 * 3 + 1] = vertex[1 * 3 + 1] = vertex[5 * 3 + 1] =
350       vertex[4 * 3 + 1]                 = range[2];
351   vertex[3 * 3 + 1] = vertex[2 * 3 + 1] = vertex[6 * 3 + 1] =
352       vertex[7 * 3 + 1]                 = range[3];
353   vertex[0 * 3 + 2] = vertex[1 * 3 + 2] = vertex[2 * 3 + 2] =
354       vertex[3 * 3 + 2]                 = range[4];
355   vertex[4 * 3 + 2] = vertex[5 * 3 + 2] = vertex[6 * 3 + 2] =
356       vertex[7 * 3 + 2]                 = range[5];
357   return;
358 }
359