Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/visuals/isosurface.c
3203 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program (in file fem/GPL-2); if not, write to the
19
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
* Boston, MA 02110-1301, USA.
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* Action routines for visual class IsoSurface.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 26 Sep 1995
40
*
41
*
42
* Modification history:
43
*
44
* 28 Sep 1995, modified vis_initialize_isosurface_visual to set the
45
* VisualName field of the visual_type structure
46
*
47
* Juha R.
48
*
49
******************************************************************************/
50
51
#include "../elmerpost.h"
52
#include "../elements/elements.h"
53
/******************************************************************************
54
*
55
* Parameter structure definitions for Isosurface visual class
56
*
57
******************************************************************************/
58
59
60
typedef struct isosurface_s
61
{
62
mesh_style_t Style;
63
64
scalar_t *ContourData;
65
scalar_t *ColorData;
66
67
scalar_t *NormalData[3];
68
69
int NofLevels;
70
double *Levels;
71
72
material_t *Material;
73
colormap_t *ColorMap;
74
75
int Recompute;
76
77
int NPolygons;
78
int MaxPolygons;
79
polygon_t *Polygons;
80
81
int LineQuality;
82
double LineWidth;
83
84
line_style_t LineStyle;
85
} isosurface_t;
86
87
#define FEPS 1.0E-9
88
89
/*******************************************************************************
90
*
91
* Name: vis_get_isosurface
92
*
93
* Purpose: Extract a surface with given threshold
94
*
95
* Parameters:
96
*
97
* Input: (triangle_t *)
98
* (vertex_t *)
99
* (double *,double,double) color quantity, and scales => 0,1
100
* (double *) surface quantity
101
* (double) threshold value
102
*
103
* Output: (line_t *) place to store the line
104
*
105
* Return value: number of points generated, line exists if (n>=2)
106
*
107
******************************************************************************/
108
static int vis_get_isosurface
109
(
110
element_model_t *model, element_t *element, vertex_t *vertices, double *C, double *F,
111
double *NX, double *NY, double *NZ, polygon_t *Polygons, int nlevels, double *levels,double CScl,double CAdd
112
)
113
{
114
static double x[ELM_MAX_ELEMENT_NODES];
115
static double y[ELM_MAX_ELEMENT_NODES];
116
static double z[ELM_MAX_ELEMENT_NODES];
117
static double f[ELM_MAX_ELEMENT_NODES];
118
static double c[ELM_MAX_ELEMENT_NODES];
119
static double u[ELM_MAX_ELEMENT_NODES];
120
static double v[ELM_MAX_ELEMENT_NODES];
121
static double w[ELM_MAX_ELEMENT_NODES];
122
123
int i,j,n,*T=element->Topology;
124
element_type_t *elmt = element->ElementType;
125
126
if ( elmt->IsoSurface )
127
{
128
for( i=0; i<elmt->NumberOfNodes; i++ )
129
{
130
x[i] = vertices[T[i]].x[0];
131
y[i] = vertices[T[i]].x[1];
132
z[i] = vertices[T[i]].x[2];
133
134
f[i] = F[T[i]];
135
if ( C )
136
c[i] = CScl*(C[T[i]]-CAdd);
137
else
138
c[i] = 0.0;
139
140
if ( NX )
141
{
142
u[i] = NX[T[i]];
143
v[i] = NY[T[i]];
144
w[i] = NZ[T[i]];
145
}
146
}
147
148
n = 0;
149
for( i=0; i<nlevels; i++ )
150
{
151
n += (*elmt->IsoSurface)( levels[i],f,c,x,y,z,u,v,w,&Polygons[n] );
152
}
153
154
return n;
155
}
156
157
return 0;
158
}
159
160
/*******************************************************************************
161
*
162
* Name: vis_isosurfaces
163
*
164
* Purpose: Draw surface given data, and threshold values
165
*
166
* Parameters:
167
*
168
* Input: (geometry_t *)
169
* (isosurface_t *) surface display params
170
* (double) time used
171
*
172
* Output: graphics
173
*
174
* Return value: if mouse interaction is going on, and time used exceeds
175
* given value (TooLong1,2) FALSE, otherwise TRUE
176
*
177
******************************************************************************/
178
static int vis_isosurface( geometry_t *geometry, element_model_t *model, isosurface_t *IsoSurface, double dt )
179
{
180
double CScl,CAdd,*Levels = IsoSurface->Levels;
181
double *C=NULL, *F=NULL, *NX = NULL, *NY = NULL, *NZ = NULL;
182
183
scalar_t *ColorData = IsoSurface->ColorData;
184
scalar_t *ContourData = IsoSurface->ContourData;
185
186
int i,j,k,l,m,n,quick;
187
188
double width = IsoSurface->LineWidth*0.005, color[3];
189
190
element_t *elements = model->Elements;
191
192
void gra_set_colormap(), gra_sphere_quality(), gra_set_material(), vis_polygon();
193
194
if ( !ContourData || !ContourData->f ) return TRUE;
195
196
if ( !GlobalOptions.StereoMode )
197
if ( IsoSurface->Material->Diffuse[3] < 1.0 )
198
{
199
if ( GlobalPass != 0 ) return TRUE;
200
} else if ( GlobalPass == 0 )
201
{
202
return TRUE;
203
}
204
205
F = ContourData->f;
206
207
if ( ColorData && ColorData->f )
208
{
209
CScl = 1.0/(ColorData->max - ColorData->min);
210
C = ColorData->f;
211
CAdd = ColorData->min;
212
213
gra_set_colormap( IsoSurface->ColorMap );
214
} else gra_set_colormap( NULL );
215
216
if ( IsoSurface->NormalData[0] && IsoSurface->NormalData[0]->f )
217
{
218
NX = IsoSurface->NormalData[0]->f;
219
NY = IsoSurface->NormalData[1]->f;
220
NZ = IsoSurface->NormalData[2]->f;
221
} else
222
{
223
gra_loff();
224
}
225
226
quick = (IsoSurface->Style == mesh_style_line);
227
quick |= epMouseDown && epMouseDownTakesTooLong;
228
229
if ( !quick && (IsoSurface->LineStyle == line_style_cylinder) )
230
{
231
gra_sphere_quality( IsoSurface->LineQuality );
232
}
233
234
if ( quick && !(epMouseDown && epMouseDownTakesTooLong) )
235
{
236
gra_line_width( IsoSurface->LineWidth );
237
} else {
238
gra_line_width( 1.0 );
239
}
240
241
gra_set_material( IsoSurface->Material );
242
243
if ( quick ) gra_polygon_mode( GRA_LINE );
244
gra_begin( GRA_TRIANGLES );
245
246
if ( IsoSurface->Recompute )
247
{
248
IsoSurface->NPolygons = 0;
249
for( i=0; i<model->NofElements; i++ )
250
{
251
if ( !elements[i].DisplayFlag ) continue;
252
253
if ( IsoSurface->MaxPolygons-IsoSurface->NPolygons < 1200 )
254
{
255
IsoSurface->MaxPolygons += 1200;
256
IsoSurface->Polygons = (polygon_t *)realloc(
257
IsoSurface->Polygons,IsoSurface->MaxPolygons*sizeof(polygon_t)
258
);
259
}
260
261
n = vis_get_isosurface(
262
model,&elements[i],geometry->Vertices,C,F,NX,NY,NZ,
263
&IsoSurface->Polygons[IsoSurface->NPolygons],IsoSurface->NofLevels,Levels,CScl,CAdd
264
);
265
266
for( j=0; j<n; j++ ) vis_polygon( &IsoSurface->Polygons[IsoSurface->NPolygons+j] );
267
268
IsoSurface->NPolygons += n;
269
270
if ( epMouseDown )
271
{
272
if ( quick )
273
{
274
if ( (i & 32) && (RealTime() - dt > TooLong2) )
275
if ( ++epMouseDownTakesTooLong > 3 )
276
{
277
gra_end();
278
gra_lon();
279
gra_polygon_mode( GRA_FILL );
280
return FALSE;
281
} else dt = RealTime();
282
} else
283
{
284
if ( RealTime() - dt > TooLong1 )
285
{
286
gra_end();
287
gra_lon();
288
289
epMouseDownTakesTooLong++;
290
return FALSE;
291
}
292
}
293
}
294
if ( BreakLoop ) break;
295
}
296
IsoSurface->Recompute = FALSE;
297
} else
298
{
299
for( j=0; j<IsoSurface->NPolygons; j++ )
300
{
301
vis_polygon( &IsoSurface->Polygons[j] );
302
303
if ( (j & 64) && epMouseDown )
304
{
305
if ( quick )
306
{
307
if ( RealTime() - dt > TooLong2 )
308
if ( ++epMouseDownTakesTooLong > 3 )
309
{
310
gra_end();
311
gra_lon();
312
gra_polygon_mode( GRA_FILL );
313
314
return FALSE;
315
} else dt = RealTime();
316
} else
317
{
318
if ( RealTime() - dt > TooLong1 )
319
{
320
gra_end();
321
gra_lon();
322
323
epMouseDownTakesTooLong++;
324
return FALSE;
325
}
326
}
327
}
328
if ( BreakLoop ) break;
329
}
330
}
331
332
gra_end();
333
gra_lon();
334
if ( quick ) gra_polygon_mode( GRA_FILL );
335
336
return TRUE;
337
}
338
339
340
/*******************************************************************************
341
*
342
* Name: vis_isosurface_alloc
343
*
344
* Purpose: allocate memory for isosurface_t structure
345
*
346
* Parameters:
347
*
348
* Input: none
349
*
350
* Output: none
351
*
352
* Return value: pointer to allocated memory
353
*
354
******************************************************************************/
355
static isosurface_t *vis_isosurface_alloc()
356
{
357
isosurface_t *isosurface = (isosurface_t *)calloc(sizeof(isosurface_t),1);
358
359
if ( !isosurface )
360
{
361
fprintf( stderr, "vis_isosurface_alloc: FATAL: can't alloc a few bytes of memory.\n" );
362
}
363
364
return isosurface;
365
}
366
367
/*******************************************************************************
368
*
369
* Name: vis_isosurface_delete
370
*
371
* Purpose: free memory associated with isosurface_t structure
372
*
373
* Parameters:
374
*
375
* Input: (isosurface_t *) pointer to structure
376
*
377
* Output: none
378
*
379
* Return value: void
380
*
381
******************************************************************************/
382
static void vis_isosurface_delete(isosurface_t *isosurface)
383
{
384
if ( isosurface ) {
385
if ( isosurface -> MaxPolygons > 0 && isosurface -> Polygons ) free( isosurface->Polygons );
386
free( isosurface );
387
}
388
}
389
390
/*******************************************************************************
391
*
392
* Name: vis_initialize_isosurface_visual
393
*
394
* Purpose: Register "Contour Line" visual type
395
*
396
* Parameters:
397
*
398
* Input: none
399
*
400
* Output: none
401
*
402
* Return value: vis_add_visual_type (malloc success probably)...
403
*
404
******************************************************************************/
405
int vis_initialize_isosurface_visual()
406
{
407
static char *visual_name = "Isosurfaces";
408
visual_type_t VisualDef;
409
410
static isosurface_t isosurface;
411
412
static visual_param_t IsosurfaceParams[] =
413
{
414
{ "Style", "%d", 0, VIS_VISUAL_PARAM_INT, 0, 0.0, NULL },
415
{ "ContourData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
416
{ "ColorData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
417
{ "NormalData0", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
418
{ "NormalData1", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
419
{ "NormalData2", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
420
{ "NofLevels", "%d", 0, VIS_VISUAL_PARAM_INT, 0, 0.0, NULL },
421
{ "Levels", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
422
{ "Material", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultMaterial },
423
{ "ColorMap", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultColorMap },
424
{ "LineWidth", "%lf",0, VIS_VISUAL_PARAM_FLOAT, 0, 1.0, NULL },
425
{ "LineQuality", "%d", 0, VIS_VISUAL_PARAM_INT, 1, 0.0, NULL },
426
{ "LineStyle", "%d", 0, VIS_VISUAL_PARAM_INT,line_style_line, 0.0, NULL },
427
{ "Recompute", "%d", 0, VIS_VISUAL_PARAM_INT, TRUE, 0.0, NULL },
428
{ NULL, NULL, 0, 0, 0, 0.0, NULL }
429
};
430
431
int n = 0;
432
433
IsosurfaceParams[n++].Offset = (char *)&isosurface.Style - (char *)&isosurface;
434
IsosurfaceParams[n++].Offset = (char *)&isosurface.ContourData - (char *)&isosurface;
435
IsosurfaceParams[n++].Offset = (char *)&isosurface.ColorData - (char *)&isosurface;
436
IsosurfaceParams[n++].Offset = (char *)&isosurface.NormalData[0] - (char *)&isosurface;
437
IsosurfaceParams[n++].Offset = (char *)&isosurface.NormalData[1] - (char *)&isosurface;
438
IsosurfaceParams[n++].Offset = (char *)&isosurface.NormalData[2] - (char *)&isosurface;
439
IsosurfaceParams[n++].Offset = (char *)&isosurface.NofLevels - (char *)&isosurface;
440
IsosurfaceParams[n++].Offset = (char *)&isosurface.Levels - (char *)&isosurface;
441
IsosurfaceParams[n++].Offset = (char *)&isosurface.Material - (char *)&isosurface;
442
IsosurfaceParams[n++].Offset = (char *)&isosurface.ColorMap - (char *)&isosurface;
443
IsosurfaceParams[n++].Offset = (char *)&isosurface.LineWidth - (char *)&isosurface;
444
IsosurfaceParams[n++].Offset = (char *)&isosurface.LineQuality - (char *)&isosurface;
445
IsosurfaceParams[n++].Offset = (char *)&isosurface.LineStyle - (char *)&isosurface;
446
IsosurfaceParams[n++].Offset = (char *)&isosurface.Recompute - (char *)&isosurface;
447
448
VisualDef.VisualName = visual_name;
449
450
VisualDef.RealizeVisual = (int (*)()) vis_isosurface;
451
VisualDef.AllocParams = (void *(*)()) vis_isosurface_alloc;
452
VisualDef.DeleteParams = (void (*)()) vis_isosurface_delete;
453
VisualDef.VisualParams = IsosurfaceParams;
454
455
return vis_add_visual_type( &VisualDef );
456
}
457
458