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 Å</td></tr><tr><td><b>%1--%2--%3</b></td><td "
629 "align=\"right\">%6°</td></tr><tr><td><b>%1--%2--%3--%4 </b></td><td "
630 "align=\"right\">%7°</td></tr><tr><td><b>%1</b> Peak Height: </td><td "
631 "align=\"right\">%8 eÅ<sup>-3</sup></td><td>[%9…%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 Å</td></tr><tr><td><b>%1--%2--%3</b></td><td "
650 "align=\"right\">%6°</td></tr><tr><td><b>%1--%2--%3--%4 </b></td><td "
651 "align=\"right\">%7°</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 Å</td><td> DMSDA: %13 Å<sup>2</sup></td></tr>"
670 "<tr><td><b>%1--%2--%3</b></td><td align=\"right\">%6°</td><td> 1,3 Distance( DANG) %14 Å</td></tr><tr><td>"
671 "<b>%1--%2--%3--%4 </b></td><td align=\"right\">%7°</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 Å</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°</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