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 the mesh visual class.
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: Juha.Ruokolainen@csc.fi
38 *
39 * Date: 26 Sep 1995
40 *
41 *
42 * Modification history:
43 *
44 * 28 Sep 1995, modified vis_initialize_mesh_visual to set the VisualName field
45 * of the visual_type structure
46 *
47 * Juha R.
48 *
49 ******************************************************************************/
50
51 #include "../elmerpost.h"
52
53
54 /******************************************************************************
55 *
56 * Parameter sructure definitios for mesh visual class
57 *
58 ******************************************************************************/
59 static char *mesh_style_names[] =
60 {
61 "none", "line", "surf", "line_and_surf", NULL
62 };
63
64 typedef struct mesh_s
65 {
66 scalar_t *ColorData;
67
68 mesh_style_t Style;
69
70 edge_style_t EdgeStyle;
71
72 material_t *Material;
73 material_t *EdgeMaterial;
74 colormap_t *ColorMap;
75
76 int LineQuality;
77 double LineWidth;
78
79 line_style_t LineStyle;
80
81 logical_t NodeNumbers;
82 } mesh_t;
83
84
85 /*******************************************************************************
86 *
87 * Name: vis_polygon
88 *
89 * Purpose:
90 *
91 *
92 * Parameters:
93 *
94 * Input: (polygon_t *) polygon
95 *
96 * Output: graphics
97 *
98 * Return value: void
99 *
100 ******************************************************************************/
vis_polygon(polygon_t * poly)101 void vis_polygon( polygon_t *poly)
102 {
103 int n=3;
104
105 gra_poly3( n,poly->x,poly->y,poly->z,poly->u,poly->v,poly->w,poly->c );
106 }
107
108 /*******************************************************************************
109 *
110 * Name: vis_triangle
111 *
112 * Purpose:
113 *
114 *
115 * Parameters:
116 *
117 * Input: (triangle_t *) triangle
118 * (vertex_t *) vertex array
119 * (double *) quantity to use color the edges (or NULL)
120 * (double,double ) CScl,CAdd are constatnt to scale color
121 * range (0-1)
122 * (line_style_t) line style, either line_style_line or
123 * line_style_cylider
124 *
125 * Output: graphics
126 *
127 * Return value: void
128 *
129 ******************************************************************************/
vis_triangle(triangle_t * t,vertex_t * v,double * color,double CScl,double CAdd)130 void vis_triangle
131 (
132 triangle_t *t,vertex_t *v,double *color,double CScl,double CAdd
133 )
134 {
135 float x[3][3],n[3][3],c[3];
136 int j,k;
137
138 for( j=0; j<3; j++ )
139 {
140 k = t->v[j];
141 x[j][0] = v[k].x[0];
142 x[j][1] = v[k].x[1];
143 x[j][2] = v[k].x[2];
144
145 n[j][0] = t->u[j][0];
146 n[j][1] = t->u[j][1];
147 n[j][2] = t->u[j][2];
148
149 if ( color ) c[j] = CScl * ( color[k]-CAdd );
150 }
151
152 gra_triangle( x,n,c );
153 }
154
155 /*******************************************************************************
156 *
157 * Name: vis_draw_edge
158 *
159 * Purpose: draw element edge as line or cylinder
160 *
161 * Parameters:
162 *
163 * Input: (vertex_t *) vertex array
164 * (int,int) edge vertex indices
165 * (double *) color quantity
166 * (double,double ) CScl,CAdd are constatnt to scale color
167 * range (0-1)
168 * (line_style_t) line style, either line_style_line or
169 * line_style_cylider
170 * (double) line width, cylinder radius.
171 *
172 *
173 * Output: graphics
174 *
175 * Return value: void
176 *
177 ******************************************************************************/
vis_draw_edge(vertex_t * vertex,int v0,int v1,double * color,double CScl,double CAdd,line_style_t style,double width)178 static void vis_draw_edge(vertex_t *vertex,int v0,int v1,double *color,double CScl,
179 double CAdd,line_style_t style,double width)
180 {
181 double c0=0.0,c1=1.0;
182
183 /*
184 * if color function given scale values to 0-1
185 */
186 if ( color )
187 {
188 c0 = CScl*( color[v0] - CAdd );
189 c1 = CScl*( color[v1] - CAdd );
190 }
191
192 gra_line( vertex[v0].x,c0,vertex[v1].x,c1,style,width );
193 }
194
195 /*******************************************************************************
196 *
197 * Name: vis_mesh
198 *
199 * Purpose: draw mesh as lines or surface, with color codes or not
200 *
201 * Parameters:
202 *
203 * Input: (geometry_t *) triangles to draw
204 * (mesh_t *) mesh display parameters
205 * (double)
206 *
207 * Output: graphics
208 *
209 * Return value: if mouse interaction is going on, and time used exeeds
210 * given value (TooLong1,2) FALSE, otherwise TRUE
211 *
212 ******************************************************************************/
vis_mesh(geometry_t * geometry,element_model_t * model,mesh_t * Mesh,double dt)213 static int vis_mesh( geometry_t *geometry, element_model_t *model, mesh_t *Mesh,double dt )
214 {
215 scalar_t *ColorData = Mesh->ColorData;
216
217 vertex_t *v = geometry->Vertices;
218
219 edge_list_t *edge;
220
221 double width = Mesh->LineWidth*0.005,CScl=1.0,CAdd=0.0,*C=NULL;
222
223 int i,j,quick,N=geometry->VertexCount,NT=geometry->TriangleCount;
224
225 element_t *elements = model->Elements;
226
227 static char str[100];
228
229 if ( !GlobalOptions.StereoMode )
230 if ( Mesh->Material->Diffuse[3] < 1.0 )
231 {
232 if ( GlobalPass != 0 ) return TRUE;
233 } else if ( GlobalPass == 0 )
234 {
235 return TRUE;
236 }
237
238 quick = (Mesh->Style == mesh_style_line && Mesh->LineStyle == line_style_line );
239 quick &= ~Mesh->NodeNumbers;
240 quick |= epMouseDown && epMouseDownTakesTooLong;
241
242 gra_set_material( Mesh->Material );
243
244 if ( quick && !(epMouseDown && epMouseDownTakesTooLong) )
245 {
246 gra_line_width( Mesh->LineWidth );
247 } else {
248 gra_line_width( 1.0 );
249 }
250
251 if ( ColorData && ColorData->f )
252 {
253 C = ColorData->f;
254
255 CAdd = ColorData->min;
256 if ( ABS(ColorData->max - ColorData->min)>0.0 )
257 CScl = 1.0 / (ColorData->max - ColorData->min);
258 else
259 CScl = 1.0;
260
261 gra_set_colormap( Mesh->ColorMap );
262 } else gra_set_colormap( NULL );
263
264 if ( quick )
265 {
266 gra_set_material( Mesh->EdgeMaterial );
267 gra_beg_lines();
268
269 for( i=0; i<N; i++ )
270 {
271 if ( v[i].ElementModelNode )
272 {
273 for( edge=geometry->Edges[i].EdgeList; edge != NULL; edge = edge->Next )
274 {
275 if ( edge->Element && !edge->Element->DisplayFlag ) continue;
276 if ( Mesh->EdgeStyle == edge_style_all || ABS(edge->Count) == 1 )
277 {
278 vis_draw_edge( v,i,edge->Entry,C,CScl,CAdd,line_style_line,width );
279 }
280 }
281 } else break;
282
283 if ( epMouseDown && (i & 128) )
284 {
285 if ( RealTime() - dt > TooLong2 )
286 if ( ++epMouseDownTakesTooLong > 3 )
287 {
288 gra_end_lines();
289 return FALSE;
290 } else dt = RealTime();
291 }
292
293 if ( BreakLoop ) break;
294 }
295
296 gra_end_lines();
297 gra_set_material( Mesh->Material );
298
299 return TRUE;
300 }
301
302 if ( Mesh->NodeNumbers )
303 {
304 for( i=0; i<N; i++ )
305 {
306 if ( v[i].ElementModelNode )
307 {
308 glRasterPos3f( v[i].x[0],v[i].x[1],v[i].x[2]);
309 sprintf( str, "N %d", i );
310 PrintString( str );
311 }
312 }
313 }
314
315 if ( Mesh->Style == mesh_style_surf || Mesh->Style == mesh_style_line_and_surf )
316 {
317 triangle_t *t = geometry->Triangles;
318
319 gra_begin( GRA_TRIANGLES );
320 for( i=0; i<NT; i++,t++ )
321 {
322 if ( t->Element && !t->Element->DisplayFlag ) continue;
323
324 if ( Mesh->EdgeStyle != edge_style_all && t->Count > 1 ) continue;
325
326 vis_triangle( t,v,C,CScl,CAdd );
327
328 if ( epMouseDown && (i & 8) )
329 if ( RealTime() - dt > TooLong1 )
330 {
331 epMouseDownTakesTooLong++;
332 gra_end();
333 return FALSE;
334 }
335
336 if ( BreakLoop ) break;
337 }
338 gra_end();
339 }
340
341 if ( Mesh->Style == mesh_style_line_and_surf ) gra_set_colormap( NULL );
342
343 if ( Mesh->Style == mesh_style_line || Mesh->Style == mesh_style_line_and_surf )
344 {
345
346 glMatrixMode(GL_PROJECTION);
347 glPushMatrix();
348 glTranslatef(0.0,0.0,0.005);
349 glMatrixMode(GL_MODELVIEW);
350
351 gra_set_material( Mesh->EdgeMaterial );
352
353 if ( Mesh->LineStyle == line_style_cylinder )
354 {
355 gra_sphere_quality( Mesh->LineQuality );
356
357 for( i=0; i<N; i++ )
358 {
359 if ( v[i].ElementModelNode )
360 {
361 for( edge=geometry->Edges[i].EdgeList; edge != NULL; edge = edge->Next )
362 {
363 if ( edge->Element && !edge->Element->DisplayFlag ) continue;
364 if ( Mesh->EdgeStyle == edge_style_all || ABS(edge->Count) == 1 )
365 {
366 j = edge->Entry;
367 vis_draw_edge( v,i,j,C,CScl,CAdd,line_style_cylinder,width );
368 }
369 }
370 } else break;
371
372 if ( epMouseDown && (i & 8) )
373 if ( RealTime() - dt > TooLong1 )
374 {
375 epMouseDownTakesTooLong++;
376 glMatrixMode(GL_PROJECTION);
377 glPopMatrix();
378 glMatrixMode( GL_MODELVIEW );
379 return FALSE;
380 }
381
382 if ( BreakLoop ) break;
383 }
384 } else
385 {
386 gra_line_width( Mesh->LineWidth );
387 gra_beg_lines();
388 for( i=0; i<N; i++ )
389 {
390 if ( v[i].ElementModelNode )
391 {
392 for( edge=geometry->Edges[i].EdgeList; edge != NULL; edge = edge->Next )
393 {
394 if ( edge->Element && !edge->Element->DisplayFlag ) continue;
395 if ( Mesh->EdgeStyle == edge_style_all || ABS(edge->Count) == 1 )
396 {
397 vis_draw_edge( v,i,edge->Entry,C,CScl,CAdd,line_style_line,width );
398 }
399 }
400 } else break;
401
402 if ( epMouseDown && (i & 32) )
403 if ( RealTime() - dt > TooLong1 )
404 {
405 epMouseDownTakesTooLong++;
406 gra_end_lines();
407 glMatrixMode(GL_PROJECTION);
408 glPopMatrix();
409 glMatrixMode( GL_MODELVIEW );
410 return FALSE;
411 }
412
413 if ( BreakLoop ) break;
414 }
415 gra_end_lines();
416 }
417 glMatrixMode(GL_PROJECTION);
418 glPopMatrix();
419 glMatrixMode( GL_MODELVIEW );
420 }
421
422 return TRUE;
423 }
424
425 /*******************************************************************************
426 *
427 * Name: vis_mesh_alloc
428 *
429 * Purpose: allocate memory for mesh_t structure
430 *
431 * Parameters:
432 *
433 * Input: none
434 *
435 * Output: none
436 *
437 * Return value: pointer to allocated memory
438 *
439 ******************************************************************************/
vis_mesh_alloc()440 static mesh_t *vis_mesh_alloc()
441 {
442 mesh_t *mesh = (mesh_t *)calloc(sizeof(mesh_t),1);
443
444 if ( !mesh )
445 {
446 fprintf( stderr, "vis_mesh_alloc: FATAL: can't alloc a few bytes of memory\n" );
447 }
448
449 return mesh;
450 }
451
452 /*******************************************************************************
453 *
454 * Name: vis_mesh_delete
455 *
456 * Purpose: free memory associated with mesh_t structure
457 *
458 * Parameters:
459 *
460 * Input: (mesh_t *) pointer to structure
461 *
462 * Output: none
463 *
464 * Return value: void
465 *
466 ******************************************************************************/
vis_mesh_delete(mesh_t * mesh)467 static void vis_mesh_delete(mesh_t *mesh)
468 {
469 if ( mesh ) free( mesh );
470 }
471
472 /*******************************************************************************
473 *
474 * Name: vis_initialize_mesh_visual
475 *
476 * Purpose: Register "Mesh" visual type
477 *
478 * Parameters:
479 *
480 * Input: none
481 *
482 * Output: none
483 *
484 * Return value: vis_add_visual_type (malloc success probably)...
485 *
486 ******************************************************************************/
vis_initialize_mesh_visual()487 int vis_initialize_mesh_visual()
488 {
489 static char *visual_name = "Mesh";
490 visual_type_t VisualDef;
491
492 static mesh_t mesh;
493
494 static visual_param_t MeshParams[] =
495 {
496 { "ColorData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
497 { "Style", "%d", 0, VIS_VISUAL_PARAM_INT, mesh_style_line, 0.0, NULL },
498 { "EdgeStyle", "%d", 0, VIS_VISUAL_PARAM_INT, edge_style_all, 0.0, NULL },
499 { "Material", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultMaterial },
500 { "EdgeMaterial", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultEdgeMaterial },
501 { "ColorMap", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultColorMap },
502 { "LineWidth", "%lf", 0, VIS_VISUAL_PARAM_FLOAT, 0, 1.0, NULL },
503 { "LineQuality", "%d", 0, VIS_VISUAL_PARAM_INT, 1, 0.0, NULL },
504 { "LineStyle", "%d", 0, VIS_VISUAL_PARAM_INT, 0, 0.0, NULL },
505 { "NodeNumbers", "%d", 0, VIS_VISUAL_PARAM_LOGICAL, 0, 0.0, NULL },
506 { NULL, NULL, 0, 0, 0, 0.0, NULL }
507 };
508
509 int n = 0;
510
511 MeshParams[n++].Offset = (char *)&mesh.ColorData - (char *)&mesh;
512 MeshParams[n++].Offset = (char *)&mesh.Style - (char *)&mesh;
513 MeshParams[n++].Offset = (char *)&mesh.EdgeStyle - (char *)&mesh;
514 MeshParams[n++].Offset = (char *)&mesh.Material - (char *)&mesh;
515 MeshParams[n++].Offset = (char *)&mesh.EdgeMaterial - (char *)&mesh;
516 MeshParams[n++].Offset = (char *)&mesh.ColorMap - (char *)&mesh;
517 MeshParams[n++].Offset = (char *)&mesh.LineWidth - (char *)&mesh;
518 MeshParams[n++].Offset = (char *)&mesh.LineQuality - (char *)&mesh;
519 MeshParams[n++].Offset = (char *)&mesh.LineStyle - (char *)&mesh;
520 MeshParams[n++].Offset = (char *)&mesh.NodeNumbers - (char *)&mesh;
521
522 VisualDef.VisualName = visual_name;
523
524 VisualDef.RealizeVisual = (int (*)()) vis_mesh;
525 VisualDef.AllocParams = (void *(*)()) vis_mesh_alloc;
526 VisualDef.DeleteParams = (void (*)()) vis_mesh_delete;
527 VisualDef.VisualParams = MeshParams;
528
529 return vis_add_visual_type( &VisualDef );
530 }
531