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