afcf0ee0cf1ad9792a88bac61ac14c92953fe776
[alexxy/gromacs.git] / src / ngmx / molps.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <math.h>
40 #include "sysstuff.h"
41 #include "string.h"
42 #include "smalloc.h"
43 #include "macros.h"
44 #include "xutil.h"
45 #include "3dview.h"
46 #include "gmx_fatal.h"
47 #include "buttons.h"
48 #include "manager.h"
49 #include "nmol.h"
50 #include "writeps.h"
51 #include "nleg.h"
52
53 #define MSIZE 4
54
55 static void ps_draw_atom(t_psdata ps,atom_id ai,iv2 vec2[],char **atomnm[])
56 {
57   int xi,yi;
58   
59   xi=vec2[ai][XX];
60   yi=vec2[ai][YY];
61   ps_rgb(ps,Type2RGB(*atomnm[ai]));
62   ps_line(ps,xi-MSIZE,yi,xi+MSIZE+1,yi);
63   ps_line(ps,xi,yi-MSIZE,xi,yi+MSIZE+1);
64 }
65
66 /* Global variables */
67 static rvec gl_fbox,gl_hbox,gl_mhbox;
68
69 static void init_pbc(matrix box)
70 {
71   int i;
72
73   for(i=0; (i<DIM); i++) {
74     gl_fbox[i]  =  box[i][i];
75     gl_hbox[i]  =  gl_fbox[i]*0.5;
76     gl_mhbox[i] = -gl_hbox[i];
77   }
78 }
79
80 static bool local_pbc_dx(rvec x1, rvec x2)
81 {
82   int  i;
83   real dx;
84   
85   for(i=0; (i<DIM); i++) {
86     dx=x1[i]-x2[i];
87     if (dx > gl_hbox[i])
88       return FALSE;
89     else if (dx <= gl_mhbox[i])
90       return FALSE;
91   }
92   return TRUE;
93 }
94
95 static void ps_draw_bond(t_psdata ps,
96                          atom_id ai,atom_id aj,iv2 vec2[],
97                          rvec x[],char **atomnm[],int size[],bool bBalls)
98 {
99   char    *ic,*jc;
100   int     xi,yi,xj,yj;
101   int     xm,ym;
102
103   if (bBalls) {
104     ps_draw_atom(ps,ai,vec2,atomnm);
105     ps_draw_atom(ps,aj,vec2,atomnm);
106   }
107   else {
108     if (local_pbc_dx(x[ai],x[aj])) {
109       ic=*atomnm[ai];
110       jc=*atomnm[aj];
111       xi=vec2[ai][XX];
112       yi=vec2[ai][YY];
113       xj=vec2[aj][XX];
114       yj=vec2[aj][YY];
115       
116       if (ic != jc) {
117         xm=(xi+xj) >> 1;
118         ym=(yi+yj) >> 1;
119       
120         ps_rgb(ps,Type2RGB(ic));
121         ps_line(ps,xi,yi,xm,ym);
122         ps_rgb(ps,Type2RGB(jc));
123         ps_line(ps,xm,ym,xj,yj);
124       }
125       else {
126         ps_rgb(ps,Type2RGB(ic));
127         ps_line(ps,xi,yi,xj,yj);
128       }
129     }
130   }
131 }
132
133 void ps_draw_objects(t_psdata ps,int nobj,t_object objs[],iv2 vec2[],rvec x[],
134                      char **atomnm[],int size[],bool bShowHydro,int bond_type,
135                      bool bPlus)
136 {
137   bool     bBalls;
138   int      i;
139   t_object *obj;
140
141   bBalls=FALSE;
142   for(i=0; (i<nobj); i++) {
143     obj=&(objs[i]);
144     switch (obj->eO) {
145     case eOSingle:
146       ps_draw_atom(ps,obj->ai,vec2,atomnm);
147       break;
148     case eOBond:
149       ps_draw_bond(ps,obj->ai,obj->aj,vec2,x,atomnm,size,bBalls);
150       break;
151     case eOHBond:
152       if (bShowHydro)
153         ps_draw_bond(ps,obj->ai,obj->aj,vec2,x,atomnm,size,bBalls);
154       break;
155     default:
156       break;
157     }
158   }
159 }
160
161 static void v4_to_iv2(vec4 x4,iv2 v2,int x0,int y0,real sx,real sy)
162 {
163   real inv_z;
164
165   inv_z=1.0/x4[ZZ];
166   v2[XX]=x0+sx*x4[XX]*inv_z;
167   v2[YY]=y0-sy*x4[YY]*inv_z;
168 }
169
170 static void draw_box(t_psdata ps,t_3dview *view,matrix box,
171                      int x0,int y0,real sx,real sy)
172 {
173   int  ivec[8][4] =  { 
174     { 0,0,0,1 }, { 1,0,0,1 }, { 1,1,0,1 }, { 0,1,0,1 },
175     { 0,0,1,1 }, { 1,0,1,1 }, { 1,1,1,1 }, { 0,1,1,1 }
176   };
177   int  bonds[12][2] = {
178     { 0,1 }, { 1,2 }, { 2,3 }, { 3,0 }, 
179     { 4,5 }, { 5,6 }, { 6,7 }, { 7,4 },
180     { 0,4 }, { 1,5 }, { 2,6 }, { 3,7 }
181   };
182   int  i,j;
183   rvec corner[8];
184   vec4 x4;
185   iv2  vec2[12];
186
187   for (i=0; (i<8); i++) {
188     for (j=0; (j<DIM); j++)
189       corner[i][j] = ivec[i][j]*box[j][j];
190     m4_op(view->proj,corner[i],x4);
191     v4_to_iv2(x4,vec2[i],x0,y0,sx,sy);
192   }
193   ps_color(ps,0,0,0.5);
194   for (i=0; (i<12); i++)
195     ps_line(ps,
196             vec2[bonds[i][0]][XX],vec2[bonds[i][0]][YY],
197             vec2[bonds[i][1]][XX],vec2[bonds[i][1]][YY]);
198 }
199
200 void ps_draw_mol(t_psdata ps,t_manager *man)
201 {
202   static char tstr[2][20];
203   static int  ntime=0;
204   t_windata *win;
205   t_3dview  *view;
206   t_molwin  *mw;
207   int       i,x0,y0,nvis;
208   iv2       *vec2;
209   real      sx,sy;
210   vec4      x4;
211
212   if (!man->status)
213     return;
214
215   view=man->view;
216   mw=man->molw;
217
218   win=&(mw->wd);
219
220   vec2=man->ix;
221   x0=win->width/2;
222   y0=win->height/2;
223   sx=win->width/2*view->sc_x;
224   sy=win->height/2*view->sc_y;
225
226   init_pbc(man->box);
227
228   /* create_visibility(man); */
229
230   for(i=0; (i<man->natom); i++) {
231     if (man->bVis[i]) {
232       m4_op(view->proj,man->x[i],x4);
233       man->zz[i]=x4[ZZ];
234       v4_to_iv2(x4,vec2[i],x0,y0,sx,sy);
235     }
236   }
237   set_sizes(man,sx,sy);
238   
239   z_fill (man,man->zz);
240   
241   /* Start drawing 
242   XClearWindow(x11->disp,win->self); */
243
244   /* Draw Time 
245   sprintf(tstr[ntime],"Time: %.3 ps",man->time);
246   if (strcmp(tstr[ntime],tstr[1-ntime]) != 0) {
247     set_vbtime(x11,man->vbox,tstr[ntime]);
248     ntime=1-ntime;
249   }*/
250
251   if (mw->boxtype != esbNone)
252     draw_box(ps,view,man->box,x0,y0,sx,sy);
253
254   /* Should sort on Z-Coordinates here! */
255   nvis=filter_vis(man);
256   if (nvis && man->bSort)
257     qsort(man->obj,nvis,sizeof(man->obj[0]),compare_obj);
258   
259   /* Draw the objects */
260   ps_draw_objects(ps,
261                   nvis,man->obj,man->ix,man->x,man->top.atoms.atomname,
262                   man->size,
263                   mw->bShowHydrogen,mw->bond_type,man->bPlus);
264
265   /* Draw the labels */
266   ps_color(ps,0,0,0);
267   for(i=0; (i<man->natom); i++) 
268     if (man->bLabel[i] && man->bVis[i]) 
269       ps_text(ps,vec2[i][XX]+2,vec2[i][YY]-2,man->szLab[i]);
270 }
271