1 
2 /****************************************************************************
3  **
4  ** Copyright (C) 2011 Christian B. Huebschle & George M. Sheldrick
5  ** All rights reserved.
6  ** Contact: chuebsch@moliso.de
7  **
8  ** This file is part of the ShelXle
9  **
10  ** This file may be used under the terms of the GNU Lesser
11  ** General Public License version 2.1 as published by the Free Software
12  ** Foundation and appearing in the file COPYING included in the
13  ** packaging of this file.  Please review the following information to
14  ** ensure the GNU Lesser General Public License version 2.1 requirements
15  ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16  **
17  **
18  ****************************************************************************/
19 #ifndef MOLECULE_H
20 #define MOLECULE_H 1
21 #include <math.h>
22 #ifndef fmin
23 #define fmin(x, y) (((x) < (y)) ? (x) : (y))
24 #endif
25 #ifndef fmax
26 #define fmax(x, y) (((x) > (y)) ? (x) : (y))
27 #endif
28 #if defined _MSC_VER &&  _MSC_VER == 1500
29 #ifndef round
30 #define round(x) (x<0?ceil((x)-0.5):floor((x)+0.5))
31 #endif
32 #endif
33 #include <QString>
34 #include <QStringList>
35 #include <QList>
36 #include <QtOpenGL>
37 #include <QGLShaderProgram>
38 //#if defined (Q_WS_MAC) || defined(Q_OS_MAC)
39 //#include <OpenGL/glu.h>
40 // //#include <glu.h>
41 //#else
42 //#include <GL/glu.h>
43 //#endif
44 #include "glureplace.h"
45 #include <QtCore>
46 #ifndef M_PI
47 #define	M_PI		3.14159265358979323846
48 #endif
49 #ifndef M_PIf
50 #define	M_PIf		3.14159265358979323846f
51 #endif
52 #define ATOM_STYLE_WALLS 1
53 #define ATOM_STYLE_RINGS 2
54 #define ATOM_STYLE_SPHERE 4
55 #define ATOM_STYLE_SOLID 8
56 #define ATOM_STYLE_WHITERING 16
57 #define ATOM_STYLE_NOLABEL 32
58 #define ATOM_STYLE_NOADP 64
59 #define ATOM_STYLE_PLAID 128
60 #define ATOM_STYLE_METAL 256
61 #include <QSettings>
62 #ifndef GLAPIENTRY
63 #if defined(_MSC_VER) || defined(__MINGW32__)
64 #define GLAPIENTRY __stdcall
65 #else
66 #define GLAPIENTRY
67 #endif
68 #endif
69 
70 #ifndef GLAPIENTRYP
71 #define GLAPIENTRYP GLAPIENTRY *
72 #endif
73 
74 typedef void (GLAPIENTRYP GLU_func_ptr)(void);
75 //GLOBAL SETTINGS
76 //static int global_zero_counter=0;
77 //! V3 is a three dimensional vector in cartesian space
78 struct V3 {
79   double x//! x is the X coordinate
80     ,y//! y is the Y coordinate
81     ,z//! z is the Z coordinate
82     ;
83   //  int rc;
V3V384   inline V3( void ){}
V3V385   inline V3( const double& _x, const double& _y, const double& _z ) :
86     x(_x), y(_y), z(_z)//!< initializer
87     //,rc(0)
88   {
89     ;
90   }
91   inline V3& operator *= ( const double& d ){
92     x *= d;
93     y *= d;
94     z *= d;
95     return *this;
96   }//!< The *= operator to scale by a scalar
97   inline V3& operator += ( const V3& v ){
98     x += v.x;
99     y += v.y;
100     z += v.z;
101     return *this;
102   }//!< The += operator to add a V3
103   inline V3& operator += ( const double& v ){
104     x += v;
105     y += v;
106     z += v;
107     return *this;
108   }//!< The += operator to add a scalar
109 };
110 inline V3 operator + ( const V3& v1, const V3& v2 ) {
111   V3 t;
112   t.x = v1.x + v2.x;
113   t.y = v1.y + v2.y;
114   t.z = v1.z + v2.z;
115   return t;
116 }//!< The + operator to add two V3
117 inline V3 operator - ( const V3& v1, const V3& v2 ) {
118   V3 t;
119   t.x = v1.x - v2.x;
120   t.y = v1.y - v2.y;
121   t.z = v1.z - v2.z;
122   return t;
123 }//!< The + operator to subtract two V3
124 inline V3 operator * ( const V3& v, const double& d ) {
125   V3 t;
126   t.x = v.x*d;
127   t.y = v.y*d;
128   t.z = v.z*d;
129   return t;
130 }//!< The * to scale a V3
131 inline V3 operator * ( const double& d, const V3& v ) {
132   V3 t;
133   t.x = v.x*d;
134   t.y = v.y*d;
135   t.z = v.z*d;
136   return t;
137 }//!< The * to scale a V3
138 inline V3 operator % ( const V3& v1, const V3& v2 ) {
139   V3 t;
140   t.x = v1.y*v2.z - v2.y*v1.z;
141   t.y = v1.z*v2.x - v2.z*v1.x;
142   t.z = v1.x*v2.y - v2.x*v1.y;
143   return t;
144 }//!< The % operator the cross product of two V3
145 inline double operator * ( const V3& v1, const V3& v2 ) {
146   return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
147 }//!< The * operator the scalar product of two V3
Norm(const V3 & v)148 inline double Norm( const V3& v ) {
149   return v.x*v.x + v.y*v.y + v.z*v.z;
150 }//!< The squared lenght of a V3
Distance(const V3 & v1,const V3 & v2)151 inline double Distance( const V3& v1, const V3& v2 ) {
152   return Norm(v1 - v2);
153 }//!< The squared distance between two V3
154 inline bool operator == (const V3& v1, const V3& v2 ) {
155   //  return ((v1.x==v2.x)&&(v1.y==v2.y)&&(v1.z==v2.z));
156   return (Distance(v1,v2)<0.005);
157 }
Normalize(V3 v)158 inline V3& Normalize( V3 v ) {
159   static V3 erg=V3(1,0,0);
160   if (Norm(v))  erg= (v * (1.0/sqrt(Norm(v))));
161   return erg;
162 }
163 //! Matrix is a 3 x 3 Matrix with all needed operators
164 struct Matrix{
165   double m11, m21, m31, m12, m22, m32, m13, m23, m33;
MatrixMatrix166   inline Matrix(void){}
MatrixMatrix167   inline Matrix( const V3 &a, const V3 &b, const V3 &c):
168     m11(a.x), m21(b.x), m31(c.x),
169     m12(a.y), m22(b.y), m32(c.y),
170     m13(a.z), m23(b.z), m33(c.z){;}
MatrixMatrix171   inline Matrix( const double& x11, const double& x21, const double& x31,
172       const double& x12, const double& x22, const double& x32,
173       const double& x13, const double& x23, const double& x33):
174     m11(x11), m21(x21), m31(x31),
175     m12(x12), m22(x22), m32(x32),
176     m13(x13), m23(x23), m33(x33){;}
177 
178 };
transponse(Matrix a)179 inline Matrix transponse (Matrix a){//transponse
180   return Matrix(
181       a.m11, a.m12, a.m13,
182       a.m21, a.m22, a.m23,
183       a.m31, a.m32, a.m33);
184 }
determinant(Matrix a)185 inline double determinant (Matrix a){
186   return a.m11*a.m22*a.m33 - a.m11*a.m23*a.m32 - a.m12*a.m21*a.m33 + a.m12*a.m23*a.m31 +a.m13*a.m21*a.m32 -a.m13*a.m22*a.m31;
187 }
inverse(Matrix A)188 inline Matrix inverse (Matrix A){
189   double D = determinant(A);
190   if (D==0) return A;
191   D=1.0/D;
192   return Matrix(
193       D*(A.m22*A.m33-A.m23*A.m32),//x11
194       D*(A.m13*A.m32-A.m12*A.m33),//x21
195       D*(A.m21*A.m23-A.m13*A.m22),//x31
196       D*(A.m23*A.m31-A.m21*A.m33),//x12
197       D*(A.m11*A.m33-A.m13*A.m31),//x22
198       D*(A.m13*A.m21-A.m11*A.m23),//x32
199       D*(A.m21*A.m32-A.m22*A.m31),//x13
200       D*(A.m12*A.m31-A.m11*A.m32),//x23
201       D*(A.m11*A.m22-A.m12*A.m21)//x33
202       );
203 }
204 inline bool operator == (const Matrix &a,const Matrix &b){
205   return ((a.m11 == b.m11)&&(a.m21 == b.m21)&&(a.m31 == b.m31)&&
206       (a.m12 == b.m12)&&(a.m22 == b.m22)&&(a.m23 == b.m23)&&
207       (a.m13 == b.m13)&&(a.m32 == b.m32)&&(a.m33 == b.m33));
208 }
209 inline Matrix operator * (const Matrix &a,const Matrix &b){
210   Matrix erg;
211   erg.m11 = a.m11 * b.m11 + a.m21 * b.m12 + a.m31 * b.m13;
212   erg.m21 = a.m11 * b.m21 + a.m21 * b.m22 + a.m31 * b.m23;
213   erg.m31 = a.m11 * b.m31 + a.m21 * b.m32 + a.m31 * b.m33;
214 
215   erg.m12 = a.m12 * b.m11 + a.m22 * b.m12 + a.m32 * b.m13;
216   erg.m22 = a.m12 * b.m21 + a.m22 * b.m22 + a.m32 * b.m23;
217   erg.m32 = a.m12 * b.m31 + a.m22 * b.m32 + a.m32 * b.m33;
218 
219   erg.m13 = a.m13 * b.m11 + a.m23 * b.m12 + a.m33 * b.m13;
220   erg.m23 = a.m13 * b.m21 + a.m23 * b.m22 + a.m33 * b.m23;
221   erg.m33 = a.m13 * b.m31 + a.m23 * b.m32 + a.m33 * b.m33;
222   return erg;
223 }
224 inline V3 operator * (const Matrix &a, const V3 &b){
225   V3 erg;
226   erg.x = a.m11*b.x + a.m21*b.y + a.m31*b.z;
227   erg.y = a.m12*b.x + a.m22*b.y + a.m32*b.z;
228   erg.z = a.m13*b.x + a.m23*b.y + a.m33*b.z;
229   return erg;
230 }
231 inline V3 operator * (const V3 &a, const Matrix &b){
232   V3 erg;
233   erg.x = b.m11*a.x + b.m12*a.y + b.m13*a.z;
234   erg.y = b.m21*a.x + b.m22*a.y + b.m23*a.z;
235   erg.z = b.m31*a.x + b.m32*a.y + b.m33*a.z;
236   return erg;
237 }
238 inline Matrix operator * (const Matrix &a,const double &b){
239   Matrix erg;
240   erg.m11 = a.m11*b;
241   erg.m21 = a.m21*b;
242   erg.m31 = a.m31*b;
243 
244   erg.m12 = a.m12*b;
245   erg.m22 = a.m22*b;
246   erg.m32 = a.m32*b;
247 
248   erg.m13 = a.m13*b;
249   erg.m23 = a.m23*b;
250   erg.m33 = a.m33*b;
251   return erg;
252 }
253 inline Matrix operator + (const Matrix &a, const Matrix &b){
254   Matrix erg;
255   erg.m11 = a.m11+b.m11;
256   erg.m21 = a.m21+b.m21;
257   erg.m31 = a.m31+b.m31;
258 
259   erg.m12 = a.m12+b.m12;
260   erg.m22 = a.m22+b.m22;
261   erg.m32 = a.m32+b.m32;
262 
263   erg.m13 = a.m13+b.m13;
264   erg.m23 = a.m23+b.m23;
265   erg.m33 = a.m33+b.m33;
266   return erg;
267 }
268 
269 inline bool operator < (const Matrix &a, const Matrix &b){
270     return  (
271             (a.m11<b.m11)&&
272             (a.m21<b.m21)&&
273             (a.m31<b.m31)&&
274             (a.m12<b.m12)&&
275             (a.m22<b.m22)&&
276             (a.m32<b.m32)&&
277             (a.m13<b.m13)&&
278             (a.m23<b.m23)&&
279             (a.m33<b.m33));
280 }
281 //! MyAtom an atom object
282 typedef struct MyAtom{
283   //! Label is the atom label with residue nuber seperated by '_' and the symmetry operation number seperated by french quotes.
284   QString Label;
285   //! ResiClass is the four or three letters residue class
286   QString ResiClass;
287   //! The original line in the res file.
288   QString orginalLine;
289   //! fragment number of the structure part
290   int molindex;
291   //! Binary flag for fixed (tied to first FVAR) atom parameters.
292   int fixFlag;
293   //! the symmetry number
294   int symmGroup ;
295   //!symmetry operation number
296   int sg;
297   //! platon style symetry code (s555)
298   int scod;
299   //! index of the source atom in the asymmetric unit
300   int auidx;
301   //! a is hidden flag
302   int hidden;
303   //! the site occupancy factor as it is the file e.g. 11.000
304   double sof_org;
305   //! the site occupancy factor e.g. 1.0 or 0.5
306   double sof;
307   //! isotropric flag
308   bool isIso;
309   //! the Uiso string as it appears in the res file eg -1.5 for 150% of the ueq of the horse atom
310   QString ufiso_org;
311   //! the fractional Uij
312   Matrix uf;
313   //! the cartesian Uij
314   Matrix uc;
315   //! the cartesian coordinates.
316   V3 pos;
317   //! the fractional coordinates.
318   V3 frac;
319   //! the electrondensity value of a Q-Peak.
320   double peakHeight;
321   //! the residue number
322   int resiNr;
323   //! the atomic number
324   int an;
325   //! the (dissordered) part number
326   int part;
327   //! the style type of the atom
328   int style;
329   //! the afix type of the parent atom
330   int afixParent;
331   //! the afix type
332   int afix;
333   //! the screen position X
334   GLdouble screenX;
335   //! the screen position Y
336   GLdouble screenY;
337 }MyAtom;
338 inline bool  operator == (const MyAtom &a1,const MyAtom &a2){
339   return ((a1.Label == a2.Label)&&(a1.resiNr == a2.resiNr)&&(a1.part == a2.part)&&(a1.symmGroup == a2.symmGroup));
340 }
341 inline bool operator < (const MyAtom &a1, const MyAtom &a2){
342   return (a1.Label < a2.Label);
343 }
344 inline bool operator < (MyAtom &a1, MyAtom &a2){
345   return (a1.Label < a2.Label);
346 }
347 //! MyBond a bond object
348 typedef struct MyBond{
349   //! a pointer to the atom where the bond starts
350   MyAtom const *ato1;
351   //! a pointer to the atom where the bond ends
352   MyAtom const *ato2;
353   //! the bond length
354   double length;
355   //! the index of the atom where the bond starts
356   int a1;
357   //! the index of the atom where the bond ends
358   int a2;
359 }MyBond;
360 inline bool operator ==(const MyBond &a1,const MyBond &a2){
361     return ((a1.a1==a2.a1)&&(a1.a2==a2.a2))||((a1.a2==a2.a1)&&(a1.a1==a2.a2));
362 }
363 //! for the BIND instruction
364 typedef struct MyBind{
365   QString Lab1,Lab2;
366 }MyBind;
367 
368 struct Vert {
369   int faces[3];
370   V3 pos;
371 };
372 
373 typedef struct VPoly{
374  V3 mid,nor,verts0,verts1;
375  int acol,intra;
376 }VPoly;
377 
378 typedef struct PPoly{
379  V3 mid,nor,verts0,verts1;
380  int colr,n;
381  V3 glide;
382 }PPoly;
383 
384 typedef QList<MyBond> Connection;
385 typedef QList<MyAtom> CEnvironment;
386 //! Unit cell parameters
387 struct Cell {
388   //! the dimension a in Angstrom
389   double a;
390   //! the dimension b in Angstrom
391   double b;
392   //! the dimension c in Angstrom
393   double c;
394   //! the angle alpha in degrees
395   double al;
396   //! the angle beta in degrees
397   double be;
398   //! the angle gamma in degrees
399   double ga;
400   //! \f$\varphi =  \sqrt(1 - (\cos(\alpha)^2) - (\cos(\beta)^2) - (\cos(\gamma)^2) + 2\cos(\alpha)\cos(\beta)\cos(\gamma))\f$
401   double phi;
402   //! the cell volume in Angstrom^3
403   double V;
404   //! the reciprocal dimension a
405   double as;
406   //! the reciprocal dimension b
407   double bs;
408   //! the reciprocal dimension c
409   double cs;
410 
411   //! \f$ \tau = c ((\cos(\alpha) - \cos(\beta)  \cos(\gamma)) / \sin(\gamma))\f$
412   double tau;
413   //! \f$ \cos(\gamma)\f$
414   double cosga;
415   //! \f$ \cos(\alpha) \f$
416   double cosal;
417   //! \f$ \cos(\beta) \f$
418   double cosbe;
419   //! \f$ \sin(\alpha) \f$
420   double sinal;
421   //! \f$ \sin(\beta) \f$
422   double sinbe;
423   //! \f$ \sin(\gamma) \f$
424   double singa;
425   //! \f$ \tan(\gamma) \f$
426   double tanga;
427   double cosra;//! cos reciprocal alpha
428   double cosrb;//! cos reciprocal beta
429   double cosrg;//! cos reciprocal gamma
430   //! List of symmetry operators
431   QList<Matrix> symmops;
432   //! List of translations
433   QList<V3> trans;
434   //!number of symmops without centring and inversion applyed
435   int ns0;
436   //! space group is centred (A,B,C,I,F)
437   bool centered;
438   //! space group is centro symmetric
439   bool centeric;
440   //! ZERR string as it is from the res file
441   QString Z;
442   //! the wavelenth  \f$ \lambda  \f$ in Angstroms
443   double wave;
444   Matrix G,Gi;//metric tensor and its inverse
445 };
446 //! shortest distance matrix item type
447 struct SdmItem{
448   //! shortest contact distance
449   double d;
450   //! atom index of the starting atom
451   int a1;
452   //! atom index of the ending atom
453   int a2;
454   //! symmetry number of the contact
455   int sn;
456   V3 floorD;
457   //! contact is covalent
458   bool covalent;
459 };
460 
461 inline bool operator < (const SdmItem &a1, const SdmItem &a2){
462   return (a1.d<a2.d);
463 }
464 
465 struct Tripel{
466   int n[3];
467   V3 midcenter;
468 };
469 inline bool operator == (const Tripel& v1, const Tripel& v2 ) {
470   return ((v1.n[0]==v2.n[0])&&(v1.n[1]==v2.n[1])&&(v1.n[2]==v2.n[2]));
471 }
472 //!Knopf is a list of neighbors of an atom
473 struct Knopf{
474   //! neighbors is list of atom indices of neigbours of that atom
475   QList<int> neighbors;
476 };
477 class Ring;
478 /*! \brief Molecule is a crystallography and molecular structure object of shelXle.
479  *
480  * It has routines to convert coordinates and
481  * ADPs from fractional to cartesian space, symmetry operations etc. It provides also routintes to draw atoms bonds and q-peaks.
482  * It is thought that there is only one instance of this class in ShelXle during runtime. Molecule accesses the settings file of ShelXle.
483  */
484 class Molecule{
485   public:
486     GLfloat fgc[4];
487     bool mist;
488     int fogrange;
489     bool nopm1;//!< No part minus n ghost
490     bool highlightEquivalents;//!< Symmetry generated objects will be drawn in lighter colors if this is true
491     bool qbeforehkl;//!< There are Q-Peaks before HKLF instruction
492     bool growQPeak;//!< Q-Peaks should be treated with symmetry operators
493     bool monoQrom;//!< Q-Peaks in a single color instead of a gradient.
494     bool noQPeaksPlease;//!< Q-Peaks are not shown if this is true
495     bool HFixSuitableAtomsOnly;//!< Prevent fixing H atoms on atoms with mallformed ADPs
496     QColor mQolor;//!< the single Q-Peak color
497     double  qboMin,qboMax;
498     double exti,swat,osf;
499     int hklf;
500     double hklScale,hklSigmaScale,hklOmitSig,hklOmit2th,hklShellLow,hklShellHig;
501     Matrix hklMat;
502     QString titl;
503     QString mynewnameis;
504     int LOD;//!< The Level of Detail
505     QGLShaderProgram *g_Program,*saveProg;//shaders with Qt
506     int g_program;//GL handle for shader program
507     Molecule();//!<The constructor
508     int icocnt;
509     int latt;
510     int afix5(int idx);//!< retuns fo example 65 if less then 6 non H atoms (in AFIX 66) are before this line.
511     int afix5(const CEnvironment &atm, int idx);
512     void setHBondMaxDist(double d);
513     void setHBondMaxAngl(double w);
514     int genSymCode(int s, int h, int k, int l);//!< creates a platon style symmetry code as an integer (s555)
515     V3 applySymCode(const V3 &frac, int scode);//!< applies a platon style symmetry code as an integer (s555)
516     double hbdist();
517     double hbangl();
518     int installShader();
519     void Farbverlauf (GLfloat wrt,GLfloat min,GLfloat max);//!<computes a gradient color for wrt which is between min and max and calls glColor. @param wrt value for which a color should be assigned. @param min minimum value of wrt.  @param max maximum value of wrt.
520     Cell cell;//!<The unit cell parameters
521     QString Fragments;//!<A html string of the kind "<b>The asymmetric unit contains N fragments.</b><br>" were N is the number of fragments.
522     QList<SdmItem> sdm;//!< shortest distance matrix.
523     QList<SdmItem> envi_sdm;//!< shortest distance matrix for the ENVIron ment listing functionality.
524     QList<SdmItem> contact;//!< shortest distance matrix with possible hydrogen bonds for auto HFIX.
525     QList<Matrix> symmopsEQIV;//!< list of symmetry operations from  EQIV instructions.
526     QStringList labelEQIV;//!< list of atom lable from  EQIV instructions.
527     QList<V3> transEQIV;//!< list of translation from  EQIV instructions.
528     QMap<QString,int> eqivMap;//!< maps labelEQIV and symmetry operation indices.
529     QList<MyBind> freeatoms,//!< bond list for FREE instructions
530       bindatoms;//!< bond list for BIND instructions
531     QList<Knopf> knoepfe;//!< neighbors list of each atom
532     QMap<int,int> bindPart;
533     bool canbeDonor(int an);
534     bool canbeAcceptor(int an);
535     bool is2Dissordered4H(const MyAtom &atom);
536     QList<int> theseAreAcceptors;
537     QList<int> theseAreDonors;
538     int adp,//!<if non zero the atoms and bons are drwn in ellipsoid style.
539         intern,
540         bondColorStyle;//!< uni colored bonds or bonds half and half colored like the connected atoms.
541     double bondStrength;//!< cylinder radius of the bonds in Angstrom
542     double qPeakRad;//!< icosahedron size in Angstrom
543     double beloRad;//!< triacontahedron size in Angstrom
544     QColor beloColor;//!< triacontahedron color
545     bool   beloColorByDefden;
546     bool   beloLabels;
547     Matrix rotarb(double *arr);
548     GLuint hbtex; //!< texture handle for hydrogen bonds
549     //	 hbtex2; //!< texture handle for
550     GLuint adpwall,//!< texture handle elipsoid walls
551            adpwall_plaid;//!< texture handle elipsoid walls different style
552     // int nonPositiveDefinite;
553     int proba,//!< probability level of the ellipsoids
554         tubes,//!< tube mode instead of ball stick
555         dratom;//!< wire style of atoms
556     //V3 VZ;
557     QColor AtomColor[109];//!<List of colors for all supported elements.
558     int AtomStyle[109];//!<List of atom style types for all supported elements.
559     double arad[109];//!<List of ball radii for ball stick visulaization  for all supported elements.
560     unsigned short Kovalenz_Radien[109];//!<List of covalent radii for all supported elements.
561     int pseFontSize;//!< Font size for the PSEWidget to be stored in the settings.
562     double  pmin,//!< minimum peak height of the Q-Peaks.
563             pmax;//!< maximum peak height of the Q-Peaks.
564     double  lmin,//!< minimum a for belo.
565             lmax;//!< maximum a for belo.
566     QColor bondColor;//!< the color of the bonds in uni colored mode.
567 
568     QColor enviBondColor,//!< covalent color in ENVI
569            enviHBColor,//!< hydrogen bond color in ENVI
570            enviDefaultColor;//!< default color in ENVI
571     CEnvironment asymm;//!< atom list containing the asymertic unit
572     CEnvironment showatoms;//!< atom list containing all atoms to be drawn.
573     CEnvironment splitLeftAtoms;
574     CEnvironment splitRightAtoms;
575     CEnvironment selectedatoms;//!< atom list of selected atoms.
576     CEnvironment duplicateAtoms;//!< atom list of identcal labeled atoms.
577     CEnvironment legendAtoms;//!< Atoms in a key legend.
578     Connection showbonds;//!< list of visible bonds.
579     Connection splitbonds;
580     Connection lbonds;//!< list of line bonds (for Q-Peaks)
581     CEnvironment fitatoms;//!<
582     Connection fitbonds;//!<
583     Connection theH_Bonds;
584     QStringList usedSymmetry;//!< List of internal symmetry codes of symmetry operations curently applied.
585     QString HumanSymmetry;//!< A human readable list of symmetry operations in use.
586     QSettings *einstellung;//!< the QSetttings for ShelXle.
587     QString ffmpegexe;
588     int vorobas;
589     QString voroMsg;
590     QList<VPoly> vtriangles;
591     double planeTransparence;
592     QList<PPoly> ptriangles;
593     QList<V3>  axvecs;
594     QList<int> axcols;
595     QList<int> axoprs;
596     QList<int> invoprs;
597     QList<V3>  invvecs;
598     QList<int> dontshowSop;
599     QList<int> dontshowSel;
600     QList<QColor> symmColors;
601     void voronoij(CEnvironment au, int intat=-1);
602     void drawVoronoi(V3 auge);
603     void drawPlanes();
604     void drawAxses();
605     void drawInversionCenters();
606     double ueq(Matrix m);
607     double averageUeq();
608     V3 intersectPoint(V3 rayVector, V3 rayPoint, V3 planeNormal, V3 planePoint, bool &ok);
609     void make1Plane(V3 planeNormal, V3 pointOnPlane,V3 glide, int ac, int n);
610     void findSymmElements();
611     void packPoint(const V3 &point, QList<V3> &wearein);//!< Pack inside cell
612     void packLine(const V3 &p1,const V3 &p2, V3 &vec, QList<V3> &wearein, int c,QList<int> &dc);//!< Pack inside cell
613     void specialPts(const Matrix &mat, const V3 &trans, QList<V3> &points);
614     //unsigned short ElNeg[83];
615     //
616     //
617     QString nameSymmOp(Matrix m, int &fold, V3 &axis);
618     QStringList sdmcompleter();
619     QList<SdmItem> computeSDM(CEnvironment au);
620     void atoms(CEnvironment atom,int proba=50,double radscal=1.0);
621     bool shaders_work;//!< can glsl shader run on this machine?
622     bool program_in_use;//!< glsl program active
623     bool useShaders;//!< the user whats shader
624     void shaderAtoms(CEnvironment atom,int proba=50, double radScal=1.0);//!< like void atoms(CEnvironment atom,int proba=50); but with shaders
625     void pappe();//!< the inner walls of an ellipsoid (use ony with shaders and 'wall' uniform set)
626     void bonds(Connection bond);
627     void dbond(Connection bond,int ccode=0);
628     void lbond();
629     void billBoard();
630     QString h_bonds(Connection bond,CEnvironment atoms);
631     void h_bonds2(Connection bond,CEnvironment atoms);
632     void unitCell();
633     Connection connecting(const CEnvironment &atom, bool eac=false);
634     bool decodeSymmCard(const QString symmCard);
635     bool decodeSymmCardEQIV(const QString symmCard);
636     //void countMols(QList<INP> & xdinp);
637     //bool applyLatticeCentro(const QChar latt,const bool centro);
638     QString symmcode2human(QStringList brauchSymm);//!< converts a list of internal symmetry codes in human readable ones.
639     QString symmcode2human(QString brauchSymm);//!< converts an internal symmetry code into human readable symmetry operation description
640     QString symmcode2human(QString brauchSymm, int j);//!< converts an internal symmetry code into human readable symmetry operation description prepends french quotes j:
641     QString symmcode2human(int s);
642     QString symmCard2Code(QString symmCard);
643     void frac2kart (V3 x, V3 & y);
644     void kart2frac (V3 x, V3 & y);
645     int getOZ(QString S1);//!< returns the atomic number (starting from 0) for a given chmical elememt symbol S1. @param S1 element symbol.
646     double shortestDistance(QString sc);
647     static double winkel(V3 a,V3 b);//!< calculates the angle in degrees between two vectors
648     double dieder(V3 a,V3 b, V3 c);//!< calculates a torsion angle from 3 given vectors
649     static V3 kreuzX(double x1,double y1,double z1,double x2,double y2,double z2) ;//!< a cross product
650     double fl(double x,double y, double z);//!< calculates the length of a vector given by x,y,z in fractional coordinates in Angstroms @param x,y,z fractional coordinates of a vector.
651     double wl(V3 f2, V3 f1, V3 f3);//!< calculates angle in degrees of the 3 positional vectors in fractional space.
652     void cellSetup();//!< calculates unit cell parameters from a,b,c, alpha, beta, gammma
653     void fuse();
654     void grow();
655     void grow_plus();
656     void fillCell();
657     void uniqueInCell();
658     void packer(QStringList brauchSymm);
659     void packInLimits(double ami, double ama, double bmi, double bma, double cmi, double cma);//!< Pack inside given limits (eg multiple unit cells)
660     CEnvironment packInLimits(CEnvironment &au, double ami, double ama, double bmi, double bma, double cmi, double cma);//!< Pack inside given limits (eg multiple unit cells)
661     void applyLatticeCentro(int gitter);
662     void Uf2Uo(const Matrix x, Matrix & y) ;
663     void Usym (Matrix x,Matrix sym, Matrix & y);
664     void USymCode(Matrix x,int scod, Matrix & y);
665     double dimension();
666     double dimension(CEnvironment ce);
667     void expandAt(int index);
668     void expandAll();
669     void complete();
670     void enviSDM(double range);
671     QString pse(int oz);//!< returns the chemical symbol for the given atomic number (starting from 0)
672     void loadSettings();
673     void dodecaeder(GLfloat r);
674     void icosaeder(GLfloat r);
675     void triacontaeder(GLfloat r);
676     void cube(GLfloat r);
maxmols()677     int maxmols(){return maxmol;}//!< returns the number of fragments (molecules)
newstructure()678     void newstructure(){maxmol=0;}//!< new structure initialize maxmol to 0
thepse()679     const QStringList thepse(){return PSE;}
pseSize()680     int pseSize(){return PSE.size();}
681     Matrix u2b(Matrix u);//!< compute Bij values from Uij
682     Matrix b2u(Matrix u);//!< compute Uij values from Bij
683     void extendChain(QList<Ring > &rings, QList<int> &currentChain, QList<QList<int> > &neighbors,QSet<int> &nogo);
684 
685     void inventNewLabels(QList<int> &result);//!< lets see where it goes
686     double * jacobi(const Matrix &uij, V3 &ev);
687     void exportOBJ(QString fileName,const CEnvironment &atoms, const Connection &_bonds);
688 
689     int rankMySymmOp(Matrix m, V3 t);
690   private:
691     void neighborSort(Knopf &kn);
692     bool checkExtensions();
693     double HAMax,HAWink;
694     void ellipse(int style);
695     void hirsh(Connection bond);
696     void sphere(int adp,int style=7);
697     void mySphere(int bal);
698     void myCylinder(int rod);
699     void cylinder(double strength, double length);
700     //  void ikosa(double R);
701     //  V3 eigenvalues(const Matrix m);
702     //  Matrix eigenvectors(const Matrix m,const V3 l);
703 
704     int maxmol;
705 
706     int lichtH;
707     int whiteringH;
708     int wallH;
709     int ballH;
710     int ringH;
711     int openH;
712     int adpsH;
713     int Licht;
714     int lodH;
715     int fogH;
716     int fograngeH;
717     int bgH;
718 
719     QStringList PSE;
720 };
721 
722 class Ring{
723   private:
724     bool complete;
725 
726   public:
727     bool done;
728     QList<Tripel> t;
729     QList<int> members;
730     V3 center;
Ring(Tripel t1,Tripel t2)731     Ring(Tripel t1,Tripel t2){
732       complete=false;
733       done=false;
734       t.append(t1);
735       t.append(t2);
736       center = t1.midcenter + t2.midcenter;
737       members.append(t1.n[1]);
738       members.append(t1.n[0]);
739       members.append(t1.n[2]);
740       if (!members.contains(t2.n[1])) members.append(t2.n[1]);
741       if (!members.contains(t2.n[0])) members.append(t2.n[0]);
742       if (!members.contains(t2.n[2])) members.append(t2.n[2]);
743 
744     }
~Ring()745     ~Ring(){
746       t.clear();
747       members.clear();
748     }
749 
isComplete()750     bool isComplete(){
751       if (complete) return complete;
752       complete = (members.size()==t.size());
753       if (complete) bringInOrder();
754       //printf("CPLTE%d %d %d\n",complete,members.size(),t.size());
755       return complete;
756     }
757 
theCenter()758     V3 theCenter(){
759       return center*(1.0/t.size());
760     }
761 
bringInOrder()762     void bringInOrder(){
763       //printf("bio\n");
764       //for (int aai=0; aai<members.size(); aai++)printf("Members %d\n",members.at(aai));
765       members.clear();
766       members.append(t.at(0).n[0]);
767       int loop=0;
768       while (members.size()!=t.size()){
769         loop++;
770         for (int i=0; i<t.size(); i++){
771           if ((members.last()==t.at(i).n[1])&&(!members.contains(t.at(i).n[0]))&&((members.size()+1==t.size())||(members.first()!=t.at(i).n[2])))
772             members.append(t.at(i).n[0]); else
773               if ((members.last()==t.at(i).n[2])&&(!members.contains(t.at(i).n[0]))&&((members.size()+1==t.size())||(members.first()!=t.at(i).n[1])))
774                 members.append(t.at(i).n[0]);
775         }
776         if (loop>50){
777           /*printf("ALARM? %d %d %d\n",members.size(),t.size(),loop);
778             for (int aai=0; aai<members.size(); aai++)printf("members %d\n",members.at(aai));
779             for (int tai=0; tai<t.size(); tai++)printf("t %d %d %d\n",t.at(tai).n[0],t.at(tai).n[1],t.at(tai).n[2]);*/
780           complete=false;
781           done=true;
782           members.clear();
783           return;
784         }
785       }
786       isItARealRing();
787     }
788 
isItARealRing()789     void isItARealRing(){
790       //printf("complete %d length %d %d\n",complete,t.size(),members.size());
791       if (complete==false) return;
792       bool killme=false;
793       killme = (t.size()!=members.size());
794       for (int i=0; i<t.size(); i++){
795         int u,v,w;
796         u=members.indexOf(t.at(i).n[0]);
797         v=members.indexOf(t.at(i).n[1]);
798         w=members.indexOf(t.at(i).n[2]);
799         killme|=!((((u+1)%t.size()==v)&&((u-1+t.size())%t.size()==w))||(((u+1)%t.size()==w)&&((u-1+t.size())%t.size()==v)));
800         killme|=(u*v*w<0);
801         /*printf("%d?%d %d %d %d ?%d\n",i,u,v,w,
802           (((u+1)%t.size()==v)&&((u-1+t.size())%t.size()==w))||
803           (((u+1)%t.size()==w)&&((u-1+t.size())%t.size()==v)),
804           u*v*w<0);// */
805 
806       }
807       if (killme) {
808         //printf("NOT A REAL RING!\n");
809         complete=false;
810         members.clear();
811         done=true;
812       }
813     }
814 
printRing(Molecule * mol)815     void printRing(Molecule *mol){
816       QString str="+";
817       for (int i = 0; i < members.size(); i++){
818         str.append(mol->asymm.at(members.at(i)).Label);
819         str.append((i==members.size()-1)?"+\n+":"=");
820       }
821       int l=str.size()-4;
822       for (int i=0; i<l; i++) str.append("=");
823       str.append("+\n");
824       printf("%s",str.toStdString().c_str());
825       str.clear();
826     }
827 
debugRing(Molecule * mol)828     void debugRing(Molecule *mol){
829       printRing(mol);
830       QString str="+";
831       for (int i = 0; i < t.size(); i++){
832         str.append("|");
833         str.append(mol->asymm.at(t.at(i).n[1]).Label);
834         str.append("~");
835         str.append(mol->asymm.at(t.at(i).n[0]).Label);
836         str.append("~");
837         str.append(mol->asymm.at(t.at(i).n[2]).Label);
838         str.append((i==t.size()-1)?"+\n+":"=");
839       }
840       int l=str.size()-4;
841       for (int i=0; i<l; i++) str.append("=");
842       str.append("+\n");
843       printf("%s",str.toStdString().c_str());
844       str.clear();
845 
846     }
847 
addTripel(Tripel nt)848     void addTripel(Tripel nt){
849       if (t.contains(nt)) return;
850       t.append(nt);
851       center += nt.midcenter;
852       if (!members.contains(nt.n[1])) members.append(nt.n[1]);
853       if (!members.contains(nt.n[0])) members.append(nt.n[0]);
854       if (!members.contains(nt.n[2])) members.append(nt.n[2]);
855       isComplete();
856     }
857 
858 };
859 #endif
860