1 /****************************************************************************
2  **
3  ** Copyright (C) 2011 Christian B. Huebschle & George M. Sheldrick
4  ** All rights reserved.
5  ** Contact: chuebsch@moliso.de
6  **
7  ** This file is part of the ShelXle
8  **
9  ** This file may be used under the terms of the GNU Lesser
10  ** General Public License version 2.1 as published by the Free Software
11  ** Foundation and appearing in the file COPYING included in the
12  ** packaging of this file.  Please review the following information to
13  ** ensure the GNU Lesser General Public License version 2.1 requirements
14  ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
15  **
16  **
17  ****************************************************************************/
18 //äöüß needed to keep this file UTF8 QString::fromUtf8("»")
19 #include "chgl.h"
20 #include "deprecation.h"
21 //#if defined (Q_WS_MAC) || defined (Q_OS_MAC)
22 //#include <OpenGL/glu.h>
23 //#include <glu.h>
24 //#else
25 //#include <GL/glu.h>
26 //#endif
27 #include <QtGui>
28 #include <QtOpenGL>
29 #include <QDialog>
30 #ifndef GL_MULTISAMPLE
31 #define ICH_KANNTE_NICHT_MS 42
32 #define GL_MULTISAMPLE  0x809D
33 #endif
34 //
35 //#define HIDE_REASON_SELECT          1
36 //#define HIDE_REASON_THIS_FRAGMENT   2
37 //#define HIDE_REASON_OTHER_FRAGMENT  4
38 //#define HIDE_REASON_HYDROGEN        8
39 //#define HIDE_REASON_QPEAK          16
40 //
41 
42 
__RotateCS(double c,double s,double & X,double & Y)43 inline void ChGL::__RotateCS( double c, double s, double& X, double& Y ) {
44   double T = X;
45   X = c*X - s*Y;
46   Y = s*T + c*Y;
47 }
48 
glTranslateL(const double dx,const double dy,const double dz)49 void ChGL::glTranslateL( const double dx, const double dy, const double dz ) {
50   double mat[4][4];
51 
52   glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mat );
53   mat[3][0] += dx;  mat[3][1] += dy;  mat[3][2] += dz;
54   glLoadMatrixd((double*)mat);
55 }
glRotateL(const double dang,const double x,const double y,const double z)56 void ChGL::glRotateL( const double dang, const double x, const double y, const double z ) {
57   double mat[4][4];
58 #ifndef M_PI
59 #define	M_PI		3.14159265358979323846	/* pi */
60 #endif
61 
62   double s = z;
63   s = sin(dang*M_PI/180);
64   const double c = cos(dang*M_PI/180);
65   glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mat );
66   //  glGetDoublev( GL_PROJECTION_MATRIX, (double*)mat );
67   if( x!=0.0 ){
68     __RotateCS( c, s, mat[0][1], mat[0][2] );
69     __RotateCS( c, s, mat[1][1], mat[1][2] );
70     __RotateCS( c, s, mat[2][1], mat[2][2] );
71     //    printf("x\n");
72   }else if( y!=0.0 ){
73     __RotateCS( c, s, mat[0][2], mat[0][0] );
74     __RotateCS( c, s, mat[1][2], mat[1][0] );
75     __RotateCS( c, s, mat[2][2], mat[2][0] );
76     //    printf("y\n");
77   }else{
78     __RotateCS( c, s, mat[0][0], mat[0][1] );
79     __RotateCS( c, s, mat[1][0], mat[1][1] );
80     __RotateCS( c, s, mat[2][0], mat[2][1] );
81     //    printf("z\n");
82   }
83   glLoadMatrixd((double*)mat);
84 }
85 
86 
87 
88 
saveOrientation()89 void ChGL::saveOrientation(){
90   QString fn=QFileDialog::getSaveFileName(this, tr("Save Orientation into file "), "orientation.ini",
91       "orientation.ini (*.ini);;");
92 
93   if (fn.isEmpty()) return;
94   QFile mconf(fn);
95   mconf.open(QIODevice::WriteOnly|QIODevice::Text);
96   GLdouble mm[16];
97   glGetDoublev(GL_MODELVIEW_MATRIX,mm);
98   mconf.write(QString("%1/%2/%3/%4/%5/%6/%7/%8/%9/%10/%11/%12/%13/%14/%15/%16\n")
99       .arg(mm[0]).arg(mm[1]).arg(mm[2]).arg(mm[3]).arg( mm[4]).arg(mm[5])
100       .arg(mm[6]).arg(mm[7]).arg( mm[8]).arg(mm[9]).arg(mm[10]).arg(mm[11])
101       .arg( mm[12]).arg(mm[13]).arg(mm[14]).arg(mm[15]).toLatin1());
102   mconf.close();
103 }
104 
saveOrientation(QString fn)105 void ChGL::saveOrientation(QString fn){
106   if (fn.isEmpty()) return;
107   QFile mconf(fn);
108   mconf.open(QIODevice::WriteOnly|QIODevice::Text);
109   GLdouble mm[16];
110   glGetDoublev(GL_MODELVIEW_MATRIX,mm);
111   mconf.write(QString("%1/%2/%3/%4/%5/%6/%7/%8/%9/%10/%11/%12/%13/%14/%15/%16\n")
112       .arg(mm[0]).arg(mm[1]).arg(mm[2]).arg(mm[3]).arg( mm[4]).arg(mm[5])
113       .arg(mm[6]).arg(mm[7]).arg( mm[8]).arg(mm[9]).arg(mm[10]).arg(mm[11])
114       .arg( mm[12]).arg(mm[13]).arg(mm[14]).arg(mm[15]).toLatin1());
115   mconf.close();
116 }
117 
rotateIdle()118 void ChGL::rotateIdle(){
119     if (idl!=nullptr){
120         glRotateL(0.5,0.0,1.0,0.0);
121         updateGL();
122     }
123 }
124 
loadOrientation(QString fn)125 void ChGL::loadOrientation(QString fn){
126   if (fn.isEmpty()) return;
127   QFile miconf(fn);
128   miconf.open(QIODevice::ReadOnly|QIODevice::Text);
129   QString all=miconf.readAll();
130   miconf.close();
131 
132   MM[0] = all.section('/',0,0).toDouble();
133   MM[1] = all.section('/',1,1).toDouble();
134   MM[2] = all.section('/',2,2).toDouble();
135   MM[3] = all.section('/',3,3).toDouble();
136   MM[4] = all.section('/',4,4).toDouble();
137   MM[5] = all.section('/',5,5).toDouble();
138   MM[6] = all.section('/',6,6).toDouble();
139   MM[7] = all.section('/',7,7).toDouble();
140   MM[8] = all.section('/',8,8).toDouble();
141   MM[9] = all.section('/',9,9).toDouble();
142   MM[10]= all.section('/',10,10).toDouble();
143   MM[11]= all.section('/',11,11).toDouble();
144   MM[12]= all.section('/',12,12).toDouble();
145   MM[13]= all.section('/',13,13).toDouble();
146   MM[14]= all.section('/',14,14).toDouble();
147   MM[15]= all.section('/',15,15).toDouble();
148   printf("matrix:\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n",
149       MM[0],
150       MM[1] ,
151       MM[2] ,
152       MM[3] ,
153       MM[4] ,
154       MM[5] ,
155       MM[6] ,
156       MM[7] ,
157       MM[8] ,
158       MM[9] ,
159       MM[10],
160       MM[11],
161       MM[12],
162       MM[13],
163       MM[14],
164       MM[15]);
165   setMatrix();
166   //  emit mconf();
167   updateGL();
168 }
169 
loadOrientation()170 void ChGL::loadOrientation(){
171   QString fn=QFileDialog::getOpenFileName(this, tr("Open MoleCoolQt MolIso Settings file "), "MoleCoolQt.moliso.ini",
172       "MoleCoolQt.moliso.ini (*.ini);;" );
173 
174   if (fn.isEmpty()) return;
175   QFile miconf(fn);
176   miconf.open(QIODevice::ReadOnly|QIODevice::Text);
177   QString all=miconf.readAll();
178   miconf.close();
179 
180   MM[0] = all.section('/',0,0).toDouble();
181   MM[1] = all.section('/',1,1).toDouble();
182   MM[2] = all.section('/',2,2).toDouble();
183   MM[3] = all.section('/',3,3).toDouble();
184   MM[4] = all.section('/',4,4).toDouble();
185   MM[5] = all.section('/',5,5).toDouble();
186   MM[6] = all.section('/',6,6).toDouble();
187   MM[7] = all.section('/',7,7).toDouble();
188   MM[8] = all.section('/',8,8).toDouble();
189   MM[9] = all.section('/',9,9).toDouble();
190   MM[10]= all.section('/',10,10).toDouble();
191   MM[11]= all.section('/',11,11).toDouble();
192   MM[12]= all.section('/',12,12).toDouble();
193   MM[13]= all.section('/',13,13).toDouble();
194   MM[14]= all.section('/',14,14).toDouble();
195   MM[15]= all.section('/',15,15).toDouble();
196   printf("matrix:\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n%12g %12g %12g %12g\n",
197       MM[0],
198       MM[1] ,
199       MM[2] ,
200       MM[3] ,
201       MM[4] ,
202       MM[5] ,
203       MM[6] ,
204       MM[7] ,
205       MM[8] ,
206       MM[9] ,
207       MM[10],
208       MM[11],
209       MM[12],
210       MM[13],
211       MM[14],
212       MM[15]);
213   setMatrix();
214   //  emit mconf();
215   updateGL();
216 }
217 
setMatrix()218 void ChGL::setMatrix(){
219   glMatrixMode(GL_MODELVIEW);
220   /*GLdouble det=
221     MM[0]*MM[5]*MM[10] - MM[8]*MM[5]*MM[2]+
222     MM[1]*MM[6]*MM[8]  - MM[9]*MM[6]*MM[0]+
223     MM[2]*MM[4]*MM[9]  - MM[10]*MM[4]*MM[1];*/
224   //printf("Determinant is %g\n",det);
225   //if ((det>0.1)&&(det<9.0))
226   glLoadMatrixd(MM);
227   /*else {
228     MM[0]=1;
229     MM[1]=0;
230     MM[2]=0;
231     MM[3]=0;
232     MM[4]=0;
233     MM[5]=1;
234     MM[6]=0;
235     MM[7]=0;
236     MM[8]=0;
237     MM[9]=0;
238     MM[10]=1;
239     MM[11]=0;
240     MM[12]=0;
241     MM[13]=0;
242     MM[14]=-200;
243     MM[15]=1;
244     glLoadIdentity();
245     glLoadMatrixd(MM);
246     }*/
247   updateGL();
248 }
249 
250 
251 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
252 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
253 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
254 //ChGL::ChGL(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers),parent){                                                        ///////////////
ChGL(QWidget * parent)255 ChGL::ChGL(QWidget *parent) :QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::DeprecatedFunctions),parent){
256   //printf("ChGL::ChGL\n");|QGL::DoubleBuffer|QGL::DepthBuffer|QGL::DirectRendering|QGL::StereoBuffers
257   QGLFormat glf=format();
258   printf("sampleBuffers=%d alpha=%d doubleBuffer=%d depth=%d directRendering=%d stereo=%d hasOverlay=%d stencil=%d samples=%d sync?%d\n"
259       ,glf.sampleBuffers(), glf.alpha(), glf.doubleBuffer(), glf.depth(), glf.directRendering(), glf.stereo(),glf.hasOverlay(),glf.stencil (),glf.samples(),glf.swapInterval());
260 #ifdef ICH_KANNTE_NICHT_MS
261   printf("msaa ndef %d\n",ICH_KANNTE_NICHT_MS);
262 #endif
263   inRenameMode=false;
264   fVertexes.resize(28);
265   fNormals.resize(28);
266   pause=true;
267   altpivot=false;
268   whyNotSplit=nullptr;
269   axx=nullptr;
270   axy=nullptr;
271   axz=nullptr;
272   depthcueing=false;
273   retinafktr=1;
274   on=false;
275   idl=nullptr;
276   manualAx=nullptr;
277   //orthoView=false;
278   withsymm=0;
279   labScal=0.3;
280   exporting=false;
281   dratpause=80;
282   murx=0;
283   chparent=parent;
284   envirange=3.2;
285   apair.clear();
286   enviNoQ= new QAction("Exclude Q-peaks from environment listing", this);
287   enviCova = new QAction("List only covalent bonds.",this);
288   enviButt= new QToolButton(this);
289   enviButt->setText("clear ENVI");
290   connect(enviButt,SIGNAL(clicked()),this,SLOT(clearEnvi()));
291   enviSelect= new QToolButton(this);
292   enviSelect->setText("Select ENVI");
293   connect(enviSelect,SIGNAL(clicked()),this,SLOT(selectEnvi()));
294   wireButt= new QAction("Wiremodel while rotate",this);
295   wireButt->setCheckable(true);
296   wireButt->setChecked(false);//defaut changed 13.12.2019
297   rainbowPlot= new QAction("Contour plot in rainbow colors",this);
298   rainbowPlot->setCheckable(true);
299   rainbowPlot->setChecked(false);
300   rainbowPlot->setVisible(false);
301   enviButt->setVisible(false);
302   enviSelect->setVisible(false);
303   enviNoQ->setCheckable(true);
304   enviNoQ->setChecked(false);
305   enviCova->setCheckable(true);
306   enviCova->setChecked(false);
307   mol=new Molecule();
308   warLabel=noWaitLabel=false;
309   viewAngle=29.0;
310   imFokus=afok=-1;
311   pickradius=200.0;
312   //printf("__ChGL::ChGL\n");
313   moving = new QTimer(this);
314   moving->setSingleShot(true);
315   connect(moving,SIGNAL(timeout()),this,SLOT(updateGL()));
316   p=pp=ppp=0;
317   bggradient=true;
318   altemitte=V3(0,0,0);
319   hiddenThings=false;
320   hideReason=0;
321   qcutoff=-9;
322   setMinimumSize(200,200);
323   myFont=QFont("Arial",16);
324   centerSelection = new QAction(this);//for a dirty fix
325   rotze=-1;                                                                                              ///////////////
326   stereo_mode=0;                                                                                         ///////////////a
327   atomsClickable=true;                                                                                   ///////////////
328   mouseOverInteraction=true;                                                                             ///////////////
329   //  warfaul=
330   drawUc=false;
331 
332   // 0  1  2  3
333   // 4  5  6  7
334   // 8  9 10 11
335   //12 13 14 15
336   MM[0]=-1;
337   MM[1]=MM[2]=MM[3]=MM[4]=MM[7]=MM[8]=MM[11]=MM[12]=MM[13]=0;
338   MM[5]=-0.242536;
339   MM[6]=0.970142;
340   MM[9]=0.970142;
341   MM[10]=0.242536;
342   MM[15]=1.0;
343   //MM[1]=MM[2]=MM[3]=MM[4]=MM[6]=MM[7]=MM[8]=MM[9]=MM[11]=MM[12]=MM[13]=0.0;
344   MM[14]=-200.0;
345   drawDF=drawFO= drawAx=drawAt=drawADP=drawBo=drawLa=drawHb=true;
346   //glEnable(GL_MULTISAMPLE);
347   ///////////////
348 #if (QT_VERSION >= 0x040600) && defined (Q_WS_MAC)
349   grabGesture(Qt::PinchGesture);
350   grabGesture(Qt::SwipeGesture);
351 #endif
352   /*
353      QGLFormat fmt=QGLFormat::defaultFormat() ;
354   //fmt.setOption(QGL::StereoBuffers);
355   fmt.setOption(QGL::DirectRendering|QGL::StereoBuffers);
356   //fmt.setOption(QGL::);
357   setFormat(fmt);
358   */
359   //                                                                                                     ///////////////
360 }                                                                                                        ///////////////
361 
~ChGL()362 ChGL::~ChGL(){
363   if (mol->g_Program!=nullptr) mol->g_Program->deleteLater();
364   labelTextures.clear();
365   //printf("Destructor of chGL %d %d\n",fVertexes.size(),fNormals.size());
366   int sumsize=0;
367   for (int i=0; i<fVertexes.size(); i++) {sumsize+=fVertexes[i].size(); fVertexes[i].clear();}
368   for (int i=0; i<fNormals.size(); i++) {sumsize+=fNormals[i].size(); fNormals[i].clear();}
369   fVertexes.clear();
370   fNormals.clear();
371   //printf("Destructor of chGL freed %d normals and vertices.\n",sumsize);
372 }
373 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
374 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
375 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376 
377 #if (QT_VERSION >= 0x040600) && (defined (Q_WS_MAC) || defined(Q_OS_MAC))
event(QEvent * event)378 bool ChGL::event(QEvent *event){
379   if (event->type() == QEvent::Gesture)
380     return gestureEvent(static_cast<QGestureEvent*>(event));
381   return QWidget::event(event);
382 }
383 
gestureEvent(QGestureEvent * event)384 bool ChGL::gestureEvent(QGestureEvent *event){
385   if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
386     swipeTriggered(static_cast<QSwipeGesture *>(swipe));
387   else
388     if (QGesture *pinch = event->gesture(Qt::PinchGesture))
389       pinchTriggered(static_cast<QPinchGesture *>(pinch));
390   return true;
391 }
392 
pinchTriggered(QPinchGesture * gesture)393 void ChGL::pinchTriggered(QPinchGesture *gesture){
394   QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
395   if (changeFlags & QPinchGesture::RotationAngleChanged) {
396     qreal value = gesture->property("rotationAngle").toReal();
397     rotZ(value/-36.0);
398   }
399   if (changeFlags & QPinchGesture::ScaleFactorChanged) {
400     qreal value = gesture->property("scaleFactor").toReal();
401     gZoom(value-1.0);
402   }
403   updateGL();
404 }
405 
swipeTriggered(QSwipeGesture * gesture)406 void ChGL::swipeTriggered(QSwipeGesture *gesture) {
407   if (gesture->horizontalDirection() == QSwipeGesture::Left) glRotateL(-5.0,0.0f,1.0f,0.0f);
408   if (gesture->horizontalDirection() == QSwipeGesture::Right) glRotateL(5.0,0.0f,1.0f,0.0f);
409   if (gesture->verticalDirection() == QSwipeGesture::Up) glRotateL(-5.0,1.0f,0.0f,0.0f);
410   if (gesture->verticalDirection() == QSwipeGesture::Down) glRotateL(5.0,1.0f,0.0f,0.0f);
411   updateGL();
412 }
413 #endif
414 
415 
416 
transform_point(GLdouble out[4],const GLdouble m[16],const GLdouble in[4])417 static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]) {
418 #define M(row,col)  m[col*4+row]
419   out[0] =
420     M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
421   out[1] =
422     M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
423   out[2] =
424     M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
425   out[3] =
426     M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
427 #undef M
428 }
429 int scrx=0,scry=0;
430 int scrx0=0,scry0=0;
431 bool rectangle=false;
posTo2D(V3 obj,const GLdouble model[16],const GLdouble proj[16],const GLint viewport[4],GLdouble * winx,GLdouble * winy,int retinafktr)432 static inline bool  posTo2D(V3 obj,
433     const GLdouble model[16], const GLdouble proj[16],
434     const GLint viewport[4],
435     GLdouble * winx, GLdouble * winy,int retinafktr) {
436   GLdouble in[4], out[4];
437 
438   in[0] = obj.x;
439   in[1] = obj.y;
440   in[2] = obj.z;
441   in[3] = 1.0;
442   transform_point(out, model, in);
443   transform_point(in, proj, out);
444 
445   if (in[3] == 0.0) return false;
446 
447   in[0] /= in[3];
448   in[1] /= in[3];
449   in[2] /= in[3];
450 
451   *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
452   *winy = viewport[1] + (1 - in[1]) * viewport[3] / 2;
453   *winx/=retinafktr;
454   *winy/=retinafktr;
455   return true;
456 
457 }
458 
459 
changeEnviRange()460 void ChGL::changeEnviRange(){//! a dialog for a new ChGL.envirange.
461   bool ok;
462   double r=QInputDialog::getDouble ( this,"Envi-Range", "change environment range", envirange,0.7,8.0,2,&ok);
463   if (ok) envirange=r;
464 }
465 
mousePressEvent(QMouseEvent * event)466 void ChGL::mousePressEvent(QMouseEvent *event) {
467 
468     altpivot=false;
469   if (rectangle){
470     rectangle=false;
471     updateGL();
472   }
473   lastPos = event->pos();
474   p = qMin(p,mol->showatoms.size()-1);
475   pp = qMin(pp,mol->showatoms.size()-1);
476   ppp = qMin(ppp,mol->showatoms.size()-1);
477 
478   p = qMax(p,0);
479   pp = qMax(pp,0);
480   ppp = qMax(ppp,0);
481   double nahda=pickradius,da=0;
482   int nahdai=-1;
483   for (int j=0; j<mol->showatoms.size();j++){
484     if (mol->showatoms.at(j).hidden) continue;
485     da=(((mol->showatoms.at(j).screenX-event->x())*( mol->showatoms.at(j).screenX-event->x()))+
486         ((mol->showatoms.at(j).screenY-event->y())*( mol->showatoms.at(j).screenY-event->y())));
487     nahdai=(da<nahda)?j:nahdai;
488     nahda=qMin(nahda,da);
489   }
490   //  printf("press =>%d RNM%d %d\n",nahdai,inRenameMode,mol->selectedatoms.size());
491   //if (nahdai!=-1)printf("MousePressEvent %d %d %f\n",nahdai,mol->showatoms.size(),nahda);
492   //  fprintf(stderr,"pressed %d %d %d  %d\n",p,pp,ppp,mol->showatoms.size());
493   if (event->buttons() & Qt::MidButton){
494 
495     if (nahdai < 0) {
496     }else
497       if (nahdai<mol->showatoms.size()) {
498         int index=nahdai;
499         if (index==(-1))return;
500         rotze=((int)index<mol->showatoms.size())?index:-1;
501         if (rotze>-1){ rCenter->show();
502 
503           glGetDoublev(GL_MODELVIEW_MATRIX,MM);
504           MM[12]=MM[13]=0;
505           glLoadMatrixd(MM);
506         }
507         updateGL();
508 
509       }
510   }
511   //*/
512   //  if((reSe | moveLab| invEditAble | atomsClickable| xdSetupMode) &&
513   if (event->buttons() & Qt::LeftButton){
514     scrx0=lastPos.x();
515     scry0=lastPos.y();
516     if (nahdai < 0) {
517     }else
518       if (nahdai<mol->showatoms.size()) {
519         int index=nahdai;
520         if (index==(-1))return;
521         double w=0,dw=0;
522         if ((pp!=p)&&(pp!=index)&&(p!=index)) {
523           V3 aa1=mol->showatoms.at(p).pos-mol->showatoms.at(pp).pos;
524           V3 aa2=mol->showatoms.at(p).pos-mol->showatoms.at(index).pos;
525           w=mol->winkel(aa1,aa2);
526           if ((ppp!=p)&&(ppp!=pp)&&(ppp!=index))
527             dw=mol->dieder(mol->showatoms.at(pp).pos-mol->showatoms.at(ppp).pos,
528                 mol->showatoms.at(pp).pos-mol->showatoms.at(p).pos,
529                 mol->showatoms.at(p).pos-mol->showatoms.at(index).pos);
530         }
531         if (atomsClickable){
532           emit jumpit(index);
533          /* printf("%s %d %d\n",
534               mol->showatoms.at(index).Label.toStdString().c_str(),
535               mol->showatoms.at(index).scod,
536               mol->showatoms.at(index).an);*/
537           if (inRenameMode) return;
538           if (!inRenameMode){
539             apair.clear();
540             if (event->modifiers()==Qt::NoModifier) {
541               int isschon=-1;
542               for (int i=0; i< mol->selectedatoms.size();i++){
543                 isschon=(mol->selectedatoms.at(i).style==index)?index:isschon;
544               }
545               mol->selectedatoms.clear();
546               if (isschon==-1){
547                 mol->selectedatoms.append(mol->showatoms[index]);
548                 mol->selectedatoms.last().style=index;
549               }
550             }
551             if ((manualAx!=nullptr)&&(!manualAx->isChecked())&&(event->modifiers()==Qt::AltModifier)) {
552               int pv1=pivot1cb->findText(mol->showatoms.at(p).Label);
553               int pv2=pivot2cb->findText(mol->showatoms.at(index).Label);
554               if ((pv1>-1)&&(pv2)){
555                   emit pivot1Changed(pv1);
556                   emit pivot2Changed(pv2);
557                   altpivot=true;
558                   //printf("new axe %d %d\n",pv1,pv2);
559               }
560 
561             }
562             if (event->modifiers()==Qt::ShiftModifier) {
563               int min=mol->showatoms.size(), max=-1;
564               for (int i=0; i< mol->selectedatoms.size();i++){
565                 min=qMin(mol->selectedatoms.at(i).style,min);
566                 max=qMax(mol->selectedatoms.at(i).style,max);
567               }
568               min=qMin((int)index,min);
569               max=qMax((int)index,max);
570               mol->selectedatoms.clear();
571               for (int i=min; i<=max; i++){
572                 mol->selectedatoms.append(mol->showatoms[i]);
573                 mol->selectedatoms.last().style=i;
574               }
575             }
576             if (event->modifiers()==Qt::ControlModifier) {
577               if (mol->selectedatoms.contains(mol->showatoms[index])){
578                 mol->selectedatoms.removeOne(mol->showatoms[index]);
579               } else {
580                 mol->selectedatoms.append(mol->showatoms[index]);
581                 mol->selectedatoms.last().style=index;
582                 //                for (int oo=0; oo<mol->selectedatoms.size(); oo++) qDebug()<<mol->selectedatoms.at(oo).Label<<mol->selectedatoms.at(oo).symmGroup<< mol->selectedatoms.at(oo).style<<mol->selectedatoms.size();
583               }
584             }
585             //	  std::cout<<mol->selectedatoms.size()<<mol->selectedatoms.last().Label.toStdString()<<std::endl;
586             emit selectionChanged();
587             updateBondActions();
588             updateGL();
589           }
590           //
591 
592           V3 hin;
593           double dmsda=0;
594           hin = Normalize(mol->showatoms.at(index).pos-mol->showatoms.at(p).pos);
595           if ((mol->showatoms.at(index).an>-1) && (mol->showatoms.at(p).an))
596             dmsda = fabs(((hin*mol->showatoms.at(index).uc)*hin)- ((hin*mol->showatoms.at(p).uc)*hin));
597           //
598           bool syok;
599           QString symml;
600           int syid=mol->showatoms.at(index).Label.section(QString::fromUtf8("»"),1).toInt(&syok);
601           if (mol->usedSymmetry.size()&&syok) symml=mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid);
602           syid=mol->showatoms.at(p).Label.section(QString::fromUtf8("»"),1).toInt(&syok);
603           if ((mol->usedSymmetry.size())&&(syok)&&(!symml.contains(mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid))))
604             symml+=mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid);
605 
606           syid=mol->showatoms.at(pp).Label.section(QString::fromUtf8("»"),1).toInt(&syok);
607           if ((mol->usedSymmetry.size())&&(syok)&&(!symml.contains(mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid))))
608             symml+=mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid);
609 
610           syid=mol->showatoms.at(ppp).Label.section(QString::fromUtf8("»"),1).toInt(&syok);
611           if ((mol->usedSymmetry.size())&&(syok)&&(!symml.contains(mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid))))
612             symml+=mol->symmcode2human(mol->usedSymmetry.at(syid-1),syid);
613           /*printf("%s org=%s iso=%d\n a%9.6f b%9.6f c%9.6f  %9.6f %9.6f %9.6f\n d%9.6f e%9.6f f%9.6f  %9.6f %9.6f %9.6f\n g%9.6f h%9.6f i%9.6f  %9.6f %9.6f %9.6f\n\n",
614             mol->showatoms.at(index).Label.toStdString().c_str(),
615             mol->showatoms.at(index).ufiso_org.toStdString().c_str(),
616             mol->showatoms.at(index).isIso,
617             mol->showatoms.at(index).uf.m11,mol->showatoms.at(index).uf.m12,mol->showatoms.at(index).uf.m13,  mol->showatoms.at(index).uc.m11,mol->showatoms.at(index).uc.m12,mol->showatoms.at(index).uc.m13,
618             mol->showatoms.at(index).uf.m21,mol->showatoms.at(index).uf.m22,mol->showatoms.at(index).uf.m23,  mol->showatoms.at(index).uc.m21,mol->showatoms.at(index).uc.m22,mol->showatoms.at(index).uc.m23,
619             mol->showatoms.at(index).uf.m31,mol->showatoms.at(index).uf.m32,mol->showatoms.at(index).uf.m33,  mol->showatoms.at(index).uc.m31,mol->showatoms.at(index).uc.m32,mol->showatoms.at(index).uc.m33
620             );// */
621 
622           if ((index!=p)&&(index!=pp)&&(mol->showatoms.at(index).Label[0]=='Q')){
623             /*printf("scod %d %f %f %f \n",mol->showatoms.at(index).scod,
624               mol->showatoms.at(index).frac.x,
625               mol->showatoms.at(index).frac.y,
626               mol->showatoms.at(index).frac.z);//  **/
627             emit bigmessage(QString("<hr><table><tr><td><b>%1</b></td><td align=\"right\"></td></tr><tr><td><b>%1--%2</b>"
628                   "</td><td align=\"right\">%5 &Aring;</td></tr><tr><td><b>%1--%2--%3</b></td><td "
629                   "align=\"right\">%6&deg;</td></tr><tr><td><b>%1--%2--%3--%4 </b></td><td "
630                   "align=\"right\">%7&deg;</td></tr><tr><td><b>%1</b> Peak Height: </td><td "
631                   "align=\"right\">%8 e&Aring;<sup>-3</sup></td><td>[%9&hellip;%10]"
632                   "</td></tr></table>%11")
633                 .arg((mol->showatoms.at(index).Label))                     //1
634                 .arg((mol->showatoms.at(p).Label))				//3
635                 .arg((mol->showatoms.at(pp).Label))			                //5			                                                //8
636                 .arg((mol->showatoms.at(ppp).Label))			                        //9
637                 .arg(sqrt(Distance(mol->showatoms.at(index).pos,mol->showatoms.at(p).pos)),8,'f',3) //4
638                 .arg(w,8,'f',2)
639                 .arg(dw,8,'f',2)
640                 .arg(mol->showatoms.at(index).peakHeight,8,'f',2)
641                 .arg(mol->pmin,3,'f',2)
642                 .arg(mol->pmax,3,'f',2)
643                 .arg(symml)
644 
645                 );
646           }
647           else if ((index!=p)&&(index!=pp)&&(mol->showatoms.at(index).Label[0]=='L')&&(mol->showatoms.at(index).an==-42)){
648             emit bigmessage(QString("<hr><table><tr><td><b>%1</b></td><td align=\"right\"></td></tr><tr><td><b>%1--%2</b>"
649                   "</td><td align=\"right\">%5 &Aring;</td></tr><tr><td><b>%1--%2--%3</b></td><td "
650                   "align=\"right\">%6&deg;</td></tr><tr><td><b>%1--%2--%3--%4 </b></td><td "
651                   "align=\"right\">%7&deg;</td></tr><tr><td><b>%1</b> a exp(-b x<sup>2</sup>)</td><td "
652                   "align=\"right\">a = %8 </td><td> b = %9 "
653                   "</td></tr></table>%11")
654                 .arg((mol->showatoms.at(index).Label))                     //1
655                 .arg((mol->showatoms.at(p).Label))				//3
656                 .arg((mol->showatoms.at(pp).Label))			                //5			                                                //8
657                 .arg((mol->showatoms.at(ppp).Label))			                        //9
658                 .arg(sqrt(Distance(mol->showatoms.at(index).pos,mol->showatoms.at(p).pos)),8,'f',3) //4
659                 .arg(w,8,'f',2)
660                 .arg(dw,8,'f',2)
661                 .arg(mol->showatoms.at(index).sof,8,'f',2)
662                 .arg(mol->showatoms.at(index).peakHeight,8,'f',2)
663                 .arg(symml)
664 
665                 );
666           }
667           else if ((index!=p)&&(index!=pp)){
668             emit bigmessage(QString("<br><hr><table><tr><td><b>%1</b> part: %8 residue: %9 %10 (fragment: %12)</td><td align=\"right\">"
669                   "</td></tr><tr><td><b>%1--%2</b></td><td align=\"right\">%5 &Aring;</td><td>&nbsp;&nbsp;&nbsp;DMSDA: %13 &Aring;<sup>2</sup></td></tr>"
670                   "<tr><td><b>%1--%2--%3</b></td><td align=\"right\">%6&deg;</td><td>&nbsp;&nbsp;&nbsp;1,3 Distance( DANG) %14 &Aring;</td></tr><tr><td>"
671                   "<b>%1--%2--%3--%4 </b></td><td align=\"right\">%7&deg;</td></tr></table>%11")
672                 .arg((mol->showatoms.at(index).Label))			       //1
673                 .arg((mol->showatoms.at(p).Label))			               //2
674                 .arg((mol->showatoms.at(pp).Label))			       //3
675                 .arg((mol->showatoms.at(ppp).Label))			       //4
676                 .arg(sqrt(Distance(mol->showatoms.at(index).pos,mol->showatoms.at(p).pos)),8,'f',3) //5
677                 .arg(w,8,'f',2)			                            //6
678                 .arg(dw,8,'f',2)                                               //7
679                 .arg(mol->showatoms.at(index).part)
680                 .arg(mol->showatoms.at(index).resiNr)
681                 .arg(mol->showatoms.at(index).ResiClass)
682                 .arg(symml)
683                 .arg(mol->showatoms.at(index).molindex)
684                 .arg(dmsda,5,'e',2)
685                 .arg(sqrt(Distance(mol->showatoms.at(index).pos,mol->showatoms.at(pp).pos)),8,'f',3)
686                 );
687           }
688           //				   ,QMessageBox::Ok);
689           ppp = pp;
690           pp = p;
691           p = index;
692         }
693 
694         //888
695       }
696   }
697 }
698 
mouseMoveEvent(QMouseEvent * event)699 void ChGL::mouseMoveEvent(QMouseEvent *event) {
700   double nahda=pickradius,da=0;
701   rectangle=false;
702   int nahdai=-1;
703   bool changed=false;
704   scrx=event->x();
705   scry=event->y();
706   for (int j=0; j<mol->showatoms.size();j++){
707     if (mol->showatoms.at(j).hidden) continue;
708     da=(((mol->showatoms.at(j).screenX-event->x())*( mol->showatoms.at(j).screenX-event->x()))+
709         ((mol->showatoms.at(j).screenY-event->y())*( mol->showatoms.at(j).screenY-event->y())));
710     nahdai=(da<nahda)?j:nahdai;
711     nahda=qMin(nahda,da);
712   }
713   //if (nahdai!=-1)printf("MouseMoveEvent %d %d %f\n",nahdai,mol->showatoms.size(),nahda);
714   // printf("move =>%d\n",nahdai);
715   if ((mouseOverInteraction)&&(!event->buttons())) {
716     if (imFokus!=nahdai) changed=true;
717     imFokus=nahdai;
718     if (imFokus==-1) {
719       emit qpfoci(-1.0);
720       emit message("");
721     }
722     else {
723       emit message(mol->showatoms.at(imFokus).Label);
724       if ((mol->showatoms.at(imFokus).an<0)) emit qpfoci(mol->showatoms.at(imFokus).peakHeight);
725       else qpfoci(-1.0);
726     }
727 
728     if (changed) {
729       // printf("MouseMoveEvent changed %d %d %d\n",nahdai,mol->showatoms.size(),imFokus);fflush(stdout);
730       updateGL();
731     }
732     return;
733   }
734   GLfloat dx = GLfloat( event->x() - lastPos.x()) / ww;
735   GLfloat dy = GLfloat( event->y() - lastPos.y()) / wh;
736 
737   if (event->buttons() & Qt::MidButton){
738 
739     moving->start(dratpause);
740     glTranslateL(dx*viewAngle*3,-dy*viewAngle*3,0);
741     updateGL();
742   }
743 
744   if ((event->buttons() & Qt::LeftButton && (event->modifiers()==(Qt::ShiftModifier|Qt::ControlModifier)))) {
745     rectangle=true;
746     int minxp=ww,minyp=wh,maxxp=0,maxyp=0;
747     minxp=qMin(scrx0,scrx);
748     minyp=qMin(scry0,scry);
749     maxxp=qMax(scrx0,scrx);
750     maxyp=qMax(scry0,scry);
751     mol->selectedatoms.clear();
752     for (int j=0; j<mol->showatoms.size();j++){
753       if (mol->showatoms.at(j).hidden) continue;
754       if ((mol->showatoms.at(j).screenX>minxp)&&
755           (mol->showatoms.at(j).screenX<maxxp)&&
756           (mol->showatoms.at(j).screenY>minyp)&&
757           (mol->showatoms.at(j).screenY<maxyp)){
758 
759         mol->selectedatoms.append(mol->showatoms[j]);
760         mol->selectedatoms.last().style=j;
761       }
762     }
763     updateBondActions();
764     updateGL();
765   }else
766     if ((event->buttons() & Qt::LeftButton)) {
767       if (event->modifiers()==Qt::ShiftModifier) {
768         moving->start(dratpause);
769         glTranslateL(dx*viewAngle*3,-dy*viewAngle*3,0);
770         updateGL();}
771       else
772       {
773         moving->start(dratpause);
774         double slow=1.0;
775         if (event->modifiers()==Qt::ShiftModifier) slow=0.25;
776         if (event->modifiers()==Qt::ControlModifier) slow=0.06;
777         emit movedByUser();
778         //if ((idl!=nullptr)&&(idl->isActive())) idl->stop();
779         if ((manualAx!=nullptr)&&(manualAx->isChecked())&&(event->modifiers()==Qt::AltModifier)){
780             GLdouble mm[16];
781             glGetDoublev(GL_MODELVIEW_MATRIX,mm);
782             double det=
783               mm[0]*mm[5]*mm[10] - mm[8]*mm[5]*mm[2]+
784               mm[1]*mm[6]*mm[8]  - mm[9]*mm[6]*mm[0]+
785               mm[2]*mm[4]*mm[9]  - mm[10]*mm[4]*mm[1];
786             Matrix mat=Matrix(mm[0],mm[1],mm[2],mm[4],mm[5],mm[6],mm[8],mm[9],mm[10]);
787             //printf("A%g %g\n",determinant(mat),det);
788             mat=mat*pow(det,-1.0/3.0);
789             //printf("B%g %g\n",determinant(mat),det);
790 
791             V3 axe=Normalize(V3(axx->value(),axy->value(),axz->value()));
792             axe=transponse(mat)*axe;
793             double arr[4];
794             arr[0]=dx*360.0;
795             arr[1]=0.0;
796             arr[2]=1.0;
797             arr[3]=0.0;
798             axe=mol->rotarb(arr)*axe;
799             arr[0]=dy*360.0;
800             arr[1]=1.0;
801             arr[2]=0.0;
802             arr[3]=0.0;
803             axe=mol->rotarb(arr)*axe;
804             axe=mat*axe;
805             axx->setValue(axe.x);
806             axy->setValue(axe.y);
807             axz->setValue(axe.z);
808             splitRotate();
809         }else{
810         glRotateL(dy*360.0*slow,1.0f,0.0f,0.0f);
811         glRotateL(dx*360.0*slow,0.0f,1.0f,0.0f);
812       }
813       }
814       updateGL();
815     }
816     else if((event->buttons() & Qt::RightButton)){
817       if (!invertMouseZoom->isChecked()){
818 
819         moving->start(dratpause);
820         glScaled(1.0-dy,1.0-dy,1.0-dy);
821         //     mlsc/=1.0-dy;
822       }else {
823 
824         moving->start(dratpause);
825         glScaled(1.0+dy,1.0+dy,1.0+dy);
826         //     mlsc/=1.0+dy;
827       }
828       updateGL();
829     }
830   lastPos = event->pos();
831 }
832 
lastClicked()833 QList<int> ChGL::lastClicked(){
834   QList<int> pppp;
835   //if ((ppp>=0)&&(ppp<mol->showatoms.size())&&(ppp!=pp)&&(ppp!=p)) pppp.append(ppp);
836   if ((  p>=0)&&(  p<mol->showatoms.size())) pppp.append(p);
837   if (( pp>=0)&&( pp<mol->showatoms.size())&&(pp!=p)) pppp.append(pp);
838   return pppp;
839 }
840 
wheelEvent(QWheelEvent * event)841 void ChGL::wheelEvent(QWheelEvent *event){
842   /*
843 modifiers:
844 Qt::NoModifier	        0x00000000	No modifier key is pressed.
845 Qt::ShiftModifier	    0x02000000	A Shift key on the keyboard is pressed.
846 Qt::ControlModifier	    0x04000000	A Ctrl key on the keyboard is pressed.
847 Qt::AltModifier	        0x08000000	An Alt key on the keyboard is pressed.
848 Qt::MetaModifier	    0x10000000	A Meta key on the keyboard is pressed.
849 Qt::KeypadModifier	    0x20000000	A keypad button is pressed.
850 Qt::GroupSwitchModifier	0x40000000	X11 only. A Mode_switch key on the keyboard is pressed.
851 */
852   int numDegrees = event->delta() / 8;
853   int numSteps = numDegrees / 15;
854   if (event->modifiers()==Qt::NoModifier){
855     int d = myFont.pointSize();
856     d=(d+numSteps>4)?d+numSteps:d;
857     labScal+=0.01*numSteps;
858     labScal=(labScal<0.1)?0.1:labScal;
859     d=qMax(d,7);
860     if (!useTextureLabels->isChecked()) myFont.setPointSize(d);
861     updateGL();
862   }
863   if (event->modifiers()==Qt::ControlModifier){
864     emit diffscroll(numSteps,1);
865   }
866   if (event->modifiers()==Qt::ShiftModifier){
867     emit diffscroll(numSteps,0);
868   }
869   if (event->modifiers()==(Qt::AltModifier|Qt::ShiftModifier)){
870     double va=viewAngle+0.1*numSteps;
871     setViewAngle(va);
872   }
873   if (event->modifiers()==Qt::AltModifier){
874     int afr=mol->fogrange;
875     mol->fogrange+=numSteps*5;
876     mol->fogrange=qMax(mol->fogrange,1);
877     mol->fogrange=qMin(mol->fogrange,204);
878     //printf("fogrange = %d\n", mol->fogrange);
879     if (afr!=mol->fogrange){
880       glFogi(GL_FOG_MODE,GL_LINEAR);
881       glFogi(GL_FOG_START,205-mol->fogrange);
882       glFogi(GL_FOG_END,205+mol->fogrange);
883       GLfloat fgc[4]={(GLfloat)backGroundColor.redF(),(GLfloat)backGroundColor.greenF(),(GLfloat)backGroundColor.blueF(),1.0};
884       glFogfv(GL_FOG_COLOR,fgc);
885       updateGL();}
886   }
887 
888   event->accept();
889 }
890 
contextMenuEvent(QContextMenuEvent * event)891 void ChGL::contextMenuEvent(QContextMenuEvent *event){
892   double nahda=pickradius,da=0;
893   int nahdai=-1;
894   for (int j=0; j<mol->showatoms.size();j++){
895     if (mol->showatoms.at(j).hidden) continue;
896     da=(((mol->showatoms.at(j).screenX-event->x())*( mol->showatoms.at(j).screenX-event->x()))+
897         ((mol->showatoms.at(j).screenY-event->y())*( mol->showatoms.at(j).screenY-event->y())));
898     nahdai=(da<nahda)?j:nahdai;
899     nahda=qMin(nahda,da);
900   }
901 
902   //printf("contextEvent %d %d %f\n",nahdai,mol->showatoms.size(),nahda);
903   if ((nahdai < 0)||(mol->showatoms.size()<nahdai)) {
904     return;
905   }
906   else {
907     int idx=nahdai;
908     ImeanThisAtom=idx;
909     if (idx>mol->showatoms.size()) return;
910     QList<QAction *> sfas = sfacMenu->actions();
911     for (int k=0;k<sfas.size();k++){
912       sfas[k]->setEnabled(sfas[k]->text()!=mol->pse(mol->showatoms.at(idx).an));
913     }
914     QMenu *menu = new QMenu(mol->showatoms.at(idx).Label);
915     if (mol->showatoms.at(idx).symmGroup==0) menu->addMenu(sfacMenu);
916     QAction *a;
917     if ((mol->selectedatoms.isEmpty())&&(mol->showatoms.at(idx).symmGroup==0)) {
918       a=menu->addAction(QIcon(":/xle-icons/killselected.svg"),QString("Delete %1 ").arg(mol->showatoms.at(idx).Label),
919           chparent,SLOT(deleteSelectedAtoms()));
920       a->setData(idx);
921     }else if (mol->showatoms.at(idx).symmGroup==0){
922       a=menu->addAction(QIcon(":/xle-icons/killselected.svg"),QString("Delete selected atoms"),
923           chparent,SLOT(deleteSelectedAtoms()));
924       a->setData(-1);
925     }
926     if (!mol->selectedatoms.isEmpty()) a=menu->addAction("Change RESI or PART of selected atoms",chparent,SLOT(changeResiPart()));
927     menu->addSeparator();
928     a=menu->addAction(QString("Set rotation center to %1").arg(mol->showatoms.at(idx).Label),this,SLOT(setRotationCenter()));
929     a->setData(idx);
930     a=menu->addAction(QString("Expand contacts around %1").arg(mol->showatoms.at(idx).Label),this,SLOT(expand()));
931     a->setData(idx);
932     a=menu->addAction(QString("Hide this fragment"),this,SLOT(hideThisFragment()));
933     a->setData(idx);
934     a=menu->addAction(QString("Select this fragment"),this,SLOT(selectThisFragment()));
935     a->setData(idx);
936     a=menu->addAction(QString("Hide other fragments"),this,SLOT(hideOtherFragments()));
937     a->setData(idx);
938     a=menu->addAction(QString("Fragment includes symmetry generated"), this ,SLOT(toogleWithSymmetry(bool)));
939     a->setCheckable(true);
940     a->setChecked(!(withsymm));
941     if (!mol->selectedatoms.isEmpty()) a=menu->addAction("Hide selected Atoms",this,SLOT(hideSelected()));
942     bool hasSameBonds=false;//for sadi two neighbor) atoms need to be same atomic number and no hydrogen
943     //it warks if they are not the same but gives a warning and does not make much sense
944     if (idx<mol->asymm.size()) for (int nb=1; nb<mol->knoepfe.at(idx).neighbors.size(); nb++){
945       if ((mol->knoepfe.at(idx).neighbors.at(nb-1)>=mol->asymm.size())||(mol->knoepfe.at(idx).neighbors.at(nb)>=mol->asymm.size())) continue;
946       if ((mol->asymm.at(mol->knoepfe.at(idx).neighbors.at(nb-1)).an>0)&&
947           (mol->asymm.at(mol->knoepfe.at(idx).neighbors.at(nb-1)).an==mol->asymm.at(mol->knoepfe.at(idx).neighbors.at(nb)).an))hasSameBonds=true;
948     }
949     //  qDebug()<<hasSameBonds;
950     if(!mol->selectedatoms.isEmpty()){
951       QMenu *RestrMenu = new QMenu("Add restraints");
952       QMenu *ConstrMenu = new QMenu("Add constraints");
953       RestrMenu->addAction("ISOR", this, SLOT(addISOR()));
954       if (hasSameBonds){
955         QAction *restr;
956         restr=RestrMenu->addAction("SADI", this, SLOT(addSADI()));
957         restr->setData(idx);
958       }
959       if(mol->selectedatoms.size() == 2){
960         RestrMenu->addAction("DFIX", this, SLOT(addDFIX()));
961         RestrMenu->addAction("DANG", this, SLOT(addDANG()));
962       }
963       if(mol->selectedatoms.size() >= 4){
964         RestrMenu->addAction("FLAT", this, SLOT(addFLAT()));
965       }
966       if(mol->selectedatoms.size() > 1){
967         ConstrMenu->addAction("EXYZ", this, SLOT(addEXYZ()));
968         ConstrMenu->addAction("EADP", this, SLOT(addEADP()));
969         RestrMenu->addAction("RIGU", this, SLOT(addRIGU()));
970         RestrMenu->addAction("DELU", this, SLOT(addDELU()));
971         RestrMenu->addAction("SIMU", this, SLOT(addSIMU()));
972         RestrMenu->addAction("CHIV", this, SLOT(addCHIV()));
973       }
974       menu->addMenu(RestrMenu);
975       menu->addMenu(ConstrMenu);
976     }else if (hasSameBonds) {
977       QMenu *RestrMenu = new QMenu("Add restraints");
978       QAction *restr;
979       restr=RestrMenu->addAction("SADI", this, SLOT(addSADI()));
980       restr->setData(idx);
981       menu->addMenu(RestrMenu);
982     }
983     menu->addSeparator();
984     QMenu *enviMenu = new QMenu("ENVI-Settings");
985     enviMenu->addAction("Change envi range", this, SLOT(changeEnviRange()));
986     enviMenu->addAction(enviNoQ);
987     enviMenu->addAction(enviCova);
988     menu->addMenu(enviMenu);
989     if ((int) idx < mol->asymm.size()){
990       a=menu->addAction(QString("List ENVIronment of %1").arg(mol->showatoms.at(idx).Label),this,SLOT(envi()));
991       a->setData(idx);
992     }
993     menu->addSeparator();
994     int ssgr=0;
995     int adpat=0;
996     for (int seli=0; seli<mol->selectedatoms.size(); seli++){
997       if ((mol->showatoms.at(seli).symmGroup==0)&&(!mol->selectedatoms.at(seli).isIso))adpat++;
998     }
999     for (int seli=0; seli<mol->selectedatoms.size(); seli++){
1000       if (mol->selectedatoms.at(seli).symmGroup>0) ssgr+=mol->selectedatoms.at(seli).symmGroup;
1001       else {
1002         ssgr=0;
1003         break;
1004       }
1005     }
1006     if (ssgr) adpat=0;
1007     if (ssgr){
1008       a=menu->addAction(QString("Move selected atoms to selected sites"),
1009           chparent,SLOT(moveSymmMateSel()));
1010       //////// 28.03.12
1011       if (mol->showatoms.at(idx).part<0){
1012         a=menu->addAction(QString("Copy %1 here").arg(mol->showatoms.at(idx).Label.section("_",0,0)),
1013             chparent,SLOT(copySymmMate()));
1014         a->setData(idx);
1015       }
1016       //////// -
1017     }else{
1018       if (mol->showatoms.at(idx).symmGroup>0){
1019         a=menu->addAction(QString("Move %1 here").arg(mol->showatoms.at(idx).Label.section("_",0,0)),
1020             chparent,SLOT(moveSymmMate()));
1021         a->setData(idx);
1022         if (mol->showatoms.at(idx).part<0){
1023           a=menu->addAction(QString("Copy %1 here").arg(mol->showatoms.at(idx).Label.section("_",0,0)),
1024               chparent,SLOT(copySymmMate()));
1025           a->setData(idx);
1026         }
1027 
1028       }
1029     }
1030     menu->addSeparator();
1031     if ((nahdai<mol->asymm.size())&&(mol->knoepfe.at(idx).neighbors.size()==1)&&((mol->showatoms.at(idx).an==6)||(mol->showatoms.at(idx).an==5))) {
1032 
1033       //	printf("%s hat %d Nachbarn\n",mol->showatoms.at(idx).Label.toStdString().c_str(),mol->knoepfe.at(idx).neighbors.size());
1034       a=menu->addAction(QString("Add dissordered %1 Hydrogen atoms").arg(((mol->showatoms.at(idx).an==5))?"methyl":"-NH3"),chparent,SLOT(addDissorderedMethyl()));
1035       a->setData(idx);
1036       a=menu->addAction(QString("Add ordered %1 Hydrogen atoms").arg(((mol->showatoms.at(idx).an==5))?"methyl":"-NH3+"),chparent,SLOT(addMethyl()));
1037       a->setData(idx);
1038       a=menu->addAction(QString("Add terminal %1 Hydrogen atoms").arg(((mol->showatoms.at(idx).an==5))?"=CH2 ":"=NH2+"),chparent,SLOT(addH93()));
1039       a->setData(idx);
1040       if (mol->showatoms.at(idx).an==5){
1041         a=menu->addAction(QString("Add acetylenic C-H Hydrogen atom"),chparent,SLOT(addH163()));
1042         a->setData(idx);
1043       }
1044       if (mol->showatoms.at(idx).an==6){
1045         a=menu->addAction(QString("Add %1 Hydrogen atoms").arg("-NH2 (non planar)"),chparent,SLOT(addHnonplanarAminR1()));
1046         a->setData(idx);
1047       }
1048     }
1049     if ((nahdai<mol->asymm.size())&&(mol->knoepfe.at(idx).neighbors.size()==1)&&(mol->showatoms.at(idx).an==7)){
1050         a->setData(idx);
1051         a=menu->addAction(QString("Add hydroxyl Hydrogen atom to %1").arg(mol->showatoms.at(idx).Label.section("_",0,0)),chparent,SLOT(addHydroxyl()));
1052         a->setData(idx);
1053     }
1054     if ((nahdai<mol->asymm.size())&&(mol->knoepfe.at(idx).neighbors.size()==2)&&((mol->showatoms.at(idx).an==6)||(mol->showatoms.at(idx).an==5))) {
1055       a=menu->addAction(QString("Add %1 Hydrogen atoms").arg(((mol->showatoms.at(idx).an==5))?">CH2":">NH2+"),chparent,SLOT(addH23()));
1056       a->setData(idx);
1057       a=menu->addAction(QString("Add %1 Hydrogen atom").arg(((mol->showatoms.at(idx).an==5))?">CH":">NH (planar)"),chparent,SLOT(addH43()));
1058       a->setData(idx);
1059       //addHnonplanarAminR2();
1060       if (mol->showatoms.at(idx).an==6){
1061         a=menu->addAction(QString("Add %1 Hydrogen atom").arg(">NH (non planar)"),chparent,SLOT(addHnonplanarAminR2()));
1062         a->setData(idx);
1063       }
1064     }
1065     if ((idx < mol->asymm.size()) && (mol->asymm.at(idx).an>-1)) {
1066       a=menu->addAction(QString("Use %1 as new label for rename mode").arg(mol->showatoms.at(idx).Label.section("_",0,0)),chparent,SLOT(renameThisAtom()));
1067       a->setData(idx);
1068     }
1069 
1070     if(!mol->selectedatoms.isEmpty()){
1071       menu->addAction(QString("Make selected atoms ANIS"),this,SLOT(addANIS()));
1072     }
1073     if (adpat) {
1074       if (mol->selectedatoms.isEmpty()){
1075         a=menu->addAction(QIcon(":/xle-icons/sina.svg"),QString("make %1 isotropic (ISOT)")
1076             .arg(mol->showatoms.at(idx).Label),chparent,SLOT(sina()));
1077         a->setData(idx);
1078       }else{
1079         a=menu->addAction(QIcon(":/xle-icons/sina.svg"),QString("make selected atoms isotropic (ISOT)"),chparent,SLOT(sina()));
1080         a->setData(-1);
1081       }
1082     }
1083     if ((idx<mol->asymm.size())&&(mol->asymm.at(idx).an>-1)){
1084         QAction *a = menu->addAction("Draw voronoi polyeder of this atom",chparent,SLOT(makeVoro()));
1085         a->setData(idx);
1086       }
1087 
1088     if (mol->showatoms.at(p).molindex!=mol->showatoms.at(idx).molindex){
1089       menu->addSeparator();
1090       a=menu->addAction(QString("Inherit Labels from molecule around %1 to atoms around %2")
1091           .arg(mol->showatoms.at(p).Label)
1092           .arg(mol->showatoms.at(idx).Label)
1093           ,chparent,SLOT(inheritLabels()));
1094       ppp = pp;
1095       pp = p;
1096       p = idx;
1097 
1098     }
1099 
1100     menu->exec(event->globalPos());
1101     delete enviMenu;
1102     delete menu;
1103   }
1104 }
1105 
Listen()1106 void ChGL::Listen(){//! forces the lists to be rerendered.
1107   murx=-__LINE__;
1108 }
1109 
disSelection()1110 void ChGL::disSelection(){//! Un select everything.
1111   //rotCenter();
1112   QTime rzeit;
1113   rzeit.start();
1114   mol->selectedatoms.clear();
1115   apair.clear();
1116   updateBondActions();
1117   updateGL();
1118 }
1119 
selectPair(const QString & s)1120 void ChGL::selectPair(const QString &s){
1121   apair.clear();
1122   //! Selelects two atoms from the spaces separated string s. @param space separated pair of atom labels.
1123   mol->selectedatoms.clear();
1124   if (s.isEmpty()) {
1125     updateGL();
1126     return;
1127   }
1128   QStringList index=s.split(' ',skipEmptyParts);
1129   if (index.size()<2) {
1130     updateGL();
1131     return;
1132   }
1133   /*
1134    *
1135    length=b.length;
1136    ato1=b.ato1;
1137    ato2=b.ato2;
1138    a1=b.a1;
1139    a2=b.a2;
1140    */
1141   MyBond pair;
1142   pair.length=1.0;
1143   for (int i=0; i<index.size();i++){
1144     mol->selectedatoms.append(mol->showatoms[index.at(i).toInt()]);
1145     mol->selectedatoms.last().style=index.at(i).toInt();
1146     if (i==0){
1147       pair.ato1=&mol->selectedatoms.last();
1148       pair.a1=index.at(i).toInt();
1149     }else{
1150       pair.ato2=&mol->selectedatoms.last();
1151       pair.a2=index.at(i).toInt();
1152     }
1153   }
1154   //printf("a pair is made %d %d\n",pair.a1,pair.a2);
1155   apair.append(pair);
1156   //updateBondActions();
1157   updateGL();
1158 }
1159 
pairing(QList<int> ima,QList<int> imb)1160 void ChGL::pairing(QList<int> ima, QList<int> imb){
1161   MyBond pair;
1162   pair.length=1.0;
1163   for (int i=0; i<ima.size(); i++){
1164     pair.ato1=&mol->showatoms[ima.at(i)];
1165     pair.ato2=&mol->showatoms[imb.at(i)];
1166     pair.a1=ima.at(i);
1167     pair.a2=ima.at(i);
1168     apair.append(pair);
1169   }
1170   updateGL();
1171 }
1172 
selectResiByNr(int nr)1173 void ChGL::selectResiByNr(int nr){//! Selects atoms in residues with the same residue number. @param nr residue number.
1174   mol->selectedatoms.clear();
1175   apair.clear();
1176   for (int i=0; i<mol->showatoms.size();i++){
1177     if (mol->showatoms.at(i).resiNr==nr) {
1178       mol->selectedatoms.append(mol->showatoms[i]);
1179       mol->selectedatoms.last().style=i;
1180     }
1181   }
1182   draw();
1183   if (hiddenThings) hideNonSelected();
1184   updateBondActions();
1185   updateGL();
1186 }
1187 
invertSelection()1188 void ChGL::invertSelection(){//!Inverts stelection, means selected atoms get disselected and vice versa.
1189   CEnvironment tempa=mol->selectedatoms;
1190   //  printf("invert %d %d\n",tempa.size(),mol->selectedatoms.size());
1191   mol->selectedatoms.clear();
1192 
1193   for (int i=0; i<mol->showatoms.size();i++){
1194     if (!tempa.contains(mol->showatoms.at(i))) {
1195       mol->selectedatoms.append(mol->showatoms[i]);
1196       mol->selectedatoms.last().style=i;
1197     }
1198   }
1199   draw();
1200   rehide();
1201   updateBondActions();
1202   updateGL();
1203 }
1204 
findPivot()1205 void ChGL::findPivot(){
1206     //printf("findpv %p\n",whyNotSplit);
1207     if ((altpivot)||(whyNotSplit==nullptr)) return;
1208    // for(int i=0; i<mol->showatoms.size(); i++) mol->showatoms[i].hidden=0;
1209     if (mol->selectedatoms.size()<3) {
1210         whyNotSplit->setText("<h2>Select at least 3 atoms first.</h2>");
1211         emit splitable(canSplitRotate());
1212         return;
1213     }
1214     //printf("findPivot: ");
1215     pivot=-1;pivot2=-1;
1216     emit pivot2Changed(pivot2);
1217     emit pivot1Changed(pivot);
1218     int molidx=-1,mi;
1219     seat.clear();
1220     for (int i=0; i<mol->selectedatoms.size();i++){//all selectet atoms have to be in the same molecule
1221         int ii=mol->selectedatoms.at(i).style;
1222         if ((ii<0)||(ii>=mol->asymm.size()))continue;
1223         mi=mol->asymm.at(ii).molindex;
1224         if ((molidx!=-1)&&(molidx!=mi)) {
1225             whyNotSplit->setText("<h2>Selected atoms have to be in the same molecule.</h2>");
1226             emit splitable(canSplitRotate());
1227             return;
1228         }
1229         molidx=mi;
1230         seat.append(ii);
1231     }
1232     int atinmol=0;
1233     for (int i=0; i<mol->asymm.size();i++){
1234         if (mol->asymm.at(i).molindex==molidx) atinmol++;
1235     }
1236     //printf("==%d\n",__LINE__);
1237     if (mol->selectedatoms.size()>=atinmol) {
1238         whyNotSplit->setText("<h2>Only a part of a molecule may be selected.<br>Or you have to specify atoms definig the rotation axis yourself.</h2>");
1239         emit splitable(canSplitRotate());
1240         return;
1241     } //only a part of the molecule may be selected
1242     // */
1243     for (int i=0;i<seat.size();i++){
1244         //printf("**%d %d\n",mol->knoepfe.size(),seat.at(i));
1245         int isin=0,ks=mol->knoepfe.at(seat.at(i)).neighbors.size();
1246         for (int j=0;j<ks; j++){
1247             int nb=mol->knoepfe.at(seat.at(i)).neighbors.at(j);
1248             if (seat.contains(nb))isin++;
1249         }
1250         if ((pivot==-1)&&(isin<ks)) {pivot=seat.at(i);emit pivot1Changed(pivot);}
1251         else if (isin<ks) {
1252             whyNotSplit->setText("<h2>Only one atom is allowed to have bonds to none selected atoms.</h2>");
1253             emit splitable(canSplitRotate());
1254             return;
1255         }
1256     }
1257     //printf("==%d\n",__LINE__);
1258     if (pivot<0) {
1259         emit splitable(canSplitRotate());
1260         return;
1261     }
1262     int isin=0,ks=mol->knoepfe.at(pivot).neighbors.size();
1263     for (int j=0;j<ks; j++){
1264         int nb=mol->knoepfe.at(pivot).neighbors.at(j);
1265         if (seat.contains(nb)){pivot2=nb;emit pivot2Changed(pivot2);isin++;}
1266     }
1267     if (isin>1) {
1268         whyNotSplit->setText("<h2>pivot atom may be bonded to only one selected atoms.</h2>");
1269         emit splitable(canSplitRotate());
1270         return;
1271     }
1272     whyNotSplit->setText(QString("<h2>You can rotate around %1=%2</h2>").arg(mol->asymm.at(pivot).Label).arg(mol->asymm.at(pivot2).Label));
1273     emit splitable(canSplitRotate());
1274 }
1275 
splitRotate()1276 void ChGL::splitRotate(){
1277     mol->splitbonds.clear();
1278     mol->splitLeftAtoms.clear();
1279     mol->splitRightAtoms.clear();
1280     if (!canSplitRotate())return;
1281     if ((pivot<0)||(pivot2<0))return;
1282     for (int i=0; i<seat.size();i++){
1283         mol->splitLeftAtoms.append(mol->asymm[seat.at(i)]);
1284         mol->splitRightAtoms.append(mol->asymm[seat.at(i)]);
1285        // if (seat.at(i)!=pivot) mol->showatoms[seat.at(i)].hidden=1;
1286     }
1287     //mol->selectedatoms.clear();
1288     //printf("%p %p\n", angle1, angle2);
1289     double arr[4];
1290     arr[0]=angle1->value();
1291     V3 ax=(manualAx->isChecked())?
1292                 Normalize(V3(axx->value(),axy->value(),axz->value())):
1293                 Normalize(mol->asymm.at(pivot).pos-mol->asymm.at(pivot2).pos);
1294     arr[1]=ax.x;
1295     arr[2]=ax.y;
1296     arr[3]=ax.z;
1297     if (!manualAx->isChecked()){
1298         axx->setValue(ax.x);
1299         axy->setValue(ax.y);
1300         axz->setValue(ax.z);
1301     }
1302     Matrix R=mol->rotarb(arr);
1303     arr[0]=-angle2->value();
1304     Matrix Rbar=mol->rotarb(arr);
1305     V3 org=mol->asymm.at(pivot).pos;
1306     for (int i=0; i<seat.size();i++){
1307         mol->splitLeftAtoms[i].pos=R*(mol->splitLeftAtoms.at(i).pos-org)+org;
1308         mol->splitRightAtoms[i].pos=Rbar*(mol->splitRightAtoms.at(i).pos-org)+org;
1309     }
1310     mol->splitbonds=mol->connecting(mol->splitRightAtoms,true);
1311     mol->splitbonds+=mol->connecting(mol->splitLeftAtoms,true);
1312     //rotze=pivot;
1313     updateGL();
1314 }
1315 
canSplitRotate()1316 bool ChGL::canSplitRotate(){
1317     if ((pivot>-1)&&(pivot2>-1)&&(pivot<mol->asymm.size())&&(pivot2<mol->asymm.size())&&(mol->selectedatoms.size()>2)) return true;
1318     return false;
1319 }
1320 
updateBondActions()1321 void ChGL::updateBondActions(){//!<changes the visibility state of QActions in the 'Selection Toolbar'.
1322   bool p=pause;
1323   pause=true;
1324   clearSelection->setVisible(!mol->selectedatoms.isEmpty());
1325   invSelection->setVisible(!mol->selectedatoms.isEmpty());
1326   centroid->setVisible(mol->selectedatoms.size()>1);
1327   centerSelection->setVisible((!mol->selectedatoms.isEmpty())||(centerSelection->isChecked()));
1328   delSelAt->setVisible(!mol->selectedatoms.isEmpty());
1329   delSelAt->setEnabled(!mol->selectedatoms.isEmpty());
1330   hideNotSelection->setVisible(!mol->selectedatoms.isEmpty());
1331   cntrPlot->setVisible(((!fVertexes[0].isEmpty()||!fVertexes[1].isEmpty())&&(mol->selectedatoms.size()==3)));
1332   unhide->setVisible(hiddenThings);
1333   invhide->setVisible(hiddenThings);
1334   if (mol->selectedatoms.size()!=2){
1335     addBond->setVisible(false);
1336     killBond->setVisible(false);
1337   }
1338   else{
1339     int da=0;
1340     for (int i=0; i<mol->showbonds.size();i++){
1341       if (((mol->selectedatoms.at(0).style==mol->showbonds.at(i).a1)||
1342             (mol->selectedatoms.at(0).style==mol->showbonds.at(i).a2))&&
1343           ((mol->selectedatoms.at(1).style==mol->showbonds.at(i).a1)||
1344            (mol->selectedatoms.at(1).style==mol->showbonds.at(i).a2))) da=i;
1345     }
1346     if (da){
1347       addBond->setVisible(false);
1348       killBond->setVisible(true);
1349       killBond->setData(da);
1350     }
1351     else{
1352       addBond->setVisible(true);
1353       killBond->setVisible(false);
1354     }
1355   }
1356   findPivot();
1357   pause=p;
1358 }
1359 
connectSelection()1360 void ChGL::connectSelection(){//!creates a bond betwen two selected atoms.
1361   if (mol->selectedatoms.size()!=2) return;
1362   MyBond b;
1363   b.a1=mol->selectedatoms.at(0).style;
1364   b.a2=mol->selectedatoms.at(1).style;
1365   b.ato1=&mol->showatoms[mol->selectedatoms.at(0).style];
1366   b.ato2=&mol->showatoms[mol->selectedatoms.at(1).style];
1367   b.length=sqrt(Distance(b.ato1->pos,b.ato2->pos));
1368   mol->showbonds.append(b);
1369   mol->selectedatoms.clear();
1370   updateBondActions();
1371   updateGL();
1372 }
1373 
disConnectSelection(int index)1374 void ChGL::disConnectSelection(int index){//! destroyes the bond between two selected atoms.
1375   mol->showbonds.removeAt(index);
1376   mol->selectedatoms.clear();
1377   updateBondActions();
1378   updateGL();
1379 }
1380 
setAtom(bool b)1381 void ChGL::setAtom(bool b){//!toggles atoms
1382   drawAt=b;
1383   updateGL();
1384 }
1385 
setBond(bool b)1386 void ChGL::setBond(bool b){//!toggles bonds
1387   drawBo=b;
1388   updateGL();
1389 }
1390 
setLabel(bool b)1391 void ChGL::setLabel(bool b){//!toggles lables
1392   drawLa=b;
1393   updateGL();
1394 }
1395 
setHBond(bool b)1396 void ChGL::setHBond(bool b){//!toggles H-bonds
1397   drawHb=b;
1398   updateGL();
1399 }
1400 
setBGGradient(bool b)1401 void ChGL::setBGGradient(bool b){//!toggles back gound gradient
1402   bggradient=b;
1403   updateGL();
1404 }
1405 
setADP(bool b)1406 void ChGL::setADP(bool b){//!toggles ellipsoids
1407   drawADP=b;
1408   updateGL();
1409 }
1410 
setMSAA(bool b)1411 void ChGL::setMSAA(bool b){
1412   if (b) {
1413     glEnable(GL_MULTISAMPLE);
1414   }
1415   else  {
1416     glDisable(GL_MULTISAMPLE);
1417   }
1418   updateGL();
1419 }
1420 
setUnit(bool b)1421 void ChGL::setUnit(bool b){//!toggles unit cell box
1422   drawUc=b;
1423   updateGL();
1424 }
1425 
changeBColor()1426 void ChGL::changeBColor(){//! a color dialog for chosing a new back ground color
1427   QColor bc= QColorDialog::getColor(backGroundColor, this);
1428   if(bc.isValid()) backGroundColor=bc;
1429   updateGL();
1430 }
1431 
changeTColor()1432 void ChGL::changeTColor(){//! a color dialog for chosing a label color
1433   QColor lc= QColorDialog::getColor(labelColor, this);
1434   if (lc.isValid()) labelColor=lc;
1435   updateGL();
1436 }
1437 
setMolecule(Molecule * m)1438 void ChGL::setMolecule(Molecule *m){//! sets the pointer to the Molecule object deletes the old one if it is exists and is differen from the new one
1439   //  printf("setMolecule\n");
1440   if (mol!=m) {
1441     if (mol) delete mol;
1442     mol=m;
1443   }
1444   double dim=mol->dimension();
1445   L=100.0/dim;
1446 }
1447 
showMatrix()1448 void ChGL::showMatrix(){
1449   //  stereo_mode++;
1450   //  stereo_mode%=4;
1451   updateGL();
1452   printf("The MMATRIX is:\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n",
1453       MM[0],MM[1],MM[2],MM[3],
1454       MM[4],MM[5],MM[6],MM[7],
1455       MM[8],MM[9],MM[10],MM[11],
1456       MM[12],MM[13],MM[14],MM[15]);
1457   GLdouble mm[16];
1458   glGetDoublev(GL_MODELVIEW_MATRIX,mm);
1459   printf("The Mmatrix is:\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n",
1460       mm[0],mm[1],mm[2],mm[3],
1461       mm[4],mm[5],mm[6],mm[7],
1462       mm[8],mm[9],mm[10],mm[11],
1463       mm[12],mm[13],mm[14],mm[15]);
1464   GLdouble det=
1465     mm[0]*mm[5]*mm[10] - mm[8]*mm[5]*mm[2]+
1466     mm[1]*mm[6]*mm[8]  - mm[9]*mm[6]*mm[0]+
1467     mm[2]*mm[4]*mm[9]  - mm[10]*mm[4]*mm[1];
1468   printf("die Determinante der Drehmatrix ist: %g\n",det);
1469   glGetDoublev(GL_PROJECTION_MATRIX,mm);
1470   printf("Die Pmatrix ist:\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n",
1471       mm[0],mm[1],mm[2],mm[3],
1472       mm[4],mm[5],mm[6],mm[7],
1473       mm[8],mm[9],mm[10],mm[11],
1474       mm[12],mm[13],mm[14],mm[15]);
1475   det=
1476     mm[0]*mm[5]*mm[10] - mm[8]*mm[5]*mm[2]+
1477     mm[1]*mm[6]*mm[8]  - mm[9]*mm[6]*mm[0]+
1478     mm[2]*mm[4]*mm[9]  - mm[10]*mm[4]*mm[1];
1479   printf("die Determinante der Drehmatrix ist: %g\n",det);
1480 }
1481 
along001()1482 void ChGL::along001(){
1483   double va=viewAngle;
1484   setViewAngle(29.0);
1485   MM[0]=1.0;
1486   MM[1]=0.0;
1487   MM[2]=0.0;
1488   MM[4]=0.0;
1489   MM[5]=-1.0;
1490   MM[6]=0.0;
1491   MM[8]=0.0;
1492   MM[9]=0.0;
1493   MM[10]=-1.0;
1494   glMatrixMode(GL_MODELVIEW);
1495   glLoadMatrixd(MM);
1496   setViewAngle(va);
1497 }
1498 
zoomOut()1499 void ChGL::zoomOut(){
1500   double va=viewAngle;
1501   setViewAngle(29.0);
1502   glMatrixMode(GL_MODELVIEW);
1503   glGetDoublev(GL_MODELVIEW_MATRIX,MM);
1504   GLdouble det=
1505     MM[0]*MM[5]*MM[10] - MM[8]*MM[5]*MM[2]+
1506     MM[1]*MM[6]*MM[8]  - MM[9]*MM[6]*MM[0]+
1507     MM[2]*MM[4]*MM[9]  - MM[10]*MM[4]*MM[1];
1508   /*printf("Die Mmatrix ist:\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n",
1509       MM[0] ,MM[1] ,MM[2] ,MM[3],
1510       MM[4] ,MM[5] ,MM[6] ,MM[7],
1511       MM[8] ,MM[9] ,MM[10],MM[11],
1512       MM[12],MM[13],MM[14],MM[15]);
1513   printf("die Determinante der Matrix ist: %g\n",det);*/
1514   if (det !=0.0){
1515     det=pow(det,1.0/3.0);
1516     MM[ 0]/=det;
1517     MM[ 1]/=det;
1518     MM[ 2]/=det;
1519     MM[ 4]/=det;
1520     MM[ 5]/=det;
1521     MM[ 6]/=det;
1522     MM[ 8]/=det;
1523     MM[ 9]/=det;
1524     MM[10]/=det;
1525     det=
1526       MM[0]*MM[5]*MM[10] - MM[8]*MM[5]*MM[2]+
1527       MM[1]*MM[6]*MM[8]  - MM[9]*MM[6]*MM[0]+
1528       MM[2]*MM[4]*MM[9]  - MM[10]*MM[4]*MM[1];
1529     /*printf("##Die Mmatrix ist:\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n%9.6f %9.6f %9.6f %9.6f\n",
1530         MM[0] ,MM[1] ,MM[2] ,MM[3],
1531         MM[4] ,MM[5] ,MM[6] ,MM[7],
1532         MM[8] ,MM[9] ,MM[10],MM[11],
1533         MM[12],MM[13],MM[14],MM[15]);
1534     printf("##die Determinante der Matrix ist: %g\n",det);*/
1535 
1536   }
1537   glLoadMatrixd(MM);
1538   setViewAngle(va);
1539 }
1540 
1541 
initializeGL()1542 void ChGL::initializeGL(){
1543   //printf("initGL\n");
1544   glEnable(GL_LINE_SMOOTH);
1545   glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
1546   const GLfloat  position[] = {100.0f, 100.0f,100.0f,0.0f};
1547   const GLfloat  diffuse[]  = { 1.0, 1.0, 1.0, 1.0 };
1548   const GLfloat  specular[] = { 1.0, 1.0, 1.0, 1.0 };
1549   const GLfloat  ambient[]  = { 0.5, 0.5, 0.5, 1.0 };
1550 
1551   glLightModeli(  GL_LIGHT_MODEL_LOCAL_VIEWER, 1 );
1552 
1553   glLightfv( GL_LIGHT0, GL_POSITION, position );
1554   glLightfv( GL_LIGHT0, GL_AMBIENT,  ambient );
1555   glLightfv( GL_LIGHT0, GL_DIFFUSE,  diffuse );
1556   glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
1557 
1558   glLightfv( GL_LIGHT1, GL_POSITION, position );
1559   glLightfv( GL_LIGHT1, GL_DIFFUSE,  diffuse );
1560   glLightfv( GL_LIGHT1, GL_AMBIENT,  ambient );
1561   glLightfv( GL_LIGHT2, GL_DIFFUSE,  diffuse );
1562 
1563 
1564   glEnable( GL_LIGHTING );
1565   glEnable( GL_LIGHT0 );
1566   glEnable( GL_BLEND);
1567   mol->fogrange=60;
1568   glDisable(GL_FOG);
1569   glFogi(GL_FOG_MODE,GL_LINEAR);
1570   glFogi(GL_FOG_START,205-mol->fogrange);
1571   glFogi(GL_FOG_END,205+mol->fogrange);
1572   GLfloat fgc[4]={(GLfloat)backGroundColor.redF(),(GLfloat)backGroundColor.greenF(),(GLfloat)backGroundColor.blueF(),1.0f};
1573   //printf("FOG %f %f %f %f\n",fgc[0],fgc[1],fgc[2],fgc[3]);
1574   glFogfv(GL_FOG_COLOR,fgc);
1575 
1576   glLightModeli(  GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1577   glAlphaFunc ( GL_GREATER, 0.01f ) ;
1578   glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1579   const GLfloat  OBJ_SPE[]   = { 0.8f, 0.8f, 0.8f, 1.0f };
1580   const GLfloat  OBJ_SHIN    = 32.0;
1581   glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,             OBJ_SPE  );
1582   glEnable     ( GL_COLOR_MATERIAL ) ;
1583   glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
1584   glMaterialf(  GL_FRONT_AND_BACK, GL_SHININESS,           OBJ_SHIN );
1585   glShadeModel( GL_SMOOTH );
1586   //glShadeModel(GL_FLAT);
1587   glEnable(GL_NORMALIZE);
1588 
1589   qglClearColor(backGroundColor);
1590 
1591   glEnable(GL_DEPTH_TEST );
1592   glDepthFunc(GL_LEQUAL);
1593   gluLookAt_(0.0, 200, 50 ,   0.0, 0.0, 0.0,   0.0, -100, 400 );
1594   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1595   setMouseTracking(true);
1596   //Listen inititialisieren ist hier!
1597   int ect=0;
1598 #ifndef GL_MAX_ELEMENTS_INDICES
1599 #define GL_MAX_ELEMENTS_INDICES           0x80E9
1600 #endif /* GL_MAX_ELEMENTS_INDICES */
1601   int midx;
1602   glGetIntegerv(GL_MAX_ELEMENTS_INDICES,&midx);
1603   //printf("GL_MAX_ELEMENTS_INDICES = %d\n",midx);
1604   if (midx<3840)mol->LOD=qMin(mol->LOD,3);
1605   if (midx<940)mol->LOD=qMin(mol->LOD,2);
1606   GLenum err = GL_NO_ERROR;
1607   while((err = glGetError()) != GL_NO_ERROR)
1608   {
1609     printf("ganz davor %d %d [%d]\n",err==GL_INVALID_VALUE ,err == GL_INVALID_OPERATION,++ect);
1610     // printf("%s\n",(char*)gluErrorString(err));
1611   }
1612   makeCurrent();
1613   const QGLContext *contxt = this->context();
1614   if (mol->g_Program==nullptr){
1615     mol->g_Program= new QGLShaderProgram(contxt, this);
1616     mol->g_program=mol->installShader();
1617   }
1618   printf("shaderprog %d context is valid = %d \n",mol->g_program,contxt->isValid());
1619   if (!mol->g_program) printf("%s\n",mol->g_Program->log().toStdString().c_str());
1620   while((err = glGetError()) != GL_NO_ERROR)
1621   {
1622     printf("kurz davor GL_INVALID_VALUE%d GL_INVALID_OPERATION%d [%d] err=%x\n",err==GL_INVALID_VALUE ,err == GL_INVALID_OPERATION,++ect,err);
1623   }
1624   on=true;
1625   setupTexture();
1626   //printf("--initGL\n");
1627   // setViewAngle((orthoView)?0.2:29.0);
1628   //§§
1629   //mol->selectedatoms.append(newAtom);
1630   //§§
1631 }
1632 
1633 
setRotationCenter()1634 void ChGL::setRotationCenter(){
1635   //! Sets the rotation center to the spezified atom
1636   QAction *action = qobject_cast<QAction *>(sender());
1637   int index=0;
1638   if (action)
1639     index=action->data().toInt();
1640   else return;
1641   if (index==(int)((GLuint)-1))return;
1642   rotze=((int)index<mol->showatoms.size())?index:-1;
1643   if (rotze>-1){
1644     rCenter->show();
1645     glGetDoublev(GL_MODELVIEW_MATRIX,MM);
1646     MM[12]=MM[13]=0;
1647     glLoadMatrixd(MM);
1648   }
1649   updateGL();
1650 }
1651 
setRotationCenter(V3 center)1652 void ChGL::setRotationCenter(V3 center){
1653  // printf("%f %f %f \n%f %f %f\n", altemitte.x, altemitte.y, altemitte.z, center.x, center.y, center.z);
1654   altcenter=center;
1655   rotze=-76185;//zip code
1656   rCenter->show();
1657   updateGL();
1658 }
1659 
1660 
setRotationCenter(int rz)1661 void ChGL::setRotationCenter(int rz){
1662   /*! Sets the rotation center to the spezified atom
1663    * @param index of the spezified atom.
1664    */
1665   rotze=((int)rz<mol->showatoms.size())?rz:-1;
1666   if (rotze>-1){
1667     rCenter->show();
1668     glGetDoublev(GL_MODELVIEW_MATRIX,MM);
1669     MM[12]=MM[13]=0;
1670     glLoadMatrixd(MM);
1671   }
1672   updateGL();
1673 }
1674 
expand()1675 void ChGL::expand(){//! Lets Molecule.expandAt(int index) serach for neighboring molecules around the specified atom.
1676   QAction *action = qobject_cast<QAction *>(sender());
1677   int index=0;
1678   if (action)
1679     index=action->data().toInt();
1680   else return;
1681   if (index==(int)((GLuint)-1))return;
1682   mol->expandAt(index);
1683   fuse->setVisible(true);
1684   grow->setVisible(false);
1685   emit bigmessage(mol->HumanSymmetry);
1686   murx=-__LINE__;
1687   updateGL();
1688 }
1689 
incFontSize()1690 void ChGL::incFontSize(){//! increases label font size
1691   myFont.setPointSize(myFont.pointSize()+1);
1692   updateGL();
1693 }
1694 
decFontSize()1695 void ChGL::decFontSize(){//! decreases label font size
1696   myFont.setPointSize(qMax(myFont.pointSize()-1,7));
1697   updateGL();
1698 
1699 }
1700 
updateLabelTextures()1701 void ChGL::updateLabelTextures(){
1702   labelTextures.clear();
1703   for (int li=0; li<mol->showatoms.size(); li++){
1704     QFont fnt=myFont;
1705     fnt.setPointSize((mol->showatoms.at(li).an>=0)?144:96);
1706     QFontMetrics mtr(myFont);
1707     QString label=mol->showatoms.at(li).Label;
1708     if (shortLabels->isChecked()) {
1709       label=label.section("_",0,0);
1710       label=label.section(QString::fromUtf8("»"),0,0);
1711     }
1712     QRect rc=mtr.boundingRect(label);
1713     QImage image(rc.width()+mtr.width("Li"), rc.height()+2,QImage::Format_ARGB32_Premultiplied);
1714     //printf("texture %d  %d x %d Pts = %d\n",li,image.width(),image.height(),fnt.pointSize());
1715 
1716     image.fill(0);
1717     QPainter p;
1718     p.begin(&image);
1719     p.setPen(QPen(Qt::white));
1720     p.setBackground(Qt::NoBrush);
1721     p.setFont(myFont);
1722     p.drawText(image.rect(), Qt::AlignRight, label);
1723     p.end();
1724     image=image.convertToFormat(QImage::Format_Indexed8);
1725     labelTextures.append(image);
1726   }
1727   extraTextures.clear();
1728   QStringList lala;
1729   lala<<"0"<<"a"<<"b"<<"c";
1730   for (int i=0; i<mol->legendAtoms.size(); i++){
1731     lala.append(mol->legendAtoms.at(i).Label);
1732   }
1733   for (int i=0; i<lala.size();i++){
1734     QFont fnt=myFont;
1735     fnt.setPointSize(96);
1736     QFontMetrics mtr(myFont);
1737     QRect rc=mtr.boundingRect(lala.at(i));
1738     QImage image(rc.width()+mtr.width("Li"),rc.height(),QImage::Format_ARGB32_Premultiplied);
1739     image.fill(0);
1740     QPainter p;
1741     p.begin(&image);
1742     p.setPen(QPen(Qt::white));
1743     p.setBackground(Qt::NoBrush);
1744     p.setFont(myFont);
1745     p.drawText(image.rect(), Qt::AlignRight, lala.at(i));
1746     p.end();
1747     image=image.convertToFormat(QImage::Format_Indexed8);
1748     extraTextures.append(image);
1749   }
1750 
1751   updateGL();
1752 
1753 }
1754 
1755 //#include <iostream>
setReNaMo(bool b)1756 void ChGL::setReNaMo(bool b){//!enter rename mode
1757   inRenameMode=b;
1758 }
1759 
rotCenter()1760 void ChGL::rotCenter(){//! reset the rotation center to the center of gravity.
1761   rotze=-1;
1762   updateGL();
1763   rCenter->hide();
1764 }
1765 
resizeGL(int width,int height)1766 void ChGL::resizeGL(int width, int height) {
1767   if (pause) {ww=width; wh=height; return;}
1768   GLint v[2];
1769   glGetIntegerv(GL_MAX_VIEWPORT_DIMS,v);
1770   //printf("MAXVP %d %d \n",v[0],v[1]);
1771   glViewport(0, 0, ww=width, wh=height);
1772   glGetIntegerv(GL_VIEWPORT, vp);
1773   retinafktr=ww/this->width();
1774   //printf("VP %d %d %d %d  w=%d h=%d  %d %d\n",vp[0],vp[1],vp[2],vp[3],ww,wh,this->width(),this->height());
1775   glMatrixMode(GL_PROJECTION);
1776   glLoadIdentity();
1777   gluPerspective_( viewAngle, (double)width/height, 5.0, 8000.0 );
1778 }
1779 
zoom(double speed)1780 void ChGL::zoom(double speed){//!scale about speed @param speed scale factor
1781   moving->start(dratpause);
1782   //  printf("%d\n",dratpause);
1783   glScaled(1.0+speed*0.1,1.0+speed*0.1,1.0+speed*0.1);
1784   updateGL();
1785 }
1786 
rotY(double speed)1787 void ChGL::rotY(double speed){//!rotate around Y axis @param speed in degrees
1788   moving->start(dratpause);
1789   glRotateL(-20.0*speed,0.0f,1.0f,0.0f);
1790   updateGL();
1791 }
1792 
gZoom(double speed)1793 void ChGL::gZoom(double speed){//!scale about speed @param speed scale factor
1794   moving->start(dratpause);
1795   glScaled(1.0+speed*0.02,1.0+speed*0.02,1.0+speed*0.02);
1796   updateGL();
1797 }
1798 
rotZ(double speed)1799 void ChGL::rotZ(double speed){//!rotate around Z axis @param speed in degrees
1800   moving->start(dratpause);
1801   glRotateL(speed,0.0f,0.0f,1.0f);
1802   updateGL();
1803 }
1804 
moveY(double speed)1805 void ChGL::moveY(double speed){//!translate the molecule in Y direction
1806   moving->start(dratpause);
1807   glTranslateL(0.0,speed,0.0);
1808   updateGL();
1809 }
1810 
moveX(double speed)1811 void ChGL::moveX(double speed){//!translate the molecule in X direction
1812   moving->start(dratpause);
1813   glTranslateL(speed,0.0,0.0);
1814   //  QMessageBox::information(this,"Px move","xmoved",QMessageBox::Ok);
1815   updateGL();
1816 }
1817 
rotX(double speed)1818 void ChGL::rotX(double speed){//!rotate around X axis @param speed in degrees
1819   moving->start(dratpause);
1820   glRotateL(-20.0*speed,1.0f,0.0f,0.0f);
1821   updateGL();
1822 }
1823 
1824 
zalman()1825 void ChGL::zalman(){//!sets the stereo mode for Zalman monitors.
1826   stereo_mode=1;
1827   minus= 1;
1828   updateGL();
1829 }
1830 
resis()1831 QStringList ChGL::resis(){
1832   QStringList l;
1833   for (int i=0; i<mol->asymm.size(); i++){
1834       if (mol->asymm.at(i).an<0)continue;
1835     if (mol->asymm.at(i).resiNr>0){
1836       if (!l.contains(QString::number(mol->asymm.at(i).resiNr),Qt::CaseInsensitive))
1837         l.append(QString::number(mol->asymm.at(i).resiNr));
1838       if (!l.contains(mol->asymm.at(i).ResiClass))
1839         l.append(mol->asymm.at(i).ResiClass);
1840     }
1841   }
1842   if (!l.isEmpty()) l.insert(0,"*");
1843   return l;
1844 }
1845 
singleBondDistance()1846 void ChGL::singleBondDistance(){
1847     if (mol->selectedatoms.size()!=2)return;
1848     QWidgetList wl = QApplication::allWidgets();
1849     for (int i=0; i<wl.size(); i++){
1850         if (wl.at(i)->objectName()=="DFIX_DIST"){
1851             QLineEdit *valueline = qobject_cast<QLineEdit *>(wl[i]);
1852             valueline->setText(QString::number(0.01*(mol->Kovalenz_Radien[mol->selectedatoms.at(0).an]+mol->Kovalenz_Radien[mol->selectedatoms.at(1).an]),10,3));
1853         }
1854     }
1855 }
1856 
addDFIX()1857 void ChGL::addDFIX(){
1858     if (mol->selectedatoms.size()!=2)return;
1859   QDialog *dia = new QDialog();
1860   dia->setWindowTitle("DFIX: Geometrical restraint");
1861   dia->setModal(false);
1862 
1863   QGridLayout *grid = new QGridLayout(dia);
1864   QLineEdit *valueline = new QLineEdit(dia);
1865   valueline->setObjectName("DFIX_DIST");
1866   QLineEdit *esdline = new QLineEdit(dia);
1867   QLabel *value = new QLabel("Value:", dia);
1868   QLabel *esd = new QLabel("ESD:", dia);
1869   QLabel *atoms = new QLabel(QString("%1==%2  : %3 A")
1870                              .arg(mol->selectedatoms.at(0).Label)
1871                              .arg(mol->selectedatoms.at(1).Label)
1872                              .arg( sqrt(Distance(mol->selectedatoms.at(0).pos,mol->selectedatoms.at(1).pos)),10,'f',3));
1873   QCheckBox *bindit = new QCheckBox("Insert BIND instruction",dia);
1874   QStringList rl = resis();
1875   QComboBox *resiCom = nullptr;
1876   if (!rl.isEmpty()){
1877     QLabel *resi = new QLabel("Residue specific",dia);
1878     resiCom = new QComboBox(dia);
1879     // Usually you want to define residue restraints with numbers at the atom:
1880     resiCom->addItem("");
1881     resiCom->addItems(rl);
1882     grid->addWidget(resi,3,0);
1883     grid->addWidget(resiCom,3,1);
1884   }
1885   // Set default value for distance and esd
1886   // Get value for DFIX. Current bond distance and default esd - 0.02
1887   valueline->setText(QString::number(sqrt(Distance(mol->selectedatoms.at(0).pos,mol->selectedatoms.at(1).pos)),10,3));
1888   esdline->setText("0.02");
1889   grid->addWidget(atoms,0,0,1,2);
1890   grid->addWidget(value,1,0);
1891   grid->addWidget(valueline,1,1);
1892   grid->addWidget(esd,2,0);
1893   grid->addWidget(esdline,2,1);
1894   grid->addWidget(bindit,4,0);
1895   QDialogButtonBox *buttonBox = new QDialogButtonBox();
1896 
1897   QPushButton *OkButton;
1898   QPushButton *CancelButton;
1899   QPushButton *singleBondButton = new QPushButton(QString("%1 A").arg(0.01*(mol->Kovalenz_Radien[mol->selectedatoms.at(0).an]+mol->Kovalenz_Radien[mol->selectedatoms.at(1).an])));
1900 
1901   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
1902   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
1903   buttonBox->addButton(singleBondButton,QDialogButtonBox::ActionRole);
1904 
1905 
1906   buttonBox->setOrientation(Qt::Horizontal);
1907 
1908   grid->addWidget(buttonBox,10,0);
1909 
1910   dia->setLayout(grid);
1911   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
1912   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
1913   connect(singleBondButton, SIGNAL(clicked()), this, SLOT(singleBondDistance()));
1914 
1915   dia->show();
1916   int a  = dia->exec();
1917 
1918   if(a == QDialog::Accepted)
1919   {
1920     // read value from value line
1921     QString s=(rl.isEmpty())?"":resiCom->currentText();
1922     emit insertDFIX(valueline->text().toDouble(),esdline->text().toDouble(),mol->selectedatoms,s);
1923     if (bindit->isChecked()) emit bindthem();
1924     mol->selectedatoms.clear();
1925   }
1926   else
1927   {
1928     if(a == QDialog::Rejected)
1929       dia->close();
1930 
1931   }
1932 
1933 
1934   //    updateBondActions();
1935 }
1936 
addDANG()1937 void ChGL::addDANG(){
1938   QDialog *dia = new QDialog(this);
1939   dia->setWindowTitle(tr("DANG: Geometrical restraint"));
1940   dia->setModal(false);
1941 
1942   QGridLayout *grid = new QGridLayout(dia);
1943   QLineEdit *valueline = new QLineEdit(dia);
1944   QLineEdit *esdline = new QLineEdit(dia);
1945   QLabel *value = new QLabel("Value:", dia);
1946   QLabel *esd = new QLabel("ESD:", dia);
1947   QStringList rl = resis();
1948   QComboBox *resiCom = nullptr;
1949   if (!rl.isEmpty()){
1950     QLabel *resi = new QLabel("Residue specific",dia);
1951     resiCom = new QComboBox(dia);
1952     resiCom->addItem("");
1953     resiCom->addItems(rl);
1954     grid->addWidget(resi,2,0);
1955     grid->addWidget(resiCom,2,1);
1956   }
1957   // Set default value for distance and esd
1958   // Get value for DANG. Current bond distance and default esd - 0.04
1959   valueline->setText(QString::number(sqrt(Distance(mol->selectedatoms.at(0).pos,mol->selectedatoms.at(1).pos)),10,3));
1960   esdline->setText("0.04");
1961 
1962   grid->addWidget(value,0,0);
1963   grid->addWidget(valueline,0,1);
1964   grid->addWidget(esd,1,0);
1965   grid->addWidget(esdline,1,1);
1966 
1967   QDialogButtonBox *buttonBox = new QDialogButtonBox();
1968 
1969   QPushButton *OkButton;
1970   QPushButton *CancelButton;
1971 
1972   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
1973   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
1974 
1975   buttonBox->setOrientation(Qt::Horizontal);
1976 
1977   grid->addWidget(buttonBox,4,0);
1978 
1979   dia->setLayout(grid);
1980   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
1981   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
1982 
1983   dia->show();
1984   int a  = dia->exec();
1985 
1986   if(a == QDialog::Accepted)
1987   {
1988     // read value from value line
1989     QString s=(rl.isEmpty())?"":resiCom->currentText();
1990     emit insertDANG(valueline->text().toDouble(),esdline->text().toDouble(),mol->selectedatoms,s);
1991     mol->selectedatoms.clear();
1992   }
1993   else
1994   {
1995     if(a == QDialog::Rejected)
1996       dia->close();
1997   }
1998 
1999 }
2000 
addFLAT()2001 void ChGL::addFLAT(){
2002   QDialog *dia = new QDialog(this);
2003   dia->setWindowTitle(tr("FLAT: Geometrical restraint"));
2004   dia->setModal(false);
2005 
2006   QGridLayout *grid = new QGridLayout(dia);
2007   QLineEdit *esdline = new QLineEdit(dia);
2008   QLabel *esd = new QLabel("ESD:", dia);
2009   QStringList rl = resis();
2010   QComboBox *resiCom = nullptr;
2011   if (!rl.isEmpty()){
2012     QLabel *resi = new QLabel("Residue specific",dia);
2013     resiCom = new QComboBox(dia);
2014     resiCom->addItem("");
2015     resiCom->addItems(rl);
2016     grid->addWidget(resi,2,0);
2017     grid->addWidget(resiCom,2,1);
2018   }
2019   // Set default value for esd
2020   esdline->setText("0.1");
2021 
2022   grid->addWidget(esd,0,0);
2023   grid->addWidget(esdline,0,1);
2024 
2025   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2026 
2027   QPushButton *OkButton;
2028   QPushButton *CancelButton;
2029 
2030   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2031   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2032 
2033   buttonBox->setOrientation(Qt::Horizontal);
2034 
2035   grid->addWidget(buttonBox,1,0);
2036 
2037   dia->setLayout(grid);
2038   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2039   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2040 
2041   dia->show();
2042   int a  = dia->exec();
2043 
2044   if(a == QDialog::Accepted)
2045   {
2046     // read value from value line
2047     QString s=(rl.isEmpty())?"":resiCom->currentText();
2048     emit insertFLAT(esdline->text().toDouble(),mol->selectedatoms,s);
2049     mol->selectedatoms.clear();
2050   }
2051   else
2052   {
2053     if(a == QDialog::Rejected)
2054       dia->close();
2055   }
2056 
2057 }
2058 
addEXYZ()2059 void ChGL::addEXYZ(){
2060   emit insertEXYZ(mol->selectedatoms);
2061   mol->selectedatoms.clear();
2062 }
2063 
addEADP()2064 void ChGL::addEADP(){
2065   emit insertEADP(mol->selectedatoms);
2066   mol->selectedatoms.clear();
2067 }
2068 
addDELU()2069 void ChGL::addDELU(){
2070   QDialog *dia = new QDialog(this);
2071   dia->setWindowTitle(tr("DELU: ADP restraint"));
2072   dia->setModal(false);
2073 
2074   QGridLayout *grid = new QGridLayout(dia);
2075   QLineEdit *esd1line = new QLineEdit(dia);
2076   QLineEdit *esd2line = new QLineEdit(dia);
2077   QLabel *esd1 = new QLabel("ESD1:", dia);
2078   QLabel *esd2 = new QLabel("ESD2:", dia);
2079   // Set default value for distance and esd
2080   esd1line->setText("0.01");
2081   esd2line->setText("0.01");
2082 
2083   grid->addWidget(esd1,0,0);
2084   grid->addWidget(esd1line,0,1);
2085   grid->addWidget(esd2,1,0);
2086   grid->addWidget(esd2line,1,1);
2087   QStringList rl = resis();
2088   QComboBox *resiCom = nullptr;
2089   if (!rl.isEmpty()){
2090     QLabel *resi = new QLabel("Residue specific",dia);
2091     resiCom = new QComboBox(dia);
2092     resiCom->addItem("");
2093     resiCom->addItems(rl);
2094     grid->addWidget(resi,3,0);
2095     grid->addWidget(resiCom,3,1);
2096   }
2097 
2098   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2099 
2100   QPushButton *OkButton;
2101   QPushButton *CancelButton;
2102 
2103   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2104   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2105 
2106   buttonBox->setOrientation(Qt::Horizontal);
2107 
2108   grid->addWidget(buttonBox,4,0);
2109 
2110   dia->setLayout(grid);
2111   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2112   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2113 
2114   dia->show();
2115   int a  = dia->exec();
2116 
2117   if(a == QDialog::Accepted)
2118   {
2119     // read value from value line
2120     QString s=(rl.isEmpty())?"":resiCom->currentText();
2121     emit insertDELU(esd1line->text().toDouble(),esd2line->text().toDouble(),mol->selectedatoms,s);
2122     mol->selectedatoms.clear();
2123   }
2124   else
2125   {
2126     if(a == QDialog::Rejected)
2127       dia->close();
2128   }
2129 }
2130 
addSIMU()2131 void ChGL::addSIMU(){
2132   QDialog *dia = new QDialog(this);
2133   dia->setWindowTitle(tr("SIMU: ADP restraint"));
2134   dia->setModal(false);
2135 
2136   QGridLayout *grid = new QGridLayout(dia);
2137   QLineEdit *esd1line = new QLineEdit(dia);
2138   QLineEdit *esd2line = new QLineEdit(dia);
2139   QLineEdit *dmaxline = new QLineEdit(dia);
2140   QLabel *esd1 = new QLabel("ESD1:", dia);
2141   QLabel *esd2 = new QLabel("ESD2:", dia);
2142   QLabel *dmax = new QLabel("dmax:", dia);
2143   // Set default value for distance and esd
2144   esd1line->setText("0.04");
2145   esd2line->setText("0.08");
2146   dmaxline->setText("2.00");
2147 
2148   grid->addWidget(esd1,0,0);
2149   grid->addWidget(esd1line,0,1);
2150   grid->addWidget(esd2,1,0);
2151   grid->addWidget(esd2line,1,1);
2152   grid->addWidget(dmax,2,0);
2153   grid->addWidget(dmaxline,2,1);
2154   QStringList rl = resis();
2155   QComboBox *resiCom = nullptr;
2156   if (!rl.isEmpty()){
2157     QLabel *resi = new QLabel("Residue specific", dia);
2158     resiCom = new QComboBox(dia);
2159     // Usually you want to define residue restraints with numbers at the atom:
2160     resiCom->addItem("");
2161     resiCom->addItems(rl);
2162     grid->addWidget(resi,3,0);
2163     grid->addWidget(resiCom,3,1);
2164   }
2165 
2166   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2167 
2168   QPushButton *OkButton;
2169   QPushButton *CancelButton;
2170 
2171   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2172   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2173 
2174   buttonBox->setOrientation(Qt::Horizontal);
2175 
2176   grid->addWidget(buttonBox,4,0);
2177 
2178   dia->setLayout(grid);
2179   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2180   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2181 
2182   dia->show();
2183   int a  = dia->exec();
2184 
2185   if(a == QDialog::Accepted)
2186   {
2187     // read value from value line
2188     QString s=(rl.isEmpty())?"":resiCom->currentText();
2189     emit insertSIMU(esd1line->text().toDouble(),esd2line->text().toDouble(),dmaxline->text().toDouble(),mol->selectedatoms,s);
2190     mol->selectedatoms.clear();
2191   }
2192   else
2193   {
2194     if(a == QDialog::Rejected)
2195       dia->close();
2196   }
2197 
2198 }
2199 
addSADI()2200 void ChGL::addSADI() {
2201   //! Adds SADI restraints between the selected atom and all bonded atoms.
2202   QAction *action = qobject_cast<QAction *>(sender());
2203   int index=-1;
2204   if (action)
2205     index=action->data().toInt();
2206   else index=-1;
2207   if (index>mol->asymm.size()) index=-1;
2208   if (index!=-1) {
2209     emit insertSADI(index);
2210   }
2211 }
2212 
addISOR()2213 void ChGL::addISOR(){
2214   QDialog *dia = new QDialog(this);
2215   dia->setWindowTitle(tr("ISOR: ADP restraint"));
2216   dia->setModal(false);
2217 
2218   QGridLayout *grid = new QGridLayout(dia);
2219   QLineEdit *esd1line = new QLineEdit(dia);
2220   QLineEdit *esd2line = new QLineEdit(dia);
2221   QLabel *esd1 = new QLabel("ESD1:", dia);
2222   QLabel *esd2 = new QLabel("ESD2:", dia);
2223   QStringList rl = resis();
2224   QComboBox *resiCom = nullptr;
2225   if (!rl.isEmpty()){
2226     QLabel *resi = new QLabel("Residue specific",dia);
2227     resiCom = new QComboBox(dia);
2228     resiCom->addItem("");
2229     resiCom->addItems(rl);
2230     grid->addWidget(resi,3,0);
2231     grid->addWidget(resiCom,3,1);
2232   }
2233   // Set default values for s and st
2234   esd1line->setText("0.1");
2235   esd2line->setText("0.2");
2236 
2237   grid->addWidget(esd1,0,0);
2238   grid->addWidget(esd1line,0,1);
2239   grid->addWidget(esd2,1,0);
2240   grid->addWidget(esd2line,1,1);
2241 
2242   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2243 
2244   QPushButton *OkButton;
2245   QPushButton *CancelButton;
2246 
2247   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2248   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2249 
2250   buttonBox->setOrientation(Qt::Horizontal);
2251 
2252   grid->addWidget(buttonBox,4,0);
2253 
2254   dia->setLayout(grid);
2255   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2256   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2257 
2258   dia->show();
2259   int a  = dia->exec();
2260 
2261   if(a == QDialog::Accepted)
2262   {
2263     // read value from value line
2264     QString s=(rl.isEmpty())?"":resiCom->currentText();
2265     emit insertISOR(esd1line->text().toDouble(),esd2line->text().toDouble(),mol->selectedatoms,s);
2266     mol->selectedatoms.clear();
2267   }
2268   else
2269   {
2270     if(a == QDialog::Rejected)
2271       dia->close();
2272   }
2273 }
2274 
addRIGU()2275 void ChGL::addRIGU(){
2276   QDialog *dia = new QDialog(this);
2277   dia->setWindowTitle(tr("RIGU: ADP restraint"));
2278   dia->setModal(false);
2279 
2280   QGridLayout *grid = new QGridLayout(dia);
2281   QLineEdit *esd1line = new QLineEdit(dia);
2282   QLineEdit *esd2line = new QLineEdit(dia);
2283   QLabel *esd1 = new QLabel("ESD1:", dia);
2284   QLabel *esd2 = new QLabel("ESD2:", dia);
2285   // Set default value for distance and esd
2286   esd1line->setText("0.004");
2287   esd2line->setText("0.004");
2288   int i(0); // index for position of widgets in the container
2289   grid->addWidget(esd1,i,0);
2290   grid->addWidget(esd1line,i++,1);
2291   grid->addWidget(esd2,i,0);
2292   grid->addWidget(esd2line,i++,1);
2293   QStringList rl = resis();
2294   QComboBox *resiCom = nullptr;
2295   if (!rl.isEmpty()){
2296     QLabel *resi = new QLabel("Residue specific",dia);
2297     resiCom = new QComboBox(dia);
2298     resiCom->addItem("");
2299     resiCom->addItems(rl);
2300     grid->addWidget(resi,i,0);
2301     grid->addWidget(resiCom,i++,1);
2302   }
2303 
2304   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2305 
2306   QPushButton *OkButton;
2307   QPushButton *CancelButton;
2308 
2309   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2310   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2311 
2312   buttonBox->setOrientation(Qt::Horizontal);
2313 
2314   grid->addWidget(buttonBox,i,0);
2315 
2316   dia->setLayout(grid);
2317   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2318   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2319 
2320   dia->show();
2321   int a  = dia->exec();
2322 
2323   if(a == QDialog::Accepted)
2324   {
2325     // read value from value line
2326     QString s=(rl.isEmpty())?"":resiCom->currentText();
2327     emit insertRIGU(esd1line->text().toDouble(),esd2line->text().toDouble(),mol->selectedatoms,s);
2328     mol->selectedatoms.clear();
2329   }
2330   else
2331   {
2332     if(a == QDialog::Rejected)
2333       dia->close();
2334   }
2335 }
2336 
addCHIV()2337 void ChGL::addCHIV(){
2338   QDialog *dia = new QDialog(this);
2339   dia->setWindowTitle(tr("CHIV: Geometrical restraint"));
2340   dia->setModal(false);
2341 
2342   QGridLayout *grid = new QGridLayout(dia);
2343   QLineEdit *volline = new QLineEdit(dia);
2344   QLineEdit *esd1line = new QLineEdit(dia);
2345   QLabel *vol = new QLabel("Volume:", dia);
2346   QLabel *esd1 = new QLabel("ESD:", dia);
2347   // Set default value for distance and esd
2348   volline->setText("0.0");
2349   esd1line->setText("0.1");
2350   int i(0); // index for position of widgets in the container
2351   grid->addWidget(vol,i,0);
2352   grid->addWidget(volline,i++,1);
2353   grid->addWidget(esd1,i,0);
2354   grid->addWidget(esd1line,i++,1);
2355   QStringList rl = resis();
2356   QComboBox *resiCom = nullptr;
2357   if (!rl.isEmpty()){
2358     QLabel *resi = new QLabel("Residue specific",dia);
2359     resiCom = new QComboBox(dia);
2360     resiCom->addItem("");
2361     resiCom->addItems(rl);
2362     grid->addWidget(resi,i,0);
2363     grid->addWidget(resiCom,i++,1);
2364   }
2365 
2366   QDialogButtonBox *buttonBox = new QDialogButtonBox();
2367 
2368   QPushButton *OkButton;
2369   QPushButton *CancelButton;
2370 
2371   OkButton = buttonBox->addButton(QDialogButtonBox::Ok);
2372   CancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
2373 
2374   buttonBox->setOrientation(Qt::Horizontal);
2375 
2376   grid->addWidget(buttonBox,i,0);
2377 
2378   dia->setLayout(grid);
2379   connect(OkButton, SIGNAL(clicked()), dia, SLOT(accept()));
2380   connect(CancelButton, SIGNAL(clicked()), dia, SLOT(reject()));
2381 
2382   dia->show();
2383   int a  = dia->exec();
2384 
2385   if(a == QDialog::Accepted)
2386   {
2387     // read value from value line
2388     QString s=(rl.isEmpty())?"":resiCom->currentText();
2389     emit insertCHIV(volline->text().toDouble(),esd1line->text().toDouble(),mol->selectedatoms,s);
2390     mol->selectedatoms.clear();
2391   }
2392   else
2393   {
2394     if(a == QDialog::Rejected)
2395       dia->close();
2396   }
2397 }
2398 
addANIS()2399 void ChGL::addANIS()
2400 {
2401   emit insertANIS(mol->selectedatoms);
2402   mol->selectedatoms.clear();
2403 }
2404 
2405 
parallel()2406 void ChGL::parallel(){//!sets the stereo mode for parallel eye side by side stereo
2407   stereo_mode=2;
2408   minus=1;
2409   updateGL();
2410 }
2411 
crosseye()2412 void ChGL::crosseye(){//!sets the stereo mode for crossed eye side by side stereo
2413   stereo_mode=3;
2414   minus=-1;
2415   updateGL();
2416 }
2417 
anaglyphRedCyan()2418 void ChGL::anaglyphRedCyan(){//!sets the stereo mode for analglyph stereo Red and Cyan glasses.
2419   stereo_mode=4;
2420   minus=1;
2421   updateGL();
2422 }
2423 
hardwareStereo()2424 void ChGL::hardwareStereo(){//!sets the stereo mode for hardware or driver supported stereo mode
2425   if (format().stereo()){
2426     stereo_mode=5;
2427     minus=-1;
2428     updateGL();
2429   }
2430   else {
2431     qDebug()<<"no stereo sorry!";
2432     emit no_hw_st();
2433   }
2434 }
2435 
nostereo()2436 void ChGL::nostereo(){//!turns the stereo mode off
2437   stereo_mode=0;
2438   updateGL();
2439 }
2440 
clearEnvi()2441 void ChGL::clearEnvi(){
2442   /*! Clears ChGL.enviPositions, ChGL.enviKat. and ChGL.labs */
2443   enviPositions.clear();
2444   labs.clear();
2445   enviKat.clear();
2446   enviButt->setVisible(false);
2447   enviSelect->setVisible(false);
2448   rotCenter();
2449 }
2450 
selectEnvi()2451 void ChGL::selectEnvi(){
2452   mol->selectedatoms.clear();
2453   if (rotze>=0) {
2454     mol->selectedatoms.append(mol->showatoms[rotze]);
2455     mol->selectedatoms.last().style=rotze;
2456   }
2457   for (int i=0; i<mol->showatoms.size(); i++){
2458     for (int j=0; j< enviPositions.size(); j++){
2459       if (mol->showatoms.at(i).pos==enviPositions.at(j)) {
2460         mol->selectedatoms.append(mol->showatoms[i]);
2461         mol->selectedatoms.last().style=i;
2462       }
2463     }
2464   }
2465   updateBondActions();
2466   updateGL();
2467 
2468 }
2469 
envi()2470 void ChGL::envi(){
2471   /*! Finds neighboring atoms around a ChGL.envirange the spezified atom and passes a html table via ChGL.bigmessage
2472    * Feeds ChGL.enviPositions, ChGL.labs  and ChGL.enviKat.
2473    * sets the rotation center to the spezified atom.
2474    * */
2475  // printf("->-ENVI-<-\n");
2476   QAction *action = qobject_cast<QAction *>(sender());
2477   int index=0;
2478   if (action)
2479     index=action->data().toInt();
2480   else index=rotze;//return;
2481   if (index<0) return;
2482   if (index>=mol->asymm.size())return;
2483   mol->enviSDM(envirange);
2484   enviPositions.clear();
2485   enviKat.clear();
2486   labs.clear();
2487   QList<bool> covs;
2488   pause=true;
2489 
2490   V3 ppc,ppf,p0;
2491   // int ssy=0;
2492   QString systr;
2493   QStringList bs;
2494   QString info;
2495   enviP0=mol->asymm.at(index).pos;
2496   info.append(QString("<hr><b>Environment of %1 </b><table border=\"0\" cellspacing=\"0\" cellpadding=\"5\">").arg(mol->asymm[index].Label));
2497   for (int i = 0; i < mol->envi_sdm.size(); i++){
2498     if ((mol->envi_sdm.at(i).a2==index)&&mol->envi_sdm.at(i).d<envirange) {
2499       if ((!mol->envi_sdm.at(i).covalent)&&(enviCova->isChecked())) continue;
2500       if ((mol->asymm[mol->envi_sdm.at(i).a1].an==-1)&&(enviNoQ->isChecked())) continue;
2501       ppf=mol->cell.symmops.at(mol->envi_sdm.at(i).sn) *
2502         mol->asymm[mol->envi_sdm.at(i).a1].frac +
2503         mol->cell.trans.at(mol->envi_sdm.at(i).sn) -//-
2504         mol->envi_sdm.at(i).floorD;
2505       mol->frac2kart(ppf,ppc);
2506       mol->frac2kart(mol->asymm[index].frac,p0);
2507       /*
2508          if (fabs(mol->envi_sdm.at(i).d-sqrt(Distance(p0,ppc)))>0.5){
2509          ppf=mol->cell.symmops.at(mol->envi_sdm.at(i).sn) *
2510          mol->asymm[mol->envi_sdm.at(i).a2].frac -
2511          mol->cell.trans.at(mol->envi_sdm.at(i).sn) -
2512          mol->envi_sdm.at(i).floorD;
2513          mol->frac2kart(ppf,ppc);
2514 
2515          }// */
2516       enviPositions.append(ppc);
2517       covs.append(mol->envi_sdm.at(i).covalent);
2518       enviKat.append((mol->envi_sdm.at(i).covalent)?1:0);
2519       if((abs(mol->asymm[mol->envi_sdm.at(i).a1].an-7)<2)
2520           &&(abs(mol->asymm[mol->envi_sdm.at(i).a2].an-7)<2)
2521           &&(fabs(mol->envi_sdm.at(i).d-2.725)<0.275)){enviKat.last()=2;}
2522 
2523       if((mol->asymm[mol->envi_sdm.at(i).a1].an==0)&&(abs(mol->asymm[mol->envi_sdm.at(i).a2].an-7)<2)&&(fabs(mol->envi_sdm.at(i).d-1.875)<0.275)){enviKat.last()=2;}
2524       if((mol->asymm[mol->envi_sdm.at(i).a2].an==0)&&(abs(mol->asymm[mol->envi_sdm.at(i).a1].an-7)<2)&&(fabs(mol->envi_sdm.at(i).d-1.875)<0.275)){enviKat.last()=2;}
2525       bool symm=((mol->envi_sdm.at(i).sn)||(!(mol->envi_sdm.at(i).floorD==V3(0,0,0))));
2526       if (symm) {
2527         QString sss=QString("%1_%2%3%4:%5,").arg(mol->envi_sdm.at(i).sn+1).arg(5-(int)mol->envi_sdm.at(i).floorD.x).arg(5-(int)mol->envi_sdm.at(i).floorD.y).arg(5-(int)mol->envi_sdm.at(i).floorD.z).arg(mol->asymm[mol->envi_sdm.at(i).a1].molindex);
2528         if (!bs.contains(sss)){
2529           bs.append(sss);
2530         }
2531 
2532         systr=QString("%1%2").arg(QString::fromUtf8("»")).arg(bs.indexOf(sss)+1);
2533         labs.append(mol->asymm[ mol->envi_sdm.at(i).a1].Label+systr);
2534       }
2535       else labs.append(mol->asymm[ mol->envi_sdm.at(i).a1].Label);
2536       info.append(QString("<tr><th style=\"background:%6\" >%1%4</th><td style=\"background:%5\" >%7<font color=%3> %2&nbsp;&Aring;</font></b></td>")
2537           .arg(mol->asymm[ mol->envi_sdm.at(i).a1].Label)
2538           .arg(mol->envi_sdm.at(i).d,8,'f',3)
2539           .arg((mol->envi_sdm.at(i).covalent)?"green":"black")
2540           .arg(symm?systr:"").arg((labs.size()%2)?"#eeeeee":"white")
2541           .arg((labs.size()%2)?"#d4d4e4":"#efefff")
2542           .arg((mol->envi_sdm.at(i).covalent)?"<b>":""));
2543       for (int j=0; j<enviPositions.size()-1; j++){
2544         double w=
2545           mol->winkel(p0-enviPositions.at(j),
2546               p0-enviPositions.last());
2547         //		printf("%s-%s-%s %g   %g %g %g\n",labs.at(j).toStdString().c_str(),mol->asymm[index].Label.toStdString().c_str(),labs.last().toStdString().c_str(),w,enviPositions.at(j).x ,enviPositions.at(j).y,enviPositions.at(j).z);
2548         info.append(QString("<td style=\"background:%3\" align=right>%4<font color=%2> %1&deg;</font></b></td>")
2549             .arg(w,8,'f',2)
2550             .arg(((mol->envi_sdm.at(i).covalent)&&(covs.at(j)))?"green":"black")
2551             .arg(((j+1)%2)?(labs.size()%2)?"#d4d4d4":"#e4e4e4":(labs.size()%2)?"#eeeeee":"#ffffff")
2552             .arg(((mol->envi_sdm.at(i).covalent)&&(covs.at(j)))?"<b>":""));
2553 
2554       }
2555       info.append("</tr>\n");
2556     }
2557   }
2558   info.append("<tr><td style=\"background:#efefff\"></td><td style=\"background:#efefff\"></td>");
2559   for (int j=0; j<enviPositions.size()-1; j++){
2560     info.append(QString("<th style=\"background:%2\">%1</th>").arg(labs.at(j)).arg(((j+1)%2)?"#d4d4e4":"#efefff"));
2561   }
2562   QString symml="";
2563   for (int j=0; j<bs.size(); j++){
2564     symml+=mol->symmcode2human(bs.at(j),j+1);
2565   }
2566   info.append(QString("</tr>\n</table>%1<hr>\n").arg(symml));
2567 
2568   enviTextures.clear();
2569   QFont fnt=myFont;
2570   fnt.setPointSize(96);
2571   QFontMetrics mtr(myFont);
2572   for (int li=0; li<labs.size(); li++){
2573     QString label=labs.at(li);
2574     int rcw=mtr.width(label);
2575     QImage image(rcw+mtr.width("Li"), mtr.height()+2,QImage::Format_ARGB32_Premultiplied);
2576     image.fill(0);
2577     QPainter p;
2578     p.begin(&image);
2579     p.setPen(QPen(Qt::white));
2580     p.setBackground(Qt::NoBrush);
2581     p.setFont(myFont);
2582     //p.drawRect( 1, 1, image.rect().width()-3, image.rect().height()-3 );
2583     p.drawText(5,image.rect().height()-3, label);
2584     p.end();
2585     enviTextures.append(image.convertToFormat(QImage::Format_Indexed8));
2586   }
2587   for (int j=0; j<enviPositions.size()-1; j++){
2588       QString label=QString::number(sqrt(Distance(enviP0,enviPositions.at(j))),'f',3);
2589       label.append("Ang");
2590       int rcw=mtr.width(label);
2591       QImage image(rcw+4, mtr.height()+4,QImage::Format_ARGB32_Premultiplied);
2592       image.fill(0);
2593       QPainter p;
2594       p.begin(&image);
2595       p.setPen(QPen(Qt::white));
2596       p.setBackground(Qt::NoBrush);
2597       p.setFont(myFont);
2598       p.drawText(0,image.rect().height()-10, label);
2599       //p.drawRect( 1, 1, image.rect().width()-3, image.rect().height()-3 );
2600       p.end();
2601       enviTextures.append(image.convertToFormat(QImage::Format_Indexed8));
2602   }
2603   emit bigmessage(info);
2604 
2605   enviButt->setVisible(true);
2606   enviSelect->setVisible(true);
2607   pause=false;
2608   setRotationCenter(index);
2609  // printf("--ENVI--\n");
2610 }
2611 
setDepthCueing(bool b)2612 void ChGL::setDepthCueing(bool b){
2613     depthcueing=b;
2614     mol->mist=b;
2615     updateGL();
2616 
2617 }
2618 
paintGL()2619 void ChGL::paintGL(){
2620   //  printf("%d pause%d\n",__LINE__,pause);
2621   /*
2622      static QGLFunctions *glf= new QGLFunctions(context());
2623      printf ("!!! %p\n",glf);
2624      GLenum stat =  glf->glCheckFramebufferStatus(GL_FRAMEBUFFER);
2625      printf("%x %x\n",stat, GL_FRAMEBUFFER_COMPLETE);
2626      if (stat!= GL_FRAMEBUFFER_COMPLETE) return;
2627      */
2628 
2629   if (!moving->isActive()) mol->dratom=0;
2630   if (pause)  return;
2631   GLenum err = GL_NO_ERROR;
2632   while((err = glGetError()) != GL_NO_ERROR)
2633   {
2634     printf("0paintGL %s err=%X\n",glError2String(err).toStdString().c_str(),err);
2635     //printf("%s\n",(char*)gluErrorString(err));
2636   }
2637   //if ((viewAngle>0.3)&&(orthoView)&&(mol->showatoms.size()>0)) setViewAngle((orthoView)?0.2:29.0);
2638   warLabel = drawLa;
2639   qglClearColor(backGroundColor);
2640   mol->fgc[0] = (GLfloat)backGroundColor.redF();
2641   mol->fgc[1] = (GLfloat)backGroundColor.greenF();
2642   mol->fgc[2] = (GLfloat)backGroundColor.blueF();
2643   mol->fgc[3] = 1.0f;
2644   glFogfv(GL_FOG_COLOR,mol->fgc);
2645   glViewport(0, 0, ww, wh);
2646   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2647   //  printf("clear %d %d\n",ww,wh);
2648   glViewport(0, 0, ww, wh);
2649   glDisable(GL_STENCIL_TEST);
2650   glGetIntegerv(GL_VIEWPORT, vp);
2651   if (!stereo_mode){
2652     //  printf("%d %d %d %d \n",vp[0],vp[1],vp[2],vp[3]);
2653     glDrawBuffer(GL_BACK);
2654     glMatrixMode(GL_PROJECTION);
2655     glLoadIdentity();
2656     gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2657     glMatrixMode(GL_MODELVIEW);
2658     glPushMatrix();
2659     if (!pause) draw();
2660     glPopMatrix();
2661   }else
2662     if (stereo_mode==1){// stereo zalman
2663       glDrawBuffer(GL_BACK);
2664       GLint viewport[4];
2665       glGetIntegerv(GL_VIEWPORT,viewport);
2666 
2667       glPushAttrib(GL_ENABLE_BIT);
2668       glMatrixMode(GL_PROJECTION);
2669       glPushMatrix();
2670       glLoadIdentity();
2671       glOrtho(0,viewport[2],0,viewport[3],-10.0,10.0);
2672       glMatrixMode(GL_MODELVIEW);
2673       glPushMatrix();
2674       glLoadIdentity();
2675       glTranslatef(0.33F,0.33F,0.0F);
2676       glDisable(GL_STENCIL_TEST);
2677       glDisable(GL_ALPHA_TEST);
2678       glDisable(GL_LIGHTING);
2679       glDisable(GL_FOG);
2680       glDisable(GL_NORMALIZE);
2681       glDisable(GL_DEPTH_TEST);
2682       glDisable(GL_COLOR_MATERIAL);
2683       glDisable(GL_LINE_SMOOTH);
2684       glDisable(GL_DITHER);
2685       glDisable(GL_BLEND);
2686       glShadeModel(GL_SMOOTH);
2687 
2688       glClearStencil(0);
2689       glColorMask(false,false,false,false);
2690       glDepthMask(false);
2691       glClear(GL_STENCIL_BUFFER_BIT);
2692 
2693       glEnable(GL_STENCIL_TEST);
2694       glStencilFunc(GL_ALWAYS, 1, 1);
2695       glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2696 
2697       glLineWidth(1.0);
2698       glBegin(GL_LINES);
2699       int h = viewport[3], w=viewport[2];
2700       int y;
2701       for(y=0;y<h;y+=2) {
2702         glVertex2i(0,y);
2703         glVertex2i(w,y);
2704       }
2705       glEnd();
2706 
2707       glColorMask(true,true,true,true);
2708       glDepthMask(true);
2709 
2710       glMatrixMode(GL_MODELVIEW);
2711       glPopMatrix();
2712       glMatrixMode(GL_PROJECTION);
2713       glPopMatrix();
2714       //
2715       glPopAttrib();
2716 
2717       glViewport(0, 0, ww, wh);
2718       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2719       glViewport(0, 0, ww, wh);
2720       glGetIntegerv(GL_VIEWPORT, vp);
2721       glMatrixMode(GL_PROJECTION);
2722       glLoadIdentity();
2723       gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2724       glMatrixMode(GL_MODELVIEW);
2725       glPushMatrix();
2726       drawLa=false;
2727       glRotateL(minus*-1.5,0,1,0);
2728       glEnable(GL_STENCIL_TEST);
2729       glStencilFunc(GL_EQUAL, 1, 1);
2730       glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2731       glEnable(GL_STENCIL_TEST);// */
2732       if (!pause) draw();
2733       glPopMatrix();
2734 
2735       drawLa= warLabel;
2736       glPushMatrix();
2737       glRotateL(minus*1.5,0,1,0);
2738       glEnable(GL_STENCIL_TEST);
2739       glStencilFunc(GL_EQUAL, 0, 1);
2740       glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2741       glEnable(GL_STENCIL_TEST);// */
2742       if (!pause) draw();
2743       glPopMatrix();
2744     }else
2745       if ((stereo_mode>1)&&(stereo_mode<4)) { //stereo_side by side
2746         glDrawBuffer(GL_BACK);
2747         glPushMatrix();
2748         glViewport(0, 0, ww/2, wh);
2749         glMatrixMode(GL_PROJECTION);
2750         glLoadIdentity();
2751         gluPerspective_( viewAngle, (double)(ww/2.0)/wh, 5.0, 8000.0 );
2752         glMatrixMode(GL_MODELVIEW);
2753         glPushMatrix();
2754         glRotateL(1.5*minus,0,1,0);
2755         if (!pause) draw();
2756         glPopMatrix();
2757         glPopMatrix();
2758         glPushMatrix();
2759         glViewport( ww / 2 , 0,ww / 2,wh );
2760         glMatrixMode(GL_PROJECTION);
2761         glLoadIdentity();
2762         gluPerspective_( viewAngle, (double)(ww/2.0)/wh, 5.0, 8000.0 );
2763         glMatrixMode(GL_MODELVIEW);
2764         glPushMatrix();
2765         glRotateL(-1.5*minus,0,1,0);
2766         if (!pause) draw();
2767         glPopMatrix();
2768         glPopMatrix();
2769 
2770       }
2771       else  if (stereo_mode==4){//anaglyph red cyan
2772         glDrawBuffer(GL_BACK);
2773         glGetIntegerv(GL_VIEWPORT, vp);
2774         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2775         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2776         glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
2777 
2778         // set camera for blue eye, red will be filtered.
2779 
2780         // draw scene
2781         glPushMatrix();
2782         glViewport(0, 0, ww, wh);
2783         glMatrixMode(GL_PROJECTION);
2784         glLoadIdentity();
2785         gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2786         glMatrixMode(GL_MODELVIEW);
2787         glPushMatrix();
2788         glRotateL(1.5*minus,0,1,0);
2789         if (!pause) draw();
2790         glPopMatrix();
2791         glPopMatrix();
2792 
2793         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2794         glClear(GL_DEPTH_BUFFER_BIT);
2795         glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
2796 
2797         // set camera for red eye, blue will be filtered.
2798 
2799         // draw scene
2800         glPushMatrix();
2801         glViewport(0, 0, ww, wh);
2802         glMatrixMode(GL_PROJECTION);
2803         glLoadIdentity();
2804         gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2805         glMatrixMode(GL_MODELVIEW);
2806         glPushMatrix();
2807         glRotateL(-1.5*minus,0,1,0);
2808         if (!pause) draw();
2809         glPopMatrix();
2810         glPopMatrix();
2811         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2812 
2813       }else  if (stereo_mode==5){//hardware stereo ???
2814         //todo  is this working??
2815         glGetIntegerv(GL_VIEWPORT, vp);
2816 
2817         //  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2818         glPushMatrix();//2
2819         glViewport(0, 0, ww, wh);
2820         glMatrixMode(GL_PROJECTION);
2821         glLoadIdentity();
2822         gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2823         glMatrixMode(GL_MODELVIEW);
2824         glPushMatrix();
2825         glRotateL(1.5*minus,0,1,0);
2826         glDrawBuffer(GL_BACK_RIGHT);
2827         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2828         if (!pause) draw();
2829         glPopMatrix();
2830         glPopMatrix();
2831 
2832         glPushMatrix();
2833         glViewport(0, 0, ww, wh);
2834         glMatrixMode(GL_PROJECTION);
2835         glLoadIdentity();
2836         gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
2837         glMatrixMode(GL_MODELVIEW);
2838         glPushMatrix();
2839         glRotateL(-1.5*minus,0,1,0);
2840         glDrawBuffer(GL_BACK_LEFT);
2841         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2842         if (!pause) draw();
2843         glPopMatrix();
2844         glPopMatrix();
2845       }
2846   {
2847     GLenum err = GL_NO_ERROR;
2848     while((err = glGetError()) != GL_NO_ERROR){
2849       printf("paintGL %s err=%X\n",glError2String(err).toStdString().c_str(),err);
2850     }
2851   }
2852   //printf("%d pause%d\n",__LINE__,pause);
2853 }
2854 
setViewAngle(double ang)2855 void ChGL::setViewAngle(double ang){
2856   /*! sets ChGL.viewAngele for the perspective view 0 is othogonal, 29 degrees is the perpective default.
2857   */
2858   if ((ang>0.001)&&(ang<160.0)){
2859     printf("View angle = %g degrees. %10.8f %f\n",ang,ang/viewAngle,viewAngle);
2860     glScaled(ang/viewAngle,ang/viewAngle,ang/viewAngle);
2861     viewAngle=ang;
2862     homeXY();
2863   }
2864 }
2865 
rehide()2866 void ChGL::rehide(){//! Trys to hide previous hidden atoms.
2867   //printf("haa %d %d %g\n",hideReason,hiddenThings,qcutoff);
2868   if (!hiddenThings) return;
2869   if ((hideReason&HIDE_REASON_SELECT)&&(mol->selectedatoms.size())) {hideNonSelected(); return;}
2870   else if (hideReason&HIDE_REASON_SELECT) hideReason-=HIDE_REASON_SELECT;
2871   int gute=frid;
2872   for (int i=0;i<mol->showatoms.size();i++){
2873     if (hideReason&HIDE_REASON_QPEAK) if (mol->showatoms[i].an==-1) {if (qcutoff>0)
2874       mol->showatoms[i].hidden=((mol->showatoms[i].peakHeight>0)&&(mol->showatoms[i].peakHeight<qcutoff))?1:0;
2875       else mol->showatoms[i].hidden=((mol->showatoms[i].peakHeight<0)&&(mol->showatoms[i].peakHeight>qcutoff))?1:0;}
2876       if (hideReason&HIDE_REASON_HYDROGEN) mol->showatoms[i].hidden=
2877         (mol->showatoms.at(i).an==0)?1:mol->showatoms.at(i).hidden;
2878       if (hideReason&(HIDE_REASON_THIS_FRAGMENT|HIDE_REASON_OTHER_FRAGMENT)){
2879         if (mol->showatoms.at(i).an>=0){
2880           if (hideReason&HIDE_REASON_THIS_FRAGMENT) mol->showatoms[i].hidden=
2881             (mol->showatoms.at(i).molindex+withsymm*9999*mol->showatoms.at(i).symmGroup!=gute)?mol->showatoms.at(i).hidden:1;
2882           if (hideReason&HIDE_REASON_OTHER_FRAGMENT)mol->showatoms[i].hidden=
2883             (mol->showatoms.at(i).molindex+withsymm*9999*mol->showatoms.at(i).symmGroup!=gute)?1:mol->showatoms.at(i).hidden;
2884         }
2885       }
2886   }
2887 
2888 }
2889 
hideNonSelected()2890 void ChGL::hideNonSelected(){//! Hides all atoms that are not selected
2891   for (int i=0;i<mol->showatoms.size();i++) mol->showatoms[i].hidden=1;
2892   for(int i=0;i<mol->selectedatoms.size();i++){
2893     if (mol->selectedatoms.at(i).style < mol->showatoms.size())
2894       mol->showatoms[mol->selectedatoms.at(i).style].hidden=0;
2895     //   std::cout<<mol->showatoms.at(mol->selectedatoms.at(i).style).Label.toStdString()<<std::endl;
2896   }
2897   hiddenThings=true;
2898   hideReason|=HIDE_REASON_SELECT;
2899   mol->selectedatoms.clear();
2900   murx=-__LINE__;
2901   updateBondActions();
2902   updateGL();
2903 }
2904 
hideSelected()2905 void ChGL::hideSelected(){//! Hides the selected atoms
2906   for(int i=0;i<mol->selectedatoms.size();i++){
2907     if (mol->selectedatoms.at(i).style < mol->showatoms.size())
2908       mol->showatoms[mol->selectedatoms.at(i).style].hidden=1;
2909     //   std::cout<<mol->showatoms.at(mol->selectedatoms.at(i).style).Label.toStdString()<<std::endl;
2910   }
2911   hiddenThings=true;
2912   mol->selectedatoms.clear();
2913   murx=-__LINE__;
2914   updateBondActions();
2915   updateGL();
2916 }
2917 
invertHidden()2918 void ChGL::invertHidden(){//!< Toggle visibility of atoms etc
2919   if (!hiddenThings) return; // nothing is hidden => hide everything now? NO!
2920   for (int i=0;i<mol->legendAtoms.size();i++) mol->legendAtoms[i].hidden=1;
2921   QHash<int,bool> anExists;
2922   for (int i = 0; i < mol->showatoms.size(); i++){
2923     mol->showatoms[i].hidden = (mol->showatoms.at(i).hidden!=0)?0:1;
2924     if (!mol->showatoms.at(i).hidden) anExists[mol->showatoms.at(i).an]=true;
2925   }
2926   for (int i=0;i<mol->legendAtoms.size();i++) if (anExists.contains(mol->legendAtoms.at(i).an)) mol->legendAtoms[i].hidden=0;
2927   frid=-10;
2928   hideReason=0;
2929   mol->selectedatoms.clear();
2930   murx=__LINE__;
2931   updateBondActions();
2932   updateGL();
2933 }
2934 
sdm()2935 void ChGL::sdm(){
2936     if (mol->asymm.size()<=SDM_Limit)return;//sdm is done regularly if number is below so we do not have to do iot now.
2937   if (!(fuse->isVisible()||grow->isVisible ())){
2938     fuse->setVisible(true);
2939     grow->setVisible(false);
2940   }
2941   mol->showatoms.clear();
2942   mol->showbonds.clear();
2943   mol->showatoms.clear();
2944   mol->showbonds.clear();
2945   mol->selectedatoms.clear();
2946   for (int o=0; o<mol->asymm.size();o++)
2947     mol->showatoms.append(mol->asymm[o]);
2948   mol->packer(mol->sdmcompleter());
2949   mol->showbonds =
2950     mol->connecting(mol->showatoms);
2951   mol->selectedatoms.clear();
2952   murx=__LINE__;
2953   bool growYes=fuse->isVisible ();
2954   mol->fuse();
2955   if (growYes) mol->grow();
2956   pause=false;
2957 //  printf("%d\n",__LINE__);
2958   updateBondActions();
2959   updateGL();
2960 }
2961 
2962 
hideThisFragment()2963 void ChGL::hideThisFragment(){//! Hides the specified molecular fragment.
2964   sdm();
2965   QAction *action = qobject_cast<QAction *>(sender());
2966   int index=0;
2967   if (action)
2968     index=action->data().toInt();
2969   else return;
2970   if (index>mol->showatoms.size()) return;
2971   int gute=mol->showatoms.at(index).molindex+9999*mol->showatoms.at(index).symmGroup;
2972   //int gute=mol->showatoms.at(index).molindex;
2973   for (int i=0;i<mol->showatoms.size();i++)
2974     if (mol->showatoms.at(i).an>=0)
2975       mol->showatoms[i].hidden=
2976         (mol->showatoms.at(i).molindex+9999*mol->showatoms.at(i).symmGroup!=gute)?mol->showatoms.at(i).hidden:1;
2977   //(mol->showatoms.at(i).molindex!=gute)?mol->showatoms.at(i).hidden:1;
2978   //
2979   frid=gute;
2980   hiddenThings=true;
2981   hideReason|=HIDE_REASON_THIS_FRAGMENT;
2982   mol->selectedatoms.clear();
2983   murx=-__LINE__;
2984   updateBondActions();
2985   updateGL();
2986 }
2987 
selectThisFragment()2988 void ChGL::selectThisFragment(){//! Selects the specified molecular fragment
2989   sdm();
2990   QAction *action = qobject_cast<QAction *>(sender());
2991   int index=0;
2992   if (action)
2993     index=action->data().toInt();
2994   else return;
2995   if (index>mol->showatoms.size()) return;
2996   mol->selectedatoms.clear();
2997   int gute=mol->showatoms.at(index).molindex+9999*mol->showatoms.at(index).symmGroup;
2998   //int gute=mol->showatoms.at(index).molindex;
2999   for (int i=0;i<mol->showatoms.size();i++)
3000     if (mol->showatoms.at(i).an>=0)
3001       if(mol->showatoms.at(i).molindex+9999*mol->showatoms.at(i).symmGroup==gute){
3002         mol->selectedatoms.append(mol->showatoms[i]);
3003         mol->selectedatoms.last().style=i;
3004       }
3005   //(mol->showatoms.at(i).molindex!=gute)?mol->showatoms.at(i).hidden:1;
3006   //
3007   updateBondActions();
3008   updateGL();
3009 }
3010 
hideHydrogens()3011 void ChGL::hideHydrogens(){//! Hides all Hydrogran atoms
3012   for (int i=0;i<mol->showatoms.size();i++) mol->showatoms[i].hidden=
3013     (mol->showatoms.at(i).an==0)?1:mol->showatoms.at(i).hidden;
3014   for (int i=0;i<mol->legendAtoms.size();i++) mol->legendAtoms[i].hidden=
3015       (mol->legendAtoms.at(i).an==0)?1:mol->legendAtoms.at(i).hidden;
3016   hiddenThings=true;
3017   hideReason|=HIDE_REASON_HYDROGEN;
3018   hideh->setVisible(false);
3019   mol->selectedatoms.clear();
3020   murx=-__LINE__;
3021   updateBondActions();
3022   updateGL();
3023 }
3024 
wuff()3025 void ChGL::wuff(){
3026   bool beloff=hideBeLo->isChecked();
3027   for (int i=0;i<mol->showatoms.size();i++) if (mol->showatoms.at(i).an==-42) mol->showatoms[i].hidden=(beloff)?0:1;
3028   for (int i=0;i<mol->legendAtoms.size();i++) if (mol->legendAtoms.at(i).an==-42) mol->legendAtoms[i].hidden=(beloff)?0:1;
3029   hiddenThings=hiddenThings||(!hideBeLo->isChecked());
3030   hideReason|=HIDE_REASON_BELO;
3031   //  hideh->setVisible(false);
3032   mol->selectedatoms.clear();
3033   murx=-__LINE__;
3034   updateBondActions();
3035   updateGL();
3036 
3037 }
3038 
farbverlauf(double wrt,double min,double max)3039 void ChGL::farbverlauf(double wrt, double min, double max){
3040     if (min>=max) max=min+0.001;
3041     double rot,gruen,blau,alpha;
3042     int lauf=0;
3043     const float farbe[6][4]={{1.0f,0.0f,0.0f,1.0f},
3044                           {1.0f,1.0f,0.0f,1.0f},
3045                           {0.0f,1.0f,0.0f,1.0f},
3046                           {0.0f,1.0f,1.0f,1.0f},
3047                           {0.0f,0.0f,1.0f,1.0f},
3048                           {1.0f,0.0f,1.0f,1.0f}};
3049     double nwrt=(wrt-min)/(max-min);
3050     nwrt=(nwrt>=1.0)?0.99999:nwrt;
3051     nwrt=(nwrt<=0.0)?0.00001:nwrt;
3052     lauf=(int (nwrt/0.2));
3053     nwrt-=(0.2*lauf);
3054     nwrt/=(0.2);
3055 
3056     rot=(((1.0-nwrt)*farbe[lauf][0]+farbe[lauf+1][0]*nwrt));
3057     gruen=(((1.0-nwrt)*farbe[lauf][1]+farbe[lauf+1][1]*nwrt));
3058     blau=(((1.0-nwrt)*farbe[lauf][2]+farbe[lauf+1][2]*nwrt));
3059     alpha=1.0;
3060     glColor4d(rot,gruen,blau,alpha);
3061 }
3062 
farbverlaufQC(double wrt,double min,double max)3063 QColor ChGL::farbverlaufQC(double wrt, double min, double max){
3064     if (min>=max) max=min+0.001;
3065     double rot,gruen,blau,alpha;
3066     int lauf=0;
3067     double farbe[6][4]={{1.0,0.0,0.0,1.0},
3068                        {1.0,1.0,0.0,1.0},
3069                           {0.0,1.0,0.0,1.0},
3070                           {0.0,1.0,1.0,1.0},
3071                           {0.0,0.0,1.0,1.0},
3072                           {1.0,0.0,1.0,1.0}};
3073     double nwrt=(wrt-min)/(max-min);
3074     nwrt=(nwrt>=1.0)?0.99999:nwrt;
3075     nwrt=(nwrt<=0.0)?0.00001:nwrt;
3076     lauf=(int (nwrt/0.2));
3077     nwrt-=(0.2*lauf);
3078     nwrt/=(0.2);
3079 
3080     rot=(((1.0-nwrt)*farbe[lauf][0]+farbe[lauf+1][0]*nwrt));
3081     gruen=(((1.0-nwrt)*farbe[lauf][1]+farbe[lauf+1][1]*nwrt));
3082     blau=(((1.0-nwrt)*farbe[lauf][2]+farbe[lauf+1][2]*nwrt));
3083     alpha=1.0;
3084     return QColor(static_cast<int>(255*rot),
3085            static_cast<int>(255*gruen),
3086            static_cast<int>(255*blau),
3087            static_cast<int>(255*alpha));
3088 }
3089 
3090 
toogleWithSymmetry(bool b)3091 void ChGL::toogleWithSymmetry(bool b){
3092   withsymm=(b)?0:1;
3093 }
3094 
hideOtherFragments()3095 void ChGL::hideOtherFragments(){//! Hides all molecular fragments except from the specified one
3096   sdm();
3097   QAction *action = qobject_cast<QAction *>(sender());
3098   int index=0;
3099   if (action)
3100     index=action->data().toInt();
3101   else return;
3102   if (index==(int)((GLuint)-1))return;
3103   if (index>mol->showatoms.size()) return;
3104   int gute=mol->showatoms.at(index).molindex+withsymm*9999*mol->showatoms.at(index).symmGroup;
3105   //int gute=mol->showatoms.at(index).molindex;
3106   //  printf("hide %d %d %d \n",withsymm,gute,mol->showatoms.at(index).molindex+9999*mol->showatoms.at(index).symmGroup);
3107   for (int i=0;i<mol->showatoms.size();i++)
3108     if (mol->showatoms.at(i).an>=0){
3109       mol->showatoms[i].hidden=
3110         //		(mol->showatoms.at(i).molindex!=gute)?1:mol->showatoms.at(i).hidden;
3111         (mol->showatoms.at(i).molindex+withsymm*9999*mol->showatoms.at(i).symmGroup!=gute)?1:mol->showatoms.at(i).hidden;
3112       //   printf("%d %d \n",mol->showatoms[i].hidden,mol->showatoms.at(i).molindex+withsymm*9999*mol->showatoms.at(i).symmGroup);
3113     }
3114   hiddenThings=true;
3115   frid=gute;
3116   hideReason|=HIDE_REASON_OTHER_FRAGMENT;
3117   mol->selectedatoms.clear();
3118   murx=-__LINE__;
3119   updateBondActions();
3120   updateGL();
3121 }
3122 
highliteQPeak(double co)3123 void ChGL::highliteQPeak(double co){//! highligts the first Q-Peak with a lower or equal peak height than co. @param co cutoff value.
3124   imFokus=-1;
3125   //printf("co %f\n",co)
3126   for (int i=0;i<mol->showatoms.size();i++){
3127     if (mol->showatoms[i].an==-66) continue;
3128     if (mol->showatoms[i].an>=0) continue;
3129     if (mol->showatoms[i].hidden)continue;
3130     if (mol->showatoms[i].peakHeight<=co) {imFokus=i; break;}
3131   }
3132   updateGL();
3133 }
3134 
hideQPeaksBelow(double cutoff)3135 void ChGL::hideQPeaksBelow(double cutoff){//!hides all Q-Peaks below the given cutoff value. @param cutoff The cutoff value.
3136   // qDebug()<<cutoff;
3137   int vor=0,nach=0;
3138   for (int i=0;i<mol->showatoms.size();i++){
3139     vor += mol->showatoms[i].hidden;
3140     if ((mol->showatoms[i].an == -1)&&(cutoff>0)) mol->showatoms[i].hidden = ((mol->showatoms[i].peakHeight>=0)&&(mol->showatoms[i].peakHeight<cutoff))?1:0;
3141     else if ((mol->showatoms[i].an ==-1)&&(cutoff<0)) mol->showatoms[i].hidden = ((mol->showatoms[i].peakHeight<=0)&&(mol->showatoms[i].peakHeight>cutoff))?1:0;
3142     //    if (mol->showatoms[i].an < 0) printf("#%d %g %d\n",mol->showatoms[i].hidden,mol->showatoms[i].peakHeight,mol->showatoms[i].peakHeight<cutoff);
3143     //    if (mol->showatoms[i].an == -66) mol->showatoms[i].hidden = 0;
3144     //    if (mol->showatoms[i].an == -42) mol->showatoms[i].hidden = 0;
3145     //  if (mol->showatoms[i].an < 0) printf("!%d %g %d\n",mol->showatoms[i].hidden,mol->showatoms[i].peakHeight,mol->showatoms[i].peakHeight<cutoff);
3146     nach += mol->showatoms[i].hidden;
3147   }
3148   for (int i=0;i<mol->legendAtoms.size();i++){
3149     if ((mol->legendAtoms[i].an == -1)&&(cutoff>0)) mol->legendAtoms[i].hidden = ((mol->legendAtoms[i].peakHeight>=0)&&(mol->legendAtoms[i].peakHeight<cutoff))?1:0;
3150     else if ((mol->legendAtoms[i].an ==-1)&&(cutoff<0)) mol->legendAtoms[i].hidden = ((mol->legendAtoms[i].peakHeight<=0)&&(mol->legendAtoms[i].peakHeight>cutoff))?1:0;
3151     //    if (mol->legendAtoms[i].an == -66) mol->legendAtoms[i].hidden = 0;
3152     //    if (mol->legendAtoms[i].an == -42) mol->legendAtoms[i].hidden = 0;
3153   }
3154   if (vor==nach) return;
3155   hiddenThings=true;
3156   hideReason|=HIDE_REASON_QPEAK;
3157   qcutoff=cutoff;
3158   mol->selectedatoms.clear();
3159   murx=-__LINE__;
3160   updateBondActions();
3161   updateGL();
3162 }
3163 
showHidden()3164 void ChGL::showHidden(){//! shows all hidden objects.
3165   int h=0;
3166   for (int i=0;i<mol->showatoms.size();i++){
3167     mol->showatoms[i].hidden=0;
3168     if (mol->showatoms[i].an==0)h++;
3169   }
3170   for (int i=0;i<mol->legendAtoms.size();i++){
3171     mol->legendAtoms[i].hidden=0;
3172     if (mol->legendAtoms[i].an==0)h++;
3173   }
3174   if (h)
3175     hideh->setVisible(true);
3176   hiddenThings=false;
3177   hideBeLo->setChecked(true);//toggle state is OK this way
3178   wuff();
3179   hideReason=0;
3180   murx=-__LINE__;
3181   updateBondActions();
3182   updateGL();
3183 }
3184 
hidePartMinusOne(bool off)3185 void ChGL::hidePartMinusOne(bool off){//! toggles the visibility state of part -N ghost atoms @param off if true no ghosts are visible.
3186 
3187   mol->nopm1=off;
3188   murx=-__LINE__;
3189   updateBondActions();
3190   updateGL();
3191 }
3192 
setupTexture()3193 void ChGL::setupTexture(){//!loads the texture images
3194   deleteTexture(mol->adpwall);
3195   deleteTexture(mol->adpwall_plaid);
3196   deleteTexture(mol->hbtex);
3197 
3198   mol->adpwall_plaid=bindTexture(QImage(QString(":/xle-icons/adpwall.png")),GL_TEXTURE_2D);
3199   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
3200   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
3201   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
3202   glBindTexture(GL_TEXTURE_2D, 0);
3203 
3204   mol->adpwall=bindTexture(QImage(QString(":/xle-icons/adpwall3.png")),GL_TEXTURE_2D);
3205   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
3206   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
3207   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
3208   glBindTexture(GL_TEXTURE_2D, 0);
3209 
3210   mol->hbtex=bindTexture(QImage(QString(":/xle-icons/hbb.png")),GL_TEXTURE_2D);
3211   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
3212   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
3213   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
3214   glBindTexture(GL_TEXTURE_2D, 0);
3215 
3216   //  mol->elitex=bindTexture(QImage(QString(":/xle-icons/eli.png")),GL_TEXTURE_2D);
3217   //  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
3218   //  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
3219   //  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
3220   //  glBindTexture(GL_TEXTURE_2D, 0);
3221   //  printf("texture %d %d \n",mol->elitex,mol->hbtex);
3222 }
3223 
homeXY()3224 void ChGL::homeXY(){//! Resets the molecule to rotate in the middle of the viewport.
3225   glGetDoublev(GL_MODELVIEW_MATRIX,MM);
3226   MM[12]=MM[13]=0;
3227   glLoadMatrixd(MM);
3228   updateGL();
3229 }
3230 
draw()3231 void ChGL::draw(){//! draws everything some times by calling display lists.
3232   //printf("draw %d pause%d\n",__LINE__,pause);
3233   if (murx) {
3234     rehide();
3235     //printf("draw->murx %d %d \n",murx,mol->monoQrom);
3236     murx=0;
3237 
3238   }
3239   glCullFace(GL_BACK);
3240   glEnable(GL_DEPTH_TEST );
3241   QFontMetrics fmtr(myFont);
3242   nonAtomFont = myFont;
3243   nonAtomFont.setPointSize(qMax(((myFont.pointSize()*2)/3),7));
3244   QFontMetrics fmtr2(nonAtomFont);
3245   if (exporting) LabelZ.clear();
3246   const GLfloat  OBJ_SPE[]   = { 0.8f, 0.8f, 0.8f, 1.0f };
3247   const GLfloat  OBJ_SHIN    = 32.0f;
3248   glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,             OBJ_SPE  );
3249   glEnable     ( GL_COLOR_MATERIAL ) ;
3250   glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
3251   glMaterialf(  GL_FRONT_AND_BACK, GL_SHININESS,           OBJ_SHIN );
3252   V3 ori=V3(0,0,0);///rotation origin
3253   V3 sumse=V3(0,0,0);
3254   int zz=0;
3255   objCnt=0;
3256   if (mol->showatoms.size()){
3257     for (int i=0;i<mol->showatoms.size();i++){
3258       if (!mol->showatoms[i].hidden) objCnt++;
3259       if ((!mol->showatoms.at(i).hidden)) {//(mol->showatoms.at(i).an>-1)&&
3260         sumse+=mol->showatoms[i].pos;
3261         zz++;
3262       }
3263     }
3264 
3265     if (zz) sumse*=1.0/zz;
3266     else {
3267       for (int i=0;i<mol->showatoms.size();i++){
3268         if (!mol->showatoms.at(i).hidden) {
3269           sumse+=mol->showatoms[i].pos;
3270           zz++;
3271         }
3272       }
3273       if (zz) sumse*=1.0/zz;
3274     }
3275   }
3276   //  printf(" zz %d %d \n",zz,mol->showatoms.size());
3277   glGetDoublev( GL_MODELVIEW_MATRIX, (double*)MM );
3278   double gmat[16];
3279   glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
3280   ori.x=gmat[0] * sumse.x + gmat[4] * sumse.y + gmat[8] * sumse.z;
3281   ori.y=gmat[1] * sumse.x + gmat[5] * sumse.y + gmat[9] * sumse.z;
3282   ori.z=gmat[2] * sumse.x + gmat[6] * sumse.y + gmat[10] * sumse.z;
3283   if (mol->showatoms.size()<=rotze){
3284     rotze=-1;
3285     rCenter->hide();
3286   }
3287   if (rotze>-1) {
3288     double gmat[16];
3289     sumse=mol->showatoms.at(rotze).pos;
3290     glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
3291     ori.x=gmat[0] * mol->showatoms.at(rotze).pos.x + gmat[4] * mol->showatoms.at(rotze).pos.y + gmat[8] *  mol->showatoms.at(rotze).pos.z;
3292     ori.y=gmat[1] * mol->showatoms.at(rotze).pos.x + gmat[5] * mol->showatoms.at(rotze).pos.y + gmat[9] *  mol->showatoms.at(rotze).pos.z;
3293     ori.z=gmat[2] * mol->showatoms.at(rotze).pos.x + gmat[6] * mol->showatoms.at(rotze).pos.y + gmat[10] * mol->showatoms.at(rotze).pos.z;
3294   }
3295   if (centerSelection->isChecked()){
3296     if (mol->selectedatoms.isEmpty()) {
3297       sumse=altemitte;//centerSelection->setChecked(false);
3298       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
3299       ori.x=gmat[0] * sumse.x + gmat[4] * sumse.y + gmat[8] * sumse.z;
3300       ori.y=gmat[1] * sumse.x + gmat[5] * sumse.y + gmat[9] * sumse.z;
3301       ori.z=gmat[2] * sumse.x + gmat[6] * sumse.y + gmat[10] * sumse.z;
3302     }
3303     else {
3304       sumse=V3(0,0,0);
3305       for (int i=0;i<mol->selectedatoms.size();i++)
3306         sumse+=mol->selectedatoms[i].pos;
3307       sumse*=1.0/mol->selectedatoms.size();
3308       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
3309       ori.x=gmat[0] * sumse.x + gmat[4] * sumse.y + gmat[8] * sumse.z;
3310       ori.y=gmat[1] * sumse.x + gmat[5] * sumse.y + gmat[9] * sumse.z;
3311       ori.z=gmat[2] * sumse.x + gmat[6] * sumse.y + gmat[10] * sumse.z;
3312 
3313 
3314     }
3315   }
3316   glPushMatrix();
3317   double mat[16];
3318   glEnable(GL_BLEND);
3319   glEnable(GL_COLOR_MATERIAL);
3320   glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mat );
3321   glLoadIdentity();
3322   glDisable( GL_LIGHTING );
3323   glDisable( GL_DEPTH_TEST );
3324   if ((bggradient)&&(!depthcueing)) {
3325     glPushMatrix();
3326     glMatrixMode(GL_PROJECTION);
3327     glLoadIdentity();
3328     gluPerspective_( 29, (double)ww/wh, 5.0, 8000.0 );
3329     glMatrixMode(GL_MODELVIEW);
3330     glPushMatrix();
3331     glBegin(GL_QUADS);
3332     double xx = ((double) ww / wh) * 2.0,
3333            yy = 1.77777777778;
3334     glColor4f(1.0f,1.0f,1.0f,0.5f);
3335     //glTexCoord2d(-1,-1);
3336     glVertex3d(-xx,-yy,-6.0);
3337     glColor4f(1.0f,1.0f,1.0f,0.5f);
3338     //glTexCoord2d(0,-1);
3339     glVertex3f( xx,-yy,-6.0);
3340     //glTexCoord2d(0,0);
3341     glColor4f(0.3f,0.3f,0.3f,0.7f);
3342     glVertex3d( xx, yy,-6.0);
3343     glColor4f(0.3f,0.3f,0.3f,0.7f);
3344     //glTexCoord2d(-1,0);
3345     glVertex3d(-xx, yy,-6.0);
3346     glEnd();
3347 
3348     glPopMatrix();
3349     glMatrixMode(GL_PROJECTION);
3350     glLoadIdentity();
3351     gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
3352     glMatrixMode(GL_MODELVIEW);
3353     glPopMatrix();
3354   }
3355   if (rectangle){
3356     glPushMatrix();
3357     glMatrixMode(GL_PROJECTION);
3358     glLoadIdentity();
3359     glOrtho(0.0,ww,0.0,wh,-1.0,1.0);
3360     glMatrixMode(GL_MODELVIEW);
3361     glPushMatrix();
3362 
3363     glEnable(GL_LINE_STIPPLE);
3364     glEnable(GL_BLEND);
3365     glLineWidth(0.3f);
3366     glDisable(GL_LIGHTING);
3367     glLineStipple(3,21845);
3368     glBegin(GL_LINE_STRIP);
3369     qglColor(labelColor);
3370     glVertex3f(scrx0,wh-scry0,0.0f);
3371     glVertex3f(scrx,wh-scry0,0.0f);
3372     glVertex3f(scrx,wh-scry,0.0f);
3373     glVertex3f(scrx0,wh-scry,0.0f);
3374     glVertex3f(scrx0,wh-scry0,0.0f);
3375     glEnd();
3376     glDisable(GL_LINE_STIPPLE);
3377     glDisable(GL_BLEND);
3378     glEnable(GL_LIGHTING);
3379     glPopMatrix();
3380     glMatrixMode(GL_PROJECTION);
3381     glLoadIdentity();
3382     gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
3383     glMatrixMode(GL_MODELVIEW);
3384     glPopMatrix();
3385   }
3386   glEnable( GL_LIGHTING );
3387   glEnable( GL_DEPTH_TEST );
3388   if (depthcueing){
3389       glEnable(GL_FOG);
3390   }else{
3391       glDisable(GL_FOG);
3392   }
3393 
3394   glLoadMatrixd(mat);
3395   glPopMatrix();
3396   glPushMatrix();
3397   if ((!(sumse==V3(0,0,0)))&&(Distance(altemitte,sumse)>0.2)){
3398     //printf("neuemitte %f %f %f %f %f %f\n",sumse.x,sumse.y,sumse.z,altemitte.x,altemitte.y,altemitte.z);
3399     if(!(altemitte==V3(0,0,0))) emit neuemitte(altemitte);
3400     altemitte=sumse;
3401   }
3402   if (rotze==-76185){
3403     glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
3404     ori.x=gmat[0] * altcenter.x + gmat[4] * altcenter.y + gmat[8] *  altcenter.z;
3405     ori.y=gmat[1] * altcenter.x + gmat[5] * altcenter.y + gmat[9] *  altcenter.z;
3406     ori.z=gmat[2] * altcenter.x + gmat[6] * altcenter.y + gmat[10] * altcenter.z;
3407   }
3408   glTranslateL(-L*ori.x,-L*ori.y,-L*ori.z);
3409 
3410   glPushMatrix();{
3411     glScaled( L, L, L );
3412     if (!mol->splitLeftAtoms.isEmpty()){
3413         if (manualAx->isChecked()){
3414             qglColor(QColor("fuchsia"));
3415             glBegin(GL_LINES);
3416             glVertex3d(mol->asymm.at(pivot).pos.x,mol->asymm.at(pivot).pos.y,mol->asymm.at(pivot).pos.z);
3417             V3 axe=mol->asymm.at(pivot).pos - Normalize(V3(axx->value(),axy->value(),axz->value()));
3418             glVertex3d(axe.x,axe.y,axe.z);
3419             glEnd();
3420             glPushMatrix();
3421             glTranslated(axe.x,axe.y,axe.z);
3422             mol->triacontaeder(0.05);
3423             glPopMatrix();
3424         }
3425         mol->dratom=5;
3426         mol->intern=0;
3427         mol->adp=0;
3428         mol->dbond(mol->splitbonds);
3429         mol->atoms(mol->splitLeftAtoms,mol->proba);
3430         mol->atoms(mol->splitRightAtoms,mol->proba);
3431 
3432         mol->dratom=0;
3433         mol->intern=1;
3434     }
3435     if ((wireButt->isChecked())&&(moving->isActive())) {
3436       mol->dratom=5;
3437       mol->intern=0;
3438       mol->adp=(drawADP)?1:0;
3439       mol->dbond(mol->showbonds);
3440       mol->atoms(mol->showatoms,mol->proba);
3441       mol->lbond();
3442     }
3443     else {
3444       if (!apair.isEmpty()){
3445         mol->dbond(apair);
3446       }
3447       if (drawHb)  {
3448         mol->tubes=(tubes&&!drawADP)?1:0;
3449         mol->adp=(drawADP)?1:0;
3450         mol->h_bonds2(mol->showbonds,mol->showatoms);
3451 
3452       }
3453       //     printf("qPeakBonds %d !%d\n",mol->lbonds.size(),mol->showatoms.size());
3454       if (qPeakBonds->isChecked())mol->lbond();//bonds
3455       if (drawAt) {
3456         mol->intern=1;
3457         mol->adp=(drawADP)?1:0;
3458         mol->tubes=(tubes&&!drawADP)?1:0;
3459         mol->atoms(mol->showatoms,mol->proba);
3460         if (drawADP&&(!mol->useShaders)) {
3461           mol->intern=0;
3462           mol->atoms(mol->showatoms,mol->proba);
3463         }
3464 
3465       }
3466 
3467       if (drawBo) {
3468         if (mol->bondColorStyle){
3469           qglColor(mol->bondColor);
3470           glDisable(GL_COLOR_MATERIAL);
3471         }
3472         mol->adp=(drawADP)?1:0;
3473         mol->tubes=(tubes)?1:0;
3474         glEnable(GL_CULL_FACE);
3475         glCullFace(GL_FRONT);
3476         mol->bonds(mol->showbonds);
3477         glDisable(GL_CULL_FACE);
3478         glCullFace(GL_BACK);
3479 
3480         glEnable(GL_COLOR_MATERIAL);
3481       }
3482     }//wireButt
3483   }glPopMatrix();
3484 
3485   if ((!habzutun)&&(!fVertexes[0].isEmpty()||!fVertexes[1].isEmpty())) {
3486       //printf("maps\n");
3487     double max;
3488     int Pers=0;
3489     if (niceTrans->isChecked()){
3490       double mm[16];
3491 
3492       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mm );
3493       max= (fabs(mm[2])>fabs(mm[6]))?mm[2]:mm[6];
3494       max=(fabs(max)<fabs(mm[10]))?mm[10]:max;
3495       if ((max==mm[2])&&(max>0.0)) Pers=0; else
3496         if ((max==mm[2])&&(max<0.0)) Pers=1; else
3497           if ((max==mm[6])&&(max>0.0)) Pers=2; else
3498             if ((max==mm[6])&&(max<0.0)) Pers=3; else
3499               if ((max==mm[10])&&(max>0.0)) Pers=4; else
3500                 if ((max==mm[10])&&(max<0.0)) Pers=5;
3501     }else Pers=0;
3502     glDisable(GL_CULL_FACE);
3503     if (fillMap->isChecked()) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3504     else glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
3505     if (lighting->isChecked())  glEnable(GL_LIGHTING);
3506     else glDisable(GL_LIGHTING);
3507     glEnable(GL_BLEND);
3508     glLineWidth(linwidth);
3509 
3510     glPushMatrix();
3511     glScaled( L, L, L);
3512     glEnableClientState(GL_VERTEX_ARRAY);
3513     glEnableClientState(GL_NORMAL_ARRAY);
3514     if (fofcact->isChecked()) {
3515       dipc.setAlphaF(lintrans);
3516       qglColor(dipc);
3517       glVertexPointer(3, GL_FLOAT, 0, fVertexes[0+4*Pers].data());
3518       glNormalPointer(GL_FLOAT, 0, fNormals[0+4*Pers].data());
3519       glDrawArrays(GL_TRIANGLES, 0, fVertexes[0+4*Pers].size()/3);
3520       dimc.setAlphaF(lintrans);
3521       qglColor(dimc);
3522       glVertexPointer(3, GL_FLOAT, 0, fVertexes[1+4*Pers].data());
3523       glNormalPointer(GL_FLOAT, 0, fNormals[1+4*Pers].data());
3524       glDrawArrays(GL_TRIANGLES, 0, fVertexes[1+4*Pers].size()/3);
3525     }
3526     if (foact->isChecked()) {
3527       fopc.setAlphaF(lintrans);
3528       qglColor(fopc);
3529       glVertexPointer(3, GL_FLOAT, 0, fVertexes[2+4*Pers].data());
3530       glNormalPointer(GL_FLOAT, 0, fNormals[2+4*Pers].data());
3531       glDrawArrays(GL_TRIANGLES, 0, fVertexes[2+4*Pers].size()/3);
3532       if (neutrons){
3533         fomc.setAlphaF(lintrans);
3534         qglColor(fomc);
3535         glVertexPointer(3, GL_FLOAT, 0, fVertexes[3+4*Pers].data());
3536         glNormalPointer(GL_FLOAT, 0, fNormals[3+4*Pers].data());
3537         glDrawArrays(GL_TRIANGLES, 0, fVertexes[3+4*Pers].size()/3);
3538       }
3539     }
3540     glDisableClientState(GL_VERTEX_ARRAY);
3541     glDisableClientState(GL_NORMAL_ARRAY);
3542     glPopMatrix();
3543 
3544     glEnable(GL_LIGHTING);
3545     glDisable(GL_BLEND);
3546     glEnable(GL_CULL_FACE);
3547     glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3548   }
3549 
3550   if (!mol->selectedatoms.isEmpty()){
3551     glPushMatrix();{
3552       glLineWidth(2);
3553       glScaled( L, L, L );
3554       mol->tubes=0;
3555       mol->intern=1;
3556       mol->adp=0;
3557       mol->dratom=1;
3558       mol->atoms(mol->selectedatoms);
3559       qglColor(labelColor);
3560       mol->dratom=0;
3561       glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3562       mol->intern=1;
3563       mol->tubes=0;
3564       mol->adp=1;
3565     }glPopMatrix();
3566   }
3567 
3568   if (!mol->fitbonds.isEmpty()){
3569     glPushMatrix();{
3570       glLineWidth(1);
3571       glScaled( L, L, L );
3572       mol->tubes=0;
3573       mol->intern=1;
3574       mol->adp=0;
3575       mol->dratom=76;
3576       mol->atoms(mol->fitatoms);
3577       mol->dbond(mol->fitbonds,76);
3578       qglColor(labelColor);
3579       mol->dratom=0;
3580       glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3581       mol->intern=1;
3582       mol->tubes=0;
3583       mol->adp=1;
3584     }glPopMatrix();
3585   }
3586   if (highlightParts->isChecked()){//PART highlighter
3587     glPushMatrix();{
3588       glScaled( L, L, L );
3589       mol->tubes=(tubes&&!drawADP)?1:0;
3590       mol->intern=0;
3591       mol->adp=(drawADP)?1:0;
3592       mol->dratom=2;
3593       mol->atoms(mol->showatoms);
3594       qglColor(labelColor);
3595     }glPopMatrix();
3596     glPushMatrix();{
3597       glDisable(GL_CULL_FACE);
3598       glScaled( L, L, L );
3599       mol->bonds(mol->showbonds);
3600       glEnable(GL_CULL_FACE);
3601     }glPopMatrix();
3602     mol->dratom=0;
3603     glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3604   }
3605   if (mol->duplicateAtoms.size()){//Duplicate highlighter
3606     glPushMatrix();{
3607       glScaled( L, L, L );
3608       mol->tubes=(tubes&&!drawADP)?1:0;
3609       mol->intern=0;
3610       mol->adp=(drawADP)?1:0;
3611       mol->dratom=2;
3612       mol->atoms(mol->duplicateAtoms);
3613 
3614       qglColor(QColor("springgreen"));
3615       glDisable(GL_DEPTH_TEST);
3616       if (stereo_mode!=1)
3617         for (int ii=0; ii<mol->duplicateAtoms.size();ii++)renderText(
3618             mol->duplicateAtoms.at(ii).pos.x,
3619             mol->duplicateAtoms.at(ii).pos.y,
3620             mol->duplicateAtoms.at(ii).pos.z,
3621             "="+mol->duplicateAtoms.at(ii).Label+"=",
3622             myFont);
3623 
3624       qglColor(labelColor);
3625     }glPopMatrix();
3626     mol->dratom=0;
3627     glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3628   }
3629   if ((imFokus>-1)&&(!drawLa)&&(imFokus<mol->showatoms.size()))
3630     if (!warLabel){
3631       CEnvironment fokat;
3632       fokat.append(mol->showatoms.at(imFokus));
3633       glPushMatrix();{
3634         glScaled( L, L, L );
3635         mol->tubes=0;
3636         mol->intern=1;
3637         mol->adp=0;
3638         mol->dratom=3;
3639         mol->atoms(fokat);
3640         qglColor(labelColor);
3641         mol->dratom=0;
3642         glDisable(GL_DEPTH_TEST);
3643         if ((stereo_mode!=1)&&(!useTextureLabels->isChecked()))renderText(
3644             fokat.at(0).pos.x,
3645             fokat.at(0).pos.y,
3646             fokat.at(0).pos.z,
3647             fokat.at(0).Label,
3648             myFont);
3649         glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
3650         glEnable(GL_DEPTH_TEST);
3651       }glPopMatrix();
3652       ///
3653       if (useTextureLabels->isChecked()){
3654         glPushMatrix();
3655         glScaled(L,L,L);
3656         if (!mol->showatoms.isEmpty()){
3657           if (mol->showatoms.size()!=labelTextures.size()) updateLabelTextures();
3658           glDisable(GL_CULL_FACE);
3659           glDisable(GL_DEPTH_TEST);
3660 
3661           glEnable(GL_BLEND);
3662           glEnable(GL_ALPHA_TEST);
3663 
3664           glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3665           glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3666           glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3667           glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3668           glEnable(GL_TEXTURE_2D);
3669 
3670           bool bigr=false;
3671           qglColor(labelColor);
3672           glPushMatrix();
3673           GLdouble mmm[16];
3674           GLuint t=bindTexture(labelTextures.at(imFokus),GL_TEXTURE_2D);
3675           double ratio=(double)labelTextures.at(imFokus).width()/labelTextures.at(imFokus).height();
3676           glTranslated(mol->showatoms.at(imFokus).pos.x,mol->showatoms.at(imFokus).pos.y,mol->showatoms.at(imFokus).pos.z);
3677           glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
3678           double ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
3679             - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
3680             + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
3681           ddd=pow(ddd,1.0/3.0);
3682           ddd*=(mol->showatoms.at(imFokus).an>=0)?1.0:0.75;
3683           ddd*=(bigr)?1.2:1.0;
3684           mmm[0]=ddd*labScal*ratio;
3685           mmm[5]=ddd*labScal;
3686           mmm[10]=ddd*labScal;
3687           mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
3688           glLoadMatrixd(mmm);
3689           mol->billBoard();
3690           glPopMatrix();
3691           deleteTexture(t);
3692         }
3693         glPopMatrix();
3694       }
3695       ///
3696 
3697     }
3698 
3699   if (enviPositions.size()){
3700     glPushMatrix();
3701     glDisable( GL_DEPTH_TEST );
3702     glEnable(GL_LINE_STIPPLE);
3703     glEnable(GL_BLEND);
3704     glLineWidth(2);
3705     glDisable(GL_LIGHTING);
3706     glLineStipple(3,21845);
3707 
3708     glScaled( L, L, L );
3709     glBegin(GL_LINES);
3710     for (int k=0;k<enviPositions.size();k++){
3711       if ((enviNoQ->isChecked())&&(labs.at(k).startsWith('Q',Qt::CaseInsensitive))) continue;
3712       switch(enviKat.at(k)){
3713         case 1: qglColor(mol->enviBondColor);break;
3714         case 2: qglColor(mol->enviHBColor);break;
3715         default:
3716                 qglColor(mol->enviDefaultColor);
3717       }
3718       //if ((Distance(enviP0,enviPositions.at(k)))<envirange*envirange)
3719       {
3720         glVertex3d(enviP0.x,enviP0.y,enviP0.z);
3721         glVertex3d(enviPositions.at(k).x,enviPositions.at(k).y,enviPositions.at(k).z);
3722       }
3723     }
3724     glEnd();
3725 
3726     glDisable(GL_CULL_FACE);
3727     glDisable(GL_DEPTH_TEST);
3728 
3729 
3730     glEnable(GL_BLEND);
3731     glEnable(GL_ALPHA_TEST);
3732 
3733     //glBindTexture(GL_TEXTURE_2D, t);
3734     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3735     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3736     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3737     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3738     glEnable(GL_TEXTURE_2D);
3739     for (int k=0;k<enviPositions.size();k++){
3740 
3741       if ((enviNoQ->isChecked())&&(labs.at(k).startsWith('Q',Qt::CaseInsensitive))) continue;
3742       if ((k+labs.size()) >= enviTextures.size()) continue;
3743       switch(enviKat.at(k)){
3744         case 1: qglColor(mol->enviBondColor);break;
3745         case 2: qglColor(mol->enviHBColor);break;
3746         default:
3747                 qglColor(mol->enviDefaultColor);
3748       }
3749       glPushMatrix();
3750       GLdouble mmm[16];
3751 
3752       GLuint t=bindTexture(enviTextures.at(k+labs.size()),GL_TEXTURE_2D);
3753       double ratio=(double)enviTextures.at(k+labs.size()).width()/enviTextures.at(k+labs.size()).height();
3754       glTranslated((enviPositions.at(k).x+enviP0.x)/2.0,
3755                    (enviPositions.at(k).y+enviP0.y)/2.0,
3756                    (enviPositions.at(k).z+enviP0.z)/2.0);
3757       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
3758       double ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
3759         - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
3760         + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
3761       ddd=pow(ddd,1.0/3.0);
3762       mmm[0]=ddd*labScal*ratio;
3763       mmm[5]=ddd*labScal;
3764       mmm[10]=ddd*labScal;
3765       mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
3766       /*
3767          printf("\n\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\n",mmm[0]
3768          ,mmm[1],mmm[2],mmm[3]
3769          ,mmm[4],mmm[5],mmm[6],mmm[7]
3770          ,mmm[8],mmm[9],mmm[10],mmm[11]
3771          ,mmm[12],mmm[13],mmm[14],mmm[15]
3772          );
3773       // */
3774       glLoadMatrixd(mmm);
3775       mol->billBoard();
3776       deleteTexture(t+labs.size());
3777       glPopMatrix();
3778       glPushMatrix();
3779       t=bindTexture(enviTextures.at(k),GL_TEXTURE_2D);
3780       ratio=(double)enviTextures.at(k).width()/enviTextures.at(k).height();
3781       glTranslated(enviPositions.at(k).x,
3782                    enviPositions.at(k).y,
3783                    enviPositions.at(k).z);
3784       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
3785       ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
3786         - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
3787         + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
3788       ddd=pow(ddd,1.0/3.0);
3789       mmm[0]=ddd*labScal*ratio;
3790       mmm[5]=ddd*labScal;
3791       mmm[10]=ddd*labScal;
3792       mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
3793       /*
3794          printf("\n\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\n",mmm[0]
3795          ,mmm[1],mmm[2],mmm[3]
3796          ,mmm[4],mmm[5],mmm[6],mmm[7]
3797          ,mmm[8],mmm[9],mmm[10],mmm[11]
3798          ,mmm[12],mmm[13],mmm[14],mmm[15]
3799          );
3800       // */
3801       glLoadMatrixd(mmm);
3802       mol->billBoard();
3803       glPopMatrix();
3804       deleteTexture(t);
3805       /*
3806       renderText((enviPositions.at(k).x+enviP0.x)/2.0,
3807           (enviPositions.at(k).y+enviP0.y)/2.0,
3808           (enviPositions.at(k).z+enviP0.z)/2.0,
3809           QString::number(sqrt(Distance(enviP0,enviPositions.at(k))),'f',3)+"Å",nonAtomFont);
3810       renderText(enviPositions.at(k).x,
3811           enviPositions.at(k).y,
3812           enviPositions.at(k).z,
3813           labs.at(k),nonAtomFont);
3814           */
3815     }
3816     glDisable(GL_LINE_STIPPLE);
3817     glEnable(GL_LIGHTING);
3818     glEnable( GL_DEPTH_TEST );
3819     glPopMatrix();
3820   }
3821   if (drawUc) {
3822     glPushMatrix();
3823     glScaled( L, L, L );
3824     mol->unitCell();
3825     glPopMatrix();
3826   }
3827   if ((!useTextureLabels->isChecked())&&(drawLa)&&(!moving->isActive())&&drawUc) {
3828     glClear( GL_DEPTH_BUFFER_BIT);
3829     V3 uz0f,uz1f,uz2f,uz3f;
3830     V3 uz0k,uz1k,uz2k,uz3k;
3831     uz0f.x=0.0;  uz0f.y=0.0;  uz0f.z=0.0;
3832     uz1f.x=1.0;  uz1f.y=0.0;  uz1f.z=0.0;
3833     uz2f.x=0.0;  uz2f.y=1.0;  uz2f.z=0.0;
3834     uz3f.x=0.0;  uz3f.y=0.0;  uz3f.z=1.0;
3835     mol->frac2kart(uz0f,uz0k);
3836     mol->frac2kart(uz1f,uz1k);
3837     mol->frac2kart(uz2f,uz2k);
3838     mol->frac2kart(uz3f,uz3k);
3839     glPushMatrix();{
3840       glScaled(L,L,L);{
3841         qglColor(labelColor);
3842 
3843         renderText(uz0k.x,uz0k.y,uz0k.z,"0",myFont);
3844         glColor4f(1.0f,0.0f,0.0f,1.0);
3845         renderText(uz1k.x,uz1k.y,uz1k.z,"a",myFont);
3846 
3847         glColor4f(0.0f,1.0f,0.0f,1.0);
3848         renderText(uz2k.x,uz2k.y,uz2k.z,"b",myFont);
3849 
3850         glColor4f(0.0f,0.0f,1.0f,1.0);
3851         renderText(uz3k.x,uz3k.y,uz3k.z,"c",myFont);
3852       }glPopMatrix();
3853     }
3854   }
3855   if ((useTextureLabels->isChecked())&&(drawLa)){
3856     glPushMatrix();
3857     glScaled(L,L,L);
3858     if (!mol->showatoms.isEmpty()){
3859       if (mol->showatoms.size()!=labelTextures.size()) updateLabelTextures();
3860       glDisable(GL_CULL_FACE);
3861       glDisable(GL_DEPTH_TEST);
3862 
3863 
3864       glEnable(GL_BLEND);
3865       glEnable(GL_ALPHA_TEST);
3866 
3867       //glBindTexture(GL_TEXTURE_2D, t);
3868       glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3869       glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3870       glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3871       glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3872       glEnable(GL_TEXTURE_2D);
3873       for (int li=0; li<mol->showatoms.size();li++){
3874         if (mol->showatoms.at(li).hidden) continue;
3875         if ((mol->nopm1)&&(mol->showatoms.at(li).symmGroup)&&(mol->showatoms.at(li).part<-0)) continue;
3876         if ((mol->AtomStyle[mol->showatoms.at(li).an]&ATOM_STYLE_NOLABEL)&&(imFokus!=li)) continue;
3877         if ((!mol->beloLabels)&&(mol->showatoms.at(li).an==-42)) continue;
3878         bool bigr=false;
3879         qglColor(labelColor);
3880         for (int si=0; si<mol->selectedatoms.size(); si++){
3881           if (li==mol->selectedatoms.at(si).style) {qglColor(QColor("#3388FF"));bigr=true;}
3882         }
3883         if (imFokus==li) {bigr=true;qglColor(QColor("#FF9900"));}
3884         glPushMatrix();
3885         GLdouble mmm[16];
3886         GLuint t=bindTexture(labelTextures.at(li),GL_TEXTURE_2D);
3887         double ratio=(double)labelTextures.at(li).width()/labelTextures.at(li).height();
3888         glTranslated(mol->showatoms.at(li).pos.x,mol->showatoms.at(li).pos.y,mol->showatoms.at(li).pos.z);
3889         glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
3890         double ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
3891           - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
3892           + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
3893         ddd=pow(ddd,1.0/3.0);
3894         ddd*=(mol->showatoms.at(li).an>=0)?1.0:0.75;
3895         ddd*=(bigr)?1.2:1.0;
3896         mmm[0]=ddd*labScal*ratio;
3897         mmm[5]=ddd*labScal;
3898         mmm[10]=ddd*labScal;
3899         mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
3900         /*
3901            printf("\n\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\n",mmm[0]
3902            ,mmm[1],mmm[2],mmm[3]
3903            ,mmm[4],mmm[5],mmm[6],mmm[7]
3904            ,mmm[8],mmm[9],mmm[10],mmm[11]
3905            ,mmm[12],mmm[13],mmm[14],mmm[15]
3906            );
3907         // */
3908         glLoadMatrixd(mmm);
3909         mol->billBoard();
3910         glPopMatrix();
3911         deleteTexture(t);
3912       }
3913       if (drawUc){
3914         V3 uz0f,uz1f,uz2f,uz3f;
3915         V3 uz0k,uz1k,uz2k,uz3k;
3916         uz0f.x=0.0;  uz0f.y=0.0;  uz0f.z=0.0;
3917         uz1f.x=1.0;  uz1f.y=0.0;  uz1f.z=0.0;
3918         uz2f.x=0.0;  uz2f.y=1.0;  uz2f.z=0.0;
3919         uz3f.x=0.0;  uz3f.y=0.0;  uz3f.z=1.0;
3920         mol->frac2kart(uz0f,uz0k);
3921         mol->frac2kart(uz1f,uz1k);
3922         mol->frac2kart(uz2f,uz2k);
3923         mol->frac2kart(uz3f,uz3k);
3924         for (int li=0; li<4; li++){
3925           glPushMatrix();
3926           GLdouble mmm[16];
3927           GLuint t=bindTexture(extraTextures.at(li),GL_TEXTURE_2D);
3928           double ratio=(double)extraTextures.at(li).width()/extraTextures.at(li).height();
3929           switch (li){
3930             case 0:
3931               qglColor(labelColor);
3932               glTranslated(uz0k.x,uz0k.y,uz0k.z);
3933               break;
3934             case 1:
3935               glColor4f(1.0f,0.0f,0.0f,1.0);
3936               glTranslated(uz1k.x,uz1k.y,uz1k.z);
3937               break;
3938             case 2:
3939               glColor4f(0.0f,1.0f,0.0f,1.0);
3940               glTranslated(uz2k.x,uz2k.y,uz2k.z);
3941               break;
3942             case 3:
3943               glColor4f(0.0f,0.0f,1.0f,1.0);
3944               glTranslated(uz3k.x,uz3k.y,uz3k.z);
3945               break;
3946           }
3947           glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
3948           double ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
3949             - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
3950             + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
3951           ddd=pow(ddd,1.0/3.0);
3952           mmm[0]=ddd*labScal*ratio;
3953           mmm[5]=ddd*labScal;
3954           mmm[10]=ddd*labScal;
3955           mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
3956           /*
3957              printf("\n\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\nd%f %f %f %f\n",mmm[0]
3958              ,mmm[1],mmm[2],mmm[3]
3959              ,mmm[4],mmm[5],mmm[6],mmm[7]
3960              ,mmm[8],mmm[9],mmm[10],mmm[11]
3961              ,mmm[12],mmm[13],mmm[14],mmm[15]
3962              );
3963           // */
3964           glLoadMatrixd(mmm);
3965           mol->billBoard();
3966           glPopMatrix();
3967           deleteTexture(t);
3968         }
3969       }
3970       glDisable(GL_TEXTURE_2D);
3971       glEnable(GL_BLEND);
3972       glDisable(GL_ALPHA_TEST);
3973       glEnable(GL_DEPTH_TEST);
3974     }
3975     glPopMatrix();
3976   }
3977   if ((!useTextureLabels->isChecked())&&(drawLa)&&(!moving->isActive())) {
3978 
3979 
3980     glClear( GL_DEPTH_BUFFER_BIT);
3981     glPushMatrix();{
3982       glScaled(L,L,L);
3983       GLdouble model[16];
3984       GLdouble proj[16];
3985       GLint viewport[4];
3986       glGetIntegerv(GL_VIEWPORT, viewport);
3987      // printf("%d %d %d %d\n",viewport[0],viewport[1],viewport[2],viewport[3]);
3988       glGetDoublev( GL_PROJECTION_MATRIX , (double*)proj );
3989       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)model );
3990       {
3991         for (int j=0;j<mol->showatoms.size();j++){
3992           if ((!mol->beloLabels)&&(mol->showatoms.at(j).an==-42)) continue;
3993           if (mol->showatoms.at(j).hidden) continue;
3994           if ((mol->nopm1)&&(mol->showatoms.at(j).symmGroup)&&(mol->showatoms.at(j).part<-0)) continue;
3995           if (imFokus==j) qglColor(QColor("#FFAA00")); else {
3996             if ((mol->highlightEquivalents)&&(mol->showatoms.at(j).symmGroup)) {
3997               if ((backGroundColor.saturation()>128)&&(abs(backGroundColor.hue()-240)<30)) qglColor(Qt::lightGray);
3998               else {
3999                 if (backGroundColor.value()<128) qglColor(QColor(Qt::blue).lighter(150));
4000                 else qglColor(Qt::darkBlue);
4001               }
4002             }
4003             else qglColor(labelColor);
4004           }
4005           //{1.0,0.0,-1.0,-190},
4006           GLdouble in[4], out[4];
4007 
4008           in[0] = mol->showatoms.at(j).pos.x;
4009           in[1] = mol->showatoms.at(j).pos.y;
4010           in[2] = mol->showatoms.at(j).pos.z;
4011           in[3] = 1.0;
4012           transform_point(out, model, in);
4013           posTo2D(mol->showatoms.at(j).pos,model,proj,vp, &mol->showatoms[j].screenX, &mol->showatoms[j].screenY,retinafktr);
4014           int xminus = fmtr.boundingRect(mol->showatoms.at(j).Label).width();
4015           int x2minus = fmtr2.boundingRect(mol->showatoms.at(j).Label).width();
4016           int yminus = fmtr.boundingRect(mol->showatoms.at(j).Label).height();
4017           int y2minus = fmtr2.boundingRect(mol->showatoms.at(j).Label).height();
4018           int displace=10;
4019           int displace2=displace/2;
4020           if (exporting){
4021             double mult= (double)ww/width();
4022             displace*=mult;
4023             displace2*=mult;
4024             labz ll;
4025             ll.x=(mol->showatoms[j].screenX<ww/2)?
4026               mol->showatoms[j].screenX-(xminus+displace):
4027               mol->showatoms[j].screenX+displace;
4028             ll.y=(mol->showatoms[j].screenY<wh/2)?
4029               mol->showatoms[j].screenY-displace2:
4030               mol->showatoms[j].screenY+yminus;
4031             ll.l=mol->showatoms.at(j).Label;
4032             ll.an=mol->showatoms.at(j).an;
4033             LabelZ.append(ll);
4034           }
4035           else{
4036             if (imFokus==j) {
4037               renderText(
4038                   (mol->showatoms[j].screenX<ww/2)?
4039                   mol->showatoms[j].screenX-(xminus+displace):
4040                   mol->showatoms[j].screenX+displace,
4041                   (mol->showatoms[j].screenY<wh/2)?
4042                   mol->showatoms[j].screenY-displace2:
4043                   mol->showatoms[j].screenY+yminus,
4044                   mol->showatoms.at(j).Label,
4045                   //nonAtomFont);
4046                 myFont);
4047               continue;
4048 
4049             }else {
4050               if ((mol->showatoms.at(j).an<0)) renderText(//(mol->selectedatoms.isEmpty())&&
4051                   (mol->showatoms[j].screenX<ww/2)?
4052                   mol->showatoms[j].screenX-(x2minus+displace):
4053                   mol->showatoms[j].screenX+displace,
4054                   (mol->showatoms[j].screenY<wh/2)?
4055                   mol->showatoms[j].screenY-displace2:
4056                   mol->showatoms[j].screenY+y2minus,
4057                   mol->showatoms.at(j).Label,
4058                   nonAtomFont);
4059               else
4060                 if ((!(mol->AtomStyle[mol->showatoms.at(j).an]&ATOM_STYLE_NOLABEL)))//(mol->selectedatoms.isEmpty())&&
4061                   renderText(
4062                       (mol->showatoms[j].screenX<ww/2)?
4063                       mol->showatoms[j].screenX-(((mol->selectedatoms.isEmpty())?xminus:x2minus)+displace):
4064                       mol->showatoms[j].screenX+displace,
4065                       (mol->showatoms[j].screenY<wh/2)?
4066                       mol->showatoms[j].screenY-displace2:
4067                       mol->showatoms[j].screenY+((mol->selectedatoms.isEmpty())?yminus:y2minus),
4068                       mol->showatoms.at(j).Label,
4069                       (mol->selectedatoms.isEmpty())?myFont:nonAtomFont);
4070             }
4071           }
4072         }
4073       }
4074       if (!exporting)for (int j=0;j<mol->selectedatoms.size();j++){
4075         int xminus = fmtr.boundingRect(mol->selectedatoms.at(j).Label).width();
4076         int yminus = fmtr.boundingRect(mol->selectedatoms.at(j).Label).height();
4077         int displace=10;
4078         int displace2=displace/2;
4079         GLdouble in[4], out[4];
4080         in[0] = mol->selectedatoms.at(j).pos.x;
4081         in[1] = mol->selectedatoms.at(j).pos.y;
4082         in[2] = mol->selectedatoms.at(j).pos.z;
4083         in[3] = 1.0;
4084         transform_point(out, model, in);
4085         posTo2D(mol->selectedatoms.at(j).pos,model,proj,viewport, &mol->selectedatoms[j].screenX, &mol->selectedatoms[j].screenY,retinafktr);
4086         //          int x2minus = fmtr2.boundingRect(mol->selectedatoms.at(j).Label).width();
4087         //          int y2minus = fmtr2.boundingRect(mol->selectedatoms.at(j).Label).height();
4088         qglColor(Qt::yellow);
4089 
4090         renderText(
4091             (mol->selectedatoms[j].screenX<ww/2)?
4092             mol->selectedatoms[j].screenX-((xminus)+displace):
4093             mol->selectedatoms[j].screenX+displace,
4094             (mol->selectedatoms[j].screenY<wh/2)?
4095             mol->selectedatoms[j].screenY-displace2:
4096             mol->selectedatoms[j].screenY+(yminus),
4097             mol->selectedatoms.at(j).Label,
4098             myFont);
4099       }
4100     }glPopMatrix();
4101   }
4102   {
4103     glPushMatrix();
4104     glScaled(L,L,L);{
4105       GLdouble model[16];
4106       GLdouble proj[16];
4107       GLint viewport[4];
4108       glGetIntegerv(GL_VIEWPORT, viewport);
4109       glGetDoublev( GL_PROJECTION_MATRIX , (double*)proj );
4110       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)model );
4111       for (int j=0;j<mol->showatoms.size();j++){
4112         {mol->showatoms[j].screenX=-200; mol->showatoms[j].screenY=-200;}
4113         if (mol->showatoms.at(j).hidden) continue;
4114         //{1.0,0.0,-1.0,-190},
4115         GLdouble in[4], out[4];
4116 
4117         in[0] = mol->showatoms.at(j).pos.x;
4118         in[1] = mol->showatoms.at(j).pos.y;
4119         in[2] = mol->showatoms.at(j).pos.z;
4120         in[3] = 1.0;
4121         transform_point(out, model, in);
4122 
4123         if ((mol->nopm1)&&(mol->showatoms.at(j).symmGroup)&&(mol->showatoms.at(j).part<-0)) continue;
4124         if (!posTo2D(mol->showatoms.at(j).pos,model,proj,viewport, &mol->showatoms[j].screenX, &mol->showatoms[j].screenY,retinafktr))
4125         {mol->showatoms[j].screenX=-200; mol->showatoms[j].screenY=-200;}
4126       }
4127     }
4128     glPopMatrix();
4129   }
4130   glPopMatrix();
4131 
4132   V3 auge=V3(0,0,206);
4133   if (mol->vorobas){
4134       glPushMatrix();
4135       glDisable(GL_CULL_FACE);
4136       glEnable(GL_DEPTH_TEST);
4137       glEnable(GL_BLEND);
4138       glEnable(GL_ALPHA_TEST);
4139 
4140       glEnable( GL_LIGHTING );
4141       glTranslateL(-L*ori.x,-L*ori.y,-L*ori.z);
4142       glScaled( L, L, L );
4143 
4144       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
4145       Matrix mvm=Matrix(gmat[0],gmat[1],gmat[2], gmat[4],gmat[5],gmat[6], gmat[8],gmat[9],gmat[10]);
4146       auge=mvm*auge;
4147       mol->drawVoronoi(auge);
4148       glPopMatrix();
4149       glLineWidth(linwidth);
4150       glDisable( GL_LIGHTING );
4151   }
4152   if (mol->ptriangles.size()||mol->axvecs.size()||mol->invvecs.size()){
4153     glPushMatrix();
4154     glDisable(GL_CULL_FACE);
4155     glEnable(GL_DEPTH_TEST);
4156     glEnable(GL_BLEND);
4157     glEnable(GL_ALPHA_TEST);
4158 
4159     glEnable( GL_LIGHTING );
4160     glTranslateL(-L*ori.x,-L*ori.y,-L*ori.z);
4161     glScaled( L, L, L );
4162 
4163     glGetDoublev( GL_MODELVIEW_MATRIX, (double*)gmat );
4164     Matrix mvm=Matrix(gmat[0],gmat[1],gmat[2], gmat[4],gmat[5],gmat[6], gmat[8],gmat[9],gmat[10]);
4165     auge=mvm*auge;
4166     mol->drawAxses();
4167     mol->drawInversionCenters();
4168     mol->drawPlanes();
4169     glPopMatrix();
4170     glLineWidth(linwidth);
4171     glDisable( GL_LIGHTING );
4172   }
4173     if (!cont.isEmpty()){
4174       glPushMatrix();{
4175         glTranslateL(-L*ori.x,-L*ori.y,-L*ori.z);
4176         glScaled( L, L, L );
4177         glDisable( GL_LIGHTING );
4178         glEnable( GL_DEPTH_TEST );
4179         glLineWidth(2.5f);
4180 
4181         glBegin(GL_LINES);
4182         for (int ci=0;ci<cont.size();ci++){
4183           if (contval.contains(ci)) {
4184               if (rainbowPlot->isChecked()) farbverlauf(contval.value(ci),contMin,contMax);
4185               else{
4186                   if (contval.value(ci)>0.0001f) {
4187                       glColor4d(0.0,0.0,1.0,1.0);
4188                   } else if (contval.value(ci)<-0.0001f){
4189                       glColor4d(1.0,0.0,0.0,1.0);
4190                   } else {
4191                       glColor4d(0.0,0.0,0.0,1.0);
4192                   }
4193               }
4194           }
4195           glVertex3d(cont.at(ci).x,cont.at(ci).y,cont.at(ci).z);
4196         }
4197         glEnd();
4198         glEnable( GL_LIGHTING );
4199         //glEnable( GL_DEPTH_TEST );
4200       }glPopMatrix();
4201       glLineWidth(0.7f);
4202     }
4203 
4204   if (atomLegend->isChecked()){
4205       glDisable(GL_FOG);
4206       mol->mist=false;
4207       for (int ali=0,alj=0; ali<mol->legendAtoms.size(); ali++){
4208           mol->legendAtoms[ali].pos.y=-6.8+alj*0.5;
4209           if (mol->legendAtoms.at(ali).hidden) continue;
4210           alj++;
4211       }
4212     glPushMatrix();{
4213       GLsizei  lw=415;
4214       GLsizei  lh=950;
4215       //printf("legend %d %d\n",lw,lh);
4216       glViewport(0, 0, lw, lh);
4217       double mat[16],mleg[16];
4218       glEnable(GL_BLEND);
4219       glEnable(GL_COLOR_MATERIAL);
4220       glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mat );
4221       for (int i=0; i<16; i++) mleg[i]=mat[i];
4222       mleg[0]=mleg[5]=mleg[10]=1.0;
4223       mleg[1]=mleg[2]=mleg[4]=mleg[6]=mleg[8]=mleg[9]=0.0;
4224       mleg[12]=mleg[13]=0;
4225       glLoadMatrixd(mleg);
4226       glPushMatrix();{
4227         glMatrixMode(GL_PROJECTION);
4228         glLoadIdentity();
4229         gluPerspective_( .1, (double)lw/lh, 5.0, 8000.0 );
4230         glMatrixMode(GL_MODELVIEW);
4231         glPushMatrix();{
4232           glDisable( GL_DEPTH_TEST );
4233           glScaled(.025,.025,.025);
4234           mol->tubes=0;
4235           mol->dratom=0;
4236           mol->intern=1;
4237           mol->adp=(drawADP)?1:0;
4238           glEnable(GL_CULL_FACE);
4239           mol->atoms(mol->legendAtoms,50,0.5);
4240           if (true){
4241             //printf("labScal=%f\n",labScal);
4242             //printf("ratio %f %f lw=%f %d\n",(double)ww/wh,lw/wh,lw,wh);
4243             double labScal_=0.35;
4244             if (mol->legendAtoms.size()+4!=extraTextures.size()) updateLabelTextures();
4245             glDisable(GL_CULL_FACE);
4246             glDisable(GL_DEPTH_TEST);
4247             glEnable(GL_BLEND);
4248             glEnable(GL_ALPHA_TEST);
4249             //glBindTexture(GL_TEXTURE_2D, t);
4250             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4251             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4252             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4253             glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4254             glEnable(GL_TEXTURE_2D);
4255             for (int li=0; li<mol->legendAtoms.size();li++){
4256               if (mol->legendAtoms.at(li).hidden) continue;
4257               if ((mol->legendAtoms.at(li).an==-1)&&(mol->noQPeaksPlease)) continue;
4258               qglColor(labelColor);
4259               glPushMatrix();{
4260                 GLdouble mmm[16];
4261                 GLuint t=bindTexture(extraTextures.at(li+4),GL_TEXTURE_2D);
4262                 //printf("t=%d %d %d\n",t,extraTextures.size(),mol->legendAtoms.size());
4263                 double ratio=(double)extraTextures.at(li+4).width()/extraTextures.at(li+4).height();
4264                 glTranslated(mol->legendAtoms.at(li).pos.x,mol->legendAtoms.at(li).pos.y-0.2,mol->legendAtoms.at(li).pos.z);
4265                 glGetDoublev( GL_MODELVIEW_MATRIX, (double*)mmm);
4266                 double ddd = mmm[0] * (mmm[5] * mmm[10] - mmm[9] * mmm[6])
4267                   - mmm[1] * (mmm[4] * mmm[10] - mmm[8] * mmm[6])
4268                   + mmm[2] * (mmm[4] *  mmm[9] - mmm[8] * mmm[5]);
4269                 ddd=pow(ddd,1.0/3.0);
4270                 ddd*=(mol->legendAtoms.at(li).an>=0)?1.0:0.75;
4271                 mmm[0]= ddd * labScal_ * ratio;
4272                 mmm[5]= ddd * labScal_;
4273                 mmm[10]=ddd * labScal_;
4274                 mmm[1]=mmm[2]=mmm[4]=mmm[6]=mmm[8]=mmm[9]=0.0;
4275                 glLoadMatrixd(mmm);
4276                 mol->billBoard();
4277                 deleteTexture(t);
4278                 glPopMatrix();}
4279             }
4280             glDisable(GL_TEXTURE_2D);
4281             glEnable(GL_BLEND);
4282             glDisable(GL_ALPHA_TEST);
4283             glEnable(GL_DEPTH_TEST);
4284 
4285           }
4286           glPopMatrix();}
4287         glEnable( GL_DEPTH_TEST );
4288         glPopMatrix();}
4289       glMatrixMode(GL_PROJECTION);
4290       glLoadIdentity();
4291       gluPerspective_( viewAngle, (double)ww/wh, 5.0, 8000.0 );
4292       glMatrixMode(GL_MODELVIEW);
4293       glViewport(0, 0, ww, wh);
4294       glLoadMatrixd(mat);
4295       glPopMatrix();}
4296     /*for (int i=0;i< mol->legendAtoms.size(); i++) {
4297       if (mol->legendAtoms.at(i).hidden) continue;
4298       qglColor(labelColor);
4299       renderText(//965
4300       ww*0.045,
4301       wh-5-i*wh/29,
4302     //      mol->legendAtoms.at(i).pos.z,
4303     mol->legendAtoms.at(i).Label,
4304     myFont);
4305     }*/
4306   }///*
4307   mol->mist=depthcueing;
4308   // */
4309   afok=imFokus;
4310   //printf("draw %d objs%d\n",__LINE__,objCnt);
4311 }
4312