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 classe ContourLines.
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_contour_lines_visual to set the
45  *              VisualName field of the visual_type structure
46  *
47  * Juha R.
48  *
49  ******************************************************************************/
50 
51 #include "../elmerpost.h"
52 
53 /******************************************************************************
54  *
55  * Parameter sructure definitios for Contour Lines visual class
56  *
57  ******************************************************************************/
58 
59 typedef struct contour_lines_s
60 {
61     scalar_t *ContourData;
62     scalar_t *ColorData;
63 
64     int NofLevels;
65     double *Levels;
66 
67     material_t *Material;
68     colormap_t *ColorMap;
69 
70     int LineQuality;
71     double LineWidth;
72 
73     line_style_t LineStyle;
74 } contour_lines_t;
75 
76 /*******************************************************************************
77  *
78  *     Name:        vis_get_isolines
79  *
80  *     Purpose:     Extract isolines with given threshold
81  *
82  *     Parameters:
83  *
84  *         Input:   (triangle_t *)
85  *                  (vertex_t   *)
86  *                  (double *,double,double)  color quantity, and scales => 0,1
87  *                  (double *)             surface quantity
88  *                  (double)               threshold value
89  *
90  *         Output:  (line_t *)             place to store the line
91  *
92  *   Return value:  number of points generated, line exists if (n>=2)
93  *
94  ******************************************************************************/
vis_get_isolines(element_model_t * model,element_t * element,vertex_t * vertices,line_t * Lines,double * C,double * F,int nlevels,double * levels,double CScl,double CAdd)95 static int vis_get_isolines
96    (
97     element_model_t *model, element_t *element, vertex_t *vertices, line_t *Lines,
98       double *C, double *F, int nlevels, double *levels,double CScl,double CAdd
99    )
100 {
101     static double x[ELM_MAX_ELEMENT_NODES];
102     static double y[ELM_MAX_ELEMENT_NODES];
103     static double z[ELM_MAX_ELEMENT_NODES];
104     static double f[ELM_MAX_ELEMENT_NODES];
105     static double c[ELM_MAX_ELEMENT_NODES];
106 
107     int i,j,n,*T=element->Topology;
108     element_type_t *elmt = element->ElementType;
109 
110     if ( elmt->IsoLine )
111     {
112         for( i=0; i<elmt->NumberOfNodes; i++ )
113         {
114             x[i] = vertices[T[i]].x[0];
115             y[i] = vertices[T[i]].x[1];
116             z[i] = vertices[T[i]].x[2];
117 
118             f[i] = F[T[i]];
119 
120             if ( C )
121                 c[i] = CScl*(C[T[i]]-CAdd);
122              else
123                 c[i] = 0.0;
124         }
125 
126         n = 0;
127         for( i=0; i<nlevels; i++ )
128         {
129             n += (*elmt->IsoLine)( levels[i],f,c,x,y,z,&Lines[n] );
130         }
131 
132         return n;
133     }
134 
135     return 0;
136 }
137 
138 
139 /*******************************************************************************
140  *
141  *     Name:        vis_draw_line
142  *
143  *     Purpose:     Draw  a line
144  *
145  *     Parameters:
146  *
147  *         Input:   (line_t *)
148  *                  (int )     line/solid
149  *                  (double)    width of line
150  *
151  *         Output:  graphics
152  *
153  *   Return value:   void
154  *
155  ******************************************************************************/
vis_draw_line(line_t * line,int quick,double width)156 static void vis_draw_line( line_t *line, int quick, double width )
157 {
158     float x[2][3],c0,c1;
159 
160     x[0][0] = line->x[0];
161     x[0][1] = line->y[0];
162     x[0][2] = line->z[0];
163 
164     x[1][0] = line->x[1];
165     x[1][1] = line->y[1];
166     x[1][2] = line->z[1];
167 
168     c0 = line->c[0];
169     c1 = line->c[1];
170 
171     if ( quick )
172     {
173         gra_line( x[0],c0,x[1],c1,line_style_line,width );
174     } else
175     {
176         gra_line( x[0],c0,x[1],c1,line_style_cylinder,width );
177         gra_sphere( x[0][0],x[0][1],x[0][2],c0, width );
178         gra_sphere( x[1][0],x[1][1],x[1][2],c1, width );
179     }
180 }
181 
182 /*******************************************************************************
183  *
184  *     Name:        vis_contour_lines
185  *
186  *     Purpose:     Draw contour lines given data, and threshold values
187  *
188  *     Parameters:
189  *
190  *         Input:   (geometry_t *)
191  *                  (contour_lines_t *) contour line display params
192  *                  (double)            time used
193  *
194  *         Output:  graphics
195  *
196  *   Return value:  if mouse interaction is going on, and time used exeeds
197  *                  given value (TooLong1,2) FALSE, otherwise TRUE
198  *
199  ******************************************************************************/
vis_contour_lines(geometry_t * geometry,element_model_t * model,contour_lines_t * ContourLines,double dt)200 static int vis_contour_lines( geometry_t *geometry, element_model_t *model, contour_lines_t *ContourLines,double dt )
201 {
202     double CScl,CAdd,*Levels=ContourLines->Levels;
203     double *C=NULL, *F=NULL;
204 
205     scalar_t *ColorData   = ContourLines->ColorData;
206     scalar_t *ContourData = ContourLines->ContourData;
207 
208     int i,j,n,quick;
209 
210     double width = ContourLines->LineWidth*0.005;
211 
212     static line_t Lines[1000];
213 
214     element_t *elements = model->Elements;
215 
216     if ( !ContourData || !ContourData->f ) return TRUE;
217 
218     if ( !GlobalOptions.StereoMode )
219       if ( ContourLines->Material->Diffuse[3]  < 1.0 )
220       {
221           if ( GlobalPass != 0 ) return TRUE;
222       } else if ( GlobalPass == 0 )
223       {
224           return TRUE;
225       }
226 
227     F = ContourData->f;
228 
229     if ( ColorData && ColorData->f )
230     {
231         CAdd = ColorData->min;
232         CScl = 1.0/(ColorData->max - ColorData->min);
233 
234         C = ColorData->f;
235 
236         gra_set_colormap( ContourLines->ColorMap );
237     } else gra_set_colormap( NULL );
238 
239     quick  = ContourLines->LineStyle == line_style_line;
240     quick |= epMouseDown && epMouseDownTakesTooLong;
241 
242     if ( !quick && (ContourLines->LineStyle == line_style_cylinder) )
243     {
244         gra_sphere_quality( ContourLines->LineQuality );
245     }
246 
247     if ( quick && !(epMouseDown && epMouseDownTakesTooLong) )
248     {
249         gra_line_width( ContourLines->LineWidth );
250     } else {
251         gra_line_width( 1.0 );
252     }
253 
254     gra_set_material( ContourLines->Material );
255 
256     if ( quick ) gra_beg_lines();
257 
258     for( i=0; i<model->NofElements; i++ )
259     {
260 
261         if ( !elements[i].DisplayFlag ) continue;
262 
263         n = vis_get_isolines
264          (
265            model,&elements[i],geometry->Vertices,Lines,C,F,ContourLines->NofLevels,Levels,CScl,CAdd
266          );
267         for( j=0; j<n; j++ ) vis_draw_line( &Lines[j], quick, width );
268 
269         if ( epMouseDown )
270         {
271             if ( quick )
272             {
273                 if ( (i & 32) && (RealTime() - dt > TooLong2) )
274                     if ( ++epMouseDownTakesTooLong > 3 )
275                     {
276                         gra_end_lines();
277                         return FALSE;
278                     } else dt = RealTime();
279             } else
280             {
281                 if ( RealTime() - dt > TooLong1 )
282                 {
283                     epMouseDownTakesTooLong++;
284                     return FALSE;
285                 }
286             }
287         }
288 
289         if ( BreakLoop ) break;
290     }
291 
292     if ( quick ) gra_end_lines();
293 
294     return TRUE;
295 }
296 
297 
298 /*******************************************************************************
299  *
300  *     Name:        vis_contour_lines_alloc
301  *
302  *     Purpose:     allocate memory for contour_lines_t structure
303  *
304  *     Parameters:
305  *
306  *         Input:   none
307  *
308  *         Output:  none
309  *
310  *   Return value:  pointer to allocated memory
311  *
312  ******************************************************************************/
vis_contour_lines_alloc()313 static contour_lines_t *vis_contour_lines_alloc()
314 {
315      contour_lines_t *contour_line = (contour_lines_t *)calloc(sizeof(contour_lines_t),1);
316 
317      if ( !contour_line )
318      {
319          fprintf( stderr, "vis_contour_lines_alloc: FATAL: can't alloc a few bytes of memory\n" );
320      }
321 
322      return contour_line;
323 }
324 
325 /*******************************************************************************
326  *
327  *     Name:        vis_contour_lines_delete
328  *
329  *     Purpose:     free memory associated with contour_lines_t structure
330  *
331  *     Parameters:
332  *
333  *         Input:   (contour_lines_t *) pointer to structure
334  *
335  *         Output:  none
336  *
337  *   Return value:  void
338  *
339  ******************************************************************************/
vis_contour_lines_delete(contour_lines_t * contour_line)340 static void vis_contour_lines_delete(contour_lines_t *contour_line)
341 {
342     if ( contour_line ) free( contour_line );
343 }
344 
345 /*******************************************************************************
346  *
347  *     Name:        vis_initialize_contour_lines_visual
348  *
349  *     Purpose:     Register "Contour Line" visual type
350  *
351  *     Parameters:
352  *
353  *         Input:   none
354  *
355  *         Output:  none
356  *
357  *   Return value:  vis_add_visual_type (malloc success probably)...
358  *
359  ******************************************************************************/
vis_initialize_contour_line_visual()360 int vis_initialize_contour_line_visual()
361 {
362     static char *visual_name = "Contour Lines";
363     visual_type_t VisualDef;
364 
365     static contour_lines_t contours;
366 
367     static visual_param_t ContourLineParams[] =
368     {
369         { "ContourData",   "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
370         { "ColorData",     "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
371         { "NofLevels","%d", 0, VIS_VISUAL_PARAM_INT,     0, 0.0, NULL },
372         { "Levels",        "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
373         { "Material",      "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultMaterial },
374         { "ColorMap",      "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultColorMap },
375         { "LineWidth",     "%lf", 0, VIS_VISUAL_PARAM_FLOAT,   0, 1.0, NULL },
376         { "LineQuality",   "%d", 0, VIS_VISUAL_PARAM_INT,     1, 0.0, NULL },
377         { "LineStyle",     "%d", 0, VIS_VISUAL_PARAM_INT,line_style_line, 0.0, NULL },
378         { NULL, NULL, 0, 0, 0, 0.0, NULL }
379     };
380 
381     int n = 0;
382 
383     ContourLineParams[n++].Offset = (char *)&contours.ContourData    - (char *)&contours;
384     ContourLineParams[n++].Offset = (char *)&contours.ColorData      - (char *)&contours;
385     ContourLineParams[n++].Offset = (char *)&contours.NofLevels      - (char *)&contours;
386     ContourLineParams[n++].Offset = (char *)&contours.Levels         - (char *)&contours;
387     ContourLineParams[n++].Offset = (char *)&contours.Material       - (char *)&contours;
388     ContourLineParams[n++].Offset = (char *)&contours.ColorMap       - (char *)&contours;
389     ContourLineParams[n++].Offset = (char *)&contours.LineWidth      - (char *)&contours;
390     ContourLineParams[n++].Offset = (char *)&contours.LineQuality    - (char *)&contours;
391     ContourLineParams[n++].Offset = (char *)&contours.LineStyle      - (char *)&contours;
392 
393     VisualDef.VisualName    = visual_name;
394 
395     VisualDef.RealizeVisual = (int   (*)()) vis_contour_lines;
396     VisualDef.AllocParams   = (void *(*)()) vis_contour_lines_alloc;
397     VisualDef.DeleteParams  = (void  (*)()) vis_contour_lines_delete;
398     VisualDef.VisualParams  = ContourLineParams;
399 
400     return vis_add_visual_type( &VisualDef );
401 }
402