60ed8f9a94a7a022cdb84f75476c0cffe2533411
[alexxy/gromacs.git] / src / ngmx / molps.c
1 /*
2  * $Id$
3  * 
4  *       This source code is part of
5  * 
6  *        G   R   O   M   A   C   S
7  * 
8  * GROningen MAchine for Chemical Simulations
9  * 
10  *               VERSION 2.0
11  * 
12  * Copyright (c) 1991-1999
13  * BIOSON Research Institute, Dept. of Biophysical Chemistry
14  * University of Groningen, The Netherlands
15  * 
16  * Please refer to:
17  * GROMACS: A message-passing parallel molecular dynamics implementation
18  * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19  * Comp. Phys. Comm. 91, 43-56 (1995)
20  * 
21  * Also check out our WWW page:
22  * http://md.chem.rug.nl/~gmx
23  * or e-mail to:
24  * gromacs@chem.rug.nl
25  * 
26  * And Hey:
27  * Great Red Oystrich Makes All Chemists Sane
28  */
29 static char *SRCID_molps_c = "$Id$";
30
31 #include <math.h>
32 #include "sysstuff.h"
33 #include "string.h"
34 #include "smalloc.h"
35 #include "macros.h"
36 #include "xutil.h"
37 #include "3dview.h"
38 #include "fatal.h"
39 #include "buttons.h"
40 #include "manager.h"
41 #include "nmol.h"
42 #include "writeps.h"
43 #include "nleg.h"
44
45 #define MSIZE 4
46
47 static void ps_draw_atom(FILE *ps,atom_id ai,iv2 vec2[],char **atomnm[])
48 {
49   int xi,yi;
50   
51   xi=vec2[ai][XX];
52   yi=vec2[ai][YY];
53   ps_rgb(ps,Type2RGB(*atomnm[ai]));
54   ps_line(ps,xi-MSIZE,yi,xi+MSIZE+1,yi);
55   ps_line(ps,xi,yi-MSIZE,xi,yi+MSIZE+1);
56 }
57
58 /* Global variables */
59 static rvec gl_fbox,gl_hbox,gl_mhbox;
60
61 static void init_pbc(matrix box)
62 {
63   int i;
64
65   for(i=0; (i<DIM); i++) {
66     gl_fbox[i]  =  box[i][i];
67     gl_hbox[i]  =  gl_fbox[i]*0.5;
68     gl_mhbox[i] = -gl_hbox[i];
69   }
70 }
71
72 static bool local_pbc_dx(rvec x1, rvec x2)
73 {
74   int  i;
75   real dx;
76   
77   for(i=0; (i<DIM); i++) {
78     dx=x1[i]-x2[i];
79     if (dx > gl_hbox[i])
80       return FALSE;
81     else if (dx <= gl_mhbox[i])
82       return FALSE;
83   }
84   return TRUE;
85 }
86
87 static void ps_draw_bond(FILE *ps,
88                          atom_id ai,atom_id aj,iv2 vec2[],
89                          rvec x[],char **atomnm[],int size[],bool bBalls)
90 {
91   char    *ic,*jc;
92   int     xi,yi,xj,yj;
93   int     xm,ym;
94
95   if (bBalls) {
96     ps_draw_atom(ps,ai,vec2,atomnm);
97     ps_draw_atom(ps,aj,vec2,atomnm);
98   }
99   else {
100     if (local_pbc_dx(x[ai],x[aj])) {
101       ic=*atomnm[ai];
102       jc=*atomnm[aj];
103       xi=vec2[ai][XX];
104       yi=vec2[ai][YY];
105       xj=vec2[aj][XX];
106       yj=vec2[aj][YY];
107       
108       if (ic != jc) {
109         xm=(xi+xj) >> 1;
110         ym=(yi+yj) >> 1;
111       
112         ps_rgb(ps,Type2RGB(ic));
113         ps_line(ps,xi,yi,xm,ym);
114         ps_rgb(ps,Type2RGB(jc));
115         ps_line(ps,xm,ym,xj,yj);
116       }
117       else {
118         ps_rgb(ps,Type2RGB(ic));
119         ps_line(ps,xi,yi,xj,yj);
120       }
121     }
122   }
123 }
124
125 void ps_draw_objects(FILE *ps,int nobj,t_object objs[],iv2 vec2[],rvec x[],
126                      char **atomnm[],int size[],bool bShowHydro,int bond_type,
127                      bool bPlus)
128 {
129   bool     bBalls;
130   int      i;
131   t_object *obj;
132
133   bBalls=FALSE;
134   for(i=0; (i<nobj); i++) {
135     obj=&(objs[i]);
136     switch (obj->eO) {
137     case eOSingle:
138       ps_draw_atom(ps,obj->ai,vec2,atomnm);
139       break;
140     case eOBond:
141       ps_draw_bond(ps,obj->ai,obj->aj,vec2,x,atomnm,size,bBalls);
142       break;
143     case eOHBond:
144       if (bShowHydro)
145         ps_draw_bond(ps,obj->ai,obj->aj,vec2,x,atomnm,size,bBalls);
146       break;
147     default:
148       break;
149     }
150   }
151 }
152
153 static void v4_to_iv2(vec4 x4,iv2 v2,int x0,int y0,real sx,real sy)
154 {
155   real inv_z;
156
157   inv_z=1.0/x4[ZZ];
158   v2[XX]=x0+sx*x4[XX]*inv_z;
159   v2[YY]=y0-sy*x4[YY]*inv_z;
160 }
161
162 static void draw_box(FILE *ps,t_3dview *view,matrix box,
163                      int x0,int y0,real sx,real sy)
164 {
165   int  ivec[8][4] =  { 
166     { 0,0,0,1 }, { 1,0,0,1 }, { 1,1,0,1 }, { 0,1,0,1 },
167     { 0,0,1,1 }, { 1,0,1,1 }, { 1,1,1,1 }, { 0,1,1,1 }
168   };
169   int  bonds[12][2] = {
170     { 0,1 }, { 1,2 }, { 2,3 }, { 3,0 }, 
171     { 4,5 }, { 5,6 }, { 6,7 }, { 7,4 },
172     { 0,4 }, { 1,5 }, { 2,6 }, { 3,7 }
173   };
174   int  i,j;
175   rvec corner[8];
176   vec4 x4;
177   iv2  vec2[12];
178
179   for (i=0; (i<8); i++) {
180     for (j=0; (j<DIM); j++)
181       corner[i][j] = ivec[i][j]*box[j][j];
182     m4_op(view->proj,corner[i],x4);
183     v4_to_iv2(x4,vec2[i],x0,y0,sx,sy);
184   }
185   ps_color(ps,0,0,0.5);
186   for (i=0; (i<12); i++)
187     ps_line(ps,
188             vec2[bonds[i][0]][XX],vec2[bonds[i][0]][YY],
189             vec2[bonds[i][1]][XX],vec2[bonds[i][1]][YY]);
190 }
191
192 void ps_draw_mol(FILE *ps,t_manager *man)
193 {
194   static char tstr[2][20];
195   static int  ntime=0;
196   t_windata *win;
197   t_3dview  *view;
198   t_molwin  *mw;
199   int       i,x0,y0,nvis;
200   iv2       *vec2;
201   real      sx,sy;
202   vec4      x4;
203
204   if (man->status == -1)
205     return;
206
207   view=man->view;
208   mw=man->molw;
209
210   win=&(mw->wd);
211
212   vec2=man->ix;
213   x0=win->width/2;
214   y0=win->height/2;
215   sx=win->width/2*view->sc_x;
216   sy=win->height/2*view->sc_y;
217
218   init_pbc(man->box);
219
220   /* create_visibility(man); */
221
222   for(i=0; (i<man->natom); i++) {
223     if (man->bVis[i]) {
224       m4_op(view->proj,man->x[i],x4);
225       man->zz[i]=x4[ZZ];
226       v4_to_iv2(x4,vec2[i],x0,y0,sx,sy);
227     }
228   }
229   set_sizes(man,sx,sy);
230   
231   z_fill (man,man->zz);
232   
233   /* Start drawing 
234   XClearWindow(x11->disp,win->self); */
235
236   /* Draw Time 
237   sprintf(tstr[ntime],"Time: %.3 ps",man->time);
238   if (strcmp(tstr[ntime],tstr[1-ntime]) != 0) {
239     set_vbtime(x11,man->vbox,tstr[ntime]);
240     ntime=1-ntime;
241   }*/
242
243   if (mw->boxtype != esbNone)
244     draw_box(ps,view,man->box,x0,y0,sx,sy);
245
246   /* Should sort on Z-Coordinates here! */
247   nvis=filter_vis(man);
248   if (nvis && man->bSort)
249     qsort(man->obj,nvis,sizeof(man->obj[0]),compare_obj);
250   
251   /* Draw the objects */
252   ps_draw_objects(ps,
253                   nvis,man->obj,man->ix,man->x,man->top.atoms.atomname,
254                   man->size,
255                   mw->bShowHydrogen,mw->bond_type,man->bPlus);
256
257   /* Draw the labels */
258   ps_color(ps,0,0,0);
259   for(i=0; (i<man->natom); i++) 
260     if (man->bLabel[i] && man->bVis[i]) 
261       ps_text(ps,vec2[i][XX]+2,vec2[i][YY]-2,man->szLab[i]);
262 }
263