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 arrow 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  *
43  * Modification history:
44  *
45  * 28 Sep 1995, modified vis_initialize_arrow_visual to set the VisualName field
46  *              of the visual_type structure
47  *
48  * Juha R.
49  *
50  ******************************************************************************/
51 
52 #include "../elmerpost.h"
53 
54 
55 /******************************************************************************
56  *
57  * Parameter sructure definitios for arrow visual class
58  *
59  ******************************************************************************/
60 typedef struct arrow_s
61 {
62     scalar_t *VectorData[4];           /* arrow direction quantity */
63     scalar_t *ColorData;               /* arrow coloring quantity */
64     scalar_t *LengthData;              /* arrow length quantity */
65     scalar_t *ThresholdData;           /* arrow thresholding quantity */
66 
67     arrow_style_t Style;               /* arrow style, stick or arrow */
68 
69     double Floor,Ceiling;               /* threshold min & max */
70 
71     double RadiusScale,LengthScale;
72     logical_t EqualLength,EqualRadius;
73 
74     material_t *Material;
75     colormap_t *ColorMap;
76 
77     int LineQuality;
78     line_style_t LineStyle;
79 } arrow_t;
80 
81 
82 /*******************************************************************************
83  *
84  *     Name:        vis_arrow
85  *
86  *     Purpose:     draw arrows given vector field
87  *
88  *     Parameters:
89  *
90  *         Input:   (geometry_t *) geometry description
91  *                  (arrow_t    *) arrow display parameters
92  *                  (double)       real time for interaction
93  *
94  *         Output:  graphics
95  *
96  *   Return value:  if mouse interaction is going on, and time used exeeds
97  *                  given value (TooLong1,2) FALSE, otherwise TRUE
98  *
99  ******************************************************************************/
vis_arrow(geometry_t * geometry,element_model_t * model,arrow_t * Arrows,double dt)100 static int vis_arrow( geometry_t *geometry, element_model_t *model, arrow_t *Arrows,double dt )
101 {
102     line_style_t line_style   = Arrows->LineStyle;
103     arrow_style_t arrow_style = Arrows->Style;
104 
105     vertex_t *v = geometry->Vertices;
106 
107     int i,N=geometry->VertexCount,quick;
108 
109     float x[3];
110 
111     vertex_face_t *face;
112 
113     element_t *elements = model->Elements;
114 
115     double LScl,CScl,CAdd,vx,vy,vz,co;
116     double R,RadiusScale,L,LengthScale;
117 
118     if ( !Arrows->VectorData ||
119          !Arrows->VectorData[1]->f || !Arrows->VectorData[2]->f || !Arrows->VectorData[3]->f
120         )
121     {
122 /*
123         fprintf( stderr, "vis_arrows: no arrow data\n" );
124 */
125         return TRUE;
126     }
127 
128     if ( !GlobalOptions.StereoMode )
129       if ( Arrows->Material->Diffuse[3]  < 1.0 )
130       {
131           if ( GlobalPass != 0 ) return TRUE;
132       } else if ( GlobalPass == 0 )
133       {
134           return TRUE;
135       }
136 
137     LengthScale = Arrows->LengthScale / 10.0;
138     RadiusScale = Arrows->RadiusScale / 10.0;
139 
140     if ( Arrows->LengthData && Arrows->LengthData->f )
141     {
142         LScl = 0.05;
143         if ( ABS( Arrows->LengthData->max - Arrows->LengthData->min ) > 1.0E-10 )
144             LScl =  1.0 / (Arrows->LengthData->max - Arrows->LengthData->min);
145     }
146 
147     if ( Arrows->ColorData && Arrows->ColorData->f )
148     {
149         CAdd = Arrows->ColorData->min;
150         CScl = 1.0 / ( Arrows->ColorData->max - Arrows->ColorData->min );
151         gra_set_colormap( Arrows->ColorMap );
152     } else gra_set_colormap( NULL );
153 
154     quick = epMouseDown && epMouseDownTakesTooLong;
155 
156     if ( quick )
157     {
158       line_style  = line_style_line;
159       arrow_style = arrow_style_stick;
160       gra_line_width( 1.0 );
161     } else
162     {
163       if ( line_style == line_style_cylinder )
164         gra_sphere_quality( Arrows->LineQuality );
165       else
166         gra_line_width( Arrows->RadiusScale );
167     }
168 
169     gra_set_material( Arrows->Material );
170 
171     for( i=0; i<N; i++,v++ )
172     {
173         if ( !v->ElementModelNode ) continue;
174 
175          for( face=v->Faces; face!=NULL; face=face->Next )
176          {
177            if ( geometry->Triangles[face->Face].Element->DisplayFlag ) break;
178          }
179 #if 1
180          if ( v->Faces && !face ) continue;
181 #else
182          if ( !face ) continue;
183 #endif
184         if ( Arrows->ThresholdData && Arrows->ThresholdData->f )
185         {
186             if ( Arrows->ThresholdData->f[i] < Arrows->Floor ||
187                  Arrows->ThresholdData->f[i] > Arrows->Ceiling ) continue;
188         }
189 
190         vx = Arrows->VectorData[1]->f[i];
191         vy = Arrows->VectorData[2]->f[i];
192         vz = Arrows->VectorData[3]->f[i];
193 
194         L  = sqrt( vx*vx + vy*vy + vz*vz );
195         if ( L < 1.0E-10 ) continue;
196 
197         L = LengthScale / L;
198         R = LengthScale * RadiusScale;
199 
200         if ( Arrows->ColorData && Arrows->ColorData->f )
201         {
202             co = CScl*(Arrows->ColorData->f[i]-CAdd);
203         }
204 
205         x[0] = L*vx;
206         x[1] = L*vy;
207         x[2] = L*vz;
208 
209         if ( !Arrows->EqualLength && Arrows->LengthData && Arrows->LengthData->f )
210         {
211             x[0] *= LScl*Arrows->LengthData->f[i];
212             x[1] *= LScl*Arrows->LengthData->f[i];
213             x[2] *= LScl*Arrows->LengthData->f[i];
214 
215             if ( !Arrows->EqualRadius )
216             {
217                 R *= LScl*Arrows->LengthData->f[i];
218             }
219         }
220 
221         gra_arrow( v->x,x,co,line_style,arrow_style,R );
222 
223         if ( epMouseDown && (i & 8) )
224         {
225             if ( !epMouseDownTakesTooLong )
226             {
227                 if ( RealTime() - dt > TooLong1 )
228                 {
229                     ++epMouseDownTakesTooLong;
230                     return FALSE;
231                 }
232             }
233             else if ( RealTime() - dt > TooLong2 )
234                 if ( ++epMouseDownTakesTooLong > 3 )
235                 {
236                     return FALSE;
237                 } else dt = RealTime();
238         }
239 
240         if ( BreakLoop ) break;
241     }
242 
243     return TRUE;
244 }
245 
246 /*******************************************************************************
247  *
248  *     Name:        vis_arrow_alloc
249  *
250  *     Purpose:     allocate memory for arrow_t structure
251  *
252  *     Parameters:
253  *
254  *         Input:   none
255  *
256  *         Output:  none
257  *
258  *   Return value:  pointer to allocated memory
259  *
260  ******************************************************************************/
vis_arrow_alloc()261 static arrow_t *vis_arrow_alloc()
262 {
263      arrow_t *arrow = (arrow_t *)calloc(sizeof(arrow_t),1);
264 
265      if ( !arrow )
266      {
267          fprintf( stderr, "vis_arrow_alloc: FATAL: can't alloc a few bytes of memory\n" );
268      }
269 
270      return arrow;
271 }
272 
273 /*******************************************************************************
274  *
275  *     Name:        vis_arrow_delete
276  *
277  *     Purpose:     free memory associated with arrow_t structure
278  *
279  *     Parameters:
280  *
281  *         Input:   (arrow_t *) pointer to structure
282  *
283  *         Output:  none
284  *
285  *   Return value:  void
286  *
287  ******************************************************************************/
vis_arrow_delete(arrow_t * arrow)288 static void vis_arrow_delete(arrow_t *arrow)
289 {
290     if ( arrow ) free( arrow );
291 }
292 
293 /*******************************************************************************
294  *
295  *     Name:        vis_initialize_arrow_visual
296  *
297  *     Purpose:     Register arrow visual type
298  *
299  *     Parameters:
300  *
301  *         Input:   none
302  *
303  *         Output:  none
304  *
305  *   Return value:  vis_add_visual_type (malloc success probably)...
306  *
307  ******************************************************************************/
vis_initialize_arrow_visual()308 int vis_initialize_arrow_visual()
309 {
310     static char *visual_name = "Arrows";
311 
312     visual_type_t VisualDef;
313 
314     static arrow_t arrow;
315 
316     static visual_param_t ArrowParams[] =
317     {
318         { "VectorData0",   "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
319         { "VectorData1",   "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
320         { "VectorData2",   "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
321         { "VectorData3",   "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
322         { "ColorData",     "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
323         { "LengthData",    "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
324         { "ThresholdData", "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
325         { "Style",         "%d",  0, VIS_VISUAL_PARAM_INT,     arrow_style_arrow, 0.0, NULL },
326         { "Floor",         "%lf", 0, VIS_VISUAL_PARAM_FLOAT,   0, 0.0, NULL },
327         { "Ceiling",       "%lf", 0, VIS_VISUAL_PARAM_FLOAT,   0, 1.0, NULL },
328         { "RadiusScale",   "%lf", 0, VIS_VISUAL_PARAM_FLOAT,   0, 1.0, NULL },
329         { "LengthScale",   "%lf", 0, VIS_VISUAL_PARAM_FLOAT,   0, 1.0, NULL },
330         { "EqualLength",   "%c",  0, VIS_VISUAL_PARAM_LOGICAL, 1, 0.0, NULL },
331         { "EqualRadius",   "%c",  0, VIS_VISUAL_PARAM_LOGICAL, 0, 0.0, NULL },
332         { "Material",      "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultMaterial },
333         { "ColorMap",      "%s",  0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultColorMap },
334         { "LineQuality",   "%d",  0, VIS_VISUAL_PARAM_INT,     1, 0.0, NULL },
335         { "LineStyle",     "%d",  0, VIS_VISUAL_PARAM_INT,     line_style_line, 0.0, NULL },
336         { NULL, NULL, 0, 0, 0,0.0, NULL }
337     };
338 
339     int n = 0;
340 
341     ArrowParams[n++].Offset = (char *)&arrow.VectorData[0] - (char *)&arrow;
342     ArrowParams[n++].Offset = (char *)&arrow.VectorData[1] - (char *)&arrow;
343     ArrowParams[n++].Offset = (char *)&arrow.VectorData[2] - (char *)&arrow;
344     ArrowParams[n++].Offset = (char *)&arrow.VectorData[3] - (char *)&arrow;
345     ArrowParams[n++].Offset = (char *)&arrow.ColorData     - (char *)&arrow;
346     ArrowParams[n++].Offset = (char *)&arrow.LengthData    - (char *)&arrow;
347     ArrowParams[n++].Offset = (char *)&arrow.ThresholdData - (char *)&arrow;
348     ArrowParams[n++].Offset = (char *)&arrow.Style         - (char *)&arrow;
349     ArrowParams[n++].Offset = (char *)&arrow.Floor         - (char *)&arrow;
350     ArrowParams[n++].Offset = (char *)&arrow.Ceiling       - (char *)&arrow;
351     ArrowParams[n++].Offset = (char *)&arrow.RadiusScale   - (char *)&arrow;
352     ArrowParams[n++].Offset = (char *)&arrow.LengthScale   - (char *)&arrow;
353     ArrowParams[n++].Offset = (char *)&arrow.EqualLength   - (char *)&arrow;
354     ArrowParams[n++].Offset = (char *)&arrow.EqualRadius   - (char *)&arrow;
355     ArrowParams[n++].Offset = (char *)&arrow.Material      - (char *)&arrow;
356     ArrowParams[n++].Offset = (char *)&arrow.ColorMap      - (char *)&arrow;
357     ArrowParams[n++].Offset = (char *)&arrow.LineQuality   - (char *)&arrow;
358     ArrowParams[n++].Offset = (char *)&arrow.LineStyle     - (char *)&arrow;
359 
360     VisualDef.VisualName    = visual_name;
361     VisualDef.RealizeVisual = (int   (*)()) vis_arrow;
362     VisualDef.AllocParams   = (void *(*)()) vis_arrow_alloc;
363     VisualDef.DeleteParams  = (void  (*)()) vis_arrow_delete;
364     VisualDef.VisualParams  = ArrowParams;
365 
366     return vis_add_visual_type( &VisualDef );
367 }
368