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 library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library 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 GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library (in file ../LGPL-2.1); if not, write
19  * to the Free Software Foundation, Inc., 51 Franklin Street,
20  * Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  *     MATC graphics main module.
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: 30 May 1996
40  *
41  *                Modified by:
42  *
43  *       Date of modification:
44  *
45  ******************************************************************************/
46 
47 /*
48  * $Id: gra.c,v 1.1.1.1 2005/04/14 13:29:14 vierinen Exp $
49  *
50  * $Log: gra.c,v $
51  * Revision 1.1.1.1  2005/04/14 13:29:14  vierinen
52  * initial matc automake package
53  *
54  * Revision 1.2  1998/08/01 12:34:40  jpr
55  *
56  * Added Id, started Log.
57  *
58  *
59  */
60 
61 #include "elmer/matc.h"
62 
63 static double gra_vsx, gra_vsy,
64              gra_vtx, gra_vty;
65 #pragma omp threadprivate (gra_vsx, gra_vsy, gra_vtx, gra_vty)
66 
67 void gra_mult(GMATRIX gm1, GMATRIX gm2);
68 void gra_ident(GMATRIX gm);
69 
gra_init_matc(devtype,name)70 void gra_init_matc(devtype, name) int devtype; char *name;
71 {
72   if ( gra_state.driver != 0 )
73   {
74     GRA_CLOSE();
75   }
76 
77   if (name != NULL)
78   {
79     if ((gra_state.out_fp = fopen(name, "w")) == NULL)
80     {
81       error("gra: open: Can't open named output stream\n");
82     }
83   }
84 
85   gra_funcs[G_VIEWPORT]    = gra_set_viewport;
86   gra_funcs[G_WINDOW]      = gra_set_window;
87   gra_funcs[G_PERSPECTIVE] = gra_perspective;
88 
89   gra_funcs[G_TRANSLATE]  = gra_translate;
90   gra_funcs[G_ROTATE]     = gra_rotate;
91   gra_funcs[G_SCALE]      = gra_scale;
92   gra_funcs[G_VIEWPOINT]  = gra_viewpoint;
93   gra_funcs[G_GETMATRIX]  = gra_getmatrix;
94   gra_funcs[G_SETMATRIX]  = gra_setmatrix;
95 
96   gra_funcs[G_DBUFFER]    = gra_dbuffer_null;
97   gra_funcs[G_SBUFFER]    = gra_dbuffer_null;
98   gra_funcs[G_SWAPBUF]    = gra_dbuffer_null;
99 
100   switch(devtype)
101   {
102 #ifdef GRA_DRV_IRIS
103     case 1: case 2:
104       gra_funcs[G_OPEN]        = gra_iris_open;
105       gra_funcs[G_CLOSE]       = gra_iris_close;
106       gra_funcs[G_CLEAR]       = gra_iris_clear;
107       gra_funcs[G_VIEWPORT]    = gra_iris_viewport;
108       gra_funcs[G_WINDOW]      = gra_iris_window;
109       gra_funcs[G_PERSPECTIVE] = gra_iris_perspective;
110       gra_funcs[G_TRANSLATE]   = gra_iris_translate;
111       gra_funcs[G_ROTATE]      = gra_iris_rotate;
112       gra_funcs[G_SCALE]       = gra_iris_scale;
113       gra_funcs[G_VIEWPOINT]   = gra_iris_viewpoint;
114       gra_funcs[G_DEFCOLOR]    = gra_iris_defcolor;
115       gra_funcs[G_COLOR]       = gra_iris_color;
116       gra_funcs[G_POLYLINE]    = gra_iris_polyline;
117       gra_funcs[G_DRAW]        = gra_iris_draw;
118       gra_funcs[G_MOVE]        = gra_iris_move;
119       gra_funcs[G_POLYMARKER]  = gra_iris_polymarker;
120       gra_funcs[G_MARKER]      = gra_iris_marker;
121       gra_funcs[G_AREAFILL]    = gra_iris_areafill;
122       gra_funcs[G_IMAGE]       = gra_iris_image;
123       gra_funcs[G_TEXT]        = gra_iris_text;
124       gra_funcs[G_SETMATRIX]   = gra_iris_setmatrix;
125       gra_funcs[G_FLUSH]       = gra_iris_flush;
126       gra_funcs[G_RESET]       = gra_iris_reset;
127       gra_funcs[G_DBUFFER]     = gra_iris_dbuffer;
128       gra_funcs[G_SBUFFER]     = gra_iris_sbuffer;
129       gra_funcs[G_SWAPBUF]     = gra_iris_swapbuf;
130       gra_state.driver = GRA_DRV_IRIS;
131     break;
132 #endif
133 
134 #ifdef GRA_DRV_TEKLIB
135     case 4105: case 4107: case 4111: case 4128: case 4129:
136       gra_funcs[G_OPEN]       = gra_teklib_open;
137       gra_funcs[G_CLOSE]      = gra_teklib_close;
138       gra_funcs[G_CLEAR]      = gra_teklib_clear;
139       gra_funcs[G_DEFCOLOR]   = gra_teklib_defcolor;
140       gra_funcs[G_COLOR]      = gra_teklib_color;
141       gra_funcs[G_POLYLINE]   = gra_teklib_polyline;
142       gra_funcs[G_DRAW]       = gra_teklib_draw;
143       gra_funcs[G_MOVE]       = gra_teklib_move;
144       gra_funcs[G_POLYMARKER] = gra_teklib_polymarker;
145       gra_funcs[G_MARKER]     = gra_teklib_marker;
146       gra_funcs[G_AREAFILL]   = gra_teklib_areafill;
147       gra_funcs[G_IMAGE]      = gra_teklib_image;
148       gra_funcs[G_TEXT]       = gra_teklib_text;
149       gra_funcs[G_FLUSH]      = gra_teklib_flush;
150       gra_funcs[G_RESET]      = gra_teklib_reset;
151       gra_state.driver = GRA_DRV_TEKLIB;
152     break;
153 #endif
154 
155 #ifdef GRA_DRV_PS
156     case 4:
157       gra_funcs[G_OPEN]       = gra_ps_open;
158       gra_funcs[G_CLOSE]      = gra_ps_close;
159       gra_funcs[G_CLEAR]      = gra_ps_clear;
160       gra_funcs[G_DEFCOLOR]   = gra_ps_defcolor;
161       gra_funcs[G_COLOR]      = gra_ps_color;
162       gra_funcs[G_POLYLINE]   = gra_ps_polyline;
163       gra_funcs[G_DRAW]       = gra_ps_draw;
164       gra_funcs[G_MOVE]       = gra_ps_move;
165       gra_funcs[G_POLYMARKER] = gra_ps_polymarker;
166       gra_funcs[G_MARKER]     = gra_ps_marker;
167       gra_funcs[G_AREAFILL]   = gra_ps_areafill;
168       gra_funcs[G_IMAGE]      = gra_ps_image;
169       gra_funcs[G_TEXT]       = gra_ps_text;
170       gra_funcs[G_FLUSH]      = gra_ps_flush;
171       gra_funcs[G_RESET]      = gra_ps_reset;
172       gra_state.driver = GRA_DRV_PS;
173     break;
174 #endif
175     default:
176       error("gra: Unknown device selection\n");
177     break;
178   }
179 
180   GRA_OPEN(devtype);
181 
182   gra_ident(gra_state.modelm);
183   gra_ident(gra_state.viewm);
184   gra_ident(gra_state.projm);
185   gra_ident(gra_state.transfm);
186 
187   GRA_WINDOW(-1.0,1.0,-1.0,1.0,-1.0,1.0);
188   GRA_VIEWPORT(0.0,1.0,0.0,1.0);
189   gra_state.pratio = 0.0;
190 }
191 
gra_close_sys()192 void gra_close_sys()
193 {
194   int i;
195 
196   if (gra_state.out_fp != NULL)
197   {
198     fclose(gra_state.out_fp);
199     gra_state.out_fp = NULL;
200   }
201 
202   for(i = 0; i < GRA_FUNCS; i++)
203   {
204     gra_funcs[i] = gra_error;
205   }
206 
207   gra_state.driver = 0;
208 }
209 
gra_dbuffer_null()210 void gra_dbuffer_null() {};
211 
gra_getmatrix(gm)212 void gra_getmatrix(gm) GMATRIX gm;
213 {
214   memcpy((char *)gm, (char *)gra_state.transfm,sizeof(GMATRIX));
215 }
216 
gra_setmatrix(gm)217 void gra_setmatrix(gm) GMATRIX gm;
218 {
219   memcpy((char *)gra_state.transfm,(char *)gm,sizeof(GMATRIX));
220   gra_ident(gra_state.modelm);
221   gra_ident(gra_state.projm);
222   gra_ident(gra_state.viewm);
223 }
224 
gra_set_transfm()225 void gra_set_transfm()
226 {
227   int i,j;
228 
229   for(i = 0; i < 4; i++)
230     for(j = 0; j < 4; j++)
231     {
232       gra_state.transfm[i][j] = gra_state.modelm[i][j];
233     }
234 
235   gra_mult(gra_state.transfm,gra_state.viewm);
236   gra_mult(gra_state.transfm,gra_state.projm);
237 }
238 
gra_mult(gm1,gm2)239 void gra_mult(gm1, gm2) GMATRIX gm1, gm2;
240 {
241   int i,j,k;
242   double s[4];
243 
244   for(i = 0; i < 4; i++)
245   {
246     for(j = 0; j < 4; j++)
247     {
248       s[j] = 0.0;
249       for(k = 0; k < 4; k++)
250       {
251         s[j] += gm1[i][k] * gm2[k][j];
252       }
253     }
254     for(j = 0; j < 4; j++)
255       gm1[i][j] = s[j];
256   }
257 }
258 
gra_ident(gm)259 void gra_ident(gm) GMATRIX gm;
260 {
261   gm[0][0] = 1; gm[0][1] = 0; gm[0][2] = 0; gm[0][3] = 0;
262   gm[1][0] = 0; gm[1][1] = 1; gm[1][2] = 0; gm[1][3] = 0;
263   gm[2][0] = 0; gm[2][1] = 0; gm[2][2] = 1; gm[2][3] = 0;
264   gm[3][0] = 0; gm[3][1] = 0; gm[3][2] = 0; gm[3][3] = 1;
265 }
266 
gra_viewpoint(xf,yf,zf,xt,yt,zt)267 void gra_viewpoint(xf,yf,zf,xt,yt,zt) double xf,yf,zf,xt,yt,zt;
268 {
269   GMATRIX gvm;
270 
271   double r1,r2;
272 
273   /*
274    * translate(-vpf);
275    */
276   gra_ident(gra_state.viewm);
277   gra_state.viewm[3][0] = -xf;
278   gra_state.viewm[3][1] = -yf;
279   gra_state.viewm[3][2] = -zf;
280 
281   xf = xf - xt;
282   yf = yf - yt;
283   zf = zf - zt;
284 
285   /*
286    * rotate(90 0 0)
287    */
288   gra_ident(gvm);
289   gvm[1][2] = -1;
290   gvm[2][1] =  1;
291   gvm[1][1] =  0;
292   gvm[2][2] =  0;
293   gra_mult(gra_state.viewm, gvm);
294 
295   r1 = sqrt(xf*xf + yf*yf);
296   if (r1 != 0)
297   {
298     gra_ident(gvm);
299     gvm[0][0] = -yf/r1;
300     gvm[2][2] =  gvm[0][0];
301     gvm[0][2] =  xf/r1;
302     gvm[2][0] = -gvm[0][2];
303     gra_mult(gra_state.viewm,gvm);
304   }
305 
306   r2 = sqrt(yf*yf + zf*zf);
307   if (r2 != 0)
308   {
309     gra_ident(gvm);
310     gvm[1][1] = r1/r2;
311     gvm[2][2] = gvm[1][1];
312     gvm[1][2] = zf/r2;
313     gvm[2][1] = -gvm[1][2];
314     gra_mult(gra_state.viewm,gvm);
315   }
316 
317   gra_ident(gvm);
318   gvm[2][2] = -1.0;
319   gra_mult(gra_state.viewm,gvm);
320 
321   gra_set_transfm();
322 }
323 
gra_rotate(rx,ry,rz)324 void gra_rotate(rx, ry, rz) double rx, ry, rz;
325 {
326   static double pip180 = 3.1415926535898/180.0;
327 #pragma omp threadprivate (pip180)
328   GMATRIX grm;
329 
330   rx *= pip180;
331   gra_ident(grm);
332   grm[1][1] =  cos(rx);
333   grm[1][2] = -sin(rx);
334   grm[2][1] =  sin(rx);
335   grm[2][2] =  cos(rx);
336   gra_mult(gra_state.modelm,grm);
337 
338   ry *= pip180;
339   gra_ident(grm);
340   grm[0][0] =  cos(ry);
341   grm[0][2] =  sin(ry);
342   grm[2][0] = -sin(ry);
343   grm[2][2] =  cos(ry);
344   gra_mult(gra_state.modelm,grm);
345 
346   rz *= pip180;
347   gra_ident(grm);
348   grm[0][0] =  cos(rz);
349   grm[0][1] = -sin(rz);
350   grm[1][0] =  sin(rz);
351   grm[1][1] =  cos(rz);
352   gra_mult(gra_state.modelm,grm);
353 
354   gra_set_transfm();
355 }
356 
gra_scale(sx,sy,sz)357 void gra_scale(sx, sy, sz) double sx, sy, sz;
358 {
359   GMATRIX gsm;
360 
361   gra_ident(gsm);
362   gsm[0][0] = sx;
363   gsm[1][1] = sy;
364   gsm[2][2] = sz;
365   gra_mult(gra_state.modelm,gsm);
366 
367   gra_set_transfm();
368 }
369 
gra_translate(tx,ty,tz)370 void gra_translate(tx, ty, tz) double tx, ty, tz;
371 {
372   GMATRIX gtm;
373 
374   gra_ident(gtm);
375   gtm[3][0] = tx;
376   gtm[3][1] = ty;
377   gtm[3][2] = tz;
378   gra_mult(gra_state.modelm,gtm);
379 
380   gra_set_transfm();
381 }
382 
gra_perspective(r)383 void gra_perspective(r) double r;
384 {
385   gra_ident(gra_state.projm);
386   gra_state.projm[0][0] = r;
387   gra_state.projm[1][1] = r;
388   gra_state.pratio = r;
389   gra_set_transfm();
390 }
391 
gra_set_proj()392 void gra_set_proj()
393 {
394   gra_vsx = (gra_state.viewport.xhigh -
395             gra_state.viewport.xlow) / 2;
396 
397   gra_vsy = (gra_state.viewport.yhigh -
398              gra_state.viewport.ylow) / 2;
399 
400   gra_vtx = gra_state.viewport.xlow + gra_vsx;
401   gra_vty = gra_state.viewport.ylow + gra_vsy;
402 }
403 
gra_set_window(x1,x2,y1,y2,z1,z2)404 void gra_set_window(x1,x2,y1,y2,z1,z2) double x1,x2,y1,y2,z1,z2;
405 {
406   GMATRIX gvm;
407 
408   gra_state.window.xlow  = x1;
409   gra_state.window.xhigh = x2;
410   gra_state.window.ylow  = y1;
411   gra_state.window.yhigh = y2;
412   gra_state.window.zlow  = z1;
413   gra_state.window.zhigh = z2;
414 
415   gra_ident(gra_state.projm);
416   gra_state.projm[0][0] = 2 / (x2-x1);
417   gra_state.projm[1][1] = 2 / (y2-y1);
418   gra_state.projm[2][2] = 2 / (z2-z1);
419 
420   gra_ident(gvm);
421   gvm[3][0] = -1 - gra_state.projm[0][0] * x1;
422   gvm[3][1] = -1 - gra_state.projm[1][1] * y1;
423   gvm[3][2] = -1 - gra_state.projm[2][2] * z1;
424   gra_mult(gra_state.projm, gvm);
425 
426   gra_state.pratio = 0.0;
427   gra_set_transfm();
428 }
429 
gra_set_viewport(x1,x2,y1,y2)430 void gra_set_viewport(x1,x2,y1,y2) double x1, x2, y1, y2;
431 {
432   gra_state.viewport.xlow  = x1;
433   gra_state.viewport.xhigh = x2;
434   gra_state.viewport.ylow  = y1;
435   gra_state.viewport.yhigh = y2;
436   gra_set_proj();
437 }
438 
gra_mtrans(x,y,z,xe,ye,ze)439 void gra_mtrans(x,y,z,xe,ye,ze) double x,y,z,*xe,*ye,*ze;
440 {
441   *xe = x * gra_state.transfm[0][0] +
442         y * gra_state.transfm[1][0] +
443         z * gra_state.transfm[2][0] +
444             gra_state.transfm[3][0];
445 
446   *ye = x * gra_state.transfm[0][1] +
447         y * gra_state.transfm[1][1] +
448         z * gra_state.transfm[2][1] +
449             gra_state.transfm[3][1];
450 
451   *ze = x * gra_state.transfm[0][2] +
452         y * gra_state.transfm[1][2] +
453         z * gra_state.transfm[2][2] +
454             gra_state.transfm[3][2];
455 
456   if (gra_state.pratio > 0.0 && *ze != 0.0)
457   {
458     *xe /= *ze; *ye /= *ze;
459   }
460 }
461 
462 /*
463  * Window to viewport transformation
464  *
465  * ViewportX = ScaleX * WindowX + TransX
466  * ScaleX = (vp.xmax - vp.xmin) / (w.xmax - w.xmin)
467  * TransX = (vp.xmin - ScaleX * w.xmin)
468  */
gra_window_to_viewport(x,y,z,xs,ys)469 void gra_window_to_viewport(x, y, z, xs, ys) double x, y, z, *xs, *ys;
470 {
471 /*
472   double xe, ye, ze;
473   gra_mtrans(x, y, z, &xe, &ye, &ze);
474 */
475 
476   *xs = gra_vsx * x + gra_vtx;
477   *ys = gra_vsy * y + gra_vty;
478 }
479 
gra_error()480 void gra_error()
481 {
482   error("gra: graphics package not initialized\n");
483 }
484