1 /*
2 
3  *****************************************************************************
4  * Author:                                                                   *
5  * ------                                                                    *
6  *  Anton Kokalj                                  Email: Tone.Kokalj@ijs.si  *
7  *  Department of Physical and Organic Chemistry  Phone: x 386 1 477 3523    *
8  *  Jozef Stefan Institute                          Fax: x 386 1 477 3811    *
9  *  Jamova 39, SI-1000 Ljubljana                                             *
10  *  SLOVENIA                                                                 *
11  *                                                                           *
12  * Source: $XCRYSDEN_TOPDIR/C/xcDisplayFunc.c
13  * ------                                                                    *
14  * Copyright (c) 1996-2003 by Anton Kokalj
15  * ------                                                                    *
16  * Modified by Eric Verfaillie ericverfaillie@yahoo.fr EV                    *
17  * may 2004                                                                  *
18  * modifcations are near EV comments                                         *
19  *****************************************************************************
20 
21 */
22 
23 #include <togl.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <GL/glu.h>
29 #include "struct.h"
30 #include "3D.h"
31 #include "xcGLparam.h"
32 #include "isosurf.h"
33 #include "molsurf.h"
34 #include "xcfunc.h"
35 
36 #define APPR_SCREENSIZE 1024
37 #define SELCOL 0
38 #define SELLINE_WIDTH 2.0   /* width of "selline" */
39 #define SELLINE_PAT 0xAAAA  /* selline stipple pattern */
40 
41 #define SPHERE_TESS_PREFACTOR 2
42 #define BOND_TESS_PREFACTOR   1
43 
44 
45 /*********************************************/
46 /*                 EV                        */
47 /*********************************************/
48 #include "anaglyph.h"
49 
50 GLdouble radiu;
51 CAMERA camera;
52 XYZ origin = {0.0,0.0,0.0};
53 /*********************************************/
54 /*                 EV                        */
55 /*********************************************/
56 
57 
58 
59 extern struct Togl *mesa_togl;
60 
61 extern Options3D      is;
62 extern RasterFontSize rf;
63 extern PERSPECTIVE    persp;
64 extern AtomicLabel    *atomLabel, globalAtomLabel;
65 extern short          *do_not_display_atomlabel;
66 extern char           *element[];
67 extern GLuint         fontOffset;
68 extern GLfloat        AtCol_Ambient_by_Diffuse;
69 extern XCantialias    antialias;
70 extern ForceVector    FV;
71 extern XYZ_Attrib     xyz;
72 OrthoProj             ort;
73 
74 extern realTimeMove makeMovie;
75 
76 /*****************************************************************************
77  * HERE LIST VARIABLES ARE DIFINED                                           */
78 GLuint PointList = -1;
79 /*
80   static GLuint SolidSpaceFillList = -1;
81   static GLuint WireSpaceFillList = -1;
82   static GLuint SolidBallList = -1;
83   static GLuint WireBallList = -1;
84   static GLuint SolidStickList = -1;
85   static GLuint WireStickList = -1;
86 */
87 /*
88   static GLuint SolidFrameList = -1;
89   static GLuint WireFrameList = -1;
90   static GLuint LineFrameList = -1;
91 */
92 /*  static GLuint LabelBallList = -1;  */
93 /*  static GLuint LabelSpaceList = -1;  */
94 
95 extern GLuint crdList; /* crdList is list for coor-sist.  */
96 extern GLuint xyplaneList; /* list for XY plane that goes with coor-sist  */
97 
98 extern GLuint tempDisable3Dlist;
99 extern GLuint tempEnable3Dlist;
100 /* --- this is for selection-lists --- */
101 /*extern GLuint SphereSelList[MAXSEL];*/
102 /*extern GLuint LineSelList[MAXSEL-1];*/
103 /* --- this is for cell-adding-type-procedure of ATOMINSE Crystal command  */
104 /*extern GLuint BasicVectorsList, AtomAddList; */
105 /****************************************************************************/
106 
107 
108 
109 /*****************************************************************************/
110 
111 /* function prototypes  */
112 GLuint xcGenLists( GLsizei i );
113 void (*xcDisplay)(struct Togl *togl) = 0x0;
114 void xcDisplayFunc( void (*Func)(struct Togl *togl) );
115 int xcToglDisplayFunc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv);
116 void xcDummyDisplay( struct Togl *togl );
117 void xcGenDispList(void);
118 void xcWireFrame2D(struct Togl *togl);
119 void xcMakePointList(void);
120 void xcPointLine2D(struct Togl *togl);
121 void xcBall2D(int iatom);
122 /*void xcMakeBallLists(void);
123   void xcMakeNewBallList( GLdouble *sizeArray , int natom ); */
124 void xcBallStick12D(struct Togl *togl);
125 void xcPipeBall2D(struct Togl *togl);
126 void xcBallStick22D(struct Togl *togl);
127 void xcSpaceFill2D(struct Togl *togl);
128 void EnableOr2D_Or3D(void);
129 static void _ambient_by_diffuse(GLfloat dst[4], GLfloat scale, GLfloat src[4]);
130 void xcRenderSolidBalls3D(void);
131 void xcRenderWireBalls3D(void);
132 void xcRenderBonds(GLenum type);
133 void xcRenderSolidSpaceFills3D(void);
134 void xcRenderWireSpaceFills3D(void);
135 void xcRenderSolidFrame3D(void);
136 void xcRenderWireFrame3D(void);
137 void xcRenderLineFrame3D(void);
138 static void xcLineStippleFrame(int ii);
139 static void MatInv33_44(double m[4][4], double minv[4][4], double *det);
140 static void MultMat44_33Vec3(double mat[4][4], double vec[3], double res[3]);
141 static void _makeAtomLabels3D(double *rad);
142 void xcMakeBallLabel3D(void);
143 void xcMakeSpaceLabel3D(void);
144 void xcDisplay3D(struct Togl *togl);
145 static void _xcDisplay3D(struct Togl *togl);
146 static void __xcDisplay3D(struct Togl *togl);
147 void xcMaybeDestroyLists(void);
148 void xcMakeProjection2D(const char *mode);
149 void xcMakeProjection3D(const char *mode);
150 static void _xcMakeProjection(GLdouble size);
151 void xcClearScreen(struct Togl *togl);
152 void xcChangeBackground(struct Togl *togl, GLclampf bckg[4]);
153 void xcDisplayXYZ(void);
154 static void goToPrevProj(void);
155 void xcTurnXYZOff(struct Togl *togl);
156 
157 void xcWireSphere (GLdouble radius);
158 void xcSolidSphere (GLdouble radius);
159 void xcWireCylinder (GLdouble radius, GLdouble height);
160 void xcSolidCylinder (GLdouble radius, GLdouble height);
161 void xcSolidBond (GLdouble radius, GLdouble height, int bondFlag);
162 void xcSolidCone (GLdouble baseradius, GLdouble topradius, GLdouble height);
163 static int CalcTessFactor(void);
164 static void HandleDisplay(struct Togl *togl);
165 static void draw_scene(void);
166 static void CameraHome(void);
167 static void Normalise(XYZ *p);
168 /*static XYZ CalcNormal(XYZ p, XYZ p1, XYZ p2);*/
169 
170 /* --- extern function prototypes ---  */
171 extern int MakeSticks1(int i,
172 		       GLdouble *x1, GLdouble *y1, GLdouble *z1,
173 		       GLdouble *x2, GLdouble *y2, GLdouble *z2,
174 		       GLdouble *x3, GLdouble *y3, GLdouble *z3,
175 		       GLdouble *x4, GLdouble *y4, GLdouble *z4);
176 extern int MakeSticks2(int i, int col, int flag);
177 
178 /* --- readstrf.c ---*/
179 extern void FindMaxRad(void);
180 
181 /* --- xcSelect.c --- */
182 extern void xcRenderSelAtoms3D(void);
183 extern void xcRenderSelBonds3D(void);
184 
185 /* --- xcAtomAdd.c --- */
186 extern void xcDisplayAddAtomBox(void);
187 
188 /* --- isorender.c --- */
189 extern void xcRenderIsosurf(int obj);
190 extern void xcRenderColorplane(int obj);
191 extern void xcRenderSurface(void);
192 
193 /* --- xcSuperCell.c --- */
194 extern void (*xcSuperCell)(void);
195 
196 /* --- xcIsoSpaceSel.c --- */
197 extern void IsoSpaceSel_Parallelogram(void);
198 extern void IsoSpaceSel_3D(void);
199 
200 /* --- xcviewport.c --- */
201 extern void MaybeClipAndMakeProjection(void);
202 
203 
204 /* --- cryNewContext.c ---  */
205 extern NEW_WIN_CONTEXT *FindWinContextByTogl(struct Togl *togl);
206 
207 /* xcdebug */
208 extern void xcdebug(const char *text);
209 
210 /* xcFont.c */
211 extern void xcFont_PrintString (const char *s);
212 
213 /* sgiAux.c */
214 extern GLuint findList1 (int lindex, GLdouble *paramArray, int size);
215 extern GLuint makeModelPtr1 (int lindex, GLdouble *sizeArray, int count);
216 
217 GLuint
xcGenLists(GLsizei i)218 xcGenLists( GLsizei i )
219 {
220   return glGenLists (i);
221   /*
222     static GLuint nlist = 1;
223     GLuint n;
224 
225     n = nlist;
226     nlist += i;
227     return n;
228   */
229 }
230 
231 
232 
233 /*****************************************************************************/
234 void
xcDisplayFunc(void (* Func)(struct Togl * togl))235 xcDisplayFunc( void (*Func)(struct Togl *togl) )
236 {
237   xcDisplay = Func;
238 }
239 /*****************************************************************************/
240 
241 
242 /*****************************************************************************/
243 /*void cryDisplayFunc( void (*DispFunc)(struct Togl *togl), struct Togl *togl );*/
244 int
xcToglDisplayFunc(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * const * objv)245 xcToglDisplayFunc(ClientData clientData, Tcl_Interp *interp,
246                   int objc, Tcl_Obj *const *objv)
247 {
248   Togl *togl;
249   /*static int toglIsInteractive = 0;*/
250 
251   if (objc != 2) {
252     Tcl_WrongNumArgs(interp, 1, objv, "pathName");
253     return TCL_ERROR;
254   }
255   if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
256     return TCL_ERROR;
257   }
258 
259   if ( togl == mesa_togl ) {
260     if (xcDisplay) (*xcDisplay)(togl);
261   } else {
262     NEW_WIN_CONTEXT *wc = FindWinContextByTogl( togl );
263     /*cryDisplayFunc( wc->xcDisplay, togl );*/
264     if (wc->xcDisplay) wc->xcDisplay( togl );
265   }
266   return TCL_OK;
267 }
268 /*
269 void cryDisplayFunc( void (*DispFunc)(struct Togl *togl), struct Togl *togl )
270 { (*DispFunc)(togl); } */
271 /*****************************************************************************/
272 
273 
274 /*****************************************************************************/
275 void
xcDummyDisplay(struct Togl * togl)276 xcDummyDisplay( struct Togl *togl )
277 {
278   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
279   glClearColor( bg[0], bg[1], bg[2], bg[3] );
280   Togl_SwapBuffers(togl);
281   xcdebug("dummy display function");
282 }
283 
284 
285 
286 /* this routine generate display Lists */
287 void
xcGenDispList(void)288 xcGenDispList(void)
289 {
290   /*int i; */
291 
292   /* generate all Display Lists; actually we need just to reserve numbers
293    * for lists */
294   PointList = xcGenLists(1);
295   /*
296     SolidSpaceFillList = xcGenLists(1);
297     WireSpaceFillList = xcGenLists(1);
298     SolidBallList = xcGenLists(1);
299     WireBallList = xcGenLists(1);
300     SolidStickList = xcGenLists(1);
301     WireStickList = xcGenLists(1);
302   */
303   /*
304     SolidFrameList = xcGenLists(1);
305     WireFrameList = xcGenLists(1);
306     LineFrameList = xcGenLists(1);
307   */
308 /*    LabelBallList = xcGenLists(1); */
309 /*    LabelSpaceList = xcGenLists(1); */
310   /*for(i=0; i<MAXSEL; i++) SphereSelList[i] = xcGenLists(1);*/
311   /*for(i=0; i<MAXSEL-1; i++) LineSelList[i] = xcGenLists(1);*/
312   /*BasicVectorsList = xcGenLists(1); */
313   /*AtomAddList = xcGenLists(1); */
314 }
315 
316 
317 
318 
319 /* xcWireFrame2D is xcDisplayFunc for WireFrames
320  * --------------------------------------------------------------
321  *                xcWireFrame2D display a WireFrames
322  *               Here I'm dealing with 'coor' structure
323  */
324 
325 void
xcWireFrame2D(struct Togl * togl)326 xcWireFrame2D(struct Togl *togl)
327 {
328   int i;
329 
330   glClear(GL_COLOR_BUFFER_BIT);
331   glLoadIdentity();
332   if (VPf.perspective)
333     glTranslated (0.0, 0.0, persp.shiftZ);
334   else
335     glTranslated(0.0, 0.0, -ort.size);
336 
337   /* fog & antialias */
338   xcFog       (togl, VPf.fog, VPf.perspective);
339   xcAntiAlias (VPf.antialias);
340 
341   glLineWidth( (GLfloat) VPf.WFlinewidth );
342   for(i = 1; i <= tmp_nobjects; i++) {
343     glBegin(GL_LINES);
344        if ( VPf.unibond) glColor3fv(unibondCol);
345        else glColor3fv( atm.col[(coor + *(iwksp + i))->sqn] );
346        glVertex3d( (coor + *(iwksp + i))->x1,
347 		   (coor + *(iwksp + i))->y1,
348 		   (coor + *(iwksp + i))->z1);
349        glVertex3d( (coor + *(iwksp + i))->x2,
350 		   (coor + *(iwksp + i))->y2,
351 		   (coor + *(iwksp + i))->z2);
352     glEnd();
353   }
354 
355   /* check if coordinate sistem should be displayed */
356   if ( VPf.xyzOn ) xcDisplayXYZ();
357 
358   glFlush();
359   Togl_SwapBuffers(togl);
360 
361   /* every snapshot movie making */
362   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
363     fprintf(stderr,"making snapshot\n");
364     createMoviePPMFrame(togl);
365   }
366 }
367 
368 
369 /* make list for point */
370 void
xcMakePointList(void)371 xcMakePointList(void)
372 {
373   GLint i, nstep;
374   GLdouble sine, cosine, dstep, r;
375   /* double cos(), sin();  */
376 
377   if ( glIsList(PointList) ) glDeleteLists( PointList, 1 );
378 
379   r = VPf.PLradius / VPf.VPfactor;
380   nstep = 12;
381   dstep = (GLdouble) nstep;
382 
383   /* PointList list was generarted in xcGenDispList */
384   glNewList( PointList, GL_COMPILE );
385     glBegin(GL_POLYGON);
386       for(i=0; i < nstep; i++)
387         {
388 	  cosine = r * cos((GLdouble) i * 2.0 * PI / dstep);
389 	  sine   = r * sin((GLdouble) i * 2.0 * PI / dstep);
390 	  glVertex2d( cosine, sine );
391 	}
392     glEnd();
393   glEndList();
394 }
395 
396 
397 /* xcPointLine2D is xcDisplayFunc for PointLines
398  * --------------------------------------------------------------
399  *                xcPointLine2D display a PointLines
400  *              Here I'm dealing with 'coor' structure
401  */
402 void
xcPointLine2D(struct Togl * togl)403 xcPointLine2D(struct Togl *togl)
404 {
405   int i;
406 
407   /*printf("In xcPointLine2D\n",NULL);
408   fflush(stdout);*/
409   glClear(GL_COLOR_BUFFER_BIT);
410   glLoadIdentity();
411   if (VPf.perspective)
412     glTranslated (0.0, 0.0, persp.shiftZ);
413   else
414     glTranslated(0.0, 0.0, -ort.size);
415 
416   /* fog & antialias */
417   xcFog       (togl, VPf.fog, VPf.perspective);
418   xcAntiAlias (VPf.antialias);
419 
420   glLineWidth( (GLfloat) VPf.PLlinewidth );
421   /*glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);*/
422   for(i = 1; i <= tmp_nobjects; i++) {
423     if ( (coor + *(iwksp + i))->flag == BOND )
424       {
425 	glBegin(GL_LINES);
426 	   /* glColor3fv( atcol[(coor + *(iwksp + i))->nat] ); */
427            if ( VPf.unibond) glColor3fv(unibondCol);
428            else glColor3fv( atm.col[(coor + *(iwksp + i))->sqn] );
429 	   glVertex3d( (coor + *(iwksp + i))->x1,
430 		       (coor + *(iwksp + i))->y1,
431 		       (coor + *(iwksp + i))->z1 );
432 	   glVertex3d( (coor + *(iwksp + i))->x2,
433 		       (coor + *(iwksp + i))->y2,
434 		       (coor + *(iwksp + i))->z2 );
435 	   glEnd();
436       }
437     if ( (coor + *(iwksp + i))->flag == ATOM )
438       {
439 	/* glColor3fv( atcol[(coor + *(iwksp + i))->nat] ); */
440 	glColor3fv( atm.col[(coor + *(iwksp + i))->sqn] );
441 	glPushMatrix();
442 	  glTranslated( (coor + *(iwksp + i))->x1,
443 			(coor + *(iwksp + i))->y1,
444 			(coor + *(iwksp + i))->z1 );
445 	  glCallList( PointList );
446 	glPopMatrix();
447       }
448   }
449 
450   /* check if coordinate sistem should be displayed */
451   if ( VPf.xyzOn ) xcDisplayXYZ();
452 
453   glFlush();
454   Togl_SwapBuffers(togl);
455 
456   /* every snapshot movie making */
457   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
458     fprintf(stderr,"making snapshot\n");
459     createMoviePPMFrame(togl);
460   }
461 }
462 
463 
xcBall2D(int iatom)464 void xcBall2D( int iatom ) {
465   GLint     nstep, i, atmn;
466   GLdouble  sine, cosine;
467   GLdouble  sizeArray[3];
468   GLuint    displayList[2];
469 
470   atmn   = (coor + iatom)->nat;
471   nstep = 3 * CalcTessFactor();
472   if ( nstep < 8 )  nstep = 8;
473 
474   sizeArray[0]   = rball[atmn];
475   sizeArray[1]   = (GLdouble) nstep;
476   sizeArray[2]   = (GLdouble) VPf.OUTlinewidth;
477   displayList[0] = findList1 (BALL, sizeArray, 3);
478   displayList[1] = findList1 (OUTLINEBALL, sizeArray, 3);
479 
480   if ( displayList[0] == 0 ) {
481     glNewList( makeModelPtr1 (BALL, sizeArray, 3),
482 	       GL_COMPILE_AND_EXECUTE );
483       glBegin(GL_POLYGON);
484       for(i=0; i < nstep; i++) {
485 	cosine = rball[atmn] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
486 	sine   = rball[atmn] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
487 	glVertex2d( cosine, sine );
488       }
489       glEnd();
490     glEndList();
491 
492     glNewList( makeModelPtr1 (OUTLINEBALL, sizeArray, 3),
493 	       GL_COMPILE_AND_EXECUTE );
494       glColor3f (0.0, 0.0, 0.0);
495       glBegin(GL_LINE_LOOP);
496       for(i=0; i < nstep; i++) {
497 	cosine = rball[atmn] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
498 	sine   = rball[atmn] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
499 	glVertex2d( cosine, sine );
500       }
501       glEnd();
502     glEndList();
503   } else {
504     /*glColor3fv (atm.col[(coor + iatom)->sqn]);*/
505     glCallList (displayList[0]);
506     glCallList (displayList[1]);
507   }
508 }
xcSmallBall2D(int iatom)509 void xcSmallBall2D( int iatom ) {
510   GLint     nstep, i;
511   GLdouble  sine, cosine;
512   GLdouble  sizeArray[3];
513   GLuint    displayList[2];
514 
515   nstep = 3 * CalcTessFactor();
516   if ( nstep < 8 )  nstep = 8;
517 
518   sizeArray[0]   = rball[1]; /* size of hydrogen atom */
519   sizeArray[1]   = (GLdouble) nstep;
520   sizeArray[2]   = (GLdouble) VPf.OUTlinewidth;
521   displayList[0] = findList1 (BALL, sizeArray, 3);
522   displayList[1] = findList1 (OUTLINEBALL, sizeArray, 3);
523 
524   if ( displayList[0] == 0 ) {
525     /*glColor3fv (atm.col[(coor + iatom)->sqn]);*/
526     glNewList( makeModelPtr1 (BALL, sizeArray, 3),
527 	       GL_COMPILE_AND_EXECUTE );
528       glBegin(GL_POLYGON);
529       for(i=0; i < nstep; i++) {
530 	cosine = rball[1] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
531 	sine   = rball[1] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
532 	glVertex2d( cosine, sine );
533       }
534       glEnd();
535     glEndList();
536 
537     glNewList( makeModelPtr1 (OUTLINEBALL, sizeArray, 3),
538 	       GL_COMPILE_AND_EXECUTE );
539       glColor3f (0.0, 0.0, 0.0);
540       glBegin(GL_LINE_LOOP);
541       for(i=0; i < nstep; i++) {
542 	cosine = rball[1] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
543 	sine   = rball[1] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
544 	glVertex2d( cosine, sine );
545       }
546       glEnd();
547     glEndList();
548   } else {
549     /*glColor3fv (atm.col[(coor + iatom)->sqn]);*/
550     glCallList (displayList[0]);
551     glCallList (displayList[1]);
552   }
553 }
xcBigBall2D(int iatom)554 void xcBigBall2D( int iatom ) {
555   GLint     nstep, i, atmn;
556   GLdouble  sine, cosine;
557   GLdouble  sizeArray[3];
558   GLuint    displayList[2];
559 
560   atmn   = (coor + iatom)->nat;
561   nstep = 6 * CalcTessFactor();
562   if ( nstep < 8 )  nstep = 8;
563 
564   sizeArray[0]   = atrad[atmn]; /* size of hydrogen atom */
565   sizeArray[1]   = (GLdouble) nstep;
566   sizeArray[2]   = (GLdouble) VPf.OUTlinewidth;
567   displayList[0] = findList1 (BALL, sizeArray, 3);
568   displayList[1] = findList1 (OUTLINEBALL, sizeArray, 3);
569 
570   if ( displayList[0] == 0 ) {
571     /*glColor3fv (atm.col[(coor + iatom)->sqn]);*/
572     glNewList( makeModelPtr1 (BALL, sizeArray, 3),
573 	       GL_COMPILE_AND_EXECUTE );
574       glBegin(GL_POLYGON);
575       for(i=0; i < nstep; i++) {
576 	cosine = atrad[atmn] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
577 	sine   = atrad[atmn] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
578 	glVertex2d( cosine, sine );
579       }
580       glEnd();
581     glEndList();
582 
583     glNewList( makeModelPtr1 (OUTLINEBALL, sizeArray, 3),
584 	       GL_COMPILE_AND_EXECUTE );
585       glColor3f (0.0, 0.0, 0.0);
586       glBegin(GL_LINE_LOOP);
587       for(i=0; i < nstep; i++) {
588 	cosine = atrad[atmn] * cos((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
589 	sine   = atrad[atmn] * sin((GLdouble) i * 2.0 * PI / (GLdouble) nstep);
590 	glVertex2d( cosine, sine );
591       }
592       glEnd();
593     glEndList();
594   } else {
595     /*glColor3fv (atm.col[(coor + iatom)->sqn]);*/
596     glCallList (displayList[0]);
597     glCallList (displayList[1]);
598   }
599 }
600 
601 
602 /* xcBallStick12D is xcDisplayFunc for Ballstick1,
603  * -----------------------------------------------
604  *             xcBallStick12D display a BallSticks1
605  *            Here I'm dealing with 'coor' structure
606  */
607 void
xcBallStick12D(struct Togl * togl)608 xcBallStick12D(struct Togl *togl)
609 {
610   register int i;
611   GLdouble x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
612 
613   glClear(GL_COLOR_BUFFER_BIT);
614   glLoadIdentity();
615   if (VPf.perspective)
616     glTranslated (0.0, 0.0, persp.shiftZ);
617   else
618     glTranslated(0.0, 0.0, -ort.size);
619 
620   /* fog & antialias */
621   xcFog       (togl, VPf.fog, VPf.perspective);
622   xcAntiAlias (VPf.antialias);
623 
624   glLineWidth( VPf.OUTlinewidth );
625   glEnable( GL_CULL_FACE );
626   glCullFace( GL_BACK );
627   for(i = 1; i <= tmp_nobjects; i++) {
628     if ( (coor + *(iwksp + i))->flag == ATOM ) {
629       glPushMatrix();
630       glTranslated( (coor + *(iwksp + i))->x1,
631 		    (coor + *(iwksp + i))->y1,
632 		    (coor + *(iwksp + i))->z1 );
633       glColor3fv (atm.col[(coor + *(iwksp + i))->sqn]);
634       xcBall2D (*(iwksp + i));
635       glPopMatrix();
636     }
637     else if ( (coor + *(iwksp + i))->flag == BOND ) {
638       MakeSticks1(*(iwksp + i),
639 		  &x1, &y1, &z1,   &x2, &y2, &z2,
640 		  &x3, &y3, &z3,   &x4, &y4, &z4);
641       glBegin(GL_POLYGON);
642         if ( VPf.unibond) glColor3fv(unibondCol);
643         else glColor3fv( atm.col[(coor + *(iwksp + i))->sqn] );
644 	glVertex3d( x1, y1, z1);
645 	glVertex3d( x2, y2, z2);
646 	glVertex3d( x3, y3, z3);
647 	glVertex3d( x4, y4, z4);
648       glEnd();
649 
650       glBegin(GL_LINE_LOOP);
651         glColor3f( 0.0, 0.0, 0.0 );
652 	glVertex3d( x1, y1, z1);
653 	glVertex3d( x2, y2, z2);
654 	glVertex3d( x3, y3, z3);
655 	glVertex3d( x4, y4, z4);
656       glEnd();
657     }
658   }
659   glDisable( GL_CULL_FACE );
660 
661   /* chack if coordinate sistem should be displayed */
662   if ( VPf.xyzOn ) xcDisplayXYZ();
663 
664   glFlush();
665   Togl_SwapBuffers(togl);
666 
667   /* every snapshot movie making */
668   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
669     fprintf(stderr,"making snapshot\n");
670     createMoviePPMFrame(togl);
671   }
672 }
673 
674 
xcPipeBall2D(struct Togl * togl)675 void xcPipeBall2D(struct Togl *togl)
676 {
677   register int i;
678 
679   glClear(GL_COLOR_BUFFER_BIT);
680   glLoadIdentity();
681   if (VPf.perspective)
682     glTranslated (0.0, 0.0, persp.shiftZ);
683   else
684     glTranslated(0.0, 0.0, -ort.size);
685 
686   /* fog & antialias */
687   xcFog       (togl, VPf.fog, VPf.perspective);
688   xcAntiAlias (VPf.antialias);
689 
690   glLineWidth( VPf.OUTlinewidth );
691   glEnable( GL_CULL_FACE );
692   glCullFace( GL_BACK );
693   for(i = 1; i <= tmp_nobjects; i++) {
694     if ( (coor + *(iwksp + i))->flag == ATOM ) {
695       glLineWidth( VPf.OUTlinewidth );
696       glPushMatrix();
697       glTranslated( (coor + *(iwksp + i))->x1,
698 		    (coor + *(iwksp + i))->y1,
699 		    (coor + *(iwksp + i))->z1 );
700       glColor3fv (atm.col[(coor + *(iwksp + i))->sqn]);
701       xcSmallBall2D (*(iwksp + i));
702       glPopMatrix();
703 
704       if ( VPf.labelsOn == 1 ) {
705 	makeAtomLabel2D ( *(iwksp + i), CENTERED_LABEL, CENTERED_LABEL );
706       }
707     }
708     else if ( (coor + *(iwksp + i))->flag == SELATOM ) {
709       glPushMatrix();
710       glTranslated( (coor + *(iwksp + i))->x1,
711 		    (coor + *(iwksp + i))->y1,
712 		    (coor + *(iwksp + i))->z1 );
713       glColor3fv( atcol[SELCOL] );
714       xcSmallBall2D (*(iwksp + i));
715       /*glCallList( (coor + *(iwksp + i))->list2 );*/
716       glPopMatrix();
717 
718       if ( VPf.labelsOn == 1 ) {
719 	makeAtomLabel2D ( *(iwksp + i), CENTERED_LABEL, CENTERED_LABEL );
720       }
721     }
722     else if ( (coor + *(iwksp + i))->flag == BOND ) {
723       glLineWidth( VPf.OUTlinewidth );
724       /* MakeSticks2(*(iwksp + i), (coor + *(iwksp + i))->nat); */
725       MakeSticks2(*(iwksp + i), (coor + *(iwksp + i))->sqn, PIPEBALL);
726     }
727     else if ( (coor + *(iwksp + i))->flag == SELBOND ) {
728       glLineWidth( VPf.OUTlinewidth );
729       MakeSticks2(*(iwksp + i), 0, PIPEBALL);
730     }
731     else if ( (coor + *(iwksp + i))->flag == SELLINE ) {
732       glLineStipple( 2, SELLINE_PAT );
733       glEnable(GL_LINE_STIPPLE);
734       glLineWidth( SELLINE_WIDTH );
735       glColor3fv( atcol[SELCOL] );
736       glBegin(GL_LINES);
737         glVertex3d( (coor + *(iwksp + i))->x1,
738 		    (coor + *(iwksp + i))->y1,
739 		    (coor + *(iwksp + i))->z1 );
740 	glVertex3d( (coor + *(iwksp + i))->x2,
741 		    (coor + *(iwksp + i))->y2,
742 		    (coor + *(iwksp + i))->z2 );
743       glEnd();
744       glDisable(GL_LINE_STIPPLE);
745     }
746     else if ( (coor + *(iwksp + i))->flag == FRAME ) {
747       if ( (coor + *(iwksp + i))->nat == 2 ) {
748 	glLineStipple(2, FRAME_PAT);
749 	glEnable(GL_LINE_STIPPLE);
750       }
751       glLineWidth( (GLfloat) VPf.framewidth );
752       glBegin(GL_LINES);
753         glColor3fv( framecol );
754 	glVertex3d( (coor + *(iwksp + i))->x1,
755 		    (coor + *(iwksp + i))->y1,
756 		    (coor + *(iwksp + i))->z1 );
757 	glVertex3d( (coor + *(iwksp + i))->x2,
758 		    (coor + *(iwksp + i))->y2,
759 		    (coor + *(iwksp + i))->z2 );
760       glEnd();
761       glDisable(GL_LINE_STIPPLE);
762     }
763   }
764   glDisable( GL_CULL_FACE );
765 
766   /* chack if coordinate sistem should be displayed */
767   if ( VPf.xyzOn ) xcDisplayXYZ();
768 
769   glFlush();
770   Togl_SwapBuffers(togl);
771 
772   /* every snapshot movie making */
773   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
774     fprintf(stderr,"making snapshot\n");
775     createMoviePPMFrame(togl);
776   }
777 }
778 
779 /* xcBallStick22D is xcDisplayFunc for Ballstick2,
780  * -----------------------------------------------
781  *             xcBallStick12D display a BallSticks2
782  *            Here I'm dealing with 'coor' structure
783  */
784 void
xcBallStick22D(struct Togl * togl)785 xcBallStick22D(struct Togl *togl)
786 {
787   register int i;
788 
789   glClear(GL_COLOR_BUFFER_BIT);
790   glLoadIdentity();
791   if (VPf.perspective)
792     glTranslated (0.0, 0.0, persp.shiftZ);
793   else
794     glTranslated(0.0, 0.0, -ort.size);
795 
796   /* fog & antialias */
797   xcFog       (togl, VPf.fog, VPf.perspective);
798   xcAntiAlias (VPf.antialias);
799 
800   glLineWidth( VPf.OUTlinewidth );
801   glEnable( GL_CULL_FACE );
802   glCullFace( GL_BACK );
803   for(i = 1; i <= tmp_nobjects; i++) {
804     if ( (coor + *(iwksp + i))->flag == ATOM ) {
805       glPushMatrix();
806       glTranslated( (coor + *(iwksp + i))->x1,
807 		    (coor + *(iwksp + i))->y1,
808 		    (coor + *(iwksp + i))->z1 );
809       glColor3fv (atm.col[(coor + *(iwksp + i))->sqn]);
810       xcBall2D (*(iwksp + i));
811       glPopMatrix();
812     }
813     else if ( (coor + *(iwksp + i))->flag == BOND ) {
814       /* MakeSticks2(*(iwksp + i), (coor + *(iwksp + i))->nat); */
815       MakeSticks2(*(iwksp + i), (coor + *(iwksp + i))->sqn, BALL);
816     }
817   }
818   glDisable( GL_CULL_FACE );
819 
820   /* chack if coordinate sistem should be displayed */
821   if ( VPf.xyzOn ) xcDisplayXYZ();
822 
823   glFlush();
824   Togl_SwapBuffers(togl);
825 
826   /* every snapshot movie making */
827   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
828     fprintf(stderr,"making snapshot\n");
829     createMoviePPMFrame(togl);
830   }
831 }
832 
833 
xcSpaceFill2D(struct Togl * togl)834 void xcSpaceFill2D(struct Togl *togl)
835 {
836   register int i;
837 
838   glClear(GL_COLOR_BUFFER_BIT);
839   glLoadIdentity();
840   if (VPf.perspective)
841     glTranslated (0.0, 0.0, persp.shiftZ);
842   else
843     glTranslated(0.0, 0.0, -ort.size);
844 
845   /* fog & antialias */
846   xcFog       (togl, VPf.fog, VPf.perspective);
847   xcAntiAlias (VPf.antialias);
848 
849   glLineWidth( VPf.OUTlinewidth );
850   glEnable( GL_CULL_FACE );
851   glCullFace( GL_BACK );
852   for(i = 1; i <= tmp_nobjects; i++) {
853     if ( (coor + *(iwksp + i))->flag == ATOM ) {
854       glLineWidth( VPf.OUTlinewidth );
855       glPushMatrix();
856       glTranslated( (coor + *(iwksp + i))->x1,
857 		    (coor + *(iwksp + i))->y1,
858 		    (coor + *(iwksp + i))->z1 );
859       glColor3fv (atm.col[(coor + *(iwksp + i))->sqn]);
860       xcBigBall2D (*(iwksp + i));
861       glPopMatrix();
862       if ( VPf.labelsOn == 1 ) {
863 	makeAtomLabel2D ( *(iwksp + i), CENTERED_LABEL, CENTERED_LABEL );
864       }
865     }
866     else if ( (coor + *(iwksp + i))->flag == SELATOM ) {
867       glPushMatrix();
868       glTranslated( (coor + *(iwksp + i))->x1,
869 		    (coor + *(iwksp + i))->y1,
870 		    (coor + *(iwksp + i))->z1 );
871       glColor3fv( atcol[SELCOL] );
872       xcBigBall2D (*(iwksp + i));
873       glPopMatrix();
874 
875       if ( VPf.labelsOn == 1 ) {
876 	makeAtomLabel2D ( *(iwksp + i), CENTERED_LABEL, CENTERED_LABEL );
877       }
878     }
879     else if ( (coor + *(iwksp + i))->flag == SELLINE ) {
880       glLineStipple( 2, SELLINE_PAT );
881       glEnable(GL_LINE_STIPPLE);
882       glLineWidth( SELLINE_WIDTH*2 );
883       glColor3fv( atcol[SELCOL] );
884       glBegin(GL_LINES);
885         glVertex3d( (coor + *(iwksp + i))->x1,
886 		    (coor + *(iwksp + i))->y1,
887 		    (coor + *(iwksp + i))->z1 );
888 	glVertex3d( (coor + *(iwksp + i))->x2,
889 		    (coor + *(iwksp + i))->y2,
890 		    (coor + *(iwksp + i))->z2 );
891       glEnd();
892       glDisable(GL_LINE_STIPPLE);
893     }
894     else if ( (coor + *(iwksp + i))->flag == FRAME ) {
895       if ( (coor + *(iwksp + i))->nat == 2 ) {
896 	glLineStipple(2, FRAME_PAT);
897 	glEnable(GL_LINE_STIPPLE);
898       }
899       glLineWidth( (GLfloat) VPf.framewidth );
900       glBegin(GL_LINES);
901         glColor3fv( framecol );
902 	glVertex3d( (coor + *(iwksp + i))->x1,
903 		    (coor + *(iwksp + i))->y1,
904 		    (coor + *(iwksp + i))->z1 );
905 	glVertex3d( (coor + *(iwksp + i))->x2,
906 		    (coor + *(iwksp + i))->y2,
907 		    (coor + *(iwksp + i))->z2 );
908       glEnd();
909       glDisable(GL_LINE_STIPPLE);
910     }
911   }
912   glDisable( GL_CULL_FACE );
913 
914   /* chack if coordinate sistem should be displayed */
915   if ( VPf.xyzOn ) xcDisplayXYZ();
916 
917   glFlush();
918   Togl_SwapBuffers(togl);
919 
920   /* every snapshot movie making */
921   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
922     fprintf(stderr,"making snapshot\n");
923     createMoviePPMFrame(togl);
924   }
925 }
926 
927 
928 /*****************************************************************************/
929 /* Do we have 2D or 3D ?????? */
930 void
EnableOr2D_Or3D(void)931 EnableOr2D_Or3D(void)
932 {
933   register int i;
934   GLenum LIGHT[8] = { GL_LIGHT0,
935 		      GL_LIGHT1,
936 		      GL_LIGHT2,
937 		      GL_LIGHT3,
938 		      GL_LIGHT4,
939 		      GL_LIGHT5,
940 		      GL_LIGHT6,
941 		      GL_LIGHT7 };
942 
943   if ( dimType == XC_2D )
944     {
945       glDisable( GL_DEPTH_TEST );
946       glDisable( GL_LIGHTING );
947       glDisable( GL_DITHER );
948       glShadeModel( GL_FLAT );
949       for (i=0; i<MAX_NUMBER_OF_LIGHTS; i++)
950 	glDisable( LIGHT[i] );
951     }
952   else if (dimType == XC_3D )
953     {
954       /*printf("XC_3D\n",NULL);*/
955       if (is.smooth) glShadeModel( GL_SMOOTH );
956       else glShadeModel( GL_FLAT );
957       glEnable( GL_DITHER );
958       glEnable( GL_DEPTH_TEST );
959       glEnable( GL_LIGHTING );
960       glEnable( GL_LIGHT0 );
961       for (i=0; i<MAX_NUMBER_OF_LIGHTS; i++)
962 	if ( light[i].isenabled )
963 	  glEnable( LIGHT[i] );
964 
965       /* turn-off 2D antialiasing */
966       xcAntiAlias (GL_FALSE);
967     }
968 }
969 
970 
971 /********************************************
972  *   xcPrimitives (sphere, cylinder, bonds)
973  ********************************************/
974 void
xcWireSphere(GLdouble radius)975 xcWireSphere (GLdouble radius)
976 {
977   GLint nstep;
978   GLUquadricObj *quadObj;
979   GLdouble      sizeArray[3];
980   GLuint        displayList;
981 
982   nstep = SPHERE_TESS_PREFACTOR * CalcTessFactor();
983   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
984 
985   /* nstep = 4 * (GLint) ( radius * VPf.VPfactor / tessFactor ); */
986   /*nstep = (GLint) (2 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
987 
988   /* nstep shouldn't be lower than 8 and greater than XX */
989   if ( nstep < 6 ) nstep = 6;
990   /* if ( nstep > 16 ) nstep = 16; */
991 
992   sizeArray[0]  = radius;
993   sizeArray[1]  = (double) nstep;
994   sizeArray[2]  = (double) VPf.WF3Dlinewidth;
995   displayList   = findList1 (SPHEREWIRE, sizeArray, 3);
996 
997   if ( displayList == 0 ) {
998     glNewList( makeModelPtr1 (SPHEREWIRE, sizeArray, 3),
999 	       GL_COMPILE_AND_EXECUTE );
1000       glLineWidth (VPf.WF3Dlinewidth);
1001       quadObj = gluNewQuadric ();
1002       gluQuadricDrawStyle (quadObj, GLU_LINE);
1003       gluQuadricNormals (quadObj, GLU_SMOOTH);
1004       gluSphere (quadObj, radius, 2*nstep, nstep);
1005     glEndList();
1006   } else {
1007     glCallList(displayList);
1008   }
1009 }
1010 
1011 
1012 void
xcSolidSphere(GLdouble radius)1013 xcSolidSphere (GLdouble radius)
1014 {
1015   GLint         nstep;
1016   GLUquadricObj *quadObj;
1017   GLdouble      sizeArray[2];
1018   GLuint        displayList;
1019 
1020   nstep = SPHERE_TESS_PREFACTOR * CalcTessFactor();
1021   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
1022 
1023   /*if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) tessFactor *= 4.0;*/
1024   /* nstep = 4 * (GLint) ( radius * VPf.VPfactor / tessFactor ); */
1025   /*nstep = (GLint) (2 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
1026 
1027   /* nstep shouldn't be lower than 8 and gretaer than XX */
1028   if ( nstep < 6 )  nstep = 6;
1029   /*if ( nstep > 16 ) nstep = 16;*/
1030 
1031   sizeArray[0]	= radius;
1032   sizeArray[1]  = (double) nstep;
1033   displayList   = findList1 (SPHERESOLID, sizeArray, 2);
1034 
1035   if ( displayList == 0 ) {
1036     glNewList( makeModelPtr1 (SPHERESOLID, sizeArray, 2),
1037 	       GL_COMPILE_AND_EXECUTE );
1038       quadObj = gluNewQuadric ();
1039       gluQuadricDrawStyle (quadObj, GLU_FILL);
1040       gluQuadricNormals (quadObj, GLU_SMOOTH);
1041       gluSphere (quadObj, radius, 2*nstep, nstep);
1042     glEndList();
1043   } else {
1044     glCallList(displayList);
1045   }
1046 }
1047 
1048 
1049 void
xcWireCylinder(GLdouble radius,GLdouble height)1050 xcWireCylinder (GLdouble radius, GLdouble height)
1051 {
1052   GLint nstep;
1053   GLUquadricObj *quadObj;
1054   GLdouble      sizeArray[4];
1055   GLuint        displayList;
1056 
1057   nstep = (int) (BOND_TESS_PREFACTOR * (float)CalcTessFactor());
1058   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
1059   /*if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) tessFactor *= 4.0;*/
1060   /* nstep = 4 * (GLint) ( radius * VPf.VPfactor / tessFactor ); */
1061   /*nstep = (GLint) (1.3 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
1062 
1063   /* nstep shouldn't be lower than 6 and gretaer than XX */
1064   if ( nstep < 6 ) nstep = 6;
1065   /*if ( nstep > 10 ) nstep = 10;*/
1066 
1067   sizeArray[0]  = radius;
1068   sizeArray[1]  = height;
1069   sizeArray[2]  = (double) nstep;
1070   sizeArray[3]  = (double) VPf.WF3Dlinewidth;
1071   displayList   = findList1 (CYLINDERWIRE, sizeArray, 4);
1072 
1073   if ( displayList == 0 ) {
1074     glNewList( makeModelPtr1 (CYLINDERWIRE, sizeArray, 4),
1075 	       GL_COMPILE_AND_EXECUTE );
1076       glLineWidth (VPf.WF3Dlinewidth);
1077       quadObj = gluNewQuadric ();
1078       gluQuadricDrawStyle (quadObj, GLU_LINE);
1079       gluQuadricNormals (quadObj, GLU_SMOOTH);
1080       gluCylinder (quadObj, radius, radius, height, nstep, 1);
1081     glEndList();
1082   } else {
1083     glCallList(displayList);
1084   }
1085 }
1086 
1087 void
xcSolidCylinder(GLdouble radius,GLdouble height)1088 xcSolidCylinder (GLdouble radius, GLdouble height)
1089 {
1090   GLint nstep;
1091   GLUquadricObj *quadObj;
1092   GLdouble      sizeArray[3];
1093   GLuint        displayList;
1094 
1095   nstep = (int) (BOND_TESS_PREFACTOR * (float)CalcTessFactor());
1096   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
1097   /* nstep = 4 * (GLint) ( radius * VPf.VPfactor / tessFactor ); */
1098   /*nstep = (GLint) (1.3 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
1099 
1100   /* nstep shouldn't be lower than 6 and gretaer than XX */
1101   if ( nstep < 6 ) nstep = 6;
1102   /* if ( nstep > 10 ) nstep = 10; */
1103 
1104   sizeArray[0]  = radius;
1105   sizeArray[1]  = height;
1106   sizeArray[2]  = (double) nstep;
1107   displayList   = findList1 (CYLINDERSOLID, sizeArray, 3);
1108 
1109   if ( displayList == 0 ) {
1110     glNewList( makeModelPtr1 (CYLINDERSOLID, sizeArray, 3),
1111 	       GL_COMPILE_AND_EXECUTE );
1112       quadObj = gluNewQuadric ();
1113       gluQuadricDrawStyle (quadObj, GLU_FILL);
1114       gluQuadricNormals (quadObj, GLU_SMOOTH);
1115       gluCylinder (quadObj, radius, radius, height, nstep, 1);
1116 
1117       /* lower-end disk */
1118       quadObj = gluNewQuadric ();
1119       gluQuadricDrawStyle (quadObj, GLU_FILL);
1120       gluQuadricNormals (quadObj, GLU_FLAT);
1121       gluQuadricOrientation( quadObj, GLU_INSIDE );
1122       gluDisk( quadObj, 0.0, radius, nstep, 1 );
1123 
1124       /* upper end disk */
1125       quadObj = gluNewQuadric ();
1126       gluQuadricDrawStyle (quadObj, GLU_FILL);
1127       gluQuadricNormals (quadObj, GLU_FLAT);
1128       gluQuadricOrientation( quadObj, GLU_OUTSIDE );
1129       glPushMatrix();
1130         glTranslated(0.0, 0.0, height);
1131 	gluDisk( quadObj, 0.0, radius, nstep, 1 );
1132       glPopMatrix();
1133     glEndList();
1134   } else {
1135     glCallList(displayList);
1136   }
1137 }
1138 
1139 
1140 void
xcSolidBond(GLdouble radius,GLdouble height,int bondFlag)1141 xcSolidBond (GLdouble radius, GLdouble height, int bondFlag)
1142 {
1143   GLint nstep;
1144   GLUquadricObj *quadObj;
1145   GLdouble      sizeArray[4];
1146   GLuint        displayList;
1147 
1148 
1149   nstep = (int) (BOND_TESS_PREFACTOR * (float) CalcTessFactor());
1150   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
1151 
1152   /* nstep = 4 * (GLint) ( radius * VPf.VPfactor / tessFactor ); */
1153   /*nstep = (GLint) (1.3 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
1154 
1155   /* nstep shouldn't be lower than 6 and gretaer than XX */
1156   if ( nstep < 6 ) nstep = 6;
1157 
1158   sizeArray[0]  = radius;
1159   sizeArray[1]  = height;
1160   sizeArray[2]  = (double) nstep;
1161   sizeArray[3]  = (double) bondFlag;
1162   displayList   = findList1 (BONDSOLID, sizeArray, 4);
1163 
1164   if ( displayList == 0 ) {
1165     glNewList( makeModelPtr1 (BONDSOLID, sizeArray, 4),
1166 	       GL_COMPILE_AND_EXECUTE );
1167       quadObj = gluNewQuadric ();
1168       gluQuadricDrawStyle (quadObj, GLU_FILL);
1169       gluQuadricNormals (quadObj, GLU_SMOOTH);
1170       gluCylinder (quadObj, radius, radius, height, nstep, 1);
1171 
1172       if ( (bondFlag == BOND_ATOM_TO_MIDBOND) ||
1173 	   (bondFlag == BOND_ATOM_TO_ATOM) ) {
1174 	/* lower-end sphere */
1175 	quadObj = gluNewQuadric ();
1176 	gluQuadricDrawStyle (quadObj, GLU_FILL);
1177 	gluQuadricNormals (quadObj, GLU_SMOOTH);
1178 	gluQuadricOrientation( quadObj, GLU_OUTSIDE );
1179 	gluSphere (quadObj, radius, nstep, nstep);
1180       }
1181 
1182       if ( (bondFlag == BOND_ATOM_TO_ATOM ) ||
1183 	   (bondFlag == BOND_MIDBOND_TO_ATOM) ) {
1184 	/* upper-end sphere */
1185 	quadObj = gluNewQuadric ();
1186 	gluQuadricDrawStyle (quadObj, GLU_FILL);
1187 	gluQuadricNormals (quadObj, GLU_SMOOTH);
1188 	gluQuadricOrientation( quadObj, GLU_OUTSIDE );
1189 	glPushMatrix();
1190           glTranslated(0.0, 0.0, height);
1191           gluSphere (quadObj, radius, nstep, nstep);
1192 	glPopMatrix();
1193       }
1194     glEndList();
1195   } else {
1196     glCallList(displayList);
1197   }
1198 }
1199 
1200 
1201 /*  Render solid Cone.
1202  */
1203 void
xcSolidCone(GLdouble baseradius,GLdouble topradius,GLdouble height)1204 xcSolidCone (GLdouble baseradius, GLdouble topradius, GLdouble height)
1205 {
1206   GLint nstep;
1207   GLUquadricObj *quadObj;
1208   GLdouble      sizeArray[4];
1209   GLuint        displayList;
1210   /*double tessFactor = VPf.tessFactor;*/
1211 
1212   nstep = (int) (BOND_TESS_PREFACTOR * (float) CalcTessFactor());
1213   if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) nstep /= 4.0;
1214 
1215   /*if ( tr.b1motion || tr.b2motion || tr.shiftB1motion ) tessFactor *= 4.0;*/
1216   /* nstep = 4 * (GLint) ( baseradius * VPf.VPfactor / tessFactor ); */
1217   /*nstep = (GLint) (1.3 * APPR_SCREENSIZE / (tessFactor * ort.size));*/
1218 
1219   /* nstep shouldn't be lower than 6 and gretaer than XX */
1220   if ( nstep < 6 ) nstep = 6;
1221 
1222   sizeArray[0]  = baseradius;
1223   sizeArray[1]  = topradius;
1224   sizeArray[2]  = height;
1225   sizeArray[3]  = (double) nstep;
1226   displayList   = findList1 (CONESOLID, sizeArray, 4);
1227 
1228   if ( displayList == 0 ) {
1229     glNewList( makeModelPtr1 (CONESOLID, sizeArray, 4),
1230 	       GL_COMPILE_AND_EXECUTE );
1231       quadObj = gluNewQuadric ();
1232       gluQuadricDrawStyle (quadObj, GLU_FILL);
1233       gluQuadricNormals (quadObj, GLU_SMOOTH);
1234       gluCylinder (quadObj, baseradius, topradius, height, nstep, 1);
1235 
1236       /* lower end disk */
1237       quadObj = gluNewQuadric ();
1238       gluQuadricDrawStyle (quadObj, GLU_FILL);
1239       gluQuadricNormals (quadObj, GLU_FLAT);
1240       gluQuadricOrientation( quadObj, GLU_INSIDE );
1241       gluDisk( quadObj, 0.0, baseradius, nstep, 1 );
1242     glEndList();
1243   } else {
1244     glCallList(displayList);
1245   }
1246 }
1247 
_ambient_by_diffuse(GLfloat dst[4],GLfloat scale,GLfloat src[4])1248 static void _ambient_by_diffuse(GLfloat dst[4], GLfloat scale, GLfloat src[4]) {
1249   COPY_AND_SCALE_V(4, dst, scale, src);
1250   CLAMP_V(4, 1.0, dst);
1251 }
1252 
1253 #define WIRE    GL_FALSE
1254 #define SOLID   GL_TRUE
1255 void
xcRenderSolidBalls3D(void)1256 xcRenderSolidBalls3D(void) {
1257   register int i;
1258   GLfloat ambient[4];
1259 
1260   for(i = 1; i <= natoms; i++) {
1261     glPushMatrix();
1262       glTranslated( *(xat + i), *(yat + i), *(zat + i) );
1263       if ( AtCol_Ambient_by_Diffuse == 1.0)
1264 	glMaterialfv ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, atm.col[i] );
1265       else {
1266 	_ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[i]);
1267 	glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1268 	glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[i]);
1269       }
1270 
1271       /* new */
1272       /*glMaterialfv( GL_FRONT, GL_SPECULAR, atm.col[i]);*/
1273       if (is.pipemode) {
1274 	xcSolidSphere( rball[1] );
1275       } else {
1276 	xcSolidSphere( rball[ *(nat + i) ] );
1277       }
1278     glPopMatrix();
1279   }
1280 }
1281 
1282 
1283 void
xcRenderWireBalls3D(void)1284 xcRenderWireBalls3D(void) {
1285   register int i;
1286   GLfloat ambient[4];
1287 
1288   for(i = 1; i <= natoms; i++) {
1289     glPushMatrix();
1290       glTranslated( *(xat + i), *(yat + i), *(zat + i) );
1291 
1292       if ( AtCol_Ambient_by_Diffuse == 1.0)
1293 	glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, atm.col[i] );
1294       else {
1295 	_ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[i]);
1296 	glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1297 	glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[i]);
1298       }
1299 
1300       if (is.pipemode) {
1301 	xcWireSphere( rball[1] );
1302       } else {
1303 	xcWireSphere( rball[ *(nat + i) ] );
1304       }
1305     glPopMatrix();
1306   }
1307 }
1308 
1309 
1310 void
xcRenderBonds(GLenum type)1311 xcRenderBonds(GLenum type)
1312 {
1313   register int i;
1314   GLfloat ambient[4];
1315 
1316   if ( VPf.unibond) {
1317     if ( AtCol_Ambient_by_Diffuse == 1.0)
1318       glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, unibondCol);
1319     else {
1320       _ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, unibondCol);
1321       glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1322       glMaterialfv (GL_FRONT, GL_DIFFUSE, unibondCol);
1323     }
1324   }
1325 
1326   if ( type == GL_FILL ) {
1327     /* hack for white bonds !!! */
1328 
1329     /*fprintf(stderr,"Bonds GL-coor:\n----------\n");*/
1330     for(i = 1; i <= nbonds; i++) {
1331       glPushMatrix();
1332       /*
1333         fprintf(stderr,"-----     %f %f %f   %f %f %f %f\n",
1334 		(coor3D + i)->x1,
1335 		(coor3D + i)->y1,
1336 		(coor3D + i)->z1,
1337 		(coor3D + i)->fibond,
1338 		(coor3D + i)->xrvb,
1339 		(coor3D + i)->yrvb,
1340 		(coor3D + i)->zrvb );
1341       */
1342 	glTranslated( (coor3D + i)->x1,
1343 		      (coor3D + i)->y1,
1344 		      (coor3D + i)->z1 );
1345 	glRotated( (coor3D + i)->fibond,
1346 		   (coor3D + i)->xrvb,
1347 		   (coor3D + i)->yrvb,
1348 		   (coor3D + i)->zrvb );
1349 	if (!VPf.unibond) {
1350 	  if ( AtCol_Ambient_by_Diffuse == 1.0)
1351 	    glMaterialfv( GL_FRONT,
1352 			  GL_AMBIENT_AND_DIFFUSE, atm.col[(coor3D + i)->sqn] );
1353 	  else {
1354 	    _ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[(coor3D + i)->sqn]);
1355 	    glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1356 	    glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[(coor3D + i)->sqn]);
1357 	  }
1358 	}
1359 	xcSolidBond( rrod, (coor3D + i)->bondl, (coor3D + i)->bondFlag );
1360 	/*xcSolidCylinder( rrod, (coor3D + i)->bondl );*/
1361 	glPopMatrix();
1362     }
1363   } else {
1364     /* GL_LINE */
1365     for(i = 1; i <= nbonds; i++) {
1366       glPushMatrix();
1367         glTranslated( (coor3D + i)->x1,
1368 		      (coor3D + i)->y1,
1369 		      (coor3D + i)->z1 );
1370 	glRotated( (coor3D + i)->fibond,
1371 		   (coor3D + i)->xrvb,
1372 		   (coor3D + i)->yrvb,
1373 		   (coor3D + i)->zrvb );
1374 	if (!VPf.unibond) {
1375 	  if ( AtCol_Ambient_by_Diffuse == 1.0)
1376 	    glMaterialfv( GL_FRONT,
1377 			  GL_AMBIENT_AND_DIFFUSE, atm.col[(coor3D + i)->sqn] );
1378 	  else {
1379 	    _ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[(coor3D + i)->sqn]);
1380 	    glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1381 	    glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[(coor3D + i)->sqn]);
1382 	  }
1383 	}
1384 	xcWireCylinder( rrod, (coor3D + i)->bondl );
1385       glPopMatrix();
1386     }
1387   }
1388 }
1389 
1390 
1391 void
xcRenderSolidSpaceFills3D(void)1392 xcRenderSolidSpaceFills3D(void)
1393 {
1394   register int i;
1395   GLfloat ambient[4];
1396 
1397   for(i = 1; i <= natoms; i++) {
1398     glPushMatrix();
1399       glTranslated( *(xat + i), *(yat + i), *(zat + i) );
1400       if ( AtCol_Ambient_by_Diffuse == 1.0)
1401 	glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, atm.col[i] );
1402       else {
1403 	_ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[i]);
1404 	glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1405 	glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[i]);
1406       }
1407 
1408       /* new */
1409       /*glMaterialfv( GL_FRONT, GL_SPECULAR, atm.col[i]);*/
1410 
1411       xcSolidSphere( atrad[ *(nat + i) ] );
1412     glPopMatrix();
1413   }
1414 }
1415 
1416 
1417 void
xcRenderWireSpaceFills3D(void)1418 xcRenderWireSpaceFills3D(void)
1419 {
1420   register int i;
1421   GLfloat ambient[4];
1422 
1423   for(i = 1; i <= natoms; i++) {
1424     glPushMatrix();
1425       glTranslated( *(xat + i), *(yat + i), *(zat + i) );
1426 
1427       if ( AtCol_Ambient_by_Diffuse == 1.0)
1428 	glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, atm.col[i] );
1429       else {
1430 	_ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, atm.col[i]);
1431 	glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1432 	glMaterialfv (GL_FRONT, GL_DIFFUSE, atm.col[i]);
1433       }
1434       xcWireSphere( atrad[ *(nat + i) ] );
1435     glPopMatrix();
1436   }
1437 }
1438 
1439 
1440 void
xcRenderSolidFrame3D(void)1441 xcRenderSolidFrame3D(void) {
1442   register int i;
1443   GLfloat ambient[4];
1444 
1445   if ( AtCol_Ambient_by_Diffuse == 1.0)
1446     glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, framecol );
1447   else {
1448     _ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, framecol );
1449     glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1450     glMaterialfv (GL_FRONT, GL_DIFFUSE, framecol);
1451   }
1452 
1453   for(i = nbonds + 1; i <= nframes + nbonds; i++) {
1454     /* if frametype == 1 -> draw a xcSolidBond frame else,
1455      * draw a line_stipple frame
1456      */
1457     if ( (coor3D + i)->nat == 1 ) {
1458       glPushMatrix();
1459         glTranslated( (coor3D + i)->x1,
1460 		      (coor3D + i)->y1,
1461 		      (coor3D + i)->z1 );
1462 	glRotated( (coor3D + i)->fibond,
1463 		   (coor3D + i)->xrvb,
1464 		   (coor3D + i)->yrvb,
1465 		   (coor3D + i)->zrvb );
1466 	xcSolidBond ( rframe, (coor3D + i)->bondl, BOND_ATOM_TO_ATOM );
1467       glPopMatrix();
1468     }
1469     else xcLineStippleFrame(i - nbonds);
1470   }
1471 }
1472 
1473 
1474 void
xcRenderWireFrame3D(void)1475 xcRenderWireFrame3D(void) {
1476   register int i;
1477   GLfloat ambient[4];
1478 
1479   if ( AtCol_Ambient_by_Diffuse == 1.0)
1480     glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, framecol );
1481   else {
1482     _ambient_by_diffuse(ambient, AtCol_Ambient_by_Diffuse, framecol );
1483     glMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
1484     glMaterialfv (GL_FRONT, GL_DIFFUSE, framecol);
1485   }
1486 
1487   for(i = nbonds + 1; i <= nframes + nbonds; i++) {
1488     if ( (coor3D + i)->nat == 1 ) {
1489       glPushMatrix();
1490         glTranslated( (coor3D + i)->x1,
1491 		      (coor3D + i)->y1,
1492 		      (coor3D + i)->z1 );
1493 	glRotated( (coor3D + i)->fibond,
1494 		   (coor3D + i)->xrvb,
1495 		   (coor3D + i)->yrvb,
1496 		   (coor3D + i)->zrvb );
1497 	xcWireCylinder ( rframe, (coor3D + i)->bondl );
1498       glPopMatrix();
1499     }
1500     else xcLineStippleFrame(i - nbonds);
1501   }
1502 }
1503 
1504 
1505 void
xcRenderLineFrame3D(void)1506 xcRenderLineFrame3D(void) {
1507   register int i;
1508 
1509   glColor3fv( framecol );
1510   /* temporary disable lighting, dihtering */
1511   glCallList( tempDisable3Dlist );
1512   for(i = 1; i <= nframes; i++) {
1513     if ( *(frametype + i) != 1 ) {
1514       glLineStipple(2, FRAME_PAT);
1515       glEnable(GL_LINE_STIPPLE);
1516     }
1517     glCallList(tempDisable3Dlist);
1518     glLineWidth( (GLfloat) VPf.framewidth );
1519     glBegin(GL_LINES);
1520       glVertex3d( *(xframe + i), *(yframe + i), *(zframe + i) );
1521       glVertex3d( *(xframe2 + i), *(yframe2 + i), *(zframe2 + i) );
1522     glEnd();
1523     glDisable(GL_LINE_STIPPLE);
1524     glCallList(tempEnable3Dlist);
1525   }
1526   /* now again enable lighting, dihtering */
1527   glCallList( tempEnable3Dlist );
1528   glEndList();
1529 }
1530 
1531 
1532 static void
xcLineStippleFrame(int ii)1533 xcLineStippleFrame(int ii)
1534 {
1535   glLineStipple(2, FRAME_PAT);
1536   glEnable(GL_LINE_STIPPLE);
1537   glCallList( tempDisable3Dlist );
1538   glColor3fv( framecol );
1539   glLineWidth( (GLfloat) VPf.framewidth );
1540   glBegin(GL_LINES);
1541     glVertex3d( *(xframe + ii), *(yframe + ii), *(zframe + ii) );
1542     glVertex3d( *(xframe2 + ii), *(yframe2 + ii), *(zframe2 + ii) );
1543   glEnd();
1544   glCallList( tempEnable3Dlist );
1545   glDisable(GL_LINE_STIPPLE);
1546 }
1547 
1548 
1549 static void
MatInv33_44(double m[4][4],double minv[4][4],double * det)1550 MatInv33_44(double m[4][4], double minv[4][4], double *det)
1551 {
1552   double f0, f1, f2, idet;
1553   register int i, j;
1554 
1555   for(i=0; i<4; i++)
1556     for(j=0; j<4; j++)
1557       minv[i][j] = m[i][j];
1558 
1559   f0 = m[1][1]*m[2][2] - m[1][2]*m[2][1];
1560   f1 = m[1][2]*m[2][0] - m[1][0]*m[2][2];
1561   f2 = m[1][0]*m[2][1] - m[1][1]*m[2][0];
1562 
1563   *det = m[0][0]*f0 + m[0][1]*f1 + m[0][2]*f2;
1564 
1565   if (*det < 1.0e-10) {
1566     /* determinant is very small; return the minv=m */
1567     return;
1568   }
1569 
1570   idet = 1.0 / *det;
1571 
1572   minv[0][0] = f0 * idet;
1573   minv[1][0] = f1 * idet;
1574   minv[2][0] = f2 * idet;
1575 
1576   f0 = m[0][0] * idet;
1577   f1 = m[0][1] * idet;
1578   f2 = m[0][2] * idet;
1579 
1580   minv[0][1] = f2*m[2][1] - f1*m[2][2];
1581   minv[1][1] = f0*m[2][2] - f2*m[2][0];
1582   minv[2][1] = f1*m[2][0] - f0*m[2][1];
1583   minv[0][2] = f1*m[1][2] - f2*m[1][1];
1584   minv[1][2] = f2*m[1][0] - f0*m[1][2];
1585   minv[2][2] = f0*m[1][1] - f1*m[1][0];
1586 }
1587 
1588 
1589 static void
MultMat44_33Vec3(double mat[4][4],double vec[3],double res[3])1590 MultMat44_33Vec3(double mat[4][4], double vec[3], double res[3])
1591 {
1592   int i;
1593   /* mat is !!!COLUMN!!!, not row major mode (due to OGL) */
1594   for(i=0; i<3; i++)
1595     res[i] = mat[0][i] * vec[0] + mat[1][i] * vec[1] + mat[2][i] * vec[2];
1596 }
1597 
1598 
_makeAtomLabels3D(double * rad)1599 static void _makeAtomLabels3D(double *rad) {
1600   register int i;
1601   double       dummy, minv[4][4], v[3], z[3], sizeF;
1602 
1603   sizeF = 2.0 * VPf.VPfactor;
1604 
1605   /* disable lighting & dihtering ... */
1606   glCallList( tempDisable3Dlist );
1607 
1608   for(i = 1; i <= natoms; i++) {
1609 
1610     z[2] = 1.01 * rad[*(nat + i)];
1611 
1612     if ( !globalAtomLabel.base && ! atomLabel[i].base ) {
1613       char    *label;
1614       GLfloat *color;
1615       /*
1616 	 render default raster font
1617       */
1618       if (atomLabel[i].base) {
1619 	label = atomLabel[i].label;
1620 	color = atomLabel[i].bright_color;
1621 	if (atomLabel[i].tkfont) {
1622 	  z[0] = (double) ( -Tk_TextWidth(atomLabel[i].tkfont, label, strlen(label)) ) / sizeF;
1623 	} else {
1624 	  z[0] = (double) (-atomLabel[i].width * (int)strlen(label)) / sizeF;
1625 	}
1626 	z[1] = (double) (-atomLabel[i].height) / sizeF;
1627       } else {
1628 	label = element[*(nat + i)];
1629 	color = globalAtomLabel.bright_color;
1630 	z[0]  = rf.w2 * (double)strlen(label);
1631 	z[1]  = rf.h2;
1632       }
1633 
1634       MatInv33_44((double (*)[4]) vec.crdvec, minv, &dummy);
1635       MultMat44_33Vec3(minv, z, v);
1636       glColor3fv (color);
1637       glRasterPos3d ( *(xat + i) + v[0],
1638 		      *(yat + i) + v[1],
1639 		      *(zat + i) + v[2] );
1640 
1641       if (atomLabel[i].base && atomLabel[i].do_display \
1642 	  && ! do_not_display_atomlabel[i]) {
1643 	/* custom label */
1644 	glListBase(atomLabel[i].base);
1645 	xcFont_PrintString (label);
1646       } else {
1647 	/* default label */
1648 	if (globalAtomLabel.do_display && !do_not_display_atomlabel[i])
1649 	  glCallList( atomlabelOffset + *(nat + i) );
1650       }
1651     } else {
1652       /*
1653 	render one of new Togl fonts
1654       */
1655 
1656       if (atomLabel[i].base) {
1657 	/* new */
1658 	glListBase (atomLabel[i].base); /* t.k. */
1659 
1660 	if (atomLabel[i].tkfont) {
1661 	  z[0] = (double) ( -Tk_TextWidth(atomLabel[i].tkfont,
1662 					  atomLabel[i].label,
1663 					  strlen(atomLabel[i].label)) ) / sizeF;
1664 	} else {
1665 	  z[0] = (double) (-atomLabel[i].width * (int)strlen(atomLabel[i].label)) / sizeF;
1666 	}
1667 	z[1] = (double) (-atomLabel[i].height) / sizeF;
1668 
1669 	MatInv33_44((double (*)[4]) vec.crdvec, minv, &dummy);
1670 	MultMat44_33Vec3(minv, z, v);
1671 	glColor3fv (atomLabel[i].bright_color);
1672 	glRasterPos3d( *(xat + i) + v[0],
1673 		       *(yat + i) + v[1],
1674 		       *(zat + i) + v[2]);
1675 	if (atomLabel[i].do_display && !do_not_display_atomlabel[i])
1676 	  xcFont_PrintString( atomLabel[i].label );
1677       } else {
1678 	/* old */
1679 	glListBase (globalAtomLabel.base); /* t.k. */
1680 	if (globalAtomLabel.tkfont) {
1681 	  z[0] = (double) ( -Tk_TextWidth(globalAtomLabel.tkfont,
1682 					  element[*(nat + i)],
1683 					  strlen(element[*(nat + i)])) ) / sizeF;
1684 	} else {
1685 	  z[0] = ((double) -globalAtomLabel.width * strlen(element[*(nat + i)])) / sizeF;
1686 	}
1687 
1688 	z[1] = ((double) -globalAtomLabel.height) / sizeF;
1689 	z[2] = 1.01 * rad[*(nat + i)];
1690 	MatInv33_44((double (*)[4]) vec.crdvec, minv, &dummy);
1691 	MultMat44_33Vec3(minv, z, v);
1692 	glColor3fv (globalAtomLabel.bright_color);
1693 	glRasterPos3d( *(xat + i) + v[0],
1694 		       *(yat + i) + v[1],
1695 		       *(zat + i) + v[2]);
1696 	if (globalAtomLabel.do_display && !do_not_display_atomlabel[i])
1697 	  xcFont_PrintString( element[*(nat + i)] );
1698       }
1699     }
1700   }
1701 
1702   /* now again enable lighting, dihtering */
1703   glCallList( tempEnable3Dlist );
1704 }
1705 
1706 
1707 void
xcMakeBallLabel3D(void)1708 xcMakeBallLabel3D(void)
1709 {
1710   _makeAtomLabels3D(rball);
1711 }
1712 
1713 void
xcMakeSpaceLabel3D(void)1714 xcMakeSpaceLabel3D(void)
1715 {
1716   _makeAtomLabels3D(atrad);
1717 }
1718 
1719 
1720 /*****************************************************************************/
1721 /* when I enter this procedure I just Made a Display, that means that
1722  * everything must be made before that
1723  */
1724 void
xcDisplay3D(struct Togl * togl)1725 xcDisplay3D(struct Togl *togl)
1726 {
1727 
1728   if ( ! VPf.antialias )
1729     {
1730       /*
1731 	 NO ANTIALIASING
1732       */
1733       _xcDisplay3D(togl);
1734     }
1735   else
1736     {
1737       /*
1738 	 ANTIALIASING
1739       */
1740       GLint viewport[4];
1741       GLfloat sx, sy;
1742       GLfloat scale, dx, dy;
1743       int min, max, count, i, j;
1744       enum {
1745 	XORG, YORG, WID, HT
1746       };
1747 
1748       glGetIntegerv(GL_VIEWPORT, viewport);
1749 
1750       sx = 2 * ort.maxx / viewport[WID];
1751       sy = 2 * ort.maxy / viewport[WID];
1752 
1753       min    = -antialias.degree;
1754       max    = -min + 1;
1755       count  = -min + max;
1756       count *= count;
1757 
1758       /* uniform scaling, less than one pixel wide */
1759       scale = -antialias.offset / min;
1760 
1761       glClear(GL_ACCUM_BUFFER_BIT);
1762 
1763       for (j = min; j < max; j++) {
1764 	for (i = min; i < max; i++)
1765 	  {
1766 	    dx = sx * scale * i;
1767 	    dy = sy * scale * j;
1768 	    glMatrixMode(GL_PROJECTION);
1769 	    glLoadIdentity();
1770 
1771 	    if ( ! VPf.perspective )
1772 	      {
1773 		glOrtho(ort.minx + dx, ort.maxx + dx,
1774 			ort.miny + dy, ort.maxy + dy,
1775 			ort.minz+ort.size, ort.maxz+ort.size);
1776 	      }
1777 	    else
1778 	      {
1779 		glFrustum (ort.minx + dx, ort.maxx + dx,
1780 			   ort.miny + dy, ort.maxy + dy,
1781 			   persp.near, persp.far);
1782 	      }
1783 	    glMatrixMode(GL_MODELVIEW);
1784 	    _xcDisplay3D(togl);
1785 	    glAccum(GL_ACCUM, 1.0 / (GLfloat)count);
1786 	  }
1787       }
1788       glAccum(GL_RETURN, 1.0);
1789     }
1790 
1791   Togl_SwapBuffers(togl);
1792 
1793   /* every snapshot movie making */
1794   if ( makeMovie.doit && makeMovie.mode == MOVIE_MODE_EVERY_SNAPSHOT && !makeMovie.printing ) {
1795     fprintf(stderr,"making snapshot\n");
1796     createMoviePPMFrame(togl);
1797   }
1798 }
1799 
1800 
_xcDisplay3D(struct Togl * togl)1801 static void _xcDisplay3D(struct Togl *togl) {
1802   /* /\* testing ... *\/ */
1803   /*   GLboolean can_do_stereo; */
1804   /*   glGetBooleanv(GL_STEREO, &can_do_stereo); */
1805   /*   is.stereo = GL_TRUE; */
1806   /* testing-end */
1807 
1808   if (is.stereo)
1809     {
1810       /***************/
1811       /* STEREO MODE */
1812       /***************/
1813 
1814       /* draw left eye image */
1815 
1816       glDrawBuffer(GL_BACK_LEFT);
1817       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1818 
1819       /* INSERT HERE ROTATION MATRIX */
1820       glLoadIdentity();
1821       if (VPf.perspective)
1822 	glTranslated (0.0, 0.0, persp.shiftZ);
1823       else
1824 	glTranslated(0.0, 0.0, -ort.size);
1825       glRotated(1.0, 0.0, 1.0, 0.0);
1826       glMultMatrixd (vec.crdvec);
1827 
1828       __xcDisplay3D(togl);
1829 
1830       /* draw right eye image */
1831 
1832       glDrawBuffer(GL_BACK_RIGHT);
1833       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1834 
1835       /* INSERT HERE ROTATION MATRIX */
1836       glLoadIdentity();
1837       if (VPf.perspective)
1838 	glTranslated (0.0, 0.0, persp.shiftZ);
1839       else
1840 	glTranslated(0.0, 0.0, -ort.size);
1841       glRotated(-1.0, 0.0, 1.0, 0.0);
1842       glMultMatrixd (vec.crdvec);
1843 
1844       __xcDisplay3D(togl);
1845     }
1846   else
1847     {
1848       /*******************/
1849       /* non STEREO MODE */
1850       /*******************/
1851 
1852       /* draw single image */
1853       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1854 
1855       /* INSERT HERE ROTATION MATRIX */
1856       glLoadIdentity();
1857       if (VPf.perspective)
1858 	glTranslated (0.0, 0.0, persp.shiftZ);
1859       else
1860 	glTranslated(0.0, 0.0, -ort.size);
1861       glMultMatrixd (vec.crdvec);
1862 
1863       __xcDisplay3D(togl);
1864     }
1865 }
1866 
1867 
__xcDisplay3D(struct Togl * togl)1868 static void __xcDisplay3D(struct Togl *togl) {
1869   int i;
1870 
1871   /* fog */
1872   xcFog (togl, VPf.fog, VPf.perspective);
1873 
1874   if (is.anaglyph)
1875     {
1876       /**************************/
1877       /* DISPLAY with ANAGLYPHs */
1878       /**************************/
1879 
1880       /* EV display anaglyph */
1881       /* anaglyph is defined as wire is.solid=GL_FALSE */
1882       glEnable(GL_COLOR_MATERIAL);
1883         CameraHome();
1884         HandleDisplay(togl);
1885       glDisable(GL_COLOR_MATERIAL);
1886     }
1887   else
1888     {
1889       /*****************************/
1890       /* DISPLAY without ANAGLYPHs */
1891       /*****************************/
1892 
1893       /* display FORCES */
1894       if (VPf.force && xcr.lforce) {
1895 	xcRenderVectorForces();
1896       }
1897 
1898       /* display H-bonds */
1899       if (VPf.Hbond) xcRenderHbonds3D();
1900 
1901       /* if (is.anaglyph) xcTurnXYZOff(togl); */
1902 
1903       tmp_nobjects = 0;
1904       if (is.solid) {
1905 	/* display SOLID Lists */
1906 	if (is.spacefillmode) {
1907 	  xcRenderSolidSpaceFills3D();
1908 	  tmp_nobjects += natoms;
1909 	}
1910 	if (is.ballmode)      {
1911 	  xcRenderSolidBalls3D();
1912 	  tmp_nobjects += natoms;
1913 	}
1914 	if (is.stickmode)     {
1915 	  xcRenderBonds(GL_FILL);
1916 	  tmp_nobjects += nbonds;
1917 	}
1918 	if (!is.lineframe && VPf.framesOn) {
1919 	  xcRenderSolidFrame3D();
1920 	  tmp_nobjects += nframes;
1921 	}
1922       } else {
1923 	if (is.spacefillmode) {
1924 	  xcRenderWireSpaceFills3D();
1925 	  tmp_nobjects += natoms;
1926 	}
1927 	if (is.ballmode)      {
1928 	  xcRenderWireBalls3D();
1929 	  tmp_nobjects += natoms;
1930 	}
1931 	if (is.stickmode)     {
1932 	  xcRenderBonds(GL_LINE);
1933 	  /* glCallList(WireStickList);*/
1934 	  tmp_nobjects += nbonds;
1935 	}
1936 	if (!is.lineframe && VPf.framesOn) {
1937 	  xcRenderWireFrame3D();
1938 	  tmp_nobjects += nframes;
1939 	}
1940       }
1941 
1942       if (is.lineframe && VPf.framesOn) {
1943 	/* set color & width for frames */
1944 	glLineWidth( VPf.framewidth );
1945 	xcRenderLineFrame3D();
1946 	tmp_nobjects += nframes;
1947       }
1948 
1949       for (i=0; i<MAX_ISOOBJECTS; i++) {
1950 	/* THIS IS NEEDED TO RENDER ISOSURFACE */
1951 	if ( VPf.isosurf[i] ) xcRenderIsosurf(i);
1952 	/* THIS IS NEEDED TO RENDER COLORPLANE */
1953 	if ( VPf.colorplane[i] ) xcRenderColorplane(i);
1954 	/* THIS IS NEEDED TO RENDER ISOLINE */
1955 	if ( VPf.isoline[i] ) xcRenderIsoLine2D(i);
1956       }
1957 
1958       /* IsoSpaceSelection */
1959       if ( VPf.isospacesel2D ) IsoSpaceSel_Parallelogram();
1960       if ( VPf.isospacesel3D ) IsoSpaceSel_3D();
1961 
1962       if ( VPf.labelsOn ) {
1963 	if ( is.ballmode || is.stickmode ) xcMakeBallLabel3D();
1964 	if ( is.spacefillmode ) xcMakeSpaceLabel3D();
1965       }
1966 
1967       /* t.k: this is temporal:
1968        * VORONOI & WIGNER-SEITZ
1969        */
1970       if ( xcr.lprimwigner && VPf.wignerseitz ) xcRenderVoronoi();
1971 
1972       /*
1973        * SUPERCELL OPTION
1974        */
1975       if ( VPf.supercell) (*xcSuperCell)();
1976 
1977       /*
1978        * NEW SURFACE OPTIONS
1979        */
1980       if ( VPf.nsurface > 0 ) xcRenderSurface();
1981 
1982       /* are we in selection mode ??? */
1983       if ( VPf.selection ) {
1984 	xcRenderSelAtoms3D();
1985 	xcRenderSelBonds3D();
1986 	/*for(i=0; i<MAXSEL-1; i++) {*/
1987 	  /*if ( glIsList(SphereSelList[i]) ) glCallList(SphereSelList[i]);*/
1988 	  /*if ( glIsList(LineSelList[i]) ) glCallList(LineSelList[i]);*/
1989 	/*}*/
1990 	/*if ( glIsList(SphereSelList[MAXSEL-1]) ) glCallList(SphereSelList[3]);*/
1991       }
1992 
1993       /* are we in atomadd mode ??? */
1994       if ( VPf.atomadd ) {
1995 	xcDisplayAddAtomBox();
1996       }
1997 
1998       /* check if coordinate sistem should be displayed */
1999       if ( VPf.xyzOn ) xcDisplayXYZ();
2000     }
2001 
2002   glFlush();
2003 
2004   printf("   ----------------\n");
2005   printf("ReMakeStr:: tmp_nobjects  = %d\n",tmp_nobjects);
2006   printf("ReMakeStr:: nbonds        = %d\n",nbonds);
2007   printf("ReMakeStr:: natoms        = %d\n",natoms);
2008   printf("ReMakeStr:: nframes       = %d\n",nframes);
2009   printf("ReMakeStr:: nobjects      = %d\n",nobjects);
2010   printf("--------------------------------------------------\n\n");
2011   fflush(stdout);
2012 }
2013 
2014 
2015 /* function delete 3D lists */
2016 /* within 3D modes a whole structure is a list, so when I close a structure
2017  * and open a new one or when I modify some radius I must delete 3D List and
2018  * create a new ones;
2019  */
2020 /*
2021 void
2022 xcMaybeDestroyLists(void)
2023 {
2024   int i;
2025 
2026   for(i=0; i<25; i++)
2027     lists[i] = NULL;
2028 }
2029 */
2030 
2031 void
xcMakeProjection2D(const char * mode)2032 xcMakeProjection2D(const char *mode)
2033 {
2034   GLdouble size;
2035 
2036   FindMaxRad();
2037   /*
2038      this is too much complicated and the drawback is that the size of
2039      displayed structure changes when chaning mode --> simplify !
2040   */
2041 
2042   /* if ( strcmp(mode,"WF") == 0 || strcmp(mode,"PL") == 0 ) */
2043   /*   /\* 1.1 is just some additional offset *\/ */
2044   /*   size = (MVf.structsize + VPf.PLradius / VPf.VPfactor) * 1.1;  */
2045   /* else if ( mode[0] == 'B' || strcmp(mode,"PB") == 0 ) { */
2046   /*   size = (MVf.structsize + max.r * VPf.ballf) * 1.1; */
2047   /* } */
2048   /* else if ( strcmp(mode,"SF") == 0 ) { */
2049   /*   size = (MVf.structsize + max.r * VPf.atradf) * 1.1; */
2050   /* } */
2051 
2052   /* this is much simpler */
2053   /*size = MVf.structsize * (size + max.r) * 1.1;*/
2054   /*size = MVf.structsize * (1.0 + max.r) * 1.1;*/
2055   size = (MVf.structsize + 2.0*max.r) * 1.05;
2056 
2057   _xcMakeProjection(size);
2058 }
2059 
2060 
2061 void
xcMakeProjection3D(const char * mode)2062 xcMakeProjection3D(const char *mode)
2063 {
2064   GLdouble size;
2065 
2066 /*   GLenum LIGHT[8] = { GL_LIGHT0, */
2067 /* 		      GL_LIGHT1, */
2068 /* 		      GL_LIGHT2, */
2069 /* 		      GL_LIGHT3, */
2070 /* 		      GL_LIGHT4, */
2071 /* 		      GL_LIGHT5, */
2072 /* 		      GL_LIGHT6, */
2073 /* 		      GL_LIGHT7 }; */
2074 
2075   FindMaxRad();
2076  /*
2077      this is too much complicated and the drawback is that the size of
2078      displayed structure changes when chaning mode --> simplify !
2079   */
2080 
2081   /* size = MVf.structsize; */
2082   /* if ( strcmp(mode,"sticks") == 0 || strcmp(mode,"balls") == 0 ) */
2083   /*   size = (size + max.r * VPf.ballf) * 1.1; */
2084   /* else if ( strcmp(mode,"space") == 0 ) */
2085   /*   size = (size + max.r) * 1.1; */
2086 
2087   /* this is much simpler */
2088   /*size = MVf.structsize * (size + max.r) * 1.1;*/
2089   /*size = MVf.structsize * (1.0 + max.r) * 1.1;*/
2090   size = (MVf.structsize + 2.0*max.r) * 1.05;
2091 
2092   _xcMakeProjection(size);
2093 }
2094 
_xcMakeProjection(GLdouble size)2095 static void _xcMakeProjection(GLdouble size) {
2096   register int i;
2097   int isoobject = 0;
2098   MOL_SURF     *m;
2099   ISOSURFACE   *iso;
2100   float _size;
2101   double structsize, fulls_vs_structs, ratio;
2102   static double old_fulls_vs_structs = 1.0;
2103 
2104   structsize = size;
2105 
2106   /* if isoXXXXX is rendered, than it may be greater than the structure,
2107    * take this into account
2108    */
2109   for (i=ISOOBJ_BASE; i<MAX_ISOOBJECTS; i++)
2110     if ( VPf.isosurf[i] || VPf.colorplane[i] || VPf.isoline[i] ) {
2111       isoobject = 1;
2112       break;
2113     }
2114   if ( isoobject && MVf.isosize > size ) size = MVf.isosize;
2115 
2116   /* are we in Iso_Space_Selection mode ??? */
2117   if ( (VPf.isospacesel2D || VPf.isospacesel3D) &&
2118        MVf.isospaceselsize > size )
2119     size = MVf.isospaceselsize;
2120 
2121   /* do we specify to render Wigner-Seitz cells ??? */
2122   if ( VPf.wignerseitz && MVf.wignerseitzsize > size )
2123     size = MVf.wignerseitzsize;
2124 
2125   /* this is temporal
2126      if ( xcr.lprimwigner ) size = MVf.structsize + wsp.max;
2127   */
2128 
2129   /* size of forces */
2130 
2131   size = FV.max_size > size ? FV.max_size : size;
2132 
2133   /* size of molecular surfaces */
2134 
2135   for (i=0; i<VPf.nsurface; i++)
2136     {
2137       if (!VPf.surface[i]) continue;
2138 
2139       m   = (MOL_SURF *) VPf.surfacePtr[i];
2140       iso = FindIsoSurf( m->isosurf_index );
2141       if (!iso) {
2142 	continue;
2143       }
2144       _size = distfv (m->size);
2145       size = _size > size ? _size : size;
2146     }
2147 
2148   if ( VPf.stropened && structsize > 0.0 ) {
2149     fulls_vs_structs     = size / structsize;
2150     ratio                = fulls_vs_structs / old_fulls_vs_structs;
2151     old_fulls_vs_structs = fulls_vs_structs;
2152     tr.zoom *= ratio;
2153   }
2154 
2155   /* assign glOrtho dimensions to OrhoProj ort */
2156   ort.size = (size > 1.0 ? size : 1.0);
2157 
2158   /* MaybeClipAndMakeProjection(); */
2159   xcViewPort();
2160 
2161   /*
2162    * take care about some minimium light-settings
2163    */
2164 /*   size = ort.maxx; */
2165 /*   if ( ort.maxy > size ) */
2166 /*     size = ort.maxy; */
2167 
2168 /*   for (i=0; i< MAX_NUMBER_OF_LIGHTS; i++) { */
2169 /*     if ( light[i].isenabled ) { */
2170 /*       light[i].position[0] = size * light[i].fract_position[0]; */
2171 /*       light[i].position[1] = size * light[i].fract_position[1]; */
2172 /*       light[i].position[2] = size * light[i].fract_position[2]; */
2173 /*       light[i].position[3] = light[i].fract_position[3]; */
2174 /*       glLightfv(LIGHT[i], GL_POSITION, light[i].position); */
2175 /*       glEnable( LIGHT[i] ); */
2176 /*     } */
2177 /*   } */
2178 
2179   /* incoming: */
2180   LoadLights();
2181 }
2182 
2183 
2184 void
xcClearScreen(struct Togl * togl)2185 xcClearScreen(struct Togl *togl)
2186 {
2187   /* make a black polygon on whole window -> so structure will disapear */
2188   glClear(GL_COLOR_BUFFER_BIT);
2189   glClearColor( bg[0], bg[1], bg[2], bg[3] );
2190   glFlush();
2191   Togl_SwapBuffers( togl );
2192 }
2193 
2194 
2195 void
xcChangeBackground(struct Togl * togl,GLclampf bckg[4])2196 xcChangeBackground(struct Togl *togl, GLclampf bckg[4])
2197 {
2198   glClear(GL_COLOR_BUFFER_BIT);
2199   glClearColor( bckg[0], bckg[1], bckg[2], bckg[3] );
2200   glFlush();
2201   Togl_PostRedisplay( togl );
2202 }
2203 
2204 
2205 void
xcDisplayXYZ(void)2206 xcDisplayXYZ(void)
2207 {
2208   GLint    shadetype, fog; /* we will query shade model */
2209   GLdouble shift, f;
2210 
2211   /* disable Depth-cuing */
2212   glGetIntegerv( GL_FOG, &fog);
2213   if (fog) glDisable (GL_FOG);
2214 
2215   /*glLoadMatrixd( vec.crdvec );*/
2216   glViewport( 0, 0, CRDS_SIZE, CRDS_SIZE);
2217 
2218   /* prepare for matrices for coordinate sistem */
2219   glMatrixMode(GL_PROJECTION);
2220   glLoadIdentity();
2221 
2222   if (VPf.perspective) {
2223     /* PERSPECTIVE projection */
2224     f = 1.5 + 2.4 / persp.shiftZ;
2225     shift = -2.0*persp.shiftZ;
2226   } else {
2227     /* ORTHOGRAPHIC projection */
2228     f = 1.5 + 2.4 / ort.size;
2229     shift = f*ort.size;
2230   }
2231   glOrtho( -1.2, 1.2, -1.2, 1.2, -shift-1.2, 1.2 );
2232 
2233 
2234   glMatrixMode(GL_MODELVIEW);
2235   glLoadIdentity();
2236   glTranslated (0.0, 0.0, shift);
2237   glMultMatrixd (vec.crdvec );
2238 
2239   /* ========================================== */
2240   /*        now display coor sistem             */
2241 
2242   /* if we are in XC_2D mode clear DETPTH_BUFFER */
2243   if ( dimType == XC_2D ) {
2244     glEnable(GL_DEPTH_TEST);
2245     glClear( GL_DEPTH_BUFFER_BIT );
2246   }
2247   /* if we are in 3D turn off */
2248   if ( dimType == XC_3D ) {
2249     /* when displaying coord-sist in 3D mode,
2250      * we must Disable some things
2251      */
2252     glCallList( tempDisable3Dlist );
2253 
2254     glGetIntegerv( GL_SHADE_MODEL, &shadetype);
2255 
2256     /* go to FLAT shades, but before remember what was the shade model */
2257     if ( shadetype == GL_SMOOTH ) glShadeModel( GL_FLAT);
2258   }
2259 
2260   /* display XYZ axis */
2261   glColor4fv( xyz.axis_color );
2262   glCallList (crdList);
2263 
2264   glColor4fv( xyz.xyplane_color );
2265   glCallList (xyplaneList);
2266 
2267   /*glLoadIdentity();*/
2268 
2269   if ( dimType == XC_2D ) glDisable(GL_DEPTH_TEST);
2270   if ( dimType == XC_3D ) {
2271     /* it's better idea to make a glList for this, but so far ... */
2272     glCallList( tempEnable3Dlist );
2273     if ( shadetype == GL_SMOOTH )
2274       glShadeModel( GL_SMOOTH );
2275   }
2276   if (fog) glEnable (GL_FOG);
2277 
2278   goToPrevProj();
2279 }
2280 
2281 
2282 static void
goToPrevProj(void)2283 goToPrevProj(void)
2284 {
2285   xcViewPort();
2286 
2287   /* now go back to previous GL_PROJECTION & GL_MODELVIEW */
2288 /*   glMatrixMode(GL_PROJECTION); */
2289 /*   glLoadIdentity(); */
2290 /*   if ( dimType == XC_2D ) { */
2291 /*     gluOrtho2D(ort.minx, ort.maxx, ort.miny, ort.maxy); */
2292 /*   } else  */
2293 /*     glOrtho(ort.minx, ort.maxx, ort.miny, ort.maxy, ort.minz, ort.maxz); */
2294 /*   glMatrixMode(GL_MODELVIEW); */
2295 /*   glViewport( (GLint) VPf.x, (GLint) VPf.y,  */
2296 /* 	      (GLsizei) VPf.sizex, (GLsizei) VPf.sizey); */
2297 /*   if ( dimType == XC_2D ) glLoadIdentity();  */
2298 }
2299 
2300 
2301 void
xcTurnXYZOff(struct Togl * togl)2302 xcTurnXYZOff(struct Togl *togl)
2303 {
2304   /* turn VPf.xyzOn off */
2305   VPf.xyzOn = 0;
2306   Togl_PostRedisplay (togl);
2307 
2308 /*   if ( VPf.stropened ) { */
2309 /*   GLfloat size = 1.1 * CRDS_SIZE; */
2310 /*     /\* on place where the coor-sist is desplayed, display black rectangle *\/ */
2311 /*     /\* prepere for matrices for coordinate sistem *\/ */
2312 /*     glMatrixMode(GL_PROJECTION); */
2313 /*     glOrtho( -1.2, 1.2, -1.2, 1.2, -1.2, 1.2 ); */
2314 /*     glMatrixMode(GL_MODELVIEW); */
2315 /*     glViewport( 0.0, 0.0, size, size); */
2316 /*     glLoadIdentity(); */
2317 
2318 /*     glColor3fv( bg ); */
2319 /*     /\* if we are in 3D mode we must go to "pseudo" 2D mode *\/ */
2320 /*     if (dimType == XC_3D) { */
2321 /*       glCallList(tempDisable3Dlist); */
2322 /*       glDisable(GL_DEPTH_TEST); */
2323 /*     } */
2324 /*     glBegin(GL_POLYGON); */
2325 /*       glVertex2f(-size, size); */
2326 /*       glVertex2f( size, size); */
2327 /*       glVertex2f( size,-size); */
2328 /*       glVertex2f(-size,-size); */
2329 /*     glEnd(); */
2330 /*     /\* if 3D -> going back *\/ */
2331 /*     if (dimType == XC_3D) { */
2332 /*       glCallList(tempEnable3Dlist); */
2333 /*       glEnable(GL_DEPTH_TEST); */
2334 /*     } */
2335 /*     goToPrevProj(); */
2336 /*     glFlush(); */
2337 /*     Togl_SwapBuffers(togl); */
2338 /*   }   */
2339 }
2340 
2341 
CalcTessFactor(void)2342 static int CalcTessFactor(void) {
2343   if ( natoms < 10 ) {
2344     return (int) VPf.tessFactor;
2345   } else if ( natoms < 30 ) {
2346     return (int) (VPf.tessFactor / 1.5);
2347   } else if ( natoms < 100 ) {
2348     return (int ) (VPf.tessFactor / 2);
2349   } else {
2350     return (int) (VPf.tessFactor / 3);
2351   }
2352 }
2353 
2354 
2355 
2356 
2357 /********************************************************************
2358  ********************************************************************
2359                               EV   ANAGLYPH PART
2360  ********************************************************************
2361  ********************************************************************/
2362 
2363 /*
2364   This is the basic display callback routine
2365   It creates the geometry, lighting, and viewing position
2366 */
2367 
2368 static void
HandleDisplay(struct Togl * togl)2369 HandleDisplay(struct Togl *togl)
2370 {
2371   XYZ right,focus;
2372 
2373   /* Determine the focal point */
2374   Normalise(&camera.vd);
2375   focus.x = camera.vp.x + camera.focallength * camera.vd.x;
2376   focus.y = camera.vp.y + camera.focallength * camera.vd.y;
2377   focus.z = camera.vp.z + camera.focallength * camera.vd.z;
2378 
2379   /* Derive the the "right" vector */
2380   CROSSPROD(camera.vd,camera.vu,right);
2381   Normalise(&right);
2382   right.x *= camera.eyesep / 2.0;
2383   right.y *= camera.eyesep / 2.0;
2384   right.z *= camera.eyesep / 2.0;
2385 
2386   /* Set the buffer for writing and reading */
2387   glDrawBuffer(GL_BACK);
2388   glReadBuffer(GL_BACK);
2389 
2390   /* Clear things */
2391   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2392 
2393 
2394   /* Set projection */
2395   xcViewPort();
2396 
2397 
2398   /* Left eye filter red */
2399   glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE);
2400 
2401 
2402   /* Create the model */
2403   glMatrixMode(GL_MODELVIEW);
2404   glLoadIdentity();
2405   if (VPf.perspective)
2406     glTranslated (0.0, 0.0, persp.shiftZ);
2407   else
2408     glTranslated(0.0, 0.0, -ort.size);
2409   glMultMatrixd (vec.crdvec);
2410 
2411   gluLookAt(camera.vp.x - right.x,
2412 	    camera.vp.y - right.y,
2413 	    camera.vp.z - right.z,
2414 	    focus.x,focus.y,focus.z,
2415 	    camera.vu.x,camera.vu.y,camera.vu.z);
2416 
2417   draw_scene();
2418   glFlush();
2419 
2420 
2421   glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
2422 
2423   glDrawBuffer(GL_BACK);
2424 
2425   glClear(GL_DEPTH_BUFFER_BIT);
2426 
2427   xcViewPort();
2428 
2429   /* Right eye filter */
2430 
2431   glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_TRUE);
2432 
2433 
2434   glMatrixMode(GL_MODELVIEW);
2435   glLoadIdentity();
2436   if (VPf.perspective)
2437     glTranslated (0.0, 0.0, persp.shiftZ);
2438   else
2439     glTranslated(0.0, 0.0, -ort.size);
2440   glMultMatrixd (vec.crdvec);
2441   gluLookAt(camera.vp.x + right.x,
2442 	    camera.vp.y + right.y,
2443 	    camera.vp.z + right.z,
2444 	    focus.x,focus.y,focus.z,
2445 	    camera.vu.x,camera.vu.y,camera.vu.z);
2446 
2447   draw_scene();
2448   glFlush();
2449   glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
2450 
2451 
2452   /* Let's look at it */
2453   /*Togl_SwapBuffers(togl);*/
2454 
2455 }
2456 
2457 
2458 static void
draw_scene()2459 draw_scene()
2460 {
2461   int i;
2462   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2463   glPushMatrix();
2464   /*  Here are the options set in _xcDisplay3D for wire or solid */
2465   /* display FORCES */
2466   if (VPf.force && xcr.lforce) {
2467     xcRenderVectorForces();
2468   }
2469 
2470   /* display H-bonds */
2471   if (VPf.Hbond) xcRenderHbonds3D();
2472 
2473   tmp_nobjects = 0;
2474 
2475   if (is.solid)
2476     {
2477       /* display SOLID Lists */
2478       if (is.spacefillmode) {
2479 	xcRenderSolidSpaceFills3D();
2480 	tmp_nobjects += natoms;
2481       }
2482       if (is.ballmode)      {
2483 	xcRenderSolidBalls3D();
2484 	tmp_nobjects += natoms;
2485       }
2486       if (is.stickmode)     {
2487 	xcRenderBonds(GL_FILL);
2488 	tmp_nobjects += nbonds;
2489       }
2490       if (!is.lineframe && VPf.framesOn) {
2491 	xcRenderSolidFrame3D();
2492 	tmp_nobjects += nframes;
2493       }
2494     }
2495   else
2496     {
2497       if (is.spacefillmode) {
2498 	xcRenderWireSpaceFills3D();
2499 	tmp_nobjects += natoms;
2500       }
2501       if (is.ballmode)      {
2502 	xcRenderWireBalls3D();
2503 	tmp_nobjects += natoms;
2504       }
2505       if (is.stickmode)     {
2506 	xcRenderBonds(GL_LINE);
2507 	/* glCallList(WireStickList);*/
2508 	tmp_nobjects += nbonds;
2509       }
2510       if (!is.lineframe && VPf.framesOn) {
2511 	xcRenderWireFrame3D();
2512 	tmp_nobjects += nframes;
2513       }
2514     }
2515 
2516   if (is.lineframe && VPf.framesOn) {
2517     /* set color & width for frames */
2518     glLineWidth( VPf.framewidth );
2519     xcRenderLineFrame3D();
2520     tmp_nobjects += nframes;
2521   }
2522 
2523   for (i=0; i<MAX_ISOOBJECTS; i++) {
2524     /* THIS IS NEEDED TO RENDER ISOSURFACE */
2525     if ( VPf.isosurf[i] ) xcRenderIsosurf(i);
2526     /* THIS IS NEEDED TO RENDER COLORPLANE */
2527     if ( VPf.colorplane[i] ) xcRenderColorplane(i);
2528     /* THIS IS NEEDED TO RENDER ISOLINE */
2529     if ( VPf.isoline[i] ) xcRenderIsoLine2D(i);
2530   }
2531 
2532   /* IsoSpaceSelection */
2533   if ( VPf.isospacesel2D ) IsoSpaceSel_Parallelogram();
2534   if ( VPf.isospacesel3D ) IsoSpaceSel_3D();
2535 
2536   if ( VPf.labelsOn ) {
2537     if ( is.ballmode || is.stickmode ) xcMakeBallLabel3D();
2538     if ( is.spacefillmode ) xcMakeSpaceLabel3D();
2539   }
2540 
2541   /* t.k: this is temporal:
2542    * VORONOI & WIGNER-SEITZ
2543    */
2544   if ( xcr.lprimwigner && VPf.wignerseitz ) xcRenderVoronoi();
2545 
2546   /*
2547    * SUPERCELL OPTION
2548    */
2549   if ( VPf.supercell) (*xcSuperCell)();
2550 
2551   /*
2552    * NEW SURFACE OPTIONS
2553    */
2554   if ( VPf.nsurface > 0 ) xcRenderSurface();
2555 
2556   /* are we in selection mode ??? */
2557   if ( VPf.selection ) {
2558     xcRenderSelAtoms3D();
2559     xcRenderSelBonds3D();
2560     /*for(i=0; i<MAXSEL-1; i++) {*/
2561       /*if ( glIsList(SphereSelList[i]) ) glCallList(SphereSelList[i]);*/
2562       /*if ( glIsList(LineSelList[i]) ) glCallList(LineSelList[i]);*/
2563     /*}*/
2564     /*if ( glIsList(SphereSelList[MAXSEL-1]) ) glCallList(SphereSelList[3]);*/
2565   }
2566 
2567   /* are we in atomadd mode ??? */
2568   if ( VPf.atomadd ) {
2569     xcDisplayAddAtomBox();
2570 
2571     /* this one is not displayed because it cause problem */
2572     /* this is the only bug i have seen */
2573 
2574     /* check if coordinate sistem should be displayed */
2575     /*  if ( VPf.xyzOn ) xcDisplayXYZ(); */
2576 
2577 
2578   }
2579 
2580   glPopMatrix();
2581 }
2582 
2583 
2584 /*
2585   Move the camera to the home position
2586   Or to a predefined stereo configuration
2587   The model is assumed to be in a 10x10x10 cube
2588   Centered at the origin
2589 */
2590 static void
CameraHome()2591 CameraHome()
2592 {
2593   camera.aperture = 60;
2594 
2595 
2596   camera.pr = origin;
2597   camera.vd.x = 1;
2598   camera.vd.y = 0;
2599   camera.vd.z = 0;
2600 
2601   camera.vu.x = 0;
2602   camera.vu.y = 1;
2603   camera.vu.z = 0;
2604 
2605   camera.vp.x = 0;
2606   camera.vp.y = 0;
2607   camera.vp.z = 0;
2608 
2609   /*for the following value :*/
2610   /*    5 -> the scene semm to be on the screen */
2611   /*   15 -> the scene semm to be out of the screen */
2612   /*   10 -> the scene semm to be in the screen */
2613 
2614 
2615   camera.focallength = 5;
2616 
2617 
2618   /* Non stressful stereo setting */
2619   camera.eyesep = camera.focallength / 30.0;
2620 
2621 }
2622 
2623 /*
2624   Normalise a vector
2625 */
2626 static void
Normalise(XYZ * p)2627 Normalise(XYZ *p)
2628 {
2629   double length;
2630 
2631   length = sqrt(p->x * p->x + p->y * p->y + p->z * p->z);
2632   if (length != 0) {
2633     p->x /= length;
2634     p->y /= length;
2635     p->z /= length;
2636   } else {
2637     p->x = 0;
2638     p->y = 0;
2639     p->z = 0;
2640   }
2641 }
2642 
2643 /*
2644   Calculate the unit normal at p given two other points
2645   p1,p2 on the surface. The normal points in the direction
2646   of p1 crossproduct p2
2647 */
2648 /* static XYZ  */
2649 /* CalcNormal(XYZ p,XYZ p1,XYZ p2) */
2650 /* { */
2651 /*   XYZ n,pa,pb; */
2652 
2653 /*   pa.x = p1.x - p.x; */
2654 /*   pa.y = p1.y - p.y; */
2655 /*   pa.z = p1.z - p.z; */
2656 /*   pb.x = p2.x - p.x; */
2657 /*   pb.y = p2.y - p.y; */
2658 /*   pb.z = p2.z - p.z; */
2659 /*   Normalise(&pa); */
2660 /*   Normalise(&pb); */
2661 
2662 /*   n.x = pa.y * pb.z - pa.z * pb.y; */
2663 /*   n.y = pa.z * pb.x - pa.x * pb.z; */
2664 /*   n.z = pa.x * pb.y - pa.y * pb.x; */
2665 /*   Normalise(&n); */
2666 
2667 /*   return(n); */
2668 /* } */
2669 
2670 
2671 
2672 
2673 /********************************************************************
2674  ********************************************************************
2675                               EV
2676  ********************************************************************
2677  ********************************************************************/
2678