[med-svn] [zodiac-zeden] 10/12: New upstream version 0.6.5
Andreas Tille
tille at debian.org
Sat Dec 30 17:56:04 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository zodiac-zeden.
commit 32acdd2964bc329aaf12516123f0dd120b928cf8
Author: Andreas Tille <tille at debian.org>
Date: Sat Dec 30 18:54:40 2017 +0100
New upstream version 0.6.5
---
.cvsignore | 4 +
CVS/Entries | 43 +
CVS/Entries.Extra | 43 +
CVS/Entries.Extra.Old | 43 +
CVS/Entries.Old | 43 +
CVS/Repository | 1 +
CVS/Root | 1 +
FF.cc | 228 +
INSTALL.txt | 21 +
MMFF.cc | 3216 +++++++++++
Makefile | 145 +
Makefile.Debug | 1515 +++++
Makefile.Release | 1515 +++++
Makefile_old | 1177 ++++
MarchingCubes.cc | 2417 ++++++++
PLP.cc | 218 +
ZNdata.cc | 844 +++
ZNmolecule.cc | 4898 ++++++++++++++++
Zodiac.cc | 172 +
Zodiac.pro | 144 +
actions.cc | 536 ++
arcball.cc | 144 +
builder.cc | 837 +++
chemscore.cc | 222 +
command.cc | 1176 ++++
constants.cc | 639 +++
database.cc | 240 +
datagrid.cc | 11 +
ddwin.cc | 6168 +++++++++++++++++++++
debian/README.Debian | 17 -
debian/changelog | 5 -
debian/compat | 1 -
debian/control | 24 -
debian/copyright | 32 -
debian/docs | 1 -
debian/rules | 15 -
debian/source/format | 1 -
debian/watch | 6 -
debian/zodiac-zeden-docs.docs | 1 -
debian/zodiac-zeden-docs.install | 1 -
debian/zodiac-zeden.install | 1 -
forcefields/CVS/Entries | 14 +
forcefields/CVS/Entries.Extra | 13 +
forcefields/CVS/Entries.Extra.Old | 0
forcefields/CVS/Entries.Old | 0
forcefields/CVS/Repository | 1 +
forcefields/CVS/Root | 1 +
forcefields/Makefile | 472 ++
forcefields/Makefile.am | 8 +
forcefields/Makefile.in | 472 ++
forcefields/forcefieldghemical.cpp | 1259 +++++
forcefields/forcefieldghemical.h | 187 +
forcefields/forcefieldghemical.lo | 12 +
forcefields/forcefieldmmff94.cpp | 5022 +++++++++++++++++
forcefields/forcefieldmmff94.h | 333 ++
forcefields/forcefieldmmff94.lo | 12 +
forcefields/forcefielduff.cpp | 1460 +++++
forcefields/forcefielduff.h | 202 +
forcefields/forcefielduff.lo | 12 +
forcefields/libforcefields.la | 41 +
graphical_object.cc | 656 +++
headers/CVS/Entries | 38 +
headers/CVS/Entries.Extra | 37 +
headers/CVS/Entries.Extra.Old | 0
headers/CVS/Entries.Old | 0
headers/CVS/Repository | 1 +
headers/CVS/Root | 1 +
headers/FF.h | 110 +
headers/LookUpTable.h | 4644 ++++++++++++++++
headers/MMFF.h | 355 ++
headers/MarchingCubes.h | 437 ++
headers/PLP.h | 66 +
headers/ZNdata.h | 174 +
headers/ZNmolecule.h | 610 ++
headers/actions.h | 86 +
headers/arcball.h | 451 ++
headers/builder.h | 84 +
headers/chemscore.h | 390 ++
headers/cmat.h | 802 +++
headers/command.h | 370 ++
headers/constants.h | 205 +
headers/cutoffGrid.h | 251 +
headers/database.h | 135 +
headers/datagrid.h | 153 +
headers/ddwin.h | 718 +++
headers/function.h | 100 +
headers/graphical_object.h | 173 +
headers/ils.h | 117 +
headers/iodevice.h | 50 +
headers/maths.h | 79 +
headers/menu.h | 1541 ++++++
headers/minimize.h | 328 ++
headers/myline.h | 85 +
headers/nms.h | 676 +++
headers/optimiser.h | 92 +
headers/plants.h | 58 +
headers/plants_mainwin.h | 174 +
headers/plantsconfig.h | 107 +
headers/ply.h | 466 ++
headers/pso.h | 195 +
headers/subscrpt.h | 42 +
headers/thread.h | 319 ++
headers/vec.h | 1172 ++++
headers/wiimote.h | 65 +
icons/B.png | Bin 0 -> 1220 bytes
icons/CVS/Entries | 47 +
icons/CVS/Entries.Extra | 46 +
icons/CVS/Entries.Extra.Old | 0
icons/CVS/Entries.Old | 0
icons/CVS/Repository | 1 +
icons/CVS/Root | 1 +
icons/V.png | Bin 0 -> 917 bytes
icons/X.png | Bin 0 -> 997 bytes
icons/arrow.png | Bin 0 -> 86 bytes
icons/benzene.png | Bin 0 -> 659 bytes
icons/builder.png | Bin 0 -> 2959 bytes
icons/builder_1bond.png | Bin 0 -> 1744 bytes
icons/builder_2bond.png | Bin 0 -> 1985 bytes
icons/builder_3bond.png | Bin 0 -> 2173 bytes
icons/builder_C.png | Bin 0 -> 3375 bytes
icons/builder_N.png | Bin 0 -> 3575 bytes
icons/builder_O.png | Bin 0 -> 3445 bytes
icons/builder_S.png | Bin 0 -> 3772 bytes
icons/builder_Xbond.png | Bin 0 -> 2261 bytes
icons/builder_del.png | Bin 0 -> 3541 bytes
icons/builder_pencil.png | Bin 0 -> 1867 bytes
icons/builder_smile.png | Bin 0 -> 3883 bytes
icons/deselect.png | Bin 0 -> 1412 bytes
icons/favicon.ico | Bin 0 -> 10806 bytes
icons/furan.png | Bin 0 -> 826 bytes
icons/furanO.png | Bin 0 -> 858 bytes
icons/haptic.png | Bin 0 -> 648 bytes
icons/invert_selection.png | Bin 0 -> 1026 bytes
icons/minimise.png | Bin 0 -> 4054 bytes
icons/pencil_C.png | Bin 0 -> 1247 bytes
icons/pencil_N.png | Bin 0 -> 1160 bytes
icons/pencil_O.png | Bin 0 -> 1162 bytes
icons/pencil_S.png | Bin 0 -> 1218 bytes
icons/periodic_table.png | Bin 0 -> 710 bytes
icons/pointer_rubber.png | Bin 0 -> 1340 bytes
icons/pointer_select_square.png | Bin 0 -> 945 bytes
icons/redo.png | Bin 0 -> 2571 bytes
icons/ring3.png | Bin 0 -> 424 bytes
icons/ring4.png | Bin 0 -> 322 bytes
icons/ring5.png | Bin 0 -> 673 bytes
icons/ring6.png | Bin 0 -> 554 bytes
icons/ring7.png | Bin 0 -> 629 bytes
icons/ring8.png | Bin 0 -> 465 bytes
icons/select.png | Bin 0 -> 2058 bytes
icons/select_C.png | Bin 0 -> 1353 bytes
icons/select_H.png | Bin 0 -> 943 bytes
icons/select_all.png | Bin 0 -> 1100 bytes
icons/select_square.png | Bin 0 -> 1751 bytes
icons/undo.png | Bin 0 -> 3431 bytes
icons/zeden.icns | Bin 0 -> 194914 bytes
icons/zeden_ico.png | Bin 0 -> 648 bytes
iodevice.cc | 12 +
maths.cc | 155 +
menu.cc | 7372 +++++++++++++++++++++++++
minimize.cc | 519 ++
molsketch_helium/CMakeLists.txt | 58 +
molsketch_helium/CVS/Entries | 32 +
molsketch_helium/CVS/Entries.Extra | 31 +
molsketch_helium/CVS/Entries.Extra.Old | 0
molsketch_helium/CVS/Entries.Log | 3 +
molsketch_helium/CVS/Entries.Old | 0
molsketch_helium/CVS/Repository | 1 +
molsketch_helium/CVS/Root | 1 +
molsketch_helium/atom.cpp | 376 ++
molsketch_helium/atom.h | 191 +
molsketch_helium/bond.cpp | 370 ++
molsketch_helium/bond.h | 151 +
molsketch_helium/commands.cpp | 368 ++
molsketch_helium/commands.h | 603 ++
molsketch_helium/element.cpp | 339 ++
molsketch_helium/element.h | 74 +
molsketch_helium/fileio.cpp | 526 ++
molsketch_helium/fileio.h | 74 +
molsketch_helium/i18n/CMakeLists.txt | 29 +
molsketch_helium/i18n/CVS/Entries | 5 +
molsketch_helium/i18n/CVS/Entries.Extra | 4 +
molsketch_helium/i18n/CVS/Entries.Extra.Old | 0
molsketch_helium/i18n/CVS/Entries.Old | 0
molsketch_helium/i18n/CVS/Repository | 1 +
molsketch_helium/i18n/CVS/Root | 1 +
molsketch_helium/i18n/molsketch_cs.ts | 808 +++
molsketch_helium/i18n/molsketch_nl.ts | 713 +++
molsketch_helium/i18n/molsketch_pt_BR.ts | 580 ++
molsketch_helium/icon.rc | 1 +
molsketch_helium/images/CVS/Entries | 36 +
molsketch_helium/images/CVS/Entries.Extra | 35 +
molsketch_helium/images/CVS/Entries.Extra.Old | 0
molsketch_helium/images/CVS/Entries.Old | 0
molsketch_helium/images/CVS/Repository | 1 +
molsketch_helium/images/CVS/Root | 1 +
molsketch_helium/images/application-exit.png | Bin 0 -> 1134 bytes
molsketch_helium/images/configure.png | Bin 0 -> 2015 bytes
molsketch_helium/images/configure.svg | 665 +++
molsketch_helium/images/document-export.png | Bin 0 -> 825 bytes
molsketch_helium/images/document-import.png | Bin 0 -> 790 bytes
molsketch_helium/images/document-new.png | Bin 0 -> 873 bytes
molsketch_helium/images/document-open.png | Bin 0 -> 796 bytes
molsketch_helium/images/document-open.svg | 481 ++
molsketch_helium/images/document-print.png | Bin 0 -> 880 bytes
molsketch_helium/images/document-save-as.png | Bin 0 -> 1233 bytes
molsketch_helium/images/document-save.png | Bin 0 -> 798 bytes
molsketch_helium/images/draw-eraser.png | Bin 0 -> 1172 bytes
molsketch_helium/images/draw-freehand.png | Bin 0 -> 809 bytes
molsketch_helium/images/draw-freehand.svg | 1406 +++++
molsketch_helium/images/edit-copy.png | Bin 0 -> 644 bytes
molsketch_helium/images/edit-cut.png | Bin 0 -> 576 bytes
molsketch_helium/images/edit-paste.png | Bin 0 -> 771 bytes
molsketch_helium/images/edit-redo.png | Bin 0 -> 1245 bytes
molsketch_helium/images/edit-select-all.png | Bin 0 -> 631 bytes
molsketch_helium/images/edit-undo.png | Bin 0 -> 1220 bytes
molsketch_helium/images/help-about.png | Bin 0 -> 1041 bytes
molsketch_helium/images/help-contents.png | Bin 0 -> 1054 bytes
molsketch_helium/images/help-contextual.png | Bin 0 -> 1605 bytes
molsketch_helium/images/help.png | Bin 0 -> 1186 bytes
molsketch_helium/images/icon.svg | 819 +++
molsketch_helium/images/molsketch.ico | Bin 0 -> 67646 bytes
molsketch_helium/images/molsketch.png | Bin 0 -> 12483 bytes
molsketch_helium/images/molsketch.svg | 819 +++
molsketch_helium/images/molsketch.xpm | 465 ++
molsketch_helium/images/transform-move.png | Bin 0 -> 1127 bytes
molsketch_helium/images/transform-rotate.png | Bin 0 -> 821 bytes
molsketch_helium/images/zoom-fit-best.png | Bin 0 -> 1203 bytes
molsketch_helium/images/zoom-in.png | Bin 0 -> 1191 bytes
molsketch_helium/images/zoom-original.png | Bin 0 -> 1182 bytes
molsketch_helium/images/zoom-out.png | Bin 0 -> 1173 bytes
molsketch_helium/mainwindow.cpp | 1250 +++++
molsketch_helium/mainwindow.h | 321 ++
molsketch_helium/molecule.cpp | 540 ++
molsketch_helium/molecule.h | 186 +
molsketch_helium/mollibitem.cpp | 98 +
molsketch_helium/mollibitem.h | 66 +
molsketch_helium/molsKetch.nsi | 148 +
molsketch_helium/molscene.cpp | 1168 ++++
molsketch_helium/molscene.h | 316 ++
molsketch_helium/molsketch.desktop | 20 +
molsketch_helium/molsketch.ico | Bin 0 -> 67710 bytes
molsketch_helium/molsketch.qrc | 35 +
molsketch_helium/molview.cpp | 51 +
molsketch_helium/molview.h | 56 +
molsketch_helium/part/CMakeLists.txt | 27 +
molsketch_helium/part/CVS/Entries | 13 +
molsketch_helium/part/CVS/Entries.Extra | 12 +
molsketch_helium/part/CVS/Entries.Extra.Old | 0
molsketch_helium/part/CVS/Entries.Old | 0
molsketch_helium/part/CVS/Repository | 1 +
molsketch_helium/part/CVS/Root | 1 +
molsketch_helium/part/molsketch.svg | 819 +++
molsketch_helium/part/molsketch_factory.cpp | 77 +
molsketch_helium/part/molsketch_factory.h | 43 +
molsketch_helium/part/molsketch_factory.h~ | 41 +
molsketch_helium/part/molsketchpart.cpp | 261 +
molsketch_helium/part/molsketchpart.h | 83 +
molsketch_helium/part/molsketchpart.rc | 17 +
molsketch_helium/part/molsketchpart_shell.cpp | 236 +
molsketch_helium/part/molsketchpart_shell.h | 52 +
molsketch_helium/part/molsketchpart_shell.qrc | 5 +
molsketch_helium/part/molsketchpart_shell.rc | 8 +
molsketch_helium/periodictablewidget.cpp | 92 +
molsketch_helium/periodictablewidget.h | 64 +
molsketch_helium/settings.cpp | 181 +
molsketch_helium/settings.h | 80 +
molsketch_helium/settings.ui | 640 +++
myline.cc | 150 +
obabel_includes.h | 37 +
object_script.Zodiac.Debug | 65 +
object_script.Zodiac.Release | 65 +
parameters/CVS/Entries | 17 +
parameters/CVS/Entries.Extra | 16 +
parameters/CVS/Entries.Extra.Old | 0
parameters/CVS/Entries.Old | 0
parameters/CVS/Repository | 1 +
parameters/CVS/Root | 1 +
parameters/MMFF93SUP.PAR | 86 +
parameters/MMFFANG.PAR | 2354 ++++++++
parameters/MMFFAROM.PAR | 56 +
parameters/MMFFBNDK.PAR | 68 +
parameters/MMFFBOND.PAR | 507 ++
parameters/MMFFCHG.PAR | 512 ++
parameters/MMFFDEF.PAR | 193 +
parameters/MMFFDFSB.PAR | 39 +
parameters/MMFFHDEF.PAR | 114 +
parameters/MMFFOOP.PAR | 127 +
parameters/MMFFPBCI.PAR | 112 +
parameters/MMFFPROP.PAR | 103 +
parameters/MMFFSTBN.PAR | 292 +
parameters/MMFFSYMB.PAR | 223 +
parameters/MMFFTOR.PAR | 938 ++++
parameters/MMFFVDW.PAR | 112 +
plants.cc | 138 +
plants_mainwin.cc | 939 ++++
plantsconfig.cc | 468 ++
ply.c | 6638 ++++++++++++++++++++++
povray.cc | 616 +++
resources.qrc | 22 +
thread.cc | 1462 +++++
wiimote.cc | 322 ++
win_rc.rc | 1 +
zodiac.qrc | 47 +
zodiac.ui | 27 +
304 files changed, 94892 insertions(+), 105 deletions(-)
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..4333ee0
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,4 @@
+Debug
+Zodiac.vcproj.GRIMOIRE.scmijg.user
+Zodiac.suo
+Zodiac.ncb
\ No newline at end of file
diff --git a/CVS/Entries b/CVS/Entries
new file mode 100644
index 0000000..6e51c26
--- /dev/null
+++ b/CVS/Entries
@@ -0,0 +1,43 @@
+/.cvsignore/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/FF.cc/1.6/Wed Mar 18 13:06:25 2009//
+/INSTALL.txt/1.1/Fri Oct 3 14:22:42 2008//
+/MMFF.cc/1.4/Wed Mar 18 13:06:26 2009//
+/Makefile_old/1.2/Fri Sep 26 17:23:56 2008//
+/MarchingCubes.cc/1.3/Tue Sep 2 14:23:38 2008//
+/PLP.cc/1.3/Mon Feb 23 13:43:56 2009//
+/ZNdata.cc/1.13/Sun Apr 19 09:10:09 2009//
+/ZNmolecule.cc/1.19/Mon May 18 12:07:25 2009//
+/Zodiac.pro/1.20/Fri Oct 31 17:04:21 2008//
+/actions.cc/1.13/Wed Feb 25 13:13:39 2009//
+/arcball.cc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/builder.cc/1.11/Mon May 18 12:07:25 2009//
+/chemscore.cc/1.6/Wed Feb 25 13:13:39 2009//
+/command.cc/1.9/Mon May 18 12:07:25 2009//
+/constants.cc/1.7/Sun Apr 19 09:10:09 2009//
+/database.cc/1.11/Thu Mar 5 14:22:18 2009//
+/datagrid.cc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/ddwin.cc/1.75/Mon May 18 12:07:25 2009//
+/graphical_object.cc/1.14/Wed May 13 16:05:07 2009//
+/iodevice.cc/1.2/Fri Sep 26 12:47:58 2008//
+/maths.cc/1.2/Sun Apr 19 09:10:10 2009//
+/menu.cc/1.134/Mon May 18 12:07:25 2009//
+/minimize.cc/1.13/Mon May 18 12:07:25 2009//
+/myline.cc/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/obabel_includes.h/1.2/Mon Oct 27 12:07:02 2008//
+/plants.cc/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/plants_mainwin.cc/1.2/Mon Sep 29 09:02:23 2008//
+/plantsconfig.cc/1.2/Mon Nov 3 16:07:10 2008//
+/ply.c/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/povray.cc/1.11/Wed Apr 29 14:47:44 2009//
+/resources.qrc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/wiimote.cc/1.1.1.1/Wed Aug 20 12:43:33 2008//
+/win_rc.rc/1.1/Thu Oct 2 14:48:08 2008//
+/zodiac.qrc/1.15/Thu Oct 2 09:54:35 2008//
+/zodiac.ui/1.1.1.1/Wed Aug 20 12:43:32 2008//
+D/forcefields////
+D/headers////
+D/icons////
+D/molsketch_helium////
+D/parameters////
+/Zodiac.cc/1.7/Mon May 18 12:49:48 2009//
+/thread.cc/1.54/Mon May 18 12:45:31 2009//
diff --git a/CVS/Entries.Extra b/CVS/Entries.Extra
new file mode 100644
index 0000000..4beef37
--- /dev/null
+++ b/CVS/Entries.Extra
@@ -0,0 +1,43 @@
+/.cvsignore////*///
+/FF.cc////*///
+/INSTALL.txt////*///
+/MMFF.cc////*///
+/Makefile_old////*///
+/MarchingCubes.cc////*///
+/PLP.cc////*///
+/ZNdata.cc////*///
+/ZNmolecule.cc////*///
+/Zodiac.pro////*///
+/actions.cc////*///
+/arcball.cc////*///
+/builder.cc////*///
+/chemscore.cc////*///
+/command.cc////*///
+/constants.cc////*///
+/database.cc////*///
+/datagrid.cc////*///
+/ddwin.cc////*///
+/graphical_object.cc////*///
+/iodevice.cc////*///
+/maths.cc////*///
+/menu.cc////*///
+/minimize.cc////*///
+/myline.cc////*///
+/obabel_includes.h////*///
+/plants.cc////*///
+/plants_mainwin.cc////*///
+/plantsconfig.cc////*///
+/ply.c////*///
+/povray.cc////*///
+/resources.qrc////*///
+/wiimote.cc////*///
+/win_rc.rc////*///
+/zodiac.qrc////*///
+/zodiac.ui////*///
+D/forcefields///////
+D/headers///////
+D/icons///////
+D/molsketch_helium///////
+D/parameters///////
+/Zodiac.cc////*///
+/thread.cc////*///
diff --git a/CVS/Entries.Extra.Old b/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..d2e3290
--- /dev/null
+++ b/CVS/Entries.Extra.Old
@@ -0,0 +1,43 @@
+/.cvsignore////*///
+/FF.cc////*///
+/INSTALL.txt////*///
+/MMFF.cc////*///
+/Makefile_old////*///
+/MarchingCubes.cc////*///
+/PLP.cc////*///
+/ZNdata.cc////*///
+/ZNmolecule.cc////*///
+/Zodiac.cc////*///
+/Zodiac.pro////*///
+/actions.cc////*///
+/arcball.cc////*///
+/builder.cc////*///
+/chemscore.cc////*///
+/command.cc////*///
+/constants.cc////*///
+/database.cc////*///
+/datagrid.cc////*///
+/ddwin.cc////*///
+/graphical_object.cc////*///
+/iodevice.cc////*///
+/maths.cc////*///
+/menu.cc////*///
+/minimize.cc////*///
+/myline.cc////*///
+/obabel_includes.h////*///
+/plants.cc////*///
+/plants_mainwin.cc////*///
+/plantsconfig.cc////*///
+/ply.c////*///
+/povray.cc////*///
+/resources.qrc////*///
+/thread.cc////*///
+/wiimote.cc////*///
+/win_rc.rc////*///
+/zodiac.qrc////*///
+/zodiac.ui////*///
+D/forcefields///////
+D/headers///////
+D/icons///////
+D/molsketch_helium///////
+D/parameters///////
diff --git a/CVS/Entries.Old b/CVS/Entries.Old
new file mode 100644
index 0000000..534e247
--- /dev/null
+++ b/CVS/Entries.Old
@@ -0,0 +1,43 @@
+/.cvsignore/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/FF.cc/1.6/Wed Mar 18 13:06:25 2009//
+/INSTALL.txt/1.1/Fri Oct 3 14:22:42 2008//
+/MMFF.cc/1.4/Wed Mar 18 13:06:26 2009//
+/Makefile_old/1.2/Fri Sep 26 17:23:56 2008//
+/MarchingCubes.cc/1.3/Tue Sep 2 14:23:38 2008//
+/PLP.cc/1.3/Mon Feb 23 13:43:56 2009//
+/ZNdata.cc/1.13/Sun Apr 19 09:10:09 2009//
+/ZNmolecule.cc/1.19/Mon May 18 12:07:25 2009//
+/Zodiac.cc/1.6/Wed Mar 18 13:06:26 2009//
+/Zodiac.pro/1.20/Fri Oct 31 17:04:21 2008//
+/actions.cc/1.13/Wed Feb 25 13:13:39 2009//
+/arcball.cc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/builder.cc/1.11/Mon May 18 12:07:25 2009//
+/chemscore.cc/1.6/Wed Feb 25 13:13:39 2009//
+/command.cc/1.9/Mon May 18 12:07:25 2009//
+/constants.cc/1.7/Sun Apr 19 09:10:09 2009//
+/database.cc/1.11/Thu Mar 5 14:22:18 2009//
+/datagrid.cc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/ddwin.cc/1.75/Mon May 18 12:07:25 2009//
+/graphical_object.cc/1.14/Wed May 13 16:05:07 2009//
+/iodevice.cc/1.2/Fri Sep 26 12:47:58 2008//
+/maths.cc/1.2/Sun Apr 19 09:10:10 2009//
+/menu.cc/1.134/Mon May 18 12:07:25 2009//
+/minimize.cc/1.13/Mon May 18 12:07:25 2009//
+/myline.cc/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/obabel_includes.h/1.2/Mon Oct 27 12:07:02 2008//
+/plants.cc/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/plants_mainwin.cc/1.2/Mon Sep 29 09:02:23 2008//
+/plantsconfig.cc/1.2/Mon Nov 3 16:07:10 2008//
+/ply.c/1.1.1.1/Wed Aug 20 12:43:31 2008//
+/povray.cc/1.11/Wed Apr 29 14:47:44 2009//
+/resources.qrc/1.1.1.1/Wed Aug 20 12:43:32 2008//
+/thread.cc/1.53/Mon May 18 12:07:25 2009//
+/wiimote.cc/1.1.1.1/Wed Aug 20 12:43:33 2008//
+/win_rc.rc/1.1/Thu Oct 2 14:48:08 2008//
+/zodiac.qrc/1.15/Thu Oct 2 09:54:35 2008//
+/zodiac.ui/1.1.1.1/Wed Aug 20 12:43:32 2008//
+D/forcefields////
+D/headers////
+D/icons////
+D/molsketch_helium////
+D/parameters////
diff --git a/CVS/Repository b/CVS/Repository
new file mode 100644
index 0000000..18132c1
--- /dev/null
+++ b/CVS/Repository
@@ -0,0 +1 @@
+zodiac
diff --git a/CVS/Root b/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/FF.cc b/FF.cc
new file mode 100644
index 0000000..0f2d66c
--- /dev/null
+++ b/FF.cc
@@ -0,0 +1,228 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "database.h"
+#include "obabel_includes.h"
+#include "FF.h"
+#include "constants.h"
+#include "cutoffGrid.h"
+
+#ifdef WIN32
+#include <float.h>
+#define isnan _isnan
+#endif // WIN32
+
+
+
+ForceFieldInteraction::ForceFieldInteraction () {
+ at1 = NULL;
+ at2 = NULL;
+}
+
+/*
+double ForceFieldInteraction::derive (double &variable, double *function_value) {
+ double ref_value = variable;
+ variable = ref_value - DX;
+ cerr << "var-dx"<<variable << endl;
+ double E = value ();
+ variable = ref_value + DX;
+ cerr << "var+dx"<<variable<<endl;
+ double E2 = value ();
+ variable = ref_value;
+ if (function_value) *function_value = (E2 + E) / 2.f;
+ assert (!isnan ((E2-E)/(2*DX)));
+// cerr << "derive" << (E2-E)/(2*DX)<<endl;
+ return (E2-E)/(2*DX);
+}*/
+
+double ForceFieldInteraction::derive (Atom *at, double *function_value) {
+ vect v = get_coordinates(at);
+ double ref = v.x ();
+ set_coordinates (at,vect (ref-DX, v.y (), v.z ()));
+ double E = value ();
+ set_coordinates (at,vect (ref+DX, v.y (), v.z ()));
+ double E2 = value ();
+ set_coordinates (at,vect (ref, v.y (), v.z ()));
+ if (function_value) *function_value = (E2 + E) / 2.f;
+ assert (!isnan ((E2-E)/(2*DX)));
+// cerr << "derive" << (E2-E)/(2*DX)<<endl;
+ return (E2-E)/(2*DX);
+}
+
+double ForceFieldInteraction::derive_y (Atom *at, double *function_value) {
+ vect v = get_coordinates(at);
+ double ref = v.y ();
+ set_coordinates (at, vect (v.x (), ref-DX, v.z ()));
+ double E = value ();
+ set_coordinates (at, vect (v.x (), ref+DX, v.z ()));
+ double E2 = value ();
+ set_coordinates (at, vect (v.x (), ref, v.z ()));
+ if (function_value) *function_value = (E2 + E) / 2.f;
+ assert (!isnan ((E2-E)/(2*DX)));
+// cerr << "derive" << (E2-E)/(2*DX)<<endl;
+ return (E2-E)/(2*DX);
+}
+
+double ForceFieldInteraction::derive_z (Atom *at, double *function_value) {
+ vect v = get_coordinates(at);
+ double ref = v.z ();
+ set_coordinates (at, vect (v.x (), v.y (), ref-DX));
+ double E = value ();
+ set_coordinates (at, vect (v.x (), v.y (), ref+DX));
+ double E2 = value ();
+ set_coordinates (at, vect (v.x (), v.y (), ref));
+ if (function_value) *function_value = (E2 + E) / 2.f;
+ assert (!isnan ((E2-E)/(2*DX)));
+// cerr << "derive" << (E2-E)/(2*DX)<<endl;
+ return (E2-E)/(2*DX);
+}
+
+
+
+void ForceFieldInteraction::set_forces (bool score, double mult) {
+ assert (at1);
+ assert (at2);
+ vect v1 = get_coordinates (at1);
+ double x1 = v1.x();
+ //cerr << "v1" << v1 << endl;
+ //cerr << "x1" << x1 << endl;
+ assert (at1 != at2);
+ vect dir = subtract (get_coordinates(at1), get_coordinates(at2));
+ if (!dir.module ()) dir = vect (1., 0., 0.);
+ assert (dir.module ());
+ double score_val;
+ double force_x;
+ force_x = derive (at1, &score_val);
+ dir.multiply (force_x / dir.x());
+ dir.multiply(mult);
+ vect force1 = get_back_force (at1);
+ vect force2 = get_back_force (at2);
+ force2 += dir;
+ force1 -= dir;
+
+ set_back_force (at1, force1);
+ set_back_force (at2, force2);
+
+
+ if (score) {
+ double score1 = get_back_score (at1);
+ double score2 = get_back_score (at2);
+ // cerr <<score1;
+ score1 += score_val;
+ score2 += score_val;
+ // cerr << score1 << score_val<< endl;
+
+ set_back_score (at1, score1);
+ set_back_score (at2, score2);
+
+ }
+
+}
+
+ElasticRestrain::ElasticRestrain () : ForceFieldInteraction () { k = 1.f; dist0 = 1.5;}
+
+float ElasticRestrain::value () {
+ float d = dist (get_coordinates(at1), get_coordinates(at2)) - dist0;
+ return k * d * d;
+}
+
+
+
+ForceField::ForceField () {
+ is_initialised = false;
+ target_mol = NULL;
+ near_grid = NULL;
+ far_grid = NULL;
+}
+
+ForceField::~ForceField() {}
+
+void ForceField::clear_nonbonded_interactions () {
+// cerr <<"general clearnonb"<<endl;
+}
+
+void ForceField::clear () {
+ clear_nonbonded_interactions ();
+ environment.clear ();
+ target_mol = NULL;
+ delete near_grid;
+ delete far_grid;
+ near_grid = NULL;
+ far_grid = NULL;
+}
+
+
+void ForceField::load_mol (ZNMolecule *mol) {
+ assert (mol);
+ target_mol = mol;
+}
+
+
+void ForceField::load_environment (vector<ZNMolecule *> envir, ZNMolecule *mol, vect cent, double rad) {
+ environment.clear ();
+ for (unsigned int i=0; i<envir.size (); i++) {
+ FOR_ATOMS_OF_MOL (a, envir[i]) {
+ ZNMolecule *other_mol = (ZNMolecule *) a->GetParent ();
+ if (other_mol == mol) continue;
+ if (other_mol ->multi && mol ->multi) {
+
+ Database_molecule *dbm1 = (Database_molecule *) mol;
+ Database_molecule *dbm2 = (Database_molecule *) other_mol;
+ if (dbm1 -> database == dbm2 -> database) continue;
+ }
+ environment.push_back (&*a);
+ }
+ }
+ delete near_grid;
+ delete far_grid;
+ near_grid = new cutoffGrid<Atom*> (environment, FF_NEAR_NONBONDED_CUTOFF);
+ far_grid = new cutoffGrid<Atom*> (environment, FF_FAR_NONBONDED_CUTOFF );
+}
+
+
+void ForceField::update () {
+ load_nonbonded_interactions ();
+}
+
+void ForceField::initialize_internal (ZNMolecule* mol, vector<ZNMolecule *> envir) {
+ clear ();
+ load_environment (envir, mol);
+ load_mol (mol);
+ load_internal_interactions (0);
+}
+
+void ForceField::initialize_interaction (ZNMolecule* mol, vector<ZNMolecule *> envir, vect cent, float rad) {
+ clear ();
+ load_environment (envir, mol);
+ load_mol (mol);
+ // load_nonbonded_interactions ();
+ load_grids (cent, rad);
+
+
+}
+
+void ForceField::initialize (ZNMolecule* mol, vector<ZNMolecule *> envir) {
+ clear ();
+ load_environment (envir, mol);
+ load_mol (mol);
+ load_internal_interactions (0);
+ load_nonbonded_interactions ();
+
+}
+
+
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..aaaf1a0
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,21 @@
+Zodiac 0.6
+
+BEFORE YOU INSTALL
+
+make sure you have Qt-4.4.3 and openbabel 2.2.0 installed
+
+This source countains a Zodiac.pro file to be used with qmake to generate platform-specific makefiles
+
+Unix:
+qmake
+make
+make install
+
+Mac:
+qmake -spec macx-xcode
+will generate a Zodiac.xproj project file for Xcode
+
+
+Windows (MinGW):
+qmake -spec win32-g++
+make
diff --git a/MMFF.cc b/MMFF.cc
new file mode 100644
index 0000000..17fe11d
--- /dev/null
+++ b/MMFF.cc
@@ -0,0 +1,3216 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include <iostream>
+#include "MMFF.h"
+
+
+#include <limits> // To enable NaN usage
+#ifdef _OPENMP
+
+#include <omp.h>
+#endif
+
+#define ACCEPTOR 1
+#define DONOR 2
+#define NEITHER 0
+
+using namespace std;
+
+
+
+#ifdef WIN32
+#define isnan(x) (x != x)
+#endif // WIN32
+
+
+/*
+MMFFabInteraction::MMFFabInteraction () {
+ at3 = NULL;
+}
+*/
+
+
+
+
+
+
+
+float MMFFbsInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at1 != at2);
+ double r = dist (get_coordinates (at1), get_coordinates (at2));
+ double dr = r - r0;
+ double cs = -2.;
+ double out = 143.9325*kb*0.5*(dr*dr)*(1.+cs*dr+(7./12)*(cs*cs*dr*dr));
+ // cout <<"BOND STRETCHINGS "<<at1->GetIdx ()<<" "<<at1->GetAtomicNum ()<<" "<< at1->GetVector ()<<" "<<at2->GetVector ()<<" "<<get_MMFFtype(at1)<<" "<< get_MMFFtype(at1)<<" "<< type<<" "<< r<<" "<<r0<<" "<<dr<<" "<<out<<" "<<kb<<endl;
+
+// cerr << out<<"out"<<endl;
+ assert (!isnan (out));
+ return (float) out;
+
+}
+
+
+
+
+float MMFFabInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ assert (at1 != at3);
+ double theta = angle (get_coordinates (at1), get_coordinates (at2), get_coordinates (at3));
+ double cb = -0.4*PI/180;
+ double dtheta = theta - theta0;
+
+ if (linear) {
+ // cout << "linear"<<endl;
+ double out = 143.9325*ka* (1+ cos (theta/180*PI));
+ assert (!isnan (out));
+
+ return (float) out;
+ }
+ else {
+ double out = 0.043844*ka*0.5*dtheta*dtheta*(1+cb*dtheta);
+ assert (!isnan (out));
+ // cout <<"ANGLE BENDINGS "<<at1->GetIdx ()<<" "<<at2->GetIdx ()<<" "<<at3->GetIdx ()<<" "<< at1->GetVector ()<<" "<<at2->GetVector ()<<" "<<at3->GetVector ()<<" "<<theta0<<" "<<theta<<" "<< out <<" "<<endl;
+ return (float) out;
+ }
+ return 0.f;
+}
+
+
+
+float MMFFsbInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+// cerr <<at1 -> GetVector () << at2 -> GetVector ()<< at3 -> GetVector ()<<angle ((vect &)at1-> GetVector (), (vect &)at2-> GetVector (), (vect &)at3-> GetVector ())<<" "<<theta0<<endl;
+ double theta = angle (get_coordinates (at1), get_coordinates (at2), get_coordinates (at3));
+ double rij = dist (get_coordinates (at1), get_coordinates (at2));
+ double rkj = dist (get_coordinates (at3), get_coordinates (at2));
+ double drij = rij - r0ij;
+ double drkj = rkj - r0kj;
+ double dtheta = theta - theta0;
+ double out = 2.5121 *(kijk*drij + kkji*drkj) * dtheta;
+// cerr <<"STRETCH BENDINGS "<< out << " "<< at1 -> GetVector () << at2 -> GetVector ()<< at3 -> GetVector ()<<drij<<" "<<drkj<<dtheta<<endl;
+
+ assert (!isnan (out));
+ return (float) out;
+}
+
+
+
+float MMFFopInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ assert (at4);
+ double chi = 180.* wilson (get_coordinates (at1), get_coordinates (at2), get_coordinates (at3), get_coordinates (at4)) / PI;
+ // cout <<"OUT OF PLANE "<< opint->at1->MMFFtype<<" "<< opint->at2->MMFFtype<<" "<<opint->at3->MMFFtype<<" "<< opint->at4->MMFFtype<<" "<<chi*180/PI<<" "<<k<<" "<< 0.043844*0.5*k*chi*chi <<endl;
+ double out = 0.043844*0.5*koop*chi*chi;
+ assert (!isnan (out));
+ return (float) out;
+
+}
+
+
+float MMFFtoInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ assert (at4);
+ double phi = dihedral (get_coordinates (at1), get_coordinates (at2), get_coordinates (at3), get_coordinates (at4));
+ phi = phi*PI/180; //cos takes rad
+ // cout <<"TORSION INTERACTIONS "<< at1->MMFFtype<<" "<< at2->MMFFtype<<" "<<at3->MMFFtype<<" "<< at4->MMFFtype<<" " <<type<<" "<< phi*180/PI<<" "<<0.5*(v1 * (1 + cos (phi)) + v2 * (1 - cos (2*phi)) + v3 * (1 + cos (3*phi)))<<" "<<v1<<" "<<v2<<" "<<v3<<endl;
+ double out = 0.5*(v1 * (1.0 + cos (phi)) + v2 * (1.0 - cos (2.0*phi)) + v3 * (1.0 + cos (3.0*phi)));
+ assert (!isnan (out));
+ return (float) out;
+}
+
+
+
+float MMFFvwInteraction::value () {
+ assert (at1);
+ assert (at2);
+ assert (at1 != at2);
+#if 1
+ double r = dist(get_coordinates (at1), get_coordinates (at2));
+ double out = e*pow((1.07*r0/(r+0.07*r0)),7)*((1.12*pow(r0,7)/(pow(r,7)+0.12*pow(r0,7)))-2.);
+#else
+ double r2 = square_distance(get_coordinates (at1), get_coordinates (at2));
+ double r = sqrt (r2);
+
+ double rpow7 = r2 * r2 * r2 * r;
+ // cout <<"VDW "<< at1->ID<<" "<< at2->ID<<" "<< r<<" "<<r0<<" "<<e<<" "<<e*pow((1.07*r0/(r+0.07*r0)),7)*((1.12*pow(r0,7)/(pow(r,7)+0.12*pow(r0,7)))-2)<<endl;ble
+
+ double r0pow7 = (r0 * r0); // pow(r0, 7);
+ r0pow7 = r0pow7 * r0pow7 * r0pow7 * r0;
+
+ double rX = (1.07*r0/(r+0.07*r0));
+ double rXpow7 = rX * rX;
+ rXpow7 = rXpow7 * rXpow7 * rXpow7 * rX;
+
+ double out = e*rXpow7*((1.12*r0pow7/(rpow7+0.12*r0pow7))-2.0);
+#endif
+ assert (!isnan (out));
+ return (float) out;
+}
+
+
+float MMFFelInteraction::value () {
+ assert (at1);
+ assert (at2);
+
+ double qi = at1-> GetPartialCharge ();
+ double qj = at2-> GetPartialCharge ();
+ double delta = 0.05;
+ double r = dist (get_coordinates (at1), get_coordinates (at2));
+ // double D = 1.0; D assumed to be 1
+ // int n = 1; n assumed to be 1
+ double out = 332.0716 * qi * qj / (r + delta) * scale;
+ assert (!isnan (out));
+ return (float) out;
+}
+
+bool MMFFelInteraction::isHbond () {
+ int at1n = at1 ->GetAtomicNum ();
+ int at2n = at2 ->GetAtomicNum ();
+ if (at1n == 1) {
+ Atom *r = root_at (at1);
+ if (r) {
+ if (is_polar (r)) {
+ if (is_polar (at2)) return true;
+ };
+ }
+ }
+ else if (at2n == 1) {
+ Atom *r = root_at (at2);
+ if (r) {
+ if (is_polar (r)) {
+ if (is_polar (at1)) return true;
+ };
+ }
+ }
+
+ return false;
+}
+
+
+
+
+
+void MMFFabInteraction::set_forces (bool score, double multbm) {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ float force_1x = derive (at1);
+ float force_1y = derive_y (at1);
+ float force_1z = derive_z (at1);
+ vect force1 (-force_1x, -force_1y, -force_1z);
+
+ float force_2x = derive (at2);
+ float force_2y = derive_y (at2);
+ float force_2z = derive_z (at2);
+ vect force2 (-force_2x, -force_2y, -force_2z);
+
+ float force_3x = derive (at3);
+ float force_3y = derive_y (at3);
+ float force_3z = derive_z (at3);
+ vect force3 (-force_3x, -force_3y, -force_3z);
+ assert (!isnan (force_1x)); assert (!isnan (force_1x)); assert (!isnan (force_1x));
+ assert (!isnan (force_1y)); assert (!isnan (force_1y)); assert (!isnan (force_1y));
+ assert (!isnan (force_1z)); assert (!isnan (force_1z)); assert (!isnan (force_1z));
+
+
+
+// cerr << force1<<force2<<force3<<endl;
+ vect pforce1 = get_back_force (at1);
+ vect pforce2 = get_back_force (at2);
+ vect pforce3 = get_back_force (at3);
+ //cerr << "force was " << pforce1;
+ pforce1 = sum (pforce1, force1);
+ pforce2 = sum (pforce2, force2);
+ pforce3 = sum (pforce3, force3);
+// cerr << " and now after "<<force1<< " is "<<pforce1<<endl;
+
+ set_back_force (at1, pforce1);
+ set_back_force (at2, pforce2);
+ set_back_force (at3, pforce3);
+// cerr << "AB interaction "<< pforce1<<pforce2<<pforce3<<endl;
+}
+
+
+
+void MMFFsbInteraction::set_forces (bool score, double mult) {
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ float force_1x = derive (at1);
+ float force_1y = derive_y (at1);
+ float force_1z = derive_z (at1);
+ vect force1 (-force_1x, -force_1y, -force_1z);
+
+ float force_2x = derive (at2);
+ float force_2y = derive_y (at2);
+ float force_2z = derive_z (at2);
+ vect force2 (-force_2x, -force_2y, -force_2z);
+
+ float force_3x = derive (at3);
+ float force_3y = derive_y (at3);
+ float force_3z = derive_z (at3);
+ vect force3 (-force_3x, -force_3y, -force_3z);
+ assert (!isnan (force_1x)); assert (!isnan (force_1x)); assert (!isnan (force_1x));
+ assert (!isnan (force_1y)); assert (!isnan (force_1y)); assert (!isnan (force_1y));
+ assert (!isnan (force_1z)); assert (!isnan (force_1z)); assert (!isnan (force_1z));
+
+
+
+// cerr << force1<<force2<<force3<<endl;
+ vect pforce1 = get_back_force (at1);
+ vect pforce2 = get_back_force (at2);
+ vect pforce3 = get_back_force (at3);
+ //cerr << "force was " << pforce1;
+ pforce1 = sum (pforce1, force1);
+ pforce2 = sum (pforce2, force2);
+ pforce3 = sum (pforce3, force3);
+// cerr << " and now after "<<force1<< " is "<<pforce1<<endl;
+
+ set_back_force (at1, pforce1);
+ set_back_force (at2, pforce2);
+ set_back_force (at3, pforce3);
+// cerr << "SB interaction "<< pforce1<<pforce2<<pforce3<<endl;
+}
+
+
+
+
+void MMFFopInteraction::set_forces (bool score, double mult) {
+
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ assert (at4);
+ float force_1x = derive (at1);
+ float force_1y = derive_y (at1);
+ float force_1z = derive_z (at1);
+ vect force1 (-force_1x, -force_1y, -force_1z);
+
+ float force_2x = derive (at2);
+ float force_2y = derive_y (at2);
+ float force_2z = derive_z (at2);
+ vect force2 (-force_2x, -force_2y, -force_2z);
+
+ float force_3x = derive (at3);
+ float force_3y = derive_y (at3);
+ float force_3z = derive_z (at3);
+ vect force3 (-force_3x, -force_3y, -force_3z);
+
+ float force_4x = derive (at4);
+ float force_4y = derive_y (at4);
+ float force_4z = derive_z (at4);
+ vect force4 (-force_4x, -force_4y, -force_4z);
+
+ vect pforce1 = get_back_force (at1);
+ vect pforce2 = get_back_force (at2);
+ vect pforce3 = get_back_force (at3);
+ vect pforce4 = get_back_force (at4);
+
+ pforce1 += force1;
+ pforce2 += force2;
+ pforce3 += force3;
+ pforce4 += force4;
+
+ set_back_force (at1, pforce1);
+ set_back_force (at2, pforce2);
+ set_back_force (at3, pforce3);
+ set_back_force (at4, pforce4);
+}
+
+
+void MMFFtoInteraction::set_forces (bool score, double mult) {
+
+ assert (at1);
+ assert (at2);
+ assert (at3);
+ assert (at4);
+ float force_1x = derive (at1);
+ float force_1y = derive_y (at1);
+ float force_1z = derive_z (at1);
+ vect force1 (-force_1x, -force_1y, -force_1z);
+
+ float force_2x = derive (at2);
+ float force_2y = derive_y (at2);
+ float force_2z = derive_z (at2);
+ vect force2 (-force_2x, -force_2y, -force_2z);
+
+ float force_3x = derive (at3);
+ float force_3y = derive_y (at3);
+ float force_3z = derive_z (at3);
+ vect force3 (-force_3x, -force_3y, -force_3z);
+
+ float force_4x = derive (at4);
+ float force_4y = derive_y (at4);
+ float force_4z = derive_z (at4);
+ vect force4 (-force_4x, -force_4y, -force_4z);
+
+ vect pforce1 = get_back_force (at1);
+ vect pforce2 = get_back_force (at2);
+ vect pforce3 = get_back_force (at3);
+ vect pforce4 = get_back_force (at4);
+
+ pforce1 += force1;
+ pforce2 += force2;
+ pforce3 += force3;
+ pforce4 += force4;
+
+ set_back_force (at1, pforce1);
+ set_back_force (at2, pforce2);
+ set_back_force (at3, pforce3);
+ set_back_force (at4, pforce4);
+}
+
+
+
+
+
+
+MMFF::MMFF () {
+ is_initialised = false;
+ is_initialised = load_parameters ();
+
+}
+
+int MMFF::load_parameters () {
+ int out = 1;
+ out *= load_aromatic_parameters ();
+ out *= load_ci_parameters ();
+ out *= load_H_parameters ();
+ out *= load_atype_parameters ();
+ out *= load_atom_parameters ();
+ out *= load_ab_parameters ();
+ out *= load_bs_parameters ();
+ out *= load_sb_parameters ();
+ out *= load_sb2_parameters ();
+ out *= load_to_parameters ();
+ out *= load_vw_parameters ();
+ out *= load_op_parameters ();
+ return out;
+}
+
+
+double MMFF::compute_total_energy () {
+
+ double Einternal, Eb, Ea, Eba, Eoop, Et, Evdw, Eq;
+
+
+ Eb = compute_bond_stretchings ();
+ Ea = compute_angle_bendings ();
+ Eba = compute_stretch_bend_interactions ();
+ Eoop = compute_out_of_plane_bendings ();
+ Et = compute_torsion_interactions ();
+ Evdw = compute_van_der_waals_interactions ();
+ Eq = compute_electrostatic_interactions ();
+ Einternal = Eb + Ea + Eba + Eoop + Et + Evdw + Eq;
+
+ double Einteraction = compute_interaction_energy ();
+ return Einternal + Einteraction;
+
+}
+
+double MMFF::compute_interaction_energy () {
+ double Eq = compute_nonbonded_electrostatic_interactions ();
+ double Evdw = compute_nonbonded_van_der_waals_interactions ();
+ return Eq + Evdw;
+}
+
+
+void MMFF::compute_forces () {
+
+ compute_bond_stretching_forces ();
+ compute_angle_bending_forces ();
+ compute_stretch_bend_interaction_forces ();
+ // compute_out_of_plane_bending_forces ();
+ compute_torsion_forces ();
+ compute_van_der_waals_forces ();
+ compute_electrostatic_forces ();
+ compute_nonbonded_van_der_waals_forces ();
+ compute_nonbonded_electrostatic_forces ();
+
+}
+
+
+
+void MMFF::compute_bond_stretching_forces () {
+ //cerr << "bs " << bsInteractions.size () << endl;
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<bsInteractions.size (); i++) {
+ bsInteractions[i] -> set_forces ();
+ }
+
+}
+
+void MMFF::compute_angle_bending_forces () {
+// cerr << "ab " << abInteractions.size () << endl;
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<abInteractions.size (); i++) {
+ abInteractions[i] -> set_forces ();
+ }
+}
+
+void MMFF::compute_stretch_bend_interaction_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<sbInteractions.size (); i++) {
+ sbInteractions[i] -> set_forces ();
+ }
+}
+
+void MMFF::compute_out_of_plane_bending_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<opInteractions.size (); i++) {
+ opInteractions[i] -> set_forces ();
+ }
+}
+
+void MMFF::compute_torsion_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<toInteractions.size (); i++) {
+ toInteractions[i] -> set_forces ();
+ }
+}
+
+void MMFF::compute_electrostatic_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<elInteractions.size (); i++) {
+ if (elInteractions[i]->at1->GetPartialCharge () && elInteractions[i]->at2->GetPartialCharge ()) {
+ elInteractions[i] -> set_forces ();
+ }
+ }
+}
+
+void MMFF::compute_nonbonded_electrostatic_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<elNBInteractions.size (); i++) {
+ if (elNBInteractions[i]->at1->GetPartialCharge () && elNBInteractions[i]->at2->GetPartialCharge ()) {
+ elNBInteractions[i] -> set_forces (true); //bool enables scores to be written to atoms
+ }
+ }
+}
+
+void MMFF::compute_van_der_waals_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<vwInteractions.size (); i++) {
+ vwInteractions[i] -> set_forces ();
+ }
+}
+
+void MMFF::compute_nonbonded_van_der_waals_forces () {
+/*#ifdef _OPENMP
+#pragma omp parallel for
+#endif // _OPENMP
+*/
+ for (int i=0; i<vwNBInteractions.size (); i++) {
+ vwNBInteractions[i] -> set_forces (true); //bool enables scores to be written to atoms
+ }
+}
+
+
+
+
+double MMFF::compute_nonbonded_electrostatic_interactions () {
+ double Eq = 0.f;
+ for (unsigned int i=0; i<elNBInteractions.size (); i++) {
+ Eq += elNBInteractions[i] -> value ();
+
+ }
+ return Eq;
+}
+
+
+double MMFF::compute_nonbonded_van_der_waals_interactions () {
+ double Evdw = 0.f;
+ for (unsigned int i=0; i<vwNBInteractions.size (); i++) {
+ Evdw += vwNBInteractions[i] -> value ();
+
+ }
+ return Evdw;
+}
+
+
+double MMFF::compute_bond_stretchings () {
+ double Eb = 0.f;
+ for (unsigned int i=0; i<bsInteractions.size (); i++) {
+ Eb += bsInteractions[i] -> value ();
+
+ }
+ return Eb;
+}
+
+
+
+
+
+
+double MMFF::compute_electrostatic_interactions () {
+ double Eq = 0.f;
+ for (unsigned int i=0; i<elInteractions.size (); i++) {
+ Eq += elInteractions[i] -> value ();
+ }
+ return Eq;
+}
+
+
+double MMFF::compute_angle_bendings () {
+
+ double Ea = 0.f;
+ for (unsigned int i=0; i<abInteractions.size (); i++) {
+ Ea += abInteractions[i] -> value ();
+ }
+ return Ea;
+}
+
+double MMFF::compute_stretch_bend_interactions () {
+ double Eba = 0.f;
+ for (unsigned int i=0; i<sbInteractions.size (); i++) {
+ Eba += sbInteractions[i] -> value ();
+ }
+ return Eba;
+}
+
+double MMFF::compute_torsion_interactions () {
+ double Et = 0.f;
+ for (unsigned int i=0; i<toInteractions.size (); i++) {
+ Et += toInteractions[i] -> value ();
+ }
+ return Et;
+}
+
+double MMFF::compute_van_der_waals_interactions () {
+ double Evdw = 0.f;
+ for (unsigned int i=0; i<vwInteractions.size (); i++) {
+ Evdw += vwInteractions[i] -> value ();
+ }
+ return Evdw;
+}
+
+double MMFF::compute_out_of_plane_bendings () {
+ double Eoop = 0.f;
+ for (unsigned int i=0; i<opInteractions.size (); i++) {
+ Eoop += opInteractions[i] -> value ();
+ }
+ return Eoop;
+}
+
+
+
+
+
+/*
+
+float MMFF::compute_total_electrostatic_energy () {
+ float Eq = 0.;
+ for (unsigned int i=0; i<elNBInteractions.size (); i++) {
+ float E = compute_electrostatic_interaction (elNBInteractions[i]);
+ Eq += E;
+ elNBInteractions[i]->at1->score += E;
+ }
+ return Eq;
+}
+
+float MMFF::compute_total_van_der_waals_energy () {
+ float Evdw = 0.;
+ for (unsigned int i=0; i<vwNBInteractions.size (); i++) {
+ float E = compute_van_der_waals_interaction (vwNBInteractions[i]);
+ Evdw += E;
+ vwNBInteractions[i]->at1->score += E;
+ }
+ return Evdw;
+}
+
+
+
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+///////////////////////////////////////////FORCES////////////////////////////////////////////////////////////////////////
+
+
+/*
+
+
+void MMFF::compute_bond_stretching_force (MMFFbsInteraction *bsint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ float old_coordinate = bsint->at1-> GetVector ()[i];
+ bsint->at1-> GetVector ()[i] = old_coordinate - DX;
+ E = compute_bond_stretching (bsint);
+ bsint->at1-> GetVector ()[i] = old_coordinate + DX;
+ E2 = compute_bond_stretching (bsint);
+ bsint->at1-> GetVector ()[i] = old_coordinate;
+ bsint->at1->force[i]-= (E2-E)/(2*DX);
+ bsint->at2->force[i]+= (E2-E)/(2*DX);
+
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+void MMFF::compute_angle_bending_force (MMFFabInteraction *abint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ abint->at1-> GetVector ()[i]-= DX;
+ E = compute_angle_bending (abint);
+ abint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_angle_bending (abint);
+ abint->at1-> GetVector ()[i]-= DX;
+ abint->at1->force[i]-= (E2-E)/(2*DX);
+
+ abint->at3-> GetVector ()[i]-= DX;
+ E = compute_angle_bending (abint);
+ abint->at3-> GetVector ()[i]+= 2*DX;
+ E2 = compute_angle_bending (abint);
+ abint->at3-> GetVector ()[i]-= DX;
+ abint->at3->force[i]-= (E2-E)/(2*DX);
+
+ abint->at2-> GetVector ()[i]-= DX;
+ E = compute_angle_bending (abint);
+ abint->at2-> GetVector ()[i]+= 2*DX;
+ E2 = compute_angle_bending (abint);
+ abint->at2-> GetVector ()[i]-= DX;
+ abint->at2->force[i]-= (E2-E)/(2*DX);
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+void MMFF::compute_stretch_bend_interaction_force (MMFFsbInteraction *sbint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ sbint->at1-> GetVector ()[i]-= DX;
+ E = compute_stretch_bend_interaction (sbint);
+ sbint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_stretch_bend_interaction (sbint);
+ sbint->at1-> GetVector ()[i]-= DX;
+ sbint->at1->force[i]-= (E2-E)/(2*DX);
+
+ sbint->at3-> GetVector ()[i]-= DX;
+ E = compute_stretch_bend_interaction (sbint);
+ sbint->at3-> GetVector ()[i]+= 2*DX;
+ E2 = compute_stretch_bend_interaction (sbint);
+ sbint->at3-> GetVector ()[i]-= DX;
+ sbint->at3->force[i]-= (E2-E)/(2*DX);
+
+ sbint->at2-> GetVector ()[i]-= DX;
+ E = compute_stretch_bend_interaction (sbint);
+ sbint->at2-> GetVector ()[i]+= 2*DX;
+ E2 = compute_stretch_bend_interaction (sbint);
+ sbint->at2-> GetVector ()[i]-= DX;
+ sbint->at2->force[i]-= (E2-E)/(2*DX);
+
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+void MMFF::compute_out_of_plane_bending_force (MMFFopInteraction *opint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ opint->at4-> GetVector ()[i]-= DX;
+ E = compute_out_of_plane_bending (opint);
+ opint->at4-> GetVector ()[i]+= 2*DX;
+ E2 = compute_out_of_plane_bending (opint);
+ opint->at4-> GetVector ()[i]-= DX;
+ opint->at4->force[i]-= (E2-E)/(2*DX);
+
+ opint->at1-> GetVector ()[i]-= DX;
+ E = compute_out_of_plane_bending (opint);
+ opint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_out_of_plane_bending (opint);
+ opint->at1-> GetVector ()[i]-= DX;
+ opint->at1->force[i]-= (E2-E)/(2*DX);
+
+ opint->at2-> GetVector ()[i]-= DX;
+ E = compute_out_of_plane_bending (opint);
+ opint->at2-> GetVector ()[i]+= 2*DX;
+ E2 = compute_out_of_plane_bending (opint);
+ opint->at2-> GetVector ()[i]-= DX;
+ opint->at2->force[i]-= (E2-E)/(2*DX);
+
+ opint->at3-> GetVector ()[i]-= DX;
+ E = compute_out_of_plane_bending (opint);
+ opint->at3-> GetVector ()[i]+= 2*DX;
+ E2 = compute_out_of_plane_bending (opint);
+ opint->at3-> GetVector ()[i]-= DX;
+ opint->at3->force[i]-= (E2-E)/(2*DX);
+
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+
+void MMFF::compute_torsion_force (MMFFtoInteraction *toint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ toint->at1-> GetVector ()[i]-= DX;
+ E = compute_torsion_interaction (toint);
+ toint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_torsion_interaction (toint);
+ toint->at1-> GetVector ()[i]-= DX;
+ toint->at1->force[i]-= (E2-E)/(2*DX);
+
+ toint->at4-> GetVector ()[i]-= DX;
+ E = compute_torsion_interaction (toint);
+ toint->at4-> GetVector ()[i]+= 2*DX;
+ E2 = compute_torsion_interaction (toint);
+ toint->at4-> GetVector ()[i]-= DX;
+ toint->at4->force[i]-= (E2-E)/(2*DX);
+
+ toint->at2-> GetVector ()[i]-= DX;
+ E = compute_torsion_interaction (toint);
+ toint->at2-> GetVector ()[i]+= 2*DX;
+ E2 = compute_torsion_interaction (toint);
+ toint->at2-> GetVector ()[i]-= DX;
+ toint->at2->force[i]-= (E2-E)/(2*DX);
+
+ toint->at3-> GetVector ()[i]-= DX;
+ E = compute_torsion_interaction (toint);
+ toint->at3-> GetVector ()[i]+= 2*DX;
+ E2 = compute_torsion_interaction (toint);
+ toint->at3-> GetVector ()[i]-= DX;
+ toint->at3->force[i]-= (E2-E)/(2*DX);
+
+
+
+
+
+ toint->at4->force[i]-= (E2-E)/(2*DX);
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+
+void MMFF::compute_electrostatic_force (MMFFelInteraction *elint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ elint->at1-> GetVector ()[i]-= DX;
+ E = compute_electrostatic_interaction (elint);
+ elint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_electrostatic_interaction (elint);
+ elint->at1-> GetVector ()[i]-= DX;
+ elint->at1->force[i]-= (E2-E)/(2*DX);
+ elint->at2->force[i]+= (E2-E)/(2*DX);
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+void MMFF::compute_van_der_waals_force (MMFFvwInteraction *vwint) {
+ float E, E2;
+ for (unsigned int i=0; i<3; i++) {
+ vwint->at1-> GetVector ()[i]-= DX;
+ E = compute_van_der_waals_interaction (vwint);
+ vwint->at1-> GetVector ()[i]+= 2*DX;
+ E2 = compute_van_der_waals_interaction (vwint);
+ vwint->at1-> GetVector ()[i]-= DX;
+ vwint->at1->force[i]-= (E2-E)/(2*DX);
+ vwint->at2->force[i]+= (E2-E)/(2*DX);
+
+ }
+
+ total_energy += (E2+E)/2;
+}
+
+
+
+vector<float> MMFF::compute_van_der_waals_force_vector (MMFFvwInteraction *vwint) {
+
+ vector<float> out (3, 0);
+ double r = distance (vwint->at1-> GetVector (), vwint->at2-> GetVector ());
+ float force = compute_van_der_waals_force_module (vwint);
+ for (unsigned int i=0; i<3; i++) {
+ out[i] = vwint->at2-> GetVector ()[i]-vwint->at1-> GetVector ()[i];
+ out[i]*=force/r;
+ }
+ return out;
+}
+
+
+
+
+
+vector<float> MMFF::compute_electrostatic_force_vector (MMFFelInteraction *elint) {
+ float r = distance (elint->at1-> GetVector (), elint->at2-> GetVector ());
+ float force = compute_electrostatic_force_module (elint);
+ vector<float> out (3, 0);
+ for (unsigned int i=0; i<3; i++) {
+ out[i] = elint->at2-> GetVector ()[i]-elint->at1-> GetVector ()[i];
+ out[i]*=force/r;
+ }
+ return out;
+}
+
+
+
+
+
+float MMFF::compute_van_der_waals_force_module (MMFFvwInteraction *vwint) {
+
+
+ double e = get_vdw_e (vwint->at1, vwint->at2);
+ double r = distance (vwint->at1-> GetVector (), vwint->at2-> GetVector ());
+ double r0 = get_vdw_r0 (vwint->at1, vwint->at2);
+
+ return e*pow(1.07*r0,7)* ( (pow((1/(r+0.07*r0)),7)) * (1.12*pow(r0,7)*7*(-1)*pow (r0,6)/((pow(r,7)+
+ 0.12*pow(r0,7))*(pow(r,7)+0.12*pow(r0,7)))) + ((1.12*pow(r0,7)/(pow(r,7)+0.12 *pow(r0,7)))-2) * (-7*pow ((r+0.07*r0),-8)));
+}
+
+
+
+float MMFF::compute_electrostatic_force_module (MMFFelInteraction *elint) {
+
+ double qi = elint->at1-> charge;
+ double qj = elint->at2-> charge;
+ double delta = 0.05;
+ double r = distance (elint->at1-> GetVector (), elint->at2-> GetVector ());
+
+ return elint->scale*-332.0716*qi*qj/((r+delta)*(r+delta));
+}
+
+
+
+
+
+
+float MMFF::compute_bond_stretching_force_module (MMFFbsInteraction *bsint) {
+ float kb = bsint->kb;
+ float r = distance (bsint->at1-> GetVector (), bsint->at2-> GetVector ());
+ float r0 = bsint->r0;
+ float dr = r-r0;
+ float cs = -2.;
+ float out= 143.9325*0.5*kb*(2*dr+cs*3*dr*dr+(7./12)*cs*cs*4*dr*dr*dr);
+ return out;
+
+}
+
+
+float MMFF::compute_angle_bending_force_module (MMFFabInteraction *abint) {
+
+ float theta = angle (abint->at1-> GetVector (), abint->at2-> GetVector (), abint->at3-> GetVector ());
+ float ka = abint->ka;
+ float cb = -0.4*PI/180;
+ float theta0 = abint->theta0;
+ float dtheta = theta - theta0;
+ bool linear = abint->linear;
+ if (linear) {
+ return -143.9325*ka* (sin (theta/180*PI));
+ }
+ else {
+ return 0.043844*ka*0.5*(2*dtheta+cb*3*dtheta*dtheta);
+ }
+ return 0;
+}
+
+
+
+float MMFF::compute_out_of_plane_bending_force_module (MMFFopInteraction *opint) {
+ double k = opint->koop;
+ double chi = 180.*wilson (opint->at1-> GetVector (), opint->at2-> GetVector (),opint->at3-> GetVector (),opint->at4-> GetVector ())/PI;
+ return 0.043844*k*chi;
+}
+
+
+
+float MMFF::compute_torsion_force_module (MMFFtoInteraction *toint) {
+ int I = toint->at1->MMFFtype;
+ int J = toint->at2->MMFFtype;
+ int K = toint->at3->MMFFtype;
+ int L = toint->at4->MMFFtype;
+
+
+// int pl = toint->pl;
+//get_to_pl (toint->type, I, J, K, L); //parameters line
+ float v1 = toint->v1;
+ float v2 = toint->v2;
+ float v3 = toint->v3;
+ float phi = dihedral (toint->at1-> GetVector (), toint->at2-> GetVector (),toint-> at3-> GetVector (), toint->at4-> GetVector ());
+ phi = phi*PI/180; //cos takes rads
+ return 0.5*(v1 * (-sin(phi)) + v2 * (2*sin (2.*phi)) + v3 * (-3*sin (3.*phi)));
+}
+
+*/
+
+///////////////////////////////////////////ENERGIES////////////////////////////////////////////////////////////////////////
+
+
+/*
+double MMFF::compute_bond_stretching (MMFFbsInteraction *bsint) {
+
+
+ double kb = bsint->kb;
+ double r = distance (bsint->at1-> GetVector (), bsint->at2-> GetVector ());
+ double r0 = bsint->r0;
+ double dr = r-r0;
+ double cs = -2.;
+ // cout <<"BOND STRETCHINGS "<< bsint->at1->MMFFtype<<" "<< bsint->at2->MMFFtype<<" "<< bsint->type<<" "<< r<<" "<<r0<<" "<<dr<<" "<<143.9325*kb*0.5*dr*dr*(1+cs*dr+7/12*cs*cs*dr*dr)<<" "<<kb<<endl;
+ long double out = 143.9325*kb*0.5*(dr*dr)*(1.+cs*dr+(7./12)*(cs*cs*dr*dr));
+ // if (out<0) cout<< "dr "<<dr<<" cs "<<cs<<" primo pezzo "<< 143.9325*kb*0.5*(dr*dr)<<" secondo pezzo "<<(1+cs*dr+(7/12)*(cs*cs*dr*dr))<<endl;
+ return out;
+
+}
+
+
+
+
+
+double MMFF::compute_angle_bending (MMFFabInteraction *abint) {
+
+ double theta = angle (abint->at1-> GetVector (), abint->at2-> GetVector (), abint->at3-> GetVector ());
+ double ka = abint->ka;
+ double cb = -0.4*PI/180;
+ double theta0 = abint->theta0;
+ double dtheta = theta - theta0;
+// cout << theta0<< " "<<dtheta<<endl;
+
+ bool linear = abint->linear;
+ // cout <<"ANGLE BENDINGS "<< abint->at1->MMFFtype<<" "<< abint->at2->MMFFtype<<" "<< abint->type<<" "<<theta0<<" "<<theta<<" "<< 0.043844*ka*0.5*dtheta*dtheta*(1+cb*dtheta) <<" "<<endl;
+ if (linear) {
+ cout << "linear"<<endl;
+ return 143.9325*ka* (1+ cos (theta/180*PI));
+ }
+ else {
+ return 0.043844*ka*0.5*dtheta*dtheta*(1+cb*dtheta);
+ }
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+double MMFF::compute_stretch_bend_interaction (MMFFsbInteraction *sbint) {
+
+ double theta = angle (sbint->at1-> GetVector (), sbint->at2-> GetVector (), sbint->at3-> GetVector ());
+ double theta0 = sbint->theta0;
+ double kijk = sbint->kijk;
+ double kkji = sbint->kkji;
+ double rij = distance (sbint->at1-> GetVector (), sbint->at2-> GetVector ());
+ double rkj = distance (sbint->at3-> GetVector (), sbint->at2-> GetVector ());
+ double r0ij = sbint->r0ij;
+ double r0kj = sbint->r0kj;
+ double drij = rij - r0ij;
+ double drkj = rkj - r0kj;
+ double dtheta = theta - theta0;
+// cout <<"STRETCH BENDINGS "<< sbint->at1->MMFFtype<<" "<< sbint->at2->MMFFtype<<" "<<sbint->at3->MMFFtype<<" "<< theta<<" "<<dtheta<<" "<<2.5121 *(kijk*drij) * dtheta<<" "<<2.5121 *(kkji*drkj) * dtheta<<" "<<kijk<<" "<<kkji<<endl;
+ return 2.5121 *(kijk*drij + kkji*drkj) * dtheta;
+}
+
+
+
+double MMFF::compute_out_of_plane_bending (MMFFopInteraction *opint) {
+ double k = opint->koop;
+ double chi = 180.*wilson (opint->at1-> GetVector (), opint->at2-> GetVector (),opint->at3-> GetVector (),opint->at4-> GetVector ())/PI;
+ // cout <<"OUT OF PLANE "<< opint->at1->MMFFtype<<" "<< opint->at2->MMFFtype<<" "<<opint->at3->MMFFtype<<" "<< opint->at4->MMFFtype<<" "<<chi*180/PI<<" "<<k<<" "<< 0.043844*0.5*k*chi*chi <<endl;
+ return 0.043844*0.5*k*chi*chi;
+
+}
+
+
+
+
+
+
+double MMFF::compute_torsion_interaction (MMFFtoInteraction *toint) {
+ int I = toint->at1->MMFFtype;
+ int J = toint->at2->MMFFtype;
+ int K = toint->at3->MMFFtype;
+ int L = toint->at4->MMFFtype;
+
+
+ double v1 = toint->v1;
+ double v2 = toint->v2;
+ double v3 = toint->v3;
+ double phi = dihedral (toint->at1-> GetVector (), toint->at2-> GetVector (),toint-> at3-> GetVector (), toint->at4-> GetVector ());
+ phi = phi*PI/180; //cos takes rad
+ // cout <<"TORSION INTERACTIONS "<< toint->at1->MMFFtype<<" "<< toint->at2->MMFFtype<<" "<<toint->at3->MMFFtype<<" "<< toint->at4->MMFFtype<<" " <<toint->type<<" "<< phi*180/PI<<" "<<0.5*(v1 * (1 + cos (phi)) + v2 * (1 - cos (2*phi)) + v3 * (1 + cos (3*phi)))<<" "<<v1<<" "<<v2<<" "<<v3<<endl;
+ return 0.5*(v1 * (1.0 + cos (phi)) + v2 * (1.0 - cos (2.0*phi)) + v3 * (1.0 + cos (3.0*phi)));
+}
+
+
+
+double MMFF::compute_van_der_waals_interaction (MMFFvwInteraction *vwint) {
+
+ double e = get_vdw_e (vwint->at1, vwint->at2);
+ double r = distance (vwint->at1-> GetVector (), vwint->at2-> GetVector ());
+ double r0 = get_vdw_r0 (vwint->at1, vwint->at2);
+ // cout <<"VDW "<< vwint->at1->ID<<" "<< vwint->at2->ID<<" "<< r<<" "<<r0<<" "<<e<<" "<<e*pow((1.07*r0/(r+0.07*r0)),7)*((1.12*pow(r0,7)/(pow(r,7)+0.12*pow(r0,7)))-2)<<endl;
+ return e*pow((1.07*r0/(r+0.07*r0)),7)*((1.12*pow(r0,7)/(pow(r,7)+0.12*pow(r0,7)))-2.);
+}
+
+
+double MMFF::compute_electrostatic_interaction (MMFFelInteraction *elint) {
+
+ double qi = elint->at1-> charge;
+ double qj = elint->at2-> charge;
+ double delta = 0.05;
+ double r = distance (elint->at1-> GetVector (), elint->at2-> GetVector ());
+ // double D = 1.0; D assumed to be 1
+ // int n = 1; n assumed to be 1
+ return 332.0716*qi*qj/(r+delta)*elint->scale;
+}
+
+*/
+
+
+//______________________________________________________________________________________________________________
+
+int MMFF::get_atype_line (int I)
+{
+ for (unsigned int i = 0; i< atomParameters.size (); i++)
+ {
+ if (atomParameters[i]->type == I)
+ {
+ return i;
+ }
+ }
+
+// cerr <<i<<"non parametrized atom"<<endl;
+ cerr << I << "non parametrized atom" << endl;
+ return 0;
+}
+
+int MMFF::get_bond_type (int I, int J) {
+ int iline = 0, jline =0;
+ for (unsigned int i = 0; i< atomParameters.size (); i++) {
+ if (atomParameters[i]->type == I) {
+ iline = i;
+ break;
+ }
+ }
+ for (unsigned int i = 0; i< atomParameters.size (); i++) {
+ if (atomParameters[i]->type == J) {
+ jline = i;
+ break;
+ }
+ }
+ // cout <<iline<<" "<<jline<<endl;
+ // cout << atomParameters[iline]->multipleBond <<atomParameters[jline]->multipleBond<<endl;
+// if ((atomParameters[iline]->aromatic || atomParameters[iline]->multipleBond) && (atomParameters[jline]->aromatic || atomParameters[jline]->multipleBond) ) return 1;
+
+ if (atomParameters[iline]->multipleBond && atomParameters[jline]->multipleBond ) return 1;
+ else return 0;
+}
+
+double MMFF::get_charge_increment (int I, int J) {
+ if (I==J) return 0;
+ int correct = 1;
+ if (J<I) {
+ correct = -1;
+ int swap = J;
+ J = I;
+ I = swap;
+ }
+ for (unsigned int n=0; n<ciParameters.size (); n++) {
+ if (ciParameters[n]->I == I && ciParameters[n]->J == J ){
+ return ciParameters[n]->increment*correct;
+ }
+ }
+ cout <<"could not retrieve ci informations for atom types "<<I<<" && "<<J<<endl;
+ return 0;
+}
+
+
+string MMFF::get_aromatic_string (Atom *at) {
+ return "not implemented";
+/*
+ Ring *ring=NULL;
+ int last_size = 100;
+ for (unsigned int r=0; r<at->in_ring.size (); r++) {
+ if (at->in_ring[r]->IsAromatic () && at->in_ring[r]->Size ()<last_size) {
+ ring = at->in_ring[r];
+ last_size = ring->Size ();
+ }
+ }
+ bool N5ANION, IMCAT;
+ IMCAT = ring->IM_CAT;
+ N5ANION = ring->N5ANION;
+ int L5;
+ if (last_size ==5) {
+ if (ring->alpha_atom == NULL) L5 =4;
+ else if (ring->alpha_atom == at) L5 =1;
+ else if (at-> GetBond (ring->alpha_atom)) L5=2;
+ else L5=3;
+ }
+ else {
+ L5 =0;
+ }
+
+// cout <<at->MMFFstring<<" "<<at->GetAtomicNum ()<<" "<<last_size<<" "<<L5<<" "<<IMCAT<<" "<<N5ANION<<endl;
+ for (unsigned int n=0; n<aromaticParameters.size (); n++) {
+ if (aromaticParameters[n]->old_type==at->MMFFstring && aromaticParameters[n]->at_number==at->GetAtomicNum () && aromaticParameters[n]->ring_size==last_size && aromaticParameters[n]->L5==L5 && aromaticParameters[n]->IMCAT==IMCAT && aromaticParameters[n]->N5ANION==N5ANION){
+ return aromaticParameters[n]->arom_type;
+ }
+ }
+ string atype;
+ if (at->GetAtomicNum () ==6) atype = "C*";
+ else if (at->GetAtomicNum () ==7) atype = "N*";
+ else if (at->GetAtomicNum () ==8) atype = "O*";
+ else if (at->GetAtomicNum () ==16) atype = "S*";
+ else atype ="*";
+ for (unsigned int n=0; n<aromaticParameters.size (); n++) {
+ if (aromaticParameters[n]->old_type==atype && aromaticParameters[n]->at_number==at->GetAtomicNum () && aromaticParameters[n]->ring_size==last_size && aromaticParameters[n]->L5==L5){
+ return aromaticParameters[n]->arom_type;
+ }
+ }
+
+ return "unknown aromatic atom";
+*/
+}
+
+int MMFF::get_bs_pl (int type, int I, int J) {
+ for (unsigned int n=0; n<bsParameters.size (); n++) {
+ if (bsParameters[n]->I == I && bsParameters[n]->J == J && bsParameters[n]->type == type){
+ return n;
+ }
+ }
+ cout <<"could not retrieve bs informations for atom types "<<I<<" , "<<J<<" && bond type "<<type<<endl;
+ return 0;
+}
+
+int MMFF::get_ab_pl (int type, int I, int J, int K) {
+ for (unsigned int n=0; n<abParameters.size (); n++) {
+ if (abParameters[n]->I == I && abParameters[n]->J == J && abParameters[n]->K == K && abParameters[n]->type == type){
+ return n;
+ }
+ }
+ cout <<"could not retrieve ab informations for atom types "<<I<<" , "<<J<<" , "<<K<<" && angle type "<<type<<endl;
+ return 0;
+}
+
+int MMFF::get_sb_pl (int I, int J, int K) {
+ for (unsigned int n=0; n<sbParameters.size (); n++) {
+ if (sbParameters[n]->I == I && sbParameters[n]->J == J && sbParameters[n]->K == K){
+ return n;
+ }
+ }
+// cout <<"could not retrieve sb informations for atom types "<<I<<" , "<<J<<" && "<<K<<endl;
+ return -1;
+}
+
+int MMFF::get_sb2_pl (int RI, int RJ, int RK) {
+ // cout<<RI<<" "<<RJ<<" "<<RK<<endl;
+ for (unsigned int n=0; n<sb2Parameters.size (); n++) {
+ if (sb2Parameters[n]->I == RI && sb2Parameters[n]->J == RJ && sb2Parameters[n]->K == RK){
+ return n;
+ }
+ }
+ for (unsigned int n=0; n<sb2Parameters.size (); n++) {
+ if (sb2Parameters[n]->I == RK && sb2Parameters[n]->J == RJ && sb2Parameters[n]->I == RI){
+ return n;
+ }
+ }
+
+ cout <<"could not retrieve sb2 informations for rows "<<RI<<" , "<<RJ<<" && "<<RK<<endl;
+ return -1;
+}
+
+
+int MMFF::get_to_pl (int type, int I, int J, int K, int L) {
+ for (unsigned int n=0; n<toParameters.size (); n++) {
+ if (toParameters[n]->I == I && toParameters[n]->J == J && toParameters[n]->K == K && toParameters[n]->L == L && toParameters[n]->type==type){
+ return n;
+ }
+ }
+ for (unsigned int n=0; n<toParameters.size (); n++) {
+ if (toParameters[n]->I == 0 && toParameters[n]->J == J && toParameters[n]->K == K && toParameters[n]->L == L && toParameters[n]->type==type){
+ return n;
+ }
+ }
+ for (unsigned int n=0; n<toParameters.size (); n++) {
+ if (toParameters[n]->I == I && toParameters[n]->J == J && toParameters[n]->K == K && toParameters[n]->L == 0 && toParameters[n]->type==type){
+ return n;
+ }
+ }
+ for (unsigned int n=0; n<toParameters.size (); n++) {
+ if (toParameters[n]->I == 0 && toParameters[n]->J == J && toParameters[n]->K == K && toParameters[n]->L == 0 && toParameters[n]->type==type){
+ return n;
+ }
+ }
+ // cout <<"could not retrieve to informations for atom types "<<I<<" , "<<J<<" , "<<K<<" && "<<L<<endl;
+ return -1;
+}
+
+int MMFF::get_op_pl (int I, int J, int K, int L) {
+ for (unsigned int n=0; n<opParameters.size (); n++) {
+ if (opParameters[n]->I == I && opParameters[n]->J == J && opParameters[n]->K == K && opParameters[n]->L == L){
+ return n;
+ }
+ }
+ for (unsigned int n=0; n<opParameters.size (); n++) {
+ if (opParameters[n]->I == 0 && opParameters[n]->J == J && opParameters[n]->K == 0 && opParameters[n]->L == 0){
+ return n;
+ }
+ }
+ cout <<"could not retrieve op informations for atom types "<<I<<" , "<<J<<" , "<<K<<" && "<<L<<endl;
+ return 0;
+}
+
+
+int MMFF::get_vw_pl (int I) {
+ for (unsigned int n=0; n<vwParameters.size (); n++) {
+ if (vwParameters[n]->I == I){
+ return n;
+ }
+ }
+ cout <<"could not retrieve vw informations for atom type "<<I<<endl;
+ return 0;
+}
+
+
+
+
+bool MMFF::get_linear (int J) {
+ for (unsigned int i=0; i< atomParameters.size (); i++) {
+ if (atomParameters[i]->type == J) return atomParameters[i]->linear;
+ }
+ return false;
+ }
+
+bool MMFF::get_sbmb (int J) {
+ for (unsigned int i=0; i< atomParameters.size (); i++) {
+ if (atomParameters[i]->type == J) return atomParameters[i]->multipleBond;
+ }
+ return false;
+ }
+
+
+bool MMFF::get_arom (int J) {
+ for (unsigned int i=0; i< atomParameters.size (); i++) {
+ if (atomParameters[i]->type == J) return atomParameters[i]->aromatic;
+ }
+ return false;
+ }
+
+
+
+
+/*
+double MMFF::get_bs_kb (int I, int J) {
+ for (unsigned int n=0; n<bsParameters.size (); n++) {
+// cout<< bsParameters[n]->J <<" "<<bsParameters[n]->J<<endl;
+ if (bsParameters[n]->I == I && bsParameters[n]->J == J) {
+ return bsParameters[n]->kb;
+ }
+ }
+ cout <<"could not retrieve bs Kb for atom types "<<I<<" && "<<J<<endl;
+ return 0;
+}
+
+double MMFF::get_bs_r0 (int I, int J) {
+ for (unsigned int n=0; n<bsParameters.size (); n++) {
+ if (bsParameters[n]->I != I) continue;
+ if (bsParameters[n]->J != J) continue;
+ return bsParameters[n]->r0;
+ }
+}
+*/
+
+
+/*
+double MMFF::get_ab_theta0 (int I, int J, int K) {
+ for (unsigned int n=0; n<abParameters.size (); n++) {
+ if (abParameters[n]->I == I && abParameters[n]->J == J && abParameters[n]->K != K) {
+ return abParameters[n]->theta0;
+ }
+ }
+ cout <<"could not retrieve ab theta0 for atom types "<<I<<" , "<<J<<" && "<<K<<endl;
+ return 0;
+}
+
+double MMFF::get_ab_ka (int I, int J, int K) {
+ for (unsigned int n=0; n<abParameters.size (); n++) {
+ if (abParameters[n]->I == I && abParameters[n]->J == J && abParameters[n]->K != K) {
+ return abParameters[n]->ka;
+ }
+ }
+ cout <<"could not retrieve ab ka for atom types "<<I<<" , "<<J<<" && "<<K<<endl;
+ return 0;
+}
+
+*/
+
+
+void MMFF::empiric_to_parameters (Atom *at1, Atom *at2, Atom *at3, Atom *at4, float& v1, float &v2, float &v3) {
+/*
+ MMFFatomParameter *an1, *an2, *an3, *an4;
+
+ an1 = atomParameters[get_atype_line (at1->MMFFtype)];
+ an2 = atomParameters[get_atype_line (at2->MMFFtype)];
+ an3 = atomParameters[get_atype_line (at3->MMFFtype)];
+ an4 = atomParameters[get_atype_line (at4->MMFFtype)];
+ ZNBond *cb = at2 -> GetBond (at3);
+ bool arom;
+ if (!cb) arom = false;
+ else (arom = cb->IsAromatic ());
+ bool bo;
+ if (!cb) bo = 0;
+ else (bo = cb->GetBO ());
+
+
+ if (an2->linear || an3->linear) {
+ v1 = 0;
+ v2 = 0;
+ v3 = 0;
+ }
+ else if ((an2->aromatic && an3->aromatic && arom) || (bo ==2)) {
+ float b, p, Uj, Uk;
+ if (!an2->lonePairs && !an3->lonePairs) p = 0.5;
+ else p = 0.3;
+ if (bo==2) p = 0.4;
+ if (bo==2 && an2->multipleBond==2 && an3->multipleBond==2) p = 1;
+
+ if ((an3->valence ==3 && an2->valence ==4) || (an2->valence ==3 && an3->valence ==4)) b = 3;
+ else b=6;
+ if (bo==2) b = 6;
+ if (at2->GetAtomicNum () == 6 || at2->GetAtomicNum () == 7 || at2->GetAtomicNum () == 8) Uj = 2.0;
+ else Uj = 1.25;
+ if (at3->GetAtomicNum () == 6 || at3->GetAtomicNum () == 7 || at3->GetAtomicNum () == 8) Uj = 2.0;
+ else Uk = 1.25;
+ v1 = 0;
+ v2 = b*p*sqrt (Uj*Uk);
+ v3 = 0;
+ }
+ else if (an2->crd ==4 || an3->crd == 4) {
+ int n = 9;
+ float Vj, Vk;
+ bool no_v3 = false;
+ if (an2->crd == 4 && an3->crd == 3 && ((an3->valence ==4 || an3->valence==34) || an3->multipleBond)) no_v3=true;
+ else if (an3->crd == 4 && an2->crd == 3 && ((an2->valence ==4 || an2->valence==34) || an2->multipleBond)) no_v3=true;
+ else if (an2->crd ==4 && an3->crd==2 && (an3->valence==3 || an3->multipleBond)) no_v3=true;
+ else if (an3->crd ==4 && an2->crd==2 && (an2->valence==3 || an2->multipleBond)) no_v3=true;
+
+ if (at2->GetAtomicNum () ==6) Vj = 2.12;
+ else if (at2->GetAtomicNum () ==7) Vj = 1.5;
+ else if (at2->GetAtomicNum () ==8) Vj = 0.2;
+ else if (at2->GetAtomicNum () ==14) Vj = 1.22;
+ else if (at2->GetAtomicNum () ==15) Vj = 2.4;
+ else Vj = 0.49;
+
+ if (at3->GetAtomicNum () ==6) Vk = 2.12;
+ else if (at3->GetAtomicNum () ==7) Vk = 1.5;
+ else if (at3->GetAtomicNum () ==8) Vk = 0.2;
+ else if (at3->GetAtomicNum () ==14) Vk = 1.22;
+ else if (at3->GetAtomicNum () ==15) Vk = 2.4;
+ else Vk = 0.49;
+ v1=0;
+ v2 = 0;
+ if (!no_v3) v3 = sqrt (Vj*Vk)/n;
+ else v3 = 0;
+ }
+ else if (bo ==1 && ((an2->multipleBond && an3->multipleBond) || (an2->multipleBond && an3->lonePairs) || (an3->multipleBond && an2->lonePairs))) {
+ bool no_v = false;
+ float b, p, Uj, Uk;
+ if (an2->lonePairs && an3->lonePairs) no_v = true;
+ else if ((an2->lonePairs && an3->multipleBond) || (an3->lonePairs && an2->multipleBond) ) {
+ b=6;
+ if (an2->multipleBond && an3->multipleBond) p = 0.5;
+ else if (at2->GetAtomicNum ()>8 || at3->GetAtomicNum ()>8) p = 0.15;
+ else p=0.3;
+ }
+
+ else if ((an2->multipleBond || an3->multipleBond) && (at1->GetAtomicNum ()!=6 || at2->GetAtomicNum ()!=6)) {
+ b = 6;
+ p = 0.4;
+ }
+ else{
+ b =6;
+ p = 0.15;
+ }
+ if (at2->GetAtomicNum () == 6 || at2->GetAtomicNum () == 7 || at2->GetAtomicNum () == 8) Uj = 2.0;
+ else Uj = 1.25;
+ if (at3->GetAtomicNum () == 6 || at3->GetAtomicNum () == 7 || at3->GetAtomicNum () == 8) Uj = 2.0;
+ else Uk = 1.25;
+ v1 = 0;
+ if (!no_v) v2 = b*p*sqrt (Uj*Uk);
+ else v2 =0;
+ v3 = 0;
+
+ }
+ else {
+ if ((at2->GetAtomicNum () == 8 || at2->GetAtomicNum () == 16) && (at3->GetAtomicNum () == 8 || at3->GetAtomicNum () == 16)) {
+ float Wj, Wk;
+ Wj = 8.;
+ Wk = 8.;
+ if (at2->GetAtomicNum () ==8) Wj = 2.;
+ if (at3->GetAtomicNum () ==8) Wk = 2.;
+ v1 =0;
+ v2=-sqrt(Wj*Wk);
+ v3 = 0;
+ }
+ else {
+ float Vj, Vk;
+ int n = (an2->crd-1)*(an3->crd-1);
+ if (at2->GetAtomicNum () ==6) Vj = 2.12;
+ else if (at2->GetAtomicNum () ==7) Vj = 1.5;
+ else if (at2->GetAtomicNum () ==8) Vj = 0.2;
+ else if (at2->GetAtomicNum () ==14) Vj = 1.22;
+ else if (at2->GetAtomicNum () ==15) Vj = 2.4;
+ else Vj = 0.49;
+
+ if (at3->GetAtomicNum () ==6) Vk = 2.12;
+ else if (at3->GetAtomicNum () ==7) Vk = 1.5;
+ else if (at3->GetAtomicNum () ==8) Vk = 0.2;
+ else if (at3->GetAtomicNum () ==14) Vk = 1.22;
+ else if (at3->GetAtomicNum () ==15) Vk = 2.4;
+ else Vk = 0.49;
+ v1=0;
+ v2 = 0;
+ v3 = sqrt (Vj*Vk)/n;
+
+ }
+ }
+*/
+}
+
+
+
+
+
+
+
+double MMFF::get_vdw_e (Atom *at1, Atom *at2) {
+
+ int I = get_MMFFtype (at1);
+ int J = get_MMFFtype (at2);
+ int pli = get_vw_pl (I);
+ int plj = get_vw_pl (J);
+
+ double Gi = vwParameters [pli] -> G;
+ double Gj = vwParameters [plj] -> G;
+ double ai = vwParameters [pli] -> alpha;
+ double aj = vwParameters [plj] -> alpha;
+ double Ni = vwParameters [pli] -> N;
+ double Nj = vwParameters [plj] -> N;
+ double r0 = get_vdw_r0 (at1, at2);
+ return (181.16*Gi*Gj*ai*aj) / ((pow((ai/Ni),0.5)+pow((aj/Nj),0.5))*pow(r0,6));
+
+}
+
+
+double MMFF::get_vdw_r0 (Atom *at1, Atom *at2) {
+
+ double DARAD = 0.8;
+ double B = 0.2;
+ double beta = 12.;
+ int I = get_MMFFtype (at1);
+ int J = get_MMFFtype (at2);
+ int pli = get_vw_pl (I);
+ if ((at1->IsPolarHydrogen ()) || (at2->IsPolarHydrogen ())) B = 0;
+ double Ai = vwParameters [pli] -> A;
+ double ai = vwParameters [pli] -> alpha;
+ double r0ii = Ai*pow(ai,0.25);
+ double scale = 1;
+
+ if (I == J) return r0ii;
+ else {
+ int plj = get_vw_pl (J);
+ if ((vwParameters[pli]->DA ==ACCEPTOR && vwParameters[plj]->DA ==DONOR) || (vwParameters[plj]->DA ==ACCEPTOR && vwParameters[pli]->DA ==DONOR)) scale = DARAD;
+ double Aj = vwParameters [plj] -> A;
+ double aj = vwParameters [plj] -> alpha;
+ double r0jj = Aj*pow (aj,0.25);
+ double gamma = (r0ii-r0jj) / (r0ii + r0jj);
+ return 0.5*(r0ii + r0jj)*(1 + B* (1- exp (- beta * gamma*gamma)))*scale;
+ }
+}
+
+int MMFF::get_pt_row (int an) {
+ if (an<2) return 0;
+ else if (an < 12) return 1;
+ else if (an <20) return 2;
+ else if (an <38) return 3;
+ else return 4;
+
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void MMFF::load_internal_interactions (vector <ForceFieldInteraction *> *vect = 0) {
+ clear_internal_interactions ();
+ ZNMolecule *mol = target_mol;
+
+//bond stretchings
+ FOR_BONDS_OF_MOL (bond, mol) {
+ MMFFbsInteraction *bsint = new MMFFbsInteraction;
+ int I = get_MMFFtype (bond->GetBeginAtom ());
+ int J = get_MMFFtype (bond->GetEndAtom ());
+ if (J<I) {
+ bsint->at1 = bond->GetEndAtom ();
+ bsint->at2 = bond->GetBeginAtom ();
+ }
+ else {
+ bsint->at1 = bond->GetBeginAtom ();
+ bsint->at2 = bond->GetEndAtom ();
+ }
+ I = get_MMFFtype (bsint->at1);
+ J = get_MMFFtype (bsint->at2);
+ bsint->type = getBondType (bsint ->at1, bsint ->at2);
+ int pl = get_bs_pl (bsint->type, I, J);
+ bsint->kb = bsParameters[pl] -> kb;
+ bsint->r0 = bsParameters[pl] -> r0;
+ if (vect) vect -> push_back (bsint);
+
+ else bsInteractions.push_back (bsint);
+ // cerr << "adding BS interaction "<<endl;
+
+ }
+
+
+
+//angle interactions
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (CountBonds (&*a) >1) {
+ FOR_NBORS_OF_ATOM (n1, &*a) {
+ FOR_NBORS_OF_ATOM (n2, &*a) {
+ if (n1 -> GetIdx () < n2 -> GetIdx ()) {
+ MMFFabInteraction *abint = new MMFFabInteraction;
+ abint->at2 = &*a;
+ ZNBond *bondij, *bondjk;
+ if (get_MMFFtype (&*n1) < get_MMFFtype (&*n2)) {
+ abint->at1 = &*n1;
+ abint->at3 = &*n2;
+ bondij = a -> GetBond (&*n1);
+ bondjk = a -> GetBond (&*n2);
+ }
+ else {
+ abint->at1 = &*n2;
+ abint->at3 = &*n1;
+ bondij = a -> GetBond (&*n2);
+ bondjk = a -> GetBond (&*n1);
+ }
+ abint->type = getAngleType (abint ->at1, abint ->at2, abint ->at3);
+
+
+ int I = get_MMFFtype (abint->at1);
+ int J = get_MMFFtype (abint->at2);
+ int K = get_MMFFtype (abint->at3);
+
+
+ int abpl = get_ab_pl (abint->type, I, J, K);
+ abint->ka = abParameters[abpl]->ka;
+ abint->theta0 = abParameters[abpl]->theta0;
+ abint->linear = get_linear (get_MMFFtype (abint->at2));
+
+ if (vect) vect -> push_back (abint);
+ else abInteractions.push_back (abint);
+
+//stretch-bend
+ MMFFsbInteraction *sbint = new MMFFsbInteraction;
+ sbint->at1 =abint->at1;
+ sbint->at2 =abint->at2;
+ sbint->at3 =abint->at3;
+
+ sbint->theta0 = abint->theta0;
+ // cerr << "adding AB interaction "<<endl;
+
+
+
+ int sbpl = get_sb_pl (I, J, K);
+ if (sbpl != -1) {
+ sbint->kijk = sbParameters[sbpl]->kijk;
+ sbint->kkji = sbParameters[sbpl]->kkji;
+
+ }
+ else {
+ int sb2pl = get_sb2_pl (get_pt_row (abint->at1->GetAtomicNum ()), get_pt_row (abint->at2->GetAtomicNum ()),get_pt_row (abint->at3->GetAtomicNum ()));
+ if (sb2pl == -1) sb2pl = 1;
+ sbint->kijk = sb2Parameters[sb2pl]->kijk;
+ sbint->kkji = sb2Parameters[sb2pl]->kkji;
+ }
+ int typeij, typejk;
+ if (bondij->GetBO () ==1) typeij = get_bond_type (I, J);
+ else typeij = 0;
+ if (bondjk->GetBO () ==1) typejk = get_bond_type (K, J);
+ else typejk = 0;
+
+ int ijbspl=0, kjbspl=0;
+ if (J < I) ijbspl = get_bs_pl (typeij, J, I);
+ else ijbspl = get_bs_pl (typeij, I, J);
+
+ if (K < J) kjbspl = get_bs_pl (typeij, K, J);
+ else kjbspl = get_bs_pl (typejk, J, K);
+
+ sbint->r0ij = bsParameters[ijbspl]->r0;
+ sbint->r0kj = bsParameters[kjbspl]->r0;
+
+ if (vect) vect -> push_back (sbint);
+ else sbInteractions.push_back (sbint);
+ }
+ }
+ }
+ }
+ }
+
+//OOP interactions
+ Atom *at1, *at2, *at3, *at4;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (CountBonds (&*a) == 3) {
+ Atom *n1= NULL, *n2= NULL, *n3= NULL;
+ int nn =0;
+ FOR_NBORS_OF_ATOM (n, &*a) {
+ nn++;
+ if (nn == 1) n1 = &*n;
+ else if (nn ==2) n2 = &*n;
+ else n3 = &*n;
+ }
+ assert (n1); assert (n2); assert (n3);
+ int t1 = get_MMFFtype (n1);
+ int t2 = get_MMFFtype (n2);
+ int t3 = get_MMFFtype (n3);
+ int ta = get_MMFFtype (&*a);
+ if (t1 >= t2 && t1 >= t3) {
+ if (t2 > t3) {
+ at1 = n3;
+ at2 = &*a;
+ at3 = n2;
+ at4 = n1;
+ }
+ else {
+ at1 = n2;
+ at2 = &*a;
+ at3 = n3;
+ at4 = n1;
+ }
+ }
+ else if (t2 >= t1 && t2 >= t3) {
+ if (t1 > t3) {
+ at1 = n3;
+ at2 = &*a;
+ at3 = n1;
+ at4 = n2;
+ }
+ else {
+ at1 = n1;
+ at2 = &*a;
+ at3 = n3;
+ at4 = n2;
+ }
+
+ }
+ else {
+ if (t1 > t2) {
+ at1 = n2;
+ at2 = &*a;
+ at3 = n1;
+ at4 = n3;
+ }
+ else {
+ at1 = n1;
+ at2 = &*a;
+ at3 = n2;
+ at4 = n3;
+ }
+
+ }
+ int pl = get_op_pl (get_MMFFtype (at1), get_MMFFtype (at2),get_MMFFtype (at3),get_MMFFtype (at4));
+ double koop = opParameters[pl]->koop;
+ MMFFopInteraction *opint = new MMFFopInteraction;
+ opint->at1 = at1;
+ opint->at2 = at2;
+ opint->at3 = at3;
+ opint->at4 = at4;
+ opint->koop = koop;
+ if (vect) vect -> push_back (opint);
+ else opInteractions.push_back (opint);
+
+ opint = new MMFFopInteraction;
+ opint->at1 = at1;
+ opint->at2 = at2;
+ opint->at3 = at4;
+ opint->at4 = at3;
+ opint->koop = koop;
+ if (vect) vect -> push_back (opint);
+ else opInteractions.push_back (opint);
+
+ opint = new MMFFopInteraction;
+ opint->at1 = at3;
+ opint->at2 = at2;
+ opint->at3 = at4;
+ opint->at4 = at1;
+ opint->koop = koop;
+ if (vect) vect -> push_back (opint);
+ else opInteractions.push_back (opint);
+ }
+ }
+//torsions
+
+
+ FOR_TORSIONS_OF_MOL(t, mol) {
+ MMFFtoInteraction *toint = new MMFFtoInteraction;
+ Atom *a, *b, *c, *d;
+ a = mol -> GetAtom((*t)[0] + 1);
+ b = mol -> GetAtom((*t)[1] + 1);
+ c = mol -> GetAtom((*t)[2] + 1);
+ d = mol -> GetAtom((*t)[3] + 1);
+ int atn1 = get_MMFFtype (a);
+ int atn2 = get_MMFFtype (b);
+ int atn3 = get_MMFFtype (c);
+ int atn4 = get_MMFFtype (d);
+
+ if (atn3==atn2) {
+ if (atn4 < atn1) {
+ toint->at1 = d;
+ toint->at4 = a;
+ toint->at2 = c;
+ toint->at3 = b;
+ }
+ else {
+ toint->at1 = a;
+ toint->at4 = d;
+ toint->at2 = b;
+ toint->at3 = c;
+ }
+ }
+ else if (atn2<atn3) {
+ toint->at1 = a;
+ toint->at4 = d;
+ toint->at2 = b;
+ toint->at3 = c;
+ }
+ else {
+ toint->at1 = d;
+ toint->at4 = a;
+ toint->at2 = c;
+ toint->at3 = b;
+ }
+ int type = 0;
+ //mancano tutti i torsion type
+ toint->type = type;
+ int pl = get_to_pl (toint->type, get_MMFFtype (toint->at1), get_MMFFtype (toint->at2), get_MMFFtype (toint->at3), get_MMFFtype (toint->at4)); //parameters line
+ float V1, V2, V3;
+ if (pl!=-1) {
+ V1 = toParameters[pl]->V1;
+ V2 = toParameters[pl]->V2;
+ V3 = toParameters[pl]->V3;
+ }
+ else {
+ empiric_to_parameters (toint->at1,toint->at2,toint->at3,toint->at4,V1, V2, V3);
+ }
+ toint->v1 = V1;
+ toint->v2 = V2;
+ toint->v3 = V3;
+ if (vect) vect -> push_back (toint);
+ else toInteractions.push_back (toint);
+
+ }
+
+//nonbonded interactions
+ FOR_ATOMS_OF_MOL (a1, mol) {
+ FOR_ATOMS_OF_MOL (a2, mol) {
+ if (a1->GetIdx () < a2 -> GetIdx ()) {
+
+ unsigned int distance = 5;
+ Atom *at1 = &*a1;
+ Atom *at2 = &*a2;
+
+ //chech for 1-2 interactions
+ FOR_NBORS_OF_ATOM (n1, at1) {
+ if (&*n1 == at2) {
+ distance = 2;
+ }
+ //check for 1-3 interactions
+ FOR_NBORS_OF_ATOM (n2, &*n1) {
+ if (&*n2 == at2 && distance>3) {
+ distance = 3;
+ }
+ FOR_NBORS_OF_ATOM (n3, &*n2) {
+ if (&*n3 ==at2 && distance>4) {
+ distance = 4;
+ }
+ }
+ }
+ }
+
+ if (distance >3) {
+ MMFFvwInteraction *vwint = new MMFFvwInteraction;
+ vwint -> at1 = at1;
+ vwint -> at2 = at2;
+ vwint -> e = get_vdw_e (vwint->at1, vwint->at2);
+ vwint -> r0 = get_vdw_r0 (vwint->at1, vwint->at2);
+ if (vect) vect -> push_back (vwint);
+ else vwInteractions.push_back (vwint);
+
+ MMFFelInteraction *elint = new MMFFelInteraction;
+ elint->at1 = at1;
+ elint->at2 = at2;
+ if (distance ==4) elint->scale = 0.75;
+ else elint->scale =1;
+ if (vect) vect -> push_back (elint);
+ else elInteractions.push_back (elint);
+
+ }
+ }
+ }
+ }
+
+}
+
+int MMFF::load_aromatic_parameters () {
+
+ QFile file (":parameters/MMFFAROM.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read aromatic parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFaromaticParameter *param = new MMFFaromaticParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->old_type ;
+ liness >> param->arom_type ;
+ liness >> param->at_number ;
+ liness >> param->ring_size ;
+ liness >> param->L5 ;
+ liness >> param->IMCAT ;
+ liness >> param->N5ANION ;
+ aromaticParameters.push_back(param) ;
+ }
+ }
+ if (aromaticParameters.size ()) return 1;
+ return 0;
+}
+
+
+
+int MMFF::load_ci_parameters () {
+
+ QFile file (":parameters/MMFFCHG.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read ci parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFciParameter *param = new MMFFciParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->type ;
+ liness >> param->I ;
+ liness >> param->J ;
+ liness >> param->increment ;
+ ciParameters.push_back(param);
+ }
+ }
+ if (ciParameters.size ()) return 1;
+ return 0;
+}
+
+int MMFF::load_H_parameters () {
+
+ QFile file (":parameters/MMFFHDEF.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read H parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFHParameter *param = new MMFFHParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->parent ;
+ liness >> param->strin ;
+ HParameters.push_back(param);
+
+ }
+ }
+ if (HParameters.size ()) return 1;
+ return 0;
+}
+
+
+int MMFF::load_atype_parameters () {
+
+ QFile file (":parameters/MMFFSYMB.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read atype parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFatypeParameter *param = new MMFFatypeParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->strin ;
+ liness >> param->number ;
+ param->description = liness.str();
+ atypeParameters.push_back(param);
+
+ }
+ }
+ if (atypeParameters.size ()) return 1;
+ return 0;
+}
+
+
+
+
+int MMFF::load_atom_parameters () {
+
+ QFile file (":parameters/MMFFPROP.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read atom parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFatomParameter *param = new MMFFatomParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->type ;
+ liness >> param->atomicNumber ;
+ liness >> param->crd ;
+ liness >> param->valence ;
+ liness >> param->lonePairs ;
+ liness >> param->mltb ;
+ liness >> param->aromatic ;
+ liness >> param->linear ;
+ liness >> param->multipleBond ;
+ atomParameters.push_back(param);
+
+ }
+ }
+ if (atomParameters.size ()) return 1;
+ return 0;
+}
+
+
+int MMFF::load_ab_parameters () {
+
+
+
+ QFile file (":parameters/MMFFANG.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read ab parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFabParameter *param = new MMFFabParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->type ;
+ liness >> param->I ;
+ liness >> param->J ;
+ liness >> param->K ;
+ liness >> param->ka ;
+ liness >> param->theta0 ;
+ abParameters.push_back(param);
+ }
+ }
+ if (abParameters.size ()) return 1;
+ return 0;
+}
+
+
+int MMFF::load_bs_parameters () {
+
+
+ QFile file (":parameters/MMFFBOND.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read bs parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+
+
+
+ MMFFbsParameter *param = new MMFFbsParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->type ;
+ liness >> param->I ;
+ liness >> param->J ;
+ liness >> param->kb ;
+ liness >> param->r0 ;
+ bsParameters.push_back(param) ;
+ }
+ }
+ if (bsParameters.size ()) return 1;
+ return 0;
+}
+
+
+
+int MMFF::load_sb_parameters () {
+
+
+
+ QFile file (":parameters/MMFFSTBN.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read sb parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFsbParameter *param = new MMFFsbParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ liness >> param->I ;
+ liness >> param->J ;
+ liness >> param->K ;
+ liness >> param->kijk ;
+ liness >> param->kkji ;
+ sbParameters.push_back(param) ;
+ }
+ }
+ if (sbParameters.size ()) return 1;
+ return 0;
+}
+
+int MMFF::load_sb2_parameters () {
+
+
+ QFile file (":parameters/MMFFDFSB.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read sb2 parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+
+ MMFFsbParameter *param = new MMFFsbParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->I ;
+ liness >> param->J ;
+ liness >> param->K ;
+ liness >> param->kijk ;
+ liness >> param->kkji ;
+ sb2Parameters.push_back(param) ;
+ }
+ }
+ if (sb2Parameters.size ()) return 1;
+ return 0;
+}
+
+int MMFF::load_to_parameters () {
+
+ QFile file (":parameters/MMFFTOR.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read to parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+
+
+ MMFFtoParameter *param = new MMFFtoParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->type ;
+ liness >> param->I ;
+ liness >> param->J ;
+ liness >> param->K ;
+ liness >> param->L ;
+ liness >> param->V1 ;
+ liness >> param->V2 ;
+ liness >> param->V3 ;
+ toParameters.push_back(param) ;
+ }
+ }
+ if (toParameters.size ()) return 1;
+ return 0;
+
+}
+
+
+int MMFF::load_vw_parameters () {
+
+ QFile file (":parameters/MMFFVDW.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read vw parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFvwParameter *param = new MMFFvwParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param->I ;
+ liness >> param->alpha ;
+ liness >> param->N ;
+ liness >> param->A ;
+ liness >> param->G ;
+ char da;
+ liness >> da;
+ if (da == 'A') param->DA = ACCEPTOR;
+ else if (da == 'D') param->DA = DONOR;
+ else param->DA = NEITHER;
+ vwParameters.push_back(param) ;
+ }
+ }
+ if (vwParameters.size ()) return 1;
+ return 0;
+}
+
+int MMFF::load_op_parameters () {
+
+ QFile file (":parameters/MMFFOOP.PAR");
+ if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
+ cerr << "unable to read op parameters"<<endl;
+ return 0;
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ istringstream liness (string (line.toStdString ()));
+ MMFFopParameter *param = new MMFFopParameter;
+ string first;
+ liness >> first;
+ if (first != "*") {
+ istringstream conv (first);
+ conv >> param -> I ;
+ liness >> param -> J ;
+ liness >> param -> K ;
+ liness >> param -> L ;
+ liness >> param -> koop ;
+ opParameters.push_back(param) ;
+ }
+ }
+ if (opParameters.size ()) return 1;
+ return 0;
+}
+
+void MMFF::clear_internal_interactions () {
+ for (unsigned int i=0; i<vwInteractions.size(); i++) delete vwInteractions[i];
+ for (unsigned int i=0; i<elInteractions.size(); i++) delete elInteractions[i];
+ for (unsigned int i=0; i<bsInteractions.size(); i++) delete bsInteractions[i];
+ for (unsigned int i=0; i<abInteractions.size(); i++) delete abInteractions[i];
+ for (unsigned int i=0; i<toInteractions.size(); i++) delete toInteractions[i];
+ for (unsigned int i=0; i<sbInteractions.size(); i++) delete sbInteractions[i];
+ for (unsigned int i=0; i<opInteractions.size(); i++) delete opInteractions[i];
+
+ bsInteractions.clear ();
+ abInteractions.clear ();
+ toInteractions.clear ();
+ vwInteractions.clear ();
+ opInteractions.clear ();
+ elInteractions.clear ();
+ sbInteractions.clear ();
+
+}
+
+
+
+void MMFF::clear_nonbonded_interactions () {
+ for (unsigned int i=0; i<vwNBInteractions.size (); i++) delete vwNBInteractions[i];
+ for (unsigned int i=0; i<elNBInteractions.size (); i++) delete elNBInteractions[i];
+ vwNBInteractions.clear ();
+ elNBInteractions.clear ();
+}
+
+
+
+void MMFF::load_nonbonded_interactions_for_atom (Atom *a, queue <ForceFieldInteraction *> *queue = 0) {
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(get_coordinates (&*a));
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms -> objects;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ assert (a != neighbours[j]);
+ MMFFelInteraction *elint = new MMFFelInteraction;
+ elint -> at1 = a;
+ elint -> at2 = neighbours[j];
+ elint -> scale = 1.f;
+ if (queue) queue -> push (elint);
+ else elNBInteractions.push_back (elint);
+ }
+ }
+ objectList<Atom*>* nbAtoms2 = near_grid->getNeighborObjects(get_coordinates (&*a));
+ if (nbAtoms2) {
+ vector <Atom *> neighbours2 = nbAtoms2 -> objects;
+ for (unsigned int j=0; j<neighbours2.size (); j++) {
+ assert (a != neighbours2[j]);
+ MMFFvwInteraction *vwint = new MMFFvwInteraction;
+ vwint->at1 = a;
+ vwint->at2 = neighbours2[j];
+ vwint -> e = get_vdw_e (vwint->at1, vwint->at2);
+ vwint -> r0 = get_vdw_r0 (vwint->at1, vwint->at2);
+ // vwint->scale =1;
+ if (queue) queue -> push (vwint);
+ else vwNBInteractions.push_back (vwint);
+ }
+ }
+}
+
+
+
+
+void MMFF::load_nonbonded_interactions () {
+
+ clear_nonbonded_interactions ();
+ assert (target_mol);
+ ZNMolecule *mol = target_mol;
+ FOR_ATOMS_OF_MOL (a, target_mol) {
+ load_nonbonded_interactions_for_atom (&*a);
+ }
+}
+
+
+//_________________________________________________________________________________________________
+//_________________________________________________________________________________________________
+
+double MMFF::compute_charge (Atom *at) {
+
+ return std::numeric_limits<double>::signaling_NaN();
+
+/*
+ double q = at->MMFFstartcharge;
+ FOR_NBORS_OF_ATOM (a, at) {
+ q+= get_charge_increment (a->MMFFtype, at->MMFFtype);
+ }
+ return q;
+*/
+}
+
+void MMFF::get_strings_mol (ZNMolecule*mol) {
+/*
+ FOR_ATOMS_OF_MOL (mol, a) {
+ a->MMFFstring = getMMFFcarbonstring (a);
+ }
+ FOR_ATOMS_OF_MOL (mol, a) {
+ a->MMFFstring = getMMFFeteroatomstring (a);
+ }
+
+ for (unsigned int r=0; r<mol->rings.size (); r++ ) {
+ if (mol->rings[r]->aromatic) {
+ for (unsigned int i=0; i<mol->rings[r]->atoms.size (); i++ ) {
+ mol->rings[r]->atoms[i]->MMFFstring = get_aromatic_string (mol->rings[r]->atoms[i]);
+ }
+ }
+ }
+ for (unsigned int i=0; i<mol->atoms.size (); i++ ) {
+ if (mol->atoms[i]->GetAtomicNum ()==1) mol->atoms[i]->MMFFstring = getMMFFHstring (mol->atoms[i]);
+ }
+*/
+}
+
+void MMFF::compute_partial_charges (ZNMolecule *mol){
+/*
+ FOR_ATOMS_OF_MOL (a, mol) {
+ a -> MMFFstartcharge = getMMFFstartcharge (&*a);
+ }
+ FOR_ATOMS_OF_MOL (a, mol) {
+ a -> SetPartialCharge (compute_charge (&*a));
+ }
+*/
+}
+
+
+
+void MMFF::initialize_mol (ZNMolecule *mol) {
+/*
+ get_strings_mol (mol);
+
+ FOR_ATOMS_OF_MOL (a, mol) {
+ a -> MMFFtype = getMMFFtype (&*a);
+ }
+
+ compute_partial_charges (mol);
+*/
+}
+
+
+double MMFF::getMMFFstartcharge (Atom *at) {
+
+ return std::numeric_limits<double>::signaling_NaN();
+
+/*
+ double q = 0;
+ switch (at->MMFFtype) {
+ case 32:
+ if (at->MMFFstring=="O4CL") q= -0.25;
+ else if (at->MMFFstring=="OSMS") q= -0.5;
+ break;
+ case 55:
+ q = 0.5;
+ break;
+ case 56:
+ q = 1. /3.;
+ break;
+ case 58:
+ q = 1.;
+ break;
+ case 61:
+ if (at->bonded_to (-2, 7)) q = 1.;
+ break;
+ case 62:
+ q = -1.;
+ break;
+ case 72:
+ if (at->MMFFstring=="SM") q = -1.;
+ break;
+ case 81:
+ if (at->MMFFstring=="NIM+") q = 0.5;
+ else q = 1.;
+ break;
+ case 90:
+ q = -1.;
+ break;
+ case 93:
+ q = 1.;
+ break;
+ }
+ return q;
+*/
+}
+
+
+string MMFF::getMMFFHstring (Atom *at) {
+
+ return "not implemented";
+
+ /* if (at->GetAtomicNum ()==1 && at->CountBonds ()) {
+ string st = at->bound[0]->MMFFstring;
+ for (unsigned int i=0; i<HParameters.size (); i++) {
+ if (st==HParameters[i]->parent) return HParameters[i]->strin;
+ }
+ }
+ return "unknown H";
+*/
+}
+
+
+
+string MMFF::getMMFFcarbonstring (Atom *at) {
+
+ return "not implemented";
+
+/* bool in_ring = at->in_ring.size()>0;
+ int ring_size = 1000;
+ bool aromatic=false;
+ for (unsigned int r=0; r<at->in_ring.size (); r++){
+ if (at->in_ring[r]->atoms.size ()< ring_size) ring_size =at->in_ring[r]->atoms.size ();
+// if (at->in_ring[r]->aromatic) aromatic = true;
+ }
+ if (at->GetAtomicNum () == 6) {
+// 1 2 3 4 20 22 30 37 41 57 60 63 64 78 80 C
+// CR 1 ALKYL CARBON, SP3
+// C=C 2 VINYLIC CARBON, SP2
+// CSP2 2 GENERIC SP2 CARBON
+// C=O 3 GENERAL CARBONYL CARBON
+// C=N 3 SP2 CARBON IN C=N
+// CGD 3 GUANIDINE CARBON, DOUBLY BONDED TO N
+// C=OR 3 KETONE || ALDEHYDE CARBONYL CARBON
+// C=ON 3 AMIDE CARBONYL CARBON
+// CONN 3 UREA CARBONYL CARBON
+// COO 3 CARBOXYLIC ACID || ESTER CARBONYL CARBON
+// COON 3 CARBAMATE CARBONYL CARBON
+// COOO 3 C ARBONIC ACID || ESTER CARBONYL CARBON
+// C=OS 3 THIOESTER CARBONYL CARBON, DOUBLE BONDED TO O
+// C=S 3 THIOESTER CARBON, DOUBLY BONDED TO S
+// C=SN 3 THIOAMIDE, CARBON, DOUBLY BONDED TO S
+// CSO2 3 CARBON IN >C=SO2
+// CS=O 3 CARBON IN >C=S=O (SULFINYL GROUP)
+// CSS 3 THIOCARBOXYLIC ACID || ESTER CARBONYL CARBON
+// C=P 3 CARBON DOUBLE BONDED TO PHOSPHOROUS
+// CSP 4 ACETYLENIC CARBON
+// =C= 4 ALLENIC CARBON
+// CR4R 20 CARBON IN 4-MEMBERED RINGS
+// CR3R 22 CARBON IN A 3-MEMBERED RING
+// CE4R 30 OLEFINIC CARBON IN 4-MEMBERED RINGS
+// CB 37 CARBON AS IN BENZENE, PYRROLE
+// CO2M 41 CARBOXYLATE ANION CARBON
+// CS2M 41 CARBON IN THIOCARBOXYLATE ANION
+// CGD+ 57 GUANIDINIUM CARBON
+// CNN+ 57 C IN +N=C-N RESONANCE STRUCTURES
+// C% 60 ISONITRILE CARBON
+// C5A 63 ALPHA CARBON IN 5-MEMBERED HETEROAROMATIC RING
+// C5B 64 BETA CARBON IN 5-MEMBERED HETEROAROMATIC RING
+// C5 78 GENERAL CARBON IN 5-MEMBERED HETEROAROMATIC RING
+// CIM+ 80 C IN N-C-N IN IMIDAZOLIUM ION
+
+ int dU = 4-at->bonds.size ();
+ //general carbon
+ if ((at->bound.size ()==1) && at->bonded_to (3, 7)) return "C%";
+ if (at->bonded_to (3, -2)) return "CSP";
+ if (at->bonded_to (2, 15)) return "C=P";
+
+ if (at->bonded_to (-2, 7)==3 && dU ==1) {
+ bool g = true;
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->bound.size ()!=3) g=false;
+ }
+ if (g) return "CGD+";
+ g = true;
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->bound.size ()!=3 && at->bonds[i]->mol2Type==1 || at->bound[i]->bound.size ()!=2 && at->bonds[i]->mol2Type==2 ) g=false;
+ }
+ if (g) return "CGD";
+
+ }
+ bool IM = false;
+ for (unsigned int r=0; r<at->in_ring.size (); r++) {
+ if (at->in_ring[r]->IM_CAT) IM=true;
+ }
+
+ if (dU ==1 && at->bonded_to (2,7)==1 && at->bonded_to (1,7) ) {
+ bool res = true;
+ bool ar1, ar2;
+ ar1 = ar2 = false;
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==7 && (at->bonds[i]->kekule==2 && at->bound[i]->bound.size ()<3)) res=false;
+ if (at->bound[i]->GetAtomicNum ()==7 && at->bonds[i]->kekule==2 && at->bonds[i]->mol2Type==5) ar1=true;
+ if (at->bound[i]->GetAtomicNum ()==7 && at->bonds[i]->mol2Type==1 && !at->bonds[i]->in_ring.size()) ar2=true;
+ }
+ if (ar1 && ar2) res=false;
+ if (res) return "CNN+";
+ }
+ if (at->bonded_to (-2, 8)==2) {
+ bool carboxilate = true;
+ for (unsigned int i=0; i<at->bound.size (); i++) {
+ if (at->bound[i]->GetAtomicNum ()==8 && at->bound[i]->bound.size()>1) carboxilate=false;
+ }
+ if (carboxilate) return "CO2M";
+ }
+ if ((at->bonded_to (-2, 16))==2) {
+ bool carboxilate = true;
+ for (unsigned int i=0; i<at->bound.size (); i++) {
+ if ((at->bound[i]->GetAtomicNum ()==16) && at->bound[i]->bound.size()>1) carboxilate=false;
+ }
+ if (carboxilate) return "CS2M";
+ }
+
+
+ if (at->bonded_to (2, -2) == 2) return "=C=";
+ if (at->bonded_to (2, 16)) {
+ if (at->bonded_to (-2, 7)) return "C=SN";
+ if (at->bonded_to (1, 16)) return "CSS";
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->bound.size ()==2 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (2, 8) && at->bound[i]->bonded_to (2, 6)) return "CS=O";
+ if (at->bound[i]->bound.size ()==3 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==2 && at->bound[i]->bonded_to (2, 6)) return "CSO2";
+ }
+ if (at->bonded_to (1, 8)) return "C=S";
+ }
+
+
+ if (at->bonded_to (2, 8)) {
+ if (at->bonded_to (1, 7) ==2 || at->bonded_to (4, 7)==2) return "CONN";
+ if (at->bonded_to (-2, 7)) return "C=ON";
+ if (at->bonded_to (1, 16)) return "C=OS";
+ if (at->bonded_to (-2, 8)==2){
+ if (at->bonded_to (-2, 7)) {
+ int termO = 0;
+ for (unsigned int i=0; i<at->bound.size (); i++) {
+ if (at->bound[i]->GetAtomicNum ()==8 && at->bound[i]->bound.size ()==1) termO+=1;
+ }
+ if (termO ==2) return "COON";
+
+ }
+ return "COO";
+ }
+ if (at->bonded_to (-2, 8)>2){
+ return "COOO";
+ }
+
+ if (at->bonded_to (1, 6)) return "C=OR";
+
+ return "C=O";
+ }
+ if (dU ==1 && at->bonded_to (2, 7)) return "C=N";
+ if (in_ring) { //general ring
+
+ if (aromatic) { //aromatic ring
+ bool boo = false;
+ for (unsigned int r=0; r<at->in_ring.size(); r++) {
+ if (at->in_ring[r]->atoms.size()==5 && at->in_ring[r]->aromatic) {
+ // Ring *ring = at->in_ring[r];
+ for (unsigned int a=0; a<at->in_ring[r]->atoms.size (); a++) {
+ if (at->in_ring[r]->atoms[a]->GetAtomicNum ()!=6 ) {
+ if ((at->in_ring[r]->atoms[a]->GetAtomicNum ()==7) && (at->in_ring[r]->atoms[a]->bound.size ()!=2)) {}
+ else boo = true;
+ }
+ }
+ }
+ }
+ if (boo) { //carbon in 5 membered eteroaromatic ring
+ if (at->in_ring.size() ==1 && at->bonded_to (-2, 7)==2) {
+ if (!at->in_ring[0]->count (8) && !at->in_ring[0]->count (16)) return "CIM+";
+ }
+
+ for (unsigned int a=0; a<at->bound.size(); a++) {
+ if (at->bound[a]->GetAtomicNum ()!=6 && at->bound[a]->in_ring.size()) {
+ if (at->bound[a]->GetAtomicNum ()==7 && !(at->bound[a]->bound.size ()==3)) {}
+ else return "C5A";
+ }
+ }
+ return "C5B";
+ return "C5";
+ }
+ return "CB";
+ }
+ else { //non aromatic ring
+ if (ring_size == 3 && dU==0) return "CR3R";
+ else if (ring_size == 4) {
+ if (dU>0) return "CE4R";
+ else return "CR4R";
+ }
+ }
+ }
+ else { //non ring carbon
+ }
+ //general carbons with no other type
+
+ if (at->bonded_to (2, 6) && dU ==1) return "C=C";
+ if (dU ==0) return "CR";
+ if (dU == 1) return "CSP2";
+
+ }
+ else return "eteroatom";
+ return "Unknown C";
+*/
+}
+
+string MMFF::getMMFFeteroatomstring (Atom *at) {
+
+ return "not implemented";
+
+/*
+// bool in_ring = at->in_ring.size()>0;
+ int ring_size = 1000;
+ bool aromatic=false;
+ for (unsigned int r=0; r<at->in_ring.size (); r++){
+ if (at->in_ring[r]->atoms.size ()< ring_size) ring_size =at->in_ring[r]->atoms.size ();
+ // if (at->in_ring[r]->aromatic) aromatic = true;
+ }
+ if (at->GetAtomicNum () == 3) {// 92 Li
+// LI+ 92 LITHIUM CATION
+ return "LI+";
+ }
+
+ if (at->GetAtomicNum () == 6) return at->MMFFstring;
+ if (at->GetAtomicNum () == 7) {// 8 9 10 34 38 39 40 42 43 45 46 47 48 53 54 55 56 58 61 62 65 66 67 68 69 76 79 81 82 N
+// NR 8 NITROGEN IN ALIPHATIC AMINES
+// N=C 9 NITROGEN IN IMINES
+// N=N 9 NITROGEN IN AZO COMPOUNDS
+// NC=O 10 NITROGEN IN AMIDES
+// NC=S 10 NITROGEN IN N-C=S, THIOAMIDE
+// NN=C 10 NITROGEN IN N-N=C
+// NN=N 10 NITROGEN IN N-N=N
+// NR+ 34 QUATERNARY NITROGEN, SP3, POSITIVELY CHARGED
+// NPYD 38 NITROGEN, AS IN PYRIDINE
+// NPYL 39 NITROGEN, AS IN PYRROLE
+// NC=C 40 NITROGEN ON N-C=C
+// NC=N 40 NITROGEN IN N-C=N
+// NC=P 40 NITROGEN IN N-C=P
+// NC%C 40 NITROGEN ATTACHED TO C-C TRIPLE BOND
+// NSP 42 NITROGEN, TRIPLE BONDED
+// NSO2 43 NITROGEN IN SULFONAMIDES
+// NSO3 43 NITROGEN IN SULFONAMIDES, THREE O'S ON S
+// NPO2 43 NITROGEN IN PHOSPHONAMIDES
+// NPO3 43 NITROGEN IN PHOSPHONAMIDES, THREE O'S ON P
+// NC%N 43 NITROGEN ATTACHED TO CYANO GROUP
+// NO2 45 NITRO GROUP NITROGEN
+// NO3 45 NITRATE GROUP NITROGEN
+// N=O 46 NITROSO NITROGEN
+// NAZT 47 TERMINAL NITROGEN IN AZIDO || DIAZO GROUP
+// NSO 48 DIVALENT NITROGEN REPLACING MONOVALENT O IN SO2 GROUP
+// =N= 53 NITROGEN IN C=N=N || -N=N=N
+// N+=C 54 POSITIVELY CHARGED IMINIUM NITROGEN
+// N+=N 54 POSITIVELY CHARGED NITROGEN DOUBLE-BONDED TO N
+// NCN+ 55 N IN +N=C-N RESONANCE STRUCTURES - FORMAL CHARGE=1/2
+// NGD+ 56 GUANIDINIUM-TYPE NITROGEN - FORMAL CHARGE=1/3
+// NPD+ 58 PYRIDINIUM-TYPE NITROGEN - FORMAL CHARGE=1
+ NR% 61 ISONITRILE NITROGEN [FC = 0] || DIAZO NITROGEN [FC = 1]
+// NM 62 DEPROTONATED SULFONAMIDE N-; FORMAL CHARGE=-1
+// N5A 65 ALPHA AROM HETEROCYCLIC 5-RING NITROGEN
+// N5B 66 BETA AROM HETEROCYCLIC 5-RING NITROGEN
+// N2OX 67 SP2-HYDRIDIZED N-OXIDE NITROGEN
+// N3OX 68 SP3-HYDRIDIZED N-OXIDE NITROGEN
+// NPOX 69 PYRIDINE N-OXIDE NITROGEN
+ N5M 76 NEGATIVELY CHARGED N IN, E.G, TRI- || TETRAZOLE ANION
+ N5 79 GENERAL NITROGEN IN 5-MEMBERED HETEROCYCLIC RING
+ NIM+ 81 IMIDAZOLIUM-TYPE NITROGEN - FORMAL CHARGE=1/2
+ N5A+ 81 POSITIVE N5A NITROGEN - FORMAL CHARGE=1
+ N5B+ 81 POSITIVE N5B NITROGEN - FORMAL CHARGE=1
+ N5+ 81 POSITIVE N5 NITROGEN - FORMAL CHARGE=1
+ N5AX 82 N-OXIDE NITROGEN IN 5-RING ALPHA POSITION
+ N5BX 82 N-OXIDE NITROGEN IN 5-RING BETA POSITION
+ N5OX 82 N-OXIDE NITROGEN IN GENERAL 5-RING POSITION
+
+ int dU = 3-at->bonds.size ();
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (2, 7) && at->bound[i]->bonded_to (-2, 8) && at->bonds[i]->kekule==2) return "NSO";
+ }
+ if (dU == 1 && at->bonded_to (2, -2)==2) return "=N=";
+ if (dU == 2 && at->bound[0]->bonded_to (2, -2)==2 && at->bound[0]->GetAtomicNum ()==7) return "NAZT";
+ for (unsigned int r=0; r<at->in_ring.size ();r++) {
+ if (at->in_ring[r]->atoms.size () ==5 && at->in_ring[r]->N5ANION) return "NM";
+ }
+ if (at->bonded_to ("CGD+")) return "NGD+";
+ if (at->bonded_to ("CNN+") && !(at->bound.size ()==2)) return "NCN+";
+
+
+ if (at->bonded_to ("C=P")) return "NC=P";
+
+
+ if (dU == 1 && at->bonded_to (2, 6)) return "N=C";
+
+ if (dU == 1 && at->bonded_to (2, 7)) return "N=N";
+ if (at->bonded_to ("C=SN") || at->bonded_to ("C=S") || at->bonded_to ("CS2M")) return "NC=S";
+ if (dU == 1 && at->bonded_to (2, 8)) return "N=O";
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==8 && at->bonds[i]->kekule==1 && at->bound[i]->bound.size ()==1 && dU==-1) return "N3OX";
+ if (at->bound[i]->GetAtomicNum ()==8 && at->bonds[i]->kekule==1 && at->bound[i]->bound.size ()==1 && dU==0 && (at->bonded_to (2, -2)+at->bonded_to (5, -2)) && at->bonded_to (-2, 8)<2) return "N2OX";
+ if (at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==2 ) {
+ if (dU ==0 || at->bonded_to (2, -2)) return "NSO2";
+ if (dU==1) return "NM";
+ };
+ }
+
+
+ if (dU == 0 && (at->bonded_to (2, 6) || (at->bonded_to (5, -2)==2) && at->is_aromatic ())) return "N+=C";
+
+
+ if (dU==-1) return "NR+";
+ if (dU==0 && at->bonded_to (-2, 8)==2) return "NO2";
+ if (dU==0 && at->bonded_to (-2, 8)==3) return "NO3";
+
+
+ if (at->bonded_to ("C=ON") || at->bonded_to ("CONN") && at->bound.size ()==3) return "NC=O";
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==6 && (at->bound[i]->bonded_to (2, 6) || at->bound[i]->bonded_to (5, 6))) return "NC=C";
+ }
+
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+
+ if (at->bound[i]->GetAtomicNum ()==6 && !at->bound[i]->bonded_to (2, 8) && at->bound[i]->bonded_to (-2,7)>1 && ((at->bound[i]->bonded_to (2, 7) || at->bound[i]->bonded_to (5, 7)))) return "NC=N";
+ if (at->bound[i]->GetAtomicNum ()==6 && at->bound[i]->bonded_to (3, 7) && at->bound[i]->bonded_to (-2, 7)>1 && !at->bonded_to (3, 6)) return "NC%N";
+ if (at->bound[i]->GetAtomicNum ()==7 && at->in_ring.size ()==0 && (at->bound[i]->bonded_to (2, 6) || at->bound[i]->bonded_to (5, 6)) && !at->bound[i]->bonded_to ("CGD+") && !at->bound[i]->bonded_to ("CGD")) return "NN=C";
+ if (at->bound[i]->GetAtomicNum ()==7 && (at->bound[i]->bonded_to (2, 7) && at->bound[i]->bonded_to (1,7))) return "NN=N";
+
+ if (at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==3 ) return "NSO3";
+ if (at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==2 ) return "NPO2";
+ if (at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==3 ) return "NPO3";
+ }
+
+
+
+
+ for (unsigned int r=0; r<at->in_ring.size(); r++) {
+ Ring *ring = at->in_ring[r];
+ if (ring->aromatic && ring->atoms.size()==5 && at->in_ring.size()==1 && at->bound.size ()==3) return "NPYL";
+ if (ring->aromatic && ring->atoms.size()==6 && at->in_ring.size()==1) {
+ if (at->bonded_to (-2, 8)) return "NPOX";
+ if (dU==1) return "NPYD";
+ if (dU==0) return "NPD+";
+ }
+ }
+
+ for (unsigned int r=0; r<at->in_ring.size(); r++) {
+ Ring *ring = at->in_ring[r];
+ if (ring->aromatic && ring->atoms.size ()==5 && ring->count (6)<5) {
+ for (unsigned int a=0; a<at->bound.size(); a++) {
+ if (at->bound[a]->GetAtomicNum ()!=6 && at->bound[a]->in_ring.size()) {
+ if (at->bound[a]->GetAtomicNum ()==7 && !at->bound[a]->bound.size()==3) {}
+ else return "N5A";
+ }
+ }
+ }
+ }
+ for (unsigned int r=0; r<at->in_ring.size(); r++) {
+ Ring *ring = at->in_ring[r];
+ if (ring->aromatic && ring->atoms.size()==5) return "N5B";
+ }
+ if (dU == 0 && at->bonded_to (2, 7)) return "N+=N";
+
+ if (at->bonded_to (3, -2)) return "NSP";
+ if (at->bonded_to ("CSP")) return "NC%C";
+ if (dU == 0) return "NR";
+ }
+//____________________________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 8) {// 6 7 32 35 49 51 59 70 O
+ // bool in_ring = at->in_ring.size()>0;
+ unsigned int ring_size = 1000;
+ bool aromatic=false;
+ for (unsigned int r=0; r<at->in_ring.size (); r++){
+ if (at->in_ring[r]->atoms.size ()< ring_size) ring_size =at->in_ring[r]->atoms.size ();
+ if (at->in_ring[r]->aromatic) aromatic = true;
+ }
+ // || 6 ALCOHOL || ETHER OXYGEN
+// OC=O 6 ESTER || CARBOXYLIC ACID -O-
+// OC=C 6 ENOLIC || PHENOLIC OXYGEN
+// OC=N 6 DIVALENT OXYGEN
+// OC=S 6 THIOESTER || THIOACID -O-
+// ONO2 6 DIVALENT NITRATE "ETHER" OXYGEN
+// ON=O 6 DIVALENT NITRITE "ETHER" OXYGEN
+// OSO3 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+// OSO2 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+// OSO 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+// OS=O 6 DIVALENT OXYGEN ATTACHED TO SULFOXIDE SULFUR
+// -OS 6 GENERAL DIVALENT OX ATTACHED TO S
+// OPO3 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+// OPO2 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+// OPO 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+// -OP 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+// -O- 6 GENERAL DIVALENT O
+// O=C 7 GENERAL C=O
+// O=CN 7 CARBONYL OXYGEN, AMIDES
+// O=CR 7 CARBONYL OXYGEN, ALDEHYDES && KETONES
+// O=CO 7 CARBONYL OXYGEN, CARBOXYLIC ACIDS && ESTERS
+// O=N 7 NITROSO OXYGEN
+// O=S 7 O=S IN SULFOXIDES
+// O=S= 7 O=S ON SULFUR DOUBLY BONDED TO, E.G., CARBON
+// O2CM 32 OXYGEN IN CARBOXYLATE ANION
+// OXN 32 N-OXIDE OXYGEN
+// O2N 32 NITRO OXYGEN
+// O2NO 32 NITRO-GROUP OXYGEN IN NITRATE
+// O3N 32 NITRATE ANION OXYGEN
+// O-S 32 SINGLE TERMINAL OXYGEN ON TETRACOORD SULFUR
+// O2S 32 TERMINAL O-S IN SULFONES && SULFONAMIDES
+// O3S 32 TERMINAL O IN SULFONATES
+// O4S 32 TERMINAL O IN SO4(-3)
+ OSMS 32 TERM O IN THIOSULFINATE ANION - FORMAL CHARGE=-0.5
+// OP 32 TERMINAL O IN PHOSPHOXIDES
+// O2P 32 TERMINAL O IN PHOSPHINATES
+// O3P 32 TERMINAL OXYGEN IN PHOSPHONATES
+// O4P 32 TERMINAL OXYGEN IN PHOSPHATES && PHOSPHODIESTERS
+ O4CL 32 OXYGEN IN CLO4(-) ANION - FORMAL CHARGE=-0.25
+// OM 35 ALKOXIDE OXYGEN, NEGATIVELY CHARGED
+ // OM2 35 OXIDE OXYGEN ON SP2 CARBON, NEGATIVELY CHARGED
+// O+ 49 POSITIVELY CHARGED OXONIUM (TRICOORDINATE) OXYGEN
+// O=+ 51 POSITIVELY CHARGED OXENIUM (DICOORDINATE) OXYGEN
+// OFUR 59 AROMATIC OXYGEN AS IN FURAN
+// OH2 70 OXYGEN ON WATER
+
+
+ int dU = 2-at->bonds.size ();
+ if (at->bonded_to ("COO") && at->bonded_to (2, 6)) return "O=CO";
+ if (at->bonded_to ("COO")) return "OC=O";
+ for (unsigned int i=0; i <at->bound.size (); i++) {
+ if (at->bound[i]->GetAtomicNum ()==6 && at->bonds[i]->kekule==1 && at->bound[i]->bonded_to (2, 8) && at->bound[i]->bonded_to (1, 8)) return "OC=O";
+ }
+ if (at->bonded_to ("C=OR") || at->bonded_to ("CONN")) return "O=CR";
+ if (at->bonded_to ("C=ON") && dU ==1) return "O=CN";
+ if (at->bonded_to ("C=S")) return "OC=S";
+ if (at->bonded_to ("CO2M")) return "O2CM";
+ if (aromatic && ring_size==5) return "OFUR";
+ if (dU ==-1) return "O+";
+ if (dU ==1 && at->bonded_to (1, 6) ) {
+ if (at->bound[0]->bound.size () == 3) return "OM2";
+ return "OM";
+ }
+ if (dU ==1 && at->bonded_to (1, 7)) {
+ if (at->bound[0]->bound.size () == 2) return "OM2";
+ // return "OM";
+ }
+ if (dU ==0 && at->bonded_to (1, 1)==2) return "OH2";
+ if (dU==0 && (aromatic || at->bonded_to (2, -2))) return "O=+";
+ if (dU==1 && at->bonded_to (-2, 7)) {
+ if (at->bound[0]->bonded_to (-2, 8) ==3) {
+ int tO =0; //terminal Os on N
+ for (unsigned int i=0; i<at->bound[0]->bound.size(); i++) {
+ if (at->bound[0]->bound[i]->bound.size () ==1) tO+=1;
+ }
+ if (tO ==3) return "O3N";
+ else return "O2NO";
+ }
+ }
+
+
+ if (dU==1 && at->bonded_to (-2, 16)) {
+ if (at->bound[0]->bound.size ()==4 && at->bound[0]->bonded_to (-2, 8) ==1) return "O-S";
+ if (at->bound[0]->bonded_to (-2, 8) ==2) {
+ bool boo= true;
+ for (unsigned int i=0; i<at->bound[0]->bound.size (); i++) {
+ if (at->bound[0]->bound[i]->GetAtomicNum ()==8 && at->bound[0]->bound[i]->bound.size ()==2) boo=false;
+ }
+ if (boo) return "O2S";
+ }
+ if (at->bound[0]->bonded_to (-2, 8) ==3) return "O3S";
+ if (at->bound[0]->bonded_to (-2, 8) ==4) return "O4S";
+ }
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==6 && at->bound[i]->bonded_to (2, 7) || at->bound[i]->bonded_to (5, 7)) return "OC=N";
+ }
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->GetAtomicNum ()==6 && (at->bound[i]->bonded_to (2, 6) || at->bound[i]->bonded_to (5, 6))) return "OC=C";
+ }
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==7 && at->bound[i]->bonded_to (-2, 8)==3) return "ONO2";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==7 && at->bound[i]->bonded_to (-2, 8)==2) return "ON=O";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==7 && at->bound[i]->bonded_to (-2, 8)==2) return "O2N";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==7 && at->bound[i]->bonded_to (2, 8)==1 && at->bound[i]->bonds.size()==2) return "O=N";
+ if (dU==1 && at->bonded_to (1, 7)) return "OXN";
+ }
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==4) return "OSO3";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==3) return "OSO2";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==2 && at->bound[i]->bonded_to (2, 8)) return "OS=O";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (-2, 8)==2) return "OSO";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (2, 8) && at->bound[i]->bonded_to (2, -2)==2) return "O=S=";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==16 && at->bound[i]->bonded_to (2, 8)) return "O=S";
+
+ }
+ if (dU==0 && at->bonded_to (-2, 16)) return "-OS";
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==4) return "OPO3";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==3) return "OPO2";
+ if (dU==0 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==2) return "OPO";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==1) return "OP";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==2) return "O2P";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==3) return "O3P";
+ if (dU==1 && at->bound[i]->GetAtomicNum ()==15 && at->bound[i]->bonded_to (-2, 8)==4) return "O4P";
+
+ }
+ if (dU==0 && at->bonded_to (-2, 15)) return "-OP";
+
+
+ if (dU==0) {
+ if (at->bonded_to (1, 6) ==2 || (at->bonded_to (1, 6)==1 && at->bonded_to (1,1) ==1)) return "OR";
+ return "-O-";
+ }
+ if (at->bonded_to (2, 6)) return "O=C";
+
+ }
+//_________________________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 9) { // 11 89 F
+// F 11 FLUORINE
+// F- 89 FLUORIDE ANION
+ if (at->bonds.size () ==0) return "F-";
+ if (at->bonds.size () ==1) return "F";
+ }
+
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 11) {// 93 Na
+// NA+ 93 SODIUM CATION
+ return "NA+";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 12) { // 99 Mg
+// MG+2 99 DIPOSITIVE MAGNESIUM CATION
+ return "MG+2";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 14) { // 19 Si
+// SI 19 SILICON
+ return "SI";
+ }
+
+//____________________________________________________________________________________________________________
+ if (at->GetAtomicNum () == 15) {// 25 26 75 P
+// PO4 25 PHOSPHOROUS IN PHOSPHATES && PHOSPHODIESTERS
+// PO3 25 TETRACOORDINATE P WITH THREE ATTACHED OXYGENS
+// PO2 25 TETRACOORDINATE P WITH TWO ATTACHED OXYGENS
+// PO 25 TETRACOORDINATE P WITH ONE ATTACHED OXYGEN
+// PTET 25 GENERAL TETRACOORDINATE PHOSPHORUS
+// P 26 TRICOORDINATE P, AS IN PHOSPHINES
+// -P=C 75 PHOSPHOROUS DOUBLY BONDED TO CARBON
+ int coord = at->bonds.size ();
+ if (at->bonded_to (2, 6)) return "-P=C";
+ if (coord==4 && at->bonded_to (-2, 8)==4) return "PO4";
+ if (coord==4 && at->bonded_to (-2, 8)==3) return "PO3";
+ if (coord==4 && at->bonded_to (-2, 8)==2) return "PO2";
+ if (coord==4 && at->bonded_to (-2, 8)==1) return "PO";
+ if (coord==4) return "PTET";
+ if (coord==3) return "P";
+ }
+
+ //_________________________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==16) { // 15 16 17 18 44 72 73 74 S
+ bool aromatic=false;
+ // bool in_ring = at->in_ring.size()>0;
+ int ring_size = 1000;
+ for (unsigned int r=0; r<at->in_ring.size (); r++){
+ if (at->in_ring[r]->atoms.size ()< ring_size) ring_size =at->in_ring[r]->atoms.size ();
+ if (at->in_ring[r]->aromatic) aromatic = true;
+ }
+/*
+// S 15 SULFUR IN THIOETHERS && MERCAPTANS
+// S=C 16 TERMINAL SULFUR DOUBLY BONDED TO CARBON
+ // S=O 17 SULFUR IN SULFOXIDES
+// >S=N 17 SULFUR, TRICOORD, DOUBLY BONDED TO N
+// SO2 18 SULFUR IN SULFONES
+// SO2N 18 SULFUR IN SULFONAMIDES
+// SO3 18 SULFONATE SULFUR
+// SO4 18 SULFATE SULFUR
+// =SO2 18 SULFONE SULPHER DOUBLY BONDED TO CARBON
+// SNO 18 SULFUR IN NITROGEN ANALOG OF A SULFONE
+// STHI 44 SULFUR AS IN THIOPHENE
+// S-P 72 TERMINAL SULFUR BONDED TO PHOSPHORUS
+// S2CM 72 TERMINAL SULFUR IN THIOCARBOXYLATE ANION
+// SM 72 TERMINAL SULFUR - FORMAL CHARGE=-1
+ SSMO 72 TERMINAL SULFUR IN THIOSULFINATE GROUP
+ SO2M 73 SULFUR IN NEGATIVELY CHARGED SULFINATE GROUP
+ SSOM 73 TRICOORD SULFUR IN THIOSULFINATE GROUP
+// =S=O 74 SULFINYL SULFUR, EG. IN C=S=O
+
+ int coord = at->bonds.size ();
+
+ if (aromatic && ring_size==5) return "STHI";
+ if (at->bonded_to ("CS2M")) return "S2CM";
+ if (coord==2 && at->bonded_to (2, -2)==2 && at->bonded_to (2, 8)) return "=S=O";
+ if (coord==3 && at->bonded_to (2, 7)) return ">S=N";
+ if (coord==3 && at->bonded_to (2, 8)) return "S=O";
+ if (coord==4 && at->bonded_to (-2, 8)==4) return "SO4";
+ if (coord==4 && at->bonded_to (-2, 8)==3) return "SO3";
+ if (coord==4 && at->bonded_to (-2, 8)==2 && at->bonded_to (-2, 7)) return "SO2N";
+ if (coord==3 && at->bonded_to (-2, 8)==2 && at->bonded_to (2, 6)) return "=SO2";
+
+ if (coord==4 && at->bonded_to (-2, 8)==2) return "SO2";
+ if (coord==4 && at->bonded_to (-2, 8) && at->bonded_to (-2, 7)) return "SNO";
+
+ if (coord==1 && at->bonded_to (2, 6)) return "S=C";
+
+
+
+ if (coord==1 && at->bonded_to (-2, 15)) return "S-P";
+ if (coord==2) return "S";
+ if (coord==1) return "SM";
+ }
+//________________________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==17) { // 12 77 90 Cl
+// CL 12 CHLORINE
+// CLO4 77 CHLORINE IN PERCHLORATE ANION, CLO4(-)
+// CL- 90 CHLORIDE ANION
+ if (at->bonds.size() == 0) return "CL-";
+ if (at->bonded_to (-2, 8) == 4) return "CLO4";
+ return "CL";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==19) { // 94 K
+// K+ 94 POTASSIUM CATION
+ return "K+";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==20) { // 96 Ca
+// CA+2 96 DIPOSITIVE CALCIUM
+ return "CA+2";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==26) { // 87 88 Fe
+// FE+2 87 IRON +2 CATION
+////////////// FE+3 88 IRON +3 CATION
+ return "FE+2";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==29) { // 97 98 Cu
+// CU+1 97 MONOPOSITIVE COPPER
+///////////// CU+2 98 DIPOSITIVE COPPER
+ return "CU+1";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==30) { // 95 Zn
+// ZINC 95 DIPOSITIVE ZINC
+// ZN+2 95 DIPOSITIVE ZINC
+ return "ZN+2";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==35) { // 13 91 Br
+// BR 13 BROMINE
+// BR- 91 BROMIDE ANION
+ if (!at->bonds.size ()) return "BR-";
+ return "BR";
+ }
+//_________________________________________________________________________________________________
+ if (at->GetAtomicNum () ==53) { // 14 I
+// I 14 IODINE
+ return "I";
+ }
+
+
+ return "Unknown eteroatom";
+*/
+}
+
+
+ int MMFF::getBondType(Atom* a, Atom* b)
+ {
+ ZNMolecule *mol = (ZNMolecule *) a ->GetParent ();
+ ZNBond *bond = mol ->GetBond (a, b);
+ int I = get_MMFFtype (a);
+ int J = get_MMFFtype (b);
+ if (!bond ->IsSingle())
+ return 0;
+
+ if (!bond ->IsAromatic())
+ if (get_arom (I) && get_arom (J))
+ return 1;
+
+ if (get_sbmb (I) && get_sbmb (J))
+ return 1;
+
+ return 0;
+ }
+
+ int MMFF::getAngleType(Atom* a, Atom* b, Atom *c)
+ {
+ int sumbondtypes;
+
+ sumbondtypes = getBondType(a,b) + getBondType(b, c);
+
+ if (a->IsInRingSize(3) && b->IsInRingSize(3) && c->IsInRingSize(3) && IsInSameRing(a, c))
+ switch (sumbondtypes) {
+ case 0:
+ return 3;
+ case 1:
+ return 5;
+ case 2:
+ return 6;
+ }
+
+ if (a->IsInRingSize(4) && b->IsInRingSize(4) && c->IsInRingSize(4) && IsInSameRing(a, c))
+ switch (sumbondtypes) {
+ case 0:
+ return 4;
+ case 1:
+ return 7;
+ case 2:
+ return 8;
+ }
+
+ return sumbondtypes;
+ }
+
+
+
+int MMFF::getMMFFtype (Atom *at) {
+
+ return std::numeric_limits<int>::infinity();
+
+/*
+ string st = at->MMFFstring;
+ for (unsigned int i=0; i<atypeParameters.size (); i++) {
+ // cout <<atypeParameters[i]->strin<<endl;
+ if (st==atypeParameters[i]->strin) return atypeParameters[i]->number;
+ }
+ cout << "string "<<st<<" does not name an atom type"<<endl;
+ return 1;
+*/
+}
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3c8488f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,145 @@
+#############################################################################
+# Makefile for building: Zodiac
+# Generated by qmake (2.01a) (Qt 4.5.0) on: Mon 18. May 13:13:03 2009
+# Project: zodiac.pro
+# Template: app
+# Command: f:\qt\2009.01\qt\bin\qmake.exe -win32 -o Makefile zodiac.pro
+#############################################################################
+
+first: debug
+install: debug-install
+uninstall: debug-uninstall
+MAKEFILE = Makefile
+QMAKE = f:/qt/2009.01/qt/bin/qmake.exe
+DEL_FILE = rm
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir
+COPY = cp
+COPY_FILE = $(COPY)
+COPY_DIR = xcopy /s /q /y /i
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_PROGRAM = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+DEL_FILE = rm
+SYMLINK =
+DEL_DIR = rmdir
+MOVE = mv
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir
+SUBTARGETS = \
+ debug \
+ release
+
+debug: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug
+debug-make_default: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug
+debug-make_first: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug first
+debug-all: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug all
+debug-clean: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug clean
+debug-distclean: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug distclean
+debug-install: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug install
+debug-uninstall: $(MAKEFILE).Debug FORCE
+ $(MAKE) -f $(MAKEFILE).Debug uninstall
+release: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release
+release-make_default: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release
+release-make_first: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release first
+release-all: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release all
+release-clean: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release clean
+release-distclean: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release distclean
+release-install: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release install
+release-uninstall: $(MAKEFILE).Release FORCE
+ $(MAKE) -f $(MAKEFILE).Release uninstall
+
+Makefile: zodiac.pro f:/Qt/2009.01/qt/mkspecs/default/qmake.conf f:/Qt/2009.01/qt/mkspecs/qconfig.pri \
+ f:/Qt/2009.01/qt/mkspecs/features/qt_functions.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/qt_config.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/exclusive_builds.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/default_pre.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/default_pre.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/debug.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/debug_and_release.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/default_post.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/default_post.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/assistant.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/qt.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/opengl.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/thread.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/moc.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/rtti.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/exceptions.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/stl.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/shared.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/warn_on.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/win32/windows.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/resources.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/uic.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/yacc.prf \
+ f:/Qt/2009.01/qt/mkspecs/features/lex.prf \
+ f:/Qt/2009.01/qt/lib/qtmaind.prl
+ $(QMAKE) -win32 -o Makefile zodiac.pro
+f:/Qt/2009.01/qt/mkspecs/qconfig.pri:
+f:/Qt/2009.01/qt/mkspecs/features/qt_functions.prf:
+f:/Qt/2009.01/qt/mkspecs/features/qt_config.prf:
+f:/Qt/2009.01/qt/mkspecs/features/exclusive_builds.prf:
+f:/Qt/2009.01/qt/mkspecs/features/default_pre.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/default_pre.prf:
+f:/Qt/2009.01/qt/mkspecs/features/debug.prf:
+f:/Qt/2009.01/qt/mkspecs/features/debug_and_release.prf:
+f:/Qt/2009.01/qt/mkspecs/features/default_post.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/default_post.prf:
+f:/Qt/2009.01/qt/mkspecs/features/assistant.prf:
+f:/Qt/2009.01/qt/mkspecs/features/qt.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/opengl.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/thread.prf:
+f:/Qt/2009.01/qt/mkspecs/features/moc.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/rtti.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/exceptions.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/stl.prf:
+f:/Qt/2009.01/qt/mkspecs/features/shared.prf:
+f:/Qt/2009.01/qt/mkspecs/features/warn_on.prf:
+f:/Qt/2009.01/qt/mkspecs/features/win32/windows.prf:
+f:/Qt/2009.01/qt/mkspecs/features/resources.prf:
+f:/Qt/2009.01/qt/mkspecs/features/uic.prf:
+f:/Qt/2009.01/qt/mkspecs/features/yacc.prf:
+f:/Qt/2009.01/qt/mkspecs/features/lex.prf:
+f:\Qt\2009.01\qt\lib\qtmaind.prl:
+qmake: qmake_all FORCE
+ @$(QMAKE) -win32 -o Makefile zodiac.pro
+
+qmake_all: FORCE
+
+make_default: debug-make_default release-make_default FORCE
+make_first: debug-make_first release-make_first FORCE
+all: debug-all release-all FORCE
+clean: debug-clean release-clean FORCE
+distclean: debug-distclean release-distclean FORCE
+ -$(DEL_FILE) Makefile
+
+debug-mocclean: $(MAKEFILE).Debug
+ $(MAKE) -f $(MAKEFILE).Debug mocclean
+release-mocclean: $(MAKEFILE).Release
+ $(MAKE) -f $(MAKEFILE).Release mocclean
+mocclean: debug-mocclean release-mocclean
+
+debug-mocables: $(MAKEFILE).Debug
+ $(MAKE) -f $(MAKEFILE).Debug mocables
+release-mocables: $(MAKEFILE).Release
+ $(MAKE) -f $(MAKEFILE).Release mocables
+mocables: debug-mocables release-mocables
+FORCE:
+
+$(MAKEFILE).Debug: Makefile
+$(MAKEFILE).Release: Makefile
diff --git a/Makefile.Debug b/Makefile.Debug
new file mode 100644
index 0000000..543d1b3
--- /dev/null
+++ b/Makefile.Debug
@@ -0,0 +1,1515 @@
+#############################################################################
+# Makefile for building: Zodiac
+# Generated by qmake (2.01a) (Qt 4.5.0) on: Mon 18. May 13:13:02 2009
+# Project: zodiac.pro
+# Template: app
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_SVG_LIB -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN
+CFLAGS = -g -Wall $(DEFINES)
+CXXFLAGS = -g -frtti -fexceptions -mthreads -Wall $(DEFINES)
+INCPATH = -I'f:/Qt/2009.01/qt/include/QtCore' -I'f:/Qt/2009.01/qt/include/QtNetwork' -I'f:/Qt/2009.01/qt/include/QtGui' -I'f:/Qt/2009.01/qt/include/QtOpenGL' -I'f:/Qt/2009.01/qt/include/Qt3Support' -I'f:/Qt/2009.01/qt/include/QtSvg' -I'f:/Qt/2009.01/qt/include' -I'f:/Qt/2009.01/qt/include/QtAssistantClient' -I'f:/Qt/2009.01/qt/include/QtAssistant' -I'.' -I'headers' -I'molsketch_helium' -I'../Program Files (x86)/openbabel/include/openbabel-2.0' -I'c:/Program Files/openbabel/include/ [...]
+LINK = g++
+LFLAGS = -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -mthreads -Wl -Wl,-subsystem,windows
+LIBS = -L'f:/Qt/2009.01/qt/lib' -lopengl32 -lglu32 -lgdi32 -luser32 -lmingw32 -lqtmaind debug/win_rc_res.o "-LC:\Program Files (x86)\openbabel\lib" "-LC:\Program Files\openbabel\lib" -lopenbabel-2 -lQtAssistantClientd4 -lQtSvgd4 -lQt3Supportd4 -lQtOpenGLd4 -lQtGuid4 -lQtNetworkd4 -lQtCored4
+QMAKE = f:/qt/2009.01/qt/bin/qmake.exe
+IDC = f:/Qt/2009.01/qt/bin/idc.exe
+IDL = midl
+ZIP = zip -r -9
+DEF_FILE =
+RES_FILE = debug/win_rc_res.o
+COPY = cp
+COPY_FILE = $(COPY)
+COPY_DIR = xcopy /s /q /y /i
+DEL_FILE = rm
+DEL_DIR = rmdir
+MOVE = mv
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_PROGRAM = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+
+####### Output directory
+
+OBJECTS_DIR = debug/
+
+####### Files
+
+SOURCES = actions.cc \
+ arcball.cc \
+ builder.cc \
+ chemscore.cc \
+ command.cc \
+ constants.cc \
+ database.cc \
+ datagrid.cc \
+ ddwin.cc \
+ FF.cc \
+ graphical_object.cc \
+ iodevice.cc \
+ MarchingCubes.cc \
+ maths.cc \
+ menu.cc \
+ minimize.cc \
+ MMFF.cc \
+ myline.cc \
+ plants.cc \
+ plants_mainwin.cc \
+ plantsconfig.cc \
+ PLP.cc \
+ ply.c \
+ povray.cc \
+ thread.cc \
+ wiimote.cc \
+ ZNdata.cc \
+ ZNmolecule.cc \
+ Zodiac.cc \
+ forcefields/forcefieldghemical.cpp \
+ forcefields/forcefieldmmff94.cpp \
+ forcefields/forcefielduff.cpp \
+ molsketch_helium/atom.cpp \
+ molsketch_helium/bond.cpp \
+ molsketch_helium/commands.cpp \
+ molsketch_helium/element.cpp \
+ molsketch_helium/fileio.cpp \
+ molsketch_helium/mainwindow.cpp \
+ molsketch_helium/molecule.cpp \
+ molsketch_helium/mollibitem.cpp \
+ molsketch_helium/molscene.cpp \
+ molsketch_helium/molview.cpp \
+ molsketch_helium/periodictablewidget.cpp \
+ molsketch_helium/settings.cpp \
+ molsketch_helium/part/molsketch_factory.cpp \
+ molsketch_helium/part/molsketchpart.cpp \
+ molsketch_helium/part/molsketchpart_shell.cpp debug/moc_ddwin.cpp \
+ debug/moc_menu.cpp \
+ debug/moc_myline.cpp \
+ debug/moc_plants.cpp \
+ debug/moc_plants_mainwin.cpp \
+ debug/moc_thread.cpp \
+ debug/moc_ZNdata.cpp \
+ debug/moc_mainwindow.cpp \
+ debug/moc_molscene.cpp \
+ debug/moc_molview.cpp \
+ debug/moc_periodictablewidget.cpp \
+ debug/moc_settings.cpp \
+ debug/qrc_resources.cpp \
+ debug/qrc_zodiac.cpp \
+ debug/qrc_molsketch.cpp \
+ debug/qrc_molsketchpart_shell.cpp
+OBJECTS = debug/actions.o \
+ debug/arcball.o \
+ debug/builder.o \
+ debug/chemscore.o \
+ debug/command.o \
+ debug/constants.o \
+ debug/database.o \
+ debug/datagrid.o \
+ debug/ddwin.o \
+ debug/FF.o \
+ debug/graphical_object.o \
+ debug/iodevice.o \
+ debug/MarchingCubes.o \
+ debug/maths.o \
+ debug/menu.o \
+ debug/minimize.o \
+ debug/MMFF.o \
+ debug/myline.o \
+ debug/plants.o \
+ debug/plants_mainwin.o \
+ debug/plantsconfig.o \
+ debug/PLP.o \
+ debug/ply.o \
+ debug/povray.o \
+ debug/thread.o \
+ debug/wiimote.o \
+ debug/ZNdata.o \
+ debug/ZNmolecule.o \
+ debug/Zodiac.o \
+ debug/forcefieldghemical.o \
+ debug/forcefieldmmff94.o \
+ debug/forcefielduff.o \
+ debug/atom.o \
+ debug/bond.o \
+ debug/commands.o \
+ debug/element.o \
+ debug/fileio.o \
+ debug/mainwindow.o \
+ debug/molecule.o \
+ debug/mollibitem.o \
+ debug/molscene.o \
+ debug/molview.o \
+ debug/periodictablewidget.o \
+ debug/settings.o \
+ debug/molsketch_factory.o \
+ debug/molsketchpart.o \
+ debug/molsketchpart_shell.o \
+ debug/moc_ddwin.o \
+ debug/moc_menu.o \
+ debug/moc_myline.o \
+ debug/moc_plants.o \
+ debug/moc_plants_mainwin.o \
+ debug/moc_thread.o \
+ debug/moc_ZNdata.o \
+ debug/moc_mainwindow.o \
+ debug/moc_molscene.o \
+ debug/moc_molview.o \
+ debug/moc_periodictablewidget.o \
+ debug/moc_settings.o \
+ debug/qrc_resources.o \
+ debug/qrc_zodiac.o \
+ debug/qrc_molsketch.o \
+ debug/qrc_molsketchpart_shell.o
+DIST =
+QMAKE_TARGET = Zodiac
+DESTDIR = debug/ #avoid trailing-slash linebreak
+TARGET = Zodiac.exe
+DESTDIR_TARGET = debug/Zodiac.exe
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cc .cxx .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+first: all
+all: Makefile.Debug $(DESTDIR_TARGET)
+
+$(DESTDIR_TARGET): ui_zodiac.h ui_settings.h $(OBJECTS) debug/win_rc_res.o
+ $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.Zodiac.Debug $(LIBS)
+
+
+debug/win_rc_res.o: win_rc.rc
+ windres -i win_rc.rc -o debug/win_rc_res.o --include-dir=.
+
+qmake: FORCE
+ @$(QMAKE) -win32 -o Makefile.Debug zodiac.pro
+
+dist:
+ $(ZIP) Zodiac.zip $(SOURCES) $(DIST) zodiac.pro f:/Qt/2009.01/qt/mkspecs/qconfig.pri f:/Qt/2009.01/qt/mkspecs/features/qt_functions.prf f:/Qt/2009.01/qt/mkspecs/features/qt_config.prf f:/Qt/2009.01/qt/mkspecs/features/exclusive_builds.prf f:/Qt/2009.01/qt/mkspecs/features/default_pre.prf f:/Qt/2009.01/qt/mkspecs/features/win32/default_pre.prf f:/Qt/2009.01/qt/mkspecs/features/debug.prf f:/Qt/2009.01/qt/mkspecs/features/debug_and_release.prf f:/Qt/2009.01/qt/mkspecs/features/default_post [...]
+
+clean: compiler_clean
+ -$(DEL_FILE) debug/actions.o debug/arcball.o debug/builder.o debug/chemscore.o debug/command.o debug/constants.o debug/database.o debug/datagrid.o debug/ddwin.o debug/FF.o debug/graphical_object.o debug/iodevice.o debug/MarchingCubes.o debug/maths.o debug/menu.o debug/minimize.o debug/MMFF.o debug/myline.o debug/plants.o debug/plants_mainwin.o debug/plantsconfig.o debug/PLP.o debug/ply.o debug/povray.o debug/thread.o debug/wiimote.o debug/ZNdata.o debug/ZNmolecule.o debug/Zodiac.o debug [...]
+ -$(DEL_FILE) debug/win_rc_res.o
+
+distclean: clean
+ -$(DEL_FILE) $(DESTDIR_TARGET)
+ -$(DEL_FILE) Makefile.Debug
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_moc_header_make_all: debug/moc_ddwin.cpp debug/moc_menu.cpp debug/moc_myline.cpp debug/moc_plants.cpp debug/moc_plants_mainwin.cpp debug/moc_thread.cpp debug/moc_ZNdata.cpp debug/moc_mainwindow.cpp debug/moc_molscene.cpp debug/moc_molview.cpp debug/moc_periodictablewidget.cpp debug/moc_settings.cpp
+compiler_moc_header_clean:
+ -$(DEL_FILE) debug/moc_ddwin.cpp debug/moc_menu.cpp debug/moc_myline.cpp debug/moc_plants.cpp debug/moc_plants_mainwin.cpp debug/moc_thread.cpp debug/moc_ZNdata.cpp debug/moc_mainwindow.cpp debug/moc_molscene.cpp debug/moc_molview.cpp debug/moc_periodictablewidget.cpp debug/moc_settings.cpp
+debug/moc_ddwin.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/ddwin.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/ddwin.h -o debug/moc_ddwin.cpp
+
+debug/moc_menu.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/menu.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/menu.h -o debug/moc_menu.cpp
+
+debug/moc_myline.cpp: headers/myline.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/myline.h -o debug/moc_myline.cpp
+
+debug/moc_plants.cpp: headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/plants.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/plants.h -o debug/moc_plants.cpp
+
+debug/moc_plants_mainwin.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/plants_mainwin.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/plants_mainwin.h -o debug/moc_plants_mainwin.cpp
+
+debug/moc_thread.cpp: headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/thread.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/thread.h -o debug/moc_thread.cpp
+
+debug/moc_ZNdata.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/ZNdata.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/ZNdata.h -o debug/moc_ZNdata.cpp
+
+debug/moc_mainwindow.cpp: obabel_includes.h \
+ molsketch_helium/mainwindow.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/mainwindow.h -o debug/moc_mainwindow.cpp
+
+debug/moc_molscene.cpp: molsketch_helium/mollibitem.h \
+ molsketch_helium/molscene.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/molscene.h -o debug/moc_molscene.cpp
+
+debug/moc_molview.cpp: molsketch_helium/molview.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/molview.h -o debug/moc_molview.cpp
+
+debug/moc_periodictablewidget.cpp: molsketch_helium/periodictablewidget.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/periodictablewidget.h -o debug/moc_periodictablewidget.cpp
+
+debug/moc_settings.cpp: ui_settings.h \
+ molsketch_helium/settings.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/settings.h -o debug/moc_settings.cpp
+
+compiler_rcc_make_all: debug/qrc_resources.cpp debug/qrc_zodiac.cpp debug/qrc_molsketch.cpp debug/qrc_molsketchpart_shell.cpp
+compiler_rcc_clean:
+ -$(DEL_FILE) debug/qrc_resources.cpp debug/qrc_zodiac.cpp debug/qrc_molsketch.cpp debug/qrc_molsketchpart_shell.cpp
+debug/qrc_resources.cpp: resources.qrc \
+ parameters/MMFFOOP.PAR \
+ parameters/MMFFBNDK.PAR \
+ parameters/MMFFDEF.PAR \
+ parameters/MMFFSYMB.PAR \
+ parameters/MMFF93SUP.PAR \
+ parameters/MMFFPBCI.PAR \
+ parameters/MMFFAROM.PAR \
+ parameters/MMFFVDW.PAR \
+ parameters/MMFFSTBN.PAR \
+ parameters/MMFFDFSB.PAR \
+ parameters/MMFFANG.PAR \
+ parameters/MMFFBOND.PAR \
+ parameters/MMFFCHG.PAR \
+ parameters/MMFFHDEF.PAR \
+ parameters/MMFFPROP.PAR \
+ parameters/MMFFTOR.PAR \
+ icons/redo.png \
+ icons/undo.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name resources resources.qrc -o debug/qrc_resources.cpp
+
+debug/qrc_zodiac.cpp: zodiac.qrc \
+ icons/invert_selection.png \
+ icons/builder_S.png \
+ icons/pointer_rubber.png \
+ icons/X.png \
+ icons/select_C.png \
+ icons/ring3.png \
+ icons/builder_del.png \
+ icons/pencil_C.png \
+ icons/redo.png \
+ icons/benzene.png \
+ icons/pencil_S.png \
+ icons/builder_3bond.png \
+ icons/arrow.png \
+ icons/minimise.png \
+ icons/ring4.png \
+ icons/builder_N.png \
+ icons/deselect.png \
+ icons/builder_pencil.png \
+ icons/ring5.png \
+ icons/builder_O.png \
+ icons/periodic_table.png \
+ icons/select_H.png \
+ icons/zeden_ico.png \
+ icons/select_square.png \
+ icons/select_all.png \
+ icons/furanO.png \
+ icons/pencil_N.png \
+ icons/ring6.png \
+ icons/select.png \
+ icons/builder_1bond.png \
+ icons/undo.png \
+ icons/builder_C.png \
+ icons/pencil_O.png \
+ icons/builder_smile.png \
+ icons/ring7.png \
+ icons/builder_Xbond.png \
+ icons/pointer_select_square.png \
+ icons/V.png \
+ icons/furan.png \
+ icons/builder_2bond.png \
+ icons/haptic.png \
+ icons/ring8.png \
+ icons/builder.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name zodiac zodiac.qrc -o debug/qrc_zodiac.cpp
+
+debug/qrc_molsketch.cpp: molsketch_helium/molsketch.qrc \
+ molsketch_helium/images/document-new.png \
+ molsketch_helium/images/edit-redo.png \
+ molsketch_helium/images/zoom-original.png \
+ molsketch_helium/images/edit-copy.png \
+ molsketch_helium/images/document-import.png \
+ molsketch_helium/images/document-save-as.png \
+ molsketch_helium/images/edit-undo.png \
+ molsketch_helium/images/document-print.png \
+ molsketch_helium/images/draw-freehand.svg \
+ molsketch_helium/images/draw-eraser.png \
+ molsketch_helium/images/help-contextual.png \
+ molsketch_helium/images/document-open.png \
+ molsketch_helium/images/molsketch.png \
+ molsketch_helium/images/transform-rotate.png \
+ molsketch_helium/images/configure.svg \
+ molsketch_helium/images/help-about.png \
+ molsketch_helium/images/document-open.svg \
+ molsketch_helium/images/edit-paste.png \
+ molsketch_helium/images/zoom-fit-best.png \
+ molsketch_helium/images/configure.png \
+ molsketch_helium/images/molsketch.svg \
+ molsketch_helium/images/edit-select-all.png \
+ molsketch_helium/images/application-exit.png \
+ molsketch_helium/images/edit-cut.png \
+ molsketch_helium/images/document-save.png \
+ molsketch_helium/images/zoom-out.png \
+ molsketch_helium/images/transform-move.png \
+ molsketch_helium/images/zoom-in.png \
+ molsketch_helium/images/document-export.png \
+ molsketch_helium/images/help-contents.png \
+ molsketch_helium/images/draw-freehand.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name molsketch molsketch_helium/molsketch.qrc -o debug/qrc_molsketch.cpp
+
+debug/qrc_molsketchpart_shell.cpp: molsketch_helium/part/molsketchpart_shell.qrc \
+ molsketch_helium/part/molsketch.svg
+ f:/Qt/2009.01/qt/bin/rcc.exe -name molsketchpart_shell molsketch_helium/part/molsketchpart_shell.qrc -o debug/qrc_molsketchpart_shell.cpp
+
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+ -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_uic_make_all: ui_zodiac.h ui_settings.h
+compiler_uic_clean:
+ -$(DEL_FILE) ui_zodiac.h ui_settings.h
+ui_zodiac.h: zodiac.ui
+ f:/Qt/2009.01/qt/bin/uic.exe zodiac.ui -o ui_zodiac.h
+
+ui_settings.h: molsketch_helium/settings.ui
+ f:/Qt/2009.01/qt/bin/uic.exe molsketch_helium/settings.ui -o ui_settings.h
+
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean compiler_rcc_clean compiler_uic_clean
+
+
+
+####### Compile
+
+debug/actions.o: actions.cc headers/actions.h \
+ headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/actions.o actions.cc
+
+debug/arcball.o: arcball.cc headers/arcball.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/arcball.o arcball.cc
+
+debug/builder.o: builder.cc headers/builder.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/builder.o builder.cc
+
+debug/chemscore.o: chemscore.cc headers/chemscore.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h \
+ headers/datagrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/chemscore.o chemscore.cc
+
+debug/command.o: command.cc headers/command.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/command.o command.cc
+
+debug/constants.o: constants.cc headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/constants.o constants.cc
+
+debug/database.o: database.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/database.o database.cc
+
+debug/datagrid.o: datagrid.cc headers/datagrid.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/datagrid.o datagrid.cc
+
+debug/ddwin.o: ddwin.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/ddwin.o ddwin.cc
+
+debug/FF.o: FF.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/FF.o FF.cc
+
+debug/graphical_object.o: graphical_object.cc headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/graphical_object.o graphical_object.cc
+
+debug/iodevice.o: iodevice.cc headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/iodevice.o iodevice.cc
+
+debug/MarchingCubes.o: MarchingCubes.cc headers/MarchingCubes.h \
+ headers/ply.h \
+ headers/LookUpTable.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/wiimote.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/MarchingCubes.o MarchingCubes.cc
+
+debug/maths.o: maths.cc headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/maths.o maths.cc
+
+debug/menu.o: menu.cc headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/menu.o menu.cc
+
+debug/minimize.o: minimize.cc headers/minimize.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/minimize.o minimize.cc
+
+debug/MMFF.o: MMFF.cc headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/MMFF.o MMFF.cc
+
+debug/myline.o: myline.cc headers/myline.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/myline.o myline.cc
+
+debug/plants.o: plants.cc headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/plants.o plants.cc
+
+debug/plants_mainwin.o: plants_mainwin.cc headers/myline.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/plants_mainwin.o plants_mainwin.cc
+
+debug/plantsconfig.o: plantsconfig.cc headers/plantsconfig.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/plantsconfig.o plantsconfig.cc
+
+debug/PLP.o: PLP.cc headers/PLP.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/PLP.o PLP.cc
+
+debug/ply.o: ply.c headers/ply.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o debug/ply.o ply.c
+
+debug/povray.o: povray.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/povray.o povray.cc
+
+debug/thread.o: thread.cc headers/thread.h \
+ headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/wiimote.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/thread.o thread.cc
+
+debug/wiimote.o: wiimote.cc headers/wiimote.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/wiimote.o wiimote.cc
+
+debug/ZNdata.o: ZNdata.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/ZNdata.o ZNdata.cc
+
+debug/ZNmolecule.o: ZNmolecule.cc headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/ZNmolecule.o ZNmolecule.cc
+
+debug/Zodiac.o: Zodiac.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/Zodiac.o Zodiac.cc
+
+debug/forcefieldghemical.o: forcefields/forcefieldghemical.cpp forcefields/forcefieldghemical.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/forcefieldghemical.o forcefields/forcefieldghemical.cpp
+
+debug/forcefieldmmff94.o: forcefields/forcefieldmmff94.cpp forcefields/forcefieldmmff94.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/forcefieldmmff94.o forcefields/forcefieldmmff94.cpp
+
+debug/forcefielduff.o: forcefields/forcefielduff.cpp forcefields/forcefielduff.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/forcefielduff.o forcefields/forcefielduff.cpp
+
+debug/atom.o: molsketch_helium/atom.cpp molsketch_helium/atom.h \
+ molsketch_helium/element.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/bond.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/atom.o molsketch_helium/atom.cpp
+
+debug/bond.o: molsketch_helium/bond.cpp molsketch_helium/bond.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/bond.o molsketch_helium/bond.cpp
+
+debug/commands.o: molsketch_helium/commands.cpp molsketch_helium/commands.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/commands.o molsketch_helium/commands.cpp
+
+debug/element.o: molsketch_helium/element.cpp molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/element.o molsketch_helium/element.cpp
+
+debug/fileio.o: molsketch_helium/fileio.cpp molsketch_helium/fileio.h \
+ obabel_includes.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/fileio.o molsketch_helium/fileio.cpp
+
+debug/mainwindow.o: molsketch_helium/mainwindow.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/mainwindow.h \
+ obabel_includes.h \
+ molsketch_helium/molview.h \
+ molsketch_helium/element.h \
+ molsketch_helium/settings.h \
+ ui_settings.h \
+ molsketch_helium/fileio.h \
+ molsketch_helium/periodictablewidget.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/mainwindow.o molsketch_helium/mainwindow.cpp
+
+debug/molecule.o: molsketch_helium/molecule.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molecule.o molsketch_helium/molecule.cpp
+
+debug/mollibitem.o: molsketch_helium/mollibitem.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/fileio.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/mollibitem.o molsketch_helium/mollibitem.cpp
+
+debug/molscene.o: molsketch_helium/molscene.cpp molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/commands.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molscene.o molsketch_helium/molscene.cpp
+
+debug/molview.o: molsketch_helium/molview.cpp molsketch_helium/molview.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molview.o molsketch_helium/molview.cpp
+
+debug/periodictablewidget.o: molsketch_helium/periodictablewidget.cpp molsketch_helium/periodictablewidget.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/periodictablewidget.o molsketch_helium/periodictablewidget.cpp
+
+debug/settings.o: molsketch_helium/settings.cpp molsketch_helium/settings.h \
+ ui_settings.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/settings.o molsketch_helium/settings.cpp
+
+debug/molsketch_factory.o: molsketch_helium/part/molsketch_factory.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molsketch_factory.o molsketch_helium/part/molsketch_factory.cpp
+
+debug/molsketchpart.o: molsketch_helium/part/molsketchpart.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molsketchpart.o molsketch_helium/part/molsketchpart.cpp
+
+debug/molsketchpart_shell.o: molsketch_helium/part/molsketchpart_shell.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/molsketchpart_shell.o molsketch_helium/part/molsketchpart_shell.cpp
+
+debug/moc_ddwin.o: debug/moc_ddwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_ddwin.o debug/moc_ddwin.cpp
+
+debug/moc_menu.o: debug/moc_menu.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_menu.o debug/moc_menu.cpp
+
+debug/moc_myline.o: debug/moc_myline.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_myline.o debug/moc_myline.cpp
+
+debug/moc_plants.o: debug/moc_plants.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_plants.o debug/moc_plants.cpp
+
+debug/moc_plants_mainwin.o: debug/moc_plants_mainwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_plants_mainwin.o debug/moc_plants_mainwin.cpp
+
+debug/moc_thread.o: debug/moc_thread.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_thread.o debug/moc_thread.cpp
+
+debug/moc_ZNdata.o: debug/moc_ZNdata.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_ZNdata.o debug/moc_ZNdata.cpp
+
+debug/moc_mainwindow.o: debug/moc_mainwindow.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_mainwindow.o debug/moc_mainwindow.cpp
+
+debug/moc_molscene.o: debug/moc_molscene.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_molscene.o debug/moc_molscene.cpp
+
+debug/moc_molview.o: debug/moc_molview.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_molview.o debug/moc_molview.cpp
+
+debug/moc_periodictablewidget.o: debug/moc_periodictablewidget.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_periodictablewidget.o debug/moc_periodictablewidget.cpp
+
+debug/moc_settings.o: debug/moc_settings.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/moc_settings.o debug/moc_settings.cpp
+
+debug/qrc_resources.o: debug/qrc_resources.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/qrc_resources.o debug/qrc_resources.cpp
+
+debug/qrc_zodiac.o: debug/qrc_zodiac.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/qrc_zodiac.o debug/qrc_zodiac.cpp
+
+debug/qrc_molsketch.o: debug/qrc_molsketch.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/qrc_molsketch.o debug/qrc_molsketch.cpp
+
+debug/qrc_molsketchpart_shell.o: debug/qrc_molsketchpart_shell.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug/qrc_molsketchpart_shell.o debug/qrc_molsketchpart_shell.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
diff --git a/Makefile.Release b/Makefile.Release
new file mode 100644
index 0000000..f40e117
--- /dev/null
+++ b/Makefile.Release
@@ -0,0 +1,1515 @@
+#############################################################################
+# Makefile for building: Zodiac
+# Generated by qmake (2.01a) (Qt 4.5.0) on: Mon 18. May 13:13:03 2009
+# Project: zodiac.pro
+# Template: app
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_SVG_LIB -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN
+CFLAGS = -O2 -Wall $(DEFINES) -D HAPTICS
+CXXFLAGS = -O2 -frtti -fexceptions -mthreads -Wall $(DEFINES) -D HAPTICS
+INCPATH = -I'f:/Qt/2009.01/qt/include/QtCore' -I'f:/Qt/2009.01/qt/include/QtNetwork' -I'f:/Qt/2009.01/qt/include/QtGui' -I'f:/Qt/2009.01/qt/include/QtOpenGL' -I'f:/Qt/2009.01/qt/include/Qt3Support' -I'f:/Qt/2009.01/qt/include/QtSvg' -I'f:/Qt/2009.01/qt/include' -I'f:/Qt/2009.01/qt/include/QtAssistantClient' -I'f:/Qt/2009.01/qt/include/QtAssistant' -I'.' -I'headers' -I'molsketch_helium' -I'../Program Files (x86)/openbabel/include/openbabel-2.0' -I'c:/Program Files/openbabel/include/ [...]
+LINK = g++
+LFLAGS = -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads -Wl -Wl,-subsystem,windows
+LIBS = -L'f:/Qt/2009.01/qt/lib' -lopengl32 -lglu32 -lgdi32 -luser32 -lmingw32 -lqtmain release/win_rc_res.o "-LC:\Program Files (x86)\openbabel\lib" "-LC:\Program Files\openbabel\lib" -lopenbabel-2 -lQtAssistantClient4 -lQtSvg4 -lQt3Support4 -lQtOpenGL4 -lQtGui4 -lQtNetwork4 -lQtCore4 "C:\Program Files (x86)\SensAble\3DTouch\lib\hd.lib"
+QMAKE = f:/qt/2009.01/qt/bin/qmake.exe
+IDC = f:/Qt/2009.01/qt/bin/idc.exe
+IDL = midl
+ZIP = zip -r -9
+DEF_FILE =
+RES_FILE = release/win_rc_res.o
+COPY = cp
+COPY_FILE = $(COPY)
+COPY_DIR = xcopy /s /q /y /i
+DEL_FILE = rm
+DEL_DIR = rmdir
+MOVE = mv
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir
+INSTALL_FILE = $(COPY_FILE)
+INSTALL_PROGRAM = $(COPY_FILE)
+INSTALL_DIR = $(COPY_DIR)
+
+####### Output directory
+
+OBJECTS_DIR = release/
+
+####### Files
+
+SOURCES = actions.cc \
+ arcball.cc \
+ builder.cc \
+ chemscore.cc \
+ command.cc \
+ constants.cc \
+ database.cc \
+ datagrid.cc \
+ ddwin.cc \
+ FF.cc \
+ graphical_object.cc \
+ iodevice.cc \
+ MarchingCubes.cc \
+ maths.cc \
+ menu.cc \
+ minimize.cc \
+ MMFF.cc \
+ myline.cc \
+ plants.cc \
+ plants_mainwin.cc \
+ plantsconfig.cc \
+ PLP.cc \
+ ply.c \
+ povray.cc \
+ thread.cc \
+ wiimote.cc \
+ ZNdata.cc \
+ ZNmolecule.cc \
+ Zodiac.cc \
+ forcefields/forcefieldghemical.cpp \
+ forcefields/forcefieldmmff94.cpp \
+ forcefields/forcefielduff.cpp \
+ molsketch_helium/atom.cpp \
+ molsketch_helium/bond.cpp \
+ molsketch_helium/commands.cpp \
+ molsketch_helium/element.cpp \
+ molsketch_helium/fileio.cpp \
+ molsketch_helium/mainwindow.cpp \
+ molsketch_helium/molecule.cpp \
+ molsketch_helium/mollibitem.cpp \
+ molsketch_helium/molscene.cpp \
+ molsketch_helium/molview.cpp \
+ molsketch_helium/periodictablewidget.cpp \
+ molsketch_helium/settings.cpp \
+ molsketch_helium/part/molsketch_factory.cpp \
+ molsketch_helium/part/molsketchpart.cpp \
+ molsketch_helium/part/molsketchpart_shell.cpp release/moc_ddwin.cpp \
+ release/moc_menu.cpp \
+ release/moc_myline.cpp \
+ release/moc_plants.cpp \
+ release/moc_plants_mainwin.cpp \
+ release/moc_thread.cpp \
+ release/moc_ZNdata.cpp \
+ release/moc_mainwindow.cpp \
+ release/moc_molscene.cpp \
+ release/moc_molview.cpp \
+ release/moc_periodictablewidget.cpp \
+ release/moc_settings.cpp \
+ release/qrc_resources.cpp \
+ release/qrc_zodiac.cpp \
+ release/qrc_molsketch.cpp \
+ release/qrc_molsketchpart_shell.cpp
+OBJECTS = release/actions.o \
+ release/arcball.o \
+ release/builder.o \
+ release/chemscore.o \
+ release/command.o \
+ release/constants.o \
+ release/database.o \
+ release/datagrid.o \
+ release/ddwin.o \
+ release/FF.o \
+ release/graphical_object.o \
+ release/iodevice.o \
+ release/MarchingCubes.o \
+ release/maths.o \
+ release/menu.o \
+ release/minimize.o \
+ release/MMFF.o \
+ release/myline.o \
+ release/plants.o \
+ release/plants_mainwin.o \
+ release/plantsconfig.o \
+ release/PLP.o \
+ release/ply.o \
+ release/povray.o \
+ release/thread.o \
+ release/wiimote.o \
+ release/ZNdata.o \
+ release/ZNmolecule.o \
+ release/Zodiac.o \
+ release/forcefieldghemical.o \
+ release/forcefieldmmff94.o \
+ release/forcefielduff.o \
+ release/atom.o \
+ release/bond.o \
+ release/commands.o \
+ release/element.o \
+ release/fileio.o \
+ release/mainwindow.o \
+ release/molecule.o \
+ release/mollibitem.o \
+ release/molscene.o \
+ release/molview.o \
+ release/periodictablewidget.o \
+ release/settings.o \
+ release/molsketch_factory.o \
+ release/molsketchpart.o \
+ release/molsketchpart_shell.o \
+ release/moc_ddwin.o \
+ release/moc_menu.o \
+ release/moc_myline.o \
+ release/moc_plants.o \
+ release/moc_plants_mainwin.o \
+ release/moc_thread.o \
+ release/moc_ZNdata.o \
+ release/moc_mainwindow.o \
+ release/moc_molscene.o \
+ release/moc_molview.o \
+ release/moc_periodictablewidget.o \
+ release/moc_settings.o \
+ release/qrc_resources.o \
+ release/qrc_zodiac.o \
+ release/qrc_molsketch.o \
+ release/qrc_molsketchpart_shell.o
+DIST =
+QMAKE_TARGET = Zodiac
+DESTDIR = release/ #avoid trailing-slash linebreak
+TARGET = Zodiac.exe
+DESTDIR_TARGET = release/Zodiac.exe
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cc .cxx .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+first: all
+all: Makefile.Release $(DESTDIR_TARGET)
+
+$(DESTDIR_TARGET): ui_zodiac.h ui_settings.h $(OBJECTS) release/win_rc_res.o
+ $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.Zodiac.Release $(LIBS)
+
+
+release/win_rc_res.o: win_rc.rc
+ windres -i win_rc.rc -o release/win_rc_res.o --include-dir=.
+
+qmake: FORCE
+ @$(QMAKE) -win32 -o Makefile.Release zodiac.pro
+
+dist:
+ $(ZIP) Zodiac.zip $(SOURCES) $(DIST) zodiac.pro f:/Qt/2009.01/qt/mkspecs/qconfig.pri f:/Qt/2009.01/qt/mkspecs/features/qt_functions.prf f:/Qt/2009.01/qt/mkspecs/features/qt_config.prf f:/Qt/2009.01/qt/mkspecs/features/exclusive_builds.prf f:/Qt/2009.01/qt/mkspecs/features/default_pre.prf f:/Qt/2009.01/qt/mkspecs/features/win32/default_pre.prf f:/Qt/2009.01/qt/mkspecs/features/release.prf f:/Qt/2009.01/qt/mkspecs/features/debug_and_release.prf f:/Qt/2009.01/qt/mkspecs/features/default_po [...]
+
+clean: compiler_clean
+ -$(DEL_FILE) release/actions.o release/arcball.o release/builder.o release/chemscore.o release/command.o release/constants.o release/database.o release/datagrid.o release/ddwin.o release/FF.o release/graphical_object.o release/iodevice.o release/MarchingCubes.o release/maths.o release/menu.o release/minimize.o release/MMFF.o release/myline.o release/plants.o release/plants_mainwin.o release/plantsconfig.o release/PLP.o release/ply.o release/povray.o release/thread.o release/wiimote.o re [...]
+ -$(DEL_FILE) release/win_rc_res.o
+
+distclean: clean
+ -$(DEL_FILE) $(DESTDIR_TARGET)
+ -$(DEL_FILE) Makefile.Release
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_moc_header_make_all: release/moc_ddwin.cpp release/moc_menu.cpp release/moc_myline.cpp release/moc_plants.cpp release/moc_plants_mainwin.cpp release/moc_thread.cpp release/moc_ZNdata.cpp release/moc_mainwindow.cpp release/moc_molscene.cpp release/moc_molview.cpp release/moc_periodictablewidget.cpp release/moc_settings.cpp
+compiler_moc_header_clean:
+ -$(DEL_FILE) release/moc_ddwin.cpp release/moc_menu.cpp release/moc_myline.cpp release/moc_plants.cpp release/moc_plants_mainwin.cpp release/moc_thread.cpp release/moc_ZNdata.cpp release/moc_mainwindow.cpp release/moc_molscene.cpp release/moc_molview.cpp release/moc_periodictablewidget.cpp release/moc_settings.cpp
+release/moc_ddwin.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/ddwin.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/ddwin.h -o release/moc_ddwin.cpp
+
+release/moc_menu.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/menu.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/menu.h -o release/moc_menu.cpp
+
+release/moc_myline.cpp: headers/myline.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/myline.h -o release/moc_myline.cpp
+
+release/moc_plants.cpp: headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/plants.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/plants.h -o release/moc_plants.cpp
+
+release/moc_plants_mainwin.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/plants_mainwin.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/plants_mainwin.h -o release/moc_plants_mainwin.cpp
+
+release/moc_thread.cpp: headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/thread.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/thread.h -o release/moc_thread.cpp
+
+release/moc_ZNdata.cpp: headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/ZNdata.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 headers/ZNdata.h -o release/moc_ZNdata.cpp
+
+release/moc_mainwindow.cpp: obabel_includes.h \
+ molsketch_helium/mainwindow.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/mainwindow.h -o release/moc_mainwindow.cpp
+
+release/moc_molscene.cpp: molsketch_helium/mollibitem.h \
+ molsketch_helium/molscene.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/molscene.h -o release/moc_molscene.cpp
+
+release/moc_molview.cpp: molsketch_helium/molview.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/molview.h -o release/moc_molview.cpp
+
+release/moc_periodictablewidget.cpp: molsketch_helium/periodictablewidget.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/periodictablewidget.h -o release/moc_periodictablewidget.cpp
+
+release/moc_settings.cpp: ui_settings.h \
+ molsketch_helium/settings.h
+ f:/Qt/2009.01/qt/bin/moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 molsketch_helium/settings.h -o release/moc_settings.cpp
+
+compiler_rcc_make_all: release/qrc_resources.cpp release/qrc_zodiac.cpp release/qrc_molsketch.cpp release/qrc_molsketchpart_shell.cpp
+compiler_rcc_clean:
+ -$(DEL_FILE) release/qrc_resources.cpp release/qrc_zodiac.cpp release/qrc_molsketch.cpp release/qrc_molsketchpart_shell.cpp
+release/qrc_resources.cpp: resources.qrc \
+ parameters/MMFFOOP.PAR \
+ parameters/MMFFBNDK.PAR \
+ parameters/MMFFDEF.PAR \
+ parameters/MMFFSYMB.PAR \
+ parameters/MMFF93SUP.PAR \
+ parameters/MMFFPBCI.PAR \
+ parameters/MMFFAROM.PAR \
+ parameters/MMFFVDW.PAR \
+ parameters/MMFFSTBN.PAR \
+ parameters/MMFFDFSB.PAR \
+ parameters/MMFFANG.PAR \
+ parameters/MMFFBOND.PAR \
+ parameters/MMFFCHG.PAR \
+ parameters/MMFFHDEF.PAR \
+ parameters/MMFFPROP.PAR \
+ parameters/MMFFTOR.PAR \
+ icons/redo.png \
+ icons/undo.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name resources resources.qrc -o release/qrc_resources.cpp
+
+release/qrc_zodiac.cpp: zodiac.qrc \
+ icons/invert_selection.png \
+ icons/builder_S.png \
+ icons/pointer_rubber.png \
+ icons/X.png \
+ icons/select_C.png \
+ icons/ring3.png \
+ icons/builder_del.png \
+ icons/pencil_C.png \
+ icons/redo.png \
+ icons/benzene.png \
+ icons/pencil_S.png \
+ icons/builder_3bond.png \
+ icons/arrow.png \
+ icons/minimise.png \
+ icons/ring4.png \
+ icons/builder_N.png \
+ icons/deselect.png \
+ icons/builder_pencil.png \
+ icons/ring5.png \
+ icons/builder_O.png \
+ icons/periodic_table.png \
+ icons/select_H.png \
+ icons/zeden_ico.png \
+ icons/select_square.png \
+ icons/select_all.png \
+ icons/furanO.png \
+ icons/pencil_N.png \
+ icons/ring6.png \
+ icons/select.png \
+ icons/builder_1bond.png \
+ icons/undo.png \
+ icons/builder_C.png \
+ icons/pencil_O.png \
+ icons/builder_smile.png \
+ icons/ring7.png \
+ icons/builder_Xbond.png \
+ icons/pointer_select_square.png \
+ icons/V.png \
+ icons/furan.png \
+ icons/builder_2bond.png \
+ icons/haptic.png \
+ icons/ring8.png \
+ icons/builder.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name zodiac zodiac.qrc -o release/qrc_zodiac.cpp
+
+release/qrc_molsketch.cpp: molsketch_helium/molsketch.qrc \
+ molsketch_helium/images/document-new.png \
+ molsketch_helium/images/edit-redo.png \
+ molsketch_helium/images/zoom-original.png \
+ molsketch_helium/images/edit-copy.png \
+ molsketch_helium/images/document-import.png \
+ molsketch_helium/images/document-save-as.png \
+ molsketch_helium/images/edit-undo.png \
+ molsketch_helium/images/document-print.png \
+ molsketch_helium/images/draw-freehand.svg \
+ molsketch_helium/images/draw-eraser.png \
+ molsketch_helium/images/help-contextual.png \
+ molsketch_helium/images/document-open.png \
+ molsketch_helium/images/molsketch.png \
+ molsketch_helium/images/transform-rotate.png \
+ molsketch_helium/images/configure.svg \
+ molsketch_helium/images/help-about.png \
+ molsketch_helium/images/document-open.svg \
+ molsketch_helium/images/edit-paste.png \
+ molsketch_helium/images/zoom-fit-best.png \
+ molsketch_helium/images/configure.png \
+ molsketch_helium/images/molsketch.svg \
+ molsketch_helium/images/edit-select-all.png \
+ molsketch_helium/images/application-exit.png \
+ molsketch_helium/images/edit-cut.png \
+ molsketch_helium/images/document-save.png \
+ molsketch_helium/images/zoom-out.png \
+ molsketch_helium/images/transform-move.png \
+ molsketch_helium/images/zoom-in.png \
+ molsketch_helium/images/document-export.png \
+ molsketch_helium/images/help-contents.png \
+ molsketch_helium/images/draw-freehand.png
+ f:/Qt/2009.01/qt/bin/rcc.exe -name molsketch molsketch_helium/molsketch.qrc -o release/qrc_molsketch.cpp
+
+release/qrc_molsketchpart_shell.cpp: molsketch_helium/part/molsketchpart_shell.qrc \
+ molsketch_helium/part/molsketch.svg
+ f:/Qt/2009.01/qt/bin/rcc.exe -name molsketchpart_shell molsketch_helium/part/molsketchpart_shell.qrc -o release/qrc_molsketchpart_shell.cpp
+
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+ -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_uic_make_all: ui_zodiac.h ui_settings.h
+compiler_uic_clean:
+ -$(DEL_FILE) ui_zodiac.h ui_settings.h
+ui_zodiac.h: zodiac.ui
+ f:/Qt/2009.01/qt/bin/uic.exe zodiac.ui -o ui_zodiac.h
+
+ui_settings.h: molsketch_helium/settings.ui
+ f:/Qt/2009.01/qt/bin/uic.exe molsketch_helium/settings.ui -o ui_settings.h
+
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean compiler_rcc_clean compiler_uic_clean
+
+
+
+####### Compile
+
+release/actions.o: actions.cc headers/actions.h \
+ headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/actions.o actions.cc
+
+release/arcball.o: arcball.cc headers/arcball.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/arcball.o arcball.cc
+
+release/builder.o: builder.cc headers/builder.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/builder.o builder.cc
+
+release/chemscore.o: chemscore.cc headers/chemscore.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h \
+ headers/datagrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/chemscore.o chemscore.cc
+
+release/command.o: command.cc headers/command.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/command.o command.cc
+
+release/constants.o: constants.cc headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/constants.o constants.cc
+
+release/database.o: database.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/database.o database.cc
+
+release/datagrid.o: datagrid.cc headers/datagrid.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/datagrid.o datagrid.cc
+
+release/ddwin.o: ddwin.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/ddwin.o ddwin.cc
+
+release/FF.o: FF.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/FF.o FF.cc
+
+release/graphical_object.o: graphical_object.cc headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/graphical_object.o graphical_object.cc
+
+release/iodevice.o: iodevice.cc headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/iodevice.o iodevice.cc
+
+release/MarchingCubes.o: MarchingCubes.cc headers/MarchingCubes.h \
+ headers/ply.h \
+ headers/LookUpTable.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/wiimote.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/MarchingCubes.o MarchingCubes.cc
+
+release/maths.o: maths.cc headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/maths.o maths.cc
+
+release/menu.o: menu.cc headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/menu.o menu.cc
+
+release/minimize.o: minimize.cc headers/minimize.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/minimize.o minimize.cc
+
+release/MMFF.o: MMFF.cc headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/MMFF.o MMFF.cc
+
+release/myline.o: myline.cc headers/myline.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/myline.o myline.cc
+
+release/plants.o: plants.cc headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/plants.o plants.cc
+
+release/plants_mainwin.o: plants_mainwin.cc headers/myline.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/plants_mainwin.o plants_mainwin.cc
+
+release/plantsconfig.o: plantsconfig.cc headers/plantsconfig.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/myline.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/plantsconfig.o plantsconfig.cc
+
+release/PLP.o: PLP.cc headers/PLP.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/PLP.o PLP.cc
+
+release/ply.o: ply.c headers/ply.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o release/ply.o ply.c
+
+release/povray.o: povray.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/povray.o povray.cc
+
+release/thread.o: thread.cc headers/thread.h \
+ headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h \
+ headers/pso.h \
+ headers/wiimote.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/thread.o thread.cc
+
+release/wiimote.o: wiimote.cc headers/wiimote.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/wiimote.o wiimote.cc
+
+release/ZNdata.o: ZNdata.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/ZNdata.o ZNdata.cc
+
+release/ZNmolecule.o: ZNmolecule.cc headers/ZNmolecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/ZNmolecule.o ZNmolecule.cc
+
+release/Zodiac.o: Zodiac.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ obabel_includes.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/ZNmolecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/pso.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ molsketch_helium/mainwindow.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/Zodiac.o Zodiac.cc
+
+release/forcefieldghemical.o: forcefields/forcefieldghemical.cpp forcefields/forcefieldghemical.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/forcefieldghemical.o forcefields/forcefieldghemical.cpp
+
+release/forcefieldmmff94.o: forcefields/forcefieldmmff94.cpp forcefields/forcefieldmmff94.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/forcefieldmmff94.o forcefields/forcefieldmmff94.cpp
+
+release/forcefielduff.o: forcefields/forcefielduff.cpp forcefields/forcefielduff.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/forcefielduff.o forcefields/forcefielduff.cpp
+
+release/atom.o: molsketch_helium/atom.cpp molsketch_helium/atom.h \
+ molsketch_helium/element.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/bond.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/atom.o molsketch_helium/atom.cpp
+
+release/bond.o: molsketch_helium/bond.cpp molsketch_helium/bond.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/bond.o molsketch_helium/bond.cpp
+
+release/commands.o: molsketch_helium/commands.cpp molsketch_helium/commands.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/commands.o molsketch_helium/commands.cpp
+
+release/element.o: molsketch_helium/element.cpp molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/element.o molsketch_helium/element.cpp
+
+release/fileio.o: molsketch_helium/fileio.cpp molsketch_helium/fileio.h \
+ obabel_includes.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/fileio.o molsketch_helium/fileio.cpp
+
+release/mainwindow.o: molsketch_helium/mainwindow.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/mainwindow.h \
+ obabel_includes.h \
+ molsketch_helium/molview.h \
+ molsketch_helium/element.h \
+ molsketch_helium/settings.h \
+ ui_settings.h \
+ molsketch_helium/fileio.h \
+ molsketch_helium/periodictablewidget.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/mainwindow.o molsketch_helium/mainwindow.cpp
+
+release/molecule.o: molsketch_helium/molecule.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molecule.o molsketch_helium/molecule.cpp
+
+release/mollibitem.o: molsketch_helium/mollibitem.cpp molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/fileio.h \
+ obabel_includes.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/mollibitem.o molsketch_helium/mollibitem.cpp
+
+release/molscene.o: molsketch_helium/molscene.cpp molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/commands.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molscene.o molsketch_helium/molscene.cpp
+
+release/molview.o: molsketch_helium/molview.cpp molsketch_helium/molview.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molview.o molsketch_helium/molview.cpp
+
+release/periodictablewidget.o: molsketch_helium/periodictablewidget.cpp molsketch_helium/periodictablewidget.h \
+ molsketch_helium/element.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/periodictablewidget.o molsketch_helium/periodictablewidget.cpp
+
+release/settings.o: molsketch_helium/settings.cpp molsketch_helium/settings.h \
+ ui_settings.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/mollibitem.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/settings.o molsketch_helium/settings.cpp
+
+release/molsketch_factory.o: molsketch_helium/part/molsketch_factory.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molsketch_factory.o molsketch_helium/part/molsketch_factory.cpp
+
+release/molsketchpart.o: molsketch_helium/part/molsketchpart.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molsketchpart.o molsketch_helium/part/molsketchpart.cpp
+
+release/molsketchpart_shell.o: molsketch_helium/part/molsketchpart_shell.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/molsketchpart_shell.o molsketch_helium/part/molsketchpart_shell.cpp
+
+release/moc_ddwin.o: release/moc_ddwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_ddwin.o release/moc_ddwin.cpp
+
+release/moc_menu.o: release/moc_menu.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_menu.o release/moc_menu.cpp
+
+release/moc_myline.o: release/moc_myline.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_myline.o release/moc_myline.cpp
+
+release/moc_plants.o: release/moc_plants.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_plants.o release/moc_plants.cpp
+
+release/moc_plants_mainwin.o: release/moc_plants_mainwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_plants_mainwin.o release/moc_plants_mainwin.cpp
+
+release/moc_thread.o: release/moc_thread.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_thread.o release/moc_thread.cpp
+
+release/moc_ZNdata.o: release/moc_ZNdata.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_ZNdata.o release/moc_ZNdata.cpp
+
+release/moc_mainwindow.o: release/moc_mainwindow.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_mainwindow.o release/moc_mainwindow.cpp
+
+release/moc_molscene.o: release/moc_molscene.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_molscene.o release/moc_molscene.cpp
+
+release/moc_molview.o: release/moc_molview.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_molview.o release/moc_molview.cpp
+
+release/moc_periodictablewidget.o: release/moc_periodictablewidget.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_periodictablewidget.o release/moc_periodictablewidget.cpp
+
+release/moc_settings.o: release/moc_settings.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/moc_settings.o release/moc_settings.cpp
+
+release/qrc_resources.o: release/qrc_resources.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/qrc_resources.o release/qrc_resources.cpp
+
+release/qrc_zodiac.o: release/qrc_zodiac.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/qrc_zodiac.o release/qrc_zodiac.cpp
+
+release/qrc_molsketch.o: release/qrc_molsketch.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/qrc_molsketch.o release/qrc_molsketch.cpp
+
+release/qrc_molsketchpart_shell.o: release/qrc_molsketchpart_shell.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release/qrc_molsketchpart_shell.o release/qrc_molsketchpart_shell.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
diff --git a/Makefile_old b/Makefile_old
new file mode 100644
index 0000000..ccce08c
--- /dev/null
+++ b/Makefile_old
@@ -0,0 +1,1177 @@
+#############################################################################
+# Makefile for building: Zodiac
+# Generated by qmake (2.01a) (Qt 4.3.4) on: Wed Aug 20 11:48:17 2008
+# Project: Zodiac.pro
+# Template: app
+# Command: /usr/bin/qmake -unix -o Makefile Zodiac.pro
+#############################################################################
+
+####### Compiler, tools and options
+
+CC = gcc
+CXX = g++
+DEFINES = -DQT_SHARED -DQT_GUI_LIB -DQT_CORE_LIB
+CFLAGS = -pipe -g -Wall -W -D_REENTRANT $(DEFINES) -D NDEBUG -O3 -fopenmp
+CXXFLAGS = -pipe -fpermissive -g -Wall -W -D_REENTRANT $(DEFINES) -D NDEBUG -O3 -fopenmp
+INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I/usr/include/qt4/Qt3Support -I./headers -I. -I. -I/usr/local/openbabel-2.0 -I/usr/include/qt4/QtOpenGL/
+LINK = g++
+LFLAGS = -Wl,--no-undefined
+LIBS = $(SUBLIBS) -L/usr/lib -lQtGui -lQtCore -lpthread -lQt3Support -lQtOpenGL -lopenbabel -lQtAssistantClient
+AR = ar cqs
+RANLIB =
+QMAKE = /usr/bin/qmake
+TAR = tar -cf
+COMPRESS = gzip -9f
+COPY = cp -f
+SED = sed
+COPY_FILE = $(COPY)
+COPY_DIR = $(COPY) -r
+INSTALL_FILE = install -m 644 -p
+INSTALL_DIR = $(COPY_DIR)
+INSTALL_PROGRAM = install -m 755 -p
+DEL_FILE = rm -f
+SYMLINK = ln -sf
+DEL_DIR = rmdir
+MOVE = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR = mkdir -p
+
+####### Output directory
+
+OBJECTS_DIR = ./objects
+
+####### Files
+
+SOURCES = actions.cc \
+ arcball.cc \
+ builder.cc \
+ chemscore.cc \
+ command.cc \
+ constants.cc \
+ database.cc \
+ datagrid.cc \
+ ddwin.cc \
+ FF.cc \
+ graphical_object.cc \
+ haptics.cpp \
+ MarchingCubes.cc \
+ maths.cc \
+ menu.cc \
+ minimize.cc \
+ MMFF.cc \
+ molecule.cc \
+ myline.cc \
+ plants.cc \
+ plants_mainwin.cc \
+ plantsconfig.cc \
+ PLP.cc \
+ ply.c \
+ povray.cc \
+ thread.cc \
+ wiimote.cc \
+ ZNdata.cc \
+ Zodiac.cc \
+ headers/iodevice.cc moc_ddwin.cpp \
+ moc_thread.cpp \
+ moc_menu.cpp \
+ moc_myline.cpp \
+ moc_plants.cpp \
+ moc_plants_mainwin.cpp \
+ qrc_resources.cpp \
+ qrc_zodiac.cpp
+OBJECTS = actions.o \
+ arcball.o \
+ builder.o \
+ chemscore.o \
+ command.o \
+ constants.o \
+ database.o \
+ datagrid.o \
+ ddwin.o \
+ FF.o \
+ graphical_object.o \
+ haptics.o \
+ MarchingCubes.o \
+ maths.o \
+ menu.o \
+ minimize.o \
+ MMFF.o \
+ molecule.o \
+ myline.o \
+ plants.o \
+ plants_mainwin.o \
+ plantsconfig.o \
+ PLP.o \
+ ply.o \
+ povray.o \
+ thread.o \
+ wiimote.o \
+ ZNdata.o \
+ Zodiac.o \
+ iodevice.o \
+ moc_ddwin.o \
+ moc_thread.o \
+ moc_menu.o \
+ moc_myline.o \
+ moc_plants.o \
+ moc_plants_mainwin.o \
+ qrc_resources.o \
+ qrc_zodiac.o
+DIST = /usr/share/qt4/mkspecs/common/g++.conf \
+ /usr/share/qt4/mkspecs/common/unix.conf \
+ /usr/share/qt4/mkspecs/common/linux.conf \
+ /usr/share/qt4/mkspecs/qconfig.pri \
+ /usr/share/qt4/mkspecs/features/qt_functions.prf \
+ /usr/share/qt4/mkspecs/features/qt_config.prf \
+ /usr/share/qt4/mkspecs/features/exclusive_builds.prf \
+ /usr/share/qt4/mkspecs/features/default_pre.prf \
+ /usr/share/qt4/mkspecs/features/debug.prf \
+ /usr/share/qt4/mkspecs/features/default_post.prf \
+ /usr/share/qt4/mkspecs/features/warn_on.prf \
+ /usr/share/qt4/mkspecs/features/qt.prf \
+ /usr/share/qt4/mkspecs/features/unix/thread.prf \
+ /usr/share/qt4/mkspecs/features/moc.prf \
+ /usr/share/qt4/mkspecs/features/resources.prf \
+ /usr/share/qt4/mkspecs/features/uic.prf \
+ /usr/share/qt4/mkspecs/features/yacc.prf \
+ /usr/share/qt4/mkspecs/features/lex.prf \
+ Zodiac.pro
+QMAKE_TARGET = Zodiac
+DESTDIR =
+TARGET = Zodiac
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile $(TARGET)
+
+$(TARGET): ui_zodiac.h $(OBJECTS)
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
+
+Makefile: Zodiac.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/g++.conf \
+ /usr/share/qt4/mkspecs/common/unix.conf \
+ /usr/share/qt4/mkspecs/common/linux.conf \
+ /usr/share/qt4/mkspecs/qconfig.pri \
+ /usr/share/qt4/mkspecs/features/qt_functions.prf \
+ /usr/share/qt4/mkspecs/features/qt_config.prf \
+ /usr/share/qt4/mkspecs/features/exclusive_builds.prf \
+ /usr/share/qt4/mkspecs/features/default_pre.prf \
+ /usr/share/qt4/mkspecs/features/debug.prf \
+ /usr/share/qt4/mkspecs/features/default_post.prf \
+ /usr/share/qt4/mkspecs/features/warn_on.prf \
+ /usr/share/qt4/mkspecs/features/qt.prf \
+ /usr/share/qt4/mkspecs/features/unix/thread.prf \
+ /usr/share/qt4/mkspecs/features/moc.prf \
+ /usr/share/qt4/mkspecs/features/resources.prf \
+ /usr/share/qt4/mkspecs/features/uic.prf \
+ /usr/share/qt4/mkspecs/features/yacc.prf \
+ /usr/share/qt4/mkspecs/features/lex.prf
+ $(QMAKE) -unix -o Makefile Zodiac.pro
+/usr/share/qt4/mkspecs/common/g++.conf:
+/usr/share/qt4/mkspecs/common/unix.conf:
+/usr/share/qt4/mkspecs/common/linux.conf:
+/usr/share/qt4/mkspecs/qconfig.pri:
+/usr/share/qt4/mkspecs/features/qt_functions.prf:
+/usr/share/qt4/mkspecs/features/qt_config.prf:
+/usr/share/qt4/mkspecs/features/exclusive_builds.prf:
+/usr/share/qt4/mkspecs/features/default_pre.prf:
+/usr/share/qt4/mkspecs/features/debug.prf:
+/usr/share/qt4/mkspecs/features/default_post.prf:
+/usr/share/qt4/mkspecs/features/warn_on.prf:
+/usr/share/qt4/mkspecs/features/qt.prf:
+/usr/share/qt4/mkspecs/features/unix/thread.prf:
+/usr/share/qt4/mkspecs/features/moc.prf:
+/usr/share/qt4/mkspecs/features/resources.prf:
+/usr/share/qt4/mkspecs/features/uic.prf:
+/usr/share/qt4/mkspecs/features/yacc.prf:
+/usr/share/qt4/mkspecs/features/lex.prf:
+qmake: FORCE
+ @$(QMAKE) -unix -o Makefile Zodiac.pro
+
+dist:
+ @$(CHK_DIR_EXISTS) .tmp/Zodiac1.0.0 || $(MKDIR) .tmp/Zodiac1.0.0
+ $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/Zodiac1.0.0/ && $(COPY_FILE) --parents arcball.h cmat.h ddwin.h thread.h vec.h wiimote.h ZNdata.h headers/actions.h headers/builder.h headers/chemscore.h headers/command.h headers/constants.h headers/cutoffGrid.h headers/database.h headers/datagrid.h headers/FF.h headers/function.h headers/graphical_object.h headers/haptics.h headers/ils.h headers/iodevice.h headers/LookUpTable.h headers/MarchingCubes.h headers/maths.h headers/menu.h header [...]
+
+
+clean:compiler_clean
+ -$(DEL_FILE) $(OBJECTS)
+ -$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+ -$(DEL_FILE) $(TARGET)
+ -$(DEL_FILE) Makefile
+
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_moc_header_make_all: moc_ddwin.cpp moc_thread.cpp moc_menu.cpp moc_myline.cpp moc_plants.cpp moc_plants_mainwin.cpp
+compiler_moc_header_clean:
+ -$(DEL_FILE) moc_ddwin.cpp moc_thread.cpp moc_menu.cpp moc_myline.cpp moc_plants.cpp moc_plants_mainwin.cpp
+moc_ddwin.cpp: headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/ddwin.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) ddwin.h -o moc_ddwin.cpp
+
+moc_thread.cpp: headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/thread.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) thread.h -o moc_thread.cpp
+
+moc_menu.cpp: headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/menu.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) headers/menu.h -o moc_menu.cpp
+
+moc_myline.cpp: headers/myline.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) headers/myline.h -o moc_myline.cpp
+
+moc_plants.cpp: headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/plants.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) headers/plants.h -o moc_plants.cpp
+
+moc_plants_mainwin.cpp: headers/constants.h \
+ headers/maths.h \
+ headers/myline.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/plants_mainwin.h
+ /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) headers/plants_mainwin.h -o moc_plants_mainwin.cpp
+
+compiler_rcc_make_all: qrc_resources.cpp qrc_zodiac.cpp
+compiler_rcc_clean:
+ -$(DEL_FILE) qrc_resources.cpp qrc_zodiac.cpp
+qrc_resources.cpp: resources.qrc \
+ parameters/MMFFOOP.PAR \
+ parameters/MMFFBNDK.PAR \
+ parameters/MMFFDEF.PAR \
+ parameters/MMFFSYMB.PAR \
+ parameters/MMFF93SUP.PAR \
+ parameters/MMFFPBCI.PAR \
+ parameters/MMFFAROM.PAR \
+ parameters/MMFFVDW.PAR \
+ parameters/MMFFSTBN.PAR \
+ parameters/MMFFDFSB.PAR \
+ parameters/MMFFANG.PAR \
+ parameters/MMFFBOND.PAR \
+ parameters/MMFFCHG.PAR \
+ parameters/MMFFHDEF.PAR \
+ parameters/MMFFPROP.PAR \
+ parameters/MMFFTOR.PAR \
+ icons/redo.png \
+ icons/undo.png
+ /usr/bin/rcc -name resources resources.qrc -o qrc_resources.cpp
+
+qrc_zodiac.cpp: zodiac.qrc \
+ icons/haptic.png \
+ icons/redo.png \
+ icons/minimise.png \
+ icons/undo.png \
+ icons/zeden_ico.png
+ /usr/bin/rcc -name zodiac zodiac.qrc -o qrc_zodiac.cpp
+
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+ -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_uic_make_all: ui_zodiac.h
+compiler_uic_clean:
+ -$(DEL_FILE) ui_zodiac.h
+ui_zodiac.h: zodiac.ui
+ /usr/bin/uic-qt4 zodiac.ui -o ui_zodiac.h
+
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean compiler_rcc_clean compiler_uic_clean
+
+####### Compile
+
+actions.o: actions.cc headers/actions.h \
+ headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o actions.o actions.cc
+
+arcball.o: arcball.cc headers/arcball.h \
+ headers/constants.h \
+ headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o arcball.o arcball.cc
+
+builder.o: builder.cc headers/builder.h \
+ headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o builder.o builder.cc
+
+chemscore.o: chemscore.cc headers/chemscore.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/cutoffGrid.h \
+ headers/datagrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o chemscore.o chemscore.cc
+
+command.o: command.cc headers/command.h \
+ headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o command.o command.cc
+
+constants.o: constants.cc headers/constants.h \
+ headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o constants.o constants.cc
+
+database.o: database.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o database.o database.cc
+
+datagrid.o: datagrid.cc headers/datagrid.h \
+ headers/constants.h \
+ headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o datagrid.o datagrid.cc
+
+ddwin.o: ddwin.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ddwin.o ddwin.cc
+
+FF.o: FF.cc headers/database.h \
+ headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o FF.o FF.cc
+
+graphical_object.o: graphical_object.cc headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/ddwin.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o graphical_object.o graphical_object.cc
+
+haptics.o: haptics.cpp headers/haptics.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o haptics.o haptics.cpp
+
+
+MarchingCubes.o: MarchingCubes.cc headers/MarchingCubes.h \
+ headers/ply.h \
+ headers/LookUpTable.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o MarchingCubes.o MarchingCubes.cc
+
+maths.o: maths.cc headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o maths.o maths.cc
+
+menu.o: menu.cc headers/menu.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o menu.o menu.cc
+
+minimize.o: minimize.cc headers/minimize.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/haptics.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o minimize.o minimize.cc
+
+MMFF.o: MMFF.cc headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o MMFF.o MMFF.cc
+
+molecule.o: molecule.cc headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o molecule.o molecule.cc
+
+myline.o: myline.cc headers/myline.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o myline.o myline.cc
+
+plants.o: plants.cc headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o plants.o plants.cc
+
+plants_mainwin.o: plants_mainwin.cc headers/myline.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/plants.h \
+ headers/plantsconfig.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o plants_mainwin.o plants_mainwin.cc
+
+plantsconfig.o: plantsconfig.cc headers/plantsconfig.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/myline.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o plantsconfig.o plantsconfig.cc
+
+PLP.o: PLP.cc headers/PLP.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/cutoffGrid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o PLP.o PLP.cc
+
+ply.o: ply.c headers/ply.h
+ $(CC) -c $(CFLAGS) $(INCPATH) -o ply.o ply.c
+
+povray.o: povray.cc headers/ddwin.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/graphical_object.h \
+ headers/MarchingCubes.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o povray.o povray.cc
+
+thread.o: thread.cc headers/thread.h \
+ headers/graphical_object.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MarchingCubes.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/minimize.h \
+ headers/ZNdata.h \
+ headers/MMFF.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/function.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/haptics.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o thread.o thread.cc
+
+wiimote.o: wiimote.cc headers/wiimote.h \
+ headers/maths.h \
+ /usr/local/include/cwiid.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o wiimote.o wiimote.cc
+
+ZNdata.o: ZNdata.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZNdata.o ZNdata.cc
+
+Zodiac.o: Zodiac.cc headers/ZNdata.h \
+ headers/constants.h \
+ headers/maths.h \
+ headers/MMFF.h \
+ headers/FF.h \
+ headers/molecule.h \
+ headers/cutoffGrid.h \
+ headers/PLP.h \
+ headers/chemscore.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/arcball.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/myline.h \
+ headers/plantsconfig.h \
+ headers/MarchingCubes.h \
+ headers/graphical_object.h \
+ headers/minimize.h \
+ headers/thread.h \
+ headers/wiimote.h \
+ /usr/local/include/cwiid.h \
+ headers/ils.h \
+ headers/optimiser.h \
+ headers/function.h \
+ headers/nms.h \
+ headers/subscrpt.h \
+ headers/cmat.h \
+ headers/vec.h \
+ headers/builder.h \
+ headers/menu.h \
+ headers/command.h \
+ headers/database.h \
+ headers/actions.h \
+ headers/iodevice.h \
+ headers/haptics.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Zodiac.o Zodiac.cc
+
+iodevice.o: headers/iodevice.cc headers/iodevice.h \
+ headers/maths.h
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o iodevice.o headers/iodevice.cc
+
+moc_ddwin.o: moc_ddwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ddwin.o moc_ddwin.cpp
+
+moc_thread.o: moc_thread.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_thread.o moc_thread.cpp
+
+moc_menu.o: moc_menu.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_menu.o moc_menu.cpp
+
+moc_myline.o: moc_myline.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_myline.o moc_myline.cpp
+
+moc_plants.o: moc_plants.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_plants.o moc_plants.cpp
+
+moc_plants_mainwin.o: moc_plants_mainwin.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_plants_mainwin.o moc_plants_mainwin.cpp
+
+qrc_resources.o: qrc_resources.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qrc_resources.o qrc_resources.cpp
+
+qrc_zodiac.o: qrc_zodiac.cpp
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qrc_zodiac.o qrc_zodiac.cpp
+
+####### Install
+
+install: FORCE
+
+uninstall: FORCE
+
+FORCE:
+
diff --git a/MarchingCubes.cc b/MarchingCubes.cc
new file mode 100644
index 0000000..df3a005
--- /dev/null
+++ b/MarchingCubes.cc
@@ -0,0 +1,2417 @@
+/**
+
+ * @file MarchingCubes.cpp
+
+ * @author Thomas Lewiner <thomas.lewiner at polytechnique.org>
+
+ * @author Math Dept, PUC-Rio
+
+ * @version 0.2
+
+ * @date 12/08/2002
+
+ *
+
+ * @brief MarchingCubes Algorithm
+
+ */
+
+//________________________________________________
+
+
+
+
+
+#if !defined(WIN32) || defined(__CYGWIN__)
+
+#pragma implementation
+
+#endif // WIN32
+
+
+
+#include <math.h>
+
+#include <time.h>
+
+#include <memory.h>
+
+#include <float.h>
+
+#include "MarchingCubes.h"
+
+#include "ply.h"
+
+#include "LookUpTable.h"
+
+#include "thread.h"
+
+// step size of the arrays of vertices && triangles
+
+#define ALLOC_SIZE 65536
+
+
+
+//_____________________________________________________________________________
+
+// print cube for debug
+
+void MarchingCubes::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; }
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Constructor
+
+MarchingCubes::MarchingCubes( const int size_x /*= -1*/, const int size_y /*= -1*/, const int size_z /*= -1*/ ) :
+
+//-----------------------------------------------------------------------------
+
+ _originalMC(false),
+
+ _ext_data (false),
+
+ _size_x (size_x),
+
+ _size_y (size_y),
+
+ _size_z (size_z),
+
+ _data ((real *)NULL),
+
+ _x_verts (( int *)NULL),
+
+ _y_verts (( int *)NULL),
+
+ _z_verts (( int *)NULL),
+
+ _nverts (0),
+
+ _ntrigs (0),
+
+ _Nverts (0),
+
+ _Ntrigs (0),
+
+ _vertices (( Vertex *)NULL),
+
+ _triangles ((Triangle*)NULL)
+
+{}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Destructor
+
+MarchingCubes::~MarchingCubes()
+
+//-----------------------------------------------------------------------------
+
+{
+
+ clean_all() ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// main algorithm
+
+void MarchingCubes::run( real iso, int *prog, int *max )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if (max) *max = _size_z -2;
+ printf("Marching Cubes begin: cpu %ld\n", clock() ) ;
+
+
+
+ compute_intersection_points( iso ) ;
+
+
+
+ for( _k = 0 ; _k < _size_z-1 ; _k++ ) {
+ if (prog) *prog = _k;
+ for( _j = 0 ; _j < _size_y-1 ; _j++ )
+
+ for( _i = 0 ; _i < _size_x-1 ; _i++ )
+
+ {
+
+ _lut_entry = 0 ;
+
+ for( int p = 0 ; p < 8 ; ++p )
+
+ {
+
+ _cube[p] = get_data( _i+((p^(p>>1))&1), _j+((p>>1)&1), _k+((p>>2)&1) ) - iso ;
+
+ if( fabs( _cube[p] ) < FLT_EPSILON ) _cube[p] = FLT_EPSILON ;
+
+ if( _cube[p] > 0 ) _lut_entry += 1 << p ;
+
+ }
+
+/*
+
+ if( ( _cube[0] = get_data( _i , _j , _k ) ) > 0 ) _lut_entry += 1 ;
+
+ if( ( _cube[1] = get_data(_i+1, _j , _k ) ) > 0 ) _lut_entry += 2 ;
+
+ if( ( _cube[2] = get_data(_i+1,_j+1, _k ) ) > 0 ) _lut_entry += 4 ;
+
+ if( ( _cube[3] = get_data( _i ,_j+1, _k ) ) > 0 ) _lut_entry += 8 ;
+
+ if( ( _cube[4] = get_data( _i , _j ,_k+1) ) > 0 ) _lut_entry += 16 ;
+
+ if( ( _cube[5] = get_data(_i+1, _j ,_k+1) ) > 0 ) _lut_entry += 32 ;
+
+ if( ( _cube[6] = get_data(_i+1,_j+1,_k+1) ) > 0 ) _lut_entry += 64 ;
+
+ if( ( _cube[7] = get_data( _i ,_j+1,_k+1) ) > 0 ) _lut_entry += 128 ;
+
+*/
+
+ process_cube( ) ;
+
+ } }
+
+
+
+ printf("Marching Cubes end: cpu %ld\n", clock() ) ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// init temporary structures (must set sizes before call)
+
+void MarchingCubes::init_temps()
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( !_ext_data )
+
+ _data = new real [_size_x * _size_y * _size_z] ;
+
+ _x_verts = new int [_size_x * _size_y * _size_z] ;
+
+ _y_verts = new int [_size_x * _size_y * _size_z] ;
+
+ _z_verts = new int [_size_x * _size_y * _size_z] ;
+
+
+
+ memset( _x_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+ memset( _y_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+ memset( _z_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// init all structures (must set sizes before call)
+
+void MarchingCubes::init_all ()
+
+//-----------------------------------------------------------------------------
+
+{
+
+ init_temps() ;
+
+
+
+ _nverts = _ntrigs = 0 ;
+
+ _Nverts = _Ntrigs = ALLOC_SIZE ;
+
+ _vertices = new Vertex [_Nverts] ;
+
+ _triangles = new Triangle[_Ntrigs] ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// clean temporary structures
+
+void MarchingCubes::clean_temps()
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( !_ext_data )
+
+ delete [] _data;
+
+ delete [] _x_verts;
+
+ delete [] _y_verts;
+
+ delete [] _z_verts;
+
+
+
+ if( !_ext_data )
+
+ _data = (real*)NULL ;
+
+ _x_verts = (int*)NULL ;
+
+ _y_verts = (int*)NULL ;
+
+ _z_verts = (int*)NULL ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+void MarchingCubes::clean_mesh ()
+{
+ delete [] _vertices ;
+
+ delete [] _triangles ;
+
+ _vertices = (Vertex *)NULL ;
+
+ _triangles = (Triangle *)NULL ;
+
+ _nverts = _ntrigs = 0 ;
+
+ _Nverts = _Ntrigs = 0 ;
+
+
+ delete [] _x_verts;
+
+ delete [] _y_verts;
+
+ delete [] _z_verts;
+
+
+ _x_verts = (int*)NULL ;
+
+ _y_verts = (int*)NULL ;
+
+ _z_verts = (int*)NULL ;
+
+}
+
+
+void MarchingCubes::init_mesh ()
+{
+ _x_verts = new int [_size_x * _size_y * _size_z] ;
+
+ _y_verts = new int [_size_x * _size_y * _size_z] ;
+
+ _z_verts = new int [_size_x * _size_y * _size_z] ;
+
+
+
+ memset( _x_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+ memset( _y_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+ memset( _z_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;
+
+ _nverts = _ntrigs = 0 ;
+
+ _Nverts = _Ntrigs = ALLOC_SIZE ;
+
+ _vertices = new Vertex [_Nverts] ;
+
+ _triangles = new Triangle[_Ntrigs] ;
+
+}
+
+
+//_____________________________________________________________________________
+
+// clean all structures
+
+void MarchingCubes::clean_all()
+
+//-----------------------------------------------------------------------------
+
+{
+
+ clean_temps() ;
+
+ delete [] _vertices ;
+
+ delete [] _triangles ;
+
+ _vertices = (Vertex *)NULL ;
+
+ _triangles = (Triangle *)NULL ;
+
+ _nverts = _ntrigs = 0 ;
+
+ _Nverts = _Ntrigs = 0 ;
+
+
+
+ _size_x = _size_y = _size_z = -1 ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Compute the intersection points
+
+void MarchingCubes::compute_intersection_points( real iso )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ for( _k = 0 ; _k < _size_z ; _k++ )
+
+ for( _j = 0 ; _j < _size_y ; _j++ )
+
+ for( _i = 0 ; _i < _size_x ; _i++ )
+
+ {
+
+ _cube[0] = get_data( _i, _j, _k ) - iso ;
+
+ if( _i < _size_x - 1 ) _cube[1] = get_data(_i+1, _j , _k ) - iso ;
+
+ else _cube[1] = _cube[0] ;
+
+
+
+ if( _j < _size_y - 1 ) _cube[3] = get_data( _i ,_j+1, _k ) - iso ;
+
+ else _cube[3] = _cube[0] ;
+
+
+
+ if( _k < _size_z - 1 ) _cube[4] = get_data( _i , _j ,_k+1) - iso ;
+
+ else _cube[4] = _cube[0] ;
+
+
+
+ if( fabs( _cube[0] ) < FLT_EPSILON ) _cube[0] = FLT_EPSILON ;
+
+ if( fabs( _cube[1] ) < FLT_EPSILON ) _cube[1] = FLT_EPSILON ;
+
+ if( fabs( _cube[3] ) < FLT_EPSILON ) _cube[3] = FLT_EPSILON ;
+
+ if( fabs( _cube[4] ) < FLT_EPSILON ) _cube[4] = FLT_EPSILON ;
+
+
+
+ if( _cube[0] < 0 )
+
+ {
+
+ if( _cube[1] > 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ;
+
+ if( _cube[3] > 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ;
+
+ if( _cube[4] > 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ;
+
+ }
+
+ else
+
+ {
+
+ if( _cube[1] < 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ;
+
+ if( _cube[3] < 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ;
+
+ if( _cube[4] < 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ;
+
+ }
+
+ }
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Test a face
+
+// if face>0 return true if the face contains a part of the surface
+
+bool MarchingCubes::test_face( schar face )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ real A,B,C,D ;
+
+
+
+ switch( face )
+
+ {
+
+ case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ;
+
+ case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ;
+
+ case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ;
+
+ case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ;
+
+ case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ;
+
+ case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ;
+
+ default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ;
+
+ };
+
+
+
+ if( fabs( A*C - B*D ) < FLT_EPSILON )
+
+ return face >= 0 ;
+
+ return face * A * ( A*C - B*D ) >= 0 ; // face && A invert signs
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Test the interior of a cube
+
+// if s == 7, return true if the interior is empty
+
+// if s ==-7, return false if the interior is empty
+
+bool MarchingCubes::test_interior( schar s )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ real t, At=0, Bt=0, Ct=0, Dt=0, a, b ;
+
+ char test = 0 ;
+
+ char edge = -1 ; // reference edge of the triangulation
+
+
+
+ switch( _case )
+
+ {
+
+ case 4 :
+
+ case 10 :
+
+ a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ;
+
+ b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] )
+
+ - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ;
+
+ t = - b / (2*a) ;
+
+ if( t<0 || t>1 ) return s>0 ;
+
+
+
+ At = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
+
+ Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
+
+ Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
+
+ Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
+
+ break ;
+
+
+
+ case 6 :
+
+ case 7 :
+
+ case 12 :
+
+ case 13 :
+
+ switch( _case )
+
+ {
+
+ case 6 : edge = test6 [_config][2] ; break ;
+
+ case 7 : edge = test7 [_config][4] ; break ;
+
+ case 12 : edge = test12[_config][3] ; break ;
+
+ case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ;
+
+ }
+
+ switch( edge )
+
+ {
+
+ case 0 :
+
+ t = _cube[0] / ( _cube[0] - _cube[1] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
+
+ Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
+
+ Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ;
+
+ break ;
+
+ case 1 :
+
+ t = _cube[1] / ( _cube[1] - _cube[2] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
+
+ Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
+
+ Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ;
+
+ break ;
+
+ case 2 :
+
+ t = _cube[2] / ( _cube[2] - _cube[3] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
+
+ Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
+
+ Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ;
+
+ break ;
+
+ case 3 :
+
+ t = _cube[3] / ( _cube[3] - _cube[0] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
+
+ Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
+
+ Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ;
+
+ break ;
+
+ case 4 :
+
+ t = _cube[4] / ( _cube[4] - _cube[5] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ;
+
+ Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ;
+
+ Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ;
+
+ break ;
+
+ case 5 :
+
+ t = _cube[5] / ( _cube[5] - _cube[6] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ;
+
+ Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ;
+
+ Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ;
+
+ break ;
+
+ case 6 :
+
+ t = _cube[6] / ( _cube[6] - _cube[7] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ;
+
+ Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ;
+
+ Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ;
+
+ break ;
+
+ case 7 :
+
+ t = _cube[7] / ( _cube[7] - _cube[4] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ;
+
+ Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ;
+
+ Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ;
+
+ break ;
+
+ case 8 :
+
+ t = _cube[0] / ( _cube[0] - _cube[4] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
+
+ Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
+
+ Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
+
+ break ;
+
+ case 9 :
+
+ t = _cube[1] / ( _cube[1] - _cube[5] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
+
+ Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
+
+ Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
+
+ break ;
+
+ case 10 :
+
+ t = _cube[2] / ( _cube[2] - _cube[6] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
+
+ Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
+
+ Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;
+
+ break ;
+
+ case 11 :
+
+ t = _cube[3] / ( _cube[3] - _cube[7] ) ;
+
+ At = 0 ;
+
+ Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;
+
+ Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ;
+
+ Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;
+
+ break ;
+
+ default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ;
+
+ }
+
+ break ;
+
+
+
+ default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; break ;
+
+ }
+
+
+
+ if( At >= 0 ) test ++ ;
+
+ if( Bt >= 0 ) test += 2 ;
+
+ if( Ct >= 0 ) test += 4 ;
+
+ if( Dt >= 0 ) test += 8 ;
+
+ switch( test )
+
+ {
+
+ case 0 : return s>0 ;
+
+ case 1 : return s>0 ;
+
+ case 2 : return s>0 ;
+
+ case 3 : return s>0 ;
+
+ case 4 : return s>0 ;
+
+ case 5 : if( At * Ct - Bt * Dt < FLT_EPSILON ) return s>0 ; break ;
+
+ case 6 : return s>0 ;
+
+ case 7 : return s<0 ;
+
+ case 8 : return s>0 ;
+
+ case 9 : return s>0 ;
+
+ case 10 : if( At * Ct - Bt * Dt >= FLT_EPSILON ) return s>0 ; break ;
+
+ case 11 : return s<0 ;
+
+ case 12 : return s>0 ;
+
+ case 13 : return s<0 ;
+
+ case 14 : return s<0 ;
+
+ case 15 : return s<0 ;
+
+ }
+
+
+
+ return s<0 ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Process a unit cube
+
+void MarchingCubes::process_cube( )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( _originalMC )
+
+ {
+
+ char nt = 0 ;
+
+ while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ;
+
+ add_triangle( casesClassic[_lut_entry], nt ) ;
+
+ return ;
+
+ }
+
+
+
+ int v12 = -1 ;
+
+ _case = cases[_lut_entry][0] ;
+
+ _config = cases[_lut_entry][1] ;
+
+ _subconfig = 0 ;
+
+
+
+ switch( _case )
+
+ {
+
+ case 0 :
+
+ break ;
+
+
+
+ case 1 :
+
+ add_triangle( tiling1[_config], 1 ) ;
+
+ break ;
+
+
+
+ case 2 :
+
+ add_triangle( tiling2[_config], 2 ) ;
+
+ break ;
+
+
+
+ case 3 :
+
+ if( test_face( test3[_config]) )
+
+ add_triangle( tiling3_2[_config], 4 ) ; // 3.2
+
+ else
+
+ add_triangle( tiling3_1[_config], 2 ) ; // 3.1
+
+ break ;
+
+
+
+ case 4 :
+
+ if( test_interior( test4[_config]) )
+
+ add_triangle( tiling4_1[_config], 2 ) ; // 4.1.1
+
+ else
+
+ add_triangle( tiling4_2[_config], 6 ) ; // 4.1.2
+
+ break ;
+
+
+
+ case 5 :
+
+ add_triangle( tiling5[_config], 3 ) ;
+
+ break ;
+
+
+
+ case 6 :
+
+ if( test_face( test6[_config][0]) )
+
+ add_triangle( tiling6_2[_config], 5 ) ; // 6.2
+
+ else
+
+ {
+
+ if( test_interior( test6[_config][1]) )
+
+ add_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1
+
+ else
+
+ add_triangle( tiling6_1_2[_config], 7 ) ; // 6.1.2
+
+ }
+
+ break ;
+
+
+
+ case 7 :
+
+ if( test_face( test7[_config][0] ) ) _subconfig += 1 ;
+
+ if( test_face( test7[_config][1] ) ) _subconfig += 2 ;
+
+ if( test_face( test7[_config][2] ) ) _subconfig += 4 ;
+
+ switch( _subconfig )
+
+ {
+
+ case 0 :
+
+ add_triangle( tiling7_1[_config], 3 ) ; break ;
+
+ case 1 :
+
+ add_triangle( tiling7_2[_config][0], 5 ) ; break ;
+
+ case 2 :
+
+ add_triangle( tiling7_2[_config][1], 5 ) ; break ;
+
+ case 3 :
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling7_3[_config][0], 9, v12 ) ; break ;
+
+ case 4 :
+
+ add_triangle( tiling7_2[_config][2], 5 ) ; break ;
+
+ case 5 :
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling7_3[_config][1], 9, v12 ) ; break ;
+
+ case 6 :
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling7_3[_config][2], 9, v12 ) ; break ;
+
+ case 7 :
+
+ if( test_interior( test7[_config][3]) )
+
+ add_triangle( tiling7_4_2[_config], 9 ) ;
+
+ else
+
+ add_triangle( tiling7_4_1[_config], 5 ) ;
+
+ break ;
+
+ };
+
+ break ;
+
+
+
+ case 8 :
+
+ add_triangle( tiling8[_config], 2 ) ;
+
+ break ;
+
+
+
+ case 9 :
+
+ add_triangle( tiling9[_config], 4 ) ;
+
+ break ;
+
+
+
+ case 10 :
+
+ if( test_face( test10[_config][0]) )
+
+ {
+
+ if( test_face( test10[_config][1]) )
+
+ add_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1
+
+ else
+
+ {
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2
+
+ }
+
+ }
+
+ else
+
+ {
+
+ if( test_face( test10[_config][1]) )
+
+ {
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2
+
+ }
+
+ else
+
+ {
+
+ if( test_interior( test10[_config][2]) )
+
+ add_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1
+
+ else
+
+ add_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2
+
+ }
+
+ }
+
+ break ;
+
+
+
+ case 11 :
+
+ add_triangle( tiling11[_config], 4 ) ;
+
+ break ;
+
+
+
+ case 12 :
+
+ if( test_face( test12[_config][0]) )
+
+ {
+
+ if( test_face( test12[_config][1]) )
+
+ add_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1
+
+ else
+
+ {
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2
+
+ }
+
+ }
+
+ else
+
+ {
+
+ if( test_face( test12[_config][1]) )
+
+ {
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2
+
+ }
+
+ else
+
+ {
+
+ if( test_interior( test12[_config][2]) )
+
+ add_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1
+
+ else
+
+ add_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2
+
+ }
+
+ }
+
+ break ;
+
+
+
+ case 13 :
+
+ if( test_face( test13[_config][0] ) ) _subconfig += 1 ;
+
+ if( test_face( test13[_config][1] ) ) _subconfig += 2 ;
+
+ if( test_face( test13[_config][2] ) ) _subconfig += 4 ;
+
+ if( test_face( test13[_config][3] ) ) _subconfig += 8 ;
+
+ if( test_face( test13[_config][4] ) ) _subconfig += 16 ;
+
+ if( test_face( test13[_config][5] ) ) _subconfig += 32 ;
+
+ switch( subconfig13[_subconfig] )
+
+ {
+
+ case 0 :/* 13.1 */
+
+ add_triangle( tiling13_1[_config], 4 ) ; break ;
+
+
+
+ case 1 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][0], 6 ) ; break ;
+
+ case 2 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][1], 6 ) ; break ;
+
+ case 3 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][2], 6 ) ; break ;
+
+ case 4 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][3], 6 ) ; break ;
+
+ case 5 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][4], 6 ) ; break ;
+
+ case 6 :/* 13.2 */
+
+ add_triangle( tiling13_2[_config][5], 6 ) ; break ;
+
+
+
+ case 7 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][0], 10, v12 ) ; break ;
+
+ case 8 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][1], 10, v12 ) ; break ;
+
+ case 9 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][2], 10, v12 ) ; break ;
+
+ case 10 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][3], 10, v12 ) ; break ;
+
+ case 11 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][4], 10, v12 ) ; break ;
+
+ case 12 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][5], 10, v12 ) ; break ;
+
+ case 13 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][6], 10, v12 ) ; break ;
+
+ case 14 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][7], 10, v12 ) ; break ;
+
+ case 15 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][8], 10, v12 ) ; break ;
+
+ case 16 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][9], 10, v12 ) ; break ;
+
+ case 17 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][10], 10, v12 ) ; break ;
+
+ case 18 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3[_config][11], 10, v12 ) ; break ;
+
+
+
+ case 19 :/* 13.4 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_4[_config][0], 12, v12 ) ; break ;
+
+ case 20 :/* 13.4 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_4[_config][1], 12, v12 ) ; break ;
+
+ case 21 :/* 13.4 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_4[_config][2], 12, v12 ) ; break ;
+
+ case 22 :/* 13.4 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_4[_config][3], 12, v12 ) ; break ;
+
+
+
+ case 23 :/* 13.5 */
+
+ _subconfig = 0 ;
+
+ if( test_interior( test13[_config][6] ) )
+
+ add_triangle( tiling13_5_1[_config][0], 6 ) ;
+
+ else
+
+ add_triangle( tiling13_5_2[_config][0], 10 ) ;
+
+ break ;
+
+ case 24 :/* 13.5 */
+
+ _subconfig = 1 ;
+
+ if( test_interior( test13[_config][6] ) )
+
+ add_triangle( tiling13_5_1[_config][1], 6 ) ;
+
+ else
+
+ add_triangle( tiling13_5_2[_config][1], 10 ) ;
+
+ break ;
+
+ case 25 :/* 13.5 */
+
+ _subconfig = 2 ;
+
+ if( test_interior( test13[_config][6] ) )
+
+ add_triangle( tiling13_5_1[_config][2], 6 ) ;
+
+ else
+
+ add_triangle( tiling13_5_2[_config][2], 10 ) ;
+
+ break ;
+
+ case 26 :/* 13.5 */
+
+ _subconfig = 3 ;
+
+ if( test_interior( test13[_config][6] ) )
+
+ add_triangle( tiling13_5_1[_config][3], 6 ) ;
+
+ else
+
+ add_triangle( tiling13_5_2[_config][3], 10 ) ;
+
+ break ;
+
+
+
+ case 27 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ;
+
+ case 28 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ;
+
+ case 29 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ;
+
+ case 30 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ;
+
+ case 31 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ;
+
+ case 32 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ;
+
+ case 33 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ;
+
+ case 34 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ;
+
+ case 35 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ;
+
+ case 36 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ;
+
+ case 37 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ;
+
+ case 38 :/* 13.3 */
+
+ v12 = add_c_vertex() ;
+
+ add_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ;
+
+
+
+ case 39 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][0], 6 ) ; break ;
+
+ case 40 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][1], 6 ) ; break ;
+
+ case 41 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][2], 6 ) ; break ;
+
+ case 42 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][3], 6 ) ; break ;
+
+ case 43 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][4], 6 ) ; break ;
+
+ case 44 :/* 13.2 */
+
+ add_triangle( tiling13_2_[_config][5], 6 ) ; break ;
+
+
+
+ case 45 :/* 13.1 */
+
+ add_triangle( tiling13_1_[_config], 4 ) ; break ;
+
+
+
+ default :
+
+ printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ;
+
+ }
+
+ break ;
+
+
+
+ case 14 :
+
+ add_triangle( tiling14[_config], 4 ) ;
+
+ break ;
+
+ };
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Adding triangles
+
+void MarchingCubes::add_triangle( const char* trig, char n, int v12 )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ int tv[3] ;
+
+
+
+ for( int t = 0 ; t < 3*n ; t++ )
+
+ {
+
+ switch( trig[t] )
+
+ {
+
+ case 0 : tv[ t % 3 ] = get_x_vert( _i , _j , _k ) ; break ;
+
+ case 1 : tv[ t % 3 ] = get_y_vert(_i+1, _j , _k ) ; break ;
+
+ case 2 : tv[ t % 3 ] = get_x_vert( _i ,_j+1, _k ) ; break ;
+
+ case 3 : tv[ t % 3 ] = get_y_vert( _i , _j , _k ) ; break ;
+
+ case 4 : tv[ t % 3 ] = get_x_vert( _i , _j ,_k+1) ; break ;
+
+ case 5 : tv[ t % 3 ] = get_y_vert(_i+1, _j ,_k+1) ; break ;
+
+ case 6 : tv[ t % 3 ] = get_x_vert( _i ,_j+1,_k+1) ; break ;
+
+ case 7 : tv[ t % 3 ] = get_y_vert( _i , _j ,_k+1) ; break ;
+
+ case 8 : tv[ t % 3 ] = get_z_vert( _i , _j , _k ) ; break ;
+
+ case 9 : tv[ t % 3 ] = get_z_vert(_i+1, _j , _k ) ; break ;
+
+ case 10 : tv[ t % 3 ] = get_z_vert(_i+1,_j+1, _k ) ; break ;
+
+ case 11 : tv[ t % 3 ] = get_z_vert( _i ,_j+1, _k ) ; break ;
+
+ case 12 : tv[ t % 3 ] = v12 ; break ;
+
+ default : break ;
+
+ }
+
+
+
+ if( tv[t%3] == -1 )
+
+ {
+
+ printf("Marching Cubes: invalid triangle %d\n", _ntrigs+1) ;
+
+ print_cube() ;
+
+ }
+
+
+
+ if( t%3 == 2 )
+
+ {
+
+ if( _ntrigs >= _Ntrigs )
+
+ {
+
+ Triangle *temp = _triangles ;
+
+ _triangles = new Triangle[ 2*_Ntrigs ] ;
+
+ memcpy( _triangles, temp, _Ntrigs*sizeof(Triangle) ) ;
+
+ delete[] temp ;
+
+ printf("%d allocated triangles\n", _Ntrigs) ;
+
+ _Ntrigs *= 2 ;
+
+ }
+
+
+
+ Triangle *T = _triangles + _ntrigs++ ;
+
+ T->v1 = tv[0] ;
+
+ T->v2 = tv[1] ;
+
+ T->v3 = tv[2] ;
+
+ }
+
+ }
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Calculating gradient
+
+
+
+real MarchingCubes::get_x_grad( const int i, const int j, const int k ) const
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( i > 0 )
+
+ {
+
+ if ( i < _size_x - 1 )
+
+ return ( get_data( i+1, j, k ) - get_data( i-1, j, k ) ) / 2 ;
+
+ else
+
+ return get_data( i, j, k ) - get_data( i-1, j, k ) ;
+
+ }
+
+ else
+
+ return get_data( i+1, j, k ) - get_data( i, j, k ) ;
+
+}
+
+//-----------------------------------------------------------------------------
+
+
+
+real MarchingCubes::get_y_grad( const int i, const int j, const int k ) const
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( j > 0 )
+
+ {
+
+ if ( j < _size_y - 1 )
+
+ return ( get_data( i, j+1, k ) - get_data( i, j-1, k ) ) / 2 ;
+
+ else
+
+ return get_data( i, j, k ) - get_data( i, j-1, k ) ;
+
+ }
+
+ else
+
+ return get_data( i, j+1, k ) - get_data( i, j, k ) ;
+
+}
+
+//-----------------------------------------------------------------------------
+
+
+
+real MarchingCubes::get_z_grad( const int i, const int j, const int k ) const
+
+//-----------------------------------------------------------------------------
+
+{
+
+ if( k > 0 )
+
+ {
+
+ if ( k < _size_z - 1 )
+
+ return ( get_data( i, j, k+1 ) - get_data( i, j, k-1 ) ) / 2 ;
+
+ else
+
+ return get_data( i, j, k ) - get_data( i, j, k-1 ) ;
+
+ }
+
+ else
+
+ return get_data( i, j, k+1 ) - get_data( i, j, k ) ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Adding vertices
+
+
+
+void MarchingCubes::test_vertex_addition()
+
+{
+
+ if( _nverts >= _Nverts )
+
+ {
+
+ Vertex *temp = _vertices ;
+
+ _vertices = new Vertex[ _Nverts*2 ] ;
+
+ memcpy( _vertices, temp, _Nverts*sizeof(Vertex) ) ;
+
+ delete[] temp ;
+
+ printf("%d allocated vertices\n", _Nverts) ;
+
+ _Nverts *= 2 ;
+
+ }
+
+}
+
+
+
+
+
+int MarchingCubes::add_x_vertex( )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ test_vertex_addition() ;
+
+ Vertex *vert = _vertices + _nverts++ ;
+
+
+
+ real u = ( _cube[0] ) / ( _cube[0] - _cube[1] ) ;
+
+
+
+ vert->x = (real)_i+u;
+
+ vert->y = (real) _j ;
+
+ vert->z = (real) _k ;
+
+
+
+ vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i+1,_j,_k) ;
+
+ vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i+1,_j,_k) ;
+
+ vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i+1,_j,_k) ;
+
+
+
+ u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ;
+
+ if( u > 0 )
+
+ {
+
+ vert->nx /= u ;
+
+ vert->ny /= u ;
+
+ vert->nz /= u ;
+
+ }
+
+
+
+
+
+ return _nverts-1 ;
+
+}
+
+//-----------------------------------------------------------------------------
+
+
+
+int MarchingCubes::add_y_vertex( )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ test_vertex_addition() ;
+
+ Vertex *vert = _vertices + _nverts++ ;
+
+
+
+ real u = ( _cube[0] ) / ( _cube[0] - _cube[3] ) ;
+
+
+
+ vert->x = (real) _i ;
+
+ vert->y = (real)_j+u;
+
+ vert->z = (real) _k ;
+
+
+
+ vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j+1,_k) ;
+
+ vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j+1,_k) ;
+
+ vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j+1,_k) ;
+
+
+
+ u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ;
+
+ if( u > 0 )
+
+ {
+
+ vert->nx /= u ;
+
+ vert->ny /= u ;
+
+ vert->nz /= u ;
+
+ }
+
+
+
+ return _nverts-1 ;
+
+}
+
+//-----------------------------------------------------------------------------
+
+
+
+int MarchingCubes::add_z_vertex( )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ test_vertex_addition() ;
+
+ Vertex *vert = _vertices + _nverts++ ;
+
+
+
+ real u = ( _cube[0] ) / ( _cube[0] - _cube[4] ) ;
+
+
+
+ vert->x = (real) _i ;
+
+ vert->y = (real) _j ;
+
+ vert->z = (real)_k+u;
+
+
+
+ vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j,_k+1) ;
+
+ vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j,_k+1) ;
+
+ vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j,_k+1) ;
+
+
+
+ u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ;
+
+ if( u > 0 )
+
+ {
+
+ vert->nx /= u ;
+
+ vert->ny /= u ;
+
+ vert->nz /= u ;
+
+ }
+
+
+
+ return _nverts-1 ;
+
+}
+
+
+
+
+
+int MarchingCubes::add_c_vertex( )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ test_vertex_addition() ;
+
+ Vertex *vert = _vertices + _nverts++ ;
+
+
+
+ real u = 0 ;
+
+ int vid ;
+
+
+
+ vert->x = vert->y = vert->z = vert->nx = vert->ny = vert->nz = 0 ;
+
+
+
+ // Computes the average of the intersection points of the cube
+
+ vid = get_x_vert( _i , _j , _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_y_vert(_i+1, _j , _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_x_vert( _i ,_j+1, _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_y_vert( _i , _j , _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_x_vert( _i , _j ,_k+1) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_y_vert(_i+1, _j ,_k+1) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_x_vert( _i ,_j+1,_k+1) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_y_vert( _i , _j ,_k+1) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_z_vert( _i , _j , _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_z_vert(_i+1, _j , _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_z_vert(_i+1,_j+1, _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+ vid = get_z_vert( _i ,_j+1, _k ) ;
+
+ if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; }
+
+
+
+ vert->x /= u ;
+
+ vert->y /= u ;
+
+ vert->z /= u ;
+
+
+
+ u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ;
+
+ if( u > 0 )
+
+ {
+
+ vert->nx /= u ;
+
+ vert->ny /= u ;
+
+ vert->nz /= u ;
+
+ }
+
+
+
+ return _nverts-1 ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Grid exportation
+
+void MarchingCubes::writeISO(const char *fn )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ unsigned char buf[sizeof(float)] ;
+
+
+
+ FILE *fp = fopen( fn, "wb" ) ;
+
+
+
+ // header
+
+ * (int*) buf = _size_x ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (int*) buf = _size_y ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (int*) buf = _size_z ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+
+
+ * (float*) buf = -1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (float*) buf = 1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (float*) buf = -1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (float*) buf = 1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (float*) buf = -1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ * (float*) buf = 1.0f ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+
+
+ for( int i = 0 ; i < _size_x ; i++ )
+
+ {
+
+ for( int j = 0 ; j < _size_y ; j++ )
+
+ {
+
+ for( int k = 0 ; k < _size_z ; k++ )
+
+ {
+
+ * (float*) buf = (float)get_data( i,j,k ) ;
+
+ fwrite(buf, sizeof(float), 1, fp);
+
+ }
+
+ }
+
+ }
+
+
+
+ fclose(fp) ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// PLY exportation
+
+
+
+void MarchingCubes::writePLY(const char *fn, bool bin )
+
+//-----------------------------------------------------------------------------
+
+{
+
+
+
+ typedef struct PlyFace {
+
+ unsigned char nverts; /* number of Vertex indices in list */
+
+ int *verts; /* Vertex index list */
+
+ } PlyFace;
+
+
+
+
+
+ PlyProperty vert_props[] = { /* list of property information for a PlyVertex */
+
+ {"x", Float32, Float32, offsetof( Vertex,x ), 0, 0, 0, 0},
+
+ {"y", Float32, Float32, offsetof( Vertex,y ), 0, 0, 0, 0},
+
+ {"z", Float32, Float32, offsetof( Vertex,z ), 0, 0, 0, 0},
+
+ {"nx", Float32, Float32, offsetof( Vertex,nx ), 0, 0, 0, 0},
+
+ {"ny", Float32, Float32, offsetof( Vertex,ny ), 0, 0, 0, 0},
+
+ {"nz", Float32, Float32, offsetof( Vertex,nz ), 0, 0, 0, 0}
+
+ };
+
+
+
+ PlyProperty face_props[] = { /* list of property information for a PlyFace */
+
+ {"vertex_indices", Int32, Int32, offsetof( PlyFace,verts ),
+
+ 1, Uint8, Uint8, offsetof( PlyFace,nverts )},
+
+ };
+
+
+
+
+
+ PlyFile *ply;
+
+ FILE *fp = fopen( fn, "w" );
+
+
+
+ int i ;
+
+ PlyFace face ;
+
+ int verts[3] ;
+
+ char *elem_names[] = { "vertex", "face" };
+
+ printf("Marching Cubes::writePLY(%s)...", fn ) ;
+
+ ply = write_ply ( fp, 2, elem_names, bin? PLY_BINARY_LE : PLY_ASCII );
+
+
+
+ /* describe what properties go into the PlyVertex elements */
+
+ describe_element_ply ( ply, "vertex", _nverts );
+
+ describe_property_ply ( ply, &vert_props[0] );
+
+ describe_property_ply ( ply, &vert_props[1] );
+
+ describe_property_ply ( ply, &vert_props[2] );
+
+ describe_property_ply ( ply, &vert_props[3] );
+
+ describe_property_ply ( ply, &vert_props[4] );
+
+ describe_property_ply ( ply, &vert_props[5] );
+
+
+
+ /* describe PlyFace properties (just list of PlyVertex indices) */
+
+ describe_element_ply ( ply, "face", _ntrigs );
+
+ describe_property_ply ( ply, &face_props[0] );
+
+
+
+ header_complete_ply ( ply );
+
+
+
+ /* set up && write the PlyVertex elements */
+
+ put_element_setup_ply ( ply, "vertex" );
+
+ for ( i = 0; i < _nverts; i++ )
+
+ put_element_ply ( ply, ( void * ) &(_vertices[i]) );
+
+ printf(" %d vertices written\n", _nverts ) ;
+
+
+
+ /* set up && write the PlyFace elements */
+
+ put_element_setup_ply ( ply, "face" );
+
+ face.nverts = 3 ;
+
+ face.verts = verts ;
+
+ for ( i = 0; i < _ntrigs; i++ )
+
+ {
+
+ face.verts[0] = _triangles[i].v1 ;
+
+ face.verts[1] = _triangles[i].v2 ;
+
+ face.verts[2] = _triangles[i].v3 ;
+
+ put_element_ply ( ply, ( void * ) &face );
+
+ }
+
+ printf(" %d triangles written\n", _ntrigs ) ;
+
+
+
+ close_ply ( ply );
+
+ free_ply ( ply );
+
+ fclose( fp ) ;
+
+}
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+// Open Inventor / VRML 1.0 ascii exportation
+
+void MarchingCubes::writeIV(const char *fn )
+
+//-----------------------------------------------------------------------------
+
+{
+
+ FILE *fp = fopen( fn, "w" ) ;
+
+ int i ;
+
+
+
+ printf("Marching Cubes::exportIV(%s)...", fn) ;
+
+
+
+ fprintf( fp, "#Inventor V2.1 ascii \n\nSeparator { \n ShapeHints {\n vertexOrdering COUNTERCLOCKWISE\n shapeType UNKNOWN_SHAPE_TYPE\n creaseAngle 0.0\n }\n Coordinate3 { \n point [ \n" ) ;
+
+ for ( i = 0; i < _nverts; i++ )
+
+ fprintf( fp, " %f %f %f,\n", _vertices[i].x, _vertices[i].y, _vertices[i].z ) ;
+
+ printf(" %d vertices written\n", _nverts ) ;
+
+
+
+ fprintf( fp, "\n ] \n} \nNormal { \nvector [ \n" ) ;
+
+ for ( i = 0; i < _nverts; i++ )
+
+ fprintf( fp, " %f %f %f,\n", _vertices[i].nx, _vertices[i].ny, _vertices[i].nz ) ;
+
+
+
+ fprintf( fp, "\n ] \n} \nIndexedFaceSet { \ncoordIndex [ \n" ) ;
+
+ for ( i = 0; i < _ntrigs; i++ )
+
+ fprintf( fp, "%d, %d, %d, -1,\n", _triangles[i].v1, _triangles[i].v2, _triangles[i].v3 ) ;
+
+
+
+ fprintf( fp, " ] \n } \n } \n" ) ;
+
+ fclose( fp ) ;
+
+ printf(" %d triangles written\n", _ntrigs ) ;
+
+}
+
+//_____________________________________________________________________________
+
diff --git a/PLP.cc b/PLP.cc
new file mode 100644
index 0000000..aa592ad
--- /dev/null
+++ b/PLP.cc
@@ -0,0 +1,218 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "PLP.h"
+
+#define DONOR 0
+#define ACCEPTOR 1
+#define BOTH 2
+#define NONPOLAR 3
+
+#define STERIC 0
+#define HBOND 1
+#define REPULSIVE 2
+
+
+float PLPInteraction::value () {
+ float r = dist (at1-> GetVector (), at2-> GetVector ());
+ float a, b, c, d, e, f;
+ float hb = 1;
+ if (type == STERIC) {
+
+ b = etab.GetVdwRad(at1 -> GetAtomicNum ()) + etab.GetVdwRad(at2 -> GetAtomicNum ());
+ a = 0.93f * b;
+ c = 1.25f * b;
+ d = 1.5f * b;
+ e = -0.4f;
+ f = 15.f;
+ }
+ else if (type == HBOND) {
+ double ang = angle (root, at2-> GetVector (), at1-> GetVector ());
+ // if (ang>PI) ang = 2*PI-ang;
+ // cout <<ang;
+ if (ang < 90.f) hb = 0.f;
+ else if (ang < 120.f) hb = (ang-90.f)/(30.f);
+ else hb = 1.f;
+ // cout <<"hb "<<hb<<endl;
+ a = 2.3f;
+ b = 2.6f;
+ c = 3.1f;
+ d = 3.4f;
+ e = -2.f;
+ f = 15.f;
+ }
+ else if (type == REPULSIVE) {
+ a = 3.4f;
+ e = 0.f;
+ f = 15.f;
+ }
+ if (r < a) return f*(a-r)/a*hb;
+ else if (type != REPULSIVE) {
+ if (r<b) return e*(r-a)/(b-a)*hb;
+ else if (r<c) return e*hb;
+ else if (r<d) return e*(d-r)/(d-c)*hb;
+ else return 0.f;
+ }
+ else return 0.f;
+}
+
+
+
+
+
+PLP::PLP () {
+ is_initialised = TRUE;
+}
+
+
+
+void PLP::clear_nonbonded_interactions () {
+ for (unsigned int i=0; i<NBInteractions.size (); i++) delete NBInteractions[i];
+ NBInteractions.clear ();
+}
+
+
+
+
+
+void PLP::compute_forces () {
+ for (unsigned int i=0; i<NBInteractions.size (); i++) {
+ NBInteractions[i] -> set_forces ();
+ }
+}
+
+/*
+void PLP::compute_force (PLPInteraction *plpint) {
+ for (unsigned int i=0; i<3; i++) {
+ plpint->at1-> GetVector ()[i]-= DX;
+ float E = compute_interaction (plpint);
+ plpint->at1-> GetVector ()[i]+= 2*DX;
+ float E2 = compute_interaction (plpint);
+ plpint->at1-> GetVector ()[i]-= DX;
+ plpint->at1->force[i]-= (E2-E)/(2*DX); //3* force
+ plpint->at2->force[i]+= (E2-E)/(2*DX);
+
+ }
+}
+
+float PLP::compute_interaction (PLPInteraction *plpint) {
+ float r = distance (plpint->at1-> GetVector (), plpint->at2-> GetVector ());
+ float a, b, c, d, e, f;
+ float hb = 1;
+ if (plpint->type == STERIC) {
+ b = plpint->at1->vdw + plpint->at2->vdw;
+ a = 0.93*b;
+ c = 1.25*b;
+ d = 1.5*b;
+ e = -0.4;
+ f = 15;
+ }
+ else if (plpint->type == HBOND) {
+ double ang = angle (plpint->root, plpint->at2-> GetVector (), plpint->at1-> GetVector ());
+ // if (ang>PI) ang = 2*PI-ang;
+ // cout <<ang;
+ if (ang<90) hb = 0;
+ else if (ang<120) hb = (ang-90)/(30);
+ else hb = 1;
+ // cout <<"hb "<<hb<<endl;
+ a = 2.3;
+ b = 2.6;
+ c = 3.1;
+ d = 3.4;
+ e = -2;
+ f = 15;
+ }
+ else if (plpint->type == REPULSIVE) {
+ a = 3.4;
+ e = 0;
+ f = 15;
+ }
+ if (r < a) return f*(a-r)/a*hb;
+ else if (plpint->type != REPULSIVE) {
+ if (r<b) return e*(r-a)/(b-a)*hb;
+ else if (r<c) return e*hb;
+ else if (r<d) return e*(d-r)/(d-c)*hb;
+ else return 0;
+ }
+ else return 0;
+}
+
+*/
+
+
+void PLP::load_internal_interactions () {}
+
+void PLP::load_nonbonded_interactions () {
+
+ clear_nonbonded_interactions ();
+ ZNMolecule *mol = target_mol;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (a -> IsHydrogen ()) continue;
+ objectList<Atom*>* nbAtoms = far_grid->getNeighborObjects(get_coordinates (&*a));
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ if (neighbours[j]-> IsHydrogen ()) continue;
+ float x = 0.f, y = 0.f, z = 0.f;
+ if (neighbours[j]-> GetAtomicNum () == 7 || neighbours[j]-> GetAtomicNum () == 8) {
+ FOR_NBORS_OF_ATOM (n, neighbours[j]) {
+ if (n -> IsHydrogen ()) {
+ x += get_coordinates (&*n).x();
+ y += get_coordinates (&*n).y();
+ z += get_coordinates (&*n).z();
+ }
+ }
+ x/= CountBonds (neighbours[j]);
+ y/= CountBonds (neighbours[j]);
+ z/= CountBonds (neighbours[j]);
+ }
+ PLPInteraction *plpint = new PLPInteraction;
+ plpint -> at1 = &*a;
+ plpint -> at2 = neighbours[j];
+ plpint -> I = getPLPtype (plpint->at1);
+ plpint -> J = getPLPtype (plpint->at2);
+ plpint -> type = getPLPinteractiontype (plpint->I, plpint->J);
+ plpint -> root.x() = x;
+ plpint -> root.y() = y;
+ plpint -> root.z() = z;
+ NBInteractions.push_back (plpint);
+ }
+ }
+ }
+}
+
+
+int PLP::getPLPtype (Atom *at) {
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+ if (at->IsOxygen ()) {
+ if (mol->bonded_to (at, -2, 1)) return BOTH;
+ else return ACCEPTOR;
+ }
+ else if (at -> IsNitrogen () ) {
+ if (mol->bonded_to (at, -2, 1)) return DONOR;
+ else return ACCEPTOR;
+ }
+ else return NONPOLAR;
+}
+
+
+int PLP::getPLPinteractiontype (int I, int J) {
+ if (I==NONPOLAR || J==NONPOLAR) return STERIC;
+ else if (I == BOTH || J ==BOTH) {return HBOND;}
+ else if (I != J) { return HBOND;}
+ else return REPULSIVE;
+}
diff --git a/ZNdata.cc b/ZNdata.cc
new file mode 100644
index 0000000..77cbddc
--- /dev/null
+++ b/ZNdata.cc
@@ -0,0 +1,844 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ZNdata.h"
+
+
+
+
+////////////////////////////////////DATA//////////////////////////////////////////////////////////////////
+
+//class MyListBoxItem;
+
+Data::Data (QApplication *master) : QObject (){
+ haptic_position_lock = new QReadWriteLock ();
+ qapp = master;
+ ncounter =0.f;
+
+ twodwin = new MainWindow ();
+ current_force_x = current_force_y = current_force_z = 0.;
+ current_position_x = current_position_y = current_position_z = 0.;
+ current_yaw = current_pitch = current_roll = 0.;
+ last_yaw = last_pitch = last_roll = 0.;
+
+ total_energy_haptic = 0.;
+ mmff = new MMFF ();
+ actions = new Actions (this);
+
+
+ minimize = new Minimize (this);
+
+
+ charge_begin = -80.f;
+ charge_end = +80.f;
+
+ score_begin = -80.f;
+ score_mid = +0.f ;
+ score_end = +80.f;
+
+
+ constant_color = color (0, 0, 0);
+ charge_begin_color = color (0, 0, 255);
+ charge_end_color = color (255, 0, 0);
+ score_begin_color = color (0, 255, 0);
+ score_mid_color = color (200, 200, 200);
+ score_end_color = color (255, 0, 0);
+
+
+ undo_stack = new QUndoStack ();
+ load_defaults ();
+ load_preferences ();
+
+
+}
+
+void Data::load_haptic_device () {
+#ifdef HAPI
+
+ // Create a new haptics device, using any device connected.
+
+ haptic_device = new (AnyHapticsDevice);
+
+ // initialize the device
+ if (haptic_device ->initDevice () != HAPIHapticsDevice::SUCCESS) {
+
+
+ // initilization failed, print error message and quit
+ cerr << haptic_device ->getLastErrorMsg () << endl;
+ }
+ haptic_device ->enableDevice ();
+// H3DUtil::SimpleThread a_simple_thread(haptic_callback, (void *) this);
+
+ HapticForceThread *hapt_thread = new HapticForceThread (this, ddwin);
+
+ hapt_thread ->start ();
+
+#endif //HAPI
+}
+
+void Data::set_ddwin (DDWin *ddw){
+ ddwin =ddw;
+ ddwin->data = this;
+ // minimize -> haptic_thread = new HapticThread (0, ddwin);
+
+ connect(twodwin->to3DAct,SIGNAL(triggered()), this, SLOT(from_2D_to_3D()));
+
+}
+
+void Data::from_2D_to_3D () {
+ vector <OpenBabel::OBMol *>mols = twodwin ->get_OB_mols ();
+ for (unsigned int i = 0; i < mols.size (); i++) {
+ ZNMolecule *add_mol = (ZNMolecule *) (mols[i]);
+ add_mol ->multi = false;
+ add_mol ->selection = false;
+ finalise_molecule (add_mol);
+ actions -> reprotonate (add_mol);
+ finalise_molecule (add_mol);
+ ddwin ->add_molecule (add_mol);
+ ddwin ->set_current_target (add_mol);
+ }
+}
+
+void Data::load_defaults () {
+ for (unsigned int i = 0; i < vars.size (); i++) {
+ delete vars[i];
+ }
+ vars.clear ();
+ vars.push_back (new StringDataVar ("plants_exe", ""));
+ ColorDataVar *bgvar = new ColorDataVar ("background_color", color (255, 255, 255, 255));
+ background_color = bgvar ->value_ptr ();
+ vars.push_back (bgvar);
+ DoubleDataVar *qsvar = new DoubleDataVar ("quality_scale", 5.0);
+ quality_scale = qsvar ->value_ptr ();
+ vars.push_back (qsvar);
+
+ DoubleDataVar *vdwsvar = new DoubleDataVar ("vdw_scale", 0.2);
+ vdw_scale = vdwsvar ->value_ptr ();
+ vars.push_back (vdwsvar);
+ DoubleDataVar *srvar = new DoubleDataVar ("stick_radius", 0.12);
+ stick_radius = srvar ->value_ptr ();
+ vars.push_back (srvar);
+ DoubleDataVar *sprvar = new DoubleDataVar ("sphere_radius", 0.12);
+ sphere_radius = sprvar ->value_ptr ();
+ vars.push_back (sprvar);
+
+ DoubleDataVar *dbssvar = new DoubleDataVar ("double_bond_stick_scale", 0.7);
+ double_bond_stick_scale = dbssvar ->value_ptr ();
+ vars.push_back (dbssvar);
+
+ DoubleDataVar *dbsvar = new DoubleDataVar ("double_bond_separation", 0.15);
+ double_bond_separation = dbsvar ->value_ptr ();
+ vars.push_back (dbsvar);
+
+ DoubleDataVar *lwvar = new DoubleDataVar ("line_width", 1.2);
+ line_width = lwvar ->value_ptr ();
+ vars.push_back (lwvar);
+
+ DoubleDataVar *backbone_tube_helix_a_var = new DoubleDataVar ("backbone_tube_helix_a", 1.0);
+ backbone_tube_helix_a = backbone_tube_helix_a_var ->value_ptr ();
+ vars.push_back (backbone_tube_helix_a_var);
+
+ DoubleDataVar *backbone_tube_helix_b_var = new DoubleDataVar ("backbone_tube_helix_b", .3);
+ backbone_tube_helix_b = backbone_tube_helix_b_var ->value_ptr ();
+ vars.push_back (backbone_tube_helix_b_var);
+
+ DoubleDataVar *backbone_tube_helix_c_var = new DoubleDataVar ("backbone_tube_helix_c", 1.0);
+ backbone_tube_helix_c = backbone_tube_helix_c_var ->value_ptr ();
+ vars.push_back (backbone_tube_helix_c_var);
+
+ DoubleDataVar *backbone_tube_sheet_a_var = new DoubleDataVar ("backbone_tube_sheet_a", 1.0);
+ backbone_tube_sheet_a = backbone_tube_sheet_a_var ->value_ptr ();
+ vars.push_back (backbone_tube_sheet_a_var);
+
+ DoubleDataVar *backbone_tube_sheet_b_var = new DoubleDataVar ("backbone_tube_sheet_b", .3);
+ backbone_tube_sheet_b = backbone_tube_sheet_b_var ->value_ptr ();
+ vars.push_back (backbone_tube_sheet_b_var);
+
+ DoubleDataVar *backbone_tube_sheet_c_var = new DoubleDataVar ("backbone_tube_sheet_c", 1.0);
+ backbone_tube_sheet_c = backbone_tube_sheet_c_var ->value_ptr ();
+ vars.push_back (backbone_tube_sheet_c_var);
+
+ DoubleDataVar *backbone_tube_random_a_var = new DoubleDataVar ("backbone_tube_random_a", .2);
+ backbone_tube_random_a = backbone_tube_random_a_var ->value_ptr ();
+ vars.push_back (backbone_tube_random_a_var);
+
+ DoubleDataVar *backbone_tube_random_b_var = new DoubleDataVar ("backbone_tube_random_b", .2);
+ backbone_tube_random_b = backbone_tube_random_b_var ->value_ptr ();
+ vars.push_back (backbone_tube_random_b_var);
+
+ DoubleDataVar *backbone_tube_random_c_var = new DoubleDataVar ("backbone_tube_random_c", 0.0);
+ backbone_tube_random_c = backbone_tube_random_c_var ->value_ptr ();
+ vars.push_back (backbone_tube_random_c_var);
+
+}
+
+void Data::write_preferences () {
+ string pref_name = "Zodiac.ini";
+
+ ofstream ofs(pref_name.c_str ());
+ for (unsigned int i=0; i<vars.size (); i++) {
+ ofs << vars[i] ->write_string ()<<endl;
+ }
+
+ ofs.close ();
+
+}
+
+void Data::load_preferences () {
+ string pref_name = "Zodiac.ini";
+
+ ifstream ifs (pref_name.c_str ());
+ if (ifs.good ()) {
+ string buffer;
+ while (getline(ifs, buffer)) {
+ for (unsigned int i=0; i<vars.size (); i++) {
+ vars[i] ->load (buffer);
+ }
+ }
+ }
+
+}
+
+void *haptic_callback (void * data) {
+
+#ifdef HAPI
+ Data *dat = (Data *) data;
+
+
+
+Vec3 position = dat ->haptic_device->getRawPosition();
+Vec3 angles (0.f, 0.f, 0.f);
+//Rotation haptic_device ->getOrientation();
+
+ dat ->haptic_position_lock ->lockForWrite ();
+ dat ->current_position_x = position.x*2000;
+ dat ->current_position_y = position.y*2000;
+ dat ->current_position_z = position.z*2000;
+ dat ->haptic_position_lock ->unlock ();
+
+
+// dat ->current_position_y = 0.;
+// dat ->current_position_z = 0.;
+
+// dat ->current_position_x = 0;
+// dat ->current_position_y = 0;
+// dat ->current_position_z = 0;
+
+ //cerr << position << endl;
+ //cerr << position.x << " position"<<endl;
+
+ dat ->current_pitch = angles[2];
+ dat ->current_roll = angles[0];
+ dat ->current_yaw = angles[1];
+
+ dat ->current_pitch = 0.;
+ dat ->current_roll = 0.;
+ dat ->current_yaw = 0.;
+
+ //Vec3 force_to_render (dat ->current_force_x, dat ->current_force_y, dat ->current_force_z);
+ //dat ->haptic_device ->sendForce (force_to_render);
+
+#endif //HAPI
+ return 0;
+
+}
+
+
+void ColorDataVar::load (string buffer) {
+ istringstream line(buffer);
+ string token;
+ line >> token;
+
+ if (token == name) {
+ int count = 0;
+ vector <int> vals;
+ string q;
+ while (!line.eof ()) {
+ count++;
+ line >> q;
+ vals.push_back (string_to_int (q));
+ }
+ if (count < 3) cerr <<name<<" not enough values";
+ else if (count > 4 ) cerr <<name<< "too many values";
+ else if (count == 4) {_value = color (vals [0], vals[1], vals [2], vals[3]); cerr <<vals [0]<<" "<<vals[1]<<" "<<vals[2]<<" "<<vals[3]<<endl; }
+ else {_value = color (vals [1], vals[2], vals [3]);}
+ }
+
+}
+
+
+void StringDataVar::load (string buffer) {
+ istringstream line(buffer);
+ string token;
+ line >> token;
+
+ if (token == name) {
+ int count = 0;
+ string q;
+ while (!line.eof ()) {
+ count++;
+
+ line >> q;
+ }
+ if (!count) cerr <<name<<" no value";
+ else if (count > 1 ) cerr <<name<< "multiple values";
+ else _value = q;
+ }
+
+}
+
+
+
+void DoubleDataVar::load (string buffer) {
+ istringstream line(buffer);
+ string token;
+ line >> token;
+
+ if (token == name) {
+ int count = 0;
+ string q;
+ while (!line.eof ()) {
+ count++;
+
+ line >> q;
+ }
+ if (!count) cerr <<name<<" no value";
+ else if (count > 1 ) cerr <<name<< "multiple values";
+ else _value = string_to_double (q);
+ }
+
+}
+
+
+/*
+void Data::set_FF (MMFF *mmf, TriposFF *triposf, PLP *pl){
+ mmff =mmf;
+ triposff =triposf;
+ plp = pl;
+
+
+}
+*/
+
+ZNMolecule* Data::check_mol2 (string filename){
+ return 0;
+
+ /* cout << "reading file "<<filename<<endl;
+ ZNMolecule *mol = new ZNMolecule ();
+ ifstream ifs (filename.c_str() );
+ bool b = false;
+ bool multi = (mol->readMultiMOL2 (filename, ifs, b)==2);
+ unsigned int asize =mol->atoms.size ();
+ if (asize>0) {
+ mol->valid=true;
+ }
+ if (multi) {
+ cout <<" multimol2"<<endl;
+ delete mol;
+ bool go_on = true;
+ Database* database = new Database ();
+ ifstream mfs (filename.c_str() );
+ b = false;
+ while (go_on) {
+ Database_molecule *new_mol = new Database_molecule ();
+ cout <<"b="<<b<<endl;
+ new_mol->readMultiMOL2 (filename, mfs, b);
+ b = true;
+ if (new_mol->atoms.size () < 1) {
+ go_on = false;
+ delete new_mol;
+ }
+ else {
+ new_mol->database = database;
+ new_mol->number = database->molecules.size ()+1;
+ new_mol->valid = true;
+ database->molecules.push_back (new_mol);
+ // cerr << database->molecules.size ()<<endl;
+ }
+ }
+ mol = (ZNMolecule *) database->molecules[0];
+ }
+ return mol;
+*/
+}
+
+
+
+/*
+
+////////////////////////////////////CONFLINE//////////////////////////////////////////////////////////////////
+
+
+
+#include <iostream>
+#include <sstream>
+
+
+#include <string>
+
+
+
+
+Confline::Confline (char ctype, string cfilestr, string cdefval, MyLine* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetl = ctarget; type = ctype;
+
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr,string cdefval, QPushButton* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetb = ctarget;type = ctype;
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr,string cdefval, QComboBox* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetcb = ctarget;type = ctype;
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,QLineEdit* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetle = ctarget;type = ctype;
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,MyLineF* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetlf = ctarget; type = ctype;
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,Q3ListBox* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetlb = ctarget; type = ctype;
+Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,MainWin* ctarget)
+{
+defval = cdefval;filestr = cfilestr; targetmw = ctarget; type = ctype;
+Default ();
+}
+
+int Confline::getInt (string mystr){
+ istringstream iss (mystr);
+ int i;
+ iss>>i;
+ return i;
+}
+
+
+void Confline::Default () {
+ current = defval;
+ if (type=='m' || type=='M' ) {vector.clear();};
+ }
+
+
+
+void Confline::Apply () {
+ if (type=='l') {
+ targetl->ins (current);
+
+ }
+
+ if (type=='f') {
+ targetlf->ins (current);
+
+ }
+ else if (type=='b') {
+
+ targetb->setOn (getInt (current));
+
+ }
+ else if (type=='c') {
+
+ targetcb->setCurrentText (current);
+
+ }
+
+ else if (type=='m') {
+ targetlb->clear ();
+ for (unsigned int j=0; j<vector.size(); j++){
+ targetlb->insertItem(vector[j]);
+
+ }
+ }
+
+ else if (type=='M') {
+ targetlb->clear ();
+ for (unsigned int j=0; j<vector.size(); j++){
+ targetlb->insertItem(new MyListBoxItem (vector[j], targetlb));
+
+ }
+ }
+
+
+
+ else if (type=='s') {
+ istringstream line(current);
+ string nbsx, nbsy, nbsz;
+ line >> nbsx >>nbsy >> nbsz;
+ targetmw->bsx->ins ("");
+ targetmw->bsy->ins ("");
+ targetmw->bsz->ins ("");
+ targetmw->bsx->ins (nbsx);
+ targetmw->bsy->ins (nbsy);
+ targetmw->bsz->ins (nbsz);
+
+ }
+
+
+}
+
+
+void Confline::Get () {
+ if (type=='l') {
+ current = targetl->val ();
+
+ }
+
+ if (type=='f') {
+ current = targetlf->val ();
+
+ }
+ else if (type=='b') {
+ current = boolstr (targetb->isOn ());
+
+
+ }
+ else if (type=='c') {
+
+ QString t = targetcb->currentText (); current = t.latin1();
+
+
+ }
+
+ else if (type=='m') {
+
+ if (targetlb->count ()) {
+ vector.clear ();
+ for (unsigned int j=0; j<targetlb->count() ; j++){
+ vector.push_back (targetlb->text (j));
+ }
+ }
+
+ }
+
+ else if (type=='M') {
+
+ if (targetlb->count ()) {
+ vector.clear ();
+ for (unsigned int j=0; j<targetlb->count() ; j++){
+ vector.push_back (targetlb->item (j)->text ());
+ cout << "check this" << targetlb->item (j)->text () << endl;
+ }
+ }
+
+
+ }
+
+
+ else if (type=='s') {
+ istringstream line(current);
+ string nbsx, nbsy, nbsz;
+ line >> nbsx >>nbsy >> nbsz;
+ current = targetmw->bsx->val ();
+ current.append (" ");
+ current.append (targetmw->bsy->val ());
+ current.append (" ");
+ current.append (targetmw->bsz->val ());
+ }
+
+
+}
+
+
+
+string Confline ::boolstr (bool boo){
+ if (boo) return "1";
+ else return "0";
+}
+
+
+////////////////////////////////////CONFIGURATION//////////////////////////////////////////////////////////////////
+
+Configuration::Configuration (Data *dat) {
+ setdata (dat);
+
+
+
+ conf.push_back (new Confline ('l',"aco_ants","20", data->window->mainwin->aants));
+ conf.push_back (new Confline ('l',"aco_evap", "0.15", data->window->mainwin->aevap));
+ conf.push_back (new Confline ('l',"aco_sigma", "1.0", data->window->mainwin->asigma));
+ conf.push_back (new Confline ('b',"flip_amide_bonds", "0", data->window->mainwin->flipab));
+ conf.push_back (new Confline ('b',"flip_planar_n", "1", data->window->mainwin->flipn));
+ conf.push_back (new Confline ('b',"force_flipped_bonds_planarity", "0", data->window->mainwin->ffbp));
+ conf.push_back (new Confline ('c',"scoring_function", "chemplp", data->window->mainwin->sfchoice));
+ conf.push_back (new Confline ('b',"chemplp_weak_cho", "0", data->window->mainwin->cho));
+ conf.push_back (new Confline ('c',"ligand_intra_score", "clash", data->window->mainwin->lintra));
+ conf.push_back (new Confline ('l',"chemplp_charged_hb_weight", "1.5", data->window->mainwin->chbw));
+ conf.push_back (new Confline ('l',"chemplp_charged_metal_weight", "1.5", data->window->mainwin->cmw));
+ conf.push_back (new Confline ('l',"chemplp_hbond_weight", "-4.0", data->window->mainwin->hbw));
+ conf.push_back (new Confline ('l',"chemplp_hbond_cho_weight", "-3.0", data->window->mainwin->hbchow));
+ conf.push_back (new Confline ('l',"chemplp_metal_weight", "-9.0", data->window->mainwin->mw));
+ conf.push_back (new Confline ('l',"chemplp_plp_weight", "0.7", data->window->mainwin->plpw));
+ conf.push_back (new Confline ('l',"chemplp_intercept_weight", "-20.0", data->window->mainwin->iw));
+ conf.push_back (new Confline ('l',"cluster_rmsd", "2.0", data->window->mainwin->crmsd));
+ conf.push_back (new Confline ('l',"cluster_structures", "5", data->window->mainwin->cs));
+
+
+ conf.push_back (new Confline ('M',"ifile", "", data->window->mainwin->iflb));
+ conf.push_back (new Confline ('f',"protein_file", "", data->window->mainwin->pfile));
+ conf.push_back (new Confline ('l',"output_dir", "", data->window->mainwin->odir));
+ conf.push_back (new Confline ('s',"bindingsite_center", "", data->window->mainwin));
+ conf.push_back (new Confline ('l',"bindingsite_radius", "", data->window->mainwin->bsr));
+ conf.push_back (new Confline ('b',"write_protein_conformations", "1", data->window->mainwin->wpc));
+ conf.push_back (new Confline ('b',"write_rescored_structures", "0", data->window->mainwin->wrs));
+ conf.push_back (new Confline ('b',"write_multi_mol2", "1", data->window->mainwin->wmm2));
+ conf.push_back (new Confline ('b',"write_ranking_links", "0", data->window->mainwin->wrl));
+ conf.push_back (new Confline ('b',"write_ranking_multi_mol2", "0", data->window->mainwin->wrmm2));
+ conf.push_back (new Confline ('b',"write_protein_bindingsite", "1", data->window->mainwin->wpb));
+ conf.push_back (new Confline ('b',"write_protein_splitted", "1", data->window->mainwin->wps));
+ conf.push_back (new Confline ('b',"write_per_atom_scores", "0", data->window->mainwin->wpas));
+
+ conf.push_back (new Confline ('m',"constr", "", data->window->mainwin->constrlb));
+
+ conf.push_back (new Confline ('m',"flex", "", data->window->mainwin->flexlb));
+ conf.push_back (new Confline ('b',"rigid_ligand", "0", data->window->mainwin->rigidl));
+ conf.push_back (new Confline ('b',"rigid_all", "0", data->window->mainwin->rigida));
+ conf.push_back (new Confline ('l',"intra_protein_score_weight", "0.4", data->window->mainwin->ipsw));
+
+ conf.push_back (new Confline ('f',"water_molecule_definition", "", data->window->mainwin->wref));
+ conf.push_back (new Confline ('m',"water", "", data->window->mainwin->waterlb));
+ conf.push_back (new Confline ('l',"water_protein_hb_weight", "1.0", data->window->mainwin->wphb));
+ conf.push_back (new Confline ('l',"water_ligand_hb_weight", "1.0", data->window->mainwin->wlhb));
+ conf.push_back (new Confline ('l',"water_water_hb_weight", "1.0", data->window->mainwin->wwhb));
+ conf.push_back (new Confline ('l',"no_water_ligand_hb_penalty", "0.0", data->window->mainwin->nwhbp));
+
+
+
+
+
+
+
+
+
+ Default ();
+}
+
+void Configuration::setdata (Data *datas){
+ data = datas;
+ data->config = this;
+ // win->conf = this;
+
+}
+
+
+void Configuration::Default () {
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Default ();
+
+ }
+
+
+}
+
+
+void Configuration::Apply (){
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Apply ();
+ data->window->mainwin->check_ligands ();
+ data->ddwin->load_waters ();
+ }
+
+
+}
+
+
+void Configuration::Get (){
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Get ();
+ }
+}
+
+
+
+void Configuration::Read (const char * filename){
+ if (filename) {
+ ifstream ifs (filename);
+ string buffer;
+ vector<string> ifiles, vflex, vconstr, vwater;
+ ifiles.clear(); vflex.clear (); vconstr.clear (); vwater.clear ();
+ while (getline(ifs, buffer)) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+
+ if (token == "ligand_list" || token == "ligand_file") {
+ string s = token;
+ while (not line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ ifiles.push_back (s);
+ }
+
+
+
+
+ else if (token == "chemplp_protein_hb_constraint" || token == "shape_constraint" || token == "surface_distance_constraint" || token == "ligand_intra_distance_constraint" || token == "protein_ligand_distance_constraint") {
+ string s = token;
+ while (not line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ vconstr.push_back (s);
+ }
+
+ else if (token == "flexible_protein_side_chain_number" || token == "fixed_protein_bond" || token == "flexible_protein_side_chain_string") {
+ string s = token;
+ while (not line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ vflex.push_back (s);
+ }
+
+ else if (token == "water_molecule") {
+ string s = token;
+ vector <float> wat;
+ wat.clear ();
+ while (not line2.eof ()) {
+
+ float f;
+ string q;
+
+ line2 >> q;
+ istringstream lin (q);
+ lin >> f;
+ wat.push_back (f);
+ s.append (" ");s.append (q);
+ }
+ vwater.push_back (s);
+
+ data->waters.push_back(wat);
+ }
+
+
+
+ for (unsigned i=0; i<conf.size (); i++){
+ if (token == conf[i]->filestr && conf[i]->type!='s') {
+ line2>>conf[i]->current;
+ break;
+ }
+ if (token == conf[i]->filestr && conf[i]->type=='s') {
+ string x, y, z;
+ line2>>x>>y>>z;
+ conf[i]->current=x;conf[i]->current.append (" ");
+ conf[i]->current.append(y);conf[i]->current.append (" "); conf[i]->current.append(z);
+ }
+
+
+ }
+
+
+
+
+
+ for (unsigned i=0; i<conf.size (); i++){
+ if (conf[i]->filestr == "ifile") {
+ conf[i]->vector = ifiles;
+
+ }
+ if (conf[i]->filestr == "constr") {
+ conf[i]->vector = vconstr;
+
+ }
+ if (conf[i]->filestr == "flex") {
+ conf[i]->vector = vflex;
+
+ }
+ if (conf[i]->filestr == "water") {
+ conf[i]->vector = vwater;
+
+ }
+
+ }
+ }
+
+ }
+}
+
+
+
+
+
+
+void Configuration::Write (const char * filename){
+
+ ofstream *file = new ofstream(filename);
+ *file << "#Generated by PLANTS FE version " <<VERSION<< endl<<endl;
+
+ for (unsigned int i=0;i<conf.size(); i++){
+ if (i == 0){*file << endl << endl << "#ALGORITHM" << endl;};
+ if (i == 17){*file << endl << endl << "#INPUT-OUTPUT" << endl;};
+ if (i == 29){*file << endl << endl << "#CONSTRAINTS && FLEXIBILITY" << endl;};
+ if (i == 33){*file << endl << endl << "#WATER" << endl;};
+ if (conf[i]->type=='m' || conf[i]->type=='M' ){
+ for (unsigned int j=0;j<conf[i]->vector.size(); j++){
+ *file << conf[i]->vector[j] << endl;
+ }
+ }
+ else{
+ *file << conf[i]->filestr << " " << conf[i]->current << endl;
+ }
+ }
+
+
+
+
+
+
+
+
+ file->close();
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+*/
+
+bool is_db_extended (ZNMolecule *mol) {
+ bool ext = false;
+ if (mol -> multi) {
+ Database_molecule *dm = (Database_molecule *) mol;
+ if (dm -> database -> has_extend_enabled ()) ext = true;
+ }
+ return ext;
+}
diff --git a/ZNmolecule.cc b/ZNmolecule.cc
new file mode 100644
index 0000000..d45f78e
--- /dev/null
+++ b/ZNmolecule.cc
@@ -0,0 +1,4898 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+
+#include "ZNmolecule.h"
+
+float very_fast_RMSD (ZNMolecule *a, ZNMolecule *b) { //assumes that the molecules are identical and atoms are in the correct order
+ if (a ->NumAtoms() != b ->NumAtoms()) return -1;
+ else {
+ float tot = 0.f;
+ int n = 0;
+ FOR_ATOMS_OF_MOL (at, a) {
+ n++;
+ int indx = at ->GetIdx ();
+ Atom *bat = b ->GetAtom(indx);
+ vect ca = get_coordinates(&*at);
+ vect cb = get_coordinates(&*bat);
+ float squared = (ca.x () -cb.x()) * (ca.x () -cb.x()) + (ca.y () -cb.y()) * (ca.y () -cb.y()) + (ca.z () -cb.z()) * (ca.z () -cb.z());
+ tot += squared;
+ }
+ tot /= n;
+ return sqrt (tot);
+ }
+}
+
+
+
+void rotorConnection::set_dihedral (double angle) {
+ dihedral = angle;
+ vect center = get_coordinates (to_atom);
+ vect axis = subtract (center, get_coordinates (from_atom));
+ vector <Fragment *> fragments = to_fragment ->get_children ();
+ fragments.push_back (to_fragment);
+ quaternion q = axis_angle_to_quaternion(axis, angle);
+ for (unsigned int i = 0; i < fragments.size (); i++) {
+ fragments[i] ->quaternion_rotate (center, q);
+ }
+}
+
+bool is_polar (Atom *at) {
+ int i = at ->GetAtomicNum ();
+ if (i == 7 || i == 8 || i == 9) return true;
+ return false;
+}
+
+Atom *root_at (Atom *at) {
+ FOR_NBORS_OF_ATOM (n, at) {
+ return &*n;
+ }
+ return 0;
+}
+
+
+
+vect get_coordinates (Atom *at) {
+ vect v = (vect &) at -> GetVector ();
+ return v;
+}
+
+vect get_coordinates (SurfVertex *ver) {
+ vect v = (vect &) ver -> GetVector ();
+ return v;
+
+}
+
+
+
+void set_coordinates (Atom *at, vect v) {
+ at -> SetVector (v);
+}
+
+void sum_to_coordinates (Atom *at, vect v) {
+ vect v1 = (vect &) at -> GetVector ();
+ vect v2 = sum (v, v1);
+ at -> SetVector (v2);
+}
+
+void set_center (ZNMolecule *mol, vect v) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> set_center (v);
+}
+
+vect get_center (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ return d -> get_center ();
+}
+
+void set_fragments_perceived (ZNMolecule *mol, bool b) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> _fragments_perceived = b;
+}
+
+bool get_fragments_perceived (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ return d -> _fragments_perceived;
+}
+
+void set_backbone_perceived (ZNMolecule *mol, bool b) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> _backbone_perceived = b;
+}
+
+bool get_backbone_perceived (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ return d -> _backbone_perceived;
+}
+
+
+vect get_min_corner (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ return d -> get_min_corner ();
+}
+
+vect get_max_corner (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ return d -> get_max_corner ();
+}
+
+void set_min_corner (ZNMolecule *mol, vect v) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> set_min_corner (v);
+}
+
+void set_max_corner (ZNMolecule *mol, vect v) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> set_max_corner (v);
+}
+
+
+void lock_geometry_for_read (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> lock -> lockForRead ();
+}
+
+void lock_geometry_for_write (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> lock -> lockForWrite ();
+}
+
+void unlock_geometry (ZNMolecule *mol) {
+ GeometryData *d = (GeometryData *) mol -> GetData (GEOMETRY_DATA_INDEX);
+ assert (d);
+ d -> lock -> unlock ();
+}
+
+void mend_coordinates (ZNMolecule *mol) {
+ if (mol) {
+ // FOR_ATOMS_OF_MOL (a, mol) {
+ // vect v = get_coordinates(&*a);
+ // if (isnan (v.x())) v.x() = 0.;
+ // if (isnan (v.y())) v.y() = 0.;
+ // if (isnan (v.z())) v.z() = 0.;
+ // set_coordinates(&*a, v);
+ // }
+ if (mol ->NumAtoms ()) {
+ OBBuilder obbuild;
+ obbuild.Build (*mol);
+ }
+ }
+}
+
+void molecule_has_changed (ZNMolecule *mol) {
+ set_fragments_perceived(mol, false);
+ set_backbone_perceived(mol, false);
+}
+
+vect find_mass_center (vector<Atom*>& invec){
+
+ unsigned int i;
+ vect midCoo;
+
+
+ unsigned int numMid = 0;
+ for (i = 0; i < invec.size(); i++) {
+ vect a = sum (midCoo, get_coordinates (invec[i]));
+ midCoo = a;
+ numMid++;
+
+ }
+
+ midCoo.multiply (1.0f/(float) numMid);
+
+ /*
+ float radius = 0.0;
+ for (i = 0; i < invec.size(); i++) {
+
+ float r2 = (invec[i]-> GetVector ()[0] - midCoo[0]) *(invec[i]-> GetVector ()[0] - midCoo[0]) +
+ (invec[i]-> GetVector ()[1] - midCoo[1]) *(invec[i]-> GetVector ()[1] - midCoo[1]) +
+ (invec[i]-> GetVector ()[2] - midCoo[2]) *(invec[i]-> GetVector ()[2] - midCoo[2]);
+ if (r2 > radius) {
+ radius = r2;
+ }
+ }
+
+ */
+
+ return midCoo;
+
+}
+
+double get_vdw (Atom *at) {
+ int atn = at -> GetAtomicNum ();
+ double rad = etab.GetVdwRad (atn);
+ return rad;
+}
+
+
+
+bool get_visible (Atom *at) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_visible ();
+}
+
+
+bool get_visible (ZNBond *bo) {
+ return (get_visible (bo -> GetBeginAtom ()) && (get_visible (bo -> GetEndAtom ())));
+}
+
+void set_visible (Atom *at, bool vis) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_visible (vis);
+}
+
+
+color get_color (Atom *at) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_color ();
+}
+
+
+void set_color (Atom *at, color col) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_color (col);
+}
+
+vect get_force (Atom *at) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ return d -> get_force_value ();
+}
+
+void set_force (Atom *at, vect v) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ d -> set_force_value (v);
+}
+
+vect get_back_force (Atom *at) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ return d -> get_back_force_value ();
+}
+
+void set_back_force (Atom *at, vect v) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ d -> set_back_force_value (v);
+}
+
+void flush_forces (Atom *at) {
+ vect f = get_back_force (at);
+ set_force (at, f);
+ vect n (0., 0., 0.);
+ set_back_force (at, n);
+}
+
+void flush_scores (Atom *at) {
+ double f = get_back_score (at);
+ // cerr << f << endl;
+ set_score (at, f);
+ set_back_score (at, 0.);
+}
+
+
+void lock_force_mutex (Atom *at) {
+ /* MutexData *d = (MutexData *) at -> GetData ("force_mutex");
+ assert (d);
+ d -> GetGenericValue () ->lock ();*/
+}
+
+void unlock_force_mutex (Atom *at) {
+ /* MutexData *d = (MutexData *) at -> GetData ("force_mutex");
+ assert (d);
+ d -> GetGenericValue () ->unlock ();*/
+}
+
+vect get_root_fragment_center (ZNMolecule *mol) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ return d -> get_fragment_list ()[0] -> get_center ();
+}
+
+
+void set_fragment_list (ZNMolecule *mol, vector <Fragment *> fragment_list) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ d -> set_fragment_list (fragment_list);
+}
+
+vector <Fragment *> get_fragments (ZNMolecule *mol) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ return d -> get_fragment_list ();
+
+}
+
+void add_rotor (ZNMolecule *mol, rotorConnection *connection) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ d -> add_rotor (connection);
+}
+
+void clear_rotors (ZNMolecule *mol) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ d -> clear_rotors ();
+}
+
+
+vector <rotorConnection *> &get_rotors (ZNMolecule *mol) {
+ MolecularFragmentData *d = (MolecularFragmentData *) mol -> GetData (MOLECULAR_FRAGMENT_DATA_INDEX);
+ assert (d);
+ return d -> get_rotors ();
+}
+
+void initialise_dihedrals(ZNMolecule *mol, bool complete) {
+ vector <Fragment *> fragments = get_fragments (mol);
+ for (unsigned int i = 0; i < fragments.size (); i++) {
+ fragments[i] ->reset_coordinates (complete);
+ }
+}
+
+void set_dihedrals (ZNMolecule *mol, vector <double> dihedrals) {
+
+
+ initialise_dihedrals (mol);
+ vector <rotorConnection *> rotors = get_rotors (mol);
+ if (rotors.size () == dihedrals.size ()) {
+ for (unsigned int i = 0; i < rotors.size (); i ++) {
+ rotors[i] ->set_dihedral (dihedrals[i]);
+ }
+ }
+}
+
+void build_molecule_from_dofs (ZNMolecule *mol, vector <float> dofs, bool moving) {
+ lock_geometry_for_write (mol);
+ int gap = 0;
+ if (moving) gap = 6;
+ initialise_dihedrals (mol, true);
+ vector <rotorConnection *> rotors = get_rotors (mol);
+ //cerr << rotors.size () <<" "<< gap<<" "<<dofs.size ()<< endl;
+ if (rotors.size () + gap == dofs.size ()) {
+ for (unsigned int i = 0; i < rotors.size (); i ++) {
+ rotors[i] ->set_dihedral ((double) dofs[i + gap]);
+ }
+ }
+ if (moving) {
+ vect center = get_root_fragment_center (mol);
+ quaternion q = yaw_pitch_roll_to_quaternion (dofs[3], dofs[4], dofs[5]);
+ rotate_molecule (mol, q, center);
+ vect v = vect (dofs[0], dofs[1], dofs[2]);
+ translate_molecule (mol, v);
+ }
+ unlock_geometry (mol);
+}
+
+
+
+vector <double> get_dihedrals (ZNMolecule *mol) {
+ vector <double> out;
+ vector <rotorConnection *> rotors = get_rotors (mol);
+ for (unsigned int i = 0; i < rotors.size (); i ++) {
+ out.push_back (rotors[i] ->dihedral);
+ }
+ return out;
+
+}
+
+
+bool is_helix (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return (d -> ss == 0);
+}
+
+bool is_sheet (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return (d -> ss == 1);
+}
+
+bool is_random (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return (d -> ss == 2);
+}
+
+void set_backbone_direction (Resid *res, vect v) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ d -> backbone_dir = v;
+}
+
+void set_backbone_points (Resid *res, vector <vect> v) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ d -> backbone_points = v;
+}
+
+
+
+void find_secondary_structure (Resid *res) {
+ unsigned int ss = 2;
+ float phi = get_phi (res);
+ float psi = get_psi (res);
+ float t = 20;
+ int ss_score = 0;
+ Resid *prev_turn = get_previous_residue(res, 4);
+ if (prev_turn) {
+ Atom *N = get_N (res);
+ Atom *O = get_O (prev_turn);
+ if (N && O) {
+ float dis2 = square_distance (get_coordinates (N), get_coordinates (O));
+ if (dis2 < 16) ss_score += 1;
+ }
+ }
+ Resid *follow_turn = get_following_residue(res, 4);
+ if (follow_turn) {
+ Atom *N = get_N (follow_turn);
+ Atom *O = get_O (res);
+ if (N && O) {
+ float dis2 = square_distance (get_coordinates (N), get_coordinates (O));
+ if (dis2 < 16) ss_score += 1;
+ }
+ }
+ if ((-57-t < phi && -57+t > phi) && (-47-t < psi && -47+t > psi)) ss_score += 1;
+ if (ss_score >= 2) ss = 0;
+ else if ((-140-t < phi && -110+t > phi) && (110-t < psi && 135+t > psi)) ss = 1;
+ set_ss ( res, ss);
+}
+
+int get_ss (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return d ->ss;
+}
+
+void set_ss (Resid *res, int sec) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ d -> ss = sec;
+}
+
+color get_color (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return d -> col;
+}
+
+void set_color (Resid *res, color c) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ d ->col = c;
+}
+
+
+vect get_backbone_direction (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return d -> backbone_dir;
+}
+
+vector <vect> get_backbone_points (Resid *res) {
+ BackboneData *d = (BackboneData *) res -> GetData (BACKBONE_DATA_INDEX);
+ assert (d);
+ return d -> backbone_points ;
+}
+
+vect get_start_reference (Resid *res) {
+ vector <vect> lis = get_backbone_points (res);
+ if (lis.size ()) return lis [1];
+ return vect (0., 0., 0.);
+}
+
+vect get_end_reference (Resid *res) {
+ vector <vect> lis = get_backbone_points (res);
+ return lis [lis.size ()-2];
+}
+
+void add_guide_points_to_backbone (Resid *res, vector <vect> &lis){
+
+ Resid *prec_res = get_previous_residue (res);
+ Resid *following_res = get_following_residue (res);
+ if (prec_res) {
+ lis.insert(lis.begin(), get_end_reference (prec_res));
+ }
+
+ else if (lis.size () > 1){
+ vect v = lis [1];
+ vect c = lis [0];
+ c.multiply(2.);
+ lis.insert(lis.begin(), subtract (c, v));
+ }
+ else {
+ lis.insert(lis.begin(), vect (0., 0., 0.));
+
+ }
+ if (following_res) {
+ lis.push_back (get_start_reference (following_res));
+ }
+ else if (lis.size () > 1) {
+ vect v = lis [lis.size ()-2];
+ vect c = lis [lis.size ()-1];
+ c.multiply(2.);
+ lis.push_back (subtract (c, v));
+ }
+ else lis.push_back (vect (0., 0., -1.));
+
+}
+
+void color_backbone_ss (ZNMolecule *mol, color hel, color sheet, color random) {
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ if (is_helix(&*res)) set_color (&*res, hel);
+ else if (is_sheet (&*res)) set_color (&*res, sheet);
+ else set_color (&*res, random);
+ }
+ set_needs_backbone_redraw(mol,true);
+}
+
+void color_backbone_color (ZNMolecule *mol, color c) {
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ set_color (&*res, c) ;
+ }
+ set_needs_backbone_redraw(mol,true);
+
+}
+
+void find_backbone_data (ZNMolecule *mol) {
+ if (!get_backbone_perceived(mol)) {
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ find_backbone_points (&*res);
+ find_backbone_direction (&*res);
+ }
+ // FOR_RESIDUES_OF_MOL (res, mol) {
+ // add_guide_points_to_backbone (&*res);
+ // }
+ int smooth_cycles = 3;
+ for (int i = 0; i < smooth_cycles; i++) {
+
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ vector <vect> lis = get_backbone_points(&*res);
+ add_guide_points_to_backbone (&*res, lis);
+ lis = smooth_list(lis);
+ set_backbone_points(&*res, lis);
+ }
+ // FOR_RESIDUES_OF_MOL (res, mol) {
+ // add_guide_points_to_backbone (&*res);
+ // }
+
+ }
+ find_secondary_structure (mol);
+ set_backbone_perceived(mol, true);
+ }
+
+
+}
+
+void find_secondary_structure(ZNMolecule *mol) {
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ find_secondary_structure (&*res);
+
+ }
+ //extend candidate sheets to fill holes
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ int ss = get_ss (&*res);
+ Resid *res2 = get_previous_residue(&*res);
+ if (res2 && (get_ss (&*res) == 1)) {
+ if (get_ss (res2) == 2) set_ss (res2, 1);
+ }
+ }
+
+ bool continuing = false;
+ Resid *res1 = NULL;
+ //check for sheet Hbond partners
+ FOR_RESIDUES_OF_MOL (res, mol) {
+
+
+ int ss = get_ss (&*res);
+ if (ss == 0) {
+ continuing = false;
+ continue;
+ }
+ if (continuing) {
+ Resid *next_res = get_following_residue(res1);
+ if (is_bsheet (&*res, next_res)) {
+ set_ss (&*res, 1);
+ set_ss (next_res, 1);
+ res1 = get_following_residue(res1);
+ }
+ else {
+ next_res = get_previous_residue(res1);
+ if (is_bsheet (&*res, next_res)) {
+ set_ss (&*res, 1);
+ set_ss (next_res, 1);
+ res1 = get_previous_residue(res1);
+ }
+ else {
+ res1 = find_sheet_partner (&*res, mol);
+
+ if (res1) {
+ continuing = true;
+ set_ss (&*res, 1);
+ set_ss (res1, 1);
+ }
+ else {
+ set_ss (&*res, 2);
+ continuing = false;
+ res1 = NULL;
+ }
+ }
+ }
+
+
+ }
+ else { // start new sheet
+ res1 = find_sheet_partner (&*res, mol);
+ if (res1) {
+ continuing = true;
+ set_ss (&*res, 1);
+ set_ss (res1, 1);
+ }
+ else {
+ set_ss (&*res, 2);
+ }
+ }
+
+ }
+
+}
+
+
+Resid *find_sheet_partner (Resid *res, ZNMolecule *mol) {
+ FOR_RESIDUES_OF_MOL (res1, mol) {
+
+ int d = res1 ->GetIdx () - res ->GetIdx ();
+ if (d*d < 5) continue;
+ if (is_bsheet(res, &*res1)) return &*res1;
+ }
+ return NULL;
+}
+
+
+bool is_bsheet (Resid *res1, Resid *res2) {
+ if (!res1) return false;
+ if (!res2) return false;
+ if (get_ss (res1) != 1) return false;
+ if (get_ss (res2) != 1) return false;
+ Atom *n, *o;
+ n = get_N (res1);
+ o = get_O (res2);
+ if (square_distance(get_coordinates (n), get_coordinates (o)) < 25.f) return true;
+ n = get_N (res2);
+ o = get_O (res1);
+ if (square_distance(get_coordinates (n), get_coordinates (o)) < 25.f) return true;
+ return false;
+}
+
+void find_backbone_direction (Resid *res) {
+ vect out (0., 0., 1.);
+ Atom *at_o = get_O (res);
+ Atom *at_c = get_C (res);
+ if (at_o && at_c) {
+ out = subtract (get_coordinates(at_o), get_coordinates(at_c));
+
+ }
+
+ set_backbone_direction (res, out);
+}
+
+
+
+void find_backbone_points (Resid *res) {
+ bool prec = false, fol = false;
+ vect prec_vect = vect (0, 0,0);
+ vect fol_vect = vect (0, 0,0);
+ vector <vect> out;
+ ZNMolecule *mol = NULL;
+ FOR_ATOMS_OF_RESIDUE (a, res) {
+ mol = (ZNMolecule *) &*a -> GetParent ();
+ }
+ int indx = res -> GetIdx ();
+ Resid *prec_res = get_previous_residue (res);
+ if (prec_res) {
+ if (res ->GetChainNum () == prec_res ->GetChainNum ()) {
+ Atom *prec_c = get_C (prec_res);
+ if (prec_c) {
+ prec = true;
+ prec_vect = get_coordinates(prec_c);
+ }
+
+ }
+ }
+ Resid *fol_res = get_following_residue(res);
+ if (fol_res) {
+ if (res ->GetChainNum () == fol_res ->GetChainNum ()) {
+ Atom *fol_n = get_N (fol_res);
+ if (fol_n) {
+ fol = true;
+ fol_vect = get_coordinates(fol_n);
+ }
+
+ }
+ }
+
+ Atom *n = 0;
+ Atom *ca = 0;
+ Atom *c = 0;
+ n = get_N (res);
+ ca = get_CA (res);
+ c = get_C (res);
+ if (n && c && ca) {
+ vect vca = get_coordinates(ca);
+ vect vc = get_coordinates(c);
+ vect vn = get_coordinates (n);
+ if (prec) {
+ out.push_back(mean (prec_vect, vn));
+ }
+ else out.push_back(vn);
+ // out.push_back (mean (mean (vn, vca), mean (vca, vc)));
+ // out.push_back(mean (vca, vc));
+
+
+ if (fol) {
+ out.push_back(mean (fol_vect, vc));
+ }
+ else out.push_back (vc);
+ }
+
+
+
+ set_backbone_points (res, out);
+}
+
+
+
+
+vector <vect> smooth_list (vector <vect> lis){ // P A B ... C F interpolates between A B C etc, P and F are discarded after calculation
+ if (lis.size () > 2) {
+ vector <vect> ilist, out;
+ vect lasti;
+ for (unsigned int i = 1; i < lis.size () -1; i++) {
+ vect i1, i2;
+ interpolate (lis[i-1], lis[i], lis[i+1], i1, i2);
+ if (i > 1) {
+ // cerr << i1 << i2<<endl;
+ ilist.push_back (mean (i1, lasti));
+
+ }
+ lasti = i2;
+
+ }
+ out.push_back (lis[1]);
+ //discarding first and last interpolated points
+ for (unsigned int i = 0; i < ilist.size (); i++) {
+ out.push_back (ilist[i]);
+ out.push_back (lis [i+2]);
+ }
+ return out;
+ }
+ else { return lis;}
+
+}
+
+
+
+
+void finalise_molecule (ZNMolecule *mol) { //builds kinematic chains ZNinits etc etc
+ mol ->ZNinit();
+ if (mol ->NumAtoms ()) { // allows for empty molecules to be finalised
+
+ // build_kinematic_chain(mol);
+ // find_backbone_data (mol);
+ }
+}
+
+
+void build_kinematic_chain (ZNMolecule *mol) {
+ if (!get_fragments_perceived(mol)) {
+ clear_rotors (mol);
+ FOR_ATOMS_OF_MOL (a, mol) {
+ set_kinematic_chain_visited(&*a, false);
+ }
+
+ vector <Fragment *> fragments;
+ queue <Atom *> atom_queue;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (!get_kinematic_chain_visited (&*a)) {
+ Fragment *fragment = new Fragment;
+ fragments.push_back (fragment);
+ fragment ->set_number (fragments.size ());
+
+ atom_queue.push (&*a);
+ set_kinematic_chain_visited (&*a, true);
+
+ while (!atom_queue.empty ()) {
+ Atom *current_atom = atom_queue.front ();
+ atom_queue.pop ();
+ fragment ->add_atom (current_atom);
+ set_fragment (current_atom, fragment);
+ FOR_NBORS_OF_ATOM (neighbour, current_atom) {
+ ZNBond *bond = current_atom ->GetBond (&*neighbour);
+ if (! get_kinematic_chain_visited(&*neighbour) && !bond ->IsRotor()) {
+ atom_queue.push (&*neighbour);
+ set_kinematic_chain_visited (&*neighbour, true);
+ }
+ }
+ }
+ }
+ }
+ FOR_BONDS_OF_MOL (b, mol) {
+ if (b ->IsRotor ()) {
+ Atom *begin_atom = b ->GetBeginAtom ();
+ Atom *end_atom = b ->GetEndAtom ();
+ Fragment *begin_fragment = get_fragment(begin_atom);
+ Fragment *end_fragment = get_fragment(end_atom);
+ rotorConnection *connection1 = new rotorConnection ();
+ connection1 ->bond = &*b;
+ connection1 ->from_atom = begin_atom;
+ connection1 ->to_atom = end_atom;
+ connection1 ->to_fragment = end_fragment;
+ connection1 ->to_keep = false;
+ begin_fragment -> add_rotor_connection (connection1);
+
+ rotorConnection *connection2 = new rotorConnection ();
+ connection2 ->bond = &*b;
+ connection2 ->from_atom = end_atom;
+ connection2 ->to_atom = begin_atom;
+ connection2 ->to_fragment = begin_fragment;
+ connection2 ->to_keep = false;
+ end_fragment -> add_rotor_connection (connection2);
+ }
+ }
+ if (fragments.size ()) {
+ Fragment *biggest_fragment = fragments[0];
+ for (unsigned int i = 0; i < fragments.size (); i++) {
+ fragments[i] -> set_visited (false);
+ if (fragments[i] ->size () > biggest_fragment ->size ()) {
+ biggest_fragment = fragments[i];
+ }
+ }
+ queue <Fragment *> fragment_queue;
+ fragment_queue.push (biggest_fragment);
+ biggest_fragment ->set_visited (true);
+
+ while (!fragment_queue.empty ()) {
+ Fragment *current_fragment = fragment_queue.front ();
+ fragment_queue.pop ();
+ for (unsigned int j = 0; j < current_fragment->number_of_connections (); j++) {
+ rotorConnection *connection = current_fragment ->get_rotor_connection (j);
+ Fragment *next_fragment = connection ->to_fragment;
+ if (!next_fragment ->get_visited ()) {
+ next_fragment ->set_visited(true);
+ fragment_queue.push (next_fragment);
+ connection -> to_keep = true;
+ add_rotor (mol, connection);
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < fragments.size (); i++) {
+ fragments[i] -> clean_connections ();
+ fragments[i] -> set_center ();
+ }
+
+
+ for (unsigned int i = 0; i < fragments.size (); i++) {
+
+ fragments[i] ->find_children ();
+ }
+ set_fragment_list (mol, fragments);
+
+ }
+ set_fragments_perceived(mol, true);
+ }
+
+}
+
+
+
+
+int get_MMFFtype (Atom *atom) {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ OBBond *bond;
+ int oxygenCount, nitrogenCount, sulphurCount, doubleBondTo;
+ ////////////////////////////////
+ // Aromatic Atoms
+ ////////////////////////////////
+ if (atom->IsAromatic()) {
+ if (atom->IsInRingSize(5)) {
+ bool IsAromatic = false;
+ vector<OBAtom*> alphaPos, betaPos;
+ vector<OBAtom*> alphaAtoms, betaAtoms;
+
+ if (atom->IsSulfur()) {
+ return 44; // Aromatic 5-ring sulfur with pi lone pair (STHI)
+ }
+ if (atom->IsOxygen()) {
+ return 59; // Aromatic 5-ring oxygen with pi lone pair (OFUR)
+ }
+ if (atom->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 82; // N-oxide nitrogen in 5-ring alpha position,
+ // N-oxide nitrogen in 5-ring beta position,
+ // N-oxide nitrogen in other 5-ring position,
+ // (N5AX, N5BX, N5OX)
+ }
+ }
+ }
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (!((mol -> GetBond(atom, &*nbr))->IsAromatic()) || !nbr->IsInRingSize(5))
+ continue;
+
+ if (IsInSameRing(atom, &*nbr)) {
+ alphaPos.push_back(&*nbr);
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->GetIdx() == atom->GetIdx())
+ continue;
+ if (!((mol -> GetBond(&*nbr, &*nbrNbr))->IsAromatic()) || !nbrNbr->IsInRingSize(5))
+ continue;
+
+ IsAromatic = true;
+
+ if (IsInSameRing(atom, &*nbrNbr)) {
+ betaPos.push_back(&*nbrNbr);
+ }
+ }
+ }
+
+ if (IsAromatic) {
+
+
+ for (unsigned int i = 0; i < alphaPos.size(); i++) {
+ if (alphaPos[i]->IsSulfur()) {
+ alphaAtoms.push_back(alphaPos[i]);
+ } else if (alphaPos[i]->IsOxygen()) {
+ alphaAtoms.push_back(alphaPos[i]);
+ } else if (alphaPos[i]->IsNitrogen() && (alphaPos[i]->GetValence() == 3)) {
+ bool IsNOxide = false;
+ FOR_NBORS_OF_ATOM (nbr, alphaPos[i]) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ IsNOxide = true;
+ }
+ }
+
+ if (!IsNOxide) {
+ alphaAtoms.push_back(alphaPos[i]);
+ }
+ }
+ }
+ for (unsigned int i = 0; i < betaPos.size(); i++) {
+ if (betaPos[i]->IsSulfur()) {
+ betaAtoms.push_back(betaPos[i]);
+ } else if (betaPos[i]->IsOxygen()) {
+ betaAtoms.push_back(betaPos[i]);
+ } else if (betaPos[i]->IsNitrogen() && (betaPos[i]->GetValence() == 3)) {
+ bool IsNOxide = false;
+ FOR_NBORS_OF_ATOM (nbr, betaPos[i]) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ IsNOxide = true;
+ }
+ }
+
+ if (!IsNOxide) {
+ betaAtoms.push_back(betaPos[i]);
+ }
+ }
+ }
+ if (!betaAtoms.size()) {
+ nitrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ // cout << "BOSum=" << nbr->BOSum() << endl;
+ if (nbr->IsNitrogen() && (nbr->GetValence() == 3)) {
+ if ((nbr->BOSum() == 4) && nbr->IsAromatic()) {
+ nitrogenCount++;
+ } else if ((nbr->BOSum() == 3) && !nbr->IsAromatic()) {
+ nitrogenCount++;
+ }
+ }
+ }
+ if (nitrogenCount >= 2) {
+ return 80; // Aromatic carbon between N's in imidazolium (CIM+)
+ }
+ }
+ if (!alphaAtoms.size() && !betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ // there is no S:, O:, or N:
+ // this is the case for anions with only carbon and nitrogen in the ring
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ // this is the N: atom
+ return 39; // Aromatic 5 ring nitrogen with pi lone pair (NPYL)
+ } else {
+ // again, no S:, O:, or N:
+ return 76; // Nitrogen in 5-ring aromatic anion (N5M)
+ }
+ }
+ }
+ if (alphaAtoms.size() == 2) {
+ if (atom->IsCarbon() && IsInSameRing(alphaAtoms[0], alphaAtoms[1])) {
+ if (alphaAtoms[0]->IsNitrogen() && alphaAtoms[1]->IsNitrogen()) {
+ if ((alphaAtoms[0]->GetValence() == 3) && (alphaAtoms[1]->GetValence() == 3)) {
+ return 80; // Aromatic carbon between N's in imidazolium (CIM+)
+ }
+ }
+ }
+ }
+ if (alphaAtoms.size() && !betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ return 63; // Aromatic 5-ring C, alpha to N:, O:, or S: (C5A)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ return 81; // Posivite nitrogen in 5-ring alpha position (N5A+)
+ } else {
+ return 65; // Aromatic 5-ring N, alpha to N:, O:, or S: (N5A)
+ }
+ }
+ }
+ if (!alphaAtoms.size() && betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ return 64; // Aromatic 5-ring C, beta to N:, O:, or S: (C5B)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ return 81; // Posivite nitrogen in 5-ring beta position (N5B+)
+ } else {
+ return 66; // Aromatic 5-ring N, beta to N:, O:, or S: (N5B)
+ }
+ }
+ }
+ if (alphaAtoms.size() && betaAtoms.size()) {
+ for (unsigned int i = 0; i < alphaAtoms.size(); i++) {
+ for (unsigned int j = 0; j < betaAtoms.size(); j++) {
+ if (!IsInSameRing(alphaAtoms[i], betaAtoms[j])) {
+ if (atom->IsCarbon()) {
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ return 79; // General nitrogen in 5-membered aromatic ring (N5)
+ }
+ }
+ }
+ }
+ for (unsigned int i = 0; i < alphaAtoms.size(); i++) {
+ if (alphaAtoms[i]->IsSulfur() || alphaAtoms[i]->IsOxygen()) {
+ if (atom->IsCarbon()) {
+ return 63; // Aromatic 5-ring C, alpha to N:, O:, or S: (C5A)
+ } else if (atom->IsNitrogen()) {
+ return 65; // Aromatic 5-ring N, alpha to N:, O:, or S: (N5A)
+ }
+ }
+ }
+ for (unsigned int i = 0; i < betaAtoms.size(); i++) {
+ if (betaAtoms[i]->IsSulfur() || betaAtoms[i]->IsOxygen()) {
+ if (atom->IsCarbon()) {
+ return 64; // Aromatic 5-ring C, beta to N:, O:, or S: (C5B)
+ } else if (atom->IsNitrogen()) {
+ return 66; // Aromatic 5-ring N, beta to N:, O:, or S: (N5B)
+ }
+ }
+ }
+
+ if (atom->IsCarbon()) {
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ return 79; // General nitrogen in 5-membered aromatic ring (N5)
+ }
+ }
+ }
+ }
+
+ if (atom->IsInRingSize(6)) {
+
+ if (atom->IsCarbon()) {
+ return 37; // Aromatic carbon, e.g., in benzene (CB)
+ } else if (atom->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 69; // Pyridinium N-oxide nitrogen (NPOX)
+ }
+ }
+
+ if (atom->GetValence() == 3) {
+ return 58; // Aromatic nitrogen in pyridinium (NPD+)
+ } else {
+ return 38; // Aromatic nitrogen with sigma lone pair (NPYD)
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Hydrogen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 1) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ return 5; // Hydrogen attatched to carbon (HC)
+ }
+ if (nbr->GetAtomicNum() == 14) {
+ return 5; // Hydrogen attatched to silicon (HSI)
+ }
+ if (nbr->IsOxygen()) {
+ if (nbr->BOSum() == 3) {
+ if (nbr->GetValence() == 3) {
+ return 50; // Hydrogen on oxonium oxygen (HO+)
+ } else {
+ return 52; // Hydrogen on oxenium oxygen (HO=+)
+ }
+ }
+
+ int hydrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen()) {
+ hydrogenCount++;
+ continue;
+ }
+ if (nbrNbr->IsCarbon()) {
+ if (nbrNbr->IsAromatic()) {
+ return 29; // phenol
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = mol -> GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsOxygen()) {
+ return 24; // Hydroxyl hydrogen in carboxylic acids (HOCO)
+ }
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen()) {
+ return 29; // Enolic or phenolic hydroxyl hydrogen,
+ // Hydroxyl hydrogen in HO-C=N moiety (HOCC, HOCN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsPhosphorus()) {
+ return 24; // Hydroxyl hydrogen in H-O-P moiety (HOP)
+ }
+ if (nbrNbr->IsSulfur()) {
+ return 33; // Hydrogen on oxygen attached to sulfur (HOS)
+ }
+
+ }
+ if (hydrogenCount == 2) {
+ return 31; // Hydroxyl hydrogen in water (HOH)
+ }
+
+ return 21; // Hydroxyl hydrogen in alcohols, Generic hydroxyl hydrogen (HOR, HO)
+ }
+ if (nbr->IsNitrogen()) {
+ switch (get_MMFFtype(&*nbr)) {
+ case 81:
+ return 36; // Hydrogen on imidazolium nitrogen (HIM+)
+ case 68:
+ return 23; // Hydrogen on N in N-oxide (HNOX)
+ case 67:
+ return 23; // Hydrogen on N in N-oxide (HNOX)
+ case 62:
+ return 23; // Generic hydrogen on sp3 nitrogen, e.g., in amines (HNR)
+ case 56:
+ return 36; // Hydrogen on guanimdinium nitrogen (HGD+)
+ case 55:
+ return 36; // Hydrogen on amidinium nitrogen (HNN+)
+ case 43:
+ return 28; // Hydrogen on NSO, NSO2, or NSO3 nitrogen, Hydrogen on N triply bonded to C (HNSO, HNC%)
+ case 39:
+ return 23; // Hydrogen on nitrogen in pyrrole (HPYL)
+ case 8:
+ return 23; // Generic hydrogen on sp3 nitrogen, e.g., in amines, Hydrogen on nitrogen in ammonia (HNR, H3N)
+ }
+
+ if (nbr->BOSum() == 4) {
+ if (nbr->GetValence() == 2) {
+ return 28; // Hydrogen on N triply bonded to C (HNC%)
+ } else {
+ return 36; // Hydrogen on pyridinium nitrogen, Hydrogen on protonated imine nitrogen (HPD+, HNC+)
+ }
+ }
+
+ if (nbr->GetValence() == 2) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen())
+ continue;
+
+ bond = mol -> GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbr->IsCarbon() || nbrNbr->IsNitrogen()) {
+ return 27; // Hydrogen on imine nitrogen, Hydrogen on azo nitrogen (HN=C, HN=N)
+ }
+
+ return 28; // Generic hydrogen on sp2 nitrogen (HSP2)
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen())
+ continue;
+
+ if (nbrNbr->IsCarbon()) {
+ if (nbrNbr->IsAromatic()) {
+ return 28; // deloc. lp pair
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = mol -> GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen() || nbrNbrNbr->IsOxygen() || nbrNbrNbr->IsSulfur()) {
+ return 28; // Hydrogen on amide nitrogen, Hydrogen on thioamide nitrogen,
+ // Hydrogen on enamine nitrogen, Hydrogen in H-N-C=N moiety (HNCO, HNCS, HNCC, HNCN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = mol -> GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen()) {
+ return 28; // Hydrogen in H-N-N=C moiety, Hydrogen in H-N-N=N moiety (HNNC, HNNN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsSulfur()) {
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ if (nbrNbrNbr->IsOxygen() || (nbrNbrNbr->GetValence() == 1)) {
+ return 28; // Hydrogen on NSO, NSO2 or NSO3 nitrogen (HNSO)
+ }
+ }
+ }
+ }
+
+ return 23; // Generic hydrogen on sp3 nitrogen e.g., in amines,
+ // Hydrogen on nitrogen in pyrrole, Hydrogen in ammonia,
+ // Hydrogen on N in N-oxide (HNR, HPYL, H3N, HNOX)
+ }
+ if (nbr->IsSulfur() || nbr->IsPhosphorus()) {
+ return 71; // Hydrogen attached to sulfur, Hydrogen attached to >S= sulfur doubly bonded to N,
+ // Hydrogen attached to phosphorus (HS, HS=N, HP)
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Lithium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 3) {
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 92; // Lithium cation (LI+)
+ }
+ }
+
+ ////////////////////////////////
+ // Carbon
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 6) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ if (atom->IsInRingSize(3)) {
+ return 22; // Aliphatic carbon in 3-membered ring (CR3R)
+ }
+
+ if (atom->IsInRingSize(4)) {
+ return 20; // Aliphatic carbon in 4-membered ring (CR4R)
+ }
+
+ return 1; // Alkyl carbon (CR)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ int N2count = 0;
+ int N3count = 0;
+ oxygenCount = sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+
+ if (nbr->GetValence() == 1) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ } else if (nbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ } else if (nbr->GetValence() == 3) {
+ if (nbr->IsNitrogen()) {
+ N3count++;
+ }
+ } else if ((nbr->GetValence() == 2) && bond->IsDouble()) {
+ if (nbr->IsNitrogen()) {
+ N2count++;
+ }
+ }
+ }
+ if ((N3count >= 2) && (doubleBondTo == 7) && !N2count) {
+ // N3==C--N3
+ return 57; // Guanidinium carbon, Carbon in +N=C-N: resonance structures (CGD+, CNN+)
+ }
+ if ((oxygenCount == 2) || (sulphurCount == 2)) {
+ // O1-?-C-?-O1 or S1-?-C-?-S1
+ return 41; // Carbon in carboxylate anion, Carbon in thiocarboxylate anion (CO2M, CS2M)
+ }
+ if (atom->IsInRingSize(4) && (doubleBondTo == 6)) {
+ return 30; // Olefinic carbon in 4-membered ring (CR4E)
+ }
+ if ((doubleBondTo == 7) || (doubleBondTo == 8) ||
+ (doubleBondTo == 15) || (doubleBondTo == 16)) {
+ // C==N, C==O, C==P, C==S
+ return 3; // Generic carbonyl carbon, Imine-type carbon, Guanidine carbon,
+ // Ketone or aldehyde carbonyl carbon, Amide carbonyl carbon,
+ // Carboxylic acid or ester carbonyl carbon, Carbamate carbonyl carbon,
+ // Carbonic acid or ester carbonyl carbon, Thioester carbonyl (double
+ // bonded to O or S), Thioamide carbon (double bonded to S), Carbon
+ // in >C=SO2, Sulfinyl carbon in >C=S=O, Thiocarboxylic acid or ester
+ // carbon, Carbon doubly bonded to P (C=O, C=N, CGD, C=OR, C=ON, COO,
+ // COON, COOO, C=OS, C=S, C=SN, CSO2, CS=O, CSS, C=P)
+ }
+
+ return 2; // Vinylic Carbon, Generic sp2 carbon (C=C, CSP2)
+
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ return 4; // Acetylenic carbon, Allenic caron (CSP, =C=)
+ }
+ // 1 neighbours
+ if (atom->GetValence() == 1) {
+ return 60; // Isonitrile carbon (C%-)
+ }
+ }
+
+ ////////////////////////////////
+ // Nitrogen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 7) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 68; // sp3-hybridized N-oxide nitrogen (N3OX)
+ }
+ }
+
+ return 34; // Quaternary nitrogen (NR+)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ if (atom->BOSum() == 4) {
+ oxygenCount = nitrogenCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ if (nbr->IsNitrogen()) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = 7;
+ }
+ }
+ if (nbr->IsCarbon()) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 3)) {
+ nitrogenCount++;
+ }
+ }
+ }
+ }
+ }
+
+ if (oxygenCount == 1) {
+ return 67; // sp2-hybridized N-oxide nitrogen (N2OX)
+ }
+ if (oxygenCount >= 2) {
+ return 45; // Nitrogen in nitro group, Nitrogen in nitrate group (NO2, NO3)
+ }
+
+ if (nitrogenCount == 1) {
+ return 54; // Iminium nitrogen (N+=C)
+ }
+ if (nitrogenCount == 2) {
+ return 55; // Either nitrogen in N+=C-N: (NCN+)
+ }
+ if (nitrogenCount == 3) {
+ return 56; // Guanidinium nitrogen (NGD+)
+ }
+
+ if (doubleBondTo == 7) {
+ return 54; // Positivly charged nitrogen doubly bonded to nitrogen (N+=N)
+ }
+ }
+
+ if (atom->BOSum() == 3) {
+ bool IsAmide = false;
+ bool IsSulfonAmide = false;
+ bool IsNNNorNNC = false;
+ int tripleBondTo = 0;
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur() || nbr->IsPhosphorus()) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount >= 2) {
+ IsSulfonAmide = true;
+ //return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = mol -> GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble() && (nbrNbr->IsOxygen() || nbrNbr->IsSulfur())) {
+ IsAmide = true;
+ //return 10; // Amide nitrogen, Thioamide nitrogen (NC=O, NC=S)
+ }
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ int N2count = 0;
+ int N3count = 0;
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = mol -> GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbrNbr->GetAtomicNum();
+ }
+ if (bond->IsAromatic()) {
+ if ((nbrNbr->GetAtomicNum() == 7) || (nbrNbr->GetAtomicNum() == 6)) {
+ doubleBondTo = nbrNbr->GetAtomicNum();
+ }
+ }
+ if (bond->IsTriple()) {
+ tripleBondTo = nbrNbr->GetAtomicNum();
+ }
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 3)) {
+ int nbrOxygen = 0;
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->IsOxygen()) {
+ nbrOxygen++;
+ }
+ }
+ if (nbrOxygen < 2) {
+ N3count++;
+ }
+ }
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 2) && (bond->IsDouble() || bond->IsAromatic())) {
+ N2count++;
+ }
+ if (nbrNbr->IsAromatic()) {
+ if (nbrNbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ if (nbrNbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ }
+ }
+ if (N3count == 3) {
+ return 56; // Guanidinium nitrogen (NGD+)
+ }
+
+ if (!IsAmide && !IsSulfonAmide && !oxygenCount && !sulphurCount && nbr->IsAromatic()) {
+ return 40;
+ }
+
+ if ((N3count == 2) && (doubleBondTo == 7) && !N2count) {
+ return 55; // Either nitrogen in N+=C-N: (NCN+)
+ }
+ }
+
+ if (nbr->IsNitrogen()) {
+ nitrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = mol -> GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbr->IsCarbon()) {
+ oxygenCount = sulphurCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ if (nbrNbrNbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ if (nbrNbrNbr->IsSulfur()) {
+ nitrogenCount++;
+ }
+ }
+ if (!oxygenCount && !sulphurCount && (nitrogenCount == 1)) {
+ bool bondToAromC = false;
+ FOR_NBORS_OF_ATOM (nbr2, atom) {
+ if (nbr2->IsAromatic() && nbr2->IsCarbon() && nbr2->IsInRingSize(6)) {
+ bondToAromC = true;
+ }
+ }
+ if (!bondToAromC) {
+ IsNNNorNNC = true;
+ }
+ }
+ }
+ if (nbrNbr->IsNitrogen()) {
+ bool bondToAromC = false;
+ FOR_NBORS_OF_ATOM (nbr2, atom) {
+ if (nbr2->IsAromatic() && nbr2->IsCarbon() && nbr2->IsInRingSize(6)) {
+ bondToAromC = true;
+ }
+ }
+ if (!bondToAromC) {
+ IsNNNorNNC = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (IsSulfonAmide) {
+ return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ if (IsAmide) {
+ return 10; // Amide nitrogen, Thioamide nitrogen (NC=O, NC=S)
+ }
+
+ if ((doubleBondTo == 6) || (doubleBondTo == 7) ||(doubleBondTo == 15) || (tripleBondTo == 6)) {
+ return 40; // Enamine or aniline nitrogen (deloc. lp), Nitrogen in N-C=N with deloc. lp,
+ // Nitrogen in N-C=N with deloc. lp, Nitrogen attached to C-C triple bond
+ // (NC=C, NC=N, NC=P, NC%C)
+ }
+ if (tripleBondTo == 7) {
+ return 43; // Nitrogen attached to cyano group (NC%N)
+ }
+ if (IsNNNorNNC) {
+ return 10; // Nitrogen in N-N=C moiety with deloc. lp
+ // Nitrogen in N-N=N moiety with deloc. lp (NN=C, NN=N)
+ }
+
+ return 8; // Amine nitrogen (NR)
+ }
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ if (atom->BOSum() == 4) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsTriple()) {
+ return 61; // Isonitrile nitrogen (NR%)
+ }
+ }
+
+ return 53; // Central nitrogen in C=N=N or N=N=N (=N=)
+ }
+
+ if (atom->BOSum() == 3) {
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (nbr->IsOxygen() && bond->IsDouble() && (nbr->GetValence() == 1)) {
+ return 46; // Nitrogen in nitroso group (N=O)
+ }
+ if ((nbr->IsCarbon() || nbr->IsNitrogen()) && bond->IsDouble()) {
+ return 9; // Iminie nitrogen, Azo-group nitrogen (N=C, N=N)
+ }
+ }
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur()) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount >= 2) {
+ return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ }
+ }
+ }
+
+ if (atom->BOSum() == 2) {
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount == 1) {
+ return 48; // Divalent nitrogen replacing monovalent O in SO2 group (NSO)
+ }
+ }
+ }
+
+ return 62; // Anionic divalent nitrogen (NM)
+ }
+ }
+ // 1 neighbours
+ if (atom->GetValence() == 1) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsTriple()) {
+ return 42; // Triply bonded nitrogen (NSP)
+ }
+ if (nbr->IsNitrogen() && (nbr->GetValence() == 2)) {
+ return 47; // Terminal nitrogen in azido or diazo group (NAZT)
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Oxygen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 8) {
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ return 49; // Oxonium oxygen (O+)
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ int hydrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsHydrogen()) {
+ hydrogenCount++;
+ }
+ }
+
+ if (hydrogenCount == 2) {
+ // H--O--H
+ return 70; // Oxygen in water (OH2)
+ }
+ if (atom->BOSum() == 3) {
+ return 51; // Oxenium oxygen (O=+)
+ }
+
+ return 6; // Generic divalent oxygen, Ether oxygen, Carboxylic acid or ester oxygen,
+ // Enolic or phenolic oxygen, Oxygen in -O-C=N- moiety, Divalent oxygen in
+ // thioacid or ester, Divalent nitrate "ether" oxygen, Divalent oxygen in
+ // sulfate group, Divalent oxygen in sulfite group, One of two divalent
+ // oxygens attached to sulfur, Divalent oxygen in R(RO)S=O, Other divalent
+ // oxygen attached to sulfur, Divalent oxygen in phosphate group, Divalent
+ // oxygen in phosphite group, Divalent oxygen (one of two oxygens attached
+ // to P), Other divalent oxygen (-O-, OR, OC=O, OC=C, OC=N, OC=S, ONO2,
+ // ON=O, OSO3, OSO2, OSO, OS=O, -OS, OPO3, OPO2, OPO, -OP)
+
+ // 59 ar
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+
+ if (nbr->IsCarbon() || nbr->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ if (nbrNbr->IsSulfur() && (nbrNbr->GetValence() == 1)) {
+ sulphurCount++;
+ }
+ }
+ }
+ // O---H
+ if (nbr->IsHydrogen()) {
+ return 35;
+ }
+ // O-?-C
+ if (nbr->IsCarbon()) {
+ if (oxygenCount == 2) {
+ // O-?-C-?-O
+ return 32; // Oxygen in carboxylate group (O2CM)
+ }
+ if (bond->IsSingle()) {
+ // O--C
+ return 35; // Oxide oxygen on sp3 carbon, Oxide oxygen on sp2 carbon (OM, OM2)
+ } else {
+ // O==C
+ return 7; // Generic carbonyl oxygen, Carbonyl oxygen in amides,
+ // Carbonyl oxygen in aldehydes and ketones, Carbonyl
+ // oxygen in acids or esters (O=C, O=CN, O=CR, O=CO)
+ }
+ }
+ // O-?-N
+ if (nbr->IsNitrogen()) {
+ if (oxygenCount >= 2) {
+ // O-?-N-?-O
+ return 32; // Oxygen in nitro group, Nitro-group oxygen in nitrate,
+ // Nitrate anion oxygen (O2N, O2NO, O3N)
+ }
+ if (bond->IsSingle()) {
+ // O--N
+ return 32; // Oxygen in N-oxides (ONX)
+ } else {
+ // O==N
+ return 7; // Nitroso oxygen (O=N)
+ }
+ }
+ // O-?-S
+ if (nbr->IsSulfur()) {
+ if (sulphurCount == 1) {
+ // O1-?-S-?-S1
+ return 32; // Terminal oxygen in thiosulfinate anion (OSMS)
+ }
+ if (bond->IsSingle()) {
+ // O--S
+ return 32; // Single terminal oxygen on sulfur, One of 2 terminal O's on sulfur,
+ // One of 3 terminal O's on sulfur, Terminal O in sulfate anion,
+ // (O-S, O2S, O3S, O4S)
+ } else {
+ // O==S
+ return 7; // Doubly bonded sulfoxide oxygen, O=S on sulfur doubly bonded
+ // to, e.g., C (O=S, O=S=)
+ }
+ }
+
+ return 32; // Oxygen in phosphine oxide, One of 2 terminal O's on sulfur,
+ // One of 3 terminal O's on sulfur, One of 4 terminal O's on sulfur,
+ // Oxygen in perchlorate anion (OP, O2P, O3P, O4P, O4Cl)
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Flourine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 9) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 11; // Fluorine (F)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 89; // Fluoride anion (F-)
+ }
+ }
+
+ ////////////////////////////////
+ // Sodium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 11) {
+ return 93; // Sodium cation (NA+)
+ }
+
+ ////////////////////////////////
+ // Magnesium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 12) {
+ return 99; // Dipositive magnesium cation (MG+2)
+ }
+
+ ////////////////////////////////
+ // Silicon
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 14) {
+ return 19; // Silicon (SI)
+ }
+
+ ////////////////////////////////
+ // Phosphorus
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 15) {
+ if (atom->GetValence() == 4) {
+ return 25; // Phosphate group phosphorus, Phosphorus with 3 attached oxygens,
+ // Phosphorus with 2 attached oxygens, Phosphine oxide phosphorus,
+ // General tetracoordinate phosphorus (PO4, PO3, PO2, PO, PTET)
+ }
+ if (atom->GetValence() == 3) {
+ return 26; // Phosphorus in phosphines (P)
+ }
+ if (atom->GetValence() == 2) {
+ return 75; // Phosphorus doubly bonded to C (-P=C)
+ }
+ }
+
+ ////////////////////////////////
+ // Sulfur
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 16) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ return 18; // Sulfone sulfur, Sulfonamide sulfur, Sulfonate group sulfur,
+ // Sulfate group sulfur, Sulfur in nitrogen analog of sulfone
+ // (SO2, SO2N, SO3, SO4, SNO)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ oxygenCount = sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+
+ if (nbr->GetValence() == 1) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ } else if (nbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ }
+ }
+
+ if (oxygenCount == 2) {
+ if (doubleBondTo == 6) {
+ return 18; // Sulfone sulfur, doubly bonded to carbon (=SO2)
+ }
+ return 73; // Sulfur in anionic sulfinate group (SO2M)
+ }
+ if (oxygenCount && sulphurCount)
+ return 73; // Tricoordinate sulfur in anionic thiosulfinate group (SSOM)
+
+ //if ((doubleBondTo == 6) || (doubleBondTo == 8))
+ return 17; // Sulfur doubly bonded to carbon, Sulfoxide sulfur (S=C, S=O)
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen()) {
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = 8;
+ }
+ }
+ }
+
+ if (doubleBondTo == 8)
+ return 74; // Sulfinyl sulfur, e.g., in C=S=O (=S=O)
+
+ return 15; // Thiol, sulfide, or disulfide sulfor (S)
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsSulfur() && (nbrNbr->GetValence() == 1)) {
+ sulphurCount++;
+ }
+ }
+ bond = mol -> GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+ }
+
+ if ((doubleBondTo == 6) && (sulphurCount != 2)) {
+ return 16; // Sulfur doubly bonded to carbon (S=C)
+ }
+
+ return 72; // Terminal sulfur bonded to P, Anionic terminal sulfur,
+ // Terminal sulfur in thiosulfinate group (S-P, SM, SSMO)
+ }
+
+ // 44 ar
+ }
+
+ ////////////////////////////////
+ // Clorine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 17) {
+ // 4 neighbour
+ if (atom->GetValence() == 4) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount == 4)
+ return 77; // Perchlorate anion chlorine (CLO4)
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 12; // Chlorine (CL)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 90; // Chloride anion (CL-)
+ }
+ }
+
+ ////////////////////////////////
+ // Potasium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 19) {
+ return 94; // Potasium cation (K+)
+ }
+
+ ////////////////////////////////
+ // Calcium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 20) {
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 96; // Dipositive calcium cation (CA+2)
+ }
+ }
+
+ ////////////////////////////////
+ // Iron
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 26) {
+ return 87; // Dipositive iron (FE+2)
+ return 88; // Tripositive iron (FE+3)
+ }
+
+ ////////////////////////////////
+ // Copper
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 29) {
+ return 97; // Monopositive copper cation (CU+1)
+ return 98; // Dipositive copper cation (CU+2)
+ }
+
+ ////////////////////////////////
+ // Zinc
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 30) {
+ return 95; // Dipositive zinc cation (ZN+2)
+ }
+
+ ////////////////////////////////
+ // Bromine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 35) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 13; // Bromine (BR)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 91; // Bromide anion (BR-)
+ }
+ }
+
+ ////////////////////////////////
+ // Iodine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 53) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 14; // Iodine (I)
+ }
+ }
+
+
+
+ return 0;
+}
+
+
+bool IsInSameRing(Atom* a, Atom* b) {
+ ZNMolecule *mol = (ZNMolecule *) a -> GetParent ();
+ bool a_in, b_in;
+ vector<OBRing*> vr;
+ vr = mol -> GetSSSR();
+
+ vector<OBRing*>::iterator i;
+ vector<int>::iterator j;
+
+ for (i = vr.begin();i != vr.end();i++) {
+ a_in = false;
+ b_in = false;
+ for(j = (*i)->_path.begin();j != (*i)->_path.end();j++) {
+ if ((unsigned)(*j) == a->GetIdx())
+ a_in = true;
+ if ((unsigned)(*j) == b->GetIdx())
+ b_in = true;
+ }
+
+ if (a_in && b_in)
+ return true;
+ }
+
+ return false;
+};
+
+
+void set_backbone_style (Atom *at, int n) {
+ ZNMolecule *mol = (ZNMolecule *) at ->GetParent ();
+ set_backbone_display_style (mol, n);
+}
+
+
+int get_ds (Atom *at) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ int out = d -> get_display_style ();
+ if (out == -1) {
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+ return get_atoms_display_style (mol);
+ }
+ else return out;
+}
+
+
+void set_ds (Atom *at, int ds) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_display_style (ds);
+}
+
+
+int get_ds (ZNBond *b) {
+ BondDisplayData *d = (BondDisplayData *) b -> GetData (BOND_DISPLAY_DATA_INDEX);
+ assert (d);
+ int out = d -> get_display_style ();
+ if (out == -1) {
+ ZNMolecule *mol = (ZNMolecule *) b -> GetParent ();
+ return get_bonds_display_style (mol);
+ }
+ else return out;
+}
+
+bool get_needs_redraw (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return (d -> get_needs_redraw ()|| mol->selection); //forces redraw of selections for pulsing
+}
+
+bool get_needs_backbone_redraw (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return (d -> get_needs_backbone_redraw ());
+}
+
+void set_needs_backbone_redraw (ZNMolecule *mol, bool b) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_needs_backbone_redraw (b);
+}
+
+void set_needs_redraw (ZNMolecule *mol, bool b) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_needs_redraw (b);
+ if (b) d ->set_needs_backbone_redraw(b);
+}
+
+bool get_clippable (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_clippable ();
+}
+
+void set_clippable (ZNMolecule *mol, bool cl) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_clippable (cl);
+}
+
+
+int get_atoms_display_style (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_atoms_display_style ();
+}
+int get_bonds_display_style (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_bonds_display_style ();
+}
+int get_backbone_display_style (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_backbone_display_style ();
+}
+
+void set_atoms_display_style (ZNMolecule *mol, int i) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_atoms_display_style (i);
+}
+void set_bonds_display_style (ZNMolecule *mol, int i) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_bonds_display_style (i);
+}
+void set_backbone_display_style (ZNMolecule *mol, int i) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_backbone_display_style (i);
+}
+
+void set_ds (ZNBond *b, int ds) {
+ BondDisplayData *d = (BondDisplayData *) b -> GetData (BOND_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_display_style (ds);
+}
+
+
+bool get_selected (Atom *at) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_selected ();
+}
+
+
+void set_selected (Atom *at, bool s) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_selected (s);
+}
+
+
+bool get_selected (ZNBond *b) {
+ bool s1 = get_selected (b -> GetBeginAtom ());
+ bool s2 = get_selected (b -> GetEndAtom ());
+ return (s1 && s2);
+}
+
+
+void set_selected (ZNBond *b, bool s) {
+ set_selected (b -> GetBeginAtom (), s);
+ set_selected (b -> GetEndAtom (), s);
+}
+
+
+
+
+double get_score (Atom *at) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ return d -> get_score_value ();
+}
+
+void set_score (Atom *at, double dd) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ d -> set_score_value (dd);
+}
+
+
+double get_back_score (Atom *at) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ return d -> get_back_score_value ();
+}
+
+void set_back_score (Atom *at, double dd) {
+ MinimisationData *d = (MinimisationData *) at -> GetData (MINIMISATION_DATA_INDEX);
+ assert (d);
+ d -> set_back_score_value (dd);
+}
+
+
+
+bool get_kinematic_chain_visited (Atom *at) {
+ AtomicFragmentData *d = (AtomicFragmentData *) at -> GetData (ATOMIC_FRAGMENT_DATA_INDEX);
+ assert (d);
+ return d -> get_kinematic_chain_visited ();
+}
+
+Fragment *get_fragment (Atom *at) {
+ AtomicFragmentData *d = (AtomicFragmentData *) at -> GetData (ATOMIC_FRAGMENT_DATA_INDEX);
+ assert (d);
+ return d -> get_fragment ();
+}
+
+void set_kinematic_chain_visited (Atom *at, bool ksv) {
+ AtomicFragmentData *d = (AtomicFragmentData *) at -> GetData (ATOMIC_FRAGMENT_DATA_INDEX);
+ assert (d);
+ d -> set_kinematic_chain_visited (ksv);
+}
+
+void set_fragment (Atom *at, Fragment *frag) {
+ AtomicFragmentData *d = (AtomicFragmentData *) at -> GetData (ATOMIC_FRAGMENT_DATA_INDEX);
+ assert (d);
+ d -> set_fragment (frag);
+}
+
+
+int CountBonds (Atom *at) {
+ int count = 0;
+ OBBond *bond;
+ OBBondIterator i;
+ for (bond = at -> BeginBond(i);bond;bond = at -> NextBond(i))
+ count++;
+
+ return(count);
+}
+
+
+int get_line_list (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_line_list ();
+};
+
+int get_backbone_list1 (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_backbone_list1 ();
+};
+
+int get_backbone_list2 (ZNMolecule *mol) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_backbone_list2 ();
+};
+
+int get_stick_list (ZNMolecule *mol){
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d -> get_stick_list ();
+};
+
+void set_display_lists (ZNMolecule *mol, int ll, int bl1, int bl2, int sl) {
+ MolecularDisplayData *d = (MolecularDisplayData *) mol -> GetData (MOLECULAR_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_line_list (ll);
+ d -> set_backbone_list1 (bl1);
+ d -> set_backbone_list2 (bl2);
+ d -> set_stick_list (sl);
+}
+
+void rotate_molecule (ZNMolecule *mol, quaternion q, vect center) {
+ FOR_ATOMS_OF_MOL(a, mol) {
+ rotate_atom (&*a, q, center);
+ }
+}
+
+
+void rotate_atom (Atom *at, quaternion q, vect center) {
+ vect v = get_coordinates (at);
+ v = subtract (v, center);
+ v = rotate_vector_using_quaternion (v, q);
+ v = sum (v, center);
+ set_coordinates (at, v);
+}
+
+void translate_molecule (ZNMolecule *mol, vect v) {
+ FOR_ATOMS_OF_MOL(a, mol) {
+ sum_to_coordinates(&*a, v);
+ }
+ vect c = get_center (mol);
+ set_center (mol, sum (c, v));
+}
+
+
+ZNMolecule *sum (ZNMolecule *mol1, ZNMolecule *mol2) {
+ ZNMolecule *mol3 = new ZNMolecule (*mol1);
+ *mol3 += *mol2;
+ return mol3;
+}
+
+ZNMolecule::ZNMolecule () : OBMol () {
+ multi = false;
+ selection = false;
+}
+
+
+ZNMolecule::ZNMolecule (const ZNMolecule &mol)
+//: OBMol( *(OBMol::OBMol *)&mol )
+: OBMol( mol )
+{
+ // OBMol::OBMol (*this);
+ // (*(OBMol::OBMol *)this)(mol);
+ multi = false;
+ selection = false;
+ ZNinit ();
+}
+
+ZNMolecule &ZNMolecule::operator =(const ZNMolecule &mol)
+{
+ OBMol::operator =(mol);
+
+ multi = false;
+ selection = false;
+ ZNinit ();
+ return *this;
+}
+
+ZNMolecule &ZNMolecule::operator +=(const ZNMolecule &mol)
+{
+ OBMol::operator +=(mol);
+
+ multi = false;
+ selection = false;
+ ZNinit ();
+ return *this;
+}
+
+
+
+
+bool get_sad (Atom *at) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ return d ->get_sad ();
+}
+
+
+void set_sad (Atom *at, bool s) {
+ AtomicDisplayData *d = (AtomicDisplayData *) at -> GetData (ATOMIC_DISPLAY_DATA_INDEX);
+ assert (d);
+ d -> set_sad (s);
+}
+
+
+MinimisationData::MinimisationData () : OBGenericData ("force", MINIMISATION_DATA_INDEX) {
+ _force = vect (0., 0., 0.);
+ _back_force = vect (0., 0., 0.);
+ _score = 0.;
+ _back_score = 0.;
+}
+
+AtomicFragmentData::AtomicFragmentData () : OBGenericData ("fragment", ATOMIC_FRAGMENT_DATA_INDEX) {
+ _fragment = NULL;
+ _kinematic_chain_visited = false;
+}
+
+BackboneData::BackboneData () : OBGenericData ("backbone", BACKBONE_DATA_INDEX) {
+ ss = 2; //random (1 = alpha helix 2 = beta sheet)
+ backbone_dir = vect (1., 0., 0.);
+ col = color (1.f, 1.f, 1.f, 1.f);
+}
+
+MolecularFragmentData::MolecularFragmentData () : OBGenericData ("fragment", MOLECULAR_FRAGMENT_DATA_INDEX) {
+}
+
+GeometryData::GeometryData () : OBGenericData ("geometry", GEOMETRY_DATA_INDEX), lock (new QReadWriteLock) {
+ _fragments_perceived = false;
+ _backbone_perceived = false;
+}
+
+BondDisplayData::BondDisplayData () : OBGenericData ("display", BOND_DISPLAY_DATA_INDEX) {
+ _display_style = -1;
+}
+
+AtomicDisplayData::AtomicDisplayData () : OBGenericData ("display", ATOMIC_DISPLAY_DATA_INDEX)
+{
+ _visible = true;
+ _selected = false;
+ _sphere_already_drawn = false;
+ _display_style = -1;
+}
+
+MolecularDisplayData::MolecularDisplayData () : OBGenericData ("display", MOLECULAR_DISPLAY_DATA_INDEX)
+{
+ _atom_display_style = 0;
+ _bond_display_style = 1;
+ _backbone_display_style = 0;
+ _clippable = false;
+}
+
+
+
+void find_center (ZNMolecule *mol) {
+ int n = 0;
+ double x, y, z;
+ x = 0.;
+ y = 0.;
+ z = 0.;
+
+ FOR_ATOMS_OF_MOL (a, mol) {
+ vect coor = get_coordinates (&*a);
+
+ n++;
+ x += coor. x ();
+ y += coor. y ();
+ z += coor. z ();
+ }
+ x /= n;
+ y /= n;
+ z /= n;
+
+ set_center (mol, vect (x, y, z));
+}
+
+
+void find_limits (ZNMolecule *mol) {
+ double xm, ym, zm, xM, yM, zM;
+ xm = ym = zm = 99999999;
+ xM = yM = zM = -99999999;
+ double xt=0., yt=0., zt=0.;
+ FOR_ATOMS_OF_MOL (a, mol) {
+
+ vect coor = get_coordinates (&*a);
+ xt = coor.x();
+ yt = coor.y();
+ zt = coor.z();
+ if (xt < xm) xm = xt;
+ if (xt > xM) xM = xt;
+ if (yt < ym) ym = yt;
+ if (yt > yM) yM = yt;
+ if (zt < zm) zm = zt;
+ if (zt > zM) zM = zt;
+ }
+ if ((xm > xM || ym > yM || zm > zM) && mol ->NumAtoms ()) cerr << "error in calculating limits" <<endl;
+ set_min_corner (mol, vect (xm, ym, zm));
+ set_max_corner (mol, vect (xM, yM, zM));
+
+}
+
+void ZNMolecule::ZNinit_bond (ZNBond *b) {
+ if (!b -> HasData ("display")) {
+ BondDisplayData *display_data = new BondDisplayData;
+ display_data -> SetAttribute ("display");
+ b ->SetData (display_data);
+ }
+}
+
+void ZNMolecule::ZNinit_residue (Resid *r) {
+ if (!r -> HasData ("backbone")) {
+ BackboneData *backbone_data = new BackboneData;
+ backbone_data -> SetAttribute ("backbone");
+ r ->SetData (backbone_data);
+ }
+}
+
+void ZNMolecule::ZNinit_atom (Atom *a) {
+
+ if (!a -> HasData ("display")) {
+ AtomicDisplayData *display_data = new AtomicDisplayData;
+ display_data -> SetAttribute ("display");
+ a ->SetData (display_data);
+ }
+ if (!a -> HasData ("minimisation")) {
+ MinimisationData *force_data = new MinimisationData;
+ force_data -> SetAttribute ("minimisation");
+ a ->SetData (force_data);
+ }
+
+ if (!a -> HasData ("fragment")) {
+ AtomicFragmentData *fragment_data = new AtomicFragmentData;
+ fragment_data -> SetAttribute ("fragment");
+ a ->SetData (fragment_data);
+ }
+
+ /* if (!a -> HasData ("force_mutex")) {
+ MutexData *mut = new MutexData;
+ QMutex *mutex = new QMutex;
+ mut -> SetValue (mutex);
+ mut -> SetAttribute ("force_mutex");
+ a -> SetData (mut);
+ }*/
+
+ set_color_mw (&*a) ;
+
+
+ // a -> displayStyle = 0;
+ // stringstream ss;
+ // ss <<(GetEnergy ());
+ // cerr <<ss.str ()<<endl;
+ // double d = 0.000003;
+ // cerr << "d "<<d;
+
+ // a -> vdw = etab.GetVdwRad (a -> GetAtomicNum ());
+ // cerr << a->vdw;
+ // a -> col = a -> get_color_mw () ;
+}
+
+
+
+void ZNMolecule::ZNinit () {
+ needs_recolor = false;
+ //cerr << HasNonZeroCoords () << endl;
+
+ if (!HasData ("fragment")) {
+ MolecularFragmentData *fragment_data = new MolecularFragmentData;
+ fragment_data -> SetAttribute ("fragment");
+ SetData (fragment_data);
+ }
+ if (!HasData ("geometry")) {
+ GeometryData *geometry_data = new GeometryData;
+ geometry_data -> SetAttribute ("geometry");
+ SetData (geometry_data);
+ }
+ if (!HasData ("display")) {
+ MolecularDisplayData *display_data = new MolecularDisplayData;
+ display_data -> SetAttribute ("display");
+ SetData (display_data);
+ }
+
+
+ if (!HasNonZeroCoords ()) mend_coordinates (this);
+
+ FOR_ATOMS_OF_MOL (a, this) {
+ ZNinit_atom (&*a);
+ }
+ FOR_BONDS_OF_MOL (b, this) {
+
+ ZNinit_bond (&*b);
+ }
+ FOR_RESIDUES_OF_MOL (r, this) {
+ ZNinit_residue (&*r);
+ }
+ find_limits(this);
+}
+
+ZNBond * ZNMolecule::ZNAddBond (ZNBond *bond) {
+ int first = bond -> GetBeginAtomIdx();
+ int second = bond -> GetEndAtomIdx();
+ int order = bond -> GetBO();
+ int flags = bond -> GetFlags();
+ int insertpos = -1;
+
+
+
+
+ if (first == second)
+ return(NULL);
+
+ // BeginModify();
+
+ if ((unsigned)first <= NumAtoms() && (unsigned)second <= NumAtoms()
+ && !GetBond(first, second))
+ //atoms exist and bond doesn't
+ {
+ if (!bond)
+ {
+ EndModify();
+ return(NULL);
+ }
+
+ OBAtom *bgn,*end;
+ bgn = GetAtom(first);
+ end = GetAtom(second);
+ if (!bgn || !end)
+ {
+ obErrorLog.ThrowError(__FUNCTION__, "Unable to add bond - invalid atom index", obDebug);
+ return(NULL);
+ }
+ bond->Set(_nbonds,bgn,end,order,flags);
+ bond->SetParent(this);
+
+ //set aromatic flags if it has the appropriate order
+ if (order == 5)
+ {
+ bond->SetAromatic();
+ bgn->SetAromatic();
+ end->SetAromatic();
+ }
+
+#define OBBondIncrement 100
+ if (_vbond.empty() || _nbonds+1 >= _vbond.size())
+ {
+ _vbond.resize(_nbonds+OBBondIncrement);
+ vector<OBBond*>::iterator i;
+ for (i = _vbond.begin(),i+=(_nbonds+1);i != _vbond.end();++i)
+ *i = (OBBond*)NULL;
+ }
+#undef OBBondIncrement
+
+ _vbond[_nbonds] = (OBBond*)bond;
+ _nbonds++;
+
+ if (insertpos == -1)
+ {
+ bgn->AddBond(bond);
+ end->AddBond(bond);
+ }
+ else
+ {
+ if (insertpos >= static_cast<int>(bgn->GetValence()))
+ bgn->AddBond(bond);
+ else //need to insert the bond for the connectivity order to be preserved
+ { //otherwise stereochemistry gets screwed up
+ vector<OBBond*>::iterator bi;
+ bgn->BeginNbrAtom(bi);
+ bi += insertpos;
+ bgn->InsertBond(bi,bond);
+ }
+ end->AddBond(bond);
+ }
+ }
+ else //at least one atom doesn't exist yet - add to bond_q
+ SetData(new OBVirtualBond(first,second,order,flags));
+
+ // EndModify();
+ return(bond);
+
+}
+void ZNMolecule::ZNSetConformers () {
+ int n = NumConformers ();
+ if (n) {
+ cerr << "ZNSetConformers" << endl;
+ //clear out the multiconformer data
+ vector<double*>::iterator k;
+ for (k = _vconf.begin();k != _vconf.end();++k)
+ delete [] *k;
+ _vconf.clear();
+ }
+
+
+
+ AddConformer (_c);
+}
+
+bool ZNMolecule::ZNAddHydrogens(Atom *atom)
+{
+
+ OBAtom *h;
+
+ //count up number of hydrogens to add
+ int hcount,count=0;
+ vector<pair<OBAtom*,int> > vhadd;
+ // cerr << "2" << endl;
+ hcount = atom->GetImplicitValence() - atom->GetValence();
+
+ //Jan 05 Implicit valency now left alone; use spin multiplicity for implicit Hs
+ int mult = atom->GetSpinMultiplicity();
+ // cerr << "3" << endl;
+ if(mult==2) //radical
+ hcount-=1;
+ else if(mult==1 || mult==3) //carbene
+ hcount-=2;
+
+ if (hcount < 0)
+ hcount = 0;
+ if (hcount)
+ {
+ vhadd.push_back(pair<OBAtom*,int>(atom,hcount));
+ count += hcount;
+ }
+
+ if (count == 0)
+ return(true);
+ // cerr << "4" << endl;
+
+ /* //realloc memory in coordinate arrays for new hydroges
+ double *tmpf;
+ vector<double*>::iterator j;
+ for (j = _vconf.begin();j != _vconf.end();++j)
+ {
+ cerr << "ok "<< endl;
+ tmpf = new double [(NumAtoms()+count)*3+10];
+ cerr << *j << endl;
+ memcpy(tmpf,(*j),sizeof(double)*NumAtoms()*3);
+ cerr << "ok "<< endl;
+ delete []*j;
+ cerr << "ok "<< endl;
+ *j = tmpf;
+ cerr << "ok "<< endl;
+ }
+ */
+ IncrementMod();
+ // cerr << "5" << endl;
+ int m,n=0;
+ vector3 v;
+ vector<pair<OBAtom*,int> >::iterator k;
+ double hbrad = etab.CorrectedBondRad(1,0);
+
+ for (k = vhadd.begin();k != vhadd.end();++k)
+ {
+ // cerr << "ok" << endl;
+ atom = k->first;
+ double bondlen = hbrad+etab.CorrectedBondRad(atom->GetAtomicNum(),atom->GetHyb());
+ for (m = 0;m < k->second;++m)
+
+ {
+ // cerr << "ok1" << endl;
+ // for (n = 0;n < NumConformers();++n)
+
+
+ // {
+ // cerr << "ok2" << endl;
+ SetConformer(n);
+ // cerr <<"vx"<< endl;
+ atom->GetNewBondVector(v,bondlen);
+
+ // _c[(NumAtoms())*3] = v.x();
+ // _c[(NumAtoms())*3+1] = v.y();
+ // _c[(NumAtoms())*3+2] = v.z();
+ // cerr << v.x ()<< "vx";
+ // }
+ h = NewAtom();
+ h->SetType("H");
+ h->SetAtomicNum(1);
+ AddBond(atom->GetIdx(),h->GetIdx(),1);
+ h->SetVector(v);
+ }
+ }
+
+ DecrementMod();
+ SetConformer(0);
+
+ //reset atom type and partial charge flags
+ //_flags &= (~(OB_PCHARGE_MOL|OB_ATOMTYPES_MOL));
+
+ return(true);
+}
+
+
+Atom * ZNMolecule::ZNAddAtom (Atom *atom) {
+
+ // BeginModify();
+ ZNinit_atom (atom);
+ OBAtom *obatom = CreateAtom();
+ obatom = atom;
+ // cerr << "color" << obatom -> HasData ("color") << endl;
+ obatom->SetIdx(_natoms+1);
+ obatom->SetParent(this);
+
+
+#define OBAtomIncrement 100
+
+ if (_vatom.empty() || _natoms+1 >= _vatom.size())
+ {
+ _vatom.resize(_natoms+OBAtomIncrement);
+ vector<OBAtom*>::iterator j;
+ for (j = _vatom.begin(),j+=(_natoms+1);j != _vatom.end();++j)
+ *j = (OBAtom*)NULL;
+ }
+#undef OBAtomIncrement
+
+ _vatom[_natoms] = (OBAtom*)obatom;
+ _natoms++;
+ /*
+ if (HasData(OBGenericDataType::VirtualBondData))
+ {
+ add bonds that have been queued
+ OBVirtualBond *vb;
+ vector<OBGenericData*> verase;
+ vector<OBGenericData*>::iterator i;
+ for (i = BeginData();i != EndData();++i)
+ if ((*i)->GetDataType() == OBGenericDataType::VirtualBondData)
+ {
+ vb = (OBVirtualBond*)*i;
+ if (static_cast<unsigned int>(vb->GetBgn()) > _natoms ||
+ static_cast<unsigned int>(vb->GetEnd()) > _natoms)
+ continue;
+ if (obatom->GetIdx() == static_cast<unsigned int>(vb->GetBgn())
+ || obatom->GetIdx() == static_cast<unsigned int>(vb->GetEnd()))
+ {
+ AddBond(vb->GetBgn(),vb->GetEnd(),vb->GetOrder());
+ verase.push_back(*i);
+ }
+ }
+
+ if (!verase.empty())
+ DeleteData(verase);
+ }
+
+ // EndModify();
+
+ return(obatom);
+ */
+}
+
+
+
+int ZNMolecule::bonded_to (Atom *at, int bondtype, int atnumb) {
+ int out = 0;
+
+
+ if (bondtype!=5) {
+ FOR_NBORS_OF_ATOM (n, at) {
+ int an = n -> GetAtomicNum ();
+ if (an == atnumb || atnumb == -2) {
+ ZNBond *bond = at -> GetBond (&*n);
+ if (bond -> GetBO () == bondtype || bondtype == -2) {
+ out += 1;
+ }
+ }
+
+ }
+ }
+ return out;
+}
+
+
+
+bool ZNMolecule::RemoveAtom (Atom *atom) {
+ //// if (atom->IsHydrogen())
+ //// return(DeleteHydrogen(atom));
+
+ BeginModify();
+ //don't need to do anything with coordinates b/c
+ //BeginModify() blows away coordinates
+
+ //find bonds to delete
+ OBAtom *nbr;
+ vector<OBBond*> vdb;
+ vector<OBBond*>::iterator j;
+ for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j))
+ vdb.push_back(*j);
+
+ for (j = vdb.begin();j != vdb.end();++j)
+ RemoveBond((OBBond *)*j); //delete bonds
+
+ _vatom.erase(_vatom.begin()+(atom->GetIdx()-1));
+ _natoms--;
+
+ //reset all the indices to the atoms
+ int idx;
+ vector<OBAtom*>::iterator i;
+ OBAtom *atomi;
+ for (idx=1,atomi = BeginAtom(i);atomi;atomi = NextAtom(i),++idx)
+ atomi->SetIdx(idx);
+
+ EndModify();
+
+ // DestroyAtom(atom);
+
+ return(true);
+}
+/*
+ bool ZNMolecule::RemoveHydrogen (Atom *atom) {
+ //deletes the hydrogen atom passed to the function
+ if (!atom->IsHydrogen())
+ return false;
+
+ //find bonds to delete
+ OBAtom *nbr;
+ vector<OBBond*> vdb;
+ vector<OBBond*>::iterator j;
+ for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j))
+ vdb.push_back(*j);
+
+ IncrementMod();
+ for (j = vdb.begin();j != vdb.end();++j)
+ DeleteBond((OBBond*)*j); //delete bonds
+ DecrementMod();
+
+ int idx;
+ if (atom->GetIdx() != NumAtoms())
+ {
+ idx = atom->GetCIdx();
+ int size = NumAtoms()-atom->GetIdx();
+ vector<double*>::iterator k;
+ for (k = _vconf.begin();k != _vconf.end();++k)
+ memmove((char*)&(*k)[idx],(char*)&(*k)[idx+3],sizeof(double)*3*size);
+
+ }
+
+ _vatom.erase(_vatom.begin()+(atom->GetIdx()-1));
+ _natoms--;
+
+ //reset all the indices to the atoms
+ vector<OBAtom*>::iterator i;
+ OBAtom *atomi;
+ for (idx=1,atomi = BeginAtom(i);atomi;atomi = NextAtom(i),++idx)
+ atomi->SetIdx(idx);
+
+ UnsetHydrogensAdded();
+
+ // DestroyAtom(atom);
+ return(true);
+
+ }
+ */
+bool ZNMolecule::RemoveBond (ZNBond *bond) {
+ BeginModify();
+
+ (bond->GetBeginAtom())->DeleteBond(bond);
+ (bond->GetEndAtom())->DeleteBond(bond);
+ _vbond.erase(_vbond.begin() + bond->GetIdx()); // bond index starts at 0!!!
+ _nbonds--;
+
+ vector<OBBond*>::iterator i;
+ int j;
+ OBBond *bondi;
+ for (bondi = BeginBond(i),j=0;bondi;bondi = NextBond(i),++j)
+ bondi->SetIdx(j);
+
+ EndModify();
+
+ // DestroyBond(bond);
+
+ return(true);
+}
+
+
+
+color ZNMolecule::get_color_mw (Atom *at) {
+ //etable should have color data as well...
+ vector <double> colors;
+ colors = etab.GetRGB (at -> GetAtomicNum ());
+ /* if (at -> GetAtomicNum () == 6) {
+ colors [0] = 0.;
+ colors [1] = 0.;
+ colors [2] = 0.;
+ }*/
+ return color ((float) colors[0], (float)colors[1],(float) colors[2]);
+ /*
+ float r, g, b;
+ switch (at -> GetAtomicNumber) {
+ case 1: r=1.0f; g=1.0f; b=1.0f;
+ break;
+ case 6: r=0.f; g=0.f; b=0.f;
+
+ break;
+ case 7: r=0.0f; g=0.0f; b=1.0f;
+ break;
+ case 8: r=1.0f; g=0.0f; b=0.0f;
+ break;
+ case 15: r=0.f; g=1.0f; b=0.5f;
+ break;
+ case 16: r=1.0f; g=1.0f; b=0.0f;
+ break;
+
+ default: r=0.7f; g= 0.7f; b=0.7f;
+ }
+ return color (r, g, b);
+ */
+}
+
+int ZNMolecule::get_ds_from_neighbour (Atom *at)
+{
+ int out = 1;
+ Atom *n;
+ OBBondIterator i;
+ n = at -> BeginNbrAtom (i);
+ if (n) return get_ds (n);
+ return out;
+}
+
+
+int ZNMolecule::get_ds_from_neighbour (ZNBond *bo)
+{
+ int out = 1;
+ Atom *at = bo -> GetBeginAtom ();
+ FOR_BONDS_OF_ATOM (b, at) {
+ if (&*b != &*bo) return get_ds (&*b);
+ }
+ at = bo -> GetEndAtom ();
+ FOR_BONDS_OF_ATOM (b, at) {
+ if (&*b != &*bo) return get_ds (&*b);
+ }
+ return out;
+ return out;
+}
+
+
+void ZNMolecule::ZNAddHydrogens (double ph) {
+ AddHydrogens (false, true, ph);
+ ZNinit ();
+}
+
+
+void ZNMolecule::set_color_mw (Atom *at){
+ set_color (at, get_color_mw (at));
+}
+
+
+void ZNMolecule::add_atom_bonded_to (vect coords, int atomnum, Atom *at) {
+ Atom *at2 = new Atom;
+ ZNinit_atom (at);
+ at2 -> SetVector (coords);
+ at2 -> SetAtomicNum (atomnum);
+ ZNBond *b = new ZNBond;
+ ZNinit_bond (b);
+ b -> SetBondOrder (1);
+ add_atom_bonded_to (at2, b, at);
+}
+
+
+
+void ZNMolecule::add_atom_bonded_to (Atom *to_add, ZNBond *bond, Atom *partner) {
+ // to_add -> getVdw ();
+ if (!bond -> GetBondOrder ()) bond -> SetBondOrder (1);
+ assert (partner -> GetParent () == this);
+
+
+ ZNAddAtom (to_add);
+ // set_ds (to_add, get_ds (partner));
+ set_color_mw (to_add);
+
+ bond -> SetBegin (to_add);
+ bond -> SetEnd (partner);
+ ZNAddBond (bond);
+
+ // AddBond (to_add -> GetIdx (), partner -> GetIdx (), 1);
+ // bond = GetBond (to_add -> GetIdx (), partner -> GetIdx ());
+ ZNinit_bond (bond);
+ /* if (NumBonds ()) {
+ //change to get ds from first bond.
+ ZNBond *first_b = GetBond (0); //not safe
+ set_ds (bond, get_ds (first_b));
+ }
+ else set_ds (bond, 1);
+ */
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+ using namespace std;
+
+ class Mol2Par;
+
+
+ */
+Selection::Selection () : ZNMolecule () {
+ selection = true;
+ SetTitle ("Selection");
+ ZNinit ();
+ molecules.clear ();
+}
+
+
+
+void Selection::deselect () {
+ FOR_ATOMS_OF_MOL (a, this) {
+ set_selected (&*a, false);
+ }
+ set_needs_redraw (this, true);
+}
+
+
+void Selection::add_mol (ZNMolecule *mol) {
+ bool add = true;
+ for (unsigned int i=0; i<molecules.size (); i++) {
+ if (molecules[i] == mol) {
+ add = false;
+ break;
+ }
+ }
+ if (add) molecules.push_back (mol);
+}
+
+void Selection::select_atom (Atom *at) {
+ if (!get_selected (at)) {
+ set_selected (at, true);
+ ZNAddAtomToSelection (at);
+ }
+ add_mol ((ZNMolecule *) at ->GetParent ());
+}
+
+void Selection::select_atoms (vector <Atom *> to_add) {
+ for (unsigned int i = 0; i < to_add.size (); i++) {
+ select_atom (to_add[i]);
+ }
+}
+
+
+void Selection::extend_to_residue () {
+ vector <Atom *> to_add;
+ FOR_ATOMS_OF_MOL (a, this) {
+ // ZNMolecule * mol = (ZNMolecule *) a ->GetParent ();
+ Resid *res = a ->GetResidue ();
+ FOR_ATOMS_OF_RESIDUE (at, res) {
+ to_add.push_back (&*at);
+ }
+
+ }
+ select_atoms (to_add);
+ find_center (this);
+ find_limits (this);
+ set_needs_redraw (this, true);
+
+}
+
+void Selection::extend_to_fragment () {
+ vector <Atom *> to_add;
+ FOR_ATOMS_OF_MOL (a, this) {
+ // ZNMolecule * mol = (ZNMolecule *) a ->GetParent ();
+ Fragment *frag = get_fragment (&*a);
+ vector <Atom *> ats = frag -> get_atoms_list ();
+ for (unsigned int i = 0; i < ats.size (); i++) {
+ to_add.push_back (ats[i]);
+ }
+
+ }
+ select_atoms (to_add);
+ find_center (this);
+ find_limits (this);
+ set_needs_redraw (this, true);
+
+}
+
+void Selection::extend_to_neighbours () {
+ vector <Atom *> to_add;
+ FOR_ATOMS_OF_MOL (a, this) {
+ // ZNMolecule * mol = (ZNMolecule *) a ->GetParent ();
+ FOR_NBORS_OF_ATOM (n, &*a) {
+ to_add.push_back (&*n);
+ }
+
+ }
+ select_atoms (to_add);
+ find_center (this);
+ find_limits (this);
+ set_needs_redraw (this, true);
+}
+
+
+ZNBond * Selection::ZNAddBondToSelection (ZNBond *bond) {
+ int first = bond -> GetBeginAtomIdx();
+ int second = bond -> GetEndAtomIdx();
+ int order = bond -> GetBO();
+ int flags = bond -> GetFlags();
+ int insertpos = -1;
+
+
+
+
+ if (first == second)
+ return(NULL);
+
+ // BeginModify();
+
+ if ((unsigned)first <= NumAtoms() && (unsigned)second <= NumAtoms()
+ && !GetBond(first, second))
+ //atoms exist and bond doesn't
+ {
+ if (!bond)
+ {
+ EndModify();
+ return(NULL);
+ }
+
+ OBAtom *bgn,*end;
+ bgn = GetAtom(first);
+ end = GetAtom(second);
+ if (!bgn || !end)
+ {
+ obErrorLog.ThrowError(__FUNCTION__, "Unable to add bond - invalid atom index", obDebug);
+ return(NULL);
+ }
+ // bond->Set(_nbonds,bgn,end,order,flags);
+ // bond->SetParent(this);
+
+ //set aromatic flags if it has the appropriate order
+ if (order == 5)
+ {
+ bond->SetAromatic();
+ bgn->SetAromatic();
+ end->SetAromatic();
+ }
+
+#define OBBondIncrement 100
+ if (_vbond.empty() || _nbonds+1 >= _vbond.size())
+ {
+ _vbond.resize(_nbonds+OBBondIncrement);
+ vector<OBBond*>::iterator i;
+ for (i = _vbond.begin(),i+=(_nbonds+1);i != _vbond.end();++i)
+ *i = (OBBond*)NULL;
+ }
+#undef OBBondIncrement
+
+ _vbond[_nbonds] = (OBBond*)bond;
+ _nbonds++;
+
+ if (insertpos == -1)
+ {
+ // bgn->AddBond(bond);
+ // end->AddBond(bond);
+ }
+ else
+ {
+ if (insertpos >= static_cast<int>(bgn->GetValence()))
+ bgn->AddBond(bond);
+ else //need to insert the bond for the connectivity order to be preserved
+ { //otherwise stereochemistry gets screwed up
+ vector<OBBond*>::iterator bi;
+ bgn->BeginNbrAtom(bi);
+ bi += insertpos;
+ // bgn->InsertBond(bi,bond);
+ }
+ // end->AddBond(bond);
+ }
+ }
+ else //at least one atom doesn't exist yet - add to bond_q
+ SetData(new OBVirtualBond(first,second,order,flags));
+
+ // EndModify();
+ return(bond);
+
+}
+
+
+
+
+
+Atom * Selection::ZNAddAtomToSelection (Atom *atom) {
+
+ // BeginModify();
+ // ZNinit_atom (atom);
+ OBAtom *obatom = atom;
+ // cerr << "color" << obatom -> HasData ("color") << endl;
+ // obatom->SetIdx(_natoms+1);
+ // obatom->SetParent(this);
+
+
+#define OBAtomIncrement 100
+
+ if (_vatom.empty() || _natoms+1 >= _vatom.size())
+ {
+ _vatom.resize(_natoms+OBAtomIncrement);
+ vector<OBAtom*>::iterator j;
+ for (j = _vatom.begin(),j+=(_natoms+1);j != _vatom.end();++j)
+ *j = (OBAtom*)NULL;
+ }
+#undef OBAtomIncrement
+
+ _vatom[_natoms] = (OBAtom*)obatom;
+ _natoms++;
+
+ // if (HasData(OBGenericDataType::VirtualBondData))
+ // {
+ // /*add bonds that have been queued*/
+ // OBVirtualBond *vb;
+ // vector<OBGenericData*> verase;
+ // vector<OBGenericData*>::iterator i;
+ // for (i = BeginData();i != EndData();++i)
+ // if ((*i)->GetDataType() == OBGenericDataType::VirtualBondData)
+ // {
+ // vb = (OBVirtualBond*)*i;
+ // if (static_cast<unsigned int>(vb->GetBgn()) > _natoms ||
+ // static_cast<unsigned int>(vb->GetEnd()) > _natoms)
+ // continue;
+ // if (obatom->GetIdx() == static_cast<unsigned int>(vb->GetBgn())
+ // || obatom->GetIdx() == static_cast<unsigned int>(vb->GetEnd()))
+ // {
+ // AddBond(vb->GetBgn(),vb->GetEnd(),vb->GetOrder());
+ // verase.push_back(*i);
+ // }
+ // }
+ //
+ // if (!verase.empty())
+ // DeleteData(verase);
+ // }
+
+ // EndModify();
+
+ return(obatom);
+
+}
+
+
+
+
+
+
+
+Fragment::Fragment () {
+ _visited = false;
+ set_number (0);
+ set_translation(vect (0., 0., 0.));
+ set_rotation (quaternion (1., 0., 0., 0.));
+
+}
+
+void Fragment::clean_connections () {
+ vector <rotorConnection *> to_keep, to_del;
+ for (unsigned int i = 0; i < _rotor_connections.size (); i ++) {
+ if (_rotor_connections[i] ->to_keep) {
+ to_keep.push_back(_rotor_connections[i]);
+ }
+ else {
+ to_del.push_back(_rotor_connections[i]);
+ }
+ }
+ for (unsigned int i = 0; i < to_del.size(); i++) {
+ delete to_del[i];
+ }
+ _rotor_connections = to_keep;
+}
+
+void Fragment::quaternion_rotate (vect center, quaternion q) {
+ for (unsigned int i = 0; i < _atoms.size (); i++) {
+ vect c = subtract (_last_coordinates[i], center);
+ c = rotate_vector_using_quaternion(c, q);
+ c = sum (c, center);
+ set_coordinates(_atoms[i], c);
+ _last_coordinates[i] = c;
+
+ }
+}
+
+vector <Fragment *> Fragment::get_first_order_children () {
+ vector <Fragment *> out;
+ for (unsigned int i = 0; i < _rotor_connections.size (); i++) {
+ out.push_back(_rotor_connections[i] ->to_fragment);
+ }
+ return out;
+}
+
+
+vector <Fragment *> Fragment::all_children () {
+ vector <Fragment *> out, last_order, build_last_order;
+ last_order = get_first_order_children();
+ out = last_order;
+ while (last_order.size ()) {
+ build_last_order.clear ();
+ for (unsigned int i = 0; i < last_order.size (); i++) {
+ vector <Fragment *> children = last_order[i] ->get_first_order_children ();
+ for (unsigned int j = 0; j< children.size (); j++) {
+ build_last_order.push_back(children [j]);
+ }
+ }
+ last_order = build_last_order;
+ for (unsigned int j = 0; j< last_order.size (); j++) {
+ out.push_back(last_order [j]);
+ }
+ }
+ return out;
+}
+
+
+
+
+Resid *get_previous_residue (Resid *res, int gap) {
+ ZNMolecule *mol = NULL;
+ FOR_ATOMS_OF_RESIDUE (a, res) {
+ mol = (ZNMolecule *) &*a -> GetParent ();
+ break;
+ }
+ int indx = res -> GetIdx ();
+ if (indx - gap >= 0) {
+ Resid *prec_res = mol -> GetResidue (indx - gap);
+ if (res ->GetChainNum () == prec_res ->GetChainNum ()) {
+ Atom *N = NULL;
+ Atom *C = NULL;
+ N = get_N (res);
+ C = get_C (prec_res);
+ if (N && C) {
+ if (mol ->GetBond (N, C)) return prec_res;
+ if (gap > 1) return prec_res;
+ }
+ }
+ }
+ return NULL;
+}
+
+Resid *get_following_residue (Resid *res, int gap) {
+ ZNMolecule *mol = NULL;
+ FOR_ATOMS_OF_RESIDUE (a, res) {
+ mol = (ZNMolecule *) &*a -> GetParent ();
+ break;
+ }
+ int indx = res -> GetIdx ();
+ Resid *fol_res = mol -> GetResidue (indx + gap);
+ if (!fol_res) return NULL;
+ if (res ->GetChainNum () == fol_res ->GetChainNum ()) {
+ Atom *N = NULL;
+ Atom *C = NULL;
+ N = get_N (fol_res);
+ C = get_C (res);
+ if (N && C) {
+ if (mol ->GetBond (N, C)) return fol_res;
+ if (gap > 1) return fol_res;
+ }
+ }
+
+ else return NULL;
+}
+
+Atom *get_O (Resid *res) {
+ Atom *C = get_C (res);
+ if (C) {
+ FOR_NBORS_OF_ATOM (O, C) {
+ if (O ->IsOxygen ()) return &*O;
+ }
+ }
+ return NULL;
+}
+
+
+Atom *get_CA (Resid *res) {
+ FOR_ATOMS_OF_RESIDUE(a, res) {
+ QString atomID = QString(res->GetAtomID(&*a).c_str());
+ atomID = atomID.trimmed();
+ if (atomID == "CA") {
+ return &*a;
+
+ }
+ // if (atomID == " CA ") {
+ // return &*a;
+
+ // }
+ }
+ return NULL;
+}
+
+Atom *get_N (Resid *res) {
+ FOR_ATOMS_OF_RESIDUE(a, res) {
+ QString atomID = QString(res->GetAtomID(&*a).c_str());
+ atomID = atomID.trimmed();
+ if (atomID == "N") {
+ return &*a;
+
+ }
+ // if (atomID == " N ") {
+ // return &*a;
+
+ // }
+ }
+ return NULL;
+}
+
+Atom *get_C (Resid *res) {
+ FOR_ATOMS_OF_RESIDUE(a, res) {
+ QString atomID = QString(res->GetAtomID(&*a).c_str());
+ atomID = atomID.trimmed();
+ if (atomID == "C") {
+ return &*a;
+
+ }
+ // if (atomID == " C ") {
+ // return &*a;
+
+ // }
+ }
+ return NULL;
+}
+
+
+double get_phi (Resid *res) {
+ ZNMolecule *mol = NULL;
+ Atom *Cp, *CA, *N, *C;
+ CA = get_CA (res);
+ N = get_N (res);
+ C = get_C (res);
+ Resid *prec_r = get_previous_residue(res);
+ if (prec_r) {
+ Cp = get_C (prec_r);
+ if (Cp && CA && N && C) {
+ return dihedral (get_coordinates(Cp), get_coordinates(N), get_coordinates(CA), get_coordinates(C));
+ }
+
+ }
+ return 0;
+
+}
+
+double get_psi (Resid *res) {
+ ZNMolecule *mol = NULL;
+ Atom *Nf, *CA, *N, *C;
+ CA = get_CA (res);
+ N = get_N (res);
+ C = get_C (res);
+ Resid *fol_r = get_following_residue(res);
+ if (fol_r) {
+ Nf = get_N (fol_r);
+ if (Nf && CA && N && C) {
+ return dihedral (get_coordinates(N), get_coordinates(CA), get_coordinates(C), get_coordinates(Nf));
+ }
+
+ }
+ return 0;
+
+}
+
+
+/*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ void Atom::find_mol2_type () {
+ switch (atomicNumber) {
+ case 1:
+ atomType = "H";
+ break;
+ case 6:
+ if (is_aromatic ()) atomType == "C.ar";
+ else if (bound.size ()== 2) atomType == "C.1";
+ else if (bound.size ()== 3) atomType == "C.2";
+ else if (bound.size ()== 4) atomType == "C.3";
+ break;
+ case 7:
+ if (is_aromatic ()) atomType == "N.ar";
+ else if (bound.size ()== 2) atomType == "N.1";
+ else if (bound.size ()== 3) atomType == "N.2";
+ else if (bound.size ()== 4) atomType == "N.3";
+ case 8:
+ if (is_aromatic ()) atomType == "O.ar";
+ else if (bound.size ()== 1) atomType == "O.2";
+ else if (bound.size ()== 2) atomType == "O.3";
+ break;
+
+ }
+ }
+
+ unsigned int Atom::bonded_to (int bondtype, int atnumb) {
+ unsigned int out = 0;
+ if (bondtype!=5) {
+ for (unsigned int n=0; n<bonds.size(); n++) {
+ if (bonds[n]->kekule == bondtype || bondtype == -2) {
+ if (bound[n]->atomicNumber == atnumb || atnumb == -2) {
+ out += 1;
+ }
+ }
+ }
+ }
+ else {
+ for (unsigned int n=0; n<bonds.size(); n++) {
+ if (bonds[n]->mol2Type == bondtype || bondtype == -2) {
+ if (bound[n]->atomicNumber == atnumb || atnumb == -2) {
+ out += 1;
+ }
+ }
+ }
+ }
+ return out;
+ }
+
+ unsigned int Atom::bonded_to (string MMFFstring) {
+ unsigned int out = 0;
+ for (unsigned int n=0; n<bound.size(); n++) {
+ if (bound[n]->MMFFstring == MMFFstring) {
+ out += 1;
+
+ }
+ }
+ return out;
+ }
+
+ bool Atom::bonded_to (Atom *at) {
+ for (unsigned int n=0; n<bound.size(); n++) {
+ if (bound[n]== at) {
+ return true;
+
+ }
+ }
+ return false;
+ }
+
+
+
+ bool Atom::is_in_ring (Ring *rin) {
+ if (!in_ring.size ()) return false;
+ else {
+ for (unsigned int r=0; r<in_ring.size (); r++) {
+ if (in_ring[r]==rin) return true;
+ }
+ }
+ return false;
+ }
+
+ bool Atom::is_aromatic () {
+ bool ar = false;
+ for (unsigned r=0; r<in_ring.size (); r++) {
+ if (in_ring[r]->aromatic) ar =true;
+ }
+ return ar;
+ }
+
+
+ bool Atom::isSp2 (){
+ if (mol2Type==2 || mol2Type==3 || mol2Type==6 || mol2Type==9 || mol2Type==11 || mol2Type==18)
+ return true;
+ else return false;
+ }
+
+
+ color Atom::get_color_mw () {
+ float r, g, b;
+ switch (atomicNumber) {
+ case 1: r=1.0f; g=1.0f; b=1.0f;
+ break;
+ case 6: r=0.f; g=0.f; b=0.f;
+
+ break;
+ case 7: r=0.0f; g=0.0f; b=1.0f;
+ break;
+ case 8: r=1.0f; g=0.0f; b=0.0f;
+ break;
+ case 15: r=0.f; g=1.0f; b=0.5f;
+ break;
+ case 16: r=1.0f; g=1.0f; b=0.0f;
+ break;
+
+ default: r=0.7f; g= 0.7f; b=0.7f;
+ }
+ return color (r, g, b);
+ }
+
+ void Atom::set_color_mw (){
+ col = get_color_mw ();
+ }
+
+
+
+
+
+
+ ZNBond::ZNBond () {
+ fr_visited = false;
+ fr_parent = NULL;
+ }
+
+ bool ZNBond::is_aromatic () {
+ bool ar = false;
+ for (unsigned r=0; r<in_ring.size (); r++) {
+ if (in_ring[r]->aromatic) ar =true;
+ }
+ return ar;
+ }
+
+
+ bool ZNBond::is_rotatable () {
+ if (mol2Type != 1) return false; //multiple bond
+ if (atomPTR[0]->bound.size () == 1 || atomPTR[1]->bound.size () == 1) return false; //to terminal atom
+ if (in_ring.size ()) return false; //ring bond
+ if (atomPTR[0]->atomicNumber == 6 && atomPTR[0]->bonded_to (1, 1) == 3) return false; //to terminal CH3
+ if (atomPTR[1]->atomicNumber == 6 && atomPTR[1]->bonded_to (1, 1) == 3) return false; //to terminal CH3
+ return true;
+ }
+
+
+ bool ZNBond::conjugated_to (unsigned int order, Ring *ring) {
+ for (unsigned int b=0; b<atomPTR[0]->bonds.size (); b++) {
+ if (atomPTR[0]->bonds[b]->kekule == order && atomPTR[0]->bonds[b]!=this && atomPTR[0]->bonds[b]->is_in_ring (ring)) return true;
+ }
+ for (unsigned int b=0; b<atomPTR[1]->bonds.size (); b++) {
+ if (atomPTR[1]->bonds[b]->kekule == order && atomPTR[1]->bonds[b]!=this && atomPTR[1]->bonds[b]->is_in_ring (ring)) return true;
+ }
+ return false;
+ }
+
+ bool ZNBond::is_in_ring (Ring *rin) {
+ if (!in_ring.size ()) return false;
+ else {
+ for (unsigned int r=0; r<in_ring.size (); r++) {
+ if (in_ring[r]==rin) return true;
+ }
+ }
+ return false;
+ }
+
+
+
+
+ void ZNBond::set_order (int ord) {
+ mol2Type = ord;
+ kekule = ord;
+ }
+
+
+
+
+
+
+ Atom::Atom () {
+ col = color (0, 0, 0, 255);
+ visible = true;
+ selected = false;
+ score = 0.f;
+ no2bond = false;
+ inBackBone = false;
+ sphere_already_drawn = false;
+ displayStyle = 0;
+ fragment = NULL;
+ residue = NULL;
+ ID = 0;
+ atomicNumber = 6;
+ substructureNumber = 0;
+ substructureName = "";
+
+ vdw = 1.0;
+
+
+ }
+
+ void Atom::getVdw () {
+ vdw = mol2par->getVdw(atomicNumber);
+ }
+
+ /*
+
+ int ZNMolecule::readPDB (string filename, ifstream&) {
+ string PDBAtom = "HETATM";
+ string PDBConnect = "CONECT";
+ string PDBEnd = "END";
+
+ string buffer ="";
+ unsigned int lineNumber = 0;
+ name = filename;
+ bool go_on = TRUE;
+ go_on = getline(file, buffer);
+ while (go_on) {
+ lineNumber++;// cout <<lineNumber;
+ istringstream issGlobal(buffer);
+ string token;
+ issGlobal >> token;
+
+ if (token == PDBAtom) {}
+ else if (token == PDBConnect) {}
+ else if (token == PDBEnd) {
+ go_on = false;
+ }
+ }
+
+
+ }
+
+ */
+/*
+
+
+ int ZNMolecule::readMultiMOL2(string filename, ifstream& file, bool& continueRead)
+ {
+ string triposZNMolecule = "@<TRIPOS>MOLECULE";
+ string triposAtom = "@<TRIPOS>ATOM";
+ string triposSubStructure = "@<TRIPOS>SUBSTRUCTURE";
+ string triposBACKBONE = "BACKBONE";
+ string triposDICT = "DICT";
+ string triposESSENTIAL = "ESSENTIAL";
+ string triposDIRECT = "DIRECT";
+ string triposINTERRES = "INTERRES";
+ string triposBond = "@<TRIPOS>BOND";
+
+
+
+ string buffer ="";
+ unsigned int lineNumber = 0;
+ name = filename;
+
+
+ bool newZNMoleculeFound = false;
+ bool nextZNMoleculeFound = false;
+
+ bool res = true;
+ if (!continueRead) {
+ res = getline(file, buffer);
+
+
+ }
+ while (res && !nextZNMoleculeFound) {
+
+ lineNumber++;// cout <<lineNumber;
+ istringstream issGlobal(buffer);
+ string token;
+ issGlobal >> token;
+ int atomCount, bondCount, substructCount;
+ // cout << token <<" "<<lineNumber<<endl;
+ if (token == triposZNMolecule || continueRead) {
+ if (!newZNMoleculeFound) {
+ newZNMoleculeFound = true;
+ continueRead = false;
+ getline(file, buffer);
+ lineNumber++;
+ description = buffer;
+ // cout << "Description: " << description << endl;
+ getline(file, buffer);
+ lineNumber++;
+ istringstream iss(buffer);
+ iss >> atomCount;
+ if (!checkInputStream(filename, "Atom count expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> bondCount;
+ if (!checkInputStream(filename, "ZNBond count expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> substructCount;
+ /// /*if (!checkInputStream(filename, "Substructure count expected.", lineNumber, iss)) {
+ /// return false;
+ /// }
+ }
+ else {
+ nextZNMoleculeFound = true;
+ // continueRead = true;
+ }
+ }
+ else if (token == triposAtom) {
+ for (unsigned int i = 0; i < atomCount; i++) {
+ getline(file, buffer);
+ lineNumber++;
+ istringstream iss(buffer);
+
+ unsigned int atomNumber = 0;
+ string atomName = "";
+ string atomType = "";
+ unsigned int atomSubstructureNumber = 1;
+ string atomSubstructureName = "";
+ float atomCharge = 0.0;
+ float x, y, z;
+ iss >> atomNumber;
+ if (!checkInputStream(filename, "Atom number expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> atomName;
+ if (!checkInputStream(filename, "Atom name expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> x;
+ if (!checkInputStream(filename, "Atom coordinate X expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> y;
+ if (!checkInputStream(filename, "Atom coordinate Y expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> z;
+ if (!checkInputStream(filename, "Atom coordinate Z expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> atomType;
+ if (!checkInputStream(filename, "Atom type expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> atomSubstructureNumber;
+ if (!checkInputStream(filename, "Atom substructure ID expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> atomSubstructureName;
+ if (!checkInputStream(filename, "Atom substructure name expected.", lineNumber, iss)) {
+ return false;
+ }
+ iss >> atomCharge;
+ if (!checkInputStream(filename, "Atom charge expected.", lineNumber, iss)) {
+ return false;
+ }
+
+ unsigned int mol2Type = mol2par->getmol2AtomTypeID(atomType);
+ /// if (mol2Type == 20) {
+ //// cerr << "REMOVED LONE PAIR: " << atomNumber << endl;
+ ///// cout << "removed lone pair " << setw(5) << setfill (' ') << atomName << "(" << setw(4) << setfill (' ') << atomNumber << ") " << endl;
+ //// continue;
+ /// }
+ Atom* atom = new Atom();
+ atom->atomType = atomType;
+ atom->mol2Type = mol2Type;
+ atom->atomicNumber = mol2par->getOrdinalNumber(atomType);
+
+ atom->getVdw ();
+
+ atom->number = atomNumber;
+ atom->name = atomName;
+
+ atom->substructureNumber = atomSubstructureNumber;
+ atom->substructureName = atomSubstructureName;
+ atom->charge = atomCharge;
+ atom->inBackBone = false;
+
+ atom->sphere_already_drawn = false;
+ atom->displayStyle = 0;
+
+ atom-> GetVector () = vect (x, y, z);
+
+
+ atom->ID = atoms.size();
+
+ /////// atom->isProtein = isProtein;
+ ///// atom->isWater = isWater;
+ ////// atom->isLigand = !isProtein && !isWater;
+
+ atom->set_color_mw ();
+ atoms.push_back(atom);
+ string atomProperty;
+ while (getline(iss, atomProperty, '|')) {
+ // skip white spaces
+ istringstream iss2(atomProperty);
+ iss2 >> atomProperty;
+ //cout << bondProperty << "|";
+ // check for backbone
+ if (atomProperty == triposBACKBONE) {
+ atom->inBackBone = true;
+ atom->mol2BACKBONE = true;
+ }
+ if (atomProperty == triposDICT) {
+ atom->mol2DICT = true;
+ }
+ if (atomProperty == triposESSENTIAL) {
+ atom->mol2ESSENTIAL = true;
+ }
+ if (atomProperty == triposDIRECT) {
+ atom->mol2DIRECT = true;
+ }
+
+
+
+
+ }
+ }
+ }
+ else if (token == triposBond) {
+ for (unsigned int i = 0; i < bondCount; i++) {
+ getline(file, buffer);
+ lineNumber++;
+ istringstream iss(buffer);
+
+ unsigned int bondNumber;
+ unsigned int fromAtom;
+ unsigned int toAtom;
+ string bondType;
+
+ iss >> bondNumber;
+ if (!checkInputStream(filename, "ZNBond number expected.", lineNumber, iss)) {
+ return 0;
+ }
+ iss >> fromAtom;
+ if (!checkInputStream(filename, "ZNBond atom 1 expected.", lineNumber, iss)) {
+ return 0;
+ }
+ iss >> toAtom;
+ if (!checkInputStream(filename, "ZNBond atom 2 expected.", lineNumber, iss)) {
+ return 0;
+ }
+ iss >> bondType;
+ if (!checkInputStream(filename, "ZNBond type expected.", lineNumber, iss)) {
+ return 0;
+ }
+
+
+ ZNBond* bond = new ZNBond();
+ bond->mol2Type = mol2par->getmol2BondTypeID(bondType);
+ bond->kekule = bond->mol2Type;
+ bond->number = bondNumber;
+ // bond->hasCoplanar0 = false;
+ // bond->hasCoplanar1 = false;
+ bond->displayStyle = 1;
+
+ bool atomFound1 = false;
+ bool atomFound2 = false;
+ for (unsigned int j = 0; j < atoms.size() && !atomFound1; j++) {
+ if (atoms[j]->number == fromAtom) {
+ bond->atomID[0] = j;
+ bond->atomPTR[0] = atoms[j];
+ atomFound1 = true;
+ }
+ }
+ for (unsigned int j = 0; j < atoms.size() && !atomFound2; j++) {
+ if (atoms[j]->number == toAtom) {
+ bond->atomID[1] = j;
+ bond->atomPTR[1] = atoms[j];
+ atomFound2 = true;
+ }
+ }
+
+
+ if (!atomFound1 || !atomFound2) {
+ //cerr << "parse error in file " << filename << " (line " << lineNumber << "): Could not find atom " << fromAtom << ". Exit." << endl;
+ //exit(1);
+ //cerr << "REMOVED BOND: " << bondNumber << endl;
+ cout << "removed bond " << setw(5) << setfill (' ') << bondNumber << endl;
+ delete bond;
+ }
+ bonds.push_back(bond);
+ }
+ }
+ if (!nextZNMoleculeFound) res = getline(file, buffer);
+ }
+
+
+ find_bound ();
+ find_residues ();
+ find_fragments ();
+ find_rings ();
+ find_kekule ();
+ find_limits ();
+ find_center ();
+
+ cout<<fragments.size()<<" fragments"<<endl;
+ if (nextZNMoleculeFound) {
+ return 2;
+ }
+ return 1;
+ }
+
+ ZNBond * ZNMolecule::find_bond (Atom *at1, Atom *at2) {
+ for (unsigned int i=0; i<at1->bonds.size (); i++) {
+ if (at1->bonds[i]->atomPTR[0]==at1 && at1->bonds[i]->atomPTR[1]==at2) return at1->bonds[i];
+ if (at1->bonds[i]->atomPTR[1]==at1 && at1->bonds[i]->atomPTR[0]==at2) return at1->bonds[i];
+ }
+ return NULL;
+ }
+
+
+
+
+ void ZNMolecule::remove (ZNBond* bo) {
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i] == bo) {
+ bonds.erase (bonds.begin ()+i);
+ return;
+ }
+ }
+ }
+
+ void ZNMolecule::remove (Atom* at) {
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i] == at) {
+ atoms.erase (atoms.begin ()+i);
+ return;
+ }
+ }
+ }
+
+
+
+
+ void ZNMolecule::del (ZNBond* bo) {
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i] == bo) {
+ bonds.erase (bonds.begin ()+i);
+ delete bo;
+ return;
+ }
+ }
+ }
+
+ void ZNMolecule::del (Atom* at) {
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i] == at) {
+ atoms.erase (atoms.begin ()+i);
+ delete at;
+ return;
+ }
+ }
+ }
+
+ void ZNMolecule::add (Atom *at) {
+ atoms.push_back (at);
+ }
+
+ void ZNMolecule::add (ZNBond *bo) {
+ bonds.push_back (bo);
+ }
+
+
+
+
+
+ void ZNMolecule::add_atom_bonded_to (Atom *to_add, Atom *partner) {
+ ZNBond *bond = new ZNBond;
+ add_atom_bonded_to (to_add, bond, partner);
+ }
+
+
+
+
+ Atom *ZNMolecule::add_atom_bonded_to (vect coords, int atomnum, Atom *at) {
+ ZNMolecule *mol = at->residue->molecule;
+ Atom *new_at = new Atom;
+ new_at->atomicNumber = atomnum;
+ new_at-> GetVector () = coords;
+ new_at->substructureNumber = at->substructureNumber;
+ new_at->substructureName = at->substructureName;
+
+ new_at->getVdw ();
+ new_at->set_color_mw ();
+ new_at->displayStyle = at->displayStyle;
+ mol->atoms.push_back (new_at);
+ ZNBond *bond = new ZNBond;
+ bond->atomPTR[0] = at;
+ bond->atomPTR[1] = new_at;
+ bond->mol2Type = 1;
+ bond->kekule = 1;
+ if (mol->bonds.size ()) bond->displayStyle = mol->bonds[0]->displayStyle;
+ else bond->displayStyle = 1;
+ mol->bonds.push_back (bond);
+ return new_at;
+ }
+
+ void ZNMolecule::number_atoms () {
+ for (unsigned int i=0; i<atoms.size (); i++) atoms[i]->ID = i;
+ }
+
+ void ZNMolecule::number_bonds () {
+ for (unsigned int j=0; j<bonds.size (); j++) {
+ bonds[j]->number = j;
+ bonds[j]->atomID[0] = bonds[j]->atomPTR[0]->ID;
+ bonds[j]->atomID[1] = bonds[j]->atomPTR[1]->ID;
+ }
+ }
+
+ void ZNMolecule::find_bound () {
+ for (unsigned int i=0; i<atoms.size (); i++) {
+
+ atoms[i]->no2bond = false;
+ atoms[i]->bonds.clear ();
+ atoms[i]->bound.clear ();
+ }
+ for (unsigned int j=0; j<bonds.size (); j++) {
+ ZNBond *bond = bonds[j];
+ bond->kekule = bond->mol2Type;
+ bond->atomPTR[0]->bound.push_back (bond->atomPTR[1]);
+ bond->atomPTR[1]->bound.push_back (bond->atomPTR[0]);
+ bond->atomPTR[0]->bonds.push_back (bond);
+ bond->atomPTR[1]->bonds.push_back (bond);
+
+ }
+ }
+
+
+
+ void ZNMolecule::find_center () {
+ center = find_mass_center (atoms);
+ }
+
+
+ void ZNMolecule::find_kekule () {
+ bool go_on = true;
+ int nn=0;
+ while (go_on) {
+ go_on = false;
+ for (unsigned int r=0; r<rings.size (); r++) {
+ Ring *rin = rings[r];
+ if (rin->aromatic) {
+ if (rin->kekule_type>nn) go_on=true;
+ if (rin->kekule_type==nn) rin->find_kekule ();
+ }
+ }
+ for (unsigned int r=0; r<rings.size (); r++) {
+ if (!rings[r]->aromatic) {
+ for (unsigned int b=0; b<rings[r]->bonds.size (); b++) {
+ if (rings[r]->bonds[b]->mol2Type==5) {
+ rings[r]->find_kekule_pseudoaromatic ();
+ break;
+ }
+ }
+ }
+ }
+ nn++;
+ }
+ for (unsigned int r=0; r<rings.size (); r++) {
+ Ring *rin = rings[r];
+ if (rin->aromatic) rin->test_kekule_aromaticity ();
+ }
+ }
+
+ void ZNMolecule::find_limits () {
+ if (atoms.size ()) {
+ float xm, ym, zm, xM, yM, zM;
+ xm = xM = atoms[0]-> GetVector ().x();
+ ym = yM = atoms[0]-> GetVector ().y();
+ zm = zM = atoms[0]-> GetVector ().z();
+ for (unsigned a=0; a<atoms.size(); a++){
+ if (atoms[a]-> GetVector ().x()<xm) xm= atoms[a]-> GetVector ().x();
+ if (atoms[a]-> GetVector ().x()>xM) xM= atoms[a]-> GetVector ().x();
+ if (atoms[a]-> GetVector ().y()<ym) ym= atoms[a]-> GetVector ().y();
+ if (atoms[a]-> GetVector ().y()>yM) yM= atoms[a]-> GetVector ().y();
+ if (atoms[a]-> GetVector ().z()<zm) zm= atoms[a]-> GetVector ().z();
+ if (atoms[a]-> GetVector ().z()>zM) zM= atoms[a]-> GetVector ().z();
+ }
+ min_corner = vect (xm, ym, zm);
+ max_corner = vect (xM, yM, zM);
+ }
+ }
+
+ void ZNMolecule::find_fragments () {
+ fragments.clear ();
+ for (unsigned int a=0; a<atoms.size(); a++) {
+ atoms[a]->visited = false;
+ }
+ for (unsigned int a=0; a<atoms.size(); a++) {
+ if (atoms[a]->visited) continue;
+ Fragment *fragment = new Fragment ();
+ queue <Atom*> queue;
+ queue.push (atoms[a]);
+ atoms[a]->visited = true;
+ while (queue.size () ) {
+ Atom *at = queue.front();
+ queue.pop ();
+ fragment->atoms.push_back (at);
+ for (unsigned int i=0; i<at->bonds.size (); i++) {
+ if (!at->bonds[i]->is_rotatable () && !at->bound[i]->visited) {
+ queue.push (at->bound[i]);
+ at->bound[i]->visited = true;
+ }
+ }
+ }
+ fragments.push_back (fragment);
+
+ }
+
+ }
+
+ void ZNMolecule::find_rings () {
+ for (unsigned int i=0; i<rings.size (); i++) {
+ delete rings[i];
+ }
+ rings.clear ();
+ for (unsigned int a=0; a<atoms.size (); a++) {
+ atoms[a]->in_ring.clear ();
+ }
+ for (unsigned int b=0; b<bonds.size (); b++) {
+ bonds[b]->in_ring.clear ();
+ }
+
+
+ for (unsigned int b=0; b<bonds.size(); b++){
+ // cout << "b ";
+ if ((bonds[b]->atomPTR[0]->bonds.size ()==1) || (bonds[b]->atomPTR[1]->bonds.size ()==1) || bonds[b]->in_ring.size ()) continue;
+ queue <ZNBond*> queue;
+ // cout <<"ok"<<endl;
+ for (unsigned int b2=0; b2<bonds.size(); b2++) {
+ bonds[b2]->fr_visited = false;
+ bonds[b2]->fr_parent = NULL;
+
+ }
+
+ // int nr = 0;
+ // cout <<"direction "<<b0dir<<endl;
+
+ bonds[b]->fr_dir = 0;
+ bonds[b]->fr_visited = true;
+ bonds[b]->fr_parent = NULL;
+ queue.push (bonds[b]);
+ bool ring_found = false;
+ // cout <<"starting from bond "<<bonds[b]->number<<endl;
+ while (queue.size () && !ring_found) {
+ ZNBond *bo = queue.front();
+ queue.pop ();
+ // cout << "popping "<<bo->number<<endl;
+ for (unsigned int bb = 0; bb<bo->atomPTR[bo->fr_dir]->bonds.size (); bb++) {
+ ZNBond *nextbo = bo->atomPTR[bo->fr_dir]->bonds[bb];
+ if (nextbo!=bo && nextbo->atomPTR[0]->bound.size()!=1 && nextbo->atomPTR[1]->bound.size()!=1 ) {
+
+ if (nextbo->fr_visited) {
+ // cout <<nextbo->number<<" already visited"<<endl;
+ if (nextbo==bonds[b])
+ ring_found=close_ring (bo);
+ }
+ else{
+ int dir = 0;
+ for (unsigned int d=0; d<nextbo->atomPTR[0]->bonds.size(); d++){
+ if (nextbo->atomPTR[0]->bonds[d]==bo) {
+ dir = 1;
+ break;
+ }
+ }
+ nextbo->fr_dir = dir;
+ nextbo->fr_parent = bo;
+
+ nextbo->fr_visited = true;
+ // cout << "pushing "<<nextbo->number<<" "<<nextbo->atomPTR[0]->ID<<" "<< nextbo->atomPTR[1]->ID<<endl;
+ queue.push (nextbo);
+ }
+ }
+ }
+
+ }
+
+ }
+ // cout<<"rings "<<nr<<endl;
+ }
+
+
+ bool ZNMolecule::close_ring (ZNBond *bo) {
+ vector <ZNBond*> out_bonds;
+ ZNBond *curr_bo;
+ // cout <<"close rings"<<endl;
+ curr_bo = bo;
+ out_bonds.push_back (bo);
+ while (curr_bo->fr_parent) {
+ out_bonds.push_back (curr_bo->fr_parent);
+ curr_bo = curr_bo->fr_parent;
+ }
+
+ // for (unsigned int q=0; q<out_bonds.size(); q++) cout<<out_bonds[q]<<" "; cout <<endl;
+
+
+ if (true) {
+
+
+ bool already_found = false;
+ if (!already_found) {
+ Ring *ring = new Ring;
+ // bool aromatic = true;
+ for (unsigned int i=0; i<out_bonds.size(); i++) {
+ // if (out_bonds[i]->mol2Type!=5) aromatic = false;
+ out_bonds[i]->in_ring.push_back (ring);
+ bool not_put0 = true;
+ bool not_put1 = true;
+ for(unsigned int at=0; at<ring->atoms.size();at++){
+ if (ring->atoms[at]==out_bonds[i]->atomPTR[0]) {
+ not_put0 = false;
+ }
+ if (ring->atoms[at]==out_bonds[i]->atomPTR[1]) {
+ not_put1 = false;
+ }
+
+ }
+ if (not_put0) {
+ ring->atoms.push_back (out_bonds[i]->atomPTR[0]);
+ out_bonds[i]->atomPTR[0]->in_ring.push_back (ring);
+ }
+ if (not_put1) {
+ ring->atoms.push_back (out_bonds[i]->atomPTR[1]);
+ out_bonds[i]->atomPTR[1]->in_ring.push_back (ring);
+ }
+ ring->bonds.push_back (out_bonds[i]);
+ }
+ ring->center = find_mass_center (ring->atoms);
+
+ ring->test_aromaticity ();
+ rings.push_back (ring);
+ return 1;
+ }
+ }
+ else return 0;
+ }
+
+ void ZNMolecule::findBonds (Atom *atom, vector <ZNBond*>& out){
+ unsigned int ID=atom->ID;
+ for (unsigned int i=0; i<bonds.size ();i++) {
+ for (unsigned int j=0; j<2;j++) {
+ if (bonds[i]->atomID[j]==ID) {
+ // cout <<"bond found"<<endl;
+ out.push_back (bonds[i]);
+ }
+ }
+ }
+ // cout <<"atom "<<atom->atomType<<" bound to "<<out.size()<<" other atoms"<<endl;
+
+
+ }
+
+ Atom* ZNMolecule::findOtherAtom (ZNBond *bond, Atom *atom){
+ if (bond->atomID[0]!=atom->ID) return bond->atomPTR[0];
+ else if (bond->atomID[1]!=atom->ID) return bond->atomPTR[1];
+ else {
+ cerr << "Atom "<< atom->ID << "not in bond "<< bond->number<<endl;
+ return bond->atomPTR[0];
+ }
+ }
+
+
+ void ZNMolecule::find_residues (){
+ vector<string> vec;
+ vector<int> vecn;
+ int lastn = -1;
+ bool resf = false;
+ for (unsigned int i=0; i<residues.size (); i++) {
+ delete residues[i];
+ }
+ residues.clear ();
+
+ for (unsigned int i=0; i<atoms.size(); i++) {
+ resf = false;
+ int ssnum =atoms[i]->substructureNumber;
+
+ if (ssnum != lastn) {
+ for (unsigned int j=0; j<vecn.size(); j++) {
+ if (ssnum == vecn[j]) {
+ resf = true;
+ break;
+ }
+ }
+ if (!resf){
+ lastn = ssnum;
+ vecn.push_back (ssnum);
+ assert (i>=0 && i<atoms.size ());
+ string ssname =atoms[i]->substructureName;
+ stringstream ssn;
+ ssn << ssnum ;
+ vec.push_back (ssn.str ()+" "+ssname+ssn.str());
+ Residue *res = new Residue ();
+ res->number = ssnum;
+ res->name = ssname;
+
+ res->molecule = this;
+ residues.push_back (res);
+ }
+ }
+ }
+ for (unsigned int i = 0; i<atoms.size (); i++) {
+ for (unsigned int j = 0; j<residues.size (); j++) {
+ if (atoms[i]->substructureNumber==residues[j]->number) {
+ residues[j]->atoms.push_back (atoms[i]);
+ atoms[i]->residue=residues[j];
+ break;
+ }
+ }
+ }
+
+ for (unsigned int j = 0; j<residues.size (); j++) {
+ for (unsigned int i = 0; i<residues[j]->atoms.size (); i++) {
+ if (residues[j]->atoms[i]->inBackBone) {
+ if (residues[j]->atoms[i]->atomType == "N.am" ) {
+ residues[j]->NB = residues[j]->atoms[i];
+ residues[j]->hasNB = true;
+ }
+ else if (residues[j]->atoms[i]->atomType == "C.2" ) {residues[j]->CB = residues[j]->atoms[i];
+ residues[j]->hasCB = true;
+ }
+ else if (residues[j]->atoms[i]->atomType == "C.3" ) {residues[j]->CA = residues[j]->atoms[i];
+ residues[j]->hasCA = true;
+ }
+ }
+ }
+
+ if (residues[j]->hasNB && residues[j]->hasCB && residues[j]->hasCA){
+ vect point;
+
+ for (unsigned int n=0; n<residues[j]->NB->bound.size ();n++) {
+ if (residues[j]->NB->bound[n]->atomType == "C.2") {
+ vect pre;
+ pre = residues[j]->NB->bound[n]-> GetVector ();
+ point = mean (pre, residues[j]->NB-> GetVector ());
+ residues[j]->backbone_list.push_back (point);
+
+
+ }
+ }
+
+ point = mean (residues[j]->NB-> GetVector (), residues[j]->CA-> GetVector ());
+ residues[j]->backbone_list.push_back (point);
+
+
+ point = mean (residues[j]->CB-> GetVector (), residues[j]->CA-> GetVector ());
+ residues[j]->backbone_list.push_back (point);
+
+ for (unsigned int n=0; n<residues[j]->CB->bound.size ();n++) {
+ if (residues[j]->CB->bound[n]->atomType == "N.am") {
+ vect fol;
+ fol = residues[j]->CB->bound[n]-> GetVector ();
+ point = mean (fol, residues[j]->CB-> GetVector ());
+ residues[j]->backbone_list.push_back (point);
+
+ }
+ }
+
+ }
+ if (residues[j]->backbone_list.size()) {
+ for (unsigned int n =0; n<8; n++) {
+ residues[j]->refine_backbone ();
+ }
+
+ }
+
+ }
+ res_strings = vec;
+
+ }
+
+
+ Residue::Residue (){
+ backbone_style = 0;
+ backbone_visible = true;
+ hasCA = false;
+ hasNB = false;
+ hasCB = false;
+ backbone_color = color (0.8, 0.8, 0.f, 1.f);
+
+ backbone_list.clear ();
+ };
+
+ void Residue::refine_backbone (){
+ vector <vect> nb;
+ nb.push_back (backbone_list[0]);
+ for (unsigned int i=0; i<backbone_list.size ()-1; i++){
+ vect point;
+ point = mean (backbone_list[i], backbone_list [i+1]);
+ nb.push_back (point);
+ }
+ nb.push_back (backbone_list[backbone_list.size ()-1]);
+ backbone_list = nb;
+ }
+
+
+ Ring::Ring () {
+ alpha_atom = NULL;
+ IM_CAT = false;
+ N5ANION = false;
+ }
+
+ void Ring::complete_kekule () {
+ bool go_on = true;
+ while (go_on) {
+ go_on = false;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i]->kekule==5) {
+ if (bonds[i]->conjugated_to (2, this) && bonds[i]->conjugated_to (1, this)) {
+ bonds[i]->kekule =1;
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set to 1"<<endl;
+ }
+ else if (bonds[i]->conjugated_to (2, this)) {
+ bonds[i]->kekule =1;
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set to 1"<<endl;
+ }
+ else if (bonds[i]->conjugated_to (1, this) && !bonds[i]->atomPTR[0]->no2bond && !bonds[i]->atomPTR[1]->no2bond) {
+ bonds[i]->kekule =2;
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set to 2"<<endl;
+ bonds[i]->atomPTR[0]->no2bond = true;
+ bonds[i]->atomPTR[1]->no2bond = true;
+ }
+
+ else if (!bonds[i]->conjugated_to (2, this) && !bonds[i]->conjugated_to (1, this)) {
+ go_on = true;
+ }
+ }
+ }
+ }
+ }
+
+ bool Ring::all_aromatic () {
+ bool all_arom = true;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i]->kekule!=5) all_arom=false;
+ }
+ return all_arom;
+ }
+
+ void Ring::find_kekule_pseudoaromatic () {
+ cout <<"pseudo"<<endl;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if ((bonds[i]->atomPTR[0]->no2bond || bonds[i]->atomPTR[1]->no2bond) && bonds[i]->kekule==5) {
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<"set as 1"<<endl;
+ bonds[i]->kekule=1;
+ }
+ }
+ bool go_on = true;
+ while (go_on) {
+ go_on = false;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (((bonds[i]->atomPTR[0]->atomicNumber==7 && bonds[i]->atomPTR[0]->bound.size ()==2) || (bonds[i]->atomPTR[0]->atomicNumber==6 && bonds[i]->atomPTR[0]->bound.size ()==3)) &&
+ ((bonds[i]->atomPTR[1]->atomicNumber==7 && bonds[i]->atomPTR[1]->bound.size ()==2) || (bonds[i]->atomPTR[1]->atomicNumber==6 && bonds[i]->atomPTR[1]->bound.size ()==3)) &&
+ bonds[i]->conjugated_to (1, this) &&
+ !bonds[i]->conjugated_to (2, this) &&
+ bonds[i]->kekule==5 &&
+ !bonds[i]->atomPTR[0]->no2bond &&
+ !bonds[i]->atomPTR[1]->no2bond) {
+
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set as 2"<<endl;
+ bonds[i]->atomPTR[0]->no2bond = true;
+ bonds[i]->atomPTR[1]->no2bond = true;
+
+
+ bonds[i]->kekule=2;
+ go_on = true;
+
+ }
+ if (bonds[i]->conjugated_to (2, this) && bonds[i]->kekule==5) {
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set as 1"<<endl;
+ bonds[i]->kekule=1;
+ go_on = true;
+ }
+ }
+ }
+
+ go_on = true;
+ while (go_on) {
+ go_on = false;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (((bonds[i]->atomPTR[0]->atomicNumber==7) || (bonds[i]->atomPTR[0]->atomicNumber==6 && bonds[i]->atomPTR[0]->bound.size ()==3)) &&
+ ((bonds[i]->atomPTR[1]->atomicNumber==7) || (bonds[i]->atomPTR[1]->atomicNumber==6 && bonds[i]->atomPTR[1]->bound.size ()==3)) &&
+ bonds[i]->conjugated_to (1, this) &&
+ !bonds[i]->conjugated_to (2, this) &&
+ bonds[i]->kekule==5 &&
+ !bonds[i]->atomPTR[0]->no2bond &&
+ !bonds[i]->atomPTR[1]->no2bond) {
+
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set as 2"<<endl;
+ bonds[i]->atomPTR[0]->no2bond = true;
+ bonds[i]->atomPTR[1]->no2bond = true;
+
+
+ bonds[i]->kekule=2;
+ go_on = true;
+
+ }
+ if (bonds[i]->conjugated_to (2, this) && bonds[i]->kekule==5) {
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set as 1"<<endl;
+ bonds[i]->kekule=1;
+ go_on = true;
+ }
+ }
+
+
+
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i]->kekule == 5) {
+ bonds[i]->kekule=1;
+ cout<<"bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<" set as 1"<<endl;
+ }
+ }
+ }
+ }
+
+ void Ring::find_kekule () {
+
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if ((bonds[i]->atomPTR[0]->no2bond || bonds[i]->atomPTR[1]->no2bond) && bonds[i]->kekule==5) {
+ cout<<"find_kekule: bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<"set as 1"<<endl;
+ bonds[i]->kekule=1;
+ }
+ }
+
+ if (atoms.size ()==5) {
+ cout<<"find kekule 5 membered ring"<<endl;
+ if (alpha_atom) {
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if ((bonds[i]->atomPTR[0]==alpha_atom || bonds[i]->atomPTR[1]==alpha_atom) && bonds[i]->kekule==5) {
+ bonds[i]->kekule=1;
+
+ }
+ }
+ complete_kekule ();
+ }
+ else {
+ if (all_aromatic ()) bonds[0]->kekule =1;
+ complete_kekule ();
+ }
+
+ }
+ else if (atoms.size ()==6) {
+ cout<<"find kekule 6 membered ring"<<endl;
+
+
+ if (all_aromatic ()) {
+ cout <<"all aromatic"<<endl;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i]->in_ring.size()>1 && (!bonds[i]->atomPTR[0]->no2bond && !bonds[i]->atomPTR[1]->no2bond)) {
+ bonds[i]->kekule = 2;
+ cout<<"ring fusion bond "<<bonds[i]->atomPTR[0]->ID<<" "<<bonds[i]->atomPTR[1]->ID<<"set as 2"<<endl;
+ bonds[i]->atomPTR[0]->no2bond = true;
+ bonds[i]->atomPTR[1]->no2bond = true;
+
+ }
+ }
+ }
+
+ if (all_aromatic ()) {
+ bonds[0]->kekule =1;
+ cout<<"random bond "<<bonds[0]->atomPTR[0]->ID<<" "<<bonds[0]->atomPTR[1]->ID<<"set as 1"<<endl;
+ }
+ complete_kekule ();
+
+ }
+
+ }
+ unsigned int Ring::count (int an) {
+ unsigned int out = 0;
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i]->atomicNumber == an) out+=1;
+ }
+ return out;
+ }
+
+ void Ring::test_kekule_aromaticity () {
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ bool not_ar = true;
+ for (unsigned int j=0; j<atoms[i]->bonds.size (); j++) {
+ if (atoms[i]->bonds[j]->kekule==2 && atoms[i]->bonds[j]->mol2Type==5) not_ar=false;
+ }
+ if (atoms[i]->atomicNumber==8 || atoms[i]->atomicNumber==16) not_ar=false;
+ if (atoms[i]->atomicNumber==7 && atoms[i]->bound.size ()==3 && atoms.size ()!=6) not_ar=false;
+ if (not_ar) {
+ aromatic = false;
+ break;
+ }
+ }
+ }
+
+ void Ring::test_aromaticity () {
+
+ bool ar = false;
+ bool quit = false;
+ unsigned int size = atoms.size ();
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i]->bound.size ()>3) {
+ aromatic =false;
+ quit = true;
+ atoms[i]->no2bond = true;
+ cout <<atoms[i]->ID<<" set as no2bond"<<endl;
+ // return;
+ }
+ for (unsigned int j=0; j<atoms[i]->bound.size (); j++) {
+ if (!atoms[i]->bound[j]->is_in_ring (this) && atoms[i]->bonds[j]->mol2Type==2) {
+ aromatic=false;
+ quit = true;
+ atoms[i]->no2bond = true;
+ cout <<atoms[i]->ID<<" set as no2bond"<<endl;
+ // return;
+ }
+ }
+ }
+ if (quit) return;
+ int pyrrole_n = 0;
+ int pyridine_n = 0;
+ int os = 0;
+ Atom *lasto = NULL;
+ Atom *lastn = NULL;
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i]->atomicNumber==8 || atoms[i]->atomicNumber==16) {
+ os ++;
+ lasto = atoms[i];
+ }
+ if (atoms[i]->atomicNumber==7 && atoms[i]->bound.size ()==3) {
+ pyrrole_n++;
+ lastn = atoms[i];
+ }
+ if (atoms[i]->atomicNumber==7 && atoms[i]->bound.size ()==2) {
+ pyridine_n++;
+ }
+ }
+
+
+ if (size<5) ar=false;
+
+ else if (size ==5) {
+
+ if (os) { //furane thiophene
+ if (os>1) ar=false;
+ else {
+ ar=true;
+ kekule_type = 0;
+ alpha_atom = lasto;
+ cout <<lasto->ID<<" set as no2bond"<<endl;
+ lasto->no2bond = true;
+ if (pyrrole_n) IM_CAT = true;
+ }
+ }
+ else if (pyrrole_n==1) { //pyrrole , pyrazole, imidazole, triazole && tetrazole
+ ar=true;
+ alpha_atom = lastn;
+ lastn->no2bond = true;
+ kekule_type = 0;
+
+ }
+ else if (pyrrole_n==2 && pyridine_n) {
+ cout <<"false"<<endl;
+ ar = false;
+ }
+ else if (pyrrole_n==2) {//imidaziolium cation
+
+ int nCC =0, NH=0;
+ ZNBond *lastCC;
+ for (unsigned int i=0; i<bonds.size (); i++) {
+ if (bonds[i]->atomPTR[0]->atomicNumber==6 && bonds[i]->atomPTR[1]->atomicNumber==6) {
+ nCC++;
+ lastCC = bonds[i];
+ }
+ }
+ for (unsigned int i=0; i<atoms.size (); i++) {
+ if (atoms[i]->atomicNumber==7 && atoms[i]->bonded_to (1, 1)) {
+ NH++;
+ }
+ }
+ if (nCC==1 && NH==2) {//imidazolium
+ cout <<"imidazolium"<<endl;
+ lastCC->kekule=2;
+ lastCC->atomPTR[0]->no2bond = true;
+ lastCC->atomPTR[0]->no2bond = true;
+ kekule_type =4;
+ ar = true;
+ alpha_atom = NULL;
+ IM_CAT = true;
+ }
+ else {
+ ar = false;
+ }
+
+ }
+ else if (pyridine_n ==4 && !pyrrole_n) { //tetrazole anion
+ cout<<"tetrazole anion"<<endl;
+ ar = true;
+ kekule_type = 3;
+ N5ANION = true;
+ alpha_atom = NULL;
+ }
+
+ else ar=false;
+ }
+ else if (size ==6) {
+ kekule_type = 3;
+ if (os) ar=false;
+ else ar=true;
+ }
+ else ar=false;
+
+ aromatic = ar;
+
+ }
+
+
+
+
+ vect find_mass_center (vector<Atom*>& invec){
+
+ unsigned int i;
+ vect midCoo;
+
+
+ unsigned int numMid = 0;
+ for (i = 0; i < invec.size(); i++) {
+ vect a = sum (midCoo, invec[i]-> GetVector ());
+ midCoo = a;
+ numMid++;
+
+ }
+
+ midCoo.multiply (1.0f/(float) numMid);
+
+ /*
+ float radius = 0.0;
+ for (i = 0; i < invec.size(); i++) {
+
+ float r2 = (invec[i]-> GetVector ()[0] - midCoo[0]) *(invec[i]-> GetVector ()[0] - midCoo[0]) +
+ (invec[i]-> GetVector ()[1] - midCoo[1]) *(invec[i]-> GetVector ()[1] - midCoo[1]) +
+ (invec[i]-> GetVector ()[2] - midCoo[2]) *(invec[i]-> GetVector ()[2] - midCoo[2]);
+ if (r2 > radius) {
+ radius = r2;
+ }
+ }
+
+
+
+ return midCoo;
+
+ }
+
+ */
+
diff --git a/Zodiac.cc b/Zodiac.cc
new file mode 100644
index 0000000..62d64eb
--- /dev/null
+++ b/Zodiac.cc
@@ -0,0 +1,172 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifdef HAPTICS
+#include <HD/hd.h>
+#endif //HAPTICS
+
+#include "qwidget.h"
+#include <qapplication.h>
+#include "ZNdata.h"
+#include <string>
+#include "constants.h"
+#include "ddwin.h"
+#include "MMFF.h"
+
+#include <QTranslator>
+#include <QLocale>
+#ifdef HAPTICS
+//#include "haptics.h"
+
+
+
+static HHD ghHD = HD_INVALID_HANDLE;
+static HDSchedulerHandle gSchedulerCallback = HD_INVALID_HANDLE;
+HDSchedulerHandle gCallbackHandle = 0;
+HDCallbackCode HDCALLBACK Haptics(void *);
+#endif //HAPTICS
+
+int main( int argc, char **argv )
+{
+
+// wiimote_kickstart() ;
+
+
+ QApplication a( argc, argv );
+
+ //QString locale = QLocale::system().name();
+ // QTranslator translator;
+ // translator.load(QString("zodiac_") + locale);
+ // a.installTranslator(&translator);
+
+
+
+
+ Data dat (&a);
+
+ DDWin ddwin (0, &dat);
+ dat.load_haptic_device ();
+
+#ifdef HAPTICS
+ // - haptics - //
+ // Call the haptics initialization function
+// HapticsClass::StaticInit();
+ // - haptics - //
+
+
+ std::cout << "haptics callback" << "\n";
+ gSchedulerCallback = hdScheduleAsynchronous(
+ Haptics, &dat, HD_MAX_SCHEDULER_PRIORITY);
+
+ HDErrorInfo error;
+ ghHD = hdInitDevice(HD_DEFAULT_DEVICE);
+ if (HD_DEVICE_ERROR(error = hdGetError()))
+ {
+
+ fprintf(stderr, "\nPress any key to quit.\n");
+ getchar();
+ //exit(-1);
+ }
+ printf("Found device %s\n",hdGetString(HD_DEVICE_MODEL_TYPE));
+ hdEnable(HD_FORCE_OUTPUT);
+ hdEnable(HD_MAX_FORCE_CLAMPING);
+ hdStartScheduler ();
+ // current_force_x = new double (0.);
+ // current_force_y = new double (0.);
+ // current_force_z = new double (0.);
+ if (HD_DEVICE_ERROR(error = hdGetError()))
+ {
+
+ fprintf(stderr, "\nPress any key to quit.\n");
+ return -1;
+ }
+#endif //HAPTICS
+
+ ddwin.show ();
+
+ if (argc >1) {
+ for (unsigned int i=1; i<argc; i++) {
+ ddwin.load_file (argv[i]);
+ }
+ }
+ int exitCode = a.exec();
+
+#ifdef HAPTICS
+ // - haptics - //
+// gHaptics.uninit();
+ hdStopScheduler();
+ hdUnschedule(gSchedulerCallback);
+
+ if (ghHD != HD_INVALID_HANDLE)
+ {
+ hdDisableDevice(ghHD);
+ ghHD = HD_INVALID_HANDLE;
+ }
+ // - haptics - //
+#endif //HAPTICS
+
+ return exitCode;
+
+}
+
+
+
+#ifdef HAPTICS
+HDCallbackCode HDCALLBACK Haptics(void *data)
+{
+
+ hdBeginFrame(ghHD);
+ Data *dat = (Data *) data;
+
+ static HDboolean bRenderForce = 0;
+ HDErrorInfo error;
+
+ HDint nCurrentButtons, nLastButtons;
+ double position [3];
+ double angles [3];
+
+
+ hdGetDoublev(HD_CURRENT_GIMBAL_ANGLES,angles);
+ hdGetDoublev(HD_CURRENT_POSITION, position);
+ dat -> current_position_x = position[0];
+ dat -> current_position_y = position[1];
+ dat -> current_position_z = position[2];
+
+
+
+
+ dat -> current_pitch = angles[2];
+ dat -> current_roll = angles[0];
+ dat -> current_yaw = angles[1];
+
+
+// cerr << dat ->current_pitch << endl;
+double force [3];
+force [0] = dat -> current_force_x;
+force [1] = dat -> current_force_y;
+force [2] = dat -> current_force_z;
+
+ hdSetDoublev(HD_CURRENT_FORCE, force);
+ hdEndFrame(ghHD);
+ return HD_CALLBACK_CONTINUE;
+
+}
+#endif // HAPTICS
+
+
diff --git a/Zodiac.pro b/Zodiac.pro
new file mode 100644
index 0000000..deb3483
--- /dev/null
+++ b/Zodiac.pro
@@ -0,0 +1,144 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Tue 30. Sep 18:26:14 2008
+######################################################################
+
+TEMPLATE = app
+TARGET = Zodiac
+DEPENDPATH += . \
+ debug \
+ forcefields \
+ headers \
+ molsketch_helium \
+ molsketch_helium\i18n \
+ molsketch_helium\part
+INCLUDEPATH += . headers molsketch_helium
+CONFIG += qt assistant
+QT += qt3support opengl svg
+unix:LIBS += -L/usr/local/lib -L/usr/lib -lopenbabel
+win32:LIBS += -L"C:\Program Files (x86)\openbabel\lib"
+win32:LIBS += -L"C:\Program Files\openbabel\lib" -lopenbabel-2
+win32 {
+INCLUDEPATH += "C:\Program Files (x86)\openbabel\include\openbabel-2.0"
+INCLUDEPATH += "C:\Program Files\openbabel\include\openbabel-2.0"
+}
+unix: INCLUDEPATH += /usr/local/include/openbabel-2.0 /usr/include/openbabel-2.0
+unix: RC_FILE = icons/zeden.icns
+win32: RC_FILE = win_rc.rc
+
+unix:exe.path = /usr/local/bin
+unix:exe.files = Zodiac
+
+unix:INSTALLS +=exe
+
+# Input
+HEADERS += obabel_includes.h \
+ forcefields/forcefieldghemical.h \
+ forcefields/forcefieldmmff94.h \
+ forcefields/forcefielduff.h \
+ headers/actions.h \
+ headers/arcball.h \
+ headers/builder.h \
+ headers/chemscore.h \
+ headers/cmat.h \
+ headers/command.h \
+ headers/constants.h \
+ headers/cutoffGrid.h \
+ headers/database.h \
+ headers/datagrid.h \
+ headers/ddwin.h \
+ headers/FF.h \
+ headers/function.h \
+ headers/graphical_object.h \
+ headers/ils.h \
+ headers/iodevice.h \
+ headers/LookUpTable.h \
+ headers/MarchingCubes.h \
+ headers/maths.h \
+ headers/menu.h \
+ headers/minimize.h \
+ headers/MMFF.h \
+ headers/myline.h \
+ headers/nms.h \
+ headers/optimiser.h \
+ headers/plants.h \
+ headers/plants_mainwin.h \
+ headers/plantsconfig.h \
+ headers/PLP.h \
+ headers/ply.h \
+ headers/pso.h \
+ headers/subscrpt.h \
+ headers/thread.h \
+ headers/vec.h \
+ headers/wiimote.h \
+ headers/ZNdata.h \
+ headers/ZNmolecule.h \
+ molsketch_helium/atom.h \
+ molsketch_helium/bond.h \
+ molsketch_helium/commands.h \
+ molsketch_helium/element.h \
+ molsketch_helium/fileio.h \
+ molsketch_helium/mainwindow.h \
+ molsketch_helium/molecule.h \
+ molsketch_helium/mollibitem.h \
+ molsketch_helium/molscene.h \
+ molsketch_helium/molview.h \
+ molsketch_helium/periodictablewidget.h \
+ molsketch_helium/settings.h \
+ molsketch_helium/part/molsketch_factory.h \
+ molsketch_helium/part/molsketchpart.h \
+ molsketch_helium/part/molsketchpart_shell.h
+FORMS += zodiac.ui molsketch_helium/settings.ui
+SOURCES += actions.cc \
+ arcball.cc \
+ builder.cc \
+ chemscore.cc \
+ command.cc \
+ constants.cc \
+ database.cc \
+ datagrid.cc \
+ ddwin.cc \
+ FF.cc \
+ graphical_object.cc \
+ iodevice.cc \
+ MarchingCubes.cc \
+ maths.cc \
+ menu.cc \
+ minimize.cc \
+ MMFF.cc \
+ myline.cc \
+ plants.cc \
+ plants_mainwin.cc \
+ plantsconfig.cc \
+ PLP.cc \
+ ply.c \
+ povray.cc \
+ thread.cc \
+ wiimote.cc \
+ ZNdata.cc \
+ ZNmolecule.cc \
+ Zodiac.cc \
+ forcefields/forcefieldghemical.cpp \
+ forcefields/forcefieldmmff94.cpp \
+ forcefields/forcefielduff.cpp \
+ molsketch_helium/atom.cpp \
+ molsketch_helium/bond.cpp \
+ molsketch_helium/commands.cpp \
+ molsketch_helium/element.cpp \
+ molsketch_helium/fileio.cpp \
+ molsketch_helium/mainwindow.cpp \
+ molsketch_helium/molecule.cpp \
+ molsketch_helium/mollibitem.cpp \
+ molsketch_helium/molscene.cpp \
+ molsketch_helium/molview.cpp \
+ molsketch_helium/periodictablewidget.cpp \
+ molsketch_helium/settings.cpp \
+ molsketch_helium/part/molsketch_factory.cpp \
+ molsketch_helium/part/molsketchpart.cpp \
+ molsketch_helium/part/molsketchpart_shell.cpp
+RESOURCES += resources.qrc \
+ zodiac.qrc \
+ molsketch_helium/molsketch.qrc \
+ molsketch_helium/part/molsketchpart_shell.qrc
+TRANSLATIONS += molsketch_helium/i18n/molsketch_cs.ts \
+ molsketch_helium/i18n/molsketch_nl.ts \
+ molsketch_helium/i18n/molsketch_pt_BR.ts
diff --git a/actions.cc b/actions.cc
new file mode 100644
index 0000000..86b56e0
--- /dev/null
+++ b/actions.cc
@@ -0,0 +1,536 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#include "actions.h"
+class Data;
+
+Actions::Actions (Data *dat) {
+ data = dat;
+}
+
+
+double Actions::compute_total_energy (ZNMolecule *mol) {
+Chemscore *chem = new Chemscore;
+ chem -> initialize_interaction (mol, data ->ddwin ->molecules);
+ chem -> load_nonbonded_interactions ();
+ float e = chem ->compute_total_energy ();
+ delete chem;
+ return e;
+// data->mmff->initialize (mol, data -> ddwin ->molecules);
+// return data -> mmff->compute_total_energy ();
+}
+
+vector <double> Actions::compute_total_energy (Database *dat) {
+ vector <double> v;
+ // cerr << "entries "<< dat->count_entries ()<< endl;
+ for (unsigned int i = 0; i < dat ->count_entries (); i ++) {
+ v.push_back (compute_total_energy (dat -> get_molecule (i)));
+ }
+ return v;
+}
+
+
+double Actions::compute_logP (ZNMolecule *mol) {
+
+ OBDescriptor* pDesc = OBDescriptor::FindType("logP");
+ if(pDesc)
+ return pDesc->Predict(mol);
+ else return 0. ;
+
+}
+
+vector <double> Actions::compute_logP (Database *dat) {
+ vector <double> v;
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ v.push_back (compute_logP (dat -> get_molecule (i)));
+ }
+ return v;
+}
+
+
+
+void Actions::minimise (ZNMolecule *mol) {
+
+ data -> undo_stack -> beginMacro ("Energy Minimisation");
+ MoveAtomsCommand *command = new MoveAtomsCommand (data -> ddwin -> gl, 1);
+ FOR_ATOMS_OF_MOL(a, mol) {
+ command -> add (&*a, get_coordinates(&*a));
+ }
+ data -> ddwin -> execute (command);
+
+ // cerr << "create" << endl;
+ MinimiseThread *thread = new MinimiseThread (0, data -> ddwin);
+ // cerr << "set" << endl;
+ thread -> set_molecule (mol);
+ // cerr << "go" << endl;
+ data ->ddwin ->run_thread (thread);
+ // thread -> start ();
+ data -> ddwin -> connect (thread, SIGNAL (finished ()), data -> ddwin, SLOT (end_minimisation ()));
+}
+
+
+
+
+void Actions::minimise (Database *dat) {
+ DatabaseMinimiseThread *thread = new DatabaseMinimiseThread (0, dat, data -> ddwin);
+ data ->ddwin ->run_thread (thread);
+ //thread -> start ();
+}
+
+
+
+
+
+void Actions::change_display_style (ZNMolecule *mol, int ats, int bds, int backds) {
+ ChangeDisplayStyleCommand *command = new ChangeDisplayStyleCommand (data -> ddwin -> gl);
+ FOR_ATOMS_OF_MOL(a, mol) {
+ // int new_style = ats;
+ command -> add (&*a, ats);
+ }
+ FOR_BONDS_OF_MOL (b, mol) {
+ // int new_style = bds;
+ command -> add (&*b, bds);
+ }
+ if (mol -> selection) { //selected bonds are not in selection... we must find them checking the atoms.
+ FOR_ATOMS_OF_MOL(a, mol) {
+ // int new_style = ats;
+ ZNMolecule * parent_mol = (ZNMolecule *) a -> GetParent ();
+ FOR_NBORS_OF_ATOM (n, &*a) {
+
+ if (get_selected (&*n)) {
+ if (a ->GetIdx () < n -> GetIdx ()) {
+ ZNBond *bo = parent_mol ->GetBond (&*n, &*a);
+ command -> add (bo, bds);
+ }
+ }
+ }
+ }
+ }
+ command -> add (mol, ats, bds, backds);
+ command -> set_name ();
+ data ->ddwin ->execute (command);
+ data ->ddwin ->gl ->draw_molecule (mol);
+}
+
+
+
+
+void Actions::change_display_style (Database *dat, int ats, int bds, int backds) {
+ data -> undo_stack -> beginMacro ("Change Database Display Style");
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ change_display_style (dat ->get_molecule (i), ats, bds, backds);
+ }
+ data ->undo_stack ->endMacro ();
+
+}
+
+
+
+void Actions::hide_hydrogens (ZNMolecule *mol) {
+ data ->ddwin ->gl ->hide_hydrogens (mol);
+}
+
+void Actions::hide_hydrogens (Database *dat) {
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ hide_hydrogens (dat ->get_molecule (i));
+ }
+
+}
+
+void Actions::hide_nonpolar_hydrogens (ZNMolecule *mol) {
+ data ->ddwin ->gl ->hide_nonpolar_hydrogens (mol);
+}
+
+void Actions::hide_nonpolar_hydrogens (Database *dat) {
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ hide_nonpolar_hydrogens (dat ->get_molecule (i));
+ }
+
+}
+
+void Actions::hide_all_atoms (ZNMolecule *mol) {
+ data ->ddwin ->gl ->hide_all_atoms (mol);
+}
+
+void Actions::hide_all_atoms (Database *dat) {
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ hide_all_atoms (dat ->get_molecule (i));
+ }
+
+}
+
+
+
+void Actions::show_all_atoms (ZNMolecule *mol) {
+ data ->ddwin ->gl ->show_all_atoms (mol);
+}
+
+void Actions::show_all_atoms (Database *dat) {
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ show_all_atoms (dat ->get_molecule (i));
+ }
+
+}
+
+void Actions::apply_color_masks (vector <color_mask> masks, ZNMolecule *mol) {
+ data ->ddwin ->gl ->apply_color_masks (masks, mol);
+}
+
+void Actions::apply_color_masks (vector <color_mask> masks, Database *dat) {
+ data ->undo_stack -> beginMacro ("Color Database");
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ apply_color_masks (masks, dat ->get_molecule (i));
+ }
+ data ->undo_stack -> endMacro ();
+
+}
+
+void Actions::save_as (ZNMolecule *mol, string filename) {
+
+ ofstream ofs(filename.c_str ());
+ OBConversion conv;
+ conv.SetOutStream(&ofs);
+ OBFormat* outFormat = conv.FormatFromExt(filename.c_str ());
+ if (outFormat) {
+ conv.SetOutFormat (outFormat);
+ conv.Write (mol);
+ }
+ ofs.close ();
+
+}
+
+void Actions::save_session_as (string filename) {
+ ofstream ofs(filename.c_str ());
+ ofs << "#ROTATION_MATRIX "<<data ->ddwin ->gl ->Transform.M [0]<<" "<<data ->ddwin ->gl ->Transform.M [1]<<" "<<data ->ddwin ->gl ->Transform.M [2]<<" "<<
+ data ->ddwin ->gl ->Transform.M [4]<<" "<<data ->ddwin ->gl ->Transform.M [5]<<" "<<data ->ddwin ->gl ->Transform.M [6]<<" "<<
+ data ->ddwin ->gl ->Transform.M [8]<<" "<<data ->ddwin ->gl ->Transform.M [9]<<" "<<data ->ddwin ->gl ->Transform.M [10]<<endl;
+ ofs << "#TRANSLATION "<<data ->ddwin ->gl ->view_translations.x()<<" "<<data ->ddwin ->gl ->view_translations.y()<<" "<<data ->ddwin ->gl ->view_translations.z()<<endl;
+ ofs << "#CENTER_OF_ROTATION "<<data ->ddwin ->gl ->center_of_rotation.x()<<" "<<data ->ddwin ->gl ->center_of_rotation.y()<<" "<<data ->ddwin ->gl ->center_of_rotation.z()<<endl;
+ for (unsigned int i = 1; i < data ->ddwin ->molecules.size (); i++) {
+ ZNMolecule *mol = data ->ddwin ->molecules[i];
+ if (!mol ->selection && !mol ->multi) {
+ ofs << "#BEGIN_MOLECULE"<<endl;
+ ofs << "#BEGIN_MOLECULAR_DATA"<<endl;
+ OBConversion conv;
+ conv.SetOutStream(&ofs);
+ conv.SetOutFormat ("MOL2");
+ conv.Write (mol);
+ ofs << "#END_MOLECULAR_DATA"<<endl;
+ int ads = get_atoms_display_style (mol);
+ int bds = get_bonds_display_style (mol);
+ ofs << "#ATOMS_DISPLAY_STYLE "<< ads<< endl;
+ ofs << "#BONDS_DISPLAY_STYLE "<< bds<< endl;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ color c = get_color (&*a);
+ int ds = get_ds (&*a);
+ ofs << "#ATOMIC_COLOR "<<a->GetIdx ()<<" "<<c.redF ()<<" "<<c.greenF ()<<" "<<c.blueF ()<<" "<<c.alphaF ()<<endl;
+ if (ds != ads) ofs << "#ATOMIC_DISPLAY_STYLE "<< a ->GetIdx ()<<" "<<ds<<endl;
+ }
+ FOR_BONDS_OF_MOL (b, mol) {
+ int ds = get_ds (&*b);
+ if (ds != bds) ofs << "#BOND_DISPLAY_STYLE "<< b ->GetIdx ()<<" "<<ds<<endl;
+ }
+ ofs << "#END_MOLECULE"<<endl;
+ }
+ }
+ for (unsigned int j = 0; j < data ->ddwin ->graphical_objects.size (); j++) {
+ if (data ->ddwin ->graphical_objects[j] -> is_surface ()) {
+ ofs <<"#BEGIN_SURFACE"<<endl;
+ Surface *surf = (Surface *) data ->ddwin ->graphical_objects[j];
+ for (unsigned int f = 0; f < surf ->faces.size (); f++) {
+ ofs <<"#FACE "<<surf ->faces[f] ->v1 -> coordinates.x ()<<" "<<surf ->faces[f] ->v1 -> coordinates.y ()<<" "<<surf ->faces[f] ->v1 -> coordinates.z ()<<" ";
+ ofs <<surf ->faces[f] ->v1 -> normal.x ()<<" "<<surf ->faces[f] ->v1 -> normal.y ()<<" "<<surf ->faces[f] ->v1 -> normal.z ()<<" ";
+ ofs <<surf ->faces[f] ->v1 -> col.redF ()<<" "<<surf ->faces[f] ->v1 -> col.greenF ()<<" "<<surf ->faces[f] ->v1 -> col.blueF ()<<" "<<surf ->faces[f] ->v1 -> col.alphaF ()<<" ";
+
+ ofs <<surf ->faces[f] ->v2 -> coordinates.x ()<<" "<<surf ->faces[f] ->v2 -> coordinates.y ()<<" "<<surf ->faces[f] ->v2 -> coordinates.z ()<<" ";
+ ofs <<surf ->faces[f] ->v2 -> normal.x ()<<" "<<surf ->faces[f] ->v2 -> normal.y ()<<" "<<surf ->faces[f] ->v2 -> normal.z ()<<" ";
+ ofs <<surf ->faces[f] ->v2 -> col.redF ()<<" "<<surf ->faces[f] ->v2 -> col.greenF ()<<" "<<surf ->faces[f] ->v2 -> col.blueF ()<<" "<<surf ->faces[f] ->v2 -> col.alphaF ()<<" ";
+
+ ofs <<surf ->faces[f] ->v3 -> coordinates.x ()<<" "<<surf ->faces[f] ->v3 -> coordinates.y ()<<" "<<surf ->faces[f] ->v3 -> coordinates.z ()<<" ";
+ ofs <<surf ->faces[f] ->v3 -> normal.x ()<<" "<<surf ->faces[f] ->v3 -> normal.y ()<<" "<<surf ->faces[f] ->v3 -> normal.z ()<<" ";
+ ofs <<surf ->faces[f] ->v3 -> col.redF ()<<" "<<surf ->faces[f] ->v3 -> col.greenF ()<<" "<<surf ->faces[f] ->v3 -> col.blueF ()<<" "<<surf ->faces[f] ->v3 -> col.alphaF ()<<endl;
+ }
+ ofs <<"#END_SURFACE"<<endl;
+ }
+ }
+
+
+ ofs.close ();
+}
+
+void Actions::load_session (string filename) {
+ bool reading_molecule = false, reading_surf = false;
+ // bool matrix = false;
+ data -> undo_stack -> beginMacro ("Load session ");
+ ifstream ifs (filename.c_str ());
+ string buffer;
+ stringstream ss;
+ ZNMolecule *last_mol = NULL;
+ Surface *last_surf = NULL;
+ while (getline(ifs, buffer)) {
+ istringstream line(buffer);
+ string token;
+ line >> token;
+ if (token == "#END_MOLECULAR_DATA") {
+ ZNMolecule *mol = new ZNMolecule ();
+ last_mol = mol;
+ reading_molecule = false;
+ OBConversion conv;
+ stringstream ss1 (ss.str ());
+ // cerr << ss.str ()<<endl;
+ conv.SetInStream(&ss1);
+ conv.SetInFormat ("MOL2");
+ conv.Read (mol);
+ finalise_molecule (mol);
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol, data ->ddwin);
+ data -> ddwin -> execute (command);
+ ss.str(" ");
+ // cerr << ss.str ()<<endl;
+ }
+ else if (token == "#END_SURFACE" && reading_surf) {
+ Surface *surf = last_surf;
+ surf -> lst = data ->ddwin -> gl -> new_list ();
+ surf ->render ();
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (surf, data ->ddwin);
+ data -> ddwin -> execute (command);
+ last_surf = NULL;
+ reading_surf = false;
+ }
+ else if (reading_molecule) {
+ ss << buffer<<endl;
+ }
+ else if (token == "#ATOMS_DISPLAY_STYLE" && last_mol) {
+ int ds;
+ line >> ds;
+ set_atoms_display_style (last_mol, ds);
+ }
+ else if (token == "#BONDS_DISPLAY_STYLE" && last_mol) {
+ int ds;
+ line >> ds;
+ set_bonds_display_style (last_mol, ds);
+ }
+ else if (token == "#ATOMIC_COLOR" && last_mol) {
+ int n;
+ float r, g, b, a;
+ line >> n;
+ line >> r;
+ line >> g;
+ line >> b;
+ line >> a;
+ set_color (last_mol ->GetAtom (n), color (r, g, b, a));
+ }
+ else if (token == "#ATOMIC_DISPLAY_STYLE" && last_mol) {
+ int n, ds;
+ line >> n;
+ line >> ds;
+ set_ds (last_mol ->GetAtom (n), ds);
+ }
+ else if (token == "#BOND_DISPLAY_STYLE" && last_mol) {
+ int n, ds;
+ line >> n;
+ line >> ds;
+ set_ds (last_mol ->GetBond (n), ds);
+ }
+ else if (token == "#FACE" and reading_surf) {
+ SurfFace *face = new SurfFace;
+ float x, y, z;
+ float r, g, b, a;
+ SurfVertex *v1 = new SurfVertex ();
+ line >> x;
+ line >> y;
+ line >> z;
+ v1 ->coordinates = vect (x, y, z);
+ line >> x;
+ line >> y;
+ line >> z;
+ v1 ->normal = vect (x, y, z);
+ line >> r;
+ line >> g;
+ line >> b;
+ line >> a;
+ v1 ->col = color (r, g, b, a);
+
+ SurfVertex *v2 = new SurfVertex;
+ line >> x;
+ line >> y;
+ line >> z;
+ v2 ->coordinates = vect (x, y, z);
+ line >> x;
+ line >> y;
+ line >> z;
+ v2 ->normal = vect (x, y, z);
+ line >> r;
+ line >> g;
+ line >> b;
+ line >> a;
+ v2 ->col = color (r, g, b, a);
+
+ SurfVertex *v3 = new SurfVertex;
+ line >> x;
+ line >> y;
+ line >> z;
+ v3 ->coordinates = vect (x, y, z);
+ line >> x;
+ line >> y;
+ line >> z;
+ v3 ->normal = vect (x, y, z);
+ line >> r;
+ line >> g;
+ line >> b;
+ line >> a;
+ v3 ->col = color (r, g, b, a);
+ face ->v1 = v1;
+ face ->v2 = v2;
+ face ->v3 = v3;
+ last_surf ->faces.push_back (face);
+ last_surf ->vertices.push_back (v1);
+ last_surf ->vertices.push_back (v2);
+ last_surf ->vertices.push_back (v3);
+
+ }
+ else if (token == "#ROTATION_MATRIX") {
+ float m0, m1, m2, m3, m4, m5, m6, m7, m8;
+ line >> m0;
+ line >> m1;
+ line >> m2;
+ line >> m3;
+ line >> m4;
+ line >> m5;
+ line >> m6;
+ line >> m7;
+ line >> m8;
+ ChangeFloatCommand *command0 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [0], m0, data ->ddwin ->gl);
+ ChangeFloatCommand *command1 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [1], m1, data ->ddwin ->gl);
+ ChangeFloatCommand *command2 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [2], m2, data ->ddwin ->gl);
+ ChangeFloatCommand *command3 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [4], m3, data ->ddwin ->gl);
+ ChangeFloatCommand *command4 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [5], m4, data ->ddwin ->gl);
+ ChangeFloatCommand *command5 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [6], m5, data ->ddwin ->gl);
+ ChangeFloatCommand *command6 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [8], m6, data ->ddwin ->gl);
+ ChangeFloatCommand *command7 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [9], m7, data ->ddwin ->gl);
+ ChangeFloatCommand *command8 = new ChangeFloatCommand (data ->ddwin ->gl ->Transform.M [10], m8, data ->ddwin ->gl);
+ ChangeFloatCommand *command10 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [0], m0, data ->ddwin ->gl);
+ ChangeFloatCommand *command11 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [1], m1, data ->ddwin ->gl);
+ ChangeFloatCommand *command12 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [2], m2, data ->ddwin ->gl);
+ ChangeFloatCommand *command13 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [3], m3, data ->ddwin ->gl);
+ ChangeFloatCommand *command14 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [4], m4, data ->ddwin ->gl);
+ ChangeFloatCommand *command15 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [5], m5, data ->ddwin ->gl);
+ ChangeFloatCommand *command16 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [6], m6, data ->ddwin ->gl);
+ ChangeFloatCommand *command17 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [7], m7, data ->ddwin ->gl);
+ ChangeFloatCommand *command18 = new ChangeFloatCommand (data ->ddwin ->gl ->LastRot.M [8], m8, data ->ddwin ->gl);
+ data -> ddwin -> execute (command0);
+ data -> ddwin -> execute (command1);
+ data -> ddwin -> execute (command2);
+ data -> ddwin -> execute (command3);
+ data -> ddwin -> execute (command4);
+ data -> ddwin -> execute (command5);
+ data -> ddwin -> execute (command6);
+ data -> ddwin -> execute (command7);
+ data -> ddwin -> execute (command8);
+ data -> ddwin -> execute (command10);
+ data -> ddwin -> execute (command11);
+ data -> ddwin -> execute (command12);
+ data -> ddwin -> execute (command13);
+ data -> ddwin -> execute (command14);
+ data -> ddwin -> execute (command15);
+ data -> ddwin -> execute (command16);
+ data -> ddwin -> execute (command17);
+ data -> ddwin -> execute (command18);
+ }
+ else if (token == "#BEGIN_MOLECULAR_DATA") {
+ reading_molecule = true;
+ }
+ else if (token == "#BEGIN_SURFACE") {
+ last_surf = new Surface ();
+ reading_surf = true;
+ }
+ else if (token == "#TRANSLATION") {
+ float trvx, trvy, trvz;
+ line >> trvx;
+ line >> trvy;
+ line >> trvz;
+ ChangeVectorCommand *command = new ChangeVectorCommand (data ->ddwin ->gl ->view_translations, vect (trvx, trvy, trvz), data ->ddwin ->gl);
+ data -> ddwin -> execute (command);
+ }
+ else if (token == "#CENTER_OF_ROTATION") {
+ float crx, cry, crz;
+ line >> crx;
+ line >> cry;
+ line >> crz;
+ ChangeVectorCommand *command = new ChangeVectorCommand (data ->ddwin ->gl ->center_of_rotation, vect (crx, cry, crz), data ->ddwin ->gl);
+ data -> ddwin -> execute (command);
+ }
+
+ }
+ data ->undo_stack ->endMacro ();
+}
+
+void Actions::save_as (Database *dat, string filename) {
+ ofstream ofs(filename.c_str ());
+ OBConversion conv;
+ conv.SetOutStream(&ofs);
+ OBFormat* outFormat = conv.FormatFromExt(filename.c_str ());
+ conv.SetOutFormat (outFormat);
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ conv.Write (dat ->get_molecule (i));
+ }
+ string csv_name = filename+".csv";
+ save_csv (dat, csv_name);
+}
+
+void Actions::save_csv (Database *dat, string filename) {
+ ofstream f (filename.c_str ());
+ for (unsigned int i = 0; i < dat -> field_names.size (); i ++) {
+ f << dat ->field_names[i];
+ if (i != dat -> count_fields ()-1) f<<",";
+ }
+ f<<endl;
+ for (unsigned int j = 0; j < dat -> count_entries (); j ++) {
+ for (unsigned int i = 0; i < dat -> count_fields (); i ++) {
+ f << dat ->entries[j]->cells[i]->get_string ();
+ if (i != dat -> count_fields ()-1) f<<",";
+ }
+ f<<endl;
+ }
+}
+
+void Actions::reprotonate (ZNMolecule *mol, double ph) {
+ ReprotonateCommand *command = new ReprotonateCommand (mol, data -> ddwin, ph);
+ data -> ddwin -> execute (command);
+}
+
+
+
+void Actions::reprotonate (Database *dat, double ph) {
+ data ->undo_stack -> beginMacro ("Reprotonate Database");
+ for (unsigned int i = 0; i < dat -> count_entries (); i ++) {
+ ReprotonateCommand *command = new ReprotonateCommand (dat ->get_molecule (i), data -> ddwin, ph);
+ data -> ddwin -> execute (command);
+ }
+ data ->undo_stack -> endMacro ();
+
+}
+
+
+
+void Actions::set_scores_from_charges (ZNMolecule *mol) {
+
+}
+
+void Actions::set_scores_from_charges (Database *dat) {
+
+}
diff --git a/arcball.cc b/arcball.cc
new file mode 100644
index 0000000..bc81787
--- /dev/null
+++ b/arcball.cc
@@ -0,0 +1,144 @@
+/** KempoApi: The Turloc Toolkit *****************************/
+/** * * **/
+/** ** ** Filename: ArcBall.cpp **/
+/** ** Version: Common **/
+/** ** **/
+/** **/
+/** Arcball class for mouse manipulation. **/
+/** **/
+/** **/
+/** **/
+/** **/
+/** (C) 1999-2003 Tatewake.com **/
+/** History: **/
+/** 08/17/2003 - (TJG) - Creation **/
+/** 09/23/2003 - (TJG) - Bug fix && optimization **/
+/** 09/25/2003 - (TJG) - Version for NeHe Basecode users **/
+/** **/
+/*************************************************************/
+
+#ifdef WIN32
+#define VC_EXTRALEAN
+#include <windows.h>
+#endif // WIN32
+
+//#include <GL/gl.h> // Header File For The OpenGL32 Library
+//#include <GL/glu.h> // Header File For The GLu32 Library
+#include <QtOpenGL/qgl.h>
+#include <stdio.h>
+#include <iostream>
+
+#include <math.h> // Needed for sqrtf
+
+#include "arcball.h" // ArcBall header
+
+//Arcball sphere constants:
+//Diameter is 2.0f
+//Radius is 1.0f
+//Radius squared is 1.0f
+
+
+
+void ArcBall_t::_mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const
+{
+ Point2fT TempPt;
+ GLfloat length;
+
+ //Copy paramter into temp point
+ TempPt = *NewPt;
+
+ //Adjust point coords && scale down to range of [-1 ... 1]
+ TempPt.s.X = (TempPt.s.X * this->AdjustWidth) - 1.0f;
+ TempPt.s.Y = 1.0f - (TempPt.s.Y * this->AdjustHeight);
+
+ //Compute the square of the length of the vector to the point from the center
+ length = (TempPt.s.X * TempPt.s.X) + (TempPt.s.Y * TempPt.s.Y);
+
+ //If the point is mapped outside of the sphere... (length > radius squared)
+ if (length > 1.0f)
+ {
+ GLfloat norm;
+
+ //Compute a normalizing factor (radius / sqrt(length))
+ norm = 1.0f / FuncSqrt(length);
+
+ //Return the "normalized" vector, a point on the sphere
+ NewVec->s.X = TempPt.s.X * norm;
+ NewVec->s.Y = TempPt.s.Y * norm;
+ NewVec->s.Z = 0.0f;
+ }
+ else //Else it's on the inside
+ {
+ //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
+ NewVec->s.X = TempPt.s.X;
+ NewVec->s.Y = TempPt.s.Y;
+ NewVec->s.Z = FuncSqrt(1.0f - length);
+ }
+}
+
+//Create/Destroy
+ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)
+{
+ //Clear initial values
+ this->StVec.s.X =
+ this->StVec.s.Y =
+ this->StVec.s.Z =
+
+ this->EnVec.s.X =
+ this->EnVec.s.Y =
+ this->EnVec.s.Z = 0.0f;
+
+ //Set initial bounds
+ this->setBounds(NewWidth, NewHeight);
+}
+
+//Mouse down
+void ArcBall_t::click(const Point2fT* NewPt)
+{
+ //Map the point to the sphere
+ this->_mapToSphere(NewPt, &this->StVec);
+
+}
+
+//Mouse drag, calculate rotation
+void ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot)
+{
+ //Map the point to the sphere
+ this->_mapToSphere(NewPt, &this->EnVec);
+ this ->map_vector_on_vector (this -> StVec, this -> EnVec, NewRot);
+}
+
+void ArcBall_t::map_vector_on_vector (Vector3fT v1, Vector3fT v2, Quat4fT* NewRot)
+{
+
+ //Return the quaternion equivalent to the rotation
+ if (NewRot)
+ {
+ Vector3fT Perp;
+
+ //Compute the vector perpendicular to the begin && end vectors
+ Vector3fCross(&Perp, &v1, &v2);
+
+ //Compute the length of the perpendicular vector
+ if (Vector3fLength(&Perp) > Epsilon) //if its non-zero
+ {
+ //We're ok, so return the perpendicular vector as the transform after all
+ NewRot->s.X = Perp.s.X;
+ NewRot->s.Y = Perp.s.Y;
+ NewRot->s.Z = Perp.s.Z;
+ // cout << NewRot->s.X <<" "<< NewRot->s.Y <<" "<<NewRot->s.Z <<" "<< endl;
+ //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
+ NewRot->s.W= Vector3fDot(&v1, &v2);
+ }
+ else //if its zero
+ {
+ //The begin && end vectors coincide, so return an identity transform
+ NewRot->s.X =
+ NewRot->s.Y =
+ NewRot->s.Z =
+ NewRot->s.W = 0.0f;
+ }
+ }
+
+
+}
diff --git a/builder.cc b/builder.cc
new file mode 100644
index 0000000..e270e77
--- /dev/null
+++ b/builder.cc
@@ -0,0 +1,837 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+
+
+
+#include "builder.h"
+
+
+Builder::Builder (DDWin *ddw) {
+ ddwin = ddw;
+ start_magic_pencil_atom = NULL;
+ last_magic_pencil_atom = NULL;
+ mcounter = 1;
+
+}
+
+
+void Builder::save_Hs (Atom *at, vector <Atom *> &prev_ats, vector <ZNBond *> &prev_bonds) {
+ prev_ats.clear ();
+ prev_bonds.clear ();
+ FOR_NBORS_OF_ATOM (n, at) {
+ if (n -> IsHydrogen ()) {
+ ZNBond *bo = at -> GetBond (&*n);
+ if (bo) {
+ prev_ats.push_back (&*n);
+ prev_bonds.push_back (bo);
+ }
+ }
+ }
+}
+
+
+void Builder::add_Hs (Atom *at, vector <Atom *> &atoms, vector <ZNBond *> &bonds) {
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+
+ if (atoms.size () && bonds.size ()) {
+ assert (atoms.size() == bonds.size ());
+ for (unsigned int i = 0; i< atoms.size (); i++) {
+ mol -> add_atom_bonded_to (atoms[i], bonds[i], at);
+ }
+ }
+}
+
+
+void Builder::delete_Hs (ZNMolecule *mol) {
+// cerr << "removing_Hs" << endl;
+ vector <Atom *>to_del;
+ FOR_ATOMS_OF_MOL (n, mol) {
+ if (n) {
+ if (n -> IsHydrogen ()) {
+ to_del.push_back (&*n);
+ }
+ }
+ }
+ for (unsigned int i = 0; i < to_del.size (); i++) {
+ mol -> RemoveAtom (to_del[i]);
+ }
+ // cerr << "removed_Hs" << endl;
+}
+
+
+
+
+
+void Builder::delete_Hs (Atom *at) {
+ // cerr << "removing_Hs" << endl;
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+ vector <Atom *>to_del;
+ FOR_NBORS_OF_ATOM (n, at) {
+ if (n) {
+ if (n -> IsHydrogen ()) {
+ to_del.push_back (&*n);
+ }
+ }
+ }
+ for (unsigned int i = 0; i < to_del.size (); i++) {
+ mol -> RemoveAtom (to_del[i]);
+ }
+ // cerr << "removed_Hs" << endl;
+}
+
+
+
+void Builder::add_atom (int atomnum) {
+ vector <Atom *> to_select;
+ bool continue_mol = find_target ();
+ if (!continue_mol) {
+ vect coord;
+ Atom * new_at = new_atom (coord, atomnum);
+ FOR_NBORS_OF_ATOM (n, new_at) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+ else {
+ FOR_ATOMS_OF_MOL (at, ddwin ->target_molecule) {
+
+ if (!at->IsHydrogen ()) {
+ mutate_atom_to (&*at, atomnum);
+ FOR_NBORS_OF_ATOM (n, &*at) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+
+ else { //adding to an H
+ OBBondIterator i;
+ Atom *parent = at -> BeginNbrAtom (i);
+ if (parent) {
+ // vect v = parent -> GetNewBondVector ()
+ Atom *new_atom =add_atom_bonded_to (get_coordinates (&*at), atomnum, parent);
+ FOR_NBORS_OF_ATOM (n, new_atom) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ ddwin ->deselect ();
+ ddwin ->select (to_select);
+ ddwin ->set_current_target (-1);
+ ddwin->gl->draw_molecule (ddwin->target_molecule);
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Builder::add_fragment (string str) {
+ OBConversion conv;
+ ZNMolecule *mol = new ZNMolecule ();
+ conv.SetInFormat ("SMI");
+ conv.ReadString (mol, str);
+ bool continue_mol = find_target ();
+ if (!continue_mol) {
+ add_mol (str);
+ }
+ else {
+ if (ddwin ->target_molecule ->NumAtoms () ==1) {
+ Atom *to_add = ddwin ->target_molecule ->GetAtom (1);
+ ddwin ->deselect ();
+ ZNMolecule *old_mol = (ZNMolecule *) to_add ->GetParent ();
+ old_mol ->DeleteHydrogens (to_add);
+ old_mol ->ZNinit ();
+ int oldat_idx = to_add ->GetIdx ();
+
+ OBConversion conv;
+ conv.SetInFormat ("SMI");
+ conv.ReadString (mol, str);
+
+ // mol -> AddHydrogens ();
+ mend_coordinates (mol);
+
+ int newat_idx = old_mol ->NumAtoms () +1;
+ (*old_mol) += (*mol);
+ OBBuilder obbuild;
+ obbuild.Connect (*old_mol, oldat_idx, newat_idx);
+ mend_coordinates (old_mol);
+
+ old_mol ->AddHydrogens ();
+ old_mol ->ZNinit ();
+
+
+ }
+ /*
+ FOR_ATOMS_OF_MOL (at, ddwin ->target_molecule) {
+ if (!at->IsHydrogen ()) {
+ mutate_atom_to (&*at, atomnum);
+ FOR_NBORS_OF_ATOM (n, &*at) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+
+ else { //adding to an H
+ OBBondIterator i;
+ Atom *parent = at -> BeginNbrAtom (i);
+ if (parent) {
+ // vect v = parent -> GetNewBondVector ()
+ Atom *new_atom =add_atom_bonded_to (get_coordinates (&*at), atomnum, parent);
+ FOR_NBORS_OF_ATOM (n, new_atom) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+ }
+ }
+ */
+ }
+// ddwin ->deselect ();
+// ddwin ->select (to_select);
+// ddwin ->set_current_target (-1);
+// ddwin->gl->draw_molecule (ddwin->target_molecule);
+}
+
+
+void Builder::add_mol (string str) {
+ vector <Atom *> to_select;
+ bool continue_mol = find_target ();
+ if (!continue_mol) {
+ OBConversion conv;
+ ZNMolecule *mol = new ZNMolecule ();
+ conv.SetInFormat ("SMI");
+ conv.ReadString (mol, str);
+ mol -> AddHydrogens ();
+ mend_coordinates (mol);
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol, ddwin);
+ ddwin -> execute (command);
+ }
+ else {
+//cerr<< "add_mol: 3"<<endl;
+/*
+ OBConversion conv;
+ ZNMolecule *mol = new ZNMolecule ();
+ conv.SetInFormat ("SMI");
+ conv.ReadString (mol, str);
+
+
+
+ mutate_atom_to (&*at, atomnum);
+ FOR_NBORS_OF_ATOM (n, &*at) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+*/
+
+/*
+ FOR_ATOMS_OF_MOL (at, ddwin ->target_molecule) {
+
+ if (!at->IsHydrogen ()) {
+ mutate_atom_to (&*at, atomnum);
+ FOR_NBORS_OF_ATOM (n, &*at) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+
+ else { //adding to an H
+ OBBondIterator i;
+ Atom *parent = at -> BeginNbrAtom (i);
+ if (parent) {
+ // vect v = parent -> GetNewBondVector ()
+ Atom *new_atom =add_atom_bonded_to (get_coordinates (&*at), atomnum, parent);
+ FOR_NBORS_OF_ATOM (n, new_atom) {
+ if (n->IsHydrogen ()) {
+ to_select.push_back (&*n);
+ break;
+ }
+ }
+ }
+ }
+ }
+*/
+
+ }
+ ddwin ->deselect ();
+/*
+ ddwin ->select (to_select);
+ ddwin ->set_current_target (-1);
+ ddwin->gl->draw_molecule (ddwin->target_molecule);
+*/
+}
+///////////////////////////////////////////////////////////////////////////////
+
+void Builder::mutate_atom_to (Atom *at, unsigned int atomnum) {
+ if (at -> GetAtomicNum () != atomnum) {
+ MutateAtomCommand *command = new MutateAtomCommand (at, atomnum, ddwin);
+ ddwin -> execute (command);
+ }
+
+}
+
+
+
+Atom *Builder::add_atom_bonded_to (vect coord, int atmnum, Atom *at) {
+ // cerr << "add" << endl;
+ Atom *new_at = new Atom ();
+ new_at -> SetAtomicNum (atmnum);
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+ mol->ZNinit_atom (new_at);
+ set_coordinates (new_at, coord);
+ ZNBond *bo = new ZNBond ();
+ AddAtomCommand *command = new AddAtomCommand (new_at, bo, at, ddwin);
+ ddwin -> execute (command);
+ return command -> atom;
+}
+
+
+
+
+
+
+
+
+Atom *Builder::new_atom (vect coord, int atomnum) {
+ Atom *at = new Atom ();
+ at->SetAtomicNum (atomnum);
+
+
+ ZNMolecule *mol = new ZNMolecule ();
+ // mol -> ZNinit_atom (at);
+
+
+/// mol -> set_color_mw (at);
+
+
+
+ stringstream ssname;
+ ssname << "New Molecule " << mcounter;
+ string s = ssname.str ();
+ mol -> SetTitle (s);
+ mcounter++;
+ mol -> ZNAddAtom (at);
+ set_coordinates (at, coord);
+ mol -> ZNSetConformers ();
+ finalise_molecule(mol);
+ mol -> ZNAddHydrogens (at);
+
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol, ddwin);
+ ddwin -> execute (command);
+ return at;
+
+}
+
+bool Builder::find_target () {
+ if (ddwin->target_molecule->selection) return true;
+ else {
+ return false;
+ }
+}
+
+
+
+
+
+ZNBond *Builder::new_bond (Atom *at1, Atom *at2, int order) {
+ if (at1 -> GetParent () == at2 -> GetParent ()) {
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ ZNBond *bo = mol -> GetBond (at1, at2);
+ if (!bo) {
+ bo = new ZNBond;
+ mol -> ZNinit_bond (bo);
+ bo -> SetBegin (at1);
+ bo -> SetEnd (at2);
+ AddBondCommand *command = new AddBondCommand (bo, ddwin);
+ ddwin -> execute (command);
+ }
+ bo -> SetBondOrder (order);
+ ddwin->gl->draw_molecule (mol);
+
+ return bo;
+ }
+ else {
+ ZNMolecule *mol1 = (ZNMolecule *) at1 -> GetParent ();
+ ZNMolecule *mol2 = (ZNMolecule *) at2 -> GetParent ();
+ ZNMolecule *mol3 = sum (mol1, mol2);
+ Atom *new_at1 = mol3 ->GetAtom (at1 ->GetIdx ());
+ // cerr << new_at1 -> GetVector () << at1 ->GetVector ()<< endl;
+ Atom *new_at2 = mol3 ->GetAtom (at2 ->GetIdx () + mol1 -> NumAtoms ());
+ // cerr << new_at2 -> GetVector () << at2 ->GetVector ()<< endl;
+ ZNBond *bo = new ZNBond;
+ bo -> SetBegin (new_at1);
+ bo -> SetEnd (new_at2);
+ mol3 -> ZNinit_bond (bo);
+ bo -> SetBondOrder (1);
+
+ AddBondCommand *bond_command = new AddBondCommand (bo, ddwin);
+ bond_command -> redo ();
+ delete bond_command;
+
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol3, ddwin);
+ DeleteZNMoleculeCommand *command1 = new DeleteZNMoleculeCommand (mol1, ddwin);
+ DeleteZNMoleculeCommand *command2 = new DeleteZNMoleculeCommand (mol2, ddwin);
+ ddwin ->data -> undo_stack -> beginMacro ("Merge ZNMolecules");
+ ddwin ->execute (command2);
+ ddwin ->execute (command1);
+ ddwin ->execute (command);
+
+ ddwin ->data -> undo_stack -> endMacro ();
+
+ }
+ return NULL;
+}
+
+void Builder::set_bond (ZNBond *bo, int order) {
+ ModifyBondCommand *command = new ModifyBondCommand (bo, order, ddwin);
+ ddwin -> execute (command);
+}
+
+void Builder::delete_bond (ZNBond *bo) {
+ DeleteBondCommand *command = new DeleteBondCommand (bo, ddwin);
+ ddwin -> execute (command);
+}
+
+
+void Builder::set_aromatic (Ring *ring) {
+ /* ddwin -> data -> undo_stack -> beginMacro ("Set Aromatic");
+ RedefineZNMoleculeCommand *redefine1 = new RedefineZNMoleculeCommand (ring->atoms[0]->residue->molecule, this, 1);
+ ddwin -> execute (redefine1);
+ for (unsigned int i=0; i<ring->bonds.size (); i++) {
+ ModifyBondCommand *command = new ModifyBondCommand (ring -> bonds[i], 5, ddwin, false);
+ ddwin -> execute (command);
+ }
+ RedefineZNMoleculeCommand *redefine = new RedefineZNMoleculeCommand (ring->atoms[0]->residue->molecule, this, 0);
+ ddwin -> execute (redefine);
+ ddwin -> data ->undo_stack -> endMacro ();
+*/
+}
+
+
+
+
+void Builder::set_non_aromatic (Ring *ring) {
+ /* ddwin -> data -> undo_stack -> beginMacro ("Set Non Aromatic");
+ RedefineZNMoleculeCommand *redefine1 = new RedefineZNMoleculeCommand (ring->atoms[0]->residue->molecule, this, 1);
+ ddwin -> execute (redefine1);
+ for (unsigned int i=0; i<ring->bonds.size (); i++) {
+ ModifyBondCommand *command = new ModifyBondCommand (ring -> bonds[i], 1, ddwin, false);
+ ddwin -> execute (command);
+ }
+ RedefineZNMoleculeCommand *redefine = new RedefineZNMoleculeCommand (ring->atoms[0]->residue->molecule, this, 0);
+ ddwin -> execute (redefine);
+ ddwin -> data ->undo_stack -> endMacro ();
+*/
+}
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+void Builder::add_H (Atom *at, vector <Atom *> &atoms, vector <ZNBond *> &bonds) {
+
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+ bool planar = at -> HasDoubleBond ();
+ bool linear = at -> HasBondOfOrder (3);
+
+
+ if (atoms.size () && bonds.size ()) {
+ assert (atoms.size() == bonds.size ());
+ for (unsigned int i = 0; i< atoms.size (); i++) {
+ mol -> add_atom_bonded_to (atoms[i], bonds[i], at);
+ }
+ }
+ else {
+
+ int ntoadd = at -> GetImplicitValence() - at -> GetValence();
+ int nbrs = at -> GetValence ();
+ if (ntoadd == 4) {
+ Atom *dummy = new Atom;
+ vect c = get_coordinates (at);
+ c.x () -= 1.5;
+ set_coordinates (dummy, c);
+
+ vect coord2, coord3, coord4;
+ four_coordinates (dummy, at, coord2, coord3, coord4);
+ mol->add_atom_bonded_to (c, 1, at);
+ mol->add_atom_bonded_to (coord2, 1, at);
+ mol->add_atom_bonded_to (coord3, 1, at);
+ mol->add_atom_bonded_to (coord4, 1, at);
+ delete dummy;
+ }
+
+
+ else if (ntoadd == 3) {
+ if (!nbrs) {
+ Atom *dummy = new Atom;
+ vect c = get_coordinates (dummy);
+ c.x() -= 1.5;
+ set_coordinates (dummy, c);
+ vect coord2, coord3, coord4;
+ four_coordinates (dummy, at, coord2, coord3, coord4);
+
+ mol->add_atom_bonded_to (coord2, 1, at);
+ mol->add_atom_bonded_to (coord3, 1, at);
+ mol->add_atom_bonded_to (coord4, 1, at);
+
+ delete dummy;
+
+ }
+ else {
+ vect coord2, coord3, coord4;
+ OBBondIterator i;
+ Atom *neigh1 = at -> BeginNbrAtom (i);
+
+
+ four_coordinates (neigh1, at, coord2, coord3, coord4);
+ mol->add_atom_bonded_to (coord2, 1, at);
+ mol->add_atom_bonded_to (coord3, 1, at);
+ mol->add_atom_bonded_to (coord4, 1, at);
+
+ }
+ }
+ else if (ntoadd == 2) {
+ if (nbrs == 2) {
+ vect coord1, coord2;
+
+ OBBondIterator i;
+ Atom *neigh1 = at -> BeginNbrAtom (i);
+ Atom *neigh2 = at -> NextNbrAtom (i);
+ assert (neigh2 != at);
+ assert (neigh1 != at);
+ assert (neigh2 != neigh1);
+
+ two_tetrahedral_coordinates (neigh1, neigh2, at, coord1, coord2);
+
+
+ mol->add_atom_bonded_to (coord1, 1, at);
+ mol->add_atom_bonded_to (coord2, 1, at);
+
+ }
+ else if (planar) {
+ vect coord1, coord2, coord3;
+ OBBondIterator i;
+ Atom *neigh1 = at -> BeginNbrAtom (i);
+ three_coordinates (neigh1, at, coord1, coord2);
+
+ mol->add_atom_bonded_to (coord1, 1, at);
+ mol->add_atom_bonded_to (coord2, 1, at);
+
+ }
+ else if (!CountBonds (at)) {
+ Atom *dummy = new Atom;
+ vect v (-1.5, 0, 0);
+ set_coordinates (dummy, v);
+ vect coord1, coord2, coord3;
+ four_coordinates (dummy, at, coord1, coord2, coord3);
+
+ mol->add_atom_bonded_to (coord1, 1, at);
+ mol->add_atom_bonded_to (coord2, 1, at);
+ delete dummy;
+ }
+ else {
+ vect coord1, coord2, coord3;
+ OBBondIterator i;
+ Atom *neigh1 = at -> BeginNbrAtom (i);
+ four_coordinates (neigh1, at, coord1, coord2, coord3);
+
+ mol->add_atom_bonded_to (coord1, 1, at);
+ mol->add_atom_bonded_to (coord2, 1, at);
+ }
+ }
+ else if (ntoadd == 1) {
+ if (planar || linear || nbrs == 3) {
+ vect coord1;
+ one_H (at, coord1);
+
+ mol->add_atom_bonded_to (coord1, 1, at);
+
+
+
+ }
+ else if (!nbrs) {
+ vect coord;
+ coord = get_coordinates (at);
+ coord.x() -= 1.5;
+
+ mol->add_atom_bonded_to (coord, 1, at);
+
+ }
+ else {
+ vect coord1, coord2, coord3, coord4;
+ OBBondIterator i;
+ Atom *neigh1 = at -> BeginNbrAtom (i);
+ four_coordinates (neigh1, at, coord2, coord3, coord4);
+
+ mol->add_atom_bonded_to (coord2, 1, at);
+
+
+ }
+ }
+
+// mol->find_bound ();
+
+ }
+}
+
+
+
+
+
+
+void Builder::delete_atom (Atom *at) {
+ ZNMolecule *mol = (ZNMolecule *) at->GetParent ();
+ int heavy_atoms = 0;
+ FOR_ATOMS_OF_MOL (a, mol){
+ if (!a -> IsHydrogen ()) {
+ heavy_atoms++;
+ if (heavy_atoms > 1) break;
+ }
+ }
+
+ if (heavy_atoms <= 1) {
+ DeleteZNMoleculeCommand *command = new DeleteZNMoleculeCommand (mol, ddwin);
+ ddwin -> execute (command);
+ }
+ else {
+ DeleteAtomCommand *command = new DeleteAtomCommand (at, ddwin);
+ ddwin -> execute (command);
+ }
+
+}
+
+
+
+
+void Builder::redefine_mol (ZNMolecule *mol) {
+/* // cout <<"find_bound"<<endl;
+ mol->find_bound ();
+ mol->number_atoms ();
+ mol->number_bonds ();
+// cout <<"find_res"<<endl;
+ mol->find_residues ();
+// cout <<"find_rings"<<endl;
+ mol->find_rings ();
+ mol->find_kekule ();
+ mol->find_limits ();
+ mol->find_center ();
+ for (unsigned int i=0; i<mol->atoms.size (); i++) {
+ mol->atoms[i]->find_mol2_type ();
+ }
+// cout <<"find_strings"<<endl;
+// cout <<"find_init"<<endl;
+ ddwin->data->mmff->initialize_mol (mol);
+// cout <<"done"<<endl;
+*/
+}
+
+void Builder::add_bond (int order) {
+ ZNMolecule *mol = ddwin ->target_molecule;
+ if (mol ->selection && mol ->NumAtoms () ==2) {
+ Atom *at1 = mol ->GetAtom (1); //atoms numeration migh change in next releases of openbabel to 0 and 1
+ Atom *at2 = mol ->GetAtom (2);
+ new_bond (at1, at2, order);
+ }
+
+}
+
+
+
+
+
+void Builder::delete_Hs (Atom *at, vector <Atom *> &del_atoms, vector <ZNBond *> &del_bonds) {
+ del_atoms.clear ();
+ del_bonds.clear ();
+ ZNMolecule* mol = (ZNMolecule *) at -> GetParent ();
+
+ FOR_NBORS_OF_ATOM (n, at) {
+ if (n -> IsHydrogen ()) {
+ del_atoms.push_back (&*n);
+ ZNBond * b;
+ b = mol -> GetBond (&*n, at);
+ del_bonds.push_back (b);
+
+ // mol -> RemoveBond (b);
+
+ }
+ }
+ for (int i = (del_atoms.size () -1); i >= 0; i--) {
+
+ mol -> RemoveAtom (del_atoms[i]);
+
+ }
+ // mol->find_bound ();
+}
+
+void Builder::one_H (Atom *center, vect &coord) {
+ float dis = 1.5f;
+ if (CountBonds (center)) {
+ coord.null ();
+
+ FOR_NBORS_OF_ATOM (n, center) {
+ coord = sum (coord, get_coordinates (&*n));
+ }
+ coord.multiply (1.f/(float) CountBonds (center));
+ vect cv = get_coordinates(center);
+ vect sumv = cv;
+ sumv.multiply (2);
+ coord = subtract (sumv, coord);
+ vect coord_cent = subtract (coord, cv);
+ float coor_mod = coord_cent.module ();
+ coord = subtract (coord, cv);
+ coord.multiply (dis / coor_mod);
+ coord = sum (cv, coord);
+
+ }
+ else {
+ coord = get_coordinates(center);
+ coord.x() += 1.5f;
+ }
+}
+
+
+
+void Builder::two_tetrahedral_coordinates (Atom *root1, Atom *root2, Atom *center, vect &coord2, vect &coord3) {
+ float dis = 1.5f;
+ vect r1c, r2c, cc;
+ r1c = get_coordinates(root1);
+ r2c = get_coordinates(root2);
+ cc = get_coordinates(center);
+ vect middle_point = mean (r1c, r2c);
+ coord2 = middle_point;
+ coord3 = middle_point;
+ vect root_axis1 = subtract (r1c, cc);
+ vect root_axis2 = subtract (r2c, cc);
+ vect rotation_axis = cross_product (root_axis1, root_axis2);
+ rotate_around_vector (middle_point, rotation_axis, cc, PI/2);
+ vect rot_axis2;
+ rot_axis2 = subtract (middle_point, cc);
+
+ double mid_mod = rot_axis2.module ();
+ if (mid_mod < 0.00002) mid_mod = 0.00002;
+ vect v = subtract (coord3, cc);
+ v.multiply (dis / mid_mod);
+ coord2 = sum (cc, v);
+ coord3 = coord2;
+ rotate_around_vector (coord2, rot_axis2, cc, PI*(125.25)/180);
+ rotate_around_vector (coord3, rot_axis2, cc, -PI*(125.25)/180);
+
+}
+
+void Builder::three_coordinates (Atom* root, Atom *center, vect &coord2, vect &coord3) {
+ float d = 1.5f;
+ vect root_bond, rotation_axis, plane_bond, reference, rv, cv;
+ rv = get_coordinates(root);
+ cv = get_coordinates(center);
+ if (CountBonds (root)) {
+ OBBondIterator i;
+ Atom *neigh1 = root -> BeginNbrAtom (i);
+ reference = get_coordinates(neigh1);
+ }
+ else {
+ reference = subtract (rv, vect (1., 1., 1.));
+ }
+ root_bond = subtract (rv, cv);
+ plane_bond = subtract (reference, rv);
+ root_bond.scale_to (d);
+ coord2 = sum (cv, root_bond);
+ coord3 = coord2;
+ rotation_axis = cross_product (root_bond, plane_bond);
+
+ rotate_around_vector (coord2, rotation_axis, cv, 2*PI/3);
+ rotate_around_vector (coord3, rotation_axis, cv, -2*PI/3);
+
+}
+
+void Builder::set_magic_pencil_atomic_number (int atomn) {
+ magic_pencil_atomic_number = atomn;
+ switch (atomn){
+ case -2:
+ ddwin ->gl ->setCursor(QCursor (QPixmap (":icons/pointer_rubber.png"), 2, 27));
+ break;
+ case 6:
+ ddwin ->gl ->setCursor(QCursor (QPixmap (":icons/pencil_C.png"), 0, 29));
+ break;
+ case 7:
+ ddwin ->gl ->setCursor(QCursor (QPixmap (":icons/pencil_N.png"), 0, 29));
+ break;
+ case 8:
+ ddwin ->gl ->setCursor(QCursor (QPixmap (":icons/pencil_O.png"), 0, 29));
+ break;
+ case 16:
+ ddwin ->gl ->setCursor(QCursor (QPixmap (":icons/pencil_S.png"), 0, 29));
+ break;
+ }
+
+}
+
+void Builder::four_coordinates (Atom* root, Atom *center, vect &coord2, vect &coord3, vect &coord4) {
+ vect root_bond, rotation_axis, plane_bond, reference, rv, cv;
+ rv = get_coordinates(root);
+ cv = get_coordinates(center);
+ float dist = 1.5f;
+// if (root -> NumAtoms ()) {
+ // reference = root -> BeginAtom () -> GetVector ();
+ // }
+ if (false) {}
+ else {
+ reference = subtract (rv, vect (1., 1., 1.));
+ }
+ root_bond = subtract (cv, rv);
+ plane_bond = subtract (rv, reference);
+
+ rotation_axis = cross_product (root_bond, plane_bond);
+ root_bond.scale_to (dist);
+ coord2 = subtract (cv, root_bond);
+ coord3 = subtract (cv, root_bond);
+ coord4 = subtract (cv, root_bond);
+
+ if (!rotation_axis.square_module ()) rotation_axis.z () += 1;
+ rotate_around_vector (coord2, rotation_axis, cv, PI*109.5/180);
+ rotate_around_vector (coord3, rotation_axis, cv, PI*109.5/180);
+ rotate_around_vector (coord4, rotation_axis, cv, PI*109.5/180);
+
+ rotate_around_vector (coord3, root_bond, cv, 2*PI/3);
+ rotate_around_vector (coord4, root_bond, cv, -2*PI/3);
+
+}
diff --git a/chemscore.cc b/chemscore.cc
new file mode 100644
index 0000000..e0b9d15
--- /dev/null
+++ b/chemscore.cc
@@ -0,0 +1,222 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "chemscore.h"
+#include "math.h"
+
+
+
+using namespace OpenBabel;
+
+float f (float x, float x1, float x2) {
+ if (x<= x1) return 1;
+ else if (x>x2) return 0;
+ else return (x2-x)/(x2-x1);
+
+}
+
+
+float ChemscoreHBInteraction::value () {
+ float r = dist (get_coordinates (at1), get_coordinates (at2));
+ float ang;
+ if (at1->GetAtomicNum () == 1) ang = angle (get_coordinates (at2), get_coordinates (at1), get_coordinates (root));
+ else ang = angle (get_coordinates (at1), get_coordinates (at2), get_coordinates (root));
+ float dghbond = -3.34f;
+ float r0 = 1.85f;
+ float a0 = 180.f;
+ float drab = r-r0;
+ if (drab < 0) drab = -drab;
+ float daab = ang-a0;
+ if (daab < 0) daab = -daab;
+ float dr1 = 0.25f;
+ float dr2 = 0.65f;
+ float da1 = 30.f;
+ float da2 = 80.f;
+// if (isnan (dghbond * f(drab, dr1, dr2) * f(daab, da1, da2))) cerr << "isnan chemscore" << drab << " "<< dr1 << " " << f(daab, da1, da2) << endl;
+// cerr << "value" <<dghbond * f(drab, dr1, dr2) * f(daab, da1, da2)<< endl;
+ return dghbond * f(drab, dr1, dr2) * f(daab, da1, da2);
+}
+
+
+float ChemscoreLiInteraction::value () {
+ float r1, r2, dg;
+ if (metal) {
+ dg = -6.03f;
+ r1 = 2.6f;
+ r2 = 3.0f;
+ }
+ else {
+ dg = -0.117f;
+ r1 = 4.1f;
+ r2 = 7.1f;
+ }
+ float r = dist (get_coordinates (at1), get_coordinates (at2));
+ //if (isnan (dg * f(r, r1, r2))) cerr << "isnan chemscore" << dg << " "<< r << " " << f(r, r1, r2) << endl;
+
+ return dg * f(r, r1, r2);
+
+}
+
+
+
+
+float ChemscoreClInteraction::value () {
+ float r = dist (get_coordinates (at1), get_coordinates (at2));
+ if (type == 0) {
+ float rcl = 1.6f;
+ float dghb = -3.34f;
+ if (r>rcl) return 0.f;
+ else return (20.f/dghb)*(rcl-r)/rcl;
+ }
+ else if (type == 1) {
+ float rcl = 1.38f;
+ float dgm = -6.03f;
+ if (r>rcl) return 0.f;
+ else return (20.f/dgm)*(rcl-r)/rcl;
+
+ }
+ else {
+ float rcl;
+ if (at1->GetAtomicNum () == 16 || at2->GetAtomicNum () == 16) rcl=3.35f;
+ else rcl = 3.1f;
+ if (r>rcl) return 0.f;
+ else return 1.f+4.f*(rcl-r)/rcl-1.f;
+ }
+}
+
+
+
+
+Chemscore::Chemscore () : ForceField () {
+ is_initialised = TRUE;
+ LiGrid = NULL;
+ ClGrid = NULL;
+}
+
+int Chemscore::getChemscoretype (Atom *at) {
+ ZNMolecule *mol = (ZNMolecule *) at -> GetParent ();
+
+ if (at->GetAtomicNum () == 8) {
+ return ZN_CS_ACCEPTOR;
+ }
+ if (at->GetAtomicNum () == 7) {
+ if (CountBonds (at) <3) return ZN_CS_ACCEPTOR;
+ else return ZN_CS_POLAR;
+ }
+ if (at->GetAtomicNum () == 1 && (mol -> bonded_to (at, -2, 7) || mol -> bonded_to (at, -2, 8))) return ZN_CS_DONOR;
+ if (at->GetAtomicNum () == 15) return ZN_CS_POLAR;
+ if (at->GetAtomicNum () == 9) return ZN_CS_POLAR;
+ if (at->GetAtomicNum () == 16 && (mol->bonded_to (at, -2,7)+mol ->bonded_to (at, -2,8))) return ZN_CS_POLAR;
+
+ if (at->GetAtomicNum () == 6) {
+ if (mol ->bonded_to (at, 3, 7)) return ZN_CS_POLAR;
+ else if (mol ->bonded_to (at, 2, 8)) return ZN_CS_POLAR;
+ else if ((mol ->bonded_to (at, -2,7)+mol ->bonded_to (at, -2,8))>2) return ZN_CS_POLAR;
+ else return ZN_CS_NONPOLAR;
+ }
+ if (at->GetAtomicNum () == 26) return ZN_CS_METAL; //iron other metals are missing
+ return ZN_CS_NONPOLAR;
+
+
+
+
+
+
+
+
+/* implicit H parametrization
+ if (at->GetAtomicNum () == 8) {
+ if (mol ->bonded_to (at, -2, 1)) return BOTH;
+ else return ACCEPTOR;
+ }
+ if (at->GetAtomicNum () == 7) {
+ if (mol ->bonded_to (at, -2, 1) ) && (mol ->bonded_to (at, 2, 6) )) return BOTH; //imine
+ else if (mol ->bonded_to (at, -2, 1) )) return DONOR;
+ else if (bound.size ()<3) return ACCCEPTOR;
+ else return POLAR;
+ }
+ if (at->GetAtomicNum () == 1 && (mol ->bonded_to (at, -2, 7) || mol ->bonded_to (at, -2, 8))) return DONOR;
+ if (at->GetAtomicNum () == 15) return POLAR;
+ if (at->GetAtomicNum () == 9) return POLAR;
+ if (at->GetAtomicNum () == 16 && (mol ->bonded_to (at, -2,7)+mol ->bonded_to (at, -2,8)) return POLAR;
+
+ if (at->GetAtomicNum () == 6) {
+ if (mol ->bonded_to (at, 3, N)) return POLAR;
+ else if (mol ->bonded_to (at, 2, O)) return POLAR;
+ else if ((mol ->bonded_to (at, -2,7)+mol ->bonded_to (at, -2,8))>2) return POLAR;
+ else return NONPOLAR;
+ }
+ if (at->GetAtomicNum () == 26) return METAL; //iron other metals are missing
+ return NONPOLAR;
+
+*/
+}
+
+
+
+
+
+
+void Chemscore::clear_nonbonded_interactions () {
+ for (unsigned int i=0; i<HBInteractions.size (); i++) delete HBInteractions[i];
+ HBInteractions.clear ();
+ for (unsigned int i=0; i<ClInteractions.size (); i++) delete ClInteractions[i];
+ ClInteractions.clear ();
+ for (unsigned int i=0; i<LiInteractions.size (); i++) delete LiInteractions[i];
+ LiInteractions.clear ();
+}
+
+
+
+
+
+void Chemscore::compute_forces () {
+ for (unsigned int i=0; i<HBInteractions.size (); i++) {
+ HBInteractions[i] -> set_forces ();
+ }
+ for (unsigned int i=0; i<LiInteractions.size (); i++) {
+ LiInteractions[i] -> set_forces ();
+ }
+ for (unsigned int i=0; i<ClInteractions.size (); i++) {
+ ClInteractions[i] -> set_forces ();
+ }
+}
+
+
+void Chemscore::load_grids (vect cent, double rad) {
+ vect min_corner = vect (cent.x()-rad,cent.y()-rad,cent.z()-rad);
+ vect max_corner = vect (cent.x()+rad,cent.y()+rad,cent.z()+rad);
+ LiGrid = new DataGrid (min_corner, max_corner, 0.3);
+ ClGrid = new DataGrid (min_corner, max_corner, 0.3);
+ for (int k = 0; k < LiGrid -> z_size (); k++) {
+ for (int j = 0; j < LiGrid -> y_size (); j++) {
+ for (int i = 0; i < LiGrid -> x_size (); i++) {
+ float xx = LiGrid ->get_x (i);
+ float yy = LiGrid ->get_y (j);
+ float zz = LiGrid ->get_z (k);
+ LiGrid ->set_value (i, j, k, Livalue (vect (xx, yy, zz)));
+ ClGrid ->set_value (i, j, k, Clvalue (vect (xx, yy, zz)));
+ }
+ }
+ }
+
+
+}
+
+
+
diff --git a/command.cc b/command.cc
new file mode 100644
index 0000000..ae41272
--- /dev/null
+++ b/command.cc
@@ -0,0 +1,1176 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "command.h"
+
+
+
+Command::Command () : QUndoCommand (0)
+{
+ first_time = true;
+ // get_time ();
+}
+
+void Command::get_time () {
+ // commandtime = time (NULL);
+
+}
+
+
+bool Command::same_time (Command *other) {
+
+ // double diff = difftime (commandtime, other -> commandtime);
+ // assert (diff >= 0);
+ // if (diff < 1) return true;
+ // else return false;
+ return false;
+}
+
+/*
+bool Command::mergeWith (const QUndoCommand *other) {
+ cout <<" merge"<<endl;
+ return true;
+}
+*/
+
+void Command::name (string str) {
+ setText (QString (str.c_str ()));
+}
+
+ColorAtomCommand::ColorAtomCommand (MyGl *gl_point) : Command ()
+{
+
+ gl = gl_point;
+ setText ( QString (string("color:").c_str ()));
+
+}
+
+
+
+
+
+ColorAtomCommand::ColorAtomCommand (Atom *at, color pres_col, MyGl *gl_point) : Command ()
+{
+ gl = gl_point;
+ add (at, pres_col);
+ setText ( QString (string("color: 1 atom").c_str ()));
+
+}
+
+void ColorAtomCommand::redo () {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_color (target_atoms[i], present_colors [i]);
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ gl -> draw_molecule (mol);
+ }
+}
+
+void ColorAtomCommand::add (Atom *at, color col) {
+ target_atoms.push_back (at);
+ color c = get_color (at);
+ present_colors.push_back ( col);
+ previous_colors.push_back ( c );
+
+}
+
+
+void ColorAtomCommand::undo () {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_color (target_atoms[i], previous_colors [i]);
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ gl -> draw_molecule (mol);
+ }
+
+}
+
+int ColorAtomCommand::id () const {
+ return 1;
+}
+
+void ColorAtomCommand::set_name () {
+ stringstream ss;
+ ss << target_atoms.size ();
+ setText ( QString ( ( string("color: ")+ ss.str ()+ string (" atoms") ).c_str ()));
+}
+
+bool ColorAtomCommand::mergeWith (const QUndoCommand *other) {
+ if (other->id() != id())
+ return false;
+ const ColorAtomCommand *oth = static_cast<const ColorAtomCommand*>(other);
+ // if (! same_time (oth)) return false;
+ target_atoms.push_back (oth ->target_atoms[0]);
+ previous_colors.push_back (oth ->previous_colors[0]);
+ present_colors.push_back (oth ->present_colors[0]);
+ stringstream ss;
+ ss << target_atoms.size ();
+ setText ( QString ( ( string("color: ")+ ss.str ()+ string (" atoms") ).c_str ()));
+
+ return true;
+}
+
+//////////////////////////////////////
+
+ChangeDisplayStyleCommand::ChangeDisplayStyleCommand (MyGl *gl_point) : Command ()
+{
+ redraw = false;
+ gl = gl_point;
+ setText ( QString (string("change display style: 1 bond").c_str ()));
+
+}
+
+
+ChangeDisplayStyleCommand::ChangeDisplayStyleCommand (Atom *at, int disp_style, MyGl *gl_point) : Command ()
+{
+ redraw = false;
+ gl = gl_point;
+ add (at, disp_style);
+ setText ( QString (string("change display style: 1 atom").c_str ()));
+
+}
+
+ChangeDisplayStyleCommand::ChangeDisplayStyleCommand (ZNBond *bo, int disp_style, MyGl *gl_point) : Command ()
+{
+ gl = gl_point;
+ add (bo, disp_style);
+ setText ( QString (string("change display style: 1 bond").c_str ()));
+
+}
+
+void ChangeDisplayStyleCommand::add (ZNMolecule *mol, int at_di, int bo_di, int backbone_di) {
+ target_molecules.push_back (mol);
+ present_styles_molecule_atoms.push_back (at_di);
+ present_styles_molecule_bonds.push_back (bo_di);
+ previous_styles_molecule_atoms.push_back (get_atoms_display_style (mol));
+ previous_styles_molecule_bonds.push_back (get_bonds_display_style (mol));
+ present_styles_molecule_backbone.push_back (backbone_di);
+ previous_styles_molecule_backbone.push_back (get_backbone_display_style (mol));
+}
+
+void ChangeDisplayStyleCommand::add (ZNBond *bo, int disp_style) {
+ target_bonds.push_back (bo);
+ present_styles_bonds.push_back (disp_style);
+ previous_styles_bonds.push_back (get_ds (bo));
+}
+
+
+void ChangeDisplayStyleCommand::add (Atom *at, int disp_style) {
+ target_atoms.push_back (at);
+ present_styles_atoms.push_back (disp_style);
+ previous_styles_atoms.push_back (get_ds (at));
+}
+
+
+
+
+void ChangeDisplayStyleCommand::set_name () {
+
+ string out = "change display style: ";
+ if (target_atoms.size ()) {
+ stringstream ss;
+ ss << target_atoms.size ();
+ string plur = "s";
+ if (target_atoms.size () == 1) plur = "";
+ out += ss.str();
+ out += " atom"+plur;
+ out += " ";
+ }
+ if (target_bonds.size ()) {
+ stringstream ss;
+ ss << target_bonds.size ();
+ string plur = "s";
+ if (target_bonds.size () == 1) plur = "";
+ out += ss.str();
+ out += " bond"+plur;
+ out += " ";
+ }
+
+
+
+ setText ( QString (out.c_str ()));
+}
+
+
+void ChangeDisplayStyleCommand::redo () {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_ds (target_atoms[i],present_styles_atoms [i]);
+ }
+ for (unsigned int i=0; i < target_bonds.size (); i++) {
+ set_ds (target_bonds[i], present_styles_bonds [i]);
+ }
+ for (unsigned int i=0; i < target_molecules.size (); i++) {
+ set_atoms_display_style (target_molecules [i], present_styles_molecule_atoms [i]);
+ set_bonds_display_style (target_molecules [i], present_styles_molecule_bonds [i]);
+ set_backbone_display_style (target_molecules [i], present_styles_molecule_backbone [i]);
+ }
+ if (redraw) {
+ vector <ZNMolecule *> drawn_mols;
+ for (unsigned int i =0; i < target_atoms.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+ if (redr) {
+ drawn_mols.push_back (mol);
+ gl -> draw_molecule (mol);
+ }
+ }
+ for (unsigned int i =0; i < target_bonds.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_bonds[i] -> GetBeginAtom () -> GetParent ();
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+
+ if (redr) {
+ drawn_mols.push_back (mol);
+ gl -> draw_molecule (mol);
+
+ }
+ }
+ }
+ redraw = true;
+}
+
+void ChangeDisplayStyleCommand::undo () {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_ds (target_atoms [i], previous_styles_atoms [i]);
+ }
+ for (unsigned int i=0; i < target_bonds.size (); i++) {
+ set_ds (target_bonds [i], previous_styles_bonds [i]);
+ }
+
+ for (unsigned int i=0; i < target_molecules.size (); i++) {
+ set_atoms_display_style (target_molecules [i], previous_styles_molecule_atoms [i]);
+ set_bonds_display_style (target_molecules [i], previous_styles_molecule_bonds [i]);
+ set_backbone_display_style (target_molecules [i], previous_styles_molecule_backbone [i]);
+ }
+
+
+ vector <ZNMolecule *> drawn_mols;
+ for (unsigned int i =0; i < target_atoms.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+ if (redr) {
+ drawn_mols.push_back (mol);
+ gl -> draw_molecule (mol);
+ }
+
+ for (unsigned int i =0; i < target_bonds.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_bonds[i] -> GetBeginAtom () -> GetParent ();
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+
+ if (redr) {
+ drawn_mols.push_back (mol);
+ gl -> draw_molecule (mol);
+
+ }
+ }
+ }
+
+}
+/*
+int ChangeDisplayStyleCommand::id () const {
+ return 2;
+}
+
+
+bool ChangeDisplayStyleCommand::mergeWith (const QUndoCommand *other) {
+ if (other->id() != id())
+ return false;
+ const ChangeDisplayStyleCommand *oth = static_cast<const ChangeDisplayStyleCommand*>(other);
+ // if (! same_time (oth)) return false;
+ if (oth -> target_atoms.size ()) {
+ target_atoms.push_back (oth ->target_atoms[0]);
+ assert (oth -> previous_styles_atoms.size ());
+ assert (oth -> present_styles_atoms.size ());
+ previous_styles_atoms.push_back (oth -> previous_styles_atoms[0]);
+ present_styles_atoms.push_back (oth -> present_styles_atoms[0]);
+ }
+ if (oth -> target_bonds.size ()) {
+ target_bonds.push_back (oth ->target_bonds[0]);
+ assert (oth -> previous_styles_bonds.size ());
+ assert (oth -> present_styles_bonds.size ());
+ previous_styles_bonds.push_back (oth -> previous_styles_bonds[0]);
+ present_styles_bonds.push_back (oth -> present_styles_bonds[0]);
+ }
+
+ set_name ();
+ return true;
+}
+*/
+
+/////////////////////////////////////////////////////////////////////////////
+
+ChangeFloatCommand::ChangeFloatCommand (float &fl, float val, MyGl *gl_point, string name) : Command ()
+{
+ gl = gl_point;
+ setText ( QString (name.c_str ()));
+ f = &fl;
+ previous_value = fl;
+ present_value = val;
+
+}
+
+void ChangeFloatCommand::undo () {
+ *f = previous_value;
+
+}
+
+
+void ChangeFloatCommand::redo () {
+ *f = present_value;
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+ChangeVectorCommand::ChangeVectorCommand (vect &vec, vect val, MyGl *gl_point, string name) : Command ()
+{
+ gl = gl_point;
+ setText ( QString (name.c_str ()));
+ v = &vec;
+ previous_value = vec;
+ present_value = val;
+
+}
+
+
+
+
+void ChangeVectorCommand::undo () {
+ *v = previous_value;
+
+}
+
+
+void ChangeVectorCommand::redo () {
+ *v = present_value;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
+/*
+
+ChangeZNMoleculeCommand::ChangeZNMoleculeCommand (MyGl *gl_point, string name, bool first_d) : Command ()
+
+{
+ first_do = first_d;
+ gl = gl_point;
+ setText ( QString (name.c_str ()));
+ mol = NULL;
+ present_value = NULL;
+ previous_value = NULL;
+
+}
+
+
+void ChangeZNMoleculeCommand::add (ZNMolecule *m, ZNMolecule *prev_val) {
+ cerr << "adding"<<endl;
+ mol = m;
+ if (previous_value) delete previous_value;
+ if (present_value) delete present_value;
+ previous_value = new ZNMolecule ();
+ previous_value -> copy_from (prev_val);
+ present_value = new ZNMolecule ();
+ present_value -> copy_from (mol);
+ cerr << "added"<<endl;
+}
+
+void ChangeZNMoleculeCommand::undo () {
+ // for (unsigned int i=0; i < mols.size (); i++) {
+ // ZNMolecule *mol = mols [i];
+ // *mol = previous_values [i];
+ // gl -> draw_molecule (mol);
+
+
+ // }
+
+}
+
+
+void ChangeZNMoleculeCommand::redo () {
+ // for (unsigned int i=0; i < mols.size (); i++) {
+ // ZNMolecule *mol = mols [i];
+ // *mol = present_values [i];
+// gl -> draw_molecule (mol);
+
+ //}
+}
+////////////////////////////////////////////////
+*/
+
+MoveAtomsCommand::MoveAtomsCommand (MyGl *gl_point, int mod) : Command ()
+{
+ mode = mod;
+ redraw = true;
+ gl = gl_point;
+ setText ( QString (string("move atoms").c_str ()));
+
+}
+
+
+void MoveAtomsCommand::redo () {
+ if (mode != 1) {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_coordinates (target_atoms [i], present_coordinates [i]);
+ }
+ if (redraw) {
+ vector <ZNMolecule *> drawn_mols;
+ for (unsigned int i =0; i < target_atoms.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ molecule_has_changed (mol);
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+ if (redr) {
+ gl -> draw_molecule (mol);
+ drawn_mols.push_back (mol);
+ }
+ }
+ }
+ redraw = true;
+ }
+}
+void MoveAtomsCommand::add (Atom *at, vect coo) {
+ target_atoms.push_back (at);
+ previous_coordinates.push_back ( coo);
+ present_coordinates.push_back ( get_coordinates(at));
+
+}
+
+
+void MoveAtomsCommand::undo () {
+ if (mode != 0) {
+ for (unsigned int i=0; i < target_atoms.size (); i++) {
+ set_coordinates (target_atoms [i] ,previous_coordinates [i]);
+ }
+ if (redraw) {
+ vector <ZNMolecule *> drawn_mols;
+ for (unsigned int i =0; i < target_atoms.size (); i++) {
+ ZNMolecule * mol = (ZNMolecule *) target_atoms[i] -> GetParent ();
+ molecule_has_changed (mol);
+
+ bool redr = true;
+ for (unsigned int j =0; j < drawn_mols.size (); j++) {
+ if (mol == drawn_mols[j]) {
+ redr = false;
+ break;
+ }
+ }
+
+ if (redr) {
+ gl -> draw_molecule (mol);
+ drawn_mols.push_back (mol);
+ }
+ }
+ }
+ }
+}
+
+
+void MoveAtomsCommand::set_name () {
+ stringstream ss;
+ ss << target_atoms.size ();
+ setText ( QString ( ( string("move: ")+ ss.str ()+ string (" atoms") ).c_str ()));
+}
+
+//////////////////////////////////////////////////////////////////////
+
+CreateGraphicalObjectCommand::CreateGraphicalObjectCommand (GraphicalObject *obj, DDWin *ddwin_point): Command ()
+ {
+ rank = -1;
+ ddwin = ddwin_point;
+ setText ( QString ("Create Graphical Object"));
+ object = obj;
+
+}
+
+
+
+void CreateGraphicalObjectCommand::redo () {
+
+ if (rank == -1) ddwin -> graphical_objects.push_back (object);
+ else ddwin -> graphical_objects.insert (ddwin -> graphical_objects.begin () + rank, object);
+ ddwin ->emit_go_updated();
+ ddwin -> graphical_objects_menu -> update_slot ();
+
+}
+
+void CreateGraphicalObjectCommand::undo () {
+ for (unsigned int i =0; i< ddwin -> graphical_objects.size (); i++) {
+ if (ddwin -> graphical_objects[i] == object) {
+ ddwin -> graphical_objects.erase (ddwin -> graphical_objects.begin ()+i);
+ ddwin ->emit_go_updated();
+ ddwin -> graphical_objects_menu -> update_slot ();
+ rank = i;
+
+ break;
+ }
+ }
+}
+//////////////////////////////////////////////////////////////////
+
+DeleteGraphicalObjectCommand::DeleteGraphicalObjectCommand (GraphicalObject *obj, DDWin *ddwin_point) : Command ()
+{
+ rank = -1;
+ ddwin = ddwin_point;
+ setText ( QString ("Delete Graphical Object"));
+
+ object = obj;
+}
+
+
+
+void DeleteGraphicalObjectCommand::undo () {
+
+ if (rank == -1) ddwin -> graphical_objects.push_back (object);
+ else ddwin -> graphical_objects.insert (ddwin -> graphical_objects.begin () + rank, object);
+ ddwin -> emit_go_updated ();
+ ddwin -> graphical_objects_menu -> update_slot ();
+
+}
+
+void DeleteGraphicalObjectCommand::redo () {
+ for (unsigned int i =0; i< ddwin -> graphical_objects.size (); i++) {
+ if (ddwin -> graphical_objects[i] == object) {
+ ddwin -> graphical_objects.erase (ddwin -> graphical_objects.begin ()+i);
+ ddwin -> emit_go_updated ();
+ ddwin -> graphical_objects_menu -> update_slot ();
+ rank = i;
+
+ break;
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+////////////////////////////////////////////////////////////////////
+
+CreateZNMoleculeCommand::CreateZNMoleculeCommand ( ZNMolecule * molecule, DDWin *ddwin_point) : Command ()
+{
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Create ")+QString (molecule -> GetTitle ()));
+ mol = molecule;
+ finalise_molecule(mol);
+ ddwin->gl->draw_molecule (ddwin->target_molecule);
+}
+
+void CreateZNMoleculeCommand::redo () {
+ ddwin -> add_molecule (mol);
+ ddwin -> set_current_target (-1);
+ ddwin -> gl -> draw_molecule (mol);
+
+
+
+}
+
+
+void CreateZNMoleculeCommand::undo () {
+ ddwin -> remove_molecule (mol);
+ ddwin -> set_current_target (0);
+ ddwin -> gl -> draw_molecule (mol);
+
+}
+///////////////////////////////////////////////////
+
+DeleteZNMoleculeCommand::DeleteZNMoleculeCommand (ZNMolecule *molecule, DDWin *ddwin_point): CreateZNMoleculeCommand (molecule, ddwin_point) {
+ setText ( QString ("Delete ")+QString (molecule -> GetTitle ()));
+}
+
+
+void DeleteZNMoleculeCommand::redo () {
+ CreateZNMoleculeCommand::undo ();
+}
+
+
+void DeleteZNMoleculeCommand::undo () {
+ CreateZNMoleculeCommand::redo ();
+}
+
+
+////////////////////////////////////////////////
+MutateAtomCommand::MutateAtomCommand ( Atom *at, int atn, DDWin *ddwin_point): Command ()
+ {
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Mutate Atom"));
+ currentn = atn;
+ precn = at-> GetAtomicNum ();
+ atom = at;
+
+
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+
+
+ // first_time = true;
+
+ builder -> save_Hs (atom, prev_H_atoms, prev_H_bonds);
+ builder -> delete_Hs (at);
+ atom -> SetAtomicNum (currentn);
+ mol -> ZNAddHydrogens (atom);
+ builder -> save_Hs (atom, curr_H_atoms, curr_H_bonds);
+ finalise_molecule(mol);
+ molecule_has_changed (mol);
+
+}
+
+void MutateAtomCommand::redo () {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ if (!first_time) {
+ builder -> delete_Hs (atom);
+ atom -> SetAtomicNum (currentn);
+ builder -> add_Hs (atom, curr_H_atoms, curr_H_bonds);
+
+ }
+ first_time = false;
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+
+
+}
+
+void MutateAtomCommand::undo () {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ builder -> delete_Hs (atom);
+ atom -> SetAtomicNum (precn);
+ mol -> set_color_mw (atom) ;
+ builder -> add_Hs (atom, prev_H_atoms, prev_H_bonds);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+}
+///////////////////////////////////////////////////////////
+
+DeleteAtomCommand::DeleteAtomCommand (Atom *at, DDWin *ddwin_point) : Command ()
+{
+
+ ddwin = ddwin_point;
+ setText ( QString ("Remove atom"));
+ atom = at;
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ builder ->save_Hs (at, prev_H_atoms, prev_H_bonds);
+ FOR_NBORS_OF_ATOM (n, at) {
+ if (!n ->IsHydrogen ()) {
+ neighs.push_back (&*n);
+ bonds.push_back (mol ->GetBond (at, &*n));
+ vector <Atom *> H_atoms;
+ vector <ZNBond *> H_bonds;
+ builder ->save_Hs (&*n, H_atoms, H_bonds);
+ prev_targets_H_atoms.push_back (H_atoms);
+ prev_targets_H_bonds.push_back (H_bonds);
+ vector <Atom *> p_H_atoms;
+ vector <ZNBond *> p_H_bonds;
+
+ curr_targets_H_atoms.push_back (p_H_atoms);
+ curr_targets_H_bonds.push_back (p_H_bonds);
+
+ }
+ }
+ molecule_has_changed (mol);
+
+
+
+ /* ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Remove atom"));
+ atom = at;
+ for (unsigned int i = 0; i < at -> bound.size (); i++) {
+ if (atom -> bound [i] -> isHydrogen ()) {
+ bound.push_back (atom -> bound[i]);
+ bonds.push_back (atom -> bonds[i]);
+ vector <Atom *> prevH;
+ vector <Atom *> postH;
+ vector <ZNBond *> prevb;
+ vector <ZNBond *> postb;
+ prev_targets_H_atoms.push_back (prevH);
+ curr_targets_H_atoms.push_back (postH);
+ prev_targets_H_bonds.push_back (prevb);
+ curr_targets_H_bonds.push_back (postb);
+
+ }
+ }
+
+*/
+}
+
+
+void DeleteAtomCommand::redo () {
+
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ builder -> delete_Hs (atom);
+ mol -> RemoveAtom (atom);
+ for (unsigned int i = 0; i < prev_targets_H_atoms.size (); i++) {
+ builder ->delete_Hs (neighs[i]);
+ if (!curr_targets_H_atoms[i].size ()) {
+
+ mol ->ZNAddHydrogens (neighs[i]);
+
+ builder -> save_Hs (neighs[i], curr_targets_H_atoms[i], curr_targets_H_bonds[i]);
+ // mol ->RemoveBond (bonds[i]);
+
+ }
+ else builder -> add_Hs (neighs[i], curr_targets_H_atoms[i], curr_targets_H_bonds[i]);
+ }
+ finalise_molecule(mol);
+ // builder -> delete_Hs (partner);
+ // builder -> add_Hs (atom, prev_H_atoms, prev_H_bonds);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+
+/* ZNMolecule *mol = atom -> GetParent ();
+ for (unsigned int i = 0; i < bonds.size (); i++) {
+ mol -> remove (bonds[i]);
+ }
+ builder -> delete_Hs (atom, prev_H_atoms, prev_H_bonds);
+ mol -> remove (atom);
+ for (unsigned int i = 0; i < bonds.size (); i++) {
+ builder -> delete_Hs (bound[i], prev_targets_H_atoms[i], prev_targets_H_bonds[i]);
+ builder -> add_H (bound[i], curr_targets_H_atoms[i], curr_targets_H_bonds[i]);
+ }
+
+ builder -> redefine_mol (mol);
+ ddwin -> gl -> draw_molecule (atom->residue->molecule);
+*/
+}
+
+
+
+void DeleteAtomCommand::undo () {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+
+ mol -> ZNAddAtom (atom);
+ builder -> add_Hs (atom, prev_H_atoms, prev_H_bonds);
+ for (unsigned int i = 0; i < prev_targets_H_atoms.size (); i++) {
+
+ builder -> delete_Hs (neighs[i]);
+ builder -> add_Hs (neighs[i], prev_targets_H_atoms[i], prev_targets_H_bonds[i]);
+ mol ->ZNAddBond (bonds[i]);
+ }
+ finalise_molecule(mol);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+ /*
+
+
+
+ AddAtomCommand::AddAtomCommand ( Atom *at, ZNBond *bo, Atom *part, DDWin *ddwin_point) : Command ()
+ {
+ ZNMolecule *mol = (ZNMolecule *) part -> GetParent ();
+ // first_time = true;
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Add atom"));
+ atom = at;
+ partner = part;
+ bond = bo;
+ builder -> save_Hs (partner, prev_H_atoms, prev_H_bonds);
+ // builder -> save_Hs (at, prev_target_H_atoms, prev_target_H_bonds);
+ builder -> delete_Hs (partner);
+ mol -> add_atom_bonded_to (atom, bond, partner);
+ mol -> ZNAddHydrogens (partner);
+ mol -> ZNAddHydrogens (at);
+ builder -> save_Hs (partner, curr_H_atoms, curr_H_bonds);
+ builder -> save_Hs (at, curr_target_H_atoms, curr_target_H_bonds);
+ finalise_molecule(mol);
+ }
+
+
+ void AddAtomCommand::redo () {
+ if (!first_time) {
+
+ ZNMolecule *mol = (ZNMolecule *) partner -> GetParent ();
+ builder -> delete_Hs (partner);
+ mol -> add_atom_bonded_to (atom, bond, partner);
+
+
+ // builder -> redefine_mol (mol);
+
+ // builder -> delete_Hs (atom);
+ builder -> add_Hs (partner, curr_H_atoms, curr_H_bonds);
+ builder -> add_Hs (atom, curr_target_H_atoms, curr_target_H_bonds);
+
+ // builder -> redefine_mol (mol);
+
+ ddwin -> gl -> draw_molecule (mol);
+ }
+ first_time = false;
+ }
+
+ void AddAtomCommand::undo () {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ builder -> delete_Hs (atom);
+ mol -> RemoveAtom (atom);
+ // mol -> RemoveBond (bond);
+ builder -> delete_Hs (partner);
+ builder -> add_Hs (partner, prev_H_atoms, prev_H_bonds);
+ ddwin -> gl -> draw_molecule (mol);
+
+
+
+ }
+
+
+
+
+
+
+ ZNMolecule *mol = atom -> GetParent ();
+ mol -> add (atom);
+ for (unsigned int i = 0; i < bonds.size (); i++) {
+ mol -> add (bonds[i]);
+ }
+ builder -> delete_Hs (atom, curr_H_atoms, curr_H_bonds);
+ builder -> add_H (atom, prev_H_atoms, prev_H_bonds);
+ for (unsigned int i = 0; i < bonds.size (); i++) {
+ builder -> delete_Hs (bound[i], curr_targets_H_atoms[i], curr_targets_H_bonds[i]);
+ builder -> add_H (bound[i], prev_targets_H_atoms[i], prev_targets_H_bonds[i]);
+ }
+
+ builder -> redefine_mol (mol);
+ ddwin -> gl -> draw_molecule (atom->residue->molecule);
+*/
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////
+
+
+
+AddAtomCommand::AddAtomCommand ( Atom *at, ZNBond *bo, Atom *part, DDWin *ddwin_point) : Command ()
+{
+ ZNMolecule *mol = (ZNMolecule *) part -> GetParent ();
+ // first_time = true;
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Add atom"));
+ atom = at;
+ partner = part;
+ bond = bo;
+ builder -> save_Hs (partner, prev_H_atoms, prev_H_bonds);
+ // builder -> save_Hs (at, prev_target_H_atoms, prev_target_H_bonds);
+ builder -> delete_Hs (partner);
+ mol -> add_atom_bonded_to (atom, bond, partner);
+ mol -> ZNAddHydrogens (partner);
+ mol -> ZNAddHydrogens (at);
+ builder -> save_Hs (partner, curr_H_atoms, curr_H_bonds);
+ builder -> save_Hs (at, curr_target_H_atoms, curr_target_H_bonds);
+ finalise_molecule(mol);
+ molecule_has_changed (mol);
+}
+
+
+void AddAtomCommand::redo () {
+ ZNMolecule *mol = (ZNMolecule *) partner -> GetParent ();
+
+ if (!first_time) {
+
+ builder -> delete_Hs (partner);
+ mol -> add_atom_bonded_to (atom, bond, partner);
+
+
+ // builder -> redefine_mol (mol);
+
+ // builder -> delete_Hs (atom);
+ builder -> add_Hs (partner, curr_H_atoms, curr_H_bonds);
+ builder -> add_Hs (atom, curr_target_H_atoms, curr_target_H_bonds);
+
+ // builder -> redefine_mol (mol);
+
+ ddwin -> gl -> draw_molecule (mol);
+ }
+ first_time = false;
+ molecule_has_changed (mol);
+}
+
+void AddAtomCommand::undo () {
+ ZNMolecule *mol = (ZNMolecule *) atom -> GetParent ();
+ builder -> delete_Hs (atom);
+ mol -> RemoveAtom (atom);
+ // mol -> RemoveBond (bond);
+ builder -> delete_Hs (partner);
+ builder -> add_Hs (partner, prev_H_atoms, prev_H_bonds);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+
+
+
+}
+
+
+///////////////////////////////////////////////////////////
+
+AddBondCommand::AddBondCommand (ZNBond *bo, DDWin *ddwin_point): Command ()
+ {
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Add bond"));
+ bond = bo;
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+
+ builder -> save_Hs (at1, prev_H_atoms0, prev_H_bonds0);
+ builder -> save_Hs (at2, prev_H_atoms1, prev_H_bonds1);
+
+
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+ mol -> ZNAddBond (bond);
+ mol -> ZNAddHydrogens (at1);
+ mol -> ZNAddHydrogens (at2);
+ builder -> save_Hs (at1, curr_H_atoms0, curr_H_bonds0);
+ builder -> save_Hs (at2, curr_H_atoms1, curr_H_bonds1);
+ finalise_molecule(mol);
+ molecule_has_changed (mol);
+
+}
+
+
+void AddBondCommand::redo () {
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ if (!first_time) {
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+ mol -> ZNAddBond (bond);
+ builder -> add_Hs (at1, curr_H_atoms0, curr_H_bonds0);
+ builder -> add_Hs (at2, curr_H_atoms1, curr_H_bonds1);
+ }
+ ddwin -> gl -> draw_molecule (mol);
+ first_time = false;
+ molecule_has_changed (mol);
+
+}
+
+void AddBondCommand::undo () {
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+ mol -> RemoveBond (bond);
+ builder -> add_Hs (at1, prev_H_atoms0, prev_H_bonds0);
+ builder -> add_Hs (at2, prev_H_atoms1, prev_H_bonds1);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+}
+
+
+DeleteBondCommand::DeleteBondCommand (ZNBond *bo, DDWin *ddwin_point) : AddBondCommand (bo, ddwin_point) {
+ setText ( QString ("Delete bond"));
+
+}
+
+void DeleteBondCommand::undo () {
+ AddBondCommand::redo ();
+}
+
+
+void DeleteBondCommand::redo () {
+ AddBondCommand::undo ();
+}
+///////////////////////////////////////////////////////////
+
+ModifyBondCommand::ModifyBondCommand (ZNBond *bo, int new_o, DDWin *ddwin_point, bool red) : Command ()
+{
+ first_time = true;
+ redefine = red;
+ new_order = new_o;
+ old_order = bo -> GetBondOrder ();
+ ddwin = ddwin_point;
+ builder = ddwin -> builder;
+ setText ( QString ("Change ZNBond Order"));
+ bond = bo;
+
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ builder -> save_Hs (at1, prev_H_atoms0, prev_H_bonds0);
+ builder -> save_Hs (at2, prev_H_atoms1, prev_H_bonds1);
+ // builder -> save_Hs (at, prev_target_H_atoms, prev_target_H_bonds);
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+
+ bond -> SetBondOrder (new_order);
+ mol -> ZNAddHydrogens (at1);
+ mol -> ZNAddHydrogens (at2);
+ builder -> save_Hs (at1, curr_H_atoms0, curr_H_bonds0);
+ builder -> save_Hs (at2, curr_H_atoms1, curr_H_bonds1);
+ finalise_molecule(mol);
+ molecule_has_changed (mol);
+}
+
+
+void ModifyBondCommand::redo () {
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ if (!first_time) {
+
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+ bond -> SetBondOrder (new_order);
+ builder -> add_Hs (at1, curr_H_atoms0, curr_H_bonds0);
+ builder -> add_Hs (at2, curr_H_atoms1, curr_H_bonds1);
+
+ }
+ ddwin -> gl -> draw_molecule (mol);
+ first_time = false;
+ molecule_has_changed (mol);
+}
+
+
+void ModifyBondCommand::undo () {
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ ZNMolecule *mol = (ZNMolecule *) at1 -> GetParent ();
+ builder -> delete_Hs (at1);
+ builder -> delete_Hs (at2);
+ bond -> SetBondOrder (old_order);
+ builder -> add_Hs (at1, prev_H_atoms0, prev_H_bonds0);
+ builder -> add_Hs (at2, prev_H_atoms1, prev_H_bonds1);
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+
+}
+
+
+///////////////////////////////////////////////////////////
+
+RedefineZNMoleculeCommand::RedefineZNMoleculeCommand (ZNMolecule *mo, Builder *bu, int mod) : Command ()
+{
+/* mode = mod;
+ builder = bu;
+ setText ( QString ("Redefine Mol"));
+ mol = mo;
+*/
+}
+
+
+void RedefineZNMoleculeCommand::redo () {
+/* if (mode !=1 ) {
+ builder -> redefine_mol (mol);
+ builder -> ddwin -> gl -> draw_molecule (mol);
+ }
+*/
+}
+
+void RedefineZNMoleculeCommand::undo () {
+/* if (mode != 0) {
+ builder -> redefine_mol (mol);
+ builder -> ddwin -> gl -> draw_molecule (mol);
+ }
+*/
+}
+
+
+///////////////////////////////////////////////////////////////////////
+
+
+ReprotonateCommand::ReprotonateCommand (ZNMolecule *molecule, DDWin *ddw, double ph) {
+ setText ( QString ("Reprotonate"));
+ ddwin = ddw;
+ mol = molecule;
+ first_time = true;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (a ->IsHydrogen ()) {
+ prev_H_atoms.push_back (&*a);
+ OBBondIterator i;
+ Atom *b = a -> BeginNbrAtom (i);
+ prev_partners.push_back (&*b);
+ prev_H_bonds.push_back (mol -> GetBond (&*a, b));
+ // prec_bonds.push_back ()
+ }
+ }
+
+ ddwin ->builder -> delete_Hs (mol);
+ mol -> ZNAddHydrogens (ph);
+ ddwin ->gl -> draw_molecule (mol);
+
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (a ->IsHydrogen ()) {
+ curr_H_atoms.push_back (&*a);
+ OBBondIterator i;
+ Atom *b = a -> BeginNbrAtom (i);
+ curr_partners.push_back (&*b);
+ curr_H_bonds.push_back (mol -> GetBond (&*a, b));
+ // prec_bonds.push_back ()
+ }
+ }
+ molecule_has_changed (mol);
+}
+
+
+void ReprotonateCommand::redo () {
+ if (!first_time) {
+ ddwin ->builder -> delete_Hs (mol);
+ for (unsigned int i = 0; i< curr_H_atoms.size (); i++) {
+ mol -> add_atom_bonded_to (curr_H_atoms[i], curr_H_bonds[i], curr_partners[i]);
+ }
+
+ }
+ ddwin -> gl -> draw_molecule (mol);
+ first_time = false;
+ molecule_has_changed (mol);
+}
+
+
+void ReprotonateCommand::undo () {
+ ddwin ->builder -> delete_Hs (mol);
+ for (unsigned int i = 0; i< prev_H_atoms.size (); i++) {
+ mol -> add_atom_bonded_to (prev_H_atoms[i], prev_H_bonds[i], prev_partners[i]);
+ }
+ ddwin -> gl -> draw_molecule (mol);
+ molecule_has_changed (mol);
+}
diff --git a/constants.cc b/constants.cc
new file mode 100644
index 0000000..82a63f0
--- /dev/null
+++ b/constants.cc
@@ -0,0 +1,639 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "constants.h"
+#include <math.h>
+
+#ifdef WIN32
+#include <float.h>
+#define isnan _isnan
+#endif // WIN32
+
+
+color average_3_colors (float score, color c1, color c2, color c3, float begin, float mid, float end) {
+float mid_width = 0.1 * (mid - begin);
+float mid_width2 = 0.1 * (end - mid);
+if (mid_width2 < mid_width) mid_width = mid_width2;
+
+
+
+float q = score;
+if (q <= begin) {
+ return c1;
+}
+else if (q >= end) {
+ return c3;
+}
+else if (q>= mid - mid_width && q<= mid + mid_width) {
+ return c2;
+
+}
+else if (q<= mid) {
+ float perc = (mid - q - mid_width) / (mid - begin - mid_width);
+ float b_red = c1.redF ();
+ float b_green = c1.greenF ();
+ float b_blue = c1.blueF ();
+ float b_alpha = c1.alphaF ();
+ float m_red = c2.redF ();
+ float m_green = c2.greenF ();
+ float m_blue = c2.blueF ();
+ float m_alpha = c2.alphaF ();
+
+ float r = (b_red * perc + m_red * (1-perc)) ;
+ float g = (b_green* perc + m_green * (1-perc)) ;
+ float b = (b_blue * perc + m_blue * (1-perc)) ;
+ float a = (b_alpha * perc + m_alpha * (1-perc)) ;
+ return color (r, g, b, a);
+
+}
+else {
+ float perc = (q - mid -mid_width) / (end -mid_width- mid);
+ float e_red = c3.redF ();
+ float e_green = c3.greenF ();
+ float e_blue = c3.blueF ();
+ float e_alpha = c3.alphaF ();
+ float m_red = c2.redF ();
+ float m_green = c2.greenF ();
+ float m_blue = c2.blueF ();
+ float m_alpha = c2.alphaF ();
+
+ float r = (m_red * perc + e_red * (1-perc)) ;
+ float g = (m_green* perc + e_green * (1-perc)) ;
+ float b = (m_blue * perc + e_blue * (1-perc)) ;
+ float a = (m_alpha * perc + e_alpha * (1-perc)) ;
+ return color (r, g, b, a);
+
+}
+
+}
+
+
+
+
+
+float angle (vect coord1, vect coord2, vect coord3) {
+ vect v1 = subtract (coord1, coord2);
+ vect v2 = subtract (coord3, coord2);
+ float cosine = dot_product (v1, v2)/(v1.module () * v2.module ());
+ if (cosine < -1) cosine = -1;
+ else if (cosine > 1) cosine = 1;
+ return (acos (cosine)) * 180 / PI;
+
+
+}
+
+
+float signed_angle (vect coord1, vect coord2, vect coord3) {
+ vect v1 = subtract (coord1, coord2);
+ vect v2 = subtract (coord3, coord2);
+ vect c = cross_product (v1, v2);
+ float angle = atan2(c.module (), dot_product(v1, v2))* 180 / PI;
+ vect reference (0., 0., 1.);
+ return dot_product (c, reference) < 0.f ? -angle : angle;
+}
+
+
+double dihedral (vect coord1, vect coord2, vect coord3, vect coord4) {
+ vect v1 = subtract (coord1, coord2);
+ vect v2 = subtract (coord3, coord2);
+ vect n1 = cross_product (v1, v2);
+ vect v3 = v2;
+ v3.multiply (-1.0f);
+ vect v4 = subtract (coord4, coord3);
+ vect n2 = cross_product (v3, v4);
+ vect orig;
+ orig.null ();
+ float mult = 1.f;
+ if (dot_product (v2, cross_product(n1, n2)) < 0.) mult = -1.f;
+ return mult * angle (n1, orig, n2);
+}
+
+
+
+
+double wilson (vect coord1, vect coord2, vect coord3, vect coord4) {
+ vect v1 = subtract (coord1, coord2);
+ vect v2 = subtract (coord3, coord2);
+ vect n1 = cross_product (v1, v2);
+ float a = n1.x();
+ float b = n1.y();
+ float c = n1.z();
+ float d = -1.f * (coord2.x() * n1.x() + coord2.y() * n1.y() + coord2.z() * n1.z());
+ double dis = (a*coord4.x() + b*coord4.y() +c*coord4.z() +d) / n1.module ();
+ double sin = dis / dist (coord4, coord2);
+ if (sin < -1.f) sin = -1.f;
+ if (sin > 1.f) sin = 1.f;
+ return asin (sin);
+}
+
+double wilson (float *coord1, float *coord2, float *coord3, float *coord4){
+ float v1x, v1y, v1z, v2x, v2y, v2z, n1[3], a, b, c, d;
+
+ v1x = coord1[0]-coord2[0];
+ v1y = coord1[1]-coord2[1];
+ v1z = coord1[2]-coord2[2];
+
+
+ v2x = coord3[0]-coord2[0];
+ v2y = coord3[1]-coord2[1];
+ v2z = coord3[2]-coord2[2];
+
+ n1[0] = v1y*v2z - v1z*v2y;
+ n1[1] = v1z*v2x - v1x*v2z;
+ n1[2] = v1x*v2y - v1y*v2x;
+
+ a = n1[0];
+ b = n1[1];
+ c = n1[2];
+ d = -1* (coord2[0]*n1[0]+coord2[1]*n1[1]+coord2[2]*n1[2]);
+ double dist = (a*coord4[0] + b*coord4[1] +c*coord4[2] +d)/sqrt (a*a +b*b+c*c);
+ double si = dist/distance (coord4, coord2);
+ if (si > 1.) si = 1.;
+ else if (si < -1.) si = -1.;
+ return asin (si);
+}
+
+
+void rotate_around_vector (vect &point, vect torque, vect center, float angle) {
+ torque.normalise ();
+ vect dir = subtract (point, center);
+ float sa =sin(angle);
+ float ca =cos(angle);
+ float u = torque.x();
+ float v = torque.y();
+ float w = torque.z();
+ float x = dir.x();
+ float y = dir.y();
+ float z = dir.z();
+
+ float ux = u*x;
+ float uy = u*y;
+ float uz = u*z;
+ float vx = v*x;
+ float vy = v*y;
+ float vz = v*z;
+ float wx = w*x;
+ float wy = w*y;
+ float wz = w*z;
+
+ point.x()= u*(ux+vy+wz)+(x*(v*v+w*w)-u*(vy+wz))*ca+(-wy+vz)*sa+center.x();
+ point.y()= v*(ux+vy+wz)+(y*(u*u+w*w)-v*(ux+wz))*ca+(wx-uz)*sa+center.y();
+ point.z()= w*(ux+vy+wz)+(z*(u*u+v*v)-w*(ux+vy))*ca+(-vx+uy)*sa+center.z();
+
+}
+
+
+void rotate_to_plane (vect up_point, vect right_point, vect cent_point) {
+ vect pointA, pointB, pointC;
+ pointA = subtract (up_point, cent_point);
+ pointB = subtract (right_point, cent_point);
+ pointC = cent_point;
+ float rangle;
+ float A, B, C;
+ glTranslatef (pointC.x(), pointC.y(), pointC.z());
+ //equation of plane Ax + By + Cz = 0
+
+ if (!pointA.z() && !pointB.z()) { //all three points on z=0 plane... we're already there
+
+ }
+ else if (pointA.x() && pointB.x() && (pointA.y()*pointB.x()-pointA.x()*pointB.y())){
+ //equation (A/C)*x + (B/C)*y +z = 0
+ C = 1.f;
+ B = (pointA.x()*pointB.z()-pointB.x()*pointA.z())/(pointA.y()*pointB.x()-pointA.x()*pointB.y());
+ A = (-pointA.z()-B*pointA.y())/pointA.x();
+ //rotation axis A*x + B*y
+ //perpendicular aA + bB = 0
+
+
+ //perpendicular -B*x + A*y = 0
+ //point x=1 y=B/A
+ //point on the plane z= -(A + B*B/A)
+ float xp, yp, zp;
+ xp = 1.f;
+ yp = B/A;
+ zp = -(A + B*B/A);
+
+ float dist = sqrt(xp*xp+ yp*yp+zp*zp);
+ float s = zp / dist;
+ if (s > 1.f) s= 1.f;
+ else if (s < -1.f) s = -1.f;
+
+
+ rangle = asin (s);
+// cout<<rangle*180/PI;
+ // cout<<(-A/B*xp+yp)*zp;
+ if (rangle<0) {
+ rangle = -rangle;
+
+ }
+ // if (yp > -A/B*xp);
+ // rangle = PI+rangle;
+ glRotatef (-rangle*180/PI, B, -A, 0);
+
+
+
+ }
+
+ vect O;
+ O.null ();
+ vect rot_vec (B, -A, 0.f);
+ vect rot_vec2 (0.f, 0.f, 1.f);
+
+ vect a_point = pointA;
+ vect b_point = pointB;
+
+ rotate_around_vector (a_point, rot_vec, O, rangle);
+// cout << a_point [0]<<" "<< a_point [1]<<" "<< a_point [2]<<" "<<rangle<<endl;
+
+
+ float dis = a_point.module ();
+ float sang;
+ float start_ang;
+ float c = a_point.x()/dis;
+ if (c > 1.f) c= 1.f;
+ else if (c < -1.f) c = -1.f;
+ sang = acos (c);
+
+
+ if (a_point.y()<0.f) start_ang = sang;
+
+ // cout <<sang<<endl;
+ else start_ang = -sang;
+ glRotatef (-start_ang*180/PI, 0, 0, 1);
+
+
+ rotate_around_vector (b_point, rot_vec, O, rangle);
+ rotate_around_vector (b_point, rot_vec2, O, start_ang);
+ // cout << b_point [0]<<" "<< b_point [1]<<" "<< b_point [2]<<" "<<start_ang<<endl;
+ if (b_point.y()>0) glRotatef (180, 1, 0, 0);
+
+
+}
+
+
+
+
+void components (vect vec, vect ref, vect ¶llel, vect &normal){
+ assert (!isnan (vec.module ()));
+ assert (!isnan (ref.module ()));
+ ref.normalise ();
+ double mod = dot_product (vec, ref);
+// cerr << vec.x() << " "<< vec.y() << " "<< vec.z() << " "<< ref.x() << " "<< ref.y() << " "<< ref.z() << " "<< endl;
+ ref.multiply (mod);
+ parallel = ref;
+ normal = subtract (vec, parallel);
+ assert (!isnan (parallel.module ()));
+ assert (!isnan (normal.module ()));
+}
+
+
+
+
+
+
+
+vect torque (vect force, vect coords, vect center) {
+ vect pos = subtract (coords, center);
+ return cross_product (pos, force);
+}
+
+
+void axis_angle_to_quaternion (vect axis, float angle, float *quaternion) {
+ axis.normalise ();
+ float s = sin(angle/2);
+ quaternion[0] = cos(angle/2);
+ quaternion[1] = axis.x() * s;
+ quaternion[2] = axis.y() * s;
+ quaternion[3] = axis.z() * s;
+}
+
+quaternion axis_angle_to_quaternion (vect axis, float angle) { //angle in rads
+ axis.normalise ();
+ float s = sin(angle/2);
+ quaternion q (cos(angle/2), axis.x() * s, axis.y() * s, axis.z() * s);
+ return q;
+}
+
+void axis_angle_to_quaternion (float *axis, float angle, float *quaternion) { //angle in rads
+
+ float ax[3];
+ ax[0] = axis[0];
+ ax[1] = axis[1];
+ ax[2] = axis[2];
+ float ax_mod = sqrt (ax[0]*ax[0]+ax[1]*ax[1]+ax[2]*ax[2]);
+ if (ax_mod && angle) {
+ ax[0] /= ax_mod;
+ ax[1] /= ax_mod;
+ ax[2] /= ax_mod;
+
+ // cout << "axis "<<ax[0]<<" "<<ax[1]<<" "<<ax[2]<< endl;
+ float s = sin(angle/2);
+ quaternion[0] = cos(angle/2);
+ quaternion[1] = ax[0] * s;
+ quaternion[2] = ax[1] * s;
+ quaternion[3] = ax[2] * s;
+
+ }
+
+ else {
+ quaternion[0] = 1;
+ quaternion[1] = 0;
+ quaternion[1] = 0;
+ quaternion[1] = 0;
+ }
+}
+
+
+quaternion yaw_pitch_roll_to_quaternion (float yaw, float pitch, float roll) {
+ quaternion x = axis_angle_to_quaternion (vect(1.,0.,0.), roll);
+ quaternion y = axis_angle_to_quaternion (vect(0.,1.,0.), pitch);
+ quaternion z = axis_angle_to_quaternion (vect(0.,0.,1.), yaw);
+
+
+
+ x = multiply_quaternions ( x, y );
+ y = multiply_quaternions (x, z);
+
+ return x;
+}
+
+
+void multiply_quaternions (float *q1, float *q2, float *prod) {
+
+ prod[0] = q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3];
+ prod[1] = q1[0]*q2[1] + q1[1]*q2[0] + q1[2]*q2[3] - q1[3]*q2[2];
+ prod[2] = q1[0]*q2[2] - q1[1]*q2[3] + q1[2]*q2[0] + q1[3]*q2[1];
+ prod[3] = q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1] + q1[3]*q2[0];
+
+
+
+}
+
+
+quaternion multiply_quaternions (quaternion q1, quaternion q2) {
+ double w = q1.w ()*q2.w () - q1.x ()*q2.x () - q1.y ()*q2.y () - q1.z ()*q2.z ();
+ double x = q1.w ()*q2.x () + q1.x ()*q2.w () + q1.y ()*q2.z () - q1.z ()*q2.y ();
+ double y = q1.w ()*q2.y () - q1.x ()*q2.z () + q1.y ()*q2.w () + q1.z ()*q2.x () ;
+ double z = q1.w ()*q2.z () + q1.x ()*q2.y () - q1.y ()*q2.x () + q1.z ()*q2.w () ;
+ return quaternion (w, x, y, z);
+
+}
+
+
+
+void invert_matrix_9 (double *m, double *i) {
+ double m11, m12, m13, m21, m22, m23, m31, m32, m33;
+ m11 = m[0];
+ m12 = m[1];
+ m13 = m[2];
+ m21 = m[3];
+ m22 = m[4];
+ m23 = m[5];
+ m31 = m[6];
+ m32 = m[7];
+ m33 = m[8];
+ double det = m11*m22*m33 + m12*m23*m31 + m13*m31*m32 - m11*m23*m32 - m12*m21*m33 - m13*m22*m31;
+ if (det == 0) det = 0.0000001f;
+ i[0] = (m22*m33 - m23*m32) / det;
+ i[1] = (m13*m32 - m12*m33) / det;
+ i[2] = (m12*m23 - m13*m22) / det;
+ i[3] = (m23*m31 - m21*m33) / det;
+ i[4] = (m11*m33 - m13*m31) / det;
+ i[5] = (m13*m21 - m11*m23) / det;
+ i[6] = (m21*m32 - m22*m31) / det;
+ i[7] = (m12*m31 - m11*m32) / det;
+ i[8] = (m11*m22 - m12*m21) / det;
+
+}
+
+
+void map_vector_on_vector_quaternion (vect v1, vect v2, float *quaternion) {
+ v1.normalise();
+ v2.normalise();
+ vect axis = cross_product(v1, v2);
+ float angle = acos (dot_product(v1, v2));
+ axis_angle_to_quaternion (axis, angle, quaternion);
+
+}
+
+
+quaternion map_vector_on_vector_quaternion (vect v1, vect v2) {
+ quaternion q (0., 1., 0., 0.);
+ v1.normalise();
+ v2.normalise();
+ vect axis = cross_product(v1, v2);
+ double dotproduct = dot_product(v1, v2);
+ if (dotproduct >1.) dotproduct = 1.;
+ if (dotproduct <-1.) dotproduct = -1.;
+ float angle = acos (dotproduct);
+ q = axis_angle_to_quaternion (axis, angle);
+ return q;
+
+}
+
+
+
+vect rotate_vector_using_matrix_9 (vect v, double *m) {
+ double m11, m12, m13, m21, m22, m23, m31, m32, m33;
+ m11 = m[0];
+ m12 = m[1];
+ m13 = m[2];
+ m21 = m[3];
+ m22 = m[4];
+ m23 = m[5];
+ m31 = m[6];
+ m32 = m[7];
+ m33 = m[8];
+ vect out;
+ out.x() = m11*v.x() + m12*v.y() + m13*v.z();
+ out.y() = m21*v.x() + m22*v.y() + m23*v.z();
+ out.z() = m31*v.x() + m32*v.y() + m33*v.z();
+ return out;
+}
+
+
+vect rotate_vector_using_matrix_16 (vect v, double *m) {
+ double m11, m12, m13, m21, m22, m23, m31, m32, m33; // w, x, y, z;
+ m11 = m[0];
+ m12 = m[1];
+ m13 = m[2];
+ m21 = m[4];
+ m22 = m[5];
+ m23 = m[6];
+ m31 = m[7];
+ m32 = m[8];
+ m33 = m[9];
+ vect out;
+ out.x() = m11*v.x() + m12*v.y() + m13*v.z();
+ out.y() = m21*v.x() + m22*v.y() + m23*v.z();
+ out.z() = m31*v.x() + m32*v.y() + m33*v.z();
+ return out;
+}
+
+vect rotate_vector_using_quaternion (vect v, quaternion q) {
+ double m11, m12, m13, m21, m22, m23, m31, m32, m33, w, x, y, z;
+ w = q.w ();
+ x = q.x ();
+ y = q.y ();
+ z = q.z ();
+ m11 = 1 - 2 * ( y*y + z*z );
+ m12 = 2 * ( x*y - z*w );
+ m13 = 2 * ( x*z + y*w );
+ m21 = 2 * ( x*y + z*w );
+ m22 = 1 - 2 * ( x*x + z*z );
+ m23 = 2 * ( y*z - x*w );
+ m31 = 2 * ( x*z - y*w );
+ m32 = 2 * ( y*z + x*w );
+ m33 = 1 - 2 * ( x*x + y*y );
+ vect out;
+ out.x() = m11*v.x() + m12*v.y() + m13*v.z();
+ out.y() = m21*v.x() + m22*v.y() + m23*v.z();
+ out.z() = m31*v.x() + m32*v.y() + m33*v.z();
+ return out;
+}
+
+
+
+vect rotate_vector_using_quaternion (vect v, float *q) {
+ double m11, m12, m13, m21, m22, m23, m31, m32, m33, w, x, y, z;
+ w = q[0];
+ x = q[1];
+ y = q[2];
+ z = q[3];
+ m11 = 1 - 2 * ( y*y + z*z );
+ m12 = 2 * ( x*y - z*w );
+ m13 = 2 * ( x*z + y*w );
+ m21 = 2 * ( x*y + z*w );
+ m22 = 1 - 2 * ( x*x + z*z );
+ m23 = 2 * ( y*z - x*w );
+ m31 = 2 * ( x*z - y*w );
+ m32 = 2 * ( y*z + x*w );
+ m33 = 1 - 2 * ( x*x + y*y );
+ vect out;
+ out.x() = m11*v.x() + m12*v.y() + m13*v.z();
+ out.y() = m21*v.x() + m22*v.y() + m23*v.z();
+ out.z() = m31*v.x() + m32*v.y() + m33*v.z();
+ return out;
+}
+
+
+void rotate_vector_using_quaternion (float *v, float *q, float *out) {
+ float m11, m12, m13, m21, m22, m23, m31, m32, m33, w, x, y, z;
+ w = q[0];
+ x = q[1];
+ y = q[2];
+ z = q[3];
+/* m11 = 1-2*y*y-2*z*z;
+ m12 = 2*x*y-2*w*z;
+ m13 = 2*x*z+2*w*y;
+ m21 = 2*x*y+2*w*z;
+ m22 = 1-2*x*x-2*z*z;
+ m23 = 2*y*z-2*w*x;
+ m31 = 2*x*z-2*w*y;
+ m32 = 2*y*z-2*w*x;
+ m33 = 1-2*x*x-2*y*y;
+*/
+
+
+ m11 = 1 - 2 * ( y*y + z*z );
+ m12 = 2 * ( x*y - z*w );
+ m13 = 2 * ( x*z + y*w );
+ m21 = 2 * ( x*y + z*w );
+ m22 = 1 - 2 * ( x*x + z*z );
+ m23 = 2 * ( y*z - x*w );
+ m31 = 2 * ( x*z - y*w );
+ m32 = 2 * ( y*z + x*w );
+ m33 = 1 - 2 * ( x*x + y*y );
+
+
+
+
+
+
+
+
+ out[0] = m11*v[0] + m12*v[1] + m13*v[2];
+ out[1] = m21*v[0] + m22*v[1] + m23*v[2];
+ out[2] = m31*v[0] + m32*v[1] + m33*v[2];
+
+}
+
+void normalize_quaternion (float *q) {
+ float mod = sqrt (q[0]*q[0]+q[1]*q[1]+q[2]*q[2]+q[3]*q[3]);
+// cout <<q[0]<<" "<<q[0]/mod<<" "<<mod<<endl;
+ q[0] /= mod;
+ q[1] /= mod;
+ q[2] /= mod;
+ q[3] /= mod;
+}
+
+
+
+double string_to_double (string s) {
+ istringstream ss (s);
+ double d;
+ ss >> d;
+ return d;
+};
+
+
+int string_to_int (string s) {
+ istringstream ss (s);
+ int i;
+ ss >> i;
+ return i;
+}
+string int_to_string (int i) {
+ stringstream ss;
+ ss << i;
+ return ss.str ();
+}
+
+string double_to_string (double d) {
+ stringstream ss;
+ ss << d;
+ return ss.str ();
+}
+
+
+color mean (color c1, color c2) {
+ return color ((float)(c1.redF()+c2.redF())*0.5f,(float) (c1.greenF()+c2.greenF())*0.5f,(float) (c1.blueF()+c2.blueF())*0.5f,(float) (c1.alphaF()+c2.alphaF())*0.5f);
+}
+color::color () : QColor ()
+{
+ setRedF (1.f);
+ setGreenF (1.f);
+ setBlueF (1.f);
+ setAlphaF (1.f);
+}
+
+color::color (float r, float g, float b, float a) : QColor ()
+{
+ setRedF (r);
+ setGreenF (g);
+ setBlueF (b);
+ setAlphaF (a);
+}
+
+
+color::color (int r, int g, int b, int a) : QColor (r, g, b, a) {}
+
+
+
+
diff --git a/database.cc b/database.cc
new file mode 100644
index 0000000..c5f7d51
--- /dev/null
+++ b/database.cc
@@ -0,0 +1,240 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "database.h"
+
+
+Database_molecule::Database_molecule () : ZNMolecule (), database (NULL) {
+ multi = true;
+
+}
+
+
+
+
+Database_molecule::Database_molecule (const ZNMolecule &mol)
+//: ZNMolecule( *(ZNMolecule::ZNMolecule *)&mol )
+: ZNMolecule( mol )
+{
+
+ // OBMol::OBMol (*this);
+ // (*(OBMol::OBMol *)this)(mol);
+ multi = true;
+}
+
+Database_molecule &Database_molecule::operator =(const Database_molecule &mol)
+{
+// *(ZNMolecule::ZNMolecule *)this = *(ZNMolecule::ZNMolecule *)&mol;
+ ZNMolecule::operator =(mol);
+ multi = true;
+ return *this;
+}
+
+
+
+
+Database::Database () : _needs_redraw (false), _hidden (true), _extend_enabled (false), dummy_mol (new Database_molecule ()){
+ dummy_mol = new Database_molecule ();
+ dummy_mol -> database = this;
+ dummy_mol -> number = -1;
+ finalise_molecule (dummy_mol);
+ mutex = new QReadWriteLock ();
+ field_names.push_back ("Molecule");
+ sorting_column = new int (0);
+}
+
+void Database::safe_add_field (string name, vector <double> data) {
+ mutex ->lockForWrite ();
+ add_field (name, data);
+ mutex ->unlock ();
+}
+void Database::add_field (string name, vector <double> data) {
+ if (data.size () == count_entries ()) {
+ field_names.push_back (name);
+ for (unsigned int i = 0; i < data.size (); i++) {
+ DoubleDatabaseCell *cell = new DoubleDatabaseCell (data[i]);
+ entries[i] ->cells.push_back (cell);
+
+ }
+
+ }
+ set_needs_redraw (true);
+}
+
+void Database::safe_add_field (string name, vector <string> data, char type) {
+ mutex ->lockForWrite ();
+ add_field (name, data, type);
+ mutex ->unlock ();
+}
+
+void Database::add_field (string name, vector <string> data, char type) {
+
+ if (data.size () == count_entries ()) {
+ field_names.push_back (name);
+ for (unsigned int i = 0; i < data.size (); i++) {
+ if (type == 'd') {
+ double doub = string_to_double (data[i]);
+ DoubleDatabaseCell *cell = new DoubleDatabaseCell (doub);
+ entries[i]->cells.push_back (cell);
+ }
+ }
+
+ }
+ set_needs_redraw (true);
+
+}
+
+ZNMolecule *Database::get_molecule (int n) {
+ if (count_entries () > n) {
+ return ((ZNMoleculeDatabaseCell *) entries[n]->cells[0])->get_molecule ();
+ }
+ else return NULL;
+}
+
+void Database::safe_add_mol (Database_molecule *mol) {
+ mutex ->lockForWrite ();
+ add_mol (mol);
+ mutex ->unlock ();
+}
+
+void Database::add_mol (Database_molecule *mol) {
+
+ DatabaseEntry *entry = new DatabaseEntry (mol);
+ ZNMoleculeDatabaseCell *cell = new ZNMoleculeDatabaseCell (mol);
+ entry ->cells.clear ();
+
+ entry ->cells.push_back (cell);
+ for (unsigned int i = 1; i < field_names.size (); i++) {
+ DoubleDatabaseCell *cell2 = new DoubleDatabaseCell (0);
+ entry ->cells.push_back (cell2);
+ }
+ entry ->sorting_column = sorting_column;
+ //cerr << "assign "<<entry ->sorting_column <<" "<< &sorting_column;
+ entries.push_back (entry);
+ mol -> database = this;
+ mol -> number = count_entries ()-1;
+ set_needs_redraw (true);
+
+}
+
+void Database::delete_entry (int i) {
+ if (0<=i<count_entries()) {
+ delete entries [i];
+ entries.erase (entries.begin ()+i);
+ }
+}
+
+void Database::safe_sort_up (int column) {
+ mutex ->lockForWrite ();
+ sort_up (column);
+ mutex ->unlock ();
+}
+
+void Database::safe_sort_down (int column) {
+ mutex ->lockForWrite ();
+ sort_down (column);
+ mutex ->unlock ();
+}
+
+void Database::sort_up (int column) {
+// cerr <<"sorting up" << column <<endl;
+ if (0 <= column < count_fields ()) {
+ *sorting_column = column;
+ sort (entries.begin (), entries.end (), compare_cell ());
+ set_needs_redraw (true);
+ }
+ // cerr <<"sorting up end" << endl;
+
+}
+
+
+void Database::sort_down (int column) {
+ // cerr <<"sorting down" << column <<endl;
+ if (0 <= column < count_fields ()) {
+ sort (entries.begin (), entries.end (), compare_cell ());
+ reverse (entries.begin (), entries.end ());
+ set_needs_redraw (true);
+ }
+ // cerr <<"sorting down end" << endl;
+}
+
+void Database::safe_merge_with (Database *dat) {
+ mutex ->lockForWrite ();
+ merge_with (dat);
+ mutex ->unlock ();
+}
+
+
+void Database::merge_with (Database *dat) {
+ for (unsigned int i = 0; i < dat ->count_entries (); i++) {
+ Database_molecule *new_mol = new Database_molecule (*dat ->get_molecule (i));
+ add_mol (new_mol);
+ }
+}
+
+
+bool Database::has_extend_enabled () {
+ return _extend_enabled;
+}
+
+/*
+void Database::renumber () {
+ for (unsigned int i = 0; i < ref_molecules.size (); i++) {
+ ref_molecules[i] -> number = i;
+ }
+}
+*/
+
+void Database::import_csv (string filename) {
+ ifstream ifs (filename.c_str ());
+ string line, token;
+ vector < vector < string > > dats;
+ vector <string> names;
+ vector <string> value_line;
+ getline (ifs, line);
+ istringstream iss (line);
+ while (getline (iss, token, ',')) {
+ names.push_back (token);
+ }
+ for (unsigned int i = 0; i < names.size (); i++) {
+ vector <string> dat;
+ dats.push_back (dat);
+ }
+ while (getline(ifs, line)) {
+ value_line.clear ();
+ istringstream iss(line);
+ string token;
+ while (getline(iss, token, ',')){
+ value_line.push_back (token);
+ }
+ if (value_line.size () == names.size ()) {
+ for (unsigned int i = 0; i < value_line.size (); i ++) {
+ dats[i].push_back (value_line[i]);
+ }
+ }
+ }
+ ifs.close();
+ if (dats.size ()) {
+ cerr <<dats[0].size ()<<" "<<count_entries ()<<endl;
+ if (dats[0].size () == count_entries ()) {
+ for (unsigned int i = 1; i < dats.size (); i++) {
+ add_field (names[i], dats[i]);
+ }
+ }
+ }
+}
diff --git a/datagrid.cc b/datagrid.cc
new file mode 100644
index 0000000..e699424
--- /dev/null
+++ b/datagrid.cc
@@ -0,0 +1,11 @@
+/*
+ * datagrid.cc
+ * Zodiac
+ *
+ * Created by Nicola Zonta on 28/07/2008.
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "datagrid.h"
+
diff --git a/ddwin.cc b/ddwin.cc
new file mode 100644
index 0000000..a72b4fc
--- /dev/null
+++ b/ddwin.cc
@@ -0,0 +1,6168 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ddwin.h"
+
+
+#define WIREFRAME 0
+#define STICK 1
+#define CPK 2
+#define BALLANDSTICK 3
+#define BALLANDLINE 4
+
+#define NO_ATOMS 0
+#define SPHERES 1
+#define CPK_SPHERES 2
+#define SCALED_CPK_SPHERES 3
+
+#define NO_BONDS 0
+#define LINES 1
+#define STICKS 2
+
+#define BACKBONE_LINE 0
+#define BACKBONE_STICK 1
+
+
+#define AROMATIC_RINGS 0
+#define KEKULE 1
+#define AROMATIC_BONDS 2
+
+
+//modes
+#define NONE 0
+#define SELECT 1
+#define BUILDER 2
+#define MAGIC_PENCIL 3
+#define SELECT_EXTEND 4
+
+
+//color masks
+#define ELEMENT 0
+#define CHARGE 1
+#define SCORE 2
+#define COLOR 3
+
+
+
+//using namespace OpenBabel;
+
+
+
+/*
+
+void DDWin::read_grid_file (string filename, Grid &grid) {
+ float min =0;
+ float max =0;
+ bool line_read = false;
+ grid.vec.clear ();
+ string line ="";
+ ifstream file (filename.c_str ());
+ line_read = getline(file, line);
+
+ istringstream iss (line);
+ iss >> grid.OX;
+ iss >> grid.OY;
+ iss >> grid.OZ;
+ iss >> grid.NX;
+ iss >> grid.NY;
+ iss >> grid.NZ;
+ iss >> grid.RES;
+
+
+ for (unsigned int x =0; x<grid.NX; x++) {
+ for (unsigned int y =0; y<grid.NY; y++) {
+ for (unsigned int z =0; z<grid.NZ; z++) {
+
+ line_read = getline(file, line);
+ istringstream iss (line);
+ float val =0;
+ iss >> val;
+
+ if (val) {
+ if (x==0 && y==0 && z==0) {min =val; max = val;}
+ if (min > val) min =val;
+ if (max < val) max =val;
+ Grid_dot dot;
+ dot.val = val;
+ dot.x() = grid.OX+x*grid.RES;
+ dot.y() = grid.OY+y*grid.RES;
+ dot.z() = grid.OZ+z*grid.RES;
+ grid.vec.push_back (dot);
+ }
+ }
+ }
+ }
+ grid.min = min; grid.max=max;
+ cout<< "min "<<min<<" max "<<max;
+
+}
+
+
+*/
+
+ GLfloat x = 800.0f; GLfloat y = 600.0f;
+ ArcBallT ArcBall(x,y);
+Point2fT MousePt;
+const float PI2 = 2.0*3.1415926535f;
+GLUquadricObj *quadratic;
+
+
+
+
+
+
+DDWin::DDWin (QWidget *parent, Data *dat)
+: QMainWindow (parent), g_stencil_mask(0), g_stencil_mask_needs_redraw(false), g_stencil_mask_frame_counter(0),
+g_stereoMode(StereoMode_None)
+{
+ setAcceptDrops(true) ;
+ last_visited_dir = "";
+ edit_lock_counter = 0;
+ setMinimumWidth (400);
+ dat->set_ddwin (this);
+ accel = new Q3Accel (this);
+ setup_accel ();
+ setWindowTitle( QString(TITLE.c_str()) + QString(VERSION.c_str()) );
+ setWindowIcon ((QPixmap (":icons/zeden_ico.png")));
+ connect (this, SIGNAL (non_selection_molecules_updated ()), SLOT (emit_targets_updated()));
+
+
+ // QGLFormat f;
+ // f.setStereo (true);
+// f.setSampleBuffers (true);
+
+// QGLFormat::setDefaultFormat (f);
+ gl = new MyGl (this);
+ assert (gl);
+
+ setCentralWidget (gl);
+
+
+
+ undo_view = new QUndoView ();
+ undo_view -> setStack (data -> undo_stack);
+
+
+ ZNMolecule *all = new ZNMolecule;
+ assert (all);
+ all ->ZNinit();
+ all -> SetTitle ("all");
+ molecules.push_back (all);
+ target_molecule = all;
+ current_target = 0;
+ backbone_shown = true;
+ haptic_mode = false;
+ minimizing = false;
+
+ adding_restrains = false;
+ rec_movie = false;
+ rec_pov_movie = false;
+ show_labels = true;
+ last_frame = 0;
+ mode = NONE;
+
+ resize (800,600);
+ builder = new Builder (this);
+
+ set_popups ();
+
+ draw_menu ();
+}
+
+
+
+void DDWin::closeEvent(QCloseEvent *event)
+ {
+ QWidget::closeEvent(event);
+ cout << "quitting " <<endl;
+ assert (data);
+ assert (data -> qapp);
+ data ->write_preferences ();
+ data -> qapp -> quit ();
+ }
+
+
+
+
+
+
+
+
+void DDWin::raytraced_screenshot_slot () {
+ string filename;
+ filename = "povray.pov";
+ write_POV_source (filename);
+ string povcommand = "povray";
+ float ratio = 1.f;
+ int width = (int) (gl -> width () * ratio);
+ int height = (int) (gl -> height () * ratio);
+ stringstream command;
+ command << povcommand << " -UV +A -I" << filename << " -W" << width <<" -H" << height <<"&";
+ system (command.str ().c_str ());
+}
+
+
+void DDWin::emit_targets_updated () {targets_updated ();}
+
+string DDWin::write_mol2_string (ZNMolecule *mol) {
+ return "not implemented";
+
+/*
+ stringstream out;
+ out << "@<TRIPOS>MOLECULE"<<endl;
+ out<<mol->name<<endl;
+ out<<mol->atoms.size ()<<" "<<mol->bonds.size ()<<" 0 0"<<endl;
+ out<<endl<<endl;
+ out<<"@<TRIPOS>ATOM"<<endl;
+ for (unsigned int i=0; i<mol->atoms.size (); i++) {
+ Atom *at = mol->atoms[i];
+ out << at->ID<<" "<<at->mol2Type<<" "<<at-> GetVector ().x()<<" "<<at-> GetVector ().y()<<" "<<at-> GetVector ().z()<<" "<<at->atomType<<" "<<at->residue->number<<" "<<at->residue->name<<" "<<at->charge<<endl;
+ }
+ out<<"@<TRIPOS>BOND"<<endl;
+ for (unsigned int i=0; i<mol->bonds.size (); i++) {
+ string type;
+ ZNBond *bo = mol->bonds[i];
+ if (bo->mol2Type ==1) type = "1";
+ else if (bo->mol2Type ==2) type = "2";
+ else if (bo->mol2Type ==3) type = "3";
+ else if (bo->mol2Type ==4) type = "am";
+ else type = "ar";
+
+ out<<bo->number<<" "<<bo->GetBeginAtom ()->ID<<" "<<bo->GetEndAtom ()->ID<<" "<<type<<endl;
+ }
+ return out.str ();
+*/
+}
+
+
+
+void DDWin::open_file_slot () {
+ QString mol_name = QFileDialog::getOpenFileName(this, tr ("Open file"), last_visited_dir, tr("All Files (*)"));
+
+ if (!mol_name.isEmpty ()) {
+ last_visited_dir = QDir (mol_name).path ();
+ load_file (mol_name.toStdString());
+ }
+}
+
+void DDWin::open_session_file_slot () {
+ QString mol_name = QFileDialog::getOpenFileName(this, tr ("Open file"), last_visited_dir, tr("Zodiac Session Files (*.zod)"));
+ if (!mol_name.isEmpty ()) data ->actions ->load_session (mol_name.toStdString ());
+/*
+ if (!mol_name.isEmpty ()) {
+ last_visited_dir = QDir (mol_name).path ();
+ load_file (mol_name.toStdString());
+ }
+*/
+}
+
+void DDWin::set_lists (ZNMolecule *mol) {
+ int bl1, bl2, ll, sl;
+ int zero = gl ->new_list ();
+
+ bl1 = gl->new_list ();
+ bl2 = gl->new_list ();
+ ll = gl->new_list ();
+ sl = gl->new_list ();
+
+ // if (mol->multi) {
+ // Database_molecule *dm;
+ // dm = (Database_molecule *) mol;
+ // for (unsigned int i=0; i<dm->database->molecules.size (); i++) {
+ // set_display_lists (dm->database->molecules[i], ll, bl1, bl2, sl); }
+ // }
+ // else {
+ set_display_lists (mol, ll, bl1, bl2, sl);
+ // }
+
+}
+
+
+void DDWin::show_grid (Database *dat) {
+ for (unsigned int i = 0; i < database_grids.size (); i++) {
+ if (database_grids [i] ->database == dat) {
+ database_grids[i] -> show ();
+ database_grids[i] -> raise ();
+ }
+ }
+}
+
+void DDWin::select (vector <Atom *> atoms) {
+ deselect ();
+ Selection *sel = new Selection ();
+ for (unsigned int i = 0; i < atoms.size (); i++) {
+ sel ->select_atom (atoms[i]);
+ }
+ add_molecule (sel);
+}
+
+void DDWin::select (Atom *at) {
+ deselect ();
+ Selection *sel = new Selection ();
+ sel -> select_atom (at);
+ add_molecule (sel);
+}
+
+void DDWin::load_file (string mol_name) {
+ ifstream ifs(mol_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(mol_name.c_str ());
+ ZNMolecule *mol = new ZNMolecule ();
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ ZNMolecule *mol2 = new ZNMolecule ();
+ if (conv.Read(mol2)) {
+ add_database (load_multi_file (mol_name));
+ }
+ else {
+ finalise_molecule (mol);
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol, this);
+ execute (command);
+ gl -> set_center_of_rotation (get_center (mol));
+ gl -> set_center_of_view (get_center (mol));
+
+
+
+ }
+ }
+ else {
+cerr << "could not read file "<<mol_name<<endl;
+ delete mol;
+ }
+}
+
+
+Database *DDWin::load_multi_file (string mol_name) {
+ Database *database = new Database ();
+ ifstream ifs(mol_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(mol_name.c_str ());
+ conv.SetInFormat(inFormat) ;
+ bool go_on = true;
+ int nn = 0;
+ while (go_on) {
+ Database_molecule *mol = new Database_molecule ();
+ go_on = conv.Read (mol);
+ if (mol -> NumAtoms ()) {
+ nn++;
+ database -> add_mol (mol);
+
+ stringstream ss;
+ ss <<nn;
+ string name = string ("ZNMolecule ")+ss.str ();
+ mol -> SetTitle (name);
+ finalise_molecule (mol);
+ set_lists (mol);
+ if (mol ->NumAtoms () < 100) {
+ set_bonds_display_style (mol, 2);
+ }
+ if (!mol ->NumBonds ()) {
+ set_atoms_display_style (mol, 1);
+ }
+
+
+ }
+ else delete mol;
+ }
+ database -> import_csv (mol_name+".csv");
+ return database;
+
+}
+
+
+void DDWin::deselect () {
+ ZNMolecule *selected_mol = 0;
+ if (target_molecule->selection) {
+
+ Selection *target_sel = (Selection *) target_molecule;
+ set_current_target (0);
+
+ if ( target_sel ->get_molecules ().size () ){
+
+ selected_mol = target_sel ->get_molecules ()[0];
+ }
+ }
+
+ for (unsigned int i=0; i < molecules.size (); i++) {
+ int s = molecules.size ();
+ assert ((s-1-(int) i) < molecules.size ());
+ assert ((s-1-(int) i) >= 0);
+ if (molecules[s-1-i] -> selection) {
+ Selection *sel = (Selection *) molecules[s-1-i];
+ sel -> deselect ();
+ target->removeItem (s-1-i);
+ molecules.erase (molecules.begin ()+s-1-i);
+ // delete sel; cannot use this because OBMol distructor would delete all atoms in sel
+
+
+ }
+ }
+ if (selected_mol) {
+ set_current_target (selected_mol);
+ }
+ for (unsigned int i=0; i < molecules.size (); i++) {
+ gl ->draw_molecule (molecules[i]);
+ }
+}
+
+
+
+
+Sphere* DDWin::new_sphere (string name) {
+ for (unsigned int i=0; i<graphical_objects.size (); i++) {
+ if (graphical_objects[i]->name==name) return (Sphere *) graphical_objects[i];
+ }
+ Sphere *sphere= new Sphere;
+ sphere ->set_name (name);
+ graphical_objects.push_back (sphere);
+ return sphere;
+
+
+}
+
+
+
+void DDWin::add_molecule (ZNMolecule *mol) {
+ if (string (mol ->GetTitle ()) == "") {
+ stringstream ssname;
+ if (mol ->multi) ssname << "Database " << builder ->mcounter++;
+ else ssname << "New Molecule " << builder ->mcounter++;
+ string s = ssname.str ();
+ mol -> SetTitle (s);
+ }
+ set_lists (mol);
+ if (mol ->NumAtoms () < 100) {
+ set_bonds_display_style (mol, 2);
+ }
+ if (!mol ->NumBonds ()) {
+ set_atoms_display_style (mol, 1);
+ }
+ molecules.push_back (mol);
+ target->insertItem (1000, QString( mol->GetTitle ()));
+ if (!mol ->selection) non_selection_molecules_updated ();
+ else targets_updated ();
+}
+
+
+void DDWin::add_database (Database *database) {
+ DatabaseGrid *grid = new DatabaseGrid (0, database, data);
+ database_grids.push_back (grid);
+ ZNMolecule *target = database ->dummy_mol;
+ if (database ->get_molecule (0)) {
+ target = database ->get_molecule (0);
+ }
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (target, this);
+ execute (command);
+// gl -> set_center_of_rotation (get_center (target));
+// gl -> set_center_of_view (get_center (target));
+ grid ->set_mol();
+
+
+// grid -> show ();
+// grid -> raise ();
+
+}
+
+void DDWin::new_molecule (string name) {
+ ZNMolecule *mol = new ZNMolecule ();
+ mol-> SetTitle (name);
+ add_molecule (mol);
+
+}
+
+
+
+void DDWin::resizeEvent (QResizeEvent *){
+// target->move (width()-400,0);
+
+}
+
+void DDWin::create_menu_actions () {
+
+ openAct = new QAction (tr("&Open File"), this);
+ openAct->setShortcut (tr ("Ctrl+O"));
+ connect (openAct, SIGNAL (triggered ()), this, SLOT (open_file_slot ()));
+
+ openSessionAct = new QAction (tr("&Open Session File"), this);
+ openSessionAct->setShortcut (tr ("Ctrl+E"));
+ connect (openSessionAct, SIGNAL (triggered ()), this, SLOT (open_session_file_slot ()));
+
+ saveasAct = new QAction (tr("Save as..."), this);
+ saveasAct->setShortcut (tr ("Ctrl+S"));
+ connect (saveasAct, SIGNAL (triggered ()), this, SLOT (save_as_slot ()));
+
+ saveSessionAsAct = new QAction (tr("Save Session as..."), this);
+ saveSessionAsAct->setShortcut (tr ("Ctrl+A"));
+ connect (saveSessionAsAct, SIGNAL (triggered ()), this, SLOT (save_session_as_slot ()));
+
+ screenshotAct = new QAction (tr("&Screenshot"), this);
+ screenshotAct->setShortcut (tr ("Ctrl+N"));
+ connect (screenshotAct, SIGNAL (triggered ()), this, SLOT (screenshot_slot ()));
+
+ raytracedscreenshotAct = new QAction (tr("&Raytraced Screenshot POVRAY"), this);
+ raytracedscreenshotAct->setShortcut (tr ("Ctrl+R"));
+ connect (raytracedscreenshotAct, SIGNAL (triggered ()), this, SLOT (raytraced_screenshot_slot ()));
+
+ movieAct = new QAction (tr("Start / save &Movie"), this);
+ movieAct->setShortcut (tr ("Ctrl+M"));
+ connect (movieAct, SIGNAL (triggered ()), this, SLOT (movie_slot ()));
+
+ raytracedmovieAct = new QAction (tr("Start / save Raytraced Movie"), this);
+ // screenshotAct->setShortcut (tr ("Ctrl+O"));
+ connect (raytracedmovieAct, SIGNAL (triggered ()), this, SLOT (raytraced_movie_slot ()));
+
+ quitAct = new QAction (tr("&Quit"), this);
+ quitAct ->setShortcut (tr ("Ctrl+Q"));
+ connect (quitAct, SIGNAL (triggered ()), this, SLOT (close ()));
+
+ newdatabaseAct = new QAction (tr ("Create new Database"), this);
+ connect (newdatabaseAct, SIGNAL (triggered ()), this, SLOT (new_database_slot ()));
+
+ builderAct = new QAction (tr("&Builder"), this);
+ builderAct->setShortcut (tr ("Ctrl+B"));
+ connect (builderAct, SIGNAL (triggered ()), this, SLOT (builder_slot ()));
+
+ twodwinAct = new QAction (tr("&2D Editor - molsKetch"), this);
+ twodwinAct->setShortcut (tr ("Ctrl+K"));
+ connect (twodwinAct, SIGNAL (triggered ()), this, SLOT (twodwin_slot ()));
+
+ historyAct = new QAction (tr("History"), this);
+ historyAct->setShortcut (tr ("Ctrl+H"));
+ connect (historyAct, SIGNAL (triggered ()), this, SLOT (history_slot ()));
+
+ settingsAct = new QAction (tr("&Preferences"), this);
+ settingsAct ->setShortcut (tr ("Ctrl+P"));
+ connect (settingsAct, SIGNAL (triggered ()), this, SLOT (pref_slot ()));
+
+ wiimoteAct = new QAction (tr("Connect Wiimote for head tracking"), this);
+ connect (wiimoteAct, SIGNAL (triggered ()), this, SLOT (wiimote_slot ()));
+
+ wiimote2Act = new QAction (tr("Connect Wiimote for 3D input"), this);
+ connect (wiimote2Act, SIGNAL (triggered ()), this, SLOT (wiimote2_slot ()));
+
+
+
+ hideHAct = new QAction (tr("Hide Hydrogens"), this);
+ connect (hideHAct, SIGNAL (triggered ()), this, SLOT (hide_hydrogens_slot ()));
+
+ hidenpHAct = new QAction (tr("Hide non polar Hydrogens"), this);
+ connect (hideHAct, SIGNAL (triggered ()), this, SLOT (hide_nonpolar_hydrogens_slot ()));
+
+ hideallAct = new QAction (tr("Hide All Atoms"), this);
+ connect (hideallAct, SIGNAL (triggered ()), this, SLOT (hide_all_atoms_slot ()));
+
+ showallAct = new QAction (tr("Show All Atoms"), this);
+ connect (showallAct, SIGNAL (triggered ()), this, SLOT (show_all_atoms_slot ()));
+
+ displaysettingsAct = new QAction (tr("&Display Settings"), this);
+ displaysettingsAct->setShortcut (tr ("Ctrl+D"));
+ connect (displaysettingsAct, SIGNAL (triggered ()), this, SLOT (display_settings_slot ()));
+
+ sequenceAct = new QAction (tr("&Sequence"), this);
+ connect (sequenceAct, SIGNAL (triggered ()), this, SLOT (sequence_slot ()));
+
+ DDsettingsAct = new QAction (tr("3D Settings"), this);
+ connect (DDsettingsAct, SIGNAL (triggered ()), this, SLOT (DD_settings_slot ()));
+
+
+ enableclippingAct = new QAction (tr("enable clipping"), this);
+ connect (enableclippingAct, SIGNAL (triggered ()), this, SLOT (enable_clipping_slot ()));
+
+ disableclippingAct = new QAction (tr("disable clipping"), this);
+ connect (disableclippingAct, SIGNAL (triggered ()), this, SLOT (disable_clipping_slot ()));
+
+ DDsettingsAct = new QAction (tr("3D Settings"), this);
+ connect (DDsettingsAct, SIGNAL (triggered ()), this, SLOT (DD_settings_slot ()));
+
+ colorAct = new QAction (tr("Color"), this);
+ connect (colorAct, SIGNAL (triggered ()), this, SLOT (color_slot ()));
+
+ backboneColorAct = new QAction (tr("Backbone Color"), this);
+ connect (backboneColorAct, SIGNAL (triggered ()), this, SLOT (backbone_color_slot ()));
+
+
+
+ backgroundcolorAct = new QAction (tr("Background Color"), this);
+ connect (backgroundcolorAct, SIGNAL (triggered ()), this, SLOT (background_color_slot ()));
+
+
+ hapticAct = new QAction (tr("Haptic mode"), this);
+ hapticAct -> setIcon (QPixmap (":icons/haptic.png"));
+ connect (hapticAct, SIGNAL (triggered ()), this, SLOT (haptic_slot ()));
+
+ dockingAct = new QAction (tr("Docking"), this);
+ connect (dockingAct, SIGNAL (triggered ()), this, SLOT (docking_slot ()));
+
+ plantsAct = new QAction (tr("Plants"), this);
+ connect (plantsAct, SIGNAL (triggered ()), this, SLOT (plants_slot ()));
+
+ gamessAct = new QAction (tr("Create Gamess input"), this);
+ connect (gamessAct, SIGNAL (triggered ()), this, SLOT (gamess_slot ()));
+
+ energyAct = new QAction (tr("Compute Energies"), this);
+ connect (energyAct, SIGNAL (triggered ()), this, SLOT (compute_energy_slot ()));
+
+ logPAct = new QAction (tr("Predict LogP"), this);
+ connect (logPAct, SIGNAL (triggered ()), this, SLOT (logP_slot ()));
+
+
+ minimiseAct = new QAction (tr("Energy Minimise"), this);
+ minimiseAct -> setIcon (QPixmap (":icons/minimise.png"));
+ connect (minimiseAct, SIGNAL (triggered ()), this, SLOT (minimise_energy_slot ()));
+
+ partialQAct = new QAction (tr("Gasteiger Partial Charges"), this);
+ connect (partialQAct, SIGNAL (triggered ()), this, SLOT (partial_charges_slot ()));
+
+ scoresCharge = new QAction (tr("Scores from Charges"), this);
+ connect (scoresCharge, SIGNAL (triggered ()), this, SLOT (scores_from_charges_slot ()));
+
+ conformationalSearchAct = new QAction (tr("Conformational Search"), this);
+ connect (conformationalSearchAct, SIGNAL (triggered ()), this, SLOT (conformers_slot ()));
+
+
+ addHsAct = new QAction (tr("Add Hydrogens"), this);
+ connect (addHsAct, SIGNAL (triggered ()), this, SLOT (add_Hs_slot ()));
+
+ duplicateAct = new QAction (tr("Duplicate mol"), this);
+ connect (duplicateAct, SIGNAL (triggered ()), this, SLOT (duplicate_slot ()));
+
+ surfaceAct = new QAction (tr("Molecular Surface"), this);
+ connect (surfaceAct, SIGNAL (triggered ()), this, SLOT (surface_slot ()));
+
+ mapAct = new QAction (tr("Map"), this);
+ connect (mapAct, SIGNAL (triggered ()), this, SLOT (map_slot ()));
+
+ sphereAct = new QAction (tr("Sphere"), this);
+ connect (sphereAct, SIGNAL (triggered ()), this, SLOT (sphere_slot ()));
+
+ backbonetosurfAct = new QAction (tr("Backbone to surface"), this);
+ connect (backbonetosurfAct, SIGNAL (triggered ()), this, SLOT (backbone_to_surface_slot ()));
+
+ graphicalobjectsAct = new QAction (tr("Graphical Objects"), this);
+ connect (graphicalobjectsAct, SIGNAL (triggered ()), this, SLOT (graphical_objects_slot ()));
+
+
+ iodeviceAct = new QAction (tr("I/O device list"), this);
+ connect (iodeviceAct, SIGNAL (triggered ()), this, SLOT (iodevice_slot ()));
+
+ aboutAct = new QAction (tr("About"), this);
+ connect (aboutAct, SIGNAL (triggered ()), this, SLOT (about_slot ()));
+
+
+
+ selectAllAct = new QAction (tr("Select All Atoms"), this);
+ selectAllAct -> setIcon (QPixmap (":icons/select_all.png"));
+ connect (selectAllAct, SIGNAL (triggered ()), this, SLOT (select_all_slot ()));
+
+ deselectAct = new QAction (tr("Deselect"), this);
+ deselectAct -> setIcon (QPixmap (":icons/deselect.png"));
+ connect (deselectAct, SIGNAL (triggered ()), this, SLOT (deselect_slot ()));
+
+
+ invertSelectAct = new QAction (tr("Invert Selection"), this);
+ invertSelectAct -> setIcon (QPixmap (":icons/invert_selection.png"));
+ connect (invertSelectAct, SIGNAL (triggered ()), this, SLOT (invert_selection_slot ()));
+
+
+ selectCAct = new QAction (tr("Select Carbons"), this);
+ selectCAct -> setIcon (QPixmap (":icons/select_C.png"));
+ connect (selectCAct, SIGNAL (triggered ()), this, SLOT (select_C_slot ()));
+
+ selectHAct = new QAction (tr("Select Hydrogens"), this);
+ selectHAct -> setIcon (QPixmap (":icons/select_H.png"));
+ connect (selectHAct, SIGNAL (triggered ()), this, SLOT (select_H_slot ()));
+
+
+ selectsquareAct = new QAction (tr("Select Square"), this);
+ selectsquareAct -> setIcon (QPixmap (":icons/select_square.png"));
+ connect (selectsquareAct, SIGNAL (triggered ()), this, SLOT (select_square_slot ()));
+
+
+
+ buildCAct = new QAction (tr("Carbon"), this);
+ buildCAct -> setIcon (QPixmap (":icons/builder_C.png"));
+ connect (buildCAct, SIGNAL (triggered ()), this, SLOT (build_C_slot ()));
+
+ buildOAct = new QAction (tr("Oxygen"), this);
+ buildOAct -> setIcon (QPixmap (":icons/builder_O.png"));
+ connect (buildOAct, SIGNAL (triggered ()), this, SLOT (build_O_slot ()));
+
+ buildNAct = new QAction (tr("Nitrogen"), this);
+ buildNAct -> setIcon (QPixmap (":icons/builder_N.png"));
+ connect (buildNAct, SIGNAL (triggered ()), this, SLOT (build_N_slot ()));
+
+ buildSAct = new QAction (tr("Sulphur"), this);
+ buildSAct -> setIcon (QPixmap (":icons/builder_S.png"));
+ connect (buildSAct, SIGNAL (triggered ()), this, SLOT (build_S_slot ()));
+
+
+ buildsinglebondAct = new QAction (tr("Single bond"), this);
+ buildsinglebondAct -> setIcon (QPixmap (":icons/builder_1bond.png"));
+ connect (buildsinglebondAct, SIGNAL (triggered ()), this, SLOT (build_single_bond_slot ()));
+
+
+
+ builddoublebondAct = new QAction (tr("Double bond"), this);
+ builddoublebondAct -> setIcon (QPixmap (":icons/builder_2bond.png"));
+ connect (builddoublebondAct, SIGNAL (triggered ()), this, SLOT (build_double_bond_slot ()));
+
+ buildtriplebondAct = new QAction (tr("Triple bond"), this);
+ buildtriplebondAct -> setIcon (QPixmap (":icons/builder_3bond.png"));
+ connect (buildtriplebondAct, SIGNAL (triggered ()), this, SLOT (build_triple_bond_slot ()));
+
+ deletebondAct = new QAction (tr("Delete bond"), this);
+ deletebondAct -> setIcon (QPixmap (":icons/builder_Xbond.png"));
+ connect (deletebondAct, SIGNAL (triggered ()), this, SLOT (delete_bond_slot ()));
+
+
+ deleteatomAct = new QAction (tr("Delete atom"), this);
+ deleteatomAct -> setIcon (QPixmap (":icons/builder_del.png"));
+// connect (deleteatomAct, SIGNAL (triggered ()), this, SLOT ( ));
+
+ magicpencilButt = new QPushButton (QIcon (":icons/builder_pencil.png"), "");
+
+ magicpencilButt ->setIconSize (QSize (32, 32));
+ magicpencilButt ->resize (32, 32);
+ magicpencilButt ->setCheckable (true);
+// magicpencilAct = new QAction (tr("Magic pencil"), this);
+// magicpencilAct -> setIcon (QPixmap (":icons/builder_pencil.png"));
+ connect (magicpencilButt, SIGNAL (toggled (bool)), this, SLOT (magic_pencil_toggle_slot (bool) ));
+
+ buildsmileAct = new QAction (tr("SMILE"), this);
+ buildsmileAct -> setIcon (QPixmap (":icons/builder_smile.png"));
+// connect (buildsmileAct, SIGNAL (triggered ()), this, SLOT ( ));
+
+
+ periodictableAct = new QAction (tr("Periodic Table"), this);
+ periodictableAct -> setIcon (QPixmap (":icons/periodic_table.png"));
+ connect (periodictableAct, SIGNAL (triggered ()), this, SLOT (periodic_table_slot () ));
+
+
+
+ undoAct = data -> undo_stack -> createUndoAction ( this );
+ undoAct -> setIcon (QPixmap (":icons/undo.png"));
+ undoAct->setShortcut (tr ("Ctrl+Z"));
+
+
+ redoAct = data -> undo_stack -> createRedoAction ( this );
+ redoAct -> setIcon (QPixmap (":icons/redo.png"));
+ redoAct->setShortcut (tr ("Shift+Ctrl+Z"));
+
+
+
+ colorsAct = new QAction (tr("Color molecule"), this);;
+ QPixmap pix(24, 24);
+ pix.fill(molecule_color);
+ colorsAct->setIcon(pix);
+ connect (colorsAct, SIGNAL (triggered ()), this, SLOT (quick_color_slot ()));
+
+ colors_chooserAct = new QAction (tr("change color"), this);;
+ colors_chooserAct -> setIcon (QPixmap (":icons/arrow.png"));
+ connect (colors_chooserAct, SIGNAL (triggered ()), this, SLOT (change_color_slot ()));
+
+ centerAct = new QAction (tr("View"), this);;
+ connect (centerAct, SIGNAL (triggered ()), this, SLOT (center_slot ()));
+
+
+}
+
+
+void DDWin::periodic_table_slot () {
+
+cerr << "periodic table" <<endl;
+
+
+}
+
+
+
+void DDWin::draw_menu (){
+
+
+ create_menu_actions ();
+
+ QMenu *file = new QMenu(tr("&File"), this );
+ Q_CHECK_PTR( file );
+ file -> addAction (openAct);
+ file -> addAction (openSessionAct);
+ file -> addAction (saveasAct);
+ file -> addAction (saveSessionAsAct);
+ file -> addAction (screenshotAct);
+ file -> addAction (raytracedscreenshotAct);
+ // file -> addAction (movieAct);
+ // file -> addAction (raytracedmovieAct);
+ file -> addAction (quitAct);
+
+
+ QMenu *edit = new QMenu(tr("&Edit"), this );
+ Q_CHECK_PTR( edit );
+ edit -> addAction (builderAct);
+ edit -> addAction (twodwinAct);
+ edit -> addAction (newdatabaseAct);
+ edit -> addAction (historyAct);
+
+ // edit -> addAction (wiimoteAct);
+ // edit -> addAction (wiimote2Act);
+// edit -> addAction (iodeviceAct);
+ edit -> addAction (settingsAct);
+
+ QMenu *show = new QMenu(tr("&Show"), this );
+ Q_CHECK_PTR( show );
+ show -> addAction (hideHAct);
+ show -> addAction (hidenpHAct);
+ show -> addAction (hideallAct);
+ show -> addAction (showallAct);
+
+
+ QMenu *display = new QMenu(tr("&Display"), this );
+ Q_CHECK_PTR( display );
+ display -> addAction (displaysettingsAct);
+ display -> addAction (sequenceAct);
+ display -> addAction (DDsettingsAct);
+ display -> addAction (enableclippingAct);
+ display -> addAction (disableclippingAct);
+ display -> addAction (colorAct);
+ display -> addAction (backboneColorAct);
+ display -> addAction (backgroundcolorAct);
+
+
+
+ QMenu *compute = new QMenu(tr("&Compute"), this );
+ Q_CHECK_PTR( compute );
+ compute -> addAction (hapticAct);
+ compute -> addAction (dockingAct);
+ compute -> addAction (plantsAct);
+ compute -> addAction (gamessAct);
+ compute -> addAction (energyAct);
+ compute -> addAction (logPAct);
+ compute -> addAction (minimiseAct);
+ compute -> addAction (partialQAct);
+ compute -> addAction (scoresCharge);
+ compute -> addAction (conformationalSearchAct);
+
+ QMenu *utilities = new QMenu(tr("&Utilities"), this );
+ Q_CHECK_PTR( utilities );
+ utilities -> addAction ( addHsAct );
+ utilities -> addAction (duplicateAct);
+
+
+ QMenu *graph_objects = new QMenu(tr("&Graphical Objects"), this );
+ Q_CHECK_PTR( graph_objects );
+ graph_objects -> addAction (surfaceAct);
+ graph_objects -> addAction (mapAct);
+ graph_objects -> addAction (sphereAct);
+ graph_objects -> addAction (backbonetosurfAct);
+ graph_objects -> addAction (graphicalobjectsAct);
+
+
+ QMenu *about = new QMenu(tr("&About"), this );
+ Q_CHECK_PTR( about );
+ about -> addAction (aboutAct);
+
+
+ QMenuBar *menu = menuBar ();
+ menu->addMenu ( file );
+ menu->addMenu ( edit );
+ menu->addMenu ( show );
+ menu->addMenu ( display );
+ menu->addMenu ( compute );
+ menu->addMenu ( graph_objects );
+ menu->addMenu ( utilities );
+ menu->addMenu ( about );
+
+ target = new QComboBox( menu );
+ target->setMinimumWidth (400);
+ target->insertItem(0, "All" );
+ targets_updated ();
+
+ current_mode = new QLabel ("");
+
+ toolbar = new QToolBar ("Main");
+ target_toolbar = new QToolBar ("Control");
+ select_tb = new QToolBar ("Select");
+ builder_tb = new QToolBar ("Builder");
+ connect (target_toolbar, SIGNAL (orientationChanged (Qt::Orientation)), this, SLOT (resize_target_toolbar (Qt::Orientation)));
+ addToolBar (toolbar);
+ addToolBar (target_toolbar);
+ addToolBar (Qt::RightToolBarArea, select_tb);
+ addToolBar (Qt::RightToolBarArea, builder_tb);
+
+ //MyColorButton *colors = new MyColorButton (toolbar ->layout (), molecule_color);
+
+ hide_toolbars ();
+ toolbar -> addAction (undoAct);
+ toolbar -> addAction (redoAct);
+ toolbar -> addAction (minimiseAct);
+ toolbar -> addAction (hapticAct);
+
+ toolbar ->addSeparator ();
+
+ toolbar -> addAction (colorsAct);
+ toolbar -> addAction (centerAct);
+// toolbar -> addAction (colors_chooserAct);
+
+
+ target_toolbar -> addWidget (target);
+ target_toolbar -> addWidget (current_mode);
+
+ select_tb -> addAction (selectAllAct);
+ select_tb -> addAction (deselectAct);
+ select_tb -> addAction (invertSelectAct);
+ select_tb -> addAction (selectCAct);
+ select_tb -> addAction (selectHAct);
+ select_tb -> addAction (selectsquareAct);
+
+
+
+ builder_tb -> addAction (buildCAct);
+ builder_tb -> addAction (buildOAct);
+ builder_tb -> addAction (buildNAct);
+ builder_tb -> addAction (buildSAct);
+ builder_tb -> addAction (buildsinglebondAct);
+ builder_tb -> addAction (builddoublebondAct);
+ builder_tb -> addAction (buildtriplebondAct);
+ builder_tb -> addAction (deletebondAct);
+ builder_tb -> addAction (deleteatomAct);
+ //builder_tb -> addAction (magicpencilAct);
+ builder_tb -> addWidget (magicpencilButt);
+ builder_tb -> addAction (buildsmileAct);
+// builder_tb -> addAction (periodictableAct);
+
+ connect (target, SIGNAL (activated (int)), this, SLOT (set_current_target_slot (int)));
+
+}
+
+void DDWin::quick_color_slot () {
+ change_color_slot ();
+ if (current_target) {
+ ColorAtomCommand *color_atom = new ColorAtomCommand (gl);
+ FOR_ATOMS_OF_MOL (at, target_molecule) {
+ if (target_molecule ->selection || at ->GetAtomicNum ()==6) {
+ color_atom -> add (&*at, molecule_color);
+ }
+ }
+ color_atom->set_name ();
+ execute (color_atom);
+ }
+
+
+}
+
+
+void DDWin::center_slot () {
+ if (current_target) {
+ gl -> set_center_of_rotation (get_center (target_molecule));
+ gl -> set_center_of_view (get_center (target_molecule));
+ }
+}
+
+void DDWin::change_color_slot () {
+ QColor new_color = QColorDialog::getColor(molecule_color, this );
+ if ( new_color.isValid () ) {
+ molecule_color.setRed (new_color.red ());
+ molecule_color.setGreen (new_color.green ());
+ molecule_color.setBlue (new_color.blue ());
+ molecule_color.setAlpha (new_color.alpha ());
+
+ }
+ QPixmap pix(24, 24);
+ pix.fill(molecule_color);
+ colorsAct->setIcon(pix);
+}
+
+
+
+void DDWin::resize_target_toolbar (Qt::Orientation orient) {
+ if (orient == Qt::Horizontal) {
+ target -> setMinimumWidth (400);
+ }
+ else {
+ target -> setMinimumWidth (40);
+ target -> setMaximumWidth (40);
+ }
+}
+
+void DDWin::hide_toolbars () {
+// toolbar -> hide ();
+ select_tb -> hide ();
+ builder_tb -> hide ();
+}
+
+
+void DDWin::delete_current_molecule () {
+ delete_molecule (molecules [current_target]);
+ sequence_menu ->del_from_tab (molecules [current_target]);
+}
+
+void DDWin::delete_molecule (ZNMolecule *mol) {
+ for (unsigned int i=0; i<molecules.size (); i++) {
+ if (molecules[i] == mol) {
+ target->removeItem (i);
+ molecules.erase (molecules.begin ()+i);
+ set_current_target (0);
+ if (!mol ->selection) non_selection_molecules_updated ();
+ else targets_updated ();
+ delete mol;
+ break;
+ }
+ }
+}
+
+
+void DDWin::remove_molecule (ZNMolecule *mol) {
+ for (unsigned int i=0; i<molecules.size (); i++) {
+ if (molecules[i] == mol) {
+ target->removeItem (i);
+ molecules.erase (molecules.begin ()+i);
+ set_current_target (0);
+
+ break;
+ }
+ }
+
+}
+
+
+
+/*
+
+void DDWin::redraw (ZNMolecule *mol) {
+ if (mol -> needs_redraw) {
+ gl -> draw_molecule (mol);
+ mol -> needs_redraw = false;
+ }
+}
+
+
+ */
+void DDWin::recolor_by_score (ZNMolecule *mol) {
+ if (mol -> needs_recolor) {
+ vector <color_mask> masks;
+ color_mask mask;
+ mask.intensity = 1.0f;
+ mask.only_to = 0;
+ mask.excluding = 0;
+ mask.type = 2; //score //see menu.cc
+ masks.push_back (mask);
+ gl -> apply_color_masks (masks, mol, false);
+ mol -> needs_recolor = false;
+ }
+}
+
+
+void DDWin::end_minimisation () {
+
+ MoveAtomsCommand *command = new MoveAtomsCommand (gl, 0);
+ // FOR_ATOMS_OF_MOL (a, data -> minimize -> minimising_molecule) {
+ // command -> add (&*a, (vect &) a -> GetVector ());
+ // }
+
+ // execute (command);
+ data -> undo_stack -> endMacro ();
+ data -> minimize -> deinitialise_minimisation ();
+}
+
+void DDWin::delete_graphical_object (int i) {
+ assert (i>-1 && i<graphical_objects.size ());
+ go_updated ();
+ DeleteGraphicalObjectCommand *command = new DeleteGraphicalObjectCommand (graphical_objects[i], this);
+ execute (command);
+}
+
+
+
+
+
+
+void DDWin::screenshot_slot () {
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save Screenshot"), "",tr("Portable pixel map (*.ppm)"));
+
+ if (!s.isNull()) gl->screenshot (s);
+
+}
+
+void DDWin::movie_slot () {
+ if (!rec_movie) {
+ rec_movie = TRUE;
+ gl->movie_time = QTime::currentTime ();
+ }
+ else {
+ rec_movie = FALSE;
+
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save Movie"), "",tr("MPEG (*.mpg)"));
+
+ if (!s.isNull()) {
+ ofstream *file = new ofstream("__conf__");
+ *file<< "BASE_FILE_FORMAT PPM"<<endl;
+ *file<< "INPUT"<<endl;
+ *file<< "__movie__*.ppm [0-"<<last_frame-1<<"]"<<endl;
+ *file<< "END_INPUT"<<endl;
+ *file<< "INPUT_DIR ."<<endl;
+ *file<< "IQSCALE 1"<<endl;
+ *file<< "PQSCALE 1"<<endl;
+ *file<< "BQSCALE 1"<<endl;
+ *file<< "RANGE 1"<<endl;
+ *file<< "PSEARCH_ALG SUBSAMPLE"<<endl;
+ *file<< "GOP_SIZE 1"<<endl;
+ *file<< "PATTERN I"<<endl;
+ *file<< "PIXEL FULL"<<endl;
+ *file<< "INPUT_CONVERT *"<<endl;
+ *file<< "SLICES_PER_FRAME 1"<<endl;
+ *file<< "BSEARCH_ALG SIMPLE"<<endl;
+ *file<< "REFERENCE_FRAME DECODED"<<endl;
+ *file<< "FRAME_RATE 25"<<endl;
+ *file<< "OUTPUT " << s.toStdString() <<endl;
+ system ("ppmtompeg __conf__*");
+ }
+
+ last_frame = 0;
+ system ("rm __*");
+ }
+}
+
+
+
+void DDWin::raytraced_movie_slot () {
+ if (!rec_pov_movie) {
+ rec_pov_movie = TRUE;
+ gl->movie_time = QTime::currentTime ();
+ }
+ else {
+ rec_pov_movie = FALSE;
+
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save Movie"), "",tr("MPEG (*.mpg)"));
+
+ if (!s.isNull()) {
+ ofstream *file = new ofstream("__conf__");
+ *file<< "BASE_FILE_FORMAT PPM"<<endl;
+ *file<< "INPUT"<<endl;
+ *file<< "__movie__*.ppm [0-"<<last_frame-1<<"]"<<endl;
+ *file<< "END_INPUT"<<endl;
+ *file<< "INPUT_DIR ."<<endl;
+ *file<< "IQSCALE 1"<<endl;
+ *file<< "PQSCALE 1"<<endl;
+ *file<< "BQSCALE 1"<<endl;
+ *file<< "RANGE 1"<<endl;
+ *file<< "PSEARCH_ALG SUBSAMPLE"<<endl;
+ *file<< "GOP_SIZE 1"<<endl;
+ *file<< "PATTERN I"<<endl;
+ *file<< "PIXEL FULL"<<endl;
+ *file<< "INPUT_CONVERT *"<<endl;
+ *file<< "SLICES_PER_FRAME 1"<<endl;
+ *file<< "BSEARCH_ALG SIMPLE"<<endl;
+ *file<< "REFERENCE_FRAME DECODED"<<endl;
+ *file<< "FRAME_RATE 25"<<endl;
+ *file<< "OUTPUT " << s.toStdString() <<endl;
+ for (unsigned int i=0; i<last_frame; i++) {
+ stringstream ss;
+ ss<<i;
+ string command = "povray __movie__"+ss.str()+".pov +FP -UV -H480 -W640";
+ system (command.c_str());
+ }
+ system ("ppmtompeg __conf__ ");
+ }
+
+ last_frame = 0;
+ system ("rm __*");
+ }
+}
+
+
+void DDWin::show_atom_properties (Atom* at){
+ clicked_atom_menu->set (at);
+
+ clicked_atom_menu->show ();
+ clicked_atom_menu->raise ();
+}
+
+
+void DDWin::execute (Command * comm) {
+ data -> undo_stack -> push (comm);
+}
+
+void DDWin::run_thread (Thread *thread) {
+ running_threads.push_back (thread);
+ thread ->start ();
+}
+
+/*
+int DDWin::style_str_to_i (string style){
+
+
+ if (style=="No Atoms") return NO_ATOMS;
+ else if (style=="Spheres") return SPHERES;
+ else if (style=="CPK Spheres") return CPK_SPHERES;
+ else if (style=="Scaled CPK Spheres") return SCALED_CPK_SPHERES;
+
+ else if (style=="No Bonds") return NO_BONDS;
+ else if (style=="Lines") return LINES;
+ else if (style=="Sticks") return STICKS;
+
+ else if (style=="Aromatic rings") return AROMATIC_RINGS;
+ else if (style=="Kekule resonance structures") return KEKULE;
+// else if (style=="Aromatic bonds") return AROMATIC_BONDS;
+ return 0;
+
+
+}
+*/
+
+
+void DDWin::save_as_slot () {
+ /*
+ QFileDialog save_file(this);
+
+ QStringList filters;
+ filters << "Tripos mol2 (*.mol2)"
+ << "InChI (*.inchi)"
+ << "MDL Molfile (*.mol)"
+ << "Protein Data Bank (*.pdb)"
+ << "sdf (*.sdf)"
+ << "smile (*.smi)";
+
+
+ save_file.setNameFilters (filters);
+ save_file.setAcceptMode (QFileDialog::AcceptSave);
+ save_file.exec();
+
+ QString ext = save_file.selectedNameFilter();
+
+ QString filter = save_file.selectedNameFilter();
+ filter.truncate (filter.lastIndexOf (')'));
+ filter.remove (0, filter.indexOf ('*')+1);
+ QString s = save_file.selectedFile();
+ if (!s.contains ('.') ) s+= filter;
+ */
+
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save file"), last_visited_dir, tr("All Files (*)"));
+
+
+
+ if (!s.isNull()) {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) data -> actions -> save_as (target_molecule, s.toStdString ());
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm ->database;
+ data ->actions ->save_as (dat, s.toStdString ());
+ }
+ }
+
+
+ }
+
+}
+
+
+void DDWin::save_session_as_slot () {
+/*
+ QFileDialog save_file(this);
+
+ QStringList filters;
+ filters << "Zodiac session (*.zod)";
+
+ save_file.setNameFilters (filters);
+ save_file.setAcceptMode (QFileDialog::AcceptSave);
+ save_file.exec();
+
+ QString ext = save_file.selectedNameFilter();
+
+ QString filter = save_file.selectedNameFilter();
+ filter.truncate (filter.lastIndexOf (')'));
+ filter.remove (0, filter.indexOf ('*')+1);
+ QString s = save_file.selectedFile();
+ if (!s.contains ('.') ) s+= filter;
+ */
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save file"), last_visited_dir, tr("Zodiac Session files (*.zod)"));
+
+ if (!s.isNull()) {
+
+ data ->actions ->save_session_as (s.toStdString ());
+ }
+
+
+}
+
+
+void DDWin::set_current_target_slot (int index) {
+ current_target = index;
+ target_molecule = molecules [index];
+ if (target_molecule->multi) {
+ Database_molecule *dm;
+ dm = (Database_molecule *) target_molecule;
+ show_grid (dm ->database);
+ }
+
+
+}
+
+void DDWin::set_current_target (int index) {
+ if (index<0) index+=molecules.size ();
+ target->setCurrentIndex (index);
+ set_current_target_slot (index);
+
+}
+
+void DDWin::set_current_target (ZNMolecule *mol) {
+ int index = -1;
+ for (unsigned int i=0; i<molecules.size (); i++) {
+
+ if (molecules[i] == mol) {index = i; break;}
+ }
+
+ if (index>0) {
+ set_current_target (index);
+ }
+
+}
+
+void DDWin::scores_from_charges_slot () {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) data ->actions ->set_scores_from_charges (target_molecule);
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm ->database;
+ data ->actions ->set_scores_from_charges (dat);
+ }
+
+ }
+ else {
+ for (unsigned int i=0; i<molecules.size (); i++) {
+ data ->actions ->set_scores_from_charges (molecules[i]);
+ }
+ }
+
+}
+
+
+void DDWin::new_database_slot () {
+ Database *dat = new Database ();
+ add_database (dat);
+}
+
+
+
+
+void DDWin::partial_charges_slot () {
+ if (current_target) {
+ OBGastChrg gastchrg;
+ gastchrg.AssignPartialCharges (*target_molecule);
+ gl->draw_molecule (target_molecule);
+ }
+
+ else {
+ for (unsigned int i=0; i<molecules.size (); i++) {
+ data->mmff->compute_partial_charges (molecules[i]);
+ gl->draw_molecule (molecules[i]);
+ }
+ }
+}
+
+void DDWin::atdebug_slot () {
+ /* ofstream *file = new ofstream("/home/nicola/Desktop/debug");
+ show_labels = false;
+ for (unsigned int i=1; i<346+1; i++) {
+
+ stringstream ss;
+ ss<<i;
+ load_file ("/home/nicola/MMFF94/hypervalent/hyp"+ss.str()+".mol2");
+ }
+ for (unsigned int m=1; m<molecules.size (); m++) {
+ int sum=0;
+ for (unsigned int a=0; a<molecules[m]->atoms.size (); a++) {
+ sum += molecules[m]->atoms[a]->MMFFtype;
+ }
+ *file<<sum<<endl;
+ }
+ file->close ();
+ system ("/home/nicola/Desktop/compare.py /home/nicola/Desktop/debug /home/nicola/Desktop/true_atypes");
+
+*/
+}
+
+void DDWin::color_slot () {
+ color_menu->show ();
+ color_menu->raise ();
+}
+
+void DDWin::backbone_color_slot () {
+ b_color_menu->display ();
+}
+
+void DDWin::background_color_slot () {
+ color_settings_menu->show ();
+ color_settings_menu->raise ();
+}
+
+
+void DDWin::surface_slot () {
+ surface_menu -> show ();
+ surface_menu -> raise ();
+}
+
+void DDWin::map_slot () {
+ map_menu ->display ();
+}
+
+void DDWin::sphere_slot () {
+ sphere_menu -> show ();
+ sphere_menu -> raise ();
+}
+
+void DDWin::backbone_to_surface_slot () {
+ if (current_target) {
+ Surface *surf = new Surface;
+ gl ->backbone_to_surface (target_molecule, surf);
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (surf, this);
+ execute (command);
+ }
+}
+
+void DDWin::graphical_objects_slot () {
+ graphical_objects_menu -> show ();
+ graphical_objects_menu -> raise ();
+}
+
+
+void DDWin::haptic_slot () {
+ if (current_target) {
+ haptic_menu->show ();
+ haptic_menu->raise ();
+ }
+}
+
+void DDWin::compute_energy_slot () {
+/* ZNMolecule *molecule = target_molecule;
+ Chemscore *chemscore = new Chemscore;
+ MMFF* mmff = new MMFF;
+ build_kinematic_chain(molecule);
+ Minimize *min = new Minimize (data, mmff, chemscore);
+ min ->set_molecule (molecule);
+ // min ->internal_ff ->initialize_internal (molecule, ddwin ->molecules);
+ min ->interaction_ff ->initialize_interaction (molecule, molecules, get_center (molecule), 12);
+
+
+*/
+
+ bool ext = false;
+ if (current_target) {
+ if (target_molecule -> multi) {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ if (dm -> database -> has_extend_enabled ()) ext = true;
+ }
+ if (!ext) {
+ data->mmff->initialize (target_molecule, molecules);
+ float bs, ab, to, sb, vw, op, el;
+ stringstream out;
+ ab = data->mmff->compute_angle_bendings ();
+ to = data->mmff->compute_torsion_interactions ();
+ sb = data->mmff->compute_stretch_bend_interactions ();
+ vw = data->mmff->compute_van_der_waals_interactions ();
+ op = data->mmff->compute_out_of_plane_bendings ();
+ el = data->mmff->compute_electrostatic_interactions ();
+ bs = data->mmff->compute_bond_stretchings ();
+
+ out << "BS = "<<bs<<endl;
+ out << "AB = "<<ab<<endl;
+ out << "TO = "<<to<<endl;
+ out << "SB = "<<sb<<endl;
+ out << "OP = "<<op<<endl;
+ out << "EL = "<<el<<endl;
+ out << "VW = "<<vw<<endl;
+ out << "total = "<<data -> actions -> compute_total_energy (target_molecule);
+ QMessageBox::information( this, QString("Zodiac"), QString(out.str().c_str()));
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ dat -> add_field ("Energy", data -> actions -> compute_total_energy (dat));
+ }
+ }
+}
+
+void DDWin::logP_slot () {
+ bool ext = false;
+ if (current_target) {
+ if (target_molecule -> multi) {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ if (dm -> database -> has_extend_enabled ()) ext = true;
+ }
+ if (!ext) {
+ stringstream out;
+ out << "Predicted logP: ";
+ out << data -> actions -> compute_logP (target_molecule);
+ QMessageBox::information( this, QString("Zodiac"), QString(out.str().c_str()));
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ dat -> add_field ("cLogP", data -> actions -> compute_logP (dat));
+ }
+ }
+
+}
+
+
+void DDWin::minimise_energy_slot () {
+ if (current_target ) {
+ if (!target_molecule -> selection) {
+ if (!is_db_extended (target_molecule)) {
+ data -> actions -> minimise (target_molecule);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data -> actions -> minimise (dat);
+ }
+ }
+ }
+}
+
+
+void DDWin::iodevice_slot () {
+ iodevice_menu -> display ();
+
+
+}
+
+
+void DDWin::plants_slot () {
+ //Plants *plants= new Plants ( 0, "plants conf", data );
+ plants_menu -> display ();
+}
+
+void DDWin::conformers_slot () {
+ conformers_menu -> display ();
+}
+
+void DDWin::docking_slot () {
+ docking_menu -> display ();
+}
+
+void DDWin::gamess_slot () {
+ gamess_menu -> display ();
+}
+
+void DDWin::hide_hydrogens_slot () {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) {
+ data -> actions -> hide_hydrogens (target_molecule);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data -> actions -> hide_hydrogens (dat);
+ }
+ }
+
+ else gl -> hide_hydrogens (molecules);
+}
+
+
+
+void DDWin::hide_nonpolar_hydrogens_slot () {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) {
+ data -> actions -> hide_nonpolar_hydrogens (target_molecule);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data -> actions -> hide_nonpolar_hydrogens (dat);
+ }
+ }
+
+ else gl -> hide_hydrogens (molecules);
+}
+
+
+void DDWin::hide_all_atoms_slot () {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) {
+ data ->actions -> hide_all_atoms (target_molecule);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data ->actions -> hide_all_atoms (dat);
+ }
+ }
+
+ else gl -> hide_all_atoms (molecules);
+}
+
+void DDWin::show_all_atoms_slot () {
+ if (current_target) {
+ if (!is_db_extended (target_molecule)) {
+ data ->actions -> show_all_atoms (target_molecule);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data ->actions -> show_all_atoms (dat);
+ }
+ }
+
+ else gl -> show_all_atoms (molecules);
+}
+
+
+void DDWin::add_Hs_slot () {
+ if (current_target) {
+ bool ok;
+ double ph = QInputDialog::getDouble(this, tr("Protonate Molecule"),
+ tr("pH:"), 7.4, 0, 14, 1, &ok);
+ if (ok)
+ {
+ if (!is_db_extended (target_molecule)) {
+ data ->actions ->reprotonate (target_molecule, ph);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) target_molecule;
+ Database *dat = dm -> database;
+ data ->actions ->reprotonate (dat, ph);
+
+ }
+ }
+ }
+}
+
+
+void DDWin::duplicate_slot () {
+ if (current_target) {
+ ZNMolecule *new_mol = new ZNMolecule (*target_molecule);
+ add_molecule (new_mol);
+ }
+}
+
+/*
+void DDWin::color_by_atom_slot () {
+ if (current_target) gl->color_by_atom (target_molecule);
+ else gl->color_by_atom (molecules);
+}
+
+
+
+void DDWin::color_by_charge_slot (){
+ if (current_target) gl->color_by_charge (target_molecule);
+ else gl->color_by_charge (molecules);
+}
+
+void DDWin::color_by_score_slot (){
+ if (current_target) gl->color_by_score (target_molecule);
+ else {
+ for (unsigned int i =0; i<molecules.size (); i++) gl->color_by_score (molecules[i]);
+ }
+}
+
+
+void DDWin::color_carbons_slot (){
+ QColor c = QColorDialog::getColor(Qt::white, this );
+ if ( c.isValid() ) {
+ float col[3];
+ col[0] = (float)(c.red())/255;
+ col[1] = (float)(c.green())/255;
+ col[2] = (float)(c.blue())/255;
+ if (current_target) gl->color_atoms (target_molecule, 6, col);
+ else gl->color_atoms (molecules, 6, col);
+ }
+}
+*/
+/////////////////////////////////////////////DRAG AND DROP////////////////////////////////////////////
+
+void DDWin::dragEnterEvent( QDragEnterEvent * event) {
+ // cout << "drag enter event"<<endl ;
+
+ // if (event->mimeData()->hasText())
+ event->acceptProposedAction();
+
+}
+
+void DDWin::dragMoveEvent(QDragMoveEvent *event)
+{
+ // cout << "drag move event"<<endl ;
+ event->acceptProposedAction();
+}
+
+void DDWin::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ // cout << "drag leave event"<<endl ;
+ event->accept();
+}
+
+
+void DDWin::dropEvent(QDropEvent *event)
+{
+// cout << "drop event" << endl;
+ if (event->mimeData()->hasUrls()) {
+ QList<QUrl> urlList = event->mimeData ()->urls();
+ for (int i = 0; i < urlList.size()/* && i < 32*/; ++i) {
+ QString url = urlList.at(i).toLocalFile ();
+ last_visited_dir = QDir (url).path ();
+ load_file (url.toStdString ());
+ }
+ }
+
+
+ event->acceptProposedAction();
+}
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void DDWin::not_impl_slot ()
+{
+ QMessageBox::about( this, "About Zodiac" ,
+ QString(("ZODIAC. Version " + VERSION + "\n"
+ "Not Implemented yet.. please be patient.. ").c_str()) );
+}
+
+
+void DDWin::builder_slot () {
+ builder_menu->show ();
+ builder_menu->raise ();
+}
+
+void DDWin::twodwin_slot () {
+ data ->twodwin ->show ();
+ data ->twodwin ->raise ();
+}
+
+void DDWin::history_slot () {
+ undo_view -> show ();
+ undo_view -> raise ();
+}
+
+
+void DDWin::wiimote_slot () {
+ HeadTrackingThread *thread = new HeadTrackingThread (0, this);
+ run_thread (thread);
+// thread -> start ();
+}
+
+void DDWin::wiimote2_slot () {
+ WiimoteTrackingThread *thread = new WiimoteTrackingThread (0, this);
+ run_thread (thread);
+// thread -> start ();
+}
+
+
+void DDWin::pref_slot () {
+ pref_menu ->display ();
+}
+
+
+void DDWin::DD_settings_slot () {
+ DDsettings_menu->show ();
+ DDsettings_menu->raise ();
+}
+
+void DDWin::enable_clipping_slot () {
+ if (current_target) {
+ set_clippable (target_molecule, true);
+ }
+}
+
+void DDWin::disable_clipping_slot () {
+ if (current_target) {
+ set_clippable (target_molecule, false);
+ }
+}
+
+
+
+void DDWin::display_settings_slot () {
+ display_menu -> display ();
+}
+
+void DDWin::sequence_slot () {
+ sequence_menu -> display ();
+}
+
+void DDWin::about_slot ()
+{
+ QMessageBox::about( this, "About Zodiac" ,
+ QString(("ZODIAC. I feel good! Version "+VERSION+ "\n"
+ "Code by Nicola Zonta. All rights reserved.\n"
+ "For bug reports, suggestions or any other feedback please visit our website at www.zeden.org or email me at zontan at cf.ac.uk\n\n").c_str()) );
+}
+
+
+
+
+void DDWin::setup_accel () {
+ accel->connectItem( accel->insertItem(Qt::Key_Escape), this, SLOT(esc_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_Delete), this, SLOT(del_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_Backspace), this, SLOT(del_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_A), this, SLOT(a_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_B), this, SLOT(b_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_C), this, SLOT(c_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_D), this, SLOT(d_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_E), this, SLOT(e_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_F), this, SLOT(f_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_H), this, SLOT(h_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_I), this, SLOT(i_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_M), this, SLOT(m_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_N), this, SLOT(n_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_O), this, SLOT(o_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_R), this, SLOT(r_pressed()) );
+ accel->connectItem( accel->insertItem(Qt::Key_S), this, SLOT(s_pressed()) );
+
+}
+
+void DDWin::deselect_slot () {
+ deselect();
+}
+void DDWin::select_all_slot () {
+ if (current_target) {
+ ZNMolecule *target = 0;
+ if (!target_molecule -> selection) target = target_molecule;
+ else target = ((Selection *) target_molecule) ->get_molecules ()[0];
+ deselect ();
+ Selection *sel = new Selection;
+ FOR_ATOMS_OF_MOL (a, target){
+ sel ->select_atom (&*a);
+ }
+ find_center (sel);
+ find_limits (sel);
+ add_molecule (sel);
+ set_current_target (-1);
+ }
+
+}
+
+void DDWin::invert_selection_slot () {
+ if (current_target) {
+ ZNMolecule *target = 0;
+ if (!target_molecule -> selection) target = target_molecule;
+ else target = ((Selection *) target_molecule) ->get_molecules ()[0];
+
+
+ vector <Atom *> atoms;
+ FOR_ATOMS_OF_MOL (a, target){
+ if (!get_selected (&*a)) atoms.push_back (&*a);
+ }
+
+ deselect ();
+ Selection *sel = new Selection;
+ sel ->select_atoms (atoms);
+ find_center (sel);
+ find_limits (sel);
+ add_molecule (sel);
+ set_current_target (-1);
+ }
+}
+
+void DDWin::select_C_slot () {
+ gl -> select_MW (6);
+}
+
+
+void DDWin::select_H_slot () {
+ gl -> select_MW (1);
+}
+
+
+void DDWin::select_square_slot () {
+ gl ->select_square_mode = true;
+ gl ->setCursor(QCursor (QPixmap (":icons/pointer_select_square.png"), 0, 0));
+}
+
+
+
+void DDWin::build_C_slot () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (6);
+ }
+ else builder->add_atom (6);
+}
+
+void DDWin::build_S_slot () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (16);
+ }
+ else builder->add_atom (16);
+}
+
+void DDWin::build_O_slot () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (8);
+ }
+ else builder->add_atom (8);
+}
+
+void DDWin::build_N_slot () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (7);
+ }
+ else builder->add_atom (7);
+}
+
+
+void DDWin::build_single_bond_slot () {
+ builder->add_bond (1);
+}
+
+void DDWin::build_double_bond_slot () {
+ builder->add_bond (2);
+}
+
+void DDWin::build_triple_bond_slot () {
+ builder->add_bond (3);
+}
+
+void DDWin::delete_bond_slot () {
+ // builder->remove_bond ();
+}
+
+//key slots
+
+void DDWin::magic_pencil_toggle_slot (bool checked) {
+ if (checked) {
+ magic_pencil_start ();
+ }
+ else {
+ magic_pencil_end ();
+ }
+}
+void DDWin::magic_pencil_start () {
+ magicpencilButt -> setChecked (true);
+ switch_mode (MAGIC_PENCIL);
+ builder->set_magic_pencil_atomic_number (6);
+}
+void DDWin::magic_pencil_end () {
+ magicpencilButt -> setChecked (false);
+ gl ->unsetCursor();
+ gl -> magic_pencil = false;
+ builder->last_magic_pencil_atom = NULL;
+ switch_mode (BUILDER);
+}
+
+void DDWin::del_pressed () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (-2);
+
+ }
+ if (mode == NONE) {
+ if (current_target) delete_current_molecule ();
+ }
+}
+
+void DDWin::esc_pressed () {
+ if (mode == MAGIC_PENCIL) {
+ magic_pencil_end ();
+ }
+ else {
+ switch_mode (NONE);
+ gl ->unsetCursor();
+ }
+}
+
+
+
+void DDWin::a_pressed () {
+ if (mode == SELECT) {
+ selectAllAct ->trigger ();
+ }
+}
+
+
+void DDWin::b_pressed () {
+ if (mode == NONE) switch_mode (BUILDER);
+
+}
+
+void DDWin::c_pressed () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (6);
+
+ }
+ if (mode == SELECT) {
+ selectCAct ->trigger ();
+ }
+}
+
+void DDWin::d_pressed () {
+ if (mode == SELECT) {
+ deselectAct ->trigger ();
+ }
+}
+
+void DDWin::e_pressed () {
+ if (mode == SELECT) {
+ switch_mode (SELECT_EXTEND);
+ }
+}
+
+void DDWin::f_pressed () {
+ if (mode == SELECT_EXTEND) {
+ if (target_molecule ->selection) {
+ Selection *sel = (Selection *) target_molecule;
+ sel ->extend_to_fragment ();
+ }
+
+ }
+
+}
+
+
+void DDWin::h_pressed () {
+ if (mode == SELECT) {
+ selectHAct ->trigger ();
+ }
+}
+
+void DDWin::m_pressed () {
+ if (mode == BUILDER) {
+ magic_pencil_start ();
+
+ }
+}
+
+
+void DDWin::n_pressed () {
+ if (mode == SELECT_EXTEND) {
+ if (target_molecule ->selection) {
+ Selection *sel = (Selection *) target_molecule;
+ sel ->extend_to_neighbours ();
+ }
+
+ }
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (7);
+ }
+}
+
+void DDWin::i_pressed () {
+ if (mode == SELECT) {
+ invertSelectAct ->trigger ();
+ }
+}
+
+void DDWin::o_pressed () {
+ if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (8);
+ }
+}
+
+
+void DDWin::r_pressed () {
+ if (mode == SELECT_EXTEND) {
+ if (target_molecule ->selection) {
+ Selection *sel = (Selection *) target_molecule;
+ sel ->extend_to_residue ();
+ }
+
+ }
+
+}
+
+
+void DDWin::s_pressed () {
+ if (mode == NONE) switch_mode (SELECT);
+ else if (mode == MAGIC_PENCIL) {
+ builder->set_magic_pencil_atomic_number (16);
+ }
+ else if (mode == SELECT) {
+ selectsquareAct ->trigger ();
+ }
+
+}
+
+void DDWin::switch_mode (int m) {
+ hide_toolbars ();
+ if (m == SELECT) {
+ mode = SELECT;
+ select_tb -> show ();
+ mode_string = "Select";
+ }
+ else if (m == SELECT_EXTEND) {
+ mode = SELECT_EXTEND;
+ mode_string = "Select - Extend";
+ }
+ else if (m == BUILDER) {
+ mode = BUILDER;
+ builder_tb -> show ();
+ mode_string = "Builder";
+ }
+ else if (m == MAGIC_PENCIL) {
+ mode = MAGIC_PENCIL;
+ builder_tb -> show ();
+ mode_string = "Builder";
+ }
+ else {
+ mode = NONE;
+ mode_string = "";
+ }
+
+ current_mode ->setText (QString(mode_string.c_str ()));
+
+}
+
+
+void DDWin::lock_editing () {
+ if (edit_lock_counter < 0) edit_lock_counter = 0;
+ edit_lock_counter ++;
+ builderAct -> setEnabled (false);
+ minimiseAct -> setEnabled (false);
+ builder_menu -> hide ();
+ if (mode == MAGIC_PENCIL || mode == BUILDER) esc_pressed ();
+}
+
+
+void DDWin::unlock_editing () {
+ edit_lock_counter --;
+ if (edit_lock_counter < 1) {
+ builderAct -> setEnabled (true);
+ minimiseAct -> setEnabled (true);
+ }
+}
+
+
+
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+MyGl::MyGl (DDWin *parent)
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+{
+
+
+ setMouseTracking (true);
+ ddwin = parent;
+ setAcceptDrops(true) ;
+ init_vars ();
+ void GL ();
+
+
+}
+
+void MyGl::init_vars (){
+
+ needs_GL_update = false;
+ next_list = 0;
+
+
+// bindingsite_list = new_list ();
+// waters_list = new_list ();
+
+ select_color = SELECT_COLOR ;
+
+
+
+ aromatic_display_style = AROMATIC_DISPLAY_STYLE;
+
+
+ aromatic_bond_inter_distance =AROMATIC_BOND_INTER_DISTANCE;
+
+
+ double_bond_stick_radius_scale = DOUBLE_BOND_STICK_RADIUS_SCALE;
+
+
+ surface_resolution = SURFACE_RESOLUTION;
+
+ fog_begin = FOG_BEGIN;
+
+ stereo_toe_in_angle = 1.14576f;
+ stereo_inter_eye_semi_distance = 0.2f;
+
+
+ head_tracking_x_position = 0.f;
+ head_tracking_y_position = 0.f;
+
+ center_of_rotation = vect ();
+ center_of_view = vect ();
+ view_translations = vect ();
+
+ zbeginy = 0.0f;
+ tbeginx = 0.0f;
+ tbeginy = 0.0f;
+
+
+ up_point = vect (0., 1., 0.);
+ down_point = vect (0., -1., 0.);
+ left_point = vect (-1., 0., 0.);
+ right_point = vect (1., 0., 0.);
+
+ zoom = false; translate = false; rotate = false; select = false; move = false; spin = false; selection_square = false; magic_pencil = false; select_square_mode = false;
+ clicked_atom = new Atom;
+
+
+
+
+ Transform.M[0] = 1.0f; Transform.M[1] = 0.0f; Transform.M[2] = 0.0f; Transform.M[3] = 0.0f;
+ Transform.M[4] = 0.0f; Transform.M[5] = 1.0f; Transform.M[6] = 0.0f; Transform.M[7] = 0.0f;
+ Transform.M[8] = 0.0f; Transform.M[9] = 0.0f; Transform.M[10] = 1.0f; Transform.M[11] = 0.0f;
+ Transform.M[12] = 0.0f; Transform.M[13] = 0.0f; Transform.M[14] = 0.0f; Transform.M[15] = 1.0f;
+
+ Head_Tracking_Transf.M[0] = 1.0f; Head_Tracking_Transf.M[1] = 0.0f; Head_Tracking_Transf.M[2] = 0.0f; Head_Tracking_Transf.M[3] = 0.0f;
+ Head_Tracking_Transf.M[4] = 0.0f; Head_Tracking_Transf.M[5] = 1.0f; Head_Tracking_Transf.M[6] = 0.0f; Head_Tracking_Transf.M[7] = 0.0f;
+ Head_Tracking_Transf.M[8] = 0.0f; Head_Tracking_Transf.M[9] = 0.0f; Head_Tracking_Transf.M[10] = 1.0f; Head_Tracking_Transf.M[11] = 0.0f;
+ Head_Tracking_Transf.M[12] = 0.0f; Head_Tracking_Transf.M[13] = 0.0f; Head_Tracking_Transf.M[14] = 0.0f; Head_Tracking_Transf.M[15] = 1.0f;
+
+ LastRot.M[0] = 1.0f; LastRot.M[1] = 0.0f; LastRot.M[2] = 0.0f;
+ LastRot.M[3] = 0.0f; LastRot.M[4] = 1.0f; LastRot.M[5] = 0.0f;
+ LastRot.M[6] = 0.0f; LastRot.M[7] = 0.0f; LastRot.M[8] = 1.0f;
+
+ // Last_Head_Tracking_Rot.M[0] = 1.0f; Last_Head_Tracking_Rot.M[1] = 0.0f; Last_Head_Tracking_Rot.M[2] = 0.0f;
+ // Last_Head_Tracking_Rot.M[3] = 0.0f; Last_Head_Tracking_Rot.M[4] = 1.0f; Last_Head_Tracking_Rot.M[5] = 0.0f;
+ // Last_Head_Tracking_Rot.M[6] = 0.0f; Last_Head_Tracking_Rot.M[7] = 0.0f; Last_Head_Tracking_Rot.M[8] = 1.0f;
+
+
+
+
+ ThisRot.M[0] = 1.0f; ThisRot.M[1] = 0.0f; ThisRot.M[2] = 0.0f;
+ ThisRot.M[3] = 0.0f; ThisRot.M[4] = 1.0f; ThisRot.M[5] = 0.0f;
+ ThisRot.M[6] = 0.0f; ThisRot.M[7] = 0.0f; ThisRot.M[8] = 1.0f;
+
+ select_pulse = 0;
+
+
+ startTimer (30);
+
+
+
+}
+
+
+void MyGl::timerEvent ( QTimerEvent * event ) {
+ select_pulse ++; //int that controls the pulsating color for selections.
+ set_clipping_plane (); //rotates the general clipping plane to be parallel to the viewer
+ for (unsigned int i = 0; i < ddwin ->molecules.size (); i++) {
+ if (get_needs_redraw(ddwin ->molecules[i])) {
+ GL_update_molecule(ddwin ->molecules[i]);
+ }
+ if (get_needs_backbone_redraw (ddwin ->molecules[i])) {
+ GL_update_backbone(ddwin ->molecules[i]);
+ }
+ }
+ for (unsigned int i = 0; i < ddwin ->database_grids.size (); i++) {
+ if (ddwin ->database_grids[i] ->database ->get_needs_redraw ()) {
+ ddwin ->database_grids[i] ->update_graphics ();
+ }
+ }
+ if (!ddwin ->running_threads.size ()) {
+ ddwin ->thread_menu ->hide ();
+ }
+ else {
+ ddwin ->thread_menu -> show ();
+ for (unsigned int i = 0; i < ddwin ->running_threads.size (); i++) {
+ if (ddwin ->running_threads[i] -> isFinished ()) {
+ Thread *th = ddwin ->running_threads[i];
+ ddwin ->running_threads.erase (ddwin ->running_threads.begin ()+i);
+ ddwin ->thread_menu -> clear (i);
+ i --;
+ delete th;
+ }
+ else {
+ ddwin ->thread_menu -> display_thread (i, ddwin ->running_threads[i]);
+ }
+ }
+ }
+ ddwin ->haptic_menu ->update_energy (); //triggers an update of the energy value if haptic simulation is running
+ ddwin ->haptic_menu ->maybe_save_result ();
+ updateGL (); //redraw the graphic scene
+}
+
+void MyGl::set_clipping_plane () {
+ GLdouble x1, x2, x3, y1, y2, y3, z1, z2, z3;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+ double centerz = 0.995;
+
+ gluUnProject (viewport[2]/2, viewport[3], centerz, model, proj, viewport, &x1, &y1, &z1);
+ gluUnProject (viewport[2], viewport[3]/2, centerz, model, proj, viewport, &x2, &y2, &z2);
+ gluUnProject (viewport[2]/2, viewport[3]/2, centerz, model, proj, viewport, &x3, &y3, &z3);
+
+ GLdouble a, b, c, d;
+ a = y1*(z2-z3) + y2*(z3-z1) + y3*(z1-z2);
+ b = z1*(x2-x3) + z2*(x3-x1) + z3*(x1-x2);
+ c = x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2);
+ d = -(x1* (y2*z3 - y3*z2) + x2*(y3*z1 - y1*z3) + x3*(y1*z2 - y2*z1));
+ double eq [4] = {a, b, c, d};
+ glClipPlane (GL_CLIP_PLANE0, eq);
+}
+
+void MyGl::free_list (int list) {
+ if (next_list == list +1) next_list--;
+ else empty_lists.push_back (list);
+}
+
+
+
+int MyGl::new_list () {
+ int out;
+ if (empty_lists.size() ) {
+ out = empty_lists [empty_lists.size()-1];
+ empty_lists.pop_back ();
+
+ }
+ else {
+ out = next_list;
+ next_list++;
+ }
+ return out;
+}
+
+
+
+
+
+void MyGl::translate_molecule (ZNMolecule *mol, vect v) {
+ FOR_ATOMS_OF_MOL(a, mol) {
+ sum_to_coordinates(&*a, v);
+ }
+ vect c = get_center (mol);
+ set_center (mol, sum (c, v));
+}
+
+
+
+
+void MyGl::move_molecule (ZNMolecule *mol, float x, float y, float z, bool cut_bool) {
+ vect v (x, y, z);
+ if (cut_bool) {
+ float mod = v.module ();
+ float cut = 0.5;
+ if (mod>cut) {
+ v.scale_to (cut);
+ }
+ }
+ FOR_ATOMS_OF_MOL(a, mol) {
+ sum_to_coordinates(&*a, v);
+ }
+ vect c = get_center (mol);
+ set_center (mol, sum (c, v));
+}
+
+
+
+
+
+
+void MyGl::initializeGL ()
+{
+ GLboolean stereo;
+ glGetBooleanv(GL_STEREO, &stereo);
+
+ // IJG: Needs to be populated from a tick box in the GUI!!!
+ ddwin -> g_stereoMode = DDWin::StereoMode_None;
+
+ // Should we automatically select stereo mode if we discovery stereo
+ // is in use?
+#if 0
+ if (stereo)
+ {
+ ddwin->g_stereoMode = DDWin::StereoMode_ViaOpenGL;
+ }
+#endif
+
+
+ // glEnable( GL_CULL_FACE );
+ glEnable (GL_NORMALIZE);
+
+ glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
+ color background_color = *ddwin ->data ->background_color;
+ glClearColor (background_color.redF (), background_color.greenF (), background_color.blueF (), background_color.alphaF ());
+ GLfloat fogColor[4]= {background_color.redF (), background_color.greenF (), background_color.blueF (), background_color.alphaF ()};
+ glFogfv(GL_FOG_COLOR, fogColor);
+
+ glClearDepth (1.0f); // Depth Buffer Setup
+ glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less || Equal)
+
+ // g_openGlStereoAvailable = GL_TRUE;
+ if (ddwin->g_stereoMode == DDWin::StereoMode_ViaOpenGL) {glEnable (GL_STEREO);}
+
+ glEnable (GL_DEPTH_TEST); // Enable Depth Testing
+ // Select Flat Shading (Nice Definition Of Objects)
+// glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
+
+ quadratic=gluNewQuadric(); // Create A Pointer To The Quadric Object
+ gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals
+ gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords
+
+ glEnable(GL_LIGHT0); // Enable Default Light
+ glEnable(GL_LIGHTING); // Enable Lighting
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,1.0);
+ // glEnable(GL_POINT_SMOOTH); //antialiasing
+ // glEnable(GL_LINE_SMOOTH);
+// glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+
+
+// glEnable(GL_POLYGON_SMOOTH);
+// glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+ glShadeModel(GL_SMOOTH);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,specular);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_COLOR_MATERIAL);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Enable Alpha Blending (disable alpha testing)
+ glEnable(GL_BLEND);
+
+
+
+ // glFogi(GL_FOG_MODE, GL_LINEAR);
+
+ glFogf(GL_FOG_DENSITY, 0.005f);
+ glHint(GL_FOG_HINT, GL_DONT_CARE);
+ glFogf(GL_FOG_START, fog_begin);
+ glFogf(GL_FOG_END, 10000.0f);
+ glEnable(GL_FOG);
+
+}
+/*
+void MyGl::haptic_timer () {
+ QTime t = QTime::currentTime ();
+ float diff = time.msecsTo (t);
+ if (diff <1) diff = 1;
+ float fps = 1000/diff;
+ stringstream ss;
+ ss<<fps<<" fps"<<endl;
+ ddwin->mode_string = ss.str ();
+ time = t;
+ ZNMolecule * min_mol = ddwin->data->minimize->interaction_ff->target_mol;
+ ddwin->data->minimize->haptic_step ();
+ draw_molecule (min_mol);
+}
+
+*/
+/*
+void MyGl::timerEvent ( QTimerEvent * ) {
+ // ddwin->mode_string = "";
+ float f = 0.001;
+ // if (ddwin->mode == SELECT) {
+ // ddwin->mode_string = "Select";
+ // }
+ // if (ddwin->mode == BUILDER) {
+ // ddwin->mode_string = "Builder";
+ // }
+
+
+ if (ddwin->haptic_mode) {
+ haptic_timer ();
+ }
+
+ if (ddwin->minimizing) {
+ ddwin->data->minimize->minimize_energy_step ();
+ }
+ if (ddwin->rec_movie) {
+ QTime t = QTime::currentTime ();
+ int msecs = movie_time.msecsTo (t);
+ if (msecs>1000/30) {
+ movie_time = t;
+ stringstream ss;
+ ss << ddwin->last_frame;
+ screenshot (QString("__movie__") + QString(ss.str().c_str()) + QString(".ppm"));
+ ddwin->last_frame++;
+ }
+ }
+ if (ddwin->rec_pov_movie) {
+ QTime t = QTime::currentTime ();
+ int msecs = movie_time.msecsTo (t);
+ if (msecs>1000/30) {
+ movie_time = t;
+ stringstream ss;
+ ss << ddwin->last_frame;
+ string filename ="__movie__"+ss.str()+".pov";
+ ddwin->write_POV_source (filename);
+ ddwin->last_frame++;
+ }
+ }
+}
+*/
+
+
+void MyGl::paintGL () {
+
+
+ color background_color = *ddwin ->data ->background_color;
+
+ GLfloat fogColor[4]= {background_color.redF (), background_color.greenF (), background_color.blueF (), background_color.alphaF ()};
+ glFogfv(GL_FOG_COLOR, fogColor);
+ glClearColor (background_color.redF (), background_color.greenF (), background_color.blueF (), background_color.alphaF ());
+ // cout <<"paintGL"<<endl;
+
+ glLineWidth (*ddwin ->data ->line_width);
+
+
+ GLdouble farx, fary, farz;
+ GLdouble nearx, neary, nearz;
+ GLdouble frontx, fronty, frontz;
+ GLdouble rightx, righty, rightz, upx, upy, upz, downx, downy, downz, leftx, lefty, leftz;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+
+
+ double centerz = 0.995;
+
+
+ gluUnProject (viewport[2]/2, viewport[3], centerz, model, proj, viewport, &upx, &upy, &upz);
+ gluUnProject (viewport[2], viewport[3]/2, centerz, model, proj, viewport, &rightx, &righty, &rightz);
+ gluUnProject (viewport[2]/2, 0, centerz, model, proj, viewport, &downx, &downy, &downz);
+ gluUnProject (0, viewport[3]/2, centerz, model, proj, viewport, &leftx, &lefty, &leftz);
+
+ gluUnProject (viewport[2]/2, viewport[3]/2, 1, model, proj, viewport, &farx, &fary, &farz);
+ gluUnProject (viewport[2]/2, viewport[3]/2, 0, model, proj, viewport, &nearx, &neary, &nearz);
+ float modfront = sqrt ((nearx-farx)*(nearx-farx)+(neary-fary)*(neary-fary)+(nearz-farz)*(nearz-farz));
+ frontx = (nearx-farx)/modfront;
+ fronty = (neary-fary)/modfront;
+ frontz = (nearz-farz)/modfront;
+
+
+ up_point = vect (upx, upy, upz);
+ down_point = vect (downx, downy, downz);
+ left_point = vect (leftx, lefty, leftz);
+ right_point = vect (rightx, righty, rightz);
+
+
+
+ int numFrameBuffers = 1;
+
+ if (ddwin->g_stereoMode != DDWin::StereoMode_None)
+ {
+ numFrameBuffers = 2;
+ }
+
+
+ for (int frameBuffer = 0; frameBuffer < numFrameBuffers; frameBuffer++)
+ {
+ if (ddwin->g_stereoMode == DDWin::StereoMode_ViaOpenGL)
+ {
+ if (frameBuffer == 0)
+ {
+ glDrawBuffer(GL_BACK_LEFT);
+ }
+ else
+ {
+ glDrawBuffer(GL_BACK_RIGHT);
+ }
+ }
+ else
+ {
+ glDrawBuffer(GL_BACK);
+ }
+
+ // IJG
+ if( ddwin->g_stereoMode == DDWin::StereoMode_VerticalInterlace ||
+ ddwin->g_stereoMode == DDWin::StereoMode_HorizontalInterlace )
+ {
+ ddwin->g_stencil_mask_frame_counter++;
+
+#if 0
+ // Occasionally force a redraw... we never know if (eg) someone else
+ // has nuked the stencil buffer...
+ if ((ddwin->g_stencil_mask_frame_counter % 20) == 0)
+ {
+ ddwin->g_stencil_mask_needs_redraw = true;
+ }
+#endif
+
+ if (ddwin->g_stencil_mask_needs_redraw)
+ {
+ ddwin->g_stencil_mask_needs_redraw = false;
+
+ glDrawPixels( ddwin->g_stencil_mask_width, ddwin->g_stencil_mask_height,
+ GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, ddwin->g_stencil_mask );
+ }
+
+ // render only every second line
+ glEnable(GL_STENCIL_TEST);
+
+ if (frameBuffer == 0)
+ {
+ // Only screen clear prior to first render - we need to merge both images,
+ // so they're rendered to the same buffer.
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glStencilFunc(GL_EQUAL, 1, 1);
+ }
+ else
+ {
+ glStencilFunc(GL_NOTEQUAL, 1, 1);
+ }
+
+ glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
+ }
+ else
+ {
+ glDisable(GL_STENCIL_TEST);
+
+ // Normal stereo mode or mono mode requires a screen clear before each render
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+
+ glDisable (GL_LIGHTING);
+ glColor4f (0.5,0.,0.5, 1.);
+ // renderText (20, 20, QString(ddwin->mode_string.c_str()));
+ glEnable (GL_LIGHTING);
+
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ // float centerx = translatefx/10;
+ // float centery = -translatefy/10;
+ // float centerz = -zoomf/10;
+ // glTranslatef (centerx, centery, centerz-15.0);
+
+
+ matrix_transformations (true, frameBuffer);
+
+ // IJG
+#if 0
+ if( mirror_in_y )
+ {
+ glScalef( 1, -1, 1 );
+ glFrontFace( GL_CW );
+ }
+ else
+ {
+ glFrontFace( GL_CCW );
+ }
+#endif // 0
+#ifdef GL_MULTISAMPLE
+ glEnable (GL_MULTISAMPLE);
+#endif //GL_MULTISAMPLE
+ for (unsigned int i =1; i<ddwin->molecules.size(); i++) {
+ if (!ddwin->molecules[i]->selection) { //selections are not drawn
+ if (get_clippable (ddwin->molecules[i])) glEnable (GL_CLIP_PLANE0);
+ GLdouble cx, cy, cz;
+ vect cent = get_center (ddwin ->molecules[i]);
+ gluProject (cent.x(), cent.y(), cent.z(),model, proj, viewport,&cx, &cy, &cz);
+
+ // glFogf(GL_FOG_START, cz);
+ // glFogf(GL_FOG_END, cz+0.000002);
+ // GLfloat f;
+ // glGetFloatv (GL_FOG_START, &f);
+ // cerr << f <<endl;
+ // cerr << cz*10000<<endl;
+ // glEnable(GL_FOG);
+ // float cx = ddwin -> molecules[i] -> center.x();
+ // float cy = ddwin -> molecules[i] -> center.y();
+ // float cz = ddwin -> molecules[i] -> center.z();
+ // float nz = cx*model[2] + cy*model[6] + cz*model[10] + model[14];
+ // cerr << nz << endl;
+ // glFogf(GL_FOG_START, -nz);
+ // glFogf(GL_FOG_END, -nz+20);
+ glDisable (GL_LIGHTING);
+ glCallList (get_line_list (ddwin->molecules[i]));
+ glLineWidth (3.f);
+ glCallList (get_backbone_list1 (ddwin->molecules[i]));
+ glLineWidth (*ddwin ->data ->line_width);
+ glEnable(GL_LIGHTING);
+ glCallList (get_stick_list (ddwin->molecules[i]));
+ glCallList (get_backbone_list2 (ddwin->molecules[i]));
+ if (ddwin->show_labels && 0) {
+ FOR_ATOMS_OF_MOL(at, ddwin -> molecules[i]) {
+ glColor4f (0.,0.,0.,1.);
+ stringstream ss, ss2;
+
+ }
+ }
+ }
+ glDisable (GL_CLIP_PLANE0);
+ }
+
+ for (unsigned int i =0; i<ddwin->graphical_objects.size(); i++) {
+ if (ddwin->graphical_objects[i]->is_clippable ()) glEnable (GL_CLIP_PLANE0);
+ if (ddwin->graphical_objects[i]->mesh) glDisable (GL_LIGHTING);
+ glCallList (ddwin->graphical_objects[i]->lst);
+ glEnable(GL_LIGHTING);
+ glDisable (GL_CLIP_PLANE0);
+ }
+ glDisable (GL_LIGHTING);
+ for (unsigned int i = 0; i<ddwin ->Hbonds.size (); i++) {
+ color c (1.f, 0.f, 0.f, ddwin ->Hbonds[i].perc);
+ my_line(ddwin ->Hbonds[i].v1, ddwin ->Hbonds[i].v2, c, c);
+ }
+// for (unsigned int i = 0; i<ddwin ->vertex_list.size (); i++) {
+// color c (1.f, 0.f, 0.f, 1.f);
+// my_line(ddwin ->vertex_list[i], sum (ddwin ->vertex_list[i], vect(0.1,0.,0.)), c, c);
+// }
+ glEnable(GL_LIGHTING);
+#ifdef GL_MULTISAMPLE
+ glDisable (GL_MULTISAMPLE);
+#endif //GL_MULTISAMPLE
+
+ // SELECTION SQUARE
+ if (selection_square) {
+ GLdouble x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4;
+ gluUnProject (selection_square_x1, viewport[3]-selection_square_y1, 0, model, proj, viewport, &x1, &y1, &z1);
+ gluUnProject (selection_square_x1, viewport[3]-selection_square_y2, 0, model, proj, viewport, &x2, &y2, &z2);
+ gluUnProject (selection_square_x2, viewport[3]-selection_square_y2, 0, model, proj, viewport, &x3, &y3, &z3);
+ gluUnProject (selection_square_x2, viewport[3]-selection_square_y1, 0, model, proj, viewport, &x4, &y4, &z4);
+ glDisable (GL_LIGHTING);
+ set_color (select_color);
+ glBegin (GL_LINE_STRIP);
+ glVertex3d (x1, y1, z1);
+ glVertex3d (x2, y2, z2);
+ glVertex3d (x3, y3, z3);
+ glVertex3d (x4, y4, z4);
+ glVertex3d (x1, y1, z1);
+
+ glEnd ();
+ glEnable(GL_LIGHTING);
+ }
+ // MAGIC PENCIL
+ if (magic_pencil) {
+ glDisable (GL_LIGHTING);
+ set_color (select_color);
+ glBegin (GL_LINE_STRIP);
+ for (unsigned int i=0; i<ddwin->magic_pencil_trail_x.size (); i++) {
+ glVertex3d (ddwin->magic_pencil_trail_x[i],ddwin->magic_pencil_trail_y[i],ddwin->magic_pencil_trail_z[i]);
+ }
+ glEnd ();
+ glEnable(GL_LIGHTING);
+ }
+ if (ddwin->builder->last_magic_pencil_atom) {
+ Atom *last = ddwin->builder->last_magic_pencil_atom;
+ glDisable (GL_LIGHTING);
+ GLdouble lx, ly, lz, lax, lay, laz, lxx, lyy, lzz;
+ vect v = get_coordinates(last);
+ gluProject (v.x(), v.y(), v.z(),model, proj, viewport,&lax, &lay, &laz);
+ gluUnProject (lax, lay, 0, model, proj, viewport, &lxx, &lyy, &lzz);
+ gluUnProject (lastx, viewport[3]-lasty, 0, model, proj, viewport, &lx, &ly, &lz);
+ set_color (select_color);
+ glBegin (GL_LINES);
+ // cout <<lxx <<lyy<<lzz<<endl;
+ // cout <<lx <<ly<<lz<<endl;
+ glVertex3d (lxx, lyy, lzz);
+ glVertex3d (lx, ly, lz);
+
+
+ glEnd ();
+ glEnable(GL_LIGHTING);
+ }
+ ddwin ->haptic_menu ->restrain_lock ->lockForRead ();
+ for (unsigned int i = 0; i < ddwin ->haptic_menu ->restrains.size (); i++) {
+ color c (0.f, 1.f, 0.f, 1.f);
+ glDisable (GL_LIGHTING);
+ my_line (get_coordinates (ddwin ->haptic_menu ->restrains[i] ->at1), get_coordinates (ddwin ->haptic_menu ->restrains[i] ->at2), c, c);
+ glEnable (GL_LIGHTING);
+ }
+ ddwin ->haptic_menu ->restrain_lock ->unlock ();
+ }
+ glFlush ();
+
+ needs_GL_update = false;
+}
+
+void MyGl::refreshStencilBuffer()
+{
+ // IJG
+ if ( (ddwin->g_stereoMode == DDWin::StereoMode_HorizontalInterlace)
+ || (ddwin->g_stereoMode == DDWin::StereoMode_VerticalInterlace) ) //this line read horizontal as well
+ {
+ // build up stencil buffer
+ int wp2 = width();
+ // width needs to be a power of 2 because of how glDrawPixels work.
+ // The extra values will be ignored.
+ wp2 += 4 - (width() % 4);
+ int h = height();
+
+ // Only release the memory if it needs to be reallocated...
+ if ( (ddwin->g_stencil_mask_width != wp2)
+ || (ddwin->g_stencil_mask_height != h) )
+ {
+ if ( ddwin -> g_stencil_mask )
+ {
+ free( ddwin -> g_stencil_mask );
+ }
+
+ ddwin -> g_stencil_mask = (unsigned char *) malloc( wp2*h );
+ ddwin -> g_stencil_mask_width = wp2;
+ ddwin -> g_stencil_mask_height = h;
+ }
+
+ // Always redraw the stencil contents just in case...
+ // we may be the same size window, but could be a different
+ // interlace from before.
+ if ( ddwin -> g_stereoMode == DDWin::StereoMode_HorizontalInterlace )
+ {
+ for( int i = 0; i < h; i++ )
+ for( int j = 0; j < wp2; j++ )
+ ddwin -> g_stencil_mask[i*wp2+j]=(i+1)%2;
+ }
+ else if ( ddwin -> g_stereoMode == DDWin::StereoMode_VerticalInterlace )
+ {
+ for( int i = 0; i < h; i++ )
+ for( int j = 0; j < wp2; j++ )
+ ddwin -> g_stencil_mask[i*wp2+j]=(j+1)%2;
+ }
+
+ ddwin->g_stencil_mask_needs_redraw = true;
+ }
+ else
+ {
+ // Don't need a stencil, so release the memory
+ if( ddwin -> g_stencil_mask )
+ {
+ free( ddwin -> g_stencil_mask );
+ ddwin -> g_stencil_mask = 0;
+ }
+ }
+}
+
+void MyGl::resizeGL( int width, int height )
+{
+ GLfloat w = (float) width / (float) height;
+
+ // cout<<"Viewport resized to "<<width<<" "<<height<<endl;
+
+ glViewport( 0, 0, width, height );
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(45.0f, w, 0.1f, 10000.0f);
+// glFrustum( -w, w, -h, h, 1.0, 10000.0 );
+ ArcBall.setBounds(width, height);
+
+ refreshStencilBuffer();
+}
+
+void MyGl::matrix_transformations (bool stereo, int frameBuffer) {
+
+
+ if ((ddwin->g_stereoMode != DDWin::StereoMode_None) && stereo)
+ {
+ if (frameBuffer == 0)
+ {
+ glRotatef (+stereo_toe_in_angle, 0.f, 1.f, 0.f);
+ glTranslatef(-stereo_inter_eye_semi_distance, 0.0f, 0.0f);
+ }
+ else
+ {
+ glRotatef (-stereo_toe_in_angle, 0.f, 1.f, 0.f);
+ glTranslatef(+stereo_inter_eye_semi_distance, 0.0f, 0.0f);
+ }
+ }
+
+
+
+ glMultMatrixf(Head_Tracking_Transf.M);
+ glTranslatef (head_tracking_x_position, -head_tracking_y_position, 0.f);
+
+
+ glTranslatef (0, 0, -15.f);
+ glTranslatef (view_translations.x(),view_translations.y(),view_translations.z());
+
+ // vect new_center_of_view = rotate_vector (subtract (center_of_view, center_of_rotation));
+ // glTranslatef (new_center_of_view[0],new_center_of_view[1],new_center_of_view[2]);
+
+
+ // Transform.M[12] = center_of_rotation.x();
+ // Transform.M[13] = center_of_rotation.y();
+ // Transform.M[14] = center_of_rotation.z();
+
+ glMultMatrixf(Transform.M);
+
+
+ glTranslatef (-center_of_rotation.x(),-center_of_rotation.y(),-center_of_rotation.z());
+
+ // glTranslatef(-center_of_rotation.x(),-center_of_rotation.y(),-center_of_rotation.z());
+
+
+}
+
+
+
+
+
+
+
+void MyGl::mousePressEvent ( QMouseEvent * e )
+{
+
+ float x = e->x(); float y = e->y();
+ Qt::MouseButton button = e->button ();
+
+ if (button == Qt::RightButton)
+ {
+ if (ddwin->mode == MAGIC_PENCIL) {
+ begin_magic_pencil (x, y);
+ }
+ else {
+ select = true;
+ begin_zoom (y);
+ }
+ }
+ else if (button == Qt::MidButton)
+ {
+ if (e->modifiers ()==Qt::ShiftModifier) {
+ begin_selection_square (x, y);
+ }
+ else begin_translate (x, y);
+ }
+ else if (button == Qt::LeftButton)
+ {
+
+
+ if (e->modifiers () == Qt::ShiftModifier) {
+ if (ddwin->current_target!=0)
+ begin_move (x, y);
+ }
+ else if (e->modifiers () == Qt::ControlModifier) {
+ if (ddwin->current_target!=0)
+ begin_spin (x, y);
+ }
+ else if (select_square_mode) {
+ begin_selection_square (x, y);
+ }
+ else {
+ begin_rotate (x, y);
+ }
+ }
+
+}
+
+void MyGl::mouseReleaseEvent ( QMouseEvent * e )
+{
+ float x = e->x(); float y = e->y();
+ Qt::MouseButton button = e->button ();
+ if (button == Qt::RightButton)
+ {
+ zoom = false;
+ if (select){
+ selectf (x,y);
+ select = false;
+ }
+ if (magic_pencil) {
+ end_magic_pencil (x, y);
+ }
+ }
+ else if (button == Qt::MidButton)
+ {
+ translate = false;
+ if (selection_square) end_selection_square ();
+ }
+ else if (button == Qt::LeftButton)
+ {
+ rotate = false;
+ move = false;
+ spin = false;
+ if (selection_square) end_selection_square ();
+
+ LastRot = ThisRot;
+
+
+ }
+}
+
+void MyGl::mouseMoveEvent ( QMouseEvent * e )
+{
+
+ float x = e->x(); float y = e->y();
+ lastx = x; lasty = y;
+
+
+
+
+ if (zoom){
+ continue_zoom (y);
+ select = false;
+ }
+ if (translate){
+ continue_translate (x, y);
+ }
+ if (rotate){
+ continue_rotate (x, y);
+ }
+ if (move) {
+ continue_move (x, y);
+ }
+ if (spin) {
+ continue_spin (x, y);
+ }
+ if (selection_square) {
+ continue_selection_square (x, y);
+ }
+ if (magic_pencil) {
+ continue_magic_pencil (x, y);
+ }
+
+}
+
+void MyGl::begin_magic_pencil (float x, float y) {
+ // cout <<"begin"<<endl;
+ magic_pencil = true;
+ Atom *a = select_atom (x, y, 10, 10);
+ if (a) {
+ ddwin->builder->start_magic_pencil_atom = a;
+ }
+ else {
+ ddwin->builder->start_magic_pencil_atom = NULL;
+ }
+
+}
+
+void MyGl::continue_magic_pencil (float x, float y) {
+ // cout <<"continue"<<endl;
+ // cout <<ddwin->magic_pencil_trail_x.size ()<<endl;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+ GLdouble xx, yy, zz;
+ gluUnProject (x, viewport[3]-y, 0, model, proj, viewport, &xx, &yy, &zz);
+ ddwin->magic_pencil_trail_x.push_back (xx);
+ ddwin->magic_pencil_trail_y.push_back (yy);
+ ddwin->magic_pencil_trail_z.push_back (zz);
+ ddwin->magic_pencil_trail_wx.push_back (x);
+ ddwin->magic_pencil_trail_wy.push_back (y);
+
+}
+
+void MyGl::end_magic_pencil (float x, float y) {
+
+
+ // cout <<"end"<<endl;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+ GLdouble xx, yy, zz;
+
+
+ if (ddwin->magic_pencil_trail_x.size () < 10) { //click
+ if (ddwin->builder->magic_pencil_atomic_number==-2) { //rubber
+ Atom *a = select_atom (x, y, 10, 10);
+ if (a) {
+ ddwin->builder->delete_atom (a);
+ }
+ }
+ else { //builder
+ Atom *a = select_atom (x, y, 10, 10);
+ if (a) { //click on an atom
+ if (!a -> IsHydrogen ()) {
+ if (ddwin->builder->last_magic_pencil_atom) { //continuing line
+ if (&*a == ddwin->builder->last_magic_pencil_atom || a -> GetBond (ddwin -> builder -> last_magic_pencil_atom)) {
+
+ ddwin->builder->last_magic_pencil_atom = NULL;
+ }
+
+ else {
+
+ ddwin->builder->new_bond (a, ddwin->builder->last_magic_pencil_atom);
+ }
+ }
+ ddwin->builder->mutate_atom_to (a, ddwin->builder->magic_pencil_atomic_number);
+ ddwin->builder->last_magic_pencil_atom = a;
+ }
+ }
+ else { //click on empty spot
+ if (ddwin->builder->last_magic_pencil_atom) {
+ GLdouble lx, ly, lz;
+ Atom *last = ddwin->builder->last_magic_pencil_atom;
+ vect v = get_coordinates(last);
+ gluProject (v.x(), v.y(), v.z(),model, proj, viewport,&lx, &ly, &lz);
+ gluUnProject (x, viewport[3]-y, lz, model, proj, viewport, &xx, &yy, &zz);
+ Atom *at;
+ vect coord (xx, yy, zz);
+ at = ddwin->builder->add_atom_bonded_to (coord, ddwin->builder->magic_pencil_atomic_number, last);
+ ddwin->builder->last_magic_pencil_atom = at;
+ draw_molecule ((ZNMolecule *) last -> GetParent ());
+ }
+ else {
+ GLdouble lx, ly, lz;
+ gluProject (0, 0, 0,model, proj, viewport,&lx, &ly, &lz);
+ gluUnProject (x, viewport[3]-y, lz, model, proj, viewport, &xx, &yy, &zz);
+ vect coord (xx, yy, zz);
+ Atom *at;
+ at = ddwin->builder->new_atom (coord, ddwin->builder->magic_pencil_atomic_number);
+ ddwin->builder->last_magic_pencil_atom = at;
+ draw_molecule ((ZNMolecule *) at-> GetParent ());
+ }
+ }
+
+ }
+ }
+ else { //drag
+
+
+ Atom *a = select_atom (x, y, 10, 10);
+ if (a && ddwin->builder->start_magic_pencil_atom) {
+ if (a!=ddwin->builder->start_magic_pencil_atom) {
+ ZNBond *bo = a-> GetBond (ddwin->builder->start_magic_pencil_atom);
+ if (bo) { // edit bond
+ if (ddwin->builder->magic_pencil_atomic_number==-2) { //rubber
+ if (bo-> IsTriple ()) ddwin->builder->set_bond (bo, 2);
+ else if (bo-> IsDouble ()) ddwin->builder->set_bond (bo, 1);
+ else if (bo -> IsSingle ()) ddwin -> builder -> delete_bond (bo);
+ // draw_molecule (bo->GetBeginAtom ()-> GetParent ());
+ }
+ else {
+ if (bo -> IsSingle ()) ddwin->builder->set_bond (bo, 2);
+ else if (bo -> IsDouble ()) ddwin->builder->set_bond (bo, 3);
+ // draw_molecule (bo->GetBeginAtom ()-> GetParent ());
+ }
+ }
+
+ }
+ }
+ else {
+ float x1 = ddwin->magic_pencil_trail_wx[0];
+ float x2 = ddwin->magic_pencil_trail_wx[ddwin->magic_pencil_trail_wx.size ()-1];
+ float y1 = ddwin->magic_pencil_trail_wy[0];
+ float y2 = ddwin->magic_pencil_trail_wy[ddwin->magic_pencil_trail_wy.size ()-1];
+ if ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) < 100) {
+/*
+ vector<OBRing*>::iterator ring;
+ vector<OBRing*> *rlist = (vector<OBRing*>*)ddwin -> target_molecule -> GetData("RingList");
+ for (ring = rlist->begin();ring != rlist->end();++ring) {
+
+ GLdouble cx, cy, cz, ax, ay, az;
+ gluProject (ring -> center.x(), ring- > center.y(), ring->center.z(),model, proj, viewport,&cx, &cy, &cz);
+
+ gluProject (ring->atoms[0]-> GetVector ().x(), ring->atoms[0]-> GetVector ().y(), ring->atoms[0]-> GetVector ().z(),model, proj, viewport,&ax, &ay, &az);
+ ay = viewport[3]-ay; //mouse coordinates
+ cy = viewport[3]-cy;
+ float r2 = (ax-cx)*(ax-cx)+(ay-cy)*(ay-cy);
+ bool boo = true;
+ for (unsigned int i=0; i<ddwin->magic_pencil_trail_wx.size (); i+=5) {
+ float ccx = ddwin->magic_pencil_trail_wx[i];
+ float ccy = ddwin->magic_pencil_trail_wy[i];
+ // cout <<(ccx-cx)*(ccx-cx)+(ccy-cy)*(ccy-cy)<<endl;
+ if ((ccx-cx)*(ccx-cx)+(ccy-cy)*(ccy-cy) > r2) {
+ boo = false;
+ break;
+ }
+ }
+
+ if (boo) {
+ if (ddwin->builder->magic_pencil_atomic_number==-2) { //rubber
+ ddwin->builder -> set_non_aromatic (ddwin->target_molecule->rings[r]);
+ }
+ else ddwin->builder -> set_aromatic (ddwin->target_molecule->rings[r]);
+ }
+ }
+
+ */
+ }
+ else {
+ ddwin->builder->last_magic_pencil_atom = NULL;
+
+ }
+ }
+ }
+
+ magic_pencil = false;
+ ddwin->magic_pencil_trail_x.clear ();
+ ddwin->magic_pencil_trail_y.clear ();
+ ddwin->magic_pencil_trail_z.clear ();
+ ddwin->magic_pencil_trail_wx.clear ();
+ ddwin->magic_pencil_trail_wy.clear ();
+
+
+}
+
+void MyGl::begin_selection_square (float x, float y) {
+ // cout<<"begin square"<<endl;
+ selection_square = true;
+ selection_square_x1 = x;
+ selection_square_y1 = y;
+ continue_selection_square (x, y);
+}
+
+void MyGl::continue_selection_square (float x, float y) {
+ selection_square_x2 = x;
+ selection_square_y2 = y;
+
+}
+
+
+void MyGl::end_selection_square () {
+
+ selection_square = false; //drawing the square
+ select_square_mode = false; //waiting for a click to start the square
+ unsetCursor();
+ select_square ();
+
+}
+
+
+
+
+
+void MyGl::begin_zoom (float y )
+{
+ zoom = true;
+ zbeginy = y;
+}
+
+void MyGl::continue_zoom (float y )
+{
+ view_translations.z() -= (y - zbeginy);
+ zbeginy = y;
+
+}
+
+void MyGl::begin_move (float x, float y )
+{
+ move = true;
+ continue_move (x, y);
+}
+
+void MyGl::begin_spin (float x, float y )
+{
+ spin = true;
+ sbeginx = x;
+}
+
+void MyGl::begin_translate (float x, float y )
+{
+ translate = true;
+ tbeginx = x; tbeginy = y;
+}
+
+void MyGl::continue_translate (float x, float y )
+{
+// translatefx += (x - tbeginx);
+// translatefy += (y - tbeginy);
+ view_translations.x() +=(x - tbeginx)/10;
+ view_translations.y() -=(y - tbeginy)/10;
+
+ tbeginx = x; tbeginy = y;
+
+}
+
+void MyGl::translate_view (vect v) {
+ view_translations = sum (view_translations, v);
+}
+
+void MyGl::continue_move (float x, float y )
+{
+ // GLdouble camerax, cameray, cameraz;
+ // GLdouble upx, upy, upz;
+// GLdouble rightx, righty, rightz;
+ GLdouble centx, centy, centz;
+ GLdouble targx, targy, targz;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+
+ // gluUnProject (viewport[2]/2, viewport[3]/2, 0, model, proj, viewport, &camerax, &cameray, &cameraz);
+// gluUnProject (viewport[2]/2, viewport[3], 0, model, proj, viewport, &upx, &upy, &upz);
+// gluUnProject (viewport[2], viewport[3]/2, 0, model, proj, viewport, &rightx, &righty, &rightz);
+ vect center = get_center (ddwin->target_molecule);
+ gluProject (center.x(), center.y(), center.z(),model, proj, viewport,¢x, ¢y, ¢z);
+ gluUnProject (x, viewport[3]-y, centz, model, proj, viewport, &targx, &targy, &targz);
+
+ move_molecule (ddwin->target_molecule, targx-center.x(), targy-center.y(), targz-center.z(), false);
+// move_molecule (ddwin->target_molecule, xx, yy, zz);
+ draw_molecule (ddwin->target_molecule);
+
+}
+
+void MyGl::continue_spin (float x, float y )
+{
+ GLdouble axisx, axisy, axisz, farx, fary, farz;
+ GLint viewport [4];
+ GLdouble model [16];
+ GLdouble proj [16];
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, model);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+
+ gluUnProject (viewport[2]/2, viewport[3]/2, 0, model, proj, viewport, &axisx, &axisy, &axisz);
+ gluUnProject (viewport[2]/2, viewport[3]/2, 1, model, proj, viewport, &farx, &fary, &farz);
+
+ axisx-=farx; axisy-=fary; axisz-=farz;
+ float mod = sqrt(axisx*axisx+axisy*axisy+axisz*axisz);
+ axisx/=mod; axisy/=mod; axisz/=mod;
+
+ float spin = (x - sbeginx)/50;
+// cout << upx<<" "<<upy<<endl;
+
+
+ vect axis (axisx, axisy, axisz);
+
+ FOR_ATOMS_OF_MOL(a, ddwin -> target_molecule) {
+ vect v = get_coordinates (&*a);
+ rotate_around_vector (v, axis, get_center (ddwin->target_molecule), spin);
+ }
+ draw_molecule (ddwin->target_molecule);
+ sbeginx = x;
+}
+
+void MyGl::begin_rotate (float x, float y )
+{
+ // cerr <<"begin rotate";
+ rotate = true;
+// ThisRot = LastRot;
+ // Point2fT MousePt ;
+ MousePt.T[0] =x; MousePt.T[1] = y;
+ ArcBall.click(&MousePt);
+}
+void MyGl::continue_rotate (float x, float y )
+{
+ // cerr <<"continue rotate";
+ Quat4fT ThisQuat;
+ // Point2fT MousePt ;
+ MousePt.T[0] =x; MousePt.T[1] = y;
+ ArcBall.drag(&MousePt, &ThisQuat); // Update End Vector && Get Rotation As Quaternion
+ Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // Convert Quaternion Into Matrix3fT
+ Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One
+ Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Set Our Final Transform's Rotation From This One
+
+}
+
+void MyGl::select_MW (unsigned int an) {
+ ZNMolecule *selected_mol = NULL;
+ if (ddwin -> target_molecule -> selection) {
+ Selection *sel = (Selection *) ddwin -> target_molecule;
+ if (sel -> get_molecules ().size () == 1) {
+ selected_mol = sel -> get_molecules ()[0];
+ }
+
+ if (selected_mol) ddwin -> set_current_target (selected_mol);
+ else ddwin -> set_current_target (0);
+ }
+ ddwin -> deselect ();
+ ZNMolecule *mol = ddwin -> target_molecule;
+
+ Selection *sel = new Selection ();
+ ddwin ->add_molecule (sel);
+ // ddwin->molecules.push_back (sel);
+ // ddwin->target->insertItem (1000, QString(sel -> GetTitle ()));
+// ddwin-> emit_targets_updated ();
+ ddwin->set_current_target (-1);
+ FOR_ATOMS_OF_MOL (a, mol) {
+ if (a-> GetAtomicNum () == an) sel -> select_atom (&*a);
+ }
+
+ find_limits (sel);
+ find_center (sel);
+
+}
+
+
+
+void MyGl::select_square () {
+ ZNMolecule *selected_mol = NULL;
+ if (ddwin -> target_molecule -> selection) {
+ Selection *sel = (Selection *) ddwin -> target_molecule;
+ if (sel -> get_molecules ().size () == 1) {
+ selected_mol = sel -> get_molecules ()[0];
+ }
+
+ if (selected_mol) ddwin -> set_current_target (selected_mol);
+ else ddwin -> set_current_target (0);
+ }
+ ddwin -> deselect ();
+ ZNMolecule *mol = ddwin -> target_molecule;
+ GLint viewport[4];
+ GLuint *buffer = new GLuint[ddwin->target_molecule -> NumAtoms ()*4];
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix ();
+ glLoadIdentity ();
+
+
+ matrix_transformations ();
+
+ glSelectBuffer (ddwin->target_molecule -> NumAtoms ()*4, buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+ glPushName(0);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity() ;
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ int x1, x2, y1, y2;
+ if (selection_square_x1<selection_square_x2) {
+ x1 = selection_square_x1;
+ x2 = selection_square_x2;
+ }
+ else {
+ x2 = selection_square_x1;
+ x1 = selection_square_x2;
+ }
+ if (selection_square_y1<selection_square_y2) {
+ y1 = selection_square_y1;
+ y2 = selection_square_y2;
+ }
+ else {
+ y2 = selection_square_y1;
+ y1 = selection_square_y2;
+ }
+ gluPickMatrix((x1+x2)/2, viewport[3]-(y1+y2)/2, x2-x1, y2-y1, viewport);
+ gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 10000.0f);
+ glMatrixMode(GL_MODELVIEW);
+
+ draw_atoms_for_selection (ddwin->target_molecule);
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+
+
+ int hits = glRenderMode (GL_RENDER);
+
+
+ if (hits){
+ // cerr << hits << endl;
+ Selection *sel = new Selection ();
+
+ for (unsigned int i=0; i<hits; i++) {
+ Atom * at = mol -> GetAtom (buffer[i*4+3]);
+ assert (at);
+ sel -> select_atom (at);
+ }
+
+ // FOR_BONDS_OF_MOL(b, mol) {
+ // if (get_selected (&*b)) sel -> ZNAddBondToSelection (&*b);
+ // }
+
+ find_limits (sel);
+ find_center (sel);
+ ddwin ->add_molecule (sel);
+ ddwin->set_current_target (-1);
+
+
+ }
+
+ delete[] buffer;
+}
+
+
+Atom * MyGl::select_atom (float x, float y, int dx, int dy) {
+ GLint viewport[4];
+ GLuint buffer[512];
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix ();
+ glLoadIdentity ();
+
+ glLoadIdentity();
+
+ matrix_transformations ();
+
+ glSelectBuffer (510, buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+ glPushName(0);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity() ;
+ // GLfloat w = viewport[2] / viewport[3];
+ // GLfloat h = 1.0;
+ // glFrustum( -w, w, -h, h, 1.0, 10000.0 );
+
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ gluPickMatrix(x, viewport[3]-y, dx, dy, viewport);
+ gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 10000.0f);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ draw_atoms_for_selection (ddwin->target_molecule);
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+
+
+ int hits = glRenderMode (GL_RENDER);
+ if (hits){
+ Atom *a = ddwin->target_molecule->GetAtom (buffer[3]);
+ return a;
+
+ }
+ else return NULL;
+
+ // if len (hits):
+ // print len (hits)
+ // print hits[0]
+ // selected = self.master.data.atoms[hits [0][2][0]]
+ // print selected.typ, selected.coords
+ // # print self.docking_sphere_center_coords
+ // self.ogl.tkRedraw()
+
+
+
+}
+
+
+
+
+
+void MyGl::selectf (float x, float y) {
+
+ Atom *a = select_atom (x, y, 5, 5);
+ if (a) {
+ if (ddwin ->adding_restrains) {
+ ddwin ->haptic_menu ->add_restrain_atom (a);
+ }
+ else {
+ clicked_atom=a;
+ ddwin->show_atom_properties (clicked_atom);
+ }
+ }
+
+}
+
+
+void MyGl::draw_ring_line (Ring* ring) {
+/* glPushMatrix ();
+ vect center = ring->center;
+
+ rotate_to_plane (ring->bonds[0]->GetBeginAtom ()-> GetVector (),ring->bonds[0]->GetEndAtom ()-> GetVector (), center);
+
+
+ float slices = 40;
+// float rad1 = stick_rad;
+// float rad2 = stick_rad;
+ float angl = 0.0;
+ float da = 2*PI/slices;
+
+
+
+ glBegin (GL_LINE_STRIP);
+
+ ZNBond *this_bond = ring->bonds[0];
+ Atom *prev_atom = ring->bonds[0]->GetBeginAtom ();
+ Atom *next_atom = ring->bonds[0]->GetEndAtom ();
+// cout <<"next atom "<<ring->bonds[0]->GetEndAtom ()->ID<<endl;
+ Atom *start_atom = prev_atom;
+ // float dir_coords [3];
+ // for (unsigned int i=0; i<3; i++) dir_coords[i]=next_atom-> GetVector ()[i];
+ // rotate_around_vector (dir_coords, rot_vec, O, rangle);
+ // float tang;
+ // float test_ang;
+ // dis = sqrt (dir_coords[0]*dir_coords[0]+dir_coords[1]*dir_coords[1]+dir_coords[2]*dir_coords[2]);
+// tang = acos (dir_coords[0]/dis);
+ // if (dir_coords[1]<0) test_ang = tang;
+// else test_ang = PI-tang;
+
+ // if (test_ang<start_ang) {
+ // Atom *sw;
+ // sw = prev_atom;
+ // prev_atom = next_atom;
+ // next_atom = sw;
+ // }
+
+
+ float rad = dist (ring->bonds[0]->GetBeginAtom ()-> GetVector (), center) * cos (PI/ring->bonds.size ())-aromatic_bond_inter_distance; //apotema -
+ float curr_ang;
+ int maxc = angle (prev_atom-> GetVector (), ring->center, next_atom-> GetVector ())/180*PI/da;
+ int c = 0;
+ for (unsigned int n=0; n<slices+1; n++){
+ angl = n*da+PI/2;
+ // cout <<c<<" "<<maxc<<endl;
+ if (c>maxc) {
+ c=0;
+ prev_atom = next_atom;
+ // next_atom = ring->atoms[0];
+ for (unsigned int rb=0; rb<ring->bonds.size (); rb++) {
+ if (ring->bonds[rb]!=this_bond && ring->bonds[rb]->GetBeginAtom ()==next_atom) {
+ next_atom = ring->bonds[rb]->GetEndAtom ();
+ this_bond = ring->bonds[rb];
+ // cout<<"next atom "<<ring->bonds[rb]->GetEndAtom ()->ID<<endl;
+ break;
+ }
+ if (ring->bonds[rb]!=this_bond && ring->bonds[rb]->GetEndAtom ()==next_atom) {
+ next_atom = ring->bonds[rb]->GetBeginAtom ();
+ this_bond = ring->bonds[rb];
+ // cout<<"next atom "<<ring->bonds[rb]->GetBeginAtom ()->ID<<endl;
+ break;
+ }
+
+ }
+ maxc = angle (prev_atom-> GetVector (), ring->center, next_atom-> GetVector ())/180*PI/da;
+
+ }
+ float r = (c*next_atom->col.redF () + (maxc-c)*prev_atom->col.redF ())/maxc;
+ float g = (c*next_atom->col.greenF ()+(maxc-c)*prev_atom->col.greenF ())/maxc;
+ float b = (c*next_atom->col.blueF () +(maxc-c)*prev_atom->col.blueF ())/maxc;
+ float a = (c*next_atom->col.alphaF () +(maxc-c)*prev_atom->col.alphaF ())/maxc;
+
+ glColor4f (r, g, b, a);
+ glVertex3f (sin (angl)*rad, cos (angl)*rad, 0);
+ c++;
+ }
+ glEnd ();
+ glPopMatrix ();
+
+*/
+}
+
+
+void MyGl::draw_ring_stick (Ring* ring) {
+/*
+
+ glPushMatrix ();
+ vect center = ring->center;
+
+ rotate_to_plane (ring->bonds[0]->GetBeginAtom ()-> GetVector (), ring->bonds[0]->GetEndAtom ()-> GetVector (), center);
+
+
+ float slices = 40;
+ float slices2 = 20;
+// float rad1 = stick_rad;
+// float rad2 = stick_rad;
+ float angl = 0.0;
+ float angl2 = 0.0;
+ float da = 2*PI/slices;
+ float da2 = 2*PI/slices2;
+
+ float radtwo = stick_rad/2;
+ float rad = dist (ring->bonds[0]->GetBeginAtom ()-> GetVector (), center) * cos (PI/ring->bonds.size ())-aromatic_bond_inter_distance; //apotema - /apotema -
+ //equation of plane Ax + By + Cz = 0
+ rad-=radtwo;
+
+ ZNBond *this_bond = ring->bonds[0];
+ Atom *prev_atom = ring->bonds[0]->GetBeginAtom ();
+ Atom *next_atom = ring->bonds[0]->GetEndAtom ();
+// cout <<"next atom "<<ring->bonds[0]->GetEndAtom ()->ID<<endl;
+ Atom *start_atom = prev_atom;
+
+
+ float curr_ang;
+ int maxc = angle (prev_atom-> GetVector (), ring->center, next_atom-> GetVector ())/180*PI/da;
+ int c = 0;
+
+
+
+
+ vect cent (0.f, 0.f, 0.f);
+ vect cent2(0.f, 0.f, 0.f);
+
+
+ for (unsigned int n=0; n<slices; n++){
+ angl = n*da+PI/2; //+start_ang+PI/2;
+ glBegin (GL_QUAD_STRIP);
+
+
+ if (c>maxc) {
+ c=0;
+ prev_atom = next_atom;
+ // next_atom = ring->atoms[0];
+ for (unsigned int rb=0; rb<ring->bonds.size (); rb++) {
+ if (ring->bonds[rb]!=this_bond && ring->bonds[rb]->GetBeginAtom ()==next_atom) {
+ next_atom = ring->bonds[rb]->GetEndAtom ();
+ this_bond = ring->bonds[rb];
+ // cout<<"next atom "<<ring->bonds[rb]->GetEndAtom ()->ID<<endl;
+ break;
+ }
+ if (ring->bonds[rb]!=this_bond && ring->bonds[rb]->GetEndAtom ()==next_atom) {
+ next_atom = ring->bonds[rb]->GetBeginAtom ();
+ this_bond = ring->bonds[rb];
+ // cout<<"next atom "<<ring->bonds[rb]->GetBeginAtom ()->ID<<endl;
+ break;
+ }
+
+ }
+ maxc = angle (prev_atom-> GetVector (), ring->center, next_atom-> GetVector ())/180*PI/da;
+
+ }
+ float r = (c*next_atom->col.redF ()+(maxc-c)*prev_atom->col.redF ())/maxc;
+ float g = (c*next_atom-> col.greenF ()+(maxc-c)*prev_atom->col.greenF ())/maxc;
+ float b = (c*next_atom-> col.blueF ()+(maxc-c)*prev_atom->col.blueF ())/maxc;
+ float a = (c*next_atom-> col.alphaF ()+(maxc-c)*prev_atom-> col.alphaF ())/maxc;
+
+ float r2 = ((c+1)*next_atom-> col.redF ()+(maxc-c-1)*prev_atom-> col.redF ())/maxc;
+ float g2 = ((c+1)*next_atom-> col.greenF ()+(maxc-c-1)*prev_atom-> col.greenF ())/maxc;
+ float b2 = ((c+1)*next_atom-> col.blueF ()+(maxc-c-1)*prev_atom-> col.blueF ())/maxc;
+ float a2 = ((c+1)*next_atom-> col.alphaF ()+(maxc-c-1)*prev_atom-> col.alphaF ())/maxc;
+
+
+
+
+
+
+
+
+ for (unsigned int n2=0; n2<slices2; n2++) {
+ angl2 = n2*da2;
+ vect v, v2;
+ v.x() = sin (angl)*(rad+radtwo);
+ v.y() = cos (angl)*(rad+radtwo);
+ v.z() = 0.f;
+ v2.x() = sin (angl+da)*(rad+radtwo);
+ v2.y() = cos (angl+da)*(rad+radtwo);
+ v2.z() = 0.f;
+ cent.x() = sin (angl)*(rad);
+ cent.y() = cos (angl)*(rad);
+ cent.z() = 0.f;
+ cent2.x() = sin (angl+da)*(rad);
+ cent2.y() = cos (angl+da)*(rad);
+ cent2.z() = 0.f;
+ vect tang;
+ vect tang2;
+ tang.x() = (cos (angl));
+ tang.y() = (-sin (angl));
+ tang.z() = 0.f;
+ tang2.x() = (cos (angl+da));
+ tang2.y() = (-sin (angl+da));
+ tang2.z() = 0.f;
+
+
+ // glVertex3fv (v);
+ // glVertex3fv (v2);
+ rotate_around_vector (v, tang, cent, angl2);
+ rotate_around_vector (v2, tang2, cent2, angl2);
+ glNormal3f (-(v.x() - cent.x()), -(v.y()-cent.y()),-(v.z()-cent.z()));
+ glColor4f (r, g, b, a);
+ glVertex3f (v.x(), v.y(), v.z());
+ glNormal3f (-(v2.x()-cent2.x()), -(v2.y()-cent2.y()),-(v2.z()-cent2.z()));
+ glColor4f (r2, g2, b2, a2);
+ glVertex3f (v2.x(), v2.y(), v2.z());
+
+ }
+ glEnd ();
+ c++;
+ }
+
+ glPopMatrix ();
+
+*/
+}
+
+
+
+
+
+
+void MyGl::draw_bond_line (ZNBond* bond)
+{
+ glBegin(GL_LINES);
+ Atom *at1 = bond->GetBeginAtom ();
+ Atom *at2 = bond ->GetEndAtom ();
+ vect v1 = get_coordinates (at1);
+ vect v2 = get_coordinates (at2);
+ setAtomColor(at1);
+ glVertex3d(v1.x(), v1.y(), v1.z());
+ setAtomColor(at2);
+ glVertex3d(v2.x(), v2.y(), v2.z());
+ glEnd();
+}
+
+void MyGl::draw_aromatic_bond_line (ZNBond* bond) {
+ float d=0.08f;
+ glBegin(GL_LINES);
+ Atom *at1 = bond->GetBeginAtom ();
+ Atom *at2 = bond ->GetEndAtom ();
+ vect v1 = get_coordinates (at1);
+ vect v2 = get_coordinates (at2);
+ setAtomColor(at1);
+ glVertex3d(v1.x(), v1.y(), v1.z());
+ setAtomColor(at2);
+ glVertex3d(v2.x(), v2.y(), v2.z());
+ glEnd();
+
+
+/* if (bond->hasCoplanar0) {
+ Atom *at0 = bond-> GetBeginAtom ();
+ Atom *co0 =bond->coplanarAtom0;
+ Atom *at1 = bond-> GetEndAtom ();
+ float vecx = co0-> GetVector ().x()-at0-> GetVector ().x();
+ float vecy = co0-> GetVector ().y()-at0-> GetVector ().y();
+ float vecz = co0-> GetVector ().z()-at0-> GetVector ().z();
+ float mod = sqrt (vecx*vecx+vecy*vecy+vecz*vecz);
+ vecx/=mod;
+ vecy/=mod;
+ vecz/=mod;
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(1, 0xF0F0);
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(at0-> GetVector ().x()+vecx*d,at0-> GetVector ().y()+vecy*d,at0-> GetVector ().z()+vecz*d );
+ setAtomColor(at1);
+ glVertex3f(at1-> GetVector ().x()+vecx*d,at1-> GetVector ().y()+vecy*d,at1-> GetVector ().z()+vecz*d );
+ glEnd();
+ glDisable (GL_LINE_STIPPLE);
+ }
+
+ else if (bond->hasCoplanar1) {
+ Atom *at0 = bond-> GetBeginAtom ();
+ Atom *co1 =bond->coplanarAtom1;
+ Atom *at1 = bond-> GetEndAtom ();
+ float vecx = co1-> GetVector ().x()-at1-> GetVector ().x();
+ float vecy = co1-> GetVector ().y()-at1-> GetVector ().y();
+ float vecz = co1-> GetVector ().z()-at1-> GetVector ().z();
+ float mod = sqrt (vecx*vecx+vecy*vecy+vecz*vecz);
+ vecx/=mod;
+ vecy/=mod;
+ vecz/=mod;
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(1, 0xF0F0);
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(at0-> GetVector ().x()+vecx*d,at0-> GetVector ().y()+vecy*d,at0-> GetVector ().z()+vecz*d );
+ setAtomColor(at1);
+ glVertex3f(at1-> GetVector ().x()+vecx*d,at1-> GetVector ().y()+vecy*d,at1-> GetVector ().z()+vecz*d );
+ glEnd();
+ glDisable (GL_LINE_STIPPLE);
+ }*/
+}
+
+void MyGl::draw_triple_bond_line (ZNBond * bond) {
+ draw_bond_line (bond);
+ draw_double_bond_line (bond);
+}
+
+
+
+void MyGl::draw_double_bond_line (ZNBond* bond) {
+ Atom *at0 = bond->GetBeginAtom ();
+ Atom *at1 = bond->GetEndAtom ();
+
+ float verts [4][3];
+ compute_double_bond_vertexes (bond, verts);
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(verts[0][0], verts[0][1], verts [0][2]);
+ setAtomColor(at1);
+ glVertex3f(verts[2][0], verts[2][1], verts[2][2]);
+ glEnd();
+
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(verts[1][0], verts[1][1], verts[1][2]);
+ setAtomColor(at1);
+ glVertex3f(verts[3][0], verts[3][1], verts[3][2]);
+ glEnd();
+
+}
+
+
+
+// if (found0 && !found1) {
+
+// }
+
+
+
+/*
+ Atom *at0, *co1, *at1;
+ if (bond->hasCoplanar1) {
+ at0 = bond-> GetBeginAtom ();
+ co1 =bond->coplanarAtom1;
+ at1 = bond-> GetEndAtom ();
+ }
+
+ else {
+ at1 = bond-> GetBeginAtom ();
+ co1 =bond->coplanarAtom0;
+ at0 = bond-> GetEndAtom (); }
+
+
+ float vecx = co1-> GetVector ().x()-at1-> GetVector ().x();
+ float vecy = co1-> GetVector ().y()-at1-> GetVector ().y();
+ float vecz = co1-> GetVector ().z()-at1-> GetVector ().z();
+ float mod = sqrt (vecx*vecx+vecy*vecy+vecz*vecz);
+ vecx/=mod;
+ vecy/=mod;
+ vecz/=mod;
+ vector <float> vec;
+ vector <float> ref;
+ vector <float> nor;
+ vector <float> par;
+ ref.push_back(at1-> GetVector ().x()-at0-> GetVector ().x());
+ ref.push_back(at1-> GetVector ().y()-at0-> GetVector ().y());
+ ref.push_back(at1-> GetVector ().z()-at0-> GetVector ().z());
+ vec.push_back(vecx); vec.push_back(vecy); vec.push_back(vecz);
+ components (vec, ref, par, nor);
+
+ float a1x=at0-> GetVector ().x()+nor[0]*d-par[0]*d;
+ float a1y=at0-> GetVector ().y()+nor[1]*d-par[1]*d;
+ float a1z=at0-> GetVector ().z()+nor[2]*d-par[2]*d;
+
+ float a2x=at1-> GetVector ().x()+nor[0]*d+par[0]*d;
+ float a2y=at1-> GetVector ().y()+nor[1]*d+par[1]*d;
+ float a2z=at1-> GetVector ().z()+nor[2]*d+par[2]*d;
+
+
+
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(a1x, a1y, a1z);
+ setAtomColor(at1);
+ glVertex3f(a2x, a2y, a2z);
+ glEnd();
+
+ a1x=at0-> GetVector ().x()-nor[0]*d-par[0]*d;
+ a1y=at0-> GetVector ().y()-nor[1]*d-par[1]*d;
+ a1z=at0-> GetVector ().z()-nor[2]*d-par[2]*d;
+
+ a2x=at1-> GetVector ().x()-nor[0]*d+par[0]*d;
+ a2y=at1-> GetVector ().y()-nor[1]*d+par[1]*d;
+ a2z=at1-> GetVector ().z()-nor[2]*d+par[2]*d;
+
+ glBegin(GL_LINES);
+ setAtomColor(at0);
+ glVertex3f(a1x, a1y, a1z);
+ setAtomColor(at1);
+ glVertex3f(a2x, a2y, a2z);
+ glEnd();
+ }
+
+*/
+
+
+
+void MyGl::draw_bond_stick(ZNBond* bond)
+{
+
+ float angle, height, mod_of_vector;
+ Atom *at1 = bond -> GetBeginAtom ();
+ Atom *at2 = bond -> GetEndAtom ();
+ vect at1c = get_coordinates(at1);
+ vect at2c = get_coordinates (at2);
+
+
+
+ vect vector = subtract (at2c, at1c);
+
+
+
+ mod_of_vector = vector.module ();
+
+ vector *= 1/mod_of_vector;
+
+ height = mod_of_vector;
+
+ angle = acos (vector.z ()) * 180.0 / PI;
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+// setAtomColor(bond->GetBeginAtom ());
+ glPushMatrix ();
+
+
+
+ glTranslated (at1c.x (), at1c.y(), at1c.z());
+ glRotated (180.0, 0.0, 0.0, 1.0);
+ glRotated (angle, vector.y (), -1.0 * vector.x (), 0.0);
+
+
+
+// gluCylinder (quadratic,stick_rad,stick_rad,mod_of_vector*0.5,16, 1);
+
+ my_cylinder (*ddwin ->data ->stick_radius, *ddwin ->data ->stick_radius, height, *ddwin ->data ->quality_scale * 5, bond->GetBeginAtom (), bond->GetEndAtom ());
+
+ glPopMatrix ();
+
+ Atom *at1p = bond -> GetBeginAtom ();
+ Atom *at2p = bond -> GetEndAtom ();
+
+
+ if (!get_sad (at1p)) {
+ set_sad (at1p, true);
+ glPushMatrix ();
+ setAtomColor(at1);
+ glTranslatef (at1c.x(), at1c.y (), at1c.z ());
+ gluSphere (quadratic, *ddwin ->data ->stick_radius, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ }
+ if (!get_sad (at2p)) {
+ set_sad (at2p, true);
+ glPushMatrix ();
+ setAtomColor(at2);
+ glTranslatef (at2c.x(), at2c.y (), at2c.z ());
+ gluSphere (quadratic, *ddwin ->data ->stick_radius, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ }
+
+
+
+ // setAtomColor(bond->GetEndAtom ());
+ // glPushMatrix ();
+
+// glTranslatef (bond->GetBeginAtom ()-> GetVector ().x() + 0.5 * (bond->GetEndAtom ()-> GetVector ().x() - bond->GetBeginAtom ()-> GetVector ().x()),
+ // bond->GetBeginAtom ()-> GetVector ().y() + 0.5 * (bond->GetEndAtom ()-> GetVector ().y() - bond->GetBeginAtom ()-> GetVector ().y()),
+ // bond->GetBeginAtom ()-> GetVector ().z() + 0.5 * (bond->GetEndAtom ()-> GetVector ().z() - bond->GetBeginAtom ()-> GetVector ().z()));
+ // glRotatef (180.0, 0.0, 0.0, 1.0);
+ // glRotatef (angle, vector[1], -1.0 * vector[0], 0.0);
+
+
+ // gluCylinder (quadratic,stick_rad,stick_rad,0.5 * mod_of_vector,10, 1);
+
+ // glPopMatrix ();
+
+
+}
+
+
+void MyGl::draw_double_bond_stick (ZNBond* bond) {
+
+
+
+ float verts [4][3];
+
+ float angle, height;
+ compute_double_bond_vertexes (bond, verts);
+ vect vector (verts[2][0]-verts[0][0], verts[2][1]-verts[0][1], verts[2][2]-verts[0][2]);
+ height = vector.module ();
+ vector.normalise ();
+
+
+ angle = acos (vector.z()) * 180.0f / PI;
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+
+ glPushMatrix ();
+
+
+ glTranslatef (verts[0][0], verts[0][1], verts[0][2]);
+ glRotatef (180.0f, 0.0f, 0.0f, 1.0f);
+ glRotatef (angle, vector.y(), -1.0 * vector.x(), 0.0f);
+
+// gluCylinder (quadratic,stick_rad,stick_rad,mod_of_vector*0.5,16, 1);
+
+ my_cylinder (*ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, height, *ddwin ->data ->quality_scale * 5, bond->GetBeginAtom (),bond->GetEndAtom ());
+
+ glPopMatrix ();
+
+ vector = vect (verts[3][0]-verts[1][0], verts[3][1]-verts[1][1], verts[3][2]-verts[1][2]);
+ height = vector.module ();
+ vector.normalise ();
+
+
+ angle = acos (vector.z()) * 180.0f / PI;
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+
+ glPushMatrix ();
+
+
+ glTranslatef (verts[1][0], verts[1][1], verts[1][2]);
+ glRotatef (180.0, 0.0, 0.0, 1.0);
+ glRotatef (angle, vector.y(), -1.0 * vector.x(), 0.0);
+
+// gluCylinder (quadratic,stick_rad,stick_rad,mod_of_vector*0.5,16, 1);
+
+ my_cylinder (*ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, height, *ddwin ->data ->quality_scale * 5, bond->GetBeginAtom (),bond->GetEndAtom ());
+
+ glPopMatrix ();
+ // ZNMolecule *mol = (ZNMolecule *) bond -> GetParent ();
+ if (CountBonds (bond->GetBeginAtom ())== 1) {
+ glPushMatrix ();
+ setAtomColor(bond->GetBeginAtom ());
+ glTranslatef (verts[0][0], verts[0][1], verts[0][2]);
+ gluSphere (quadratic, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ glPushMatrix ();
+ glTranslatef (verts[1][0], verts[1][1], verts[1][2]);
+ gluSphere (quadratic, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ }
+ if (CountBonds (bond->GetEndAtom ())== 1) {
+ glPushMatrix ();
+ setAtomColor(bond->GetEndAtom ());
+ glTranslatef (verts[2][0], verts[2][1], verts[2][2]);
+ gluSphere (quadratic, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ glPushMatrix ();
+ glTranslatef (verts[3][0], verts[3][1], verts[3][2]);
+ gluSphere (quadratic, *ddwin ->data ->stick_radius * *ddwin ->data ->double_bond_stick_scale, *ddwin ->data ->quality_scale * 5, *ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+ }
+
+
+
+}
+
+void MyGl::draw_triple_bond_stick (ZNBond* bond) {
+ draw_bond_stick (bond);
+ draw_double_bond_stick (bond);
+
+}
+
+
+void MyGl::draw_aromatic_bond_stick (ZNBond* bond) {
+ draw_bond_stick (bond); /*
+ float angle, height, mod_of_vector;
+ float vecto[3];
+ float d=aromatic_bond_inter_distance;
+ Atom *at0, *co1, *at1;
+ if (bond->hasCoplanar1) {
+ at0 = bond-> GetBeginAtom ();
+ co1 =bond->coplanarAtom1;
+ at1 = bond-> GetEndAtom ();
+ }
+
+ else {
+ at1 = bond-> GetBeginAtom ();
+ co1 =bond->coplanarAtom0;
+ at0 = bond-> GetEndAtom (); }
+
+ float vecx = co1-> GetVector ().x()-at1-> GetVector ().x();
+ float vecy = co1-> GetVector ().y()-at1-> GetVector ().y();
+ float vecz = co1-> GetVector ().z()-at1-> GetVector ().z();
+ float mod = sqrt (vecx*vecx+vecy*vecy+vecz*vecz);
+ vecx/=mod;
+ vecy/=mod;
+ vecz/=mod;
+ vector <float> vec;
+ vector <float> ref;
+ vector <float> nor;
+ vector <float> par;
+
+ ref.push_back(at0-> GetVector ().x()-at1-> GetVector ().x());
+ ref.push_back(at0-> GetVector ().y()-at1-> GetVector ().y());
+ ref.push_back(at0-> GetVector ().z()-at1-> GetVector ().z());
+ vec.push_back(vecx); vec.push_back(vecy); vec.push_back(vecz);
+ components (vec, ref, par, nor);
+
+ float a1x=at0-> GetVector ().x()+nor[0]*d+par[0]*d;
+ float a1y=at0-> GetVector ().y()+nor[1]*d+par[1]*d;
+ float a1z=at0-> GetVector ().z()+nor[2]*d+par[2]*d;
+
+ float a2x=at1-> GetVector ().x()+nor[0]*d-par[0]*d;
+ float a2y=at1-> GetVector ().y()+nor[1]*d-par[1]*d;
+ float a2z=at1-> GetVector ().z()+nor[2]*d-par[2]*d;
+
+ vecto[0] = a2x-a1x;
+ vecto[1] = a2y-a1y;
+ vecto[2] = a2z-a1z;
+ mod_of_vector = sqrt(vecto[0]* vecto[0] + vecto[1]* vecto[1] + vecto[2]* vecto[2]);
+
+ vecto[0] /= mod_of_vector;
+ vecto[1] /= mod_of_vector;
+ vecto[2] /= mod_of_vector;
+
+
+
+ height = mod_of_vector;
+
+ angle = acos (vecto[2]) * 180.0 / PI;
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+
+
+ glPushMatrix ();
+
+ glTranslatef (a1x, a1y, a1z);
+ glRotatef (180.0, 0.0, 0.0, 1.0);
+ glRotatef (angle, vecto[1], -1.0 * vecto[0], 0.0);
+
+
+ my_cylinder (stick_rad*double_bond_stick_radius_scale*0.5, stick_rad*double_bond_stick_radius_scale*0.5, mod_of_vector, stick_precision, at0,at1);
+ glPopMatrix ();
+*/
+
+}
+
+
+
+void MyGl::draw_atom_sphere(Atom* atom) {
+
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ vect v = get_coordinates(atom);
+ setAtomColor(atom);
+ glPushMatrix ();
+ glTranslatef (v.x(), v.y(), v.z());
+ // my_sphere (sphere_radius,2*sphere_precision,sphere_precision, atom);
+ gluSphere (quadratic,*ddwin ->data ->sphere_radius,*ddwin ->data ->quality_scale * 5,*ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+
+}
+
+void MyGl::draw_atom_sel_sphere(Atom* atom) {
+ vect v = get_coordinates(atom);
+ // glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ // setAtomColor(atom);
+ glPushMatrix ();
+ glTranslatef (v.x(), v.y(), v.z());
+ gluSphere (quadratic,*ddwin ->data ->sphere_radius,6,6);
+ glPopMatrix ();
+
+}
+
+
+void MyGl::draw_atom_vdw_sphere(Atom* atom) {
+ vect v = get_coordinates(atom);
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ setAtomColor(atom);
+ glPushMatrix ();
+ glTranslatef (v.x(), v.y(), v.z());
+ double vdw = etab.GetVdwRad (atom -> GetAtomicNum ());
+ gluSphere (quadratic, vdw, *ddwin ->data ->quality_scale * 7, *ddwin ->data ->quality_scale * 7);
+ glPopMatrix ();
+
+}
+
+void MyGl::draw_atom_scaled_vdw_sphere(Atom* atom) {
+ vect v = get_coordinates(atom);
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ setAtomColor(atom);
+ glPushMatrix ();
+ glTranslatef (v.x(), v.y(), v.z());
+ // my_sphere (atom->vdw*vdw_scale,sphere_precision,sphere_precision, atom);
+ double vdw = etab.GetVdwRad (atom -> GetAtomicNum ());
+ gluSphere (quadratic, vdw**ddwin ->data ->vdw_scale,*ddwin ->data ->quality_scale * 5,*ddwin ->data ->quality_scale * 5);
+ glPopMatrix ();
+
+}
+
+void MyGl::draw_molecule (ZNMolecule *mol) {
+ set_needs_redraw(mol, true);
+}
+
+void MyGl::GL_update_molecule (ZNMolecule* mol) {
+ lock_geometry_for_read (mol);
+ redraw_counter++;
+ if (mol->selection) {
+ draw_list ( (Selection *) mol);
+ }
+ else draw_list (mol);
+ set_needs_redraw(mol, false);
+ unlock_geometry (mol);
+}
+
+void MyGl::GL_update_backbone (ZNMolecule* mol) {
+ lock_geometry_for_read (mol);
+ draw_backbone_list(mol);
+ set_needs_backbone_redraw(mol, false);
+ unlock_geometry (mol);
+}
+
+void MyGl::draw_list (MarchingCubes * cube) {
+
+ float xm = cube->size_x ();
+ float ym = cube->size_y ();
+ float zm = cube->size_z ();
+ float xmin = cube->xmin ();
+ float ymin = cube->ymin ();
+ float zmin = cube->zmin ();
+ float xmax = cube->xmax ();
+ float ymax = cube->ymax ();
+ float zmax = cube->zmax ();
+// cout <<xmin<<" "<<ymin<<" "<<zmin<<" "<<xmax<<" "<<" "<<ymax<<" "<<zmax<<endl;
+
+ for (unsigned int i=0; i<cube->ntrigs (); i++) {
+ glColor4f (1.,1.,1., 1.);
+ glBegin (GL_TRIANGLES);
+ Vertex *v1 = cube->vert(cube->trig (i)->v1);
+ Vertex *v2 = cube->vert(cube->trig (i)->v2);
+ Vertex *v3 = cube->vert(cube->trig (i)->v3);
+ glNormal3f (v1->nx, v1->ny, v1->nz);
+ glVertex3f (v1->x*(xmax-xmin)/xm+xmin, v1->y*(ymax-ymin)/ym+ymin, v1->z*(zmax-zmin)/zm+zmin);
+ glNormal3f (v2->nx, v2->ny, v2->nz);
+ glVertex3f (v2->x*(xmax-xmin)/xm+xmin, v2->y*(ymax-ymin)/ym+ymin, v2->z*(zmax-zmin)/zm+zmin);
+ glNormal3f (v3->nx, v3->ny, v3->nz);
+ glVertex3f (v3->x*(xmax-xmin)/xm+xmin, v3->y*(ymax-ymin)/ym+ymin, v3->z*(zmax-zmin)/zm+zmin);
+ glEnd ();
+ }
+}
+/*
+void MyGl::draw_list (Grid& grid, int list) {
+
+ glNewList(list,GL_COMPILE);
+ // glBegin (GL_POINTS);
+ float min, max;
+ min =grid.min;
+ max=grid.max;
+ glPointSize (20.0);
+ glBegin (GL_POINTS);
+
+ for (unsigned i =0; i<grid.vec.size (); i++) {
+ float col = (grid.vec[i].val-min)/(max-min);
+ glColor4f (2*col-1,0,1-(2*col-1),2*col-1);//col*col*col*0.6);
+ if (col >0.5){
+ glVertex3f (grid.vec[i].x(), grid.vec[i].y(),grid.vec[i].z());
+ }
+ }
+ glEnd ();
+
+ glEndList ();
+
+ }
+*/
+
+
+void MyGl::draw_list (Selection* sel) {
+ find_limits (sel);
+ find_center (sel);
+ for (unsigned int i=0; i < sel->get_molecules ().size (); i++) {
+ draw_list (sel->get_molecules ()[i]);
+ }
+}
+
+
+void MyGl::backbone_to_surface (ZNMolecule *mol, Surface *surf) {
+ find_backbone_data (mol);
+ FOR_RESIDUES_OF_MOL (res, mol) {
+ draw_backbone_stick (&*res, surf);
+ }
+ surf ->render();
+}
+
+
+void MyGl::draw_backbone_list (ZNMolecule *mol) {
+ glNewList(get_backbone_list1 (mol),GL_COMPILE);
+ FOR_RESIDUES_OF_MOL (r, mol) {
+ if (get_backbone_display_style (mol) == 1) {
+ find_backbone_data (mol);
+ draw_backbone_line (&*r);
+ }
+ }
+ glEndList ();
+ glNewList(get_backbone_list2 (mol),GL_COMPILE);
+ FOR_RESIDUES_OF_MOL (r, mol) {
+
+ if (get_backbone_display_style (mol) == 2) {
+ find_backbone_data (mol);
+ draw_backbone_stick(&*r);
+ }
+ }
+ glEndList ();
+}
+
+void MyGl::draw_list (ZNMolecule* mol) {
+
+ find_limits (mol);
+
+ find_center (mol);
+
+
+ FOR_ATOMS_OF_MOL(a, mol) {
+ set_sad (&*a, false);
+ }
+ glNewList(get_line_list (mol),GL_COMPILE);
+
+ FOR_BONDS_OF_MOL (b, mol) {
+ Atom *at1 = b -> GetBeginAtom ();
+ Atom *at2 = b -> GetEndAtom ();
+
+ bool vis = get_visible (&*b);
+ int dsi = get_ds (&*b);
+
+
+ if (vis) {
+
+ int order;
+ if (aromatic_display_style == AROMATIC_RINGS && b -> IsAromatic ()) order = 1;
+ else order = b -> GetBondOrder ();
+
+ // cout << order<<" "<<mol->bonds[i]->kekule<<" "<<mol->bonds[i]->mol2Type<< endl;
+ switch (dsi) {
+ case LINES:
+ switch (order) {
+ case 1:
+ draw_bond_line (&*b);
+ break;
+ case 2:
+ draw_double_bond_line (&*b);
+ break;
+ case 3:
+ draw_triple_bond_line (&*b);
+ break;
+ // case 4:
+ // draw_aromatic_bond_line (&*b);
+ // break;
+ // case 5:
+ // if (aromatic_display_style != AROMATIC_RINGS) draw_aromatic_bond_line (&*b);
+ // else draw_bond_line (&*b);
+ // break;
+ }
+ break;
+ }
+ }
+ }
+
+ // vector<OBRing*>::iterator i;
+ // vector<OBRing*> *rlist = (vector<OBRing*>*)mol -> GetData("RingList");
+/*
+ for (i = rlist->begin();i != rlist->end();++i)
+ {
+
+ //// set the center somehow
+
+ if ((*i) -> IsAromatic () && aromatic_display_style == AROMATIC_RING) {
+ bool lines = false;
+ for (unsigned int ra=0; ra < (*i) -> bonds.size (); ra++) {
+ if ((*i) -> bonds[ra] -> displayStyle == LINES) {
+ lines = true;
+ break;
+ }
+ }
+ if (lines) draw_ring_line (*i);
+ }
+ }
+ glEndList ();
+*/
+
+ glEndList ();
+ glNewList(get_stick_list (mol),GL_COMPILE);
+
+
+ FOR_BONDS_OF_MOL (b, mol) {
+ Atom *at1 = b -> GetBeginAtom ();
+ Atom *at2 = b -> GetEndAtom ();
+
+ bool vis = get_visible (&*b);
+ int dsi = get_ds (&*b);
+ if (vis) {
+ switch (dsi) {
+ case STICKS:
+ int order;
+ if (aromatic_display_style == AROMATIC_RINGS && b -> IsAromatic ()) order = 1;
+ else order = b -> GetBondOrder ();
+
+ if (order == 1) draw_bond_stick (&*b);
+ else if (order == 2) draw_double_bond_stick (&*b);
+ else if (order == 3) draw_triple_bond_stick (&*b);
+ // else if (order == 4) draw_aromatic_bond_stick (&*b);
+ // else if (order == 5) {
+ // if (aromatic_display_style != AROMATIC_RINGS) draw_aromatic_bond_stick (&*b);
+ // else draw_bond_stick (&*b);
+ // }
+ break;
+
+ }
+ }
+ }
+
+ FOR_ATOMS_OF_MOL(a, mol) {
+ bool v = get_visible (&*a);
+ int dsi = get_ds (&*a);
+
+
+ if (v) {
+ switch (dsi) {
+ case NO_ATOMS:
+ break;
+ case SPHERES:
+ draw_atom_sphere (&*a);
+ break;
+ case CPK_SPHERES:
+ draw_atom_vdw_sphere (&*a);
+ break;
+ case SCALED_CPK_SPHERES:
+ draw_atom_scaled_vdw_sphere (&*a);
+ break;
+ }
+ }
+
+ }
+
+ /* rlist = (vector<OBRing*>*)mol -> GetData("RingList");
+ for (i = rlist->begin();i != rlist->end();++i)
+ {
+ bool stick = false;
+
+ if ((*i) -> IsAromatic ()) {
+ for (unsigned int ra=0; ra< (*i) -> bonds.size (); ra++) {
+ if ((*i) -> bonds[ra] -> displayStyle==STICKS) {
+ stick = true;
+ break;
+ }
+ }
+ if (stick && aromatic_display_style==AROMATIC_RINGS) draw_ring_stick (*i);
+ }
+ }
+*/
+ glEndList ();
+
+ draw_backbone_list (mol);
+}
+
+
+
+void MyGl::draw_atoms_for_selection (ZNMolecule *mol){ //only works in rendermode select
+ // glNewList(27,GL_COMPILE);
+ int i = 0;
+ FOR_ATOMS_OF_MOL(a, mol) {
+ i = a -> GetIdx ();
+ glLoadName(i);
+ draw_atom_sel_sphere (&*a);
+ }
+ // glEndList ();
+}
+
+
+void MyGl::openGLSetColor (color col) {
+ float r, g, b, a;
+ r= col.redF ();
+ g= col.greenF ();
+ b= col.blueF ();
+ a= col.alphaF ();
+ glColor4f (r, g, b, a);
+}
+
+
+void MyGl::setAtomColor(Atom* atom)
+{
+
+ float r, g, b, a;
+ color col = get_color (atom);
+ bool sel = get_selected (atom);
+ if (sel) {
+ float scr, scg, scb, sca;
+ scr = select_color.redF ();
+ scg = select_color.greenF ();
+ scb = select_color.blueF ();
+ sca = select_color.alphaF () * (0.5 + 0.5*sin ((float) select_pulse*3/40));
+
+ r = scr * sca + col.redF () * ( 1 - sca);
+ g = scg * sca + col.greenF () * ( 1 - sca);
+ b = scb * sca + col.blueF () * ( 1 - sca);
+ a = col.alphaF ();
+ }
+ else {
+ r= col.redF ();
+ g= col.greenF ();
+ b= col.blueF ();
+ a= col.alphaF ();
+ }
+ glColor4f (r, g, b, a);
+
+}
+/*
+void MyGl::update_current_color () {
+}
+*/
+
+
+
+void MyGl::hide_hydrogens (ZNMolecule* mol){
+
+ FOR_ATOMS_OF_MOL(a, mol) {
+ if (a -> IsHydrogen ()) {
+ set_visible (&*a, false);
+ }
+ }
+ draw_molecule (mol);
+}
+
+
+void MyGl::hide_hydrogens (vector <ZNMolecule *> molecules) {
+ for (unsigned int n =0; n<molecules.size (); n++ ) hide_hydrogens (molecules[n]);
+}
+
+void MyGl::hide_nonpolar_hydrogens (ZNMolecule* mol){
+ FOR_ATOMS_OF_MOL(a, mol) {
+ if (a -> IsNonPolarHydrogen ()) {
+ set_visible (&*a, false);
+ }
+ }
+ draw_molecule (mol);
+
+}
+
+
+void MyGl::hide_nonpolar_hydrogens (vector <ZNMolecule *> molecules) {
+ for (unsigned int n =0; n<molecules.size (); n++ ) hide_nonpolar_hydrogens (molecules[n]);
+}
+
+
+void MyGl::show_all_atoms (ZNMolecule* mol){
+ FOR_ATOMS_OF_MOL(a, mol) {
+ set_visible (&*a, true);
+ }
+ draw_molecule (mol);
+}
+
+void MyGl::show_all_atoms (vector <ZNMolecule *> molecules) {
+ for (unsigned int n =0; n<molecules.size (); n++ ) show_all_atoms (molecules[n]);
+}
+
+void MyGl::hide_all_atoms (ZNMolecule* mol){
+ FOR_ATOMS_OF_MOL(a, mol) {
+ set_visible (&*a, false);
+ }
+ draw_molecule (mol);
+}
+
+void MyGl::hide_all_atoms (vector <ZNMolecule *> molecules) {
+ for (unsigned int n =0; n<molecules.size (); n++ ) hide_all_atoms (molecules[n]);
+}
+
+
+void MyGl::apply_color_masks (vector <color_mask> masks, ZNMolecule *mol, bool undoable) {
+ float c_red, c_green, c_blue, c_alpha, ce_red, ce_green, ce_blue, ce_alpha, cb_red, cb_green, cb_blue, cb_alpha, sb_red, sb_green, sb_blue, sb_alpha, sm_red, sm_green, sm_blue, sm_alpha, se_red, se_green, se_blue, se_alpha, mid_width;
+
+ mid_width = 0.1f;
+
+ c_red = ddwin -> data -> constant_color.redF () ;
+ c_green = ddwin -> data -> constant_color.greenF ();
+ c_blue = ddwin -> data -> constant_color.blueF () ;
+ c_alpha = ddwin -> data -> constant_color.alphaF () ;
+
+ cb_red = ddwin -> data -> charge_begin_color.redF () ;
+ cb_green = ddwin -> data -> charge_begin_color.greenF ();
+ cb_blue = ddwin -> data -> charge_begin_color.blueF () ;
+ cb_alpha = ddwin -> data -> charge_begin_color.alphaF () ;
+
+ ce_red = ddwin -> data -> charge_end_color.redF () ;
+ ce_green = ddwin -> data -> charge_end_color.greenF ();
+ ce_blue = ddwin -> data -> charge_end_color.blueF () ;
+ ce_alpha = ddwin -> data -> charge_end_color.alphaF () ;
+
+ sb_red = ddwin -> data -> score_begin_color.redF () ;
+ sb_green = ddwin -> data -> score_begin_color.greenF ();
+ sb_blue = ddwin -> data -> score_begin_color.blueF () ;
+ sb_alpha = ddwin -> data -> score_begin_color.alphaF () ;
+
+
+ sm_red = ddwin -> data -> score_mid_color.redF () ;
+ sm_green = ddwin -> data -> score_mid_color.greenF ();
+ sm_blue = ddwin -> data -> score_mid_color.blueF () ;
+ sm_alpha = ddwin -> data -> score_mid_color.alphaF () ;
+
+ se_red = ddwin -> data -> score_end_color.redF () ;
+ se_green = ddwin -> data -> score_end_color.greenF ();
+ se_blue = ddwin -> data -> score_end_color.blueF () ;
+ se_alpha = ddwin -> data -> score_end_color.alphaF () ;
+
+ ColorAtomCommand *color_atom = new ColorAtomCommand (this);
+
+ FOR_ATOMS_OF_MOL(at, mol) {
+ float newr = 0.f , newg = 0.f , newb = 0.f, newa = 0.f;
+
+ for (unsigned int ms=0; ms < masks.size (); ms++) {
+ if (masks[ms].type == ELEMENT) {
+ float r=0.f, g=0.f, b=0.f, a = 0.f;
+ color col = mol -> get_color_mw (&*at);
+ r = col.redF ();
+ g = col.greenF ();
+ b = col.blueF ();
+ a = col.alphaF ();
+ r *= masks[ms].intensity;
+ g *= masks[ms].intensity;
+ b *= masks[ms].intensity;
+ a *= masks[ms].intensity;
+ assert (!(r > 1.f));
+ assert (!(g > 1.f));
+ assert (!(b > 1.f));
+ assert (!(a > 1.f));
+
+ newr += r;
+ newg += g;
+ newb += b;
+ newa += a;
+ }
+
+ else if (masks[ms].type == CHARGE) {
+ float r, g, b, a;
+ float q = at -> GetPartialCharge ();
+ if (q <= ddwin -> data -> charge_begin) {
+ r = cb_red * masks[ms].intensity;
+ g = cb_green * masks[ms].intensity;
+ b = cb_blue * masks[ms].intensity;
+ a = cb_alpha * masks[ms].intensity;
+ }
+ else if (q >= ddwin -> data -> charge_end) {
+ r = ce_red * masks[ms].intensity;
+ g = ce_green * masks[ms].intensity;
+ b = ce_blue * masks[ms].intensity;
+ a = ce_alpha * masks[ms].intensity;
+ }
+ else {
+ float perc = (ddwin -> data -> charge_end - q) / (ddwin -> data -> charge_end - ddwin -> data -> charge_begin);
+ r = (cb_red * perc + ce_red * (1-perc)) * masks[ms].intensity;
+ g = (cb_green* perc + ce_green * (1-perc)) * masks[ms].intensity;
+ b = (cb_blue * perc + ce_blue * (1-perc)) * masks[ms].intensity;
+ a = (cb_alpha * perc + ce_alpha * (1-perc)) * masks[ms].intensity;
+
+ }
+ assert (!(r > 1.f));
+ assert (!(g > 1.f));
+ assert (!(b > 1.f));
+ assert (!(a > 1.f));
+ newr += r;
+ newg += g;
+ newb += b;
+ newa += a;
+
+ }
+
+ else if (masks[ms].type == SCORE) {
+ float r, g, b, a;
+ float q = get_score (&*at);
+
+
+ color col = average_3_colors (q, ddwin ->data ->score_begin_color, ddwin ->data ->score_mid_color, ddwin ->data ->score_end_color,
+ ddwin ->data ->score_begin, ddwin ->data ->score_mid, ddwin ->data ->score_end) ;
+
+ r = col.redF () * masks[ms].intensity;
+ g = col.greenF () * masks[ms].intensity;
+ b = col.blueF () * masks[ms].intensity;
+ a = col.alphaF () * masks[ms].intensity;
+
+/* if (q <= ddwin -> data -> score_begin) {
+ r = sb_red * masks[ms].intensity;
+ g = sb_green * masks[ms].intensity;
+ b = sb_blue * masks[ms].intensity;
+ a = sb_alpha * masks[ms].intensity;
+ }
+ else if (q >= ddwin -> data -> score_end) {
+ r = se_red * masks[ms].intensity;
+ g = se_green * masks[ms].intensity;
+ b = se_blue * masks[ms].intensity;
+ a = se_alpha * masks[ms].intensity;
+ }
+ else if (q>= ddwin -> data ->score_mid - mid_width && q<= ddwin -> data ->score_mid + mid_width) {
+ r = sm_red * masks[ms].intensity;
+ g = sm_green * masks[ms].intensity;
+ b = sm_blue * masks[ms].intensity;
+ a = sm_alpha * masks[ms].intensity;
+
+ }
+ else if (q<= ddwin -> data -> score_mid) {
+ float perc = (ddwin -> data -> score_mid - q - mid_width) / (ddwin -> data -> score_mid - ddwin -> data -> score_begin - mid_width);
+ r = (sb_red * perc + sm_red * (1-perc)) * masks[ms].intensity;
+ g = (sb_green* perc + sm_green * (1-perc)) * masks[ms].intensity;
+ b = (sb_blue * perc + sm_blue * (1-perc)) * masks[ms].intensity;
+ a = (sb_alpha * perc + sm_alpha * (1-perc)) * masks[ms].intensity;
+
+ }
+ else {
+ float perc = (ddwin -> data -> score_end - q + mid_width) / (ddwin -> data -> score_end +mid_width- ddwin -> data -> score_mid);
+ r = (sm_red * perc + se_red * (1-perc)) * masks[ms].intensity;
+ g = (sm_green* perc + se_green * (1-perc)) * masks[ms].intensity;
+ b = (sm_blue * perc + se_blue * (1-perc)) * masks[ms].intensity;
+ a = (sm_alpha * perc + se_alpha * (1-perc)) * masks[ms].intensity;
+
+ }
+
+ */
+ assert (!(r > 1.f));
+ assert (!(g > 1.f));
+ assert (!(b > 1.f));
+ assert (!(a > 1.f));
+ newr += r;
+ newg += g;
+ newb += b;
+ newa += a;
+
+ }
+
+
+ else if (masks[ms].type == COLOR) {
+ float r = c_red * masks[ms].intensity;
+ float g = c_green * masks[ms].intensity;
+ float b = c_blue * masks[ms].intensity;
+ float a = c_alpha * masks[ms].intensity;
+ assert (!(r > 1.f));
+ assert (!(g > 1.f));
+ assert (!(b > 1.f));
+ newr += r;
+ newg += g;
+ newb += b;
+ newa += a;
+ }
+ }
+
+ color colo (newr, newg, newb, newa);
+ if (undoable) color_atom -> add (&*at, colo);
+
+ else {
+ set_color (&*at, colo);
+ }
+
+ }
+ if (undoable) {
+ color_atom->set_name ();
+ ddwin -> execute (color_atom);
+ }
+ draw_molecule (mol);
+}
+
+
+void MyGl::set_center_of_rotation (vect v) {
+ vect dis = unrotate_vector (subtract (v,center_of_rotation));
+ ChangeVectorCommand *command1 = new ChangeVectorCommand (center_of_rotation, v, this,"Set center of rotation");
+ ChangeVectorCommand *command2 = new ChangeVectorCommand (view_translations, sum (view_translations,dis), this,"Set center of rotation");
+ ddwin -> execute (command1);
+ ddwin -> execute (command2);
+}
+/*
+void MyGl::set_center_of_rotation (float x, float y, float z){
+ vect v (x, y, z);
+ set_center_of_rotation (v);
+}
+*/
+
+void MyGl::set_center_of_view (vect v) {
+ vect dis = subtract (v,center_of_rotation);
+ dis = unrotate_vector (dis);
+ ChangeVectorCommand *command = new ChangeVectorCommand (view_translations, dis, this, "Set center of view");
+ ddwin -> execute (command);
+ //view_translations = vect ();
+
+}
+
+
+
+
+void MyGl::screenshot (QString filename){
+
+ GLint viewport [4];
+ glGetIntegerv (GL_VIEWPORT, viewport);
+ int w = viewport [2]; int h = viewport [3];
+
+ unsigned char* image = new unsigned char[3*w*h];
+
+ FILE* fptr = fopen (filename.toLatin1(), "w" );
+ fprintf(fptr, "P6\n");
+ fprintf(fptr, "%d %d\n", w, h );
+ fprintf(fptr, "255\n" );
+
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ glReadBuffer(GL_BACK);
+ glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,image);
+ for (int j=h-1;j>=0;j--) {
+ for (int i=0;i<w;i++) {
+ fputc(image[3*j*w+3*i+0],fptr);
+ fputc(image[3*j*w+3*i+1],fptr);
+ fputc(image[3*j*w+3*i+2],fptr);
+ }
+ }
+ fclose(fptr);
+ delete[] image;
+
+
+
+
+
+}
+
+
+/////////////////////////////////////////SLOTS///////////////////////////////////////////////////////////////
+
+void MyGl::head_tracking_update (int x, int y) {
+ float scale = 0.1f;
+ float xf = x;
+ float yf = y;
+ xf *= scale;
+ yf *= scale;
+ float dist = 300.f;
+ head_tracking_x_position = xf;
+ head_tracking_y_position = yf;
+ vect new_vec (xf, yf, dist);
+ new_vec.normalise ();
+ Quat4fT Quat;
+ Vector3fT vec1, vec2;
+ vec1.s.X = -new_vec.x ();
+ vec1.s.Y = new_vec.y ();
+ vec1.s.Z = new_vec.z ();
+
+ vec2.s.X = 0.;
+ vec2.s.Y = 0.;
+ vec2.s.Z = 1.;
+ ArcBall.map_vector_on_vector (vec1, vec2, &Quat);
+
+ Matrix3fSetRotationFromQuat4f(&ThisRot, &Quat); // Convert Quaternion Into Matrix3fT
+// Matrix3fMulMatrix3f(&ThisRot, &Last_Head_Tracking_Rot); // Accumulate Last Rotation Into This One
+ Matrix4fSetRotationFromMatrix3f(&Head_Tracking_Transf, &ThisRot);
+
+
+}
+
+void MyGl::move_camera (float x, float y, float z) {
+ vect v (x, y, z);
+ view_translations = sum (view_translations, v);
+
+}
+
+
+void MyGl::move_target (float x, float y, float z) {
+ ZNMolecule *mol = ddwin -> target_molecule;
+ vect v (x, y, z);
+ double rot [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ v = rotate_vector_using_matrix_9 (v, rot);
+ translate_molecule (mol, v);
+ draw_molecule(mol);
+
+}
+
+
+void MyGl::map_vector_on_vector_world (double x1, double y1, double z1, double x2, double y2, double z2) {
+ Quat4fT Quat;
+ Vector3fT vec1, vec2;
+ vec1.s.X = x1;
+ vec1.s.Y = y1;
+ vec1.s.Z = z1;
+
+ vec2.s.X = x2;
+ vec2.s.Y = y2;
+ vec2.s.Z = z2;
+ ArcBall.map_vector_on_vector (vec1, vec2, &Quat);
+
+
+ Matrix3fSetRotationFromQuat4f(&ThisRot, &Quat); // Convert Quaternion Into Matrix3fT
+ Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One
+ Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);
+
+ LastRot = ThisRot;
+
+}
+
+
+
+void MyGl::map_vector_on_vector_target (double x1, double y1, double z1, double x2, double y2, double z2) {
+ quaternion q (1., 0., 0., 0.);
+ vect v1 (x1, y1, z1);
+ vect v2 (x2, y2, z2);
+ double rot [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ v1 = rotate_vector_using_matrix_9 (v1, rot);
+ v2 = rotate_vector_using_matrix_9 (v2, rot);
+
+ q = map_vector_on_vector_quaternion (v1, v2);
+ rotate_molecule (ddwin->target_molecule, q, get_center (ddwin->target_molecule));
+ draw_molecule (ddwin->target_molecule);
+
+}
+
+vect MyGl::apply_world_rotation (vect v) {
+ double rot [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ return rotate_vector_using_matrix_9 (v, rot);
+}
+
+vect MyGl::deapply_world_rotation (vect v) {
+ double rot [9], inv[9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ invert_matrix_9 (rot, inv);
+ return rotate_vector_using_matrix_9 (v, inv);
+}
+
+////////////////////////////////////UTILITIES///////////////////////////////////////////////////////////////
+
+
+void MyGl::haptic_to_world_coordinates (vect &haptic_p, vect &world_p, float minx, float maxx, float miny, float maxy, float minz, float maxz) {
+
+ vect upv, downv, leftv, rightv;
+ get_viewport_points (upv, downv, leftv, rightv);
+ float leftx = leftv.x ();
+ float lefty = leftv.y ();
+ float leftz = leftv.z ();
+
+ float rightx = rightv.x ();
+ float righty = rightv.y ();
+ float rightz = rightv.z ();
+
+ float upx = upv.x ();
+ float upy = upv.y ();
+ float upz = upv.z ();
+
+ float downx = downv.x ();
+ float downy = downv.y ();
+ float downz = downv.z ();
+
+
+ vect up (upx-downx, upy-downy, upz-downz);
+ float modup = up.module ();
+ up.multiply (1.f/modup);
+
+
+ vect right (rightx-leftx, righty-lefty, rightz-leftz);
+ float modright = right.module ();
+ right.multiply (1.f/modright);
+
+
+ float scale = modup;
+ if (modup > modright) scale = modright;
+ vect out;
+ out = cross_product (right, up);
+
+
+ vect central_point;
+
+
+
+ central_point.x() = leftx + (right.x() * modright)/2;
+ central_point.y() = lefty + (right.y() * modright)/2;
+ central_point.z() = leftz + (right.z() * modright)/2;
+
+ float hx = (haptic_p.x()-(minx + maxx)/2) / (maxx - minx);
+ float hy = (haptic_p.y()-(miny + maxy)/2) / (maxy - miny);
+ float hz = (haptic_p.z()-(minz + maxz)/2) / (maxz - minz);
+
+ world_p.x() = central_point.x() + scale * (right.x() * hx + up.x() * hy + out.x() * hz);
+ world_p.y() = central_point.y() + scale * (right.y() * hx + up.y() * hy + out.y() * hz);
+ world_p.z() = central_point.z() + scale * (right.z() * hx + up.z() * hy + out.z() * hz);
+
+}
+
+
+
+
+
+void MyGl::world_to_haptic_coordinates (vect &world_p, vect &haptic_p, float minx, float maxx, float miny, float maxy, float minz, float maxz) {
+
+ double rot [9], inv [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ invert_matrix_9 (rot, inv);
+ world_p = rotate_vector_using_matrix_9 (world_p, inv);
+
+/*
+ vect upv, downv, leftv, rightv;
+ get_viewport_points (upv, downv, leftv, rightv);
+
+ float leftx = leftv.x ();
+ float lefty = leftv.y ();
+ float leftz = leftv.z ();
+
+ float rightx = rightv.x ();
+ float righty = rightv.y ();
+ float rightz = rightv.z ();
+
+ float upx = upv.x ();
+ float upy = upv.y ();
+ float upz = upv.z ();
+
+ float downx = downv.x ();
+ float downy = downv.y ();
+ float downz = downv.z ();
+
+
+ vect up = upv - downv;
+ float modup = up.module ();
+ up.multiply (1.f/modup);
+
+
+ vect right (rightx-leftx, righty-lefty, rightz-leftz);
+ float modright = right.module ();
+ right.multiply (1.f/modright);
+
+
+ float scale = modup;
+ if (modup > modright) scale = modright;
+ vect out;
+ out = cross_product (right, up);
+
+ vect none;
+
+ vect up_world, right_world, out_world;
+
+ components (world_p, up, up_world, none);
+ components (world_p, right, right_world, none);
+ components (world_p, out, out_world, none);
+
+
+
+ haptic_p.x() = right_world.module ();
+ haptic_p.y() = up_world.module ();
+ haptic_p.z() = out_world.module ();
+*/
+
+}
+
+
+
+vect MyGl::rotate_vector (vect v) {
+ double rot [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ return rotate_vector_using_matrix_9 (v, rot);
+
+}
+
+
+vect MyGl::unrotate_vector (vect v) {
+ double rot [9], inv [9];
+ rot [0] = Transform.M [0];
+ rot [1] = Transform.M [1];
+ rot [2] = Transform.M [2];
+ rot [3] = Transform.M [4];
+ rot [4] = Transform.M [5];
+ rot [5] = Transform.M [6];
+ rot [6] = Transform.M [8];
+ rot [7] = Transform.M [9];
+ rot [8] = Transform.M [10];
+ invert_matrix_9 (rot, inv);
+ return rotate_vector_using_matrix_9 (v, inv);
+}
+
+void MyGl::draw_backbone_stick (Resid *res, Surface *surf) {
+ int n_points = *ddwin ->data ->quality_scale * 9;
+ vector <vect> random_points;
+ vector <vect> helix_points;
+ vector <vect> sheet_points;
+ float ha = *ddwin ->data ->backbone_tube_helix_a;
+ float hb = *ddwin ->data ->backbone_tube_helix_b;
+ float hc = *ddwin ->data ->backbone_tube_helix_c;
+ float sa = *ddwin ->data ->backbone_tube_sheet_a;
+ float sb = *ddwin ->data ->backbone_tube_sheet_b;
+ float sc = *ddwin ->data ->backbone_tube_sheet_c;
+ float ra = *ddwin ->data ->backbone_tube_random_a;
+ float rb = *ddwin ->data ->backbone_tube_random_b;
+ float rc = *ddwin ->data ->backbone_tube_random_c;
+
+ for (unsigned int i = 0; i < n_points; i++) {
+ float da = 2*M_PI/(n_points-1);
+ float angl = i * da;
+ random_points.push_back(vect (sin (angl)*rb- (rc*rb *sin (angl)*sin (angl)*sin(angl)), cos (angl)*ra , 0.));
+ helix_points.push_back(vect (sin (angl)*hb- (hc*hb *sin (angl)*sin (angl)*sin(angl)), cos (angl)*ha , 0.));
+ sheet_points.push_back(vect (sin (angl)*sb- (sc*sb *sin (angl)*sin (angl)*sin(angl)), cos (angl)*sa , 0.));
+ }
+ vector <vect> *last_shape, *shape, *next_shape;
+ color last_col, col, next_col;
+ col = get_color (res);
+ last_col = col;
+ next_col = col;
+ last_shape = &random_points;
+ next_shape = &random_points;
+ shape = &random_points;
+
+ if (is_helix (res)) shape = &helix_points;
+ else if (is_sheet (res)) shape = &sheet_points;
+
+ vect dir = get_backbone_direction (res);
+ Resid *prec_res = get_previous_residue(res);
+ Resid *follow_res = get_following_residue(res);
+ vect lastdir, nextdir;
+ if (prec_res) {
+ last_col = get_color (prec_res);
+ lastdir = get_backbone_direction(prec_res);
+ if (is_helix (prec_res)) last_shape = &helix_points;
+ else if (is_sheet (prec_res)) last_shape = &sheet_points;
+ }
+ else lastdir = dir;
+ if (follow_res) {
+ next_col = get_color (follow_res);
+ nextdir = get_backbone_direction(follow_res);
+ if (is_helix (follow_res)) next_shape = &helix_points;
+ else if (is_sheet (follow_res)) next_shape = &sheet_points;
+ }
+ else nextdir = dir;
+ if (dot_product(lastdir, dir) < 0.) lastdir.multiply(-1.);
+ if (dot_product(nextdir, dir) < 0.) nextdir.multiply(-1.);
+
+ lastdir = mean (dir, lastdir);
+ nextdir = mean (nextdir, dir);
+ lastdir.normalise();
+ nextdir.normalise();
+ vector <vect> points = get_backbone_points (res);
+ add_guide_points_to_backbone (&*res, points);
+
+ color c2 = mean (last_col, col);
+ color c1 = mean (next_col, col);
+// if (is_helix (res)) {c1 = c2 = color (1.f, 0.f, 0.f);}
+// else if (is_sheet (res)) {c1 = c2 = color (1.f, 1.f, 0.f);}
+
+
+
+ if (points.size () > 3) {
+ float tot = ((float) points.size () -3);
+
+ for (unsigned int i = 3; i < points.size (); i++) {
+
+ float dt = ((float) i-3) / tot;
+ dt = sin ((dt-0.5f)*M_PI);
+
+ dt*= 0.5f;
+ dt += 0.5f;
+
+ color cc1, cc2;
+ cc1 = color ((float)(c1.redF()*dt+c2.redF()*(1-dt)),((float) c1.greenF()*dt+c2.greenF()*(1-dt)),(float) (c1.blueF()*dt+c2.blueF()*(1-dt)),((float) c1.alphaF()*dt+c2.alphaF()*(1-dt)));
+ vect v1, v2;
+ v2 = lastdir;
+ v1 = nextdir;
+ vector <vect> shape1, shape2;
+ for (unsigned int n = 0; n < n_points; n++) {
+ vect vv2 = mean ((*last_shape)[n], (*shape) [n]);
+ vect vv1 = mean ((*next_shape)[n], (*shape) [n]);
+ shape1.push_back (vect (vv1.x()*dt + vv2.x()*(1-dt), vv1.y()*dt + vv2.y()*(1-dt), vv1.z()*dt + vv2.z()*(1-dt) ) );
+ }
+
+ vect d (v1.x()*dt + v2.x()*(1-dt), v1.y()*dt + v2.y()*(1-dt), v1.z()*dt + v2.z()*(1-dt) );
+
+ dt = ((float) i-2) / tot;
+ dt = sin ((dt-0.5f) * PI);
+ dt*= 0.5f;
+ dt += 0.5f;
+
+ cc2 = color ((float)(c1.redF()*dt+c2.redF()*(1-dt)),((float) c1.greenF()*dt+c2.greenF()*(1-dt)),(float) (c1.blueF()*dt+c2.blueF()*(1-dt)),((float) c1.alphaF()*dt+c2.alphaF()*(1-dt)));
+
+ for (unsigned int n = 0; n < n_points; n++) {
+ vect vv2 = mean ((*last_shape)[n], (*shape) [n]);
+ vect vv1 = mean ((*next_shape)[n], (*shape) [n]);
+ shape2.push_back (vect (vv1.x()*dt + vv2.x()*(1-dt), vv1.y()*dt + vv2.y()*(1-dt), vv1.z()*dt + vv2.z()*(1-dt) ) );
+ }
+ vect d2 (v1.x()*dt + v2.x()*(1-dt), v1.y()*dt + v2.y()*(1-dt), v1.z()*dt + v2.z()*(1-dt) );
+ // cerr << d<<d2<<lastdir<<nextdir<<endl;
+ // d2.normalise ();
+
+ // d = d2 = vect (1., 0., 0.);
+
+ my_backbone_ribbon (points[i-3], points [i-2],points [i-1],points [i], d, d2, cc1, cc2, shape1, shape2, surf);
+
+ }
+
+ }
+
+}
+
+void MyGl::draw_backbone_line (Resid *res) {
+ vector <vect> points = get_backbone_points (res);
+ color last_col, col, next_col;
+ col = get_color (res);
+ last_col = col;
+ next_col = col;
+ Resid *prec_res = get_previous_residue(res);
+ Resid *follow_res = get_following_residue(res);
+ if (prec_res) {
+ last_col = get_color (prec_res);
+ }
+ if (follow_res) {
+ next_col = get_color (follow_res);
+
+ }
+
+
+ color c2 = mean (last_col, col);
+ color c1 = mean (next_col, col);
+
+
+
+ if (points.size () > 1) {
+ for (unsigned int i = 1; i < points.size (); i++) {
+ float dt = ((float) i-1) / points.size ();
+ color cc1 = color ((float)(c1.redF()*dt+c2.redF()*(1-dt)),((float) c1.greenF()*dt+c2.greenF()*(1-dt)),(float) (c1.blueF()*dt+c2.blueF()*(1-dt)),((float) c1.alphaF()*dt+c2.alphaF()*(1-dt)));
+ dt = ((float) i) / points.size ();
+ color cc2 = color ((float)(c1.redF()*dt+c2.redF()*(1-dt)),((float) c1.greenF()*dt+c2.greenF()*(1-dt)),(float) (c1.blueF()*dt+c2.blueF()*(1-dt)),((float) c1.alphaF()*dt+c2.alphaF()*(1-dt)));
+
+ my_line (points[i-1], points [i], cc1, cc2);
+ }
+ }
+
+}
+
+
+void MyGl::my_cylinder (float radone, float radtwo, float lenght,unsigned int slices, Atom* at1, Atom*at2){
+
+ glBegin (GL_QUAD_STRIP);
+ float angle = 0.0;
+ float da = 2*PI/slices;
+
+ for (unsigned int n=0; n<slices+1; n++){
+ angle = n*da;
+ setAtomColor(at1);
+ glNormal3f (sin (angle), cos (angle), 0);
+ glVertex3f (sin (angle)*radone, cos (angle)*radone, 0);
+
+ setAtomColor(at2);
+ glNormal3f (sin (angle), cos (angle), 0);
+ glVertex3f (sin (angle)*radtwo, cos (angle)*radtwo, lenght);
+ }
+ glEnd ();
+}
+
+void MyGl::my_line (vect v1, vect v2, color c1, color c2) {
+ glBegin(GL_LINES);
+ openGLSetColor(c1);
+ glVertex3f (v1.x(), v1.y(), v1.z());
+
+ openGLSetColor(c2);
+ glVertex3f (v2.x(), v2.y(), v2.z());
+ glEnd();
+}
+
+
+void MyGl::my_backbone_ribbon (vect v1, vect v2, vect v3, vect v4, vect dir, vect dir2, color c1, color c2, vector <vect> shape1, vector <vect> shape2, Surface *surf) {
+ //Sandri's method
+ vect prec_vect = subtract (v2, v1);
+ vect cyl_vect = subtract (v3, v2);
+ vect post_vect = subtract (v4, v3);
+ prec_vect.normalise();
+ post_vect.normalise();
+ cyl_vect.normalise();
+ vect norm1 = mean (prec_vect, cyl_vect);
+ vect norm2 = mean (cyl_vect, post_vect);
+
+
+
+ vect par1, pp1, par2, pp2;
+ components (dir, norm1, par1, pp1);
+ components (dir2, norm2, par2, pp2);
+
+ double m1 [9], m2 [9], m [9];
+
+/*
+
+ vect newz = cyl_vect;
+ vect newy = dir;
+
+ vect newx = cross_product(newz, newy);
+ newy = cross_product(newz, newx);
+ newz.normalise();
+ newy.normalise();
+ newx.normalise();
+
+
+
+
+ m[0] = newx.x ();
+ m[3] = newx.y ();
+ m[6] = newx.z ();
+ m[1] = newy.x ();
+ m[4] = newy.y ();
+ m[7] = newy.z ();
+ m[2] = newz.x ();
+ m[5] = newz.y ();
+ m[8] = newz.z ();
+ quaternion q = map_vector_on_vector_quaternion(vect (0., 0., 1.), cyl_vect);
+
+
+*/
+
+
+
+
+
+
+ vect newz1 = norm1;
+ vect newy1 = pp1;
+ newz1.normalise();
+ newy1.normalise();
+ vect newx1 = cross_product(newy1, newz1);
+
+ m1[0] = newx1.x ();
+ m1[3] = newx1.y ();
+ m1[6] = newx1.z ();
+ m1[1] = newy1.x ();
+ m1[4] = newy1.y ();
+ m1[7] = newy1.z ();
+ m1[2] = newz1.x ();
+ m1[5] = newz1.y ();
+ m1[8] = newz1.z ();
+
+
+ vect newz2 = norm2;
+ vect newy2 = pp2;
+ newz2.normalise();
+ newy2.normalise();
+ vect newx2 = cross_product(newy2, newz2);
+
+ m2[0] = newx2.x ();
+ m2[3] = newx2.y ();
+ m2[6] = newx2.z ();
+ m2[1] = newy2.x ();
+ m2[4] = newy2.y ();
+ m2[7] = newy2.z ();
+ m2[2] = newz2.x ();
+ m2[5] = newz2.y ();
+ m2[8] = newz2.z ();
+
+ float angl = 0.f;
+
+ glBegin (GL_QUAD_STRIP);
+ int slices = shape1.size ();
+ vect lastp1, lastp2, lastn1, lastn2;
+ SurfVertex *lastv1, *lastv2;
+
+ for (unsigned int n=0; n<slices; n++){
+
+
+ vect p1 = shape1[n];
+ vect p2 = shape2[n];
+
+ int last_n = n-1;
+ if (last_n < 0) last_n = slices-2;
+ int next_n = n+1;
+ if (next_n >= slices) next_n = 1;
+
+ vect tan1 = subtract(shape1[next_n], shape1[last_n]);
+ vect tan2 = subtract(shape2[next_n], shape2[last_n]);
+ vect n1 = vect (-tan1.y(), tan1.x (), 0);
+ vect n2 = vect (-tan2.y(), tan2.x (), 0);
+
+ p1 = rotate_vector_using_matrix_9(p1, m1);
+ p2 = rotate_vector_using_matrix_9(p2, m2);
+
+ n1 = rotate_vector_using_matrix_9(n1, m1);
+ n2 = rotate_vector_using_matrix_9(n2, m2);
+
+ // p1 = rotate_vector_using_quaternion(p1, q);
+// p2 = rotate_vector_using_quaternion(p2, q);
+
+ // vect n1 = p1;
+ // vect n2 = p2;
+
+ p1 += v2;
+ p2 += v3;
+
+ if (!surf) {
+ openGLSetColor(c1);
+ glNormal3f (n1.x (), n1.y (), n1.z ());
+ glVertex3f (p1.x (), p1.y (), p1.z ());
+
+
+ openGLSetColor(c2);
+ glNormal3f (n2.x (), n2.y (), n2.z ());
+ glVertex3f (p2.x (), p2.y (), p2.z ());
+ }
+
+
+
+
+ else {
+ int num = surf ->vertices.size ();
+ SurfVertex *newv1 = new SurfVertex;
+ newv1->n = num;
+ newv1->normal = n1;
+ newv1->coordinates = p1;
+ newv1 ->col = c1;
+
+ SurfVertex *newv2 = new SurfVertex;
+ newv2->n = num+1;
+ newv2->normal = n2;
+ newv2->coordinates = p2;
+ newv2 ->col = c2;
+ if (n>0) {
+
+ SurfFace *face = new SurfFace;
+ face ->v1 = lastv1;
+ face ->v2 = lastv2;
+ face ->v3 = newv2;
+ SurfFace *face2 = new SurfFace;
+ face2 ->v1 = newv2;
+ face2 ->v2 = newv1;
+ face2 ->v3 = lastv1;
+
+ surf ->faces.push_back (face);
+ surf ->faces.push_back (face2);
+ }
+ lastp1 = p1;
+ lastp2 = p2;
+ lastn1 = n1;
+ lastn2 = n2;
+ lastv1 = newv1;
+ lastv2 = newv2;
+ surf ->vertices.push_back (lastv1);
+ surf ->vertices.push_back (lastv2);
+
+ }
+ }
+ glEnd ();
+
+
+
+
+}
+
+
+
+void MyGl::my_cylinder (vect v1, vect v2, vect v3, vect v4, float radone, float radtwo, color c1, color c2, unsigned int slices) {
+ vect prec_vect = subtract (v2, v1);
+ vect cyl_vect = subtract (v3, v2);
+ vect post_vect = subtract (v4, v3);
+ prec_vect.normalise();
+ post_vect.normalise();
+ cyl_vect.normalise();
+ vect norm1 = mean (prec_vect, cyl_vect);
+ vect norm2 = mean (cyl_vect, post_vect);
+
+
+ glBegin (GL_QUAD_STRIP);
+ float angle = 0.0;
+ float da = 2*PI/slices;
+ quaternion q1 (0., 1., 0., 0.);
+ quaternion q2 (0., 1., 0., 0.);
+ q1 = map_vector_on_vector_quaternion(vect (0., 0., 1.), norm1);
+ q2 = map_vector_on_vector_quaternion(vect (0., 0., 1.), norm2);
+
+
+
+ quaternion spin_quaternion1 (0., 1., 0., 0.);
+ quaternion spin_quaternion2 (0., 1., 0., 0.);
+ vect pp1 = vect (0., radone, 0.);
+ pp1 = rotate_vector_using_quaternion(pp1, q1);
+ vect pp2 = vect (0., radtwo, 0.);
+ pp2 = rotate_vector_using_quaternion(pp2, q2);
+
+ vect ref (3600., 0., 0.);
+ vect origin (0., 0., 0.);
+ double spin_angle1 = dihedral(pp1, origin, norm1, sum (norm1, ref))*M_PI/180.;
+ spin_quaternion1 = axis_angle_to_quaternion(norm1, spin_angle1);
+
+ double spin_angle2 = dihedral(pp2, origin, norm2, sum (norm2, ref))*M_PI/180.;
+ spin_quaternion2 = axis_angle_to_quaternion(norm2, spin_angle2);
+
+
+
+ for (unsigned int n=0; n<slices+1; n++){
+ angle = n*da;
+
+ vect p1 = vect ( sin (angle)*radone, cos (angle)*radone, 0.);
+ vect p2 = vect ( sin (angle)*radtwo, cos (angle)*radtwo, 0.);
+
+
+
+ p1 = rotate_vector_using_quaternion(p1, q1);
+ p2 = rotate_vector_using_quaternion(p2, q2);
+
+
+// p1 = rotate_vector_using_quaternion(p1, spin_quaternion1);
+// p2 = rotate_vector_using_quaternion(p2, spin_quaternion2);
+
+ p1 += v2;
+ p2 += v3;
+
+
+
+ openGLSetColor(c1);
+ vect n1 = subtract (p1,v2);
+ vect n2 = subtract (p2,v3);
+ glNormal3f (n1.x (), n1.y (), n1.z ());
+ glVertex3f (p1.x (), p1.y (), p1.z ());
+
+
+ openGLSetColor(c2);
+ glNormal3f (n2.x (), n2.y (), n2.z ());
+ glVertex3f (p2.x (), p2.y (), p2.z ());
+ }
+ glEnd ();
+ glPopMatrix ();
+
+
+
+
+}
+
+
+void MyGl::my_cylinder (vect v1, vect v2, float radone, float radtwo, color c1, color c2, unsigned int slices) {
+ float angle_dir, height, mod_of_vector;
+ vect at1c = v1;
+ vect at2c = v2;
+
+ vect vector = subtract (at2c, at1c);
+ mod_of_vector = vector.module ();
+
+ vector *= 1/mod_of_vector;
+ height = mod_of_vector;
+
+ angle_dir = acos (vector.z ()) * 180.0 / PI;
+ glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ // setAtomColor(bond->GetBeginAtom ());
+
+
+ glPushMatrix ();
+
+
+
+ glTranslated (at1c.x (), at1c.y(), at1c.z());
+ glRotated (180.0, 0.0, 0.0, 1.0);
+ glRotated (angle_dir, vector.y (), -1.0 * vector.x (), 0.0);
+
+
+ glBegin (GL_QUAD_STRIP);
+ float angle = 0.0;
+ float da = 2*PI/slices;
+
+ for (unsigned int n=0; n<slices+1; n++){
+ angle = n*da;
+ openGLSetColor(c1);
+ glNormal3f (sin (angle), cos (angle), 0);
+ glVertex3f (sin (angle)*radone, cos (angle)*radone, 0);
+
+ openGLSetColor(c2);
+ glNormal3f (sin (angle), cos (angle), 0);
+ glVertex3f (sin (angle)*radtwo, cos (angle)*radtwo, height);
+ }
+ glEnd ();
+ glPopMatrix ();
+
+}
+
+
+
+void MyGl::my_sphere (float rad, unsigned int slices, unsigned int stacks, Atom* at){
+/*
+// setAtomColor(at);
+ float da = 2*PI/slices;
+ float x = 0;
+ float y = 0;
+
+ float x2 = 0;
+ float y2 = 0;
+
+ float vx =0;
+ float vy =0;
+ float vz =0;
+
+ float vx2 =0;
+ float vy2 =0;
+ float vz2 =0;
+
+ float px2 =0;
+ float py2 =0;
+ float pz2 =0;
+
+ float px =0;
+ float py =0;
+ float pz =0;
+
+ float angle;
+ float da2 = PI/stacks;
+ float r = 0.5; float g = 0.5; float b = 0.5; float a = 1.;
+ float dr = 0; float dg = 0; float db = 0;
+
+ vector <float> rr;
+
+ for (unsigned int i=0; i<at->bound.size();i++) {
+ float bx = at->bound[i]-> GetVector ().x()-at-> GetVector ().x();
+ float by = at->bound[i]-> GetVector ().y()-at-> GetVector ().y();
+ float bz = at->bound[i]-> GetVector ().z()-at-> GetVector ().z();
+ rr.push_back (sqrt (bx*bx+by*by+bz*bz));
+
+ }
+
+ for (unsigned int n=0; n<slices; n++){
+
+
+
+ angle = n*da;
+ x = sin (angle);
+ y = cos (angle);
+
+ x2 = sin (angle+da);
+ y2 = cos (angle+da);
+
+ glBegin (GL_QUAD_STRIP);
+ for (unsigned int m=0; m<stacks+1; m++){
+ r = at -> col.redF ();
+ g = at -> col.greenF ();
+ b = at -> col.blueF ();
+ a = at -> col.alphaF ();
+
+ float angle2 = -PI+m*da2;
+
+ vx = x*sin (angle2); vy = y*sin (angle2); vz= cos(angle2);
+ vx2 =x2*sin (angle2); vy2 = y2*sin (angle2); vz2= cos (angle2);
+ px = vx*rad; py = vy*rad; pz = vz*rad;
+ px2 = vx2*rad; py2 = vy2*rad; pz2 = vz2*rad;
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ float bx = at->bound[i]-> GetVector ().x()-at-> GetVector ().x();
+ float by = at->bound[i]-> GetVector ().y()-at-> GetVector ().y();
+ float bz = at->bound[i]-> GetVector ().z()-at-> GetVector ().z();
+ float d=sqrt((bx-px2)*(bx-px2)+(by-py2)*(by-py2)+(bz-pz2)*(bz-pz2));
+ float rd = rr[i];
+ float dc = (rd-d)/rd;
+ if (dc<0) dc=0;
+
+ dr+=(-at-> col.redF ()+at->bound[i]-> col.redF ())*dc;
+ dg+=(-at-> col.greenF ()+at->bound[i]-> col.greenF ())*dc;
+ db+=(-at-> col.blueF ()+at->bound[i]-> col.blueF ())*dc;
+ }
+
+ r+=dr; g+=dg; b+=db;
+
+ glColor4f (r, g, b, a);
+
+ glNormal3f ( vx2, vy2, vz2);
+ glVertex3f (px2, py2, pz2);
+
+ dr=0; dg=0; db=0;
+ r = at -> col.redF ();
+ g = at -> col.greenF ();
+ b = at -> col.blueF ();
+ a = at -> col.alphaF ();
+ for (unsigned int i=0; i<at->bound.size(); i++) {
+ if (at->bound[i]->visible==true) {
+ float bx = at->bound[i]-> GetVector ().x()-at-> GetVector ().x();
+ float by = at->bound[i]-> GetVector ().y()-at-> GetVector ().y();
+ float bz = at->bound[i]-> GetVector ().z()-at-> GetVector ().z();
+ float d=sqrt((bx-px)*(bx-px)+(by-py)*(by-py)+(bz-pz)*(bz-pz));
+ float rd = rr[i];
+ float dc = (rd-d)/rd;
+ if (dc<0) dc=0;
+
+ dr+=(-at-> col.redF ()+at->bound[i]-> col.redF ())*dc;
+ dg+=(-at-> col.greenF ()+at->bound[i]-> col.greenF ())*dc;
+ db+=(-at-> col.blueF ()+at->bound[i]-> col.blueF ())*dc;
+ }
+ }
+
+
+ r+=dr; g+=dg; b+=db;
+
+ glColor4f (r, g, b, a);
+
+ glNormal3f (vx, vy, vz);
+ glVertex3f (px, py, pz);
+
+ }
+
+ glEnd ();
+
+ }
+*/
+}
+
+
+
+
+void MyGl::compute_double_bond_vertexes (ZNBond *bond, float out [4][3], float d) {
+
+ bool b0a = false;
+ bool b0b = false;
+ bool b1a = false;
+ bool b1b = false;
+
+ if (!d) d = *ddwin ->data ->double_bond_separation/2;
+ Atom *at0 = bond -> GetBeginAtom ();
+ Atom *at1 = bond -> GetEndAtom ();
+ vect c0 = get_coordinates(at0);
+ vect c1 = get_coordinates(at1);
+
+ vect v01 = subtract (c1, c0);
+ vect v10 = subtract (c0, c1);
+ vect v0a = c0;
+ vect v0b = c0;
+ vect v1a = c1;
+ vect v1b = c1;
+
+ int cb0 = CountBonds (at0);
+ int cb1 = CountBonds (at1);
+
+ if (0) { //bond -> IsInRing ()) {
+ }
+ else {
+
+ if (cb0 > 3) {
+ }
+ else if (cb0 == 3) {
+ int found = 0;
+ Atom *b0 = NULL;
+ Atom *b1 = NULL;
+ FOR_NBORS_OF_ATOM (n, at0) {
+ if (&*n != at1) {
+ if (found == 0) b0 = &*n;
+ else if (found == 1) b1 = &*n;
+ else break;
+ found++;
+ }
+ }
+ assert (b0);
+ assert (b1);
+ vect veccb0 = get_coordinates (b0);
+ vect veccb1 = get_coordinates (b1);
+
+ v0a = subtract (veccb0, c0); //some form of checking which side of the axis we are is needed to avoid crossing double bonds
+
+ v0b = subtract (veccb1, c0);
+ b0a = true;
+ b0b = true;
+
+ }
+ else if (cb0 == 2) {
+ }
+ else {
+ }
+
+
+ if (cb1 > 3) {
+ }
+ else if (cb1 == 3) {
+ int found = 0;
+ Atom *b0 = NULL;
+ Atom *b1 = NULL;
+ FOR_NBORS_OF_ATOM (n1, at1) {
+ if (&*n1 != at0) {
+ if (found == 0) b0 = &*n1;
+ else if (found == 1) b1 = &*n1;
+ else break;
+ found++;
+ }
+ }
+ assert (b0);
+ assert (b1);
+ vect cb0 = get_coordinates(b0);
+ vect cb1 = get_coordinates (b1);
+
+ v1a = subtract (cb0, c1); //some form of checking which side of the axis we are is needed to avoid crossing double bonds
+ v1b = subtract (cb1, c1);
+ b1a = true;
+ b1b = true;
+
+ }
+ else if (cb1 == 2) {
+ }
+ else {
+ }
+
+
+
+ }
+ vect parallel, normal;
+
+ if ((b0a && b0b) && !(b1a && b1b)) {
+ components (v0a, v01, parallel, normal);
+ v1a = normal;
+ normal.multiply (-1);
+ v1b = normal;
+
+ }
+ else if (!(b0a && b0b) && (b1a && b1b)) {
+ components (v1a, v10, parallel, normal);
+ v0a = normal;
+ normal.multiply (-1.);
+ v0b = normal;
+
+ }
+ else if ((b0a && b0b) && (b1a && b1b)) {}
+
+ else {
+ vect base (1., 1., 1.);
+ components (base, v01, parallel, normal);
+ v0a = normal;
+ v1a = normal;
+ normal.multiply (-1.);
+ v0b = normal;
+ v1b = normal;
+ }
+
+ assert (!isnan (v0a.x()));
+ assert (!isnan (v01.x()));
+
+
+ components (v0a, v01, parallel, normal);
+ assert (normal.module ());
+ assert (!isnan(normal.module ()));
+ v0a.multiply (d/normal.module ());
+
+ components (v0b, v01, parallel, normal);
+ v0b.multiply (d/normal.module ());
+
+ components (v1a, v10, parallel, normal);
+ v1a.multiply (d/normal.module ());
+
+ components (v1b, v10, parallel, normal);
+ v1b.multiply (d/normal.module ());
+
+ assert (!isnan (v0a.x ()));
+
+ float dist1 = dist (v0a, v1a);
+ float dist2 = dist (v0a, v1b);
+ if (dist2 < dist1) {
+ vect swap = v1a;
+ v1a = v1b;
+ v1b = swap;
+ }
+
+
+ vect o0, o1, o2, o3;
+ o0 = sum (c0, v0a);
+ o1 = sum (c0, v0b);
+ o2 = sum (c1, v1a);
+ o3 = sum (c1, v1b);
+
+ assert (!isnan (o0.x ()));
+ out[0][0] = o0.x();
+ out[0][1] = o0.y();
+ out[0][2] = o0.z();
+
+ out[1][0] = o1.x();
+ out[1][1] = o1.y();
+ out[1][2] = o1.z();
+
+
+ out[2][0] = o2.x();
+ out[2][1] = o2.y();
+ out[2][2] = o2.z();
+
+ out[3][0] = o3.x();
+ out[3][1] = o3.y();
+ out[3][2] = o3.z();
+
+
+
+/*
+ float c01 [3];
+ float c02 [3];
+ float c11 [3];
+ float c12 [3];
+ c01[0]=0.; c01[1]=0.; c01[2]=0.;
+ c02[0]=0.; c02[1]=0.; c02[2]=0.;
+ c11[0]=0.; c11[1]=0.; c11[2]=0.;
+ c12[0]=0.; c12[1]=0.; c12[2]=0.;
+ float swapx, swapy, swapz;
+ bool found0 = false;
+ bool found1 = false;
+
+
+ if (at0 -> bound.size ()>2) {
+ unsigned int oldn = 0;
+ for (unsigned int n = 0; n<at0->bound.size(); n++) {
+ if (at0->bound[n]->ID!= at1->ID) {
+ c01[0] = at0->bound[n]-> GetVector ().x();
+ c01[1] = at0->bound[n]-> GetVector ().y();
+ c01[2] = at0->bound[n]-> GetVector ().z();
+ oldn = n;
+ break;
+ }
+ }
+ for (unsigned int n1 = oldn+1; n1<at0->bound.size(); n1++) {
+ if (at0->bound[n1]->ID!= at1->ID) {
+ c02[0] = at0->bound[n1]-> GetVector ().x();
+ c02[1] = at0->bound[n1]-> GetVector ().y();
+ c02[2] = at0->bound[n1]-> GetVector ().z();
+ break;
+ }
+ }
+ found0 = true;
+ }
+
+ if (at1->bound.size ()>2) {
+ unsigned int oldn = 0;
+ for (unsigned int n = 0; n<at1->bound.size(); n++) {
+ if (at1->bound[n]->ID!= at0->ID) {
+ c11[0] = at1->bound[n]-> GetVector ().x();
+ c11[1] = at1->bound[n]-> GetVector ().y();
+ c11[2] = at1->bound[n]-> GetVector ().z();
+ oldn = n;
+ break;
+ }
+ }
+ for (unsigned int n1=oldn+1; n1<at1->bound.size(); n1++) {
+ if (at1->bound[n1]->ID!= at0->ID) {
+ c12[0] = at1->bound[n1]-> GetVector ().x();
+ c12[1] = at1->bound[n1]-> GetVector ().y();
+ c12[2] = at1->bound[n1]-> GetVector ().z();
+ break;
+ }
+ }
+ found1 = true;
+ }
+
+ float refx, refy, refz;
+
+ vect vec, ref, nor, par;
+
+
+
+ ref = subtract (at1 -> GetVector (), at0 -> GetVector ());
+ ref.multiply (-1);
+
+ if (!found0 && found1) {
+ vec.null (); nor.null (); par.null ();
+ // cout <<"not found 0"<<endl;
+ vec = vect (c11[0]-at1-> GetVector ().x(), c11[1]-at1-> GetVector ().y(),c11[2]-at1-> GetVector ().z());
+ components (vec, ref, par, nor);
+ c01[0]=at0-> GetVector ().x()+nor.x();
+ c01[1]=at0-> GetVector ().y()+nor.y();
+ c01[2]=at0-> GetVector ().z()+nor.z();
+ c02[0]=at0-> GetVector ().x()-nor.x();
+ c02[1]=at0-> GetVector ().y()-nor.y();
+ c02[2]=at0-> GetVector ().z()-nor.z();
+ }
+ // ref[0]*=-1; ref[1]*=-1; ref[2]*=-1;
+ if (found0 && !found1) {
+ vec.null (); nor.null (); par.null ();
+ // cout <<"not found 1"<<endl;
+ vec = vect (c01[0]-at0-> GetVector ().x(), c01[1]-at0-> GetVector ().y(), c01[2]-at0-> GetVector ().z() );
+ components (vec, ref, par, nor);
+ c11[0]=at1-> GetVector ().x()+nor.x();
+ c11[1]=at1-> GetVector ().y()+nor.y();
+ c11[2]=at1-> GetVector ().z()+nor.z();
+ c12[0]=at1-> GetVector ().x()-nor.x();
+ c12[1]=at1-> GetVector ().y()-nor.y();
+ c12[2]=at1-> GetVector ().z()-nor.z();
+ }
+
+
+
+
+ if ( (c11[0]-c01[0])*(c11[0]-c01[0]) + (c11[1]-c01[1])*(c11[1]-c01[1]) + (c11[2]-c01[2])*(c11[2]-c01[2]) >
+(c12[0]-c01[0])*(c12[0]-c01[0]) + (c12[1]-c01[1])*(c12[1]-c01[1]) + (c12[2]-c01[2])*(c12[2]-c01[2])) {
+ swapx = c01[0]; swapy = c01[1]; swapz = c01[2];
+ c01[0] = c02[0]; c01[1] = c02[1]; c01[2] = c02[2];
+ c02[0] = swapx; c02[1] = swapy; c02[2] = swapz;
+ }
+
+
+ //float v01x, v01y, v01z, v02x, v02y, v02z, v11x, v11y, v11z, v12x, v12y, v12z,
+
+
+
+
+
+ out[0][0] = c01[0]-at0-> GetVector ().x();
+ out[0][1] = c01[1]-at0-> GetVector ().y();
+ out[0][2] = c01[2]-at0-> GetVector ().z();
+
+ out[1][0] = c02[0]-at0-> GetVector ().x();
+ out[1][1] = c02[1]-at0-> GetVector ().y();
+ out[1][2] = c02[2]-at0-> GetVector ().z();
+
+ out[2][0] = c11[0]-at1-> GetVector ().x();
+ out[2][1] = c11[1]-at1-> GetVector ().y();
+ out[2][2] = c11[2]-at1-> GetVector ().z();
+
+ out[3][0] = c12[0]-at1-> GetVector ().x();
+ out[3][1] = c12[1]-at1-> GetVector ().y();
+ out[3][2] = c12[2]-at1-> GetVector ().z();
+
+
+ vec.null (); nor.null (); par.null ();
+
+ vec = vect (out[0][0],out[0][1], out[0][2]);
+// cout << "case 1"<<endl;
+ components (vec, ref, par, nor);
+ float module = nor.module ();
+ out[0][0] *= d / module;
+ out[0][1] *= d / module;
+ out[0][2] *= d / module;
+
+ vec.null (); nor.null ();
+
+ vec = vect (out[1][0], out[1][1] ,out[1][2]);
+ // cout << "case 2"<<endl;
+ components (vec, ref, par, nor);
+ module = nor.module ();
+ out[1][0] *= d / module;
+ out[1][1] *= d / module;
+ out[1][2] *= d / module;
+
+
+ vec = vect (out[2][0], out[2][1] ,out[2][2]);
+
+// cout << "case 3"<<endl;
+ components (vec, ref, par, nor);
+ module = nor.module ();
+ out[2][0] *= d / module;
+ out[2][1] *= d / module;
+ out[2][2] *= d / module;
+
+ vec = vect (out[3][0], out[3][1] ,out[3][2]);
+// cout << "case 4"<<endl;
+ components (vec, ref, par, nor);
+ module = nor.module ();
+ out[3][0] *= d / module;
+ out[3][1] *= d / module;
+ out[3][2] *= d / module;
+
+
+ out[0][0] += at0-> GetVector ().x();
+ out[0][1] += at0-> GetVector ().y();
+ out[0][2] += at0-> GetVector ().z();
+
+ out[1][0] += at0-> GetVector ().x();
+ out[1][1] += at0-> GetVector ().y();
+ out[1][2] += at0-> GetVector ().z();
+
+
+ out[2][0] += at1-> GetVector ().x();
+ out[2][1] += at1-> GetVector ().y();
+ out[2][2] += at1-> GetVector ().z();
+
+ out[3][0] += at1-> GetVector ().x();
+ out[3][1] += at1-> GetVector ().y();
+ out[3][2] += at1-> GetVector ().z();
+
+*/
+
+
+
+}
+
+
+
+
+
+
+
+
+void set_color (color c) {
+ glColor4f (c.redF (), c.greenF (), c.blueF (), c.alphaF ());
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/debian/README.Debian b/debian/README.Debian
deleted file mode 100644
index 3a56438..0000000
--- a/debian/README.Debian
+++ /dev/null
@@ -1,17 +0,0 @@
-zodiac-zeden for Debian
------------------
-
-Zodiac is a molecular modelling suite for computation, analysis and display of molecular data. It features state-of-the-art tools for managing molecular databases, run molecular docking experiments, compute raytraced images and much more.
-
-
-Zodiac is OPEN SOURCE : Zodiac's code is licensed under the GPL.
-
-Zodiac is CROSS PLATFORM: Current supported OS include Windows, Linux and MacOsX.
-
-Zodiac is MULTILINGUAL: Zodiac is built upon the openbabel library, that grants the ability to read and write over 80 chemical formats.
-
-Zodiac is INTUITIVE: Built with QT4, uses interactive menus and drag and drop.
-
-Zodiac is FAST: Supports muti-threading to exploit multiprocessors machines or cluster
-
- -- Alex Mestiashvili <alex at biotec.tu-dresden.de> Tue, 15 Feb 2011 09:56:24 +0000
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 95d1ca7..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-zodiac-zeden (0.6.5-1) UNRELEASED; urgency=low
-
- * Initial release (Closes: #613528)
-
- -- Alex Mestiashvili <alex at biotec.tu-dresden.de> Tue, 15 Feb 2011 09:56:24 +0000
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index f599e28..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 7fb91ea..0000000
--- a/debian/control
+++ /dev/null
@@ -1,24 +0,0 @@
-Source: zodiac-zeden
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Alex Mestiashvili <alex at biotec.tu-dresden.de>
-Section: science
-Priority: optional
-Build-Depends: debhelper (>= 10),
- qt4-qmake,
- libqt4-dev,
- libqt4-opengl-dev,
- libopenbabel-dev
-Standards-Version: 3.9.8
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/zodiac-zeden/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/zodiac-zeden/trunk/
-Homepage: https://sourceforge.net/projects/zodiac-zeden/
-
-Package: zodiac-zeden
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends}
-Description: ZODIAC - Zeden's Organise DIsplay And Compute
- Zodiac is a molecular modelling suite for computation, analysis and display of
- molecular data. It features state-of-the-art tools for managing molecular
- databases, run molecular docking experiments, compute raytraced images
- and much more.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 8a765f1..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,32 +0,0 @@
-Format: http://dep.debian.net/deps/dep5
-Upstream-Name: zodiac-zeden
-Source: http://sourceforge.net/projects/zodiac-zeden/files/zodiac/0.6.5/
-
-Files: *
-Copyright: 2008 Nicola Zonta ,<nicola.zonta at zeden.org>
-License: GPL-3.0+
-
-Files: ply.c
-Copyright: 1998 Georgia Institute of Technology.
-License: GPL-2.0+
-
-Files: debian/*
-Copyright: 2011 Alex Mestiashvili <alex at biotec.tu-dresden.de>
-License: GPL-2.0+
-
-License: GPL-2.0+
- This package is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- .
- This package is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- .
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>
- .
- On Debian systems, the complete text of the GNU General
- Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 9c144d7..0000000
--- a/debian/docs
+++ /dev/null
@@ -1 +0,0 @@
-INSTALL.txt
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 9d031bf..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# debian/rules for zodiac-zeden
-
-# Uncomment this to turn on verbose mode.
-export DH_VERBOSE=1
-
-# This has to be exported to make some magic below work.
-export DH_OPTIONS
-
-%:
- dh $@
-
-override_dh_auto_configure:
- qmake-qt4 Zodiac.pro
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index aaf7625..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,6 +0,0 @@
-version=3
-
-opts="uversionmangle=s/\_/./g" \
-http://sf.net/zodiac-zeden/zodiac_(.*)_src\.zip
-
-
diff --git a/debian/zodiac-zeden-docs.docs b/debian/zodiac-zeden-docs.docs
deleted file mode 100644
index d4f4542..0000000
--- a/debian/zodiac-zeden-docs.docs
+++ /dev/null
@@ -1 +0,0 @@
-#DOCS#
diff --git a/debian/zodiac-zeden-docs.install b/debian/zodiac-zeden-docs.install
deleted file mode 100644
index d4f4542..0000000
--- a/debian/zodiac-zeden-docs.install
+++ /dev/null
@@ -1 +0,0 @@
-#DOCS#
diff --git a/debian/zodiac-zeden.install b/debian/zodiac-zeden.install
deleted file mode 100644
index 29172f1..0000000
--- a/debian/zodiac-zeden.install
+++ /dev/null
@@ -1 +0,0 @@
-Zodiac usr/bin/
diff --git a/forcefields/CVS/Entries b/forcefields/CVS/Entries
new file mode 100644
index 0000000..3bebf22
--- /dev/null
+++ b/forcefields/CVS/Entries
@@ -0,0 +1,14 @@
+/Makefile/1.1/Mon Sep 29 10:27:15 2008//
+/Makefile.am/1.1/Mon Sep 29 10:27:16 2008//
+/Makefile.in/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldghemical.cpp/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldghemical.h/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldghemical.lo/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldmmff94.cpp/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldmmff94.h/1.1/Mon Sep 29 10:27:17 2008//
+/forcefieldmmff94.lo/1.1/Mon Sep 29 10:27:18 2008//
+/forcefielduff.cpp/1.1/Mon Sep 29 10:27:18 2008//
+/forcefielduff.h/1.1/Mon Sep 29 10:27:18 2008//
+/forcefielduff.lo/1.1/Mon Sep 29 10:27:18 2008//
+/libforcefields.la/1.1/Mon Sep 29 10:27:18 2008//
+D
diff --git a/forcefields/CVS/Entries.Extra b/forcefields/CVS/Entries.Extra
new file mode 100644
index 0000000..306b177
--- /dev/null
+++ b/forcefields/CVS/Entries.Extra
@@ -0,0 +1,13 @@
+/Makefile////*///
+/Makefile.am////*///
+/Makefile.in////*///
+/forcefieldghemical.cpp////*///
+/forcefieldghemical.h////*///
+/forcefieldghemical.lo////*///
+/forcefieldmmff94.cpp////*///
+/forcefieldmmff94.h////*///
+/forcefieldmmff94.lo////*///
+/forcefielduff.cpp////*///
+/forcefielduff.h////*///
+/forcefielduff.lo////*///
+/libforcefields.la////*///
diff --git a/forcefields/CVS/Entries.Extra.Old b/forcefields/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/forcefields/CVS/Entries.Old b/forcefields/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/forcefields/CVS/Repository b/forcefields/CVS/Repository
new file mode 100644
index 0000000..d9e1e29
--- /dev/null
+++ b/forcefields/CVS/Repository
@@ -0,0 +1 @@
+zodiac/forcefields
diff --git a/forcefields/CVS/Root b/forcefields/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/forcefields/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/forcefields/Makefile b/forcefields/Makefile
new file mode 100644
index 0000000..5f88bd1
--- /dev/null
+++ b/forcefields/Makefile
@@ -0,0 +1,472 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# src/forcefields/Makefile. Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+pkgdatadir = $(datadir)/openbabel
+pkgincludedir = $(includedir)/openbabel
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = i386-apple-darwin9.0.0
+host_triplet = i386-apple-darwin9.0.0
+subdir = src/forcefields
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/autoconf/libtool.m4 \
+ $(top_srcdir)/autoconf/ltoptions.m4 \
+ $(top_srcdir)/autoconf/ltsugar.m4 \
+ $(top_srcdir)/autoconf/ltversion.m4 \
+ $(top_srcdir)/autoconf/lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libforcefields_la_LIBADD =
+am_libforcefields_la_OBJECTS = forcefieldghemical.lo \
+ forcefieldmmff94.lo forcefielduff.lo
+libforcefields_la_OBJECTS = $(am_libforcefields_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libforcefields_la_SOURCES)
+DIST_SOURCES = $(libforcefields_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibdir = $(libdir)/$(PACKAGE)
+ACLOCAL = ${SHELL} /Users/nicola/Desktop/openbabel-2.2.0/missing --run aclocal-1.10
+AMTAR = ${SHELL} /Users/nicola/Desktop/openbabel-2.2.0/missing --run tar
+AR = ar
+AS = as
+AUTOCONF = sleep 9 ; true || autoconf || skipped
+AUTOHEADER = sleep 9 ; true || autoheader || skipped
+AUTOMAKE = sleep 9 ; true || automake || skipped
+AWK = awk
+BOOST_CPPFLAGS = -I/include/boost-0
+BOOST_LDFLAGS = -L/lib
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS =
+CXX = g++
+CXXCPP = g++ -E
+CXXDEPMODE = depmode=gcc3
+CXXFLAGS = -g -O2
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DLLTOOL = dlltool
+DOXYGEN =
+DSYMUTIL = dsymutil
+DUMPBIN =
+ECHO_C = \c
+ECHO_N =
+ECHO_T =
+EGREP = /usr/bin/grep -E
+EXEEXT =
+FGREP = /usr/bin/grep -F
+GREP = /usr/bin/grep
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = /usr/libexec/gcc/i686-apple-darwin9/4.0.1/ld
+LDFLAGS =
+LIBDL =
+LIBOBJS =
+LIBS = -lz -lm
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO = lipo
+LN_S = ln -s
+LTLIBOBJS =
+MAINT = #
+MAKEINFO = ${SHELL} /Users/nicola/Desktop/openbabel-2.2.0/missing --run makeinfo
+MKDIR_P = ../.././install-sh -c -d
+NM = /usr/bin/nm -p
+NMEDIT = nmedit
+OBJDUMP = objdump
+OBJEXT = o
+OTOOL = otool
+OTOOL64 = :
+PACKAGE = openbabel
+PACKAGE_BUGREPORT = openbabel-discuss at lists.sourceforge.net
+PACKAGE_NAME = Open Babel
+PACKAGE_STRING = Open Babel 2.2.0
+PACKAGE_TARNAME = openbabel
+PACKAGE_VERSION = 2.2.0
+PATH_SEPARATOR = :
+PERL = /usr/bin/perl
+PROVE = /usr/bin/prove
+PYTHON = /usr/bin/python
+RANLIB = ranlib
+RUBY = /usr/bin/ruby
+SED = /usr/bin/sed
+SET_MAKE =
+SHELL = /bin/sh
+STRIP = strip
+SWIG = /usr/bin/swig
+VERSION = 2.2.0
+WXCONFIG = /usr/bin/wx-config
+WX_CPPFLAGS =
+WX_CXXFLAGS =
+WX_LIBS =
+XML2_CONFIG = /usr/bin/xml2-config
+XML_CPPFLAGS = -I/usr/include/libxml2
+XML_LIBS = -L/usr/lib -lxml2 -lz -lpthread -licucore -lm
+abs_builddir = /Users/nicola/Desktop/openbabel-2.2.0/src/forcefields
+abs_srcdir = /Users/nicola/Desktop/openbabel-2.2.0/src/forcefields
+abs_top_builddir = /Users/nicola/Desktop/openbabel-2.2.0
+abs_top_srcdir = /Users/nicola/Desktop/openbabel-2.2.0
+ac_ct_CC = gcc
+ac_ct_CXX = g++
+ac_ct_DUMPBIN =
+am__include = include
+am__leading_dot = .
+am__quote =
+am__tar = ${AMTAR} chof - "$$tardir"
+am__untar = ${AMTAR} xf -
+bindir = ${exec_prefix}/bin
+build = i386-apple-darwin9.0.0
+build_alias =
+build_cpu = i386
+build_os = darwin9.0.0
+build_vendor = apple
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = i386-apple-darwin9.0.0
+host_alias =
+host_cpu = i386
+host_os = darwin9.0.0
+host_vendor = apple
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = $(SHELL) /Users/nicola/Desktop/openbabel-2.2.0/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+lt_ECHO = /bin/echo
+mandir = ${datarootdir}/man
+mkdir_p = $(top_builddir)/./install-sh -c -d
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /usr/local
+program_transform_name = s,x,x,
+psdir = ${docdir}
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias =
+top_build_prefix = ../../
+top_builddir = ../..
+top_srcdir = ../..
+noinst_LTLIBRARIES = libforcefields.la
+libforcefields_la_SOURCES = forcefieldghemical.cpp \
+ forcefieldmmff94.cpp forcefielduff.cpp
+
+AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+EXTRA_DIST = forcefieldghemical.h forcefieldmmff94.h \
+ forcefielduff.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/forcefields/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/forcefields/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: # $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): # $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libforcefields.la: $(libforcefields_la_OBJECTS) $(libforcefields_la_DEPENDENCIES)
+ $(CXXLINK) $(libforcefields_la_OBJECTS) $(libforcefields_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+include ./$(DEPDIR)/forcefieldghemical.Plo
+include ./$(DEPDIR)/forcefieldmmff94.Plo
+include ./$(DEPDIR)/forcefielduff.Plo
+
+.cpp.o:
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+# source='$<' object='$@' libtool=no \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+# source='$<' object='$@' libtool=yes \
+# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+# $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/forcefields/Makefile.am b/forcefields/Makefile.am
new file mode 100644
index 0000000..9590963
--- /dev/null
+++ b/forcefields/Makefile.am
@@ -0,0 +1,8 @@
+noinst_LTLIBRARIES = libforcefields.la
+libforcefields_la_SOURCES = forcefieldghemical.cpp \
+ forcefieldmmff94.cpp forcefielduff.cpp
+
+AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+
+EXTRA_DIST = forcefieldghemical.h forcefieldmmff94.h \
+ forcefielduff.h
diff --git a/forcefields/Makefile.in b/forcefields/Makefile.in
new file mode 100644
index 0000000..2799c56
--- /dev/null
+++ b/forcefields/Makefile.in
@@ -0,0 +1,472 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/forcefields
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/autoconf/libtool.m4 \
+ $(top_srcdir)/autoconf/ltoptions.m4 \
+ $(top_srcdir)/autoconf/ltsugar.m4 \
+ $(top_srcdir)/autoconf/ltversion.m4 \
+ $(top_srcdir)/autoconf/lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libforcefields_la_LIBADD =
+am_libforcefields_la_OBJECTS = forcefieldghemical.lo \
+ forcefieldmmff94.lo forcefielduff.lo
+libforcefields_la_OBJECTS = $(am_libforcefields_la_OBJECTS)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libforcefields_la_SOURCES)
+DIST_SOURCES = $(libforcefields_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibdir = @pkglibdir@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
+BOOST_LDFLAGS = @BOOST_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PROVE = @PROVE@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SWIG = @SWIG@
+VERSION = @VERSION@
+WXCONFIG = @WXCONFIG@
+WX_CPPFLAGS = @WX_CPPFLAGS@
+WX_CXXFLAGS = @WX_CXXFLAGS@
+WX_LIBS = @WX_LIBS@
+XML2_CONFIG = @XML2_CONFIG@
+XML_CPPFLAGS = @XML_CPPFLAGS@
+XML_LIBS = @XML_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libforcefields.la
+libforcefields_la_SOURCES = forcefieldghemical.cpp \
+ forcefieldmmff94.cpp forcefielduff.cpp
+
+AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+EXTRA_DIST = forcefieldghemical.h forcefieldmmff94.h \
+ forcefielduff.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/forcefields/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/forcefields/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libforcefields.la: $(libforcefields_la_OBJECTS) $(libforcefields_la_DEPENDENCIES)
+ $(CXXLINK) $(libforcefields_la_OBJECTS) $(libforcefields_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forcefieldghemical.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forcefieldmmff94.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forcefielduff.Plo at am__quote@
+
+.cpp.o:
+ at am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ at am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+ at am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/forcefields/forcefieldghemical.cpp b/forcefields/forcefieldghemical.cpp
new file mode 100644
index 0000000..db73d0e
--- /dev/null
+++ b/forcefields/forcefieldghemical.cpp
@@ -0,0 +1,1259 @@
+/**********************************************************************
+forcefieldghemical.cpp - Ghemical force field.
+
+Copyright (C) 2006-2007 by Tim Vandermeersch <tim.vandermeersch at gmail.com>
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+#include <openbabel/babelconfig.h>
+#include <openbabel/mol.h>
+#include <openbabel/locale.h>
+
+#include "forcefieldghemical.h"
+
+using namespace std;
+
+namespace OpenBabel
+{
+ template<bool gradients>
+ void OBFFBondCalculationGhemical::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ double delta2;
+
+ if (gradients) {
+ rab = OBForceField::VectorBondDerivative(pos_a, pos_b, force_a, force_b);
+ delta = rab - r0;
+ delta2 = delta * delta;
+
+ const double dE = 2.0 * kb * delta;
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ delta = rab - r0;
+ delta2 = delta * delta;
+ }
+
+ energy = kb * delta2;
+ }
+
+ template<bool gradients>
+ double OBForceFieldGhemical::E_Bond()
+ {
+ vector<OBFFBondCalculationGhemical>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nB O N D S T R E T C H I N G\n\n");
+ OBFFLog("ATOM TYPES BOND BOND IDEAL FORCE\n");
+ OBFFLog(" I J TYPE LENGTH LENGTH CONSTANT DELTA ENERGY\n");
+ OBFFLog("------------------------------------------------------------------------\n");
+ }
+
+ for (i = _bondcalculations.begin(); i != _bondcalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%s %s %d %8.3f %8.3f %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).bt, (*i).rab, (*i).r0, (*i).kb, (*i).delta, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL BOND STRETCHING ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFAngleCalculationGhemical::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c)) {
+ energy = 0.0;
+ return;
+ }
+
+ double delta2;
+
+ if (gradients) {
+ theta = OBForceField::VectorAngleDerivative(pos_a, pos_b, pos_c, force_a, force_b, force_c);
+ delta = theta - theta0;
+
+ const double dE = RAD_TO_DEG * 2.0 * ka * delta;
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ OBForceField::VectorSelfMultiply(force_c, dE);
+ } else {
+ theta = OBForceField::VectorAngle(pos_a, pos_b, pos_c);
+ delta = theta - theta0;
+ }
+
+ if (!isfinite(theta))
+ theta = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ delta2 = delta * delta;
+
+ energy = ka * delta2;
+ }
+
+ template<bool gradients>
+ double OBForceFieldGhemical::E_Angle()
+ {
+ vector<OBFFAngleCalculationGhemical>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nA N G L E B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES VALENCE IDEAL FORCE\n");
+ OBFFLog(" I J K ANGLE ANGLE CONSTANT DELTA ENERGY\n");
+ OBFFLog("-----------------------------------------------------------------------------\n");
+ }
+
+ for (i = _anglecalculations.begin(); i != _anglecalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ AddGradient((*i).force_c, (*i).idx_c);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%s %s %s %8.3f %8.3f %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).c->GetType(), (*i).theta, (*i).theta0, (*i).ka, (*i).delta, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ANGLE BENDING ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFTorsionCalculationGhemical::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c, idx_d)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ tor = DEG_TO_RAD * OBForceField::VectorTorsionDerivative(pos_a, pos_b, pos_c, pos_d,
+ force_a, force_b, force_c, force_d);
+ if (!isfinite(tor))
+ tor = 1.0e-3;
+
+ const double sine = sin(tor);
+ const double sine2 = sin(2.0 * tor);
+ const double sine3 = sin(3.0 * tor);
+ const double dE = k1 * sine - k2 * 2.0 * sine2 + k3 * 3.0 * sine3;
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ OBForceField::VectorSelfMultiply(force_c, dE);
+ OBForceField::VectorSelfMultiply(force_d, dE);
+ } else {
+ tor = DEG_TO_RAD * OBForceField::VectorTorsion(pos_a, pos_b, pos_c, pos_d);
+ if (!isfinite(tor)) // stop any NaN or infinity
+ tor = 1.0e-3; // rather than NaN
+ }
+
+ const double cosine = cos(tor);
+ const double cosine2 = cos(2.0 * tor);
+ const double cosine3 = cos(3.0 * tor);
+
+ const double phi1 = 1.0 + cosine;
+ const double phi2 = 1.0 - cosine2;
+ const double phi3 = 1.0 + cosine3;
+
+ energy = k1 * phi1 + k2 * phi2 + k3 * phi3;
+
+ }
+
+ template<bool gradients>
+ double OBForceFieldGhemical::E_Torsion()
+ {
+ vector<OBFFTorsionCalculationGhemical>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nT O R S I O N A L\n\n");
+ OBFFLog("----ATOM TYPES----- FORCE TORSION\n");
+ OBFFLog(" I J K L CONSTANT s ANGLE n ENERGY\n");
+ OBFFLog("----------------------------------------------------------------\n");
+ }
+
+ for (i = _torsioncalculations.begin(); i != _torsioncalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ AddGradient((*i).force_c, (*i).idx_c);
+ AddGradient((*i).force_d, (*i).idx_d);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%s %s %s %s %6.3f %5.0f %8.3f %1.0f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).c->GetType(), (*i).d->GetType(), (*i).V, (*i).s, (*i).tor, (*i).n, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL TORSIONAL ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFVDWCalculationGhemical::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ rab = OBForceField::VectorDistanceDerivative(pos_a, pos_b, force_a, force_b);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ }
+
+ const double term = rab / ka;
+
+ double term6 = term * term * term; // ^3
+ term6 = term6 * term6; // ^6
+ const double term12 = term6 * term6; // ^12
+
+ energy = (1.0 / term12) - (1.0 / term6);
+
+ if (gradients) {
+ const double term13 = term * term12; // ^13
+ const double term7 = term * term6; // ^7
+ const double dE = - (12.0 / ka) * (1.0 / term13) + (6.0 / ka) * (1.0 / term7);
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldGhemical::E_VDW()
+ {
+ vector<OBFFVDWCalculationGhemical>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nV A N D E R W A A L S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij kij ENERGY\n");
+ OBFFLog("-----------------------------------------\n");
+ // XX XX -000.000 -000.000 -000.000 -000.000
+ }
+
+ unsigned int j = 0;
+ for (i = _vdwcalculations.begin(); i != _vdwcalculations.end(); ++i, ++j) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_vdwpairs.BitIsSet(j))
+ continue;
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%s %s %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).rab, (*i).kab, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL VAN DER WAALS ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFElectrostaticCalculationGhemical::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ rab = OBForceField::VectorDistanceDerivative(pos_a, pos_b, force_a, force_b);
+ const double rab2 = rab * rab;
+ const double dE = -qq / rab2;
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ }
+
+ if (IsNearZero(rab, 1.0e-3))
+ rab = 1.0e-3;
+
+ energy = qq / rab;
+ }
+
+ template<bool gradients>
+ double OBForceFieldGhemical::E_Electrostatic()
+ {
+ vector<OBFFElectrostaticCalculationGhemical>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nE L E C T R O S T A T I C I N T E R A C T I O N S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij 332.17*QiQj ENERGY\n");
+ OBFFLog("-------------------------------------------\n");
+ // XX XX -000.000 -000.000 -000.000
+ }
+
+ unsigned int j = 0;
+ for (i = _electrostaticcalculations.begin(); i != _electrostaticcalculations.end(); ++i, ++j) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_elepairs.BitIsSet(j))
+ continue;
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%s %s %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).rab, (*i).qq, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ELECTROSTATIC ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ //***********************************************
+ //Make a global instance
+ OBForceFieldGhemical theForceFieldGhemical("Ghemical", true);
+ //***********************************************
+
+ OBForceFieldGhemical::~OBForceFieldGhemical()
+ {
+ }
+
+ OBForceFieldGhemical &OBForceFieldGhemical::operator=(OBForceFieldGhemical &src)
+ {
+ _mol = src._mol;
+ _init = src._init;
+
+ _ffbondparams = src._ffbondparams;
+ _ffangleparams = src._ffangleparams;
+ _fftorsionparams = src._fftorsionparams;
+ _ffvdwparams = src._ffvdwparams;
+
+ _bondcalculations = src._bondcalculations;
+ _anglecalculations = src._anglecalculations;
+ _torsioncalculations = src._torsioncalculations;
+ _vdwcalculations = src._vdwcalculations;
+ _electrostaticcalculations = src._electrostaticcalculations;
+
+ return *this;
+ }
+
+ bool OBForceFieldGhemical::SetupCalculations()
+ {
+ OBFFParameter *parameter;
+ OBAtom *a, *b, *c, *d;
+
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("\nS E T T I N G U P C A L C U L A T I O N S\n\n");
+
+ //
+ // ZNBond Calculations
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP BOND CALCULATIONS...\n");
+
+ OBFFBondCalculationGhemical bondcalc;
+ int bondtype;
+
+ _bondcalculations.clear();
+
+ FOR_BONDS_OF_MOL(bond, _mol) {
+ a = bond->GetBeginAtom();
+ b = bond->GetEndAtom();
+
+ // skip this bond if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two bond atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validBond = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()))
+ validBond = true;
+ }
+ if (!validBond)
+ continue;
+ }
+
+ bondtype = bond->GetBondOrder();
+ if (bond->IsAromatic())
+ bondtype = 5;
+
+ bondcalc.a = a;
+ bondcalc.b = b;
+ bondcalc.bt = bondtype;
+
+ parameter = GetParameterGhemical(bondtype, a->GetType(), b->GetType(), NULL, NULL, _ffbondparams);
+ if (parameter == NULL) {
+ parameter = GetParameterGhemical(bondtype, "FFFF", a->GetType(), NULL, NULL, _ffbondparams);
+ if (parameter == NULL) {
+ parameter = GetParameterGhemical(bondtype, "FFFF", b->GetType(), NULL, NULL, _ffbondparams);
+ if (parameter == NULL) {
+ bondcalc.kb = KCAL_TO_KJ * 500.0;
+ bondcalc.r0 = 1.100;
+ bondcalc.SetupPointers();
+
+ _bondcalculations.push_back(bondcalc);
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, "COULD NOT FIND PARAMETERS FOR BOND %s-%s, USING DEFAULT PARAMETERS\n", a->GetType(), b->GetType());
+ OBFFLog(_logbuf);
+ }
+
+ continue;
+ }
+ }
+ }
+ bondcalc.kb = KCAL_TO_KJ * parameter->_dpar[1];
+ bondcalc.r0 = parameter->_dpar[0];
+ bondcalc.SetupPointers();
+
+ _bondcalculations.push_back(bondcalc);
+ }
+
+ //
+ // Angle Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ANGLE CALCULATIONS...\n");
+
+ OBFFAngleCalculationGhemical anglecalc;
+
+ _anglecalculations.clear();
+
+ FOR_ANGLES_OF_MOL(angle, _mol) {
+ b = _mol.GetAtom((*angle)[0] + 1);
+ a = _mol.GetAtom((*angle)[1] + 1);
+ c = _mol.GetAtom((*angle)[2] + 1);
+
+ // skip this angle if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) || _constraints.IsIgnored(c->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the three angle atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validAngle = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()))
+ validAngle = true;
+ }
+ if (!validAngle)
+ continue;
+ }
+
+ anglecalc.a = a;
+ anglecalc.b = b;
+ anglecalc.c = c;
+
+ parameter = GetParameter(a->GetType(), b->GetType(), c->GetType(), NULL, _ffangleparams);
+ if (parameter == NULL) {
+ parameter = GetParameter("FFFF", b->GetType(), c->GetType(), NULL, _ffangleparams);
+ if (parameter == NULL) {
+ parameter = GetParameter(a->GetType(), b->GetType(), "FFFF", NULL, _ffangleparams);
+ if (parameter == NULL) {
+ parameter = GetParameter("FFFF", b->GetType(), "FFFF", NULL, _ffangleparams);
+ if (parameter == NULL) {
+ anglecalc.ka = KCAL_TO_KJ * 0.020;
+ anglecalc.theta0 = 120.0;
+ anglecalc.SetupPointers();
+
+ _anglecalculations.push_back(anglecalc);
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, "COULD NOT FIND PARAMETERS FOR ANGLE %s-%s-%s, USING DEFAULT PARAMETERS\n", a->GetType(), b->GetType(), c->GetType());
+ OBFFLog(_logbuf);
+ }
+
+ continue;
+ }
+ }
+ }
+ }
+ anglecalc.ka = KCAL_TO_KJ * parameter->_dpar[1];
+ anglecalc.theta0 = parameter->_dpar[0];
+ anglecalc.SetupPointers();
+
+ _anglecalculations.push_back(anglecalc);
+ }
+
+ //
+ // Torsion Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP TORSION CALCULATIONS...\n");
+
+ OBFFTorsionCalculationGhemical torsioncalc;
+ int torsiontype;
+ int s;
+
+ _torsioncalculations.clear();
+
+ FOR_TORSIONS_OF_MOL(t, _mol) {
+ a = _mol.GetAtom((*t)[0] + 1);
+ b = _mol.GetAtom((*t)[1] + 1);
+ c = _mol.GetAtom((*t)[2] + 1);
+ d = _mol.GetAtom((*t)[3] + 1);
+
+ // skip this torsion if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) ||
+ _constraints.IsIgnored(c->GetIdx()) || _constraints.IsIgnored(d->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the four torsion atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validTorsion = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()) && _intraGroup[i].BitIsOn(d->GetIdx()))
+ validTorsion = true;
+ }
+ if (!validTorsion)
+ continue;
+ }
+
+ OBBond *bc = _mol.GetBond(b, c);
+ torsiontype = bc->GetBondOrder();
+ if (bc->IsAromatic())
+ torsiontype = 5;
+
+ torsioncalc.a = a;
+ torsioncalc.b = b;
+ torsioncalc.c = c;
+ torsioncalc.d = d;
+ torsioncalc.tt = torsiontype;
+
+ parameter = GetParameterGhemical(torsiontype, a->GetType(), b->GetType(), c->GetType(), d->GetType(), _fftorsionparams);
+ if (parameter == NULL) {
+ parameter = GetParameterGhemical(torsiontype, "FFFF", b->GetType(), c->GetType(), d->GetType(), _fftorsionparams);
+ if (parameter == NULL) {
+ parameter = GetParameterGhemical(torsiontype, a->GetType(), b->GetType(), c->GetType(), "FFFF", _fftorsionparams);
+ if (parameter == NULL) {
+ parameter = GetParameterGhemical(torsiontype, "FFFF", b->GetType(), c->GetType(), "FFFF", _fftorsionparams);
+ if (parameter == NULL) {
+ torsioncalc.V = 0.0;
+ torsioncalc.s = 1.0;
+ torsioncalc.n = 1.0;
+
+ torsioncalc.k1 = 0.0;
+ torsioncalc.k2 = 0.0;
+ torsioncalc.k3 = 0.0;
+ torsioncalc.SetupPointers();
+ _torsioncalculations.push_back(torsioncalc);
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, "COULD NOT FIND PARAMETERS FOR TORSION %s-%s-%s-%s, USING DEFAULT PARAMETERS\n", a->GetType(), b->GetType(), c->GetType(), d->GetType());
+ OBFFLog(_logbuf);
+ }
+
+ continue;
+ }
+ }
+ }
+ }
+ torsioncalc.V = KCAL_TO_KJ * parameter->_dpar[0];
+ torsioncalc.s = parameter->_dpar[1];
+ torsioncalc.n = parameter->_dpar[2];
+
+ s = (int) (torsioncalc.s * torsioncalc.n);
+ switch(s) {
+ case +3:
+ torsioncalc.k1 = 0.0;
+ torsioncalc.k2 = 0.0;
+ torsioncalc.k3 = torsioncalc.V;
+ break;
+ case +2:
+ torsioncalc.k1 = 0.0;
+ torsioncalc.k2 = -torsioncalc.V;
+ torsioncalc.k3 = 0.0;
+ break;
+ case +1:
+ torsioncalc.k1 = torsioncalc.V;
+ torsioncalc.k2 = 0.0;
+ torsioncalc.k3 = 0.0;
+ break;
+ case -1:
+ torsioncalc.k1 = -torsioncalc.V;
+ torsioncalc.k2 = 0.0;
+ torsioncalc.k3 = 0.0;
+ break;
+ case -2:
+ torsioncalc.k1 = 0.0;
+ torsioncalc.k2 = torsioncalc.V;
+ torsioncalc.k3 = 0.0;
+ break;
+ case -3:
+ torsioncalc.k1 = 0.0;
+ torsioncalc.k2 = 0.0;
+ torsioncalc.k3 = -torsioncalc.V;
+ break;
+ }
+
+ torsioncalc.SetupPointers();
+ _torsioncalculations.push_back(torsioncalc);
+ }
+
+ //
+ // VDW Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP VAN DER WAALS CALCULATIONS...\n");
+
+ OBFFVDWCalculationGhemical vdwcalc;
+ OBFFParameter *parameter_a, *parameter_b;
+
+ _vdwcalculations.clear();
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this vdw if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validVDW = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validVDW = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validVDW = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validVDW = true;
+ }
+
+ if (!validVDW)
+ continue;
+ }
+
+ parameter_a = GetParameter(a->GetType(), NULL, NULL, NULL, _ffvdwparams);
+ if (parameter_a == NULL) { // no vdw parameter -> use hydrogen
+ vdwcalc.Ra = 1.5;
+ vdwcalc.ka = 0.042;
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, "COULD NOT FIND VDW PARAMETERS FOR ATOM %s, USING HYDROGEN VDW PARAMETERS\n", a->GetType());
+ OBFFLog(_logbuf);
+ }
+ } else {
+ vdwcalc.Ra = parameter_a->_dpar[0];
+ vdwcalc.ka = parameter_a->_dpar[1];
+ }
+
+ parameter_b = GetParameter(b->GetType(), NULL, NULL, NULL, _ffvdwparams);
+ if (parameter_b == NULL) { // no vdw parameter -> use hydrogen
+ vdwcalc.Rb = 1.5;
+ vdwcalc.kb = 0.042;
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, "COULD NOT FIND VDW PARAMETERS FOR ATOM %s, USING HYDROGEN VDW PARAMETERS\n", b->GetType());
+ OBFFLog(_logbuf);
+ }
+ } else {
+ vdwcalc.Rb = parameter_b->_dpar[0];
+ vdwcalc.kb = parameter_b->_dpar[1];
+ }
+
+ vdwcalc.a = &*a;
+ vdwcalc.b = &*b;
+
+ //this calculations only need to be done once for each pair,
+ //we do them now and save them for later use
+ vdwcalc.kab = KCAL_TO_KJ * sqrt(vdwcalc.ka * vdwcalc.kb);
+
+ // 1-4 scaling
+ if (a->IsOneFour(b))
+ vdwcalc.kab *= 0.5;
+ /*
+ vdwcalc.is14 = false;
+ FOR_NBORS_OF_ATOM (nbr, a)
+ FOR_NBORS_OF_ATOM (nbr2, &*nbr)
+ FOR_NBORS_OF_ATOM (nbr3, &*nbr2)
+ if (b == &*nbr3) {
+ vdwcalc.is14 = true;
+ vdwcalc.kab *= 0.5;
+ }
+ */
+
+ // not sure why this is needed, but validation showed it works...
+ /*
+ if (a->IsInRingSize(6) && b->IsInRingSize(6) && IsInSameRing(a, b))
+ vdwcalc.samering = true;
+ else if ((a->IsInRingSize(5) || a->IsInRingSize(4)) && (b->IsInRingSize(5) || b->IsInRingSize(4)))
+ vdwcalc.samering = true;
+ else
+ vdwcalc.samering = false;
+ */
+
+ vdwcalc.ka = (vdwcalc.Ra + vdwcalc.Rb) * pow(1.0 * vdwcalc.kab , 1.0 / 12.0);
+ vdwcalc.kb = (vdwcalc.Ra + vdwcalc.Rb) * pow(2.0 * vdwcalc.kab , 1.0 / 6.0);
+ vdwcalc.SetupPointers();
+
+ _vdwcalculations.push_back(vdwcalc);
+ }
+
+ //
+ // Electrostatic Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ELECTROSTATIC CALCULATIONS...\n");
+
+ OBFFElectrostaticCalculationGhemical elecalc;
+
+ _electrostaticcalculations.clear();
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this ele if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validEle = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validEle = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validEle = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validEle = true;
+ }
+
+ if (!validEle)
+ continue;
+ }
+
+ elecalc.qq = KCAL_TO_KJ * 332.17 * a->GetPartialCharge() * b->GetPartialCharge();
+
+ if (elecalc.qq) {
+ elecalc.a = &*a;
+ elecalc.b = &*b;
+
+ // 1-4 scaling
+ if (a->IsOneFour(b))
+ elecalc.qq *= 0.5;
+
+ elecalc.SetupPointers();
+ _electrostaticcalculations.push_back(elecalc);
+ }
+ }
+
+ return true;
+ }
+
+ bool OBForceFieldGhemical::SetupPointers()
+ {
+ for (unsigned int i = 0; i < _bondcalculations.size(); ++i)
+ _bondcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _anglecalculations.size(); ++i)
+ _anglecalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _torsioncalculations.size(); ++i)
+ _torsioncalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _vdwcalculations.size(); ++i)
+ _vdwcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _electrostaticcalculations.size(); ++i)
+ _electrostaticcalculations[i].SetupPointers();
+
+ return true;
+ }
+
+
+ bool OBForceFieldGhemical::ParseParamFile()
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/ghemical.prm
+ ifstream ifs;
+ if (OpenDatafile(ifs, "ghemical.prm").length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open ghemical.prm", obError);
+ return false;
+ }
+
+ // Set the locale for number parsing to avoid locale issues: PR#1785463
+ obLocale.SetLocale();
+
+ while (ifs.getline(buffer, 80)) {
+ tokenize(vs, buffer);
+
+ if (EQn(buffer, "bond", 4)) {
+ parameter.clear();
+ parameter._a = vs[1];
+ parameter._b = vs[2];
+ parameter._dpar.push_back(atof(vs[4].c_str())); // length
+ parameter._dpar.push_back(atof(vs[5].c_str())); // force cte
+ parameter._ipar.resize(1);
+ if (EQn(vs[3].c_str(), "S", 1))
+ parameter._ipar[0] = 1;
+ if (EQn(vs[3].c_str(), "D", 1))
+ parameter._ipar[0] = 2;
+ if (EQn(vs[3].c_str(), "T", 1))
+ parameter._ipar[0] = 3;
+ if (EQn(vs[3].c_str(), "C", 1))
+ parameter._ipar[0] = 5;
+ _ffbondparams.push_back(parameter);
+ }
+ if (EQn(buffer, "angle", 5)) {
+ parameter.clear();
+ parameter._a = vs[1];
+ parameter._b = vs[2];
+ parameter._c = vs[3];
+ parameter._dpar.push_back(atof(vs[5].c_str())); // angle
+ parameter._dpar.push_back(atof(vs[6].c_str())); // force cte
+ _ffangleparams.push_back(parameter);
+ }
+ if (EQn(buffer, "torsion", 7)) {
+ parameter.clear();
+ parameter._a = vs[1];
+ parameter._b = vs[2];
+ parameter._c = vs[3];
+ parameter._d = vs[4];
+ parameter._dpar.resize(3);
+ parameter._dpar[0] = atof(vs[6].c_str()); // force cte
+ parameter._dpar[2] = atof(vs[8].c_str()); // n
+ if (EQn(vs[7].c_str(), "+", 1))
+ parameter._dpar[1] = +1; // s
+ else if (EQn(vs[7].c_str(), "-", 1))
+ parameter._dpar[1] = -1; // s
+
+ parameter._ipar.resize(1);
+ if (EQn(vs[5].c_str(), "?S?", 3))
+ parameter._ipar[0] = 1;
+ else if (EQn(vs[5].c_str(), "?D?", 3))
+ parameter._ipar[0] = 2;
+ else if (EQn(vs[5].c_str(), "?T?", 3))
+ parameter._ipar[0] = 3;
+ else if (EQn(vs[5].c_str(), "?C?", 3))
+ parameter._ipar[0] = 5;
+ _fftorsionparams.push_back(parameter);
+ }
+ if (EQn(buffer, "vdw", 3)) {
+ parameter.clear();
+ parameter._a = vs[1];
+ parameter._dpar.push_back(atof(vs[2].c_str())); // r
+ parameter._dpar.push_back(atof(vs[3].c_str())); // force cte
+ _ffvdwparams.push_back(parameter);
+ }
+ if (EQn(buffer, "charge", 6)) {
+ parameter.clear();
+ parameter._a = vs[1];
+ parameter._b = vs[2];
+ parameter._ipar.resize(1);
+ if (EQn(vs[3].c_str(), "S", 1))
+ parameter._ipar[0] = 1;
+ else if (EQn(vs[3].c_str(), "D", 1))
+ parameter._ipar[0] = 2;
+ parameter._dpar.push_back(atof(vs[4].c_str())); // charge
+ _ffchargeparams.push_back(parameter);
+ }
+ }
+
+ if (ifs)
+ ifs.close();
+
+ // return the locale to the original one
+ obLocale.RestoreLocale();
+
+ return 0;
+ }
+
+ bool OBForceFieldGhemical::SetTypes()
+ {
+ vector<vector<int> > _mlist; //!< match list for atom typing
+ vector<pair<OBSmartsPattern*,string> > _vexttyp; //!< external atom type rules
+ vector<vector<int> >::iterator j;
+ vector<pair<OBSmartsPattern*,string> >::iterator i;
+ OBSmartsPattern *sp;
+ vector<string> vs;
+ char buffer[80];
+
+ _mol.SetAtomTypesPerceived();
+
+ // open data/ghemical.prm
+ ifstream ifs;
+ if (OpenDatafile(ifs, "ghemical.prm").length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open ghemical.prm", obError);
+ return false;
+ }
+
+ // Set the locale for number parsing to avoid locale issues: PR#1785463
+ obLocale.SetLocale();
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "atom", 4)) {
+ tokenize(vs, buffer);
+
+ sp = new OBSmartsPattern;
+ if (sp->Init(vs[1]))
+ _vexttyp.push_back(pair<OBSmartsPattern*,string> (sp,vs[2]));
+ else {
+ delete sp;
+ sp = NULL;
+ obErrorLog.ThrowError(__FUNCTION__, " Could not parse atom type table from ghemical.prm", obInfo);
+ return false;
+ }
+ }
+ }
+
+ for (i = _vexttyp.begin();i != _vexttyp.end();++i) {
+ if (i->first->Match(_mol)) {
+ _mlist = i->first->GetMapList();
+ for (j = _mlist.begin();j != _mlist.end();++j) {
+ _mol.GetAtom((*j)[0])->SetType(i->second);
+ }
+ }
+ }
+
+ SetPartialCharges();
+
+ IF_OBFF_LOGLVL_LOW {
+ OBFFLog("\nA T O M T Y P E S\n\n");
+ OBFFLog("IDX\tTYPE\n");
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ snprintf(_logbuf, BUFF_SIZE, "%d\t%s\n", a->GetIdx(), a->GetType());
+ OBFFLog(_logbuf);
+ }
+
+ OBFFLog("\nC H A R G E S\n\n");
+ OBFFLog("IDX\tCHARGE\n");
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ snprintf(_logbuf, BUFF_SIZE, "%d\t%f\n", a->GetIdx(), a->GetPartialCharge());
+ OBFFLog(_logbuf);
+ }
+ }
+
+ // DEBUG (validation)
+ //FOR_ATOMS_OF_MOL (a, _mol)
+ // if (atoi(a->GetType()) != 0)
+ // cout << "ATOMTYPE " << atoi(a->GetType()) << endl;
+ // else
+ // cout << "ATOMTYPE " << a->GetType() << endl;
+
+ if (ifs)
+ ifs.close();
+
+ // return the locale to the original one
+ obLocale.RestoreLocale();
+
+ return true;
+ }
+
+ bool OBForceFieldGhemical::SetPartialCharges()
+ {
+ OBAtom *a, *b;
+ int bondtype;
+
+ _mol.SetAutomaticPartialCharge(false);
+ _mol.SetPartialChargesPerceived();
+
+ // set all partial charges to 0.0
+ FOR_ATOMS_OF_MOL (atom, _mol)
+ atom->SetPartialCharge(0.0);
+
+ FOR_BONDS_OF_MOL (bond, _mol) {
+ a = bond->GetBeginAtom();
+ b = bond->GetEndAtom();
+ bondtype = bond->GetBondOrder();
+
+ string _a(a->GetType());
+ string _b(b->GetType());
+
+ for (unsigned int idx=0; idx < _ffchargeparams.size(); ++idx) {
+ if (((_a == _ffchargeparams[idx]._a) && (_b == _ffchargeparams[idx]._b)) && (bondtype == _ffchargeparams[idx]._ipar[0])) {
+ a->SetPartialCharge(a->GetPartialCharge() - _ffchargeparams[idx]._dpar[0]);
+ b->SetPartialCharge(b->GetPartialCharge() + _ffchargeparams[idx]._dpar[0]);
+ } else if (((_a == _ffchargeparams[idx]._b) && (_b == _ffchargeparams[idx]._a)) && (bondtype == _ffchargeparams[idx]._ipar[0])) {
+ a->SetPartialCharge(a->GetPartialCharge() + _ffchargeparams[idx]._dpar[0]);
+ b->SetPartialCharge(b->GetPartialCharge() - _ffchargeparams[idx]._dpar[0]);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ double OBForceFieldGhemical::Energy(bool gradients)
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_MEDIUM
+ OBFFLog("\nE N E R G Y\n\n");
+
+ if (gradients) {
+ ClearGradients();
+ energy = E_Bond<true>();
+ energy += E_Angle<true>();
+ energy += E_Torsion<true>();
+ energy += E_VDW<true>();
+ energy += E_Electrostatic<true>();
+ } else {
+ energy = E_Bond<false>();
+ energy += E_Angle<false>();
+ energy += E_Torsion<false>();
+ energy += E_VDW<false>();
+ energy += E_Electrostatic<false>();
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, "\nTOTAL ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ OBFFParameter* OBForceFieldGhemical::GetParameterGhemical(int type, const char* a, const char* b, const char* c, const char* d,
+ vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+ if (a == NULL)
+ return NULL;
+
+ if (b == NULL) {
+ string _a(a);
+ for (unsigned int idx=0; idx < parameter.size(); ++idx)
+ if ((_a == parameter[idx]._a) && (type == parameter[idx]._ipar[0])) {
+ par = ¶meter[idx];
+ return par;
+ }
+ return NULL;
+ }
+ if (c == NULL) {
+ string _a(a);
+ string _b(b);
+ for (unsigned int idx=0; idx < parameter.size(); ++idx) {
+ if ( ((_a == parameter[idx]._a) && (_b == parameter[idx]._b) &&
+ (type == parameter[idx]._ipar[0])) ||
+ ((_a == parameter[idx]._b) && (_b == parameter[idx]._a)) &&
+ (type == parameter[idx]._ipar[0]) ) {
+ par = ¶meter[idx];
+ return par;
+ }
+ }
+ return NULL;
+ }
+ if (d == NULL) {
+ string _a(a);
+ string _b(b);
+ string _c(c);
+ for (unsigned int idx=0; idx < parameter.size(); ++idx) {
+ if ( ((_a == parameter[idx]._a) && (_b == parameter[idx]._b) &&
+ (_c == parameter[idx]._c) &&
+ (type == parameter[idx]._ipar[0]))||
+ ((_a == parameter[idx]._c) && (_b == parameter[idx]._b) &&
+ (_c == parameter[idx]._a) && (type == parameter[idx]._ipar[0])) ) {
+ par = ¶meter[idx];
+ return par;
+ }
+ }
+ return NULL;
+ }
+ string _a(a);
+ string _b(b);
+ string _c(c);
+ string _d(d);
+
+ for (unsigned int idx=0; idx < parameter.size(); ++idx) {
+ if ( ((_a == parameter[idx]._a) && (_b == parameter[idx]._b) &&
+ (_c == parameter[idx]._c) && (_d == parameter[idx]._d) &&
+ (type == parameter[idx]._ipar[0])) ||
+ ((_a == parameter[idx]._d) && (_b == parameter[idx]._c) &&
+ (_c == parameter[idx]._b) && (_d == parameter[idx]._a) &&
+ (type == parameter[idx]._ipar[0])) ) {
+ par = ¶meter[idx];
+ return par;
+ }
+ }
+
+ return NULL;
+ }
+
+ bool OBForceFieldGhemical::ValidateGradients ()
+ {
+ vector3 numgrad, anagrad, err;
+ int coordIdx;
+
+ bool passed = true; // set to false if any component fails
+
+ OBFFLog("\nV A L I D A T E G R A D I E N T S\n\n");
+ OBFFLog("ATOM IDX NUMERICAL GRADIENT ANALYTICAL GRADIENT REL. ERROR (%) \n");
+ OBFFLog("----------------------------------------------------------------------------------------\n");
+ // "XX (000.000, 000.000, 000.000) (000.000, 000.000, 000.000) (00.00, 00.00, 00.00)"
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ coordIdx = (a->GetIdx() - 1) * 3;
+
+ // OBFF_ENERGY
+ numgrad = NumericalDerivative(&*a, OBFF_ENERGY);
+ Energy(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, "%2d (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", a->GetIdx(), numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+
+ // OBFF_EBOND
+ numgrad = NumericalDerivative(&*a, OBFF_EBOND);
+ ClearGradients();
+ E_Bond();
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " bond (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ // 8% tolerance here because some bonds have slight instability
+ if (err.x() > 8.0 || err.y() > 8.0 || err.z() > 8.0)
+ passed = false;
+
+ // OBFF_EANGLE
+ numgrad = NumericalDerivative(&*a, OBFF_EANGLE);
+ ClearGradients();
+ E_Angle();
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " angle (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_ETORSION
+ numgrad = NumericalDerivative(&*a, OBFF_ETORSION);
+ ClearGradients();
+ E_Torsion();
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " torsion (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EVDW
+ numgrad = NumericalDerivative(&*a, OBFF_EVDW);
+ ClearGradients();
+ E_VDW();
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " vdw (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EELECTROSTATIC
+ numgrad = NumericalDerivative(&*a, OBFF_EELECTROSTATIC);
+ ClearGradients();
+ E_Electrostatic();
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " electro (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+ }
+
+ return passed; // are all components good enough?
+ }
+
+} // end namespace OpenBabel
+
+//! \file forcefieldghemical.cpp
+//! \brief Ghemical force field
diff --git a/forcefields/forcefieldghemical.h b/forcefields/forcefieldghemical.h
new file mode 100644
index 0000000..9fcef12
--- /dev/null
+++ b/forcefields/forcefieldghemical.h
@@ -0,0 +1,187 @@
+/**********************************************************************
+forcefieldghemical.h - Ghemical force field.
+
+Copyright (C) 2006 by Tim Vandermeersch <tim.vandermeersch at gmail.com>
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include <openbabel/forcefield.h>
+#include <openbabel/base.h>
+#include <openbabel/mol.h>
+
+namespace OpenBabel
+{
+ class OBFFBondCalculationGhemical : public OBFFCalculation2
+ {
+ public:
+ int bt; // bondtype (BTIJ)
+ double kb, r0, rab, delta;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFAngleCalculationGhemical : public OBFFCalculation3
+ {
+ public:
+ double ka, theta, theta0, delta;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFTorsionCalculationGhemical : public OBFFCalculation4
+ {
+ public:
+ int tt; //torsiontype (TTIJKL)
+ double V, s, n, tor;
+ double k1, k2, k3;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFVDWCalculationGhemical : public OBFFCalculation2
+ {
+ public:
+ bool is14, samering;
+ double ka, Ra, kb, Rb, kab, rab;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFElectrostaticCalculationGhemical : public OBFFCalculation2
+ {
+ public:
+ double qq, rab;
+
+ template<bool> void Compute();
+ };
+
+ // Class OBForceFieldGhemical
+ // class introduction in forcefieldghemical.cpp
+ class OBForceFieldGhemical: public OBForceField
+ {
+ protected:
+ //! Parses the parameter file
+ bool ParseParamFile();
+ //! Sets atomtypes to Ghemical types in _mol
+ bool SetTypes();
+ //! Sets partial charges to Ghemical charges in _mol
+ bool SetPartialCharges();
+ //! fill OBFFXXXCalculation vectors
+ bool SetupCalculations();
+ //! Setup pointers in OBFFXXXCalculation vectors
+ bool SetupPointers();
+ //! Same as OBForceField::GetParameter, but takes (bond/angle/torsion) type in account.
+ OBFFParameter* GetParameterGhemical(int type, const char* a, const char* b,
+ const char* c, const char* d, std::vector<OBFFParameter> ¶meter);
+
+ // OBFFParameter vectors to contain the parameters
+ std::vector<OBFFParameter> _ffbondparams;
+ std::vector<OBFFParameter> _ffangleparams;
+ std::vector<OBFFParameter> _fftorsionparams;
+ std::vector<OBFFParameter> _ffvdwparams;
+ std::vector<OBFFParameter> _ffchargeparams;
+
+ // OBFFXXXCalculationYYY vectors to contain the calculations
+ std::vector<OBFFBondCalculationGhemical> _bondcalculations;
+ std::vector<OBFFAngleCalculationGhemical> _anglecalculations;
+ std::vector<OBFFTorsionCalculationGhemical> _torsioncalculations;
+ std::vector<OBFFVDWCalculationGhemical> _vdwcalculations;
+ std::vector<OBFFElectrostaticCalculationGhemical> _electrostaticcalculations;
+
+ public:
+ //! Constructor
+ explicit OBForceFieldGhemical(const char* ID, bool IsDefault=true) : OBForceField(ID, IsDefault)
+ {
+ _init = false;
+ _rvdw = 7.0;
+ _rele = 15.0;
+ _pairfreq = 10;
+ _cutoff = false;
+ _linesearch = LineSearchType::Simple;
+ }
+
+ //! Destructor
+ virtual ~OBForceFieldGhemical();
+
+ //! Assignment
+ OBForceFieldGhemical &operator = (OBForceFieldGhemical &);
+
+ //! Get the description for this force field
+ const char* Description()
+ {
+ return "Ghemical force field.";
+ }
+
+ //!Clone the current instance. May be desirable in multithreaded environments
+ virtual OBForceFieldGhemical* MakeNewInstance(){ return new OBForceFieldGhemical(*this); }
+
+ //! Get the unit in which the energy is expressed
+ std::string GetUnit()
+ {
+ return std::string("kJ/mol");
+ }
+
+ //! \return that analytical gradients are implemented for Ghemical
+ bool HasAnalyticalGradients() { return true; }
+
+ //! Setup
+ bool Setup(OBMol &mol);
+
+ //! \return total energy
+ double Energy(bool gradients = true);
+ //! Returns the bond stretching energy
+ template<bool> double E_Bond();
+ double E_Bond(bool gradients = true)
+ {
+ return gradients ? E_Bond<true>() : E_Bond<false>();
+ }
+ //! Returns the angle bending energy
+ template<bool> double E_Angle();
+ double E_Angle(bool gradients = true)
+ {
+ return gradients ? E_Angle<true>() : E_Angle<false>();
+ }
+ //! Returns the torsional energy
+ template<bool> double E_Torsion();
+ double E_Torsion(bool gradients = true)
+ {
+ return gradients ? E_Torsion<true>() : E_Torsion<false>();
+ }
+ //! Returns the Van der Waals energy (Buckingham potential)
+ template<bool> double E_VDW();
+ double E_VDW(bool gradients = true)
+ {
+ return gradients ? E_VDW<true>() : E_VDW<false>();
+ }
+ //! Returns the dipole-dipole interaction energy
+ template<bool> double E_Electrostatic();
+ double E_Electrostatic(bool gradients = true)
+ {
+ return gradients ? E_Electrostatic<true>() : E_Electrostatic<false>();
+ }
+
+ //! Compare and print the numerical and analytical gradients
+ bool ValidateGradients();
+
+ }; // class OBForceFieldGhemical
+
+}// namespace OpenBabel
+
+//! \file forcefieldghemical.h
+//! \brief Ghemical force field
+
diff --git a/forcefields/forcefieldghemical.lo b/forcefields/forcefieldghemical.lo
new file mode 100644
index 0000000..7e2a391
--- /dev/null
+++ b/forcefields/forcefieldghemical.lo
@@ -0,0 +1,12 @@
+# forcefieldghemical.lo - a libtool object file
+# Generated by ltmain.sh (GNU libtool) 2.2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/forcefieldghemical.o'
+
+# Name of the non-PIC object
+non_pic_object=none
+
diff --git a/forcefields/forcefieldmmff94.cpp b/forcefields/forcefieldmmff94.cpp
new file mode 100644
index 0000000..af9c54f
--- /dev/null
+++ b/forcefields/forcefieldmmff94.cpp
@@ -0,0 +1,5022 @@
+/*********************************************************************
+forcefieldmmff94.cpp - MMFF94 force field
+
+Copyright (C) 2006-2008 by Tim Vandermeersch <tim.vandermeersch at gmail.com>
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+/*
+ * Source code layout:
+ * - Functions to calculate the actual interactions
+ * - Parse parameter files
+ * - Setup Functions
+ * - Validation functions
+ * - Calculate bond type, angle type, stretch-bend type, torsion type
+ * - Various tables & misc. functions
+ *
+ */
+
+#include <openbabel/babelconfig.h>
+#include <openbabel/obconversion.h>
+#include <openbabel/mol.h>
+#include <openbabel/locale.h>
+
+#include <iomanip>
+#include "forcefieldmmff94.h"
+
+using namespace std;
+
+namespace OpenBabel
+{
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Functions to calculate the actual interactions
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ double OBForceFieldMMFF94::Energy(bool gradients)
+ {
+ double energy;
+
+ IF_OBFF_LOGLVL_MEDIUM
+ OBFFLog("\nE N E R G Y\n\n");
+
+ if (gradients) {
+ ClearGradients();
+ energy = E_Bond<true>();
+ energy += E_Angle<true>();
+ energy += E_StrBnd<true>();
+ energy += E_Torsion<true>();
+ energy += E_OOP<true>();
+ energy += E_VDW<true>();
+ energy += E_Electrostatic<true>();
+ } else {
+ energy = E_Bond<false>();
+ energy += E_Angle<false>();
+ energy += E_StrBnd<false>();
+ energy += E_Torsion<false>();
+ energy += E_OOP<false>();
+ energy += E_VDW<false>();
+ energy += E_Electrostatic<false>();
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, "\nTOTAL ENERGY = %8.5f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ //
+ // MMFF part I - page 494
+ //
+ // kb_ij 7
+ // EB_ij = 143.9325 ------- /\r_ij^2 (1 + cs /\_rij + ---- cs^2 r_ij^2)
+ // 2 12
+ //
+ // kb_ij force constant (md/A)
+ //
+ // /\r_ij r_ij - r0_ij (A)
+ //
+ // cs cubic stretch constant = -2 A^(-1)
+ //
+ template<bool gradients>
+ inline void OBFFBondCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ double delta2;
+
+ if (gradients) {
+ rab = OBForceField::VectorBondDerivative(pos_a, pos_b, force_a, force_b);
+ delta = rab - r0;
+ delta2 = delta * delta;
+
+ const double dE = 143.9325 * kb * delta * (1.0 - 3.0 * delta + 14.0/3.0 * delta2);
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ delta = rab - r0;
+ delta2 = delta * delta;
+ }
+
+ energy = kb * delta2 * (1.0 - 2.0 * delta + 7.0/3.0 * delta2);
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_Bond()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nB O N D S T R E T C H I N G\n\n");
+ OBFFLog("ATOM TYPES FF BOND IDEAL FORCE\n");
+ OBFFLog(" I J CLASS LENGTH LENGTH CONSTANT DELTA ENERGY\n");
+ OBFFLog("------------------------------------------------------------------------\n");
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _bondcalculations.size(); ++i) {
+ _bondcalculations[i].template Compute<gradients>();
+ energy += _bondcalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_bondcalculations[i].force_a, _bondcalculations[i].idx_a);
+ AddGradient(_bondcalculations[i].force_b, _bondcalculations[i].idx_b);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %d %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ atoi(_bondcalculations[i].a->GetType()), atoi(_bondcalculations[i].b->GetType()),
+ _bondcalculations[i].bt, _bondcalculations[i].rab, _bondcalculations[i].r0,
+ _bondcalculations[i].kb, _bondcalculations[i].delta,
+ 143.9325 * 0.5 * _bondcalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _bondcalculations.size(); ++i) {
+ if (gradients) {
+ AddGradient(_bondcalculations[i].force_a, _bondcalculations[i].idx_a);
+ AddGradient(_bondcalculations[i].force_b, _bondcalculations[i].idx_b);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL BOND STRETCHING ENERGY = %8.5f %s\n", 143.9325 * 0.5 * energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return (143.9325 * 0.5 * energy);
+ }
+
+ //
+ // MMFF part I - page 495
+ //
+ // ka_ijk
+ // EA_ijk = 0.438449325 -------- /\0_ijk^2 (1 + cs /\0_ijk)
+ // 2
+ //
+ // ka_ijk force constant (md A/rad^2)
+ //
+ // /\0_ijk 0_ijk - 00_ijk (degrees)
+ //
+ // cs cubic bend constant = -0.007 deg^-1 = -0.4 rad^-1
+ //
+ template<bool gradients>
+ inline void OBFFAngleCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c)) {
+ energy = 0.0;
+ return;
+ }
+
+ double delta2, dE;
+
+ if (gradients) {
+ theta = OBForceField::VectorAngleDerivative(pos_a, pos_b, pos_c, force_a, force_b, force_c);
+
+ if (!isfinite(theta))
+ theta = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ delta = theta - theta0;
+
+ if (linear) {
+ energy = 143.9325 * ka * (1.0 + cos((theta) * DEG_TO_RAD));
+ dE = -sin((theta) * DEG_TO_RAD) * 143.9325 * ka;
+ } else {
+ delta2 = delta * delta;
+ energy = 0.043844 * 0.5 * ka * delta2 * (1.0 - 0.007 * delta);
+ dE = RAD_TO_DEG * 0.043844 * ka * delta * (1.0 - 1.5 * 0.007 * delta);
+ }
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ OBForceField::VectorSelfMultiply(force_c, dE);
+ } else {
+ theta = OBForceField::VectorAngle(pos_a, pos_b, pos_c);
+
+ if (!isfinite(theta))
+ theta = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ delta = theta - theta0;
+
+ if (linear) {
+ energy = 143.9325 * ka * (1.0 + cos(theta * DEG_TO_RAD));
+ } else {
+ delta2 = delta * delta;
+ energy = 0.043844 * 0.5 * ka * delta2 * (1.0 - 0.007 * delta);
+ }
+
+ }
+
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_Angle()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nA N G L E B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES FF VALENCE IDEAL FORCE\n");
+ OBFFLog(" I J K CLASS ANGLE ANGLE CONSTANT DELTA ENERGY\n");
+ OBFFLog("-----------------------------------------------------------------------------\n");
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _anglecalculations.size(); ++i) {
+
+ _anglecalculations[i].template Compute<gradients>();
+ energy += _anglecalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_anglecalculations[i].force_a, _anglecalculations[i].idx_a);
+ AddGradient(_anglecalculations[i].force_b, _anglecalculations[i].idx_b);
+ AddGradient(_anglecalculations[i].force_c, _anglecalculations[i].idx_c);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %2d %d %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ atoi(_anglecalculations[i].a->GetType()), atoi(_anglecalculations[i].b->GetType()),
+ atoi(_anglecalculations[i].c->GetType()), _anglecalculations[i].at,
+ _anglecalculations[i].theta, _anglecalculations[i].theta0,
+ _anglecalculations[i].ka, _anglecalculations[i].delta,
+ _anglecalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _anglecalculations.size(); ++i) {
+ if (gradients) {
+ AddGradient(_anglecalculations[i].force_a, _anglecalculations[i].idx_a);
+ AddGradient(_anglecalculations[i].force_b, _anglecalculations[i].idx_b);
+ AddGradient(_anglecalculations[i].force_c, _anglecalculations[i].idx_c);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ANGLE BENDING ENERGY = %8.5f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ //
+ // MMFF part I - page 495
+ //
+ // EBA_ijk = 2.51210 (kba_ijk /\r_ij + kba_kji /\r_kj) /\0_ijk
+ //
+ // kba_ijk force constant (md/rad)
+ // kba_kji force constant (md/rad)
+ //
+ // /\r_xx see above
+ // /\0_ijk see above
+ //
+ template<bool gradients>
+ inline void OBFFStrBndCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ theta = OBForceField::VectorAngleDerivative(pos_a, pos_b, pos_c,
+ force_abc_a, force_abc_b, force_abc_c);
+ rab = OBForceField::VectorDistanceDerivative(pos_a, pos_b, force_ab_a, force_ab_b);
+ rbc = OBForceField::VectorDistanceDerivative(pos_b, pos_c, force_bc_b, force_bc_c);
+ } else {
+ theta = OBForceField::VectorAngle(pos_a, pos_b, pos_c);
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ rbc = OBForceField::VectorDistance(pos_b, pos_c);
+ }
+
+ if (!isfinite(theta))
+ theta = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ delta_theta = theta - theta0;
+ delta_rab = rab - rab0;
+ delta_rbc = rbc - rbc0;
+ const double factor = RAD_TO_DEG * (kbaABC * delta_rab + kbaCBA * delta_rbc);
+
+ energy = DEG_TO_RAD * factor * delta_theta;
+ if (gradients) {
+ //grada = 2.51210 * (kbaABC * rab_da * delta_theta + RAD_TO_DEG * theta_da * (kbaABC * delta_rab + kbaCBA * delta_rbc));
+ OBForceField::VectorSelfMultiply(force_ab_a, (kbaABC*delta_theta));
+ OBForceField::VectorSelfMultiply(force_abc_a, factor);
+ OBForceField::VectorAdd(force_ab_a, force_abc_a, force_ab_a);
+ OBForceField::VectorMultiply(force_ab_a, 2.51210, force_a);
+ //gradc = 2.51210 * (kbaCBA * rbc_dc * delta_theta + RAD_TO_DEG * theta_dc * (kbaABC * delta_rab + kbaCBA * delta_rbc));
+ OBForceField::VectorSelfMultiply(force_bc_c, (kbaCBA*delta_theta));
+ OBForceField::VectorSelfMultiply(force_abc_c, factor);
+ OBForceField::VectorAdd(force_bc_c, force_abc_c, force_bc_c);
+ OBForceField::VectorMultiply(force_bc_c, 2.51210, force_c);
+ //gradb = -grada - gradc;
+ OBForceField::VectorAdd(force_a, force_c, force_b);
+ OBForceField::VectorSelfMultiply(force_b, -1.0);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_StrBnd()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nS T R E T C H B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES FF VALENCE DELTA FORCE CONSTANT\n");
+ OBFFLog(" I J K CLASS ANGLE ANGLE I J J K ENERGY\n");
+ OBFFLog("---------------------------------------------------------------------------\n");
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _strbndcalculations.size(); ++i) {
+
+ _strbndcalculations[i].template Compute<gradients>();
+ energy += _strbndcalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_strbndcalculations[i].force_a, _strbndcalculations[i].idx_a);
+ AddGradient(_strbndcalculations[i].force_b, _strbndcalculations[i].idx_b);
+ AddGradient(_strbndcalculations[i].force_c, _strbndcalculations[i].idx_c);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %2d %2d %8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ atoi(_strbndcalculations[i].a->GetType()), atoi(_strbndcalculations[i].b->GetType()),
+ atoi(_strbndcalculations[i].c->GetType()), _strbndcalculations[i].sbt,
+ _strbndcalculations[i].theta, _strbndcalculations[i].delta_theta,
+ _strbndcalculations[i].kbaABC, _strbndcalculations[i].kbaCBA,
+ 2.51210 * _strbndcalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _strbndcalculations.size(); ++i) {
+ if (gradients) {
+ AddGradient(_strbndcalculations[i].force_a, _strbndcalculations[i].idx_a);
+ AddGradient(_strbndcalculations[i].force_b, _strbndcalculations[i].idx_b);
+ AddGradient(_strbndcalculations[i].force_c, _strbndcalculations[i].idx_c);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL STRETCH BENDING ENERGY = %8.5f %s\n", 2.51210 * energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return (2.51210 * energy);
+ }
+
+ int OBForceFieldMMFF94::GetElementRow(OBAtom *atom)
+ {
+ int row;
+
+ row = 0;
+
+ if (atom->GetAtomicNum() > 2)
+ row++;
+ if (atom->GetAtomicNum() > 10)
+ row++;
+ if (atom->GetAtomicNum() > 18)
+ row++;
+ if (atom->GetAtomicNum() > 36)
+ row++;
+ if (atom->GetAtomicNum() > 54)
+ row++;
+ if (atom->GetAtomicNum() > 86)
+ row++;
+
+ return row;
+ }
+
+ //
+ // MMFF part I - page 495
+ //
+ // ET_ijkl = 0.5 ( V1 (1 + cos(0_ijkl)) + V2 (1 - cos(2 0_ijkl)) + V3 (1 + cos(3 0_ijkl)) )
+ //
+ // V1 force constant (md/rad)
+ // V2 force constant (md/rad)
+ // V3 force constant (md/rad)
+ //
+ // 0_ijkl torsion angle (degrees)
+ //
+ template<bool gradients>
+ inline void OBFFTorsionCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c, idx_d)) {
+ energy = 0.0;
+ return;
+ }
+
+ double cosine, cosine2, cosine3;
+ double phi1, phi2, phi3;
+ double dE, sine, sine2, sine3;
+
+ if (gradients) {
+ tor = OBForceField::VectorTorsionDerivative(pos_a, pos_b, pos_c, pos_d,
+ force_a, force_b, force_c, force_d);
+ if (!isfinite(tor))
+ tor = 1.0e-3;
+
+ sine = sin(DEG_TO_RAD * tor);
+ sine2 = sin(2.0 * DEG_TO_RAD * tor);
+ sine3 = sin(3.0 * DEG_TO_RAD * tor);
+
+ dE = 0.5 * (v1 * sine - 2.0 * v2 * sine2 + 3.0 * v3 * sine3); // MMFF
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ OBForceField::VectorSelfMultiply(force_c, dE);
+ OBForceField::VectorSelfMultiply(force_d, dE);
+ } else {
+ tor = OBForceField::VectorTorsion(pos_a, pos_b, pos_c, pos_d);
+ if (!isfinite(tor))
+ tor = 1.0e-3;
+ }
+
+ cosine = cos(DEG_TO_RAD * tor);
+ cosine2 = cos(DEG_TO_RAD * 2 * tor);
+ cosine3 = cos(DEG_TO_RAD * 3 * tor);
+
+ phi1 = 1.0 + cosine;
+ phi2 = 1.0 - cosine2;
+ phi3 = 1.0 + cosine3;
+
+ energy = (v1 * phi1 + v2 * phi2 + v3 * phi3);
+
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_Torsion()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nT O R S I O N A L\n\n");
+ OBFFLog("ATOM TYPES FF TORSION FORCE CONSTANT\n");
+ OBFFLog(" I J K L CLASS ANGLE V1 V2 V3 ENERGY\n");
+ OBFFLog("--------------------------------------------------------------------\n");
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _torsioncalculations.size(); ++i) {
+
+ _torsioncalculations[i].template Compute<gradients>();
+ energy += _torsioncalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_torsioncalculations[i].force_a, _torsioncalculations[i].idx_a);
+ AddGradient(_torsioncalculations[i].force_b, _torsioncalculations[i].idx_b);
+ AddGradient(_torsioncalculations[i].force_c, _torsioncalculations[i].idx_c);
+ AddGradient(_torsioncalculations[i].force_d, _torsioncalculations[i].idx_d);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %2d %2d %d %8.3f %6.3f %6.3f %6.3f %8.3f\n",
+ atoi(_torsioncalculations[i].a->GetType()), atoi(_torsioncalculations[i].b->GetType()),
+ atoi(_torsioncalculations[i].c->GetType()), atoi(_torsioncalculations[i].d->GetType()),
+ _torsioncalculations[i].tt, _torsioncalculations[i].tor, _torsioncalculations[i].v1,
+ _torsioncalculations[i].v2, _torsioncalculations[i].v3, 0.5 * _torsioncalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _torsioncalculations.size(); ++i) {
+ if (gradients) {
+ AddGradient(_torsioncalculations[i].force_a, _torsioncalculations[i].idx_a);
+ AddGradient(_torsioncalculations[i].force_b, _torsioncalculations[i].idx_b);
+ AddGradient(_torsioncalculations[i].force_c, _torsioncalculations[i].idx_c);
+ AddGradient(_torsioncalculations[i].force_d, _torsioncalculations[i].idx_d);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL TORSIONAL ENERGY = %8.5f %s\n", 0.5 * energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return (0.5 * energy);
+ }
+
+ // //
+ // a //
+ // \ //
+ // b---d plane = a-b-c //
+ // / //
+ // c //
+ // //
+ template<bool gradients>
+ void OBFFOOPCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c, idx_d)) {
+ energy = 0.0;
+ return;
+ }
+
+ double angle2, dE;
+
+ if (gradients) {
+ angle = OBForceField::VectorOOPDerivative(pos_a, pos_b, pos_c, pos_d,
+ force_a, force_b, force_c, force_d);
+
+ dE = (-1.0 * RAD_TO_DEG * 0.043844 * angle * koop) / cos(angle * DEG_TO_RAD);
+
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ OBForceField::VectorSelfMultiply(force_c, dE);
+ OBForceField::VectorSelfMultiply(force_d, dE);
+ } else {
+ angle = OBForceField::VectorOOP(pos_a, pos_b, pos_c, pos_d);
+ }
+
+ if (!isfinite(angle))
+ angle = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ angle2 = angle * angle;
+ energy = koop * angle2;
+
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_OOP()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nO U T - O F - P L A N E B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES FF OOP FORCE\n");
+ OBFFLog(" I J K L CLASS ANGLE CONSTANT ENERGY\n");
+ OBFFLog("----------------------------------------------------------\n");
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _oopcalculations.size(); ++i) {
+
+ _oopcalculations[i].template Compute<gradients>();
+ energy += _oopcalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_oopcalculations[i].force_a, _oopcalculations[i].idx_a);
+ AddGradient(_oopcalculations[i].force_b, _oopcalculations[i].idx_b);
+ AddGradient(_oopcalculations[i].force_c, _oopcalculations[i].idx_c);
+ AddGradient(_oopcalculations[i].force_d, _oopcalculations[i].idx_d);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %2d %2d 0 %8.3f %8.3f %8.3f\n",
+ atoi(_oopcalculations[i].a->GetType()), atoi(_oopcalculations[i].b->GetType()),
+ atoi(_oopcalculations[i].c->GetType()), atoi(_oopcalculations[i].d->GetType()),
+ _oopcalculations[i].angle, _oopcalculations[i].koop,
+ 0.043844 * 0.5 * _oopcalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _oopcalculations.size(); ++i) {
+ if (gradients) {
+ AddGradient(_oopcalculations[i].force_a, _oopcalculations[i].idx_a);
+ AddGradient(_oopcalculations[i].force_b, _oopcalculations[i].idx_b);
+ AddGradient(_oopcalculations[i].force_c, _oopcalculations[i].idx_c);
+ AddGradient(_oopcalculations[i].force_d, _oopcalculations[i].idx_d);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL OUT-OF-PLANE BENDING ENERGY = %8.5f %s\n", 0.043844 * 0.5 * energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return (0.043844 * 0.5 * energy);
+ }
+
+ template<bool gradients>
+ inline void OBFFVDWCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ rab = OBForceField::VectorDistanceDerivative(pos_a, pos_b, force_a, force_b);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ }
+
+ const double rab7 = rab*rab*rab*rab*rab*rab*rab;
+
+ double erep = (1.07 * R_AB) / (rab + 0.07 * R_AB); //***
+ double erep7 = erep*erep*erep*erep*erep*erep*erep;
+
+ double eattr = (((1.12 * R_AB7) / (rab7 + 0.12 * R_AB7)) - 2.0);
+
+ energy = epsilon * erep7 * eattr;
+
+ if (gradients) {
+ const double q = rab / R_AB;
+ const double q6 = q*q*q*q*q*q;
+ const double q7 = q6 * q;
+ erep = 1.07 / (q + 0.07);
+ erep7 = erep*erep*erep*erep*erep*erep*erep;
+ const double term = q7 + 0.12;
+ const double term2 = term * term;
+ eattr = (-7.84 * q6) / term2 + ((-7.84 / term) + 14) / (q + 0.07);
+ const double dE = (epsilon / R_AB) * erep7 * eattr;
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_VDW()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nV A N D E R W A A L S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij R*IJ EPSILON ENERGY\n");
+ OBFFLog("--------------------------------------------------\n");
+ // XX XX -000.000 -000.000 -000.000 -000.000
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _vdwcalculations.size(); ++i) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_vdwpairs.BitIsSet(i))
+ continue;
+
+ _vdwcalculations[i].template Compute<gradients>();
+ energy += _vdwcalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_vdwcalculations[i].force_a, _vdwcalculations[i].idx_a);
+ AddGradient(_vdwcalculations[i].force_b, _vdwcalculations[i].idx_b);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %8.3f %8.3f %8.3f %8.3f\n",
+ atoi(_vdwcalculations[i].a->GetType()), atoi(_vdwcalculations[i].b->GetType()),
+ _vdwcalculations[i].rab, _vdwcalculations[i].R_AB, _vdwcalculations[i].epsilon, _vdwcalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _vdwcalculations.size(); ++i) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_vdwpairs.BitIsSet(i))
+ continue;
+
+ if (gradients) {
+ AddGradient(_vdwcalculations[i].force_a, _vdwcalculations[i].idx_a);
+ AddGradient(_vdwcalculations[i].force_b, _vdwcalculations[i].idx_b);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL VAN DER WAALS ENERGY = %8.5f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ template<bool gradients>
+ inline void OBFFElectrostaticCalculationMMFF94::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ if (gradients) {
+ rab = OBForceField::VectorDistanceDerivative(pos_a, pos_b, force_a, force_b);
+ rab += 0.05; // ??
+ const double rab2 = rab * rab;
+ const double dE = -qq / rab2;
+ OBForceField::VectorSelfMultiply(force_a, dE);
+ OBForceField::VectorSelfMultiply(force_b, dE);
+ } else {
+ rab = OBForceField::VectorDistance(pos_a, pos_b);
+ rab += 0.05; // ??
+ }
+
+ energy = qq / rab;
+ }
+
+ template<bool gradients>
+ double OBForceFieldMMFF94::E_Electrostatic()
+ {
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nE L E C T R O S T A T I C I N T E R A C T I O N S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij Qi Qj ENERGY\n");
+ OBFFLog("-----------------------------------------------------\n");
+ // XX XX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
+ }
+
+ #ifdef _OPENMP
+ #pragma omp parallel for reduction(+:energy)
+ #endif
+ for (int i = 0; i < _electrostaticcalculations.size(); ++i) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_elepairs.BitIsSet(i))
+ continue;
+
+ _electrostaticcalculations[i].template Compute<gradients>();
+ energy += _electrostaticcalculations[i].energy;
+
+ #ifndef _OPENMP
+ if (gradients) {
+ AddGradient(_electrostaticcalculations[i].force_a, _electrostaticcalculations[i].idx_a);
+ AddGradient(_electrostaticcalculations[i].force_b, _electrostaticcalculations[i].idx_b);
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %2d %8.3f %8.3f %8.3f %8.3f\n",
+ atoi(_electrostaticcalculations[i].a->GetType()), atoi(_electrostaticcalculations[i].b->GetType()),
+ _electrostaticcalculations[i].rab, _electrostaticcalculations[i].a->GetPartialCharge(),
+ _electrostaticcalculations[i].b->GetPartialCharge(), _electrostaticcalculations[i].energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ #ifdef _OPENMP
+ for (int i = 0; i < _electrostaticcalculations.size(); ++i) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_elepairs.BitIsSet(i))
+ continue;
+
+ if (gradients) {
+ AddGradient(_electrostaticcalculations[i].force_a, _electrostaticcalculations[i].idx_a);
+ AddGradient(_electrostaticcalculations[i].force_b, _electrostaticcalculations[i].idx_b);
+ }
+ }
+ #endif
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ELECTROSTATIC ENERGY = %8.5f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ //
+ // OBForceFieldMMFF member functions
+ //
+ //***********************************************
+ //Make a global instance
+ OBForceFieldMMFF94 theForceFieldMMFF94("MMFF94", false);
+ OBForceFieldMMFF94 theForceFieldMMFF94s("MMFF94s", false);
+ //***********************************************
+
+ OBForceFieldMMFF94::~OBForceFieldMMFF94()
+ {
+ }
+
+ OBForceFieldMMFF94 &OBForceFieldMMFF94::operator=(OBForceFieldMMFF94 &src)
+ {
+ _mol = src._mol;
+ _init = src._init;
+ return *this;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Parse parameter files
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ bool OBForceFieldMMFF94::ParseParamFile()
+ {
+ // Set the locale for number parsing to avoid locale issues: PR#1785463
+ obLocale.SetLocale();
+
+ vector<string> vs;
+ char buffer[80];
+
+ // open data/_parFile
+ ifstream ifs;
+ if (OpenDatafile(ifs, _parFile).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open parameter file", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "#", 1)) continue;
+
+ tokenize(vs, buffer);
+ if (vs.size() < 2)
+ continue;
+
+ if (vs[0] == "prop")
+ ParseParamProp(vs[1]);
+ if (vs[0] == "def")
+ ParseParamDef(vs[1]);
+ if (vs[0] == "bond")
+ ParseParamBond(vs[1]);
+ if (vs[0] == "ang")
+ ParseParamAngle(vs[1]);
+ if (vs[0] == "bndk")
+ ParseParamBndk(vs[1]);
+ if (vs[0] == "chg")
+ ParseParamCharge(vs[1]);
+ if (vs[0] == "dfsb")
+ ParseParamDfsb(vs[1]);
+ if (vs[0] == "oop")
+ ParseParamOOP(vs[1]);
+ if (vs[0] == "pbci")
+ ParseParamPbci(vs[1]);
+ if (vs[0] == "stbn")
+ ParseParamStrBnd(vs[1]);
+ if (vs[0] == "tor")
+ ParseParamTorsion(vs[1]);
+ if (vs[0] == "vdw")
+ ParseParamVDW(vs[1]);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ // return the locale to the original one
+ obLocale.RestoreLocale();
+ return true;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamBond(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffbond.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffbond.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[0].c_str())); // FF class
+ parameter.a = atoi(vs[1].c_str());
+ parameter.b = atoi(vs[2].c_str());
+ parameter._dpar.push_back(atof(vs[3].c_str())); // kb
+ parameter._dpar.push_back(atof(vs[4].c_str())); // r0
+ _ffbondparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamBndk(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffbndk.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffbndk.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[0].c_str());
+ parameter.b = atoi(vs[1].c_str());
+ parameter._dpar.push_back(atof(vs[2].c_str())); // r0-ref
+ parameter._dpar.push_back(atof(vs[3].c_str())); // kb-ref
+ _ffbndkparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamAngle(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffang.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffang.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[0].c_str())); // FF class
+ parameter.a = atoi(vs[1].c_str());
+ parameter.b = atoi(vs[2].c_str());
+ parameter.c = atoi(vs[3].c_str());
+ parameter._dpar.push_back(atof(vs[4].c_str())); // ka
+ parameter._dpar.push_back(atof(vs[5].c_str())); // theta0
+ _ffangleparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamStrBnd(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffstbn.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffstbn.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[0].c_str())); // FF class
+ parameter.a = atoi(vs[1].c_str());
+ parameter.b = atoi(vs[2].c_str());
+ parameter.c = atoi(vs[3].c_str());
+ parameter._dpar.push_back(atof(vs[4].c_str())); // kbaIJK
+ parameter._dpar.push_back(atof(vs[5].c_str())); // kbaKJI
+ _ffstrbndparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamDfsb(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffdfsb.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffdfsb.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[0].c_str());
+ parameter.b = atoi(vs[1].c_str());
+ parameter.c = atoi(vs[2].c_str());
+ parameter._dpar.push_back(atof(vs[3].c_str())); // kbaIJK
+ parameter._dpar.push_back(atof(vs[4].c_str())); // kbaKJI
+ _ffdfsbparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamOOP(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffoop.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffoop.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[0].c_str());
+ parameter.b = atoi(vs[1].c_str());
+ parameter.c = atoi(vs[2].c_str());
+ parameter.d = atoi(vs[3].c_str());
+ parameter._dpar.push_back(atof(vs[4].c_str())); // koop
+ _ffoopparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamTorsion(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmfftor.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmfftor.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[0].c_str())); // FF class
+ parameter.a = atoi(vs[1].c_str());
+ parameter.b = atoi(vs[2].c_str());
+ parameter.c = atoi(vs[3].c_str());
+ parameter.d = atoi(vs[4].c_str());
+ parameter._dpar.push_back(atof(vs[5].c_str())); // v1
+ parameter._dpar.push_back(atof(vs[6].c_str())); // v2
+ parameter._dpar.push_back(atof(vs[7].c_str())); // v3
+ _fftorsionparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamVDW(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffvdw.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffvdw.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[0].c_str());
+ parameter._dpar.push_back(atof(vs[1].c_str())); // alpha-i
+ parameter._dpar.push_back(atof(vs[2].c_str())); // N-i
+ parameter._dpar.push_back(atof(vs[3].c_str())); // A-i
+ parameter._dpar.push_back(atof(vs[4].c_str())); // G-i
+ if (EQn(vs[5].c_str(), "-", 1))
+ parameter._ipar.push_back(0);
+ else if (EQn(vs[5].c_str(), "D", 1))
+ parameter._ipar.push_back(1); // hydrogen bond donor
+ else if (EQn(vs[5].c_str(), "A", 1))
+ parameter._ipar.push_back(2); // hydrogen bond acceptor
+ _ffvdwparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamCharge(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffchg.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffchg.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[0].c_str())); // FF class
+ parameter.a = atoi(vs[1].c_str());
+ parameter.b = atoi(vs[2].c_str());
+ parameter._dpar.push_back(atof(vs[3].c_str())); // bci
+ _ffchgparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamPbci(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffpbci.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffpbci", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[1].c_str());
+ parameter._dpar.push_back(atof(vs[2].c_str())); // pbci
+ parameter._dpar.push_back(atof(vs[3].c_str())); // fcadj
+ _ffpbciparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamProp(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffprop.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffprop.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter.a = atoi(vs[0].c_str()); // atom type
+ parameter._ipar.push_back(atoi(vs[1].c_str())); // at.no
+ parameter._ipar.push_back(atoi(vs[2].c_str())); // crd
+ parameter._ipar.push_back(atoi(vs[3].c_str())); // val
+ parameter._ipar.push_back(atoi(vs[4].c_str())); // pilp
+ parameter._ipar.push_back(atoi(vs[5].c_str())); // mltb
+ parameter._ipar.push_back(atoi(vs[6].c_str())); // arom
+ parameter._ipar.push_back(atoi(vs[7].c_str())); // linh
+ parameter._ipar.push_back(atoi(vs[8].c_str())); // sbmb
+
+ if (parameter._ipar[3])
+ _ffpropPilp.SetBitOn(parameter.a);
+ if (parameter._ipar[5])
+ _ffpropArom.SetBitOn(parameter.a);
+ if (parameter._ipar[6])
+ _ffpropLin.SetBitOn(parameter.a);
+ if (parameter._ipar[7])
+ _ffpropSbmb.SetBitOn(parameter.a);
+
+ _ffpropparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::ParseParamDef(std::string &filename)
+ {
+ vector<string> vs;
+ char buffer[80];
+
+ OBFFParameter parameter;
+
+ // open data/mmffdef.par
+ ifstream ifs;
+ if (OpenDatafile(ifs, filename).length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open mmffdef.par", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, 80)) {
+ if (EQn(buffer, "*", 1)) continue;
+ if (EQn(buffer, "$", 1)) continue;
+
+ tokenize(vs, buffer);
+
+ parameter.clear();
+ parameter._ipar.push_back(atoi(vs[1].c_str())); // level 1
+ parameter._ipar.push_back(atoi(vs[2].c_str())); // level 2
+ parameter._ipar.push_back(atoi(vs[3].c_str())); // level 3
+ parameter._ipar.push_back(atoi(vs[4].c_str())); // level 4
+ parameter._ipar.push_back(atoi(vs[5].c_str())); // level 5
+ _ffdefparams.push_back(parameter);
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return 0;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Setup Functions
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // The MMFF94 article doesn't seem to include information about how
+ // aromaticity is perceived. This function was written by studying the
+ // MMFF_opti.log file, trail-and-error and using the MMFF94 validation
+ // set to check the results (If all atom types are assigned correctly,
+ // aromatic rings are probably detected correctly)
+ bool OBForceFieldMMFF94::PerceiveAromatic()
+ {
+ bool done = false; // not done actually....
+ OBAtom *ringatom;
+ OBBond *ringbond;
+ vector<OBRing*> vr;
+ vr = _mol.GetSSSR();
+
+ vector<OBRing*>::iterator ri;
+ vector<int>::iterator rj;
+ int n, index, ringsize, first_rj, prev_rj, pi_electrons;
+ for (ri = vr.begin();ri != vr.end();++ri) { // for each ring
+ ringsize = (*ri)->Size();
+
+ n = 1;
+ pi_electrons = 0;
+ for(rj = (*ri)->_path.begin();rj != (*ri)->_path.end();rj++) { // for each ring atom
+ index = *rj;
+ ringatom = _mol.GetAtom(index);
+
+ // is the bond to the previous ring atom double?
+ if (n > 1) {
+ ringbond = _mol.GetBond(prev_rj, index);
+ if (!ringbond) {
+ prev_rj = index;
+ continue;
+ }
+ if (ringbond->GetBO() == 2) {
+ pi_electrons += 2;
+ prev_rj = index;
+ n++;
+ continue;
+ }
+ prev_rj = index;
+ } else {
+ prev_rj = index;
+ first_rj = index;
+ }
+
+ // does the current ring atom have a exocyclic double bond?
+ FOR_NBORS_OF_ATOM (nbr, ringatom) {
+ if ((*ri)->IsInRing(nbr->GetIdx()))
+ continue;
+
+ if (!nbr->IsAromatic())
+ continue;
+
+ ringbond = _mol.GetBond(nbr->GetIdx(), index);
+ if (!ringbond) {
+ continue;
+ }
+ if (ringbond->GetBO() == 2)
+ pi_electrons++;
+ }
+
+ // is the atom N, O or S in 5 rings
+ if (ringsize == 5 &&
+ ringatom->GetIdx() == (*ri)->GetRootAtom())
+ pi_electrons += 2;
+
+ n++;
+
+ } // for each ring atom
+
+ // is the bond from the first to the last atom double?
+ ringbond = _mol.GetBond(first_rj, index);
+ if (ringbond) {
+ if (ringbond->GetBO() == 2)
+ pi_electrons += 2;
+ }
+
+ if ((pi_electrons == 6) && ((ringsize == 5) || (ringsize == 6))) {
+ // mark ring atoms as aromatic
+ for(rj = (*ri)->_path.begin();rj != (*ri)->_path.end();rj++) {
+ if (!_mol.GetAtom(*rj)->IsAromatic())
+ done = true;
+ _mol.GetAtom(*rj)->SetAromatic();
+ }
+ // mark all ring bonds as aromatic
+ FOR_BONDS_OF_MOL (bond, _mol)
+ if((*ri)->IsMember(&*bond))
+ bond->SetAromatic();
+ }
+ }
+
+ return done;
+ }
+
+ // Symbolic atom typing is skipped
+ //
+ // atom typing is based on:
+ // MMFF94 I - Table III
+ // MMFF94 V - Table I
+ //
+ int OBForceFieldMMFF94::GetType(OBAtom *atom)
+ {
+ OBBond *bond;
+ int oxygenCount, nitrogenCount, sulphurCount, doubleBondTo;
+ ////////////////////////////////
+ // Aromatic Atoms
+ ////////////////////////////////
+ if (atom->IsAromatic()) {
+ if (atom->IsInRingSize(5)) {
+ bool IsAromatic = false;
+ vector<OBAtom*> alphaPos, betaPos;
+ vector<OBAtom*> alphaAtoms, betaAtoms;
+
+ if (atom->IsSulfur()) {
+ return 44; // Aromatic 5-ring sulfur with pi lone pair (STHI)
+ }
+ if (atom->IsOxygen()) {
+ return 59; // Aromatic 5-ring oxygen with pi lone pair (OFUR)
+ }
+ if (atom->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 82; // N-oxide nitrogen in 5-ring alpha position,
+ // N-oxide nitrogen in 5-ring beta position,
+ // N-oxide nitrogen in other 5-ring position,
+ // (N5AX, N5BX, N5OX)
+ }
+ }
+ }
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (!((_mol.GetBond(atom, &*nbr))->IsAromatic()) || !nbr->IsInRingSize(5))
+ continue;
+
+ if (IsInSameRing(atom, &*nbr)) {
+ alphaPos.push_back(&*nbr);
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->GetIdx() == atom->GetIdx())
+ continue;
+ if (!((_mol.GetBond(&*nbr, &*nbrNbr))->IsAromatic()) || !nbrNbr->IsInRingSize(5))
+ continue;
+
+ IsAromatic = true;
+
+ if (IsInSameRing(atom, &*nbrNbr)) {
+ betaPos.push_back(&*nbrNbr);
+ }
+ }
+ }
+
+ if (IsAromatic) {
+
+
+ for (unsigned int i = 0; i < alphaPos.size(); i++) {
+ if (alphaPos[i]->IsSulfur()) {
+ alphaAtoms.push_back(alphaPos[i]);
+ } else if (alphaPos[i]->IsOxygen()) {
+ alphaAtoms.push_back(alphaPos[i]);
+ } else if (alphaPos[i]->IsNitrogen() && (alphaPos[i]->GetValence() == 3)) {
+ bool IsNOxide = false;
+ FOR_NBORS_OF_ATOM (nbr, alphaPos[i]) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ IsNOxide = true;
+ }
+ }
+
+ if (!IsNOxide) {
+ alphaAtoms.push_back(alphaPos[i]);
+ }
+ }
+ }
+ for (unsigned int i = 0; i < betaPos.size(); i++) {
+ if (betaPos[i]->IsSulfur()) {
+ betaAtoms.push_back(betaPos[i]);
+ } else if (betaPos[i]->IsOxygen()) {
+ betaAtoms.push_back(betaPos[i]);
+ } else if (betaPos[i]->IsNitrogen() && (betaPos[i]->GetValence() == 3)) {
+ bool IsNOxide = false;
+ FOR_NBORS_OF_ATOM (nbr, betaPos[i]) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ IsNOxide = true;
+ }
+ }
+
+ if (!IsNOxide) {
+ betaAtoms.push_back(betaPos[i]);
+ }
+ }
+ }
+ if (!betaAtoms.size()) {
+ nitrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsNitrogen() && (nbr->GetValence() == 3)) {
+ if ((nbr->BOSum() == 4) && nbr->IsAromatic()) {
+ nitrogenCount++;
+ } else if ((nbr->BOSum() == 3) && !nbr->IsAromatic()) {
+ nitrogenCount++;
+ }
+ }
+ }
+ if (nitrogenCount >= 2) {
+ return 80; // Aromatic carbon between N's in imidazolium (CIM+)
+ }
+ }
+ if (!alphaAtoms.size() && !betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ // there is no S:, O:, or N:
+ // this is the case for anions with only carbon and nitrogen in the ring
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ // this is the N: atom
+ return 39; // Aromatic 5 ring nitrogen with pi lone pair (NPYL)
+ } else {
+ // again, no S:, O:, or N:
+ return 76; // Nitrogen in 5-ring aromatic anion (N5M)
+ }
+ }
+ }
+ if (alphaAtoms.size() == 2) {
+ if (atom->IsCarbon() && IsInSameRing(alphaAtoms[0], alphaAtoms[1])) {
+ if (alphaAtoms[0]->IsNitrogen() && alphaAtoms[1]->IsNitrogen()) {
+ if ((alphaAtoms[0]->GetValence() == 3) && (alphaAtoms[1]->GetValence() == 3)) {
+ return 80; // Aromatic carbon between N's in imidazolium (CIM+)
+ }
+ }
+ }
+ }
+ if (alphaAtoms.size() && !betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ return 63; // Aromatic 5-ring C, alpha to N:, O:, or S: (C5A)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ return 81; // Posivite nitrogen in 5-ring alpha position (N5A+)
+ } else {
+ return 65; // Aromatic 5-ring N, alpha to N:, O:, or S: (N5A)
+ }
+ }
+ }
+ if (!alphaAtoms.size() && betaAtoms.size()) {
+ if (atom->IsCarbon()) {
+ return 64; // Aromatic 5-ring C, beta to N:, O:, or S: (C5B)
+ } else if (atom->IsNitrogen()) {
+ if (atom->GetValence() == 3) {
+ return 81; // Posivite nitrogen in 5-ring beta position (N5B+)
+ } else {
+ return 66; // Aromatic 5-ring N, beta to N:, O:, or S: (N5B)
+ }
+ }
+ }
+ if (alphaAtoms.size() && betaAtoms.size()) {
+ for (unsigned int i = 0; i < alphaAtoms.size(); i++) {
+ for (unsigned int j = 0; j < betaAtoms.size(); j++) {
+ if (!IsInSameRing(alphaAtoms[i], betaAtoms[j])) {
+ if (atom->IsCarbon()) {
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ return 79; // General nitrogen in 5-membered aromatic ring (N5)
+ }
+ }
+ }
+ }
+ for (unsigned int i = 0; i < alphaAtoms.size(); i++) {
+ if (alphaAtoms[i]->IsSulfur() || alphaAtoms[i]->IsOxygen()) {
+ if (atom->IsCarbon()) {
+ return 63; // Aromatic 5-ring C, alpha to N:, O:, or S: (C5A)
+ } else if (atom->IsNitrogen()) {
+ return 65; // Aromatic 5-ring N, alpha to N:, O:, or S: (N5A)
+ }
+ }
+ }
+ for (unsigned int i = 0; i < betaAtoms.size(); i++) {
+ if (betaAtoms[i]->IsSulfur() || betaAtoms[i]->IsOxygen()) {
+ if (atom->IsCarbon()) {
+ return 64; // Aromatic 5-ring C, beta to N:, O:, or S: (C5B)
+ } else if (atom->IsNitrogen()) {
+ return 66; // Aromatic 5-ring N, beta to N:, O:, or S: (N5B)
+ }
+ }
+ }
+
+ if (atom->IsCarbon()) {
+ return 78; // General carbon in 5-membered aromatic ring (C5)
+ } else if (atom->IsNitrogen()) {
+ return 79; // General nitrogen in 5-membered aromatic ring (N5)
+ }
+ }
+ }
+ }
+
+ if (atom->IsInRingSize(6)) {
+
+ if (atom->IsCarbon()) {
+ return 37; // Aromatic carbon, e.g., in benzene (CB)
+ } else if (atom->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 69; // Pyridinium N-oxide nitrogen (NPOX)
+ }
+ }
+
+ if (atom->GetValence() == 3) {
+ return 58; // Aromatic nitrogen in pyridinium (NPD+)
+ } else {
+ return 38; // Aromatic nitrogen with sigma lone pair (NPYD)
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Hydrogen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 1) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ return 5; // Hydrogen attatched to carbon (HC)
+ }
+ if (nbr->GetAtomicNum() == 14) {
+ return 5; // Hydrogen attatched to silicon (HSI)
+ }
+ if (nbr->IsOxygen()) {
+ if (nbr->BOSum() == 3) {
+ if (nbr->GetValence() == 3) {
+ return 50; // Hydrogen on oxonium oxygen (HO+)
+ } else {
+ return 52; // Hydrogen on oxenium oxygen (HO=+)
+ }
+ }
+
+ int hydrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen()) {
+ hydrogenCount++;
+ continue;
+ }
+ if (nbrNbr->IsCarbon()) {
+ if (nbrNbr->IsAromatic()) {
+ return 29; // phenol
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = _mol.GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsOxygen()) {
+ return 24; // Hydroxyl hydrogen in carboxylic acids (HOCO)
+ }
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen()) {
+ return 29; // Enolic or phenolic hydroxyl hydrogen,
+ // Hydroxyl hydrogen in HO-C=N moiety (HOCC, HOCN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsPhosphorus()) {
+ return 24; // Hydroxyl hydrogen in H-O-P moiety (HOP)
+ }
+ if (nbrNbr->IsSulfur()) {
+ return 33; // Hydrogen on oxygen attached to sulfur (HOS)
+ }
+
+ }
+ if (hydrogenCount == 2) {
+ return 31; // Hydroxyl hydrogen in water (HOH)
+ }
+
+ return 21; // Hydroxyl hydrogen in alcohols, Generic hydroxyl hydrogen (HOR, HO)
+ }
+ if (nbr->IsNitrogen()) {
+ switch (GetType(&*nbr)) {
+ case 81:
+ return 36; // Hydrogen on imidazolium nitrogen (HIM+)
+ case 68:
+ return 23; // Hydrogen on N in N-oxide (HNOX)
+ case 67:
+ return 23; // Hydrogen on N in N-oxide (HNOX)
+ case 62:
+ return 23; // Generic hydrogen on sp3 nitrogen, e.g., in amines (HNR)
+ case 56:
+ return 36; // Hydrogen on guanimdinium nitrogen (HGD+)
+ case 55:
+ return 36; // Hydrogen on amidinium nitrogen (HNN+)
+ case 43:
+ return 28; // Hydrogen on NSO, NSO2, or NSO3 nitrogen, Hydrogen on N triply bonded to C (HNSO, HNC%)
+ case 39:
+ return 23; // Hydrogen on nitrogen in pyrrole (HPYL)
+ case 8:
+ return 23; // Generic hydrogen on sp3 nitrogen, e.g., in amines, Hydrogen on nitrogen in ammonia (HNR, H3N)
+ }
+
+ if (nbr->BOSum() == 4) {
+ if (nbr->GetValence() == 2) {
+ return 28; // Hydrogen on N triply bonded to C (HNC%)
+ } else {
+ return 36; // Hydrogen on pyridinium nitrogen, Hydrogen on protonated imine nitrogen (HPD+, HNC+)
+ }
+ }
+
+ if (nbr->GetValence() == 2) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen())
+ continue;
+
+ bond = _mol.GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbr->IsCarbon() || nbrNbr->IsNitrogen()) {
+ return 27; // Hydrogen on imine nitrogen, Hydrogen on azo nitrogen (HN=C, HN=N)
+ }
+
+ return 28; // Generic hydrogen on sp2 nitrogen (HSP2)
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsHydrogen())
+ continue;
+
+ if (nbrNbr->IsCarbon()) {
+ if (nbrNbr->IsAromatic()) {
+ return 28; // deloc. lp pair
+ }
+
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = _mol.GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen() || nbrNbrNbr->IsOxygen() || nbrNbrNbr->IsSulfur()) {
+ return 28; // Hydrogen on amide nitrogen, Hydrogen on thioamide nitrogen,
+ // Hydrogen on enamine nitrogen, Hydrogen in H-N-C=N moiety (HNCO, HNCS, HNCC, HNCN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ bond = _mol.GetBond(&*nbrNbr, &*nbrNbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbrNbr->IsCarbon() || nbrNbrNbr->IsNitrogen()) {
+ return 28; // Hydrogen in H-N-N=C moiety, Hydrogen in H-N-N=N moiety (HNNC, HNNN)
+ }
+ }
+ }
+ }
+ if (nbrNbr->IsSulfur()) {
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->GetIdx() == nbr->GetIdx())
+ continue;
+
+ if (nbrNbrNbr->IsOxygen() || (nbrNbrNbr->GetValence() == 1)) {
+ return 28; // Hydrogen on NSO, NSO2 or NSO3 nitrogen (HNSO)
+ }
+ }
+ }
+ }
+
+ return 23; // Generic hydrogen on sp3 nitrogen e.g., in amines,
+ // Hydrogen on nitrogen in pyrrole, Hydrogen in ammonia,
+ // Hydrogen on N in N-oxide (HNR, HPYL, H3N, HNOX)
+ }
+ if (nbr->IsSulfur() || nbr->IsPhosphorus()) {
+ return 71; // Hydrogen attached to sulfur, Hydrogen attached to >S= sulfur doubly bonded to N,
+ // Hydrogen attached to phosphorus (HS, HS=N, HP)
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Lithium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 3) {
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 92; // Lithium cation (LI+)
+ }
+ }
+
+ ////////////////////////////////
+ // Carbon
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 6) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ if (atom->IsInRingSize(3)) {
+ return 22; // Aliphatic carbon in 3-membered ring (CR3R)
+ }
+
+ if (atom->IsInRingSize(4)) {
+ return 20; // Aliphatic carbon in 4-membered ring (CR4R)
+ }
+
+ return 1; // Alkyl carbon (CR)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ int N2count = 0;
+ int N3count = 0;
+ oxygenCount = sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+
+ if (nbr->GetValence() == 1) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ } else if (nbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ } else if (nbr->GetValence() == 3) {
+ if (nbr->IsNitrogen()) {
+ N3count++;
+ }
+ } else if ((nbr->GetValence() == 2) && bond->IsDouble()) {
+ if (nbr->IsNitrogen()) {
+ N2count++;
+ }
+ }
+ }
+ if ((N3count >= 2) && (doubleBondTo == 7) && !N2count) {
+ // N3==C--N3
+ return 57; // Guanidinium carbon, Carbon in +N=C-N: resonance structures (CGD+, CNN+)
+ }
+ if ((oxygenCount == 2) || (sulphurCount == 2)) {
+ // O1-?-C-?-O1 or S1-?-C-?-S1
+ return 41; // Carbon in carboxylate anion, Carbon in thiocarboxylate anion (CO2M, CS2M)
+ }
+ if (atom->IsInRingSize(4) && (doubleBondTo == 6)) {
+ return 30; // Olefinic carbon in 4-membered ring (CR4E)
+ }
+ if ((doubleBondTo == 7) || (doubleBondTo == 8) ||
+ (doubleBondTo == 15) || (doubleBondTo == 16)) {
+ // C==N, C==O, C==P, C==S
+ return 3; // Generic carbonyl carbon, Imine-type carbon, Guanidine carbon,
+ // Ketone or aldehyde carbonyl carbon, Amide carbonyl carbon,
+ // Carboxylic acid or ester carbonyl carbon, Carbamate carbonyl carbon,
+ // Carbonic acid or ester carbonyl carbon, Thioester carbonyl (double
+ // bonded to O or S), Thioamide carbon (double bonded to S), Carbon
+ // in >C=SO2, Sulfinyl carbon in >C=S=O, Thiocarboxylic acid or ester
+ // carbon, Carbon doubly bonded to P (C=O, C=N, CGD, C=OR, C=ON, COO,
+ // COON, COOO, C=OS, C=S, C=SN, CSO2, CS=O, CSS, C=P)
+ }
+
+ return 2; // Vinylic Carbon, Generic sp2 carbon (C=C, CSP2)
+
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ return 4; // Acetylenic carbon, Allenic caron (CSP, =C=)
+ }
+ // 1 neighbours
+ if (atom->GetValence() == 1) {
+ return 60; // Isonitrile carbon (C%-)
+ }
+ }
+
+ ////////////////////////////////
+ // Nitrogen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 7) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ return 68; // sp3-hybridized N-oxide nitrogen (N3OX)
+ }
+ }
+
+ return 34; // Quaternary nitrogen (NR+)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ if (atom->BOSum() == 4) {
+ oxygenCount = nitrogenCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen() && (nbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ if (nbr->IsNitrogen()) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = 7;
+ }
+ }
+ if (nbr->IsCarbon()) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 3)) {
+ nitrogenCount++;
+ }
+ }
+ }
+ }
+ }
+
+ if (oxygenCount == 1) {
+ return 67; // sp2-hybridized N-oxide nitrogen (N2OX)
+ }
+ if (oxygenCount >= 2) {
+ return 45; // Nitrogen in nitro group, Nitrogen in nitrate group (NO2, NO3)
+ }
+
+ if (nitrogenCount == 1) {
+ return 54; // Iminium nitrogen (N+=C)
+ }
+ if (nitrogenCount == 2) {
+ return 55; // Either nitrogen in N+=C-N: (NCN+)
+ }
+ if (nitrogenCount == 3) {
+ return 56; // Guanidinium nitrogen (NGD+)
+ }
+
+ if (doubleBondTo == 7) {
+ return 54; // Positivly charged nitrogen doubly bonded to nitrogen (N+=N)
+ }
+ }
+
+ if (atom->BOSum() == 3) {
+ bool IsAmide = false;
+ bool IsSulfonAmide = false;
+ bool IsNNNorNNC = false;
+ int tripleBondTo = 0;
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur() || nbr->IsPhosphorus()) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount >= 2) {
+ IsSulfonAmide = true;
+ //return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = _mol.GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble() && (nbrNbr->IsOxygen() || nbrNbr->IsSulfur())) {
+ IsAmide = true;
+ //return 10; // Amide nitrogen, Thioamide nitrogen (NC=O, NC=S)
+ }
+ }
+ }
+ }
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsCarbon()) {
+ int N2count = 0;
+ int N3count = 0;
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = _mol.GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbrNbr->GetAtomicNum();
+ }
+ if (bond->IsAromatic()) {
+ if ((nbrNbr->GetAtomicNum() == 7) || (nbrNbr->GetAtomicNum() == 6)) {
+ doubleBondTo = nbrNbr->GetAtomicNum();
+ }
+ }
+ if (bond->IsTriple()) {
+ tripleBondTo = nbrNbr->GetAtomicNum();
+ }
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 3)) {
+ int nbrOxygen = 0;
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->IsOxygen()) {
+ nbrOxygen++;
+ }
+ }
+ if (nbrOxygen < 2) {
+ N3count++;
+ }
+ }
+ if (nbrNbr->IsNitrogen() && (nbrNbr->GetValence() == 2) && (bond->IsDouble() || bond->IsAromatic())) {
+ N2count++;
+ }
+ if (nbrNbr->IsAromatic()) {
+ if (nbrNbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ if (nbrNbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ }
+ }
+ if (N3count == 3) {
+ return 56; // Guanidinium nitrogen (NGD+)
+ }
+
+ if (!IsAmide && !IsSulfonAmide && !oxygenCount && !sulphurCount && nbr->IsAromatic()) {
+ return 40;
+ }
+
+ if ((N3count == 2) && (doubleBondTo == 7) && !N2count) {
+ return 55; // Either nitrogen in N+=C-N: (NCN+)
+ }
+ }
+
+ if (nbr->IsNitrogen()) {
+ nitrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ bond = _mol.GetBond(&*nbr, &*nbrNbr);
+ if (bond->IsDouble()) {
+ if (nbrNbr->IsCarbon()) {
+ oxygenCount = sulphurCount = 0;
+ FOR_NBORS_OF_ATOM (nbrNbrNbr, &*nbrNbr) {
+ if (nbrNbrNbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ if (nbrNbrNbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ if (nbrNbrNbr->IsSulfur()) {
+ nitrogenCount++;
+ }
+ }
+ if (!oxygenCount && !sulphurCount && (nitrogenCount == 1)) {
+ bool bondToAromC = false;
+ FOR_NBORS_OF_ATOM (nbr2, atom) {
+ if (nbr2->IsAromatic() && nbr2->IsCarbon() && nbr2->IsInRingSize(6)) {
+ bondToAromC = true;
+ }
+ }
+ if (!bondToAromC) {
+ IsNNNorNNC = true;
+ }
+ }
+ }
+ if (nbrNbr->IsNitrogen()) {
+ bool bondToAromC = false;
+ FOR_NBORS_OF_ATOM (nbr2, atom) {
+ if (nbr2->IsAromatic() && nbr2->IsCarbon() && nbr2->IsInRingSize(6)) {
+ bondToAromC = true;
+ }
+ }
+ if (!bondToAromC) {
+ IsNNNorNNC = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (IsSulfonAmide) {
+ return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ if (IsAmide) {
+ return 10; // Amide nitrogen, Thioamide nitrogen (NC=O, NC=S)
+ }
+
+ if ((doubleBondTo == 6) || (doubleBondTo == 7) ||(doubleBondTo == 15) || (tripleBondTo == 6)) {
+ return 40; // Enamine or aniline nitrogen (deloc. lp), Nitrogen in N-C=N with deloc. lp,
+ // Nitrogen in N-C=N with deloc. lp, Nitrogen attached to C-C triple bond
+ // (NC=C, NC=N, NC=P, NC%C)
+ }
+ if (tripleBondTo == 7) {
+ return 43; // Nitrogen attached to cyano group (NC%N)
+ }
+ if (IsNNNorNNC) {
+ return 10; // Nitrogen in N-N=C moiety with deloc. lp
+ // Nitrogen in N-N=N moiety with deloc. lp (NN=C, NN=N)
+ }
+
+ return 8; // Amine nitrogen (NR)
+ }
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ if (atom->BOSum() == 4) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsTriple()) {
+ return 61; // Isonitrile nitrogen (NR%)
+ }
+ }
+
+ return 53; // Central nitrogen in C=N=N or N=N=N (=N=)
+ }
+
+ if (atom->BOSum() == 3) {
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (nbr->IsOxygen() && bond->IsDouble() && (nbr->GetValence() == 1)) {
+ return 46; // Nitrogen in nitroso group (N=O)
+ }
+ if ((nbr->IsCarbon() || nbr->IsNitrogen()) && bond->IsDouble()) {
+ return 9; // Iminie nitrogen, Azo-group nitrogen (N=C, N=N)
+ }
+ }
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur()) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount >= 2) {
+ return 43; // Sulfonamide nitrogen (NSO2, NSO3)
+ }
+ }
+ }
+ }
+
+ if (atom->BOSum() == 2) {
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsSulfur()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount == 1) {
+ return 48; // Divalent nitrogen replacing monovalent O in SO2 group (NSO)
+ }
+ }
+ }
+
+ return 62; // Anionic divalent nitrogen (NM)
+ }
+ }
+ // 1 neighbours
+ if (atom->GetValence() == 1) {
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsTriple()) {
+ return 42; // Triply bonded nitrogen (NSP)
+ }
+ if (nbr->IsNitrogen() && (nbr->GetValence() == 2)) {
+ return 47; // Terminal nitrogen in azido or diazo group (NAZT)
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Oxygen
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 8) {
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ return 49; // Oxonium oxygen (O+)
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ int hydrogenCount = 0;
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsHydrogen()) {
+ hydrogenCount++;
+ }
+ }
+
+ if (hydrogenCount == 2) {
+ // H--O--H
+ return 70; // Oxygen in water (OH2)
+ }
+ if (atom->BOSum() == 3) {
+ return 51; // Oxenium oxygen (O=+)
+ }
+
+ return 6; // Generic divalent oxygen, Ether oxygen, Carboxylic acid or ester oxygen,
+ // Enolic or phenolic oxygen, Oxygen in -O-C=N- moiety, Divalent oxygen in
+ // thioacid or ester, Divalent nitrate "ether" oxygen, Divalent oxygen in
+ // sulfate group, Divalent oxygen in sulfite group, One of two divalent
+ // oxygens attached to sulfur, Divalent oxygen in R(RO)S=O, Other divalent
+ // oxygen attached to sulfur, Divalent oxygen in phosphate group, Divalent
+ // oxygen in phosphite group, Divalent oxygen (one of two oxygens attached
+ // to P), Other divalent oxygen (-O-, OR, OC=O, OC=C, OC=N, OC=S, ONO2,
+ // ON=O, OSO3, OSO2, OSO, OS=O, -OS, OPO3, OPO2, OPO, -OP)
+
+ // 59 ar
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ oxygenCount = sulphurCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+
+ if (nbr->IsCarbon() || nbr->IsNitrogen()) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsOxygen() && (nbrNbr->GetValence() == 1)) {
+ oxygenCount++;
+ }
+ if (nbrNbr->IsSulfur() && (nbrNbr->GetValence() == 1)) {
+ sulphurCount++;
+ }
+ }
+ }
+ // O---H
+ if (nbr->IsHydrogen()) {
+ return 35;
+ }
+ // O-?-C
+ if (nbr->IsCarbon()) {
+ if (oxygenCount == 2) {
+ // O-?-C-?-O
+ return 32; // Oxygen in carboxylate group (O2CM)
+ }
+ if (bond->IsSingle()) {
+ // O--C
+ return 35; // Oxide oxygen on sp3 carbon, Oxide oxygen on sp2 carbon (OM, OM2)
+ } else {
+ // O==C
+ return 7; // Generic carbonyl oxygen, Carbonyl oxygen in amides,
+ // Carbonyl oxygen in aldehydes and ketones, Carbonyl
+ // oxygen in acids or esters (O=C, O=CN, O=CR, O=CO)
+ }
+ }
+ // O-?-N
+ if (nbr->IsNitrogen()) {
+ if (oxygenCount >= 2) {
+ // O-?-N-?-O
+ return 32; // Oxygen in nitro group, Nitro-group oxygen in nitrate,
+ // Nitrate anion oxygen (O2N, O2NO, O3N)
+ }
+ if (bond->IsSingle()) {
+ // O--N
+ return 32; // Oxygen in N-oxides (ONX)
+ } else {
+ // O==N
+ return 7; // Nitroso oxygen (O=N)
+ }
+ }
+ // O-?-S
+ if (nbr->IsSulfur()) {
+ if (sulphurCount == 1) {
+ // O1-?-S-?-S1
+ return 32; // Terminal oxygen in thiosulfinate anion (OSMS)
+ }
+ if (bond->IsSingle()) {
+ // O--S
+ return 32; // Single terminal oxygen on sulfur, One of 2 terminal O's on sulfur,
+ // One of 3 terminal O's on sulfur, Terminal O in sulfate anion,
+ // (O-S, O2S, O3S, O4S)
+ } else {
+ // O==S
+ return 7; // Doubly bonded sulfoxide oxygen, O=S on sulfur doubly bonded
+ // to, e.g., C (O=S, O=S=)
+ }
+ }
+
+ return 32; // Oxygen in phosphine oxide, One of 2 terminal O's on sulfur,
+ // One of 3 terminal O's on sulfur, One of 4 terminal O's on sulfur,
+ // Oxygen in perchlorate anion (OP, O2P, O3P, O4P, O4Cl)
+ }
+ }
+ }
+
+ ////////////////////////////////
+ // Flourine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 9) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 11; // Fluorine (F)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 89; // Fluoride anion (F-)
+ }
+ }
+
+ ////////////////////////////////
+ // Sodium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 11) {
+ return 93; // Sodium cation (NA+)
+ }
+
+ ////////////////////////////////
+ // Magnesium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 12) {
+ return 99; // Dipositive magnesium cation (MG+2)
+ }
+
+ ////////////////////////////////
+ // Silicon
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 14) {
+ return 19; // Silicon (SI)
+ }
+
+ ////////////////////////////////
+ // Phosphorus
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 15) {
+ if (atom->GetValence() == 4) {
+ return 25; // Phosphate group phosphorus, Phosphorus with 3 attached oxygens,
+ // Phosphorus with 2 attached oxygens, Phosphine oxide phosphorus,
+ // General tetracoordinate phosphorus (PO4, PO3, PO2, PO, PTET)
+ }
+ if (atom->GetValence() == 3) {
+ return 26; // Phosphorus in phosphines (P)
+ }
+ if (atom->GetValence() == 2) {
+ return 75; // Phosphorus doubly bonded to C (-P=C)
+ }
+ }
+
+ ////////////////////////////////
+ // Sulfur
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 16) {
+ // 4 neighbours
+ if (atom->GetValence() == 4) {
+ return 18; // Sulfone sulfur, Sulfonamide sulfur, Sulfonate group sulfur,
+ // Sulfate group sulfur, Sulfur in nitrogen analog of sulfone
+ // (SO2, SO2N, SO3, SO4, SNO)
+ }
+ // 3 neighbours
+ if (atom->GetValence() == 3) {
+ oxygenCount = sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+
+ if (nbr->GetValence() == 1) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ } else if (nbr->IsSulfur()) {
+ sulphurCount++;
+ }
+ }
+ }
+
+ if (oxygenCount == 2) {
+ if (doubleBondTo == 6) {
+ return 18; // Sulfone sulfur, doubly bonded to carbon (=SO2)
+ }
+ return 73; // Sulfur in anionic sulfinate group (SO2M)
+ }
+ if (oxygenCount && sulphurCount)
+ return 73; // Tricoordinate sulfur in anionic thiosulfinate group (SSOM)
+
+ //if ((doubleBondTo == 6) || (doubleBondTo == 8))
+ return 17; // Sulfur doubly bonded to carbon, Sulfoxide sulfur (S=C, S=O)
+ }
+ // 2 neighbours
+ if (atom->GetValence() == 2) {
+ doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen()) {
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = 8;
+ }
+ }
+ }
+
+ if (doubleBondTo == 8)
+ return 74; // Sulfinyl sulfur, e.g., in C=S=O (=S=O)
+
+ return 15; // Thiol, sulfide, or disulfide sulfor (S)
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ sulphurCount = doubleBondTo = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ FOR_NBORS_OF_ATOM (nbrNbr, &*nbr) {
+ if (nbrNbr->IsSulfur() && (nbrNbr->GetValence() == 1)) {
+ sulphurCount++;
+ }
+ }
+ bond = _mol.GetBond(&*nbr, atom);
+ if (bond->IsDouble()) {
+ doubleBondTo = nbr->GetAtomicNum();
+ }
+ }
+
+ if ((doubleBondTo == 6) && (sulphurCount != 2)) {
+ return 16; // Sulfur doubly bonded to carbon (S=C)
+ }
+
+ return 72; // Terminal sulfur bonded to P, Anionic terminal sulfur,
+ // Terminal sulfur in thiosulfinate group (S-P, SM, SSMO)
+ }
+
+ // 44 ar
+ }
+
+ ////////////////////////////////
+ // Clorine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 17) {
+ // 4 neighbour
+ if (atom->GetValence() == 4) {
+ oxygenCount = 0;
+
+ FOR_NBORS_OF_ATOM (nbr, atom) {
+ if (nbr->IsOxygen()) {
+ oxygenCount++;
+ }
+ }
+ if (oxygenCount == 4)
+ return 77; // Perchlorate anion chlorine (CLO4)
+ }
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 12; // Chlorine (CL)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 90; // Chloride anion (CL-)
+ }
+ }
+
+ ////////////////////////////////
+ // Potasium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 19) {
+ return 94; // Potasium cation (K+)
+ }
+
+ ////////////////////////////////
+ // Calcium
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 20) {
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 96; // Dipositive calcium cation (CA+2)
+ }
+ }
+
+ ////////////////////////////////
+ // Iron
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 26) {
+ return 87; // Dipositive iron (FE+2)
+ return 88; // Tripositive iron (FE+3)
+ }
+
+ ////////////////////////////////
+ // Copper
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 29) {
+ return 97; // Monopositive copper cation (CU+1)
+ return 98; // Dipositive copper cation (CU+2)
+ }
+
+ ////////////////////////////////
+ // Zinc
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 30) {
+ return 95; // Dipositive zinc cation (ZN+2)
+ }
+
+ ////////////////////////////////
+ // Bromine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 35) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 13; // Bromine (BR)
+ }
+ // 0 neighbours
+ if (atom->GetValence() == 0) {
+ return 91; // Bromide anion (BR-)
+ }
+ }
+
+ ////////////////////////////////
+ // Iodine
+ ////////////////////////////////
+ if (atom->GetAtomicNum() == 53) {
+ // 1 neighbour
+ if (atom->GetValence() == 1) {
+ return 14; // Iodine (I)
+ }
+ }
+
+
+
+ return 0;
+ }
+
+ bool OBForceFieldMMFF94::SetTypes()
+ {
+ char type[4];
+
+ _mol.SetAtomTypesPerceived();
+
+ // mark all atoms and bonds as non-aromatic
+ _mol.SetAromaticPerceived();
+ FOR_BONDS_OF_MOL (bond, _mol)
+ bond->UnsetAromatic();
+ FOR_ATOMS_OF_MOL (atom, _mol)
+ atom->UnsetAromatic();
+
+ // It might be needed to run this function more than once...
+ bool done = true;
+ while (done) {
+ done = PerceiveAromatic();
+ }
+
+ FOR_ATOMS_OF_MOL (atom, _mol) {
+ snprintf(type, 3, "%d", GetType(&*atom));
+ atom->SetType(type);
+ }
+
+ PrintTypes();
+
+ return true;
+ }
+
+ bool OBForceFieldMMFF94::SetupCalculations()
+ {
+ OBFFParameter *parameter;
+ OBAtom *a, *b, *c, *d;
+ int type_a, type_b, type_c, type_d;
+ bool found;
+ int order;
+
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("\nS E T T I N G U P C A L C U L A T I O N S\n\n");
+
+ //
+ // ZNBond Calculations
+ //
+ // no "step-down" procedure
+ // MMFF part V - page 625 (empirical rule)
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP BOND CALCULATIONS...\n");
+
+ OBFFBondCalculationMMFF94 bondcalc;
+ int bondtype;
+
+ _bondcalculations.clear();
+
+ FOR_BONDS_OF_MOL(bond, _mol) {
+ a = bond->GetBeginAtom();
+ b = bond->GetEndAtom();
+
+ // skip this bond if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two bond atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validBond = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()))
+ validBond = true;
+ }
+ if (!validBond)
+ continue;
+ }
+
+ bondtype = GetBondType(a, b);
+
+ parameter = GetTypedParameter2Atom(bondtype, atoi(a->GetType()), atoi(b->GetType()), _ffbondparams); // from mmffbond.par
+ if (parameter == NULL) {
+ parameter = GetParameter2Atom(a->GetAtomicNum(), b->GetAtomicNum(), _ffbndkparams); // from mmffbndk.par - emperical rules
+ if (parameter == NULL) {
+ IF_OBFF_LOGLVL_LOW {
+ // This should never happen
+ snprintf(_logbuf, BUFF_SIZE, " COULD NOT FIND PARAMETERS FOR BOND %d-%d (IDX)...\n", a->GetIdx(), b->GetIdx());
+ OBFFLog(_logbuf);
+ }
+ return false;
+ } else {
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR BOND STRETCHING %d-%d (IDX)...\n", a->GetIdx(), b->GetIdx());
+ OBFFLog(_logbuf);
+ }
+
+ double rr, rr2, rr4, rr6;
+ bondcalc.a = a;
+ bondcalc.b = b;
+ bondcalc.r0 = GetRuleBondLength(a, b);
+
+ rr = parameter->_dpar[0] / bondcalc.r0; // parameter->_dpar[0] = r0-ref
+ rr2 = rr * rr;
+ rr4 = rr2 * rr2;
+ rr6 = rr4 * rr2;
+
+ bondcalc.kb = parameter->_dpar[1] * rr6; // parameter->_dpar[1] = kb-ref
+ bondcalc.bt = bondtype;
+ bondcalc.SetupPointers();
+
+ _bondcalculations.push_back(bondcalc);
+ }
+ } else {
+ bondcalc.a = a;
+ bondcalc.b = b;
+ bondcalc.kb = parameter->_dpar[0];
+ bondcalc.r0 = parameter->_dpar[1];
+ bondcalc.bt = bondtype;
+ bondcalc.SetupPointers();
+
+ _bondcalculations.push_back(bondcalc);
+ }
+ }
+
+ //
+ // Angle Calculations
+ //
+ // MMFF part I - page 513 ("step-down" prodedure)
+ // MMFF part I - page 519 (reference 68 is actually a footnote)
+ // MMFF part V - page 627 (empirical rule)
+ //
+ // First try and find an exact match, if this fails, step down using the equivalences from mmffdef.par
+ // five-stage protocol: 1-1-1, 2-2-2, 3-2-3, 4-2-4, 5-2-5
+ // If this fails, use empirical rules
+ // Since 1-1-1 = 2-2-2, we will only try 1-1-1 before going to 3-2-3
+ //
+ // Stretch-Bend Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ANGLE & STRETCH-BEND CALCULATIONS...\n");
+
+ OBFFAngleCalculationMMFF94 anglecalc;
+ OBFFStrBndCalculationMMFF94 strbndcalc;
+ int angletype, strbndtype, bondtype1, bondtype2;
+
+ _anglecalculations.clear();
+ _strbndcalculations.clear();
+
+ FOR_ANGLES_OF_MOL(angle, _mol) {
+ b = _mol.GetAtom((*angle)[0] + 1);
+ a = _mol.GetAtom((*angle)[1] + 1);
+ c = _mol.GetAtom((*angle)[2] + 1);
+
+ type_a = atoi(a->GetType());
+ type_b = atoi(b->GetType());
+ type_c = atoi(c->GetType());
+
+ // skip this angle if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) || _constraints.IsIgnored(c->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the three angle atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validAngle = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()))
+ validAngle = true;
+ }
+ if (!validAngle)
+ continue;
+ }
+
+ angletype = GetAngleType(a, b, c);
+ strbndtype = GetStrBndType(a, b, c);
+ bondtype1 = GetBondType(a, b);
+ bondtype2 = GetBondType(b, c);
+
+ if (HasLinSet(type_b)) {
+ anglecalc.linear = true;
+ } else {
+ anglecalc.linear = false;
+ }
+
+ // try exact match
+ parameter = GetTypedParameter3Atom(angletype, type_a, type_b, type_c, _ffangleparams);
+ if (parameter == NULL) // try 3-2-3
+ parameter = GetTypedParameter3Atom(angletype, EqLvl3(type_a), type_b, EqLvl3(type_c), _ffangleparams);
+ if (parameter == NULL) // try 4-2-4
+ parameter = GetTypedParameter3Atom(angletype, EqLvl4(type_a), type_b, EqLvl4(type_c), _ffangleparams);
+ if (parameter == NULL) // try 5-2-5
+ parameter = GetTypedParameter3Atom(angletype, EqLvl5(type_a), type_b, EqLvl5(type_c), _ffangleparams);
+
+ if (parameter) {
+ anglecalc.ka = parameter->_dpar[0];
+ anglecalc.theta0 = parameter->_dpar[1];
+ strbndcalc.theta0 = parameter->_dpar[1]; // **
+ } else {
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " USING DEFAULT ANGLE FOR %d-%d-%d (IDX)...\n", a->GetIdx(), b->GetIdx(), c->GetIdx());
+ snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR ANGLE BENDING %d-%d-%d (IDX)...\n", a->GetIdx(), b->GetIdx(), c->GetIdx());
+ OBFFLog(_logbuf);
+ }
+
+ anglecalc.ka = 0.0;
+ anglecalc.theta0 = 120.0;
+
+ if (GetCrd(type_b) == 4)
+ anglecalc.theta0 = 109.45;
+
+ if ((GetCrd(type_b) == 2) && b->IsOxygen())
+ anglecalc.theta0 = 105.0;
+
+ if (b->GetAtomicNum() > 10)
+ anglecalc.theta0 = 95.0;
+
+ if (HasLinSet(type_b))
+ anglecalc.theta0 = 180.0;
+
+ if ((GetCrd(type_b) == 3) && (GetVal(type_b) == 3) && !GetMltb(type_b)) {
+ if (b->IsNitrogen()) {
+ anglecalc.theta0 = 107.0;
+ } else {
+ anglecalc.theta0 = 92.0;
+ }
+ }
+
+ if (a->IsInRingSize(3) && b->IsInRingSize(3) && c->IsInRingSize(3) && IsInSameRing(a, c))
+ anglecalc.theta0 = 60.0;
+
+ if (a->IsInRingSize(4) && b->IsInRingSize(4) && c->IsInRingSize(4) && IsInSameRing(a, c))
+ anglecalc.theta0 = 90.0;
+
+ strbndcalc.theta0 = anglecalc.theta0; // **
+ }
+
+ // empirical rule for 0-b-0 and standard angles
+ if (anglecalc.ka == 0.0) {
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR ANGLE BENDING FORCE CONSTANT %d-%d-%d (IDX)...\n", a->GetIdx(), b->GetIdx(), c->GetIdx());
+ OBFFLog(_logbuf);
+ }
+
+ double beta, Za, Zc, Cb, r0ab, r0bc, theta, theta2, D, rr, rr2;
+ Za = GetZParam(a);
+ Cb = GetZParam(b);
+ Zc = GetZParam(c);
+
+ r0ab = GetBondLength(a, b);
+ r0bc = GetBondLength(b, c);
+ rr = r0ab + r0bc;
+ rr2 = rr * rr;
+ D = (r0ab - r0bc) / rr2;
+
+ theta = anglecalc.theta0;
+ theta2 = theta * theta;
+
+ beta = 1.75;
+ if (a->IsInRingSize(4) && b->IsInRingSize(4) && c->IsInRingSize(4) && IsInSameRing(a, c))
+ beta = 0.85 * beta;
+ if (a->IsInRingSize(3) && b->IsInRingSize(3) && c->IsInRingSize(3) && IsInSameRing(a, c))
+ beta = 0.05 * beta;
+
+ anglecalc.ka = (beta * Za * Cb * Zc * exp(-2 * D)) / (rr * theta2);
+ }
+
+ anglecalc.a = a;
+ anglecalc.b = b;
+ anglecalc.c = c;
+ anglecalc.at = angletype;
+
+ anglecalc.SetupPointers();
+ _anglecalculations.push_back(anglecalc);
+
+ if (anglecalc.linear)
+ continue;
+
+ parameter = GetTypedParameter3Atom(strbndtype, type_a, type_b, type_c, _ffstrbndparams);
+ if (parameter == NULL) {
+ int rowa, rowb, rowc;
+
+ // This is not a real empirical rule...
+ //IF_OBFF_LOGLVL_LOW {
+ // snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR STRETCH-BENDING FORCE CONSTANT %d-%d-%d (IDX)...\n", a->GetIdx(), b->GetIdx(), c->GetIdx());
+ // OBFFLog(_logbuf);
+ //}
+
+ rowa = GetElementRow(a);
+ rowb = GetElementRow(b);
+ rowc = GetElementRow(c);
+
+ parameter = GetParameter3Atom(rowa, rowb, rowc, _ffdfsbparams);
+
+ if (parameter == NULL) {
+ // This should never happen
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " COULD NOT FIND PARAMETERS FOR STRETCH-BEND %d-%d-%d (IDX)...\n", a->GetIdx(), b->GetIdx(), c->GetIdx());
+ OBFFLog(_logbuf);
+ }
+ return false;
+ }
+
+ if (rowa == parameter->a) {
+ strbndcalc.kbaABC = parameter->_dpar[0];
+ strbndcalc.kbaCBA = parameter->_dpar[1];
+ } else {
+ strbndcalc.kbaABC = parameter->_dpar[1];
+ strbndcalc.kbaCBA = parameter->_dpar[0];
+ }
+ } else {
+ if (type_a == parameter->a) {
+ strbndcalc.kbaABC = parameter->_dpar[0];
+ strbndcalc.kbaCBA = parameter->_dpar[1];
+ } else {
+ strbndcalc.kbaABC = parameter->_dpar[1];
+ strbndcalc.kbaCBA = parameter->_dpar[0];
+ }
+ }
+
+ strbndcalc.rab0 = GetBondLength(a, b);
+ strbndcalc.rbc0 = GetBondLength(b ,c);
+ strbndcalc.a = a;
+ strbndcalc.b = b;
+ strbndcalc.c = c;
+ strbndcalc.sbt = strbndtype;
+ strbndcalc.SetupPointers();
+ // Set the pointers to addresses in the anglecalc, find the matching bondcalcs and do the same.
+ // This should improve performance by not calculating all this twice. We could do the same
+ // for torsion and angles since the bond lengths are calculated for bond stretching first.
+ //bool found_angle = false;
+ /*
+ for (unsigned int ai = 0; ai < _anglecalculations.size(); ++ai) {
+ if ( (_anglecalculations[ai].a->GetIdx() == a->GetIdx()) &&
+ (_anglecalculations[ai].b->GetIdx() == b->GetIdx()) &&
+ (_anglecalculations[ai].c->GetIdx() == c->GetIdx()) ) {
+ strbndcalc.theta = &(_anglecalculations[ai].theta);
+ strbndcalc.force_abc_a = _anglecalculations[ai].force_a;
+ strbndcalc.force_abc_b = _anglecalculations[ai].force_b;
+ strbndcalc.force_abc_c = _anglecalculations[ai].force_c;
+ found_angle = true;
+ break;
+ } else if ( (_anglecalculations[ai].a->GetIdx() == c->GetIdx()) &&
+ (_anglecalculations[ai].b->GetIdx() == b->GetIdx()) &&
+ (_anglecalculations[ai].c->GetIdx() == a->GetIdx()) ) {
+ strbndcalc.theta = &(_anglecalculations[ai].theta);
+ strbndcalc.force_abc_a = _anglecalculations[ai].force_c;
+ strbndcalc.force_abc_b = _anglecalculations[ai].force_b;
+ strbndcalc.force_abc_c = _anglecalculations[ai].force_a;
+ found_angle = true;
+ break;
+ }
+ }
+ */
+
+ /*
+ vector<OBFFAngleCalculationMMFF94>::iterator ai;
+ for (ai = _anglecalculations.begin(); ai != _anglecalculations.end(); ++ai) {
+ if ( (((*ai).a)->GetIdx() == a->GetIdx()) && (((*ai).b)->GetIdx() == b->GetIdx()) && (((*ai).c)->GetIdx() == c->GetIdx()) ) {
+ strbndcalc.theta = (*ai).theta;
+ cout << "theta prt = " << (*ai).theta << endl;
+ cout << "delta prt = " << &((*ai).delta) << endl;
+ cout << "GetThetaPointer = " << ai->GetThetaPointer() << endl;
+ strbndcalc.force_abc_a = (*ai).force_a;
+ strbndcalc.force_abc_b = (*ai).force_b;
+ strbndcalc.force_abc_c = (*ai).force_c;
+ found_angle = true;
+ break;
+ } else if ( (((*ai).a)->GetIdx() == c->GetIdx()) && (((*ai).b)->GetIdx() == b->GetIdx()) && (((*ai).c)->GetIdx() == a->GetIdx()) ) {
+ strbndcalc.theta = (*ai).theta;
+ strbndcalc.force_abc_a = (*ai).force_c;
+ strbndcalc.force_abc_b = (*ai).force_b;
+ strbndcalc.force_abc_c = (*ai).force_a;
+ found_angle = true;
+ break;
+ }
+ }
+ if (!found_angle) // didn't find matching angle, shouldn't happen, but continue to be safe
+ continue;
+
+
+ bool found_rab = false;
+ bool found_rbc = false;
+ vector<OBFFBondCalculationMMFF94>::iterator bi;
+ for (bi = _bondcalculations.begin(); bi != _bondcalculations.end(); ++bi) {
+ // find rab
+ if ( (((*bi).a)->GetIdx() == a->GetIdx()) && (((*bi).b)->GetIdx() == b->GetIdx()) ) {
+ strbndcalc.rab = &((*bi).rab);
+ strbndcalc.force_ab_a = (*bi).force_a;
+ strbndcalc.force_ab_b = (*bi).force_b;
+ found_rab = true;
+ } else if ( (((*bi).a)->GetIdx() == b->GetIdx()) && (((*bi).b)->GetIdx() == a->GetIdx()) ) {
+ strbndcalc.rab = &((*bi).rab);
+ strbndcalc.force_ab_a = (*bi).force_b;
+ strbndcalc.force_ab_b = (*bi).force_a;
+ found_rab = true;
+ }
+ // find rbc
+ if ( (((*bi).a)->GetIdx() == b->GetIdx()) && (((*bi).b)->GetIdx() == c->GetIdx()) ) {
+ strbndcalc.rbc = &(bondcalc.rab);
+ strbndcalc.force_ab_a = (*bi).force_a;
+ strbndcalc.force_ab_b = (*bi).force_b;
+ found_rbc = true;
+ } else if ( (((*bi).a)->GetIdx() == c->GetIdx()) && (((*bi).b)->GetIdx() == b->GetIdx()) ) {
+ strbndcalc.rbc = &(bondcalc.rab);
+ strbndcalc.force_ab_a = (*bi).force_b;
+ strbndcalc.force_ab_b = (*bi).force_a;
+ found_rbc = true;
+ }
+
+ if (found_rab && found_rbc)
+ break;
+ }
+ if (!found_rab || !found_rbc) // didn't find matching bond, or atoms overlap
+ continue;
+ */
+ _strbndcalculations.push_back(strbndcalc);
+
+ }
+
+ //
+ // Torsion Calculations
+ //
+ // MMFF part I - page 513 ("step-down" prodedure)
+ // MMFF part I - page 519 (reference 68 is actually a footnote)
+ // MMFF part IV - page 631 (empirical rule)
+ //
+ // First try and find an exact match, if this fails, step down using the equivalences from mmffdef.par
+ // five-stage protocol: 1-1-1-1, 2-2-2-2, 3-2-2-5, 5-2-2-3, 5-2-2-5
+ // If this fails, use empirical rules
+ // Since 1-1-1-1 = 2-2-2-2, we will only try 1-1-1-1 before going to 3-2-2-5
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP TORSION CALCULATIONS...\n");
+
+ OBFFTorsionCalculationMMFF94 torsioncalc;
+ int torsiontype;
+
+ _torsioncalculations.clear();
+
+ FOR_TORSIONS_OF_MOL(t, _mol) {
+ a = _mol.GetAtom((*t)[0] + 1);
+ b = _mol.GetAtom((*t)[1] + 1);
+ c = _mol.GetAtom((*t)[2] + 1);
+ d = _mol.GetAtom((*t)[3] + 1);
+
+ type_a = atoi(a->GetType());
+ type_b = atoi(b->GetType());
+ type_c = atoi(c->GetType());
+ type_d = atoi(d->GetType());
+
+ // skip this torsion if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) ||
+ _constraints.IsIgnored(c->GetIdx()) || _constraints.IsIgnored(d->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the four torsion atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validTorsion = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()) && _intraGroup[i].BitIsOn(d->GetIdx()))
+ validTorsion = true;
+ }
+ if (!validTorsion)
+ continue;
+ }
+
+ torsiontype = GetTorsionType(a, b, c, d);
+ // CXT = MC*(J*MA**3 + K*MA**2 + I*MA + L) + TTijkl MC = 6, MA = 136
+ order = (type_c*2515456 + type_b*18496 + type_d*136 + type_a)
+ - (type_b*2515456 + type_c*18496 + type_a*136 + type_d);
+
+ if (order >= 0) {
+ // try exact match
+ parameter = GetTypedParameter4Atom(torsiontype, type_a, type_b, type_c, type_d, _fftorsionparams);
+ if (parameter == NULL) // try 3-2-2-5
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl3(type_a), type_b, type_c, EqLvl5(type_d), _fftorsionparams);
+ if (parameter == NULL) // try 5-2-2-3
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl5(type_a), type_b, type_c, EqLvl3(type_d), _fftorsionparams);
+ if (parameter == NULL) // try 5-2-2-5
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl5(type_a), type_b, type_c, EqLvl5(type_d), _fftorsionparams);
+ } else {
+ // try exact match
+ parameter = GetTypedParameter4Atom(torsiontype, type_d, type_c, type_b, type_a, _fftorsionparams);
+ if (parameter == NULL) // try 3-2-2-5
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl3(type_d), type_c, type_b, EqLvl5(type_a), _fftorsionparams);
+ if (parameter == NULL) // try 5-2-2-3
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl5(type_d), type_c, type_b, EqLvl3(type_a), _fftorsionparams);
+ if (parameter == NULL) // try 5-2-2-5
+ parameter = GetTypedParameter4Atom(torsiontype, EqLvl5(type_d), type_c, type_b, EqLvl5(type_a), _fftorsionparams);
+ }
+
+ if (parameter) {
+ torsioncalc.v1 = parameter->_dpar[0];
+ torsioncalc.v2 = parameter->_dpar[1];
+ torsioncalc.v3 = parameter->_dpar[2];
+ } else {
+ bool found_rule = false;
+
+ //IF_OBFF_LOGLVL_LOW {
+ // snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR TORSION FORCE CONSTANT %d-%d-%d-%d (IDX)...\n",
+ // a->GetIdx(), b->GetIdx(), c->GetIdx(), d->GetIdx());
+ // OBFFLog(_logbuf);
+ //}
+
+ // rule (a) page 631
+ if (HasLinSet(type_b) || HasLinSet(type_c))
+ continue;
+
+ // rule (b) page 631
+ if (b->GetBond(c)->IsAromatic()) {
+ double Ub, Uc, pi_bc, beta;
+ Ub = GetUParam(b);
+ Uc = GetUParam(c);
+
+ if (!HasPilpSet(type_b) && !HasPilpSet(type_c))
+ pi_bc = 0.5;
+ else
+ pi_bc = 0.3;
+
+ if (((GetVal(type_b) == 3) && (GetVal(type_c) == 4)) ||
+ ((GetVal(type_b) == 4) && (GetVal(type_c) == 3)))
+ beta = 3.0;
+ else
+ beta = 6.0;
+
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = beta * pi_bc * sqrt(Ub * Uc);
+ torsioncalc.v3 = 0.0;
+ found_rule = true;
+ } else {
+ // rule (c) page 631
+ double Ub, Uc, pi_bc, beta;
+ Ub = GetUParam(b);
+ Uc = GetUParam(c);
+
+ if (((GetMltb(type_b) == 2) && (GetMltb(type_c) == 2)) && a->GetBond(b)->IsDouble())
+ pi_bc = 1.0;
+ else
+ pi_bc = 0.4;
+
+ beta = 6.0;
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = beta * pi_bc * sqrt(Ub * Uc);
+ torsioncalc.v3 = 0.0;
+ found_rule = true;
+ }
+
+ // rule (d) page 632
+ if (!found_rule)
+ if (((GetCrd(type_b) == 4) && (GetCrd(type_c) == 4))) {
+ double Vb, Vc;
+ Vb = GetVParam(b);
+ Vc = GetVParam(c);
+
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = 0.0;
+ torsioncalc.v3 = sqrt(Vb * Vc) / 9.0;
+ found_rule = true;
+ }
+
+ // rule (e) page 632
+ if (!found_rule)
+ if (((GetCrd(type_b) == 4) && (GetCrd(type_c) != 4))) {
+ if (GetCrd(type_c) == 3) // case (1)
+ if ((GetVal(type_c) == 4) || (GetVal(type_c) == 34) || (GetMltb(type_c) != 0))
+ continue;
+
+ if (GetCrd(type_c) == 2) // case (2)
+ if ((GetVal(type_c) == 3) || (GetMltb(type_c) != 0))
+ continue;
+
+ // case (3) saturated bonds -- see rule (h)
+ }
+
+ // rule (f) page 632
+ if (!found_rule)
+ if (((GetCrd(type_b) != 4) && (GetCrd(type_c) == 4))) {
+ if (GetCrd(type_b) == 3) // case (1)
+ if ((GetVal(type_b) == 4) || (GetVal(type_b) == 34) || (GetMltb(type_b) != 0))
+ continue;
+
+ if (GetCrd(type_b) == 2) // case (2)
+ if ((GetVal(type_b) == 3) || (GetMltb(type_b) != 0))
+ continue;
+
+ // case (3) saturated bonds
+ }
+
+ // rule (g) page 632
+ if (!found_rule)
+ if (b->GetBond(c)->IsSingle() && (
+ (GetMltb(type_b) && GetMltb(type_c)) ||
+ (GetMltb(type_b) && HasPilpSet(type_c)) ||
+ (GetMltb(type_c) && HasPilpSet(type_b)) )) {
+ if (HasPilpSet(type_b) && HasPilpSet(type_c)) // case (1)
+ continue;
+
+ double Ub, Uc, pi_bc, beta;
+ Ub = GetUParam(b);
+ Uc = GetUParam(c);
+ beta = 6.0;
+
+ if (HasPilpSet(type_b) && GetMltb(type_c)) { // case (2)
+ if (GetMltb(type_c) == 1)
+ pi_bc = 0.5;
+ else if ((GetElementRow(b) == 1) && (GetElementRow(c) == 1))
+ pi_bc = 0.3;
+ else
+ pi_bc = 0.15;
+ found_rule = true;
+ }
+
+ if (HasPilpSet(type_c) && GetMltb(type_b)) { // case (3)
+ if (GetMltb(type_b) == 1)
+ pi_bc = 0.5;
+ else if ((GetElementRow(b) == 1) && (GetElementRow(c) == 1))
+ pi_bc = 0.3;
+ else
+ pi_bc = 0.15;
+ found_rule = true;
+ }
+
+ if (!found_rule)
+ if (((GetMltb(type_b) == 1) || (GetMltb(type_c) == 1)) && (!b->IsCarbon() || !c->IsCarbon())) {
+ pi_bc = 0.4;
+ found_rule = true;
+ }
+
+ if (!found_rule)
+ pi_bc = 0.15;
+
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = beta * pi_bc * sqrt(Ub * Uc);
+ torsioncalc.v3 = 0.0;
+ found_rule = true;
+ }
+
+ // rule (h) page 632
+ if (!found_rule)
+ if ((b->IsOxygen() || b->IsSulfur()) && (c->IsOxygen() || c->IsSulfur())) {
+ double Wb, Wc;
+
+ if (b->IsOxygen()) {
+ Wb = 2.0;
+ }
+ else {
+ Wb = 8.0;
+ }
+
+ if (c->IsOxygen()) {
+ Wc = 2.0;
+ }
+ else {
+ Wc = 8.0;
+ }
+
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = -sqrt(Wb * Wc);
+ torsioncalc.v3 = 0.0;
+ } else {
+ double Vb, Vc, Nbc;
+ Vb = GetVParam(b);
+ Vc = GetVParam(c);
+
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " USING EMPIRICAL RULE FOR TORSION FORCE CONSTANT %d-%d-%d-%d (IDX)...\n",
+ a->GetIdx(), b->GetIdx(), c->GetIdx(), d->GetIdx());
+ OBFFLog(_logbuf);
+ }
+
+ Nbc = GetCrd(type_b) * GetCrd(type_c);
+
+ torsioncalc.v1 = 0.0;
+ torsioncalc.v2 = 0.0;
+ torsioncalc.v3 = sqrt(Vb * Vc) / Nbc;
+ }
+ }
+
+ torsioncalc.a = a;
+ torsioncalc.b = b;
+ torsioncalc.c = c;
+ torsioncalc.d = d;
+ torsioncalc.SetupPointers();
+ torsioncalc.tt = torsiontype;
+
+ _torsioncalculations.push_back(torsioncalc);
+ }
+
+ //
+ // Out-Of-Plane Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP OOP CALCULATIONS...\n");
+
+ OBFFOOPCalculationMMFF94 oopcalc;
+
+ _oopcalculations.clear();
+
+ FOR_ATOMS_OF_MOL(atom, _mol) {
+ b = (OBAtom*) &*atom;
+
+ found = false;
+
+ type_b = atoi(b->GetType());
+
+ for (unsigned int idx=0; idx < _ffoopparams.size(); idx++) {
+ if (type_b == _ffoopparams[idx].b) {
+ a = NULL;
+ c = NULL;
+ d = NULL;
+
+ FOR_NBORS_OF_ATOM(nbr, b) {
+ if (a ==NULL)
+ a = (OBAtom*) &*nbr;
+ else if (c == NULL)
+ c = (OBAtom*) &*nbr;
+ else
+ d = (OBAtom*) &*nbr;
+ }
+
+ if ((a == NULL) || (c == NULL) || (d == NULL))
+ break;
+
+ type_a = atoi(a->GetType());
+ type_c = atoi(c->GetType());
+ type_d = atoi(d->GetType());
+
+ // skip this oop if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) ||
+ _constraints.IsIgnored(c->GetIdx()) || _constraints.IsIgnored(d->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the four oop atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validOOP = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()) && _intraGroup[i].BitIsOn(d->GetIdx()))
+ validOOP = true;
+ }
+ if (!validOOP)
+ continue;
+ }
+
+ if (((type_a == _ffoopparams[idx].a) && (type_c == _ffoopparams[idx].c) && (type_d == _ffoopparams[idx].d)) ||
+ ((type_c == _ffoopparams[idx].a) && (type_a == _ffoopparams[idx].c) && (type_d == _ffoopparams[idx].d)) ||
+ ((type_c == _ffoopparams[idx].a) && (type_d == _ffoopparams[idx].c) && (type_a == _ffoopparams[idx].d)) ||
+ ((type_d == _ffoopparams[idx].a) && (type_c == _ffoopparams[idx].c) && (type_a == _ffoopparams[idx].d)) ||
+ ((type_a == _ffoopparams[idx].a) && (type_d == _ffoopparams[idx].c) && (type_c == _ffoopparams[idx].d)) ||
+ ((type_d == _ffoopparams[idx].a) && (type_a == _ffoopparams[idx].c) && (type_c == _ffoopparams[idx].d)))
+ {
+ found = true;
+
+ oopcalc.koop = _ffoopparams[idx]._dpar[0];
+
+ // A-B-CD || C-B-AD PLANE = ABC
+ oopcalc.a = a;
+ oopcalc.b = b;
+ oopcalc.c = c;
+ oopcalc.d = d;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // C-B-DA || D-B-CA PLANE BCD
+ oopcalc.a = d;
+ oopcalc.d = a;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // A-B-DC || D-B-AC PLANE ABD
+ oopcalc.a = a;
+ oopcalc.c = d;
+ oopcalc.d = c;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+ }
+
+ if ((_ffoopparams[idx].a == 0) && (_ffoopparams[idx].c == 0) && (_ffoopparams[idx].d == 0) && !found) // *-XX-*-*
+ {
+ oopcalc.koop = _ffoopparams[idx]._dpar[0];
+
+ // A-B-CD || C-B-AD PLANE = ABC
+ oopcalc.a = a;
+ oopcalc.b = b;
+ oopcalc.c = c;
+ oopcalc.d = d;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // C-B-DA || D-B-CA PLANE BCD
+ oopcalc.a = d;
+ oopcalc.d = a;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // A-B-DC || D-B-AC PLANE ABD
+ oopcalc.a = a;
+ oopcalc.c = d;
+ oopcalc.d = c;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+ }
+ }
+ }
+ }
+
+ //
+ // VDW Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP VAN DER WAALS CALCULATIONS...\n");
+
+ OBFFVDWCalculationMMFF94 vdwcalc;
+
+ _vdwcalculations.clear();
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this vdw if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validVDW = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validVDW = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validVDW = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validVDW = true;
+ }
+
+ if (!validVDW)
+ continue;
+ }
+
+ OBFFParameter *parameter_a, *parameter_b;
+ parameter_a = GetParameter1Atom(atoi(a->GetType()), _ffvdwparams);
+ parameter_b = GetParameter1Atom(atoi(b->GetType()), _ffvdwparams);
+ if ((parameter_a == NULL) || (parameter_b == NULL)) {
+ IF_OBFF_LOGLVL_LOW {
+ snprintf(_logbuf, BUFF_SIZE, " COULD NOT FIND VAN DER WAALS PARAMETERS FOR %d-%d (IDX)...\n", a->GetIdx(), b->GetIdx());
+ OBFFLog(_logbuf);
+ }
+
+ return false;
+ }
+
+ vdwcalc.a = a;
+ vdwcalc.alpha_a = parameter_a->_dpar[0];
+ vdwcalc.Na = parameter_a->_dpar[1];
+ vdwcalc.Aa = parameter_a->_dpar[2];
+ vdwcalc.Ga = parameter_a->_dpar[3];
+ vdwcalc.aDA = parameter_a->_ipar[0];
+
+ vdwcalc.b = b;
+ vdwcalc.alpha_b = parameter_b->_dpar[0];
+ vdwcalc.Nb = parameter_b->_dpar[1];
+ vdwcalc.Ab = parameter_b->_dpar[2];
+ vdwcalc.Gb = parameter_b->_dpar[3];
+ vdwcalc.bDA = parameter_b->_ipar[0];
+
+ //these calculations only need to be done once for each pair,
+ //we do them now and save them for later use
+ double R_AA, R_BB, R_AB6, g_AB, g_AB2;
+ double R_AB2, R_AB4, /*R_AB7,*/ sqrt_a, sqrt_b;
+
+ R_AA = vdwcalc.Aa * pow(vdwcalc.alpha_a, 0.25);
+ R_BB = vdwcalc.Ab * pow(vdwcalc.alpha_b, 0.25);
+ sqrt_a = sqrt(vdwcalc.alpha_a / vdwcalc.Na);
+ sqrt_b = sqrt(vdwcalc.alpha_b / vdwcalc.Nb);
+
+ if (vdwcalc.aDA == 1) { // hydrogen bond donor
+ vdwcalc.R_AB = 0.5 * (R_AA + R_BB);
+ R_AB2 = vdwcalc.R_AB * vdwcalc.R_AB;
+ R_AB4 = R_AB2 * R_AB2;
+ R_AB6 = R_AB4 * R_AB2;
+
+ if (vdwcalc.bDA == 2) { // hydrogen bond acceptor
+ vdwcalc.epsilon = 0.5 * (181.16 * vdwcalc.Ga * vdwcalc.Gb * vdwcalc.alpha_a * vdwcalc.alpha_b) / (sqrt_a + sqrt_b) * (1.0 / R_AB6);
+ // R_AB is scaled to 0.8 for D-A interactions. The value used in the calculation of epsilon is not scaled.
+ vdwcalc.R_AB = 0.8 * vdwcalc.R_AB;
+ } else
+ vdwcalc.epsilon = (181.16 * vdwcalc.Ga * vdwcalc.Gb * vdwcalc.alpha_a * vdwcalc.alpha_b) / (sqrt_a + sqrt_b) * (1.0 / R_AB6);
+
+ R_AB2 = vdwcalc.R_AB * vdwcalc.R_AB;
+ R_AB4 = R_AB2 * R_AB2;
+ R_AB6 = R_AB4 * R_AB2;
+ vdwcalc.R_AB7 = R_AB6 * vdwcalc.R_AB;
+ } else if (vdwcalc.bDA == 1) { // hydrogen bond donor
+ vdwcalc.R_AB = 0.5 * (R_AA + R_BB);
+ R_AB2 = vdwcalc.R_AB * vdwcalc.R_AB;
+ R_AB4 = R_AB2 * R_AB2;
+ R_AB6 = R_AB4 * R_AB2;
+
+ if (vdwcalc.aDA == 2) { // hydrogen bond acceptor
+ vdwcalc.epsilon = 0.5 * (181.16 * vdwcalc.Ga * vdwcalc.Gb * vdwcalc.alpha_a * vdwcalc.alpha_b) / (sqrt_a + sqrt_b) * (1.0 / R_AB6);
+ // R_AB is scaled to 0.8 for D-A interactions. The value used in the calculation of epsilon is not scaled.
+ vdwcalc.R_AB = 0.8 * vdwcalc.R_AB;
+ } else
+ vdwcalc.epsilon = (181.16 * vdwcalc.Ga * vdwcalc.Gb * vdwcalc.alpha_a * vdwcalc.alpha_b) / (sqrt_a + sqrt_b) * (1.0 / R_AB6);
+
+ R_AB2 = vdwcalc.R_AB * vdwcalc.R_AB;
+ R_AB4 = R_AB2 * R_AB2;
+ R_AB6 = R_AB4 * R_AB2;
+ vdwcalc.R_AB7 = R_AB6 * vdwcalc.R_AB;
+ } else {
+ g_AB = (R_AA - R_BB) / ( R_AA + R_BB);
+ g_AB2 = g_AB * g_AB;
+ vdwcalc.R_AB = 0.5 * (R_AA + R_BB) * (1.0 + 0.2 * (1.0 - exp(-12.0 * g_AB2)));
+ R_AB2 = vdwcalc.R_AB * vdwcalc.R_AB;
+ R_AB4 = R_AB2 * R_AB2;
+ R_AB6 = R_AB4 * R_AB2;
+ vdwcalc.R_AB7 = R_AB6 * vdwcalc.R_AB;
+ vdwcalc.epsilon = (181.16 * vdwcalc.Ga * vdwcalc.Gb * vdwcalc.alpha_a * vdwcalc.alpha_b) / (sqrt_a + sqrt_b) * (1.0 / R_AB6);
+ }
+
+ vdwcalc.SetupPointers();
+ _vdwcalculations.push_back(vdwcalc);
+ }
+
+ //
+ // Electrostatic Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ELECTROSTATIC CALCULATIONS...\n");
+
+ OBFFElectrostaticCalculationMMFF94 elecalc;
+
+ _electrostaticcalculations.clear();
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this ele if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validEle = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validEle = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validEle = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validEle = true;
+ }
+
+ if (!validEle)
+ continue;
+ }
+
+ elecalc.qq = 332.0716 * a->GetPartialCharge() * b->GetPartialCharge();
+
+ if (elecalc.qq) {
+ elecalc.a = &*a;
+ elecalc.b = &*b;
+
+ // 1-4 scaling
+ if (a->IsOneFour(b))
+ elecalc.qq *= 0.75;
+
+ elecalc.SetupPointers();
+ _electrostaticcalculations.push_back(elecalc);
+ }
+ }
+
+ return true;
+ }
+
+ bool OBForceFieldMMFF94::SetupPointers()
+ {
+ for (unsigned int i = 0; i < _bondcalculations.size(); ++i)
+ _bondcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _anglecalculations.size(); ++i)
+ _anglecalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _strbndcalculations.size(); ++i)
+ _strbndcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _torsioncalculations.size(); ++i)
+ _torsioncalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _oopcalculations.size(); ++i)
+ _oopcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _vdwcalculations.size(); ++i)
+ _vdwcalculations[i].SetupPointers();
+ for (unsigned int i = 0; i < _electrostaticcalculations.size(); ++i)
+ _electrostaticcalculations[i].SetupPointers();
+
+ return true;
+ }
+
+
+ // we set the the formal charge with SetPartialCharge because formal charges
+ // in MMFF94 are not always and integer
+ bool OBForceFieldMMFF94::SetFormalCharges()
+ {
+ _mol.SetAutomaticPartialCharge(false);
+
+ FOR_ATOMS_OF_MOL (atom, _mol) {
+ int type = atoi(atom->GetType());
+ atom->SetPartialCharge(0.0);
+
+ bool done = false;
+ switch (type) {
+ case 34:
+ case 49:
+ case 51:
+ case 54:
+ case 58:
+ case 92:
+ case 93:
+ case 94:
+ case 97:
+ atom->SetPartialCharge(1.0);
+ done = true;
+ break;
+ case 35:
+ case 62:
+ case 89:
+ case 90:
+ case 91:
+ atom->SetPartialCharge(-1.0);
+ done = true;
+ break;
+ case 55:
+ atom->SetPartialCharge(0.5);
+ done = true;
+ break;
+ case 56:
+ atom->SetPartialCharge(1.0/3.0);
+ done = true;
+ break;
+ case 87:
+ case 95:
+ case 96:
+ case 98:
+ case 99:
+ atom->SetPartialCharge(2.0);
+ done = true;
+ break;
+ //case 98:
+ // atom->SetPartialCharge(3.0);
+ default:
+ break;
+ }
+
+ if (done)
+ continue;
+
+ if (type == 32) {
+ int o_count = 0;
+ bool sulfonamide = false;
+ int s_count = 0;
+
+ FOR_NBORS_OF_ATOM(nbr, &*atom) {
+ FOR_NBORS_OF_ATOM(nbr2, &*nbr) {
+ if (nbr2->IsOxygen() && (nbr2->GetValence() == 1))
+ o_count++;
+ if (nbr2->IsSulfur() && (nbr2->GetValence() == 1))
+ s_count++;
+ if (nbr2->IsNitrogen() && !nbr2->IsAromatic())
+ sulfonamide = true;
+ }
+
+ if (nbr->IsCarbon())
+ atom->SetPartialCharge(-0.5); // O2CM
+
+ if (nbr->IsNitrogen() && (o_count == 3))
+ atom->SetPartialCharge(-1.0 / o_count); // O3N
+
+ if (nbr->IsSulfur() && !sulfonamide)
+ if (((o_count + s_count) == 2) && (nbr->GetValence() == 3) && (nbr->BOSum() == 3))
+ atom->SetPartialCharge(-0.5); // O2S
+ else if ((o_count + s_count) == 3)
+ atom->SetPartialCharge(-1.0 / 3.0); // O3S
+ else if ((o_count + s_count) == 4)
+ atom->SetPartialCharge(-0.5); // O4S
+
+ if (nbr->IsPhosphorus())
+ if ((o_count + s_count) == 2)
+ atom->SetPartialCharge(-0.5); // O2P
+ else if ((o_count + s_count) == 3)
+ atom->SetPartialCharge(-2.0 / 3.0); // O3P
+ else if ((o_count + s_count) == 4)
+ atom->SetPartialCharge(-0.25); // O4P
+
+ if (type == 77)
+ atom->SetPartialCharge(-0.25); // O4CL
+ }
+ } else if (type == 61) {
+ FOR_NBORS_OF_ATOM(nbr, &*atom)
+ if (atom->GetBond(&*nbr)->IsTriple() && nbr->IsNitrogen())
+ atom->SetPartialCharge(1.0);
+ } else if (type == 72) {
+ int s_count = 0;
+
+ FOR_NBORS_OF_ATOM(nbr, &*atom) {
+ if (nbr->IsSulfur())
+ s_count++;
+
+ if (nbr->IsPhosphorus() || nbr->IsSulfur()) {
+ FOR_NBORS_OF_ATOM(nbr2, &*nbr)
+ if ((nbr2->IsSulfur() || nbr2->IsOxygen()) && (nbr2->GetValence() == 1) && (atom->GetIdx() != nbr2->GetIdx()))
+ atom->SetPartialCharge(-0.5);
+ } else
+ atom->SetPartialCharge(-1.0);
+
+ if (nbr->IsCarbon())
+ FOR_NBORS_OF_ATOM(nbr2, &*nbr)
+ if (nbr2->IsSulfur() && (nbr2->GetValence() == 1) && (atom->GetIdx() != nbr2->GetIdx()))
+ atom->SetPartialCharge(-0.5); // SSMO
+
+ if (s_count >= 2)
+ atom->SetPartialCharge(-0.5); // SSMO
+ }
+ } else if (type == 76) {
+ vector<OBRing*> vr;
+ vr = _mol.GetSSSR();
+ vector<OBRing*>::iterator ri;
+ vector<int>::iterator rj;
+ int n_count;
+
+ for (ri = vr.begin();ri != vr.end();ri++) { // for each ring
+ n_count = 0;
+
+ if ((*ri)->IsAromatic() && (*ri)->IsMember(&*atom) && ((*ri)->Size() == 5)) {
+ for(rj = (*ri)->_path.begin();rj != (*ri)->_path.end();rj++) // for each ring atom
+ if (_mol.GetAtom(*rj)->IsNitrogen())
+ n_count++;
+
+ if (n_count > 1)
+ atom->SetPartialCharge(-1.0 / n_count);
+ }
+ }
+ } else if (type == 81) {
+ atom->SetPartialCharge(1.0);
+
+ vector<OBRing*> vr;
+ vr = _mol.GetSSSR();
+ vector<OBRing*>::iterator ri;
+ vector<int>::iterator rj;
+ for (ri = vr.begin();ri != vr.end();ri++) // for each ring
+ if ((*ri)->IsAromatic() && (*ri)->IsMember(&*atom) && ((*ri)->Size() == 5)) {
+ int n_count = 0;
+ for(rj = (*ri)->_path.begin();rj != (*ri)->_path.end();rj++) // for each ring atom
+ if (_mol.GetAtom(*rj)->IsNitrogen() && (_mol.GetAtom(*rj)->GetValence() == 3))
+ n_count++;
+
+ atom->SetPartialCharge(1.0 / n_count); // NIM+
+
+ FOR_NBORS_OF_ATOM(nbr, &*atom)
+ FOR_NBORS_OF_ATOM(nbr2, &*nbr)
+ if (atoi(nbr2->GetType()) == 56)
+ atom->SetPartialCharge(1.0 / 3.0);
+
+ FOR_NBORS_OF_ATOM(nbr, &*atom)
+ FOR_NBORS_OF_ATOM(nbr2, &*nbr)
+ if (atoi(nbr2->GetType()) == 55)
+ atom->SetPartialCharge(1.0 / (1.0 + n_count));
+ }
+ }
+
+ }
+
+ PrintFormalCharges();
+
+ return true;
+ }
+
+ bool OBForceFieldMMFF94::SetPartialCharges()
+ {
+ vector<double> charges(_mol.NumAtoms()+1, 0);
+ double M, Wab, factor, q0a, q0b, Pa, Pb;
+
+ FOR_ATOMS_OF_MOL (atom, _mol) {
+ int type = atoi(atom->GetType());
+
+ switch (type) {
+ case 32:
+ case 35:
+ case 72:
+ factor = 0.5;
+ break;
+ case 62:
+ case 76:
+ factor = 0.25;
+ break;
+ default:
+ factor = 0.0;
+ break;
+ }
+
+ M = GetCrd(type);
+ q0a = atom->GetPartialCharge();
+
+ // charge sharing
+ if (!factor)
+ FOR_NBORS_OF_ATOM (nbr, &*atom)
+ if (nbr->GetPartialCharge() < 0.0)
+ q0a += nbr->GetPartialCharge() / (2.0 * nbr->GetValence());
+
+ // needed for SEYWUO, positive charge sharing?
+ if (type == 62)
+ FOR_NBORS_OF_ATOM (nbr, &*atom)
+ if (nbr->GetPartialCharge() > 0.0)
+ q0a -= nbr->GetPartialCharge() / 2.0;
+
+ q0b = 0.0;
+ Wab = 0.0;
+ Pa = Pb = 0.0;
+ FOR_NBORS_OF_ATOM (nbr, &*atom) {
+ int nbr_type = atoi(nbr->GetType());
+
+ q0b += nbr->GetPartialCharge();
+
+ bool bci_found = false;
+ for (unsigned int idx=0; idx < _ffchgparams.size(); idx++)
+ if (GetBondType(&*atom, &*nbr) == _ffchgparams[idx]._ipar[0])
+ if ((type == _ffchgparams[idx].a) && (nbr_type == _ffchgparams[idx].b)) {
+ Wab += -_ffchgparams[idx]._dpar[0];
+ bci_found = true;
+ } else if ((type == _ffchgparams[idx].b) && (nbr_type == _ffchgparams[idx].a)) {
+ Wab += _ffchgparams[idx]._dpar[0];
+ bci_found = true;
+ }
+
+ if (!bci_found) {
+ for (unsigned int idx=0; idx < _ffpbciparams.size(); idx++) {
+ if (type == _ffpbciparams[idx].a)
+ Pa = _ffpbciparams[idx]._dpar[0];
+ if (nbr_type == _ffpbciparams[idx].a)
+ Pb = _ffpbciparams[idx]._dpar[0];
+ }
+ Wab += Pa - Pb;
+ }
+ }
+
+ if (factor)
+ charges[atom->GetIdx()] = (1.0 - M * factor) * q0a + factor * q0b + Wab;
+ else
+ charges[atom->GetIdx()] = q0a + Wab;
+ }
+
+ FOR_ATOMS_OF_MOL (atom, _mol)
+ atom->SetPartialCharge(charges[atom->GetIdx()]);
+
+ PrintPartialCharges();
+
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Validation functions
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // used to validate the implementation
+ bool OBForceFieldMMFF94::Validate ()
+ {
+ OBConversion conv;
+ OBFormat *format_in = conv.FindFormat("mol2");
+ vector<string> vs;
+ vector<int> types;
+ vector<double> fcharges, pcharges;
+ vector<double> bond_lengths;
+ char buffer[150], _logbuf[100];
+ bool molfound, atomfound, bondfound, fchgfound, pchgfound;
+ double etot, ebond, eangle, eoop, estbn, etor, evdw, eeq;
+ double termcount; //1=bond, 2=angle, 3=strbnd, 4=torsion, 5=oop
+ int n = 0;
+
+ if (!format_in || !conv.SetInFormat(format_in)) {
+ obErrorLog.ThrowError(__FUNCTION__, "Could not set mol2 input format", obError);
+ return false;
+ }
+
+ ifstream ifs, ifs2;
+ ofstream ofs;
+
+ ifs.open("MMFF94_dative.mol2");
+ if (!ifs) {
+ obErrorLog.ThrowError(__FUNCTION__, "Could not open ./MMFF94_dative.mol2", obError);
+ return false;
+ }
+
+ ifs2.open("MMFF94_opti.log");
+ if (!ifs2) {
+ obErrorLog.ThrowError(__FUNCTION__, "Coulg not open ./MMFF_opti.log", obError);
+ return false;
+ }
+
+ ofs.open("MMFF94_openbabel.log");
+ if (!ofs) {
+ obErrorLog.ThrowError(__FUNCTION__, "Coulg not open ./MMFF_openbabel.log", obError);
+ return false;
+ }
+
+ if (!_init) {
+ ParseParamFile();
+ _init = true;
+ }
+
+
+ SetLogFile(&ofs);
+ SetLogLevel(OBFF_LOGLVL_HIGH);
+
+ for (unsigned int c=1;; c++) {
+ _mol.Clear();
+ types.clear();
+ fcharges.clear();
+ pcharges.clear();
+ bond_lengths.clear();
+
+ if (!conv.Read(&_mol, &ifs))
+ break;
+ if (_mol.Empty())
+ break;
+
+ _ncoords = _mol.NumAtoms() * 3;
+ _gradientPtr = new double[_ncoords];
+
+ SetTypes();
+
+ if ((c == 98) || (c == 692)) // CUDPAS & VUWXUG
+ continue;
+
+ termcount = 0;
+ molfound = false;
+ atomfound = false;
+ bondfound = false;
+ fchgfound = false;
+ pchgfound = false;
+
+ while (ifs2.getline(buffer, 150)) {
+ tokenize(vs, buffer);
+ if (vs.size() == 0) {
+ bondfound = false;
+ continue;
+ }
+
+ string str(buffer);
+ if (string::npos != str.find(_mol.GetTitle(),0))
+ molfound = true;
+
+ if (atomfound) {
+ if (n) {
+ types.push_back(atoi(vs[2].c_str()));
+ types.push_back(atoi(vs[5].c_str()));
+ types.push_back(atoi(vs[8].c_str()));
+ types.push_back(atoi(vs[11].c_str()));
+ } else {
+ if (vs.size() > 2)
+ types.push_back(atoi(vs[2].c_str()));
+ if (vs.size() > 5)
+ types.push_back(atoi(vs[5].c_str()));
+ if (vs.size() > 8)
+ types.push_back(atoi(vs[8].c_str()));
+
+ atomfound = false;
+ }
+ n--;
+ }
+
+ if (fchgfound) {
+ if (n) {
+ fcharges.push_back(atof(vs[2].c_str()));
+ fcharges.push_back(atof(vs[5].c_str()));
+ fcharges.push_back(atof(vs[8].c_str()));
+ fcharges.push_back(atof(vs[11].c_str()));
+ } else {
+ if (vs.size() > 2)
+ fcharges.push_back(atof(vs[2].c_str()));
+ if (vs.size() > 5)
+ fcharges.push_back(atof(vs[5].c_str()));
+ if (vs.size() > 8)
+ fcharges.push_back(atof(vs[8].c_str()));
+
+ fchgfound = false;
+ }
+ n--;
+ }
+
+ if (pchgfound) {
+ if (n) {
+ pcharges.push_back(atof(vs[2].c_str()));
+ pcharges.push_back(atof(vs[5].c_str()));
+ pcharges.push_back(atof(vs[8].c_str()));
+ pcharges.push_back(atof(vs[11].c_str()));
+ } else {
+ if (vs.size() > 2)
+ pcharges.push_back(atof(vs[2].c_str()));
+ if (vs.size() > 5)
+ pcharges.push_back(atof(vs[5].c_str()));
+ if (vs.size() > 8)
+ pcharges.push_back(atof(vs[8].c_str()));
+
+ pchgfound = false;
+ }
+ n--;
+ }
+
+ if (molfound && EQn(buffer, " ATOM NAME TYPE", 16)) {
+ atomfound = true;
+ n = _mol.NumAtoms() / 4;
+ }
+ if (molfound && EQn(buffer, " ATOM FCHARGE", 17)) {
+ fchgfound = true;
+ n = _mol.NumAtoms() / 4;
+ }
+ if (molfound && EQn(buffer, " ATOM CHARGE", 17)) {
+ pchgfound = true;
+ n = _mol.NumAtoms() / 4;
+ }
+
+ if (bondfound)
+ bond_lengths.push_back(atof(vs[7].c_str()));
+
+ if (molfound) {
+ if (EQn(buffer, " Total ENERGY", 13))
+ etot = atof(vs[3].c_str());
+ if (EQn(buffer, " ZNBond Stretching", 16))
+ ebond = atof(vs[2].c_str());
+ if (EQn(buffer, " Angle Bending", 14))
+ eangle = atof(vs[2].c_str());
+ if (EQn(buffer, " Out-of-Plane Bending", 21))
+ eoop = atof(vs[2].c_str());
+ if (EQn(buffer, " Stretch-Bend", 13))
+ estbn = atof(vs[1].c_str());
+ if (EQn(buffer, " Total Torsion", 18))
+ etor = atof(vs[2].c_str());
+ if (EQn(buffer, " Net vdW", 12))
+ evdw = atof(vs[2].c_str());
+ if (EQn(buffer, " Electrostatic", 14))
+ eeq = atof(vs[1].c_str());
+ if (EQn(buffer, " ---------------------", 22) && (termcount == 0)) {
+ termcount++;
+ bondfound = true;
+ }
+ if (EQn(buffer, " OPTIMOL> # read next", 22))
+ break;
+ }
+
+
+
+ } // while (getline)
+
+ vector<int>::iterator i;
+ vector<double>::iterator di;
+ unsigned int ni;
+ bool failed;
+
+ cout << "--------------------------------------------------------------------------------" << endl;
+ cout << " " << endl;
+ cout << " VALIDATE MOLECULE " << c << ": " << _mol.GetTitle() << endl;
+ cout << " " << endl;
+ cout << "IDX HYB AROM OB_TYPE LOG_TYPE RESULT " << endl;
+ cout << "---------------------------------------------- " << endl;
+
+ ni = 1;
+ failed = false;
+ for (i = types.begin(); i != types.end();i++) {
+ if (ni > _mol.NumAtoms())
+ continue;
+
+ if ( (atoi(_mol.GetAtom(ni)->GetType()) == 87) ||
+ (atoi(_mol.GetAtom(ni)->GetType()) == 97)
+ ) continue;
+
+ if (atoi(_mol.GetAtom(ni)->GetType()) == (*i))
+ snprintf(_logbuf, BUFF_SIZE, "%2d %3d %4d %3d %3d PASSED", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetHyb(),
+ _mol.GetAtom(ni)->IsAromatic(), atoi(_mol.GetAtom(ni)->GetType()), *i);
+ else {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %3d %4d %3d %3d XXX FAILED XXX", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetHyb(),
+ _mol.GetAtom(ni)->IsAromatic(), atoi(_mol.GetAtom(ni)->GetType()), *i);
+ failed = true;
+ }
+
+ cout << _logbuf << endl;
+
+ ni++;
+ }
+
+ if (failed) {
+ cout << "Could not successfully assign atom types" << endl;
+ return false;
+ //continue;
+ }
+
+ SetFormalCharges();
+ cout << endl;
+ cout << "IDX OB_FCARGE LOG_FCHARGE RESULT" << endl;
+ cout << "----------------------------------------" << endl;
+
+ ni = 1;
+ for (di = fcharges.begin(); di != fcharges.end(); di++) {
+ if (ni > _mol.NumAtoms())
+ continue;
+
+ if ( (atoi(_mol.GetAtom(ni)->GetType()) == 87) ||
+ (atoi(_mol.GetAtom(ni)->GetType()) == 97)
+ ) continue;
+
+ if (fabs((*di) - _mol.GetAtom(ni)->GetPartialCharge()) <= 0.001)
+ snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f PASSED", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetPartialCharge(), *di);
+ else {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f XXX FAILED XXX", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetPartialCharge(), *di);
+ failed = true;
+ }
+
+ cout << _logbuf << endl;
+
+ ni++;
+ }
+
+ if (failed) {
+ cout << "Could not successfully assign formal charges" << endl;
+ //return false;
+ continue;
+ }
+
+ SetPartialCharges();
+ cout << endl;
+ cout << "IDX OB_PCARGE LOG_PCHARGE RESULT" << endl;
+ cout << "----------------------------------------" << endl;
+
+ ni = 1;
+ for (di = pcharges.begin(); di != pcharges.end(); di++) {
+ if (ni > _mol.NumAtoms())
+ continue;
+
+ if ( (atoi(_mol.GetAtom(ni)->GetType()) == 87) ||
+ (atoi(_mol.GetAtom(ni)->GetType()) == 97)
+ ) continue;
+
+ if (fabs((*di) - _mol.GetAtom(ni)->GetPartialCharge()) <= 0.001)
+ snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f PASSED", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetPartialCharge(), *di);
+ else {
+ snprintf(_logbuf, BUFF_SIZE, "%2d %7.4f %7.4f XXX FAILED XXX", _mol.GetAtom(ni)->GetIdx(), _mol.GetAtom(ni)->GetPartialCharge(), *di);
+ failed = true;
+ }
+
+ cout << _logbuf << endl;
+
+ ni++;
+ }
+
+ if (failed) {
+ cout << "Could not successfully assign partial charges" << endl;
+ //return false;
+ continue;
+ }
+
+
+
+ if (!SetupCalculations()) {
+ cout << "Could not setup calculations (missing parameters...)" << endl;
+ return false;
+ //continue;
+ }
+
+ double delta;
+ cout << endl;
+ cout << "TERM OB ENERGY LOG ENERGY DELTA" << endl;
+ cout << "---------------------------------------------------------------" << endl;
+
+ delta = (E_Bond() - ebond);
+ snprintf(_logbuf, BUFF_SIZE, "ZNBond Stretching %11.5f %11.5f %11.5f", E_Bond(), ebond, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_Angle() - eangle);
+ snprintf(_logbuf, BUFF_SIZE, "Angle Bending %11.5f %11.5f %11.5f", E_Angle(), eangle, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_StrBnd() - estbn);
+ snprintf(_logbuf, BUFF_SIZE, "Stretch-Bending %11.5f %11.5f %11.5f", E_StrBnd(), estbn, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_OOP() - eoop);
+ snprintf(_logbuf, BUFF_SIZE, "Out-Of-Plane Bending %11.5f %11.5f %11.5f", E_OOP(), eoop, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_Torsion() - etor);
+ snprintf(_logbuf, BUFF_SIZE, "Torsional %11.5f %11.5f %11.5f", E_Torsion(), etor, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_VDW() - evdw);
+ snprintf(_logbuf, BUFF_SIZE, "Van der Waals %11.5f %11.5f %11.5f", E_VDW(), evdw, delta);
+ cout << _logbuf << endl;
+
+ delta = (E_Electrostatic() - eeq);
+ snprintf(_logbuf, BUFF_SIZE, "Electrostatic %11.5f %11.5f %11.5f", E_Electrostatic(), eeq, delta);
+ cout << _logbuf << endl;
+
+ cout << endl;
+ delta = (Energy() - etot);
+ snprintf(_logbuf, BUFF_SIZE, "Total ENERGY %11.5f %11.5f %11.5f", Energy(), etot, delta);
+ cout << _logbuf << endl;
+
+ } // for (unsigned int c;; c++ )
+
+ if (ifs)
+ ifs.close();
+ if (ifs2)
+ ifs2.close();
+
+ return true;
+ }
+
+ bool OBForceFieldMMFF94::ValidateGradients ()
+ {
+ vector3 numgrad, anagrad, err;
+ int coordIdx;
+
+ bool passed = true; // set to false if any component fails
+
+ cout << "----------------------------------------------------------------------------------------" << endl;
+ cout << " " << endl;
+ cout << " VALIDATE GRADIENTS : " << _mol.GetTitle() << endl;
+ cout << " " << endl;
+ cout << " " << endl;
+ cout << "ATOM IDX NUMERICAL GRADIENT ANALYTICAL GRADIENT REL. ERROR (%) " << endl;
+ cout << "----------------------------------------------------------------------------------------" << endl;
+ // "XX (000.000, 000.000, 000.000) (000.000, 000.000, 000.000) (00.00, 00.00, 00.00)"
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ coordIdx = (a->GetIdx() - 1) * 3;
+
+ // OBFF_ENERGY
+ numgrad = NumericalDerivative(&*a, OBFF_ENERGY);
+ Energy(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, "%2d (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", a->GetIdx(), numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+
+ // OBFF_EBOND
+ numgrad = NumericalDerivative(&*a, OBFF_EBOND);
+ ClearGradients();
+ E_Bond(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " bond (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EANGLE
+ numgrad = NumericalDerivative(&*a, OBFF_EANGLE);
+ ClearGradients();
+ E_Angle(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " angle (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_ESTRBND
+ numgrad = NumericalDerivative(&*a, OBFF_ESTRBND);
+ ClearGradients();
+ E_StrBnd(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " strbnd (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_ETORSION
+ numgrad = NumericalDerivative(&*a, OBFF_ETORSION);
+ ClearGradients();
+ E_Torsion(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " torsion (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EOOP
+ numgrad = NumericalDerivative(&*a, OBFF_EOOP);
+ ClearGradients();
+ E_OOP(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " oop (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ // disable OOP gradient validation for now -- some small errors, but nothing major
+ // if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ // passed = false;
+
+ // OBFF_EVDW
+ numgrad = NumericalDerivative(&*a, OBFF_EVDW);
+ ClearGradients();
+ E_VDW(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " vdw (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EELECTROSTATIC
+ numgrad = NumericalDerivative(&*a, OBFF_EELECTROSTATIC);
+ ClearGradients();
+ E_Electrostatic(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " electro (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+ }
+
+ return passed; // did we pass every single component?
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Calculate bond type, angle type, stretch-bend type, torsion type
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ //
+ // MMFF part V - page 620
+ //
+ // BTij is 1 when:
+ // a) single bond between atoms i and j, both i and j are not aromatic and both types have sbmb set in mmffprop.par, or
+ // b) bewtween two aromatic atoms, but the bond is not aromatic (e.g. connecting bond in biphenyl)
+ //
+ int OBForceFieldMMFF94::GetBondType(OBAtom* a, OBAtom* b)
+ {
+ if (!_mol.GetBond(a,b)->IsSingle())
+ return 0;
+
+ if (!_mol.GetBond(a,b)->IsAromatic())
+ if (HasAromSet(atoi(a->GetType())) && HasAromSet(atoi(b->GetType())))
+ return 1;
+
+ if (HasSbmbSet(atoi(a->GetType())) && HasSbmbSet(atoi(b->GetType())))
+ return 1;
+
+ return 0;
+ }
+
+ int OBForceFieldMMFF94::GetAngleType(OBAtom* a, OBAtom* b, OBAtom *c)
+ {
+ int sumbondtypes;
+
+ sumbondtypes = GetBondType(a,b) + GetBondType(b, c);
+
+ if (a->IsInRingSize(3) && b->IsInRingSize(3) && c->IsInRingSize(3) && IsInSameRing(a, c))
+ switch (sumbondtypes) {
+ case 0:
+ return 3;
+ case 1:
+ return 5;
+ case 2:
+ return 6;
+ }
+
+ if (a->IsInRingSize(4) && b->IsInRingSize(4) && c->IsInRingSize(4) && IsInSameRing(a, c))
+ switch (sumbondtypes) {
+ case 0:
+ return 4;
+ case 1:
+ return 7;
+ case 2:
+ return 8;
+ }
+
+ return sumbondtypes;
+ }
+
+ int OBForceFieldMMFF94::GetStrBndType(OBAtom* a, OBAtom* b, OBAtom *c)
+ {
+ int btab, btbc, atabc;
+ bool inverse;
+
+ btab = GetBondType(a, b);
+ btbc = GetBondType(b, c);
+ atabc = GetAngleType(a, b, c);
+
+ if (atoi(a->GetType()) <= atoi(c->GetType()))
+ inverse = false;
+ else
+ inverse = true;
+
+ switch (atabc) {
+ case 0:
+ return 0;
+
+ case 1:
+ if (btab)
+ if (!inverse)
+ return 1;
+ else
+ return 2;
+ if (btbc)
+ if (!inverse)
+ return 2;
+ else
+ return 1;
+
+ case 2:
+ return 3;
+
+ case 3:
+ return 5;
+
+ case 4:
+ return 4;
+
+ case 5:
+ if (btab)
+ if (!inverse)
+ return 6;
+ else
+ return 7;
+ if (btbc)
+ if (!inverse)
+ return 7;
+ else
+ return 6;
+
+ case 6:
+ return 8;
+
+ case 7:
+ if (btab)
+ if (!inverse)
+ return 9;
+ else
+ return 10;
+ if (btbc)
+ if (!inverse)
+ return 10;
+ else
+ return 9;
+
+ case 8:
+ return 11;
+ }
+
+ return 0;
+ }
+
+ //
+ // MMFF part IV - page 609
+ //
+ // TTijkl = 1 when BTjk = 1
+ // TTijkl = 2 when BTjk = 0 but BTij and/or BTkl = 1
+ // TTijkl = 4 when i, j, k and l are all members of the same four-membered ring
+ // TTijkl = 5 when i, j, k and l are members of a five-membered ring and at least one is a sp3-hybridized carbon (MMFF atom type 1)
+ //
+ int OBForceFieldMMFF94::GetTorsionType(OBAtom* a, OBAtom* b, OBAtom *c, OBAtom *d)
+ {
+ int btab, btbc, btcd;
+
+ btab = GetBondType(a, b);
+ btbc = GetBondType(b, c);
+ btcd = GetBondType(c, d);
+
+ if (btbc == 1)
+ return 1;
+
+ if (a->IsInRingSize(4) && b->IsInRingSize(4) && c->IsInRingSize(4) && d->IsInRingSize(4))
+ if (IsInSameRing(a,b) && IsInSameRing(b,c) && IsInSameRing(c,d))
+ return 4;
+
+ if (_mol.GetBond(b,c)->IsSingle()) {
+ if (btab || btcd)
+ return 2;
+ /*
+ unsigned int order1 = GetCXT(0, atoi(d->GetType()), atoi(c->GetType()), atoi(b->GetType()), atoi(a->GetType()));
+ unsigned int order2 = GetCXT(0, atoi(a->GetType()), atoi(b->GetType()), atoi(c->GetType()), atoi(d->GetType()));
+
+ cout << "GetTorsionType(" << a->GetType() << ", " << b->GetType() << ", " << c->GetType() << ", " << d->GetType() << ")" << endl;
+ cout << " order1 = " << order1 << endl;
+ cout << " order2 = " << order2 << endl;
+ cout << " btab = " << btab << endl;
+ cout << " btbc = " << btbc << endl;
+ cout << " btcd = " << btcd << endl;
+ */
+ }
+
+ if (a->IsInRingSize(5) && b->IsInRingSize(5) && c->IsInRingSize(5) && d->IsInRingSize(5)) {
+ vector<OBRing*> vr;
+ vr = _mol.GetSSSR();
+
+ if( !((atoi(a->GetType()) == 1) || (atoi(b->GetType()) == 1) || (atoi(c->GetType()) == 1) || (atoi(d->GetType()) == 1)) )
+ return 0;
+
+ vector<OBRing*>::iterator ri;
+ vector<int>::iterator rj;
+ for (ri = vr.begin();ri != vr.end();++ri) { // for each ring
+ if ((*ri)->IsAromatic())
+ continue;
+
+ if ((*ri)->Size() != 5)
+ continue;
+
+ if (!(*ri)->IsMember(a) || !(*ri)->IsMember(b) || !(*ri)->IsMember(c) || !(*ri)->IsMember(d))
+ continue;
+
+ return 5;
+ }
+ }
+
+
+ return 0;
+ }
+
+ // CXB = MC * (I * MA + J) + BTij
+ unsigned int OBForceFieldMMFF94::GetCXB(int type, int a, int b)
+ {
+ unsigned int cxb;
+ cxb = 2 * (a * 136 + b) + type;
+ return cxb;
+ }
+
+ // CXA = MC * (J * MA^2 + I * MA + K) + ATijk
+ unsigned int OBForceFieldMMFF94::GetCXA(int type, int a, int b, int c)
+ {
+ unsigned int cxa;
+ cxa = 9 * (b * 18496 + a * 136 + c) + type;
+ return cxa;
+ }
+
+ // CXS = MC * (J * MA^2 + I * MA + K) + STijk
+ unsigned int OBForceFieldMMFF94::GetCXS(int type, int a, int b, int c)
+ {
+ unsigned int cxs;
+ cxs = 12 * (b * 18496 + a * 136 + c) + type;
+ return cxs;
+ }
+
+ // CXO = J * MA^3 + I * MA^2 + K * MA + L
+ unsigned int OBForceFieldMMFF94::GetCXO(int a, int b, int c, int d)
+ {
+ unsigned int cxo;
+ cxo = b * 2515456 + a * 18496 + c * 136 + d;
+ return cxo;
+ }
+
+ // CXT = MC * (J * MA^3 + K * MA^2 + I * MA + L) + TTijkl
+ unsigned int OBForceFieldMMFF94::GetCXT(int type, int a, int b, int c, int d)
+ {
+ unsigned int cxt;
+ cxt = 6 * (b * 2515456 + c * 18496 + a * 136 + d) + type;
+ return cxt;
+ }
+
+ // CXQ = MC * (I * MA + J) + BTij
+ unsigned int OBForceFieldMMFF94::GetCXQ(int type, int a, int b)
+ {
+ unsigned int cxq;
+ cxq = 2 * (a * 136 + b) + type;
+ return cxq;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Various tables & misc. functions
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // MMFF part V - TABLE I
+ bool OBForceFieldMMFF94::HasLinSet(int atomtype)
+ {
+ return _ffpropLin.BitIsSet(atomtype);
+ }
+
+ // MMFF part V - TABLE I
+ bool OBForceFieldMMFF94::HasPilpSet(int atomtype)
+ {
+ return _ffpropPilp.BitIsSet(atomtype);
+ }
+
+ // MMFF part V - TABLE I
+ bool OBForceFieldMMFF94::HasAromSet(int atomtype)
+ {
+ return _ffpropArom.BitIsSet(atomtype);
+ }
+
+ // MMFF part V - TABLE I
+ bool OBForceFieldMMFF94::HasSbmbSet(int atomtype)
+ {
+ return _ffpropSbmb.BitIsSet(atomtype);
+ }
+
+ // MMFF part V - TABLE I
+ int OBForceFieldMMFF94::GetCrd(int atomtype)
+ {
+ OBFFParameter *par;
+
+ par = GetParameter1Atom(atomtype, _ffpropparams); // from mmffprop.par
+ if (par)
+ return par->_ipar[1];
+
+ return 0;
+ }
+
+ // MMFF part V - TABLE I
+ int OBForceFieldMMFF94::GetVal(int atomtype)
+ {
+ OBFFParameter *par;
+
+ par = GetParameter1Atom(atomtype, _ffpropparams); // from mmffprop.par
+ if (par)
+ return par->_ipar[2];
+
+ return 0;
+ }
+
+ // MMFF part V - TABLE I
+ int OBForceFieldMMFF94::GetMltb(int atomtype)
+ {
+ OBFFParameter *par;
+
+ par = GetParameter1Atom(atomtype, _ffpropparams); // from mmffprop.par
+ if (par)
+ return par->_ipar[4];
+
+ return 0;
+ }
+
+ // MMFF part I - TABLE IV
+ int OBForceFieldMMFF94::EqLvl2(int type)
+ {
+ for (unsigned int idx=0; idx < _ffdefparams.size(); idx++)
+ if (_ffdefparams[idx]._ipar[0] == type)
+ return _ffdefparams[idx]._ipar[1];
+
+ return type;
+ }
+
+ // MMFF part I - TABLE IV
+ int OBForceFieldMMFF94::EqLvl3(int type)
+ {
+ for (unsigned int idx=0; idx < _ffdefparams.size(); idx++)
+ if (_ffdefparams[idx]._ipar[0] == type)
+ return _ffdefparams[idx]._ipar[2];
+
+ return type;
+ }
+
+ // MMFF part I - TABLE IV
+ int OBForceFieldMMFF94::EqLvl4(int type)
+ {
+ for (unsigned int idx=0; idx < _ffdefparams.size(); idx++)
+ if (_ffdefparams[idx]._ipar[0] == type)
+ return _ffdefparams[idx]._ipar[3];
+
+ return type;
+ }
+
+ // MMFF part I - TABLE IV
+ int OBForceFieldMMFF94::EqLvl5(int type)
+ {
+ for (unsigned int idx=0; idx < _ffdefparams.size(); idx++)
+ if (_ffdefparams[idx]._ipar[0] == type)
+ return _ffdefparams[idx]._ipar[4];
+
+ return type;
+ }
+
+ // MMFF part V - TABLE VI
+ double OBForceFieldMMFF94::GetZParam(OBAtom* atom)
+ {
+ if (atom->IsHydrogen())
+ return 1.395;
+ if (atom->IsCarbon())
+ return 2.494;
+ if (atom->IsNitrogen())
+ return 2.711;
+ if (atom->IsOxygen())
+ return 3.045;
+ if (atom->GetAtomicNum() == 9) // F
+ return 2.847;
+ if (atom->GetAtomicNum() == 14) // Si
+ return 2.350;
+ if (atom->IsPhosphorus())
+ return 2.350;
+ if (atom->IsSulfur())
+ return 2.980;
+ if (atom->GetAtomicNum() == 17) // Cl
+ return 2.909;
+ if (atom->GetAtomicNum() == 35) // Br
+ return 3.017;
+ if (atom->GetAtomicNum() == 53) // I
+ return 3.086;
+
+ return 0.0;
+ }
+
+ // MMFF part V - TABLE VI
+ double OBForceFieldMMFF94::GetCParam(OBAtom* atom)
+ {
+ if (atom->GetAtomicNum() == 5) // B
+ return 0.704;
+ if (atom->IsCarbon())
+ return 1.016;
+ if (atom->IsNitrogen())
+ return 1.113;
+ if (atom->IsOxygen())
+ return 1.337;
+ if (atom->GetAtomicNum() == 14) // Si
+ return 0.811;
+ if (atom->IsPhosphorus())
+ return 1.068;
+ if (atom->IsSulfur())
+ return 1.249;
+ if (atom->GetAtomicNum() == 17) // Cl
+ return 1.078;
+ if (atom->GetAtomicNum() == 33) // As
+ return 0.825;
+
+ return 0.0;
+ }
+
+ // MMFF part V - TABLE X
+ double OBForceFieldMMFF94::GetUParam(OBAtom* atom)
+ {
+ if (atom->IsCarbon())
+ return 2.0;
+ if (atom->IsNitrogen())
+ return 2.0;
+ if (atom->IsOxygen())
+ return 2.0;
+ if (atom->GetAtomicNum() == 14) // Si
+ return 1.25;
+ if (atom->IsPhosphorus())
+ return 1.25;
+ if (atom->IsSulfur())
+ return 1.25;
+
+ return 0.0;
+ }
+
+ // MMFF part V - TABLE X
+ double OBForceFieldMMFF94::GetVParam(OBAtom* atom)
+ {
+ if (atom->IsCarbon())
+ return 2.12;
+ if (atom->IsNitrogen())
+ return 1.5;
+ if (atom->IsOxygen())
+ return 0.2;
+ if (atom->GetAtomicNum() == 14) // Si
+ return 1.22;
+ if (atom->IsPhosphorus())
+ return 2.4;
+ if (atom->IsSulfur())
+ return 0.49;
+
+ return 0.0;
+ }
+
+ // R Blom and A Haaland, J. Mol. Struct., 128, 21-27 (1985)
+ double OBForceFieldMMFF94::GetCovalentRadius(OBAtom* a) {
+
+ switch (a->GetAtomicNum()) {
+ case 1:
+ return 0.33; // corrected value from MMFF part V
+ case 5:
+ return 0.81;
+ case 6:
+ return 0.77; // corrected value from MMFF part V
+ case 7:
+ return 0.73;
+ case 8:
+ return 0.72;
+ case 9:
+ return 0.74;
+ case 13:
+ return 1.22;
+ case 14:
+ return 1.15;
+ case 15:
+ return 1.09;
+ case 16:
+ return 1.03;
+ case 17:
+ return 1.01;
+ case 31:
+ return 1.19;
+ case 32:
+ return 1.20;
+ case 33:
+ return 1.20;
+ case 34:
+ return 1.16;
+ case 35:
+ return 1.15;
+ case 44:
+ return 1.46;
+ case 50:
+ return 1.40;
+ case 51:
+ return 1.41;
+ case 52:
+ return 1.35;
+ case 53:
+ return 1.33;
+ case 81:
+ return 1.51;
+ case 82:
+ return 1.53;
+ case 83:
+ return 1.55;
+ default:
+ return etab.GetCovalentRad(a->GetAtomicNum());
+ }
+ }
+
+ double OBForceFieldMMFF94::GetBondLength(OBAtom* a, OBAtom* b)
+ {
+ OBFFParameter *parameter;
+ double rab;
+
+ parameter = GetTypedParameter2Atom(GetBondType(a, b), atoi(a->GetType()), atoi(b->GetType()), _ffbondparams);
+ if (parameter == NULL)
+ rab = GetRuleBondLength(a, b);
+ else
+ rab = parameter->_dpar[1];
+
+ return rab;
+ }
+
+ // MMFF part V - page 625
+ double OBForceFieldMMFF94::GetRuleBondLength(OBAtom* a, OBAtom* b)
+ {
+ double r0ab, r0a, r0b, c, Xa, Xb;
+ int Ha, Hb, BOab;
+ r0a = GetCovalentRadius(a);
+ r0b = GetCovalentRadius(b);
+ Xa = etab.GetAllredRochowElectroNeg(a->GetAtomicNum());
+ Xb = etab.GetAllredRochowElectroNeg(b->GetAtomicNum());
+
+
+ if (a->IsHydrogen())
+ r0a = 0.33;
+ if (b->IsHydrogen())
+ r0b = 0.33;
+
+ if (a->IsHydrogen() || b->IsHydrogen())
+ c = 0.050;
+ else
+ c = 0.085;
+
+ if (GetMltb(atoi(a->GetType()) == 3))
+ Ha = 1;
+ else if ((GetMltb(atoi(a->GetType())) == 1) || (GetMltb(atoi(a->GetType())) == 2))
+ Ha = 2;
+ else
+ Ha = 3;
+
+ if (GetMltb(atoi(b->GetType()) == 3))
+ Hb = 1;
+ else if ((GetMltb(atoi(b->GetType())) == 1) || (GetMltb(atoi(b->GetType())) == 2))
+ Hb = 2;
+ else
+ Hb = 3;
+
+ BOab = a->GetBond(b)->GetBondOrder();
+ if ((GetMltb(atoi(a->GetType())) == 1) && (GetMltb(atoi(b->GetType())) == 1))
+ BOab = 4;
+ if ((GetMltb(atoi(a->GetType())) == 1) && (GetMltb(atoi(b->GetType())) == 2))
+ BOab = 5;
+ if ((GetMltb(atoi(a->GetType())) == 2) && (GetMltb(atoi(b->GetType())) == 1))
+ BOab = 5;
+ if (a->GetBond(b)->IsAromatic())
+ if (!HasPilpSet(atoi(a->GetType())) && !HasPilpSet(atoi(b->GetType())))
+ BOab = 4;
+ else
+ BOab = 5;
+
+ switch (BOab) {
+ case 5:
+ r0a -= 0.04;
+ r0b -= 0.04;
+ break;
+ case 4:
+ r0a -= 0.075;
+ r0b -= 0.075;
+ break;
+ case 3:
+ r0a -= 0.17;
+ r0b -= 0.17;
+ break;
+ case 2:
+ r0a -= 0.10;
+ r0b -= 0.10;
+ break;
+ case 1:
+ if (Ha == 1)
+ r0a -= 0.08;
+ if (Ha == 2)
+ r0a -= 0.03;
+ if (Hb == 1)
+ r0b -= 0.08;
+ if (Hb == 2)
+ r0b -= 0.03;
+ }
+
+ /*
+ cout << "Ha=" << Ha << " Hb=" << Hb << " BOab=" << BOab << endl;
+ cout << "r0a=" << r0a << " Xa=" << Xa << endl;
+ cout << "r0b=" << r0b << " Xb=" << Xb << endl;
+ cout << "r0a + r0b=" << r0a +r0b << endl;
+ cout << "c=" << c << " |Xa-Xb|=" << fabs(Xa-Xb) << " |Xa-Xb|^1.4=" << pow(fabs(Xa-Xb), 1.4) << endl;
+ */
+ r0ab = r0a + r0b - c * pow(fabs(Xa - Xb), 1.4) - 0.008;
+
+ return r0ab;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetParameter1Atom(int a, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (a == parameter[idx].a) {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetParameter2Atom(int a, int b, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (((a == parameter[idx].a) && (b == parameter[idx].b)) ||
+ ((a == parameter[idx].b) && (b == parameter[idx].a)))
+ {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetParameter3Atom(int a, int b, int c, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (((a == parameter[idx].a) && (b == parameter[idx].b) && (c == parameter[idx].c)) ||
+ ((a == parameter[idx].c) && (b == parameter[idx].b) && (c == parameter[idx].a)))
+ {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetTypedParameter2Atom(int ffclass, int a, int b, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (((a == parameter[idx].a) && (b == parameter[idx].b) && (ffclass == parameter[idx]._ipar[0])) ||
+ ((a == parameter[idx].b) && (b == parameter[idx].a) && (ffclass == parameter[idx]._ipar[0])))
+ {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetTypedParameter3Atom(int ffclass, int a, int b, int c, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (((a == parameter[idx].a) && (b == parameter[idx].b) && (c == parameter[idx].c) && (ffclass == parameter[idx]._ipar[0])) ||
+ ((a == parameter[idx].c) && (b == parameter[idx].b) && (c == parameter[idx].a) && (ffclass == parameter[idx]._ipar[0])) )
+ {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+ OBFFParameter* OBForceFieldMMFF94::GetTypedParameter4Atom(int ffclass, int a, int b, int c, int d, std::vector<OBFFParameter> ¶meter)
+ {
+ OBFFParameter *par;
+
+ for (unsigned int idx=0; idx < parameter.size(); idx++)
+ if (((a == parameter[idx].a) && (b == parameter[idx].b) && (c == parameter[idx].c) &&
+ (d == parameter[idx].d) && (ffclass == parameter[idx]._ipar[0]))
+ /* || ((a == parameter[idx].d) && (b == parameter[idx].c) && (c == parameter[idx].b) &&
+ (d == parameter[idx].a) && (ffclass == parameter[idx]._ipar[0])) */ )
+ {
+ par = ¶meter[idx];
+ return par;
+ }
+
+ return NULL;
+ }
+
+} // end namespace OpenBabel
+
+//! \file forcefieldmmff94.cpp
+//! \brief MMFF94 force field
diff --git a/forcefields/forcefieldmmff94.h b/forcefields/forcefieldmmff94.h
new file mode 100644
index 0000000..2411941
--- /dev/null
+++ b/forcefields/forcefieldmmff94.h
@@ -0,0 +1,333 @@
+/**********************************************************************
+forcefieldmmff94.h - MMFF94
+
+Copyright (C) 2006 by Tim Vandermeersch <tim.vandermeersch at gmail.com>
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include <openbabel/parsmart.h>
+#include <openbabel/forcefield.h>
+#include <openbabel/base.h>
+#include <openbabel/mol.h>
+
+namespace OpenBabel
+{
+ class OBFFBondCalculationMMFF94 : public OBFFCalculation2
+ {
+ public:
+ int bt; // bondtype (BTIJ)
+ double kb, r0, rab, delta;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFAngleCalculationMMFF94 : public OBFFCalculation3
+ {
+ public:
+ int at; //angletype (ATIJK)
+ bool linear;
+ double ka, theta, theta0, delta;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFStrBndCalculationMMFF94 : public OBFFCalculation3
+ {
+ public:
+ int sbt; //strbndtype (SBTIJK)
+ double kbaABC, kbaCBA, theta0, rab0, rbc0, delta_theta, delta_rab, delta_rbc;
+ double theta, rab, rbc;
+ double force_ab_a[3], force_ab_b[3], force_bc_b[3], force_bc_c[3];
+ double force_abc_a[3], force_abc_b[3], force_abc_c[3];
+
+ template<bool> void Compute();
+ };
+
+ class OBFFTorsionCalculationMMFF94 : public OBFFCalculation4
+ {
+ public:
+ int tt; //torsiontype (TTIJKL)
+ double v1, v2, v3, tor, cosine;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFOOPCalculationMMFF94 : public OBFFCalculation4
+ {
+ public:
+ double koop, angle;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFVDWCalculationMMFF94 : public OBFFCalculation2
+ {
+ public:
+ int aDA, bDA; // hydrogen donor/acceptor (A=1, D=2, neither=0)
+ double rab, epsilon, alpha_a, alpha_b, Na, Nb, Aa, Ab, Ga, Gb;
+ double R_AB, R_AB7/*, erep, erep7, eattr*/;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFElectrostaticCalculationMMFF94 : public OBFFCalculation2
+ {
+ public:
+ double qq, rab;
+
+ template<bool> void Compute();
+ };
+
+ // Class OBForceFieldMMFF94
+ // class introduction in forcefieldmmff94.cpp
+ class OBForceFieldMMFF94: public OBForceField
+ {
+ protected:
+ //! \return Parses the parameter file
+ bool ParseParamFile();
+ bool ParseParamProp(std::string &filename);
+ bool ParseParamDef(std::string &filename);
+ bool ParseParamBond(std::string &filename);
+ bool ParseParamBndk(std::string &filename);
+ bool ParseParamAngle(std::string &filename);
+ bool ParseParamStrBnd(std::string &filename);
+ bool ParseParamDfsb(std::string &filename);
+ bool ParseParamOOP(std::string &filename);
+ bool ParseParamTorsion(std::string &filename);
+ bool ParseParamVDW(std::string &filename);
+ bool ParseParamCharge(std::string &filename);
+ bool ParseParamPbci(std::string &filename);
+ //! detect which rings are aromatic
+ bool PerceiveAromatic();
+ //! \return Get the MMFF94 atom type for atom
+ int GetType(OBAtom *atom);
+ //! \return Sets atomtypes to MMFF94 in _mol
+ bool SetTypes();
+ //! fill OBFFXXXCalculation vectors
+ bool SetupCalculations();
+ //! Setup pointers in OBFFXXXCalculation vectors
+ bool SetupPointers();
+ //! Sets formal charges
+ bool SetFormalCharges();
+ //! Sets partial charges
+ bool SetPartialCharges();
+ //! \return The row of the element atom in the periodic table
+ int GetElementRow(OBAtom *atom);
+ //! \return The bond type (BTIJ)
+ int GetBondType(OBAtom* a, OBAtom* b);
+ //! \return The angle type (ATIJK)
+ int GetAngleType(OBAtom* a, OBAtom* b, OBAtom *c);
+ //! \return The stretch-bend type (SBTIJK)
+ int GetStrBndType(OBAtom* a, OBAtom* b, OBAtom *c);
+ //! \return The torsion type (TTIJKL)
+ int GetTorsionType(OBAtom* a, OBAtom* b, OBAtom *c, OBAtom *d);
+ //! \return true if atomtype has sbmb set in mmffprop.par
+ bool HasSbmbSet(int atomtype);
+ //! \return true if atomtype has pilp set in mmffprop.par
+ bool HasPilpSet(int atomtype);
+ //! \return true if atomtype has arom set in mmffprop.par
+ bool HasAromSet(int atomtype);
+ //! \return true if atomtype has lin set in mmffprop.par
+ bool HasLinSet(int atomtype);
+ //! \return the crd value for the atomtype in mmffprop.par
+ int GetCrd(int atomtype);
+ //! \return the val value for the atomtype in mmffprop.par
+ int GetVal(int atomtype);
+ //! \return the mltb value for the atomtype in mmffprop.par
+ int GetMltb(int atomtype);
+ //! \return the level 2 equivalent atom type for type (mmffdef.par)
+ int EqLvl2(int type);
+ //! \return the level 3 equivalent atom type for type (mmffdef.par)
+ int EqLvl3(int type);
+ //! \return the level 4 equivalent atom type for type (mmffdef.par)
+ int EqLvl4(int type);
+ //! \return the level 5 equivalent atom type for type (mmffdef.par)
+ int EqLvl5(int type);
+ //! \return the canonical bond index
+ unsigned int GetCXB(int type, int a, int b);
+ //! \return the canonical angle index
+ unsigned int GetCXA(int type, int a, int b, int c);
+ //! \return the canonical stretch-bend index
+ unsigned int GetCXS(int type, int a, int b, int c);
+ //! \return the canonical out-of-plane index
+ unsigned int GetCXO(int a, int b, int c, int d);
+ //! \return the canonical torsion index
+ unsigned int GetCXT(int type, int a, int b, int c, int d);
+ //! \return the canonical bond-charge-increment index
+ unsigned int GetCXQ(int type, int a, int b);
+ //! \return the U value for the atom from table X page 631
+ double GetUParam(OBAtom* atom);
+ //! \return the Z value for the atom from table VI page 628
+ double GetZParam(OBAtom* atom);
+ //! \return the C value for the atom from table VI page 628
+ double GetCParam(OBAtom* atom);
+ //! \return the V value for the atom from table X page 631
+ double GetVParam(OBAtom* atom);
+ //! return the covalent radius from Blom and Haaland, value from etab if not available
+ double GetCovalentRadius(OBAtom* a);
+ //! return the bond length calculated with a modified version of the Schomaker-Stevenson rule
+ double GetRuleBondLength(OBAtom* a, OBAtom* b);
+ //! return the bond length from mmffbond.par, if not found, one is calculated with a modified version of the Schomaker-Stevenson rule
+ double GetBondLength(OBAtom* a, OBAtom* b);
+
+ //! Same as OBForceField::GetParameter, but takes (bond/angle/torsion) type in account and takes 0 as wildcart.
+ OBFFParameter* GetParameter1Atom(int a, std::vector<OBFFParameter> ¶meter);
+ OBFFParameter* GetParameter2Atom(int a, int b, std::vector<OBFFParameter> ¶meter);
+ OBFFParameter* GetParameter3Atom(int a, int b, int c, std::vector<OBFFParameter> ¶meter);
+
+ //! Same as OBForceField::GetParameter, but takes (bond/angle/torsion) type in account and takes 0 as wildcart.
+ OBFFParameter* GetTypedParameter2Atom(int ffclass, int a, int b, std::vector<OBFFParameter> ¶meter);
+ OBFFParameter* GetTypedParameter3Atom(int ffclass, int a, int b, int c, std::vector<OBFFParameter> ¶meter);
+ OBFFParameter* GetTypedParameter4Atom(int ffclass, int a, int b, int c, int d, std::vector<OBFFParameter> ¶meter);
+
+
+ // OBFFParameter vectors to contain the parameters
+ std::vector<OBFFParameter> _ffbondparams;
+ std::vector<OBFFParameter> _ffbndkparams;
+ std::vector<OBFFParameter> _ffangleparams;
+ std::vector<OBFFParameter> _ffstrbndparams;
+ std::vector<OBFFParameter> _ffdfsbparams;
+ std::vector<OBFFParameter> _fftorsionparams;
+ std::vector<OBFFParameter> _ffoopparams;
+ std::vector<OBFFParameter> _ffvdwparams;
+ std::vector<OBFFParameter> _ffchgparams;
+ std::vector<OBFFParameter> _ffpbciparams;
+ std::vector<OBFFParameter> _ffdefparams;
+ std::vector<OBFFParameter> _ffpropparams;
+ OBBitVec _ffpropPilp;
+ OBBitVec _ffpropArom;
+ OBBitVec _ffpropLin;
+ OBBitVec _ffpropSbmb;
+
+ // OBFFXXXCalculationYYY vectors to contain the calculations
+ std::vector<OBFFBondCalculationMMFF94> _bondcalculations;
+ std::vector<OBFFAngleCalculationMMFF94> _anglecalculations;
+ std::vector<OBFFStrBndCalculationMMFF94> _strbndcalculations;
+ std::vector<OBFFTorsionCalculationMMFF94> _torsioncalculations;
+ std::vector<OBFFOOPCalculationMMFF94> _oopcalculations;
+ std::vector<OBFFVDWCalculationMMFF94> _vdwcalculations;
+ std::vector<OBFFElectrostaticCalculationMMFF94> _electrostaticcalculations;
+
+ bool mmff94s;
+
+ public:
+ //! Constructor
+ explicit OBForceFieldMMFF94(const char* ID, bool IsDefault=true) : OBForceField(ID, IsDefault)
+ {
+ _init = false;
+ _rvdw = 7.0;
+ _rele = 15.0;
+ _pairfreq = 15;
+ _cutoff = false;
+ _linesearch = LineSearchType::Simple;
+ if (!strncmp(ID, "MMFF94s", 7)) {
+ mmff94s = true;
+ _parFile = std::string("mmff94s.ff");
+ } else {
+ mmff94s = false;
+ _parFile = std::string("mmff94.ff");
+ }
+ }
+
+ //! Destructor
+ virtual ~OBForceFieldMMFF94();
+
+ //! Assignment
+ OBForceFieldMMFF94 &operator = (OBForceFieldMMFF94 &);
+
+ //!Clone the current instance. May be desirable in multithreaded environments
+ virtual OBForceFieldMMFF94* MakeNewInstance()
+ {
+ return new OBForceFieldMMFF94(*this);
+ }
+
+ //! Get the description for this force field
+ const char* Description()
+ {
+ if (mmff94s)
+ return "MMFF94s force field.";
+ else
+ return "MMFF94 force field.";
+ }
+
+ //! Get the unit in which the energy is expressed
+ std::string GetUnit()
+ {
+ return std::string("kcal/mol");
+ }
+
+ //! \return that analytical gradients are implemented for MMFF94
+ bool HasAnalyticalGradients() { return true; }
+
+ //! Returns total energy
+ double Energy(bool gradients = true);
+ //! Returns the bond stretching energy
+ template<bool> double E_Bond();
+ double E_Bond(bool gradients = true)
+ {
+ return gradients ? E_Bond<true>() : E_Bond<false>();
+ }
+ //! Returns the angle bending energy
+ template<bool> double E_Angle();
+ double E_Angle(bool gradients = true)
+ {
+ return gradients ? E_Angle<true>() : E_Angle<false>();
+ }
+ //! Returns the stretch-bend energy
+ template<bool> double E_StrBnd();
+ double E_StrBnd(bool gradients = true)
+ {
+ return gradients ? E_StrBnd<true>() : E_StrBnd<false>();
+ }
+ //! Returns the torsional energy
+ template<bool> double E_Torsion();
+ double E_Torsion(bool gradients = true)
+ {
+ return gradients ? E_Torsion<true>() : E_Torsion<false>();
+ }
+ //! Returns the out-of-plane bending energy
+ template<bool> double E_OOP();
+ double E_OOP(bool gradients = true)
+ {
+ return gradients ? E_OOP<true>() : E_OOP<false>();
+ }
+ //! Returns the Van der Waals energy (Buckingham potential)
+ template<bool> double E_VDW();
+ double E_VDW(bool gradients = true)
+ {
+ return gradients ? E_VDW<true>() : E_VDW<false>();
+ }
+ //! Returns the dipole-dipole interaction energy
+ template<bool> double E_Electrostatic();
+ double E_Electrostatic(bool gradients = true)
+ {
+ return gradients ? E_Electrostatic<true>() : E_Electrostatic<false>();
+ }
+
+ //! Validate MMFF94 using validation suite
+ bool Validate();
+ //! Compare and print the numerical and analytical gradients
+ bool ValidateGradients();
+
+ }; // class OBForceFieldMM2
+
+}// namespace OpenBabel
+
+//! \file forcefieldmmff94.h
+//! \brief MMFF94 force field
+
diff --git a/forcefields/forcefieldmmff94.lo b/forcefields/forcefieldmmff94.lo
new file mode 100644
index 0000000..6d27e0c
--- /dev/null
+++ b/forcefields/forcefieldmmff94.lo
@@ -0,0 +1,12 @@
+# forcefieldmmff94.lo - a libtool object file
+# Generated by ltmain.sh (GNU libtool) 2.2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/forcefieldmmff94.o'
+
+# Name of the non-PIC object
+non_pic_object=none
+
diff --git a/forcefields/forcefielduff.cpp b/forcefields/forcefielduff.cpp
new file mode 100644
index 0000000..6481e04
--- /dev/null
+++ b/forcefields/forcefielduff.cpp
@@ -0,0 +1,1460 @@
+/**********************************************************************
+forcefielduff.cpp - UFF force field.
+
+Copyright (C) 2007-2008 by Geoffrey Hutchison
+Some portions Copyright (C) 2006-2008 by Tim Vandermeersch
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+#include <openbabel/babelconfig.h>
+#include <openbabel/mol.h>
+#include <openbabel/locale.h>
+
+#include "forcefielduff.h"
+
+
+using namespace std;
+
+// This implementation was created based on open code and reference websites:
+// http://towhee.sourceforge.net/forcefields/uff.html
+// http://rdkit.org/
+// http://franklin.chm.colostate.edu/mmac/uff.html
+// (for the last, use the Wayback Machine: http://www.archive.org/
+
+// As well, the main UFF paper:
+// Rappe, A. K., et. al.; J. Am. Chem. Soc. (1992) 114(25) p. 10024-10035.
+
+namespace OpenBabel
+{
+ template<bool gradients>
+ void OBFFBondCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 vab, da, db;
+ double delta2, dE;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ rab = OBForceField::VectorLengthDerivative(da, db);
+ } else
+ rab = a->GetDistance(b);
+
+ delta = rab - r0; // we pre-compute the r0 below
+ delta2 = delta * delta;
+ energy = kb * delta2; // we fold the 1/2 into kb below
+
+ if (gradients) {
+ dE = 2.0 * kb * delta;
+ da *= dE;
+ db *= dE;
+ da.Get(force_a);
+ db.Get(force_b);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_Bond()
+ {
+ vector<OBFFBondCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nB O N D S T R E T C H I N G\n\n");
+ OBFFLog("ATOM TYPES BOND BOND IDEAL FORCE\n");
+ OBFFLog(" I J TYPE LENGTH LENGTH CONSTANT DELTA ENERGY\n");
+ OBFFLog("------------------------------------------------------------------------\n");
+ }
+
+ for (i = _bondcalculations.begin(); i != _bondcalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %4.2f%8.3f %8.3f %8.3f %8.3f %8.3f\n",
+ (*i).a->GetType(), (*i).b->GetType(),
+ (*i).bt, (*i).rab, (*i).r0, (*i).kb, (*i).delta, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL BOND STRETCHING ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFAngleCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 da, db, dc;
+ double dE;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ dc = c->GetVector();
+ theta = OBForceField::VectorAngleDerivative(da, db, dc) * DEG_TO_RAD;
+ } else {
+ theta = a->GetAngle(b, c) * DEG_TO_RAD;
+ }
+
+ if (!isfinite(theta))
+ theta = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us
+
+ double cosT = cos(theta);
+ switch (coord) {
+ case 1: // sp -- linear case, minima at 180 degrees, max (amplitude 2*ka) at 0, 360
+ // Fixed typo from Rappe paper (i.e., it's NOT 1 - cosT)
+ energy = ka*(1.0 + cosT);
+ break;
+ case 2: // sp2 -- trigonal planar, min at 120, 240, max at 0, 360 (amplitude 2*ka)
+ // Rappe form: (1 - cos 3*theta) -- minima at 0, 360 (bad...)
+ energy = (ka/4.5) * (1.0 + (1.0 + cosT)*(4.0*cosT));
+ break;
+ case 4: // square planar // min at 90, 180, 270, max at 0, 360 (amplitude 2*ka)
+ case 6: // octahedral
+ // Rappe form: (1 - cos 4*theta) -- minima at 0, 360 (bad...)
+ energy = ka * (1.0 + cosT)*cosT*cosT;
+ break;
+ default: // general (sp3) coordination
+ energy = ka*(c0 + c1*cosT + c2*(2.0*cosT*cosT - 1.0)); // use cos 2t = (2cos^2 - 1)
+ }
+
+ if (gradients) {
+ double sinT = sin(theta);
+
+ switch (coord) {
+ case 1: // sp -- linear case
+ dE = -ka * sinT;
+ break;
+ case 2: // sp2 -- trigonal planar
+ dE = -(ka*4.0/4.5) * (sinT + sin(2.0*theta));
+ break;
+ case 4: // square planar
+ case 6: // octahedral
+ dE = -ka * cosT * (2.0 + 3.0 * cosT) * sinT;
+ break;
+ default: // general (sp3) coordination
+ dE = -ka * (c1*sinT + 2.0 * c2*sin(2.0 * theta));
+ }
+
+
+ da *= dE; // da = dTheta/dx * dE/dTheta
+ db *= dE; // da = dTheta/dx * dE/dTheta
+ dc *= dE; // da = dTheta/dx * dE/dTheta
+ da.Get(force_a);
+ db.Get(force_b);
+ dc.Get(force_c);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_Angle()
+ {
+ vector<OBFFAngleCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nA N G L E B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES VALENCE IDEAL FORCE\n");
+ OBFFLog(" I J K ANGLE ANGLE CONSTANT DELTA ENERGY\n");
+ OBFFLog("-----------------------------------------------------------------------------\n");
+ }
+
+ for (i = _anglecalculations.begin(); i != _anglecalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ AddGradient((*i).force_c, (*i).idx_c);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %-5s%8.3f %8.3f %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).c->GetType(), (*i).theta * RAD_TO_DEG, (*i).theta0, (*i).ka, (*i).delta, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ANGLE BENDING ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFTorsionCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c, idx_d)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 da, db, dc, dd;
+ double cosine;
+ double dE;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ dc = c->GetVector();
+ dd = d->GetVector();
+ tor = OBForceField::VectorTorsionDerivative(da, db, dc, dd);
+ if (!isfinite(tor))
+ tor = 1.0e-3;
+ tor *= DEG_TO_RAD;
+ } else {
+ vector3 vab, vbc, vcd, abbc, bccd;
+ vab = a->GetVector() - b->GetVector();
+ vbc = b->GetVector() - c->GetVector();
+ vcd = c->GetVector() - d->GetVector();
+ abbc = cross(vab, vbc);
+ bccd = cross(vbc, vcd);
+
+ double dotAbbcBccd = dot(abbc,bccd);
+ tor = acos(dotAbbcBccd / (abbc.length() * bccd.length()));
+ if (IsNearZero(dotAbbcBccd) || !isfinite(tor)) { // stop any NaN or infinity
+ tor = 1.0e-3; // rather than NaN
+ }
+ else if (dotAbbcBccd > 0.0) {
+ tor = -tor;
+ }
+ }
+
+ cosine = cos(tor * n);
+ energy = V * (1.0 - cosNPhi0*cosine);
+
+ if (gradients) {
+ dE = -(V * n * cosNPhi0 * sin(n * tor));
+ da *= dE;
+ db *= dE;
+ dc *= dE;
+ dd *= dE;
+ da.Get(force_a);
+ db.Get(force_b);
+ dc.Get(force_c);
+ dd.Get(force_d);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_Torsion()
+ {
+ vector<OBFFTorsionCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nT O R S I O N A L\n\n");
+ OBFFLog("----ATOM TYPES----- FORCE TORSION\n");
+ OBFFLog(" I J K L CONSTANT ANGLE ENERGY\n");
+ OBFFLog("----------------------------------------------------------------\n");
+ }
+
+ for (i = _torsioncalculations.begin(); i != _torsioncalculations.end(); ++i) {
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ AddGradient((*i).force_c, (*i).idx_c);
+ AddGradient((*i).force_d, (*i).idx_d);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %-5s %-5s%6.3f %8.3f %8.3f\n",
+ (*i).a->GetType(), (*i).b->GetType(),
+ (*i).c->GetType(), (*i).d->GetType(), (*i).V,
+ (*i).tor * RAD_TO_DEG, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL TORSIONAL ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ /*
+ // a
+ // \
+ // b---d plane = a-b-c
+ // /
+ // c
+ */
+ template<bool gradients>
+ void OBFFOOPCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b, idx_c, idx_d)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 da, db, dc, dd;
+ double dE;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ dc = c->GetVector();
+ dd = d->GetVector();
+ angle = OBForceField::VectorOOPDerivative(da, db, dc, dd) * DEG_TO_RAD;
+
+ if (!isfinite(angle))
+ angle = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+
+ // somehow we already get the -1 from the OOPDeriv -- so we'll omit it here
+ dE = koop * (c1*sin(angle) + 2.0 * c2 * sin(2.0*angle));
+ da *= dE;
+ db *= dE;
+ dc *= dE;
+ dd *= dE;
+ da.Get(force_a);
+ db.Get(force_b);
+ dc.Get(force_c);
+ dd.Get(force_d);
+ } else {
+ angle = DEG_TO_RAD*Point2PlaneAngle(d->GetVector(), a->GetVector(), b->GetVector(), c->GetVector());
+ if (!isfinite(angle))
+ angle = 0.0; // doesn't explain why GetAngle is returning NaN but solves it for us;
+ }
+
+ energy = koop * (c0 + c1 * cos(angle) + c2 * cos(2.0*angle));
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_OOP()
+ {
+ vector<OBFFOOPCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nO U T - O F - P L A N E B E N D I N G\n\n");
+ OBFFLog("ATOM TYPES OOP FORCE \n");
+ OBFFLog(" I J K L ANGLE CONSTANT ENERGY\n");
+ OBFFLog("----------------------------------------------------------\n");
+ }
+
+ for (i = _oopcalculations.begin(); i != _oopcalculations.end(); ++i) {
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ AddGradient((*i).force_c, (*i).idx_c);
+ AddGradient((*i).force_d, (*i).idx_d);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %-5s %-5s%8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(), (*i).c->GetType(), (*i).d->GetType(),
+ (*i).angle * RAD_TO_DEG, (*i).koop, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL OUT-OF-PLANE BENDING ENERGY = %8.3f\n", energy);
+ OBFFLog(_logbuf);
+ }
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFVDWCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 da, db;
+ double term6, term12, dE, term7, term13;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ rab = OBForceField::VectorLengthDerivative(da, db);
+ } else
+ rab = a->GetDistance(b);
+
+ if (IsNearZero(rab, 1.0e-3))
+ rab = 1.0e-3;
+
+ term7 = term13 = term6 = ka / rab;
+
+ term6 = term6 * term6 * term6; // ^3
+ term6 = term6 * term6; // ^6
+ term12 = term6 * term6; // ^12
+
+ energy = kab * ((term12) - (2.0 * term6));
+
+ if (gradients) {
+ term13 = term13 * term12; // ^13
+ term7 = term7 * term6; // ^7
+ dE = kab * 12.0 * (term7/ka - term13/ka);
+ da *= dE;
+ db *= dE;
+ da.Get(force_a);
+ db.Get(force_b);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_VDW()
+ {
+ vector<OBFFVDWCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nV A N D E R W A A L S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij kij ENERGY\n");
+ OBFFLog("-----------------------------------------\n");
+ // XX XX -000.000 -000.000 -000.000 -000.000
+ }
+
+ unsigned int j = 0;
+ for (i = _vdwcalculations.begin(); i != _vdwcalculations.end(); ++i, ++j) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_vdwpairs.BitIsSet(j))
+ continue;
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).rab, (*i).kab, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL VAN DER WAALS ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ template<bool gradients>
+ void OBFFElectrostaticCalculationUFF::Compute()
+ {
+ if (OBForceField::IgnoreCalculation(idx_a, idx_b)) {
+ energy = 0.0;
+ return;
+ }
+
+ vector3 da, db;
+ double dE, rab2;
+
+ if (gradients) {
+ da = a->GetVector();
+ db = b->GetVector();
+ rab = OBForceField::VectorLengthDerivative(da, db);
+ } else
+ rab = a->GetDistance(b);
+
+ if (IsNearZero(rab, 1.0e-3))
+ rab = 1.0e-3;
+
+ energy = qq / rab;
+
+ if (gradients) {
+ rab2 = rab * rab;
+ dE = -qq / rab2;
+ da *= dE;
+ db *= dE;
+ da.Get(force_a);
+ db.Get(force_b);
+ }
+ }
+
+ template<bool gradients>
+ double OBForceFieldUFF::E_Electrostatic()
+ {
+ vector<OBFFElectrostaticCalculationUFF>::iterator i;
+ double energy = 0.0;
+
+ IF_OBFF_LOGLVL_HIGH {
+ OBFFLog("\nE L E C T R O S T A T I C I N T E R A C T I O N S\n\n");
+ OBFFLog("ATOM TYPES\n");
+ OBFFLog(" I J Rij 332.17*QiQj ENERGY\n");
+ OBFFLog("-------------------------------------------\n");
+ // XX XX -000.000 -000.000 -000.000
+ }
+
+ unsigned int j = 0;
+ for (i = _electrostaticcalculations.begin(); i != _electrostaticcalculations.end(); ++i, ++j) {
+ // Cut-off check
+ if (_cutoff)
+ if (!_elepairs.BitIsSet(j))
+ continue;
+
+ i->template Compute<gradients>();
+ energy += i->energy;
+
+ if (gradients) {
+ AddGradient((*i).force_a, (*i).idx_a);
+ AddGradient((*i).force_b, (*i).idx_b);
+ }
+
+ IF_OBFF_LOGLVL_HIGH {
+ snprintf(_logbuf, BUFF_SIZE, "%-5s %-5s %8.3f %8.3f %8.3f\n", (*i).a->GetType(), (*i).b->GetType(),
+ (*i).rab, (*i).qq, (*i).energy);
+ OBFFLog(_logbuf);
+ }
+ }
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, " TOTAL ELECTROSTATIC ENERGY = %8.3f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ //***********************************************
+ //Make a global instance
+ OBForceFieldUFF theForceFieldUFF("UFF", true);
+ //***********************************************
+
+ OBForceFieldUFF::~OBForceFieldUFF()
+ {
+ }
+
+ OBForceFieldUFF &OBForceFieldUFF::operator=(OBForceFieldUFF &src)
+ {
+ _mol = src._mol;
+
+ _ffparams = src._ffparams;
+
+ _bondcalculations = src._bondcalculations;
+ _anglecalculations = src._anglecalculations;
+ _torsioncalculations = src._torsioncalculations;
+ _oopcalculations = src._oopcalculations;
+ _vdwcalculations = src._vdwcalculations;
+ _electrostaticcalculations = src._electrostaticcalculations;
+ _init = src._init;
+
+ return *this;
+ }
+
+ double CalculateBondDistance(OBFFParameter *i, OBFFParameter *j, double bondorder)
+ {
+ double ri, rj;
+ double chiI, chiJ;
+ double rbo, ren;
+ ri = i->_dpar[0];
+ rj = j->_dpar[0];
+ chiI = i->_dpar[8];
+ chiJ = j->_dpar[8];
+
+ // precompute the equilibrium geometry
+ // From equation 3
+ rbo = -0.1332*(ri+rj)*log(bondorder);
+ // From equation 4
+ ren = ri*rj*(pow((sqrt(chiI) - sqrt(chiJ)),2.0)) / (chiI*ri + chiJ*rj);
+ // From equation 2
+ // NOTE: See http://towhee.sourceforge.net/forcefields/uff.html
+ // There is a typo in the published paper
+ return(ri + rj + rbo - ren);
+ }
+
+ bool OBForceFieldUFF::SetupCalculations()
+ {
+ OBFFParameter *parameterA, *parameterB, *parameterC;
+ OBAtom *a, *b, *c, *d;
+
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("\nS E T T I N G U P C A L C U L A T I O N S\n\n");
+
+ //
+ // ZNBond Calculations
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP BOND CALCULATIONS...\n");
+
+ OBFFBondCalculationUFF bondcalc;
+ double bondorder;
+
+ _bondcalculations.clear();
+
+ FOR_BONDS_OF_MOL(bond, _mol) {
+ a = bond->GetBeginAtom();
+ b = bond->GetEndAtom();
+
+ // skip this bond if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two bond atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validBond = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()))
+ validBond = true;
+ }
+ if (!validBond)
+ continue;
+ }
+
+ bondorder = bond->GetBondOrder();
+ if (bond->IsAromatic())
+ bondorder = 1.5;
+ if (bond->IsAmide())
+ bondorder = 1.41;
+
+ bondcalc.a = a;
+ bondcalc.b = b;
+ bondcalc.bt = bondorder;
+
+ parameterA = GetParameterUFF(a->GetType(), _ffparams);
+ parameterB = GetParameterUFF(b->GetType(), _ffparams);
+
+ bondcalc.r0 = CalculateBondDistance(parameterA, parameterB, bondorder);
+
+ // here we fold the 1/2 into the kij from equation 1a
+ // Otherwise, this is equation 6 from the UFF paper.
+ bondcalc.kb = (0.5 * KCAL_TO_KJ * 664.12
+ * parameterA->_dpar[5] * parameterB->_dpar[5])
+ / (bondcalc.r0 * bondcalc.r0 * bondcalc.r0);
+
+ bondcalc.SetupPointers();
+ _bondcalculations.push_back(bondcalc);
+ }
+
+ //
+ // Angle Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ANGLE CALCULATIONS...\n");
+
+ OBFFAngleCalculationUFF anglecalc;
+
+ _anglecalculations.clear();
+
+ double sinT0;
+ double rab, rbc, rac;
+ OBBond *bondPtr;
+ FOR_ANGLES_OF_MOL(angle, _mol) {
+ b = _mol.GetAtom((*angle)[0] + 1);
+ a = _mol.GetAtom((*angle)[1] + 1);
+ c = _mol.GetAtom((*angle)[2] + 1);
+
+ // skip this angle if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) || _constraints.IsIgnored(c->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the three angle atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validAngle = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()))
+ validAngle = true;
+ }
+ if (!validAngle)
+ continue;
+ }
+
+ anglecalc.a = a;
+ anglecalc.b = b;
+ anglecalc.c = c;
+
+ parameterA = GetParameterUFF(a->GetType(), _ffparams);
+ parameterB = GetParameterUFF(b->GetType(), _ffparams);
+ parameterC = GetParameterUFF(c->GetType(), _ffparams);
+
+ anglecalc.coord = parameterB->_ipar[0]; // coordination of central atom
+
+ anglecalc.zi = parameterA->_dpar[5];
+ anglecalc.zk = parameterC->_dpar[5];
+ anglecalc.theta0 = parameterB->_dpar[1];
+ anglecalc.cosT0 = cos(anglecalc.theta0 * DEG_TO_RAD);
+ sinT0 = sin(anglecalc.theta0 * DEG_TO_RAD);
+ anglecalc.c2 = 1.0 / (4.0 * sinT0 * sinT0);
+ anglecalc.c1 = -4.0 * anglecalc.c2 * anglecalc.cosT0;
+ anglecalc.c0 = anglecalc.c2*(2.0*anglecalc.cosT0*anglecalc.cosT0 + 1.0);
+
+ // Precompute the force constant
+ bondPtr = _mol.GetBond(a,b);
+ bondorder = bondPtr->GetBondOrder();
+ if (bondPtr->IsAromatic())
+ bondorder = 1.5;
+ if (bondPtr->IsAmide())
+ bondorder = 1.41;
+ rab = CalculateBondDistance(parameterA, parameterB, bondorder);
+
+ bondPtr = _mol.GetBond(b,c);
+ bondorder = bondPtr->GetBondOrder();
+ if (bondPtr->IsAromatic())
+ bondorder = 1.5;
+ if (bondPtr->IsAmide())
+ bondorder = 1.41;
+ rbc = CalculateBondDistance(parameterB, parameterC, bondorder);
+ rac = sqrt(rab*rab + rbc*rbc - 2.0 * rab*rbc*anglecalc.cosT0);
+
+ // Equation 13 from paper -- corrected by Towhee
+ // Note that 1/(rij * rjk) cancels with rij*rjk in eqn. 13
+ anglecalc.ka = (644.12 * KCAL_TO_KJ) * (anglecalc.zi * anglecalc.zk / (pow(rac, 5.0)));
+ anglecalc.ka *= (3.0*rab*rbc*(1.0 - anglecalc.cosT0*anglecalc.cosT0) - rac*rac*anglecalc.cosT0);
+
+ anglecalc.SetupPointers();
+ _anglecalculations.push_back(anglecalc);
+ }
+
+ //
+ // Torsion Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP TORSION CALCULATIONS...\n");
+
+ OBFFTorsionCalculationUFF torsioncalc;
+ double torsiontype;
+ double phi0 = 0.0;
+
+ _torsioncalculations.clear();
+
+ double vi, vj;
+ FOR_TORSIONS_OF_MOL(t, _mol) {
+ a = _mol.GetAtom((*t)[0] + 1);
+ b = _mol.GetAtom((*t)[1] + 1);
+ c = _mol.GetAtom((*t)[2] + 1);
+ d = _mol.GetAtom((*t)[3] + 1);
+
+ // skip this torsion if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) ||
+ _constraints.IsIgnored(c->GetIdx()) || _constraints.IsIgnored(d->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the four torsion atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validTorsion = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()) && _intraGroup[i].BitIsOn(d->GetIdx()))
+ validTorsion = true;
+ }
+ if (!validTorsion)
+ continue;
+ }
+
+ OBBond *bc = _mol.GetBond(b, c);
+ torsiontype = bc->GetBondOrder();
+ if (bc->IsAromatic())
+ torsiontype = 1.5;
+ if (bc->IsAmide())
+ torsiontype = 1.41;
+
+ torsioncalc.a = a;
+ torsioncalc.b = b;
+ torsioncalc.c = c;
+ torsioncalc.d = d;
+ torsioncalc.tt = torsiontype;
+
+ parameterB = GetParameterUFF(b->GetType(), _ffparams);
+ parameterC = GetParameterUFF(c->GetType(), _ffparams);
+
+ if (parameterB->_ipar[0] == 3 && parameterC->_ipar[0] == 3) {
+ // two sp3 centers
+ phi0 = 60.0;
+ torsioncalc.n = 3;
+ vi = parameterB->_dpar[6];
+ vj = parameterC->_dpar[6];
+
+ // exception for a pair of group 6 sp3 atoms
+ switch (b->GetAtomicNum()) {
+ case 8:
+ vi = 2.0;
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ break;
+ case 16:
+ case 34:
+ case 52:
+ case 84:
+ vi = 6.8;
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ }
+ switch (c->GetAtomicNum()) {
+ case 8:
+ vj = 2.0;
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ break;
+ case 16:
+ case 34:
+ case 52:
+ case 84:
+ vj = 6.8;
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ }
+
+ torsioncalc.V = 0.5 * KCAL_TO_KJ * sqrt(vi * vj);
+
+ } else if (parameterB->_ipar[0] == 2 && parameterC->_ipar[0] == 2) {
+ // two sp2 centers
+ phi0 = 180.0;
+ torsioncalc.n = 2;
+ torsioncalc.V = 0.5 * KCAL_TO_KJ * 5.0 *
+ sqrt(parameterB->_dpar[7]*parameterC->_dpar[7]) *
+ (1.0 + 4.18 * log(torsiontype));
+ } else if ((parameterB->_ipar[0] == 2 && parameterC->_ipar[0] == 3)
+ || (parameterB->_ipar[0] == 3 && parameterC->_ipar[0] == 2)) {
+ // one sp3, one sp2
+ phi0 = 0.0;
+ torsioncalc.n = 6;
+ torsioncalc.V = 0.5 * KCAL_TO_KJ * 1.0;
+
+ // exception for group 6 sp3
+ if (parameterC->_ipar[0] == 3) {
+ switch (c->GetAtomicNum()) {
+ case 8:
+ case 16:
+ case 34:
+ case 52:
+ case 84:
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ }
+ }
+ if (parameterB->_ipar[0] == 3) {
+ switch (b->GetAtomicNum()) {
+ case 8:
+ case 16:
+ case 34:
+ case 52:
+ case 84:
+ torsioncalc.n = 2;
+ phi0 = 90.0;
+ }
+ }
+ }
+
+ if (IsNearZero(torsioncalc.V)) // don't bother calcuating this torsion
+ continue;
+
+ // still need to implement special case of sp2-sp3 with sp2-sp2
+
+ torsioncalc.cosNPhi0 = cos(torsioncalc.n * DEG_TO_RAD * phi0);
+ torsioncalc.SetupPointers();
+ _torsioncalculations.push_back(torsioncalc);
+ }
+
+ //
+ // OOP/Inversion Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP OOP CALCULATIONS...\n");
+ OBFFOOPCalculationUFF oopcalc;
+
+ _oopcalculations.clear();
+
+ double phi;
+ // The original Rappe paper in JACS isn't very clear about the parameters
+ // The following was adapted from Towhee
+ FOR_ATOMS_OF_MOL(atom, _mol) {
+ b = (OBAtom*) &*atom;
+
+ switch (b->GetAtomicNum()) {
+ case 6: // carbon
+ case 7: // nitrogen
+ case 8: // oxygen
+ case 15: // phos.
+ case 33: // as
+ case 51: // sb
+ case 83: // bi
+ break;
+ default: // no inversion term for this element
+ continue;
+ }
+
+ a = NULL;
+ c = NULL;
+ d = NULL;
+
+ if (EQn(b->GetType(), "N_3", 3) ||
+ EQn(b->GetType(), "N_2", 3) ||
+ EQn(b->GetType(), "N_R", 3) ||
+ EQn(b->GetType(), "O_2", 3) ||
+ EQn(b->GetType(), "O_R", 3)) {
+ oopcalc.c0 = 1.0;
+ oopcalc.c1 = -1.0;
+ oopcalc.c2 = 0.0;
+ oopcalc.koop = 6.0 * KCAL_TO_KJ;
+ }
+ else if (EQn(b->GetType(), "P_3+3", 5) ||
+ EQn(b->GetType(), "As3+3", 5) ||
+ EQn(b->GetType(), "Sb3+3", 5) ||
+ EQn(b->GetType(), "Bi3+3", 5)) {
+
+ if (EQn(b->GetType(), "P_3+3", 5))
+ phi = 84.4339 * DEG_TO_RAD;
+ else if (EQn(b->GetType(), "As3+3", 5))
+ phi = 86.9735 * DEG_TO_RAD;
+ else if (EQn(b->GetType(), "Sb3+3", 5))
+ phi = 87.7047 * DEG_TO_RAD;
+ else
+ phi = 90.0 * DEG_TO_RAD;
+
+ oopcalc.c1 = -4.0 * cos(phi);
+ oopcalc.c2 = 1.0;
+ oopcalc.c0 = -1.0*oopcalc.c1 * cos(phi) + oopcalc.c2*cos(2.0*phi);
+ oopcalc.koop = 22.0 * KCAL_TO_KJ;
+ }
+ else if (!(EQn(b->GetType(), "C_2", 3) || EQn(b->GetType(), "C_R", 3)))
+ continue; // inversion not defined for this atom type
+
+ // C atoms, we should check if we're bonded to O
+ FOR_NBORS_OF_ATOM(nbr, b) {
+ if (a == NULL)
+ a = (OBAtom*) &*nbr;
+ else if (c == NULL)
+ c = (OBAtom*) &*nbr;
+ else
+ d = (OBAtom*) &*nbr;
+ }
+
+ if ((a == NULL) || (c == NULL) || (d == NULL))
+ continue;
+
+ // skip this oop if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) ||
+ _constraints.IsIgnored(c->GetIdx()) || _constraints.IsIgnored(d->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the four oop atoms are in a single intraGroup
+ if (HasGroups()) {
+ bool validOOP = false;
+ for (unsigned int i=0; i < _intraGroup.size(); ++i) {
+ if (_intraGroup[i].BitIsOn(a->GetIdx()) && _intraGroup[i].BitIsOn(b->GetIdx()) &&
+ _intraGroup[i].BitIsOn(c->GetIdx()) && _intraGroup[i].BitIsOn(d->GetIdx()))
+ validOOP = true;
+ }
+ if (!validOOP)
+ continue;
+ }
+
+ if (EQn(b->GetType(), "C_2", 3) || EQn(b->GetType(), "C_R", 3)) {
+ oopcalc.c0 = 1.0;
+ oopcalc.c1 = -1.0;
+ oopcalc.c2 = 0.0;
+ oopcalc.koop = 6.0 * KCAL_TO_KJ;
+ if (EQn(a->GetType(), "O_2", 3) ||
+ EQn(c->GetType(), "O_2", 3) ||
+ EQn(d->GetType(), "O_2", 3)) {
+ oopcalc.koop = 50.0 * KCAL_TO_KJ;
+ }
+ }
+
+ // A-B-CD || C-B-AD PLANE = ABC
+ oopcalc.a = a;
+ oopcalc.b = b;
+ oopcalc.c = c;
+ oopcalc.d = d;
+ oopcalc.koop /= 3.0; // three OOPs to consider
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // C-B-DA || D-B-CA PLANE BCD
+ oopcalc.a = d;
+ oopcalc.d = a;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+
+ // A-B-DC || D-B-AC PLANE ABD
+ oopcalc.a = a;
+ oopcalc.c = d;
+ oopcalc.d = c;
+
+ oopcalc.SetupPointers();
+ _oopcalculations.push_back(oopcalc);
+ } // for all atoms
+
+ //
+ // VDW Calculations
+ //
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP VAN DER WAALS CALCULATIONS...\n");
+
+ OBFFVDWCalculationUFF vdwcalc;
+
+ _vdwcalculations.clear();
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this vdw if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validVDW = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validVDW = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validVDW = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validVDW = true;
+ }
+
+ if (!validVDW)
+ continue;
+ }
+
+ if (a->IsConnected(b)) {
+ continue;
+ }
+ if (a->IsOneThree(b)) {
+ continue;
+ }
+
+ parameterA = GetParameterUFF(a->GetType(), _ffparams);
+ parameterB = GetParameterUFF(b->GetType(), _ffparams);
+
+ vdwcalc.Ra = parameterA->_dpar[2];
+ vdwcalc.ka = parameterA->_dpar[3];
+ vdwcalc.Rb = parameterB->_dpar[2];
+ vdwcalc.kb = parameterB->_dpar[3];
+
+ vdwcalc.a = &*a;
+ vdwcalc.b = &*b;
+
+ //this calculations only need to be done once for each pair,
+ //we do them now and save them for later use
+ vdwcalc.kab = KCAL_TO_KJ * sqrt(vdwcalc.ka * vdwcalc.kb);
+
+ // 1-4 scaling
+ // This isn't mentioned in the UFF paper, but is common for other methods
+ // if (a->IsOneFour(b))
+ // vdwcalc.kab *= 0.5;
+
+ // ka now represents the xij in equation 20 -- the expected vdw distance
+ vdwcalc.ka = sqrt(vdwcalc.Ra * vdwcalc.Rb);
+
+ vdwcalc.SetupPointers();
+ _vdwcalculations.push_back(vdwcalc);
+ }
+
+ // NOTE: No electrostatics are set up
+ // If you want electrostatics with UFF (not a good idea), you will need to call SetupElectrostatics
+
+ return true;
+ }
+
+ bool OBForceFieldUFF::SetupElectrostatics()
+ {
+ //
+ // Electrostatic Calculations
+ //
+ OBAtom *a, *b;
+
+ IF_OBFF_LOGLVL_LOW
+ OBFFLog("SETTING UP ELECTROSTATIC CALCULATIONS...\n");
+
+ OBFFElectrostaticCalculationUFF elecalc;
+
+ _electrostaticcalculations.clear();
+
+ // Note that while the UFF paper mentions an electrostatic term,
+ // it does not actually use it. Both Towhee and the UFF FAQ
+ // discourage the use of electrostatics with UFF.
+
+ FOR_PAIRS_OF_MOL(p, _mol) {
+ a = _mol.GetAtom((*p)[0]);
+ b = _mol.GetAtom((*p)[1]);
+
+ // skip this ele if the atoms are ignored
+ if ( _constraints.IsIgnored(a->GetIdx()) || _constraints.IsIgnored(b->GetIdx()) )
+ continue;
+
+ // if there are any groups specified, check if the two atoms are in a single _interGroup or if
+ // two two atoms are in one of the _interGroups pairs.
+ if (HasGroups()) {
+ bool validEle = false;
+ for (unsigned int i=0; i < _interGroup.size(); ++i) {
+ if (_interGroup[i].BitIsOn(a->GetIdx()) && _interGroup[i].BitIsOn(b->GetIdx()))
+ validEle = true;
+ }
+ for (unsigned int i=0; i < _interGroups.size(); ++i) {
+ if (_interGroups[i].first.BitIsOn(a->GetIdx()) && _interGroups[i].second.BitIsOn(b->GetIdx()))
+ validEle = true;
+ if (_interGroups[i].first.BitIsOn(b->GetIdx()) && _interGroups[i].second.BitIsOn(a->GetIdx()))
+ validEle = true;
+ }
+
+ if (!validEle)
+ continue;
+ }
+
+ if (a->IsConnected(b)) {
+ continue;
+ }
+ if (a->IsOneThree(b)) {
+ continue;
+ }
+
+ // Remember that at the moment, this term is not currently used
+ // These are also the Gasteiger charges, not the Qeq mentioned in the UFF paper
+ elecalc.qq = KCAL_TO_KJ * 332.0637 * a->GetPartialCharge() * b->GetPartialCharge();
+
+ if (elecalc.qq) {
+ elecalc.a = &*a;
+ elecalc.b = &*b;
+
+ elecalc.SetupPointers();
+ _electrostaticcalculations.push_back(elecalc);
+ }
+ }
+ return true;
+ }
+
+ bool OBForceFieldUFF::ParseParamFile()
+ {
+ vector<string> vs;
+ char buffer[BUFF_SIZE];
+
+ OBFFParameter parameter;
+
+ // open data/UFF.prm
+ ifstream ifs;
+ if (OpenDatafile(ifs, "UFF.prm").length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open UFF.prm", obError);
+ return false;
+ }
+
+ // Set the locale for number parsing to avoid locale issues: PR#1785463
+ obLocale.SetLocale();
+
+ while (ifs.getline(buffer, BUFF_SIZE)) {
+ tokenize(vs, buffer);
+ if (vs.size() < 13)
+ continue;
+
+ if (EQn(buffer, "param", 5)) {
+ // set up all parameters from this
+ parameter.clear();
+ parameter._a = vs[1]; // atom type
+ parameter._dpar.push_back(atof(vs[2].c_str())); // r1
+ parameter._dpar.push_back(atof(vs[3].c_str())); // theta0
+ parameter._dpar.push_back(atof(vs[4].c_str())); // x1
+ parameter._dpar.push_back(atof(vs[5].c_str())); // D1
+ parameter._dpar.push_back(atof(vs[6].c_str())); // zeta
+ parameter._dpar.push_back(atof(vs[7].c_str())); // Z1
+ parameter._dpar.push_back(atof(vs[8].c_str())); // Vi
+ parameter._dpar.push_back(atof(vs[9].c_str())); // Uj
+ parameter._dpar.push_back(atof(vs[10].c_str())); // Xi
+ parameter._dpar.push_back(atof(vs[11].c_str())); // Hard
+ parameter._dpar.push_back(atof(vs[12].c_str())); // Radius
+
+ char coord = vs[1][2]; // 3rd character of atom type
+ switch (coord) {
+ case '1': // linear
+ parameter._ipar.push_back(1);
+ break;
+ case '2': // trigonal planar (sp2)
+ case 'R': // aromatic (N_R)
+ parameter._ipar.push_back(2);
+ break;
+ case '3': // tetrahedral (sp3)
+ parameter._ipar.push_back(3);
+ break;
+ case '4': // square planar
+ parameter._ipar.push_back(4);
+ break;
+ case '5': // trigonal bipyramidal -- not actually in parameterization
+ parameter._ipar.push_back(5);
+ break;
+ case '6': // octahedral
+ parameter._ipar.push_back(6);
+ break;
+ case '7': // pentagonal bipyramidal -- not actually in parameterization
+ parameter._ipar.push_back(7);
+ break;
+ default: // general case (unknown coordination)
+ // These atoms appear to generally be linear coordination like Cl
+ parameter._ipar.push_back(1);
+ }
+
+ _ffparams.push_back(parameter);
+ }
+ }
+
+ if (ifs)
+ ifs.close();
+
+ // return the locale to the original one
+ obLocale.RestoreLocale();
+
+ return 0;
+ }
+
+ bool OBForceFieldUFF::SetTypes()
+ {
+ vector<vector<int> > _mlist; //!< match list for atom typing
+ vector<pair<OBSmartsPattern*,string> > _vexttyp; //!< external atom type rules
+ vector<vector<int> >::iterator j;
+ vector<pair<OBSmartsPattern*,string> >::iterator i;
+ OBSmartsPattern *sp;
+ vector<string> vs;
+ char buffer[BUFF_SIZE];
+
+ _mol.SetAtomTypesPerceived();
+
+ // open data/UFF.prm
+ ifstream ifs;
+ if (OpenDatafile(ifs, "UFF.prm").length() == 0) {
+ obErrorLog.ThrowError(__FUNCTION__, "Cannot open UFF.prm", obError);
+ return false;
+ }
+
+ while (ifs.getline(buffer, BUFF_SIZE)) {
+ if (EQn(buffer, "atom", 4)) {
+ tokenize(vs, buffer);
+
+ sp = new OBSmartsPattern;
+ if (sp->Init(vs[1])) {
+ _vexttyp.push_back(pair<OBSmartsPattern*,string> (sp,vs[2]));
+ }
+ else {
+ delete sp;
+ sp = NULL;
+ obErrorLog.ThrowError(__FUNCTION__, " Could not parse atom type table from UFF.prm", obInfo);
+ return false;
+ }
+ }
+ }
+
+ for (i = _vexttyp.begin();i != _vexttyp.end();++i) {
+ if (i->first->Match(_mol)) {
+ _mlist = i->first->GetMapList();
+ for (j = _mlist.begin();j != _mlist.end();++j) {
+ _mol.GetAtom((*j)[0])->SetType(i->second);
+ }
+ }
+ }
+ IF_OBFF_LOGLVL_LOW {
+ OBFFLog("\nA T O M T Y P E S\n\n");
+ OBFFLog("IDX\tTYPE\n");
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ snprintf(_logbuf, BUFF_SIZE, "%d\t%s\n", a->GetIdx(), a->GetType());
+ OBFFLog(_logbuf);
+ }
+
+ }
+
+ if (ifs)
+ ifs.close();
+
+ return true;
+ }
+
+ double OBForceFieldUFF::Energy(bool gradients)
+ {
+ double energy;
+
+ IF_OBFF_LOGLVL_MEDIUM
+ OBFFLog("\nE N E R G Y\n\n");
+
+ if (gradients) {
+ ClearGradients();
+ energy = E_Bond<true>();
+ energy += E_Angle<true>();
+ energy += E_Torsion<true>();
+ energy += E_OOP<true>();
+ energy += E_VDW<true>();
+ } else {
+ energy = E_Bond<false>();
+ energy += E_Angle<false>();
+ energy += E_Torsion<false>();
+ energy += E_OOP<false>();
+ energy += E_VDW<false>();
+ }
+
+ // The electrostatic term, by default is 0.0
+ // You will need to call SetupEletrostatics if you want it
+ // energy += E_Electrostatic(gradients);
+
+ IF_OBFF_LOGLVL_MEDIUM {
+ snprintf(_logbuf, BUFF_SIZE, "\nTOTAL ENERGY = %8.5f %s\n", energy, GetUnit().c_str());
+ OBFFLog(_logbuf);
+ }
+
+ return energy;
+ }
+
+ OBFFParameter* OBForceFieldUFF::GetParameterUFF(std::string a, vector<OBFFParameter> ¶meter)
+ {
+ for (unsigned int idx=0; idx < parameter.size(); ++idx) {
+ if (a == parameter[idx]._a) {
+ return ¶meter[idx];
+ }
+ }
+ return NULL;
+ }
+
+ bool OBForceFieldUFF::ValidateGradients ()
+ {
+ vector3 numgrad, anagrad, err;
+ bool passed = true; // set to false if any component fails
+ int coordIdx;
+
+ OBFFLog("\nV A L I D A T E G R A D I E N T S\n\n");
+ OBFFLog("ATOM IDX NUMERICAL GRADIENT ANALYTICAL GRADIENT REL. ERROR (%) \n");
+ OBFFLog("----------------------------------------------------------------------------------------\n");
+ // "XX (000.000, 000.000, 000.000) (000.000, 000.000, 000.000) (00.00, 00.00, 00.00)"
+
+ FOR_ATOMS_OF_MOL (a, _mol) {
+ coordIdx = (a->GetIdx() - 1) * 3;
+
+ // OBFF_ENERGY (i.e., overall)
+ numgrad = NumericalDerivative(&*a, OBFF_ENERGY);
+ Energy(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, "%2d (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", a->GetIdx(), numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+
+ // OBFF_EBOND
+ numgrad = NumericalDerivative(&*a, OBFF_EBOND);
+ ClearGradients();
+ E_Bond(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " bond (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EANGLE
+ numgrad = NumericalDerivative(&*a, OBFF_EANGLE);
+ ClearGradients();
+ E_Angle(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " angle (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_ETORSION
+ numgrad = NumericalDerivative(&*a, OBFF_ETORSION);
+ ClearGradients();
+ E_Torsion(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " torsion (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ // 8% tolerance here because some 180 torsions cause numerical instability
+ if (err.x() > 8.0 || err.y() > 8.0 || err.z() > 8.0)
+ passed = false;
+
+ // OBFF_EOOP
+ numgrad = NumericalDerivative(&*a, OBFF_EOOP);
+ ClearGradients();
+ E_OOP(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " oop (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+// if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+// passed = false;
+
+ // OBFF_EVDW
+ numgrad = NumericalDerivative(&*a, OBFF_EVDW);
+ ClearGradients();
+ E_VDW(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " vdw (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+
+ // OBFF_EELECTROSTATIC
+ numgrad = NumericalDerivative(&*a, OBFF_EELECTROSTATIC);
+ ClearGradients();
+ E_Electrostatic(); // compute
+ anagrad.Set(_gradientPtr[coordIdx], _gradientPtr[coordIdx+1], _gradientPtr[coordIdx+2]);
+ err = ValidateGradientError(numgrad, anagrad);
+
+ snprintf(_logbuf, BUFF_SIZE, " electro (%7.3f, %7.3f, %7.3f) (%7.3f, %7.3f, %7.3f) (%5.2f, %5.2f, %5.2f)\n", numgrad.x(), numgrad.y(), numgrad.z(),
+ anagrad.x(), anagrad.y(), anagrad.z(), err.x(), err.y(), err.z());
+ OBFFLog(_logbuf);
+ if (err.x() > 5.0 || err.y() > 5.0 || err.z() > 5.0)
+ passed = false;
+ }
+
+ return passed; // did we pass every single component?
+ }
+
+} // end namespace OpenBabel
+
+//! \file forcefieldUFF.cpp
+//! \brief UFF force field
diff --git a/forcefields/forcefielduff.h b/forcefields/forcefielduff.h
new file mode 100644
index 0000000..9eaca04
--- /dev/null
+++ b/forcefields/forcefielduff.h
@@ -0,0 +1,202 @@
+/**********************************************************************
+forcefielduff.h - UFF force field.
+
+Copyright (C) 2007 by Geoffrey Hutchison
+Some portions Copyright (C) 2006-2007 by Tim Vandermeersch
+
+This file is part of the Open Babel project.
+For more information, see <http://openbabel.sourceforge.net/>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+***********************************************************************/
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include <openbabel/forcefield.h>
+#include <openbabel/base.h>
+#include <openbabel/mol.h>
+
+namespace OpenBabel
+{
+ class OBFFBondCalculationUFF : public OBFFCalculation2
+ {
+ public:
+ double bt; // bond order (e.g., 1.41 for amide)
+ double kb, r0, rab, delta;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFAngleCalculationUFF : public OBFFCalculation3
+ {
+ public:
+ int at; //angletype (ATIJK)
+ bool linear;
+ double ka, theta0, theta, delta;
+ double c0, c1, c2;
+ double zi, zk, rij, rjk, rik;
+ double cosT0; // cos theta0
+ int coord, n;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFTorsionCalculationUFF : public OBFFCalculation4
+ {
+ public:
+ int n;
+ double tt; //torsiontype (i.e. b-c bond order)
+ double V, tor, cosNPhi0;
+
+ template<bool> void Compute();
+
+ };
+
+ class OBFFOOPCalculationUFF : public OBFFCalculation4
+ {
+ public:
+ double koop, angle;
+ double c0, c1, c2;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFVDWCalculationUFF : public OBFFCalculation2
+ {
+ public:
+ bool is14, samering;
+ double ka, Ra, kb, Rb, kab, rab;
+
+ template<bool> void Compute();
+ };
+
+ class OBFFElectrostaticCalculationUFF : public OBFFCalculation2
+ {
+ public:
+ double qq, rab;
+
+ template<bool> void Compute();
+ };
+
+ // Class OBForceFieldUFF
+ // class introduction in forcefieldUFF.cpp
+ class OBForceFieldUFF: public OBForceField
+ {
+ protected:
+ //! Parses the parameter file
+ bool ParseParamFile();
+ //! Sets atomtypes to UFF types in _mol
+ bool SetTypes();
+ //! Fill OBFFXXXCalculation vectors
+ bool SetupCalculations();
+ //! By default, electrostatic terms are disabled
+ //! This is discouraged, since the parameterization is not designed for it
+ //! But if you want, we give you the option.
+ bool SetupElectrostatics();
+ //! Same as OBForceField::GetParameter, but simpler
+ OBFFParameter* GetParameterUFF(std::string a, std::vector<OBFFParameter> ¶meter);
+
+ // OBFFParameter vectors to contain the parameters
+ std::vector<OBFFParameter> _ffparams;
+
+ // OBFFXXXCalculationYYY vectors to contain the calculations
+ std::vector<OBFFBondCalculationUFF> _bondcalculations;
+ std::vector<OBFFAngleCalculationUFF> _anglecalculations;
+ std::vector<OBFFTorsionCalculationUFF> _torsioncalculations;
+ std::vector<OBFFOOPCalculationUFF> _oopcalculations;
+ std::vector<OBFFVDWCalculationUFF> _vdwcalculations;
+ std::vector<OBFFElectrostaticCalculationUFF> _electrostaticcalculations;
+
+ public:
+ //! Constructor
+ explicit OBForceFieldUFF(const char* ID, bool IsDefault=true) : OBForceField(ID, IsDefault)
+ {
+ _init = false;
+ _rvdw = 7.0;
+ _rele = 15.0;
+ _pairfreq = 10;
+ _cutoff = false;
+ _linesearch = LineSearchType::Simple;
+ }
+
+ //! Destructor
+ virtual ~OBForceFieldUFF();
+
+ //!Clone the current instance. May be desirable in multithreaded environments
+ virtual OBForceFieldUFF* MakeNewInstance(){ return new OBForceFieldUFF(*this); }
+
+ //! Assignment
+ OBForceFieldUFF &operator = (OBForceFieldUFF &);
+
+ //! Get the description for this force field
+ const char* Description()
+ {
+ return "Universal Force Field.";
+ }
+
+ //! Get the unit in which the energy is expressed
+ std::string GetUnit()
+ {
+ return std::string("kJ/mol"); // Note that we convert from kcal/mol internally
+ }
+
+ //! \return that analytical gradients are implemented for UFF
+ bool HasAnalyticalGradients() { return true; }
+
+ //! \return total energy
+ double Energy(bool gradients = true);
+ //! \return the bond stretching energy
+ template<bool> double E_Bond();
+ double E_Bond(bool gradients = true)
+ {
+ return gradients ? E_Bond<true>() : E_Bond<false>();
+ }
+ //! Returns the angle bending energy
+ template<bool> double E_Angle();
+ double E_Angle(bool gradients = true)
+ {
+ return gradients ? E_Angle<true>() : E_Angle<false>();
+ }
+ //! Returns the torsional energy
+ template<bool> double E_Torsion();
+ double E_Torsion(bool gradients = true)
+ {
+ return gradients ? E_Torsion<true>() : E_Torsion<false>();
+ }
+ //! Returns the out-of-plane bending energy
+ template<bool> double E_OOP();
+ double E_OOP(bool gradients = true)
+ {
+ return gradients ? E_OOP<true>() : E_OOP<false>();
+ }
+ //! Returns the Van der Waals energy (Buckingham potential)
+ template<bool> double E_VDW();
+ double E_VDW(bool gradients = true)
+ {
+ return gradients ? E_VDW<true>() : E_VDW<false>();
+ }
+ //! Returns the dipole-dipole interaction energy
+ template<bool> double E_Electrostatic();
+ double E_Electrostatic(bool gradients = true)
+ {
+ return gradients ? E_Electrostatic<true>() : E_Electrostatic<false>();
+ }
+
+ //! Compare and print the numerical and analytical gradients
+ bool ValidateGradients();
+
+ }; // class OBForceFieldUFF
+
+}// namespace OpenBabel
+
+//! \file forcefieldUFF.h
+//! \brief UFF force field
diff --git a/forcefields/forcefielduff.lo b/forcefields/forcefielduff.lo
new file mode 100644
index 0000000..cc12a38
--- /dev/null
+++ b/forcefields/forcefielduff.lo
@@ -0,0 +1,12 @@
+# forcefielduff.lo - a libtool object file
+# Generated by ltmain.sh (GNU libtool) 2.2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/forcefielduff.o'
+
+# Name of the non-PIC object
+non_pic_object=none
+
diff --git a/forcefields/libforcefields.la b/forcefields/libforcefields.la
new file mode 100644
index 0000000..e3a9db0
--- /dev/null
+++ b/forcefields/libforcefields.la
@@ -0,0 +1,41 @@
+# libforcefields.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.4
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libforcefields.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=' '
+
+# Libraries that this one depends upon.
+dependency_libs=' -lz -lm'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libforcefields.
+current=
+age=
+revision=
+
+# Is this an already installed library?
+installed=no
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir=''
diff --git a/graphical_object.cc b/graphical_object.cc
new file mode 100644
index 0000000..47c9a84
--- /dev/null
+++ b/graphical_object.cc
@@ -0,0 +1,656 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#include "graphical_object.h"
+#include "constants.h"
+#include <math.h>
+#include "ddwin.h"
+
+using namespace std;
+
+GraphicalObject::GraphicalObject () : name ("no name"){
+ mesh = false;
+ set_clippable (false);
+
+}
+
+bool GraphicalObject::is_surface () {
+ return false;
+}
+
+bool GraphicalObject::is_sphere () {
+ return false;
+}
+
+bool GraphicalObject::is_grid () {
+ return false;
+}
+
+bool GraphicalObject::is_map () {
+ return false;
+}
+
+
+Map::Map () : Surface () {
+ cube = 0;
+}
+
+
+bool Map::is_map () {
+ return true;
+}
+
+void Map::clean () {
+ for (unsigned int i=0; i < faces.size (); i++) {
+ delete faces[i];
+ }
+ faces.clear ();
+ for (unsigned int i=0; i < vertices.size (); i++) {
+ delete vertices[i];
+ }
+ vertices.clear ();
+
+}
+
+void Map::render () {
+ glNewList(lst,GL_COMPILE);
+ for (unsigned int i=0; i<faces.size (); i++) {
+ glBegin (GL_TRIANGLES);
+ SurfVertex *v1 = faces[i]->v1;
+ SurfVertex *v2 = faces[i]->v2;
+ SurfVertex *v3 = faces[i]->v3;
+ set_color (v1 -> col);
+ glNormal3f (v1->normal.x(), v1->normal.y(), v1->normal.z());
+ glVertex3f (v1-> GetVector ().x(), v1-> GetVector ().y(), v1-> GetVector ().z());
+ set_color (v2 -> col);
+ glNormal3f (v2->normal.x(), v2->normal.y(), v2->normal.z());
+ glVertex3f (v2-> GetVector ().x(), v2-> GetVector ().y(), v2-> GetVector ().z());
+ set_color (v3 -> col);
+ glNormal3f (v3->normal.x(), v3->normal.y(), v3->normal.z());
+ glVertex3f (v3-> GetVector ().x(), v3-> GetVector ().y(), v3-> GetVector ().z());
+ glEnd ();
+ }
+ glEndList ();
+}
+
+Surface::Surface () {
+ mesh = false;
+ near_to_dist = 4.f;
+ near_to = 0;
+ molecule = 0;
+ grid = 0;
+}
+
+bool Surface::is_surface () {
+ return true;
+}
+
+void Surface::set_molecule (ZNMolecule *mo, ZNMolecule *near_t) {
+ molecule = mo;
+ set_clippable (get_clippable (mo));
+ vector <Atom *> atoms;
+ FOR_ATOMS_OF_MOL (a, mo) {
+ if (CountBonds (&*a) < 4) //to speed things up atoms at center of tetrhaedrons octaedrons and so on are not considered
+ atoms.push_back (&*a);
+ }
+
+ grid = new cutoffGrid<Atom*>(atoms, 4);
+
+ if (near_t) {
+ near_to = near_t;
+ vector <Atom *> atoms2;
+ FOR_ATOMS_OF_MOL (a, near_t) {
+ if (CountBonds (&*a) < 4) //to speed things up atoms at center of tetrhaedrons octaedrons and so on are not considered
+ atoms2.push_back (&*a);
+ }
+
+ near_to_grid = new cutoffGrid<Atom*>(atoms2, near_to_dist);
+
+ }
+}
+
+
+
+
+void Surface::render_as_surface () {
+ glNewList(lst,GL_COMPILE);
+ for (unsigned int i=0; i<faces.size (); i++) {
+ glBegin (GL_TRIANGLES);
+ SurfVertex *v1 = faces[i]->v1;
+ SurfVertex *v2 = faces[i]->v2;
+ SurfVertex *v3 = faces[i]->v3;
+ set_color (v1 -> col);
+ glNormal3f (v1->normal.x(), v1->normal.y(), v1->normal.z());
+ glVertex3f (v1-> GetVector ().x(), v1-> GetVector ().y(), v1-> GetVector ().z());
+ set_color (v2 -> col);
+ glNormal3f (v2->normal.x(), v2->normal.y(), v2->normal.z());
+ glVertex3f (v2-> GetVector ().x(), v2-> GetVector ().y(), v2-> GetVector ().z());
+ set_color (v3 -> col);
+ glNormal3f (v3->normal.x(), v3->normal.y(), v3->normal.z());
+ glVertex3f (v3-> GetVector ().x(), v3-> GetVector ().y(), v3-> GetVector ().z());
+ glEnd ();
+ }
+ glEndList ();
+
+
+}
+
+void Surface::render () {
+ if (mesh) render_as_mesh ();
+ else render_as_surface ();
+}
+
+void Surface::render_as_mesh () {
+ glNewList(lst,GL_COMPILE);
+ for (unsigned int i=0; i<faces.size (); i++) {
+ glBegin (GL_LINES);
+ SurfVertex *v1 = faces[i]->v1;
+ SurfVertex *v2 = faces[i]->v2;
+ SurfVertex *v3 = faces[i]->v3;
+ set_color (v1 -> col);
+ glNormal3f (v1->normal.x(), v1->normal.y(), v1->normal.z());
+ glVertex3f (v1-> GetVector ().x(), v1-> GetVector ().y(), v1-> GetVector ().z());
+ set_color (v2 -> col);
+ glNormal3f (v2->normal.x(), v2->normal.y(), v2->normal.z());
+ glVertex3f (v2-> GetVector ().x(), v2-> GetVector ().y(), v2-> GetVector ().z());
+ set_color (v3 -> col);
+ glNormal3f (v3->normal.x(), v3->normal.y(), v3->normal.z());
+ glVertex3f (v3-> GetVector ().x(), v3-> GetVector ().y(), v3-> GetVector ().z());
+
+ set_color (v1 -> col);
+ glNormal3f (v1->normal.x(), v1->normal.y(), v1->normal.z());
+ glVertex3f (v1-> GetVector ().x(), v1-> GetVector ().y(), v1-> GetVector ().z());
+ set_color (v2 -> col);
+ glNormal3f (v2->normal.x(), v2->normal.y(), v2->normal.z());
+ glVertex3f (v2-> GetVector ().x(), v2-> GetVector ().y(), v2-> GetVector ().z());
+ set_color (v3 -> col);
+ glNormal3f (v3->normal.x(), v3->normal.y(), v3->normal.z());
+ glVertex3f (v3-> GetVector ().x(), v3-> GetVector ().y(), v3-> GetVector ().z());
+
+
+
+ glEnd ();
+ }
+ glEndList ();
+
+}
+
+void Surface::color_by_mol (ZNMolecule *mol, float a) {
+ delete grid;
+ vector <Atom *> atoms;
+ FOR_ATOMS_OF_MOL (at, mol) {
+ atoms.push_back (&*at);
+ }
+
+ grid = new cutoffGrid<Atom*>(atoms, 4);
+ color_by_atom (a);
+
+}
+
+void Surface::color_by_map (Map *map, color c1, color c2, color c3, float f1, float f2, float f3) {
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ color_vertex_by_map (faces[ii]->v1,map, c1, c2, c3, f1, f2, f3);
+ color_vertex_by_map (faces[ii]->v2,map, c1, c2, c3, f1, f2, f3);
+ color_vertex_by_map (faces[ii]->v3,map, c1, c2, c3, f1, f2, f3);
+
+ }
+}
+
+void Surface::alpha_by_mol_distance (ZNMolecule *mol, float distance) {
+ if (grid) delete grid;
+ vector <Atom *> atoms;
+ FOR_ATOMS_OF_MOL (a, mol) {
+ atoms.push_back (&*a);
+ }
+
+ grid = new cutoffGrid<Atom*>(atoms, distance);
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ fade_vertex_alpha_by_atom (faces[ii]->v1, distance);
+ fade_vertex_alpha_by_atom (faces[ii]->v2, distance);
+ fade_vertex_alpha_by_atom (faces[ii]->v3, distance);
+ }
+
+}
+
+
+void Surface::color_by_atom (float a) {
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ color_vertex_by_atom_smooth (faces[ii]->v1,a);
+ color_vertex_by_atom_smooth (faces[ii]->v2,a);
+ color_vertex_by_atom_smooth (faces[ii]->v3,a);
+
+ }
+}
+
+void Surface::color_by_potential (ZNMolecule *mol, color lipo, color acc, color don, float threshold) {
+
+ Chemscore *chemscore = new Chemscore;
+ ZNMolecule *mol2 = new ZNMolecule;
+ vector <ZNMolecule *> mols;
+ mols.push_back(mol);
+ chemscore ->load_environment (mols, mol2);
+
+ float rl = lipo.redF ();
+ float gl = lipo.greenF ();
+ float bl = lipo.blueF ();
+ float al = lipo.alphaF ();
+
+ float ra = acc.redF ();
+ float ga = acc.greenF ();
+ float ba = acc.blueF ();
+ float aa = acc.alphaF ();
+
+ float rd = don.redF ();
+ float gd = don.greenF ();
+ float bd = don.blueF ();
+ float ad = don.alphaF ();
+ float r, g, b, a, tot, total_score;
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ float scorelipo1 = chemscore ->Livalue (faces[ii]->v1 ->coordinates);
+ float scoreacc1 = chemscore ->Acceptorvalue (faces[ii]->v1->coordinates);
+ float scoredon1 = chemscore ->Donorvalue (faces[ii]->v1->coordinates);
+ tot = 1 / (scorelipo1 + scoreacc1 + scoredon1);
+ total_score = scorelipo1 + scoreacc1 + scoredon1;
+ scorelipo1 *= tot;
+ scoreacc1 *= tot;
+ scoredon1 *= tot;
+ r = (rl * scorelipo1 + ra * scoreacc1 + rd * scoredon1);
+ g = (gl * scorelipo1 + ga * scoreacc1 + gd * scoredon1) ;
+ b = (bl * scorelipo1 + ba * scoreacc1 + bd * scoredon1);
+ a = (al * scorelipo1 + aa * scoreacc1 + ad * scoredon1) ;
+ if (total_score < threshold) {
+ color_vertex_by_color(faces[ii] ->v1, color (r, g, b, a));
+ }
+ else {
+ float k1 = total_score /threshold ;
+ if (k1 < 0.f) k1 = 0.f;
+ if (k1 > 1.f) k1 = 1.f;
+ float k2 = 1.f - k1;
+ float lastr = faces[ii] ->v1 ->col.redF ();
+ float lastg = faces[ii] ->v1 ->col.greenF ();
+ float lastb = faces[ii] ->v1 ->col.blueF ();
+ float lasta = faces[ii] ->v1 ->col.alphaF ();
+ color_vertex_by_color(faces[ii] ->v1, color (r*k1 + lastr*k2, g*k1 + lastg*k2, b*k1 + lastg*k2, a*k1 + lasta*k2));
+
+ }
+
+ float scorelipo2 = chemscore ->Livalue (faces[ii]->v2->coordinates);
+ float scoreacc2 = chemscore ->Acceptorvalue (faces[ii]->v2->coordinates);
+ float scoredon2 = chemscore ->Donorvalue (faces[ii]->v2->coordinates);
+ tot = 1 / (scorelipo2 + scoreacc2 + scoredon2);
+ total_score = scorelipo2 + scoreacc2 + scoredon2;
+ scorelipo2 *= tot;
+ scoreacc2 *= tot;
+ scoredon2 *= tot;
+ r = (rl * scorelipo2 + ra * scoreacc2 + rd * scoredon2);
+ g = (gl * scorelipo2 + ga * scoreacc2 + gd * scoredon2);
+ b = (bl * scorelipo2 + ba * scoreacc2 + bd * scoredon2) ;
+ a = (al * scorelipo2 + aa * scoreacc2 + ad * scoredon2);
+
+ if (total_score < threshold) {
+ color_vertex_by_color(faces[ii] ->v2, color (r, g, b, a));
+ }
+ else {
+ float k1 = total_score /threshold ;
+ if (k1 < 0.f) k1 = 0.f;
+ if (k1 > 1.f) k1 = 1.f;
+ float k2 = 1.f - k1;
+ float lastr = faces[ii] ->v2 ->col.redF ();
+ float lastg = faces[ii] ->v2 ->col.greenF ();
+ float lastb = faces[ii] ->v2 ->col.blueF ();
+ float lasta = faces[ii] ->v2 ->col.alphaF ();
+ color_vertex_by_color(faces[ii] ->v2, color (r*k1 + lastr*k2, g*k1 + lastg*k2, b*k1 + lastg*k2, a*k1 + lasta*k2));
+
+ }
+
+ float scorelipo3 = chemscore ->Livalue (faces[ii]->v3->coordinates);
+ float scoreacc3 = chemscore ->Acceptorvalue (faces[ii]->v3->coordinates);
+ float scoredon3 = chemscore ->Donorvalue (faces[ii]->v3->coordinates);
+ tot = 1 / (scorelipo3 + scoreacc3 + scoredon3);
+ total_score = scorelipo3 + scoreacc3 + scoredon3;
+ scorelipo3 *= tot;
+ scoreacc3 *= tot;
+ scoredon3 *= tot;
+ r = (rl * scorelipo3 + ra * scoreacc3 + rd * scoredon3);
+ g = (gl * scorelipo3 + ga * scoreacc3 + gd * scoredon3) ;
+ b = (bl * scorelipo3 + ba * scoreacc3 + bd * scoredon3) ;
+ a = (al * scorelipo3 + aa * scoreacc3 + ad * scoredon3);
+ if (total_score < threshold) {
+ color_vertex_by_color(faces[ii] ->v3, color (r, g, b, a));
+ }
+ else {
+ float k1 = total_score /threshold ;
+ if (k1 < 0.f) k1 = 0.f;
+ if (k1 > 1.f) k1 = 1.f;
+ float k2 = 1.f - k1;
+ float lastr = faces[ii] ->v3 ->col.redF ();
+ float lastg = faces[ii] ->v3 ->col.greenF ();
+ float lastb = faces[ii] ->v3 ->col.blueF ();
+ float lasta = faces[ii] ->v3 ->col.alphaF ();
+ color_vertex_by_color(faces[ii] ->v3, color (r*k1 + lastr*k2, g*k1 + lastg*k2, b*k1 + lastg*k2, a*k1 + lasta*k2));
+
+ }
+
+ }
+ delete mol2;
+ delete chemscore;
+}
+
+void Surface::color_by_color (color c) {
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ color_vertex_by_color (faces[ii]->v1,c);
+ color_vertex_by_color (faces[ii]->v2,c);
+ color_vertex_by_color (faces[ii]->v3,c);
+
+ }
+}
+
+
+
+
+void Surface::color_vertex_by_color (SurfVertex *vert, color c) {
+ vert -> col = c;
+}
+
+void Surface::color_vertex_by_map (SurfVertex *vert, Map *map, color c1, color c2, color c3, float f1, float f2, float f3) {
+ float score = map ->get_value (vert ->coordinates.x(), vert ->coordinates.y(), vert ->coordinates.z());
+ cerr << "score" << score<<endl;
+ color c = average_3_colors(score, c1, c2, c3, f1, f2, f3);
+ vert ->col = c;
+}
+
+void Surface::color_vertex_by_atom (SurfVertex *vert, float alp) {
+
+ objectList<Atom*>* nbAtoms = grid->getNeighborObjects(vert-> GetVector ());
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ float rr, gg, bb, aa;
+ float dis = dist (get_coordinates (neighbours[0]), get_coordinates (vert));
+ // float dis = sqrt((neighbours[0]-> GetVector ().x()-vert-> GetVector ().x())*(neighbours[0]-> GetVector ().x()-vert-> GetVector ().x())+
+ // (neighbours[0]-> GetVector ().y()-vert-> GetVector ().y())*(neighbours[0]-> GetVector ().y()-vert-> GetVector ().y())+
+ //(neighbours[0]-> GetVector ().z()-vert-> GetVector ().z())*(neighbours[0]-> GetVector ().z()-vert-> GetVector ().z()));
+ color col = get_color (neighbours[0]);
+ rr = col.redF ();
+ gg = col.greenF ();
+ bb = col.blueF ();
+ aa = col.alphaF ();
+
+ for (unsigned int i=0; i<neighbours.size (); i++) {
+ float n_dist = dist (get_coordinates (neighbours[i]), get_coordinates (vert));
+ // float n_dist = sqrt((neighbours[i]-> GetVector ().x()-vert-> GetVector ().x())*(neighbours[i]-> GetVector ().x()-vert-> GetVector ().x())+
+ // (neighbours[i]-> GetVector ().y()-vert-> GetVector ().y())*(neighbours[i]-> GetVector ().y()-vert-> GetVector ().y())+
+ //(neighbours[i]-> GetVector ().z()-vert-> GetVector ().z())*(neighbours[i]-> GetVector ().z()-vert-> GetVector ().z()));
+ if (n_dist < dis) {
+ dis = n_dist;
+ color coli = get_color (neighbours[i]);
+ rr = coli.redF ();
+ gg = coli.greenF ();
+ bb = coli.blueF ();
+ aa = coli.alphaF ();
+ }
+
+ }
+ vert -> col = color (rr, bb, gg, aa*alp);
+ }
+}
+
+void Surface::set_alpha (double d) {
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ set_vertex_alpha (faces[ii]->v1,d);
+ set_vertex_alpha (faces[ii]->v2,d);
+ set_vertex_alpha (faces[ii]->v3,d);
+
+ }
+}
+
+void Surface::multiply_alpha (double d) {
+ for (unsigned int ii=0; ii< faces.size (); ii++) {
+ multiply_vertex_alpha (faces[ii]->v1,d);
+ multiply_vertex_alpha (faces[ii]->v2,d);
+ multiply_vertex_alpha (faces[ii]->v3,d);
+
+ }
+}
+
+void Surface::set_vertex_alpha (SurfVertex *vert, float a) {
+ vert -> col.setAlphaF (a);
+}
+
+void Surface::multiply_vertex_alpha (SurfVertex *vert, float a) {
+ float f = vert ->col.alphaF ();
+
+ vert -> col.setAlphaF (a*f);
+}
+
+
+void Surface::fade_vertex_alpha_by_atom (SurfVertex *vert, float distance) {
+ objectList<Atom*>* nbAtoms = grid->getNeighborObjects(vert-> GetVector ());
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ float dis = BIG;
+ for (unsigned int i=0; i<neighbours.size (); i++) {
+ float d = dist (get_coordinates (neighbours[i]), get_coordinates (vert));
+ if (d < dis) dis = d;
+ }
+ float perc = dis / distance;
+ float alpha = 1.f;
+ if (perc < 0.4f) alpha = 1.f;
+ else if (perc >0.7f) alpha = 0.f;
+ else alpha = 1 -((perc - 0.4f) / (0.7f - 0.4f));
+ vert ->col.setAlphaF (alpha);
+ }
+ else vert ->col.setAlphaF (0.f);
+}
+
+void Surface::color_vertex_by_atom_smooth (SurfVertex *vert, float alp) { //blends 2 closest atoms color, or closest atom with previous color
+ objectList<Atom*>* nbAtoms = grid->getNeighborObjects(vert-> GetVector ());
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ float r, g, b, a;
+ r = g = b = a = 0.f;
+ float total_val = 0.f;
+ float threshold = 1.f;
+
+ for (unsigned int i=0; i<neighbours.size (); i++) {
+ float dis = dist (get_coordinates (neighbours[i]), get_coordinates (vert));
+ float val = (1 - (dis / 4.f));
+ if (val < 0) continue;
+ else {
+ color col = get_color (neighbours[i]);
+ r += col.redF()*val;
+ g += col.greenF()*val;
+ b += col.blueF()*val;
+ a += col.alphaF()*val;
+
+ total_val += val;
+ }
+
+
+
+ }
+ if (total_val > threshold) {
+ r /= total_val;
+ g /= total_val;
+ b /= total_val;
+ a /= total_val;
+ }
+ else {
+ r += vert ->col.redF () * (threshold - total_val);
+ g += vert ->col.greenF () * (threshold - total_val);
+ b += vert ->col.blueF () * (threshold - total_val);
+ a += vert ->col.alphaF () * (threshold - total_val);
+ r /= threshold;
+ g /= threshold;
+ b /= threshold;
+ a /= threshold;
+ }
+ vert -> col = color (r, g, b, a);
+ }
+
+
+ /* objectList<Atom*>* nbAtoms = grid->getNeighborObjects(vert-> GetVector ());
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ float r1, g1, b1, a1;
+ float r2, g2, b2, a2;
+ r1 = g1 = b1 = a1 = r2 = g2 = b2 = a2 = 0.f;
+ float dist1 = BIG;
+ float dist2 = BIG;
+ int idx1 = -1;
+ int idx2 = -1;
+
+ for (unsigned int i=0; i<neighbours.size (); i++) {
+ float dis = dist (get_coordinates (neighbours[i]), get_coordinates (vert));
+ if (dis < dist1) {
+ dist1 = dis;
+ idx1 = i;
+ }
+ else if (dis < dist2) {
+ dist2 = dis;
+ idx2 = i;
+ }
+
+
+ }
+
+
+
+ if (dist1 < BIG) {
+ color col = get_color (neighbours[idx1]);
+ float val = 1/ dist1;
+ // float val = 1/(dist1*dist1*dist1);
+ r1 = col.redF()*val;
+ g1 = col.greenF()*val;
+ b1 = col.blueF ()*val;
+ a1 = col.alphaF ()*val;
+ if (dist2 < BIG) {
+ color col2 = get_color (neighbours[idx2]);
+ // float val2 = 1/(dist1*dist1*dist1);
+ float val2 = 1/dist2;
+ r2 = col2.redF()*val2;
+ g2 = col2.greenF()*val2;
+ b2 = col2.blueF ()*val2;
+ a2 = col2.alphaF ()*val2;
+ float tv = val + val2;
+ vert -> col = color ((r1+r2)/tv, (g1+g2)/tv,(b1+b2)/tv,(a1+a2)/tv);
+
+ }
+ else {
+ color col2 = vert ->col;
+ float val2 = 1-val;
+ r2 = col.redF()*val2;
+ g2 = col.greenF()*val2;
+ b2 = col.blueF ()*val2;
+ a2 = col.alphaF ()*val2;
+ }
+
+ }
+ else {
+ // do nothing
+ }
+
+
+
+ }
+ */
+}
+
+
+bool Sphere::is_sphere () {
+ return true;
+}
+
+void Sphere::render () {
+ render_as_surface ();
+}
+
+void Sphere::render_as_surface () {
+ glNewList(lst,GL_COMPILE);
+ glPushMatrix ();
+ glTranslatef (center.x(), center.y(), center.z());
+ glColor4f (col.redF (), col.greenF(), col.blueF(), col.alphaF());
+ gluSphere (gluNewQuadric(), radius, 30, 30);
+ glPopMatrix ();
+ glEndList ();
+
+}
+
+
+
+
+
+Grid::Grid () {
+ cube = new MarchingCubes ();
+ res = 1.f;
+ threshold = 1.f;
+ ff = new MMFF ();
+ // function = &null;
+}
+
+float Grid::null (float x, float y, float z) {
+ cerr << "function not defined" << endl;
+ return 0.f;
+}
+
+bool Grid::is_grid () {
+ return true;
+}
+
+void Grid::init_ff () {
+ probe = new ZNMolecule ();
+ Atom *at = new Atom ();
+ at -> SetAtomicNum (6);
+ // at -> getVdw ();
+ at -> SetPartialCharge (0);
+ // at -> MMFFstring = "CR";
+ // at -> MMFFtype = 1;
+ probe->ZNAddAtom (at);
+ ff -> clear_nonbonded_interactions ();
+ ff -> initialize_interaction (probe, env);
+}
+
+
+void Grid::load () {
+
+ int xm = (int)((end.x() - origin.x())* res);
+ int ym = (int)((end.y() - origin.y())* res);
+ int zm = (int)((end.z() - origin.z())* res);
+ // cout <<xm<<" "<<ym<<" "<<zm<<endl;
+
+
+ cube->set_resolution( xm, ym, zm) ;
+ cube->set_method (false); //use original MC algo?
+ cube->set_limits (origin.x(), origin.y(), origin.z(), end.x(), end.y(), end.z());
+ cube->init_all() ;
+ float x, y, z;
+
+ for (unsigned int k=0; k<zm; k++) {
+ z = cube->to_real_z (k);
+ for (unsigned int j=0; j<ym; j++) {
+ y = cube->to_real_y (j);
+ for (unsigned int i=0; i<xm; i++) {
+ x = cube->to_real_x (i);
+ float value = function (x, y, z);
+ cube->set_data(value, i, j, k );
+ }
+ }
+ }
+ cube->run(threshold) ;
+}
+
+
diff --git a/headers/CVS/Entries b/headers/CVS/Entries
new file mode 100644
index 0000000..288f1fc
--- /dev/null
+++ b/headers/CVS/Entries
@@ -0,0 +1,38 @@
+/FF.h/1.5/Thu Feb 5 11:56:49 2009//
+/LookUpTable.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/MMFF.h/1.2/Mon Sep 29 09:02:34 2008//
+/MarchingCubes.h/1.4/Tue Apr 7 08:43:20 2009//
+/PLP.h/1.2/Mon Sep 29 09:02:35 2008//
+/ZNdata.h/1.12/Sun Apr 19 09:10:19 2009//
+/ZNmolecule.h/1.12/Mon May 18 12:07:25 2009//
+/actions.h/1.5/Thu Dec 11 11:41:29 2008//
+/arcball.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/builder.h/1.5/Wed Oct 22 08:48:46 2008//
+/chemscore.h/1.13/Wed Feb 25 13:13:40 2009//
+/cmat.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/command.h/1.7/Fri Feb 13 15:36:57 2009//
+/constants.h/1.13/Mon May 18 12:07:25 2009//
+/cutoffGrid.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/database.h/1.11/Thu Feb 26 11:54:57 2009//
+/datagrid.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/ddwin.h/1.47/Thu May 14 15:52:21 2009//
+/function.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/graphical_object.h/1.13/Wed May 13 16:05:08 2009//
+/ils.h/1.5/Fri Aug 29 11:56:14 2008//
+/iodevice.h/1.2/Fri Sep 26 12:48:00 2008//
+/maths.h/1.3/Sun Apr 19 09:10:20 2009//
+/menu.h/1.83/Mon May 18 12:07:25 2009//
+/minimize.h/1.8/Wed Mar 18 13:06:29 2009//
+/myline.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/nms.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/optimiser.h/1.4/Mon Jan 12 16:18:09 2009//
+/plants.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/plants_mainwin.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/plantsconfig.h/1.2/Mon Nov 3 16:07:11 2008//
+/ply.h/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/pso.h/1.4/Mon Jan 12 16:18:09 2009//
+/subscrpt.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/thread.h/1.15/Wed Mar 18 13:06:29 2009//
+/vec.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+/wiimote.h/1.1.1.1/Wed Aug 20 12:44:09 2008//
+D
diff --git a/headers/CVS/Entries.Extra b/headers/CVS/Entries.Extra
new file mode 100644
index 0000000..0cd6778
--- /dev/null
+++ b/headers/CVS/Entries.Extra
@@ -0,0 +1,37 @@
+/FF.h////*///
+/LookUpTable.h////*///
+/MMFF.h////*///
+/MarchingCubes.h////*///
+/PLP.h////*///
+/ZNdata.h////*///
+/ZNmolecule.h////*///
+/actions.h////*///
+/arcball.h////*///
+/builder.h////*///
+/chemscore.h////*///
+/cmat.h////*///
+/command.h////*///
+/constants.h////*///
+/cutoffGrid.h////*///
+/database.h////*///
+/datagrid.h////*///
+/ddwin.h////*///
+/function.h////*///
+/graphical_object.h////*///
+/ils.h////*///
+/iodevice.h////*///
+/maths.h////*///
+/menu.h////*///
+/minimize.h////*///
+/myline.h////*///
+/nms.h////*///
+/optimiser.h////*///
+/plants.h////*///
+/plants_mainwin.h////*///
+/plantsconfig.h////*///
+/ply.h////*///
+/pso.h////*///
+/subscrpt.h////*///
+/thread.h////*///
+/vec.h////*///
+/wiimote.h////*///
diff --git a/headers/CVS/Entries.Extra.Old b/headers/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/headers/CVS/Entries.Old b/headers/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/headers/CVS/Repository b/headers/CVS/Repository
new file mode 100644
index 0000000..7dee8d0
--- /dev/null
+++ b/headers/CVS/Repository
@@ -0,0 +1 @@
+zodiac/headers
diff --git a/headers/CVS/Root b/headers/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/headers/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/headers/FF.h b/headers/FF.h
new file mode 100644
index 0000000..d00b1d3
--- /dev/null
+++ b/headers/FF.h
@@ -0,0 +1,110 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef FF_H
+#define FF_H
+#include "ZNmolecule.h"
+#include "constants.h"
+#include "cutoffGrid.h"
+
+
+class ForceFieldInteraction {
+ public:
+ ForceFieldInteraction ();
+ Atom *at1, *at2;
+ virtual float value () = 0;
+ virtual double derive (Atom *at, double *val = NULL);
+ virtual double derive_y (Atom *at, double *val = NULL);
+ virtual double derive_z (Atom *at, double *val = NULL);
+ virtual void set_forces (bool score = FALSE, double mult = 1.);
+ inline virtual bool isHbond () {return false;};
+ inline virtual bool isElectrostatic () {return false;};
+ private:
+};
+
+
+class ElasticRestrain : public ForceFieldInteraction {
+public:
+ ElasticRestrain ();
+ double k;
+ double dist0;
+ float value ();
+};
+
+
+class ForceField {
+public:
+ ForceField ();
+ bool is_initialised;
+
+
+
+
+
+ virtual ~ForceField();
+ void clear ();
+ void load_mol (ZNMolecule *mol);
+ void load_environment (vector<ZNMolecule *> envir, ZNMolecule *mol, vect cent = vect (0., 0., 0.), double rad = 0);
+ virtual void load_grids (vect cent, double rad) {};
+ void update ();
+
+ void initialize_internal (ZNMolecule *mol, vector<ZNMolecule *> envir);
+ void initialize_interaction (ZNMolecule *mol, vector<ZNMolecule *> envir, vect cent = vect (0., 0., 0.), float rad = 0.);
+ void initialize (ZNMolecule *mol, vector<ZNMolecule *> envir);
+ virtual double compute_total_energy ()=0;
+ float total_energy;
+
+// int getPLPtype(Atom* at);
+ // int getPLPinteractiontype (int I, int J);
+
+ virtual void compute_forces ()=0;
+
+ virtual void clear_nonbonded_interactions ()=0;
+ virtual void load_nonbonded_interactions ()=0;
+ virtual void load_nonbonded_interactions_for_atom (Atom *at, queue <ForceFieldInteraction*> *q) {};
+ virtual void load_internal_interactions (vector <ForceFieldInteraction*> *v) {};
+
+ vector <ForceFieldInteraction *> restrains;
+ ZNMolecule *target_mol;
+
+protected:
+
+ vector <Atom *> environment;
+
+
+
+
+
+ cutoffGrid<Atom*>* near_grid;
+ cutoffGrid<Atom*>* far_grid;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/headers/LookUpTable.h b/headers/LookUpTable.h
new file mode 100644
index 0000000..bec47f6
--- /dev/null
+++ b/headers/LookUpTable.h
@@ -0,0 +1,4644 @@
+/**
+
+ * @file LookUpTable.h
+
+ * @author Thomas Lewiner <thomas.lewiner at polytechnique.org>
+
+ * @author Math Dept, PUC-Rio
+
+ * @version 0.2
+
+ * @date 12/08/2002
+
+ *
+
+ * @brief LookUpTable for the MarchingCubes 33 Algorithm
+
+ */
+
+//________________________________________________
+
+
+
+
+
+
+
+#ifndef _LOOKUPTABLE_H_
+
+#define _LOOKUPTABLE_H_
+
+
+
+
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief case mapping
+
+ * For each of the possible vertex states listed in this table there is a
+
+ * specific triangulation of the edge intersection points. The table lists
+
+ * all of them in the form of 0-5 edge triples with the list terminated by
+
+ * the invalid value -1. For example: case[3] list the 2 triangles
+
+ * formed when cube[0] && cube[1] are inside of the surface, but the rest of
+
+ * the cube is not.
+
+ *
+
+ * Cube description:
+
+ * 7 ________ 6 _____6__ ________
+
+ * /| /| 7/| /| /| /|
+
+ * / | / | / | /5 | / 6 / |
+
+ * 4 /_______ / | /__4____ / 10 /_______3/ |
+
+ * | | |5 | | 11 | | | | | 2 |
+
+ * | 3|__|_____|2 | |__|__2__| | 4 |__|_____|
+
+ * | / | / 8 3/ 9 / | / | /
+
+ * | / | / | / | /1 | / 5 /
+
+ * |/_______|/ |/___0___|/ |/_1_____|/
+
+ * 0 1 0 1
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char cases[256][2] = {
+
+/* 0: */ { 0, -1 },
+
+/* 1: 0, */ { 1, 0 },
+
+/* 2: 1, */ { 1, 1 },
+
+/* 3: 0, 1, */ { 2, 0 },
+
+/* 4: 2, */ { 1, 2 },
+
+/* 5: 0, 2, */ { 3, 0 },
+
+/* 6: 1, 2, */ { 2, 3 },
+
+/* 7: 0, 1, 2, */ { 5, 0 },
+
+/* 8: 3, */ { 1, 3 },
+
+/* 9: 0, 3, */ { 2, 1 },
+
+/* 10: 1, 3, */ { 3, 3 },
+
+/* 11: 0, 1, 3, */ { 5, 1 },
+
+/* 12: 2, 3, */ { 2, 5 },
+
+/* 13: 0, 2, 3, */ { 5, 4 },
+
+/* 14: 1, 2, 3, */ { 5, 9 },
+
+/* 15: 0, 1, 2, 3, */ { 8, 0 },
+
+/* 16: 4, */ { 1, 4 },
+
+/* 17: 0, 4, */ { 2, 2 },
+
+/* 18: 1, 4, */ { 3, 4 },
+
+/* 19: 0, 1, 4, */ { 5, 2 },
+
+/* 20: 2, 4, */ { 4, 2 },
+
+/* 21: 0, 2, 4, */ { 6, 2 },
+
+/* 22: 1, 2, 4, */ { 6, 9 },
+
+/* 23: 0, 1, 2, 4, */ { 11, 0 },
+
+/* 24: 3, 4, */ { 3, 8 },
+
+/* 25: 0, 3, 4, */ { 5, 5 },
+
+/* 26: 1, 3, 4, */ { 7, 3 },
+
+/* 27: 0, 1, 3, 4, */ { 9, 1 },
+
+/* 28: 2, 3, 4, */ { 6, 16 },
+
+/* 29: 0, 2, 3, 4, */ { 14, 3 },
+
+/* 30: 1, 2, 3, 4, */ { 12, 12 },
+
+/* 31: 0, 1, 2, 3, 4, */ { 5, 24 },
+
+/* 32: 5, */ { 1, 5 },
+
+/* 33: 0, 5, */ { 3, 1 },
+
+/* 34: 1, 5, */ { 2, 4 },
+
+/* 35: 0, 1, 5, */ { 5, 3 },
+
+/* 36: 2, 5, */ { 3, 6 },
+
+/* 37: 0, 2, 5, */ { 7, 0 },
+
+/* 38: 1, 2, 5, */ { 5, 10 },
+
+/* 39: 0, 1, 2, 5, */ { 9, 0 },
+
+/* 40: 3, 5, */ { 4, 3 },
+
+/* 41: 0, 3, 5, */ { 6, 4 },
+
+/* 42: 1, 3, 5, */ { 6, 11 },
+
+/* 43: 0, 1, 3, 5, */ { 14, 1 },
+
+/* 44: 2, 3, 5, */ { 6, 17 },
+
+/* 45: 0, 2, 3, 5, */ { 12, 4 },
+
+/* 46: 1, 2, 3, 5, */ { 11, 6 },
+
+/* 47: 0, 1, 2, 3, 5, */ { 5, 25 },
+
+/* 48: 4, 5, */ { 2, 8 },
+
+/* 49: 0, 4, 5, */ { 5, 7 },
+
+/* 50: 1, 4, 5, */ { 5, 12 },
+
+/* 51: 0, 1, 4, 5, */ { 8, 1 },
+
+/* 52: 2, 4, 5, */ { 6, 18 },
+
+/* 53: 0, 2, 4, 5, */ { 12, 5 },
+
+/* 54: 1, 2, 4, 5, */ { 14, 7 },
+
+/* 55: 0, 1, 2, 4, 5, */ { 5, 28 },
+
+/* 56: 3, 4, 5, */ { 6, 21 },
+
+/* 57: 0, 3, 4, 5, */ { 11, 4 },
+
+/* 58: 1, 3, 4, 5, */ { 12, 15 },
+
+/* 59: 0, 1, 3, 4, 5, */ { 5, 30 },
+
+/* 60: 2, 3, 4, 5, */ { 10, 5 },
+
+/* 61: 0, 2, 3, 4, 5, */ { 6, 32 },
+
+/* 62: 1, 2, 3, 4, 5, */ { 6, 39 },
+
+/* 63: 0, 1, 2, 3, 4, 5, */ { 2, 12 },
+
+/* 64: 6, */ { 1, 6 },
+
+/* 65: 0, 6, */ { 4, 0 },
+
+/* 66: 1, 6, */ { 3, 5 },
+
+/* 67: 0, 1, 6, */ { 6, 0 },
+
+/* 68: 2, 6, */ { 2, 6 },
+
+/* 69: 0, 2, 6, */ { 6, 3 },
+
+/* 70: 1, 2, 6, */ { 5, 11 },
+
+/* 71: 0, 1, 2, 6, */ { 14, 0 },
+
+/* 72: 3, 6, */ { 3, 9 },
+
+/* 73: 0, 3, 6, */ { 6, 5 },
+
+/* 74: 1, 3, 6, */ { 7, 4 },
+
+/* 75: 0, 1, 3, 6, */ { 12, 1 },
+
+/* 76: 2, 3, 6, */ { 5, 14 },
+
+/* 77: 0, 2, 3, 6, */ { 11, 3 },
+
+/* 78: 1, 2, 3, 6, */ { 9, 4 },
+
+/* 79: 0, 1, 2, 3, 6, */ { 5, 26 },
+
+/* 80: 4, 6, */ { 3, 10 },
+
+/* 81: 0, 4, 6, */ { 6, 6 },
+
+/* 82: 1, 4, 6, */ { 7, 5 },
+
+/* 83: 0, 1, 4, 6, */ { 12, 2 },
+
+/* 84: 2, 4, 6, */ { 6, 19 },
+
+/* 85: 0, 2, 4, 6, */ { 10, 1 },
+
+/* 86: 1, 2, 4, 6, */ { 12, 13 },
+
+/* 87: 0, 1, 2, 4, 6, */ { 6, 24 },
+
+/* 88: 3, 4, 6, */ { 7, 7 },
+
+/* 89: 0, 3, 4, 6, */ { 12, 9 },
+
+/* 90: 1, 3, 4, 6, */ { 13, 1 },
+
+/* 91: 0, 1, 3, 4, 6, */ { 7, 9 },
+
+/* 92: 2, 3, 4, 6, */ { 12, 20 },
+
+/* 93: 0, 2, 3, 4, 6, */ { 6, 33 },
+
+/* 94: 1, 2, 3, 4, 6, */ { 7, 13 },
+
+/* 95: 0, 1, 2, 3, 4, 6, */ { 3, 12 },
+
+/* 96: 5, 6, */ { 2, 10 },
+
+/* 97: 0, 5, 6, */ { 6, 7 },
+
+/* 98: 1, 5, 6, */ { 5, 13 },
+
+/* 99: 0, 1, 5, 6, */ { 11, 2 },
+
+/* 100: 2, 5, 6, */ { 5, 16 },
+
+/* 101: 0, 2, 5, 6, */ { 12, 7 },
+
+/* 102: 1, 2, 5, 6, */ { 8, 3 },
+
+/* 103: 0, 1, 2, 5, 6, */ { 5, 29 },
+
+/* 104: 3, 5, 6, */ { 6, 22 },
+
+/* 105: 0, 3, 5, 6, */ { 10, 2 },
+
+/* 106: 1, 3, 5, 6, */ { 12, 17 },
+
+/* 107: 0, 1, 3, 5, 6, */ { 6, 27 },
+
+/* 108: 2, 3, 5, 6, */ { 14, 9 },
+
+/* 109: 0, 2, 3, 5, 6, */ { 6, 34 },
+
+/* 110: 1, 2, 3, 5, 6, */ { 5, 39 },
+
+/* 111: 0, 1, 2, 3, 5, 6, */ { 2, 14 },
+
+/* 112: 4, 5, 6, */ { 5, 20 },
+
+/* 113: 0, 4, 5, 6, */ { 14, 5 },
+
+/* 114: 1, 4, 5, 6, */ { 9, 5 },
+
+/* 115: 0, 1, 4, 5, 6, */ { 5, 32 },
+
+/* 116: 2, 4, 5, 6, */ { 11, 10 },
+
+/* 117: 0, 2, 4, 5, 6, */ { 6, 35 },
+
+/* 118: 1, 2, 4, 5, 6, */ { 5, 41 },
+
+/* 119: 0, 1, 2, 4, 5, 6, */ { 2, 16 },
+
+/* 120: 3, 4, 5, 6, */ { 12, 23 },
+
+/* 121: 0, 3, 4, 5, 6, */ { 6, 37 },
+
+/* 122: 1, 3, 4, 5, 6, */ { 7, 14 },
+
+/* 123: 0, 1, 3, 4, 5, 6, */ { 3, 16 },
+
+/* 124: 2, 3, 4, 5, 6, */ { 6, 46 },
+
+/* 125: 0, 2, 3, 4, 5, 6, */ { 4, 6 },
+
+/* 126: 1, 2, 3, 4, 5, 6, */ { 3, 21 },
+
+/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 1, 8 },
+
+/* 128: 7, */ { 1, 7 },
+
+/* 129: 0, 7, */ { 3, 2 },
+
+/* 130: 1, 7, */ { 4, 1 },
+
+/* 131: 0, 1, 7, */ { 6, 1 },
+
+/* 132: 2, 7, */ { 3, 7 },
+
+/* 133: 0, 2, 7, */ { 7, 1 },
+
+/* 134: 1, 2, 7, */ { 6, 10 },
+
+/* 135: 0, 1, 2, 7, */ { 12, 0 },
+
+/* 136: 3, 7, */ { 2, 7 },
+
+/* 137: 0, 3, 7, */ { 5, 6 },
+
+/* 138: 1, 3, 7, */ { 6, 12 },
+
+/* 139: 0, 1, 3, 7, */ { 11, 1 },
+
+/* 140: 2, 3, 7, */ { 5, 15 },
+
+/* 141: 0, 2, 3, 7, */ { 9, 2 },
+
+/* 142: 1, 2, 3, 7, */ { 14, 6 },
+
+/* 143: 0, 1, 2, 3, 7, */ { 5, 27 },
+
+/* 144: 4, 7, */ { 2, 9 },
+
+/* 145: 0, 4, 7, */ { 5, 8 },
+
+/* 146: 1, 4, 7, */ { 6, 13 },
+
+/* 147: 0, 1, 4, 7, */ { 14, 2 },
+
+/* 148: 2, 4, 7, */ { 6, 20 },
+
+/* 149: 0, 2, 4, 7, */ { 12, 6 },
+
+/* 150: 1, 2, 4, 7, */ { 10, 3 },
+
+/* 151: 0, 1, 2, 4, 7, */ { 6, 25 },
+
+/* 152: 3, 4, 7, */ { 5, 18 },
+
+/* 153: 0, 3, 4, 7, */ { 8, 2 },
+
+/* 154: 1, 3, 4, 7, */ { 12, 16 },
+
+/* 155: 0, 1, 3, 4, 7, */ { 5, 31 },
+
+/* 156: 2, 3, 4, 7, */ { 11, 9 },
+
+/* 157: 0, 2, 3, 4, 7, */ { 5, 34 },
+
+/* 158: 1, 2, 3, 4, 7, */ { 6, 40 },
+
+/* 159: 0, 1, 2, 3, 4, 7, */ { 2, 13 },
+
+/* 160: 5, 7, */ { 3, 11 },
+
+/* 161: 0, 5, 7, */ { 7, 2 },
+
+/* 162: 1, 5, 7, */ { 6, 14 },
+
+/* 163: 0, 1, 5, 7, */ { 12, 3 },
+
+/* 164: 2, 5, 7, */ { 7, 6 },
+
+/* 165: 0, 2, 5, 7, */ { 13, 0 },
+
+/* 166: 1, 2, 5, 7, */ { 12, 14 },
+
+/* 167: 0, 1, 2, 5, 7, */ { 7, 8 },
+
+/* 168: 3, 5, 7, */ { 6, 23 },
+
+/* 169: 0, 3, 5, 7, */ { 12, 10 },
+
+/* 170: 1, 3, 5, 7, */ { 10, 4 },
+
+/* 171: 0, 1, 3, 5, 7, */ { 6, 28 },
+
+/* 172: 2, 3, 5, 7, */ { 12, 21 },
+
+/* 173: 0, 2, 3, 5, 7, */ { 7, 10 },
+
+/* 174: 1, 2, 3, 5, 7, */ { 6, 41 },
+
+/* 175: 0, 1, 2, 3, 5, 7, */ { 3, 13 },
+
+/* 176: 4, 5, 7, */ { 5, 21 },
+
+/* 177: 0, 4, 5, 7, */ { 9, 3 },
+
+/* 178: 1, 4, 5, 7, */ { 11, 8 },
+
+/* 179: 0, 1, 4, 5, 7, */ { 5, 33 },
+
+/* 180: 2, 4, 5, 7, */ { 12, 22 },
+
+/* 181: 0, 2, 4, 5, 7, */ { 7, 11 },
+
+/* 182: 1, 2, 4, 5, 7, */ { 6, 42 },
+
+/* 183: 0, 1, 2, 4, 5, 7, */ { 3, 14 },
+
+/* 184: 3, 4, 5, 7, */ { 14, 11 },
+
+/* 185: 0, 3, 4, 5, 7, */ { 5, 36 },
+
+/* 186: 1, 3, 4, 5, 7, */ { 6, 44 },
+
+/* 187: 0, 1, 3, 4, 5, 7, */ { 2, 17 },
+
+/* 188: 2, 3, 4, 5, 7, */ { 6, 47 },
+
+/* 189: 0, 2, 3, 4, 5, 7, */ { 3, 18 },
+
+/* 190: 1, 2, 3, 4, 5, 7, */ { 4, 7 },
+
+/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 1, 9 },
+
+/* 192: 6, 7, */ { 2, 11 },
+
+/* 193: 0, 6, 7, */ { 6, 8 },
+
+/* 194: 1, 6, 7, */ { 6, 15 },
+
+/* 195: 0, 1, 6, 7, */ { 10, 0 },
+
+/* 196: 2, 6, 7, */ { 5, 17 },
+
+/* 197: 0, 2, 6, 7, */ { 12, 8 },
+
+/* 198: 1, 2, 6, 7, */ { 11, 7 },
+
+/* 199: 0, 1, 2, 6, 7, */ { 6, 26 },
+
+/* 200: 3, 6, 7, */ { 5, 19 },
+
+/* 201: 0, 3, 6, 7, */ { 14, 4 },
+
+/* 202: 1, 3, 6, 7, */ { 12, 18 },
+
+/* 203: 0, 1, 3, 6, 7, */ { 6, 29 },
+
+/* 204: 2, 3, 6, 7, */ { 8, 4 },
+
+/* 205: 0, 2, 3, 6, 7, */ { 5, 35 },
+
+/* 206: 1, 2, 3, 6, 7, */ { 5, 40 },
+
+/* 207: 0, 1, 2, 3, 6, 7, */ { 2, 15 },
+
+/* 208: 4, 6, 7, */ { 5, 22 },
+
+/* 209: 0, 4, 6, 7, */ { 11, 5 },
+
+/* 210: 1, 4, 6, 7, */ { 12, 19 },
+
+/* 211: 0, 1, 4, 6, 7, */ { 6, 30 },
+
+/* 212: 2, 4, 6, 7, */ { 14, 10 },
+
+/* 213: 0, 2, 4, 6, 7, */ { 6, 36 },
+
+/* 214: 1, 2, 4, 6, 7, */ { 6, 43 },
+
+/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 4 },
+
+/* 216: 3, 4, 6, 7, */ { 9, 7 },
+
+/* 217: 0, 3, 4, 6, 7, */ { 5, 37 },
+
+/* 218: 1, 3, 4, 6, 7, */ { 7, 15 },
+
+/* 219: 0, 1, 3, 4, 6, 7, */ { 3, 17 },
+
+/* 220: 2, 3, 4, 6, 7, */ { 5, 44 },
+
+/* 221: 0, 2, 3, 4, 6, 7, */ { 2, 19 },
+
+/* 222: 1, 2, 3, 4, 6, 7, */ { 3, 22 },
+
+/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 1, 10 },
+
+/* 224: 5, 6, 7, */ { 5, 23 },
+
+/* 225: 0, 5, 6, 7, */ { 12, 11 },
+
+/* 226: 1, 5, 6, 7, */ { 14, 8 },
+
+/* 227: 0, 1, 5, 6, 7, */ { 6, 31 },
+
+/* 228: 2, 5, 6, 7, */ { 9, 6 },
+
+/* 229: 0, 2, 5, 6, 7, */ { 7, 12 },
+
+/* 230: 1, 2, 5, 6, 7, */ { 5, 42 },
+
+/* 231: 0, 1, 2, 5, 6, 7, */ { 3, 15 },
+
+/* 232: 3, 5, 6, 7, */ { 11, 11 },
+
+/* 233: 0, 3, 5, 6, 7, */ { 6, 38 },
+
+/* 234: 1, 3, 5, 6, 7, */ { 6, 45 },
+
+/* 235: 0, 1, 3, 5, 6, 7, */ { 4, 5 },
+
+/* 236: 2, 3, 5, 6, 7, */ { 5, 45 },
+
+/* 237: 0, 2, 3, 5, 6, 7, */ { 3, 19 },
+
+/* 238: 1, 2, 3, 5, 6, 7, */ { 2, 21 },
+
+/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 1, 11 },
+
+/* 240: 4, 5, 6, 7, */ { 8, 5 },
+
+/* 241: 0, 4, 5, 6, 7, */ { 5, 38 },
+
+/* 242: 1, 4, 5, 6, 7, */ { 5, 43 },
+
+/* 243: 0, 1, 4, 5, 6, 7, */ { 2, 18 },
+
+/* 244: 2, 4, 5, 6, 7, */ { 5, 46 },
+
+/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 20 },
+
+/* 246: 1, 2, 4, 5, 6, 7, */ { 2, 22 },
+
+/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 1, 12 },
+
+/* 248: 3, 4, 5, 6, 7, */ { 5, 47 },
+
+/* 249: 0, 3, 4, 5, 6, 7, */ { 2, 20 },
+
+/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 23 },
+
+/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 13 },
+
+/* 252: 2, 3, 4, 5, 6, 7, */ { 2, 23 },
+
+/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 1, 14 },
+
+/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 1, 15 },
+
+/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { 0, -1 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling1[16][3] = {
+
+/* 1: 0, */ { 0, 8, 3 },
+
+/* 2: 1, */ { 0, 1, 9 },
+
+/* 4: 2, */ { 1, 2, 10 },
+
+/* 8: 3, */ { 3, 11, 2 },
+
+/* 16: 4, */ { 4, 7, 8 },
+
+/* 32: 5, */ { 9, 5, 4 },
+
+/* 64: 6, */ { 10, 6, 5 },
+
+/* 128: 7, */ { 7, 6, 11 },
+
+/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6 },
+
+/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6 },
+
+/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5 },
+
+/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7 },
+
+/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11 },
+
+/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2 },
+
+/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1 },
+
+/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling2[24][6] = {
+
+/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1 },
+
+/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0 },
+
+/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4 },
+
+/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9 },
+
+/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0 },
+
+/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3 },
+
+/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1 },
+
+/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7 },
+
+/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9 },
+
+/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6 },
+
+/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10 },
+
+/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11 },
+
+/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5 },
+
+/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4 },
+
+/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8 },
+
+/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7 },
+
+/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2 },
+
+/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6 },
+
+/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10 },
+
+/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5 },
+
+/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2 },
+
+/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3 },
+
+/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11 },
+
+/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 3
+
+ * One face to test
+
+ * When the test on the specified face is positive : 4 first triangles
+
+ * When the test on the specified face is negative : 2 last triangles
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test3[24] = {
+
+/* 5: 0, 2, */ 5,
+
+/* 33: 0, 5, */ 1,
+
+/* 129: 0, 7, */ 4,
+
+/* 10: 1, 3, */ 5,
+
+/* 18: 1, 4, */ 1,
+
+/* 66: 1, 6, */ 2,
+
+/* 36: 2, 5, */ 2,
+
+/* 132: 2, 7, */ 3,
+
+/* 24: 3, 4, */ 4,
+
+/* 72: 3, 6, */ 3,
+
+/* 80: 4, 6, */ 6,
+
+/* 160: 5, 7, */ 6,
+
+/* 95: 0, 1, 2, 3, 4, 6, */ -6,
+
+/* 175: 0, 1, 2, 3, 5, 7, */ -6,
+
+/* 183: 0, 1, 2, 4, 5, 7, */ -3,
+
+/* 231: 0, 1, 2, 5, 6, 7, */ -4,
+
+/* 123: 0, 1, 3, 4, 5, 6, */ -3,
+
+/* 219: 0, 1, 3, 4, 6, 7, */ -2,
+
+/* 189: 0, 2, 3, 4, 5, 7, */ -2,
+
+/* 237: 0, 2, 3, 5, 6, 7, */ -1,
+
+/* 245: 0, 2, 4, 5, 6, 7, */ -5,
+
+/* 126: 1, 2, 3, 4, 5, 6, */ -4,
+
+/* 222: 1, 2, 3, 4, 6, 7, */ -1,
+
+/* 250: 1, 3, 4, 5, 6, 7, */ -5
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 3.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling3_1[24][6] = {
+
+/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10 },
+
+/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3 },
+
+/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6 },
+
+/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11 },
+
+/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7 },
+
+/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6 },
+
+/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4 },
+
+/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7 },
+
+/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2 },
+
+/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5 },
+
+/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8 },
+
+/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11 },
+
+/* 95: 0, 1, 2, 3, 4, 6, */ { 5, 9, 4, 11, 6, 7 },
+
+/* 175: 0, 1, 2, 3, 5, 7, */ { 6, 10, 5, 8, 7, 4 },
+
+/* 183: 0, 1, 2, 4, 5, 7, */ { 11, 3, 2, 5, 6, 10 },
+
+/* 231: 0, 1, 2, 5, 6, 7, */ { 7, 4, 8, 2, 11, 3 },
+
+/* 123: 0, 1, 3, 4, 5, 6, */ { 2, 1, 10, 7, 11, 6 },
+
+/* 219: 0, 1, 3, 4, 6, 7, */ { 10, 2, 1, 4, 5, 9 },
+
+/* 189: 0, 2, 3, 4, 5, 7, */ { 1, 0, 9, 6, 10, 5 },
+
+/* 237: 0, 2, 3, 5, 6, 7, */ { 9, 1, 0, 7, 4, 8 },
+
+/* 245: 0, 2, 4, 5, 6, 7, */ { 0, 9, 1, 11, 3, 2 },
+
+/* 126: 1, 2, 3, 4, 5, 6, */ { 8, 0, 3, 6, 7, 11 },
+
+/* 222: 1, 2, 3, 4, 6, 7, */ { 4, 5, 9, 3, 8, 0 },
+
+/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 8, 0, 10, 2, 1 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 3.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling3_2[24][12] = {
+
+/* 5: 0, 2, */ { 10, 3, 2, 10, 8, 3, 10, 1, 0, 8, 10, 0 },
+
+/* 33: 0, 5, */ { 3, 4, 8, 3, 5, 4, 3, 0, 9, 5, 3, 9 },
+
+/* 129: 0, 7, */ { 6, 8, 7, 6, 0, 8, 6, 11, 3, 0, 6, 3 },
+
+/* 10: 1, 3, */ { 11, 0, 3, 11, 9, 0, 11, 2, 1, 9, 11, 1 },
+
+/* 18: 1, 4, */ { 7, 9, 4, 7, 1, 9, 7, 8, 0, 1, 7, 0 },
+
+/* 66: 1, 6, */ { 6, 1, 10, 6, 0, 1, 9, 0, 6, 9, 6, 5 },
+
+/* 36: 2, 5, */ { 4, 10, 5, 4, 2, 10, 4, 9, 1, 2, 4, 1 },
+
+/* 132: 2, 7, */ { 7, 2, 11, 7, 1, 2, 7, 6, 10, 1, 7, 10 },
+
+/* 24: 3, 4, */ { 2, 7, 11, 2, 4, 7, 2, 3, 8, 4, 2, 8 },
+
+/* 72: 3, 6, */ { 5, 11, 6, 5, 3, 11, 5, 10, 2, 3, 5, 2 },
+
+/* 80: 4, 6, */ { 8, 6, 7, 8, 10, 6, 8, 4, 5, 10, 8, 5 },
+
+/* 160: 5, 7, */ { 11, 5, 6, 11, 9, 5, 11, 7, 4, 9, 11, 4 },
+
+/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 11, 5, 9, 11, 4, 7, 11, 4, 11, 9 },
+
+/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 8, 6, 10, 8, 5, 4, 8, 5, 8, 10 },
+
+/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 5, 11, 3, 5, 2, 10, 5, 2, 5, 3 },
+
+/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 2, 7, 4, 2, 8, 3, 2, 8, 2, 4 },
+
+/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 7, 2, 1, 7, 10, 6, 7, 10, 7, 1 },
+
+/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 4, 10, 2, 4, 1, 9, 4, 1, 4, 2 },
+
+/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 6, 1, 0, 6, 6, 0, 9, 5, 6, 9 },
+
+/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 7, 9, 1, 7, 0, 8, 7, 0, 7, 1 },
+
+/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 11, 0, 9, 11, 1, 2, 11, 1, 11, 9 },
+
+/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 6, 8, 0, 6, 3, 11, 6, 3, 6, 0 },
+
+/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 3, 4, 5, 3, 9, 0, 3, 9, 3, 5 },
+
+/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 10, 3, 8, 10, 0, 1, 10, 0, 10, 8 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 4
+
+ * Interior to test
+
+ * When the test on the interior is negative : 2 first triangles
+
+ * When the test on the interior is positive : 6 last triangles
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test4[8] = {
+
+/* 65: 0, 6, */ 7,
+
+/* 130: 1, 7, */ 7,
+
+/* 20: 2, 4, */ 7,
+
+/* 40: 3, 5, */ 7,
+
+/* 215: 0, 1, 2, 4, 6, 7, */ -7,
+
+/* 235: 0, 1, 3, 5, 6, 7, */ -7,
+
+/* 125: 0, 2, 3, 4, 5, 6, */ -7,
+
+/* 190: 1, 2, 3, 4, 5, 7, */ -7
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 4.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling4_1[8][6] = {
+
+/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6 },
+
+/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6 },
+
+/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7 },
+
+/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11 },
+
+/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 5, 9, 11, 3, 2 },
+
+/* 235: 0, 1, 3, 5, 6, 7, */ { 10, 2, 1, 7, 4, 8 },
+
+/* 125: 0, 2, 3, 4, 5, 6, */ { 9, 1, 0, 6, 7, 11 },
+
+/* 190: 1, 2, 3, 4, 5, 7, */ { 3, 8, 0, 6, 10, 5 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 4.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling4_2[8][18] = {
+
+/* 65: 0, 6, */ { 8, 5, 0, 5, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 5 },
+
+/* 130: 1, 7, */ { 9, 6, 1, 6, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 6 },
+
+/* 20: 2, 4, */ { 10, 7, 2, 7, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 7 },
+
+/* 40: 3, 5, */ { 11, 4, 3, 4, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 4 },
+
+/* 215: 0, 1, 2, 4, 6, 7, */ { 3, 4, 11, 5, 11, 4, 11, 5, 2, 9, 2, 5, 2, 9, 3, 4, 3, 9 },
+
+/* 235: 0, 1, 3, 5, 6, 7, */ { 2, 7, 10, 4, 10, 7, 10, 4, 1, 8, 1, 4, 1, 8, 2, 7, 2, 8 },
+
+/* 125: 0, 2, 3, 4, 5, 6, */ { 1, 6, 9, 7, 9, 6, 9, 7, 0, 11, 0, 7, 0, 11, 1, 6, 1, 11 },
+
+/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 5, 8, 6, 8, 5, 8, 6, 3, 10, 3, 6, 3, 10, 0, 5, 0, 10 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 5
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling5[48][9] = {
+
+/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8 },
+
+/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11 },
+
+/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1 },
+
+/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5 },
+
+/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10 },
+
+/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4 },
+
+/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0 },
+
+/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3 },
+
+/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6 },
+
+/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9 },
+
+/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2 },
+
+/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6 },
+
+/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7 },
+
+/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0 },
+
+/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3 },
+
+/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7 },
+
+/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4 },
+
+/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1 },
+
+/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2 },
+
+/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5 },
+
+/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10 },
+
+/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9 },
+
+/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8 },
+
+/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11 },
+
+/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10 },
+
+/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11 },
+
+/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8 },
+
+/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9 },
+
+/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7 },
+
+/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6 },
+
+/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5 },
+
+/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6 },
+
+/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3 },
+
+/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1 },
+
+/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4 },
+
+/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5 },
+
+/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2 },
+
+/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0 },
+
+/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10 },
+
+/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4 },
+
+/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7 },
+
+/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2 },
+
+/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0 },
+
+/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11 },
+
+/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1 },
+
+/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3 },
+
+/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8 },
+
+/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 6
+
+ * 1 face to test + eventually the interior
+
+ * When the test on the specified face is positive : 5 first triangles
+
+ * When the test on the specified face is negative :
+
+ * - if the test on the interior is negative : 3 middle triangles
+
+ * - if the test on the interior is positive : 8 last triangles
+
+ * The support edge for the interior test is marked as the 3rd column.
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test6[48][3] = {
+
+/* 67: 0, 1, 6, */ { 2, 7, 10 },
+
+/* 131: 0, 1, 7, */ { 4, 7, 11 },
+
+/* 21: 0, 2, 4, */ { 5, 7, 1 },
+
+/* 69: 0, 2, 6, */ { 5, 7, 3 },
+
+/* 41: 0, 3, 5, */ { 1, 7, 9 },
+
+/* 73: 0, 3, 6, */ { 3, 7, 10 },
+
+/* 81: 0, 4, 6, */ { 6, 7, 5 },
+
+/* 97: 0, 5, 6, */ { 1, 7, 8 },
+
+/* 193: 0, 6, 7, */ { 4, 7, 8 },
+
+/* 22: 1, 2, 4, */ { 1, 7, 8 },
+
+/* 134: 1, 2, 7, */ { 3, 7, 11 },
+
+/* 42: 1, 3, 5, */ { 5, 7, 2 },
+
+/* 138: 1, 3, 7, */ { 5, 7, 0 },
+
+/* 146: 1, 4, 7, */ { 1, 7, 9 },
+
+/* 162: 1, 5, 7, */ { 6, 7, 6 },
+
+/* 194: 1, 6, 7, */ { 2, 7, 9 },
+
+/* 28: 2, 3, 4, */ { 4, 7, 8 },
+
+/* 44: 2, 3, 5, */ { 2, 7, 9 },
+
+/* 52: 2, 4, 5, */ { 2, 7, 10 },
+
+/* 84: 2, 4, 6, */ { 6, 7, 7 },
+
+/* 148: 2, 4, 7, */ { 3, 7, 10 },
+
+/* 56: 3, 4, 5, */ { 4, 7, 11 },
+
+/* 104: 3, 5, 6, */ { 3, 7, 11 },
+
+/* 168: 3, 5, 7, */ { 6, 7, 4 },
+
+/* 87: 0, 1, 2, 4, 6, */ { -6, -7, 4 },
+
+/* 151: 0, 1, 2, 4, 7, */ { -3, -7, 11 },
+
+/* 199: 0, 1, 2, 6, 7, */ { -4, -7, 11 },
+
+/* 107: 0, 1, 3, 5, 6, */ { -3, -7, 10 },
+
+/* 171: 0, 1, 3, 5, 7, */ { -6, -7, 7 },
+
+/* 203: 0, 1, 3, 6, 7, */ { -2, -7, 10 },
+
+/* 211: 0, 1, 4, 6, 7, */ { -2, -7, 9 },
+
+/* 227: 0, 1, 5, 6, 7, */ { -4, -7, 8 },
+
+/* 61: 0, 2, 3, 4, 5, */ { -2, -7, 9 },
+
+/* 93: 0, 2, 3, 4, 6, */ { -6, -7, 6 },
+
+/* 109: 0, 2, 3, 5, 6, */ { -1, -7, 9 },
+
+/* 117: 0, 2, 4, 5, 6, */ { -5, -7, 0 },
+
+/* 213: 0, 2, 4, 6, 7, */ { -5, -7, 2 },
+
+/* 121: 0, 3, 4, 5, 6, */ { -3, -7, 11 },
+
+/* 233: 0, 3, 5, 6, 7, */ { -1, -7, 8 },
+
+/* 62: 1, 2, 3, 4, 5, */ { -4, -7, 8 },
+
+/* 158: 1, 2, 3, 4, 7, */ { -1, -7, 8 },
+
+/* 174: 1, 2, 3, 5, 7, */ { -6, -7, 5 },
+
+/* 182: 1, 2, 4, 5, 7, */ { -3, -7, 10 },
+
+/* 214: 1, 2, 4, 6, 7, */ { -1, -7, 9 },
+
+/* 186: 1, 3, 4, 5, 7, */ { -5, -7, 3 },
+
+/* 234: 1, 3, 5, 6, 7, */ { -5, -7, 1 },
+
+/* 124: 2, 3, 4, 5, 6, */ { -4, -7, 11 },
+
+/* 188: 2, 3, 4, 5, 7, */ { -2, -7, 10 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 6.1.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling6_1_1[48][9] = {
+
+/* 67: 0, 1, 6, */ { 6, 5, 10, 3, 1, 8, 9, 8, 1 },
+
+/* 131: 0, 1, 7, */ { 11, 7, 6, 9, 3, 1, 3, 9, 8 },
+
+/* 21: 0, 2, 4, */ { 1, 2, 10, 7, 0, 4, 0, 7, 3 },
+
+/* 69: 0, 2, 6, */ { 3, 0, 8, 5, 2, 6, 2, 5, 1 },
+
+/* 41: 0, 3, 5, */ { 5, 4, 9, 2, 0, 11, 8, 11, 0 },
+
+/* 73: 0, 3, 6, */ { 10, 6, 5, 8, 2, 0, 2, 8, 11 },
+
+/* 81: 0, 4, 6, */ { 10, 6, 5, 0, 4, 3, 7, 3, 4 },
+
+/* 97: 0, 5, 6, */ { 3, 0, 8, 6, 4, 10, 9, 10, 4 },
+
+/* 193: 0, 6, 7, */ { 8, 3, 0, 10, 7, 5, 7, 10, 11 },
+
+/* 22: 1, 2, 4, */ { 8, 4, 7, 10, 0, 2, 0, 10, 9 },
+
+/* 134: 1, 2, 7, */ { 7, 6, 11, 0, 2, 9, 10, 9, 2 },
+
+/* 42: 1, 3, 5, */ { 2, 3, 11, 4, 1, 5, 1, 4, 0 },
+
+/* 138: 1, 3, 7, */ { 0, 1, 9, 6, 3, 7, 3, 6, 2 },
+
+/* 146: 1, 4, 7, */ { 9, 0, 1, 11, 4, 6, 4, 11, 8 },
+
+/* 162: 1, 5, 7, */ { 11, 7, 6, 1, 5, 0, 4, 0, 5 },
+
+/* 194: 1, 6, 7, */ { 0, 1, 9, 7, 5, 11, 10, 11, 5 },
+
+/* 28: 2, 3, 4, */ { 4, 7, 8, 1, 3, 10, 11, 10, 3 },
+
+/* 44: 2, 3, 5, */ { 9, 5, 4, 11, 1, 3, 1, 11, 10 },
+
+/* 52: 2, 4, 5, */ { 10, 1, 2, 8, 5, 7, 5, 8, 9 },
+
+/* 84: 2, 4, 6, */ { 8, 4, 7, 2, 6, 1, 5, 1, 6 },
+
+/* 148: 2, 4, 7, */ { 1, 2, 10, 4, 6, 8, 11, 8, 6 },
+
+/* 56: 3, 4, 5, */ { 2, 3, 11, 5, 7, 9, 8, 9, 7 },
+
+/* 104: 3, 5, 6, */ { 11, 2, 3, 9, 6, 4, 6, 9, 10 },
+
+/* 168: 3, 5, 7, */ { 9, 5, 4, 3, 7, 2, 6, 2, 7 },
+
+/* 87: 0, 1, 2, 4, 6, */ { 4, 5, 9, 2, 7, 3, 7, 2, 6 },
+
+/* 151: 0, 1, 2, 4, 7, */ { 3, 2, 11, 4, 6, 9, 10, 9, 6 },
+
+/* 199: 0, 1, 2, 6, 7, */ { 11, 3, 2, 9, 7, 5, 7, 9, 8 },
+
+/* 107: 0, 1, 3, 5, 6, */ { 10, 2, 1, 8, 6, 4, 6, 8, 11 },
+
+/* 171: 0, 1, 3, 5, 7, */ { 7, 4, 8, 1, 6, 2, 6, 1, 5 },
+
+/* 203: 0, 1, 3, 6, 7, */ { 2, 1, 10, 7, 5, 8, 9, 8, 5 },
+
+/* 211: 0, 1, 4, 6, 7, */ { 4, 5, 9, 3, 1, 11, 10, 11, 1 },
+
+/* 227: 0, 1, 5, 6, 7, */ { 8, 7, 4, 10, 3, 1, 3, 10, 11 },
+
+/* 61: 0, 2, 3, 4, 5, */ { 9, 1, 0, 11, 5, 7, 5, 11, 10 },
+
+/* 93: 0, 2, 3, 4, 6, */ { 6, 7, 11, 0, 5, 1, 5, 0, 4 },
+
+/* 109: 0, 2, 3, 5, 6, */ { 1, 0, 9, 6, 4, 11, 8, 11, 4 },
+
+/* 117: 0, 2, 4, 5, 6, */ { 9, 1, 0, 7, 3, 6, 2, 6, 3 },
+
+/* 213: 0, 2, 4, 6, 7, */ { 11, 3, 2, 5, 1, 4, 0, 4, 1 },
+
+/* 121: 0, 3, 4, 5, 6, */ { 11, 6, 7, 9, 2, 0, 2, 9, 10 },
+
+/* 233: 0, 3, 5, 6, 7, */ { 7, 4, 8, 2, 0, 10, 9, 10, 0 },
+
+/* 62: 1, 2, 3, 4, 5, */ { 0, 3, 8, 5, 7, 10, 11, 10, 7 },
+
+/* 158: 1, 2, 3, 4, 7, */ { 8, 0, 3, 10, 4, 6, 4, 10, 9 },
+
+/* 174: 1, 2, 3, 5, 7, */ { 5, 6, 10, 3, 4, 0, 4, 3, 7 },
+
+/* 182: 1, 2, 4, 5, 7, */ { 5, 6, 10, 0, 2, 8, 11, 8, 2 },
+
+/* 214: 1, 2, 4, 6, 7, */ { 9, 4, 5, 11, 0, 2, 0, 11, 8 },
+
+/* 186: 1, 3, 4, 5, 7, */ { 8, 0, 3, 6, 2, 5, 1, 5, 2 },
+
+/* 234: 1, 3, 5, 6, 7, */ { 10, 2, 1, 4, 0, 7, 3, 7, 0 },
+
+/* 124: 2, 3, 4, 5, 6, */ { 6, 7, 11, 1, 3, 9, 8, 9, 3 },
+
+/* 188: 2, 3, 4, 5, 7, */ { 10, 5, 6, 8, 1, 3, 1, 8, 9 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 6.1.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling6_1_2[48][21] = {
+
+/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5 },
+
+/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9, 7, 8, 3, 7, 3, 11 },
+
+/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1 },
+
+/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3 },
+
+/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4 },
+
+/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8, 6, 11, 2, 6, 2, 10 },
+
+/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6 },
+
+/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9, 4, 9, 0, 8, 4, 0 },
+
+/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8 },
+
+/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10, 4, 9, 0, 4, 0, 8 },
+
+/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6 },
+
+/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2 },
+
+/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0 },
+
+/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9 },
+
+/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7 },
+
+/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10, 5, 10, 1, 9, 5, 1 },
+
+/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7 },
+
+/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11, 5, 10, 1, 5, 1, 9 },
+
+/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10 },
+
+/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4 },
+
+/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11, 6, 11, 2, 10, 6, 2 },
+
+/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8, 7, 8, 3, 11, 7, 3 },
+
+/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11 },
+
+/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5 },
+
+/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2, 5, 6, 7, 5, 7, 4 },
+
+/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10, 6, 10, 2, 11, 6, 2 },
+
+/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9, 3, 8, 7, 3, 7, 11 },
+
+/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8, 2, 11, 6, 2, 6, 10 },
+
+/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1, 4, 5, 6, 4, 6, 7 },
+
+/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9, 5, 9, 1, 10, 5, 1 },
+
+/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10, 1, 10, 5, 9, 1, 5 },
+
+/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10, 7, 11, 3, 7, 3, 8 },
+
+/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11, 1, 10, 5, 1, 5, 9 },
+
+/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0, 7, 4, 5, 7, 5, 6 },
+
+/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8, 4, 8, 0, 9, 4, 0 },
+
+/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2, 3, 2, 1, 0, 3, 1 },
+
+/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0, 1, 0, 3, 2, 1, 3 },
+
+/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9, 6, 10, 2, 6, 2, 11 },
+
+/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9, 0, 9, 4, 8, 0, 4 },
+
+/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11, 7, 11, 3, 8, 7, 3 },
+
+/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10, 0, 9, 4, 0, 4, 8 },
+
+/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3, 6, 7, 4, 6, 4, 5 },
+
+/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11, 2, 11, 6, 10, 2, 6 },
+
+/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11, 4, 8, 0, 4, 0, 9 },
+
+/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1, 2, 1, 0, 3, 2, 0 },
+
+/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3, 0, 3, 2, 1, 0, 2 },
+
+/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8, 3, 8, 7, 11, 3, 7 },
+
+/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8, 5, 9, 1, 5, 1, 10 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 6.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling6_2[48][15] = {
+
+/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9 },
+
+/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9 },
+
+/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7 },
+
+/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5 },
+
+/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8 },
+
+/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8 },
+
+/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7 },
+
+/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9 },
+
+/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10 },
+
+/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10 },
+
+/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10 },
+
+/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4 },
+
+/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6 },
+
+/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11 },
+
+/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4 },
+
+/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10 },
+
+/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11 },
+
+/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11 },
+
+/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8 },
+
+/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5 },
+
+/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11 },
+
+/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8 },
+
+/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9 },
+
+/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6 },
+
+/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2 },
+
+/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10 },
+
+/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9 },
+
+/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8 },
+
+/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1 },
+
+/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9 },
+
+/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10 },
+
+/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10 },
+
+/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11 },
+
+/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0 },
+
+/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8 },
+
+/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2 },
+
+/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0 },
+
+/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9 },
+
+/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9 },
+
+/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11 },
+
+/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10 },
+
+/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3 },
+
+/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11 },
+
+/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11 },
+
+/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1 },
+
+/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3 },
+
+/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8 },
+
+/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 7
+
+ * 3 faces to test + eventually the interior
+
+ * When the tests on the 3 specified faces are positive :
+
+ * - if the test on the interior is positive : 5 first triangles
+
+ * - if the test on the interior is negative : 9 next triangles
+
+ * When the tests on the first && the second specified faces are positive : 9 next triangles
+
+ * When the tests on the first && the third specified faces are positive : 9 next triangles
+
+ * When the tests on the second && the third specified faces are positive : 9 next triangles
+
+ * When the test on the first specified face is positive : 5 next triangles
+
+ * When the test on the second specified face is positive : 5 next triangles
+
+ * When the test on the third specified face is positive : 5 next triangles
+
+ * When the tests on the 3 specified faces are negative : 3 last triangles
+
+ * The support edge for the interior test is marked as the 5th column.
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test7[16][5] = {
+
+/* 37: 0, 2, 5, */ { 1, 2, 5, 7, 1 },
+
+/* 133: 0, 2, 7, */ { 3, 4, 5, 7, 3 },
+
+/* 161: 0, 5, 7, */ { 4, 1, 6, 7, 4 },
+
+/* 26: 1, 3, 4, */ { 4, 1, 5, 7, 0 },
+
+/* 74: 1, 3, 6, */ { 2, 3, 5, 7, 2 },
+
+/* 82: 1, 4, 6, */ { 1, 2, 6, 7, 5 },
+
+/* 164: 2, 5, 7, */ { 2, 3, 6, 7, 6 },
+
+/* 88: 3, 4, 6, */ { 3, 4, 6, 7, 7 },
+
+/* 167: 0, 1, 2, 5, 7, */ { -3, -4, -6, -7, 7 },
+
+/* 91: 0, 1, 3, 4, 6, */ { -2, -3, -6, -7, 6 },
+
+/* 173: 0, 2, 3, 5, 7, */ { -1, -2, -6, -7, 5 },
+
+/* 181: 0, 2, 4, 5, 7, */ { -2, -3, -5, -7, 2 },
+
+/* 229: 0, 2, 5, 6, 7, */ { -4, -1, -5, -7, 0 },
+
+/* 94: 1, 2, 3, 4, 6, */ { -4, -1, -6, -7, 4 },
+
+/* 122: 1, 3, 4, 5, 6, */ { -3, -4, -5, -7, 3 },
+
+/* 218: 1, 3, 4, 6, 7, */ { -1, -2, -5, -7, 1 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 7.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling7_1[16][9] = {
+
+/* 37: 0, 2, 5, */ { 9, 5, 4, 10, 1, 2, 8, 3, 0 },
+
+/* 133: 0, 2, 7, */ { 11, 7, 6, 8, 3, 0, 10, 1, 2 },
+
+/* 161: 0, 5, 7, */ { 3, 0, 8, 5, 4, 9, 7, 6, 11 },
+
+/* 26: 1, 3, 4, */ { 8, 4, 7, 9, 0, 1, 11, 2, 3 },
+
+/* 74: 1, 3, 6, */ { 10, 6, 5, 11, 2, 3, 9, 0, 1 },
+
+/* 82: 1, 4, 6, */ { 0, 1, 9, 6, 5, 10, 4, 7, 8 },
+
+/* 164: 2, 5, 7, */ { 1, 2, 10, 7, 6, 11, 5, 4, 9 },
+
+/* 88: 3, 4, 6, */ { 2, 3, 11, 4, 7, 8, 6, 5, 10 },
+
+/* 167: 0, 1, 2, 5, 7, */ { 11, 3, 2, 8, 7, 4, 10, 5, 6 },
+
+/* 91: 0, 1, 3, 4, 6, */ { 10, 2, 1, 11, 6, 7, 9, 4, 5 },
+
+/* 173: 0, 2, 3, 5, 7, */ { 9, 1, 0, 10, 5, 6, 8, 7, 4 },
+
+/* 181: 0, 2, 4, 5, 7, */ { 5, 6, 10, 3, 2, 11, 1, 0, 9 },
+
+/* 229: 0, 2, 5, 6, 7, */ { 7, 4, 8, 1, 0, 9, 3, 2, 11 },
+
+/* 94: 1, 2, 3, 4, 6, */ { 8, 0, 3, 9, 4, 5, 11, 6, 7 },
+
+/* 122: 1, 3, 4, 5, 6, */ { 6, 7, 11, 0, 3, 8, 2, 1, 10 },
+
+/* 218: 1, 3, 4, 6, 7, */ { 4, 5, 9, 2, 1, 10, 0, 3, 8 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 7.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling7_2[16][3][15] = {
+
+/* 37: 0, 2, 5, */ {
+
+ /* 1,0 */ { 1, 2, 10, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 },
+
+ /* 0,1 */ { 3, 0, 8, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 },
+
+ /* 1,1 */ { 9, 5, 4, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 }
+
+},
+
+/* 133: 0, 2, 7, */ {
+
+ /* 1,0 */ { 3, 0, 8, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 },
+
+ /* 0,1 */ { 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 },
+
+ /* 1,1 */ { 11, 7, 6, 2, 8, 3, 8, 2, 10, 8, 10, 0, 1, 0, 10 }
+
+},
+
+/* 161: 0, 5, 7, */ {
+
+ /* 1,0 */ { 9, 5, 4, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 },
+
+ /* 0,1 */ { 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 },
+
+ /* 1,1 */ { 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 }
+
+},
+
+/* 26: 1, 3, 4, */ {
+
+ /* 1,0 */ { 0, 1, 9, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 },
+
+ /* 0,1 */ { 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 },
+
+ /* 1,1 */ { 8, 4, 7, 3, 9, 0, 9, 3, 11, 9, 11, 1, 2, 1, 11 }
+
+},
+
+/* 74: 1, 3, 6, */ {
+
+ /* 1,0 */ { 2, 3, 11, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 },
+
+ /* 0,1 */ { 0, 1, 9, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 },
+
+ /* 1,1 */ { 6, 5, 10, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 }
+
+},
+
+/* 82: 1, 4, 6, */ {
+
+ /* 1,0 */ { 6, 5, 10, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 },
+
+ /* 0,1 */ { 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 },
+
+ /* 1,1 */ { 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 }
+
+},
+
+/* 164: 2, 5, 7, */ {
+
+ /* 1,0 */ { 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 },
+
+ /* 0,1 */ { 9, 5, 4, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 },
+
+ /* 1,1 */ { 1, 2, 10, 6, 11, 5, 9, 5, 11, 7, 9, 11, 9, 7, 4 }
+
+},
+
+/* 88: 3, 4, 6, */ {
+
+ /* 1,0 */ { 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 },
+
+ /* 0,1 */ { 6, 5, 10, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 },
+
+ /* 1,1 */ { 2, 3, 11, 7, 8, 6, 10, 6, 8, 4, 10, 8, 10, 4, 5 }
+
+},
+
+/* 167: 0, 1, 2, 5, 7, */ {
+
+ /* 1,0 */ { 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 },
+
+ /* 0,1 */ { 10, 5, 6, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 },
+
+ /* 1,1 */ { 11, 3, 2, 6, 8, 7, 8, 6, 10, 8, 10, 4, 5, 4, 10 }
+
+},
+
+/* 91: 0, 1, 3, 4, 6, */ {
+
+ /* 1,0 */ { 6, 7, 11, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 },
+
+ /* 0,1 */ { 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 },
+
+ /* 1,1 */ { 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 }
+
+},
+
+/* 173: 0, 2, 3, 5, 7, */ {
+
+ /* 1,0 */ { 10, 5, 6, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 },
+
+ /* 0,1 */ { 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 },
+
+ /* 1,1 */ { 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 }
+
+},
+
+/* 181: 0, 2, 4, 5, 7, */ {
+
+ /* 1,0 */ { 11, 3, 2, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 },
+
+ /* 0,1 */ { 9, 1, 0, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 },
+
+ /* 1,1 */ { 10, 5, 6, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 }
+
+},
+
+/* 229: 0, 2, 5, 6, 7, */ {
+
+ /* 1,0 */ { 9, 1, 0, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 },
+
+ /* 0,1 */ { 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 },
+
+ /* 1,1 */ { 7, 4, 8, 0, 9, 3, 11, 3, 9, 1, 11, 9, 11, 1, 2 }
+
+},
+
+/* 94: 1, 2, 3, 4, 6, */ {
+
+ /* 1,0 */ { 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 },
+
+ /* 0,1 */ { 6, 7, 11, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 },
+
+ /* 1,1 */ { 8, 0, 3, 7, 9, 4, 9, 7, 11, 9, 11, 5, 6, 5, 11 }
+
+},
+
+/* 122: 1, 3, 4, 5, 6, */ {
+
+ /* 1,0 */ { 8, 0, 3, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 },
+
+ /* 0,1 */ { 10, 2, 1, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 },
+
+ /* 1,1 */ { 6, 7, 11, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 }
+
+},
+
+/* 218: 1, 3, 4, 6, 7, */ {
+
+ /* 1,0 */ { 10, 2, 1, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 },
+
+ /* 0,1 */ { 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 },
+
+ /* 1,1 */ { 4, 5, 9, 1, 10, 0, 8, 0, 10, 2, 8, 10, 8, 2, 3 } }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 7.3
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling7_3[16][3][27] = {
+
+/* 37: 0, 2, 5, */ {
+
+ /* 1,0 */ { 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 },
+
+ /* 0,1 */ { 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 },
+
+ /* 1,1 */ { 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }
+
+},
+
+/* 133: 0, 2, 7, */ {
+
+ /* 1,0 */ { 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 },
+
+ /* 0,1 */ { 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 },
+
+ /* 1,1 */ { 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }
+
+},
+
+/* 161: 0, 5, 7, */ {
+
+ /* 1,0 */ { 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 },
+
+ /* 0,1 */ { 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 },
+
+ /* 1,1 */ { 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }
+
+},
+
+/* 26: 1, 3, 4, */ {
+
+ /* 1,0 */ { 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 },
+
+ /* 0,1 */ { 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 },
+
+ /* 1,1 */ { 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 }
+
+},
+
+/* 74: 1, 3, 6, */ {
+
+ /* 1,0 */ { 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 },
+
+ /* 0,1 */ { 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 },
+
+ /* 1,1 */ { 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 }
+
+},
+
+/* 82: 1, 4, 6, */ {
+
+ /* 1,0 */ { 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 },
+
+ /* 0,1 */ { 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 },
+
+ /* 1,1 */ { 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }
+
+},
+
+/* 164: 2, 5, 7, */ {
+
+ /* 1,0 */ { 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 },
+
+ /* 0,1 */ { 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 },
+
+ /* 1,1 */ { 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }
+
+},
+
+/* 88: 3, 4, 6, */ {
+
+ /* 1,0 */ { 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 },
+
+ /* 0,1 */ { 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 },
+
+ /* 1,1 */ { 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }
+
+},
+
+/* 167: 0, 1, 2, 5, 7, */ {
+
+ /* 1,0 */ { 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 },
+
+ /* 0,1 */ { 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 },
+
+ /* 1,1 */ { 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 }
+
+},
+
+/* 91: 0, 1, 3, 4, 6, */ {
+
+ /* 1,0 */ { 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7 },
+
+ /* 0,1 */ { 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 },
+
+ /* 1,1 */ { 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }
+
+},
+
+/* 173: 0, 2, 3, 5, 7, */ {
+
+ /* 1,0 */ { 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6 },
+
+ /* 0,1 */ { 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 },
+
+ /* 1,1 */ { 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }
+
+},
+
+/* 181: 0, 2, 4, 5, 7, */ {
+
+ /* 1,0 */ { 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 },
+
+ /* 0,1 */ { 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 },
+
+ /* 1,1 */ { 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 }
+
+},
+
+/* 229: 0, 2, 5, 6, 7, */ {
+
+ /* 1,0 */ { 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 },
+
+ /* 0,1 */ { 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 },
+
+ /* 1,1 */ { 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 }
+
+},
+
+/* 94: 1, 2, 3, 4, 6, */ {
+
+ /* 1,0 */ { 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 },
+
+ /* 0,1 */ { 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 },
+
+ /* 1,1 */ { 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 }
+
+},
+
+/* 122: 1, 3, 4, 5, 6, */ {
+
+ /* 1,0 */ { 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 },
+
+ /* 0,1 */ { 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 },
+
+ /* 1,1 */ { 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }
+
+},
+
+/* 218: 1, 3, 4, 6, 7, */ {
+
+ /* 1,0 */ { 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 },
+
+ /* 0,1 */ { 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 },
+
+ /* 1,1 */ { 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 } }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 7.4.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling7_4_1[16][15] = {
+
+/* 37: 0, 2, 5, */ { 3, 4, 8, 4, 3, 10, 2, 10, 3, 4, 10, 5, 9, 1, 0 },
+
+/* 133: 0, 2, 7, */ { 1, 6, 10, 6, 1, 8, 0, 8, 1, 6, 8, 7, 11, 3, 2 },
+
+/* 161: 0, 5, 7, */ { 11, 3, 6, 9, 6, 3, 6, 9, 5, 0, 9, 3, 7, 4, 8 },
+
+/* 26: 1, 3, 4, */ { 2, 7, 11, 7, 2, 9, 1, 9, 2, 7, 9, 4, 8, 0, 3 },
+
+/* 74: 1, 3, 6, */ { 0, 5, 9, 5, 0, 11, 3, 11, 0, 5, 11, 6, 10, 2, 1 },
+
+/* 82: 1, 4, 6, */ { 8, 0, 7, 10, 7, 0, 7, 10, 6, 1, 10, 0, 4, 5, 9 },
+
+/* 164: 2, 5, 7, */ { 9, 1, 4, 11, 4, 1, 4, 11, 7, 2, 11, 1, 5, 6, 10 },
+
+/* 88: 3, 4, 6, */ { 10, 2, 5, 8, 5, 2, 5, 8, 4, 3, 8, 2, 6, 7, 11 },
+
+/* 167: 0, 1, 2, 5, 7, */ { 5, 2, 10, 2, 5, 8, 4, 8, 5, 2, 8, 3, 11, 7, 6 },
+
+/* 91: 0, 1, 3, 4, 6, */ { 4, 1, 9, 1, 4, 11, 7, 11, 4, 1, 11, 2, 10, 6, 5 },
+
+/* 173: 0, 2, 3, 5, 7, */ { 7, 0, 8, 0, 7, 10, 6, 10, 7, 0, 10, 1, 9, 5, 4 },
+
+/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 0, 11, 0, 5, 0, 11, 3, 6, 11, 5, 1, 2, 10 },
+
+/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 2, 9, 2, 7, 2, 9, 1, 4, 9, 7, 3, 0, 8 },
+
+/* 94: 1, 2, 3, 4, 6, */ { 6, 3, 11, 3, 6, 9, 5, 9, 6, 3, 9, 0, 8, 4, 7 },
+
+/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 1, 8, 1, 6, 1, 8, 0, 7, 8, 6, 2, 3, 11 },
+
+/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 3, 10, 3, 4, 3, 10, 2, 5, 10, 4, 0, 1, 9 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 7.4.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling7_4_2[16][27] = {
+
+/* 37: 0, 2, 5, */ { 9, 4, 8, 4, 9, 5, 10, 5, 9, 1, 10, 9, 10, 1, 2, 0, 2, 1, 2, 0, 3, 8, 3, 0, 9, 8, 0 },
+
+/* 133: 0, 2, 7, */ { 11, 6, 10, 6, 11, 7, 8, 7, 11, 3, 8, 11, 8, 3, 0, 2, 0, 3, 0, 2, 1, 10, 1, 2, 11, 10, 2 },
+
+/* 161: 0, 5, 7, */ { 11, 3, 8, 0, 8, 3, 8, 0, 9, 8, 9, 4, 5, 4, 9, 4, 5, 7, 6, 7, 5, 7, 6, 11, 7, 11, 8 },
+
+/* 26: 1, 3, 4, */ { 8, 7, 11, 7, 8, 4, 9, 4, 8, 0, 9, 8, 9, 0, 1, 3, 1, 0, 1, 3, 2, 11, 2, 3, 8, 11, 3 },
+
+/* 74: 1, 3, 6, */ { 10, 5, 9, 5, 10, 6, 11, 6, 10, 2, 11, 10, 11, 2, 3, 1, 3, 2, 3, 1, 0, 9, 0, 1, 10, 9, 1 },
+
+/* 82: 1, 4, 6, */ { 8, 0, 9, 1, 9, 0, 9, 1, 10, 9, 10, 5, 6, 5, 10, 5, 6, 4, 7, 4, 6, 4, 7, 8, 4, 8, 9 },
+
+/* 164: 2, 5, 7, */ { 9, 1, 10, 2, 10, 1, 10, 2, 11, 10, 11, 6, 7, 6, 11, 6, 7, 5, 4, 5, 7, 5, 4, 9, 5, 9, 10 },
+
+/* 88: 3, 4, 6, */ { 10, 2, 11, 3, 11, 2, 11, 3, 8, 11, 8, 7, 4, 7, 8, 7, 4, 6, 5, 6, 4, 6, 5, 10, 6, 10, 11 },
+
+/* 167: 0, 1, 2, 5, 7, */ { 11, 2, 10, 2, 11, 3, 8, 3, 11, 7, 8, 11, 8, 7, 4, 6, 4, 7, 4, 6, 5, 10, 5, 6, 11, 10, 6 },
+
+/* 91: 0, 1, 3, 4, 6, */ { 10, 1, 9, 1, 10, 2, 11, 2, 10, 6, 11, 10, 11, 6, 7, 5, 7, 6, 7, 5, 4, 9, 4, 5, 10, 9, 5 },
+
+/* 173: 0, 2, 3, 5, 7, */ { 9, 0, 8, 0, 9, 1, 10, 1, 9, 5, 10, 9, 10, 5, 6, 4, 6, 5, 6, 4, 7, 8, 7, 4, 9, 8, 4 },
+
+/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 10, 6, 10, 5, 10, 6, 11, 10, 11, 2, 3, 2, 11, 2, 3, 1, 0, 1, 3, 1, 0, 9, 1, 9, 10 },
+
+/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 8, 4, 8, 7, 8, 4, 9, 8, 9, 0, 1, 0, 9, 0, 1, 3, 2, 3, 1, 3, 2, 11, 3, 11, 8 },
+
+/* 94: 1, 2, 3, 4, 6, */ { 8, 3, 11, 3, 8, 0, 9, 0, 8, 4, 9, 8, 9, 4, 5, 7, 5, 4, 5, 7, 6, 11, 6, 7, 8, 11, 7 },
+
+/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 11, 7, 11, 6, 11, 7, 8, 11, 8, 3, 0, 3, 8, 3, 0, 2, 1, 2, 0, 2, 1, 10, 2, 10, 11 },
+
+/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 9, 5, 9, 4, 9, 5, 10, 9, 10, 1, 2, 1, 10, 1, 2, 0, 3, 0, 2, 0, 3, 8, 0, 8, 9 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 8
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling8[6][6] = {
+
+/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11 },
+
+/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7 },
+
+/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2 },
+
+/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6 },
+
+/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5 },
+
+/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 9
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling9[8][12] = {
+
+/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8 },
+
+/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1 },
+
+/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8 },
+
+/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5 },
+
+/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9 },
+
+/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0 },
+
+/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2 },
+
+/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 10
+
+ * 2 faces to test + eventually the interior
+
+ * When the tests on both specified faces are positive : 4 middle triangles (1)
+
+ * When the test on the first specified face is positive : 8 first triangles
+
+ * When the test on the second specified face is positive : 8 next triangles
+
+ * When the tests on both specified faces are negative :
+
+ * - if the test on the interior is negative : 4 middle triangles
+
+ * - if the test on the interior is positive : 8 last triangles
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test10[6][3] = {
+
+/* 195: 0, 1, 6, 7, */ { 2, 4, 7 },
+
+/* 85: 0, 2, 4, 6, */ { 5, 6, 7 },
+
+/* 105: 0, 3, 5, 6, */ { 1, 3, 7 },
+
+/* 150: 1, 2, 4, 7, */ { 1, 3, 7 },
+
+/* 170: 1, 3, 5, 7, */ { 5, 6, 7 },
+
+/* 60: 2, 3, 4, 5, */ { 2, 4, 7 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 10.1.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling10_1_1[6][12] = {
+
+/* 195: 0, 1, 6, 7, */ { 5, 10, 7, 11, 7, 10, 8, 1, 9, 1, 8, 3 },
+
+/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 6, 5, 2, 4, 3, 0, 3, 4, 7 },
+
+/* 105: 0, 3, 5, 6, */ { 11, 0, 8, 0, 11, 2, 4, 9, 6, 10, 6, 9 },
+
+/* 150: 1, 2, 4, 7, */ { 9, 0, 10, 2, 10, 0, 6, 8, 4, 8, 6, 11 },
+
+/* 170: 1, 3, 5, 7, */ { 7, 2, 3, 2, 7, 6, 0, 1, 4, 5, 4, 1 },
+
+/* 60: 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 8, 10, 1, 11, 3, 11, 1 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 10.1.1 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling10_1_1_[6][12] = {
+
+/* 195: 0, 1, 6, 7, */ { 5, 9, 7, 8, 7, 9, 11, 1, 10, 1, 11, 3 },
+
+/* 85: 0, 2, 4, 6, */ { 3, 2, 7, 6, 7, 2, 4, 1, 0, 1, 4, 5 },
+
+/* 105: 0, 3, 5, 6, */ { 10, 0, 9, 0, 10, 2, 4, 8, 6, 11, 6, 8 },
+
+/* 150: 1, 2, 4, 7, */ { 8, 0, 11, 2, 11, 0, 6, 9, 4, 9, 6, 10 },
+
+/* 170: 1, 3, 5, 7, */ { 5, 2, 1, 2, 5, 6, 0, 3, 4, 7, 4, 3 },
+
+/* 60: 2, 3, 4, 5, */ { 7, 10, 5, 10, 7, 11, 9, 1, 8, 3, 8, 1 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 10.1.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling10_1_2[6][24] = {
+
+/* 195: 0, 1, 6, 7, */ { 3, 11, 7, 3, 7, 8, 9, 8, 7, 5, 9, 7, 9, 5, 10, 9, 10, 1, 3, 1, 10, 11, 3, 10 },
+
+/* 85: 0, 2, 4, 6, */ { 7, 6, 5, 7, 5, 4, 0, 4, 5, 1, 0, 5, 0, 1, 2, 0, 2, 3, 7, 3, 2, 6, 7, 2 },
+
+/* 105: 0, 3, 5, 6, */ { 11, 2, 10, 6, 11, 10, 11, 6, 4, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 10, 0, 10, 2 },
+
+/* 150: 1, 2, 4, 7, */ { 11, 2, 10, 11, 10, 6, 4, 6, 10, 9, 4, 10, 4, 9, 0, 4, 0, 8, 11, 8, 0, 2, 11, 0 },
+
+/* 170: 1, 3, 5, 7, */ { 7, 6, 5, 4, 7, 5, 7, 4, 0, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 5, 2, 5, 6 },
+
+/* 60: 2, 3, 4, 5, */ { 7, 8, 3, 11, 7, 3, 7, 11, 10, 7, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 3, 9, 3, 8 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 10.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling10_2[6][24] = {
+
+/* 195: 0, 1, 6, 7, */ { 12, 5, 9, 12, 9, 8, 12, 8, 3, 12, 3, 1, 12, 1, 10, 12, 10, 11, 12, 11, 7, 12, 7, 5 },
+
+/* 85: 0, 2, 4, 6, */ { 12, 1, 0, 12, 0, 4, 12, 4, 7, 12, 7, 3, 12, 3, 2, 12, 2, 6, 12, 6, 5, 12, 5, 1 },
+
+/* 105: 0, 3, 5, 6, */ { 4, 8, 12, 6, 4, 12, 10, 6, 12, 9, 10, 12, 0, 9, 12, 2, 0, 12, 11, 2, 12, 8, 11, 12 },
+
+/* 150: 1, 2, 4, 7, */ { 12, 9, 4, 12, 4, 6, 12, 6, 11, 12, 11, 8, 12, 8, 0, 12, 0, 2, 12, 2, 10, 12, 10, 9 },
+
+/* 170: 1, 3, 5, 7, */ { 0, 3, 12, 4, 0, 12, 5, 4, 12, 1, 5, 12, 2, 1, 12, 6, 2, 12, 7, 6, 12, 3, 7, 12 },
+
+/* 60: 2, 3, 4, 5, */ { 10, 5, 12, 11, 10, 12, 3, 11, 12, 1, 3, 12, 9, 1, 12, 8, 9, 12, 7, 8, 12, 5, 7, 12 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 10.2 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling10_2_[6][24] = {
+
+/* 195: 0, 1, 6, 7, */ { 8, 7, 12, 9, 8, 12, 1, 9, 12, 3, 1, 12, 11, 3, 12, 10, 11, 12, 5, 10, 12, 7, 5, 12 },
+
+/* 85: 0, 2, 4, 6, */ { 4, 5, 12, 0, 4, 12, 3, 0, 12, 7, 3, 12, 6, 7, 12, 2, 6, 12, 1, 2, 12, 5, 1, 12 },
+
+/* 105: 0, 3, 5, 6, */ { 12, 11, 6, 12, 6, 4, 12, 4, 9, 12, 9, 10, 12, 10, 2, 12, 2, 0, 12, 0, 8, 12, 8, 11 },
+
+/* 150: 1, 2, 4, 7, */ { 6, 10, 12, 4, 6, 12, 8, 4, 12, 11, 8, 12, 2, 11, 12, 0, 2, 12, 9, 0, 12, 10, 9, 12 },
+
+/* 170: 1, 3, 5, 7, */ { 12, 7, 4, 12, 4, 0, 12, 0, 1, 12, 1, 5, 12, 5, 6, 12, 6, 2, 12, 2, 3, 12, 3, 7 },
+
+/* 60: 2, 3, 4, 5, */ { 12, 7, 11, 12, 11, 10, 12, 10, 1, 12, 1, 3, 12, 3, 8, 12, 8, 9, 12, 9, 5, 12, 5, 7 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 11
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling11[12][12] = {
+
+/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4 },
+
+/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6 },
+
+/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10 },
+
+/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6 },
+
+/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11 },
+
+/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0 },
+
+/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3 },
+
+/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7 },
+
+/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11 },
+
+/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1 },
+
+/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7 },
+
+/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 12
+
+ * 2 faces to test + eventually the interior
+
+ * When the tests on both specified faces are positive : 4 middle triangles (1)
+
+ * When the test on the first specified face is positive : 8 first triangles
+
+ * When the test on the second specified face is positive : 8 next triangles
+
+ * When the tests on both specified faces are negative :
+
+ * - if the test on the interior is negative : 4 middle triangles
+
+ * - if the test on the interior is positive : 8 last triangles
+
+ * The support edge for the interior test is marked as the 4th column.
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char test12[24][4] = {
+
+/* 135: 0, 1, 2, 7, */ { 4, 3, 7, 11 },
+
+/* 75: 0, 1, 3, 6, */ { 3, 2, 7, 10 },
+
+/* 83: 0, 1, 4, 6, */ { 2, 6, 7, 5 },
+
+/* 163: 0, 1, 5, 7, */ { 6, 4, 7, 7 },
+
+/* 45: 0, 2, 3, 5, */ { 2, 1, 7, 9 },
+
+/* 53: 0, 2, 4, 5, */ { 5, 2, 7, 1 },
+
+/* 149: 0, 2, 4, 7, */ { 5, 3, 7, 2 },
+
+/* 101: 0, 2, 5, 6, */ { 5, 1, 7, 0 },
+
+/* 197: 0, 2, 6, 7, */ { 5, 4, 7, 3 },
+
+/* 89: 0, 3, 4, 6, */ { 6, 3, 7, 6 },
+
+/* 169: 0, 3, 5, 7, */ { 1, 6, 7, 4 },
+
+/* 225: 0, 5, 6, 7, */ { 1, 4, 7, 8 },
+
+/* 30: 1, 2, 3, 4, */ { 4, 1, 7, 8 },
+
+/* 86: 1, 2, 4, 6, */ { 6, 1, 7, 4 },
+
+/* 166: 1, 2, 5, 7, */ { 3, 6, 7, 6 },
+
+/* 58: 1, 3, 4, 5, */ { 4, 5, 7, 3 },
+
+/* 154: 1, 3, 4, 7, */ { 1, 5, 7, 0 },
+
+/* 106: 1, 3, 5, 6, */ { 3, 5, 7, 2 },
+
+/* 202: 1, 3, 6, 7, */ { 2, 5, 7, 1 },
+
+/* 210: 1, 4, 6, 7, */ { 1, 2, 7, 9 },
+
+/* 92: 2, 3, 4, 6, */ { 4, 6, 7, 7 },
+
+/* 172: 2, 3, 5, 7, */ { 6, 2, 7, 5 },
+
+/* 180: 2, 4, 5, 7, */ { 2, 3, 7, 10 },
+
+/* 120: 3, 4, 5, 6, */ { 3, 4, 7, 11 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 12.1.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling12_1_1[24][12] = {
+
+/* 135: 0, 1, 2, 7, */ { 7, 6, 11, 10, 3, 2, 3, 10, 8, 9, 8, 10 },
+
+/* 75: 0, 1, 3, 6, */ { 6, 5, 10, 9, 2, 1, 2, 9, 11, 8, 11, 9 },
+
+/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 7, 9, 4, 9, 7, 1, 3, 1, 7 },
+
+/* 163: 0, 1, 5, 7, */ { 7, 6, 11, 4, 8, 5, 3, 5, 8, 5, 3, 1 },
+
+/* 45: 0, 2, 3, 5, */ { 5, 4, 9, 8, 1, 0, 1, 8, 10, 11, 10, 8 },
+
+/* 53: 0, 2, 4, 5, */ { 1, 2, 10, 0, 9, 3, 5, 3, 9, 3, 5, 7 },
+
+/* 149: 0, 2, 4, 7, */ { 10, 1, 2, 0, 11, 3, 11, 0, 6, 4, 6, 0 },
+
+/* 101: 0, 2, 5, 6, */ { 8, 3, 0, 2, 9, 1, 9, 2, 4, 6, 4, 2 },
+
+/* 197: 0, 2, 6, 7, */ { 3, 0, 8, 2, 11, 1, 7, 1, 11, 1, 7, 5 },
+
+/* 89: 0, 3, 4, 6, */ { 6, 5, 10, 7, 11, 4, 2, 4, 11, 4, 2, 0 },
+
+/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 6, 8, 7, 8, 6, 0, 2, 0, 6 },
+
+/* 225: 0, 5, 6, 7, */ { 8, 3, 0, 7, 4, 11, 9, 11, 4, 11, 9, 10 },
+
+/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 11, 0, 3, 0, 11, 9, 10, 9, 11 },
+
+/* 86: 1, 2, 4, 6, */ { 4, 7, 8, 5, 9, 6, 0, 6, 9, 6, 0, 2 },
+
+/* 166: 1, 2, 5, 7, */ { 11, 7, 6, 4, 10, 5, 10, 4, 2, 0, 2, 4 },
+
+/* 58: 1, 3, 4, 5, */ { 11, 2, 3, 1, 8, 0, 8, 1, 7, 5, 7, 1 },
+
+/* 154: 1, 3, 4, 7, */ { 0, 1, 9, 3, 8, 2, 4, 2, 8, 2, 4, 6 },
+
+/* 106: 1, 3, 5, 6, */ { 2, 3, 11, 1, 10, 0, 6, 0, 10, 0, 6, 4 },
+
+/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 3, 10, 2, 10, 3, 5, 7, 5, 3 },
+
+/* 210: 1, 4, 6, 7, */ { 9, 0, 1, 4, 5, 8, 10, 8, 5, 8, 10, 11 },
+
+/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 5, 11, 6, 11, 5, 3, 1, 3, 5 },
+
+/* 172: 2, 3, 5, 7, */ { 5, 4, 9, 6, 10, 7, 1, 7, 10, 7, 1, 3 },
+
+/* 180: 2, 4, 5, 7, */ { 10, 1, 2, 5, 6, 9, 11, 9, 6, 9, 11, 8 },
+
+/* 120: 3, 4, 5, 6, */ { 11, 2, 3, 6, 7, 10, 8, 10, 7, 10, 8, 9 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 12.1.1 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling12_1_1_[24][12] = {
+
+/* 135: 0, 1, 2, 7, */ { 3, 2, 11, 10, 7, 6, 7, 10, 8, 9, 8, 10 },
+
+/* 75: 0, 1, 3, 6, */ { 2, 1, 10, 9, 6, 5, 6, 9, 11, 8, 11, 9 },
+
+/* 83: 0, 1, 4, 6, */ { 9, 4, 5, 7, 10, 6, 10, 7, 1, 3, 1, 7 },
+
+/* 163: 0, 1, 5, 7, */ { 7, 4, 8, 6, 11, 5, 3, 5, 11, 5, 3, 1 },
+
+/* 45: 0, 2, 3, 5, */ { 1, 0, 9, 8, 5, 4, 5, 8, 10, 11, 10, 8 },
+
+/* 53: 0, 2, 4, 5, */ { 1, 0, 9, 2, 10, 3, 5, 3, 10, 3, 5, 7 },
+
+/* 149: 0, 2, 4, 7, */ { 11, 3, 2, 0, 10, 1, 10, 0, 6, 4, 6, 0 },
+
+/* 101: 0, 2, 5, 6, */ { 9, 1, 0, 2, 8, 3, 8, 2, 4, 6, 4, 2 },
+
+/* 197: 0, 2, 6, 7, */ { 3, 2, 11, 0, 8, 1, 7, 1, 8, 1, 7, 5 },
+
+/* 89: 0, 3, 4, 6, */ { 6, 7, 11, 5, 10, 4, 2, 4, 10, 4, 2, 0 },
+
+/* 169: 0, 3, 5, 7, */ { 8, 7, 4, 6, 9, 5, 9, 6, 0, 2, 0, 6 },
+
+/* 225: 0, 5, 6, 7, */ { 8, 7, 4, 3, 0, 11, 9, 11, 0, 11, 9, 10 },
+
+/* 30: 1, 2, 3, 4, */ { 0, 3, 8, 11, 4, 7, 4, 11, 9, 10, 9, 11 },
+
+/* 86: 1, 2, 4, 6, */ { 4, 5, 9, 7, 8, 6, 0, 6, 8, 6, 0, 2 },
+
+/* 166: 1, 2, 5, 7, */ { 10, 5, 6, 4, 11, 7, 11, 4, 2, 0, 2, 4 },
+
+/* 58: 1, 3, 4, 5, */ { 8, 0, 3, 1, 11, 2, 11, 1, 7, 5, 7, 1 },
+
+/* 154: 1, 3, 4, 7, */ { 0, 3, 8, 1, 9, 2, 4, 2, 9, 2, 4, 6 },
+
+/* 106: 1, 3, 5, 6, */ { 2, 1, 10, 3, 11, 0, 6, 0, 11, 0, 6, 4 },
+
+/* 202: 1, 3, 6, 7, */ { 10, 2, 1, 3, 9, 0, 9, 3, 5, 7, 5, 3 },
+
+/* 210: 1, 4, 6, 7, */ { 9, 4, 5, 0, 1, 8, 10, 8, 1, 8, 10, 11 },
+
+/* 92: 2, 3, 4, 6, */ { 11, 6, 7, 5, 8, 4, 8, 5, 3, 1, 3, 5 },
+
+/* 172: 2, 3, 5, 7, */ { 5, 6, 10, 4, 9, 7, 1, 7, 9, 7, 1, 3 },
+
+/* 180: 2, 4, 5, 7, */ { 10, 5, 6, 1, 2, 9, 11, 9, 2, 9, 11, 8 },
+
+/* 120: 3, 4, 5, 6, */ { 11, 6, 7, 2, 3, 10, 8, 10, 3, 10, 8, 9 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 12.1.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling12_1_2[24][24] = {
+
+/* 135: 0, 1, 2, 7, */ { 7, 3, 11, 3, 7, 8, 9, 8, 7, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6, 2, 11, 3 },
+
+/* 75: 0, 1, 3, 6, */ { 6, 2, 10, 2, 6, 11, 8, 11, 6, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5, 1, 10, 2 },
+
+/* 83: 0, 1, 4, 6, */ { 10, 9, 5, 9, 10, 1, 3, 1, 10, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6, 4, 5, 9 },
+
+/* 163: 0, 1, 5, 7, */ { 7, 8, 11, 3, 11, 8, 11, 3, 1, 11, 1, 6, 5, 6, 1, 6, 5, 4, 6, 4, 7, 8, 7, 4 },
+
+/* 45: 0, 2, 3, 5, */ { 5, 1, 9, 1, 5, 10, 11, 10, 5, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 1 },
+
+/* 53: 0, 2, 4, 5, */ { 1, 9, 10, 5, 10, 9, 10, 5, 7, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1, 9, 1, 0 },
+
+/* 149: 0, 2, 4, 7, */ { 10, 11, 2, 11, 10, 6, 4, 6, 10, 1, 4, 10, 4, 1, 0, 3, 0, 1, 2, 3, 1, 3, 2, 11 },
+
+/* 101: 0, 2, 5, 6, */ { 8, 9, 0, 9, 8, 4, 6, 4, 8, 3, 6, 8, 6, 3, 2, 1, 2, 3, 0, 1, 3, 1, 0, 9 },
+
+/* 197: 0, 2, 6, 7, */ { 3, 11, 8, 7, 8, 11, 8, 7, 5, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3, 11, 3, 2 },
+
+/* 89: 0, 3, 4, 6, */ { 6, 11, 10, 2, 10, 11, 10, 2, 0, 10, 0, 5, 4, 5, 0, 5, 4, 7, 5, 7, 6, 11, 6, 7 },
+
+/* 169: 0, 3, 5, 7, */ { 9, 8, 4, 8, 9, 0, 2, 0, 9, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5, 7, 4, 8 },
+
+/* 225: 0, 5, 6, 7, */ { 8, 4, 0, 9, 0, 4, 0, 9, 10, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8, 4, 8, 7 },
+
+/* 30: 1, 2, 3, 4, */ { 4, 0, 8, 0, 4, 9, 10, 9, 4, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7, 3, 8, 0 },
+
+/* 86: 1, 2, 4, 6, */ { 4, 9, 8, 0, 8, 9, 8, 0, 2, 8, 2, 7, 6, 7, 2, 7, 6, 5, 7, 5, 4, 9, 4, 5 },
+
+/* 166: 1, 2, 5, 7, */ { 11, 10, 6, 10, 11, 2, 0, 2, 11, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7, 5, 6, 10 },
+
+/* 58: 1, 3, 4, 5, */ { 11, 8, 3, 8, 11, 7, 5, 7, 11, 2, 5, 11, 5, 2, 1, 0, 1, 2, 3, 0, 2, 0, 3, 8 },
+
+/* 154: 1, 3, 4, 7, */ { 0, 8, 9, 4, 9, 8, 9, 4, 6, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0, 8, 0, 3 },
+
+/* 106: 1, 3, 5, 6, */ { 2, 10, 11, 6, 11, 10, 11, 6, 4, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2, 10, 2, 1 },
+
+/* 202: 1, 3, 6, 7, */ { 9, 10, 1, 10, 9, 5, 7, 5, 9, 0, 7, 9, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 10 },
+
+/* 210: 1, 4, 6, 7, */ { 9, 5, 1, 10, 1, 5, 1, 10, 11, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9, 5, 9, 4 },
+
+/* 92: 2, 3, 4, 6, */ { 8, 11, 7, 11, 8, 3, 1, 3, 8, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4, 6, 7, 11 },
+
+/* 172: 2, 3, 5, 7, */ { 5, 10, 9, 1, 9, 10, 9, 1, 3, 9, 3, 4, 7, 4, 3, 4, 7, 6, 4, 6, 5, 10, 5, 6 },
+
+/* 180: 2, 4, 5, 7, */ { 10, 6, 2, 11, 2, 6, 2, 11, 8, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10, 6, 10, 5 },
+
+/* 120: 3, 4, 5, 6, */ { 11, 7, 3, 8, 3, 7, 3, 8, 9, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11, 7, 11, 6 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 12.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling12_2[24][24] = {
+
+/* 135: 0, 1, 2, 7, */ { 9, 8, 12, 10, 9, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12 },
+
+/* 75: 0, 1, 3, 6, */ { 8, 11, 12, 9, 8, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12 },
+
+/* 83: 0, 1, 4, 6, */ { 3, 1, 12, 7, 3, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 },
+
+/* 163: 0, 1, 5, 7, */ { 12, 3, 1, 12, 1, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 },
+
+/* 45: 0, 2, 3, 5, */ { 11, 10, 12, 8, 11, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12 },
+
+/* 53: 0, 2, 4, 5, */ { 12, 5, 7, 12, 7, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 },
+
+/* 149: 0, 2, 4, 7, */ { 4, 6, 12, 0, 4, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 },
+
+/* 101: 0, 2, 5, 6, */ { 6, 4, 12, 2, 6, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 },
+
+/* 197: 0, 2, 6, 7, */ { 12, 7, 5, 12, 5, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 },
+
+/* 89: 0, 3, 4, 6, */ { 12, 2, 0, 12, 0, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 },
+
+/* 169: 0, 3, 5, 7, */ { 2, 0, 12, 6, 2, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 },
+
+/* 225: 0, 5, 6, 7, */ { 12, 9, 10, 12, 10, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9 },
+
+/* 30: 1, 2, 3, 4, */ { 10, 9, 12, 11, 10, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12 },
+
+/* 86: 1, 2, 4, 6, */ { 12, 0, 2, 12, 2, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 },
+
+/* 166: 1, 2, 5, 7, */ { 0, 2, 12, 4, 0, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 },
+
+/* 58: 1, 3, 4, 5, */ { 5, 7, 12, 1, 5, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 },
+
+/* 154: 1, 3, 4, 7, */ { 12, 4, 6, 12, 6, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 },
+
+/* 106: 1, 3, 5, 6, */ { 12, 6, 4, 12, 4, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 },
+
+/* 202: 1, 3, 6, 7, */ { 7, 5, 12, 3, 7, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 },
+
+/* 210: 1, 4, 6, 7, */ { 12, 10, 11, 12, 11, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10 },
+
+/* 92: 2, 3, 4, 6, */ { 1, 3, 12, 5, 1, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 },
+
+/* 172: 2, 3, 5, 7, */ { 12, 1, 3, 12, 3, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 },
+
+/* 180: 2, 4, 5, 7, */ { 12, 11, 8, 12, 8, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11 },
+
+/* 120: 3, 4, 5, 6, */ { 12, 8, 9, 12, 9, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 12.2 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling12_2_[24][24] = {
+
+/* 135: 0, 1, 2, 7, */ { 12, 2, 11, 12, 11, 7, 12, 7, 6, 12, 6, 10, 12, 10, 9, 12, 9, 8, 12, 8, 3, 12, 3, 2 },
+
+/* 75: 0, 1, 3, 6, */ { 12, 1, 10, 12, 10, 6, 12, 6, 5, 12, 5, 9, 12, 9, 8, 12, 8, 11, 12, 11, 2, 12, 2, 1 },
+
+/* 83: 0, 1, 4, 6, */ { 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 3, 12, 3, 1, 12, 1, 9, 12, 9, 4 },
+
+/* 163: 0, 1, 5, 7, */ { 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 1, 5, 12, 3, 1, 12, 11, 3, 12, 6, 11, 12 },
+
+/* 45: 0, 2, 3, 5, */ { 12, 0, 9, 12, 9, 5, 12, 5, 4, 12, 4, 8, 12, 8, 11, 12, 11, 10, 12, 10, 1, 12, 1, 0 },
+
+/* 53: 0, 2, 4, 5, */ { 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 7, 3, 12, 5, 7, 12, 10, 5, 12, 2, 10, 12 },
+
+/* 149: 0, 2, 4, 7, */ { 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 4, 12, 4, 6, 12, 6, 10, 12, 10, 1 },
+
+/* 101: 0, 2, 5, 6, */ { 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 6, 12, 6, 4, 12, 4, 8, 12, 8, 3 },
+
+/* 197: 0, 2, 6, 7, */ { 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 5, 1, 12, 7, 5, 12, 8, 7, 12, 0, 8, 12 },
+
+/* 89: 0, 3, 4, 6, */ { 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 0, 4, 12, 2, 0, 12, 10, 2, 12, 5, 10, 12 },
+
+/* 169: 0, 3, 5, 7, */ { 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 2, 12, 2, 0, 12, 0, 8, 12, 8, 7 },
+
+/* 225: 0, 5, 6, 7, */ { 8, 7, 12, 0, 8, 12, 3, 0, 12, 11, 3, 12, 10, 11, 12, 9, 10, 12, 4, 9, 12, 7, 4, 12 },
+
+/* 30: 1, 2, 3, 4, */ { 12, 7, 8, 12, 8, 0, 12, 0, 3, 12, 3, 11, 12, 11, 10, 12, 10, 9, 12, 9, 4, 12, 4, 7 },
+
+/* 86: 1, 2, 4, 6, */ { 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 2, 6, 12, 0, 2, 12, 8, 0, 12, 7, 8, 12 },
+
+/* 166: 1, 2, 5, 7, */ { 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 0, 12, 0, 2, 12, 2, 10, 12, 10, 5 },
+
+/* 58: 1, 3, 4, 5, */ { 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 5, 12, 5, 7, 12, 7, 8, 12, 8, 0 },
+
+/* 154: 1, 3, 4, 7, */ { 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 6, 2, 12, 4, 6, 12, 8, 4, 12, 3, 8, 12 },
+
+/* 106: 1, 3, 5, 6, */ { 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 4, 0, 12, 6, 4, 12, 10, 6, 12, 1, 10, 12 },
+
+/* 202: 1, 3, 6, 7, */ { 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 7, 12, 7, 5, 12, 5, 10, 12, 10, 2 },
+
+/* 210: 1, 4, 6, 7, */ { 9, 0, 12, 5, 9, 12, 4, 5, 12, 8, 4, 12, 11, 8, 12, 10, 11, 12, 1, 10, 12, 0, 1, 12 },
+
+/* 92: 2, 3, 4, 6, */ { 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 1, 12, 1, 3, 12, 3, 11, 12, 11, 6 },
+
+/* 172: 2, 3, 5, 7, */ { 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 3, 7, 12, 1, 3, 12, 9, 1, 12, 4, 9, 12 },
+
+/* 180: 2, 4, 5, 7, */ { 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 8, 9, 12, 11, 8, 12, 2, 11, 12, 1, 2, 12 },
+
+/* 120: 3, 4, 5, 6, */ { 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 9, 10, 12, 8, 9, 12, 3, 8, 12, 2, 3, 12 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief test table for case 13
+
+ * All faces are to be tested
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13: face test */
+
+static const char test13[2][7] = {
+
+/* 165: 0, 2, 5, 7, */ { 1,2,3,4,5,6,7 },
+
+/* 90: 1, 3, 4, 6, */ { 2,3,4,1,5,6,7 },
+
+};
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief subconfiguration table for case 13
+
+ * Hard-coded tests for the subconfiguration determination
+
+ *
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13: sub configs */
+
+static const char subconfig13[64] = {
+
+/* 0: 0,0,0,0,0,0 */ 0,
+
+/* 1: 1,0,0,0,0,0 */ 1,
+
+/* 2: 0,1,0,0,0,0 */ 2,
+
+/* 3: 1,1,0,0,0,0 */ 7,
+
+/* 4: 0,0,1,0,0,0 */ 3,
+
+/* 5: 1,0,1,0,0,0 */ -1,
+
+/* 6: 0,1,1,0,0,0 */ 11,
+
+/* 7: 1,1,1,0,0,0 */ -1,
+
+/* 8: 0,0,0,1,0,0 */ 4,
+
+/* 9: 1,0,0,1,0,0 */ 8,
+
+/* 10: 0,1,0,1,0,0 */ -1,
+
+/* 11: 1,1,0,1,0,0 */ -1,
+
+/* 12: 0,0,1,1,0,0 */ 14,
+
+/* 13: 1,0,1,1,0,0 */ -1,
+
+/* 14: 0,1,1,1,0,0 */ -1,
+
+/* 15: 1,1,1,1,0,0 */ -1,
+
+/* 16: 0,0,0,0,1,0 */ 5,
+
+/* 17: 1,0,0,0,1,0 */ 9,
+
+/* 18: 0,1,0,0,1,0 */ 12,
+
+/* 19: 1,1,0,0,1,0 */ 23,
+
+/* 20: 0,0,1,0,1,0 */ 15,
+
+/* 21: 1,0,1,0,1,0 */ -1,
+
+/* 22: 0,1,1,0,1,0 */ 21,
+
+/* 23: 1,1,1,0,1,0 */ 38,
+
+/* 24: 0,0,0,1,1,0 */ 17,
+
+/* 25: 1,0,0,1,1,0 */ 20,
+
+/* 26: 0,1,0,1,1,0 */ -1,
+
+/* 27: 1,1,0,1,1,0 */ 36,
+
+/* 28: 0,0,1,1,1,0 */ 26,
+
+/* 29: 1,0,1,1,1,0 */ 33,
+
+/* 30: 0,1,1,1,1,0 */ 30,
+
+/* 31: 1,1,1,1,1,0 */ 44,
+
+/* 32: 0,0,0,0,0,1 */ 6,
+
+/* 33: 1,0,0,0,0,1 */ 10,
+
+/* 34: 0,1,0,0,0,1 */ 13,
+
+/* 35: 1,1,0,0,0,1 */ 19,
+
+/* 36: 0,0,1,0,0,1 */ 16,
+
+/* 37: 1,0,1,0,0,1 */ -1,
+
+/* 38: 0,1,1,0,0,1 */ 25,
+
+/* 39: 1,1,1,0,0,1 */ 37,
+
+/* 40: 0,0,0,1,0,1 */ 18,
+
+/* 41: 1,0,0,1,0,1 */ 24,
+
+/* 42: 0,1,0,1,0,1 */ -1,
+
+/* 43: 1,1,0,1,0,1 */ 35,
+
+/* 44: 0,0,1,1,0,1 */ 22,
+
+/* 45: 1,0,1,1,0,1 */ 32,
+
+/* 46: 0,1,1,1,0,1 */ 29,
+
+/* 47: 1,1,1,1,0,1 */ 43,
+
+/* 48: 0,0,0,0,1,1 */ -1,
+
+/* 49: 1,0,0,0,1,1 */ -1,
+
+/* 50: 0,1,0,0,1,1 */ -1,
+
+/* 51: 1,1,0,0,1,1 */ 34,
+
+/* 52: 0,0,1,0,1,1 */ -1,
+
+/* 53: 1,0,1,0,1,1 */ -1,
+
+/* 54: 0,1,1,0,1,1 */ 28,
+
+/* 55: 1,1,1,0,1,1 */ 42,
+
+/* 56: 0,0,0,1,1,1 */ -1,
+
+/* 57: 1,0,0,1,1,1 */ 31,
+
+/* 58: 0,1,0,1,1,1 */ -1,
+
+/* 59: 1,1,0,1,1,1 */ 41,
+
+/* 60: 0,0,1,1,1,1 */ 27,
+
+/* 61: 1,0,1,1,1,1 */ 40,
+
+/* 62: 0,1,1,1,1,1 */ 39,
+
+/* 63: 1,1,1,1,1,1 */ 45,
+
+};
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.1
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.1 */
+
+static const char tiling13_1[2][12] = {
+
+/* 165: 0, 2, 5, 7, */ { 11, 7, 6, 1, 2, 10, 8, 3, 0, 9, 5, 4 },
+
+/* 90: 1, 3, 4, 6, */ { 8, 4, 7, 2, 3, 11, 9, 0, 1, 10, 6, 5 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.1 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.1 */
+
+static const char tiling13_1_[2][12] = {
+
+/* 165: 0, 2, 5, 7, */ { 7, 4, 8, 11, 3, 2, 1, 0, 9, 5, 6, 10 },
+
+/* 90: 1, 3, 4, 6, */ { 6, 7, 11, 10, 2, 1, 0, 3, 8, 4, 5, 9 }
+
+};
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.2 */
+
+static const char tiling13_2[2][6][18] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+ /* 1 */ { 1, 2, 10, 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 },
+
+ /* 2 */ { 8, 3, 0, 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 },
+
+ /* 3 */ { 9, 5, 4, 8, 3, 0, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 },
+
+ /* 4 */ { 9, 5, 4, 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 },
+
+ /* 5 */ { 9, 5, 4, 11, 7, 6, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 },
+
+ /* 6 */ { 1, 2, 10, 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+ /* 1 */ { 2, 3, 11, 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 },
+
+ /* 2 */ { 9, 0, 1, 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 },
+
+ /* 3 */ { 6, 5, 10, 9, 0, 1, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 },
+
+ /* 4 */ { 6, 5, 10, 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 },
+
+ /* 5 */ { 6, 5, 10, 8, 4, 7, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 },
+
+ /* 6 */ { 2, 3, 11, 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.2 inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.2 */
+
+static const char tiling13_2_[2][6][18] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+ /* 1 */ { 10, 5, 6, 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 },
+
+ /* 2 */ { 11, 3, 2, 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 },
+
+ /* 3 */ { 1, 0, 9, 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 },
+
+ /* 4 */ { 10, 5, 6, 1, 0, 9, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 },
+
+ /* 5 */ { 10, 5, 6, 7, 4, 8, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 },
+
+ /* 6 */ { 11, 3, 2, 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+ /* 1 */ { 6, 7, 11, 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 },
+
+ /* 2 */ { 8, 0, 3, 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 },
+
+ /* 3 */ { 2, 1, 10, 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 },
+
+ /* 4 */ { 6, 7, 11, 2, 1, 10, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 },
+
+ /* 5 */ { 6, 7, 11, 4, 5, 9, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 },
+
+ /* 6 */ { 8, 0, 3, 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.3
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.3 */
+
+static const char tiling13_3[2][12][30] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+ /* 1,2 */ { 11, 7, 6, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 },
+
+ /* 1,4 */ { 1, 2, 10, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 },
+
+ /* 1,5 */ { 11, 7, 6, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 },
+
+ /* 1,6 */ { 1, 2, 10, 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 },
+
+ /* 2,3 */ { 8, 3, 0, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 },
+
+ /* 2,5 */ { 11, 7, 6, 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 },
+
+ /* 2,6 */ { 8, 3, 0, 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 },
+
+ /* 3,4 */ { 9, 5, 4, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 },
+
+ /* 3,5 */ { 9, 5, 4, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 },
+
+ /* 3,6 */ { 8, 3, 0, 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 },
+
+ /* 4,5 */ { 9, 5, 4, 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 },
+
+ /* 4,6 */ { 1, 2, 10, 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+ /* 1,2 */ { 8, 4, 7, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 },
+
+ /* 1,4 */ { 2, 3, 11, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 },
+
+ /* 1,5 */ { 8, 4, 7, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 },
+
+ /* 1,6 */ { 2, 3, 11, 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 },
+
+ /* 2,3 */ { 0, 1, 9, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 },
+
+ /* 2,5 */ { 8, 4, 7, 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 },
+
+ /* 2,6 */ { 9, 0, 1, 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 },
+
+ /* 3,4 */ { 6, 5, 10, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 },
+
+ /* 3,5 */ { 6, 5, 10, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 },
+
+ /* 3,6 */ { 9, 0, 1, 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 },
+
+ /* 4,5 */ { 6, 5, 10, 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 },
+
+ /* 4,6 */ { 2, 3, 11, 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.3, inverted
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.3 */
+
+static const char tiling13_3_[2][12][30] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+ /* 1,2 */ { 3, 2, 11, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12 },
+
+ /* 1,4 */ { 5, 6, 10, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2 },
+
+ /* 1,5 */ { 10, 5, 6, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 },
+
+ /* 1,6 */ { 11, 3, 2, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 },
+
+ /* 2,3 */ { 7, 4, 8, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 },
+
+ /* 2,5 */ { 7, 4, 8, 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 },
+
+ /* 2,6 */ { 11, 3, 2, 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 },
+
+ /* 3,4 */ { 1, 0, 9, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 },
+
+ /* 3,5 */ { 7, 4, 8, 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 },
+
+ /* 3,6 */ { 1, 0, 9, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 },
+
+ /* 4,5 */ { 10, 5, 6, 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 },
+
+ /* 4,6 */ { 9, 1, 0, 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+ /* 1,2 */ { 0, 3, 8, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12 },
+
+ /* 1,4 */ { 11, 6, 7, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3 },
+
+ /* 1,5 */ { 6, 7, 11, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 },
+
+ /* 1,6 */ { 8, 0, 3, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 },
+
+ /* 2,3 */ { 4, 5, 9, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 },
+
+ /* 2,5 */ { 4, 5, 9, 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 },
+
+ /* 2,6 */ { 8, 0, 3, 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 },
+
+ /* 3,4 */ { 2, 1, 10, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 },
+
+ /* 3,5 */ { 4, 5, 9, 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 },
+
+ /* 3,6 */ { 2, 1, 10, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 },
+
+ /* 4,5 */ { 6, 7, 11, 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 },
+
+ /* 4,6 */ { 10, 2, 1, 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.4
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.4 */
+
+static const char tiling13_4[2][4][36] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+/* 1,2,6 */ { 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 },
+
+/* 1,4,5 */ { 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 },
+
+/* 2,3,5 */ { 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 },
+
+/* 3,4,6 */ { 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+/* 1,2,6 */ { 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 },
+
+/* 1,4,5 */ { 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 },
+
+/* 2,3,5 */ { 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 },
+
+/* 3,4,6 */ { 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.5.1
+
+ * The support edge for the interior test is marked as the 1st column.
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.5.1 */
+
+static const char tiling13_5_1[2][4][18] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+/* 1,2,5 */ { 7, 6, 11, 1, 0, 9, 10, 3, 2, 3, 10, 5, 3, 5, 8, 4, 8, 5 },
+
+/* 1,4,6 */ { 1, 2, 10, 7, 4, 8, 3, 0, 11, 6, 11, 0, 9, 6, 0, 6, 9, 5 },
+
+/* 2,3,6 */ { 3, 0, 8, 5, 6, 10, 1, 2, 9, 4, 9, 2, 11, 4, 2, 4, 11, 7 },
+
+/* 3,4,5 */ { 5, 4, 9, 3, 2, 11, 8, 1, 0, 1, 8, 7, 1, 7, 10, 6, 10, 7 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+/* 1,2,5 */ { 4, 7, 8, 2, 1, 10, 11, 0, 3, 0, 11, 6, 0, 6, 9, 5, 9, 6 },
+
+/* 1,4,6 */ { 2, 3, 11, 4, 5, 9, 0, 1, 8, 7, 8, 1, 10, 7, 1, 7, 10, 6 },
+
+/* 2,3,6 */ { 0, 1, 9, 6, 7, 11, 2, 3, 10, 5, 10, 3, 8, 5, 3, 5, 8, 4 },
+
+/* 3,4,5 */ { 6, 5, 10, 0, 3, 8, 9, 2, 1, 2, 9, 4, 2, 4, 11, 7, 11, 4 }
+
+} };
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 13.5.2
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+/* 13.5.2 */
+
+static const char tiling13_5_2[2][4][30] = {
+
+/* 165: 0, 2, 5, 7, */ {
+
+/* 1,2,5 */ { 1, 0, 9, 7, 4, 8, 7, 8, 3, 7, 3, 11, 2, 11, 3, 11, 2, 10, 11, 10, 6, 5, 6, 10, 6, 5, 7, 4, 7, 5 },
+
+/* 1,4,6 */ { 7, 4, 8, 11, 3, 2, 6, 11, 2, 10, 6, 2, 6, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 0, 2, 0, 1, 0, 2, 3 },
+
+/* 2,3,6 */ { 5, 6, 10, 9, 1, 0, 4, 9, 0, 8, 4, 0, 4, 8, 7, 11, 7, 8, 3, 11, 8, 11, 3, 2, 0, 2, 3, 2, 0, 1 },
+
+/* 3,4,5 */ { 3, 2, 11, 5, 6, 10, 5, 10, 1, 5, 1, 9, 0, 9, 1, 9, 0, 8, 9, 8, 4, 4, 8, 7, 4, 7, 5, 6, 5, 7 }
+
+},
+
+/* 90: 1, 3, 4, 6, */ {
+
+/* 1,2,5 */ { 2, 1, 10, 4, 5, 9, 4, 9, 0, 4, 0, 8, 3, 8, 0, 8, 3, 11, 8, 11, 7, 6, 7, 11, 7, 6, 4, 5, 4, 6 },
+
+/* 1,4,6 */ { 4, 5, 9, 8, 0, 3, 7, 8, 3, 11, 7, 3, 7, 11, 6, 10, 6, 11, 2, 10, 11, 10, 2, 1, 3, 1, 2, 1, 3, 0 },
+
+/* 2,3,6 */ { 6, 7, 11, 10, 2, 1, 5, 10, 1, 9, 5, 1, 5, 9, 4, 8, 4, 9, 0, 8, 9, 8, 0, 3, 1, 3, 0, 3, 1, 2 },
+
+/* 3,4,5 */ { 0, 3, 8, 6, 7, 11, 6, 11, 2, 6, 2, 10, 1, 10, 2, 10, 1, 9, 10, 9, 5, 5, 9, 4, 5, 4, 6, 7, 6, 4 }
+
+} };
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief tiling table for case 14
+
+ * For each of the case above, the specific triangulation of the edge
+
+ * intersection points is given.
+
+ * When a case is ambiguous, there is an auxiliary table that contains
+
+ * the face number to test && the tiling table contains the specific
+
+ * triangulations depending on the results
+
+ * A minus sign means to invert the result of the test.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char tiling14[12][12] = {
+
+/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8 },
+
+/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5 },
+
+/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6 },
+
+/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4 },
+
+/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5 },
+
+/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10 },
+
+/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7 },
+
+/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2 },
+
+/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11 },
+
+/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3 },
+
+/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8 },
+
+/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+
+/**
+
+ * \brief original Marching Cubes implementation
+
+ * For each of the possible vertex states listed in this table there is a
+
+ * specific triangulation of the edge intersection points. The table lists
+
+ * all of them in the form of 0-5 edge triples with the list terminated by
+
+ * the invalid value -1. For example: casesClassic[3] list the 2 triangles
+
+ * formed when cube[0] && cube[1] are inside of the surface, but the rest of
+
+ * the cube is not.
+
+ */
+
+//-----------------------------------------------------------------------------
+
+static const char casesClassic[256][16] = {
+
+/* 0: */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 1: 0, */ { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 2: 1, */ { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 4: 2, */ { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 8: 3, */ { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 16: 4, */ { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 21: 0, 2, 4, */ { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 22: 1, 2, 4, */ { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
+
+/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 26: 1, 3, 4, */ { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
+
+/* 28: 2, 3, 4, */ { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
+
+/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
+
+/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 32: 5, */ { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 37: 0, 2, 5, */ { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
+
+/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 41: 0, 3, 5, */ { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 42: 1, 3, 5, */ { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
+
+/* 44: 2, 3, 5, */ { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 45: 0, 2, 3, 5, */ { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
+
+/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
+
+/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 52: 2, 4, 5, */ { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 53: 0, 2, 4, 5, */ { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
+
+/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
+
+/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 56: 3, 4, 5, */ { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
+
+/* 58: 1, 3, 4, 5, */ { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
+
+/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 60: 2, 3, 4, 5, */ { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
+
+/* 61: 0, 2, 3, 4, 5, */ { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
+
+/* 62: 1, 2, 3, 4, 5, */ { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
+
+/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 64: 6, */ { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 67: 0, 1, 6, */ { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 69: 0, 2, 6, */ { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
+
+/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 73: 0, 3, 6, */ { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 74: 1, 3, 6, */ { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 75: 0, 1, 3, 6, */ { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
+
+/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
+
+/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
+
+/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 81: 0, 4, 6, */ { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 82: 1, 4, 6, */ { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
+
+/* 84: 2, 4, 6, */ { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
+
+/* 86: 1, 2, 4, 6, */ { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
+
+/* 87: 0, 1, 2, 4, 6, */ { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
+
+/* 88: 3, 4, 6, */ { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 89: 0, 3, 4, 6, */ { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
+
+/* 90: 1, 3, 4, 6, */ { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
+
+/* 91: 0, 1, 3, 4, 6, */ { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
+
+/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
+
+/* 93: 0, 2, 3, 4, 6, */ { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
+
+/* 94: 1, 2, 3, 4, 6, */ { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
+
+/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
+
+/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 97: 0, 5, 6, */ { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
+
+/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 101: 0, 2, 5, 6, */ { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
+
+/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 104: 3, 5, 6, */ { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 105: 0, 3, 5, 6, */ { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
+
+/* 106: 1, 3, 5, 6, */ { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
+
+/* 107: 0, 1, 3, 5, 6, */ { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
+
+/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
+
+/* 109: 0, 2, 3, 5, 6, */ { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
+
+/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
+
+/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
+
+/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
+
+/* 117: 0, 2, 4, 5, 6, */ { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
+
+/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 120: 3, 4, 5, 6, */ { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
+
+/* 121: 0, 3, 4, 5, 6, */ { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
+
+/* 122: 1, 3, 4, 5, 6, */ { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
+
+/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
+
+/* 124: 2, 3, 4, 5, 6, */ { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
+
+/* 125: 0, 2, 3, 4, 5, 6, */ { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
+
+/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 128: 7, */ { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 131: 0, 1, 7, */ { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 133: 0, 2, 7, */ { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 134: 1, 2, 7, */ { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 135: 0, 1, 2, 7, */ { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
+
+/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 138: 1, 3, 7, */ { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
+
+/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
+
+/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
+
+/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 146: 1, 4, 7, */ { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
+
+/* 148: 2, 4, 7, */ { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 149: 0, 2, 4, 7, */ { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
+
+/* 150: 1, 2, 4, 7, */ { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
+
+/* 151: 0, 1, 2, 4, 7, */ { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
+
+/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 154: 1, 3, 4, 7, */ { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
+
+/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
+
+/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 158: 1, 2, 3, 4, 7, */ { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
+
+/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 161: 0, 5, 7, */ { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 162: 1, 5, 7, */ { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 163: 0, 1, 5, 7, */ { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
+
+/* 164: 2, 5, 7, */ { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 165: 0, 2, 5, 7, */ { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
+
+/* 166: 1, 2, 5, 7, */ { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
+
+/* 167: 0, 1, 2, 5, 7, */ { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
+
+/* 168: 3, 5, 7, */ { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
+
+/* 170: 1, 3, 5, 7, */ { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
+
+/* 171: 0, 1, 3, 5, 7, */ { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
+
+/* 172: 2, 3, 5, 7, */ { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
+
+/* 173: 0, 2, 3, 5, 7, */ { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
+
+/* 174: 1, 2, 3, 5, 7, */ { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
+
+/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
+
+/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
+
+/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
+
+/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 180: 2, 4, 5, 7, */ { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
+
+/* 181: 0, 2, 4, 5, 7, */ { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
+
+/* 182: 1, 2, 4, 5, 7, */ { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
+
+/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
+
+/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
+
+/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 186: 1, 3, 4, 5, 7, */ { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
+
+/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 188: 2, 3, 4, 5, 7, */ { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
+
+/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
+
+/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 193: 0, 6, 7, */ { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 194: 1, 6, 7, */ { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 195: 0, 1, 6, 7, */ { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
+
+/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 197: 0, 2, 6, 7, */ { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
+
+/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
+
+/* 199: 0, 1, 2, 6, 7, */ { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
+
+/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
+
+/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
+
+/* 203: 0, 1, 3, 6, 7, */ { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
+
+/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
+
+/* 210: 1, 4, 6, 7, */ { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
+
+/* 211: 0, 1, 4, 6, 7, */ { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
+
+/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
+
+/* 213: 0, 2, 4, 6, 7, */ { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
+
+/* 214: 1, 2, 4, 6, 7, */ { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
+
+/* 215: 0, 1, 2, 4, 6, 7, */ { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
+
+/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 218: 1, 3, 4, 6, 7, */ { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
+
+/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
+
+/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
+
+/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 225: 0, 5, 6, 7, */ { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
+
+/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
+
+/* 227: 0, 1, 5, 6, 7, */ { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
+
+/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
+
+/* 229: 0, 2, 5, 6, 7, */ { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
+
+/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
+
+/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
+
+/* 233: 0, 3, 5, 6, 7, */ { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
+
+/* 234: 1, 3, 5, 6, 7, */ { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
+
+/* 235: 0, 1, 3, 5, 6, 7, */ { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
+
+/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
+
+/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
+
+/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+
+/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
+
+};
+
+//_____________________________________________________________________________
+
+
+
+
+
+
+
+#endif // _LOOKUPTABLE_H_
+
diff --git a/headers/MMFF.h b/headers/MMFF.h
new file mode 100644
index 0000000..941027f
--- /dev/null
+++ b/headers/MMFF.h
@@ -0,0 +1,355 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef MMFF_H
+#define MMFF_H
+
+
+#include "FF.h"
+#include <QFile>
+#include <QTextStream>
+
+typedef struct {
+ int type, I, J;
+ double increment;
+} MMFFciParameter;
+
+typedef struct {
+ string parent, strin;
+} MMFFHParameter;
+
+typedef struct {
+ string strin, description;
+ int number;
+} MMFFatypeParameter;
+
+
+typedef struct {
+ int type, atomicNumber, valence, crd, mltb;
+ bool lonePairs, linear, aromatic, multipleBond;
+} MMFFatomParameter;
+
+
+typedef struct {
+ string old_type, arom_type;
+ int at_number, ring_size, L5;
+ bool IMCAT, N5ANION;
+} MMFFaromaticParameter;
+
+
+typedef struct {
+ int type, I, J, K;
+ double ka, theta0;
+} MMFFabParameter;
+
+
+class MMFFbsInteraction : public ForceFieldInteraction {
+ public:
+
+ double r0, kb;
+ int type;
+ float value ();
+};
+
+
+class MMFFabInteraction : public ForceFieldInteraction {
+ public:
+ // MMFFabInteraction ();
+ Atom *at3;
+ double ka, theta0;
+ int type;
+ bool linear;
+ float value ();
+ void set_forces (bool score = false, double mult = 1.);
+};
+
+
+class MMFFsbInteraction : public ForceFieldInteraction {
+ public:
+ Atom *at3;
+ double theta0, kijk, kkji, r0ij, r0kj;
+ float value ();
+ void set_forces (bool score = false, double mult = 1.);
+};
+
+class MMFFopInteraction : public ForceFieldInteraction {
+ public:
+ Atom *at3, *at4;
+ double koop;
+ float value ();
+ void set_forces (bool score = false, double mult = 1.);
+};
+
+
+class MMFFtoInteraction : public ForceFieldInteraction {
+ public:
+ Atom *at3, *at4;
+ double v1, v2, v3;
+ int type;
+ float value ();
+ void set_forces (bool score = false, double mult = 1.);
+};
+
+class MMFFvwInteraction : public ForceFieldInteraction {
+ public:
+ double e, r0;
+ float value ();
+};
+
+class MMFFelInteraction : public ForceFieldInteraction {
+ public:
+ double scale;
+ float value ();
+ bool isHbond ();
+ inline bool isElectrostatic () {return true;};
+};
+
+
+
+typedef struct {
+ int type, I, J;
+ double kb, r0;
+} MMFFbsParameter;
+
+
+
+typedef struct {
+ int type, I, J, K;
+ double kijk, kkji;
+} MMFFsbParameter;
+
+typedef struct {
+ int I, J, K, L;
+ double koop;
+} MMFFopParameter;
+
+
+
+
+typedef struct {
+ int type, I, J, K, L;
+ double V1, V2, V3;
+} MMFFtoParameter;
+
+
+
+
+
+typedef struct {
+ int type, I, J;
+ double alpha, N, A, G;
+ int DA;
+} MMFFvwParameter;
+
+
+class MMFF : public ForceField{
+
+public:
+ MMFF ();
+
+ // void type ();
+
+
+ void clear_nonbonded_interactions ();
+ void clear_internal_interactions ();
+
+
+ void load_internal_interactions ();
+ void load_internal_interactions (vector <ForceFieldInteraction*> *v);
+ void load_nonbonded_interactions ();
+
+ void load_nonbonded_interactions_for_atom (Atom *at, queue <ForceFieldInteraction*> *q);
+
+
+ double compute_total_energy ();
+ double compute_interaction_energy ();
+ void initialize_mol (ZNMolecule *mol);
+ void compute_partial_charges (ZNMolecule *mol);
+ void get_strings_mol (ZNMolecule *mol);
+ int getMMFFtype(Atom* at);
+ string getMMFFcarbonstring (Atom* at);
+ string getMMFFeteroatomstring (Atom* at);
+ string getMMFFHstring (Atom* at);
+ double getMMFFstartcharge (Atom* at);
+ double compute_charge (Atom *at);
+
+
+ void compute_forces ();
+
+ // void compute_total_van_der_waals_force (vector<float>& force, vector<float>& torque);
+ // void compute_total_electrostatic_force (vector<float>& force, vector<float>& torque);
+
+
+ double compute_bond_stretchings ();
+ double compute_angle_bendings ();
+ double compute_stretch_bend_interactions ();
+ double compute_out_of_plane_bendings ();
+ double compute_electrostatic_interactions ();
+ double compute_torsion_interactions ();
+ double compute_van_der_waals_interactions ();
+
+double compute_nonbonded_electrostatic_interactions ();
+double compute_nonbonded_van_der_waals_interactions ();
+
+
+private:
+
+ vector<float> compute_electrostatic_force_vector (MMFFelInteraction *elint);
+ vector<float> compute_van_der_waals_force_vector (MMFFvwInteraction *vwint);
+
+
+
+ void compute_bond_stretching_forces ();
+ void compute_van_der_waals_forces ();
+ void compute_angle_bending_forces ();
+ void compute_stretch_bend_interaction_forces ();
+ void compute_out_of_plane_bending_forces ();
+ void compute_electrostatic_forces ();
+ void compute_torsion_forces ();
+ void compute_nonbonded_van_der_waals_forces ();
+ void compute_nonbonded_electrostatic_forces ();
+
+
+
+
+/*
+ double compute_bond_stretching (MMFFbsInteraction *bsint);
+ double compute_van_der_waals_interaction (MMFFvwInteraction *vwint);
+ double compute_angle_bending (MMFFabInteraction *abinter);
+ double compute_stretch_bend_interaction (MMFFsbInteraction *sbint);
+ double compute_out_of_plane_bending (MMFFopInteraction *opint);
+ double compute_electrostatic_interaction (MMFFelInteraction *elint);
+ double compute_torsion_interaction (MMFFtoInteraction *toint);
+*/
+
+
+
+
+
+/*
+ void compute_bond_stretching_force (MMFFbsInteraction *bsint);
+ void compute_van_der_waals_force (MMFFvwInteraction *vwint);
+ void compute_angle_bending_force (MMFFabInteraction *abinter);
+ void compute_stretch_bend_interaction_force (MMFFsbInteraction *sbint);
+ void compute_out_of_plane_bending_force (MMFFopInteraction *opint);
+ void compute_electrostatic_force (MMFFelInteraction *elint);
+ void compute_torsion_force (MMFFtoInteraction *toint);
+*/
+
+
+/*
+ float compute_bond_stretching_force_module (MMFFbsInteraction *bsint);
+ float compute_van_der_waals_force_module (MMFFvwInteraction *vwint);
+ float compute_angle_bending_force_module (MMFFabInteraction *abinter);
+ float compute_stretch_bend_interaction_force_module (MMFFsbInteraction *sbint);
+ float compute_out_of_plane_bending_force_module (MMFFopInteraction *opint);
+ float compute_electrostatic_force_module (MMFFelInteraction *elint);
+ float compute_torsion_force_module (MMFFtoInteraction *toint);
+*/
+
+
+
+ vector <MMFFciParameter*> ciParameters;
+ vector <MMFFaromaticParameter*> aromaticParameters;
+ vector <MMFFatypeParameter*> atypeParameters;
+ vector <MMFFHParameter*> HParameters;
+ vector <MMFFatomParameter*> atomParameters;
+ vector <MMFFabParameter*> abParameters;
+ vector <MMFFbsParameter*> bsParameters;
+ vector <MMFFsbParameter*> sbParameters;
+ vector <MMFFsbParameter*> sb2Parameters;
+ vector <MMFFtoParameter*> toParameters;
+ vector <MMFFvwParameter*> vwParameters;
+ vector <MMFFopParameter*> opParameters;
+
+ vector <MMFFbsInteraction*> bsInteractions;
+ vector <MMFFabInteraction*> abInteractions;
+ vector <MMFFtoInteraction*> toInteractions;
+ vector <MMFFvwInteraction*> vwInteractions;
+ vector <MMFFopInteraction*> opInteractions;
+ vector <MMFFelInteraction*> elInteractions;
+ vector <MMFFsbInteraction*> sbInteractions;
+
+ vector <MMFFvwInteraction*> vwNBInteractions;
+ vector <MMFFelInteraction*> elNBInteractions;
+
+ int load_parameters ();
+ int load_ci_parameters ();
+ int load_H_parameters ();
+ int load_atype_parameters ();
+ int load_atom_parameters ();
+ int load_ab_parameters ();
+ int load_bs_parameters ();
+ int load_sb_parameters ();
+ int load_sb2_parameters ();
+ int load_to_parameters ();
+ int load_vw_parameters ();
+ int load_op_parameters ();
+ int load_aromatic_parameters ();
+
+ void empiric_to_parameters (Atom *at1, Atom *at2, Atom *at3, Atom *at4, float& v1, float &v2, float &v3);
+
+ int get_bond_type (int I, int J);
+
+
+ double get_charge_increment (int I, int J);
+
+ double get_vdw_e (Atom *at1, Atom *at2);
+ double get_vdw_r0 (Atom *at1, Atom *at2);
+ double get_bs_kb (int I, int J);
+ double get_bs_r0 (int I, int J);
+ double get_ab_ka (int I, int J, int K);
+ double get_ab_theta0 (int I, int J, int K);
+ double get_charge_rho (int I);
+ double get_charge_theta (int I);
+ int get_pt_row (int an);
+
+ string get_aromatic_string (Atom *at);
+ int get_atype_line (int I);
+ int get_ab_pl (int type, int I, int J, int K);
+ int get_bs_pl (int type, int I, int J);
+ int get_sb_pl (int I, int J, int K);
+ int get_sb2_pl (int RI, int RJ, int RK);
+ int get_to_pl (int type, int I, int J, int K, int L);
+ int get_vw_pl (int I);
+ int get_op_pl (int I, int J, int K, int L);
+ bool get_linear (int J);
+ bool get_sbmb (int J);
+ bool get_arom (int J);
+
+ int getBondType (Atom *a, Atom *b);
+ int getAngleType (Atom *a, Atom *b, Atom *c);
+
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/headers/MarchingCubes.h b/headers/MarchingCubes.h
new file mode 100644
index 0000000..992274a
--- /dev/null
+++ b/headers/MarchingCubes.h
@@ -0,0 +1,437 @@
+/**
+ * @file MarchingCubes.h
+ * @author Thomas Lewiner <thomas.lewiner at polytechnique.org>
+ * @author Math Dept, PUC-Rio
+ * @version 0.2
+ * @date 12/08/2002
+ *
+ * @brief MarchingCubes Algorithm
+ */
+//________________________________________________
+
+
+#ifndef MARCHINGCUBES_H
+#define MARCHINGCUBES_H
+
+#if !defined(WIN32) || defined(__CYGWIN__)
+#pragma interface
+#endif // WIN32
+
+
+#include <iostream>;
+using namespace std;
+//_____________________________________________________________________________
+// types
+/** unsigned char alias */
+typedef unsigned char uchar ;
+/** signed char alias */
+typedef signed char schar ;
+/** isovalue alias */
+typedef double real ;
+
+//-----------------------------------------------------------------------------
+// Vertex structure
+/** \struct Vertex "MarchingCubes.h" MarchingCubes
+ * Position && normal of a vertex
+ * \brief vertex structure
+ * \param x X coordinate
+ * \param y Y coordinate
+ * \param z Z coordinate
+ * \param nx X component of the normal
+ * \param ny Y component of the normal
+ * \param nz Z component of the normal
+ */
+typedef struct
+{
+ real x, y, z ; /**< Vertex coordinates */
+ real nx, ny, nz ; /**< Vertex normal */
+} Vertex ;
+
+//-----------------------------------------------------------------------------
+// Triangle structure
+/** \struct Triangle "MarchingCubes.h" MarchingCubes
+ * Indices of the oriented triange vertices
+ * \brief triangle structure
+ * \param v1 First vertex index
+ * \param v2 Second vertex index
+ * \param v3 Third vertex index
+ */
+typedef struct
+{
+ int v1,v2,v3 ; /**< Triangle vertices */
+} Triangle ;
+//_____________________________________________________________________________
+
+
+
+//_____________________________________________________________________________
+/** Marching Cubes algorithm wrapper */
+/** \class MarchingCubes
+ * \brief Marching Cubes algorithm.
+ */
+class MarchingCubes
+//-----------------------------------------------------------------------------
+{
+// Constructors
+public :
+ /**
+ * Main && default constructor
+ * \brief constructor
+ * \param size_x width of the grid
+ * \param size_y depth of the grid
+ * \param size_z height of the grid
+ */
+ MarchingCubes ( const int size_x = -1, const int size_y = -1, const int size_z = -1 ) ;
+ /** Destructor */
+ ~MarchingCubes() ;
+
+//-----------------------------------------------------------------------------
+// Accessors
+public :
+ inline const float xmin () const {return _xmin;}
+ inline const float ymin () const {return _ymin;}
+ inline const float zmin () const {return _zmin;}
+ inline const float xmax () const {return _xmax;}
+ inline const float ymax () const {return _ymax;}
+ inline const float zmax () const {return _zmax;}
+
+
+ /** accesses the number of vertices of the generated mesh */
+ inline const int nverts() const { return _nverts ; }
+ /** accesses the number of triangles of the generated mesh */
+ inline const int ntrigs() const { return _ntrigs ; }
+ /** accesses a specific vertex of the generated mesh */
+ inline Vertex * vert( const int i ) const { if( i < 0 || i >= _nverts ) return ( Vertex *)NULL ; return _vertices + i ; }
+ /** accesses a specific triangle of the generated mesh */
+ inline Triangle * trig( const int i ) const { if( i < 0 || i >= _ntrigs ) return (Triangle*)NULL ; return _triangles + i ; }
+
+ /** accesses the vertex buffer of the generated mesh */
+ inline Vertex *vertices () { return _vertices ; }
+ /** accesses the triangle buffer of the generated mesh */
+ inline Triangle *triangles() { return _triangles ; }
+
+ /** accesses the width of the grid */
+ inline const int size_x() const { return _size_x ; }
+ /** accesses the depth of the grid */
+ inline const int size_y() const { return _size_y ; }
+ /** accesses the height of the grid */
+ inline const int size_z() const { return _size_z ; }
+
+ inline const float to_real_x(float i) const { return _xmin+i*(_xmax-_xmin)/_size_x ; }
+ inline const float to_real_y(float j) const { return _ymin+j*(_ymax-_ymin)/_size_y ; }
+ inline const float to_real_z(float k) const { return _zmin+k*(_zmax-_zmin)/_size_z ; }
+
+ inline const int to_cube_i(float x) const { return (int) ((x-_xmin)/(_xmax-_xmin)*_size_x);}
+ inline const int to_cube_j(float y) const { return (int) ((y-_ymin)/(_ymax-_ymin)*_size_y);}
+ inline const int to_cube_k(float z) const { return (int) ((z-_zmin)/(_zmax-_zmin)*_size_z);}
+ /**
+ * changes the size of the grid
+ * \param size_x width of the grid
+ * \param size_y depth of the grid
+ * \param size_z height of the grid
+ */
+ inline void set_limits (const float xmin, const float ymin, const float zmin, const float xmax, const float ymax, const float zmax) {_xmin=xmin; _ymin=ymin; _zmin=zmin; _xmax=xmax; _ymax=ymax; _zmax=zmax;};
+
+ inline void set_resolution( const int size_x, const int size_y, const int size_z ) { _size_x = size_x ; _size_y = size_y ; _size_z = size_z ; }
+ /**
+ * selects wether the algorithm will use the enhanced topologically controlled lookup table || the original MarchingCubes
+ * \param originalMC true for the original Marching Cubes
+ */
+ inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; }
+ /**
+ * selects to use data from another class
+ * \param data is the pointer to the external data, allocated as a size_x*size_y*size_z vector running in x first
+ */
+ inline void set_ext_data ( real *data )
+ { if( !_ext_data ) delete [] _data ; _ext_data = data != NULL ; if( _ext_data ) _data = data ; }
+ /**
+ * selects to allocate data
+ */
+ inline void set_int_data () { _ext_data = false ; _data = NULL ; }
+
+ // Data access
+ /**
+ * accesses a specific cube of the grid
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline const real get_data ( const int i, const int j, const int k ) const { return _data[ i + j*_size_x + k*_size_x*_size_y] ; }
+ /**
+ * sets a specific cube of the grid
+ * \param val new value for the cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+
+ real get_interpolated_data (const real x, const real y, const real z) {
+ int i1, i2;
+ i1 = to_cube_i (x);
+ i2 = i1 + 1;
+ if (i1 < 0) {
+ i1 = 0;
+ i2 = 0;
+ }
+ else if (i2 > _size_x -1) {
+ i2 = _size_x -1 ;
+ }
+
+ int j1, j2;
+ j1 = to_cube_j (y);
+ j2 = j1 + 1;
+ if (j1 < 0) {
+ j1 = 0;
+ j2 = 0;
+ }
+ else if (j2 > _size_y -1) {
+ j2 = _size_y -1 ;
+ }
+
+ int k1, k2;
+ k1 = to_cube_k (z);
+ k2 = k1 + 1;
+ if (k1 < 0) {
+ k1 = 0;
+ k2 = 0;
+ }
+ else if (k2 > _size_z -1) {
+ k2 = _size_z -1 ;
+ }
+
+ real V000 = get_data (i1, j1, k1);
+ real V001 = get_data (i1, j1, k2);
+ real V010 = get_data (i1, j2, k1);
+ real V011 = get_data (i1, j2, k2);
+ real V100 = get_data (i2, j1, k1);
+ real V101 = get_data (i2, j1, k2);
+ real V110 = get_data (i2, j2, k1);
+ real V111 = get_data (i2, j2, k2);
+ real x_space = (_xmax - _xmin) / _size_x;
+ real y_space = (_ymax - _ymin) / _size_y;
+ real z_space = (_zmax - _zmin) / _size_z;
+
+ real xx = (x - to_real_x(i1)) / x_space;
+ real yy = (y - to_real_y(j1)) / y_space;
+ real zz = (z - to_real_z(k1)) / z_space;
+ // cerr <<j1<<" "<<j2<<" "<< y <<" "<< to_real_y(j1)<<" "<<y_space<<" "<<xx<<" "<<yy<<" "<<zz<<endl;
+ return
+ V000 *(1 - xx) *(1 - yy) *(1 - zz) +
+ V100 * xx *(1 - yy) *(1 - zz) +
+ V010 *(1 - xx) *yy *(1 - zz) +
+ V001 *(1 - xx) *(1 - yy)* zz +
+ V101 *xx *(1 - yy)* zz +
+ V011 *(1 - xx) *yy *zz +
+ V110 *xx* yy *(1 - zz) +
+ V111 *xx *yy* zz;
+
+
+
+
+ }
+
+
+ inline void set_data ( const real val, const int i, const int j, const int k ) { _data[ i + j*_size_x + k*_size_x*_size_y] = val ; }
+
+ // Data initialization
+ /** inits temporary structures (must set sizes before call) : the grid && the vertex index per cube */
+ void init_temps () ;
+ /** inits all structures (must set sizes before call) : the temporary structures && the mesh buffers */
+ void init_all () ;
+ /** clears temporary structures : the grid && the main */
+ void clean_temps() ;
+ /** clears all structures : the temporary structures && the mesh buffers */
+ void clean_all () ;
+
+ void clean_mesh () ;
+ void init_mesh ();
+
+//-----------------------------------------------------------------------------
+// Exportation
+public :
+ /**
+ * PLY exportation of the generated mesh
+ * \param fn name of the PLY file to create
+ * \param bin if true, the PLY will be written in binary mode
+ */
+ void writePLY( const char *fn, bool bin = false ) ;
+
+ /**
+ * VRML / Open Inventor exportation of the generated mesh
+ * \param fn name of the IV file to create
+ */
+ void writeIV ( const char *fn ) ;
+
+ /**
+ * ISO exportation of the input grid
+ * \param fn name of the ISO file to create
+ */
+ void writeISO( const char *fn ) ;
+
+
+//-----------------------------------------------------------------------------
+// Algorithm
+public :
+ /**
+ * Main algorithm : must be called after init_all
+ * \param iso isovalue
+ */
+ void run( real iso = (real)0.0, int *prog = 0, int *max = 0 ) ;
+
+protected :
+ /** tesselates one cube */
+ void process_cube () ;
+ /** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */
+ bool test_face ( schar face ) ;
+ /** tests if the components of the tesselation of the cube should be connected through the interior of the cube */
+ bool test_interior( schar s ) ;
+
+
+//-----------------------------------------------------------------------------
+// Operations
+protected :
+ /**
+ * computes almost all the vertices of the mesh by interpolation along the cubes edges
+ * \param iso isovalue
+ */
+ void compute_intersection_points( real iso ) ;
+
+ /**
+ * routine to add a triangle to the mesh
+ * \param trig the code for the triangle as a sequence of edges index
+ * \param n the number of triangles to produce
+ * \param v12 the index of the interior vertex to use, if necessary
+ */
+ void add_triangle ( const char* trig, char n, int v12 = -1 ) ;
+
+ /** tests && eventually doubles the vertex buffer capacity for a new vertex insertion */
+ void test_vertex_addition() ;
+ /** adds a vertex on the current horizontal edge */
+ int add_x_vertex() ;
+ /** adds a vertex on the current longitudinal edge */
+ int add_y_vertex() ;
+ /** adds a vertex on the current vertical edge */
+ int add_z_vertex() ;
+ /** adds a vertex inside the current cube */
+ int add_c_vertex() ;
+
+ /**
+ * interpolates the horizontal gradient of the implicit function at the lower vertex of the specified cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+
+
+ real get_x_grad( const int i, const int j, const int k ) const ;
+ /**
+ * interpolates the longitudinal gradient of the implicit function at the lower vertex of the specified cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ real get_y_grad( const int i, const int j, const int k ) const ;
+ /**
+ * interpolates the vertical gradient of the implicit function at the lower vertex of the specified cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ real get_z_grad( const int i, const int j, const int k ) const ;
+
+ /**
+ * accesses the pre-computed vertex index on the lower horizontal edge of a specific cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+
+
+
+ inline int get_x_vert( const int i, const int j, const int k ) const { return _x_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
+ /**
+ * accesses the pre-computed vertex index on the lower longitudinal edge of a specific cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline int get_y_vert( const int i, const int j, const int k ) const { return _y_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
+ /**
+ * accesses the pre-computed vertex index on the lower vertical edge of a specific cube
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline int get_z_vert( const int i, const int j, const int k ) const { return _z_verts[ i + j*_size_x + k*_size_x*_size_y] ; }
+
+ /**
+ * sets the pre-computed vertex index on the lower horizontal edge of a specific cube
+ * \param val the index of the new vertex
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline void set_x_vert( const int val, const int i, const int j, const int k ) { _x_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
+ /**
+ * sets the pre-computed vertex index on the lower longitudinal edge of a specific cube
+ * \param val the index of the new vertex
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline void set_y_vert( const int val, const int i, const int j, const int k ) { _y_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
+ /**
+ * sets the pre-computed vertex index on the lower vertical edge of a specific cube
+ * \param val the index of the new vertex
+ * \param i abscisse of the cube
+ * \param j ordinate of the cube
+ * \param k height of the cube
+ */
+ inline void set_z_vert( const int val, const int i, const int j, const int k ) { _z_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; }
+
+ /** prints cube for debug */
+ void print_cube() ;
+
+//-----------------------------------------------------------------------------
+// Elements
+protected :
+ bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table || the original MarchingCubes */
+ bool _ext_data ; /**< selects wether to allocate data || use data from another class */
+
+ int _size_x ; /**< width of the grid */
+ int _size_y ; /**< depth of the grid */
+ int _size_z ; /**< height of the grid */
+ real *_data ; /**< implicit function values sampled on the grid */
+
+ int *_x_verts ; /**< pre-computed vertex indices on the lower horizontal edge of each cube */
+ int *_y_verts ; /**< pre-computed vertex indices on the lower longitudinal edge of each cube */
+ int *_z_verts ; /**< pre-computed vertex indices on the lower vertical edge of each cube */
+
+ int _nverts ; /**< number of allocated vertices in the vertex buffer */
+ int _ntrigs ; /**< number of allocated triangles in the triangle buffer */
+ int _Nverts ; /**< size of the vertex buffer */
+ int _Ntrigs ; /**< size of the triangle buffer */
+ Vertex *_vertices ; /**< vertex buffer */
+ Triangle *_triangles ; /**< triangle buffer */
+
+ int _i ; /**< abscisse of the active cube */
+ int _j ; /**< height of the active cube */
+ int _k ; /**< ordinate of the active cube */
+
+ float _xmin ; /**< min abscisse of the rendered cube */
+ float _ymin ; /**< min height of the rendered cube */
+ float _zmin ; /**< min ordinate of the rendered cube */
+ float _xmax ; /**< min abscisse of the rendered cube */
+ float _ymax ; /**< min abscisse of the rendered cube */
+ float _zmax ; /**< min abscisse of the rendered cube */
+
+ real _cube[8] ; /**< values of the implicit function on the active cube */
+ uchar _lut_entry ; /**< cube sign representation in [0..255] */
+ uchar _case ; /**< case of the active cube in [0..15] */
+ uchar _config ; /**< configuration of the active cube */
+ uchar _subconfig ; /**< subconfiguration of the active cube */
+};
+//_____________________________________________________________________________
+
+
+#endif // _MARCHINGCUBES_H_
diff --git a/headers/PLP.h b/headers/PLP.h
new file mode 100644
index 0000000..4b8a909
--- /dev/null
+++ b/headers/PLP.h
@@ -0,0 +1,66 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef PLP_H
+#define PLP_H
+
+
+
+#include "FF.h"
+
+
+class PLPInteraction : public ForceFieldInteraction
+{
+ public:
+ Atom *at1, *at2;
+ vect root;
+ int I, J, type;
+ float value ();
+
+};
+
+class PLP : public ForceField {
+
+public:
+ PLP ();
+
+ // void type ();
+
+ void clear_nonbonded_interactions ();
+ void load_mol (ZNMolecule *mol);
+ void load_environment (vector<ZNMolecule *> envir, ZNMolecule *mol);
+ void load_internal_interactions ();
+ void load_nonbonded_interactions ();
+ void update ();
+
+ void initialize (ZNMolecule *mol, vector<ZNMolecule *> envir);
+ inline double compute_total_energy () {return 0.;};
+ void initialize_mol (ZNMolecule *mol);
+ int getPLPtype(Atom* at);
+ int getPLPinteractiontype (int I, int J);
+
+ void compute_forces ();
+ // void compute_force (PLPInteraction *plpint);
+ // float compute_interaction (PLPInteraction *plpint);
+
+
+private:
+ vector<PLPInteraction *> NBInteractions;
+
+};
+
+#endif
diff --git a/headers/ZNdata.h b/headers/ZNdata.h
new file mode 100644
index 0000000..b1b8fa5
--- /dev/null
+++ b/headers/ZNdata.h
@@ -0,0 +1,174 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DATA_H
+#define DATA_H
+
+
+//haptics stuff
+#ifdef HAPI
+#include <HAPI/AnyHapticsDevice.h>
+#include <HAPI/HapticForceField.h>
+#include <H3DUtil/Threads.h>
+#endif //HAPI
+
+#include "constants.h"
+#include "MMFF.h"
+#include "PLP.h"
+#include "chemscore.h"
+#include "ZNmolecule.h"
+#include "ddwin.h"
+#include <qapplication.h>
+#include "minimize.h"
+#include <QUndoStack>
+#include "actions.h"
+#include "iodevice.h"
+
+#include <sstream>
+#include "molsketch_helium/mainwindow.h"
+
+
+class Myline;
+class MylineF;
+
+#ifdef HAPI
+using namespace HAPI;
+#endif //HAPI
+class Actions;
+class Data;
+
+class DDWin;
+class Minimize;
+
+
+
+class DataVar {
+ public:
+ DataVar () {};
+ string name;
+ virtual string write_string () = 0 ;
+ virtual void load (string buffer) = 0 ;
+};
+
+class StringDataVar : public DataVar {
+ private:
+ string _value, _default;
+ public:
+ StringDataVar (string nam, string def) {name = nam; _default = def; _value = def;};
+ string write_string () {return name+" "+_value;};
+ void load (string buffer);
+};
+
+class ColorDataVar : public DataVar {
+ private:
+ color _value, _default;
+ public:
+ color *value_ptr () {return &_value;};
+ ColorDataVar (string nam, color def) {name = nam; _default = def; _value = def;};
+ string write_string () {return name+" "+int_to_string (_value.red ())+" "+int_to_string (_value.green ())+" "+int_to_string (_value.blue ())+" "+int_to_string (_value.alpha ()); };
+ void load (string buffer);
+
+};
+
+class DoubleDataVar : public DataVar {
+ private:
+ double _value, _default;
+ public:
+ double *value_ptr () {return &_value;};
+ DoubleDataVar (string nam, double def) {name = nam; _default = def; _value = def;};
+ string write_string () {return name+" "+double_to_string (_value); };
+ void load (string buffer);
+
+};
+
+
+class Data : public QObject {
+Q_OBJECT
+public:
+#ifdef HAPI
+ AnyHapticsDevice *haptic_device;
+#endif //HAPI
+ int ncounter;
+
+ double current_force_x;
+ double current_force_y;
+ double current_force_z;
+ double current_position_x;
+ double current_position_y;
+ double current_position_z;
+ double current_yaw, current_pitch, current_roll, last_pitch, last_roll, last_yaw;
+
+QReadWriteLock *haptic_position_lock;
+
+ Data (QApplication *master);//, DDWin *ddw);
+
+ void set_ddwin (DDWin *ddw);
+ // void set_FF (MMFF *mmff, TriposFF *triposff, PLP *plp);
+ QApplication *qapp;
+ DDWin *ddwin;
+ Actions *actions;
+ MMFF *mmff;
+ Minimize *minimize ;
+ MainWindow *twodwin;
+
+ color *background_color;
+ double *quality_scale, *stick_radius, *vdw_scale, *sphere_radius, *double_bond_stick_scale, *double_bond_separation, *line_width;
+ double *backbone_tube_helix_a, *backbone_tube_helix_b, *backbone_tube_helix_c, *backbone_tube_sheet_a, *backbone_tube_sheet_b, *backbone_tube_sheet_c, *backbone_tube_random_a, *backbone_tube_random_b, *backbone_tube_random_c;
+ // ZNMolecule *protein;
+
+// vector <ZNMolecule*> ligands;
+// vector <vector <float> > waters;
+
+ QUndoStack * undo_stack;
+
+// vector <IODevice *> iodevices;
+
+ color constant_color;
+ color charge_begin_color, charge_end_color;
+ color score_begin_color, score_mid_color, score_end_color;
+ vector <DataVar *> vars;
+
+ double charge_begin, charge_end;
+ double score_begin, score_mid, score_end;
+
+ float total_energy_haptic;
+
+
+ ZNMolecule* check_mol2 (string filename);
+ void load_defaults ();
+ void load_preferences ();
+ void write_preferences ();
+
+ void load_haptic_device ();
+ //void haptic_callback ();
+ string plants_exe;
+
+
+
+private:
+ void _load_var (string& buffer, string reference, string &target);
+
+private slots:
+ void from_2D_to_3D ();
+};
+
+void *haptic_callback (void *dat);
+bool is_db_extended (ZNMolecule *mol);
+
+
+#endif
diff --git a/headers/ZNmolecule.h b/headers/ZNmolecule.h
new file mode 100644
index 0000000..1c79296
--- /dev/null
+++ b/headers/ZNmolecule.h
@@ -0,0 +1,610 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef MOLECULE_H
+#define MOLECULE_H
+
+
+#include "constants.h"
+#include "obabel_includes.h"
+#include <QMutex>
+#include <QReadWriteLock>
+
+
+
+//molecule data
+const unsigned int MINIMISATION_DATA_INDEX = OBGenericDataType::CustomData0;
+const unsigned int MOLECULAR_FRAGMENT_DATA_INDEX = OBGenericDataType::CustomData1;
+const unsigned int MOLECULAR_DISPLAY_DATA_INDEX = OBGenericDataType::CustomData2;
+const unsigned int GEOMETRY_DATA_INDEX = OBGenericDataType::CustomData3;
+
+
+//atom data
+const unsigned int ATOMIC_FRAGMENT_DATA_INDEX = OBGenericDataType::CustomData0;
+const unsigned int ATOMIC_DISPLAY_DATA_INDEX = OBGenericDataType::CustomData1;
+
+//bond data
+const unsigned int BOND_DISPLAY_DATA_INDEX = OBGenericDataType::CustomData0;
+
+//residue data
+const unsigned int BACKBONE_DATA_INDEX = OBGenericDataType::CustomData0;
+
+
+typedef OpenBabel::OBAtom Atom;
+typedef OpenBabel::OBBond ZNBond;
+class Fragment;
+
+
+using namespace std;
+
+typedef struct {
+ vect v1;
+ vect v2;
+ float perc;
+} HBond;
+
+class rotorConnection {
+public:
+ rotorConnection () {bond = NULL; from_atom = NULL; to_atom = NULL; to_fragment = NULL; to_keep = false; dihedral = 0.;}
+ ~rotorConnection () {};
+ ZNBond *bond;
+ Atom *from_atom, *to_atom;
+ Fragment *to_fragment;
+ bool to_keep;
+ double dihedral;
+ void set_dihedral (double angle);
+};
+
+
+
+
+class SurfVertex
+ {
+ public:
+ SurfVertex () : col (color (255,255,255)) {};
+ inline vect& GetVector () {return coordinates;};
+ vect coordinates;
+ color col;
+ vect normal;
+ int n;
+ };
+
+
+
+class Database; class vect; class ZNMolecule;
+
+
+
+typedef OpenBabel::OBRing Ring;
+typedef OpenBabel::OBResidue Resid;
+
+
+//typedef OpenBabel::OBPairTemplate <QMutex *> MutexData;
+
+
+class MinimisationData:public OBGenericData {
+public:
+ MinimisationData ();
+ MinimisationData (const MinimisationData &dat)
+// : OBGenericData( *((OBGenericData::OBGenericData *)&dat) )
+ : OBGenericData( dat )
+ {
+ _force = dat._force;
+ _back_force = dat._back_force;
+ _score = dat._score;
+ _back_score = dat._back_score;
+ };
+ virtual OBGenericData* Clone(OBBase* parent) const {return new MinimisationData(*this);};
+ void set_force_value (vect force) {_force = force;};
+ vect get_force_value () {return _force;};
+ void set_back_force_value (vect force)
+{
+//#pragma omp parallel
+//#pragma omp critical
+{
+_back_force = force;
+}
+};
+ vect get_back_force_value () {return _back_force;};
+ void set_score_value (double score) {_score = score;};
+ double get_score_value () {return _score;};
+ void set_back_score_value (double score)
+{
+//#pragma omp parallel
+//#pragma omp critical
+{
+_back_score = score;
+}
+};
+ double get_back_score_value () {return _back_score;};
+private:
+ vect _force;
+ vect _back_force;
+ double _score, _back_score;
+};
+
+
+class AtomicFragmentData:public OBGenericData {
+public:
+ AtomicFragmentData ();
+ AtomicFragmentData (const AtomicFragmentData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {_fragment= NULL; _kinematic_chain_visited = false;};
+ virtual OBGenericData* Clone(OBBase* parent) const {return new AtomicFragmentData(*this);};
+ Fragment *get_fragment () {return _fragment;};
+ void set_fragment (Fragment *frag) {_fragment = frag;};
+ bool get_kinematic_chain_visited () {return _kinematic_chain_visited;};
+ void set_kinematic_chain_visited (bool kcv) {_kinematic_chain_visited = kcv;};
+private:
+ Fragment *_fragment;
+ bool _kinematic_chain_visited;
+};
+
+
+
+class MolecularFragmentData:public OBGenericData {
+public:
+ MolecularFragmentData ();
+ MolecularFragmentData (const MolecularFragmentData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {_fragments.clear (); _connections.clear ();};
+ virtual OBGenericData* Clone(OBBase* parent) const {return new MolecularFragmentData(*this);};
+ Fragment *get_fragment (int i) {int n = _fragments.size (); if (i<n && i>=0) return _fragments[i]; else return NULL;}
+ void set_fragment_list (vector <Fragment *> fragment_list) {_fragments = fragment_list;};
+ vector <Fragment *> &get_fragment_list () {return _fragments;};
+ void add_rotor (rotorConnection *connection) {_connections.push_back (connection);}
+ void clear_rotors () {_connections.clear ();}
+ vector <rotorConnection *> &get_rotors () {return _connections;};
+private:
+ vector <Fragment *> _fragments;
+ vector <rotorConnection *> _connections;
+};
+
+
+
+
+
+class GeometryData:public OBGenericData {
+public:
+ GeometryData ();
+ GeometryData(const GeometryData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {_center = dat._center; _min_corner = dat._min_corner; _max_corner = dat._max_corner; lock = new QReadWriteLock; _backbone_perceived = false; _fragments_perceived = false;}
+ virtual OBGenericData* Clone(OBBase* parent) const {return new GeometryData(*this);};
+ vect get_center () {return _center;};
+ void set_center (vect v) {_center = v;};
+ vect get_min_corner () {return _min_corner;};
+ vect get_max_corner () {return _max_corner;};
+ void set_min_corner (vect v) {_min_corner = v;};
+ void set_max_corner (vect v) {_max_corner = v;};
+ QReadWriteLock *lock;
+ bool _backbone_perceived, _fragments_perceived;
+
+private:
+ vect _center, _min_corner, _max_corner;
+
+
+};
+
+class MolecularDisplayData:public OBGenericData {
+public:
+ MolecularDisplayData ();
+ MolecularDisplayData (const MolecularDisplayData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {
+ _atom_display_style = dat._atom_display_style;
+ _bond_display_style = dat._bond_display_style;
+ _backbone_display_style = dat._backbone_display_style;
+ _line_list = dat._line_list; _backbone_list1 = dat._backbone_list1;
+ _backbone_list2 = dat._backbone_list2; _stick_list = dat._stick_list; _needs_redraw = true; _needs_backbone_redraw = true;
+ _clippable = dat._clippable;
+ };
+ virtual OBGenericData* Clone(OBBase* parent) const {return new MolecularDisplayData(*this);};
+ int get_atoms_display_style () {return _atom_display_style;};
+ void set_atoms_display_style (int i) {_atom_display_style = i;};
+ int get_bonds_display_style () {return _bond_display_style;};
+ void set_bonds_display_style (int i) {_bond_display_style = i;};
+ int get_backbone_display_style () {return _backbone_display_style;};
+ void set_backbone_display_style (int i) {_backbone_display_style = i;};
+ int get_line_list () {return _line_list;};
+ int get_backbone_list1 () {return _backbone_list1;};
+ int get_backbone_list2 () {return _backbone_list2;};
+ int get_stick_list () {return _stick_list;};
+ void set_line_list (int i) {_line_list = i;};
+ void set_backbone_list1 (int i) {_backbone_list1 = i;};
+ void set_backbone_list2 (int i) {_backbone_list2 = i;};
+ void set_stick_list (int i) {_stick_list = i;};
+ void set_needs_redraw (bool b) {_needs_redraw = b;};
+ bool get_needs_redraw () {return _needs_redraw;};
+ void set_needs_backbone_redraw (bool b) {_needs_backbone_redraw = b;};
+ bool get_needs_backbone_redraw () {return _needs_backbone_redraw;};
+
+ void set_clippable (bool b) {_clippable = b;};
+ bool get_clippable () {return _clippable;};
+
+
+
+private:
+ int _atom_display_style;
+ int _bond_display_style;
+ int _backbone_display_style;
+ int _line_list;
+ int _backbone_list1;
+ int _backbone_list2;
+ int _stick_list;
+ bool _needs_redraw, _clippable, _needs_backbone_redraw;
+
+};
+
+class AtomicDisplayData:public OBGenericData {
+public:
+ AtomicDisplayData ();
+ AtomicDisplayData(const AtomicDisplayData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {
+ _visible = dat._visible; _selected = dat._selected; _sphere_already_drawn = false; _display_style = dat._display_style;
+ _color = dat._color;
+ }
+ virtual OBGenericData* Clone(OBBase* parent) const {return new AtomicDisplayData(*this);};
+ bool get_visible () {return _visible;};
+ bool get_selected () {return _selected;};
+ bool get_sad () {return _sphere_already_drawn;};
+ int get_display_style () {return _display_style;};
+ color get_color () {return _color;};
+
+ void set_visible (bool b) {_visible = b;};
+ void set_display_style (int i) {_display_style = i;};
+ void set_selected(bool b) {_selected = b;};
+ void set_sad (bool b) {_sphere_already_drawn = b;};
+ void set_color (color c) {_color = c;};
+private:
+ bool _visible, _selected, _sphere_already_drawn;
+ int _display_style;
+ color _color;
+};
+
+
+class BondDisplayData:public OBGenericData {
+public:
+ BondDisplayData ();
+ BondDisplayData(const BondDisplayData &dat)
+// : OBGenericData( *(OBGenericData::OBGenericData *)&dat )
+ : OBGenericData( dat )
+ {
+ _display_style = dat._display_style;
+ }
+ virtual OBGenericData* Clone(OBBase* parent) const {return new BondDisplayData(*this);};
+ int get_display_style () {return _display_style;};
+ void set_display_style (int i) {_display_style = i;};
+
+private:
+ int _display_style;
+
+};
+
+
+class BackboneData:public OBGenericData {
+public:
+ BackboneData ();
+
+
+ color col;
+ vector <vect> backbone_points;
+ vect backbone_dir;
+ unsigned int ss;
+
+};
+
+
+vect get_coordinates (SurfVertex *v);
+
+//access atomic data
+
+vect get_coordinates (Atom *at);
+void set_coordinates (Atom *at, vect v);
+void sum_to_coordinates (Atom *at, vect v);
+
+vect find_mass_center (vector<Atom*>& invec);
+color get_color (Atom *at);
+color get_color (Resid *res);
+void set_color (Resid *res, color c);
+void set_color (Atom *at, color col);
+int get_ds (Atom *at);
+void set_ds (Atom *at, int);
+bool get_visible (Atom *at);
+void set_visible (Atom *at, bool);
+void set_force (Atom *at, vect);
+vect get_force (Atom *at);
+void lock_force_mutex (Atom *at);
+void unlock_force_mutex (Atom *at);
+void set_back_force (Atom *at, vect);
+vect get_back_force (Atom *at);
+void flush_forces (Atom *at);
+void flush_scores (Atom *at);
+void set_score (Atom *at, double);
+double get_score (Atom *at);
+void set_back_score (Atom *at, double);
+double get_back_score (Atom *at);
+
+
+
+
+bool get_selected (Atom *at);
+void set_selected (Atom *at, bool);
+bool get_sad (Atom *at);
+void set_sad (Atom *at, bool);
+
+
+
+bool get_kinematic_chain_visited (Atom *at);
+void set_kinematic_chain_visited (Atom *at, bool b);
+void set_fragment (Atom *at, Fragment *fr);
+Fragment *get_fragment (Atom *at);
+
+
+Resid *get_previous_residue (Resid *res, int gap = 1);
+Resid *get_following_residue (Resid *res, int gap = 1);
+
+Atom *get_O (Resid *res);
+Atom *get_CA (Resid *res);
+Atom *get_C (Resid *res);
+Atom *get_N (Resid *res);
+double get_phi (Resid *res);
+double get_psi (Resid *res);
+bool is_helix (Resid *res);
+bool is_sheet (Resid *res);
+bool is_random (Resid *res);
+
+void find_secondary_structure(ZNMolecule *mol);
+void find_secondary_structure (Resid *res);
+
+void color_backbone_ss (ZNMolecule *mol, color hel, color sheet, color random);
+void color_backbone_color (ZNMolecule *mol, color c);
+void set_ss (Resid *res, int);
+int get_ss (Resid *res);
+void set_backbone_direction (Resid *res, vect v);
+void set_backbone_points (Resid *res, vector <vect> points);
+vect get_backbone_direction (Resid *res);
+vect get_start_reference (Resid *res);
+vect get_end_reference (Resid *res);
+
+vector <vect> get_backbone_points (Resid *res);
+void find_backbone_data (ZNMolecule *mol);
+void set_backbone_style (Atom *at, int n);
+void find_backbone_points (Resid *res) ;
+void find_backbone_direction (Resid *res);
+vector <vect> smooth_list (vector <vect> lis);
+void add_guide_points_to_backbone (Resid *res, vector <vect> &lis);
+int get_MMFFtype (Atom *at);
+bool IsInSameRing(Atom* a, Atom* b);
+
+
+double get_vdw (Atom *at);
+
+int CountBonds (Atom *);
+bool is_polar (Atom *);
+Atom* root_at (Atom *);
+
+
+//access bond data
+int get_ds (ZNBond *b);
+void set_ds (ZNBond *b, int);
+bool get_visible (ZNBond *bo);
+bool get_selected (ZNBond *b);
+void set_selected (ZNBond *b, bool);
+
+//access molecule data
+void set_needs_redraw (ZNMolecule *, bool b);
+bool get_needs_redraw (ZNMolecule *);
+void set_needs_backbone_redraw (ZNMolecule *, bool b);
+bool get_needs_backbone_redraw (ZNMolecule *);
+void set_clippable (ZNMolecule *, bool b);
+bool get_clippable (ZNMolecule *);
+
+void set_fragment_list (ZNMolecule *mol, vector <Fragment *> fragment_list);
+void add_rotor (ZNMolecule *mol, rotorConnection *connection);
+void clear_rotors (ZNMolecule *mol);
+void build_kinematic_chain (ZNMolecule *mol);
+void mend_coordinates (ZNMolecule *mol);
+vector <rotorConnection *> &get_rotors (ZNMolecule *mol);
+void set_dihedrals (ZNMolecule *mol, vector <double> dihedrals);
+void build_molecule_from_dofs (ZNMolecule *mol, vector <float> dihedrals, bool move = false);
+
+vect get_root_fragment_center (ZNMolecule *mol) ;
+vector <Fragment *> get_fragments(ZNMolecule *mol);
+void initialise_dihedrals (ZNMolecule *mol, bool complete = false);
+vector <double> get_dihedrals(ZNMolecule *mol);
+void finalise_molecule(ZNMolecule *mol);
+void set_center (ZNMolecule *mol, vect v);
+void set_min_corner (ZNMolecule *mol, vect v);
+void set_max_corner (ZNMolecule *mol, vect v);
+vect get_min_corner (ZNMolecule *mol);
+vect get_max_corner (ZNMolecule *mol);
+vect get_center (ZNMolecule *mol);
+
+void find_limits (ZNMolecule *mol);
+void find_center (ZNMolecule *mol);
+
+int get_atoms_display_style (ZNMolecule *mol);
+int get_bonds_display_style (ZNMolecule *mol);
+int get_backbone_display_style (ZNMolecule *mol);
+
+void set_atoms_display_style (ZNMolecule *mol, int i);
+void set_bonds_display_style (ZNMolecule *mol, int i);
+void set_backbone_display_style (ZNMolecule *mol, int i);
+
+void lock_geometry_for_read (ZNMolecule *mol);
+void lock_geometry_for_write (ZNMolecule *mol);
+void unlock_geometry (ZNMolecule *mol);
+
+
+float very_fast_RMSD (ZNMolecule *a, ZNMolecule *b);
+int get_line_list (ZNMolecule *mol);
+int get_backbone_list1 (ZNMolecule *mol);
+int get_backbone_list2 (ZNMolecule *mol);
+int get_stick_list (ZNMolecule *mol);
+void set_display_lists (ZNMolecule *mol, int ll, int bl1, int bl2, int sl);
+void translate_molecule (ZNMolecule *mol, vect v);
+void rotate_molecule (ZNMolecule *mol, quaternion q, vect v);
+void rotate_atom (Atom *at, quaternion q, vect v);
+bool is_bsheet (Resid *res1, Resid *res2) ;
+Resid *find_sheet_partner (Resid *res, ZNMolecule *mol) ;
+
+void set_backbone_perceived (ZNMolecule *mol, bool b);
+bool get_backbone_perceived (ZNMolecule *mol);
+void set_fragments_perceived (ZNMolecule *mol, bool b);
+bool get_fragments_perceived (ZNMolecule *mol);
+
+void molecule_has_changed (ZNMolecule *mol);
+
+ZNMolecule *sum (ZNMolecule *mol1, ZNMolecule *mol2);
+
+class ZNMolecule : public OpenBabel::OBMol {
+ public:
+
+ ZNMolecule ();
+ ZNMolecule (const ZNMolecule &);
+ ZNMolecule &operator =(const ZNMolecule &mol);
+ ZNMolecule &operator +=(const ZNMolecule &mol);
+
+
+ bool selection, multi;
+ bool needs_recolor;
+
+
+ int bonded_to (Atom *, int, int);
+
+ void ZNinit ();
+ void ZNSetConformers ();
+ void ZNAddHydrogens (double ph = 7.4);
+ void ZNinit_atom (Atom *at);
+ void ZNinit_bond (ZNBond *bo);
+ void ZNinit_residue (Resid *re);
+ bool ZNAddHydrogens (Atom *at);
+ Atom * ZNAddAtom (Atom *at);
+ ZNBond * ZNAddBond (ZNBond *bo);
+
+
+ color get_color_mw (Atom *at);
+ void set_color_mw (Atom *at);
+ int get_ds_from_neighbour (Atom *at);
+ int get_ds_from_neighbour (ZNBond *bo);
+ void add_atom_bonded_to (Atom *to_add, ZNBond *bond, Atom *partner);
+ void add_atom_bonded_to (vect coords, int atomnum, Atom *at);
+
+ bool RemoveBond (ZNBond *bo);
+ bool RemoveAtom (Atom *at);
+
+
+
+
+};
+
+class Selection : public ZNMolecule {
+ public:
+ Selection ();
+ Atom * ZNAddAtomToSelection (Atom *at);
+ ZNBond * ZNAddBondToSelection (ZNBond *bo);
+ void deselect ();
+ void add_mol (ZNMolecule *mol);
+
+ void extend_to_residue ();
+ void extend_to_fragment ();
+ void extend_to_neighbours ();
+ void select_atom (Atom *at);
+ void select_atoms (vector <Atom *> to_add);
+ vector <ZNMolecule *>&get_molecules () {return molecules;};
+ private:
+ vector <ZNMolecule *> molecules;
+};
+
+
+class Fragment {
+public:
+ Fragment ();
+ void set_rotation (quaternion q) {_rotation_quaternion = q;};
+ quaternion get_rotation () {return _rotation_quaternion;};
+ void set_translation (vect v) {_translation_vector = v;};
+ vect get_tranlation () {return _translation_vector;};
+ vect get_center () {return _center;};
+ void set_number (unsigned int n) {_number = n;};
+ unsigned int get_number () {return _number;};
+ unsigned int number_of_connections () {return _rotor_connections.size ();};
+ rotorConnection *get_rotor_connection (unsigned int i) {return _rotor_connections[i];};
+ void add_atom (Atom *at) {_atoms.push_back (at); _reference_coordinates.push_back (get_coordinates(at)); _last_coordinates.push_back (get_coordinates (at));};
+ void add_rotor_connection (rotorConnection *rc) {_rotor_connections.push_back (rc);};
+ unsigned int size () {return _atoms.size ();};
+ void set_visited (bool b) {_visited = b;};
+ bool get_visited () {return _visited;};
+ vector <Atom *>& get_atoms_list () {return _atoms;}
+ void clean_connections ();
+ void quaternion_rotate (vect center, quaternion quat);
+ void find_children () {_children.clear (); _children = all_children();}
+ void set_center () {_center = find_mass_center (_atoms);}
+ void reset_coordinates (bool complete = false) {
+ for (unsigned int i = 0; i < _atoms.size (); i++) {
+ _last_coordinates[i] = _reference_coordinates[i];
+ if (complete) set_coordinates (_atoms[i], _reference_coordinates[i]);
+ }
+ };
+ vector <Fragment *> get_children () {return _children;};
+ vector <Fragment *> all_children ();
+ vector <Fragment *> get_first_order_children ();
+ vector <rotorConnection *> get_connections () {return _rotor_connections;};
+private:
+ vector <rotorConnection *> _rotor_connections;
+ quaternion _rotation_quaternion;
+ vect _translation_vector;
+ vect _center;
+ bool _visited;
+ vector<Atom*> _atoms;
+ vector<vect> _reference_coordinates, _last_coordinates;
+ vector<Fragment *> _children;
+ unsigned int _number;
+
+};
+
+/*
+class Ring {
+public:
+ int kekule_type; //marks the order in which kekule structures are found
+ Ring ();
+ vector<Atom*> atoms;
+ vector<ZNBond*> bonds;
+ Atom *alpha_atom;
+ bool aromatic, IM_CAT, N5ANION;
+ vect center;
+ unsigned int count (int an);
+ void test_aromaticity ();
+ void test_kekule_aromaticity ();
+ void find_kekule ();
+ void find_kekule_pseudoaromatic ();
+ void complete_kekule ();
+ bool all_aromatic ();
+
+};
+*/
+
+
+ vect find_mass_center (vector<Atom*>& atv);
+#endif
+
diff --git a/headers/actions.h b/headers/actions.h
new file mode 100644
index 0000000..1676ecd
--- /dev/null
+++ b/headers/actions.h
@@ -0,0 +1,86 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef ACTIONS_H
+#define ACTIONS_H
+
+
+#include "ZNdata.h"
+#include "obabel_includes.h"
+
+class Actions {
+ public:
+ Actions (Data *dat);
+
+
+ double compute_total_energy (ZNMolecule *mol);
+ vector <double> compute_total_energy (Database *dat);
+
+ double compute_logP (ZNMolecule *mol);
+ vector <double> compute_logP (Database *dat);
+
+
+ void reprotonate (ZNMolecule *mol, double ph = 7.4);
+ void reprotonate (Database *dat, double ph = 7.4);
+
+ void minimise (ZNMolecule *mol);
+ void minimise (Database *dat);
+
+ void change_display_style (Database *dat, int, int, int);
+ void change_display_style (ZNMolecule *mol, int, int, int);
+
+ void hide_hydrogens (ZNMolecule *mol);
+ void hide_hydrogens (Database *dat);
+
+ void hide_nonpolar_hydrogens (ZNMolecule *mol);
+ void hide_nonpolar_hydrogens (Database *dat);
+
+ void hide_all_atoms (ZNMolecule *mol);
+ void hide_all_atoms (Database *dat);
+
+ void show_all_atoms (ZNMolecule *mol);
+ void show_all_atoms (Database *dat);
+
+
+ void apply_color_masks (vector <color_mask> masks, ZNMolecule *mol);
+ void apply_color_masks (vector <color_mask> masks, Database *dat);
+
+ void save_session_as (string filename);
+ void load_session (string filename);
+ void save_as (ZNMolecule *mol, string filename);
+ void save_as (Database *dat, string filename);
+ void save_csv (Database *dat, string filename);
+
+ void set_scores_from_charges (ZNMolecule *mol);
+ void set_scores_from_charges (Database *dat);
+
+
+ private:
+ Data *data;
+};
+
+
+
+
+
+
+
+
+
+#endif
+
diff --git a/headers/arcball.h b/headers/arcball.h
new file mode 100644
index 0000000..6c6f144
--- /dev/null
+++ b/headers/arcball.h
@@ -0,0 +1,451 @@
+
+
+#ifndef ARCBALL_H
+#define ARCBALL_H
+#include <math.h>
+#include <assert.h>
+#include "constants.h"
+
+
+ typedef union Tuple2f_t
+ {
+ struct
+ {
+ GLfloat X, Y;
+ } s;
+
+ GLfloat T[2];
+ } Tuple2fT;
+
+ typedef union Tuple3f_t
+ {
+ struct
+ {
+ GLfloat X, Y, Z;
+ } s;
+
+ GLfloat T[3];
+ } Tuple3fT; //A generic 3-element tuple that is represented by single precision-floating point x,y,z coordinates.
+
+ typedef union Tuple4f_t
+ {
+ struct
+ {
+ GLfloat X, Y, Z, W;
+ } s;
+
+ GLfloat T[4];
+ } Tuple4fT; //A 4-element tuple represented by single-precision floating point x,y,z,w coordinates.
+
+ typedef union Matrix3f_t
+ {
+ struct
+ {
+ //column major
+ union { GLfloat M00; GLfloat XX; GLfloat SX; }; //XAxis.X && Scale X
+ union { GLfloat M10; GLfloat XY; }; //XAxis.Y
+ union { GLfloat M20; GLfloat XZ; }; //XAxis.Z
+ union { GLfloat M01; GLfloat YX; }; //YAxis.X
+ union { GLfloat M11; GLfloat YY; GLfloat SY; }; //YAxis.Y && Scale Y
+ union { GLfloat M21; GLfloat YZ; }; //YAxis.Z
+ union { GLfloat M02; GLfloat ZX; }; //ZAxis.X
+ union { GLfloat M12; GLfloat ZY; }; //ZAxis.Y
+ union { GLfloat M22; GLfloat ZZ; GLfloat SZ; }; //ZAxis.Z && Scale Z
+ } s;
+ GLfloat M[9];
+ } Matrix3fT; //A single precision floating point 3 by 3 matrix.
+
+ typedef union Matrix4f_t
+ {
+ struct
+ {
+ //column major
+ union { GLfloat M00; GLfloat XX; GLfloat SX; }; //XAxis.X && Scale X
+ union { GLfloat M10; GLfloat XY; }; //XAxis.Y
+ union { GLfloat M20; GLfloat XZ; }; //XAxis.Z
+ union { GLfloat M30; GLfloat XW; }; //XAxis.W
+ union { GLfloat M01; GLfloat YX; }; //YAxis.X
+ union { GLfloat M11; GLfloat YY; GLfloat SY; }; //YAxis.Y && Scale Y
+ union { GLfloat M21; GLfloat YZ; }; //YAxis.Z
+ union { GLfloat M31; GLfloat YW; }; //YAxis.W
+ union { GLfloat M02; GLfloat ZX; }; //ZAxis.X
+ union { GLfloat M12; GLfloat ZY; }; //ZAxis.Y
+ union { GLfloat M22; GLfloat ZZ; GLfloat SZ; }; //ZAxis.Z && Scale Z
+ union { GLfloat M32; GLfloat ZW; }; //ZAxis.W
+ union { GLfloat M03; GLfloat TX; }; //Trans.X
+ union { GLfloat M13; GLfloat TY; }; //Trans.Y
+ union { GLfloat M23; GLfloat TZ; }; //Trans.Z
+ union { GLfloat M33; GLfloat TW; GLfloat SW; }; //Trans.W && Scale W
+ } s;
+ GLfloat M[16];
+ } Matrix4fT; //A single precision floating point 4 by 4 matrix.
+
+
+//"Inherited" types
+#define Point2fT Tuple2fT //A 2 element point that is represented by single precision floating point x,y coordinates.
+
+#define Quat4fT Tuple4fT //A 4 element unit quaternion represented by single precision floating point x,y,z,w coordinates.
+
+#define Vector2fT Tuple2fT //A 2-element vector that is represented by single-precision floating point x,y coordinates.
+#define Vector3fT Tuple3fT //A 3-element vector that is represented by single-precision floating point x,y,z coordinates.
+
+//Custom math, || speed overrides
+#define FuncSqrt sqrtf
+
+//utility macros
+//assuming IEEE-754(GLfloat), which i believe has max precision of 7 bits
+# define Epsilon 1.0e-5
+
+//Math functions
+
+ /**
+ * Sets the value of this tuple to the vector sum of itself && tuple t1.
+ * @param t1 the other tuple
+ */
+ inline
+ static void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1)
+ {
+ assert(NewObj && t1);
+
+ NewObj->s.X += t1->s.X;
+ NewObj->s.Y += t1->s.Y;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector difference of itself && tuple t1 (this = this - t1).
+ * @param t1 the other tuple
+ */
+ inline
+ static void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1)
+ {
+ assert(NewObj && t1);
+
+ NewObj->s.X -= t1->s.X;
+ NewObj->s.Y -= t1->s.Y;
+ }
+
+ /**
+ * Sets this vector to be the vector cross product of vectors v1 && v2.
+ * @param v1 the first vector
+ * @param v2 the second vector
+ */
+ inline
+ static void Vector3fCross(Vector3fT* NewObj, const Vector3fT* v1, const Vector3fT* v2)
+ {
+ Vector3fT Result; //safe not to initialize
+
+ assert(NewObj && v1 && v2);
+
+ // store on stack once for aliasing-safty
+ // i.e. safe when a.cross(a, b)
+
+ Result.s.X = (v1->s.Y * v2->s.Z) - (v1->s.Z * v2->s.Y);
+ Result.s.Y = (v1->s.Z * v2->s.X) - (v1->s.X * v2->s.Z);
+ Result.s.Z = (v1->s.X * v2->s.Y) - (v1->s.Y * v2->s.X);
+
+ //copy result back
+ *NewObj = Result;
+ }
+
+ /**
+ * Computes the dot product of the this vector && vector v1.
+ * @param v1 the other vector
+ */
+ inline
+ static GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1)
+ {
+ assert(NewObj && v1);
+
+ return (NewObj->s.X * v1->s.X) +
+ (NewObj->s.Y * v1->s.Y) +
+ (NewObj->s.Z * v1->s.Z);
+ }
+
+ /**
+ * Returns the squared length of this vector.
+ * @return the squared length of this vector
+ */
+ inline
+ static GLfloat Vector3fLengthSquared(const Vector3fT* NewObj)
+ {
+ assert(NewObj);
+
+ return (NewObj->s.X * NewObj->s.X) +
+ (NewObj->s.Y * NewObj->s.Y) +
+ (NewObj->s.Z * NewObj->s.Z);
+ }
+
+ /**
+ * Returns the length of this vector.
+ * @return the length of this vector
+ */
+ inline
+ static GLfloat Vector3fLength(const Vector3fT* NewObj)
+ {
+ assert(NewObj);
+
+ return FuncSqrt(Vector3fLengthSquared(NewObj));
+ }
+
+ inline
+ static void Matrix3fSetZero(Matrix3fT* NewObj)
+ {
+ NewObj->s.M00 = NewObj->s.M01 = NewObj->s.M02 =
+ NewObj->s.M10 = NewObj->s.M11 = NewObj->s.M12 =
+ NewObj->s.M20 = NewObj->s.M21 = NewObj->s.M22 = 0.0f;
+ }
+
+ /**
+ * Sets this Matrix3 to identity.
+ */
+ inline
+ static void Matrix3fSetIdentity(Matrix3fT* NewObj)
+ {
+ Matrix3fSetZero(NewObj);
+
+ //then set diagonal as 1
+ NewObj->s.M00 =
+ NewObj->s.M11 =
+ NewObj->s.M22 = 1.0f;
+ }
+
+ /**
+ * Sets the value of this matrix to the matrix conversion of the
+ * quaternion argument.
+ * @param q1 the quaternion to be converted
+ */
+ //$hack this can be optimized some(if s == 0)
+ inline
+ static void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1)
+ {
+ GLfloat n, s;
+ GLfloat xs, ys, zs;
+ GLfloat wx, wy, wz;
+ GLfloat xx, xy, xz;
+ GLfloat yy, yz, zz;
+
+ assert(NewObj && q1);
+
+ n = (q1->s.X * q1->s.X) + (q1->s.Y * q1->s.Y) + (q1->s.Z * q1->s.Z) + (q1->s.W * q1->s.W);
+ s = (n > 0.0f) ? (2.0f / n) : 0.0f;
+
+ xs = q1->s.X * s; ys = q1->s.Y * s; zs = q1->s.Z * s;
+ wx = q1->s.W * xs; wy = q1->s.W * ys; wz = q1->s.W * zs;
+ xx = q1->s.X * xs; xy = q1->s.X * ys; xz = q1->s.X * zs;
+ yy = q1->s.Y * ys; yz = q1->s.Y * zs; zz = q1->s.Z * zs;
+
+ NewObj->s.XX = 1.0f - (yy + zz); NewObj->s.YX = xy - wz; NewObj->s.ZX = xz + wy;
+ NewObj->s.XY = xy + wz; NewObj->s.YY = 1.0f - (xx + zz); NewObj->s.ZY = yz - wx;
+ NewObj->s.XZ = xz - wy; NewObj->s.YZ = yz + wx; NewObj->s.ZZ = 1.0f - (xx + yy);
+ }
+
+ /**
+ * Sets the value of this matrix to the result of multiplying itself
+ * with matrix m1.
+ * @param m1 the other matrix
+ */
+ inline
+ static void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1)
+ {
+ Matrix3fT Result; //safe not to initialize
+
+ assert(NewObj && m1);
+
+ // alias-safe way.
+ Result.s.M00 = (NewObj->s.M00 * m1->s.M00) + (NewObj->s.M01 * m1->s.M10) + (NewObj->s.M02 * m1->s.M20);
+ Result.s.M01 = (NewObj->s.M00 * m1->s.M01) + (NewObj->s.M01 * m1->s.M11) + (NewObj->s.M02 * m1->s.M21);
+ Result.s.M02 = (NewObj->s.M00 * m1->s.M02) + (NewObj->s.M01 * m1->s.M12) + (NewObj->s.M02 * m1->s.M22);
+
+ Result.s.M10 = (NewObj->s.M10 * m1->s.M00) + (NewObj->s.M11 * m1->s.M10) + (NewObj->s.M12 * m1->s.M20);
+ Result.s.M11 = (NewObj->s.M10 * m1->s.M01) + (NewObj->s.M11 * m1->s.M11) + (NewObj->s.M12 * m1->s.M21);
+ Result.s.M12 = (NewObj->s.M10 * m1->s.M02) + (NewObj->s.M11 * m1->s.M12) + (NewObj->s.M12 * m1->s.M22);
+
+ Result.s.M20 = (NewObj->s.M20 * m1->s.M00) + (NewObj->s.M21 * m1->s.M10) + (NewObj->s.M22 * m1->s.M20);
+ Result.s.M21 = (NewObj->s.M20 * m1->s.M01) + (NewObj->s.M21 * m1->s.M11) + (NewObj->s.M22 * m1->s.M21);
+ Result.s.M22 = (NewObj->s.M20 * m1->s.M02) + (NewObj->s.M21 * m1->s.M12) + (NewObj->s.M22 * m1->s.M22);
+
+ //copy result back to this
+ *NewObj = Result;
+ }
+
+ inline
+ static void Matrix4fSetRotationScaleFromMatrix4f(Matrix4fT* NewObj, const Matrix4fT* m1)
+ {
+ assert(NewObj && m1);
+
+ NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX;
+ NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY;
+ NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;
+ }
+
+ /**
+ * Performs SVD on this matrix && gets scale && rotation.
+ * Rotation is placed into rot3, && rot4.
+ * @param rot3 the rotation factor(Matrix3d). if null, ignored
+ * @param rot4 the rotation factor(Matrix4) only upper 3x3 elements are changed. if null, ignored
+ * @return scale factor
+ */
+ inline
+ static GLfloat Matrix4fSVD(const Matrix4fT* NewObj, Matrix3fT* rot3, Matrix4fT* rot4)
+ {
+ GLfloat s, n;
+
+ assert(NewObj);
+
+ // this is a simple svd.
+ // Not complete but fast && reasonable.
+ // See comment in Matrix3d.
+
+ s = FuncSqrt(
+ ( (NewObj->s.XX * NewObj->s.XX) + (NewObj->s.XY * NewObj->s.XY) + (NewObj->s.XZ * NewObj->s.XZ) +
+ (NewObj->s.YX * NewObj->s.YX) + (NewObj->s.YY * NewObj->s.YY) + (NewObj->s.YZ * NewObj->s.YZ) +
+ (NewObj->s.ZX * NewObj->s.ZX) + (NewObj->s.ZY * NewObj->s.ZY) + (NewObj->s.ZZ * NewObj->s.ZZ) ) / 3.0f );
+
+ if (rot3) //if pointer not null
+ {
+ //this->getRotationScale(rot3);
+ rot3->s.XX = NewObj->s.XX; rot3->s.XY = NewObj->s.XY; rot3->s.XZ = NewObj->s.XZ;
+ rot3->s.YX = NewObj->s.YX; rot3->s.YY = NewObj->s.YY; rot3->s.YZ = NewObj->s.YZ;
+ rot3->s.ZX = NewObj->s.ZX; rot3->s.ZY = NewObj->s.ZY; rot3->s.ZZ = NewObj->s.ZZ;
+
+ // zero-div may occur.
+
+ n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) +
+ (NewObj->s.XY * NewObj->s.XY) +
+ (NewObj->s.XZ * NewObj->s.XZ) );
+ rot3->s.XX *= n;
+ rot3->s.XY *= n;
+ rot3->s.XZ *= n;
+
+ n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) +
+ (NewObj->s.YY * NewObj->s.YY) +
+ (NewObj->s.YZ * NewObj->s.YZ) );
+ rot3->s.YX *= n;
+ rot3->s.YY *= n;
+ rot3->s.YZ *= n;
+
+ n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) +
+ (NewObj->s.ZY * NewObj->s.ZY) +
+ (NewObj->s.ZZ * NewObj->s.ZZ) );
+ rot3->s.ZX *= n;
+ rot3->s.ZY *= n;
+ rot3->s.ZZ *= n;
+ }
+
+ if (rot4) //if pointer not null
+ {
+ if (rot4 != NewObj)
+ {
+ Matrix4fSetRotationScaleFromMatrix4f(rot4, NewObj); // private method
+ }
+
+ // zero-div may occur.
+
+ n = 1.0f / FuncSqrt( (NewObj->s.XX * NewObj->s.XX) +
+ (NewObj->s.XY * NewObj->s.XY) +
+ (NewObj->s.XZ * NewObj->s.XZ) );
+ rot4->s.XX *= n;
+ rot4->s.XY *= n;
+ rot4->s.XZ *= n;
+
+ n = 1.0f / FuncSqrt( (NewObj->s.YX * NewObj->s.YX) +
+ (NewObj->s.YY * NewObj->s.YY) +
+ (NewObj->s.YZ * NewObj->s.YZ) );
+ rot4->s.YX *= n;
+ rot4->s.YY *= n;
+ rot4->s.YZ *= n;
+
+ n = 1.0f / FuncSqrt( (NewObj->s.ZX * NewObj->s.ZX) +
+ (NewObj->s.ZY * NewObj->s.ZY) +
+ (NewObj->s.ZZ * NewObj->s.ZZ) );
+ rot4->s.ZX *= n;
+ rot4->s.ZY *= n;
+ rot4->s.ZZ *= n;
+ }
+
+ return s;
+ }
+
+ inline
+ static void Matrix4fSetRotationScaleFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1)
+ {
+ assert(NewObj && m1);
+
+ NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX;
+ NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY;
+ NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;
+ }
+
+ inline
+ static void Matrix4fMulRotationScale(Matrix4fT* NewObj, GLfloat scale)
+ {
+ assert(NewObj);
+
+ NewObj->s.XX *= scale; NewObj->s.YX *= scale; NewObj->s.ZX *= scale;
+ NewObj->s.XY *= scale; NewObj->s.YY *= scale; NewObj->s.ZY *= scale;
+ NewObj->s.XZ *= scale; NewObj->s.YZ *= scale; NewObj->s.ZZ *= scale;
+ }
+
+ /**
+ * Sets the rotational component (upper 3x3) of this matrix to the matrix
+ * values in the T precision Matrix3d argument; the other elements of
+ * this matrix are unchanged; a singular value decomposition is performed
+ * on this object's upper 3x3 matrix to factor out the scale, then this
+ * object's upper 3x3 matrix components are replaced by the passed rotation
+ * components, && then the scale is reapplied to the rotational
+ * components.
+ * @param m1 T precision 3x3 matrix
+ */
+ inline
+ static void Matrix4fSetRotationFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1)
+ {
+ GLfloat scale;
+
+ assert(NewObj && m1);
+
+ scale = Matrix4fSVD(NewObj, NULL, NULL);
+
+ Matrix4fSetRotationScaleFromMatrix3f(NewObj, m1);
+ Matrix4fMulRotationScale(NewObj, scale);
+ }
+
+// 8<--Snip here if you have your own math types/funcs-->8
+
+ typedef class ArcBall_t
+ {
+ protected:
+ inline
+ void _mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const;
+
+ public:
+ //Create/Destroy
+ ArcBall_t(GLfloat NewWidth, GLfloat NewHeight);
+ ~ArcBall_t() { /* nothing to do */ };
+
+ //Set new bounds
+ inline
+ void setBounds(GLfloat NewWidth, GLfloat NewHeight)
+ {
+ assert((NewWidth > 1.0f) && (NewHeight > 1.0f));
+
+ //Set adjustment factor for width/height
+ this->AdjustWidth = 1.0f / ((NewWidth - 1.0f) * 0.5f);
+ this->AdjustHeight = 1.0f / ((NewHeight - 1.0f) * 0.5f);
+ }
+
+ //Mouse down
+ void click(const Point2fT* NewPt);
+
+ //Mouse drag, calculate rotation
+ void drag(const Point2fT* NewPt, Quat4fT* NewRot);
+ void map_vector_on_vector (Vector3fT v1, Vector3fT v2, Quat4fT *NewRot);
+ // protected:
+ Vector3fT StVec; //Saved click vector
+ Vector3fT EnVec; //Saved drag vector
+ GLfloat AdjustWidth; //Mouse bounds width
+ GLfloat AdjustHeight; //Mouse bounds height
+
+ } ArcBallT;
+
+#endif
+
diff --git a/headers/builder.h b/headers/builder.h
new file mode 100644
index 0000000..bb8c173
--- /dev/null
+++ b/headers/builder.h
@@ -0,0 +1,84 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef BUILDER_H
+#define BUILDER_H
+
+#include "ZNmolecule.h"
+#include "maths.h"
+#include "constants.h"
+#include "ZNdata.h"
+#include "ddwin.h"
+
+
+class DDWin;
+class vect;
+class Builder {
+ public:
+ Builder (DDWin *ddw);
+
+ void set_magic_pencil_atomic_number (int atomn);
+ void save_Hs (Atom *at, vector <Atom *> &prev_ats, vector <ZNBond *> &prev_bonds);
+ void add_Hs (Atom *at, vector <Atom *> &atoms, vector <ZNBond *> &bonds);
+ Atom* new_atom (vect coord, int atomn);
+ ZNBond *new_bond (Atom *at1, Atom *at2, int order=1);
+ void add_atom (int atnum);
+ void add_mol (string str);
+ void add_bond (int order);
+ Atom * last_magic_pencil_atom, *start_magic_pencil_atom;
+ void set_aromatic (Ring *ring);
+ void set_non_aromatic (Ring *ring);
+ void set_bond (ZNBond *bo, int order);
+ void mutate_atom_to (Atom *at, unsigned int atomnum = 6 );
+ void redefine_mol (ZNMolecule * mol);
+ Atom * add_atom_bonded_to (vect coord, int atmnum, Atom *at);
+ int magic_pencil_atomic_number;
+
+ void delete_atom (Atom *at);
+ void delete_bond (ZNBond *bo);
+
+ void delete_Hs (Atom *at);
+ void delete_Hs (ZNMolecule *mol);
+
+
+ void add_fragment (string str);
+
+ DDWin * ddwin;
+
+ bool find_target ();
+
+
+ void add_H (Atom *at, vector <Atom *> &add_atoms, vector <ZNBond *> &add_bonds);
+ void delete_Hs (Atom *at, vector <Atom *> &del_atoms, vector <ZNBond *> &del_bonds);
+
+ void one_H (Atom *center, vect &coord2);
+ void two_tetrahedral_coordinates (Atom *root1, Atom *root2, Atom *center, vect &coord2, vect &coord3);
+ void three_coordinates (Atom * root, Atom *center, vect &coord2, vect &coord3);
+ void four_coordinates (Atom * root, Atom *center, vect &coord2, vect &coord3, vect &coord4);
+
+
+
+
+ int mcounter;
+
+};
+
+
+
+#endif
diff --git a/headers/chemscore.h b/headers/chemscore.h
new file mode 100644
index 0000000..7f1bcb8
--- /dev/null
+++ b/headers/chemscore.h
@@ -0,0 +1,390 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef CHEMSCORE_H
+#define CHEMSCORE_H
+
+
+#define ZN_CS_DONOR 0
+#define ZN_CS_ACCEPTOR 1
+#define ZN_CS_BOTH 2
+#define ZN_CS_POLAR 3
+#define ZN_CS_NONPOLAR 4
+#define ZN_CS_METAL 5
+
+#include "FF.h"
+#include "obabel_includes.h"
+#include "datagrid.h"
+
+float f (float x, float x1, float x2);
+
+class ChemscoreHBInteraction : public ForceFieldInteraction
+{
+ public:
+ Atom * root;
+ float value ();
+ inline bool isElectrostatic () {return true;};
+ inline bool isHbond () {return true;};
+};
+
+
+class ChemscoreLiInteraction : public ForceFieldInteraction
+{
+ public:
+ bool metal;
+ float value ();
+};
+
+
+class ChemscoreClInteraction : public ForceFieldInteraction
+{
+ public:
+ int type;
+ float value ();
+};
+
+
+
+
+
+
+class Chemscore : public ForceField {
+
+public:
+
+ Chemscore ();
+ void clear_nonbonded_interactions ();
+ void load_mol (ZNMolecule *mol);
+ void load_grids (vect cent, double rad);
+ // void load_internal_interactions ();
+
+ void load_nonbonded_interactions_for_atom (Atom *a, queue <ForceFieldInteraction *> *queue = 0) {
+
+ ZNMolecule *mol = (ZNMolecule *) a -> GetParent ();
+ objectList<Atom*>* nbAtoms = far_grid->getNeighborObjects(get_coordinates (&*a));
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ // cerr <<"load nonbonded inter"<<neighbours.size ()<<endl;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ Atom * root = NULL;
+ bool hb = false;
+ bool li = false;
+ bool me = false;
+ int ltype = getChemscoretype (&*a);
+ int ptype = getChemscoretype (neighbours[j]);
+ if (ltype == ZN_CS_DONOR) {
+ if (ptype == ZN_CS_ACCEPTOR) {
+ hb = true;
+ OBBondIterator i;
+ root = a -> BeginNbrAtom (i);
+ }
+ }
+ else if (ltype == ZN_CS_ACCEPTOR) {
+ if (ptype == ZN_CS_DONOR) {
+ hb = true;
+ OBBondIterator i;
+ root = neighbours[j] -> BeginNbrAtom (i);
+ }
+ else if (ptype == ZN_CS_METAL) {
+ me = true;
+ }
+ }
+ else if (ltype == ZN_CS_NONPOLAR) {
+
+ if (ptype == ZN_CS_NONPOLAR) {
+ li = true;
+ }
+ }
+
+ if (hb) {
+ ChemscoreHBInteraction *hbint = new ChemscoreHBInteraction;
+ hbint->at1 = &*a;
+ hbint->at2=neighbours[j];
+ hbint->root = root;
+ if (queue) queue -> push (hbint);
+ else HBInteractions.push_back (hbint);
+ }
+ else if (li || me) {
+ ChemscoreLiInteraction *liint = new ChemscoreLiInteraction;
+ liint->at1 = &*a;
+ liint->at2 = neighbours[j];
+ liint->metal = me;
+ if (queue) queue -> push (liint);
+ else LiInteractions.push_back (liint);
+ }
+ //clash
+ // if (neighbours[j] -> GetAtomicNum ()==1 || a -> GetAtomicNum () ==1) continue;
+ ChemscoreClInteraction *clint = new ChemscoreClInteraction;
+ clint->at1 = &*a;
+ clint->at2=neighbours[j];
+ if (ptype == ZN_CS_METAL && ltype == ZN_CS_ACCEPTOR) clint->type = 1;
+ else if ((clint->at1->GetAtomicNum () ==7 || clint->at1->GetAtomicNum () ==8) && (clint->at2->GetAtomicNum () ==7 || clint->at2->GetAtomicNum () ==8)) {
+ if (mol -> bonded_to (clint->at1,1, 1) || mol -> bonded_to (clint->at2,1,1)) clint->type = 0;
+ }
+ else clint->type = 2;
+ if (queue) queue -> push (clint);
+ else ClInteractions.push_back (clint);
+
+
+
+ }
+ }
+
+
+ }
+
+ void load_nonbonded_interactions () {
+ FOR_ATOMS_OF_MOL (a, target_mol) {
+ load_nonbonded_interactions_for_atom (&*a);
+ }
+ };
+ void update ();
+
+
+ double compute_total_energy () {
+ double E = 0., Ehb = 0., Ecl = 0., Eli = 0., Ehb2 = 0., Ecl2 = 0., Eli2 = 0.;
+
+ for (unsigned int i = 0; i < HBInteractions.size (); i++) {
+ E += HBInteractions [i] ->value ();
+ // Ehb += HBInteractions [i] ->value ();
+ }
+ for (unsigned int i = 0; i < ClInteractions.size (); i++) {
+ E += ClInteractions [i] ->value ();
+ // Ecl += ClInteractions [i] ->value ();
+ }
+ for (unsigned int i = 0; i < LiInteractions.size (); i++) {
+ E += LiInteractions [i] ->value ();
+ // Eli += LiInteractions [i] ->value ();
+ }
+ return E;
+
+ /*
+ FOR_ATOMS_OF_MOL (a, target_mol) {
+ vect v = get_coordinates (&*a);
+ int atype = getChemscoretype (&*a);
+ if (atype == ZN_CS_NONPOLAR) {
+
+ Eli2 += LiGrid -> get_value (v.x(), v.y(), v.z());
+ }
+ else if (atype == ZN_CS_ACCEPTOR) {
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ ChemscoreHBInteraction *hbint = new ChemscoreHBInteraction;
+ hbint->at1 = &*a;
+ vector <Atom *> neighbours = nbAtoms->objects;
+
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ if (getChemscoretype (neighbours[j]) == ZN_CS_DONOR) {
+ OBBondIterator i;
+ hbint ->root = neighbours[j] -> BeginNbrAtom (i);
+ hbint ->at2 = neighbours[j];
+ Ehb2 += hbint -> value ();
+ }
+ }
+ delete hbint;
+ }
+ }
+ else if (atype == ZN_CS_DONOR) {
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ ChemscoreHBInteraction *hbint = new ChemscoreHBInteraction;
+ hbint->at1 = &*a;
+ vector <Atom *> neighbours = nbAtoms->objects;
+ OBBondIterator i;
+ hbint ->root = a -> BeginNbrAtom (i);
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ if (getChemscoretype (neighbours[j]) == ZN_CS_ACCEPTOR) {
+ hbint ->at2 = neighbours[j];
+ Ehb2 += hbint -> value ();
+ }
+ }
+ delete hbint;
+ }
+ }
+
+ else {}
+ if (a ->GetAtomicNum () !=1) {
+ Ecl2 += ClGrid ->get_value (v.x(), v.y(), v.z());
+ }
+ }
+ // cerr <<"HB = "<<Ehb<<" Cl = "<<Ecl<<" Li = "<<Eli<<endl;
+ // cerr <<"HB = "<<Ehb2<<" Cl = "<<Ecl2<<" Li = "<<Eli2<<endl;
+
+ return Ehb2* + Ecl2 + Eli2;
+ */
+ };
+ void initialize_mol (ZNMolecule *mol);
+
+
+ void compute_forces ();
+
+
+
+ vector<ChemscoreClInteraction *> ClInteractions;
+ vector<ChemscoreHBInteraction *> HBInteractions;
+ vector<ChemscoreLiInteraction *> LiInteractions;
+
+ float Electrostatic_potential (vect v) {
+ float E = 0.;
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ float q = neighbours[j] -> GetPartialCharge ();
+
+ if (q) {
+
+ float r = dist (v, get_coordinates (neighbours[j]));
+ float e = 332.0716;
+ E += q*e/(r);
+ }
+ }
+ }
+ return E;
+ };
+
+
+ float Donorvalue (vect v) {
+ float E = 0.;
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ int ptype = getChemscoretype (neighbours[j]);
+
+ if (ptype == ZN_CS_ACCEPTOR) {
+
+ float r = dist (v, get_coordinates (neighbours[j]));
+ float dghbond = -3.34f;
+ float r0 = 1.85f;
+ float drab = r-r0;
+ if (drab < 0) drab = -drab;
+ float dr1 = 0.25f;
+ float dr2 = 0.65f;
+
+ E += dghbond * f(drab, dr1, dr2);
+ }
+ }
+ }
+ return E;
+ };
+
+
+
+
+
+ float Acceptorvalue (vect v) {
+ float E = 0.;
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ int ptype = getChemscoretype (neighbours[j]);
+
+ if (ptype == ZN_CS_DONOR) {
+
+ float r = dist (v, get_coordinates (neighbours[j]));
+ float dghbond = -3.34f;
+ float r0 = 1.85f;
+ float drab = r-r0;
+ if (drab < 0) drab = -drab;
+ float dr1 = 0.25f;
+ float dr2 = 0.65f;
+
+ E += dghbond * f(drab, dr1, dr2);
+ }
+ }
+ }
+ return E;
+ };
+
+
+
+
+ float Livalue (vect v) {
+ float E = 0.;
+
+ Atom *dummy = new Atom;
+ dummy -> SetVector (v);
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ ChemscoreLiInteraction *liint = new ChemscoreLiInteraction;
+ liint ->metal = false;
+ liint->at1 = dummy;
+ vector <Atom *> neighbours = nbAtoms->objects;
+
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+ int ptype = getChemscoretype (neighbours[j]);
+ if (ptype == ZN_CS_NONPOLAR) {
+
+
+ liint->at2 = neighbours[j];
+ E += liint -> value ();
+
+ }
+ }
+ delete liint;
+
+ }
+ delete dummy;
+ // cerr << E << "energy" << endl;
+ return E;
+
+ };
+
+
+ float Clvalue (vect v) {
+ float E = 0.;
+
+ Atom *dummy = new Atom;
+ dummy -> SetVector (v);
+ objectList<Atom*>* nbAtoms = far_grid ->getNeighborObjects(v);
+ if (nbAtoms) {
+ ChemscoreClInteraction *clint = new ChemscoreClInteraction;
+ clint ->type = 2;
+ clint->at1 = dummy;
+ vector <Atom *> neighbours = nbAtoms->objects;
+
+ for (unsigned int j=0; j<neighbours.size (); j++) {
+
+ if (neighbours[j] ->GetAtomicNum () !=1) {
+ clint->at2 = neighbours[j];
+ E += clint -> value ();
+ }
+
+ }
+ delete clint;
+
+ }
+ delete dummy;
+ // cerr << E << "energy" << endl;
+ return E;
+
+ };
+
+
+ private:
+ int getChemscoretype (Atom *at);
+
+ DataGrid *LiGrid, *ClGrid;
+
+
+};
+
+#endif
diff --git a/headers/cmat.h b/headers/cmat.h
new file mode 100644
index 0000000..d186d81
--- /dev/null
+++ b/headers/cmat.h
@@ -0,0 +1,802 @@
+// Template Numerical Toolkit (TNT) for Linear Algebra
+//
+// BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
+// Please see http://math.nist.gov/tnt for updates
+//
+// R. Pozo
+// Mathematical and Computational Sciences Division
+// National Institute of Standards and Technology
+
+// Modified 6/2003 to make it work with new compilers.
+// P.L. (Anne) Shepherd
+
+// ***********************************************************
+// ****IMPORTANT NOTE:
+// I have modified this code so the overloaded reference
+// operator () has C-type 0-based indexing. This is
+// a CHANGE from the original, which uses Fortran-type
+// 1-based indexing. Any program that calls the operator
+// in this version of cmat.h expecting 1-based indexing,
+// or uses an old version of cmat.h and expects 0-based
+// indexing, will get BAD RESULTS. Please BE SURE
+// you know which version of cmat.h you are using and
+// which one you need to be using.
+// ----Anne Shepherd, 6/17/03 ********************
+// ***********************************************************
+
+// C compatible matrix: row-oriented, 0-based [i][j] and 1-based (i,j) indexing
+//
+// Chris Siefert's modified namespace free version - 5/26/99
+// function (row) has been added.
+// It returns the vector that contains that row.
+// function (col) has been added.
+// It returns the vector that contains that column.
+// Also, support for multiplication by a scalar has been added.
+// Support for Vector * Matrix acting as if the vector was a row
+// vector is added.
+
+//Since Mr. Pozo never did it, here is the complete catalog of outside
+//accessable Matrix operations:
+//
+// Matrix<T>& newsize(Subscript M, Subscript N) - resize matrix
+// operator T**(){ return row_;} - ???
+// Subscript size() const { return mn_; }
+// operator = Matrix
+// operator = scalar - assigns all elements to the scalar.
+// Subscript dim(Subscript d)
+// num_rows()
+// num_cols()
+// operator[](Subscript i)
+// operator()(Subscript i)
+// operator()(Subscript i, Subscript j)
+// ostream << Matrix
+// istream >> Matrix
+// Region operator()(const Index1D &I, const Index1D &J) - ???
+// Matrix + Matrix
+// Matrix - Matrix
+// mult_element(A,B) - element by element multiplication
+// transpose(A) - matrix transposition
+// Matrix * Matrix (also matmult)
+// matmult(C, B, A) - result stored in C
+// Matrix * Vector (also matmult)
+
+// Chris Siefert Additions:
+// row(i) - returns a Vector containing the ith row.
+// col(i) - returns a Vector containing the ith column.
+// Matrix * Scalar, Scalar * Matrix (also scalmult, 1st form only).
+// Vector * Matrix (also matmult). Pretends vector is a row vector.
+//
+// Modified 7/00 by Anne Shepherd to allow for different implementations
+// of the operators new and new[]. If your compiler does not support the
+// ANSI Standard try-catch syntax, compile with -DDOLD_ALLOC flag or just
+// #define DOLD_ALLOC in your file before including our files.
+
+#ifndef CMAT_H
+#define CMAT_H
+
+#define DOLD_ALLOC
+#define OLD_LIBC
+
+
+#ifndef DOLD_ALLOC
+#include <new>
+#endif
+
+#include "vec.h"
+#include <cstdlib>
+#include <cassert>
+
+#include <iostream>
+#ifdef TNT_USE_REGIONS
+#include "region2d.h"
+#endif
+
+#include <iomanip>
+#define D_PRECISION 16
+
+
+//namespace TNT
+//{
+//typedef long Subscript;
+
+template <class T>
+class Matrix
+{
+
+
+ public:
+
+ typedef Subscript size_type;
+ typedef T value_type;
+ typedef T element_type;
+ typedef T* pointer;
+ typedef T* iterator;
+ typedef T& reference;
+ typedef const T* const_iterator;
+ typedef const T& const_reference;
+
+ Subscript lbound() const { return 1;}
+
+ protected:
+ Subscript m_;
+ Subscript n_;
+ Subscript mn_; // total size
+ T* v_;
+ T** row_;
+ T* vm1_ ; // these point to the same data, but are 1-based
+ T** rowm1_;
+
+ // internal helper function to create the array
+ // of row pointers
+
+ void initialize(Subscript M, Subscript N)
+ {
+ mn_ = M*N;
+ m_ = M;
+ n_ = N;
+
+#ifdef DOLD_ALLOC
+ v_ = new T[mn_];
+ row_ = new T*[M];
+ rowm1_ = new T*[M];
+
+ assert(v_ != NULL);
+ assert(row_ != NULL);
+ assert(rowm1_ != NULL);
+#else
+ try{
+ v_ = new T[mn_];
+ } //try
+ catch ( bad_alloc exception ) {
+ cerr << "Memory allocation failed in file cmat.h, method initialize()."
+ << "Exiting with value 1.\n";
+ exit(1);
+ } //catch
+
+ try{
+ row_ = new T*[M];
+ } //try
+ catch (bad_alloc exception) {
+ cerr << "Memory allocation failed in file cmat.h, method initialize()."
+ << "Exiting with value 1.\n";
+ exit(1);
+ } //catch
+
+ try{
+ rowm1_ = new T*[M];
+ } //try
+ catch ( bad_alloc exception ) {
+ cerr << "Memory allocation failed in file cmat.h, method initialize()."
+ << "Exiting with value 1.\n";
+ exit(1);
+ } //catch
+#endif
+
+ T* p = v_;
+ vm1_ = v_ - 1;
+ for (Subscript i=0; i<M; i++)
+ {
+ row_[i] = p;
+ rowm1_[i] = p-1;
+ p += N ;
+
+ }
+
+ rowm1_ -- ; // compensate for 1-based offset
+ }
+
+ void copy(const T* v)
+ {
+ Subscript N = m_ * n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = v[i];
+ v_[i+1] = v[i+1];
+ v_[i+2] = v[i+2];
+ v_[i+3] = v[i+3];
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = v[i];
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = v[i];
+#endif
+ }
+
+ void set(const T& val)
+ {
+ Subscript N = m_ * n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = val;
+ v_[i+1] = val;
+ v_[i+2] = val;
+ v_[i+3] = val;
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = val;
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = val;
+
+#endif
+ }
+
+
+
+ void destroy()
+ {
+ /* do nothing, if no memory has been previously allocated */
+ if (v_ == NULL) return ;
+
+ /* if we are here, then matrix was previously allocated */
+ if (v_ != NULL) delete [] (v_);
+ if (row_ != NULL) delete [] (row_);
+
+ /* return rowm1_ back to original value */
+ rowm1_ ++;
+ if (rowm1_ != NULL ) delete [] (rowm1_);
+ }
+
+
+ public:
+
+ operator T**(){ return row_; }
+ operator T**() const { return row_; }
+
+
+ Subscript size() const { return mn_; }
+
+ // constructors
+
+ Matrix() : m_(0), n_(0), mn_(0), v_(0), row_(0), vm1_(0), rowm1_(0) {};
+
+ Matrix(const Matrix<T> &A)
+ {
+ initialize(A.m_, A.n_);
+ copy(A.v_);
+ }
+
+ Matrix(Subscript M, Subscript N, const T& value = T(0))
+ {
+ initialize(M,N);
+ set(value);
+ }
+
+ Matrix(Subscript M, Subscript N, const T* v)
+ {
+ initialize(M,N);
+ copy(v);
+ }
+
+ Matrix(Subscript M, Subscript N, char *s)
+ {
+ initialize(M,N);
+
+ istringstream ins(s);
+ Subscript i, j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ ins >> row_[i][j];
+ }
+
+ // destructor
+ //
+ ~Matrix()
+ {
+ destroy();
+ }
+
+
+ // reallocating
+ //
+ Matrix<T>& newsize(Subscript M, Subscript N)
+ {
+ if (num_rows() == M && num_cols() == N)
+ return *this;
+
+ destroy();
+ initialize(M,N);
+
+ return *this;
+ }
+
+
+
+
+ // assignments
+ //
+ Matrix<T>& operator=(const Matrix<T> &A)
+ {
+ if (v_ == A.v_)
+ return *this;
+
+ if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc
+ copy(A.v_);
+
+ else
+ {
+ destroy();
+ initialize(A.m_, A.n_);
+ copy(A.v_);
+ }
+
+ return *this;
+ }
+
+ Matrix<T>& operator=(const T& scalar)
+ {
+ set(scalar);
+ return *this;
+ }
+
+
+ Subscript dim(Subscript d) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert( d >= 1);
+ assert( d <= 2);
+#endif
+ return (d==1) ? m_ : ((d==2) ? n_ : 0);
+ }
+
+ Subscript num_rows() const { return m_; }
+ Subscript num_cols() const { return n_; }
+
+
+ inline T* operator[](Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < m_) ;
+#endif
+ return row_[i];
+ }
+
+/*START - cmsief************************/
+
+ /*This is a Chris Siefert original that attempts to return a vector*/
+ inline Vector<T> row (Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < m_) ;
+#endif
+ Vector<T>temp(n_,row_[i]);
+ return (temp);
+ }
+
+ inline Vector<T> col (Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < n_) ;
+#endif
+ Vector<T>temp(m_);
+ for(long f=0;f<m_;f++) temp[f]=row_[f][i];
+ return (temp);
+ }
+/*END - cmsief************************/
+
+ inline const T* operator[](Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < m_) ;
+#endif
+ return row_[i];
+ }
+
+ /* Changed all this from being 1-based to good ol' C-type
+ * 0-based indexing.
+ * pls, 5/15/03
+ */
+
+ // this is for a sanity check later---using an old version of this
+ // file will result in off-by-1 errors and give incorrect results.
+#define _changed_f_indexing_to_c_pls
+
+ inline reference operator()(Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= mn_) ;
+#endif
+ //return vm1_[i];
+ return v_[i];
+ }
+
+ inline const_reference operator()(Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= mn_) ;
+#endif
+ //return vm1_[i];
+ return v_[i];
+ }
+
+
+ inline reference operator()(Subscript i, Subscript j)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= m_) ;
+ assert(1<=j);
+ assert(j <= n_);
+#endif
+ //return rowm1_[i][j];
+ return row_[i][j];
+ }
+
+
+
+ inline const_reference operator() (Subscript i, Subscript j) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= m_) ;
+ assert(1<=j);
+ assert(j <= n_);
+#endif
+ //return rowm1_[i][j];
+ return row_[i][j];
+ }
+
+ /* end P.L. Shepherd hacks to C-ize the () operators */
+
+#ifdef OLD_LIBC
+ friend istream & operator>>(istream &s, Matrix<T> &A);
+#else
+ // template<class T>
+ friend istream & operator>><>(istream &s, Matrix<T> &A);
+#endif
+ // friend std::istream & operator>>(std::istream &s, Matrix<T> &A);
+
+#ifdef TNT_USE_REGIONS
+
+ typedef Region2D<Matrix<T> > Region;
+
+
+ Region operator()(const Index1D &I, const Index1D &J)
+ {
+ return Region(*this, I,J);
+ }
+
+
+ typedef const_Region2D< Matrix<T> > const_Region;
+ const_Region operator()(const Index1D &I, const Index1D &J) const
+ {
+ return const_Region(*this, I,J);
+ }
+
+#endif
+
+
+};
+
+
+/* *************************** I/O ********************************/
+//std::ostream& operator<<(std::ostream &s, const Matrix<T> &A)
+template <class T>
+ostream& operator<<(ostream &s, const Matrix<T> &A)
+{
+ Subscript M=A.num_rows();
+ Subscript N=A.num_cols();
+
+ s << M << " " << N << "\n";
+
+ for (Subscript i=0; i<M; i++)
+ {
+ for (Subscript j=0; j<N; j++)
+ {
+ s <<setprecision(D_PRECISION)<< A[i][j] << " ";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+//std::istream& operator>>(std::istream &s, Matrix<T> &A)
+template <class T>
+istream& operator>>(istream &s, Matrix<T> &A)
+{
+
+ Subscript M, N;
+
+ s >> M >> N;
+
+ if ( !(M == A.m_ && N == A.n_) )
+ {
+ A.destroy();
+ A.initialize(M,N);
+ }
+
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript j=0; j<N; j++)
+ {
+ s >> A[i][j];
+ }
+
+
+ return s;
+}
+
+// *******************[ basic matrix algorithms ]***************************
+
+
+template <class T>
+Matrix<T> operator+(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] + B[i][j];
+
+ return tmp;
+}
+
+template <class T>
+Matrix<T> operator-(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] - B[i][j];
+
+ return tmp;
+}
+
+template <class T>
+Matrix<T> mult_element(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] * B[i][j];
+
+ return tmp;
+}
+
+
+template <class T>
+Matrix<T> transpose(const Matrix<T> &A)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ Matrix<T> S(N,M);
+ Subscript i, j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ S[j][i] = A[i][j];
+
+ return S;
+}
+
+
+
+template <class T>
+inline Matrix<T> matmult(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+
+#ifdef TNT_BOUNDS_CHECK
+ assert(A.num_cols() == B.num_rows());
+#endif
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+ Subscript K = B.num_cols();
+
+ Matrix<T> tmp(M,K);
+ T sum;
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript k=0; k<K; k++)
+ {
+ sum = 0;
+ for (Subscript j=0; j<N; j++)
+ sum = sum + A[i][j] * B[j][k];
+
+ tmp[i][k] = sum;
+ }
+
+ return tmp;
+}
+
+template <class T>
+inline Matrix<T> operator*(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ return matmult(A,B);
+}
+
+/*More Chris Siefert additions*/
+
+template <class T>
+inline Matrix<T> scalmult(const Matrix<T> &A,
+ const T &x)
+{
+ Matrix<T> tmp=A;
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ for(Subscript i=0;i<M;i++)
+ for(Subscript j=0;j<N;j++)
+ tmp[i][j]*=x;
+ return tmp;
+}
+
+template <class T>
+inline Matrix<T> operator*(const Matrix<T> &A,
+ const T &x)
+{
+ return scalmult(A,x);
+}
+
+template <class T>
+inline Matrix<T> operator*(const T &x,
+ const Matrix<T> &A)
+{
+ return scalmult(A,x);
+}
+
+template <class T>
+Vector<T> matmult(const Vector<T> &x, const Matrix<T> &A) {
+ /*pretends that x is a row-vector*/
+#ifdef TNT_BOUNDS_CHECK
+ assert(A.num_rows() == x.dim());
+#endif
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ Vector<T> tmp(N);
+ T sum;
+
+ for (Subscript i=0; i<N; i++)
+ {
+ sum = 0;
+ // Vector<T> coli=A.col(i);
+ for (Subscript j=0; j<M; j++)
+ sum = sum + A[j][i] * x[j];
+
+ tmp[i] = sum;
+ }
+
+ return tmp;
+
+}/*end matmult*/
+
+template <class T>
+inline Vector<T> operator*(const Vector<T> &x,
+ const Matrix<T> &A)
+{
+ return matmult(x,A);
+}
+
+
+/*end Chris Siefert additions*/
+
+template <class T>
+inline int matmult(Matrix<T>& C, const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+
+ assert(A.num_cols() == B.num_rows());
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+ Subscript K = B.num_cols();
+
+ C.newsize(M,K);
+
+ T sum;
+
+ const T* row_i;
+ const T* col_k;
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript k=0; k<K; k++)
+ {
+ row_i = &(A[i][0]);
+ col_k = &(B[0][k]);
+ sum = 0;
+ for (Subscript j=0; j<N; j++)
+ {
+ sum += *row_i * *col_k;
+ row_i++;
+ col_k += K;
+ }
+ C[i][k] = sum;
+ }
+
+ return 0;
+}
+
+
+template <class T>
+Vector<T> matmult(const Matrix<T> &A, const Vector<T> &x)
+{
+
+#ifdef TNT_BOUNDS_CHECK
+ assert(A.num_cols() == x.dim());
+#endif
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ Vector<T> tmp(M);
+ T sum;
+
+ for (Subscript i=0; i<M; i++)
+ {
+ sum = 0;
+ const T* rowi = A[i];
+ for (Subscript j=0; j<N; j++)
+ sum = sum + rowi[j] * x[j];
+
+ tmp[i] = sum;
+ }
+
+ return tmp;
+}
+
+template <class T>
+inline Vector<T> operator*(const Matrix<T> &A, const Vector<T> &x)
+{
+ return matmult(A,x);
+}
+
+//} // namespace TNT
+
+#endif
+// CMAT_H
diff --git a/headers/command.h b/headers/command.h
new file mode 100644
index 0000000..34707e2
--- /dev/null
+++ b/headers/command.h
@@ -0,0 +1,370 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#include <QUndoCommand>
+#include "ZNmolecule.h"
+#include "constants.h"
+#include "ddwin.h"
+#include <time.h>
+
+class MyGl; class DDWin; class Builder;
+
+class Command : public QUndoCommand
+{
+
+public:
+Command ();
+// virtual bool mergeWith (const QUndoCommand *other);
+void get_time ();
+//time_t commandtime;
+bool same_time (Command *other);
+void name (string str);
+bool first_time;
+
+};
+
+
+
+class ColorAtomCommand : public Command {
+ public:
+ ColorAtomCommand (MyGl *gl);
+ ColorAtomCommand (Atom *at, color col, MyGl *gl);
+ void add (Atom *at, color col);
+ vector <color> previous_colors;
+ vector <color> present_colors;
+ vector <Atom *>target_atoms;
+ void undo ();
+ void redo ();
+ int id () const;
+ bool mergeWith (const QUndoCommand *command);
+ void set_name ();
+ private:
+ MyGl *gl;
+};
+
+
+class ChangeDisplayStyleCommand : public Command {
+ public:
+ bool redraw;
+ ChangeDisplayStyleCommand (MyGl *gl);
+ ChangeDisplayStyleCommand (Atom *at, int dis, MyGl *gl);
+ ChangeDisplayStyleCommand (ZNBond *bo, int dis, MyGl *gl);
+ void add (Atom *at, int dis);
+ void add (ZNBond *bo, int dis);
+ void add (ZNMolecule *mol, int at_ds, int bo_ds, int backbone_ds);
+ void set_name ();
+ vector <int> previous_styles_atoms;
+ vector <int> present_styles_atoms;
+ vector <int> previous_styles_bonds;
+ vector <int> present_styles_bonds;
+ vector <int> present_styles_molecule_bonds;
+ vector <int> present_styles_molecule_atoms;
+ vector <int> present_styles_molecule_backbone;
+ vector <int> previous_styles_molecule_atoms;
+ vector <int> previous_styles_molecule_bonds;
+ vector <int> previous_styles_molecule_backbone;
+
+ vector <Atom *>target_atoms;
+ vector <ZNBond *>target_bonds;
+ vector <ZNMolecule *>target_molecules;
+
+ void undo ();
+ void redo ();
+ // int id () const;
+ // bool mergeWith (const QUndoCommand *command);
+ private:
+ MyGl *gl;
+};
+
+
+class ChangeFloatCommand : public Command {
+ public:
+ ChangeFloatCommand (float &f, float new_val, MyGl *gl, string name = "change value");
+ float *f;
+ float present_value;
+ float previous_value;
+
+ void undo ();
+ void redo ();
+// int id () const;
+// bool mergeWith (const QUndoCommand *command);
+ private:
+ MyGl *gl;
+};
+
+class ChangeVectorCommand : public Command {
+ public:
+ ChangeVectorCommand (vect &v, vect new_val, MyGl *gl, string name = "change vector");
+ vect *v;
+ vect present_value;
+ vect previous_value;
+
+ void undo ();
+ void redo ();
+// int id () const;
+// bool mergeWith (const QUndoCommand *command);
+ private:
+ MyGl *gl;
+};
+
+
+/*
+class ChangeZNMoleculeCommand : public Command {
+ public:
+ ChangeZNMoleculeCommand (MyGl *gl, string name = "change molecules", bool first_do = FALSE);
+
+ bool first_do;
+ ZNMolecule * mol;
+ ZNMolecule* present_value;
+ ZNMolecule* previous_value;
+ void add (ZNMolecule *mol, ZNMolecule *previous_val);
+
+ void undo ();
+ void redo ();
+// int id () const;
+// bool mergeWith (const QUndoCommand *command);
+ private:
+ MyGl *gl;
+};
+*/
+
+class MoveAtomsCommand : public Command {
+ public:
+ bool redraw;
+ MoveAtomsCommand (MyGl *gl, int mod = 2); //0 only on redo, 1 only on undo, 2 both
+ void add (Atom *at, vect vec);
+ int mode;
+ vector <vect> previous_coordinates;
+ vector <vect> present_coordinates;
+ vector <Atom *>target_atoms;
+ void undo ();
+ void redo ();
+ // int id () const;
+ // bool mergeWith (const QUndoCommand *command);
+ void set_name ();
+ private:
+ MyGl *gl;
+};
+
+
+class CreateGraphicalObjectCommand : public Command {
+ public:
+ CreateGraphicalObjectCommand (GraphicalObject *obj, DDWin *ddwin_pt);
+ int rank;
+ GraphicalObject *object;
+ void undo ();
+ void redo ();
+
+ // void set_name ();
+ private:
+ DDWin *ddwin;
+};
+
+class DeleteGraphicalObjectCommand : public Command {
+ public:
+ DeleteGraphicalObjectCommand (GraphicalObject *obj, DDWin *ddwin_pt);
+ int rank;
+ GraphicalObject *object;
+ void undo ();
+ void redo ();
+
+ // void set_name ();
+ private:
+ DDWin *ddwin;
+};
+
+
+class CreateZNMoleculeCommand : public Command {
+ public:
+ CreateZNMoleculeCommand (ZNMolecule *mol, DDWin *ddwin_pt);
+ ZNMolecule *mol;
+ virtual void undo ();
+ virtual void redo ();
+ private:
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+class DeleteZNMoleculeCommand : public CreateZNMoleculeCommand {
+ public:
+ DeleteZNMoleculeCommand (ZNMolecule *mol, DDWin *ddwin_pt);
+ void undo ();
+ void redo ();
+
+};
+
+
+class MutateAtomCommand : public Command {
+ public:
+ MutateAtomCommand (Atom *at, int atn , DDWin *ddwin_pt);
+ Atom *atom;
+ int precn;
+ int currentn;
+ void undo ();
+ void redo ();
+ vector <Atom *> prev_H_atoms;
+ vector <ZNBond *> prev_H_bonds;
+ vector <Atom *> curr_H_atoms;
+ vector <ZNBond *> curr_H_bonds;
+
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+class AddAtomCommand : public Command {
+ public:
+
+ vector <Atom *> prev_H_atoms;
+ vector <ZNBond *> prev_H_bonds;
+ vector <Atom *> curr_H_atoms;
+ vector <ZNBond *> curr_H_bonds;
+
+ vector <Atom *> curr_target_H_atoms;
+ vector <ZNBond *> curr_target_H_bonds;
+
+ vector <Atom *> prev_target_H_atoms;
+ vector <ZNBond *> prev_target_H_bonds;
+
+
+ AddAtomCommand (Atom *to_add, ZNBond *bond, Atom *bond_partner, DDWin *ddwin_pt);
+ Atom *atom;
+ ZNBond *bond;
+ Atom *partner;
+ void undo ();
+ void redo ();
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+class DeleteAtomCommand : public Command {
+ public:
+ vector <Atom *> prev_H_atoms;
+ vector <ZNBond *> prev_H_bonds;
+ vector <Atom *> curr_H_atoms;
+ vector <ZNBond *> curr_H_bonds;
+ vector <Atom *> neighs;
+ vector <vector <Atom *> > curr_targets_H_atoms;
+ vector <vector <ZNBond *> > curr_targets_H_bonds;
+
+ vector <vector <Atom *> > prev_targets_H_atoms;
+ vector <vector <ZNBond *> > prev_targets_H_bonds;
+
+
+ DeleteAtomCommand (Atom *to_remove, DDWin *ddwin_pt);
+ Atom *atom;
+ vector <ZNBond *> bonds;
+
+ void undo ();
+ void redo ();
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+
+
+class AddBondCommand : public Command {
+ public:
+ AddBondCommand (ZNBond *bo, DDWin *ddwin);
+ vector <Atom *> prev_H_atoms0;
+ vector <ZNBond *> prev_H_bonds0;
+ vector <Atom *> curr_H_atoms0;
+ vector <ZNBond *> curr_H_bonds0;
+
+ vector <Atom *> prev_H_atoms1;
+ vector <ZNBond *> prev_H_bonds1;
+ vector <Atom *> curr_H_atoms1;
+ vector <ZNBond *> curr_H_bonds1;
+
+
+ ZNBond *bond;
+ virtual void undo ();
+ virtual void redo ();
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+class DeleteBondCommand : public AddBondCommand {
+ public:
+ DeleteBondCommand (ZNBond *bo, DDWin *ddwin);
+ void undo ();
+ void redo ();
+};
+
+class ModifyBondCommand : public Command {
+ public:
+ ModifyBondCommand (ZNBond *bo, int ord, DDWin *ddwin, bool redefine = true);
+ bool redefine;
+ int new_order, old_order;
+ vector <Atom *> prev_H_atoms0;
+ vector <ZNBond *> prev_H_bonds0;
+ vector <Atom *> curr_H_atoms0;
+ vector <ZNBond *> curr_H_bonds0;
+
+ vector <Atom *> prev_H_atoms1;
+ vector <ZNBond *> prev_H_bonds1;
+ vector <Atom *> curr_H_atoms1;
+ vector <ZNBond *> curr_H_bonds1;
+
+
+ ZNBond *bond;
+ void undo ();
+ void redo ();
+ DDWin *ddwin;
+ Builder *builder;
+};
+
+
+class RedefineZNMoleculeCommand : public Command {
+ public:
+ RedefineZNMoleculeCommand (ZNMolecule *mol, Builder *bu, int mod = 2); //0 only on redo, 1 only on undo, 2 both
+ int mode;
+ ZNMolecule *mol;
+ void undo ();
+ void redo ();
+ Builder *builder;
+};
+
+
+class ReprotonateCommand : public Command {
+ public:
+ ReprotonateCommand (ZNMolecule *mol, DDWin *ddw, double ph = 7.4);
+ ZNMolecule *mol;
+ void undo ();
+ void redo ();
+ DDWin *ddwin;
+ bool first_time;
+
+ vector <Atom *> prev_H_atoms;
+ vector <ZNBond *> prev_H_bonds;
+ vector <Atom *> curr_H_atoms;
+ vector <ZNBond *> curr_H_bonds;
+ vector <Atom *> prev_partners;
+ vector <Atom *> curr_partners;
+
+};
+
+#endif
diff --git a/headers/constants.h b/headers/constants.h
new file mode 100644
index 0000000..2ae9d72
--- /dev/null
+++ b/headers/constants.h
@@ -0,0 +1,205 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+
+#include <iomanip>
+#include <queue>
+#include <vector>
+#include <fstream>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <qwidget.h>
+#include <QtOpenGL/qgl.h>
+#include <qpainter.h>
+#include "maths.h"
+#include <math.h>
+#include <assert.h>
+#include <QTime>
+
+
+
+
+
+#include "obabel_includes.h"
+
+
+#define WIREFRAME 0
+#define STICK 1
+#define CPK 2
+#define BALLANSTICK 3
+#define BALLANDLINE 4
+
+#define AROMATIC_RING 0
+#define KEKULE 1
+#define AROMATIC_BONDS 2
+
+
+using namespace std;
+using namespace Qt;
+using namespace OpenBabel;
+
+class color;
+
+static QTime last_time;
+
+
+
+typedef struct {
+ int type, only_to, excluding;
+ float intensity;
+} color_mask;
+
+
+
+
+
+
+
+class color : public QColor {
+ public:
+ color ();
+ color (float r, float g, float b, float a = 1.f);
+ color (int r, int g, int b, int a = 255);
+ inline void add (float r, float g, float b) {float cr = redF (); setRedF (cr +r); float cg = greenF (); setGreenF (cg +g); float cb = blueF (); setBlueF (cb +b);}
+
+};
+
+
+
+
+
+
+
+const GLfloat specular[] = { 0.8f, 0.8f, 0.8f, 1.0f };
+const GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 0.0f };
+
+const string TITLE = "ZODIAC v - ";
+const string VERSION = "0.6.5 beta";
+/*
+#ifdef WIN32
+const string PARAMETER_DIR = "C:\\Documents and Settings\\Nick Avis\\My Documents\\Visual Studio 2005\\Projects\\zodiac\\zodiac\\parameters\\";
+
+#else // WIN32
+const string PARAMETER_DIR = "./parameters/";
+#endif // WIN32
+*/
+
+const QPalette::ColorRole ERR_COL = QPalette::AlternateBase;
+
+
+const QPalette::ColorRole base = QPalette::Base;
+//const double M_PI = 3.1415;
+const double PI = M_PI;
+
+const float FF_FAR_NONBONDED_CUTOFF = 5.5;
+const float FF_NEAR_NONBONDED_CUTOFF = 1.5;
+const float DOUBLE_BOND_INTER_DISTANCE = 0.15f;
+const float AROMATIC_BOND_INTER_DISTANCE = 0.15f;
+
+
+
+const float DOUBLE_BOND_STICK_RADIUS_SCALE = 0.7f;
+const float SURFACE_RESOLUTION = 3.0;
+
+const int AROMATIC_DISPLAY_STYLE = KEKULE;
+
+const int FOG_BEGIN = 0;
+
+//const color BACKGROUND_COLOR = color ( 1.0f, 1.0f, 1.0f, 1.0f );
+//const color WATER_COLOR ( 0.0f, 1.0f, 0.0f, 0.5f );
+//const color BINDINGSITE_COLOR ( 0.3f, 0.0f, 0.6f, 0.2f );
+//const color CURRENT_COLOR ( 0.3f, 0.3f, 0.3f, 1.0f );
+const color SELECT_COLOR ( 19, 3, 82, 255 );
+
+const float TIMER_INTERVAL = 0.5; //msecs
+
+
+
+color average_3_colors (float score, color c1, color c2, color c3, float begin, float mid, float end) ;
+
+
+//double distance (float *coord1, float *coord2);
+float angle (vect coord1, vect coord2, vect coord3);
+
+float signed_angle (vect coord1, vect coord2, vect coord3);
+
+//double angle (float *coord1, float *coord2, float *coord3);
+//double angle (float *coord1, vector <float> coord2, float *coord3);
+double dihedral (vect coord1, vect coord2, vect coord3, vect coord4);
+//double dihedral (float *coord1, float *coord2, float *coord3, float *coord4);
+
+double wilson (vect coord1, vect coord2, vect coord3, vect coord4);
+//double wilson (float *coord1, float *coord2, float *coord3, float *coord4);
+
+
+vect torque (vect force, vect coords, vect center);
+color mean (color c1, color c2);
+
+
+void rotate_around_vector (vect &point, vect torque, vect center, float angle);
+
+
+void rotate_to_plane (vect pointA, vect pointb, vect center);
+
+
+void components (vect vec, vect ref, vect ¶ll, vect &normal);
+quaternion map_vector_on_vector_quaternion (vect v1, vect v2);
+void axis_angle_to_quaternion (vect axis, float angle, float *quaternion);
+quaternion yaw_pitch_roll_to_quaternion (float yaw, float pitch, float roll);
+quaternion axis_angle_to_quaternion(vect axis, float angle);
+void multiply_quaternions (float *q1, float *q2, float *product);
+quaternion multiply_quaternions (quaternion q1, quaternion q2);
+//vect rotate_vector_using_quaternion (vect v, float *q);
+vect rotate_vector_using_quaternion(vect v, quaternion q);
+vect rotate_vector_using_matrix_16 (vect v, double *m);
+vect rotate_vector_using_matrix_9 (vect v, double *m);
+void invert_matrix_9 (double *mat, double *inverse);
+void normalize_quaternion (double *q);
+
+
+double string_to_double (string s);
+int string_to_int (string s);
+string int_to_string (int i);
+string double_to_string (double d);
+
+
+//minimisation
+
+const int MAX_ITERATIONS = 1000;
+const double MIN_ENERGY = 0.005f;
+const double DX = 0.0005f;
+const double STEP_SIZE = 0.0005f;
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/headers/cutoffGrid.h b/headers/cutoffGrid.h
new file mode 100644
index 0000000..095524b
--- /dev/null
+++ b/headers/cutoffGrid.h
@@ -0,0 +1,251 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef cutoffGrid_H
+#define cutoffGrid_H
+
+#include <vector>
+
+using namespace std;
+
+template <class T>
+struct objectList {
+ vector<T> objects;
+};
+
+template <class T>
+struct staticCutoffNode {
+ vector<T> cellObjects;
+ objectList<T>* objects;
+};
+
+template <class T>
+class cutoffGrid
+{
+public:
+ cutoffGrid(vector<T>& objects, float cutRadius);
+ ~cutoffGrid();
+ objectList<T>* getNeighborObjects(vect pos);
+ vector<staticCutoffNode<T>*> grid;
+ int gridSize[3];
+ float gridResolution;
+ float gridMin[3];
+ int gridSizeXY;
+
+private:
+ float cutoffRadius;
+ float gridMax[3];
+ unsigned int maxSID;
+
+};
+
+
+template <class T>
+cutoffGrid<T>::cutoffGrid(vector<T>& objects, float cutRadius)
+{
+
+ gridResolution = cutRadius;
+
+ cutoffRadius = cutRadius;
+
+ if (!objects.size()) {
+ gridMin[0] = 0.0; gridMin[1] = 0.0; gridMin[2] = 0.0;
+ gridSize[0] = 0; gridSize[1] = 0; gridSize[2] = 0;
+ }
+ else {
+
+ for (unsigned int i = 0; i < objects.size(); i++) {
+ if (!i) {
+ gridMin[0] = objects[i]->GetVector ().x();
+ gridMin[1] = objects[i]->GetVector ().y();
+ gridMin[2] = objects[i]->GetVector ().z();
+
+ gridMax[0] = objects[i]->GetVector ().x();
+ gridMax[1] = objects[i]->GetVector ().y();
+ gridMax[2] = objects[i]->GetVector ().z();
+ }
+ else {
+ if (objects[i]->GetVector ().x() < gridMin[0]) {
+ gridMin[0] = objects[i]->GetVector ().x();
+ }
+ if (objects[i]->GetVector ().y() < gridMin[1]) {
+ gridMin[1] = objects[i]->GetVector ().y();
+ }
+ if (objects[i]->GetVector ().z() < gridMin[2]) {
+ gridMin[2] = objects[i]->GetVector ().z();
+ }
+ if (objects[i]->GetVector ().x() > gridMax[0]) {
+ gridMax[0] = objects[i]->GetVector ().x();
+ }
+ if (objects[i]->GetVector ().y() > gridMax[1]) {
+ gridMax[1] = objects[i]->GetVector ().y();
+ }
+ if (objects[i]->GetVector ().z() > gridMax[2]) {
+ gridMax[2] = objects[i]->GetVector ().z();
+ }
+
+ }
+ }
+
+ gridMin[0] -= 2.0 * cutRadius;
+ gridMin[1] -= 2.0 * cutRadius;
+ gridMin[2] -= 2.0 * cutRadius;
+
+ gridMax[0] += 2.0 * cutRadius;
+ gridMax[1] += 2.0 * cutRadius;
+ gridMax[2] += 2.0 * cutRadius;
+
+
+ gridSize[0] = (int)((gridMax[0] - gridMin[0]) / gridResolution + 0.5);
+ gridSize[1] = (int)((gridMax[1] - gridMin[1]) / gridResolution + 0.5);
+ gridSize[2] = (int)((gridMax[2] - gridMin[2]) / gridResolution + 0.5);
+
+
+
+ gridSizeXY = gridSize[0] * gridSize[1];
+
+ grid.resize(gridSize[0] * gridSize[1] * gridSize[2], NULL);
+
+ vector<int*> nodes;
+
+ for (unsigned int i = 0; i < objects.size(); i++) {
+
+ int gridPos[3];
+
+ gridPos[0] = (int)((objects[i]->GetVector ().x() - gridMin[0]) / gridResolution + 0.5);
+ gridPos[1] = (int)((objects[i]->GetVector ().y() - gridMin[1]) / gridResolution + 0.5);
+ gridPos[2] = (int)((objects[i]->GetVector ().z() - gridMin[2]) / gridResolution + 0.5);
+
+ if (gridPos[0] >= 0 && gridPos[0] < gridSize[0] &&
+ gridPos[1] >= 0 && gridPos[1] < gridSize[1] &&
+ gridPos[2] >= 0 && gridPos[2] < gridSize[2]) {
+
+ int index = gridPos[0] + gridPos[1] * gridSize[0] + gridPos[2] * gridSizeXY;
+ if (grid[index] == NULL) {
+ grid[index] = new staticCutoffNode<T>;
+ grid[index]->objects = new objectList<T>;
+ grid[index]->cellObjects.push_back(objects[i]);
+ int *nodeIndex = new int[3];
+ nodeIndex[0] = gridPos[0];
+ nodeIndex[1] = gridPos[1];
+ nodeIndex[2] = gridPos[2];
+
+ nodes.push_back(nodeIndex);
+ }
+ else {
+ grid[index]->cellObjects.push_back(objects[i]);
+ }
+ }
+ }
+
+ int radius = 1;
+
+ int x, y, z;
+
+ vector<int*> sphere;
+
+ for (x = -radius; x <= radius; x++)
+ for (y = -radius; y <= radius; y++)
+ for (z = -radius; z <= radius; z++) {
+ int *p = new int[3];
+ p[0] = x;
+ p[1] = y;
+ p[2] = z;
+ sphere.push_back(p);
+ }
+ for (unsigned int i = 0; i < nodes.size(); i++) {
+ int *ni = nodes[i];
+ int index = ni[0] + ni[1] * gridSize[0] + ni[2] * gridSizeXY;
+ for (unsigned int j = 0; j < sphere.size(); j++) {
+ int *p = sphere[j];
+ int newPoint[3];
+ newPoint[0] = ni[0] + p[0];
+ newPoint[1] = ni[1] + p[1];
+ newPoint[2] = ni[2] + p[2];
+
+ if (newPoint[0] >= 0 && newPoint[0] < gridSize[0] &&
+ newPoint[1] >= 0 && newPoint[1] < gridSize[1] &&
+ newPoint[2] >= 0 && newPoint[2] < gridSize[2]) {
+ int newIndex = newPoint[0] + newPoint[1] * gridSize[0] + newPoint[2] * gridSizeXY;
+ if (grid[newIndex] == NULL) {
+ grid[newIndex] = new staticCutoffNode<T>;
+ grid[newIndex]->objects = new objectList<T>;
+ }
+ for (unsigned int k = 0; k < grid[index]->cellObjects.size(); k++) {
+ grid[newIndex]->objects->objects.push_back(grid[index]->cellObjects[k]);
+ }
+ }
+ }
+ delete[] nodes[i];
+ }
+
+ for (unsigned int i = 0; i < sphere.size(); i++) {
+ if (sphere[i]) {
+ delete[] sphere[i];
+ sphere[i] = NULL;
+ }
+ }
+ sphere.clear();
+ }
+
+}
+
+
+template <class T>
+cutoffGrid<T>::~cutoffGrid()
+{
+ for (unsigned int i = 0; i < grid.size(); i++) {
+ if (grid[i]) {
+ if (grid[i]->objects) {
+ grid[i]->objects->objects.clear();
+ delete grid[i]->objects;
+ }
+ grid[i]->objects = NULL;
+ delete grid[i];
+ grid[i] = NULL;
+ }
+ }
+ grid.clear();
+}
+
+template <class T>
+objectList<T>* cutoffGrid<T>::getNeighborObjects(vect pos)
+{
+ int gridPos[3];
+
+ gridPos[0] = (int)((pos.x() - gridMin[0]) / gridResolution + 0.5);
+ gridPos[1] = (int)((pos.y() - gridMin[1]) / gridResolution + 0.5);
+ gridPos[2] = (int)((pos.z() - gridMin[2]) / gridResolution + 0.5);
+
+ if (gridPos[0] >= 0 && gridPos[0] < gridSize[0] &&
+ gridPos[1] >= 0 && gridPos[1] < gridSize[1] &&
+ gridPos[2] >= 0 && gridPos[2] < gridSize[2]) {
+
+ int index = gridPos[0] + gridPos[1] * gridSize[0] + gridPos[2] * gridSizeXY;
+ if (grid[index]) {
+ return grid[index]->objects;
+ }
+ else {
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+#endif
+
diff --git a/headers/database.h b/headers/database.h
new file mode 100644
index 0000000..3ddc4b5
--- /dev/null
+++ b/headers/database.h
@@ -0,0 +1,135 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DATABASE_H
+#define DATABASE_H
+
+#include "menu.h"
+
+
+class Database_molecule : public ZNMolecule {
+ public:
+ Database_molecule (const ZNMolecule &mol);
+ Database_molecule &operator =(const Database_molecule &mol);
+ Database_molecule ();
+ Database *database;
+ int number;
+
+};
+
+
+class DatabaseCell {
+public:
+ DatabaseCell () {};
+ virtual void set_value (string s) {};
+ virtual string get_string () {return "no data";};
+ virtual double get_double () {return 0.;};
+ virtual void set_double (double d) {};
+};
+
+
+
+
+class DatabaseEntry {
+ public:
+ DatabaseEntry (ZNMolecule *mol) {_mol = mol;};
+ vector <DatabaseCell *> cells;
+ ZNMolecule *_mol;
+ ZNMolecule *get_molecule () {return _mol;};
+ int *sorting_column;
+
+};
+
+class Database {
+public:
+
+ Database ();
+ Database_molecule *dummy_mol;
+ string name;
+ void add_mol (Database_molecule *mol);
+ void delete_entry (int i);
+ void safe_add_mol (Database_molecule *mol);
+// vector <Database_molecule *> molecules;
+ bool has_extend_enabled ();
+ vector <DatabaseEntry *> entries;
+ vector <string> field_names;
+ void add_field (string, vector <double>);
+ void add_field (string, vector <string>, char type = 'd');
+ void safe_add_field (string, vector <double>);
+ void safe_add_field (string, vector <string>, char type = 'd');
+ void safe_merge_with (Database *dat);
+ void merge_with (Database *dat);
+ ZNMolecule *get_molecule (int);
+ void import_csv (string filename);
+ bool &get_extend_enabled () {return _extend_enabled;}
+ bool &get_is_hidden () {return _hidden;}
+ bool get_needs_redraw () {return _needs_redraw;}
+ void set_needs_redraw (bool b) {_needs_redraw = b;}
+ int count_fields () {return field_names.size ();}
+ int count_entries () {return entries.size ();};
+ int *sorting_column;
+ //void renumber ();
+ QReadWriteLock *mutex;
+ void safe_sort_up (int column);
+ void safe_sort_down (int column);
+ void sort_up (int column);
+ void sort_down (int column);
+ void set_double (int field, int entry, double value) {if (entry < count_entries () && (field < count_fields())) entries [entry] ->cells [field] ->set_double (value);};
+
+
+private:
+ bool _extend_enabled, _hidden;
+ bool _needs_redraw;
+
+
+};
+
+
+struct compare_cell
+{
+ bool operator()( const DatabaseEntry* a, const DatabaseEntry* b)
+ {
+ cerr << *a ->sorting_column << " "<<*b ->sorting_column<<" " <<a ->sorting_column << " "<<b ->sorting_column<<endl;
+ return (a->cells[*a ->sorting_column]) ->get_double () < (b->cells[*b ->sorting_column]) ->get_double ();
+ }
+};
+
+class ZNMoleculeDatabaseCell: public DatabaseCell {
+ public:
+ ZNMoleculeDatabaseCell (ZNMolecule *mol) {_molecule = mol;};
+ string get_string () {return _molecule ->GetTitle ();};
+ ZNMolecule *get_molecule () {return _molecule;};
+ double get_double () {if (_molecule ->multi) return ((Database_molecule *) _molecule) -> number; else return _molecule->NumAtoms ();}
+ void set_value (string s) {_molecule ->SetTitle (s);};
+private:
+ ZNMolecule *_molecule;
+};
+
+class DoubleDatabaseCell: public DatabaseCell {
+public:
+ DoubleDatabaseCell (double d) {_value = d;};
+ string get_string () {stringstream ss; ss << _value; return ss.str ();}
+ double get_double () {return _value;}
+ void set_value (string s) {_value = string_to_double (s);};
+ void set_double (double d) {_value = d;};
+private:
+ double _value;
+
+} ;
+
+#endif
\ No newline at end of file
diff --git a/headers/datagrid.h b/headers/datagrid.h
new file mode 100644
index 0000000..4016d00
--- /dev/null
+++ b/headers/datagrid.h
@@ -0,0 +1,153 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "constants.h"
+
+class DataGrid {
+private:
+ float resolution;
+ float *_data;
+ int _x_size, _y_size, _z_size;
+ float x_length, y_length, z_length;
+ float _min_x, _min_y, _min_z;
+public:
+ DataGrid (vect min_corn, vect max_corner, float res) {
+ resolution = res;
+ _min_x = min_corn.x ();
+ _min_y = min_corn.y ();
+ _min_z = min_corn.z ();
+ x_length = max_corner.x() - _min_x;
+ y_length = max_corner.y() - _min_y;
+ z_length = max_corner.z() - _min_z;
+ if (x_length < 0.) x_length = - x_length;
+ if (y_length < 0.) y_length = - y_length;
+ if (z_length < 0.) z_length = - z_length;
+ _x_size = (int) (x_length / resolution) + 1 + 1;
+ _y_size = (int) (y_length / resolution) + 1 + 1;
+ _z_size = (int) (z_length / resolution) + 1 + 1;
+ _data = new float [_x_size *_y_size * _z_size];
+ for (unsigned int i = 0; i < _x_size * _y_size * _z_size ; i++) _data[i] = 0.;
+ };
+ ~DataGrid () {delete[] _data;};
+ void set_value (int i, int j, int k, float val) {if (i*j*k < (_x_size -1) * (_y_size-1) * (_z_size-1)) {_data[i*(_z_size*_y_size) + j * (_z_size) + k ] = val;}};
+ int x_size () {return _x_size;};
+ int y_size () {return _y_size;};
+ int z_size () {return _z_size;};
+
+
+ int get_i (float x) {
+ int i = 0;
+ float newx = x - _min_x;
+ if (0 <= newx && newx<= ( x_length)) i = (int) (newx / resolution);
+ // cerr << "get i " << x << " " << newx << " " << i << endl;
+ return i;
+ };
+
+ int get_j (float y) {
+ int j = 0;
+ float newy = y - _min_y;
+ if (0 <= newy && newy<= (y_length)) j = (int) (newy / resolution);
+ //cerr << _min_y << " " << resolution << " "<<newy << " " << y<<" "<<y_length<<" "<<j<<endl;
+ return j;
+ };
+ int get_k (float z) {
+ int k = 0;
+ float newz = z - _min_z;
+
+ if (0 <= newz && newz<= ( z_length)) k = (int) (newz / resolution);
+ // cerr << _min_z << " " << resolution << " "<<newz << " " << k<<" "<<z_length<<endl;
+ return k;
+ };
+ float get_x (int i) {
+ float x = _min_x + i*resolution;
+ // cerr << "get x " << i << " " << _min_x + x_length << " " << x << endl;
+ if (_min_x <= x && x<= (_min_x + x_length)) return x;
+
+ else return _min_x;
+ };
+ float get_y (int j) {
+ float y = _min_y + j*resolution;
+ if (_min_y <= y && y<= _min_y + y_length) return y;
+ else return _min_y;
+ };
+ float get_z (int k) {
+ float z = _min_z + k*resolution;
+ if (_min_z <= z && z<= _min_z + z_length) return z;
+ else return _min_z;
+ };
+ float get_value (float x, float y, float z) {
+
+ if (x < _min_x) x = _min_x;
+ if (y < _min_y) y = _min_y;
+ if (z < _min_z) z = _min_z;
+
+ if (x > _min_x + x_length) x = _min_x + x_length;
+ if (y > _min_y + y_length) y = _min_y + y_length;
+ if (z > _min_z + z_length) z = _min_z + z_length;
+
+ int i = get_i (x);
+ int j = get_j (y);
+ int k = get_k (z);
+ float xl = get_x (i);
+ float yl = get_y (j);
+ float zl = get_z (k);
+
+ int ii, jj, kk;
+ float dx, dy, dz;
+ if (i < _x_size -1)
+ ii = i + 1;
+
+ else ii = i;
+ if (j < _y_size -1) jj = j + 1;
+ else ii = i;
+ if (k < _z_size -1) kk = i + 1;
+ else kk = k;
+
+ dx = (x -xl) / resolution;
+ dy = (y - yl) / resolution;
+ dz = (z - zl) / resolution;
+
+ // cerr << x << " " << i << " " << xl << endl;
+ // cerr << y << " " << j << " " << yl << endl;
+ // cerr << z << " " << k << " " << zl << endl;
+
+ float V000 = _data [i*(_z_size*_y_size) + j * (_z_size) + k ];
+ float V001 = _data [i*(_z_size*_y_size) + j * (_z_size) + kk ];
+ float V010 = _data [i*(_z_size*_y_size) + jj * (_z_size) + k ];
+ float V011 = _data [i*(_z_size*_y_size) + jj * (_z_size) + kk ];
+ float V100 = _data [ii*(_z_size*_y_size) + j * (_z_size) + k ];
+ float V101 = _data [ii*(_z_size*_y_size) + j * (_z_size) + kk ];
+ float V110 = _data [ii*(_z_size*_y_size) + jj * (_z_size) + k ];
+ float V111 = _data [ii*(_z_size*_y_size) + jj * (_z_size) + kk ];
+
+ // cerr << "values "<< dx<<" " << dy<<" " <<dz << " "<< V000 << " "<< V001 << " "<< V010 << " "<< V011 << " "<< V100 << " "<< V101 << " "<< V110 << " "<< V111 << " "<<endl;
+
+ return V000 * (1 - dx) * (1 - dy) * (1 - dz) +
+ V100 * dx * (1 - dy) * (1 - dz) +
+ V010 * (1 - dx) * dy * (1 - dz) +
+ V001 * (1 - dx) * (1 - dy) * dz +
+ V101 * dx * (1 - dy) * dz +
+ V011 * (1 - dx) * dy * dz +
+ V110 * dx * dy * (1 - dz) +
+ V111 * dx * dy * dz;
+ };
+
+
+
+};
+
diff --git a/headers/ddwin.h b/headers/ddwin.h
new file mode 100644
index 0000000..51800a7
--- /dev/null
+++ b/headers/ddwin.h
@@ -0,0 +1,718 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#ifndef DDWIN_H
+#define DDWIN_H
+
+
+#include "constants.h"
+#include "ZNdata.h"
+#include <QMainWindow>
+#include "arcball.h"
+#include "ZNmolecule.h"
+#include <qlabel.h>
+#include <qcombobox.h>
+#include "plants.h"
+#include "MarchingCubes.h"
+#include "graphical_object.h"
+#include "minimize.h"
+#include "builder.h"
+#include <Qt3Support/q3accel.h>
+#include <QtGui>
+#include <qdatetime.h>
+#include "menu.h"
+#include <QUndoView>
+#include "command.h"
+#include "obabel_includes.h"
+#include "thread.h"
+
+
+
+
+#include <qmenubar.h>
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+
+#include <qlabel.h>
+#include <Qt3Support/q3grid.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qevent.h>
+#include <qdrag.h>
+#include <qdir.h>
+#include <qcolordialog.h>
+#include "database.h"
+
+
+
+#include "function.h"
+#include "ils.h"
+
+#ifdef WIN32
+#include <float.h>
+#define isnan _isnan
+#endif // WIN32
+
+
+
+
+
+
+static bool g_stereoAvailable = FALSE;
+
+//class vect;
+class MyGl; class Data; class Builder; class BuilderMenu; class HapticMenu; class Clicked_atomMenu; class ColorMenu; class ColorSettingsMenu; class GamessMenu; class PLANTSMenu; class PrefMenu;
+class BackboneColorMenu; class SurfaceMenu; class SphereMenu; class GraphicalObjectsMenu; class GraphicalObjectsColorMenu; class DDSettingsMenu; class GridMenu; class ConformersMenu; class Command; class DatabaseGrid; class IODeviceMenu; class DockingMenu; class DisplayMenu; class SequenceMenu;
+class ThreadMenu; class MapMenu;
+class MyFloatEditLine;
+class Grid;
+class Thread;
+
+typedef struct {
+ vect coordinates;
+} myVertex;
+
+
+
+class DDWin : public QMainWindow {
+ Q_OBJECT
+
+public:
+
+
+ vector <HBond> Hbonds;
+ vector <vect> vertex_list;
+ int mode;
+ QComboBox *target;
+ QLabel *current_mode;
+ QUndoView *undo_view;
+ DDWin (QWidget *parent, Data *dat);
+
+ string mode_string;
+
+ enum StereoMode { StereoMode_None, StereoMode_VerticalInterlace, StereoMode_HorizontalInterlace, StereoMode_ViaOpenGL};
+
+ StereoMode g_stereoMode;
+ unsigned char *g_stencil_mask;
+ bool g_stencil_mask_needs_redraw;
+ unsigned int g_stencil_mask_frame_counter;
+ unsigned int g_stencil_mask_height;
+ unsigned int g_stencil_mask_height_tile;
+ unsigned int g_stencil_mask_width;
+ unsigned int g_stencil_mask_width_tile;
+
+ vector <float > magic_pencil_trail_x;
+ vector <float > magic_pencil_trail_y;
+ vector <float > magic_pencil_trail_z;
+ vector <float > magic_pencil_trail_wx;
+ vector <float > magic_pencil_trail_wy;
+
+ int current_target;
+ ZNMolecule *target_molecule;
+
+ vector <ZNMolecule *> molecules;
+ vector <DatabaseGrid *> database_grids;
+ vector <GraphicalObject *> graphical_objects;
+ vector <Thread *> running_threads;
+
+ void run_thread (Thread *);
+ bool show_labels;
+ bool backbone_shown, haptic_mode, minimizing, rec_movie, rec_pov_movie, adding_restrains;
+ Data* data;
+ Builder* builder;
+
+ void load_file (string mol_name);
+ Database *load_multi_file (string mol_name);
+ Sphere* new_sphere (string name);
+
+ void new_molecule (string name);
+ void add_molecule (ZNMolecule *mol);
+ void add_database (Database *dat);
+
+ void show_atom_properties (Atom *at);
+
+/*
+ QComboBox *at_disp;
+ QComboBox *bo_disp;
+ QComboBox *ar_disp;
+ QComboBox *backbone_disp;
+*/
+ int last_frame;
+ void write_POV_source (string filename);
+ void deselect ();
+
+ MyGl *gl ;
+ void set_current_target (int index);
+ void set_current_target (ZNMolecule * mol);
+ void set_lists (ZNMolecule *mol);
+ void show_grid (Database *dat);
+
+ void select (Atom *at);
+ void select (vector <Atom *> atoms);
+
+ void delete_current_molecule ();
+ void delete_molecule (ZNMolecule *mol);
+
+ void remove_molecule (ZNMolecule *mol);
+
+ void delete_graphical_object (int i);
+
+ string write_mol2_string (ZNMolecule *mol);
+ BackboneColorMenu *b_color_menu;
+ ConformersMenu *conformers_menu;
+ HapticMenu *haptic_menu;
+ GamessMenu *gamess_menu;
+ PLANTSMenu *plants_menu;
+ DisplayMenu *display_menu;
+ SequenceMenu *sequence_menu;
+ DockingMenu *docking_menu;
+ ThreadMenu *thread_menu;
+ IODeviceMenu *iodevice_menu;
+ SurfaceMenu *surface_menu;
+ GraphicalObjectsColorMenu *go_color_menu;
+ GridMenu *grid_menu;
+ SphereMenu *sphere_menu;
+ MapMenu *map_menu;
+ GraphicalObjectsMenu *graphical_objects_menu;
+
+ void execute (Command *comm);
+
+
+ void lock_editing ();
+ void unlock_editing ();
+
+
+ private:
+ int edit_lock_counter;
+ void closeEvent(QCloseEvent *event);
+ color molecule_color;
+
+ QAction *openAct;
+ QAction *openSessionAct;
+ QAction *saveasAct;
+ QAction *saveSessionAsAct;
+ QAction *screenshotAct;
+ QAction *raytracedscreenshotAct;
+ QAction *movieAct;
+ QAction *raytracedmovieAct;
+ QAction *quitAct;
+ QAction *newdatabaseAct;
+
+ QAction *builderAct;
+ QAction *twodwinAct;
+ QAction *historyAct;
+ QAction *wiimoteAct;
+ QAction *wiimote2Act;
+ QAction *settingsAct;
+
+ QAction *hideHAct;
+ QAction *hidenpHAct;
+ QAction *showallAct;
+ QAction *hideallAct;
+
+ QAction *displaysettingsAct;
+ QAction *sequenceAct;
+ QAction *colorAct;
+ QAction *backboneColorAct;
+ QAction *backgroundcolorAct;
+ QAction *DDsettingsAct;
+ QAction *enableclippingAct;
+ QAction *disableclippingAct;
+
+ QAction *hapticAct;
+ QAction *dockingAct;
+ QAction *plantsAct;
+ QAction *gamessAct;
+ QAction *energyAct;
+ QAction *logPAct;
+ QAction *minimiseAct;
+ QAction *partialQAct;
+ QAction *scoresCharge;
+ QAction *conformationalSearchAct;
+
+ QAction *surfaceAct;
+ QAction *mapAct;
+ QAction *sphereAct;
+ QAction *backbonetosurfAct;
+ QAction *graphicalobjectsAct;
+
+ QAction *addHsAct;
+ QAction *duplicateAct;
+
+ QAction *iodeviceAct;
+
+ QAction *aboutAct;
+
+
+ QAction *undoAct;
+ QAction *redoAct;
+
+ QAction *colorsAct, *colors_chooserAct;
+ QAction *centerAct;
+
+ QAction *selectAllAct;
+ QAction *deselectAct;
+ QAction *invertSelectAct;
+ QAction *selectCAct;
+ QAction *selectHAct;
+ QAction *selectsquareAct;
+
+
+
+ QAction *buildCAct;
+ QAction *buildSAct;
+ QAction *buildNAct;
+ QAction *buildOAct;
+ QAction *buildsinglebondAct;
+ QAction *builddoublebondAct;
+ QAction *buildtriplebondAct;
+ QAction *deletebondAct;
+
+ QAction *deleteatomAct;
+ // QAction *magicpencilAct;
+
+ QPushButton *magicpencilButt;
+ QAction *buildsmileAct;
+ QAction *periodictableAct;
+
+ QToolBar *toolbar, *target_toolbar, *select_tb, *builder_tb;
+
+
+ Q3Accel *accel;
+ void setup_accel ();
+
+
+ int style_str_to_i (string style);
+ QWidget *dsetpopup;
+ BuilderMenu *builder_menu;
+ PrefMenu *pref_menu;
+ ColorMenu *color_menu;
+ ColorSettingsMenu *color_settings_menu;
+ DDSettingsMenu *DDsettings_menu;
+ Clicked_atomMenu * clicked_atom_menu;
+
+
+ void draw_menu ();
+ void hide_toolbars ();
+ void create_menu_actions ();
+ void set_popups ();
+
+
+ void dragEnterEvent( QDragEnterEvent * );
+ void dragMoveEvent( QDragMoveEvent * );
+ void dragLeaveEvent( QDragLeaveEvent * );
+ void dropEvent( QDropEvent * );
+
+ string POV_vector (vect v);
+ string POV_color (color c);
+ string POV_bond (ZNBond *bo, bool clippable = false);
+ string POV_atom (Atom *at, bool clippable = false);
+ string POV_ring (Ring *ring);
+ string POV_surface (Surface *surf, bool clippable = false);
+ string POV_map (Map *map, bool clippable = false);
+ string POV_sphere (Sphere *sph, bool clippable = false);
+ string POV_backbone (ZNMolecule *mol, bool clippable = false);
+
+ string POV_stick (vect v1, vect v2, color c1, color c2, float rad, float a1size, float a2size, bool clippable = false);
+
+ public:
+ QString last_visited_dir;
+
+ private slots:
+
+ void resize_target_toolbar (Qt::Orientation);
+ void resizeEvent (QResizeEvent *);
+
+ void open_file_slot ();
+ void open_session_file_slot ();
+ void save_as_slot ();
+ void save_session_as_slot ();
+ void screenshot_slot ();
+ void movie_slot ();
+ void raytraced_movie_slot ();
+
+ void new_database_slot ();
+ void builder_slot ();
+ void twodwin_slot ();
+
+ void history_slot ();
+ void wiimote_slot ();
+ void wiimote2_slot ();
+ void pref_slot ();
+
+ void hide_hydrogens_slot ();
+ void hide_nonpolar_hydrogens_slot ();
+ void show_all_atoms_slot ();
+ void hide_all_atoms_slot ();
+
+ void display_settings_slot ();
+ void sequence_slot ();
+ void DD_settings_slot ();
+ void disable_clipping_slot ();
+ void enable_clipping_slot ();
+ void color_slot ();
+ void backbone_color_slot ();
+ void background_color_slot ();
+
+ void surface_slot ();
+ void map_slot ();
+ void sphere_slot ();
+ void backbone_to_surface_slot ();
+ void graphical_objects_slot ();
+
+ void add_Hs_slot ();
+ void duplicate_slot ();
+
+
+ void atdebug_slot ();
+ void about_slot ();
+ void partial_charges_slot ();
+ void scores_from_charges_slot ();
+ void conformers_slot ();
+ void compute_energy_slot ();
+ void logP_slot ();
+ void minimise_energy_slot ();
+ void not_impl_slot ();
+ // void color_by_atom_slot ();
+ // void color_by_charge_slot ();
+ // void color_by_score_slot ();
+ // void color_carbons_slot ();
+
+ void haptic_slot ();
+ void plants_slot ();
+ void docking_slot ();
+ void gamess_slot ();
+ void iodevice_slot ();
+
+ void set_current_target_slot (int index);
+ void invert_selection_slot ();
+ void deselect_slot ();
+ void select_all_slot ();
+ void select_C_slot ();
+ void select_H_slot ();
+
+
+
+ void select_square_slot ();
+
+ void build_C_slot ();
+ void build_S_slot ();
+ void build_O_slot ();
+ void build_N_slot ();
+
+
+ void build_single_bond_slot ();
+ void build_double_bond_slot ();
+ void build_triple_bond_slot ();
+ void delete_bond_slot ();
+
+ void magic_pencil_toggle_slot (bool checked);
+ void magic_pencil_start ();
+ void magic_pencil_end ();
+
+ void periodic_table_slot ();
+
+ void switch_mode (int m);
+ //key slots
+ void del_pressed ();
+ void esc_pressed ();
+ void a_pressed ();
+ void b_pressed ();
+ void c_pressed ();
+ void d_pressed ();
+ void e_pressed ();
+ void f_pressed ();
+ void h_pressed ();
+ void i_pressed ();
+ void m_pressed ();
+ void n_pressed ();
+ void o_pressed ();
+ void r_pressed ();
+ void s_pressed ();
+
+
+ //toolbar slots
+
+
+
+ public slots:
+ void raytraced_screenshot_slot ();
+ // void redraw (ZNMolecule *mol);
+ void recolor_by_score (ZNMolecule *mol);
+ void end_minimisation ();
+ void change_color_slot ();
+ void quick_color_slot ();
+ void center_slot ();
+ void emit_go_updated () {go_updated();};
+ void emit_targets_updated ();
+
+ signals:
+ void non_selection_molecules_updated ();
+ void targets_updated ();
+ void go_updated ();
+ };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class MyGl : public QGLWidget
+ {
+ Q_OBJECT
+ public:
+ MyGl (DDWin *parent);
+ void timerEvent ( QTimerEvent * event );
+ void set_clipping_plane ();
+ bool needs_GL_update;
+ void matrix_transformations (bool stereo = false, int frameBuffer = 0);
+
+ void draw_molecule (ZNMolecule* mol);
+ void GL_update_molecule (ZNMolecule *mol);
+ void GL_update_backbone (ZNMolecule *mol);
+ void draw_bindingsite (float x,float y,float z, float r);
+ void screenshot (QString filename);
+ void set_center_of_rotation (vect v);
+ void set_center_of_view (vect v);
+
+
+ void refreshStencilBuffer();
+
+ color select_color;
+
+ void translate_view (vect v);
+
+ int redraw_counter;
+ int aromatic_display_style;
+
+ double double_bond_inter_distance;
+ double aromatic_bond_inter_distance;
+
+
+ double double_bond_stick_radius_scale;
+ int fog_begin;
+ double surface_resolution;
+ double stereo_toe_in_angle;
+ double stereo_inter_eye_semi_distance;
+ bool select_square_mode;
+
+ float head_tracking_x_position, head_tracking_y_position;
+
+ vect apply_world_rotation (vect v);
+ vect deapply_world_rotation (vect v);
+
+ void hide_hydrogens (ZNMolecule* mol);
+ void hide_nonpolar_hydrogens (ZNMolecule* mol);
+ void show_all_atoms (vector <ZNMolecule*> mols);
+ void hide_all_atoms (vector <ZNMolecule*> mols);
+ void hide_hydrogens (vector <ZNMolecule*> mols);
+ void hide_nonpolar_hydrogens (vector <ZNMolecule*> mols);
+ void show_all_atoms (ZNMolecule* mol);
+ void hide_all_atoms (ZNMolecule* mol);
+
+ void draw_list (ZNMolecule* mol);
+ void draw_backbone_list (ZNMolecule *mol);
+ void draw_list (Selection* sel);
+ void draw_list (MarchingCubes * cube);
+ // void draw_list (Grid& grid, int list);
+
+
+ void haptic_to_world_coordinates (vect &haptic_p, vect &world_p, float minx, float maxx, float miny, float maxy, float minz, float maxz);
+ void world_to_haptic_coordinates (vect &world_p, vect &haptic_p, float minx, float maxx, float miny, float maxy, float minz, float maxz);
+ vect rotate_vector (vect v);
+ vect unrotate_vector (vect v);
+
+
+ void move_molecule (ZNMolecule *mol, float x, float y, float z, bool cut_bool = true);
+
+
+ void translate_molecule (ZNMolecule *mol, vect v);
+
+
+ unsigned int next_list;
+ vector <int> empty_lists;
+
+ void free_list (int list);
+ int new_list ();
+ int lastx, lasty;
+
+
+ void compute_double_bond_vertexes (ZNBond *bond, float out[4][3], float d=0);
+
+ Matrix4fT Transform, Head_Tracking_Transf;
+
+ void update_current_color ();
+ QTime time, movie_time;
+ bool magic_pencil;
+ void apply_color_masks (vector <color_mask> masks, ZNMolecule *mol, bool undoable = TRUE);
+
+ inline void get_viewport_points (vect &up, vect &down, vect &left, vect &right) {up = up_point; down = down_point; left = left_point; right = right_point;}
+ public:
+ void select_MW (unsigned int an = 6);
+
+
+ vect center_of_rotation;
+ vect center_of_view, view_translations;
+ Matrix3fT LastRot, ThisRot; //Last_Head_Tracking_Rot;
+ void backbone_to_surface (ZNMolecule *mol, Surface *surf);
+ private:
+ int select_pulse;
+ vect up_point, down_point, left_point, right_point; // to define the current view. updated by every paintGL call
+
+ vector <float> vw_haptic_force;
+ vector <float> el_haptic_force;
+ vector <float> vw_haptic_torque;
+ vector <float> el_haptic_torque;
+
+ float el_haptic_e, vw_haptic_e;
+
+ Atom *clicked_atom;
+
+ float lasta2, lasta2increment;
+ bool isClicked, isDragging;
+
+
+ Point2fT MousePt;
+ bool zoom, translate, rotate, select, move, spin, selection_square;
+ int selection_square_x1, selection_square_y1, selection_square_x2, selection_square_y2;
+
+ float zbeginy, tbeginx, tbeginy, mbeginx, mbeginy, sbeginx;
+
+ DDWin *ddwin ;
+ void initializeGL ();
+ void init_vars ();
+ void paintGL();
+ void resizeGL( int width, int height );
+ void mousePressEvent ( QMouseEvent * e );
+ void mouseReleaseEvent ( QMouseEvent * e );
+ void mouseMoveEvent ( QMouseEvent * e );
+ void begin_zoom (float y);
+ void continue_zoom (float y);
+ void begin_magic_pencil (float x, float y);
+ void continue_magic_pencil (float x, float y);
+ void end_magic_pencil (float x, float y);
+ void begin_translate (float x, float y);
+ void begin_move (float x, float y);
+ void continue_translate (float x, float y);
+ void continue_move (float x, float y);
+ void begin_spin (float x, float y);
+ void continue_spin (float x, float y);
+ void begin_rotate (float x, float y);
+ void continue_rotate (float x, float y);
+ void selectf (float x, float y);
+ Atom *select_atom (float x, float y, int dx, int dy);
+ void select_square ();
+
+
+ void begin_selection_square (float x, float y);
+ void continue_selection_square (float x, float y);
+ void end_selection_square ();
+
+
+
+
+ void draw_atoms_for_selection (ZNMolecule* mol);
+ void draw_bonds_for_selection (ZNMolecule* mol);
+ void draw_bond_stick(ZNBond* bond);
+ void draw_double_bond_stick(ZNBond* bond);
+ void draw_bond_line(ZNBond* bond);
+ void draw_double_bond_line(ZNBond* bond);
+ void draw_triple_bond_line (ZNBond* bond);
+ void draw_aromatic_bond_line(ZNBond* bond);
+ void draw_aromatic_bond_stick(ZNBond* bond);
+ void draw_triple_bond_stick (ZNBond* bond);
+ void draw_ring_line (Ring* ring);
+ void draw_ring_stick (Ring* ring);
+
+ void draw_atom_sphere(Atom* atom);
+ void draw_atom_sel_sphere(Atom* atom);
+ void draw_atom_vdw_sphere(Atom* atom);
+ void draw_atom_scaled_vdw_sphere(Atom* atom);
+
+
+ void draw_backbone_line (Resid *res);
+ void draw_backbone_stick (Resid *res, Surface *surf = NULL);
+
+
+
+
+ void setAtomColor(Atom* atom);
+ void openGLSetColor (color col);
+
+
+
+ void my_line (vect v1, vect v2, color c1, color c2);
+ void my_cylinder (float rada, float radb, float lenght, unsigned int slices, Atom* at1, Atom *at2);
+ void my_backbone_ribbon (vect v1, vect v2, vect v3, vect v4, vect dir, vect dir2, color c1, color c2, vector <vect> shape1, vector <vect> shape2, Surface *surf) ;
+ void my_cylinder (vect v1, vect v2, float radone, float radtwo, color c1, color c2, unsigned int slices) ;
+ void my_cylinder (vect v1, vect v2, vect v3, vect v4, float radone, float radtwo, color c1, color c2, unsigned int slices) ;
+ void my_sphere (float rad, unsigned int slices, unsigned int stacks, Atom* at);
+
+
+
+ // void dragEnterEvent( QDragEnterEvent * );
+ // void dragMoveEvent( QDragMoveEvent * );
+ // void dragLeaveEvent( QDragLeaveEvent * );
+ // void dropEvent( QDropEvent * );
+
+
+ private slots:
+
+ void head_tracking_update (int x, int y);
+ void move_camera (float x, float y, float z);
+ void move_target (float x, float y, float z);
+ void map_vector_on_vector_world (double x1, double y1, double z1, double x2, double y2, double z2);
+ void map_vector_on_vector_target (double x1, double y1, double z1, double x2, double y2, double z2);
+
+ // void hide_hydrogens ();
+ // void hide_nonpolar_hydrogens ();
+ // void show_all ();
+
+
+
+
+
+ };
+
+void set_color (color c);
+
+
+#endif
diff --git a/headers/function.h b/headers/function.h
new file mode 100644
index 0000000..a6bc71c
--- /dev/null
+++ b/headers/function.h
@@ -0,0 +1,100 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef FUNCTION_H
+#define FUNCTION_H
+
+//#include "constants.h"
+#include <vector>
+
+using namespace std;
+
+typedef struct {
+ float* value;
+ float min_val, max_val;
+} Variable;
+
+class Function {
+ public:
+ Function () {evaluations = 0;};
+ ~Function () {};
+ virtual float evaluate () = 0;
+ vector <Variable*>& access_variables() {return _variables;};
+
+protected:
+ vector <Variable *> _variables;
+ unsigned int evaluations;
+
+};
+
+
+class Square : public Function {
+ public:
+ Square ()
+ {
+ // values.resize(1);
+ Variable* v = new Variable;
+ // v->value = &values[0];
+ *v->value = 2.0;
+ _variables.push_back(v);
+
+ };
+
+ Square (vector<float>& vv)
+ {
+ unsigned int i;
+ // values.resize(vv.size());
+ for (i = 0; i < vv.size(); i++) {
+ Variable* v = new Variable;
+ v->value = &vv[i];
+ *v->value = vv[i];
+ _variables.push_back(v);
+ }
+
+ };
+
+ ~Square () {
+ unsigned int i;
+
+ for (i = 0; i < _variables.size(); i++) {
+ if (_variables[i]) {
+ delete _variables[i];
+ }
+ }
+ };
+
+ float evaluate ()
+ {
+ evaluations++;
+ float v = 0.0;
+ unsigned int i;
+ for (i = 0; i < _variables.size(); i++) {
+ v += *_variables[i]->value * *_variables[i]->value;
+ }
+ return v;
+ };
+
+private:
+// vector<float> values;
+
+};
+
+
+
+
+#endif //FUNCTION_H
diff --git a/headers/graphical_object.h b/headers/graphical_object.h
new file mode 100644
index 0000000..fdd23ee
--- /dev/null
+++ b/headers/graphical_object.h
@@ -0,0 +1,173 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef GRAPHICAL_OBJECT_H
+#define GRAPHICAL_OBJECT_H
+
+
+
+#include "constants.h"
+#include "MarchingCubes.h"
+#include "FF.h"
+
+using namespace std;
+class MarchingCubes;
+
+
+typedef struct {
+ SurfVertex* v1;
+ SurfVertex* v2;
+ SurfVertex* v3;
+} SurfFace;
+
+class Map;
+
+class GraphicalObject {
+public:
+ GraphicalObject ();
+ string name;
+ int lst;
+ inline void set_name (string nam) {name = nam;};
+ bool mesh;
+ bool _clippable;
+ virtual bool is_surface ();
+ virtual bool is_sphere ();
+ virtual bool is_grid ();
+ virtual bool is_map ();
+ virtual void render () {};
+ virtual void color_by_color (color c) {};
+ virtual void color_by_mol (ZNMolecule *mol, float a = 1.) {};
+ virtual void color_by_potential (ZNMolecule *mol, color lipo, color hb_acc, color hb_don, float threshold = -4.f) {};
+ virtual void color_by_map (Map *map, color c1, color c2, color c3, float f1, float f2, float f3) {}
+ virtual void alpha_by_mol_distance (ZNMolecule *mol, float distance = 4.f) {};
+ virtual void multiply_alpha (double d) {};
+ virtual void set_alpha (double d) {};
+ bool is_clippable () {return _clippable;}
+ void set_clippable (bool b) {_clippable = b;}
+};
+
+class Surface : public GraphicalObject {
+
+public:
+ Surface ();
+ void color_by_atom (float a = 1.f);
+ void color_by_color (color c);
+ void color_by_mol (ZNMolecule *mol, float a = 1.f);
+ void color_by_map (Map *map, color c1, color c2, color c3, float f1, float f2, float f3);
+ void color_by_potential (ZNMolecule *mol, color lipo, color hb_acc, color hb_don, float threshold = -4.f);
+ void alpha_by_mol_distance (ZNMolecule *mol, float distance = 4.f);
+ virtual void multiply_alpha (double d) ;
+ virtual void set_alpha (double d) ;
+ void render ();
+ bool is_surface ();
+
+ float near_to_dist;
+ vector <SurfFace *> faces;
+ vector <SurfVertex *> vertices;
+ void set_molecule (ZNMolecule *mo, ZNMolecule *near_to);
+ ZNMolecule *near_to;
+ ZNMolecule *molecule;
+ cutoffGrid<Atom*> *grid;
+ cutoffGrid<Atom*> *near_to_grid;
+
+protected:
+ void fade_vertex_alpha_by_atom (SurfVertex *vert, float d);
+ void color_vertex_by_atom (SurfVertex *vert, float a);
+ void color_vertex_by_atom_smooth (SurfVertex *vert, float a);
+ void color_vertex_by_color (SurfVertex *vert, color c);
+
+ void set_vertex_alpha (SurfVertex *vert, float a);
+ void multiply_vertex_alpha (SurfVertex *vert, float a);
+ void color_vertex_by_map (SurfVertex *vert, Map *map, color c1, color c2, color c3, float f1, float f2, float f3);
+
+ void render_as_mesh ();
+ void render_as_surface ();
+
+};
+
+
+class Map : public Surface {
+public:
+ Map ();
+ void clean ();
+ bool is_map ();
+ void render ();
+ int type;
+// vector <SurfFace *> faces;
+// vector <SurfVertex *> vertices;
+ vect site_center;
+ float site_radius;
+// MarchingCubes *_mc;
+ ZNMolecule *molecule;
+ float threshold, resolution;
+ MarchingCubes *cube;
+ color solid_color;
+ float get_value (float x, float y, float z) {if (cube) return cube -> get_interpolated_data(x, y, z); else cerr <<"no no no"<<endl; return 0.f;};
+
+};
+
+
+class Sphere : public GraphicalObject {
+
+public:
+ bool is_sphere ();
+ inline void set_color (float r, float g, float b, float a) {col = color (r, g, b, a);};
+ inline void set_color (color c) {col = c;};
+// inline void set_center (float x, float y, float z) {center = vect (x, y, z);};
+ void set_center (vect cent) {center = cent;};
+ void set_radius (float r) {radius = r;};
+
+ void render ();
+ void render_as_surface ();
+
+
+ vect center;
+ color col;
+ float radius;
+
+private:
+
+
+
+};
+
+
+
+class Grid : public GraphicalObject {
+ public:
+ Grid ();
+ bool is_grid ();
+
+ vect origin;
+ vect end;
+ float res;
+ float threshold;
+ void load ();
+ ZNMolecule *probe;
+ vector <ZNMolecule *> env;
+
+ void init_ff ();
+ inline void set_env (vector <ZNMolecule *> mols) {env = mols;};
+ float (*function)(float, float, float);
+ float null (float x, float y, float z);
+ MarchingCubes *cube;
+ ForceField *ff;
+
+};
+
+#endif
diff --git a/headers/ils.h b/headers/ils.h
new file mode 100644
index 0000000..ecaef5f
--- /dev/null
+++ b/headers/ils.h
@@ -0,0 +1,117 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+
+#ifndef ILS_H
+#define ILS_H
+
+#include "optimiser.h"
+#include "nms.h"
+
+class ILS : public Optimiser {
+public:
+ ILS () : Optimiser () {};
+ ILS (Function* f) : Optimiser (f)
+ {
+ optFunc = f;
+ set_iteration_limit (0);
+
+ };
+ ~ILS () {};
+
+ float run ()
+ {
+ bool optimising = true;
+ minimiser = new NMS (optFunc);
+
+ // minimiser -> set_iteration_limit (20);
+ float variation_range = (float)M_PI;
+ unsigned int i = 0, j = 0;
+ vector<float> bestSolution;
+ float bestSolutionValue;
+ float tmpSolutionValue;
+ vector<Variable*>& vars = optFunc->access_variables();
+ for (j = 0; j < vars.size(); j++) {
+ bestSolution.push_back(*vars[j]->value);
+ }
+ bestSolutionValue = optFunc->evaluate();
+ start_timer ();
+ while (!reached_limits ()) {
+ for (j = 0; j < vars.size(); j++) {
+ do {
+ float variation_range = (vars[j]->max_val - vars[j]->min_val)/2;
+
+ *vars[j]->value = bestSolution[j] -variation_range + 2 * variation_range*(float)rand()/(float)RAND_MAX;
+ //cerr << *vars[j]->value << " "<<vars[j]->min_val <<" "<< vars[j]->max_val<<endl;
+ }
+ while ((*vars[j]->value < vars[j]->min_val) || (*vars[j]->value > vars[j]->max_val));
+ }
+ if (optimising) {
+ minimiser -> init (vars);
+ minimiser -> run ();
+
+ }
+ bool accept = true;
+ for (j = 0; j < vars.size(); j++) {
+ if ((*vars[j]->value < vars[j]->min_val) || (*vars[j]->value > vars[j]->max_val)) {
+ accept = false;
+ break;
+ }
+ }
+
+ if (accept) {
+ tmpSolutionValue = optFunc->evaluate();
+ conformation *solution = new conformation;
+ solution ->score = tmpSolutionValue;
+ for (j = 0; j < vars.size(); j++) {
+ solution ->state.push_back (*vars[j]->value);
+ }
+ results.push_back (solution);
+ if ( tmpSolutionValue < bestSolutionValue) {
+ for (j = 0; j < vars.size(); j++) {
+ bestSolution[j] = (*vars[j]->value);
+ }
+ bestSolutionValue = tmpSolutionValue;
+ cout << "BEST: " << tmpSolutionValue << endl;
+ }
+ iterations_n ++;
+ }
+ }
+ for (j = 0; j < vars.size(); j++) {
+ *vars[j]->value = bestSolution[j];
+ }
+ tmpSolutionValue = optFunc->evaluate();
+
+ sort (results.begin (), results.end (), conformationScoreCompare ());
+ /* for (j = 0; j < results.size(); j++) {
+ cerr << results[j] ->score<<" ";
+ for (i=0; i< results[j] ->state.size (); i++) {
+ cerr << results[j]->state[i];
+ }
+ cerr << endl;
+ }*/
+ return tmpSolutionValue;
+ };
+
+private:
+ Optimiser *minimiser;
+
+
+};
+
+#endif //ILS_H
\ No newline at end of file
diff --git a/headers/iodevice.h b/headers/iodevice.h
new file mode 100644
index 0000000..fc95b77
--- /dev/null
+++ b/headers/iodevice.h
@@ -0,0 +1,50 @@
+
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef IODEVICE_H
+#define IODEVICE_H
+/*
+#include "maths.h"
+
+class IODevice {
+ public:
+
+ IODevice ();
+ bool is_input () {return _input;};
+ bool is_output () {return _output;};
+ virtual void initialise () = 0;
+ virtual void deinitialise () = 0;
+ virtual vect get_current_position () = 0;
+ virtual void set_feedback (vect v) = 0;
+ std::string name;
+ protected:
+ bool _input, _output;
+ private:
+};
+
+
+
+class VideoDevice : public IODevice {
+ public:
+ VideoDevice ();
+};
+
+*/
+#endif //IODEVICE_H
+
diff --git a/headers/maths.h b/headers/maths.h
new file mode 100644
index 0000000..0fde23d
--- /dev/null
+++ b/headers/maths.h
@@ -0,0 +1,79 @@
+
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef MATHS_H
+#define MATHS_H
+
+#include <math.h>
+#include "obabel_includes.h"
+
+
+//using namespace OpenBabel;
+//struct vector3;
+//typedef OpenBabel::vector3 vect;
+
+class vect : public OpenBabel::vector3 {
+ public:
+ vect (double x = 0., double y = 0., double z = 0.);
+ vect (const OpenBabel::vector3& );
+ // double x;
+ // double y;
+ // double z;
+
+ inline double square_module () {return length_2 ();}
+ inline double module () {return length ();};
+ inline void trunc_at (double f) {if (module () > f) scale_to (f);}
+ void multiply (double f);
+ void null ();
+ void normalise ();
+ void scale_to (double f);
+
+};
+
+
+
+
+class quaternion {
+ public:
+ quaternion (double w, double x, double y, double z);
+ quaternion ();
+ inline double x () {return _x;}
+ inline double y () {return _y;}
+ inline double z () {return _z;}
+ inline double w () {return _w;}
+ private:
+ double _x, _y, _z, _w;
+
+};
+double square_distance (vect coord1, vect coord2);
+inline double dot_product (vect v1, vect v2) {return dot (v1, v2);};
+vect cross_product (vect v1, vect v2);
+
+inline vect sum (vect v1, vect v2) {return vect (v1.x()+v2.x(), v1.y()+v2.y(), v1.z()+v2.z());};
+inline vect subtract (vect v1, vect v2) {return vect (v1.x()-v2.x(), v1.y()-v2.y(), v1.z()-v2.z());};
+inline vect mean (vect v1, vect v2) {vect s = sum (v1, v2); s.multiply (0.5f); return s;}
+vect circumcenter (vect v1, vect v2, vect v3);
+double dist (vect v1, vect v2);
+void interpolate (vect v1, vect v2, vect v3, vect& i1, vect &i2);
+
+
+
+
+
+#endif
diff --git a/headers/menu.h b/headers/menu.h
new file mode 100644
index 0000000..8da5db1
--- /dev/null
+++ b/headers/menu.h
@@ -0,0 +1,1541 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef MENU_H
+#define MENU_H
+
+
+#include "constants.h"
+#include "ZNdata.h"
+#include <qmenubar.h>
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+#include <qlabel.h>
+#include <Qt3Support/q3grid.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qevent.h>
+#include <Qt3Support/q3dragobject.h>
+#include <qdir.h>
+#include <qcolordialog.h>
+#include <qtabwidget.h>
+#include <qslider.h>
+#include "ZNmolecule.h"
+#include "qstackedwidget.h"
+#include <qlistwidget.h>
+#include "command.h"
+#include <QRadioButton>
+#include "thread.h"
+#include <QTableWidget>
+
+
+#define BIG 999999999
+
+class MySlider; class MyFloatEditLine; class MyIntegerEditLine; class Builder; class Minimize; class DDWin; class MyLabelf; class MyCompleteColorSettings; class MyColorButton; class DatabaseField; class MyComboBox; class MyHideComboBox; class Data; class MyHideCheckBox; class MyGroupBox; class MyTwoColumn; class MyCheckBox; class My3Column; class MyGridColumn; class MyLineFile; class MyLineEdit; class MyListView; class MyPushButton; class MyListButton; class MyTableWidget;
+class Thread; class HapticThread;
+
+
+class ZNWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ ZNWidget (QWidget *parent = 0);
+};
+
+
+
+class ZNAdvancedWidget : public ZNWidget {
+ Q_OBJECT
+
+public:
+ ZNAdvancedWidget (const char *advance="Advanced options", bool show=true);
+ QLayout *basic_layout () {return _public ->layout ();};
+ QLayout *advanced_layout () {return _private ->layout ();};
+// QWidget *basic_widget () {return(QWidget *) _public;};
+// QWidget *advanced_widget () {return (QWidget *) _private;};
+
+private:
+
+protected:
+// MyHideCheckBox *_hide_check_box;
+ MyGroupBox *_group_box;
+ ZNWidget *_private, *_public;
+
+ protected slots:
+ void hide_advanced_slot();
+};
+
+
+
+class ZNMenu : public QMainWindow {
+ Q_OBJECT
+
+public:
+ ZNMenu (QWidget *parent, Data *dat, bool tabs=false, bool advanced = false);
+// ~ZNMenu () {~QWidget ();};
+ QWidget *main_widget () {return _main_widget;};
+ void addMenu (QMenu *menu) {menuBar () ->addMenu (menu);};
+ void display () {if (display_requirements_met ()) {show (); raise ();}};
+
+private:
+
+protected:
+ Data *_data;
+ //QMenuBar *_menu_bar;
+ virtual bool display_requirements_met () {return true;};
+ bool check_for_a_set_target ();
+ QAction *_about_action;
+ QWidget *_main_widget;
+ QTabWidget *_tabs;
+ virtual void add_menu () {};
+ void add_help ();
+
+ protected slots:
+ virtual void _show_about () {cerr<<"about"<<endl;};
+ void _load_bot_fel (string& buffer, const char *reference, MyFloatEditLine *target, const char *sep=" ");
+ void _load_bot_iel (string& buffer, const char *reference, MyIntegerEditLine *target, const char *sep=" ");
+ void _load_bot_lf (string& buffer, const char *reference, MyLineFile *target);
+ void _load_bot_chb (string& buffer, const char *reference, MyCheckBox *target);
+ void _load_bot_box (string& buffer, const char *reference, MyGroupBox *target);
+ void _load_bot_cb (string& buffer, const char *reference, MyComboBox *target);
+ void _load_bot_le (string& buffer, const char *reference, MyLineEdit *target);
+};
+
+
+
+class SurfaceMenu : public QWidget {
+ Q_OBJECT
+
+public:
+
+ SurfaceMenu ( QWidget *parent, Data *dat);
+ Data *data;
+ Surface *surface;
+
+
+private:
+// ZNMolecule *molecule;
+ QComboBox *stype;
+ QComboBox *gtype;
+
+ QComboBox *near_to;
+ MyFloatEditLine *resolution;
+ MyFloatEditLine *alpha_p, *near_to_dle;
+ MySlider *alpha_s;
+ double res;
+ float color [4];
+ int alpha;
+ int type;
+ bool mesh;
+ double near_to_f;
+
+private slots:
+ void add_surface ();
+ void draw_surface ();
+ void update_near_to ();
+
+};
+
+
+
+class MapMenu : public ZNMenu {
+ Q_OBJECT
+ public:
+ Map *map;
+ MapMenu (QWidget *parent, Data *dat);
+ MyGroupBox *_site_box;
+ MyFloatEditLine *_site_x_el;
+ MyFloatEditLine *_site_y_el;
+ MyFloatEditLine *_site_z_el;
+ MyFloatEditLine *_site_r_el;
+ MyFloatEditLine *_threshold_el;
+ MyFloatEditLine *_resolution_el;
+ MyLineEdit *_name_el;
+ MyComboBox *_type_cb;
+ double _x, _y, _z, _r, _threshold, _resolution;
+ MyPushButton *_compute_map_bt;
+ color _solid_color;
+ private:
+ private slots:
+ bool display_requirements_met () ;
+ void compute_map_slot ();
+ void add_map ();
+};
+
+
+class SphereMenu : public QWidget {
+ Q_OBJECT
+
+public:
+
+ SphereMenu ( QWidget *parent, Data* dat);
+ Data *data;
+
+private:
+ MyFloatEditLine *cent_x;
+ MyFloatEditLine *cent_y;
+ MyFloatEditLine *cent_z;
+ MyFloatEditLine *rad;
+ MySlider *alpha_s;
+ color col;
+
+ double x, y, z;
+ int alpha;
+ double radius;
+
+ private slots:
+ void draw_sphere ();
+};
+
+
+class SequenceMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ SequenceMenu (QWidget *parent, Data *dat);
+
+ public slots:
+ void update_tab ();
+ void del_from_tab (ZNMolecule *mol);
+
+private:
+ QTableWidget *tab;
+ int row, column;
+ QAction *_residue_indice, *_residue_uid, *_save_sequence;
+ QActionGroup *aminoacidGroup;
+
+ private slots:
+ void update_graphics (int row, int r, QString residue);
+ void clicked_cell (int x, int y);
+ void selected_cells ();
+ void pressed_cell (QTableWidgetItem *item);
+ void add_menu ();
+ void add_help ();
+ void _residue_indice_slot ();
+ void _residue_uid_slot ();
+ void _save_sequence_slot ();
+
+};
+
+
+class DisplayMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ DisplayMenu (QWidget *parent, Data *dat);
+ MyTwoColumn *values_tc;
+ MyGridColumn *disp_gc, *_dsetbutts_gc;
+ QComboBox *at_disp, *bo_disp, *ar_disp;
+ MyComboBox *backbone_disp;
+ QPushButton *dset_wireframe, *dset_stick, *dset_cpk, *dset_ball_and_stick, *dset_ball_and_line;
+ MyPushButton *ok_p;
+ MyGroupBox *backbone_box, *display_mode_box, *atoms_box, *bonds_box;
+
+private:
+ vector <MyFloatEditLine*> at_opts, bo_opts;
+ int style_str_to_i (string style);
+
+ private slots:
+ void disp_ok ();
+ void set_wireframe ();
+ void set_stick ();
+ void set_cpk ();
+ void set_ballandline ();
+ void set_ballandstick ();
+ void set_conf (int conf);
+};
+
+class BuilderMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ BuilderMenu (QWidget *parent, Data *dat, Builder *build);
+ MyPushButton *_C, *_N, *_O, *_S, *_F, *_H, *_P, *_Cl, *_I, *_Br, *_H_b, *_He_b, *_Li_b, *_Be_b, *_B_b, *_C_b, *_N_b, *_O_b, *_F_b, *_Ne_b, *_Na_b, *_Mg_b, *_Al_b, *_Si_b, *_P_b, *_S_b, *_Cl_b, *_Ar_b, *_K_b, *_Ca_b, *_Sc_b, *_Ti_b, *_V_b, *_Cr_b, *_Mn_b, *_Fe_b, *_Co_b, *_Ni_b, *_Cu_b, *_Zn_b, *_Ga_b, *_Ge_b, *_As_b, *_Se_b, *_Br_b, *_Kr_b, *_Rb_b, *_Sr_b, *_Y_b, *_Zr_b, *_Nb_b, *_Mo_b, *_Tc_b, *_Ru_b, *_Rh_b, *_Pd_b, *_Ag_b, *_Cd_b, *_In_b, *_Sn_b, *_Sb_b, *_Te_b, *_I_b, *_Xe_b, *_Cs_b [...]
+ Builder *builder;
+ QLineEdit *smiles;
+ MyTwoColumn *_smiles_tc;
+ MyGridColumn *_periodictable_gc, *_atoms_gc, *_bonds_gc, *_fragments_gc, *_rings_gc, *_basic_gc, *_aminoacids_gc;
+ MyGroupBox *_atoms_box, *_rings_box, *_fragments_box, *_bonds_box, *_aminoacids_box, *_nucleotides_box, *_heterocycles_box, *_smiles_box, *_del_box;
+
+ private slots:
+ void add_smiles ();
+ void add_benzene ();
+ void add_mol (string str);
+ void add_fragment (string str);
+ void add_ring3 ();
+ void add_ring4 ();
+ void add_ring5 ();
+ void add_ring6 ();
+ void add_ring7 ();
+ void add_ring8 ();
+ void add_furan ();
+ void add_furanO ();
+ void add_CO ();
+ void add_NCO ();
+ void add_COOH ();
+ void add_CCd ();
+ void add_CCt ();
+ void add_CN ();
+ void add_PO3 ();
+ void add_NO2 ();
+ void add_SO2 ();
+ void add_H ();
+ void add_He ();
+ void add_Li ();
+ void add_Be ();
+ void add_B ();
+ void add_C ();
+ void add_N ();
+ void add_O ();
+ void add_F ();
+ void add_Ne ();
+ void add_Na ();
+ void add_Mg ();
+ void add_Al ();
+ void add_Si ();
+ void add_P ();
+ void add_S ();
+ void add_Cl ();
+ void add_Ar ();
+ void add_K ();
+ void add_Ca ();
+ void add_Sc ();
+ void add_Ti ();
+ void add_V ();
+ void add_Cr ();
+ void add_Mn ();
+ void add_Fe ();
+ void add_Co ();
+ void add_Ni ();
+ void add_Cu ();
+ void add_Zn ();
+ void add_Ga ();
+ void add_Ge ();
+ void add_As ();
+ void add_Se ();
+ void add_Br ();
+ void add_Kr ();
+ void add_Rb ();
+ void add_Sr ();
+ void add_Y ();
+ void add_Zr ();
+ void add_Nb ();
+ void add_Mo ();
+ void add_Tc ();
+ void add_Ru ();
+ void add_Rh ();
+ void add_Pd ();
+ void add_Ag ();
+ void add_Cd ();
+ void add_In ();
+ void add_Sn ();
+ void add_Sb ();
+ void add_Te ();
+ void add_I ();
+ void add_Xe ();
+ void add_Cs ();
+ void add_Ba ();
+ void add_Lu ();
+ void add_Hf ();
+ void add_Ta ();
+ void add_W ();
+ void add_Re ();
+ void add_Os ();
+ void add_Ir ();
+ void add_Pt ();
+ void add_Au ();
+ void add_Hg ();
+ void add_Tl ();
+ void add_Pb ();
+ void add_Bi ();
+ void add_Po ();
+ void add_At ();
+ void add_Rn ();
+ void add_Fr ();
+ void add_Ra ();
+ void add_Lr ();
+ void add_Rf ();
+ void add_Db ();
+ void add_Sg ();
+ void add_Bh ();
+ void add_Hs ();
+ void add_Mt ();
+ void add_Ds ();
+ void add_Rg ();
+ void add_Uub ();
+ void add_Uut ();
+ void add_Uuq ();
+ void add_Uup ();
+ void add_Uuh ();
+ void add_Uus ();
+ void add_Uuo ();
+ void add_La ();
+ void add_Ce ();
+ void add_Pr ();
+ void add_Nd ();
+ void add_Pm ();
+ void add_Sm ();
+ void add_Eu ();
+ void add_Gd ();
+ void add_Tb ();
+ void add_Dy ();
+ void add_Ho ();
+ void add_Er ();
+ void add_Tm ();
+ void add_Yb ();
+ void add_Ac ();
+ void add_Th ();
+ void add_Pa ();
+ void add_U ();
+ void add_Np ();
+ void add_Pu ();
+ void add_Am ();
+ void add_Cm ();
+ void add_Bk ();
+ void add_Cf ();
+ void add_Es ();
+ void add_Fm ();
+ void add_Md ();
+ void add_No ();
+
+ void single_bond ();
+ void double_bond ();
+ void triple_bond ();
+ void no_bond ();
+
+ void add_Ala ();
+ void add_Arg ();
+ void add_Asn ();
+ void add_Asp ();
+ void add_Cys ();
+ void add_Glu ();
+ void add_Cln ();
+ void add_Gly ();
+ void add_His ();
+ void add_Ile ();
+ void add_Leu ();
+ void add_Lys ();
+ void add_Met ();
+ void add_Phe ();
+ void add_Pro ();
+ void add_Ser ();
+ void add_Thr ();
+ void add_Trp ();
+ void add_Tyr ();
+ void add_Val ();
+
+};
+
+
+
+class HapticMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ QReadWriteLock *restrain_lock;
+ QComboBox *interff;
+ QComboBox *dofmode;
+ HapticMenu ( QWidget *parent, Data* dat);
+ Minimize *minimize;
+ HapticThread *haptic_thread;
+ MyLabelf *interaction_E;
+ MyListView *restrain_list;
+ vector <ForceFieldInteraction *> restrains;
+ void update_energy ();
+ void maybe_save_result ();
+ bool automove_b, color_by_score_b, saving;
+ double cluster_RMSD, E_tolerance, last_k, last_dist, mult;
+ void add_restrain_atom (Atom *at);
+ MyFloatEditLine *restrain_dist;
+ MyFloatEditLine *restrain_k;
+ QLabel *label;
+ Atom *last_atom;
+ private slots:
+ void Ok ();
+ void end ();
+ void add_restrain ();
+ void clear_restrains ();
+ void delete_restrain (int);
+ void update_k (double);
+ void update_dist (double);
+ void update_spinboxes (int);
+
+ void user_save_current_pose ();
+};
+
+/*
+
+class BrowserMenu : public QWidget {
+ Q_OBJECT
+
+public:
+ BrowserMenu ( QWidget *parent, DDWin* ddwin);
+ int current_number;
+
+ Database *target;
+ DDWin *ddwin;
+
+ void set_mol ();
+ void set_target (Database *db);
+
+ private slots:
+ void first_slot ();
+ void prev_slot ();
+ void next_slot ();
+ void last_slot ();
+};
+
+*/
+
+class Clicked_atomMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ Clicked_atomMenu ( QWidget *parent, Data* dat);
+
+ //Q3Frame *atomselpopup;
+ QLabel *aplid, *aplat, *aplq;
+ QLineEdit *aplfc, *aplx, *aply, *aplz;
+ QLabel *resna, *resnu, *aptype;
+ QLabel *idl;
+ MyIntegerEditLine *formal_charge_le;
+
+ Atom *clicked_atom;
+
+ void set (Atom *at);
+ void update ();
+
+ int formal_charge;
+ private slots:
+ void set_value (QLabel *lab, float val) ;
+ void set_value (QLabel *lab, string val) ;
+ void set_value (QLineEdit *lab, float val) ;
+
+ void add_Hs ();
+ void set_clicked_atom_as_center_of_view ();
+ void set_clicked_atom_as_center_of_rotation ();
+};
+
+
+
+class ColorSettingsMenu : public QWidget {
+
+public:
+ DDWin *ddwin;
+ ColorSettingsMenu ( QWidget *parent, DDWin* ddwin);
+};
+
+
+
+class ColorMenu : public QWidget {
+ Q_OBJECT
+
+public:
+ DDWin *ddwin;
+ ColorMenu ( QWidget *parent, DDWin* ddwin);
+
+ QComboBox *colortype;
+ QStackedWidget *options;
+
+private:
+ QColor constant_color;
+ MyFloatEditLine *score_begin_line, *score_mid_line, *score_end_line, *charge_begin_line, *charge_end_line;
+
+ private slots:
+ void ok_slot ();
+};
+
+class BackboneColorMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ DDWin *ddwin;
+ BackboneColorMenu ( QWidget *parent, Data *dat);
+
+ QComboBox *colortype;
+ QStackedWidget *options;
+
+private:
+ color constant_color, helix_color, sheet_color, random_color;
+ MyFloatEditLine *score_begin_line, *score_mid_line, *score_end_line, *charge_begin_line, *charge_end_line;
+
+ private slots:
+ void color_ok_slot ();
+ void ss_ok_slot ();
+};
+
+
+class GraphicalObjectsColorMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ DDWin *ddwin;
+ GraphicalObjectsColorMenu ( QWidget *parent, Data *dat);
+
+ QComboBox *colortype, *molecule_target_cb, *molecule_target_cb2, *molecule_target_cb3, *maps_cb;
+ QStackedWidget *options;
+ void set_target (GraphicalObject *go) {target = go;};
+private:
+ color constant_color;
+ GraphicalObject *target;
+ double score_begin_f, score_end_f, score_mid_f;
+ color score_begin_color, score_end_color, score_mid_color, lipo_color, hb_acc_color, hb_don_color;
+ double alpha_mol_distance_d, alpha_value, alpha_multiplier ;
+ private slots:
+ void ok_slot ();
+ void update_mols ();
+ void update_maps ();
+ void mult_slot ();
+ void alpha_slot ();
+ void fade_slot ();
+
+
+};
+
+
+
+class DDSettingsMenu : public QWidget {
+ Q_OBJECT
+
+public:
+ DDWin *ddwin;
+ DDSettingsMenu ( QWidget *parent, DDWin* ddwin);
+ double focal_d;
+
+private:
+ MyFloatEditLine *inter_eye_distance, *focal_point_distance;
+ QComboBox *dd_cb;
+
+ private slots:
+ void ok_slot ();
+};
+
+
+
+class GraphicalObjectsMenu : public QWidget {
+ Q_OBJECT
+
+public:
+ DDWin *ddwin;
+ GraphicalObjectsMenu ( QWidget *parent, DDWin* ddwin);
+
+private:
+ QListWidget *list;
+ void paintEvent ( QPaintEvent * ) ;
+
+ public slots:
+ void update_slot ();
+ void delete_selected_slot ();
+ void show_color_menu (QListWidgetItem *item);
+};
+
+
+
+
+class DatabaseGrid : public ZNMenu {
+ Q_OBJECT
+
+public:
+ DatabaseGrid ( QWidget *parent, Database *db, Data *dat);
+ Database *database;
+ Data *data;
+ QTableWidget *tab;
+ //BrowserMenu *browser;
+
+ void add_menu ();
+ inline bool has_extend_enabled () {return ext_bool;};
+ int real_index_of_line (int);
+ void set_database (Database *db);
+ void update_graphics ();
+ vector <int> selected_columns ();
+
+ void set_mol ();
+
+private:
+ MyCheckBox *hide_cb;
+ void setup_actions ();
+ bool ext_bool;
+ QLineEdit *le;
+ int current_number;
+
+// void set_no_mol ();
+
+ QAction *sortupAct, *sortdownAct, *newFieldAct, *addTargetMolAct, *loadCsvAct, *mergedatabaseAct, *univocalnamesAct;
+ QAction *FiTAct, *calcAct;
+ QToolBar *toolbar;
+ private slots:
+ void manage_hide (bool b);
+ void select_row (int r);
+ void deselect_row (int r);
+ void set_row_color (int r, color c);
+ void set_current_molecule (int i);
+ void manage_number_changed (const QString str);
+ void manage_double_click (int r);
+ void add_target_molecule_slot ();
+ void merge_database_slot ();
+ void univocal_names_slot ();
+ void new_field_slot ();
+ void first_slot ();
+ void prev_slot ();
+ void next_slot ();
+ void last_slot ();
+
+ void sort_up_slot ();
+ void sort_down_slot ();
+
+ void FiT_slot ();
+ void calc_slot ();
+ void load_csv_slot ();
+ void update_cell (int row, int column);
+};
+
+
+
+class IODeviceMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ IODeviceMenu (QWidget *parent, Data *dat);
+// ~IODeviceMenu () {~ZNMenu ();};
+
+private:
+ QListView *_input_listview, *_output_listview;
+
+protected:
+
+ protected slots:
+};
+
+
+class DockingMenu : public ZNMenu {
+ Q_OBJECT
+ public:
+ DockingMenu (QWidget *parent, Data *dat);
+ MyGroupBox *_binding_site_box;
+ MyFloatEditLine *_site_x_el;
+ MyFloatEditLine *_site_y_el;
+ MyFloatEditLine *_site_z_el;
+ MyFloatEditLine *_site_r_el;
+ double _x, _y, _z, _r;
+ MyPushButton *_start_docking_bt;
+ private:
+ bool display_requirements_met ();
+ private slots:
+ void start_docking_slot ();
+};
+
+class ThreadWidget : public ZNWidget {
+ Q_OBJECT
+ public:
+ ThreadWidget (QWidget *parent = 0);
+ QLabel *_name, *_action;
+ QProgressBar *_progress_bar;
+};
+
+class ThreadMenu : public ZNMenu {
+ Q_OBJECT
+ public:
+ ThreadMenu (QWidget *parent, Data *dat);
+ void display_thread (int n, Thread *thread);
+ void clear (int i = 0);
+ private:
+ vector <ThreadWidget *> widgets;
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Preferences menu
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+class PrefMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ PrefMenu (QWidget *parent, Data *dat);
+
+ public slots:
+
+
+private:
+
+protected:
+ MyLineFile *plants_file;
+ MyLineFile *gamess_file;
+ MyPushButton *_save_preferences_b;
+ QLabel *label;
+
+ protected slots:
+ void _save_preferences ();
+
+
+
+};
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// PLANTS menu FE
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+const string VERSION_PLANTS = "1.1";
+
+
+
+class PLANTSMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ PLANTSMenu (QWidget *parent, Data *dat);
+// vector <QComboBox*> lat, pat, pres;
+// OBMol *prot;
+ vect d;
+ float f;
+ string plants_exe;
+
+private:
+
+
+protected:
+ bool runPlants;
+ void add_menu ();
+ bool check_mol2 (string line);
+ bool mol;
+// main tab
+// input options
+ MyGroupBox *_input_box;
+ MyTwoColumn *_input_tc;
+ MyLineFile *load_protein_file;
+ MyLineFile *load_ligand_file;
+ MyLineFile *load_ligand_list_file;
+ MyListView *input_file_list;
+ MyListView *input_file;
+ double _zero_value;
+ double _min_radius;
+// binding site
+ MyGroupBox *_binding_site_box;
+ MyPushButton *_binding_site_from_ligand_b;
+ MyTwoColumn *_binding_site_tc;
+ MyFloatEditLine *_site_x_el;
+ MyFloatEditLine *_site_y_el;
+ MyFloatEditLine *_site_z_el;
+ MyFloatEditLine *_site_radius_el;
+ vector3 coordinates;
+ double site_x;
+ double site_y;
+ double site_z;
+// output options
+ MyGroupBox *_output_box;
+ MyLineEdit *_output_dir;
+ My3Column *_output_tc;
+ MyGroupBox *_output_adv_box;
+ bool _write_protein_conformations_value;
+ MyCheckBox *_write_protein_conformations_chb;
+ bool _write_protein_bindingsite_value;
+ MyCheckBox *_write_protein_bindingsite_chb;
+ bool _write_protein_splitted_value;
+ MyCheckBox *_write_protein_splitted_chb;
+ bool _write_rescored_structures_value;
+ MyCheckBox *_write_rescored_structures_chb;
+ bool _write_multi_mol2_value;
+ MyCheckBox *_write_multi_mol2_chb;
+ bool _write_ranking_links_value;
+ MyCheckBox *_write_ranking_links_chb;
+ bool _write_ranking_multi_mol2_value;
+ MyCheckBox *_write_ranking_multi_mol2_chb;
+ bool _write_per_atom_scores_value;
+ MyCheckBox *_write_per_atom_scores_chb;
+ bool _write_merged_ligand_value;
+ MyCheckBox *_write_merged_ligand_chb;
+ bool _write_merged_protein_value;
+ MyCheckBox *_write_merged_protein_chb;
+ bool _write_merged_water_value;
+ MyCheckBox *_write_merged_water_chb;
+ bool _keep_original_mol2_description_value;
+ MyCheckBox *_keep_original_mol2_description_chb;
+// bool _merge_multi_conf_output_value;
+ MyGroupBox *_merge_multi_conf_output_box;
+ const char *_merge_multi_conf_character_value;
+ MyLineEdit *_merge_multi_conf_character;
+ int _merge_multi_conf_after_characters_value;
+ MyIntegerEditLine *_merge_multi_conf_after_characters_el;
+ MyTwoColumn *_merge_multi_conf_output_tc;
+// Algorithm tab
+// search options
+ MyGroupBox *_search_box;
+ MyComboBox *_search_speed_cb;
+ My3Column *_search_tc;
+ int _aco_ants_value;
+ MyIntegerEditLine *_aco_ants_el;
+ double _aco_evap_value;
+ MyFloatEditLine *_aco_evap_el;
+ double _aco_sigma_value;
+ MyFloatEditLine *_aco_sigma_el;
+ MyTwoColumn *_flip_tc;
+ bool _flip_amide_bonds_value;
+ MyCheckBox *_flip_amide_bonds_chb;
+ bool _flip_planar_n_value;
+ MyCheckBox *_flip_planar_n_chb;
+ bool _force_flipped_bonds_planarity_value;
+ MyCheckBox *_force_flipped_bonds_planarity_chb;
+ bool _force_planar_bond_rotation_value;
+ MyCheckBox *_force_planar_bond_rotation_chb;
+ MyComboBox *_rescore_mode_cb;
+// scoring options
+ MyGroupBox *_scoring_box;
+ MyComboBox *_algorithm_type_cb;
+ double _outside_binding_site_penalty_value;
+ MyFloatEditLine *_outside_binding_site_penalty_el;
+ MyTwoColumn *_score_inter_tc;
+ My3Column *_score_intra_tc;
+ MyGroupBox *_search_adv_box;
+ MyTwoColumn *_search_adv_tc;
+ bool _enable_sulphur_acceptors_value;
+ MyCheckBox *_enable_sulphur_acceptors_chb;
+ bool _chemplp_clash_include_HH_value;
+ MyCheckBox *_chemplp_clash_include_HH_chb;
+ double _chemplp_clash_include_14_value;
+ MyFloatEditLine *_chemplp_clash_include_14_el;
+ MyComboBox *_ligand_intra_score_cb;
+ MyGroupBox *_scoring_inter_box;
+ MyGroupBox *_scoring_intra_box;
+// plp/plp5
+ MyGroupBox *_plp_weights_box;
+ My3Column *_plp_weights_tc;
+ double _plp_steric_e_value;
+ MyFloatEditLine *_plp_steric_e_el;
+ double _plp_burpolar_e_value;
+ MyFloatEditLine *_plp_burpolar_e_el;
+ double _plp_hbond_e_value;
+ MyFloatEditLine *_plp_hbond_e_el;
+ double _plp_metal_e_value;
+ MyFloatEditLine *_plp_metal_e_el;
+ double _plp_repulsive_weight_value;
+ MyFloatEditLine *_plp_repulsive_weight_el;
+ double _plp_tors_weight_value;
+ MyFloatEditLine *_plp_tors_weight_el;
+// chemplp
+ MyGroupBox *_chemplp_weights_box;
+ My3Column *_chemplp_weights_tc;
+ bool _chemplp_weak_cho_value;
+ MyCheckBox *_chemplp_weak_cho_chb;
+ double _chemplp_charged_hb_weight_value;
+ MyFloatEditLine *_chemplp_charged_hb_weight_el;
+ double _chemplp_charged_metal_weight_value;
+ MyFloatEditLine *_chemplp_charged_metal_weight_el;
+ double _chemplp_hbond_weight_value;
+ MyFloatEditLine *_chemplp_hbond_weight_el;
+ double _chemplp_hbond_cho_weight_value;
+ MyFloatEditLine *_chemplp_hbond_cho_weight_el;
+ double _chemplp_metal_weight_value;
+ MyFloatEditLine *_chemplp_metal_weight_el;
+ double _chemplp_plp_weight_value;
+ MyFloatEditLine *_chemplp_plp_weight_el;
+ double _chemplp_plp_steric_e_value;
+ MyFloatEditLine *_chemplp_plp_steric_e_el;
+ double _chemplp_plp_burpolar_e_value;
+ MyFloatEditLine *_chemplp_plp_burpolar_e_el;
+ double _chemplp_plp_hbond_e_value;
+ MyFloatEditLine *_chemplp_plp_hbond_e_el;
+ double _chemplp_plp_metal_e_value;
+ MyFloatEditLine *_chemplp_plp_metal_e_el;
+ double _chemplp_plp_repulsive_weight_value;
+ MyFloatEditLine *_chemplp_plp_repulsive_weight_el;
+ double _chemplp_tors_weight_value;
+ MyFloatEditLine *_chemplp_tors_weight_el;
+ double _chemplp_lipo_weight_value;
+ MyFloatEditLine *_chemplp_lipo_weight_el;
+ double _chemplp_intercept_weight_value;
+ MyFloatEditLine *_chemplp_intercept_weight_el;
+ MyTwoColumn *_cluster_docking_tc;
+// cluster options
+ MyGroupBox *_cluster_box;
+ double _cluster_rmsd_value;
+ MyFloatEditLine *_cluster_rmsd_el;
+ int _cluster_structures_value;
+ MyIntegerEditLine *_cluster_structures_el;
+//
+ MyGroupBox *_docking_box;
+ bool _rigid_ligand_value;
+ MyCheckBox *_rigid_ligand_chb;
+ bool _rigid_all_value;
+ MyCheckBox *_rigid_all_chb;
+// Costraints tab
+ MyGroupBox *_costraints_box;
+ MyGroupBox *_protein_hb_costraint_box;
+ MyGroupBox *_shape_costraint_box;
+ MyGroupBox *_surface_distance_costraint_box;
+ MyGroupBox *_ligand_intra_distance_costraint_box;
+ MyGroupBox *_protein_ligand_distance_costraint_box;
+ MyTwoColumn *_protein_hb_costraint_tc;
+ MyTwoColumn *_shape_costraint_tc;
+ MyListView *costraints_file_list;
+ MyLineFile *load_shape_file;
+ MyTwoColumn *_costraints_tc;
+ MyFloatEditLine *_shape_weight;
+ MyPushButton *_shape_weight_b;
+ const char *title_shape;
+ MyComboBox *_protein_hb_costraint_cb;
+ MyFloatEditLine *_protein_hb_costraint_fel;
+ MyPushButton *_protein_hb_costraint_b;
+ MyFloatEditLine *_to_surface_distance;
+ MyFloatEditLine *_from_surface_distance;
+ MyPushButton *_surface_distance_b;
+ MyComboBox *_ligand_surface_distance_cb;
+ MyFloatEditLine *_weight_surface_distance_fel;
+ MyPushButton *_ligand_intra_distance_b;
+ MyPushButton *_protein_ligand_distance_b;
+ MyFloatEditLine *_from_ligand_intra_distance;
+ MyFloatEditLine *_to_ligand_intra_distance;
+ MyComboBox *_number_a_ligand_intra_distance_cb;
+ MyComboBox *_number_b_ligand_intra_distance_cb;
+ MyFloatEditLine *_weight_ligand_intra_distance;
+ MyFloatEditLine *_from_protein_ligand_distance;
+ MyFloatEditLine *_to_protein_ligand_distance;
+ MyComboBox *_number_a_protein_ligand_distance_cb;
+ MyComboBox *_number_b_protein_ligand_distance_cb;
+ MyFloatEditLine *_weight_protein_ligand_distance;
+ MyTwoColumn *_ligand_intra_distance_costraint_tc;
+ MyTwoColumn *_protein_ligand_distance_costraint_tc;
+ MyTwoColumn *_surface_distance_costraint_tc;
+// Flexibility tab
+ MyGroupBox *_flexibility_box;
+ MyTwoColumn *_flexibility_tc;
+ MyListView *flexibility_file_list;
+ double _intra_protein_score_weight_value;
+ MyFloatEditLine *_intra_protein_score_weight_el;
+ MyListButton *_flexible_protein_side_chain_string;
+ MyListButton *_fix_protein_bond;
+ MyListButton *_flexible_protein_side_chain_number;
+// Water tab
+ MyGroupBox *_water_box;
+ MyGroupBox *_water_weights_box;
+ MyTwoColumn *_water_weights_tc;
+ double _water_protein_hb_weight_value;
+ MyFloatEditLine *_water_protein_hb_weight_el;
+ double _water_ligand_hb_weight_value;
+ MyFloatEditLine *_water_ligand_hb_weight_el;
+ double _water_water_hb_weight_value;
+ MyFloatEditLine *_water_water_hb_weight_el;
+ double _no_water_ligand_hb_penalty_value;
+ MyFloatEditLine *_no_water_ligand_hb_penalty_el;
+ double _water_enable_penalty_value;
+ MyPushButton *_water_site_b;
+ MyFloatEditLine *_water_enable_penalty_el;
+ MyLineFile *load_water_file;
+ MyTwoColumn *_water_site_tc;
+ MyFloatEditLine *_water_site_x_el;
+ MyFloatEditLine *_water_site_y_el;
+ MyFloatEditLine *_water_site_z_el;
+ MyFloatEditLine *_water_site_radius_el;
+ vector3 water_coordinates;
+ double _water_min_radius;
+ double water_site_x;
+ double water_site_y;
+ double water_site_z;
+//
+ QAction *_load_action;
+ QAction *_run_action;
+ QAction *_save_action;
+ QAction *_restore_action;
+
+ string saved_file;
+
+ private slots:
+ void plp_weight (int i);
+ void set_binding_site ();
+ void set_water_site ();
+// void set_binding_site_values (float x, float y, float z, float r);
+ void update_boxes (MyListView *parent, const char *mol_name, int type);
+
+ protected slots:
+ void hide_group_box2 ();
+ void set_protein_hb_constraint_slot();
+ void set_ligand_intra_distance_slot ();
+ void set_protein_ligand_distance_slot ();
+ void set_shape_constraint_slot ();
+ void set_surface_distance_slot ();
+ void hide_group_box ();
+ void _load_slot ();
+ void _save_slot ();
+ void _run_slot ();
+ void _restore_slot ();
+ void _show_about ();
+ void add_fscs_slot();
+ void add_fscn_slot();
+ void add_fpb_slot();
+ void load_protein ();
+ void load_ligand ();
+ void load_shape ();
+ void load_ligand_list ();
+ void _err_mol ();
+ void _err_multi ();
+ void _load_bot_list_view (string& buffer, const char *reference, MyListView *target);
+ void _load_bot_water (string& buffer, const char *reference);
+ void _load_bot_bindingsite (string& buffer, const char *reference);
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+class ConformersMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ ConformersMenu (QWidget *parent, Data *dat);
+// ~ConformersMenu () {~ZNMenu ();};
+
+private:
+
+ ZNWidget *_stochastic_widget, *_systematic_widget;
+ MyHideComboBox *_type_hcb;
+protected:
+ bool display_requirements_met () {return check_for_a_set_target ();};
+ int _results, _timlim;
+ MyIntegerEditLine *_results_iel, *_timlim_iel;
+protected slots:
+ void start_thread ();
+
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// GAMESS menu FE
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+const string VERSION_GAMESS = "0.1";
+
+const string GAMESS;
+
+
+class GamessMenu : public ZNMenu {
+ Q_OBJECT
+
+public:
+ GamessMenu (QWidget *parent, Data *dat);
+// ~GamessMenu () {~ZNMenu ();};
+
+private:
+
+protected:
+// main tab
+ MyGroupBox *_base_box;
+ MyComboBox *_run_type_cb;
+ QComboBox *_semi_emp_cb;
+ QComboBox *_H_F_cb;
+ MyComboBox *_mult_cb, *_guess_cb;
+ MyComboBox *_scftyp_cb;
+ MyHideComboBox *_gbasis_hcb;
+ MyGroupBox *_solv_box;
+ QRadioButton *radio1;
+// MyComboBox *_prova_cb;
+// solvent group
+ MyHideCheckBox *_enable_solv;
+ MyComboBox *_solvent_cb;
+ MyFloatEditLine *_tabs_el;
+ QWidget *_hide;
+ double _temp;
+ MyHideCheckBox *_hide_check_box;
+ ZNWidget *_private_solv, *_public_solv;
+ int _solv;
+// ielpot tab
+ MyGroupBox *_elpot_box, *_pdc_box, *_grid_box, *_points_box;
+ MyComboBox *_where_cb, *_output_cb, *_ptsel_cb, *_constr_cb;
+ MyIntegerEditLine *_layer_iel, *_maxpdc_iel;
+ MyFloatEditLine *_vdwscl_fel, *_vdwinc_fel;
+ int _layer, _maxpdc;
+ double _vdwscl, _vdwinc;
+// system tab
+ MyGroupBox *_run_box;
+ MyComboBox *_exetyp_cb;
+ MyIntegerEditLine *_timlim_iel;
+ MyIntegerEditLine *_memory_iel;
+ int _timlim;
+ int _memory;
+ int _memory2;
+// tabs
+// ZNAdvancedWidget *_elpot_tab;
+ QWidget *_system_tab;
+ void add_menu ();
+ QAction *_load_action;
+ QAction *_test_action;
+ QAction *_save_action;
+ QAction *_restore_action;
+ int _gbasis;
+ int _gbasis_load;
+
+ bool display_requirements_met () {return check_for_a_set_target ();};
+
+ private slots:
+ void hide_temp (int i);
+ void hide_solv (int i);
+ void hide_elpot (int i);
+ void _load_bot_iel (string& buffer, const char *reference, MyIntegerEditLine *target);
+ void _load_bot_fel (string& buffer, const char *reference, MyFloatEditLine *target);
+ void _load_bot_box (string& buffer, const char *reference, MyGroupBox *target);
+ void _load_bot_cb (string& buffer, const char *reference, MyComboBox *target);
+ void _load_bot_gbasis (string& buffer);
+ void _load_bot_ngauss (string& buffer);
+ void _load_bot_ndfunc (string& buffer);
+ void _load_bot_npfunc (string& buffer);
+ void _load_bot_diffsp (string& buffer);
+ void _load_bot_diffs (string& buffer);
+
+ protected slots:
+ void _load_slot ();
+ void _save_slot ();
+ void _restore_slot ();
+ void _show_about ();
+};
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// "My" classes
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+class MyCheckBox : public QCheckBox {
+ Q_OBJECT
+
+public:
+ MyCheckBox (QLayout *parent, bool &var, string string);
+
+private:
+ bool *var;
+
+ private slots:
+ void get ();
+ void set ();
+};
+
+
+
+class MyColorButton : public QPushButton {
+ Q_OBJECT
+
+public:
+ MyColorButton (QLayout *parent, QColor &color);
+
+ void paintEvent ( QPaintEvent * ) ;
+ QColor *color;
+
+ private slots:
+ void my_clicked ();
+};
+
+
+
+class MyComboBox : public QWidget {
+ Q_OBJECT
+
+public:
+ MyComboBox (QLayout *parent, const char *name);
+ QComboBox *combo_box () {return _combo_box;};
+ void insertItem (int index, const char *name);
+ QVariant currentData () {return _combo_box ->itemData (_combo_box ->currentIndex ()); };
+ QComboBox *_combo_box;
+
+protected:
+
+};
+
+
+
+class MyCompleteColorSettings : public QWidget {
+ Q_OBJECT
+
+public:
+ MyCompleteColorSettings (QLayout *parent, color &col, string name = "");
+ MyColorButton *button;
+ MySlider *slider;
+ int alpha;
+
+ private slots:
+ void setAlpha (int i);
+};
+
+
+class MyFloatEditLine : public QWidget {
+ Q_OBJECT
+
+public:
+ MyFloatEditLine (QLayout *parent, const char *name, double& var, double min = -BIG, double max = BIG);
+
+ void set ();
+ QDoubleSpinBox *spinbox;
+ double* variable;
+
+ double currentData () {return spinbox ->value ( ); };
+
+ public slots:
+ void set_value (double d);
+ void set (double d);
+};
+
+
+
+class MyGroupBox : public QGroupBox {
+ Q_OBJECT
+
+public:
+ MyGroupBox (QLayout *parent, string str, bool checkbox = false, bool status = false);
+ MyGroupBox (string str, bool checkbox = false, bool status = false);
+};
+
+
+
+class MyHideCheckBox : public QCheckBox {
+ Q_OBJECT
+
+public:
+ MyHideCheckBox (QLayout *parent, QWidget *tar, string string);
+
+private:
+ QWidget *target;
+ MyGroupBox *_group_box;
+ void set_checked ();
+ void set_unchecked ();
+
+ private slots:
+ void get ();
+ void set ();
+ void set_2 ();
+};
+
+
+
+class MyHideComboBox : public MyComboBox {
+ Q_OBJECT
+
+public:
+ MyHideComboBox (QLayout *parent, const char *name);
+ void insertItem ( QWidget *wid, int index, const char *name, const QVariant &data = QVariant ());
+
+protected:
+ vector <QWidget *> _widgets;
+
+ protected slots:
+ void set (int i);
+};
+
+
+
+class MyIntegerEditLine : public QWidget {
+ Q_OBJECT
+
+public:
+ MyIntegerEditLine (QLayout *parent, const char *name, int& var, int min = -BIG, int max = BIG);
+
+ void set ();
+ QSpinBox *spinbox;
+ int* variable;
+
+ public slots:
+ void set_value (int val);
+// void set (const QString &);
+ void set (int d);
+};
+
+
+
+
+class MyLabelf : public QWidget {
+ Q_OBJECT
+
+public:
+ MyLabelf (QLayout *parent, const char *name, float& var);
+// ~MySlider ();
+//private:
+ QLabel *label;
+ float* variable;
+ void update ();
+ void set_variable (float *f);
+};
+
+
+class MyLineEdit : public QWidget {
+ Q_OBJECT
+
+public:
+ MyLineEdit (QLayout *parent, const char *name );
+ QLineEdit *linedit;
+ QLabel *label;
+protected:
+ const char *tag;
+};
+
+
+
+class MyLineFile : public QWidget {
+ Q_OBJECT
+
+public:
+ MyLineFile (QLayout *parent, const char *name, int valid);
+// const char* get_value ();
+// QPushButton *adbutt;
+ QLineEdit *linedit;
+ QLabel *label;
+ QLabel *control_yes;
+ QLabel *control_no;
+// void ins (QString s);
+ string val ();
+
+protected:
+ const char *tag;
+ QPushButton *fbutton;
+ char *filetype;
+ int valid;
+
+ protected slots:
+// QString ask_file ();
+ void set_file_a ();
+ void set_file_b ();
+ void set_file_c ();
+ void set_file_d ();
+};
+
+
+class MyListButton : public QWidget {
+ Q_OBJECT
+
+public:
+ MyListButton (QLayout *parent, const char *name);
+ QPushButton *fbutton;
+ QComboBox *_combo_box;
+
+protected:
+
+
+};
+
+class MyPushButton : public QWidget {
+ Q_OBJECT
+
+public:
+ MyPushButton (QLayout *parent, const char *name, int dim=0, int width=0);
+ MyPushButton (const char *name, int dim=0, int width=0);
+ QPushButton *fbutton;
+
+protected:
+
+};
+
+
+class MyListView : public QWidget {
+ Q_OBJECT
+
+public:
+ MyListView (QLayout *parent, int dim=0, int width=0, bool button=true);
+ QListWidget *_lw;
+ QPushButton *fbutton;
+ QShortcut *shortcut1, *shortcut2;
+
+
+ protected slots:
+ void del_list_view_slot ();
+ signals:
+ void deleting (int r);
+
+};
+
+
+class MySlider : public QWidget {
+ Q_OBJECT
+
+public:
+ MySlider (QLayout *parent, const char *name, int& var, int vmin, int vmax);
+// ~MySlider ();
+//private:
+ MyIntegerEditLine *pline;
+ QSlider *slider;
+
+ public slots:
+ void setValue (int i);
+};
+
+
+class MyTwoColumn : public QWidget {
+ Q_OBJECT
+
+public:
+ MyTwoColumn (QLayout *parent);
+ QLayout *left_layout () {return _left ->layout ();};
+ QLayout *right_layout () {return _right ->layout ();};
+ ZNWidget *_left, *_right;
+
+private:
+
+protected:
+
+};
+
+class My3Column : public QWidget {
+ Q_OBJECT
+
+public:
+ My3Column (QLayout *parent);
+ QLayout *left_layout () {return _left ->layout ();};
+ QLayout *center_layout () {return _center ->layout ();};
+ QLayout *right_layout () {return _right ->layout ();};
+
+private:
+
+protected:
+ ZNWidget *_left, *_center, *_right;
+};
+
+class MyGridColumn : public QWidget {
+ Q_OBJECT
+
+public:
+ MyGridColumn (QLayout *parent, int row, int col);
+ QGridLayout *gridlayout;
+
+private:
+
+protected:
+
+};
+
+
+class MyTableWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ MyTableWidget (QLayout *parent, int row, int height);
+ QTableWidget *table;
+
+private:
+
+protected:
+
+};
+
+#endif
diff --git a/headers/minimize.h b/headers/minimize.h
new file mode 100644
index 0000000..c8bc523
--- /dev/null
+++ b/headers/minimize.h
@@ -0,0 +1,328 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+#ifndef MINIMIZE_H
+#define MINIMIZE_H
+
+#include "constants.h"
+#include "ZNdata.h"
+#include "FF.h"
+#include "thread.h"
+#include "ils.h"
+#include "pso.h"
+#include "nms.h"
+
+
+class HapticThread;
+
+typedef struct {
+ vect coordinates;
+ Atom *atom;
+} Fragment_Atom;
+
+typedef struct {
+ vector <Fragment_Atom> atoms;
+ vect translation;
+ // float rotation [3];
+ float rotation_quat [4];
+} pFragment;
+
+typedef struct {
+ unsigned int type;
+ float *value;
+ float der;
+} Dof;
+
+class Data;
+class Minimize {
+
+public:
+ Minimize (Data *dat, ForceField *int_ff = 0, ForceField *inter_ff = 0);
+
+ void set_molecule (ZNMolecule *mol) {target_molecule = mol;}
+
+
+ ZNMolecule *target_molecule;
+ Optimiser *optimiser;
+
+ ZNMolecule *minimising_molecule;
+ ZNMolecule *haptic_molecule;
+
+ ForceField *internal_ff;
+ vector <ForceField *> interaction_ffs;
+ float counter;
+ float step;
+
+ bool automove;
+ bool color_by_score;
+
+ float total_E;
+ float total_interaction_E;
+ float total_internal_E;
+
+
+ float score ();
+ void start_haptic_mode ();
+
+ void initialize (ZNMolecule *mol);
+ void initialize_6 (ZNMolecule *mol);
+
+ void minimize_energy_step ();
+ float compute_energy ();
+ void apply_forces (ZNMolecule *mol, float trunc = 0.f);
+ void apply_force_to_atom (Atom *a, float trunc = 0.f);
+
+
+ //void initialise_minimisation ();
+ void deinitialise_minimisation ();
+
+
+ void clear ();
+ void clear_fragments ();
+ int haptic_dof_mode;
+ int haptic_number_of_threads;
+ vector <pFragment> fragments;
+
+
+ void update_fragment_position (pFragment&);
+private:
+ int forcefields_sanity_check ();
+
+ int iterations;
+ float last_E;
+ Data *data;
+
+
+//#ifdef HAPTICS
+public: void update_molecule_position_with_haptic_pointer (ZNMolecule *min_mol);
+//#endif //HAPTICS
+
+};
+
+
+class ScoreMolecule : public Function {
+public:
+ ScoreMolecule (Minimize *min, bool move_bool = true, vect bs_center = vect (), float bs_rad = 10) : Function (), minimise (min), moving (move_bool)
+ {
+
+ float r = bs_rad;
+ int gap = 0;
+ ZNMolecule *mol = min -> target_molecule;
+ vect curr_c = get_root_fragment_center (mol);
+ //cerr << curr_c<<bs_center<<r<< endl;
+ vector <double> vv = get_dihedrals (mol);
+ values.resize (gap + vv.size ());
+ if (moving) {
+ gap = 6;
+ values.resize (gap + vv.size ());
+ values[0] = bs_center.x() - curr_c.x();
+ Variable* v = new Variable;
+ v->value = &values[0];
+ *v->value = values[0];
+ v ->min_val = bs_center.x() - curr_c.x() -r;
+ v ->max_val = bs_center.x() - curr_c.x() +r;
+ _variables.push_back(v);
+
+ values[1] = bs_center.y() - curr_c.y();
+ Variable* v2 = new Variable;
+ v2->value = &values[1];
+ *v2->value = values[1];
+ v2 ->min_val = bs_center.y() - curr_c.y() -r;
+ v2 ->max_val = bs_center.y() - curr_c.y() +r;
+ _variables.push_back(v2);
+
+ values[2] = bs_center.z() - curr_c.z();
+ Variable* v3 = new Variable;
+ v3->value = &values[2];
+ *v3->value = values[2];
+ v3 ->min_val = bs_center.z() - curr_c.z() -r;
+ v3 ->max_val = bs_center.z() - curr_c.z() +r;
+ _variables.push_back(v3);
+
+ //rotation
+ values[3] = 0.f;
+ Variable* v4 = new Variable;
+ v4->value = &values[3];
+ *v4->value = values[3];
+ v4 ->min_val = -M_PI;
+ v4 ->max_val = M_PI;
+ _variables.push_back(v4);
+
+ values[4] = 0.f;
+ Variable* v5 = new Variable;
+ v5->value = &values[4];
+ *v5->value = values[4];
+ v5 ->min_val = -M_PI;
+ v5 ->max_val = M_PI;
+ _variables.push_back(v5);
+
+ values[5] = 0.f;
+ Variable* v6 = new Variable;
+ v6->value = &values[5];
+ *v6->value = values[5];
+ v6 ->min_val = -M_PI;
+ v6 ->max_val = M_PI;
+ _variables.push_back(v6);
+ }
+
+
+
+ for (unsigned int i = 0; i < vv.size(); i++) {
+
+ values[i+gap] = (float) vv[i];
+ Variable* v = new Variable;
+ v->value = &values[i+gap];
+ *v->value = values[i+gap];
+ v ->min_val = -M_PI;
+ v ->max_val = M_PI;
+ _variables.push_back(v);
+ }
+
+ };
+
+
+ float evaluate ()
+ {
+
+ build_molecule_from_dofs (minimise ->target_molecule, values, moving);
+ set_needs_redraw (minimise ->target_molecule, true);
+ // cerr << "score " << minimise ->score ();
+ return minimise -> score ();
+ };
+
+private:
+ vector<float> values;
+ Minimize *minimise;
+ bool moving;
+};
+
+
+
+
+
+
+
+
+
+
+/*
+
+class LinkerFunction : public Function {
+public:
+ LinkerFunction (Minimize *min, Database *frags, int ) : Function (), minimise (min), _fragments_source (frags)
+ {
+ int max_fragments = 4;
+ float r = 2.;
+
+ values.resize (6 + max_fragments * 3);
+ values[0] = 0.f;
+ Variable* v = new Variable;
+ v->value = &values[0];
+ *v->value = values[0];
+ v ->min_val = -r;
+ v ->max_val = r;
+ _variables.push_back(v);
+
+ values[1] = 0.f;
+ Variable* v2 = new Variable;
+ v2->value = &values[1];
+ *v2->value = values[1];
+ v2 ->min_val = -r;
+ v2 ->max_val = r;
+ _variables.push_back(v2);
+
+ values[2] = 0.f;
+ Variable* v3 = new Variable;
+ v3->value = &values[2];
+ *v3->value = values[2];
+ v3 ->min_val = -r;
+ v3 ->max_val = r;
+ _variables.push_back(v3);
+
+ //rotation
+ Variable* v4 = new Variable;
+ v4->value = &values[3];
+ *v4->value = values[3];
+ v4 ->min_val = -M_PI;
+ v4 ->max_val = M_PI;
+ _variables.push_back(v4);
+
+ values[1] = 0.f;
+ Variable* v5 = new Variable;
+ v5->value = &values[4];
+ *v5->value = values[4];
+ v5 ->min_val = -M_PI;
+ v5 ->max_val = M_PI;
+ _variables.push_back(v5);
+
+ values[2] = 0.f;
+ Variable* v6 = new Variable;
+ v6->value = &values[5];
+ *v6->value = values[5];
+ v6 ->min_val = -M_PI;
+ v6 ->max_val = M_PI;
+ _variables.push_back(v6);
+
+
+ for (unsigned int i = 0; i < max_fragments; i++) {
+
+ values[i+6] = 0;
+ Variable* v = new Variable;
+ v->value = &values[i+6];
+ *v->value = values[i+6];
+ v ->min_val = 0;
+ v ->max_val = _fragments_source -> count_molecules ();
+ _variables.push_back(v);
+
+
+
+ values[i+6+1] = 0;
+ Variable* rot = new Variable;
+ rot->value = &values[i+6+1];
+ *rot->value = values[i+6+1];
+ rot ->min_val = 0;
+ rot ->max_val = 2 * M_PI;
+ _variables.push_back(rot);
+ }
+
+ };
+
+
+ float evaluate ()
+ {
+
+ arrange_fragments (fragments, values);
+ // set_needs_redraw (minimise ->target_molecule, true);
+ float score = 0;
+// for (int i = 0; i < fragments.size ())
+ return minimise -> score ();
+ };
+
+private:
+ vector<float> values;
+ Minimize *minimise;
+ vector <ZNMolecule *> fragments;
+ Database *_fragments_source;
+
+ void arrange_fragments (vector <ZNMolecule *> frags, vector <float>) {};
+};
+
+
+*/
+
+
+#endif
diff --git a/headers/myline.h b/headers/myline.h
new file mode 100644
index 0000000..60d8cc1
--- /dev/null
+++ b/headers/myline.h
@@ -0,0 +1,85 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef MYLINE_H
+#define MYLINE_H
+
+#include <Qt3Support/q3hbox.h>
+#include <qlineedit.h>
+#include <iostream>
+#include <qpushbutton.h>
+#include <Qt3Support/q3tabdialog.h>
+#include <string>
+
+
+using namespace std ;
+
+
+class QLineEdit;
+
+class MyLine : public Q3HBox
+{
+ Q_OBJECT
+
+public:
+ MyLine (QWidget *parent, const char *name, int valid);
+
+ // const char* get_value ();
+ void ins (QString s);
+ string val ();
+
+
+ QLineEdit *linedit;
+
+};
+
+
+class MyLineF : public Q3HBox
+{
+ Q_OBJECT
+
+public:
+ MyLineF( QWidget *parent, QWidget *master, const char *name, int valid, int butt=0);
+ const char* get_value ();
+ QPushButton *adbutt;
+ QLineEdit *linedit;
+ void ins (QString s);
+ string val ();
+
+
+
+protected:
+ const char *tag;
+ QPushButton *fbutton;
+ char *filetype;
+// MainWin *master;
+
+protected slots:
+ QString ask_file ();
+ void set_file ();
+ void set_line ();
+
+
+
+};
+
+
+
+
+#endif
diff --git a/headers/nms.h b/headers/nms.h
new file mode 100644
index 0000000..85727ea
--- /dev/null
+++ b/headers/nms.h
@@ -0,0 +1,676 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ *class implementation of Nelder Mead Simplex Search
+ *Adam Gurson College of William & Mary 1999
+ *
+ * modified slightly by Anne Shepherd (pls), 8/00
+
+
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+
+#ifndef NMS_H
+#define NMS_H
+
+#include "optimiser.h"
+#include "subscrpt.h"
+#include "cmat.h"
+#include "vec.h"
+
+
+
+class NMS : public Optimiser {
+ public:
+ NMS () : Optimiser ()
+ {
+ };
+ NMS (Function* f) : Optimiser (f)
+ {
+ init_parameters ();
+
+ vector<Variable *> vars = optFunc ->access_variables ();
+ init (optFunc ->access_variables ());
+
+ };
+
+ ~NMS () {
+ if(simplex != NULL) delete simplex;
+ if(simplexValues != NULL) delete [] simplexValues;
+ delete centroid;
+ delete reflectionPt;
+ delete expansionPt;
+ delete contractionPt;
+ delete scratch;
+ delete scratch2;
+ //NOTE: Matrix and Vector classes have their own destructors
+ };
+
+void init (vector<Variable*>& vars) {
+ for (unsigned int i = 0; i < vars.size (); i++) {
+ (*scratch)[i] = (double) *(vars[i]->value);
+ }
+ InitRegularTriangularSimplex(scratch, 2);
+}
+
+
+void set_iteration_limit (int iter) {
+ maxCalls = iter;
+}
+void init_parameters () {
+ dimensions = optFunc ->access_variables ().size ();
+ functionCalls = 0;
+ simplex = NULL;
+ simplexValues = NULL;
+ centroid = new Vector<double>(dimensions,0.0);
+ reflectionPt = new Vector<double>(dimensions,0.0);
+ expansionPt = new Vector<double>(dimensions,0.0);
+ contractionPt = new Vector<double>(dimensions,0.0);
+ alpha = 1.0;
+ beta = 0.5;
+ gamma = 2.0;
+ sigma = 0.5;
+ maxCalls = 100000;
+ scratch = new Vector<double>(dimensions,0.0);
+ scratch2 = new Vector<double>(dimensions,0.0);
+ stoppingStepLength = 0.02;
+}
+
+ float run () {
+ double secondHighestPtValue; // used for contraction/reflection decision
+ toleranceHit = 0;
+
+ FindMinMaxIndices();
+ do {
+ FindCentroid();
+ secondHighestPtValue = simplexValues[SecondHighestPtIndex()];
+ // reflection step
+ FindReflectionPt();
+
+ // stop if at maximum function calls and update the simplex
+ /*changed 8/8/00 to fix the problem of maxCalls == -1 --pls
+ formerly read if(functionCalls <= maxCalls)
+ */
+ if (maxCalls > -1 && functionCalls >= maxCalls) {
+ FindMinMaxIndices();
+ ReplaceSimplexPoint(maxIndex, *reflectionPt);
+ simplexValues[maxIndex] = reflectionPtValue;
+ FindMinMaxIndices();
+ return 0.;
+ } // if using call budget
+
+ // possibility 1
+ if(simplexValues[minIndex] > reflectionPtValue) {
+ FindExpansionPt(); // expansion step
+
+ if (reflectionPtValue > expansionPtValue) {
+ ReplaceSimplexPoint(maxIndex, *expansionPt);
+ simplexValues[maxIndex] = expansionPtValue;
+ } // inner if
+ else {
+ ReplaceSimplexPoint(maxIndex, *reflectionPt);
+ simplexValues[maxIndex] = reflectionPtValue;
+ } // else
+ } // if for possibility 1
+
+ // possibility 2
+
+ else if( (secondHighestPtValue > reflectionPtValue ) && ( reflectionPtValue >= simplexValues[minIndex]) ) {
+ ReplaceSimplexPoint(maxIndex, *reflectionPt);
+ simplexValues[maxIndex] = reflectionPtValue;
+ } // else if for possibility 2
+
+ // possibility 3
+ else if( reflectionPtValue >= secondHighestPtValue ) {
+ FindContractionPt(); // contraction step
+ if(maxPrimePtId == 0) {
+ if( contractionPtValue > maxPrimePtValue ) {
+ ShrinkSimplex();
+ } // inner if
+ else {
+ ReplaceSimplexPoint(maxIndex, *contractionPt);
+ simplexValues[maxIndex] = contractionPtValue;
+ } // inner else
+ } // maxPrimePtId == 0
+ else if(maxPrimePtId == 1) {
+ if( contractionPtValue >= maxPrimePtValue ) {
+ ShrinkSimplex();
+ } // inner if
+ else {
+ ReplaceSimplexPoint(maxIndex, *contractionPt);
+ simplexValues[maxIndex] = contractionPtValue;
+ } // inner else
+ } // maxPrimePtId == 1
+ } // else if for possibility 3
+
+ // if we haven't taken care of the current simplex, something's wrong
+ else {
+ cerr << "Error in ExploratoryMoves() - "
+ << "Unaccounted for case.\nTerminating.\n";
+ return 0.;
+ }
+ FindMinMaxIndices();
+ } while (!Stop()); // while stopping criteria is not satisfied
+ return 0.f;
+ } // ExploratoryMoves()
+
+
+
+ void ReplaceSimplexPoint(int index, const Vector<double>& newPoint)
+ {
+ for( int i = 0; i < dimensions; i++ ) {
+ (*simplex)[index][i] = newPoint[i];
+ } // for;
+ }
+
+ void CalculateFunctionValue(int index) {
+ *scratch = (*simplex).row(index);
+ int success;
+ fcnCall(dimensions, (*scratch).begin(), simplexValues[index], success);
+ if(!success) cerr<<"Error calculating point in CalculateFunctionValue().\n";
+ }
+ // finds the f(x) value for the simplex point indexed at index and
+ // replaces the proper value in simplexValues
+
+void SetAlpha(double newAlpha)
+{
+ alpha = newAlpha;
+} // SetAlpha()
+
+void SetBeta(double newBeta)
+{
+ beta = newBeta;
+} // SetBeta()
+
+void SetGamma(double newGamma)
+{
+ gamma = newGamma;
+} // SetGamma()
+
+void SetSigma(double newSigma)
+{
+ sigma = newSigma;
+} // SetGamma()
+ // these functions allow the user to set values of the reflection,
+ // contraction, expansion, and shrinking coefficients
+
+
+bool Stop()
+{
+ if(maxCalls > -1) {
+ if(functionCalls >= maxCalls)
+ return true;
+ }
+
+ double mean = 0.0;
+
+ for( int i = 0; i <= dimensions; i++) {
+ if( i != minIndex ) {
+ mean += simplexValues[i];
+ } // if
+ } //for
+
+ mean /= (double)dimensions;
+
+ // Test for the suggested Nelder-Mead stopping criteria
+ double total = 0.0;
+ for( int i = 0; i <= dimensions; i++ ) {
+ total += pow( simplexValues[i] - mean ,2);
+ } //for
+ total /= ((double)dimensions + 1.0);
+ total = sqrt(total);
+
+
+ // printSimplex();
+ if(total < stoppingStepLength) {
+ toleranceHit = 1;
+ return true;
+ }
+ else
+ return false;
+} // Stop()
+ // returns true if the stopping criteria have been satisfied
+
+void fcnCall(int n, double *x, double& f, int& flag)
+{
+ for (unsigned int i = 0; i < n; i++) {
+ vector <Variable*>& func_vars = optFunc ->access_variables();
+ // func_vars[i] ->value = &x[i];
+ *func_vars[i] ->value = x[i];
+ }
+ f = (double) optFunc -> evaluate ();
+ functionCalls++;
+ flag = 1;
+} // fcnCall()
+
+// Simplex-altering functions
+
+ // indirection of function call for purposes of keeping an accurate
+ // tally of the number of function calls
+
+ // Simplex-altering functions
+
+void InitRegularTriangularSimplex(const Vector<double> *basePoint,
+ const double edgeLength)
+{
+ // This routine constructs a regular simplex (i.e., one in which all of
+ // the edges are of equal length) following an algorithm given by Jacoby,
+ // Kowalik, and Pizzo in "Iterative Methods for Nonlinear Optimization
+ // Problems," Prentice-Hall (1972). This algorithm also appears in
+ // Spendley, Hext, and Himsworth, "Sequential Application of Simplex
+ // Designs in Optimisation and Evolutionary Operation," Technometrics,
+ // Vol. 4, No. 4, November 1962, pages 441--461.
+
+ int i,j;
+ double p, q, temp;
+ Matrix<double> *plex = new Matrix<double>(dimensions+1,dimensions,0.0);
+ for( int col = 0; col < dimensions; col++ ) {
+ (*plex)[0][col] = (*basePoint)[col];
+ }
+
+ temp = dimensions + 1.0;
+ q = ((sqrt(temp) - 1.0) / (dimensions * sqrt(2.0))) * edgeLength;
+ p = q + ((1.0 / sqrt(2.0)) * edgeLength);
+
+ for(i = 1; i <= dimensions; i++) {
+ for(j = 0; j <= i-2; j++) {
+ (*plex)[i][j] = (*plex)[0][j] + q;
+ } // inner for 1
+ j = i - 1;
+ (*plex)[i][j] = (*plex)[0][j] + p;
+ for(j = i; j < dimensions; j++) {
+ (*plex)[i][j] = (*plex)[0][j] + q;
+ } // inner for 2
+ } // outer for
+
+ InitGeneralSimplex(plex);
+ delete plex;
+} // InitRegularTriangularSimplex()
+
+ // deletes any existing simplex and replaces it with a regular
+ // triangular simplex in the following manner:
+ //
+ // basePoint points to a point that will be the "origin" of the
+ // simplex points (it will be a part of the simplex)
+ // edgeLength is the length of each edge of the "triangle"
+ //
+ // functionCalls is reset to 0 and ALL FUNCTION VALUES ARE CALCULATED.
+ //
+ // NOTE: basePoint is assumed to be of proper dimension
+
+void InitFixedLengthRightSimplex(const Vector<double> *basePoint,
+ const double edgeLength)
+{
+ // to take advantage of code reuse, this function simply turns
+ // edgeLength into a vector of dimensions length, and then
+ // calls InitVariableLengthRightSimplex()
+
+ double* edgeLengths = new double[dimensions];
+ for( int i = 0; i < dimensions; i++ ) {
+ edgeLengths[i] = edgeLength;
+ }
+ InitVariableLengthRightSimplex(basePoint,edgeLengths);
+ delete [] edgeLengths;
+} // InitFixedLengthRightSimplex()
+ // deletes any existing simplex and replaces it with a right-angle
+ // simplex in the following manner:
+ //
+ // basePoint points to a point that will be the "origin" of the
+ // simplex points (it will be a part of the simplex)
+ // edgeLength is to be the length of each simplex side extending
+ // from the basePoint along each positive coordinate direction.
+ //
+ // functionCalls is reset to 0 and ALL FUNCTION VALUES ARE CALCULATED.
+ //
+ // NOTE: basePoint is assumed to be of proper dimension
+
+ void InitVariableLengthRightSimplex(const Vector<double> *basePoint,
+ const double* edgeLengths)
+{
+ Matrix<double> *plex = new Matrix<double>(dimensions+1,dimensions,0.0);
+ for( int i = 0; i < dimensions; i++ ) {
+ // we're building the basePoint component-by-component into
+ // the (n+1)st row
+ (*plex)[dimensions][i] = (*basePoint)[i];
+
+ // now fill in the ith row with the proper point
+ for( int j = 0; j < dimensions; j++ ) {
+ (*plex)[i][j] = (*basePoint)[j];
+ if( i == j )
+ (*plex)[i][j] += edgeLengths[i];
+ }
+ } // for
+ InitGeneralSimplex(plex);
+ delete plex;
+} // InitVariableLengthRightSimplex()
+ // deletes any existing simplex and replaces it with a right-angle
+ // simplex in the following manner:
+ //
+ // basePoint points to a point that will be the "origin" of the
+ // simplex points (it will be a part of the simplex)
+ // edgeLengths points to an array of n doubles, where n is the
+ // dimension of the given search. x_1 will then be located
+ // a distance of edgeLengths[0] away from the basepoint along the
+ // the x_1 axis, x_2 is edgeLengths[1] away on the x_2 axis, etc.
+ //
+ // functionCalls is reset to 0 and ALL FUNCTION VALUES ARE CALCULATED.
+ //
+ // NOTE: basePoint and edgeLengths are assumed to be of proper dimension
+
+void InitGeneralSimplex(const Matrix<double> *plex)
+{
+ functionCalls = 0;
+ if( simplex != NULL ) { delete simplex; }
+ if( simplexValues != NULL ) { delete [] simplexValues;}
+ simplex = new Matrix<double>((*plex));
+ simplexValues = new double[dimensions+1];
+
+ int success;
+ for( int i = 0; i <= dimensions; i++ ) {
+ *scratch = (*plex).row(i);
+ fcnCall(dimensions, (*scratch).begin(), simplexValues[i], success);
+ if(!success) cerr<<"Error with point #"<<i<<" in initial simplex.\n";
+ } // for
+ FindMinMaxIndices();
+} // InitGeneralSimplex()
+ // deletes any existing simplex and replaces it with the one
+ // pointed to by plex
+ //
+ // functionCalls is reset to 0 and ALL FUNCTION VALUES ARE CALCULATED.
+ //
+ // NOTE: THIS ASSUMES THAT plex IS OF PROPER DIMENSION
+
+void ReadSimplexFile(istream& fp)
+{
+ if(fp == NULL) {
+ cerr<<"No Input Stream in ReadSimplexFile()!\n";
+ return; // There's no file handle!!
+ }
+
+ Matrix<double> *plex = new Matrix<double>(dimensions+1,dimensions);
+ for( int i = 0; i <= dimensions; i++ ) {
+ for ( int j = 0; j < dimensions; j++ ) {
+ fp >> (*plex)[i][j];
+ } // inner for
+ } // outer for
+ InitGeneralSimplex(plex);
+ delete plex;
+} // ReadSimplexFile()
+ // may also pass cin as input stream if desired
+ // input the values of each trial point
+ // NOTE: THIS FUNCTION WILL ONLY ACCEPT n+1 POINTS
+ //
+ // functionCalls is reset to 0 and ALL FUNCTION VALUES ARE CALCULATED.
+
+ // Query functions
+
+int GetFunctionCalls() const
+{
+ return functionCalls;
+} // GetFunctionCalls()
+ // number of objective function evaluations
+
+void GetMinPoint(Vector<double>* &minimum) const
+{
+ minimum = new Vector<double>((*simplex).row(minIndex));
+} // GetMinPoint()
+ // simplex point which generates the best objective function
+ // value found thus far
+ // USER SHOULD PASS JUST A NULL POINTER, WITHOUT PREALLOCATED MEMORY
+
+double GetMinVal() const
+{
+ return simplexValues[minIndex];
+} // GetMinVal()
+ // best objective function value found thus far
+
+void GetCurrentSimplex(Matrix<double>* &plex) const
+{
+ plex = new Matrix<double>((*simplex));
+} // GetCurrentSimplex()
+ // performs a deep copy of the simplex to a Matrix pointer
+ // points to a newly allocated chunk of memory upon return
+ // USER SHOULD PASS JUST A NULL POINTER, WITHOUT PREALLOCATED MEMORY
+
+void GetCurrentSimplexValues(double* &simValues) const
+{
+ simValues = new double[dimensions+1];
+ for( int i = 0; i <= dimensions; i++ ) {
+ simValues[i] = simplexValues[i];
+ } // for
+} // GetCurrentSimplexValues()
+ // performs a deep copy of the simplexValues array to a double pointer
+ // points to a newly allocated chunk of memory upon return
+ // USER SHOULD PASS JUST A NULL POINTER, WITHOUT PREALLOCATED MEMORY
+
+int GetVarNo() const
+{
+ return dimensions;
+} // GetVarNo()
+ // returns the dimension of the problem
+
+int GetTolHit() const
+{
+ return toleranceHit;
+} // GetTolHit()
+
+ // returns toleranceHit
+
+void printSimplex() const
+{
+ for( int i = 0; i <= dimensions; i++ ) {
+ cout << " Point:";
+ for ( int j = 0; j < dimensions; j++ ) {
+ cout << (*simplex)[i][j] << "\t";
+ } // inner for
+ cout << "Value:" << simplexValues[i] << "\n";
+ } // outer for
+
+ cout << "\nFCalls: " << functionCalls << endl << endl;
+}
+ // prints out the simplex points by row, their corresponding f(x)
+ // values, and the number of function calls thus far
+
+ private:
+
+void FindMinMaxIndices()
+{
+ if(simplexValues == NULL) {
+ cerr << "Error in FindMinMaxIndices() - "
+ << "The vector of simplexValues is NULL!!\n";
+ return;
+ }
+ minIndex = 0;
+ maxIndex = dimensions;
+ double min = simplexValues[0];
+ double max = simplexValues[dimensions];
+ for( int i = 1; i <= dimensions; i++ ) {
+ if( simplexValues[i] < min ) {
+ min = simplexValues[i];
+ minIndex = i;
+ } // if
+ if( simplexValues[dimensions-i] > max ) {
+ max = simplexValues[dimensions-i];
+ maxIndex = dimensions - i;
+ } // if
+ } // for
+} // FindMinMaxIndices()
+
+ // sets minIndex to the simplex index of the point which generates
+ // the lowest value of f(x)
+ // sets maxIndex to the simplex index of the point which generates
+ // the highest value of f(x)
+
+int SecondHighestPtIndex()
+{
+ if(simplexValues == NULL) {
+ cerr << "Error in SecondHighestPtValue() - "
+ << "The vector of simplexValues is NULL!!\n";
+ return -1;
+ }
+ int secondMaxIndex = minIndex;
+ double secondMax = simplexValues[minIndex];
+ for( int i = 0; i <= dimensions; i++ ) {
+ if(i != maxIndex) {
+ if( simplexValues[i] > secondMax ) {
+ secondMax = simplexValues[i];
+ secondMaxIndex = i;
+ } // inner if
+ } // outer if
+ } // for
+ return secondMaxIndex;
+} // SecondHighestPtValue()
+
+ // returns simplex index of the point which
+ // generates the second highest value of f(x)
+
+void FindCentroid()
+{
+ (*centroid) = 0.0;
+ for( int i = 0; i <= dimensions; i++ ) {
+ if( i != maxIndex ) {
+ (*centroid) = (*centroid) + (*simplex).row(i);
+ } // if
+ } // for
+ (*centroid) = (*centroid) * ( 1.0 / (double)dimensions );
+} // FindCentroid()
+
+ // finds the centroid
+
+void FindReflectionPt()
+{
+ (*reflectionPt) = 0.0;
+ (*reflectionPt) = ( (*centroid) * (1.0 + alpha) ) -
+ ( alpha * (*simplex).row(maxIndex) );
+ int success;
+ fcnCall(dimensions, (*reflectionPt).begin(), reflectionPtValue, success);
+ if(!success) {
+ cerr << "Error finding f(x) for reflection point at"
+ << "function call #" << functionCalls << ".\n";
+ } // if
+} // FindReflectionPt()
+
+ // finds the reflection point and sets its f(x) value
+
+void FindExpansionPt()
+{
+ (*expansionPt) = 0.0;
+ (*expansionPt) = ( (*centroid) * (1.0 - gamma) ) +
+ ( gamma * (*reflectionPt) );
+ int success;
+ fcnCall(dimensions, (*expansionPt).begin(), expansionPtValue, success);
+ if(!success) {
+ cerr << "Error finding f(x) for expansion point at"
+ << "function call #" << functionCalls << ".\n";
+ } // if
+} // FindExpansionPt()
+ // finds the expansion point and sets its f(x) value
+
+void FindContractionPt()
+{
+ // need to first define maxPrimePt
+ Vector<double> *maxPrimePt = scratch;
+ if(simplexValues[maxIndex] <= reflectionPtValue) {
+ *maxPrimePt = (*simplex).row(maxIndex);
+ maxPrimePtValue = simplexValues[maxIndex];
+ maxPrimePtId = 1;
+ } // if
+ else {
+ maxPrimePt = reflectionPt;
+ maxPrimePtValue = reflectionPtValue;
+ maxPrimePtId = 0;
+ } // else
+
+ (*contractionPt) = ( (*centroid) * (1.0 - beta) ) +
+ ( beta * (*maxPrimePt) );
+ int success;
+ fcnCall(dimensions, (*contractionPt).begin(), contractionPtValue, success);
+ if(!success) {
+ cerr << "Error finding f(x) for contraction point at"
+ << "function call #" << functionCalls << ".\n";
+ } // if
+} // FindContractionPt()
+
+ // finds the contraction point and sets its f(x) value
+
+void ShrinkSimplex()
+{
+ // stop if at maximum function calls
+ // changed 5/01 to reflect maxcalls = -1 possibility ---pls
+ if ( (maxCalls != (-1))
+ && (functionCalls >= maxCalls) ) {return;}
+
+ Vector<double> *lowestPt = scratch;
+ *lowestPt = (*simplex).row(minIndex);
+ Vector<double> *tempPt = scratch2;
+ int success;
+ for( int i = 0; i <= dimensions; i++ ) {
+ if( i != minIndex ) {
+ *tempPt = (*simplex).row(i);
+ (*tempPt) = (*tempPt) + ( sigma * ( (*lowestPt)-(*tempPt) ) );
+ for( int j = 0; j < dimensions; j++ ) {
+ (*simplex)[i][j] = (*tempPt)[j];
+ } // inner for
+ fcnCall(dimensions,(*tempPt).begin(),simplexValues[i],success);
+ if (!success) cerr << "Error shrinking the simplex.\n";
+
+ // stop if at maximum function calls
+ // changed 5/01 to reflect maxcalls = -1 possibility ---pls
+ if ( (maxCalls != (-1))
+ && (functionCalls >= maxCalls) ) {return;}
+
+ } // if
+ } // outer for
+} // ShrinkSimplex()
+
+ // this function goes through the simplex and reduces the
+ // lengths of the edges adjacent to the best vertex
+
+
+ int dimensions; // the number of dimensions
+ // (the dimension of the problem)
+ Matrix<double> *simplex; // the current simplex
+ double *simplexValues; // their corresponding f(x) values
+ double alpha; // reflection coefficient
+ double beta; // contraction coefficient
+ double gamma; // expansion coefficient
+ double sigma; // shrinking coefficient
+ int maxCalls;
+ double stoppingStepLength;
+ int minIndex; // index of point generating min f(x)
+ int maxIndex; // index of point generating max f(x)
+ Vector<double> *centroid; // the current centroid
+ Vector<double> *reflectionPt; // the reflection point
+ double reflectionPtValue; // the value of f(reflectionPt)
+ Vector<double> *expansionPt; // the expansion point
+ double expansionPtValue; // the value of f(expansionPt)
+ Vector<double> *contractionPt; // the contraction point
+ double contractionPtValue; // the value of f(contractionPt)
+ double maxPrimePtValue; // min(f(maxIndexPoint),reflectionPtValue)
+ long functionCalls; // tally of number of function calls
+ int toleranceHit; // 1 if stop due to tolerance, 0 if funcCalls
+ int maxPrimePtId; // set by FindContractionPt() and used in
+ // ExploratoryMoves() to branch in pos. 3
+
+ // the following vectors are simply extra storage space
+ // that are used by functions that require a vector of
+ // size = dimensions
+ Vector<double> *scratch, *scratch2;
+
+
+
+};
+
+#endif //NMS_H
\ No newline at end of file
diff --git a/headers/optimiser.h b/headers/optimiser.h
new file mode 100644
index 0000000..513fd73
--- /dev/null
+++ b/headers/optimiser.h
@@ -0,0 +1,92 @@
+
+/* Zodiac - molecular modelling environment. www.zeden.org
+Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef OPTIMISER_H
+#define OPTIMISER_H
+
+#include "function.h"
+#include <algorithm>
+//#include <QTime>
+
+
+
+typedef struct {
+ vector <float> state;
+ float score;
+} conformation;
+
+
+class Optimiser {
+ public:
+ Optimiser () : time_limit (0) { iteration_limit = -1; optFunc = NULL; iterations_n = 1;};
+ Optimiser (Function *f) : time_limit (0) {optFunc = f; iteration_limit = -1; iterations_n = 1;};
+ ~Optimiser () {};
+ virtual void init (vector<Variable*>& vars) {};
+ virtual float run () = 0;
+ virtual void set_iteration_limit (int limit) {iteration_limit = limit; iterations_n = 0;};
+ vector <conformation *> &get_results () {return results;};
+ void set_time_limit (int t) {time_limit = t;};
+
+
+protected:
+ Function* optFunc;
+ vector <conformation *> results;
+ QTime start_time;
+ int time_limit, iteration_limit;
+ int iterations_n;
+ bool reached_limits () {
+ // cerr << "iteration_limit "<<iteration_limit<<" iteration_n "<< iterations_n<<" time_limit "<<time_limit<<" elapsed_time "<<start_time.secsTo ( QTime::currentTime () )<<endl;
+ bool t = true; bool it = true;
+ if (!time_limit) {
+ t = false;
+ }
+ else {
+ int elapsed_time = start_time.secsTo ( QTime::currentTime () );
+ if (elapsed_time > time_limit) t = true;
+ else t = false;
+ }
+ if (iteration_limit < 1) {
+ it = false;
+ }
+ else {
+ if (iterations_n > iteration_limit) it = true;
+ else it = false;
+ }
+ // if (t ) cerr << "reachced time limits"<<endl;
+ // if (it ) cerr << "reachced iterations limits "<<iterations_n << " "<<iteration_limit<<endl;
+ return (t || it);
+ }
+ void start_timer () {
+ start_time = QTime::currentTime ();
+ }
+};
+
+
+
+struct conformationScoreCompare
+{
+ bool operator()(const conformation* a, const conformation* b)
+ {
+ return a->score < b->score;
+ }
+};
+
+#endif //OPTIMISER_H
+
+
diff --git a/headers/plants.h b/headers/plants.h
new file mode 100644
index 0000000..265c9c1
--- /dev/null
+++ b/headers/plants.h
@@ -0,0 +1,58 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef PLANTS_H
+#define PLANTS_H
+
+
+#include <qfileinfo.h>
+#include "plants_mainwin.h"
+#include <Qt3Support/q3vbox.h>
+#include "plantsconfig.h"
+#include "ZNdata.h"
+class Data;
+class Configuration;
+
+
+class Plants : public Q3VBox
+{
+ Q_OBJECT
+
+public:
+
+ Plants ( QWidget *parent, const char *name, Data* dat );
+ PlantsMainWin *mainwin;
+ Data *data;
+ Configuration *config;
+private :
+
+ void create_menu ();
+ void create_menu_actions ();
+
+ QAction *openAct, *saveasAct, *resetAct, *aboutAct;
+
+private slots:
+
+ void reset ();
+ void save ();
+
+public slots:
+ void about ();
+ void load ();
+
+};
+#endif
diff --git a/headers/plants_mainwin.h b/headers/plants_mainwin.h
new file mode 100644
index 0000000..0f63a5e
--- /dev/null
+++ b/headers/plants_mainwin.h
@@ -0,0 +1,174 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef PLANTS_MAINWIN_H
+#define PLANTS_MAINWIN_H
+
+#include "constants.h"
+#include <qtabwidget.h>
+#include <qstring.h>
+#include <qfileinfo.h>
+#include <Qt3Support/q3frame.h>
+#include <qpushbutton.h>
+#include <Qt3Support/q3listbox.h>
+#include <qcombobox.h>
+#include "myline.h"
+#include "plants.h"
+#include "constants.h"
+
+
+using namespace std;
+
+class MyListBoxItem : public Q3ListBoxText
+{
+
+public:
+ bool valid;
+ MyListBoxItem(string s, Q3ListBox *par);
+
+
+protected:
+bool check_mol2 (string line);
+ Q3ListBox *parent;
+ string tex;
+ virtual void paint( QPainter * );
+ virtual int width( const Q3ListBox* ) const { return (parent->width ()-5); }
+ virtual int height( const Q3ListBox* ) const { return 20; }
+};
+
+
+
+class Plants;
+class PlantsMainWin : public QTabWidget
+{
+ Q_OBJECT
+
+public:
+ PlantsMainWin( Plants *parent);
+ Plants *window;
+ vector <QComboBox*> lat, pat, pres;
+
+
+protected:
+ QString filename;
+ QFileInfo fileinfo;
+
+
+ void setupwin();
+
+ private slots:
+ void add_water_slot();
+ void addphbc();
+ void addshc();
+ void addsdc();
+ void addidc();
+ void addldc();
+ void add_flsc_slot();
+ // void askfil(const char *dir, const char *type, QWidget *parent, const char *title, const char *text);
+ void add_phbc_slot ();
+ void add_shc_slot ();
+ void add_sdc_slot ();
+ void add_idc_slot ();
+ void add_ldc_slot ();
+ void add_lf_slot ();
+ void add_ll_slot ();
+ void set_sf_slot ();
+ void add_fixp_slot ();
+ void load_bs_from_ligand_slot ();
+ void ligand_selected (int index);
+
+ void load_protein ();
+ void load_ligand ();
+ void check_outdir ();
+ void check_bindingsite ();
+
+
+ void del_ifile ();
+ void del_constr ();
+ void del_flex ();
+ void del_water ();
+
+ private:
+
+ void update_boxes (vector<QComboBox*> &vec, vector<string>& values);
+
+
+ QWidget* phbcpopup;
+ QWidget* shcpopup;
+ QWidget* sdcpopup;
+ QWidget* idcpopup;
+ QWidget* ldcpopup;
+ QWidget* flscpopup;
+ QPushButton *addwaterb;
+ QPushButton *addphbcb;
+ QPushButton *addshcb;
+ QPushButton *addsdcb;
+ QPushButton *addidcb;
+ QPushButton *addldcb;
+ QPushButton *addflscb;
+ QPushButton *addfixpb;
+
+ QComboBox *anlined;
+ QLineEdit *phbweil;
+ QLineEdit *shfl;
+ QLineEdit *shweil;
+
+
+
+ QComboBox *sdanl;
+ QLineEdit *sdbbfl;
+ QLineEdit *sdbbtl;
+ QLineEdit *sdweil;
+ QComboBox *idanl;
+ QComboBox *idanl2;
+ QLineEdit *idbbfl;
+ QLineEdit *idbbtl;
+ QLineEdit *idweil;
+ QComboBox *ldanl;
+ QComboBox *ldanl2;
+ QLineEdit *ldbbfl;
+ QLineEdit *ldbbtl;
+ QLineEdit *ldweil;
+
+ QComboBox *flscl, *fixpl;
+
+ QPushButton *bsfl;
+
+
+ QLineEdit *xwc, *ywc, *zwc, *wr;
+
+
+ MyLineF *lfile, *llist;
+
+
+public:
+
+ MyLineF *pfile, *wref;
+ MyLine *aants, *aevap, *asigma, *chbw, *cmw, *hbw, *hbchow, *mw, *plpw, *iw, *crmsd, *cs, *odir, *ipsw, *wphb, *wlhb, *wwhb, *nwhbp, *bsx, *bsy, *bsz, *bsr;
+ QPushButton *flipab, *flipn, *ffbp;
+ QPushButton *wpc, *wrs, *wmm2, *wrl, *wrmm2, *cho, *rigidl, *rigida, *wpb, *wps, *wpas;
+ QComboBox *sfchoice, *lintra;
+ Q3ListBox *iflb, *constrlb, *flexlb, *waterlb;
+ void check_ligands ();
+ void set_bindingsite (float x, float y, float z);
+ void set_bindingsite (float x, float y, float z, float r);
+ float getfloat (string s);
+};
+
+#endif
diff --git a/headers/plantsconfig.h b/headers/plantsconfig.h
new file mode 100644
index 0000000..ed30a51
--- /dev/null
+++ b/headers/plantsconfig.h
@@ -0,0 +1,107 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef PLANTSCONFIG_H
+#define PLANTSCONFIG_H
+
+
+#include "plantsconfig.h"
+#include "plants.h"
+#include "plants_mainwin.h"
+
+class PlantsMainWin;
+class Plants;
+
+class Confline
+{
+public:
+ Confline (char type, string filestr,string defval, MyLine* targetl);
+ Confline (char type, string filestr, string defval,QPushButton* targetb);
+ Confline (char type, string filestr, string defval, QLineEdit* targetle);
+ Confline (char type, string filestr, string defval, MyLineF* targetlf);
+ Confline (char type, string filestr, string defval, QComboBox* targetcb);
+ Confline (char type, string filestr, string defval, Q3ListBox* targetlb);
+ Confline (char type, string filestr, string defval, PlantsMainWin* targetlb);
+
+ void Default ();
+ void Apply ();
+ void Get ();
+ int getInt (string mystr);
+
+
+ char type;
+ string defval, filestr, current;
+ MyLine* targetl;
+ QPushButton* targetb;
+ QLineEdit* targetle;
+ MyLineF* targetlf;
+ QComboBox* targetcb;
+ Q3ListBox* targetlb;
+ PlantsMainWin* targetmw;
+ string boolstr (bool boo);
+
+ vector<string> vect;
+
+
+ // void Read ();
+ // void Write ();
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class Configuration
+{
+
+public:
+ Configuration (Plants *plant);
+// void setdata (Data *datas);
+ void Apply ();
+ void Default ();
+ void Write (const char * filename);
+ void Read (const char * filename);
+ void Get ();
+//void Load (File* file);
+
+
+private:
+ Plants *plants;
+
+
+
+
+// vector <string> ifiles, vflex, vwater, vconstr;
+ vector <Confline*> conf;
+
+
+
+
+};
+
+
+#endif
diff --git a/headers/ply.h b/headers/ply.h
new file mode 100644
index 0000000..9627cbd
--- /dev/null
+++ b/headers/ply.h
@@ -0,0 +1,466 @@
+/*
+
+
+
+Header for PLY polygon files.
+
+
+
+- Greg Turk
+
+
+
+A PLY file contains a single polygonal _object_.
+
+
+
+An object is composed of lists of _elements_. Typical elements are
+
+vertices, faces, edges && materials.
+
+
+
+Each type of element for a given object has one || more _properties_
+
+associated with the element type. For instance, a vertex element may
+
+have as properties three floating-point values x,y,z && three unsigned
+
+chars for red, green && blue.
+
+
+
+-----------------------------------------------------------------------
+
+
+
+Copyright (c) 1998 Georgia Institute of Technology. All rights reserved.
+
+
+
+Permission to use, copy, modify && distribute this software && its
+
+documentation for any purpose is hereby granted without fee, provided
+
+that the above copyright notice && this permission notice appear in
+
+all copies of this software && that you do not sell the software.
+
+
+
+THE SOFTWARE IS PROVIDED "AS IS" && WITHOUT WARRANTY OF ANY KIND,
+
+EXPRESS, IMPLIED || OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+
+WARRANTY OF MERCHANTABILITY || FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+*/
+
+
+
+#ifndef __PLY_H__
+
+#define __PLY_H__
+
+
+
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
+
+
+
+#include <stdio.h>
+
+#include <stddef.h>
+
+
+
+#define PLY_ASCII 1 /* ascii PLY file */
+
+#define PLY_BINARY_BE 2 /* binary PLY file, big endian */
+
+#define PLY_BINARY_LE 3 /* binary PLY file, little endian */
+
+
+
+#define PLY_OKAY 0 /* ply routine worked okay */
+
+#define PLY_ERROR -1 /* error in ply routine */
+
+
+
+/* scalar data types supported by PLY format */
+
+
+
+#define StartType 0
+
+#define Int8 1
+
+#define Int16 2
+
+#define Int32 3
+
+#define Uint8 4
+
+#define Uint16 5
+
+#define Uint32 6
+
+#define Float32 7
+
+#define Float64 8
+
+#define EndType 9
+
+
+
+#define PLY_SCALAR 0
+
+#define PLY_LIST 1
+
+#define PLY_STRING 2
+
+
+
+
+
+typedef struct PlyProperty { /* description of a property */
+
+
+
+char *name; /* property name */
+
+int external_type; /* file's data type */
+
+int internal_type; /* program's data type */
+
+int offset; /* offset bytes of prop in a struct */
+
+
+
+int is_list; /* 0 = scalar, 1 = list, 2 = char string */
+
+int count_external; /* file's count type */
+
+int count_internal; /* program's count type */
+
+int count_offset; /* offset byte for list count */
+
+
+
+} PlyProperty;
+
+
+
+typedef struct PlyElement { /* description of an element */
+
+char *name; /* element name */
+
+int num; /* number of elements in this object */
+
+int size; /* size of element (bytes) || -1 if variable */
+
+int nprops; /* number of properties for this element */
+
+PlyProperty **props; /* list of properties in the file */
+
+char *store_prop; /* flags: property wanted by user? */
+
+int other_offset; /* offset to un-asked-for props, || -1 if none*/
+
+int other_size; /* size of other_props structure */
+
+} PlyElement;
+
+
+
+typedef struct PlyOtherProp { /* describes other properties in an element */
+
+char *name; /* element name */
+
+int size; /* size of other_props */
+
+int nprops; /* number of properties in other_props */
+
+PlyProperty **props; /* list of properties in other_props */
+
+} PlyOtherProp;
+
+
+
+typedef struct OtherData { /* for storing other_props for an other element */
+
+void *other_props;
+
+} OtherData;
+
+
+
+typedef struct OtherElem { /* data for one "other" element */
+
+char *elem_name; /* names of other elements */
+
+int elem_count; /* count of instances of each element */
+
+OtherData **other_data; /* actual property data for the elements */
+
+PlyOtherProp *other_props; /* description of the property data */
+
+} OtherElem;
+
+
+
+typedef struct PlyOtherElems { /* "other" elements, not interpreted by user */
+
+int num_elems; /* number of other elements */
+
+OtherElem *other_list; /* list of data for other elements */
+
+} PlyOtherElems;
+
+
+
+#define AVERAGE_RULE 1
+
+#define MAJORITY_RULE 2
+
+#define MINIMUM_RULE 3
+
+#define MAXIMUM_RULE 4
+
+#define SAME_RULE 5
+
+#define RANDOM_RULE 6
+
+
+
+typedef struct PlyPropRules { /* rules for combining "other" properties */
+
+PlyElement *elem; /* element whose rules we are making */
+
+int *rule_list; /* types of rules (AVERAGE_PLY, MAJORITY_PLY, etc.) */
+
+int nprops; /* number of properties we're combining so far */
+
+int max_props; /* maximum number of properties we have room for now */
+
+void **props; /* list of properties we're combining */
+
+float *weights; /* list of weights of the properties */
+
+} PlyPropRules;
+
+
+
+typedef struct PlyRuleList {
+
+char *name; /* name of the rule */
+
+char *element; /* name of element that rule applies to */
+
+char *property; /* name of property that rule applies to */
+
+struct PlyRuleList *next; /* pointer for linked list of rules */
+
+} PlyRuleList;
+
+
+
+typedef struct PlyFile { /* description of PLY file */
+
+FILE *fp; /* file pointer */
+
+int file_type; /* ascii || binary */
+
+float version; /* version number of file */
+
+int num_elem_types; /* number of element types of object */
+
+PlyElement **elems; /* list of elements */
+
+int num_comments; /* number of comments */
+
+char **comments; /* list of comments */
+
+int num_obj_info; /* number of items of object information */
+
+char **obj_info; /* list of object info items */
+
+PlyElement *which_elem; /* element we're currently reading || writing */
+
+PlyOtherElems *other_elems; /* "other" elements from a PLY file */
+
+PlyPropRules *current_rules; /* current propagation rules */
+
+PlyRuleList *rule_list; /* rule list from user */
+
+} PlyFile;
+
+
+
+/* memory allocation */
+
+/*
+
+extern char *my_alloc();
+
+*/
+
+#define myalloc(mem_size) my_alloc((mem_size), __LINE__, __FILE__)
+
+
+
+
+
+/* old routines */
+
+
+
+#if 0
+
+extern PlyFile *ply_write(FILE *, int, char **, int);
+
+extern PlyFile *ply_read(FILE *, int *, char ***);
+
+extern PlyFile *ply_open_for_reading( char *, int *, char ***, int *, float *);
+
+extern void ply_close(PlyFile *);
+
+extern PlyOtherProp *ply_get_other_properties(PlyFile *, char *, int);
+
+#endif
+
+
+
+extern void ply_describe_property( PlyFile * , char * , PlyProperty * );
+
+extern void ply_get_property( PlyFile * , char * , PlyProperty * );
+
+extern void ply_get_element( PlyFile * , void * );
+
+
+
+
+
+/*** delcaration of routines ***/
+
+
+
+PlyOtherElems *get_other_element_ply( PlyFile * );
+
+
+
+PlyFile *read_ply( FILE * );
+
+PlyFile *write_ply( FILE * , int, char ** , int );
+
+extern PlyFile *open_for_writing_ply( char * , int, char ** , int );
+
+void close_ply( PlyFile * );
+
+void free_ply( PlyFile * );
+
+
+
+void get_info_ply( PlyFile * , float * , int * );
+
+void free_other_elements_ply( PlyOtherElems * );
+
+
+
+void append_comment_ply( PlyFile * , char * );
+
+void append_obj_info_ply( PlyFile * , char * );
+
+void copy_comments_ply( PlyFile * , PlyFile * );
+
+void copy_obj_info_ply( PlyFile * , PlyFile * );
+
+char* *get_comments_ply( PlyFile * , int * );
+
+char* *get_obj_info_ply( PlyFile * , int * );
+
+
+
+char* *get_element_list_ply( PlyFile * , int * );
+
+int setup_property_ply( PlyFile * , PlyProperty * );
+
+void get_element_ply( PlyFile * , void * );
+
+char *setup_element_read_ply( PlyFile * , int, int * );
+
+PlyOtherProp *get_other_properties_ply( PlyFile * , int );
+
+
+
+void element_count_ply( PlyFile * , char * , int );
+
+void describe_element_ply( PlyFile * , char * , int );
+
+void describe_property_ply( PlyFile * , PlyProperty * );
+
+void describe_other_properties_ply( PlyFile * , PlyOtherProp * , int );
+
+void describe_other_elements_ply( PlyFile * , PlyOtherElems * );
+
+void get_element_setup_ply( PlyFile * , char * , int, PlyProperty * );
+
+PlyProperty* *get_element_description_ply( PlyFile * , char * , int * , int * );
+
+void element_layout_ply( PlyFile * , char * , int, int, PlyProperty * );
+
+
+
+void header_complete_ply( PlyFile * );
+
+void put_element_setup_ply( PlyFile * , char * );
+
+void put_element_ply( PlyFile * , void * );
+
+void put_other_elements_ply( PlyFile * );
+
+
+
+PlyPropRules *init_rule_ply( PlyFile * , char * );
+
+void modify_rule_ply( PlyPropRules * , char * , int );
+
+void start_props_ply( PlyFile * , PlyPropRules * );
+
+void weight_props_ply( PlyFile * , float, void * );
+
+void *get_new_props_ply( PlyFile * );
+
+void set_prop_rules_ply( PlyFile * , PlyRuleList * );
+
+PlyRuleList *append_prop_rule( PlyRuleList * , char * , char * );
+
+int matches_rule_name( char * );
+
+
+
+int equal_strings( char * , char * );
+
+char *recreate_command_line( int, char *argv[] );
+
+
+
+
+
+#ifdef __cplusplus
+
+}
+
+#endif
+
+#endif /* !__PLY_H__ */
+
+
+
diff --git a/headers/pso.h b/headers/pso.h
new file mode 100644
index 0000000..13fc767
--- /dev/null
+++ b/headers/pso.h
@@ -0,0 +1,195 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef PSO_H
+#define PSO_H
+
+#include "optimiser.h"
+#include "nms.h"
+
+
+class PSO : public Optimiser {
+public:
+ PSO () : Optimiser () {};
+ PSO (Function* f) : Optimiser (f)
+ {
+ optFunc = f;
+
+ };
+ ~PSO () {};
+
+ float run ()
+ {
+
+
+ unsigned int i;
+ unsigned int j;
+ vector<Variable*>& vars = optFunc->access_variables();
+
+ float bestSolutionValue = numeric_limits<float>::max();
+ vector<float> maxV(vars.size());
+ unsigned int nofFunc = 0;
+ float r1;
+ float r2;
+
+ vector<vector<float> > x;
+
+ bool optimising = true;
+ minimiser = new NMS (optFunc);
+ minimiser ->set_iteration_limit (20);
+
+ vector<float> fx;
+ vector<float> bestState;
+ vector<float> currentState;
+ vector<vector<float> > v;
+
+ vector<vector<float> > p;
+ vector<float> fp;
+
+ unsigned int nofParticles = 20;
+
+ x.resize(nofParticles);
+ v.resize(nofParticles);
+ p.resize(nofParticles);
+ fx.resize(nofParticles);
+ fp.resize(nofParticles);
+
+ bestState.resize(vars.size());
+
+
+ for (i = 0; i < vars.size(); i++) {
+ if (i < 3) {
+ maxV[i] = 2.0;
+ }
+ else {
+ maxV[i] = 50.0;
+ }
+ }
+
+ for (i = 0; i < nofParticles; i++) {
+ x[i].resize(vars.size());
+ v[i].resize(vars.size());
+ p[i].resize(vars.size());
+
+ for (j = 0; j < vars.size(); j++) {
+ x[i][j] = (float)rand()/(float)RAND_MAX * (vars[j]->max_val - vars[j]->min_val) + vars[j]->min_val;
+ }
+ p[i] = x[i];
+
+ for (j = 0; j < vars.size(); j++) {
+ *vars[j]->value = x[i][j];
+ }
+
+ fx[i] = optFunc->evaluate();
+ fp[i] = fx[i];
+
+ nofFunc++;
+
+
+ if (fx[i] < bestSolutionValue) {
+ bestSolutionValue = fx[i];
+ bestState = x[i];
+ }
+
+ for (j = 0; j < vars.size(); j++) {
+ v[i][j] = -maxV[j] + (float)rand()/(float)RAND_MAX * (2.0 * maxV[j]);
+ }
+ }
+
+ //unsigned int iterations = 0;
+ start_timer ();
+
+ while (!reached_limits ()) {
+ iterations_n ++;
+ currentState = bestState;
+ for (i = 0; i < nofParticles; i++) {
+
+ if (fx[i] < fp[i]) {
+ fp[i] = fx[i];
+ p[i] = x[i];
+ }
+
+ for (j = 0; j < vars.size(); j++) {
+
+ r1 = (float)rand()/(float)RAND_MAX;
+ r2 = (float)rand()/(float)RAND_MAX;
+
+
+ v[i][j] = iw*v[i][j] + ci*r1*(p[i][j]-x[i][j]) + cg*r2*(currentState[j]-x[i][j]);
+
+ if (v[i][j] > maxV[j]) {
+ v[i][j] = maxV[j];
+ }
+ if (v[i][j] < -maxV[j]) {
+ v[i][j] = -maxV[j];
+ }
+
+ x[i][j] += v[i][j];
+ }
+ for (j = 0; j < vars.size(); j++) {
+ *vars[j]->value = x[i][j];
+ }
+
+ if (optimising) {
+ minimiser -> init (vars);
+ minimiser -> run ();
+
+ }
+ fx[i] = optFunc->evaluate();
+ conformation *solution = new conformation;
+ solution ->score = fx[i];
+ for (j = 0; j < vars.size(); j++) {
+ solution ->state.push_back (*vars[j]->value);
+ }
+ results.push_back (solution);
+ for (j = 0; j < vars.size(); j++) {
+ x[i][j] = *vars[j]->value;
+ }
+
+ nofFunc++;
+
+ if (fx[i] < bestSolutionValue) {
+ bestState = x[i];
+ bestSolutionValue = fx[i];
+ }
+
+ }
+
+ for (j = 0; j < vars.size(); j++) {
+ *vars[j]->value = bestState[j];
+ }
+
+ }
+ sort (results.begin (), results.end (), conformationScoreCompare ());
+ return bestSolutionValue;
+
+ };
+
+private:
+ float ci;
+ float cg;
+ float iw;
+// PSOlocalWeight = 1.0;
+// PSOglobalWeight = 1.0;
+// PSOinertiaWeight = 0.6;
+ Optimiser *minimiser;
+};
+
+
+#endif //PSO_H
\ No newline at end of file
diff --git a/headers/subscrpt.h b/headers/subscrpt.h
new file mode 100644
index 0000000..4557e2a
--- /dev/null
+++ b/headers/subscrpt.h
@@ -0,0 +1,42 @@
+// Template Numerical Toolkit (TNT) for Linear Algebra
+//
+// R. Pozo
+// Applied and Computational Mathematics Division
+// National Institute of Standards and Technology
+
+//Chris Siefert's namespace-free version - 5/20/99
+
+#ifndef SUBSCRPT_H
+#define SUBSCRPT_H
+
+
+//---------------------------------------------------------------------
+// This definition describes the default TNT data type used for
+// indexing into TNT matrices and vectors. The data type should
+// be wide enough to index into large arrays. It defaults to an
+// "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE,
+// e.g.
+//
+// g++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ...
+//
+//---------------------------------------------------------------------
+//
+
+#ifndef TNT_SUBSCRIPT_TYPE
+#define TNT_SUBSCRIPT_TYPE int
+#endif
+
+//namespace TNT
+//{
+ typedef TNT_SUBSCRIPT_TYPE Subscript;
+//}
+
+
+// () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the
+// first elements. This offset is left as a macro for future
+// purposes, but should not be changed in the current release.
+//
+//
+#define TNT_BASE_OFFSET (1)
+
+#endif
diff --git a/headers/thread.h b/headers/thread.h
new file mode 100644
index 0000000..b93d488
--- /dev/null
+++ b/headers/thread.h
@@ -0,0 +1,319 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef THREAD_H
+#define THREAD_H
+
+#include <QMutex>
+#include <QThread>
+#include "graphical_object.h"
+#include "minimize.h"
+#include "ddwin.h"
+#include "obabel_includes.h"
+#include "wiimote.h"
+
+
+class DDWin; class Minimize;
+class Thread : public QThread {
+ Q_OBJECT
+ public:
+ Thread (QObject *parent);
+ bool is_running;
+ virtual void stop ();
+ string _name;
+ string _doing;
+ int _min_step;
+ int _max_step;
+ int _current_step;
+ // protected:
+// void run();
+};
+
+class MapThread : public Thread {
+ Q_OBJECT
+ public:
+ MapThread (QObject *parent, Map *mp, DDWin *ddw);
+ Map * map;
+ float alph, res;
+ DDWin *ddwin;
+
+
+ protected:
+ void run ();
+ void compute_map_data ();
+};
+
+class SurfaceThread : public Thread {
+ Q_OBJECT
+ public:
+ SurfaceThread (QObject *parent, Surface *surf, DDWin *ddw);
+ Surface *surface;
+ float alph, res;
+ DDWin *ddwin;
+
+
+ protected:
+ void run ();
+ void compute_surface_data ();
+};
+
+
+class SystematicConformationThread : public Thread {
+ Q_OBJECT
+public:
+ SystematicConformationThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw);
+ ZNMolecule *molecule;
+ Database *database;
+ DDWin *ddwin;
+
+
+protected:
+ void run ();
+ void generate_conformation (vector <double> &dofs, int level);
+};
+
+class StochasticConformationThread : public Thread {
+ Q_OBJECT
+public:
+ StochasticConformationThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw);
+ ZNMolecule *molecule;
+ Database *database;
+ DDWin *ddwin;
+ void set_results_number (int n) {_results_number = n;};
+ void set_time_limit (int n) {_time_limit = n;};
+
+protected:
+ void run ();
+ int _results_number, _time_limit;
+};
+
+
+class DockingThread : public Thread {
+ Q_OBJECT
+public:
+ DockingThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw);
+ ZNMolecule *molecule;
+ Database *database;
+ DDWin *ddwin;
+ void set_results_number (int n) {_results_number = n;};
+ void set_time_limit (int n) {_time_limit = n;};
+ void set_bindingsite_radius (float r) {_bindingsite_radius = r;};
+ void set_bindingsite_center (vect c) {_bindingsite_center = c;};
+
+protected:
+ void run ();
+ int _results_number, _time_limit;
+ vect _bindingsite_center;
+ float _bindingsite_radius;
+};
+
+
+class MinimiseThread : public Thread {
+ Q_OBJECT
+ public:
+ MinimiseThread (QObject *parent, DDWin *ddw);
+ ZNMolecule *molecule;
+ DDWin *ddwin;
+
+ void inline set_molecule (ZNMolecule *mol) {molecule = mol;};
+
+
+ signals:
+ void ask_redraw (ZNMolecule *mol);
+
+ private:
+
+ protected:
+ void run ();
+};
+
+class DatabaseMinimiseThread : public Thread {
+ Q_OBJECT
+ public:
+ DatabaseMinimiseThread (QObject *parent, Database *dat, DDWin *ddw);
+ Database * database;
+ DDWin *ddwin;
+ protected:
+ void run ();
+ };
+
+class HapticWorkerThread;
+class HapticForceThread : public Thread {
+ Q_OBJECT
+ public:
+ HapticForceThread (QObject *parent, DDWin *ddw);
+ DDWin *ddwin;
+ protected:
+ void run ();
+};
+
+class HapticThread : public Thread {
+ Q_OBJECT
+ public:
+ HapticThread (QObject *parent, DDWin *ddw);
+ void stop ();
+ bool save_result, last_is_user_selected, user_save_result, is_worse, saving;
+ float save_E_threshold, mult;
+ ZNMolecule *molecule;
+ Database *results;
+ DDWin *ddwin;
+ Minimize *minimise;
+ vector <float> viscous_force_x, viscous_force_y, viscous_force_z;
+ void inline set_molecule (ZNMolecule *mol) {molecule = mol;};
+ int haptic_dof_mode;
+ bool automove, color_by_score;
+ void initialise (Minimize * min);
+
+ int next_atom_to_check, internal_interaction_counter, number_of_atoms;
+ vector <Atom *> atoms;
+ vect last_center;
+ //vector <vect> forces;
+ //vector <double> scores;
+
+
+
+ QMutex atoms_mutex, internal_interactions_mutex, nonbonded_interactions_mutex;
+
+
+
+ signals:
+
+ void ask_color_by_score (ZNMolecule *mol);
+
+
+ protected:
+ void run ();
+
+ private:
+ vect total_torque;
+ double total_energy;
+ int ncycles;
+ int number_of_threads;
+ vector <HapticWorkerThread *> worker_threads;
+
+public:
+ vector <ForceFieldInteraction *> internal_interactions;
+ //vector <ForceFieldInteraction *> restrains;
+private:
+ vector <HBond> Hbonds;
+ queue <ForceFieldInteraction *> nonbonded_interactions;
+
+
+ public:
+ bool have_to_work_on_internal_interactions ();
+ bool have_to_work_on_nonbonded_interactions ();
+ bool are_atoms_finished ();
+ bool are_internal_interactions_finished ();
+ bool is_end_of_cycle ();
+ void compute_one_internal_interaction ();
+ void compute_one_nonbonded_interaction ();
+ void compute_nonbonded_interactions_for_atom (int a);
+ void compute_internal_interaction (int i);
+ void compute_restrain (int i);
+ void load_internal_interactions ();
+ void load_interactions_for_new_atom ();
+ void end_of_calculation_for_atom (Atom *at);
+ void end_of_cycle ();
+};
+
+
+class HapticWorkerThread : public Thread {
+ public:
+
+ enum HapticWorkerType { INTERNAL, INTERACTION, SINGLE};
+ HapticWorkerThread (HapticThread *ht, int i, HapticWorkerType typ);
+
+ HapticWorkerType thread_type;
+ protected:
+ void run ();
+ private:
+ HapticThread *master;
+ int number;
+
+};
+
+
+
+class GridThread : public Thread {
+ Q_OBJECT
+ public:
+ GridThread (QObject *parent, Grid *gri, DDWin *ddw);
+ Grid *grid;
+ DDWin *ddwin;
+
+
+// signals:
+// void ask_redraw (ZNMolecule *mol);
+// void ask_color_by_score (ZNMolecule *mol);
+
+
+ protected:
+ void run ();
+
+};
+
+
+class HeadTrackingThread : public Thread {
+ Q_OBJECT
+ public:
+ HeadTrackingThread (QObject *parent, DDWin *ddw);
+ DDWin *ddwin;
+
+
+
+// signals:
+// void ask_redraw (ZNMolecule *mol);
+// void ask_color_by_score (ZNMolecule *mol);
+
+ Wiimote *wiimote;
+
+ protected:
+ void run ();
+// int lastx, lasty;
+ signals:
+ void head_moved (int x, int y);
+
+};
+
+
+
+class WiimoteTrackingThread : public Thread {
+ Q_OBJECT
+ public:
+ WiimoteTrackingThread (QObject *parent, DDWin *ddw);
+ DDWin *ddwin;
+
+ Wiimote *wiimote;
+ void switch_to_mode (int i);
+
+ protected:
+ int mode;
+ bool is_moving, is_rotating;
+ void run ();
+ float lastx, lasty, lastd;
+ vect last_orientation;
+ signals:
+ void move_camera (float x, float y, float z);
+ void move_target (float x, float y, float z);
+ void rotate_world (double x1, double y1, double z1, double x2, double y2, double z2);
+ void rotate_target (double x1, double y1, double z1, double x2, double y2, double z2);
+};
+
+
+
+
+#endif //THREAD_H
diff --git a/headers/vec.h b/headers/vec.h
new file mode 100644
index 0000000..2c1d44a
--- /dev/null
+++ b/headers/vec.h
@@ -0,0 +1,1172 @@
+// Template Numerical Toolkit (TNT) for Linear Algebra
+
+//
+
+// BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
+
+// Please see http://math.nist.gov/tnt for updates
+
+//
+
+// R. Pozo
+
+// Mathematical and Computational Sciences Division
+
+// National Institute of Standards and Technology
+
+
+
+
+
+// Basic TNT numerical vector (0-based [i] AND 1-based (i) indexing )
+
+//
+
+
+
+//Chris Siefert's modified namespace-free version - 6/8/99
+
+//adding l2norm capabilities.
+
+//made the dot product the overloaded *
+
+//component-based multiply is now compmult.
+
+//added Scalar * Vector, and Vector * Scalar
+
+//added overloaded == and != operators
+
+
+
+//COMPLETE OPERATOR LIST
+
+// Vector<T>& newsize(Subscript N)
+
+// Vector<T>& operator=(const Vector<T> &A)
+
+// Vector<T>& operator=(const T& scalar)
+
+// Subscript dim() const (also size())
+
+// operator()
+
+// operator[]
+
+// ostream& operator<<(ostream &s, const Vector<T> &A)
+
+// istream & operator>>(istream &s, Vector<T> &A)
+
+// vector + vector
+
+// vector - vector
+
+// compmult(vector, vector) - componant-wise multiplication, used to be *
+
+
+
+// cmsief
+
+// friend bool operator==(const Vector<T>&A, const Vector<T>& B)
+
+// friend bool isnear(const Vector<T>&A, const Vector<T>& B, const T tolerance)
+
+// friend bool operator!=(const Vector<T>&A, const Vector<T>& B)
+
+// double l2norm()
+
+// double l2norm_sqr()
+
+// scalar * vector, vector * scalar (also scalmult)
+
+// vector * vector - dot product, uset to be dotprod
+
+
+
+
+
+#ifndef VEC_H
+
+#define VEC_H
+
+
+
+#ifndef DOLD_ALLOC
+
+#include <new>
+
+#endif
+
+
+
+#include "subscrpt.h"
+
+#include <cmath> /*for l2norms*/
+
+#include <cstdlib>
+
+#include <cassert>
+
+#include <iostream>
+
+#include <sstream>
+
+#include <iomanip>
+
+#include <fstream>
+
+//#include <strstream.h> deprecated
+
+
+
+#define D_PRECISION 16
+
+
+
+using namespace std;
+
+//namespace TNT
+
+//{
+
+
+
+//typedef long Subscript;
+
+
+
+template <class T>
+
+class Vector
+
+{
+
+
+
+
+
+ public:
+
+
+
+ typedef Subscript size_type;
+
+ typedef T value_type;
+
+ typedef T element_type;
+
+ typedef T* pointer;
+
+ typedef T* iterator;
+
+ typedef T& reference;
+
+ typedef const T* const_iterator;
+
+ typedef const T& const_reference;
+
+
+
+ Subscript lbound() const { return 1;}
+
+
+
+ protected:
+
+ T* v_;
+
+ T* vm1_; // pointer adjustment for optimzied 1-offset indexing
+
+ Subscript n_;
+
+
+
+ // internal helper function to create the array
+
+ // of row pointers
+
+
+
+ void initialize(Subscript N)
+
+ {
+
+ // adjust pointers so that they are 1-offset:
+
+ // v_[] is the internal contiguous array, it is still 0-offset
+
+ //
+
+ assert(v_ == NULL);
+
+
+
+#ifdef DOLD_ALLOC
+
+ v_ = new T[N];
+
+ assert(v_ != NULL);
+
+#else
+
+ try{
+
+ v_ = new T[N];
+
+ } //try
+
+ catch ( bad_alloc exception ) {
+
+ cerr << "Memory allocation failed in file vec.h, method initialize()."
+
+ << "Exiting with value 1.\n";
+
+ exit(1);
+
+ } //catch
+
+#endif
+
+ vm1_ = v_-1;
+
+ n_ = N;
+
+ }
+
+
+
+ void copy(const T* v)
+
+ {
+
+ Subscript N = n_;
+
+ Subscript i;
+
+
+
+#ifdef TNT_UNROLL_LOOPS
+
+ Subscript Nmod4 = N & 3;
+
+ Subscript N4 = N - Nmod4;
+
+
+
+ for (i=0; i<N4; i+=4)
+
+ {
+
+ v_[i] = v[i];
+
+ v_[i+1] = v[i+1];
+
+ v_[i+2] = v[i+2];
+
+ v_[i+3] = v[i+3];
+
+ }
+
+
+
+ for (i=N4; i< N; i++)
+
+ v_[i] = v[i];
+
+#else
+
+
+
+ for (i=0; i< N; i++)
+
+ v_[i] = v[i];
+
+#endif
+
+ }
+
+
+
+ void set(const T& val)
+
+ {
+
+ Subscript N = n_;
+
+ Subscript i;
+
+
+
+#ifdef TNT_UNROLL_LOOPS
+
+ Subscript Nmod4 = N & 3;
+
+ Subscript N4 = N - Nmod4;
+
+
+
+ for (i=0; i<N4; i+=4)
+
+ {
+
+ v_[i] = val;
+
+ v_[i+1] = val;
+
+ v_[i+2] = val;
+
+ v_[i+3] = val;
+
+ }
+
+
+
+ for (i=N4; i< N; i++)
+
+ v_[i] = val;
+
+#else
+
+
+
+ for (i=0; i< N; i++)
+
+ v_[i] = val;
+
+
+
+#endif
+
+ }
+
+
+
+
+
+
+
+ void destroy()
+
+ {
+
+ /* do nothing, if no memory has been previously allocated */
+
+ if (v_ == NULL) return ;
+
+
+
+ /* if we are here, then matrix was previously allocated */
+
+ delete [] (v_);
+
+
+
+ v_ = NULL;
+
+ vm1_ = NULL;
+
+ }
+
+
+
+
+
+ public:
+
+
+
+ // access
+
+
+
+ iterator begin() { return v_;}
+
+ iterator end() { return v_ + n_; }
+
+ const iterator begin() const { return v_;}
+
+ const iterator end() const { return v_ + n_; }
+
+
+
+ // destructor
+
+
+
+ ~Vector()
+
+ {
+
+ destroy();
+
+ }
+
+
+
+ // constructors
+
+
+
+ Vector() : v_(0), vm1_(0), n_(0) {};
+
+
+
+ Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0)
+
+ {
+
+ initialize(A.n_);
+
+ copy(A.v_);
+
+ }
+
+
+
+ Vector(Subscript N, const T& value = T(0)) : v_(0), vm1_(0), n_(0)
+
+ {
+
+ initialize(N);
+
+ set(value);
+
+ }
+
+
+
+ Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0)
+
+ {
+
+ initialize(N);
+
+ copy(v);
+
+ }
+
+
+
+ Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0)
+
+ {
+
+ initialize(N);
+
+ istringstream ins(s);
+
+
+
+ Subscript i;
+
+
+
+ for (i=0; i<N; i++)
+
+ ins >> v_[i];
+
+ }
+
+
+
+
+
+ // methods
+
+ //
+
+ Vector<T>& newsize(Subscript N)
+
+ {
+
+ if (n_ == N) return *this;
+
+
+
+ destroy();
+
+ initialize(N);
+
+
+
+ return *this;
+
+ }
+
+
+
+
+
+ // assignments
+
+ //
+
+ Vector<T>& operator=(const Vector<T> &A)
+
+ {
+
+ if (v_ == A.v_)
+
+ return *this;
+
+
+
+ if (n_ == A.n_) // no need to re-alloc
+
+ copy(A.v_);
+
+
+
+ else
+
+ {
+
+ destroy();
+
+ initialize(A.n_);
+
+ copy(A.v_);
+
+ }
+
+
+
+ return *this;
+
+ }
+
+
+
+ Vector<T>& operator=(const T& scalar)
+
+ {
+
+ set(scalar);
+
+ return *this;
+
+ }
+
+
+
+ Subscript dim() const
+
+ {
+
+ return n_;
+
+ }
+
+
+
+ Subscript size() const
+
+ {
+
+ return n_;
+
+ }
+
+
+
+ /*Equivalence Operators -cmsief*/
+
+
+
+ friend bool isnear(const Vector<T>&A, const Vector<T>& B, const T tolerance) {
+
+ bool s=true;
+
+ if(A.n_!=B.n_ || tolerance<0) return false;
+
+
+
+ for(Subscript i=0;s&&i<A.n_;i++){
+
+ if (fabs(A.v_[i]-B.v_[i]) > tolerance ) s=false;
+
+ }
+
+ return s;
+
+ }/*end isnear*/
+
+
+
+ friend bool operator==(const Vector<T>&A, const Vector<T>& B) {
+
+ bool s=true;
+
+ if(A.n_!=B.n_) return false;
+
+
+
+ for(Subscript i=0;s&&i<A.n_;i++){
+
+ if (A.v_[i]!=B.v_[i]) s=false;
+
+ }
+
+ return s;
+
+ }
+
+
+
+ friend bool operator!=(const Vector<T>&A, const Vector<T>& B) {
+
+ return !(A==B);
+
+ }
+
+
+
+ /*end cmsief*/
+
+
+
+
+
+ inline reference operator()(Subscript i)
+
+ {
+
+#ifdef TNT_BOUNDS_CHECK
+
+ assert(1<=i);
+
+ assert(i <= n_) ;
+
+#endif
+
+ return vm1_[i];
+
+ }
+
+
+
+ inline const_reference operator() (Subscript i) const
+
+ {
+
+#ifdef TNT_BOUNDS_CHECK
+
+ assert(1<=i);
+
+ assert(i <= n_) ;
+
+#endif
+
+ return vm1_[i];
+
+ }
+
+
+
+ inline reference operator[](Subscript i)
+
+ {
+
+#ifdef TNT_BOUNDS_CHECK
+
+ assert(0<=i);
+
+ assert(i < n_) ;
+
+#endif
+
+ return v_[i];
+
+ }
+
+
+
+ inline const_reference operator[](Subscript i) const
+
+ {
+
+#ifdef TNT_BOUNDS_CHECK
+
+ assert(0<=i);
+
+ assert(i < n_) ;
+
+#endif
+
+ return v_[i];
+
+ }
+
+
+
+
+
+ // friend std::istream & operator>>(std::istream &s, Vector<T> &A);
+
+#ifdef OLD_LIBC
+
+ friend istream & operator>>(istream &s, Vector<T> &A);
+
+#else
+
+ // template<class T>
+
+ friend istream & operator>><>(istream &s, Vector<T> &A);
+
+#endif
+
+
+
+// *******************[ basic norm algorithms ]***********************cmsief
+
+
+
+ double l2norm() {
+
+
+
+ /*This algorithm is drawn from the f2c'd CLAPACK from netlib.
+
+ translated by f2c (version 19940927).
+
+ Modified on 14-October-1993 to inline the call to DLASSQ.
+
+ Sven Hammarling, Nag Ltd.
+
+ Modified on 25-May-1999 to act in a C++ manner and work with R. Pozo's Vector.
+
+ Chris Siefert, College of William and Mary.
+
+ This returns the l2norm of the vector.
+
+ */
+
+
+
+ double d__1, scale, absxi, ssq;
+
+
+
+ if (n_ < 1) return (0.0);
+
+ else if (n_ == 1) return(fabs((double)v_[0]));
+
+ else {
+
+ scale = 0.0;
+
+ ssq = 1.0;
+
+
+
+ for (Subscript ix = 0; ix < n_; ix++ ) {
+
+ if (v_[ix] != 0.0) {
+
+ absxi = (d__1 = (double) v_[ix], fabs(d__1));
+
+ if (scale < absxi) {
+
+ /* Computing 2nd power */
+
+ d__1 = scale / absxi;
+
+ ssq = ssq * (d__1 * d__1) + 1.0;
+
+ scale = absxi;
+
+ }/*end if*/
+
+ else {
+
+ /* Computing 2nd power */
+
+ d__1 = absxi / scale;
+
+ ssq += d__1 * d__1;
+
+ }/*end else*/
+
+ }/*end if*/
+
+ /* L10: */
+
+ }/*end for*/
+
+ return(scale * sqrt(ssq));
+
+ }/*end else*/
+
+ }/*end l2norm - cmsief*/
+
+
+
+
+
+ double l2norm_sqr() {
+
+
+
+ /*This algorithm is drawn from the f2c'd CLAPACK from netlib.
+
+ translated by f2c (version 19940927).
+
+ Modified on 14-October-1993 to inline the call to DLASSQ.
+
+ Sven Hammarling, Nag Ltd.
+
+ Modified on 25-May-1999 to act in a C++ manner and work with R. Pozo's Vector.
+
+ Chris Siefert, College of William and Mary.
+
+ This returns the square of the l2norm.
+
+ */
+
+
+
+ double d__1, scale, absxi, ssq;
+
+
+
+ if (n_ < 1) return (0.0);
+
+ else if (n_ == 1) return(fabs((double)v_[0]*v_[0]));
+
+ else {
+
+ scale = 0.0;
+
+ ssq = 1.0;
+
+
+
+ for (Subscript ix = 0; ix < n_; ix++ ) {
+
+ if (v_[ix] != 0.0) {
+
+ absxi = (d__1 = (double) v_[ix], fabs(d__1));
+
+ if (scale < absxi) {
+
+ /* Computing 2nd power */
+
+ d__1 = scale / absxi;
+
+ ssq = ssq * (d__1 * d__1) + 1.0;
+
+ scale = absxi;
+
+ }/*end if*/
+
+ else {
+
+ /* Computing 2nd power */
+
+ d__1 = absxi / scale;
+
+ ssq += d__1 * d__1;
+
+ }/*end else*/
+
+ }/*end if*/
+
+ /* L10: */
+
+ }/*end for*/
+
+ return(scale * scale * ssq);
+
+ }/*end else*/
+
+ }/*end l2norm_sqr - cmsief*/
+
+
+
+};/*end class*/
+
+
+
+
+
+/* *************************** I/O ********************************/
+
+//std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
+
+template <class T>
+
+ostream& operator<<(ostream &s, const Vector<T> &A)
+
+{
+
+ Subscript N=A.dim();
+
+
+
+ s << N << endl;
+
+
+
+ for (Subscript i=0; i<N; i++)
+
+ s <<setprecision(D_PRECISION) << A[i] << " " << endl;
+
+ s << endl;
+
+
+
+ return s;
+
+}
+
+//std::istream & operator>>(std::istream &s, Vector<T> &A)
+
+template <class T>
+
+istream & operator>>(istream &s, Vector<T> &A)
+
+{
+
+
+
+ Subscript N;
+
+
+
+ s >> N;
+
+
+
+ if ( !(N == A.n_) )
+
+ {
+
+ A.destroy();
+
+ A.initialize(N);
+
+ }
+
+
+
+
+
+ for (Subscript i=0; i<N; i++)
+
+ s >> A[i];
+
+
+
+
+
+ return s;
+
+}
+
+
+
+
+
+// *******************[ basic matrix algorithms ]***************************
+
+
+
+/****cmsief****/
+
+template <class T>
+
+Vector<T> scalmult(const Vector<T> &A, const T &B)
+
+{
+
+ Subscript N = A.dim();
+
+ Vector<T> tmp(N);
+
+ Subscript i;
+
+ for (i=0; i<N; i++)
+
+ tmp[i] = A[i] *B;
+
+ return tmp;
+
+}
+
+
+
+
+
+template <class T>
+
+Vector<T> operator*(const Vector<T> &A, const T &B)
+
+{
+
+ return scalmult(A,B);
+
+}
+
+
+
+template <class T>
+
+Vector<T> operator*(const T &B, const Vector<T> &A)
+
+{
+
+ return scalmult(A,B);
+
+}
+
+
+
+/****end cmsief*****/
+
+
+
+template <class T>
+
+Vector<T> operator+(const Vector<T> &A,
+
+ const Vector<T> &B)
+
+{
+
+ Subscript N = A.dim();
+
+
+
+ assert(N==B.dim());
+
+
+
+ Vector<T> tmp(N);
+
+ Subscript i;
+
+
+
+ for (i=0; i<N; i++)
+
+ tmp[i] = A[i] + B[i];
+
+
+
+ return tmp;
+
+}
+
+
+
+template <class T>
+
+Vector<T> operator-(const Vector<T> &A,
+
+ const Vector<T> &B)
+
+{
+
+ Subscript N = A.dim();
+
+
+
+ assert(N==B.dim());
+
+
+
+ Vector<T> tmp(N);
+
+ Subscript i;
+
+
+
+ for (i=0; i<N; i++)
+
+ tmp[i] = A[i] - B[i];
+
+
+
+ return tmp;
+
+}
+
+
+
+//Vector<T> operator*(const Vector<T> &A, const Vector<T> &B)
+
+template <class T>
+
+Vector<T> compmult(const Vector<T> &A, const Vector<T> &B)
+
+{
+
+ Subscript N = A.dim();
+
+
+
+ assert(N==B.dim());
+
+
+
+ Vector<T> tmp(N);
+
+ Subscript i;
+
+
+
+ for (i=0; i<N; i++)
+
+ tmp[i] = A[i] * B[i];
+
+
+
+ return tmp;
+
+}
+
+
+
+//T dot_prod(const Vector<T> &A, const Vector<T> &B)
+
+template <class T>
+
+T operator* (const Vector<T> &A, const Vector<T> &B)
+
+{
+
+ Subscript N = A.dim();
+
+ assert(N == B.dim());
+
+
+
+ Subscript i;
+
+ T sum = 0;
+
+
+
+ for (i=0; i<N; i++)
+
+ sum += A[i] * B[i];
+
+
+
+ return sum;
+
+}
+
+
+
+//} /* namespace TNT */
+
+
+
+#endif
+
+// VEC_H
+
+
+
+
+
diff --git a/headers/wiimote.h b/headers/wiimote.h
new file mode 100644
index 0000000..3ddde3a
--- /dev/null
+++ b/headers/wiimote.h
@@ -0,0 +1,65 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef WIIMOTE_H
+#define WIIMOTE_H
+#include <vector>
+#include "maths.h"
+
+using namespace std;
+
+#ifdef CWIID
+#include "/usr/local/include/cwiid.h"
+
+typedef cwiid_wiimote_t Wiimote;
+
+#elif WIIUSE
+#include <wiiuse.h>
+typedef wiimote_t Wiimote;
+
+
+#else
+typedef int Wiimote;
+
+
+
+#endif //CWIID
+
+
+int wii ();
+
+Wiimote *init_wiimote (Wiimote *wiimote);
+bool is_wiimote_closed (Wiimote *wiimote);
+
+vect get_Acc_data (Wiimote *wiimote);
+
+
+void switch_led (Wiimote *wiimote, unsigned int n, bool on);
+void set_rumble (Wiimote *wiimote, bool b);
+void get_IR_data (Wiimote *wiimote, vector <int> &x, vector <int> &y);
+
+bool is_A_pressed (Wiimote *wiimote);
+bool is_B_pressed (Wiimote *wiimote);
+bool is_1_pressed (Wiimote *wiimote);
+bool is_2_pressed (Wiimote *wiimote);
+
+void poll (Wiimote *wiimote);
+
+
+
+#endif //WIIMOTE_H
diff --git a/icons/B.png b/icons/B.png
new file mode 100644
index 0000000..a4ea9fb
Binary files /dev/null and b/icons/B.png differ
diff --git a/icons/CVS/Entries b/icons/CVS/Entries
new file mode 100644
index 0000000..33c85b3
--- /dev/null
+++ b/icons/CVS/Entries
@@ -0,0 +1,47 @@
+/B.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/V.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/X.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/arrow.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/benzene.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/builder.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/builder_1bond.png/1.6/Fri Oct 3 22:58:14 2008/-kb/
+/builder_2bond.png/1.6/Fri Oct 3 22:58:14 2008/-kb/
+/builder_3bond.png/1.6/Fri Oct 3 22:58:14 2008/-kb/
+/builder_C.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/builder_N.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/builder_O.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/builder_S.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/builder_Xbond.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/builder_del.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/builder_pencil.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/builder_smile.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/deselect.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/favicon.ico/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/furan.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/furanO.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/haptic.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/invert_selection.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/minimise.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/pencil_C.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/pencil_N.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/pencil_O.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/pencil_S.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/periodic_table.png/1.4/Fri Oct 3 22:58:14 2008/-kb/
+/pointer_rubber.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/pointer_select_square.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/redo.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring3.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring4.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring5.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring6.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring7.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/ring8.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/select.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/select_C.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/select_H.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/select_all.png/1.6/Fri Oct 3 22:58:14 2008/-kb/
+/select_square.png/1.5/Fri Oct 3 22:58:14 2008/-kb/
+/undo.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/zeden.icns/1.3/Fri Oct 3 22:58:14 2008/-kb/
+/zeden_ico.png/1.3/Fri Oct 3 22:58:14 2008/-kb/
+D
diff --git a/icons/CVS/Entries.Extra b/icons/CVS/Entries.Extra
new file mode 100644
index 0000000..5cc99f5
--- /dev/null
+++ b/icons/CVS/Entries.Extra
@@ -0,0 +1,46 @@
+/B.png////*///
+/V.png////*///
+/X.png////*///
+/arrow.png////*///
+/benzene.png////*///
+/builder.png////*///
+/builder_1bond.png////*///
+/builder_2bond.png////*///
+/builder_3bond.png////*///
+/builder_C.png////*///
+/builder_N.png////*///
+/builder_O.png////*///
+/builder_S.png////*///
+/builder_Xbond.png////*///
+/builder_del.png////*///
+/builder_pencil.png////*///
+/builder_smile.png////*///
+/deselect.png////*///
+/favicon.ico////*///
+/furan.png////*///
+/furanO.png////*///
+/haptic.png////*///
+/invert_selection.png////*///
+/minimise.png////*///
+/pencil_C.png////*///
+/pencil_N.png////*///
+/pencil_O.png////*///
+/pencil_S.png////*///
+/periodic_table.png////*///
+/pointer_rubber.png////*///
+/pointer_select_square.png////*///
+/redo.png////*///
+/ring3.png////*///
+/ring4.png////*///
+/ring5.png////*///
+/ring6.png////*///
+/ring7.png////*///
+/ring8.png////*///
+/select.png////*///
+/select_C.png////*///
+/select_H.png////*///
+/select_all.png////*///
+/select_square.png////*///
+/undo.png////*///
+/zeden.icns////*///
+/zeden_ico.png////*///
diff --git a/icons/CVS/Entries.Extra.Old b/icons/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/icons/CVS/Entries.Old b/icons/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/icons/CVS/Repository b/icons/CVS/Repository
new file mode 100644
index 0000000..6c3fce0
--- /dev/null
+++ b/icons/CVS/Repository
@@ -0,0 +1 @@
+zodiac/icons
diff --git a/icons/CVS/Root b/icons/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/icons/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/icons/V.png b/icons/V.png
new file mode 100644
index 0000000..5360f67
Binary files /dev/null and b/icons/V.png differ
diff --git a/icons/X.png b/icons/X.png
new file mode 100644
index 0000000..ed8d629
Binary files /dev/null and b/icons/X.png differ
diff --git a/icons/arrow.png b/icons/arrow.png
new file mode 100644
index 0000000..4c8708f
Binary files /dev/null and b/icons/arrow.png differ
diff --git a/icons/benzene.png b/icons/benzene.png
new file mode 100644
index 0000000..179c1da
Binary files /dev/null and b/icons/benzene.png differ
diff --git a/icons/builder.png b/icons/builder.png
new file mode 100644
index 0000000..6fd880d
Binary files /dev/null and b/icons/builder.png differ
diff --git a/icons/builder_1bond.png b/icons/builder_1bond.png
new file mode 100644
index 0000000..aad160e
Binary files /dev/null and b/icons/builder_1bond.png differ
diff --git a/icons/builder_2bond.png b/icons/builder_2bond.png
new file mode 100644
index 0000000..c68862f
Binary files /dev/null and b/icons/builder_2bond.png differ
diff --git a/icons/builder_3bond.png b/icons/builder_3bond.png
new file mode 100644
index 0000000..1dd8810
Binary files /dev/null and b/icons/builder_3bond.png differ
diff --git a/icons/builder_C.png b/icons/builder_C.png
new file mode 100644
index 0000000..52f55e7
Binary files /dev/null and b/icons/builder_C.png differ
diff --git a/icons/builder_N.png b/icons/builder_N.png
new file mode 100644
index 0000000..e8df943
Binary files /dev/null and b/icons/builder_N.png differ
diff --git a/icons/builder_O.png b/icons/builder_O.png
new file mode 100644
index 0000000..f87c346
Binary files /dev/null and b/icons/builder_O.png differ
diff --git a/icons/builder_S.png b/icons/builder_S.png
new file mode 100644
index 0000000..9a69ec7
Binary files /dev/null and b/icons/builder_S.png differ
diff --git a/icons/builder_Xbond.png b/icons/builder_Xbond.png
new file mode 100644
index 0000000..1d974f0
Binary files /dev/null and b/icons/builder_Xbond.png differ
diff --git a/icons/builder_del.png b/icons/builder_del.png
new file mode 100644
index 0000000..2071d58
Binary files /dev/null and b/icons/builder_del.png differ
diff --git a/icons/builder_pencil.png b/icons/builder_pencil.png
new file mode 100644
index 0000000..2ac6683
Binary files /dev/null and b/icons/builder_pencil.png differ
diff --git a/icons/builder_smile.png b/icons/builder_smile.png
new file mode 100644
index 0000000..a317c0e
Binary files /dev/null and b/icons/builder_smile.png differ
diff --git a/icons/deselect.png b/icons/deselect.png
new file mode 100644
index 0000000..05e2fc1
Binary files /dev/null and b/icons/deselect.png differ
diff --git a/icons/favicon.ico b/icons/favicon.ico
new file mode 100644
index 0000000..04954f0
Binary files /dev/null and b/icons/favicon.ico differ
diff --git a/icons/furan.png b/icons/furan.png
new file mode 100644
index 0000000..c090202
Binary files /dev/null and b/icons/furan.png differ
diff --git a/icons/furanO.png b/icons/furanO.png
new file mode 100644
index 0000000..772bc3e
Binary files /dev/null and b/icons/furanO.png differ
diff --git a/icons/haptic.png b/icons/haptic.png
new file mode 100644
index 0000000..7f72f30
Binary files /dev/null and b/icons/haptic.png differ
diff --git a/icons/invert_selection.png b/icons/invert_selection.png
new file mode 100644
index 0000000..b4a0a2f
Binary files /dev/null and b/icons/invert_selection.png differ
diff --git a/icons/minimise.png b/icons/minimise.png
new file mode 100644
index 0000000..98ea82d
Binary files /dev/null and b/icons/minimise.png differ
diff --git a/icons/pencil_C.png b/icons/pencil_C.png
new file mode 100644
index 0000000..3438b86
Binary files /dev/null and b/icons/pencil_C.png differ
diff --git a/icons/pencil_N.png b/icons/pencil_N.png
new file mode 100644
index 0000000..335b73a
Binary files /dev/null and b/icons/pencil_N.png differ
diff --git a/icons/pencil_O.png b/icons/pencil_O.png
new file mode 100644
index 0000000..ab75fd0
Binary files /dev/null and b/icons/pencil_O.png differ
diff --git a/icons/pencil_S.png b/icons/pencil_S.png
new file mode 100644
index 0000000..7d7baa2
Binary files /dev/null and b/icons/pencil_S.png differ
diff --git a/icons/periodic_table.png b/icons/periodic_table.png
new file mode 100644
index 0000000..91c0378
Binary files /dev/null and b/icons/periodic_table.png differ
diff --git a/icons/pointer_rubber.png b/icons/pointer_rubber.png
new file mode 100644
index 0000000..f5eec5f
Binary files /dev/null and b/icons/pointer_rubber.png differ
diff --git a/icons/pointer_select_square.png b/icons/pointer_select_square.png
new file mode 100644
index 0000000..1fd150c
Binary files /dev/null and b/icons/pointer_select_square.png differ
diff --git a/icons/redo.png b/icons/redo.png
new file mode 100644
index 0000000..7eaafa4
Binary files /dev/null and b/icons/redo.png differ
diff --git a/icons/ring3.png b/icons/ring3.png
new file mode 100644
index 0000000..c96b7ef
Binary files /dev/null and b/icons/ring3.png differ
diff --git a/icons/ring4.png b/icons/ring4.png
new file mode 100644
index 0000000..18121d5
Binary files /dev/null and b/icons/ring4.png differ
diff --git a/icons/ring5.png b/icons/ring5.png
new file mode 100644
index 0000000..d120df2
Binary files /dev/null and b/icons/ring5.png differ
diff --git a/icons/ring6.png b/icons/ring6.png
new file mode 100644
index 0000000..cf7d729
Binary files /dev/null and b/icons/ring6.png differ
diff --git a/icons/ring7.png b/icons/ring7.png
new file mode 100644
index 0000000..a2b183e
Binary files /dev/null and b/icons/ring7.png differ
diff --git a/icons/ring8.png b/icons/ring8.png
new file mode 100644
index 0000000..20577a6
Binary files /dev/null and b/icons/ring8.png differ
diff --git a/icons/select.png b/icons/select.png
new file mode 100644
index 0000000..9c2f1b3
Binary files /dev/null and b/icons/select.png differ
diff --git a/icons/select_C.png b/icons/select_C.png
new file mode 100644
index 0000000..6c0122f
Binary files /dev/null and b/icons/select_C.png differ
diff --git a/icons/select_H.png b/icons/select_H.png
new file mode 100644
index 0000000..ed9cc31
Binary files /dev/null and b/icons/select_H.png differ
diff --git a/icons/select_all.png b/icons/select_all.png
new file mode 100644
index 0000000..9a97919
Binary files /dev/null and b/icons/select_all.png differ
diff --git a/icons/select_square.png b/icons/select_square.png
new file mode 100644
index 0000000..23b2714
Binary files /dev/null and b/icons/select_square.png differ
diff --git a/icons/undo.png b/icons/undo.png
new file mode 100644
index 0000000..932d010
Binary files /dev/null and b/icons/undo.png differ
diff --git a/icons/zeden.icns b/icons/zeden.icns
new file mode 100644
index 0000000..9d39b4d
Binary files /dev/null and b/icons/zeden.icns differ
diff --git a/icons/zeden_ico.png b/icons/zeden_ico.png
new file mode 100644
index 0000000..7f72f30
Binary files /dev/null and b/icons/zeden_ico.png differ
diff --git a/iodevice.cc b/iodevice.cc
new file mode 100644
index 0000000..dfe18b1
--- /dev/null
+++ b/iodevice.cc
@@ -0,0 +1,12 @@
+#include "iodevice.h"
+/*
+IODevice::IODevice () : _input (false), _output (false) {
+}
+
+
+
+VideoDevice::VideoDevice () : IODevice () {
+ _input = false;
+ _output = true;
+}
+*/
diff --git a/maths.cc b/maths.cc
new file mode 100644
index 0000000..e250d03
--- /dev/null
+++ b/maths.cc
@@ -0,0 +1,155 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "maths.h"
+#include <iostream>
+
+
+
+#define DELTA 0.000000001f
+
+using namespace std;
+quaternion::quaternion (double w, double x, double y, double z) {
+ _x = x;
+ _y = y;
+ _z = z;
+ _w = w;
+}
+
+
+quaternion::quaternion () {
+ _x = 1.;
+ _y = 0.;
+ _z = 0.;
+ _w = 0.;
+}
+
+
+vect::vect (double xi, double yi, double zi) : OpenBabel::vector3 (xi, yi, zi) {
+
+}
+
+vect::vect (const OpenBabel::vector3& v) {vect (v.x(), v.y(), v.z ()); }
+
+void vect::null () {
+ Set (0.0, 0.0, 0.0);
+}
+
+void vect::normalise () {
+ double mod = module ();
+ if (mod < DELTA) {
+ // cerr << "normalising null vector"<<endl;
+ null ();
+ }
+ else {
+ x () /= mod;
+ y () /= mod;
+ z () /= mod;
+ }
+}
+
+void vect::multiply (double f) {
+ // if (f < DELTA) {
+ // cerr << "multiplying vector by 0"<<endl;
+ // null ();
+ // }
+ // else {
+ Set (x () * f, y () * f, z () * f);
+ // }
+}
+
+void vect::scale_to (double f) {
+ normalise ();
+ multiply (f);
+}
+
+
+
+double square_distance (vect coord1, vect coord2) {
+ return (coord1.x()-coord2.x())*(coord1.x()-coord2.x()) + (coord1.y()-coord2.y())*(coord1.y()-coord2.y()) + (coord1.z()-coord2.z())*(coord1.z()-coord2.z());
+}
+
+
+
+vect circumcenter (vect v1, vect v2, vect v3) {
+ vect A = v1;
+ vect B = v2;
+ vect C = v3;
+ double a2 = square_distance(B, C);
+ double b2 = square_distance(C, A);
+ double c2 = square_distance(A, B);
+ double cx = C.x() * c2*(a2+b2-c2);
+ double cy = C.y() * c2*(a2+b2-c2);
+ double cz = C.z() * c2*(a2+b2-c2);
+ double ax = A.x() * a2*(c2+b2-a2);
+ double ay = A.y() * a2*(c2+b2-a2);
+ double az = A.z() * a2*(c2+b2-a2);
+ double bx = B.x() * b2*(a2+c2-b2);
+ double by = B.y() * b2*(a2+c2-b2);
+ double bz = B.z() * b2*(a2+c2-b2);
+
+
+ double den = 2 * (a2*b2 + a2*c2 + b2*c2)-(a2*a2 + b2*b2 + c2*c2);
+ if (den == 0.f) den = 0.0001f;
+ vect out = vect ((ax+bx+cx)/den, (ay+by+cy)/den, (az+bz+cz)/den);
+ return out;
+}
+
+void interpolate (vect v1, vect v2, vect v3, vect& i1, vect &i2) {
+ vect d1 = subtract (v1, v2);
+ vect d2 = subtract (v3, v2);
+ d1.normalise ();
+ d2.normalise ();
+ if (dot_product(d1, d2) < -0.999) {
+ i1 = mean (v1, v2);
+ i2 = mean (v2, v3);
+ }
+ else {
+ vect c = circumcenter (v1, v2, v3);
+ vect m1 = mean (v1, v2);
+ vect m2 = mean (v2, v3);
+ vect r1 = subtract (m1, c);
+ vect r2 = subtract (m2, c);
+ r1.normalise();
+ r2.normalise();
+ float r = dist (c, v1);
+
+ r1.multiply(r);
+ r2.multiply(r);
+ i1 = sum (c, r1);
+ i2 = sum (c, r2);
+ }
+}
+
+double dist (vect v1, vect v2) {
+ vect v = subtract (v1, v2);
+ return v.module ();
+}
+
+
+vect cross_product (vect v1, vect v2) {
+ vect vv ;
+
+ vv.x() = v1.y()*v2.z() - v1.z()*v2.y() ;
+ vv.y() = - v1.x()*v2.z() + v1.z()*v2.x() ;
+ vv.z() = v1.x()*v2.y() - v1.y()*v2.x() ;
+
+ return ( vv ) ;
+
+}
+
diff --git a/menu.cc b/menu.cc
new file mode 100644
index 0000000..02f99cf
--- /dev/null
+++ b/menu.cc
@@ -0,0 +1,7372 @@
+
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "menu.h"
+#include "ddwin.h"
+
+#define WIREFRAME 0
+#define STICK 1
+#define CPK 2
+#define BALLANDSTICK 3
+#define BALLANDLINE 4
+
+#define NO_ATOMS 0
+#define SPHERES 1
+#define CPK_SPHERES 2
+#define SCALED_CPK_SPHERES 3
+
+#define NO_BONDS 0
+#define LINES 1
+#define STICKS 2
+
+#define BACKBONE_LINE 0
+#define BACKBONE_STICK 1
+
+
+#define AROMATIC_RINGS 0
+#define KEKULE 1
+#define AROMATIC_BONDS 2
+
+#define ELEMENT 0
+#define CHARGE 1
+#define SCORE 2
+#define COLOR 3
+
+#define FLOAT 32
+
+
+
+
+ZNWidget::ZNWidget (QWidget *parent) : QWidget (parent) {
+ QVBoxLayout *layout = new QVBoxLayout;
+ setLayout (layout);
+ layout -> setAlignment (Qt::AlignTop);
+}
+
+
+
+
+ZNAdvancedWidget::ZNAdvancedWidget (const char *advance, bool show) : ZNWidget () {
+
+ _private = new ZNWidget ();
+ _public = new ZNWidget ();
+ _private ->hide();
+
+
+ layout () -> addWidget (_public);
+ layout () -> setAlignment (Qt::AlignTop);
+
+ basic_layout () ->setContentsMargins (0, 0, 0, 0);
+ basic_layout () -> setAlignment (Qt::AlignTop);
+
+
+ if (show == true) {
+ _group_box = new MyGroupBox (layout (), advance, true, false);
+ _group_box -> layout () -> addWidget (_private);
+ _private ->layout () -> setAlignment (Qt::AlignTop);
+ advanced_layout () ->setContentsMargins (0, 0, 0, 0);
+
+ connect (_group_box, SIGNAL (clicked (bool)), this, SLOT (hide_advanced_slot () ) );
+ }
+}
+
+void ZNAdvancedWidget::hide_advanced_slot () {
+ if (_group_box ->isChecked () == true) {
+ _private ->show();
+ }
+ else {
+ _private ->hide();
+ }
+
+}
+
+
+
+ZNMenu::ZNMenu (QWidget *parent, Data *dat, bool tabs, bool advanced) : QMainWindow (parent) {
+ if (advanced) _main_widget = new ZNAdvancedWidget ();
+ else _main_widget = new ZNWidget ();
+ setWindowTitle ("Zodiac");
+ _about_action = new QAction (tr ("&About"), this);
+
+ _about_action ->setShortcut (tr ("Control+A"));
+ connect (_about_action, SIGNAL (triggered ()), this, SLOT (_show_about ()));
+
+
+ _data = dat;
+
+ _tabs = new QTabWidget ();
+
+ if (tabs) setCentralWidget (_tabs);
+ else setCentralWidget (_main_widget);
+
+// _tabs ->addTab (_main_tab, "Main");
+// ZNAdvancedWidget *_test_tab = new ZNAdvancedWidget ();
+// _tabs ->addTab (_test_tab, "Test");
+
+}
+
+
+
+void ZNMenu::add_help () {
+ QMenu *about = new QMenu(tr("&Help"), this );
+ Q_CHECK_PTR( about );
+ about -> addAction (_about_action);
+ menuBar () ->addMenu (about);
+}
+
+
+
+bool ZNMenu::check_for_a_set_target () {
+ return _data ->ddwin ->current_target;
+}
+
+
+void ZNMenu::_load_bot_lf (string& buffer, const char *reference, MyLineFile *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ target ->linedit ->setText(q.c_str ());
+ }
+ }
+}
+
+
+void ZNMenu::_load_bot_fel (string& buffer, const char *reference, MyFloatEditLine *target, const char *sep) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+// s.append (sep);s.append (q);
+ s.append (" ");s.append (q);
+ target ->spinbox ->setValue(QString::fromStdString (q).toDouble());
+ }
+ }
+}
+
+
+void ZNMenu::_load_bot_iel (string& buffer, const char *reference, MyIntegerEditLine *target, const char *sep) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ target ->spinbox ->setValue(QString::fromStdString (q).toInt());
+ }
+ }
+}
+
+
+void ZNMenu::_load_bot_chb (string& buffer, const char *reference, MyCheckBox *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ if (q == "0") target ->setCheckState (Qt::Unchecked);
+ if (q == "1") target ->setCheckState (Qt::Checked);
+ }
+ }
+}
+
+
+void ZNMenu::_load_bot_box (string& buffer, const char *reference, MyGroupBox *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ if (q == "0") target ->setChecked (false);
+ if (q == "1") target ->setChecked (true);
+ }
+ }
+}
+
+
+void ZNMenu::_load_bot_cb (string& buffer, const char *reference, MyComboBox *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+// le combo box non funzionano!?!?!?!?!?!?!?
+ }
+ }
+}
+
+void ZNMenu::_load_bot_le (string& buffer, const char *reference, MyLineEdit *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ target ->linedit ->setText(q.c_str ());
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// CONFORMATIONAL SEARCHES
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ ConformersMenu::ConformersMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, false, false) {
+ setWindowTitle ("Conformational Search");
+ add_help ();
+
+ _type_hcb = new MyHideComboBox (main_widget () ->layout (), "Search type");
+ _stochastic_widget = new ZNWidget ();
+ _systematic_widget = new ZNWidget ();
+ main_widget ()->layout () -> addWidget (_stochastic_widget);
+ main_widget ()->layout () -> addWidget (_systematic_widget);
+
+
+ _type_hcb ->insertItem (_stochastic_widget, 0, "Stochastic", "Stochastic");
+ _type_hcb ->insertItem (_systematic_widget, 1, "Systematic", "Systematic");
+
+ //stochastic search
+ _results = 20;
+ _results_iel = new MyIntegerEditLine (_stochastic_widget ->layout (), "Number of results:", _results, 0);
+
+
+ _timlim = 60;
+ _timlim_iel = new MyIntegerEditLine (_stochastic_widget ->layout (), "Time limit (seconds):", _timlim, 0);
+
+
+
+
+
+ QPushButton *_ok_btn = new QPushButton("Start");
+ main_widget ()->layout () -> addWidget (_ok_btn);
+ connect (_ok_btn, SIGNAL( clicked() ), this, SLOT( start_thread () ) );
+ }
+
+void ConformersMenu::start_thread () {
+ if (_type_hcb ->currentData ().toString ().toStdString () == "Stochastic") {
+ ZNMolecule *mol = _data -> ddwin ->target_molecule;
+ Database *database = new Database;
+ _data ->ddwin ->add_database(database);
+ StochasticConformationThread *thread = new StochasticConformationThread (0, mol, database, _data ->ddwin) ;
+ thread ->set_results_number (_results);
+ thread ->set_time_limit (_timlim);
+ _data ->ddwin ->run_thread (thread);
+// thread ->start ();
+ }
+ else if (_type_hcb ->currentData ().toString ().toStdString () == "Systematic") {
+ ZNMolecule *mol = _data -> ddwin ->target_molecule;
+ Database *database = new Database;
+ _data ->ddwin ->add_database(database);
+ SystematicConformationThread *thread = new SystematicConformationThread (0, mol, database, _data ->ddwin) ;
+ _data ->ddwin ->run_thread (thread);
+// thread ->start ();
+ }
+}
+
+
+
+DockingMenu::DockingMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true, true) {
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (main_tab, "Input");
+ add_menu ();
+ add_help ();
+ _binding_site_box = new MyGroupBox (main_tab ->layout (), "Binding site options");
+ _site_x_el = new MyFloatEditLine (_binding_site_box ->layout (), "Binding site center X:", _x, -1000, 1000);
+ _site_y_el = new MyFloatEditLine (_binding_site_box ->layout (), "Binding site center Y:", _y, -1000, 1000);
+ _site_z_el = new MyFloatEditLine (_binding_site_box ->layout (), "Binding site center Z:", _z, -1000, 1000);
+ _site_r_el = new MyFloatEditLine (_binding_site_box ->layout (), "Binding site radius:", _r, -1000, 1000);
+ _start_docking_bt = new MyPushButton (main_tab ->layout (), "Start Docking");
+ connect (_start_docking_bt ->fbutton, SIGNAL( clicked() ), SLOT( start_docking_slot() ) );
+}
+
+void DockingMenu::start_docking_slot () {
+ Database *database = new Database;
+ ZNMolecule *mol = _data ->ddwin ->target_molecule;
+ _data ->ddwin ->add_database(database);
+ DockingThread *thread = new DockingThread (0, mol, database, _data ->ddwin) ;
+ thread ->set_bindingsite_radius (_r);
+ thread ->set_bindingsite_center (vect (_x, _y, _z));
+ thread ->set_results_number (10);
+ thread ->set_time_limit (60);
+ _data ->ddwin ->run_thread (thread);
+ // thread ->start ();
+
+}
+
+
+bool DockingMenu::display_requirements_met () {
+ bool b = check_for_a_set_target ();
+ if (b) {
+ ZNMolecule *mol = _data ->ddwin ->target_molecule;
+ vect c = get_center (mol);
+ _site_x_el ->set_value (c.x ());
+ _site_y_el ->set_value (c.y ());
+ _site_z_el ->set_value (c.z ());
+ }
+ return b;
+};
+
+ThreadWidget::ThreadWidget (QWidget *parent) : ZNWidget (parent) {
+ _name = new QLabel ("");
+ layout () -> addWidget (_name);
+ _progress_bar = new QProgressBar ();
+ layout () ->addWidget (_progress_bar);
+ _action = new QLabel ("");
+ layout () -> addWidget (_action);
+
+}
+
+ThreadMenu::ThreadMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, false, false) {
+int MAX_THREADS = 10;
+ for (unsigned int i = 0; i < MAX_THREADS; i++) {
+ ThreadWidget *widget = new ThreadWidget ();
+ widgets.push_back (widget);
+ _main_widget ->layout () -> addWidget (widget);
+ widget ->hide ();
+ }
+}
+
+void ThreadMenu::clear (int n) {
+ if (n < widgets.size ()) {
+ for (unsigned int i = n; i < widgets.size (); i++) {
+ widgets [i] -> hide ();
+ }
+ }
+}
+
+void ThreadMenu::display_thread (int n, Thread *thread) {
+ if (n < widgets.size ()) {
+ widgets[n] ->show ();
+ widgets[n] -> _name ->setText (tr(thread ->_name.c_str ()));
+ widgets[n] -> _progress_bar ->setRange (thread ->_min_step, thread ->_max_step);
+ widgets[n] -> _progress_bar ->setValue (thread ->_current_step);
+ widgets[n] -> _action ->setText (tr(thread ->_doing.c_str ())); }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Preferences menu
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PrefMenu::PrefMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true, true) {
+ setWindowTitle ("Preferences");
+
+
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);
+ ZNAdvancedWidget *rendering_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (main_tab, "External programs");
+ _tabs ->addTab (rendering_tab, "rendering");
+
+
+// _input_box = new MyGroupBox (main_tab ->basic_layout (), "Input options");
+// _input_box -> setMaximumHeight( 250 );
+
+ label = new QLabel( "Set the absolute path for each executable.", this );
+ main_tab ->basic_layout () -> addWidget (label);
+
+ plants_file = new MyLineFile (main_tab ->basic_layout (), "PLANTS", 4);
+
+// gamess_file = new MyLineFile (main_tab ->basic_layout (), "GAMESS", 1);
+
+
+ _save_preferences_b = new MyPushButton (main_tab ->basic_layout (), "Apply and Save Zodiac.ini", 0, 200);
+ connect (_save_preferences_b ->fbutton, SIGNAL( clicked() ), SLOT( _save_preferences () ) );
+
+// backgorund color
+// ZNAdvancedWidget *background_tab = new ZNAdvancedWidget ("", false);
+// _tabs ->addTab (background_tab, "Background color");
+ MyFloatEditLine *qsel = new MyFloatEditLine (rendering_tab ->basic_layout (),"Quality scale", *_data ->quality_scale, 0, 1000);
+
+
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Sphere radius", *_data ->sphere_radius);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "VdW scale", *_data ->vdw_scale);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Stick radius", *_data ->stick_radius);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Double Bond inter Distance", *_data ->double_bond_separation);
+// new MyFloatEditLine (rendering_tab ->basic_layout (), "Aromatic Bond inter Distance", _data ->ddwin ->gl->aromatic_bond_inter_distance);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Double bond scale", *_data ->double_bond_stick_scale);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Line Width", *_data ->line_width);
+
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Helix tube a", *_data ->backbone_tube_helix_a);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Helix tube b", *_data ->backbone_tube_helix_b);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Helix tube c", *_data ->backbone_tube_helix_c);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Sheet tube a", *_data ->backbone_tube_sheet_a);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Sheet tube b", *_data ->backbone_tube_sheet_b);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Sheet tube c", *_data ->backbone_tube_sheet_c);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Random tube a", *_data ->backbone_tube_random_a);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Random tube b", *_data ->backbone_tube_random_b);
+ new MyFloatEditLine (rendering_tab ->basic_layout (), "Random tube c", *_data ->backbone_tube_random_c);
+
+
+ //rendering_tab ->basic_layout ()->addWidget (qsel);
+
+}
+
+
+void PrefMenu::_save_preferences () {
+ cerr<< "Save Zodiac.ini"<<endl;
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// PLANTS menu FE
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+PLANTSMenu::PLANTSMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true, true) {
+ setWindowTitle ("PLANTS 1.1 input");
+
+ QString s = "Zodiac.ini";
+
+ if (!s.isNull()) {
+ ifstream ifs (s.toStdString ().c_str ());
+ string buffer;
+
+ while (getline(ifs, buffer)) {
+
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == "PLANTS") {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+
+ plants_exe = q.c_str ();
+ if (plants_exe != "") runPlants = true;
+ }
+ }
+ }
+ }
+
+// Main tab
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (main_tab, "Input");
+
+ _input_box = new MyGroupBox (main_tab ->basic_layout (), "Input options");
+ _input_box -> setMaximumHeight( 250 );
+
+// _input_tc = new MyTwoColumn (_input_box ->layout () );
+
+
+ load_protein_file = new MyLineFile (_input_box ->layout (), "Load protein file", 1);
+ connect(load_protein_file->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_protein () ));
+
+ load_ligand_file = new MyLineFile (_input_box ->layout (), "Load ligand file", 1);
+ connect(load_ligand_file->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_ligand () ));
+
+ input_file = new MyListView (_input_box ->layout (), 74, 0, false);
+input_file ->hide();
+
+ load_ligand_list_file = new MyLineFile (_input_box ->layout (), "Load ligand list file", 3);
+ connect(load_ligand_list_file->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_ligand_list () ));
+
+ input_file_list = new MyListView (_input_box ->layout (), 74, 0, false);
+input_file_list ->hide();
+
+ _binding_site_box = new MyGroupBox (_input_box ->layout (), "Binding site options");
+
+ _binding_site_from_ligand_b = new MyPushButton (_binding_site_box ->layout (), "Add binding site from ligand");
+ connect (_binding_site_from_ligand_b ->fbutton, SIGNAL( clicked() ), SLOT( set_binding_site() ) );
+
+ _binding_site_tc = new MyTwoColumn (_binding_site_box ->layout () );
+
+ _zero_value = 0;
+ _min_radius = 10;
+ _site_x_el = new MyFloatEditLine (_binding_site_tc ->left_layout (), "Binding site center X:", _zero_value, -1000, 1000);
+ _site_y_el = new MyFloatEditLine (_binding_site_tc ->right_layout (), "Binding site center Y:", _zero_value, -1000, 1000);
+ _site_z_el = new MyFloatEditLine (_binding_site_tc ->left_layout (), "Binding site center Z:", _zero_value, -1000, 1000);
+ _site_radius_el = new MyFloatEditLine (_binding_site_tc ->right_layout (), "Binding site radius:", _min_radius, 0, 100);
+
+// output tab
+ ZNAdvancedWidget *output_tab = new ZNAdvancedWidget ();
+ _tabs ->addTab (output_tab, "Output");
+
+ _output_box = new MyGroupBox (output_tab ->basic_layout (), "Output options");
+
+ _output_dir = new MyLineEdit (_output_box ->layout (), "Output dir");
+//_output_dir ->linedit ->setPalette(QColor(255,0,0));
+
+ _output_tc = new My3Column (output_tab ->advanced_layout () );
+
+ _write_protein_conformations_value = false;
+ _write_protein_conformations_chb = new MyCheckBox (_output_tc ->left_layout (), _write_protein_conformations_value, "Write protein conformations");
+
+ _write_protein_bindingsite_value = false;
+ _write_protein_bindingsite_chb = new MyCheckBox (_output_tc ->center_layout (), _write_protein_bindingsite_value, "Write protein binding site");
+
+ _write_protein_splitted_value = false;
+ _write_protein_splitted_chb = new MyCheckBox (_output_tc ->right_layout (), _write_protein_splitted_value, "Write protein splitted");
+
+ _write_rescored_structures_value = false;
+ _write_rescored_structures_chb = new MyCheckBox (_output_tc ->left_layout (), _write_rescored_structures_value, "Write rescored structures");
+
+ _write_multi_mol2_value = true;
+ _write_multi_mol2_chb = new MyCheckBox (_output_tc ->center_layout (), _write_multi_mol2_value, "Write multi mol2");
+
+ _write_ranking_links_value = false;
+ _write_ranking_links_chb = new MyCheckBox (_output_tc ->left_layout (), _write_ranking_links_value, "Write ranking links");
+
+ _write_ranking_multi_mol2_value = false;
+ _write_ranking_multi_mol2_chb = new MyCheckBox (_output_tc ->right_layout (), _write_ranking_multi_mol2_value, "Write ranking multi mol2");
+
+ _write_per_atom_scores_value = false;
+ _write_per_atom_scores_chb = new MyCheckBox (_output_tc ->center_layout (), _write_per_atom_scores_value, "Write score per atoms");
+
+ _write_merged_ligand_value = false;
+ _write_merged_ligand_chb = new MyCheckBox (_output_tc ->left_layout (), _write_merged_ligand_value, "Write merged ligand");
+
+ _write_merged_protein_value = false;
+ _write_merged_protein_chb = new MyCheckBox (_output_tc ->right_layout (), _write_merged_protein_value, "Write merged protein");
+
+ _write_merged_water_value = false;
+ _write_merged_water_chb = new MyCheckBox (_output_tc ->center_layout (), _write_merged_water_value, "Write merged water");
+
+ _keep_original_mol2_description_value = true;
+ _keep_original_mol2_description_chb = new MyCheckBox (_output_tc ->right_layout (), _keep_original_mol2_description_value, "Keep original mol2 description");
+
+ _merge_multi_conf_output_box = new MyGroupBox (output_tab ->advanced_layout (), "Merge multiconformer output", true, false);
+
+ _merge_multi_conf_output_tc = new MyTwoColumn (_merge_multi_conf_output_box ->layout ());
+
+ _merge_multi_conf_character_value = "_";
+ _merge_multi_conf_character = new MyLineEdit (_merge_multi_conf_output_tc ->left_layout (), "Character used for merging:");
+// _merge_multi_conf_character ->linedit -> setMaximumWidth( 50 );
+ _merge_multi_conf_character ->linedit -> setText ("_");
+
+
+ _merge_multi_conf_after_characters_value = 1;
+ _merge_multi_conf_after_characters_el = new MyIntegerEditLine (_merge_multi_conf_output_tc ->right_layout (), "Xxx:", _merge_multi_conf_after_characters_value, 1, 1000);
+
+
+// Algorithm tab
+ ZNAdvancedWidget *_algorithm_tab = new ZNAdvancedWidget ("Show scoring function options");
+ _tabs ->addTab (_algorithm_tab, "Algorithm");
+
+ _search_box = new MyGroupBox (_algorithm_tab ->basic_layout (), "Search algorithm");
+
+ _search_tc = new My3Column (_search_box ->layout () );
+
+ _search_speed_cb = new MyComboBox (_search_tc ->left_layout (), "Search speed setting:");
+ _search_speed_cb ->combo_box () ->insertItem (0, "normal (x1)", "speed1");
+ _search_speed_cb ->combo_box () ->insertItem (1, "fast (x2)", "speed2");
+ _search_speed_cb ->combo_box () ->insertItem (2, "very fast (x4)", "speed4");
+
+ _rescore_mode_cb = new MyComboBox (_search_tc ->right_layout (), "Rescore mode:");
+ _rescore_mode_cb ->combo_box () ->insertItem (0, "simplex", "simplex");
+ _rescore_mode_cb ->combo_box () ->insertItem (1, "none", "no_simplex");
+
+ _aco_ants_value = 20;
+ _aco_ants_el = new MyIntegerEditLine (_search_tc ->center_layout (), "Number of ants:", _aco_ants_value, 1);
+
+ _search_adv_box = new MyGroupBox (_search_box ->layout (), "Advanced options", true, false);
+ connect (_search_adv_box, SIGNAL (clicked (bool)), this, SLOT (hide_group_box () ) );
+
+ _search_adv_tc = new MyTwoColumn (_search_adv_box ->layout () );
+ _search_adv_tc ->hide();
+
+ _aco_evap_value = 1;
+ _aco_evap_el = new MyFloatEditLine (_search_adv_tc ->left_layout (), "Evaporation factor:", _aco_evap_value, 0, 1);
+
+ _aco_sigma_value = 1;
+ _aco_sigma_el = new MyFloatEditLine (_search_adv_tc ->left_layout (), "Sigma scaling factor:", _aco_sigma_value, 0);
+
+ _flip_amide_bonds_value = false;
+ _flip_amide_bonds_chb = new MyCheckBox (_search_adv_tc ->left_layout (), _flip_amide_bonds_value, "Flip amide bonds");
+
+ _flip_planar_n_value = false;
+ _flip_planar_n_chb = new MyCheckBox (_search_adv_tc ->right_layout (), _flip_planar_n_value, "Flip planar N");
+
+ _force_flipped_bonds_planarity_value = false;
+ _force_flipped_bonds_planarity_chb = new MyCheckBox (_search_adv_tc ->right_layout (), _force_flipped_bonds_planarity_value, "Force flipped bond planary");
+
+ _force_planar_bond_rotation_value = true;
+ _force_planar_bond_rotation_chb = new MyCheckBox (_search_adv_tc ->right_layout (), _force_planar_bond_rotation_value, "Force planar bond rotation");
+
+
+ _cluster_docking_tc = new MyTwoColumn (_algorithm_tab ->basic_layout () );
+
+ _cluster_box = new MyGroupBox (_cluster_docking_tc ->left_layout (), "Cluster algorithm");
+
+ _cluster_rmsd_value = 2.0;
+ _cluster_rmsd_el = new MyFloatEditLine (_cluster_box ->layout (), "Cluster RMSD:", _cluster_rmsd_value, 0);
+
+ _cluster_structures_value = 10;
+ _cluster_structures_el = new MyIntegerEditLine (_cluster_box ->layout (), "Cluster structures:", _cluster_structures_value, 1);
+
+
+ _docking_box = new MyGroupBox (_cluster_docking_tc ->right_layout (), "Docking typology");
+
+ _rigid_ligand_value = false;
+ _rigid_ligand_chb = new MyCheckBox (_docking_box ->layout (), _rigid_ligand_value, "Rigid ligand docking");
+
+ _rigid_all_value = false;
+ _rigid_all_chb = new MyCheckBox (_docking_box ->layout (), _rigid_all_value, "Rigid protein and ligand docking");
+
+
+ _algorithm_type_cb = new MyComboBox (_algorithm_tab ->advanced_layout (), "Scoring function type:");
+ _algorithm_type_cb ->combo_box () ->insertItem (0, "chemplp", "chemplp");
+ _algorithm_type_cb ->combo_box () ->insertItem (1, "plp", "plp");
+ _algorithm_type_cb ->combo_box () ->insertItem (2, "plp95", "plp95");
+ connect (_algorithm_type_cb ->combo_box (), SIGNAL (currentIndexChanged ( int )), this, SLOT (plp_weight ( int )) );
+
+ _scoring_inter_box = new MyGroupBox (_algorithm_tab ->advanced_layout (), "Intermolecular scoring");
+ _score_inter_tc = new MyTwoColumn (_scoring_inter_box ->layout () );
+
+ _outside_binding_site_penalty_value = 50.0;
+ _outside_binding_site_penalty_el = new MyFloatEditLine (_score_inter_tc ->left_layout (), "Outside binding site penalty:", _outside_binding_site_penalty_value, 0, 100);
+
+ _enable_sulphur_acceptors_value = false;
+ _enable_sulphur_acceptors_chb = new MyCheckBox (_score_inter_tc ->right_layout (), _enable_sulphur_acceptors_value, "Enable sulphur acceptors");
+
+
+ _scoring_intra_box = new MyGroupBox (_algorithm_tab ->advanced_layout (), "Intramolecular scoring");
+ _score_intra_tc = new My3Column (_scoring_intra_box ->layout () );
+
+ _ligand_intra_score_cb = new MyComboBox (_score_intra_tc ->left_layout (), "Ligand scoring:");
+ _ligand_intra_score_cb ->combo_box () ->insertItem (0, "clash2", "clash2");
+ _ligand_intra_score_cb ->combo_box () ->insertItem (1, "clash", "clash");
+ _ligand_intra_score_cb ->combo_box () ->insertItem (2, "all atom Lennard-Jones", "lj");
+
+ _chemplp_clash_include_14_value = 0.25;
+ _chemplp_clash_include_14_el = new MyFloatEditLine (_score_intra_tc ->center_layout (), "Scoring 1-4 interaction:", _chemplp_clash_include_14_value, 0, 1);
+
+ _chemplp_clash_include_HH_value = false;
+ _chemplp_clash_include_HH_chb = new MyCheckBox (_score_intra_tc ->right_layout (), _chemplp_clash_include_HH_value, "Scoring H-H interaction");
+
+
+ _chemplp_weights_box = new MyGroupBox (_scoring_intra_box ->layout (), "Chemplp interaction weights");
+
+
+ _chemplp_weights_tc = new My3Column (_chemplp_weights_box ->layout () );
+
+ _chemplp_charged_hb_weight_value = 2.0;
+ _chemplp_charged_hb_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->left_layout (), "Charged HB:", _chemplp_charged_hb_weight_value, -100);
+
+ _chemplp_hbond_cho_weight_value = -3.0;
+ _chemplp_hbond_cho_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->center_layout (), "HB CHO:", _chemplp_hbond_cho_weight_value, -100);
+
+ _chemplp_hbond_weight_value = -3.0;
+ _chemplp_hbond_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->right_layout (), "Neutral HB:", _chemplp_hbond_weight_value, -100);
+
+ _chemplp_metal_weight_value = -3.0;
+ _chemplp_metal_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->left_layout (), "Metal:", _chemplp_metal_weight_value, -100);
+
+ _chemplp_charged_metal_weight_value = 2.0;
+ _chemplp_charged_metal_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->center_layout (), "Charged metal:", _chemplp_charged_metal_weight_value, -100);
+
+ _chemplp_plp_weight_value = 1.0;
+ _chemplp_plp_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->left_layout (), "PLP:", _chemplp_plp_weight_value, -100);
+
+ _chemplp_plp_steric_e_value = -0.4;
+ _chemplp_plp_steric_e_el = new MyFloatEditLine (_chemplp_weights_tc ->center_layout (), "PLP steric:", _chemplp_plp_steric_e_value, -100);
+
+ _chemplp_plp_burpolar_e_value = -0.1;
+ _chemplp_plp_burpolar_e_el = new MyFloatEditLine (_chemplp_weights_tc ->right_layout (), "Polar PLP:", _chemplp_plp_burpolar_e_value, -100);
+
+ _chemplp_plp_hbond_e_value = -1.0;
+ _chemplp_plp_hbond_e_el = new MyFloatEditLine (_chemplp_weights_tc ->left_layout (), "HB PLP:", _chemplp_plp_hbond_e_value, -100);
+
+ _chemplp_plp_metal_e_value = -1.0;
+ _chemplp_plp_metal_e_el = new MyFloatEditLine (_chemplp_weights_tc ->center_layout (), "Metal PLP:", _chemplp_plp_metal_e_value, -100);
+
+ _chemplp_plp_repulsive_weight_value = 1.0;
+ _chemplp_plp_repulsive_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->right_layout (), "Repulsive PLP:", _chemplp_plp_repulsive_weight_value, -100);
+
+ _chemplp_lipo_weight_value = 0.0;
+ _chemplp_lipo_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->left_layout (), "Lipophilic:", _chemplp_lipo_weight_value, -100);
+
+ _chemplp_tors_weight_value = 2.0;
+ _chemplp_tors_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->center_layout (), "Ligand torsional:", _chemplp_tors_weight_value, -100);
+
+ _chemplp_intercept_weight_value = -20.0;
+ _chemplp_intercept_weight_el = new MyFloatEditLine (_chemplp_weights_tc ->right_layout (), "Intercept:", _chemplp_intercept_weight_value, -100);
+
+ _chemplp_weak_cho_value = true;
+ _chemplp_weak_cho_chb = new MyCheckBox (_chemplp_weights_tc ->right_layout (), _chemplp_weak_cho_value, "Weak CHO");
+
+
+ _plp_weights_box = new MyGroupBox (_scoring_intra_box ->layout (), "Plp/plp95 interaction weights");
+ _plp_weights_box ->hide ();
+
+ _plp_weights_tc = new My3Column (_plp_weights_box ->layout () );
+
+ _plp_steric_e_value = -0.4;
+ _plp_steric_e_el = new MyFloatEditLine (_plp_weights_tc ->left_layout (), "Steric:", _plp_steric_e_value, -100);
+
+ _plp_burpolar_e_value = -0.05;
+ _plp_burpolar_e_el = new MyFloatEditLine (_plp_weights_tc ->left_layout (), "Polar:", _plp_burpolar_e_value, -100);
+
+ _plp_hbond_e_value = -2.0;
+ _plp_hbond_e_el = new MyFloatEditLine (_plp_weights_tc ->center_layout (), "HB:", _plp_hbond_e_value, -100);
+
+ _plp_metal_e_value = -4.0;
+ _plp_metal_e_el = new MyFloatEditLine (_plp_weights_tc ->center_layout (), "Metal:", _plp_metal_e_value, -100);
+
+ _plp_repulsive_weight_value = 0.5;
+ _plp_repulsive_weight_el = new MyFloatEditLine (_plp_weights_tc ->right_layout (), "Repulsive:", _plp_repulsive_weight_value, -100);
+
+ _plp_tors_weight_value = 1.0;
+ _plp_tors_weight_el = new MyFloatEditLine (_plp_weights_tc ->right_layout (), "Ligand torsional:", _plp_tors_weight_value, -100);
+
+
+// Costraints tab
+ ZNAdvancedWidget *_costraints_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (_costraints_tab, "Costraints");
+
+ _costraints_box = new MyGroupBox (_costraints_tab ->basic_layout (), "Costraints");
+// _costraints_box -> setMaximumHeight( 361 );
+
+ _costraints_tc = new MyTwoColumn (_costraints_box ->layout () );
+
+
+ _protein_hb_costraint_box = new MyGroupBox (_costraints_tc ->right_layout (), "Protein HB costraints");
+
+ _protein_hb_costraint_tc = new MyTwoColumn (_protein_hb_costraint_box ->layout ());
+
+ _protein_hb_costraint_cb = new MyComboBox (_protein_hb_costraint_tc ->left_layout (), "Atom number");
+ _protein_hb_costraint_fel = new MyFloatEditLine (_protein_hb_costraint_tc ->right_layout (), "Weight", _zero_value, 0);
+ _protein_hb_costraint_b = new MyPushButton (_protein_hb_costraint_box ->layout (), "Set constraint");
+ connect (_protein_hb_costraint_b ->fbutton, SIGNAL( clicked() ), SLOT( set_protein_hb_constraint_slot() ) );
+
+
+ _shape_costraint_box = new MyGroupBox (_costraints_tc ->right_layout (), "Shape constraints");
+
+ load_shape_file = new MyLineFile (_shape_costraint_box ->layout (), "Load shape file", 1);
+ connect(load_shape_file->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_shape () ));
+
+ _shape_costraint_tc = new MyTwoColumn (_shape_costraint_box ->layout ());
+
+ _shape_weight = new MyFloatEditLine (_shape_costraint_tc ->left_layout (), "Weight: ", _zero_value, -10, 0);
+
+ _shape_weight_b = new MyPushButton (_shape_costraint_tc ->right_layout (), "Set constraint");
+ connect (_shape_weight_b ->fbutton, SIGNAL( clicked() ), SLOT( set_shape_constraint_slot() ) );
+
+
+ _surface_distance_costraint_box = new MyGroupBox (_costraints_tc ->left_layout (), "Surface distance constraints");
+
+ _surface_distance_costraint_tc = new MyTwoColumn (_surface_distance_costraint_box ->layout ());
+
+ _from_surface_distance = new MyFloatEditLine (_surface_distance_costraint_tc ->left_layout (), "From: ", _zero_value, -10, 10);
+ _to_surface_distance = new MyFloatEditLine (_surface_distance_costraint_tc ->right_layout (), "To: ", _zero_value, -10, 10);
+
+ _ligand_surface_distance_cb = new MyComboBox (_surface_distance_costraint_tc ->left_layout (), "Ligand atom number");
+
+ _weight_surface_distance_fel = new MyFloatEditLine (_surface_distance_costraint_tc ->right_layout (), "Weight: ", _zero_value, -10, 0);
+
+ _surface_distance_b = new MyPushButton (_surface_distance_costraint_box ->layout (), "Set constraint");
+ connect (_surface_distance_b ->fbutton, SIGNAL( clicked() ), SLOT( set_surface_distance_slot() ) );
+
+
+ _ligand_intra_distance_costraint_box = new MyGroupBox (_costraints_tc ->left_layout (), "Ligand intra distance constraints");
+
+ _ligand_intra_distance_costraint_tc = new MyTwoColumn (_ligand_intra_distance_costraint_box ->layout ());
+
+ _from_ligand_intra_distance = new MyFloatEditLine (_ligand_intra_distance_costraint_tc ->left_layout (), "From: ", _zero_value, -10, 10);
+ _to_ligand_intra_distance = new MyFloatEditLine (_ligand_intra_distance_costraint_tc ->right_layout (), "To: ", _zero_value, -10, 10);
+
+ _number_a_ligand_intra_distance_cb = new MyComboBox (_ligand_intra_distance_costraint_tc ->left_layout (), "Ligand atom number");
+
+ _number_b_ligand_intra_distance_cb = new MyComboBox (_ligand_intra_distance_costraint_tc ->right_layout (), "Ligand atom number");
+
+ _weight_ligand_intra_distance = new MyFloatEditLine (_ligand_intra_distance_costraint_tc ->left_layout (), "Weight: ", _zero_value, -10, 0);
+
+ _ligand_intra_distance_b = new MyPushButton (_ligand_intra_distance_costraint_tc ->right_layout (), "Set constraint");
+ connect (_ligand_intra_distance_b ->fbutton, SIGNAL( clicked() ), SLOT( set_ligand_intra_distance_slot () ) );
+
+
+ _protein_ligand_distance_costraint_box = new MyGroupBox (_costraints_tc ->left_layout (), "Protein ligand distance constraints");
+
+ _protein_ligand_distance_costraint_tc = new MyTwoColumn (_protein_ligand_distance_costraint_box ->layout ());
+
+ _from_protein_ligand_distance = new MyFloatEditLine (_protein_ligand_distance_costraint_tc ->left_layout (), "From: ", _zero_value, -10, 10);
+ _to_protein_ligand_distance = new MyFloatEditLine (_protein_ligand_distance_costraint_tc ->right_layout (), "To: ", _zero_value, -10, 10);
+
+ _number_a_protein_ligand_distance_cb = new MyComboBox (_protein_ligand_distance_costraint_tc ->left_layout (), "Protein atom number");
+
+ _number_b_protein_ligand_distance_cb = new MyComboBox (_protein_ligand_distance_costraint_tc ->right_layout (), "Ligand atom number");
+
+ _weight_protein_ligand_distance = new MyFloatEditLine (_protein_ligand_distance_costraint_tc ->left_layout (), "Weight: ", _zero_value, -10, 10);
+
+ _protein_ligand_distance_b = new MyPushButton (_protein_ligand_distance_costraint_tc ->right_layout (), "Set constraint");
+ connect (_protein_ligand_distance_b ->fbutton, SIGNAL( clicked() ), SLOT( set_protein_ligand_distance_slot () ) );
+
+ costraints_file_list = new MyListView (_costraints_tc ->right_layout (), 138 );
+
+
+// Flexibility tab
+ ZNAdvancedWidget *_flexibility_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (_flexibility_tab, "Flexibility");
+
+ _flexibility_box = new MyGroupBox (_flexibility_tab ->basic_layout (), "Flexibility");
+// _flexibility_box -> setMaximumHeight( 145 );
+
+ _flexibility_tc = new MyTwoColumn (_flexibility_box ->layout () );
+ _flexibility_tc ->_left -> setMinimumWidth ( 350 );
+
+ _flexible_protein_side_chain_string = new MyListButton (_flexibility_tc ->left_layout (), "Add flexible side chain");
+ connect (_flexible_protein_side_chain_string->fbutton, SIGNAL( clicked() ), SLOT( add_fscs_slot() ) );
+
+ _fix_protein_bond = new MyListButton (_flexibility_tc ->left_layout (), "Add fixed protein bond");
+ connect (_fix_protein_bond->fbutton, SIGNAL( clicked() ), SLOT( add_fpb_slot() ) );
+
+ _flexible_protein_side_chain_number = new MyListButton (_flexibility_tc ->left_layout (), "Add flexible side chain");
+ connect (_flexible_protein_side_chain_number->fbutton, SIGNAL( clicked() ), SLOT( add_fscn_slot() ) );
+
+ _intra_protein_score_weight_value = 0.3;
+ _intra_protein_score_weight_el = new MyFloatEditLine (_flexibility_tc ->left_layout (), "Intra protein score weight:", _intra_protein_score_weight_value, 0, 1);
+
+
+ flexibility_file_list = new MyListView (_flexibility_tc ->right_layout (), 85 );
+
+
+// Water tab
+ ZNAdvancedWidget *_water_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (_water_tab, "Water");
+
+ _water_box = new MyGroupBox (_water_tab ->basic_layout (), "Water");
+
+ _water_site_b = new MyPushButton (_water_box ->layout (), "Add water molecule");
+ connect (_water_site_b ->fbutton, SIGNAL( clicked() ), SLOT( set_water_site() ) );
+
+ _water_site_tc = new MyTwoColumn (_water_box ->layout () );
+
+ _water_min_radius = 2;
+ _water_site_x_el = new MyFloatEditLine (_water_site_tc ->left_layout (), "Water X:", _zero_value, -1000, 1000);
+ _water_site_y_el = new MyFloatEditLine (_water_site_tc ->right_layout (), "Water Y:", _zero_value, -1000, 1000);
+ _water_site_z_el = new MyFloatEditLine (_water_site_tc ->left_layout (), "Water Z:", _zero_value, -1000, 1000);
+ _water_site_radius_el = new MyFloatEditLine (_water_site_tc ->right_layout (), "Radius:", _water_min_radius, 0, 10);
+
+
+ load_water_file = new MyLineFile (_water_box ->layout (), "Water reference", 1);
+// connect(load_water_file->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_water () ));
+
+
+ _water_weights_box = new MyGroupBox (_water_box ->layout (), "Water molecule weights", true, false);
+ connect (_water_weights_box, SIGNAL (clicked (bool)), this, SLOT (hide_group_box2 () ) );
+
+ _water_weights_tc = new MyTwoColumn (_water_weights_box ->layout () );
+ _water_weights_tc -> hide();
+
+ _no_water_ligand_hb_penalty_value = 0.0;
+ _no_water_ligand_hb_penalty_el = new MyFloatEditLine (_water_weights_tc ->left_layout (), "No HB penalty:", _no_water_ligand_hb_penalty_value, -100);
+
+ _water_enable_penalty_value = 8.0;
+ _water_enable_penalty_el = new MyFloatEditLine (_water_weights_tc ->right_layout (), "No water penalty:", _water_enable_penalty_value, -100);
+
+ _water_protein_hb_weight_value = 1.0;
+ _water_protein_hb_weight_el = new MyFloatEditLine (_water_weights_tc ->left_layout (), "Water-protein HB:", _water_protein_hb_weight_value, -100);
+
+ _water_ligand_hb_weight_value = 1.0;
+ _water_ligand_hb_weight_el = new MyFloatEditLine (_water_weights_tc ->right_layout (), "Water-ligand HB:", _water_ligand_hb_weight_value, -100);
+
+ _water_water_hb_weight_value = 1.0;
+ _water_water_hb_weight_el = new MyFloatEditLine (_water_weights_tc ->left_layout (), "Water-water HB:", _water_water_hb_weight_value, -100);
+
+
+//
+ add_menu ();
+ add_help ();
+}
+
+
+void PLANTSMenu::update_boxes (MyListView *parent, const char *mol_name, int type){
+// parent ->_lw ->insertItem(type, tr( mol_name ));
+ parent ->_lw ->addItem(tr( mol_name ));
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// not very good
+// By Tosh
+void PLANTSMenu::hide_group_box () {
+ if (_search_adv_box ->isChecked () == true) {
+ _search_adv_tc ->show();
+ }
+ else {
+ _search_adv_tc ->hide();
+ }
+}
+
+
+void PLANTSMenu::hide_group_box2 () {
+ if (_water_weights_box ->isChecked () == true) {
+ _water_weights_tc ->show();
+ }
+ else {
+ _water_weights_tc ->hide();
+ }
+}
+//
+//////////////////////////////////////////////////////////////////////////////////////
+
+
+void PLANTSMenu::load_protein () {
+ string p_name = load_protein_file->val ();
+
+ load_protein_file ->control_no -> hide();
+ load_protein_file ->control_yes -> hide();
+
+ if (p_name.find (".mol2")!=string::npos) {
+
+ ifstream ifs(p_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(p_name.c_str ());
+
+ OBMol *mol = new OBMol ();
+
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ OBMol *mol2 = new OBMol ();
+
+ if (conv.Read(mol2)) {
+ load_protein_file ->linedit ->clear ();
+ load_protein_file ->control_no ->show();
+ }
+ else {
+ load_protein_file ->control_yes ->show();
+ char chain;
+ int res_number = 0;
+ int atom = 0;
+ int bond = 0;
+ string res = "";
+ string residue_plus = "";
+ FOR_BONDS_OF_MOL(b, mol)
+ {
+ bond += b;
+ stringstream ss;
+ ss << bond;
+ string bond_number = ss.str();
+ _fix_protein_bond ->_combo_box ->addItem (bond_number.c_str(), bond_number.c_str());
+ }
+ FOR_ATOMS_OF_MOL(a, mol)
+ {
+ atom += a;
+ stringstream ss;
+ ss << atom;
+ string atom_number = ss.str();
+ _protein_hb_costraint_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ _number_a_protein_ligand_distance_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ }
+ FOR_RESIDUES_OF_MOL(r, mol)
+ {
+ res_number = r->GetNum();
+ res = r->GetName();
+ chain = r->GetChain();
+ QString residue = res.c_str();
+ stringstream ss;
+ ss << res_number;
+ string residue_number = ss.str();
+ _flexible_protein_side_chain_string ->_combo_box ->addItem (residue, residue);
+ _flexible_protein_side_chain_number ->_combo_box ->addItem (residue_number.c_str(), residue_number.c_str());
+ }
+
+ }
+ }
+ else {
+ load_protein_file ->control_no -> show();
+ delete mol;
+ }
+ }
+ else {
+// _err_mol ();
+ }
+}
+
+
+void PLANTSMenu::load_ligand () {
+ string l_name = load_ligand_file->val ();
+
+ load_ligand_file ->control_no -> hide();
+ load_ligand_file ->control_yes -> hide();
+
+ if (l_name.find (".mol2")!=string::npos) {
+
+ ifstream ifs(l_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(l_name.c_str ());
+
+ OBMol *mol = new OBMol ();
+
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ OBMol *mol2 = new OBMol ();
+
+ const char *title = "";
+
+ if (conv.Read(mol2)) {
+ load_ligand_file ->control_yes -> show();
+
+ title = mol->GetTitle();
+ update_boxes (input_file, title, 2);
+ }
+ else {
+ load_ligand_file ->control_yes -> show();
+ int atom = 0;
+ FOR_ATOMS_OF_MOL(a, mol)
+ {
+ atom += a;
+ stringstream ss;
+ ss << atom;
+ string atom_number = ss.str();
+ _ligand_surface_distance_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ _number_a_ligand_intra_distance_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ _number_b_ligand_intra_distance_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ _number_b_protein_ligand_distance_cb ->_combo_box ->addItem (atom_number.c_str(), atom_number.c_str());
+ }
+ title = mol->GetTitle();
+ update_boxes (input_file, title, 2);
+ }
+
+ }
+ else {
+ load_ligand_file ->control_no -> hide();
+ delete mol;
+ }
+ }
+ else {
+// _err_mol ();
+// load_protein_file ->linedit ->setBackgroundRole (QPalette::Highlight);
+ }
+}
+
+
+void PLANTSMenu::load_shape () {
+ string s_name = load_shape_file->val ();
+
+ if (s_name.find (".mol2")!=string::npos) {
+
+ ifstream ifs(s_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(s_name.c_str ());
+
+ OBMol *mol = new OBMol ();
+
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ OBMol *mol2 = new OBMol ();
+
+ if (conv.Read(mol2)) {
+ _err_multi ();
+ }
+ else {
+// const char *title_shape = "";
+ title_shape = mol->GetTitle();
+cerr << "i have read this file "<<title_shape<<endl;
+ }
+ }
+ else {
+ _err_mol ();
+ delete mol;
+ }
+ }
+ else {
+ _err_mol ();
+// load_shape_file ->linedit ->setBackgroundRole (QPalette::Highlight);
+ }
+}
+
+
+void PLANTSMenu::set_shape_constraint_slot() {
+ string mol = load_shape_file->val ();
+ stringstream ss3;
+ ss3 << _shape_weight ->spinbox -> value ();
+ string weight = ss3.str();
+ if (mol != ""){
+ string st = "shape_costraint "+mol+" "+weight;
+ update_boxes (costraints_file_list, st.c_str(), 2);
+ }
+}
+
+
+void PLANTSMenu::load_ligand_list (){
+ string ss = load_ligand_list_file->val ();
+// QString s = QFileDialog::getOpenFileName(this,
+// tr ("Open file"), "",tr("PLANTS config File (*.pcfg);;All files (*)"));
+
+ QString s(ss.c_str ());
+
+ if (!s.isNull()) {
+ ifstream ifs (s.toStdString ().c_str ());
+ string buffer;
+
+ input_file_list ->_lw ->clear();
+
+ while (getline(ifs, buffer)) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ update_boxes (input_file_list, token.c_str(), 3);
+ }
+ }
+}
+
+
+void PLANTSMenu::set_binding_site () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("Tripos Mol2 File (*.mol2)"));
+ string bs_name = s.toStdString ();
+
+ if (bs_name.find (".mol2")!=string::npos) {
+
+ ifstream ifs(bs_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(bs_name.c_str ());
+
+ OBMol *mol = new OBMol ();
+
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ OBMol *mol2 = new OBMol ();
+
+ if (conv.Read(mol2)) {
+ _err_multi ();
+ }
+ else {
+ coordinates = mol->Center(1);
+ site_x = coordinates.x ();
+ site_y = coordinates.y ();
+ site_z = coordinates.z ();
+
+ _site_x_el ->spinbox ->setValue (site_x);
+ _site_y_el ->spinbox ->setValue (site_y);
+ _site_z_el ->spinbox ->setValue (site_z);
+ }
+ }
+ else {
+ _err_mol ();
+ delete mol;
+ }
+ }
+ else {
+// _err_mol ();
+// load_protein_file ->linedit ->setBackgroundRole (QPalette::Highlight);
+ }
+}
+
+
+void PLANTSMenu::set_water_site () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("Tripos Mol2 File (*.mol2)"));
+ string w_name = s.toStdString ();
+
+ if (w_name.find (".mol2")!=string::npos) {
+
+ ifstream ifs(w_name.c_str ());
+ OBConversion conv(&ifs);
+ OBFormat* inFormat = conv.FormatFromExt(w_name.c_str ());
+
+ OBMol *mol = new OBMol ();
+
+ if(conv.SetInFormat(inFormat) && conv.Read(mol)) {
+ OBMol *mol2 = new OBMol ();
+
+ if (conv.Read(mol2)) {
+ _err_multi ();
+ }
+ else {
+ water_coordinates = mol->Center(1);
+ water_site_x = water_coordinates.x ();
+ water_site_y = water_coordinates.y ();
+ water_site_z = water_coordinates.z ();
+
+ _water_site_x_el ->spinbox ->setValue (water_site_x);
+ _water_site_y_el ->spinbox ->setValue (water_site_y);
+ _water_site_z_el ->spinbox ->setValue (water_site_z);
+ }
+ }
+ else {
+ _err_mol ();
+ delete mol;
+ }
+ }
+ else {
+// _err_mol ();
+// load_protein_file ->linedit ->setBackgroundRole (QPalette::Highlight);
+ }
+}
+
+
+void PLANTSMenu::add_fscs_slot() {
+ string res = _flexible_protein_side_chain_string->_combo_box->currentText ().toStdString ();
+ if (res != ""){
+ string st = "flexible_protein_side_chain_string "+res;
+ update_boxes (flexibility_file_list, st.c_str(), 1);
+ }
+}
+
+
+void PLANTSMenu::add_fscn_slot() {
+ string res_number = _flexible_protein_side_chain_number->_combo_box->currentText ().toStdString ();
+ if (res_number != ""){
+ string st = "flexible_protein_side_chain_number "+res_number;
+ update_boxes (flexibility_file_list, st.c_str(), 2);
+ }
+}
+
+void PLANTSMenu::add_fpb_slot() {
+ string bond = _fix_protein_bond->_combo_box->currentText ().toStdString ();
+ if (bond != ""){
+ string st = "fix_protein_bond "+bond;
+ update_boxes (flexibility_file_list, st.c_str(), 3);
+ }
+}
+
+
+void PLANTSMenu::set_protein_hb_constraint_slot() {
+ string atom = _protein_hb_costraint_cb ->_combo_box ->currentText ().toStdString ();
+ stringstream ss;
+ ss << _protein_hb_costraint_fel ->spinbox -> value ();
+ string weight = ss.str();
+ if (atom != ""){
+ string st = "chemplp_protein_hb_costraint "+atom+" "+weight;
+ update_boxes (costraints_file_list, st.c_str(), 1);
+ }
+}
+
+void PLANTSMenu::set_surface_distance_slot () {
+ string atom = _ligand_surface_distance_cb ->_combo_box ->currentText ().toStdString ();
+ stringstream ss;
+ ss << _from_surface_distance ->spinbox -> value ();
+ string from = ss.str();
+ stringstream ss2;
+ ss2 << _to_surface_distance ->spinbox -> value ();
+ string to = ss2.str();
+ stringstream ss3;
+ ss3 << _weight_surface_distance_fel ->spinbox -> value ();
+ string weight = ss3.str();
+ if (atom != ""){
+ string st = "surface_distance_costraint "+from+to+weight+"("+atom+")";
+ update_boxes (costraints_file_list, st.c_str(), 3);
+ }
+}
+
+void PLANTSMenu::set_ligand_intra_distance_slot () {
+ string atom_a = _number_a_ligand_intra_distance_cb ->_combo_box ->currentText ().toStdString ();
+ string atom_b = _number_b_ligand_intra_distance_cb ->_combo_box ->currentText ().toStdString ();
+ stringstream ss;
+ ss << _from_ligand_intra_distance ->spinbox -> value ();
+ string from = ss.str();
+ stringstream ss2;
+ ss2 << _to_ligand_intra_distance ->spinbox -> value ();
+ string to = ss2.str();
+ stringstream ss3;
+ ss3 << _weight_ligand_intra_distance ->spinbox -> value ();
+ string weight = ss3.str();
+ if (atom_a != ""){
+ string st = "ligand_intra_distance_costraint "+from+" "+to+" "+weight+" "+atom_a+" "+atom_b;
+ update_boxes (costraints_file_list, st.c_str(), 4);
+ }
+}
+
+
+void PLANTSMenu::set_protein_ligand_distance_slot () {
+ string atom_a = _number_a_protein_ligand_distance_cb ->_combo_box ->currentText ().toStdString ();
+ string atom_b = _number_b_protein_ligand_distance_cb ->_combo_box ->currentText ().toStdString ();
+ stringstream ss;
+ ss << _from_protein_ligand_distance ->spinbox -> value ();
+ string from = ss.str();
+ stringstream ss2;
+ ss2 << _to_protein_ligand_distance ->spinbox -> value ();
+ string to = ss2.str();
+ stringstream ss3;
+ ss3 << _weight_protein_ligand_distance ->spinbox -> value ();
+ string weight = ss3.str();
+ if (atom_a != "" & atom_b != ""){
+ string st = "protein_ligand_distance_costraint "+from+" "+to+" "+weight+" "+atom_a+" "+atom_b;
+ update_boxes (costraints_file_list, st.c_str(), 5);
+ }
+
+}
+
+void PLANTSMenu::plp_weight (int i) {
+ if (i == 0) {
+ _plp_weights_box ->hide ();
+ _chemplp_weights_box ->show ();
+ }
+ else {
+ _chemplp_weights_box ->hide ();
+ _plp_weights_box ->show ();
+ }
+}
+
+void PLANTSMenu::add_menu () {
+ QMenu *file = new QMenu(tr("&File"), this );
+ _load_action = new QAction (tr ("&Open"), this);
+ connect (_load_action, SIGNAL (triggered ()), this, SLOT (_load_slot ()));
+ file -> addAction (_load_action);
+
+ _save_action = new QAction (tr ("&Save"), this);
+ connect (_save_action, SIGNAL (triggered ()), this, SLOT (_save_slot ()));
+ file -> addAction (_save_action);
+
+ if (runPlants == true) {
+ _run_action = new QAction (tr ("Save and Run"), this);
+ connect (_run_action, SIGNAL (triggered ()), this, SLOT (_run_slot ()));
+ file -> addAction (_run_action);
+ }
+
+ addMenu (file);
+
+ QMenu *settings = new QMenu(tr("&Settings"), this );
+ _restore_action = new QAction (tr ("&Restore to default"), this);
+ connect (_restore_action, SIGNAL (triggered ()), this, SLOT (_restore_slot ()));
+ settings -> addAction (_restore_action);
+ addMenu (settings);
+
+}
+
+
+void PLANTSMenu::_err_mol () {
+ QMessageBox::about( _data ->ddwin, "PLANTS 1.1 config file front end" ,
+ QString(("ZODIAC. Version "+VERSION+ "\n\n"
+ "Could not read this file\n").c_str()) );
+}
+
+void PLANTSMenu::_err_multi () {
+ QMessageBox::about( _data ->ddwin, "PLANTS 1.1 config file front end" ,
+ QString(("ZODIAC. Version "+VERSION+ "\n\n"
+ "Could not use a multy mol2 file\n").c_str()) );
+}
+
+void PLANTSMenu::_show_about () {
+ QMessageBox::about( _data ->ddwin, "About PLANTS 1.1 config file front end" ,
+ QString(("ZODIAC. Version "+VERSION+ "\n"
+ "PLANTS 1.1 config file front end. Code by Alberto Massarotti. All rights reserved.\n"
+ "For bug reports, suggestions or any other feedback please visit our website at www.zeden.org\n\n").c_str()) );
+}
+
+
+void PLANTSMenu::_load_slot () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("PLANTS config File (*.pcfg);;All files (*)"));
+
+ if (!s.isNull()) {
+ ifstream ifs (s.toStdString ().c_str ());
+ string buffer;
+
+ _restore_slot ();
+
+ while (getline(ifs, buffer)) {
+// 1.1
+ _load_bot_cb (buffer, "search_speed", _search_speed_cb);
+ _load_bot_iel (buffer, "aco_ants", _aco_ants_el);
+ _load_bot_fel (buffer, "aco_evap", _aco_evap_el);
+ _load_bot_fel (buffer, "aco_sigma", _aco_sigma_el);
+ _load_bot_chb (buffer, "flip_amide_bonds", _flip_amide_bonds_chb);
+ _load_bot_chb (buffer, "flip_planar_n", _flip_planar_n_chb);
+ _load_bot_chb (buffer, "force_flipped_bonds_planarity", _force_flipped_bonds_planarity_chb);
+ _load_bot_chb (buffer, "force_planar_bond_rotation", _force_planar_bond_rotation_chb);
+ _load_bot_cb (buffer, "rescore_mode", _rescore_mode_cb);
+// 1.2
+ _load_bot_bindingsite (buffer, "bindingsite_center");
+ _load_bot_fel (buffer, "bindingsite_radius", _site_radius_el);
+// 1.3
+ _load_bot_fel (buffer, "cluster_rmsd", _cluster_rmsd_el);
+ _load_bot_iel (buffer, "cluster_structures", _cluster_structures_el);
+// 1.4
+ _load_bot_cb (buffer, "scoring_function", _algorithm_type_cb);
+ _load_bot_fel (buffer, "outside_binding_site_penalty", _outside_binding_site_penalty_el);
+ _load_bot_chb (buffer, "enable_sulphur_acceptors", _enable_sulphur_acceptors_chb);
+ _load_bot_cb (buffer, "ligand_intra_score", _ligand_intra_score_cb);
+ _load_bot_fel (buffer, "chemplp_clash_include_14", _chemplp_clash_include_14_el);
+ _load_bot_chb (buffer, "chemplp_clash_include_HH", _chemplp_clash_include_HH_chb);
+ _load_bot_fel (buffer, "plp_steric_e", _plp_steric_e_el);
+ _load_bot_fel (buffer, "plp_burpolar_e", _plp_burpolar_e_el);
+ _load_bot_fel (buffer, "plp_hbond_e", _plp_hbond_e_el);
+ _load_bot_fel (buffer, "plp_metal_e", _plp_metal_e_el);
+ _load_bot_fel (buffer, "plp_repulsive_weight", _plp_repulsive_weight_el);
+ _load_bot_fel (buffer, "plp_tors_weight", _plp_tors_weight_el);
+ _load_bot_chb (buffer, "chemplp_weak_cho", _chemplp_weak_cho_chb);
+ _load_bot_fel (buffer, "chemplp_charged_hb_weight", _chemplp_charged_hb_weight_el);
+ _load_bot_fel (buffer, "chemplp_charged_metal_weight", _chemplp_charged_metal_weight_el);
+ _load_bot_fel (buffer, "chemplp_hbond_weight", _chemplp_hbond_weight_el);
+ _load_bot_fel (buffer, "chemplp_hbond_cho_weight", _chemplp_hbond_cho_weight_el);
+ _load_bot_fel (buffer, "chemplp_metal_weight", _chemplp_metal_weight_el);
+ _load_bot_fel (buffer, "chemplp_plp_weight", _chemplp_plp_weight_el);
+ _load_bot_fel (buffer, "chemplp_plp_steric_e", _chemplp_plp_steric_e_el);
+ _load_bot_fel (buffer, "chemplp_plp_burpolar_e", _chemplp_plp_burpolar_e_el);
+ _load_bot_fel (buffer, "chemplp_plp_hbond_e", _chemplp_plp_hbond_e_el);
+ _load_bot_fel (buffer, "chemplp_plp_metal_e", _chemplp_plp_metal_e_el);
+ _load_bot_fel (buffer, "chemplp_plp_repulsive_weight", _chemplp_plp_repulsive_weight_el);
+ _load_bot_fel (buffer, "chemplp_tors_weight", _chemplp_tors_weight_el);
+ _load_bot_fel (buffer, "chemplp_lipo_weight", _chemplp_lipo_weight_el);
+ _load_bot_fel (buffer, "chemplp_intercept_weight", _chemplp_intercept_weight_el);
+// 1.5
+ _load_bot_lf (buffer, "protein_file", load_protein_file);
+ _load_bot_lf (buffer, "ligand_file", load_ligand_file);
+ _load_bot_lf (buffer, "ligand_list", load_ligand_list_file);
+// 1.6
+ _load_bot_le (buffer, "output_dir", _output_dir);
+ _load_bot_chb (buffer, "write_protein_conformations", _write_protein_conformations_chb);
+ _load_bot_chb (buffer, "write_protein_bindingsite", _write_protein_bindingsite_chb);
+ _load_bot_chb (buffer, "write_protein_splitted", _write_protein_splitted_chb);
+ _load_bot_chb (buffer, "write_rescored_structures", _write_rescored_structures_chb);
+ _load_bot_chb (buffer, "write_multi_mol2", _write_multi_mol2_chb);
+ _load_bot_chb (buffer, "write_ranking_links", _write_ranking_links_chb);
+ _load_bot_chb (buffer, "write_ranking_multi_mol2", _write_ranking_multi_mol2_chb);
+ _load_bot_chb (buffer, "write_per_atom_scores", _write_per_atom_scores_chb);
+ _load_bot_chb (buffer, "write_merged_ligand", _write_merged_ligand_chb);
+ _load_bot_chb (buffer, "write_merged_protein", _write_merged_protein_chb);
+ _load_bot_chb (buffer, "keep_original_mol2_description", _keep_original_mol2_description_chb);
+ _load_bot_box (buffer, "merge_multi_conf_output", _merge_multi_conf_output_box);
+ _load_bot_le (buffer, "merge_multi_conf_character", _merge_multi_conf_character);
+ _load_bot_iel (buffer, "merge_multi_conf_after_characters", _merge_multi_conf_after_characters_el);
+// 1.7
+ _load_bot_list_view (buffer, "chemplp_protein_hb_costraint", costraints_file_list);
+ _load_bot_list_view (buffer, "shape_costraint", costraints_file_list);
+ _load_bot_list_view (buffer, "surface_distance_costraint", costraints_file_list);
+ _load_bot_list_view (buffer, "ligand_intra_distance_costraint", costraints_file_list);
+ _load_bot_list_view (buffer, "protein_ligand_distance_costraint", costraints_file_list);
+// 1.8
+ _load_bot_list_view (buffer, "flexible_protein_side_chain_string", flexibility_file_list);
+ _load_bot_list_view (buffer, "flexible_protein_side_chain_number", flexibility_file_list);
+ _load_bot_fel (buffer, "intra_protein_score_weight", _intra_protein_score_weight_el);
+ _load_bot_list_view (buffer, "fix_protein_bond", flexibility_file_list);
+// 1.9
+ _load_bot_chb (buffer, "rigid_ligand", _rigid_ligand_chb);
+ _load_bot_chb (buffer, "rigid_all", _rigid_all_chb);
+// 1.10
+ _load_bot_water (buffer, "water_molecule");
+ _load_bot_lf (buffer, "water_molecule_definition", load_water_file);
+ _load_bot_fel (buffer, "water_protein_hb_weight", _water_protein_hb_weight_el);
+ _load_bot_fel (buffer, "water_ligand_hb_weight", _water_ligand_hb_weight_el);
+ _load_bot_fel (buffer, "water_water_hb_weight", _water_water_hb_weight_el);
+ _load_bot_fel (buffer, "no_water_ligand_hb_penalty", _no_water_ligand_hb_penalty_el);
+ _load_bot_fel (buffer, "water_enable_penalty", _water_enable_penalty_el);
+ }
+ }
+}
+
+
+void PLANTSMenu::_load_bot_bindingsite (string& buffer, const char *reference) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ int n = 1;
+ string x = "";
+ string y = "";
+ string z = "";
+ string r = "";
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ if (n == 1) x = q;
+ else if (n == 2) y = q;
+ else if (n == 3) z = q;
+ n ++;
+ }
+ _site_x_el ->spinbox ->setValue(QString::fromStdString (x).toDouble());
+ _site_y_el ->spinbox ->setValue(QString::fromStdString (y).toDouble());
+ _site_z_el ->spinbox ->setValue(QString::fromStdString (z).toDouble());
+ }
+}
+
+
+void PLANTSMenu::_load_bot_water (string& buffer, const char *reference) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ int n = 1;
+ string x = "";
+ string y = "";
+ string z = "";
+ string r = "";
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ if (n == 1) x = q;
+ if (n == 2) y = q;
+ if (n == 3) z = q;
+ if (n == 4) r = q;
+ n = n + 1;
+ }
+ _water_site_x_el ->spinbox ->setValue(QString::fromStdString (x).toDouble());
+ _water_site_y_el ->spinbox ->setValue(QString::fromStdString (y).toDouble());
+ _water_site_z_el ->spinbox ->setValue(QString::fromStdString (z).toDouble());
+ _water_site_radius_el ->spinbox ->setValue(QString::fromStdString (r).toDouble());
+ }
+}
+
+
+void PLANTSMenu::_load_bot_list_view (string& buffer, const char *reference, MyListView *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ if (token == reference) {
+ string s = token;
+ int n = 1;
+ string a = "";
+ string b = "";
+ string c = "";
+ string d = "";
+ string e = "";
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+// target ->linedit ->setText(q.c_str ());
+ if (n == 1) a = q;
+ if (n == 2) b = q;
+ if (n == 3) c = q;
+ if (n == 4) d = q;
+ if (n == 5) e = q;
+ n = n + 1;
+ }
+ string st = token+" "+a+" "+b+" "+c+" "+d+" "+e;
+ update_boxes (target, st.c_str(), 1);
+ }
+}
+
+
+void PLANTSMenu::_run_slot () {
+ _save_slot ();
+
+ cerr << plants_exe << " --mode screen "<< saved_file <<endl;
+
+}
+
+
+void PLANTSMenu::_save_slot () {
+ QFileDialog save_file(this);
+
+ QStringList filters;
+ filters << "PLANTS config file (*.pcfg)";
+
+ save_file.setNameFilters (filters);
+ save_file.setAcceptMode (QFileDialog::AcceptSave);
+ save_file.exec();
+
+ QString ext = save_file.selectedNameFilter();
+
+ QString filter = save_file.selectedNameFilter();
+ filter.truncate (filter.lastIndexOf (')'));
+ filter.remove (0, filter.indexOf ('*')+1);
+ QString s = save_file.selectedFile();
+ if (!s.contains ('.') ) s+= filter;
+
+
+ saved_file = s.toStdString ().c_str ();
+
+ if (!s.isNull()) {
+ ofstream ofs(s.toStdString ().c_str ());
+ ofs << "#################################################################################\n"
+ "#\n"
+ "# PLANTS 1.1 config file written by Zodiac "<<VERSION<<" (www.zeden.org)\n"
+ "#\n"
+ "##################################################################################\n"
+ "\n"
+ "# 1.1 search algorithm\n"
+ "search_speed ";
+ ofs << _search_speed_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "aco_ants ";
+ ofs << _aco_ants_el ->spinbox ->value()<<endl;
+ ofs << "aco_evap ";
+ ofs << _aco_evap_el ->spinbox ->value()<<endl;
+ ofs << "aco_sigma ";
+ ofs << _aco_sigma_el ->spinbox ->value()<<endl;
+ ofs << "flip_amide_bonds ";
+ ofs << _flip_amide_bonds_chb ->isChecked()<<endl;
+ ofs << "flip_planar_n ";
+ ofs << _flip_planar_n_chb ->isChecked()<<endl;
+ ofs << "force_flipped_bonds_planarity ";
+ ofs << _force_flipped_bonds_planarity_chb ->isChecked()<<endl;
+ ofs << "force_planar_bond_rotation ";
+ ofs << _force_planar_bond_rotation_chb ->isChecked()<<endl;
+ ofs << "rescore_mode ";
+ ofs << _rescore_mode_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "\n"
+ "# 1.2 binding site\n"
+ "bindingsite_center ";
+ ofs << _site_x_el ->spinbox ->value();
+ ofs << " ";
+ ofs << _site_y_el ->spinbox ->value();
+ ofs << " ";
+ ofs << _site_z_el ->spinbox ->value()<<endl;
+ ofs << "bindingsite_radius ";
+ ofs << _site_radius_el ->spinbox ->value()<<endl;
+ ofs << "\n"
+ "# 1.3 cluster algorithm\n"
+ "cluster_rmsd ";
+ ofs << _cluster_rmsd_el ->spinbox ->value()<<endl;
+ ofs << "cluster_structures ";
+ ofs << _cluster_structures_el ->spinbox ->value()<<endl;
+ ofs << "\n"
+ "# 1.4 scoring functions\n"
+ "scoring_function ";
+ ofs << _algorithm_type_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "outside_binding_site_penalty ";
+ ofs << _outside_binding_site_penalty_el ->spinbox ->value()<<endl;
+ ofs << "enable_sulphur_acceptors ";
+ ofs << _enable_sulphur_acceptors_chb ->isChecked()<<endl;
+ ofs << "ligand_intra_score ";
+ ofs << _ligand_intra_score_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "chemplp_clash_include_14 ";
+ ofs << _chemplp_clash_include_14_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_clash_include_HH ";
+ ofs << _chemplp_clash_include_HH_chb ->isChecked()<<endl;
+
+ if (_algorithm_type_cb ->currentData ().toString ().toStdString () == "chemplp") {
+ ofs << "chemplp_weak_cho ";
+ ofs << _chemplp_weak_cho_chb ->isChecked()<<endl;
+ ofs << "chemplp_charged_hb_weight ";
+ ofs << _chemplp_charged_hb_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_charged_metal_weight ";
+ ofs << _chemplp_charged_metal_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_hbond_weight ";
+ ofs << _chemplp_hbond_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_hbond_cho_weight ";
+ ofs << _chemplp_hbond_cho_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_metal_weight ";
+ ofs << _chemplp_metal_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_weight ";
+ ofs << _chemplp_plp_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_steric_e ";
+ ofs << _chemplp_plp_steric_e_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_burpolar_e ";
+ ofs << _chemplp_plp_burpolar_e_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_hbond_e ";
+ ofs << _chemplp_plp_hbond_e_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_metal_e ";
+ ofs << _chemplp_plp_metal_e_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_plp_repulsive_weight ";
+ ofs << _chemplp_plp_repulsive_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_tors_weight ";
+ ofs << _chemplp_tors_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_lipo_weight ";
+ ofs << _chemplp_lipo_weight_el ->spinbox ->value()<<endl;
+ ofs << "chemplp_intercept_weight ";
+ ofs << _chemplp_intercept_weight_el ->spinbox ->value()<<endl;
+ }
+ else {
+ ofs << "plp_steric_e ";
+ ofs << _plp_steric_e_el ->spinbox ->value()<<endl;
+ ofs << "plp_burpolar_e ";
+ ofs << _plp_burpolar_e_el ->spinbox ->value()<<endl;
+ ofs << "plp_hbond_e ";
+ ofs << _plp_hbond_e_el ->spinbox ->value()<<endl;
+ ofs << "plp_metal_e ";
+ ofs << _plp_metal_e_el ->spinbox ->value()<<endl;
+ ofs << "plp_repulsive_weight ";
+ ofs << _plp_repulsive_weight_el ->spinbox ->value()<<endl;
+ ofs << "plp_tors_weight ";
+ ofs << _plp_tors_weight_el ->spinbox ->value()<<endl;
+ }
+
+ ofs << "\n"
+ "# 1.5 input option\n"
+ "protein_file ";
+ ofs << load_protein_file ->val ()<<endl;
+
+ if (load_ligand_file ->val () != "") {
+ ofs << "ligand_file ";
+ ofs << load_ligand_file ->val ()<<endl;
+ }
+
+ if (load_ligand_list_file ->val () != "") {
+ ofs << "ligand_list ";
+ ofs << load_ligand_list_file ->val ()<<endl;
+ }
+
+ ofs << "\n"
+ "# 1.6 output option\n"
+ "output_dir ";
+ ofs << _output_dir ->linedit ->text ().toStdString ()<<endl;
+ ofs << "write_protein_conformations ";
+ ofs << _write_protein_conformations_chb ->isChecked()<<endl;
+ ofs << "write_protein_bindingsite ";
+ ofs << _write_protein_bindingsite_chb ->isChecked()<<endl;
+ ofs << "write_protein_splitted ";
+ ofs << _write_protein_splitted_chb ->isChecked()<<endl;
+ ofs << "write_rescored_structures ";
+ ofs << _write_rescored_structures_chb ->isChecked()<<endl;
+ ofs << "write_multi_mol2 ";
+ ofs << _write_multi_mol2_chb ->isChecked()<<endl;
+ ofs << "write_ranking_links ";
+ ofs << _write_ranking_links_chb ->isChecked()<<endl;
+ ofs << "write_ranking_multi_mol2 ";
+ ofs << _write_ranking_multi_mol2_chb ->isChecked()<<endl;
+ ofs << "write_per_atom_scores ";
+ ofs << _write_per_atom_scores_chb ->isChecked()<<endl;
+ ofs << "write_merged_ligand ";
+ ofs << _write_merged_ligand_chb ->isChecked()<<endl;
+ ofs << "write_merged_protein ";
+ ofs << _write_merged_protein_chb ->isChecked()<<endl;
+ ofs << "write_merged_water ";
+ ofs << _write_merged_water_chb ->isChecked()<<endl;
+ ofs << "keep_original_mol2_description ";
+ ofs << _keep_original_mol2_description_chb ->isChecked()<<endl;
+ ofs << "merge_multi_conf_output ";
+ ofs << _merge_multi_conf_output_box ->isChecked()<<endl;
+ ofs << "merge_multi_conf_character ";
+ ofs << _merge_multi_conf_character ->linedit ->text ().toStdString ()<<endl;
+ ofs << "merge_multi_conf_after_characters ";
+ ofs << _merge_multi_conf_after_characters_el ->spinbox ->value()<<endl;
+ ofs << "\n"
+ "# 1.7 costraints\n";
+
+ for (unsigned int i = 0; i <costraints_file_list ->_lw ->count (); i++) {
+ QString q = costraints_file_list ->_lw ->item(i) ->text ();
+ ofs << q.toStdString ()<<endl;
+ }
+
+ ofs << "\n"
+ "# 1.8 flexible side-chains\n";
+ for (unsigned int i = 0; i <flexibility_file_list ->_lw ->count (); i++) {
+ QString q = flexibility_file_list ->_lw ->item(i) ->text ();
+ ofs << q.toStdString ()<<endl;
+ }
+ ofs << "\n"
+ "# 1.9 multiconformer docking\n"
+ "rigid_ligand ";
+ ofs << _rigid_ligand_chb ->isChecked()<<endl;
+ ofs << "rigid_all ";
+ ofs << _rigid_all_chb ->isChecked()<<endl;
+
+ if (_water_site_x_el ->spinbox ->value() ) {
+ ofs << "\n"
+ "# 1.10 water\n"
+ "water_molecule ";
+ ofs << _water_site_x_el ->spinbox ->value();
+ ofs << " ";
+ ofs << _water_site_y_el ->spinbox ->value();
+ ofs << " ";
+ ofs << _water_site_z_el ->spinbox ->value();
+ ofs << " ";
+ ofs << _water_site_radius_el ->spinbox ->value()<<endl;
+ ofs << "water_molecule_definition ";
+ ofs << load_water_file ->val ()<<endl;
+ ofs << "water_protein_hb_weight ";
+ ofs << _water_protein_hb_weight_el ->spinbox ->value()<<endl;
+ ofs << "water_ligand_hb_weight ";
+ ofs << _water_ligand_hb_weight_el ->spinbox ->value()<<endl;
+ ofs << "water_water_hb_weight ";
+ ofs << _water_water_hb_weight_el ->spinbox ->value()<<endl;
+ ofs << "no_water_ligand_hb_penalty ";
+ ofs << _no_water_ligand_hb_penalty_el ->spinbox ->value()<<endl;
+ ofs << "water_enable_penalty ";
+ ofs << _water_enable_penalty_el ->spinbox ->value()<<endl;
+ }
+
+ ofs << "\n"
+ "##################################################################################\n" ;
+ }
+}
+
+
+void PLANTSMenu::_restore_slot () {
+// 1.1
+ _search_speed_cb->_combo_box ->setCurrentIndex(0);
+ _aco_ants_el ->spinbox ->setValue(20);
+ _aco_evap_el ->spinbox ->setValue(1);
+ _aco_sigma_el ->spinbox ->setValue(1);
+ _flip_amide_bonds_chb ->setCheckState (Qt::Unchecked);
+ _flip_planar_n_chb ->setCheckState (Qt::Unchecked);
+ _force_flipped_bonds_planarity_chb ->setCheckState (Qt::Unchecked);
+ _force_planar_bond_rotation_chb ->setCheckState (Qt::Checked);
+ _rescore_mode_cb->_combo_box ->setCurrentIndex(0);
+// 1.2
+ _site_x_el ->spinbox ->setValue(0);
+ _site_y_el ->spinbox ->setValue(0);
+ _site_z_el ->spinbox ->setValue(0);
+ _site_radius_el ->spinbox ->setValue(10);
+// 1.3
+ _cluster_rmsd_el ->spinbox ->setValue(2);
+ _cluster_structures_el ->spinbox ->setValue(10);
+// 1.4
+ _algorithm_type_cb->_combo_box ->setCurrentIndex(0);
+ _outside_binding_site_penalty_el ->spinbox ->setValue(50);
+ _enable_sulphur_acceptors_chb ->setCheckState (Qt::Unchecked);
+ _ligand_intra_score_cb->_combo_box ->setCurrentIndex(0);
+ _chemplp_clash_include_14_el ->spinbox ->setValue(0.25);
+ _chemplp_clash_include_HH_chb ->setCheckState (Qt::Unchecked);
+ _plp_steric_e_el ->spinbox ->setValue(-0.4);
+ _plp_burpolar_e_el ->spinbox ->setValue(-0.05);
+ _plp_hbond_e_el ->spinbox ->setValue(-2);
+ _plp_metal_e_el ->spinbox ->setValue(-4);
+ _plp_repulsive_weight_el ->spinbox ->setValue(0.5);
+ _plp_tors_weight_el ->spinbox ->setValue(1);
+ _chemplp_weak_cho_chb ->setCheckState (Qt::Checked);
+ _chemplp_charged_hb_weight_el ->spinbox ->setValue(2);
+ _chemplp_charged_metal_weight_el ->spinbox ->setValue(2);
+ _chemplp_hbond_weight_el ->spinbox ->setValue(-3);
+ _chemplp_hbond_cho_weight_el ->spinbox ->setValue(-3);
+ _chemplp_metal_weight_el ->spinbox ->setValue(-6);
+ _chemplp_plp_weight_el ->spinbox ->setValue(1);
+ _chemplp_plp_steric_e_el ->spinbox ->setValue(-0.4);
+ _chemplp_plp_burpolar_e_el ->spinbox ->setValue(-0.1);
+ _chemplp_plp_hbond_e_el ->spinbox ->setValue(-1);
+ _chemplp_plp_metal_e_el ->spinbox ->setValue(-1);
+ _chemplp_plp_repulsive_weight_el ->spinbox ->setValue(1);
+ _chemplp_tors_weight_el ->spinbox ->setValue(2);
+ _chemplp_lipo_weight_el ->spinbox ->setValue(0);
+ _chemplp_intercept_weight_el ->spinbox ->setValue(-20);
+// 1.5
+ load_protein_file ->linedit ->clear();
+ load_ligand_file ->linedit ->clear();
+ input_file ->_lw ->clear();
+ load_ligand_list_file ->linedit ->clear();
+ input_file_list ->_lw ->clear();
+// 1.6
+ _output_dir ->linedit ->clear();
+ _write_protein_conformations_chb ->setCheckState (Qt::Unchecked);
+ _write_protein_bindingsite_chb ->setCheckState (Qt::Unchecked);
+ _write_protein_splitted_chb ->setCheckState (Qt::Unchecked);
+ _write_rescored_structures_chb ->setCheckState (Qt::Unchecked);
+ _write_multi_mol2_chb ->setCheckState (Qt::Checked);
+ _write_ranking_links_chb ->setCheckState (Qt::Unchecked);
+ _write_ranking_multi_mol2_chb ->setCheckState (Qt::Unchecked);
+ _write_per_atom_scores_chb ->setCheckState (Qt::Unchecked);
+ _write_merged_ligand_chb ->setCheckState (Qt::Unchecked);
+ _write_merged_protein_chb ->setCheckState (Qt::Unchecked);
+ _keep_original_mol2_description_chb ->setCheckState (Qt::Checked);
+ _merge_multi_conf_output_box ->setChecked (Qt::Unchecked);
+ _merge_multi_conf_character ->linedit ->setText("_");
+ _merge_multi_conf_after_characters_el ->spinbox ->setValue(1);
+// 1.7
+ costraints_file_list ->_lw ->clear();
+ _protein_hb_costraint_cb ->_combo_box ->clear();
+ _ligand_surface_distance_cb ->_combo_box ->clear();
+ _number_a_ligand_intra_distance_cb ->_combo_box ->clear();
+ _number_b_ligand_intra_distance_cb ->_combo_box ->clear();
+ _number_a_protein_ligand_distance_cb ->_combo_box ->clear();
+ _number_b_protein_ligand_distance_cb ->_combo_box ->clear();
+// 1.8
+ flexibility_file_list ->_lw ->clear();
+ _flexible_protein_side_chain_string ->_combo_box ->clear();
+ _fix_protein_bond ->_combo_box ->clear();
+ _flexible_protein_side_chain_number ->_combo_box ->clear();
+// 1.9
+ _rigid_ligand_chb ->setCheckState (Qt::Unchecked);
+ _rigid_all_chb ->setCheckState (Qt::Unchecked);
+// 1.10
+ _water_site_x_el ->spinbox ->setValue(0);
+ _water_site_y_el ->spinbox ->setValue(0);
+ _water_site_z_el ->spinbox ->setValue(0);
+ _water_site_radius_el ->spinbox ->setValue(2);
+ load_water_file ->linedit ->clear();
+ _water_protein_hb_weight_el ->spinbox ->setValue(1);
+ _water_ligand_hb_weight_el ->spinbox ->setValue(1);
+ _water_water_hb_weight_el ->spinbox ->setValue(1);
+ _no_water_ligand_hb_penalty_el ->spinbox ->setValue(0);
+ _water_enable_penalty_el ->spinbox ->setValue(8);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// GAMESS menu FE
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+GamessMenu::GamessMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true, true) {
+ setWindowTitle ("GAMESS input");
+
+// Main tab
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ();
+ _tabs ->addTab (main_tab, "Main");
+
+ _base_box = new MyGroupBox (main_tab ->basic_layout (), "Base settings");
+
+ _run_type_cb = new MyComboBox (_base_box ->layout (), "Calculation type:");
+ _run_type_cb ->combo_box () ->insertItem (0, "Equilibrium geometry", "optimize");
+ _run_type_cb ->combo_box () ->insertItem (1, "Single point energy", "energy");
+ _run_type_cb ->combo_box () ->insertItem (2, "Gradient", "gradient");
+ _run_type_cb ->combo_box () ->insertItem (3, "Transition state", "sadpoint");
+ _run_type_cb ->combo_box () ->insertItem (4, "Vibrational frequencies", "hessian");
+// _run_type_cb ->combo_box () ->insertItem (5, "Surface", "surf");
+// _run_type_cb ->combo_box () ->insertItem (6, "Properties", "prop");
+// _run_type_cb ->combo_box () ->insertItem (7, "IRC calculation", "irc");
+
+ _semi_emp_cb = new QComboBox ();
+ _semi_emp_cb ->insertItem (0, "AM1", "AM1");
+ _semi_emp_cb ->insertItem (1, "PM3", "PM3");
+ _semi_emp_cb ->insertItem (2, "MNDO", "MNDO");
+ _semi_emp_cb ->insertItem (3, "MIDI", "MIDI");
+
+ _H_F_cb = new QComboBox ();
+ _H_F_cb ->insertItem (0, "STO-3G", "130000");
+ _H_F_cb ->insertItem (1, "STO-4G", "140000");
+ _H_F_cb ->insertItem (2, "3-21G", "230000");
+ _H_F_cb ->insertItem (3, "3-21G*", "231000");
+ _H_F_cb ->insertItem (4, "3-21G**", "231100");
+ _H_F_cb ->insertItem (5, "3-21+G*", "231010");
+ _H_F_cb ->insertItem (6, "3-21+G**", "231110");
+ _H_F_cb ->insertItem (7, "4-31G", "340000");
+ _H_F_cb ->insertItem (8, "4-31G*", "341000");
+ _H_F_cb ->insertItem (9, "4-31G**", "341100");
+ _H_F_cb ->insertItem (10, "4-31+G*", "341010");
+ _H_F_cb ->insertItem (11, "4-31+G**", "341110");
+ _H_F_cb ->insertItem (12, "6-31G", "360000");
+ _H_F_cb ->insertItem (13, "6-31G*", "361000");
+ _H_F_cb ->insertItem (14, "6-31G**", "361100");
+ _H_F_cb ->insertItem (15, "6-31+G*", "361010");
+ _H_F_cb ->insertItem (16, "6-31+G**", "361110");
+ _H_F_cb ->insertItem (17, "6-311G", "460000");
+ _H_F_cb ->insertItem (18, "6-311G*", "461000");
+ _H_F_cb ->insertItem (19, "6-311G**", "461100");
+ _H_F_cb ->insertItem (20, "6-311+G*", "461010");
+ _H_F_cb ->insertItem (21, "6-311+G**", "461110");
+// _H_F_cb ->insertItem (22, "6-311++G(2d,p)", "462111");
+
+
+ _gbasis_hcb = new MyHideComboBox (_base_box ->layout (), "Basis set:");
+
+ _gbasis_hcb -> layout () -> addWidget (_semi_emp_cb);
+ _gbasis_hcb -> layout () -> addWidget (_H_F_cb);
+
+ _gbasis_hcb ->insertItem (_semi_emp_cb, 0, "Semi-empirical", "S_e");
+ _gbasis_hcb ->insertItem (_H_F_cb, 1, "Harteee-Fock", "H_F");
+
+ connect (_gbasis_hcb ->combo_box (), SIGNAL (currentIndexChanged ( int )), this, SLOT (hide_solv ( int )) );
+
+
+// Solvation group
+ _solv_box = new MyGroupBox (main_tab ->basic_layout (), "Solvation", true, false);
+ _solv_box ->hide ();
+
+ _solvent_cb = new MyComboBox (_solv_box ->layout (), "Solvent:");
+ _solvent_cb ->combo_box () ->insertItem (0, "No solvent", "gas");
+ _solvent_cb ->combo_box () ->insertItem (1, "Water", "water");
+ _solvent_cb ->combo_box () ->insertItem (2, "1,2-dichloroethane", "12dclet");
+ _solvent_cb ->combo_box () ->insertItem (3, "Acetone", "acetone");
+ _solvent_cb ->combo_box () ->insertItem (4, "Aniline", "aniline");
+ _solvent_cb ->combo_box () ->insertItem (5, "Benzene", "benzene");
+ _solvent_cb ->combo_box () ->insertItem (6, "Chlorobenzene", "clbenz");
+ _solvent_cb ->combo_box () ->insertItem (7, "Chloroform", "clform");
+ _solvent_cb ->combo_box () ->insertItem (8, "CCl4", "ctcl");
+ _solvent_cb ->combo_box () ->insertItem (9, "Cyclohexane", "cychex");
+ _solvent_cb ->combo_box () ->insertItem (10, "DMSO", "dmso");
+ _solvent_cb ->combo_box () ->insertItem (11, "Ethanol", "c2h5oh");
+ _solvent_cb ->combo_box () ->insertItem (12, "Methanol", "ch3oh");
+ _solvent_cb ->combo_box () ->insertItem (13, "Methyl chloride", "methycl");
+ _solvent_cb ->combo_box () ->insertItem (14, "Neptane", "neptane");
+ _solvent_cb ->combo_box () ->insertItem (15, "Nitromethane", "nitmet");
+ _solvent_cb ->combo_box () ->insertItem (16, "THF", "thf");
+ _solvent_cb ->combo_box () ->insertItem (17, "Toluene", "toluene");
+
+ connect (_solvent_cb ->combo_box (), SIGNAL (currentIndexChanged ( int )), this, SLOT (hide_temp ( int )) );
+
+ _temp = 298.0;
+ _tabs_el = new MyFloatEditLine (_solv_box ->layout (), "Absolute temperature (K):", _temp, 0);
+ _tabs_el ->hide ();
+
+
+// Main tab - advanced
+ _scftyp_cb = new MyComboBox (main_tab ->advanced_layout (), "Wavefunction:");
+ _scftyp_cb ->combo_box () ->insertItem (0, "RHF", "RHF");
+ _scftyp_cb ->combo_box () ->insertItem (1, "ROHF", "ROHF");
+ _scftyp_cb ->combo_box () ->insertItem (2, "UHF", "UHF");
+
+ _mult_cb = new MyComboBox (main_tab ->advanced_layout (), "Moltiplicity:");
+ _mult_cb ->combo_box () ->insertItem (0, "Singlet/Closed", "1");
+ _mult_cb ->combo_box () ->insertItem (1, "Doublet/Radical", "2");
+ _mult_cb ->combo_box () ->insertItem (2, "Triplet/Biradical", "3");
+ _mult_cb ->combo_box () ->insertItem (3, "Quartet", "4");
+ _mult_cb ->combo_box () ->insertItem (4, "Quintet", "5");
+ _mult_cb ->combo_box () ->insertItem (5, "Sextet", "6");
+ _mult_cb ->combo_box () ->insertItem (6, "Septet", "7");
+
+ _guess_cb = new MyComboBox (main_tab ->advanced_layout (), "Type of initial orbtal guess:");
+ _guess_cb ->combo_box () ->insertItem (0, "HUCKEL", "huckel");
+ _guess_cb ->combo_box () ->insertItem (1, "HCORE", "hcore");
+ _guess_cb ->combo_box () ->insertItem (2, "MOREAD", "moread");
+ _guess_cb ->combo_box () ->insertItem (3, "RDMINI", "rdmini");
+ _guess_cb ->combo_box () ->insertItem (4, "MOSAVED", "mosaved");
+ _guess_cb ->combo_box () ->insertItem (5, "SKIP", "skip");
+ _guess_cb ->combo_box () ->insertItem (6, "FMO", "fmo");
+
+
+// ADD ICHARG, but can'I obtain this data from zodiac????
+// ADD UNITSICHARG, but can'I obtain this data from zodiac????
+
+// elpot tab
+ ZNAdvancedWidget *elpot_tab = new ZNAdvancedWidget ();
+ _tabs ->addTab (elpot_tab, "ELPOT");
+
+ _elpot_box = new MyGroupBox (elpot_tab ->basic_layout (), "Settings", true, false);
+
+ _where_cb = new MyComboBox (_elpot_box ->layout (), "Where:");
+ _where_cb ->combo_box () ->insertItem (0, "At each nucleus", "nuclei");
+ _where_cb ->combo_box () ->insertItem (1, "Center of mass", "comass");
+ _where_cb ->combo_box () ->insertItem (2, "At points givent in $points", "points");
+ _where_cb ->combo_box () ->insertItem (3, "At grid givent in $grid", "grid");
+ _where_cb ->combo_box () ->insertItem (4, "At points controlled by $pdc", "pdc");
+
+ connect (_where_cb ->combo_box (), SIGNAL (currentIndexChanged ( int )), this, SLOT (hide_elpot ( int )) );
+
+ _output_cb = new MyComboBox (_elpot_box ->layout (), "Output:");
+ _output_cb ->combo_box () ->insertItem (0, "punch and paper", "both");
+ _output_cb ->combo_box () ->insertItem (1, "punch", "punch");
+ _output_cb ->combo_box () ->insertItem (2, "paper", "paper");
+
+ _points_box = new MyGroupBox (elpot_tab ->basic_layout (), "$POINTS");
+ _points_box ->hide ();
+
+ _grid_box = new MyGroupBox (elpot_tab ->basic_layout (), "$GRID");
+ _grid_box ->hide ();
+
+ _pdc_box = new MyGroupBox (elpot_tab ->basic_layout (), "$PDC");
+ _pdc_box ->hide ();
+
+ _ptsel_cb = new MyComboBox (_pdc_box ->layout (), "PTSEL:");
+ _ptsel_cb ->combo_box () ->insertItem (0, "Geodesic", "geodesic");
+ _ptsel_cb ->combo_box () ->insertItem (1, "Connolly", "connolly");
+ _ptsel_cb ->combo_box () ->insertItem (2, "Chelpg", "chelpg");
+
+ _constr_cb = new MyComboBox (_pdc_box ->layout (), "CONSTR:");
+ _constr_cb ->combo_box () ->insertItem (0, "None", "none");
+ _constr_cb ->combo_box () ->insertItem (1, "Charge", "charge");
+ _constr_cb ->combo_box () ->insertItem (2, "Dipole", "dipole");
+ _constr_cb ->combo_box () ->insertItem (3, "Qupole", "qupole");
+
+ _vdwscl = 1.4;
+ _vdwscl_fel = new MyFloatEditLine (_pdc_box ->layout (), "First shell of VDW spheres:", _vdwscl, 0);
+
+ _vdwinc = 0.2;
+ _vdwinc_fel = new MyFloatEditLine (_pdc_box ->layout (), "Increment for successive shells:", _vdwinc, 0);
+
+ _layer = 4;
+ _layer_iel = new MyIntegerEditLine (_pdc_box ->layout (), "Number of layers:", _layer, 0);
+
+ _maxpdc = 4;
+ _maxpdc_iel = new MyIntegerEditLine (_pdc_box ->layout (), "Total number of points:", _maxpdc, 0);
+
+// System tab
+ ZNWidget *_system_tab = new ZNWidget ();
+ _tabs ->addTab (_system_tab, "System");
+
+ _run_box = new MyGroupBox (_system_tab ->layout (), "Run settings");
+
+ _exetyp_cb = new MyComboBox (_run_box ->layout (), "Type:");
+ _exetyp_cb ->combo_box () ->insertItem (0, "Run calculation", "run");
+ _exetyp_cb ->combo_box () ->insertItem (1, "Check errors", "check");
+
+ _timlim = 600;
+ _timlim_iel = new MyIntegerEditLine (_run_box ->layout (), "Time limit (minutes):", _timlim, 0);
+
+ _memory = 2000;
+ _memory_iel = new MyIntegerEditLine (_run_box ->layout (), "Memory limit (MB):", _memory, 0);
+
+
+// test tab
+/* ZNAdvancedWidget *_test_tab = new ZNAdvancedWidget ();
+ _tabs ->addTab (_test_tab, "Test");
+
+ MyComboBox *_sopra_cb;
+ _sopra_cb = new MyComboBox (_test_tab ->basic_layout (), "Run type:");
+
+ MyComboBox *_sotto_cb;
+ _sotto_cb = new MyComboBox (_test_tab ->advanced_layout (), "Run type2:");
+*/
+
+// menu
+ add_menu ();
+ add_help ();
+}
+
+
+void GamessMenu::_show_about ()
+{
+ QMessageBox::about( _data ->ddwin, "About GAMESS input front end" ,
+ QString(("ZODIAC. Version "+VERSION+ "\n"
+ "GAMESS input front end. Code by Alberto Massarotti. All rights reserved.\n"
+ "For bug reports, suggestions or any other feedback please visit our website at www.zeden.org\n\n").c_str()) );
+}
+
+
+void GamessMenu::hide_temp (int i) {
+ if (i == 0) {
+ _tabs_el ->hide ();
+ _solv = 0;
+ }
+ else {
+ _tabs_el ->show ();
+ _solv = 1;
+ }
+}
+
+
+void GamessMenu::hide_solv (int i) {
+ if (i == 0) {
+ _solv_box ->hide ();
+ }
+ else {
+ _solv_box ->show ();
+ }
+}
+
+void GamessMenu::hide_elpot (int i) {
+ _points_box ->hide ();
+ _grid_box ->hide ();
+ _pdc_box ->hide ();
+ if (i == 2) {
+ _points_box ->show ();
+ }
+ else if (i == 3) {
+ _grid_box ->show ();
+ }
+ else if (i == 4) {
+ _pdc_box ->show ();
+ }
+}
+
+
+void GamessMenu::add_menu () {
+ QMenu *file = new QMenu(tr("&File"), this );
+ _load_action = new QAction (tr ("&Load"), this);
+ connect (_load_action, SIGNAL (triggered ()), this, SLOT (_load_slot ()));
+ file -> addAction (_load_action);
+
+ _save_action = new QAction (tr ("&Save"), this);
+ connect (_save_action, SIGNAL (triggered ()), this, SLOT (_save_slot ()));
+ file -> addAction (_save_action);
+ addMenu (file);
+
+ QMenu *settings = new QMenu(tr("&Settings"), this );
+ _restore_action = new QAction (tr ("&Restore to default"), this);
+ connect (_restore_action, SIGNAL (triggered ()), this, SLOT (_restore_slot ()));
+ settings -> addAction (_restore_action);
+ addMenu (settings);
+
+}
+
+
+void GamessMenu::_restore_slot () {
+_run_type_cb ->_combo_box ->setCurrentIndex(0);
+_gbasis_hcb ->_combo_box ->setCurrentIndex(0);
+
+_semi_emp_cb ->setCurrentIndex(0);
+
+_H_F_cb ->setCurrentIndex(0);
+_mult_cb ->_combo_box ->setCurrentIndex(0);
+
+_scftyp_cb ->_combo_box ->setCurrentIndex(0);
+_solvent_cb ->_combo_box ->setCurrentIndex(0);
+
+_tabs_el ->spinbox ->setValue(298);
+_exetyp_cb ->_combo_box ->setCurrentIndex(0);
+_timlim_iel ->spinbox ->setValue(600);
+_memory_iel ->spinbox ->setValue(2000);
+
+_guess_cb ->_combo_box ->setCurrentIndex(0);
+
+
+_where_cb ->_combo_box ->setCurrentIndex(0);
+_output_cb ->_combo_box ->setCurrentIndex(0);
+_ptsel_cb ->_combo_box ->setCurrentIndex(0);
+_constr_cb ->_combo_box ->setCurrentIndex(0);
+
+_elpot_box -> setChecked (false);
+_vdwscl_fel ->spinbox ->setValue(1.4);
+_vdwinc_fel ->spinbox ->setValue(0.2);
+_layer_iel ->spinbox ->setValue(4);
+_maxpdc_iel ->spinbox ->setValue(4);
+
+}
+
+
+void GamessMenu::_load_bot_iel (string& buffer, const char *reference, MyIntegerEditLine *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == reference) {
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (end.toStdString () == "MEMORY") {
+ target ->spinbox ->setValue(filter.toInt()/1000);
+ }
+ else {
+ target ->spinbox ->setValue(filter.toInt());
+ }
+ }
+}
+
+void GamessMenu::_load_bot_fel (string& buffer, const char *reference, MyFloatEditLine *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == reference) {
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+ target ->spinbox ->setValue(filter.toDouble());
+ }
+}
+
+void GamessMenu::_load_bot_box (string& buffer, const char *reference, MyGroupBox *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == reference) {
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+ if (filter == "0") target ->setChecked (false);
+ if (filter == "1") target ->setChecked (true);
+ }
+}
+
+void GamessMenu::_load_bot_cb (string& buffer, const char *reference, MyComboBox *target) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == reference) {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+ target ->_combo_box ->setCurrentIndex (target ->_combo_box ->findData (filter));
+ }
+}
+
+void GamessMenu::_load_bot_gbasis (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "GBASIS") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == "AM1") {
+ _gbasis_hcb ->_combo_box ->setCurrentIndex (0);
+ _semi_emp_cb ->setCurrentIndex (_semi_emp_cb ->findData (filter));
+ }
+ else if (filter.toStdString() == "PM3") {
+ _gbasis_hcb ->_combo_box ->setCurrentIndex (0);
+ _semi_emp_cb ->setCurrentIndex (_semi_emp_cb ->findData (filter));
+ }
+ else if (filter.toStdString() == "MNDO") {
+ _gbasis_hcb ->_combo_box ->setCurrentIndex (0);
+ _semi_emp_cb ->setCurrentIndex (_semi_emp_cb ->findData (filter));
+ }
+ else if (filter.toStdString() == "MIDI") {
+ _gbasis_hcb ->_combo_box ->setCurrentIndex (0);
+ _semi_emp_cb ->setCurrentIndex (_semi_emp_cb ->findData (filter));
+ }
+ else {
+ _gbasis_hcb ->_combo_box ->setCurrentIndex (1);
+
+ if (filter.toStdString() == "STO") {
+ _gbasis_load = 100000;
+ }
+ else if (filter.toStdString() == "N21") {
+ _gbasis_load = 200000;
+ }
+ else if (filter.toStdString() == "N31") {
+ _gbasis_load = 300000;
+ }
+ else if (filter.toStdString() == "N311") {
+ _gbasis_load = 400000;
+ }
+ }
+ }
+}
+
+void GamessMenu::_load_bot_ngauss (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "NGAUSS") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == "3") {
+ _gbasis_load = _gbasis_load + 30000;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ else if (filter.toStdString() == "4") {
+ _gbasis_load = _gbasis_load + 40000;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ else if (filter.toStdString() == "6") {
+ _gbasis_load = _gbasis_load + 60000;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ }
+}
+
+void GamessMenu::_load_bot_ndfunc (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "NDFUNC") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == "0") {
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ else if (filter.toStdString() == "1") {
+ _gbasis_load = _gbasis_load + 1000;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ else if (filter.toStdString() == "2") {
+ _gbasis_load = _gbasis_load + 2000;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ }
+}
+
+void GamessMenu::_load_bot_npfunc (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "NPFUNC") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == "0") {
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ else if (filter.toStdString() == "1") {
+ _gbasis_load = _gbasis_load + 100;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ }
+}
+
+void GamessMenu::_load_bot_diffsp (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "DIFFSP") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == ".true.") {
+ _gbasis_load = _gbasis_load + 10;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ }
+}
+
+void GamessMenu::_load_bot_diffs (string& buffer) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+ QString end = QString::fromStdString (token);
+ end.truncate (end.lastIndexOf ('='));
+
+ if (end.toStdString () == "DIFFS") {
+
+ QString filter = QString::fromStdString (token);
+ filter.remove (0, filter.indexOf ('=')+1);
+
+ if (filter.toStdString() == ".true.") {
+ _gbasis_load = _gbasis_load + 1;
+ _H_F_cb ->setCurrentIndex (_H_F_cb ->findData (_gbasis_load));
+ }
+ }
+}
+
+void GamessMenu::_load_slot () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("GAMESS input file (*.inp)"));
+
+ _gbasis_load = 0;
+
+ if (!s.isNull()) {
+ ifstream ifs (s.toStdString ().c_str ());
+ string buffer;
+
+ _restore_slot ();
+
+ while (getline(ifs, buffer)) {
+
+ _load_bot_iel (buffer, "TIMLIM", _timlim_iel);
+ _load_bot_iel (buffer, "MEMORY", _memory_iel);
+ _load_bot_iel (buffer, "LAYER", _layer_iel);
+ _load_bot_fel (buffer, "TABS", _tabs_el);
+ _load_bot_iel (buffer, "MAXPDC", _maxpdc_iel);
+ _load_bot_fel (buffer, "VDWSCL", _vdwscl_fel);
+ _load_bot_fel (buffer, "VDWINC", _vdwinc_fel);
+
+ _load_bot_cb (buffer, "RUNTYP", _run_type_cb);
+ _load_bot_cb (buffer, "MULT", _mult_cb);
+ _load_bot_cb (buffer, "SCFTYP", _scftyp_cb);
+ _load_bot_cb (buffer, "SOLVENT", _solvent_cb);
+ _load_bot_cb (buffer, "EXETYP", _exetyp_cb);
+ _load_bot_cb (buffer, "GUESS", _guess_cb);
+ _load_bot_cb (buffer, "WHERE", _where_cb);
+ _load_bot_cb (buffer, "OUTPUT", _output_cb);
+ _load_bot_cb (buffer, "PTSEL", _ptsel_cb);
+ _load_bot_cb (buffer, "CONSTR", _constr_cb);
+
+ _load_bot_box (buffer, "ELPOT", _elpot_box);
+
+ _load_bot_gbasis (buffer);
+ _load_bot_ngauss (buffer);
+ _load_bot_ndfunc (buffer);
+ _load_bot_npfunc (buffer);
+ _load_bot_diffsp (buffer);
+ _load_bot_diffs (buffer);
+
+ }
+ }
+}
+
+
+void GamessMenu::_save_slot () {
+ QFileDialog save_file(this);
+
+ QStringList filters;
+ filters << "GAMESS input file (*.inp)";
+
+ save_file.setNameFilters (filters);
+ save_file.setAcceptMode (QFileDialog::AcceptSave);
+ save_file.exec();
+
+ QString ext = save_file.selectedNameFilter();
+
+ QString filter = save_file.selectedNameFilter();
+ filter.truncate (filter.lastIndexOf (')'));
+ filter.remove (0, filter.indexOf ('*')+1);
+ QString s = save_file.selectedFile();
+ if (!s.contains ('.') ) s+= filter;
+
+
+ if (!s.isNull()) {
+ if (_data -> ddwin ->current_target) {
+ ofstream ofs(s.toStdString ().c_str ());
+ ofs << "!##################################################################################\n"
+ "!#\n"
+ "!# GAMESS input file written by Zodiac "<<VERSION<<" (www.zeden.org)\n"
+ "!#\n"
+ "!##################################################################################\n"
+ "\n"
+ " $BASIS\n"
+ "GBASIS=" ;
+ if (_gbasis_hcb ->currentData ().toString ().toStdString () == "S_e") {
+ ofs << _semi_emp_cb ->currentText ().toStdString () <<endl;
+ }
+ else {
+ _gbasis = _H_F_cb ->itemData (_H_F_cb ->currentIndex ()).toInt ();
+ if (_gbasis < 200000) {
+ _gbasis = _gbasis - 100000;
+ ofs << "STO" <<endl;
+ }
+ else if (_gbasis < 300000) {
+ _gbasis = _gbasis - 200000;
+ ofs << "N21" <<endl;
+ }
+ else if (_gbasis < 400000) {
+ _gbasis = _gbasis - 300000;
+ ofs << "N31" <<endl;
+ }
+ else {
+ _gbasis = _gbasis - 400000;
+ ofs << "N311" <<endl;
+ }
+
+ ofs << "NGAUSS=" ;
+ if (_gbasis < 40000) {
+ _gbasis = _gbasis - 30000;
+ ofs << "3" <<endl;
+ }
+ else if (_gbasis < 60000) {
+ _gbasis = _gbasis - 40000;
+ ofs << "4" << endl;
+ }
+ else {
+ _gbasis = _gbasis - 60000;
+ ofs << "6" << endl;
+ }
+
+ ofs << "NDFUNC=" ;
+ if (_gbasis < 1000) {
+ ofs << "0" << endl;
+ }
+ else if (_gbasis < 2000) {
+ _gbasis = _gbasis - 1000;
+ ofs << "1" << endl;
+ }
+ else {
+ _gbasis = _gbasis - 2000;
+ ofs << "2" << endl;
+ }
+
+ ofs << "NPFUNC=" ;
+ if (_gbasis < 100) {
+ ofs << "0" << endl;
+ }
+ else {
+ _gbasis = _gbasis - 100;
+ ofs << "1" << endl;
+ }
+
+ if (_gbasis < 10) {
+
+ }
+ else {
+ ofs << "DIFFSP=.true." << endl;
+ _gbasis = _gbasis - 10;
+ }
+
+ if (_gbasis < 1) {
+
+ }
+ else {
+ ofs << "DIFFS=.true." << endl;
+ }
+ }
+ ofs << " $END\n\n!##################################################################################\n\n"
+ " $CONTRL\n"
+ "SCFTYP=" ;
+ ofs << _scftyp_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "RUNTYP=" ;
+ ofs << _run_type_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "MULT=" ;
+ ofs << _mult_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "EXETYP=" ;
+ ofs << _exetyp_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n";
+ if (_solv == 1) {
+ ofs << " $PCM\n"
+ "SOLVNT=" ;
+ ofs<< _solvent_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "TABS=" ;
+ ofs<< _tabs_el ->currentData ()<<endl;
+// ofs << "RSOLV=" ;
+// ofs<< _rsolv_el ->currentData ().toString ().toStdString ()<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n";
+ }
+ ofs << " $SYSTEM\n"
+ "TIMLIM=" ;
+ ofs << _timlim_iel ->spinbox -> value ()<<endl;
+// ofs << "MWORDS=" ;
+// ofs << _mwords_cb ->currentData ().toString ().toStdString ()<<endl;
+// ofs << "MEMDD=" ;
+// ofs << _medd_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "MEMORY=" ;
+ _memory2 = _memory_iel ->spinbox -> value ();
+ _memory2 = 1000 * _memory2;
+ ofs << _memory2<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n" ;
+ if (_elpot_box -> isChecked () == true) {
+ ofs << " $ELPOT\n"
+ "IEPOT=1\n"
+ "WHERE=";
+ ofs<< _where_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "OUTPUT=";
+ ofs<< _output_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n";
+ if (_where_cb ->currentData () == "points") {
+ ofs << " $POINTS\n";
+
+ ofs << " $END\n\n!##################################################################################\n\n";
+ }
+ else if (_where_cb ->currentData () == "grid") {
+ ofs << " $GRID\n";
+
+ ofs << " $END\n\n!##################################################################################\n\n";
+ }
+ else if (_where_cb ->currentData () == "pdc") {
+ ofs << " $PDC\n"
+ "PTSEL=";
+ ofs<< _ptsel_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "CONSTR=";
+ ofs<< _constr_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << "VSWSCL=" ;
+ ofs<< _vdwscl_fel ->spinbox -> value ()<<endl;
+ ofs << "VSWINC=" ;
+ ofs<< _vdwinc_fel ->spinbox -> value ()<<endl;
+ ofs << "LAYER=" ;
+ ofs<< _layer_iel ->spinbox -> value ()<<endl;
+ ofs << "MAXPDC=" ;
+ ofs<< _maxpdc_iel ->spinbox -> value ()<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n";
+ }
+ }
+ ofs << " $GUESS\n"
+ "GUESS=" ;
+ ofs<< _guess_cb ->currentData ().toString ().toStdString ()<<endl;
+ ofs << " $END\n\n!##################################################################################\n\n" ;
+
+ ZNMolecule *mol = _data -> ddwin ->target_molecule;
+
+ OBConversion conv;
+ conv.SetOutStream(&ofs);
+ OBFormat* outFormat = conv.FormatFromExt(".inp");
+ if (outFormat) {
+ conv.SetOutFormat (outFormat);
+ conv.Write (mol);
+ }
+ }
+
+ }
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+IODeviceMenu::IODeviceMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true) {
+// setWindowTitle ("Input/Output devices");
+// _input_listview = new QListView ();
+// _output_listview = new QListView ();
+// QWidget *hbox = new QWidget ();
+// hbox ->setLayout (new QHBoxLayout ());
+// main_tab ->layout ()->addWidget (hbox);
+// hbox ->layout () ->addWidget (_input_listview);
+// hbox ->layout () ->addWidget (_output_listview);
+}
+
+
+SequenceMenu::SequenceMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, false, false) {
+ setWindowTitle ("Sequence");
+
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);;
+ setCentralWidget (main_tab);
+
+ tab = new QTableWidget();
+// connect (tab, SIGNAL (cellClicked ( int , int )) ,SLOT (clicked_cell (int, int)));
+ connect (tab, SIGNAL (itemSelectionChanged ()) ,SLOT (selected_cells ()));
+
+ main_tab ->basic_layout () ->addWidget (tab);
+
+ tab -> setSortingEnabled (false);
+// set_database(db);
+
+
+
+// display_mode_box = new MyGroupBox (main_tab ->basic_layout(), "Display mode");
+
+// _dsetbutts_gc = new MyGridColumn (display_mode_box ->layout(), 1, 5);
+
+ add_menu ();
+// add_help ();
+ connect (_data -> ddwin, SIGNAL (non_selection_molecules_updated ()), this, SLOT (update_tab ()));
+
+}
+
+void SequenceMenu::update_tab () {
+ tab ->clear ();
+ int c = 0;
+ for (unsigned int m = 1; m < _data ->ddwin ->molecules.size () ; m ++) {
+ if (!_data ->ddwin ->molecules[m]-> selection) c++;
+ }
+ tab ->setRowCount(c);
+ int res_number = 0;
+ int res_number_total = 0;
+ int num = 0;
+ string res = "";
+ char chain;
+ for (unsigned int m = 1; m < _data ->ddwin ->molecules.size () ; m ++) {
+ ZNMolecule *mol = _data ->ddwin ->molecules [m];
+ if (mol -> selection) continue;
+ QTableWidgetItem *mol_name_row = new QTableWidgetItem (mol ->GetTitle ());
+ tab ->setVerticalHeaderItem (m-1, mol_name_row);
+ FOR_RESIDUES_OF_MOL(r, mol)
+ {
+ res_number_total++;
+ }
+ column = tab ->columnCount ();
+ if (res_number_total > column) {
+ tab ->setColumnCount (res_number_total);
+ }
+
+ FOR_RESIDUES_OF_MOL(r, mol)
+ {
+ res_number = r->GetNum();
+ res = r->GetName();
+ chain = r->GetChain();
+ QString residue = res.c_str();
+ stringstream ss;
+ ss << res_number;
+ string residue_number = ss.str();
+
+ QTableWidgetItem *field_name = new QTableWidgetItem (residue);
+ tab -> setItem (m -1, num++, field_name);
+
+ }
+
+ }
+ connect (tab, SIGNAL (itemClicked ( QTableWidgetItem *)) ,SLOT (pressed_cell (QTableWidgetItem *)));
+
+ for (unsigned int j = 0; j < tab ->columnCount (); j ++) {
+ tab ->resizeColumnToContents (j);
+ }
+ /*
+ char chain;
+ int res_number = 0;
+ int res_number_total = 0;
+ string res = "";
+ string residue_plus = "";
+ FOR_RESIDUES_OF_MOL(r, mol)
+ {
+ res_number_total++;
+ }
+
+ column = tab ->columnCount ();
+ if (res_number_total > column) {
+ tab ->setColumnCount (res_number_total);
+ }
+
+ row = tab ->rowCount ();
+ row = row + 1;
+ tab ->setRowCount (row);
+
+ QTableWidgetItem *mol_name_row = new QTableWidgetItem (mol ->GetTitle ());
+ tab ->setVerticalHeaderItem (row - 1, mol_name_row);
+// connect (tab, SIGNAL (itemClicked ( QTableWidgetItem *)) ,SLOT (pressed_cell (QTableWidgetItem *)));
+
+
+ int num =0;
+ FOR_RESIDUES_OF_MOL(r, mol)
+ {
+ res_number = r->GetNum();
+ res = r->GetName();
+ chain = r->GetChain();
+ QString residue = res.c_str();
+ stringstream ss;
+ ss << res_number;
+ string residue_number = ss.str();
+
+ QTableWidgetItem *field_name = new QTableWidgetItem (residue);
+ tab -> setItem (row -1, num++, field_name);
+
+ }
+
+ for (unsigned int j = 0; j < tab ->columnCount (); j ++) {
+ tab ->resizeColumnToContents (j);
+ }
+ */
+}
+
+
+void SequenceMenu::del_from_tab (ZNMolecule *mol) {
+
+}
+
+
+void SequenceMenu::selected_cells () {
+
+ QList<QTableWidgetItem *> list;
+ list = tab ->selectedItems();
+ cerr << "size "<< list.size();
+ cerr <<endl;
+
+ if (_data ->ddwin ->current_target) {
+ ZNMolecule *target = 0;
+ _data ->ddwin ->deselect ();
+ Selection *sel = new Selection;
+ for (unsigned int i = 0; i < list.size(); i++) {
+ int column = tab ->column (list.at(i));
+ int row = tab ->row (list.at (i));
+
+ target = _data ->ddwin -> molecules[row+1];
+ Resid *res = target ->GetResidue (column);
+ FOR_ATOMS_OF_RESIDUE (at, res) {
+ sel ->select_atom (&*at);
+ }
+ }
+ find_center (sel);
+ find_limits (sel);
+ _data ->ddwin ->add_molecule (sel);
+ _data ->ddwin ->set_current_target (-1);
+
+ }
+}
+
+
+void SequenceMenu::clicked_cell (int x, int y) {
+
+//cerr << "Clicked. x: "<< x << "; y: " << y << endl;
+//cerr << mol_name_row -> text().toStdString() << endl;
+
+//cerr << tab ->verticalHeaderItem (x) ->text().toStdString() << endl;
+
+ if (_data ->ddwin ->current_target) {
+ ZNMolecule *target = 0;
+ target = _data ->ddwin -> molecules[x+1];
+ _data ->ddwin ->deselect ();
+ Selection *sel = new Selection;
+ Resid *res = target ->GetResidue (y);
+ FOR_ATOMS_OF_RESIDUE (at, res) {
+ sel ->select_atom (&*at);
+// to_add.push_back (&*at);
+ }
+ find_center (sel);
+ find_limits (sel);
+ _data ->ddwin ->add_molecule (sel);
+ _data ->ddwin ->set_current_target (-1);
+ }
+}
+
+void SequenceMenu::pressed_cell (QTableWidgetItem *item) {
+
+cerr << "Pressed. item: "<< endl;
+/*
+ if (_data ->ddwin ->current_target) {
+ ZNMolecule *target = 0;
+ if (!_data ->ddwin ->target_molecule -> selection) target = _data ->ddwin ->target_molecule;
+ else target = ((Selection *) _data ->ddwin ->target_molecule) ->get_molecules ()[0];
+ _data ->ddwin ->deselect ();
+ Selection *sel = new Selection;
+ FOR_ATOMS_OF_MOL (a, target){
+ sel ->select_atom (&*a);
+ }
+ find_center (sel);
+ find_limits (sel);
+ _data ->ddwin ->add_molecule (sel);
+ _data ->ddwin ->set_current_target (-1);
+ }
+*/
+}
+
+
+void SequenceMenu::update_graphics (int row, int r, QString residue) {
+
+
+ QTableWidgetItem *field_name = new QTableWidgetItem (residue);
+ tab -> setItem (row -1, r, field_name);
+
+/*
+ for (unsigned int j = 0; j < database ->field_names.size (); j ++) {
+ QTableWidgetItem *field_name = new QTableWidgetItem (QString (database ->field_names[j].c_str ()));
+ tab ->setHorizontalHeaderItem (j, field_name);
+ }
+
+ for (unsigned int i=0; i< database ->count_entries (); i++) {
+ for (unsigned int j = 0; j < database ->count_fields (); j ++) {
+ QTableWidgetItem *value_widget = new QTableWidgetItem ();
+ value_widget ->setData (Qt::DisplayRole, QString (database -> entries[i] ->cells[j] ->get_string ().c_str ()));
+ tab -> setItem (i, j, value_widget);
+// cerr << "insert " << i << " "<<j<<" "<< database -> entries[i] ->cells[j] ->get_string () << endl;
+ }
+ }
+ database ->set_needs_redraw (false);
+ database ->mutex ->unlock ();
+*/
+}
+
+void SequenceMenu::add_menu () {
+ QMenu *file = new QMenu(tr("&File"), this );
+ _save_sequence = new QAction (tr ("&Save sequence"), this);
+ connect (_save_sequence, SIGNAL (triggered ()), this, SLOT (_save_sequence_slot ()));
+ file -> addAction (_save_sequence);
+ addMenu (file);
+
+
+ QMenu *display = new QMenu(tr("&Display residue"), this );
+
+ _residue_indice = new QAction (tr ("&Three letters"), this);
+ connect (_residue_indice, SIGNAL (triggered ()), this, SLOT (_residue_indice_slot ()));
+ _residue_indice ->setCheckable(true);
+
+ _residue_uid = new QAction (tr ("&One letter"), this);
+ connect (_residue_uid, SIGNAL (triggered ()), this, SLOT (_residue_uid_slot ()));
+ _residue_uid ->setCheckable(true);
+
+
+ aminoacidGroup = new QActionGroup(this);
+ aminoacidGroup ->setExclusive(true);
+ aminoacidGroup ->addAction (_residue_indice);
+ aminoacidGroup ->addAction (_residue_uid);
+ _residue_indice ->setChecked(true);
+
+ display ->addAction (_residue_indice);
+ display ->addAction (_residue_uid);
+
+ addMenu (display);
+
+}
+
+
+void SequenceMenu::_save_sequence_slot () {
+// QString s = QFileDialog::getSaveFileName(this, tr ("Save As"), "",tr("Fasta (*.fasta)"));
+
+ QFileDialog save_file(this);
+
+ save_file.setNameFilter (tr("Fasta (*.fasta)"));
+ save_file.setAcceptMode (QFileDialog::AcceptSave);
+ save_file.exec();
+
+ QString ext = save_file.selectedNameFilter();
+
+ QString filter = save_file.selectedNameFilter();
+ filter.truncate (filter.lastIndexOf (')'));
+ filter.remove (0, filter.indexOf ('*')+1);
+ QString s = save_file.selectedFile();
+ if (!s.contains ('.') ) s+= filter;
+
+
+
+
+ if (!s.isNull()) {
+ if (_data ->ddwin ->current_target) {
+ _data -> actions -> save_as (_data ->ddwin ->target_molecule, s.toStdString ());
+ }
+ }
+}
+
+
+void SequenceMenu::_residue_indice_slot () {
+
+ for (unsigned int i = 0; i < tab ->rowCount (); i++) {
+
+ for (unsigned int j = 0; j < tab ->columnCount (); j++) {
+
+ QTableWidgetItem *item = tab ->item(i, j);
+ if (item) {
+
+ QString label = item ->text();
+
+ if (label == "G") tab ->item(i, j) ->setText("GLY");
+ else if (label == "P") tab ->item(i, j) ->setText("PRO");
+ else if (label == "A") tab ->item(i, j) ->setText("ALA");
+ else if (label == "V") tab ->item(i, j) ->setText("VAL");
+ else if (label == "L") tab ->item(i, j) ->setText("LEU");
+ else if (label == "I") tab ->item(i, j) ->setText("ILE");
+ else if (label == "M") tab ->item(i, j) ->setText("MET");
+ else if (label == "C") tab ->item(i, j) ->setText("CYS");
+ else if (label == "F") tab ->item(i, j) ->setText("PHE");
+ else if (label == "Y") tab ->item(i, j) ->setText("TYR");
+ else if (label == "W") tab ->item(i, j) ->setText("TRP");
+ else if (label == "H") tab ->item(i, j) ->setText("HIS");
+ else if (label == "K") tab ->item(i, j) ->setText("LYS");
+ else if (label == "R") tab ->item(i, j) ->setText("ARG");
+ else if (label == "Q") tab ->item(i, j) ->setText("GLN");
+ else if (label == "N") tab ->item(i, j) ->setText("ASN");
+ else if (label == "E") tab ->item(i, j) ->setText("GLU");
+ else if (label == "D") tab ->item(i, j) ->setText("ASP");
+ else if (label == "S") tab ->item(i, j) ->setText("SER");
+ else if (label == "T") tab ->item(i, j) ->setText("THR");
+
+ }
+ }
+ }
+ for (unsigned int j = 0; j < tab ->columnCount (); j ++) {
+ tab ->resizeColumnToContents (j);
+ }
+}
+
+void SequenceMenu::_residue_uid_slot () {
+
+ for (unsigned int i = 0; i < tab ->rowCount (); i++) {
+
+ for (unsigned int j = 0; j < tab ->columnCount (); j++) {
+
+ QTableWidgetItem *item = tab ->item(i, j);
+ if (item) {
+
+ QString label = item ->text();
+
+ if (label == "GLY") tab ->item(i, j) ->setText("G");
+ else if (label == "PRO") tab ->item(i, j) ->setText("P");
+ else if (label == "ALA") tab ->item(i, j) ->setText("A");
+ else if (label == "VAL") tab ->item(i, j) ->setText("V");
+ else if (label == "LEU") tab ->item(i, j) ->setText("L");
+ else if (label == "ILE") tab ->item(i, j) ->setText("I");
+ else if (label == "MET") tab ->item(i, j) ->setText("M");
+ else if (label == "CYS") tab ->item(i, j) ->setText("C");
+ else if (label == "PHE") tab ->item(i, j) ->setText("F");
+ else if (label == "TYR") tab ->item(i, j) ->setText("Y");
+ else if (label == "TRP") tab ->item(i, j) ->setText("W");
+ else if (label == "HIS") tab ->item(i, j) ->setText("H");
+ else if (label == "LYS") tab ->item(i, j) ->setText("K");
+ else if (label == "ARG") tab ->item(i, j) ->setText("R");
+ else if (label == "GLN") tab ->item(i, j) ->setText("Q");
+ else if (label == "ASN") tab ->item(i, j) ->setText("N");
+ else if (label == "GLU") tab ->item(i, j) ->setText("E");
+ else if (label == "ASP") tab ->item(i, j) ->setText("D");
+ else if (label == "SER") tab ->item(i, j) ->setText("S");
+ else if (label == "THR") tab ->item(i, j) ->setText("T");
+}
+ }
+ }
+ for (unsigned int j = 0; j < tab ->columnCount (); j ++) {
+ tab ->resizeColumnToContents (j);
+ }
+}
+
+void SequenceMenu::add_help () {
+ QMenu *about = new QMenu(tr("&Help"), this );
+ Q_CHECK_PTR( about );
+ about -> addAction (_about_action);
+ menuBar () ->addMenu (about);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+DisplayMenu::DisplayMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, false, true) {
+ setWindowTitle ("Display settings");
+
+ ZNAdvancedWidget *main_tab = (ZNAdvancedWidget *) _main_widget;
+
+ display_mode_box = new MyGroupBox (main_tab ->basic_layout(), "Display mode");
+
+ _dsetbutts_gc = new MyGridColumn (display_mode_box ->layout(), 1, 5);
+
+ dset_wireframe = new QPushButton("Wireframe");
+ dset_stick = new QPushButton("Sticks");
+ dset_cpk = new QPushButton("CPK");
+ dset_ball_and_stick = new QPushButton("Ball and Stick");
+ dset_ball_and_line = new QPushButton("Ball and Line");
+
+ _dsetbutts_gc ->gridlayout ->addWidget (dset_wireframe, 1, 1);
+ _dsetbutts_gc ->gridlayout ->addWidget (dset_stick, 1, 2);
+ _dsetbutts_gc ->gridlayout ->addWidget (dset_cpk, 1, 3);
+ _dsetbutts_gc ->gridlayout ->addWidget (dset_ball_and_stick, 1, 4);
+ _dsetbutts_gc ->gridlayout ->addWidget (dset_ball_and_line, 1, 5);
+
+
+ connect (dset_wireframe, SIGNAL( clicked() ), SLOT( set_wireframe() ) );
+ connect (dset_stick, SIGNAL( clicked() ), SLOT( set_stick() ) );
+ connect (dset_cpk, SIGNAL( clicked() ), SLOT( set_cpk() ) );
+ connect (dset_ball_and_stick, SIGNAL( clicked() ), SLOT( set_ballandstick() ) );
+ connect (dset_ball_and_line, SIGNAL( clicked() ), SLOT( set_ballandline() ) );
+
+
+ disp_gc = new MyGridColumn (display_mode_box ->layout(), 1, 2);
+
+ at_disp = new QComboBox ();
+ disp_gc ->gridlayout ->addWidget (at_disp, 1, 1);
+ at_disp->insertItem(0, "No Atoms" );
+ at_disp->insertItem(1, "Spheres" );
+ at_disp->insertItem(2, "CPK Spheres" );
+ at_disp->insertItem(3, "Scaled CPK Spheres" );
+
+
+
+ bo_disp = new QComboBox();
+ disp_gc ->gridlayout ->addWidget (bo_disp, 1, 2);
+ bo_disp->insertItem(0, "No Bonds" );
+ bo_disp->insertItem(1, "Lines" );
+ bo_disp->insertItem(2, "Sticks" );
+ bo_disp -> setCurrentIndex (1);
+
+ backbone_disp = new MyComboBox (display_mode_box ->layout(), "Backbone mode");
+ backbone_disp ->_combo_box ->insertItem(0, "None" );
+ backbone_disp ->_combo_box ->insertItem(1, "Line" );
+ backbone_disp ->_combo_box ->insertItem(2, "Tube" );
+ backbone_disp ->_combo_box ->setCurrentIndex (0);
+
+
+ QWidget *hwid = new QWidget;
+ hwid -> setLayout (new QHBoxLayout ());
+ hwid ->layout () ->setAlignment (Qt::AlignHCenter);
+ main_tab ->basic_layout() ->addWidget (hwid);
+ ok_p = new MyPushButton (hwid ->layout (), "Ok", 0, 100);
+ connect (ok_p ->fbutton, SIGNAL( clicked() ), SLOT( disp_ok() ) );
+
+
+
+
+
+
+
+/*
+ ar_disp = new QComboBox();
+ disp_gc ->gridlayout ->addWidget (ar_disp, 2, 1);
+ ar_disp->insertItem(0, "Aromatic rings" );
+ ar_disp->insertItem(1, "Kekule resonance structures" );
+// ar_disp->insertItem(2, "Aromatic bonds" );
+*/
+
+
+
+
+}
+
+void DisplayMenu::set_wireframe (){
+ set_conf (WIREFRAME);
+}
+
+void DisplayMenu::set_stick (){
+ set_conf (STICK);
+}
+
+void DisplayMenu::set_cpk (){
+ set_conf (CPK);
+}
+
+void DisplayMenu::set_ballandline (){
+ set_conf (BALLANDLINE);
+}
+
+void DisplayMenu::set_ballandstick (){
+ set_conf (BALLANDSTICK);
+}
+
+void DisplayMenu::set_conf (int conf){
+
+ int atom_mode, bond_mode;
+
+
+ switch (conf) {
+ case WIREFRAME:
+ atom_mode = NO_ATOMS;
+ bond_mode = LINES;
+
+ break;
+ case STICK:
+ atom_mode = NO_ATOMS;
+ bond_mode = STICKS;
+
+ break;
+ case CPK:
+ atom_mode = CPK_SPHERES;
+ bond_mode = NO_BONDS;
+ break;
+ case BALLANDSTICK:
+ atom_mode = SCALED_CPK_SPHERES;
+ bond_mode = STICKS;
+ break;
+
+ case BALLANDLINE:
+ atom_mode = SPHERES;
+ bond_mode = LINES;
+ break;
+
+ default:
+ atom_mode = NO_ATOMS;
+ bond_mode = LINES;
+
+ }
+
+ at_disp->setCurrentIndex (atom_mode);
+ bo_disp->setCurrentIndex (bond_mode);
+
+}
+
+void DisplayMenu::disp_ok () {
+ for (unsigned int i=0;i<at_opts.size();i++) at_opts[i]->set ();
+
+// _data -> ddwin ->gl ->aromatic_display_style = style_str_to_i (ar_disp->currentText().toStdString());
+ int at_st = style_str_to_i (at_disp->currentText().toStdString());
+ int bo_st = style_str_to_i (bo_disp->currentText().toStdString());
+ int backbone_st = backbone_disp ->_combo_box ->currentIndex();
+
+ if (_data -> ddwin ->current_target) {
+ bool ext = false;
+ if (_data -> ddwin ->target_molecule -> multi) {
+ Database_molecule *dm = (Database_molecule *) _data -> ddwin ->target_molecule;
+ if (dm -> database -> has_extend_enabled ()) ext = true;
+ }
+ if (!ext) {
+ _data -> actions -> change_display_style (_data -> ddwin ->target_molecule, at_st, bo_st, backbone_st);
+ }
+ else {
+ Database_molecule *dm = (Database_molecule *) _data -> ddwin ->target_molecule;
+ Database *dat = dm -> database;
+ _data -> actions -> change_display_style (dat, at_st, bo_st, backbone_st);
+ }
+
+
+ }
+}
+
+
+int DisplayMenu::style_str_to_i (string style){
+
+
+ if (style=="No Atoms") return NO_ATOMS;
+ else if (style=="Spheres") return SPHERES;
+ else if (style=="CPK Spheres") return CPK_SPHERES;
+ else if (style=="Scaled CPK Spheres") return SCALED_CPK_SPHERES;
+
+ else if (style=="No Bonds") return NO_BONDS;
+ else if (style=="Lines") return LINES;
+ else if (style=="Sticks") return STICKS;
+
+ else if (style=="Aromatic rings") return AROMATIC_RINGS;
+ else if (style=="Kekule resonance structures") return KEKULE;
+// else if (style=="Aromatic bonds") return AROMATIC_BONDS;
+ return 0;
+
+
+}
+
+
+void DDWin::set_popups (){
+
+/*
+ dsetpopup = new QWidget ();
+ dsetpopup->setWindowTitle ("Display Settings");
+
+
+// dsetpopup->setFrameStyle( Q3Frame::WinPanel|Q3Frame::Raised );
+ QVBoxLayout *dsetpopupv = new QVBoxLayout (dsetpopup);
+ dsetpopup->setMinimumSize (500, 250);
+ //
+
+
+ QHBoxLayout *dsetbutts = new QHBoxLayout ();
+ dsetpopupv -> addLayout (dsetbutts);
+ QPushButton *dset_wireframe = new QPushButton("Wireframe");
+ QPushButton *dset_stick = new QPushButton("Sticks");
+ QPushButton *dset_cpk = new QPushButton("CPK");
+ QPushButton *dset_ball_and_stick = new QPushButton("Ball and Stick");
+ QPushButton *dset_ball_and_line = new QPushButton("Ball and Line");
+
+ dsetbutts -> addWidget (dset_wireframe);
+ dsetbutts -> addWidget (dset_stick);
+ dsetbutts -> addWidget (dset_cpk);
+ dsetbutts -> addWidget (dset_ball_and_stick);
+ dsetbutts -> addWidget (dset_ball_and_line);
+
+
+
+
+ connect (dset_wireframe, SIGNAL( clicked() ), gl, SLOT( set_wireframe() ) );
+ connect (dset_stick, SIGNAL( clicked() ), gl, SLOT( set_stick() ) );
+ connect (dset_cpk, SIGNAL( clicked() ), gl, SLOT( set_cpk() ) );
+ connect (dset_ball_and_stick, SIGNAL( clicked() ), gl, SLOT( set_ballandstick() ) );
+ connect (dset_ball_and_line, SIGNAL( clicked() ), gl, SLOT( set_ballandline() ) );
+
+ QHBoxLayout *mainhbox = new QHBoxLayout ();
+ dsetpopupv -> addLayout (mainhbox);
+
+
+ ar_disp = new QComboBox();
+ ar_disp->insertItem(0, "Aromatic rings" );
+ ar_disp->insertItem(1, "Kekule resonance structures" );
+
+ ar_disp -> setCurrentIndex (gl -> aromatic_display_style);
+// ar_disp->insertItem(2, "Aromatic bonds" );
+
+ dsetpopupv -> addWidget (ar_disp);
+
+
+ backbone_disp = new QComboBox();
+ backbone_disp->insertItem(0, "None" );
+ backbone_disp->insertItem(1, "Line" );
+ backbone_disp->insertItem(2, "Tube" );
+
+ backbone_disp -> setCurrentIndex (0);
+ // ar_disp->insertItem(2, "Aromatic bonds" );
+
+ dsetpopupv -> addWidget (backbone_disp);
+
+
+ QHBoxLayout *butt2 = new QHBoxLayout ();
+ dsetpopupv -> addLayout (butt2);
+ QVBoxLayout *atomsvb = new QVBoxLayout ();
+ mainhbox -> addLayout (atomsvb);
+ QVBoxLayout *bondsvb = new QVBoxLayout ();
+ mainhbox -> addLayout (bondsvb);
+
+ at_disp = new QComboBox ();
+ atomsvb -> addWidget (at_disp);
+ at_disp->insertItem(0, "No Atoms" );
+ at_disp->insertItem(1, "Spheres" );
+ at_disp->insertItem(2, "CPK Spheres" );
+ at_disp->insertItem(3, "Scaled CPK Spheres" );
+
+
+
+ bo_disp = new QComboBox();
+ bondsvb -> addWidget (bo_disp);
+ bo_disp->insertItem(0, "No Bonds" );
+ bo_disp->insertItem(1, "Lines" );
+ bo_disp->insertItem(2, "Sticks" );
+ bo_disp -> setCurrentIndex (1);
+
+
+ at_opts.push_back (new MyFloatEditLine (atomsvb, "Sphere radius", gl->sphere_radius));
+ at_opts.push_back (new MyFloatEditLine (bondsvb, "Stick radius", gl->stick_rad));
+ at_opts.push_back (new MyFloatEditLine (bondsvb, "Double ZNBond inter Distance", gl->double_bond_inter_distance));
+ at_opts.push_back (new MyFloatEditLine (bondsvb, "Aromatic ZNBond inter Distance", gl->aromatic_bond_inter_distance));
+ at_opts.push_back (new MyFloatEditLine (atomsvb, "VdW scale", gl->vdw_scale));
+// at_opts.push_back (new MyFloatEditLine (atomsvb, "VdW Precision", gl->vdw_precision));
+ at_opts.push_back (new MyFloatEditLine (bondsvb, "Double bond scale", gl->double_bond_stick_radius_scale));
+
+ QPushButton *ok = new QPushButton("Ok");
+ butt2 -> addWidget (ok);
+ connect (ok, SIGNAL( clicked() ), SLOT( disp_ok() ) );
+
+*/
+
+
+ b_color_menu = new BackboneColorMenu (0, data);
+ go_color_menu = new GraphicalObjectsColorMenu (0, data);
+ color_menu = new ColorMenu (0, this);
+ color_settings_menu = new ColorSettingsMenu (0, this);
+ builder_menu = new BuilderMenu (0, data, builder);
+
+ pref_menu = new PrefMenu (0, data);
+
+ haptic_menu = new HapticMenu (0, data);
+ gamess_menu = new GamessMenu (0, data);
+ plants_menu = new PLANTSMenu (0, data);
+ display_menu = new DisplayMenu (0, data);
+ sequence_menu = new SequenceMenu (0, data);
+ docking_menu = new DockingMenu (0, data);
+ thread_menu = new ThreadMenu (0, data);
+ iodevice_menu = new IODeviceMenu (0, data);
+ clicked_atom_menu = new Clicked_atomMenu (0, data);
+ surface_menu = new SurfaceMenu (0, data);
+ sphere_menu = new SphereMenu (0, data);
+ conformers_menu = new ConformersMenu (0, data);
+ map_menu = new MapMenu (0, data);
+ graphical_objects_menu = new GraphicalObjectsMenu (0, this);
+ DDsettings_menu = new DDSettingsMenu (0, this);
+
+
+}
+
+
+
+void SurfaceMenu::draw_surface () {
+
+ if (data -> ddwin -> current_target) {
+ ZNMolecule *mol = data -> ddwin -> target_molecule;
+ mesh = (gtype->currentIndex ()==1);
+ float a = ((float) alpha)/100;
+ surface = new Surface ();
+ surface -> near_to_dist = near_to_f;
+ ZNMolecule *neartm = NULL;
+ if (near_to ->currentIndex ()!= 0) neartm = data ->ddwin ->molecules[near_to ->currentIndex ()];
+ else neartm = 0;
+ surface -> set_molecule (mol, neartm);
+ surface -> lst = data -> ddwin -> gl -> new_list ();
+ surface -> name = string ("Surface ") + mol -> GetTitle ();
+ surface -> mesh = mesh;
+
+
+ SurfaceThread *thread = new SurfaceThread (0, surface, data -> ddwin);
+
+ thread -> alph = a;
+ thread -> res = res;
+ data ->ddwin ->run_thread (thread);
+ //thread -> start ();
+
+
+ connect (thread, SIGNAL (finished ()), this, SLOT (add_surface ()));
+
+ }
+}
+
+
+
+void SurfaceMenu::add_surface () {
+ surface -> render ();
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (surface, data -> ddwin);
+ data -> ddwin -> execute (command);
+ data ->ddwin ->go_color_menu ->set_target(surface);
+ data ->ddwin ->go_color_menu ->display ();
+}
+
+
+
+SurfaceMenu::SurfaceMenu (QWidget *parent, Data *dat )
+ : QWidget(parent)
+{
+ near_to_f = 4.f;
+ data = dat;
+ // molecule = mol;
+ res = data->ddwin->gl->surface_resolution;
+
+
+ QVBoxLayout *vbox = new QVBoxLayout (this);
+ // this->setMinimumSize (500, 250);
+ // this->setMaximumSize (500, 250);
+ // this->setMinimumSize (500, 250);
+ // this->setMaximumSize (500, 250);
+ this->setWindowTitle("Surfaces");
+
+ resolution = new MyFloatEditLine (vbox, "Resolution", res);
+
+ stype = new QComboBox();
+ vbox -> addWidget (stype);
+ stype->insertItem(0, "Connolly" );
+// stype->insertItem(1, "Gaussian contact" );
+
+
+ gtype = new QComboBox();
+ vbox -> addWidget (gtype);
+ gtype->insertItem(0, "Surface" );
+ gtype->insertItem(1, "Mesh" );
+
+ near_to_dle = new MyFloatEditLine (vbox, "Near to", near_to_f);
+ near_to = new QComboBox ();
+ vbox -> addWidget (near_to);
+
+// QSlider *slider = new QSlider( Horizontal, this, "slider" );
+ // alpha_p = new MyFloatEditLine (vbox, "Opacity", alpha);
+// connect (slider, SIGNAL(valueChanged(int)), alpha_p, SLOT(set_value(int)) );
+// connect ();
+ alpha_s = new MySlider (vbox, "Opacity",alpha, 0, 100);
+ alpha_s->slider->setValue (100);
+ QPushButton *ok = new QPushButton ("Ok");
+ vbox -> addWidget (ok);
+ connect (ok, SIGNAL (clicked ()) ,SLOT (draw_surface ()));
+ connect (data -> ddwin, SIGNAL (targets_updated ()), this, SLOT (update_near_to ()));
+ //update_near_to ();
+
+}
+
+
+
+void SurfaceMenu::update_near_to () {
+ near_to ->clear ();
+ for (unsigned int i = 0; i < data -> ddwin -> target ->count (); i++) {
+ near_to ->insertItem (i, data -> ddwin -> target ->itemText (i));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+
+MapMenu::MapMenu (QWidget *parent, Data *dat) : ZNMenu (parent, dat, true, true) {
+ _r = 10.; _resolution = 1.5; _threshold = 0.;
+
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (main_tab, "Map");
+ add_menu ();
+ add_help ();
+ _site_box = new MyGroupBox (main_tab ->layout (), "Binding site options");
+ _site_x_el = new MyFloatEditLine (_site_box ->layout (), "Site center X:", _x, -1000, 1000);
+ _site_y_el = new MyFloatEditLine (_site_box ->layout (), "Site center Y:", _y, -1000, 1000);
+ _site_z_el = new MyFloatEditLine (_site_box ->layout (), "site center Z:", _z, -1000, 1000);
+ _site_r_el = new MyFloatEditLine (_site_box ->layout (), "Site radius:", _r, 0, 100);
+ _threshold_el = new MyFloatEditLine (_site_box ->layout (), "threshold:", _threshold, -1000, 1000);
+ _resolution_el = new MyFloatEditLine (_site_box ->layout (), "resolution:", _resolution, 0, 100);
+ _name_el = new MyLineEdit (_site_box ->layout (), "Name: ");
+ _compute_map_bt = new MyPushButton (main_tab ->layout (), "Compute Map");
+ _type_cb = new MyComboBox (_site_box ->layout (), "Potential:");
+ _type_cb ->combo_box () ->insertItem (-1, "Chemscore Lipophilic potential", 0);
+ _type_cb ->combo_box () ->insertItem (1, "Chemscore HB acceptor potential", 1);
+ _type_cb ->combo_box () ->insertItem (2, "Chemscore HB donor potential", 2);
+// _type_cb ->combo_box () ->insertItem (3, "Electrostatic Potential", 3);
+
+ MyCompleteColorSettings *_solid_color_button = new MyCompleteColorSettings (main_tab ->layout (), _solid_color);
+ connect (_compute_map_bt ->fbutton, SIGNAL( clicked() ), SLOT( compute_map_slot() ) );
+}
+
+bool MapMenu::display_requirements_met () {
+ bool b = check_for_a_set_target ();
+ if (b) {
+ ZNMolecule *mol = _data ->ddwin ->target_molecule;
+ vect c = get_center (mol);
+ _site_x_el ->set_value (c.x ());
+ _site_y_el ->set_value (c.y ());
+ _site_z_el ->set_value (c.z ());
+ string q = string ("Map ") + string (_data ->ddwin ->target_molecule ->GetTitle ());
+ _name_el ->linedit ->setText(q.c_str ());
+ }
+ return b;
+};
+
+void MapMenu::compute_map_slot () {
+ string name = _name_el ->linedit ->text ().toStdString ();
+ bool found = false;
+ for (unsigned int i = 0; i < _data ->ddwin ->graphical_objects.size (); i++) {
+ if (_data ->ddwin ->graphical_objects[i] -> is_map () && _data ->ddwin ->graphical_objects[i] -> name == name) {
+ map = (Map *) _data ->ddwin ->graphical_objects[i];
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ map = new Map ();
+ map ->solid_color = _solid_color;
+ map -> lst = _data -> ddwin -> gl -> new_list ();
+ map ->molecule = _data ->ddwin ->target_molecule;
+ map ->site_center = vect (_x, _y, _z);
+ map ->site_radius = _r;
+ map ->resolution = _resolution;
+ map ->name = name;
+ map ->type = _type_cb -> currentData ().toInt ();
+
+ }
+
+ // map -> name = string ("Map");
+
+ map ->threshold = _threshold;
+
+
+ MapThread *thread = new MapThread (0, map, _data -> ddwin);
+
+ _data ->ddwin ->run_thread (thread);
+
+ connect (thread, SIGNAL (finished ()), this, SLOT (add_map ()));
+}
+
+
+void MapMenu::add_map () {
+ map -> render ();
+ bool found = false;
+ for (unsigned int i = 0; i < _data ->ddwin ->graphical_objects.size (); i ++) {
+ if (map == (Map *) _data ->ddwin ->graphical_objects[i]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (map, _data -> ddwin);
+ _data -> ddwin -> execute (command);
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////////
+
+
+SphereMenu::SphereMenu (QWidget *parent, Data *dat )
+ : QWidget(parent)
+{
+ data = dat;
+ // molecule = mol;
+
+ x = 0; y=0, z=0;
+ QVBoxLayout *vbox = new QVBoxLayout (this);
+
+ setWindowTitle("Spheres");
+
+ cent_x = new MyFloatEditLine (vbox, "Center x", x);
+ cent_y = new MyFloatEditLine (vbox, "Center y", y);
+ cent_z = new MyFloatEditLine (vbox, "Center z", z);
+ rad = new MyFloatEditLine (vbox, "Radius", radius);
+ alpha_s = new MySlider (vbox, "Opacity",alpha, 0, 100);
+ alpha_s->slider->setValue (100);
+ MyColorButton *colorbutt = new MyColorButton (vbox, col);
+
+
+ QPushButton *ok = new QPushButton ("Ok");
+ vbox -> addWidget (ok);
+ connect (ok, SIGNAL (clicked ()) ,SLOT (draw_sphere ()));
+}
+
+
+
+void SphereMenu::draw_sphere () {
+
+ float a = (float) alpha/100;
+ col.setAlphaF (a);
+ Sphere *sphere = new Sphere ();
+ sphere -> lst = data -> ddwin -> gl -> new_list ();
+ sphere -> name = string ("Sphere");
+ sphere -> set_center (vect (x, y, z));
+ sphere -> set_radius (radius);
+ sphere -> set_color (col);
+ sphere -> render ();
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (sphere, data -> ddwin);
+ data -> ddwin -> execute (command);
+}
+
+
+///////////////////////////////////////////////////////////////////////
+
+
+
+
+/*
+void SphereMenu::draw_sphere () {
+
+ float a = alpha/100;
+ col.setAlphaF (a);
+ Sphere *sphere = new Sphere ();
+ sphere -> list = data -> ddwin -> gl -> new_list ();
+ sphere -> name = string ("Sphere");
+ sphere -> set_center (center);
+ sphere -> set_radius (radius);
+ sphere -> set_color (col);
+ sphere -> render ();
+ CreateGraphicalObjectCommand *command = new CreateGraphicalObjectCommand (sphere, data -> ddwin);
+ data -> ddwin -> execute (command);
+}
+*/
+
+///////////////////////////////////////////////////////////////////////
+
+BuilderMenu::BuilderMenu (QWidget *parent, Data *dat, Builder *build) : ZNMenu (parent, dat, true, true) {
+ setWindowTitle ("Builder");
+
+ builder = build;
+
+ ZNAdvancedWidget *main_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (main_tab, "Basic");
+
+ _basic_gc = new MyGridColumn (main_tab ->basic_layout (), 3, 3);
+
+ _atoms_box = new MyGroupBox ("Atoms");
+ _basic_gc ->gridlayout ->addWidget (_atoms_box, 1, 1);
+
+ _atoms_gc = new MyGridColumn (_atoms_box ->layout (), 1, 10);
+
+ _C = new MyPushButton ("C", 0, 30);
+ connect (_C ->fbutton, SIGNAL (clicked ()) ,SLOT (add_C ()));
+ _atoms_gc ->gridlayout ->addWidget (_C, 1, 1);
+
+ _N = new MyPushButton ("N", 0, 30);
+ connect (_N ->fbutton, SIGNAL (clicked ()) ,SLOT (add_N ()));
+ _atoms_gc ->gridlayout ->addWidget (_N, 1, 2);
+
+ _O = new MyPushButton ("O", 0, 30);
+ connect (_O ->fbutton, SIGNAL (clicked ()) ,SLOT (add_O ()));
+ _atoms_gc ->gridlayout ->addWidget (_O, 1, 3);
+
+ _F = new MyPushButton ("F", 0, 30);
+ connect (_F ->fbutton, SIGNAL (clicked ()) ,SLOT (add_F ()));
+ _atoms_gc ->gridlayout ->addWidget (_F, 2, 1);
+
+// _H = new MyPushButton ("H", 0, 30);
+// connect (_H ->fbutton, SIGNAL (clicked ()) ,SLOT (add_H ()));
+// _atoms_gc ->gridlayout ->addWidget (_H, 1, 5);
+
+ _P = new MyPushButton ("P", 0, 30);
+ connect (_P ->fbutton, SIGNAL (clicked ()) ,SLOT (add_P ()));
+ _atoms_gc ->gridlayout ->addWidget (_P, 2, 2);
+
+ _S = new MyPushButton ("S", 0, 30);
+ connect (_S ->fbutton, SIGNAL (clicked ()) ,SLOT (add_S ()));
+ _atoms_gc ->gridlayout ->addWidget (_S, 2, 3);
+
+ _Cl = new MyPushButton ("Cl", 0, 30);
+ connect (_Cl ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cl ()));
+ _atoms_gc ->gridlayout ->addWidget (_Cl, 3, 1);
+
+ _I = new MyPushButton ("I", 0, 30);
+ connect (_I ->fbutton, SIGNAL (clicked ()) ,SLOT (add_S ()));
+ _atoms_gc ->gridlayout ->addWidget (_I, 3, 2);
+
+ _Br = new MyPushButton ("Br", 0, 30);
+ connect (_Br ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Br ()));
+ _atoms_gc ->gridlayout ->addWidget (_Br, 3, 3);
+
+
+ _bonds_box = new MyGroupBox ("Bonds");
+ _basic_gc ->gridlayout ->addWidget (_bonds_box, 1, 2);
+
+ _bonds_gc = new MyGridColumn (_bonds_box ->layout (), 4, 1);
+
+ _single_bond_b = new MyPushButton ("Single bond", 0, 120);
+ connect (_single_bond_b ->fbutton, SIGNAL (clicked ()) ,SLOT (single_bond ()));
+ _bonds_gc ->gridlayout ->addWidget (_single_bond_b, 1, 1);
+
+ _double_bond_b = new MyPushButton ("Double bond", 0, 120);
+ connect (_double_bond_b ->fbutton, SIGNAL (clicked ()) ,SLOT (double_bond ()));
+ _bonds_gc ->gridlayout ->addWidget (_double_bond_b, 2, 1);
+
+ _triple_bond_b = new MyPushButton ("Triple bond", 0, 120);
+ connect (_triple_bond_b ->fbutton, SIGNAL (clicked ()) ,SLOT (triple_bond ()));
+ _bonds_gc ->gridlayout ->addWidget (_triple_bond_b, 3, 1);
+
+// _no_bond_b = new MyPushButton ("Delete bond", 0, 100);
+// connect (_no_bond_b ->fbutton, SIGNAL (clicked ()) ,SLOT (no_bond ()));
+// _bonds_gc ->gridlayout ->addWidget (_no_bond_b, 4, 1);
+
+
+ _rings_box = new MyGroupBox ("Rings");
+ _basic_gc ->gridlayout ->addWidget (_rings_box, 1, 3);
+
+ _rings_gc = new MyGridColumn (_rings_box ->layout (), 3, 3);
+
+ _ring3_b = new MyPushButton ("", 0, 30);
+ connect (_ring3_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring3 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring3_b, 1, 1);
+ _ring3_b ->fbutton ->setIcon (QIcon (":icons/ring3.png"));
+
+ _ring4_b = new MyPushButton ("", 0, 30);
+ connect (_ring4_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring4 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring4_b, 1, 2);
+ _ring4_b ->fbutton ->setIcon (QIcon (":icons/ring4.png"));
+
+ _ring5_b = new MyPushButton ("", 0, 30);
+ connect (_ring5_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring5 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring5_b, 1, 3);
+ _ring5_b ->fbutton ->setIcon (QIcon (":icons/ring5.png"));
+
+ _ring6_b = new MyPushButton ("", 0, 30);
+ connect (_ring6_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring6 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring6_b, 2, 1);
+ _ring6_b ->fbutton ->setIcon (QIcon (":icons/ring6.png"));
+
+ _ring7_b = new MyPushButton ("", 0, 30);
+ connect (_ring7_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring7 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring7_b, 2, 2);
+ _ring7_b ->fbutton ->setIcon (QIcon (":icons/ring7.png"));
+
+ _ring8_b = new MyPushButton ("", 0, 30);
+ connect (_ring8_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_ring8 ()));
+ _rings_gc ->gridlayout ->addWidget (_ring8_b, 2, 3);
+ _ring8_b ->fbutton ->setIcon (QIcon (":icons/ring8.png"));
+
+ _furanO_b = new MyPushButton ("", 0, 30);
+ connect (_furanO_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_furanO ()));
+ _rings_gc ->gridlayout ->addWidget (_furanO_b, 3, 1);
+ _furanO_b ->fbutton ->setIcon (QIcon (":icons/furanO.png"));
+
+ _furan_b = new MyPushButton ("", 0, 30);
+ connect (_furan_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_furan ()));
+ _rings_gc ->gridlayout ->addWidget (_furan_b, 3, 2);
+ _furan_b ->fbutton ->setIcon (QIcon (":icons/furan.png"));
+
+ _benzene_b = new MyPushButton ("", 0, 30);
+ connect (_benzene_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_benzene ()));
+ _rings_gc ->gridlayout ->addWidget (_benzene_b, 3, 3);
+ _benzene_b ->fbutton ->setIcon (QIcon (":icons/benzene.png"));
+
+
+ _fragments_box = new MyGroupBox ("Fragments");
+ _basic_gc ->gridlayout ->addWidget (_fragments_box, 1, 4);
+
+ _fragments_gc = new MyGridColumn (_fragments_box ->layout (), 3, 3);
+
+ _CO_b = new MyPushButton ("C=O", 0, 40);
+ connect (_CO_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_CO ()));
+ _fragments_gc ->gridlayout ->addWidget (_CO_b, 1, 1);
+// _CO_b ->fbutton ->setIcon (QIcon (":icons/CO.png"));
+
+ _NCO_b = new MyPushButton ("NC=O", 0, 40);
+ connect (_NCO_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_NCO ()));
+ _fragments_gc ->gridlayout ->addWidget (_NCO_b, 1, 2);
+// _NCO_b ->fbutton ->setIcon (QIcon (":icons/NCO.png"));
+
+ _COOH_b = new MyPushButton ("COOH", 0, 40);
+ connect (_COOH_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_COOH ()));
+ _fragments_gc ->gridlayout ->addWidget (_COOH_b, 1, 3);
+// _COOH_b ->fbutton ->setIcon (QIcon (":icons/COOH.png"));
+
+ _CCd_b = new MyPushButton ("C=C", 0, 40);
+ connect (_CCd_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_CCd ()));
+ _fragments_gc ->gridlayout ->addWidget (_CCd_b, 2, 1);
+// _CCd_b ->fbutton ->setIcon (QIcon (":icons/CCd.png"));
+
+ _CCt_b = new MyPushButton ("C#C", 0, 40);
+ connect (_CCt_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_CCt ()));
+ _fragments_gc ->gridlayout ->addWidget (_CCt_b, 2, 2);
+// _CCt_b ->fbutton ->setIcon (QIcon (":icons/CCt.png"));
+
+ _CN_b = new MyPushButton ("C#N", 0, 40);
+ connect (_CN_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_CN ()));
+ _fragments_gc ->gridlayout ->addWidget (_CN_b, 2, 3);
+// _CN_b ->fbutton ->setIcon (QIcon (":icons/CN.png"));
+
+ _NO2_b = new MyPushButton ("NO2", 0, 40);
+ connect (_NO2_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_NO2 ()));
+ _fragments_gc ->gridlayout ->addWidget (_NO2_b, 3, 1);
+// _NO2_b ->fbutton ->setIcon (QIcon (":icons/NO2.png"));
+
+ _SO2_b = new MyPushButton ("SO2", 0, 40);
+ connect (_SO2_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_SO2 ()));
+ _fragments_gc ->gridlayout ->addWidget (_SO2_b, 3, 2);
+// _SO2_b ->fbutton ->setIcon (QIcon (":icons/SO2.png"));
+
+ _PO3_b = new MyPushButton ("PO3", 0, 40);
+ connect (_PO3_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_PO3 ()));
+ _fragments_gc ->gridlayout ->addWidget (_PO3_b, 3, 3);
+// _PO3_b ->fbutton ->setIcon (QIcon (":icons/PO3.png"));
+
+
+ _smiles_box = new MyGroupBox (main_tab ->basic_layout (), "Smiles");
+
+ _smiles_tc = new MyTwoColumn (_smiles_box ->layout () );
+
+ smiles = new QLineEdit( this);
+ _smiles_tc ->left_layout () -> addWidget (smiles);
+
+ _smiles_b = new MyPushButton (_smiles_tc ->right_layout (), "Add smiles");
+ connect (_smiles_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_smiles ()));
+
+ _del_box = new MyGroupBox (main_tab ->basic_layout (), "Delete");
+
+
+// Groups
+ ZNAdvancedWidget *groups_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (groups_tab, "Groups");
+
+ _aminoacids_box = new MyGroupBox (groups_tab ->basic_layout (), "Amino acids");
+
+ _aminoacids_gc = new MyGridColumn (_aminoacids_box ->layout (), 2, 10);
+
+ _Ala_b = new MyPushButton ("Ala", 0, 35);
+ connect (_Ala_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ala ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Ala_b, 1, 1);
+
+ _Arg_b = new MyPushButton ("Arg", 0, 35);
+ connect (_Arg_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Arg ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Arg_b, 1, 2);
+
+ _Asn_b = new MyPushButton ("Asn", 0, 35);
+ connect (_Asn_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Asn ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Asn_b, 1, 3);
+
+ _Asp_b = new MyPushButton ("Asp", 0, 35);
+ connect (_Asp_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Asp ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Asp_b, 1, 4);
+
+ _Cys_b = new MyPushButton ("Cys", 0, 35);
+ connect (_Cys_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cys ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Cys_b, 1, 5);
+
+ _Glu_b = new MyPushButton ("Glu", 0, 35);
+ connect (_Glu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Glu ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Glu_b, 1, 6);
+
+ _Cln_b = new MyPushButton ("Cln", 0, 35);
+ connect (_Cln_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cln ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Cln_b, 1, 7);
+
+ _Gly_b = new MyPushButton ("Gly", 0, 35);
+ connect (_Gly_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Gly ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Gly_b, 1, 8);
+
+ _His_b = new MyPushButton ("His", 0, 35);
+ connect (_His_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_His ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_His_b, 1, 9);
+
+ _Ile_b = new MyPushButton ("Ile", 0, 35);
+ connect (_Ile_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ile ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Ile_b, 1, 10);
+
+ _Leu_b = new MyPushButton ("Leu", 0, 35);
+ connect (_Leu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Leu ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Leu_b, 2, 1);
+
+ _Lys_b = new MyPushButton ("Lys", 0, 35);
+ connect (_Lys_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Lys ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Lys_b, 2, 2);
+
+ _Met_b = new MyPushButton ("Met", 0, 35);
+ connect (_Met_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Met ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Met_b, 2, 3);
+
+ _Phe_b = new MyPushButton ("Phe", 0, 35);
+ connect (_Phe_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Phe ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Phe_b, 2, 4);
+
+ _Pro_b = new MyPushButton ("Pro", 0, 35);
+ connect (_Pro_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pro ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Pro_b, 2, 5);
+
+ _Ser_b = new MyPushButton ("Ser", 0, 35);
+ connect (_Ser_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ser ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Ser_b, 2, 6);
+
+ _Thr_b = new MyPushButton ("Thr", 0, 35);
+ connect (_Thr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Thr ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Thr_b, 2, 7);
+
+ _Trp_b = new MyPushButton ("Trp", 0, 35);
+ connect (_Trp_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Trp ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Trp_b, 2, 8);
+
+ _Tyr_b = new MyPushButton ("Tyr", 0, 35);
+ connect (_Tyr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Tyr ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Tyr_b, 2, 9);
+
+ _Val_b = new MyPushButton ("Val", 0, 35);
+ connect (_Val_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Val ()));
+ _aminoacids_gc ->gridlayout ->addWidget (_Val_b, 2, 10);
+
+
+ _heterocycles_box = new MyGroupBox (groups_tab ->basic_layout (), "Heterocycles");
+
+ _nucleotides_box = new MyGroupBox (groups_tab ->basic_layout (), "Nucleotides");
+
+
+// Periodic table
+ ZNAdvancedWidget *periodictable_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (periodictable_tab, "Periodic table");
+
+ _periodictable_gc = new MyGridColumn (periodictable_tab ->basic_layout (), 9, 18);
+
+ QFont font("Helvetica", 8);
+
+ _H_b = new MyPushButton ("H", 18, 24);
+ connect (_H_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_H ()));
+ _periodictable_gc ->gridlayout ->addWidget (_H_b, 1, 1);
+
+ _He_b = new MyPushButton ("He", 18, 24);
+ connect (_He_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_He ()));
+ _periodictable_gc ->gridlayout ->addWidget (_He_b, 1, 18);
+
+ _Li_b = new MyPushButton ("Li", 18, 24);
+ connect (_Li_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Li ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Li_b, 2, 1);
+
+ _Be_b = new MyPushButton ("Be", 18, 24);
+ connect (_Be_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Be ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Be_b, 2, 2);
+
+ _B_b = new MyPushButton ("B", 18, 24);
+ connect (_B_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_B ()));
+ _periodictable_gc ->gridlayout ->addWidget (_B_b, 2, 13);
+
+ _C_b = new MyPushButton ("C", 18, 24);
+ connect (_C_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_C ()));
+ _periodictable_gc ->gridlayout ->addWidget (_C_b, 2, 14);
+
+ _N_b = new MyPushButton ("N", 18, 24);
+ connect (_N_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_N ()));
+ _periodictable_gc ->gridlayout ->addWidget (_N_b, 2, 15);
+
+ _O_b = new MyPushButton ("O", 18, 24);
+ connect (_O_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_O ()));
+ _periodictable_gc ->gridlayout ->addWidget (_O_b, 2, 16);
+
+ _F_b = new MyPushButton ("F", 18, 24);
+ connect (_F_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_F ()));
+ _periodictable_gc ->gridlayout ->addWidget (_F_b, 2, 17);
+
+ _Ne_b = new MyPushButton ("Ne", 18, 24);
+ connect (_Ne_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ne ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ne_b, 2, 18);
+
+ _Na_b = new MyPushButton ("Na", 18, 24);
+ connect (_Na_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Na ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Na_b, 3, 1);
+
+ _Mg_b = new MyPushButton ("Mg", 18, 24);
+ connect (_Mg_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Mg ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Mg_b, 3, 2);
+
+ _Al_b = new MyPushButton ("Al", 18, 24);
+ connect (_Al_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Al ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Al_b, 3, 13);
+
+ _Si_b = new MyPushButton ("Si", 18, 24);
+ connect (_Si_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Si ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Si_b, 3, 14);
+
+ _P_b = new MyPushButton ("P", 18, 24);
+ connect (_P_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_P ()));
+ _periodictable_gc ->gridlayout ->addWidget (_P_b, 3, 15);
+
+ _S_b = new MyPushButton ("S", 18, 24);
+ connect (_S_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_S ()));
+ _periodictable_gc ->gridlayout ->addWidget (_S_b, 3, 16);
+
+ _Cl_b = new MyPushButton ("Cl", 18, 24);
+ connect (_Cl_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cl ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cl_b, 3, 17);
+
+ _Ar_b = new MyPushButton ("Ar", 18, 24);
+ connect (_Ar_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ar ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ar_b, 3, 18);
+
+ _K_b = new MyPushButton ("K", 18, 24);
+ connect (_K_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_K ()));
+ _periodictable_gc ->gridlayout ->addWidget (_K_b, 4, 1);
+
+ _Ca_b = new MyPushButton ("Ca", 18, 24);
+ connect (_Ca_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ca ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ca_b, 4, 2);
+
+ _Sc_b = new MyPushButton ("Sc", 18, 24);
+ connect (_Sc_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sc ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sc_b, 4, 3);
+
+ _Ti_b = new MyPushButton ("Ti", 18, 24);
+ connect (_Ti_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ti ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ti_b, 4, 4);
+
+ _V_b = new MyPushButton ("V", 18, 24);
+ connect (_V_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_V ()));
+ _periodictable_gc ->gridlayout ->addWidget (_V_b, 4, 5);
+
+ _Cr_b = new MyPushButton ("Cr", 18, 24);
+ connect (_Cr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cr_b, 4, 6);
+
+ _Mn_b = new MyPushButton ("Mn", 18, 24);
+ connect (_Mn_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Mn ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Mn_b, 4, 7);
+
+ _Fe_b = new MyPushButton ("Fe", 18, 24);
+ connect (_Fe_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Fe ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Fe_b, 4, 8);
+
+ _Co_b = new MyPushButton ("Co", 18, 24);
+ connect (_Co_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Co ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Co_b, 4, 9);
+
+ _Ni_b = new MyPushButton ("Ni", 18, 24);
+ connect (_Ni_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ni ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ni_b, 4, 10);
+
+ _Cu_b = new MyPushButton ("Cu", 18, 24);
+ connect (_Cu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cu ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cu_b, 4, 11);
+
+ _Zn_b = new MyPushButton ("Zn", 18, 24);
+ connect (_Zn_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Zn ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Zn_b, 4, 12);
+
+ _Ga_b = new MyPushButton ("Ga", 18, 24);
+ connect (_Ga_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ga ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ga_b, 4, 13);
+
+ _Ge_b = new MyPushButton ("Ge", 18, 24);
+ connect (_Ge_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ge ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ge_b, 4, 14);
+
+ _As_b = new MyPushButton ("As", 18, 24);
+ connect (_As_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_As ()));
+ _periodictable_gc ->gridlayout ->addWidget (_As_b, 4, 15);
+
+ _Se_b = new MyPushButton ("Se", 18, 24);
+ connect (_Se_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Se ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Se_b, 4, 16);
+
+ _Br_b = new MyPushButton ("Br", 18, 24);
+ connect (_Br_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Br ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Br_b, 4, 17);
+
+ _Kr_b = new MyPushButton ("Kr", 18, 24);
+ connect (_Kr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Kr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Kr_b, 4, 18);
+
+ _Rb_b = new MyPushButton ("Rb", 18, 24);
+ connect (_Rb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Rb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Rb_b, 5, 1);
+
+ _Sr_b = new MyPushButton ("Sr", 18, 24);
+ connect (_Sr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sr_b, 5, 2);
+
+ _Y_b = new MyPushButton ("Y", 18, 24);
+ connect (_Y_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Y ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Y_b, 5, 3);
+
+ _Zr_b = new MyPushButton ("Zr", 18, 24);
+ connect (_Zr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Zr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Zr_b, 5, 4);
+
+ _Nb_b = new MyPushButton ("Nb", 18, 24);
+ connect (_Nb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Nb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Nb_b, 5, 5);
+
+ _Mo_b = new MyPushButton ("Mo", 18, 24);
+ connect (_Mo_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Mo ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Mo_b, 5, 6);
+
+ _Tc_b = new MyPushButton ("Tc", 18, 24);
+ connect (_Tc_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Tc ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Tc_b, 5, 7);
+
+ _Ru_b = new MyPushButton ("Ru", 18, 24);
+ connect (_Ru_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ru ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ru_b, 5, 8);
+
+ _Rh_b = new MyPushButton ("Rh", 18, 24);
+ connect (_Rh_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Rh ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Rh_b, 5, 9);
+
+ _Pd_b = new MyPushButton ("Pd", 18, 24);
+ connect (_Pd_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pd ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pd_b, 5, 10);
+
+ _Ag_b = new MyPushButton ("Ag", 18, 24);
+ connect (_Ag_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ag ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ag_b, 5, 11);
+
+ _Cd_b = new MyPushButton ("Cd", 18, 24);
+ connect (_Cd_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cd ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cd_b, 5, 12);
+
+ _In_b = new MyPushButton ("In", 18, 24);
+ connect (_In_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_In ()));
+ _periodictable_gc ->gridlayout ->addWidget (_In_b, 5, 13);
+
+ _Sn_b = new MyPushButton ("Sn", 18, 24);
+ connect (_Sn_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sn ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sn_b, 5, 14);
+
+ _Sb_b = new MyPushButton ("Sb", 18, 24);
+ connect (_Sb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sb_b, 5, 15);
+
+ _Te_b = new MyPushButton ("Te", 18, 24);
+ connect (_Te_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Te ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Te_b, 5, 16);
+
+ _I_b = new MyPushButton ("I", 18, 24);
+ connect (_I_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_I ()));
+ _periodictable_gc ->gridlayout ->addWidget (_I_b, 5, 17);
+
+ _Xe_b = new MyPushButton ("Xe", 18, 24);
+ connect (_Xe_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Xe ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Xe_b, 5, 18);
+
+ _Cs_b = new MyPushButton ("Cs", 18, 24);
+ connect (_Cs_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cs ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cs_b, 6, 1);
+
+ _Ba_b = new MyPushButton ("Ba", 18, 24);
+ connect (_Ba_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ba ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ba_b, 6, 2);
+
+ _Lu_b = new MyPushButton ("Lu", 18, 24);
+ connect (_Lu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Lu ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Lu_b, 8, 17);
+
+ _Hf_b = new MyPushButton ("Hf", 18, 24);
+ connect (_Hf_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Hf ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Hf_b, 6, 4);
+
+ _Ta_b = new MyPushButton ("Ta", 18, 24);
+ connect (_Ta_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ta ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ta_b, 6, 5);
+
+ _W_b = new MyPushButton ("W", 18, 24);
+ connect (_W_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_W ()));
+ _periodictable_gc ->gridlayout ->addWidget (_W_b, 6, 6);
+
+ _Re_b = new MyPushButton ("Re", 18, 24);
+ connect (_Re_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Re ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Re_b, 6, 7);
+
+ _Os_b = new MyPushButton ("Os", 18, 24);
+ connect (_Os_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Os ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Os_b, 6, 8);
+
+ _Ir_b = new MyPushButton ("Ir", 18, 24);
+ connect (_Ir_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ir ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ir_b, 6, 9);
+
+ _Pt_b = new MyPushButton ("Pt", 18, 24);
+ connect (_Pt_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pt ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pt_b, 6, 10);
+
+ _Au_b = new MyPushButton ("Au", 18, 24);
+ connect (_Au_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Au ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Au_b, 6, 11);
+
+ _Hg_b = new MyPushButton ("Hg", 18, 24);
+ connect (_Hg_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Hg ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Hg_b, 6, 12);
+
+ _Tl_b = new MyPushButton ("Tl", 18, 24);
+ connect (_Tl_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Tl ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Tl_b, 6, 13);
+
+ _Pb_b = new MyPushButton ("Pb", 18, 24);
+ connect (_Pb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pb_b, 6, 14);
+
+ _Bi_b = new MyPushButton ("Bi", 18, 24);
+ connect (_Bi_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Bi ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Bi_b, 6, 15);
+
+ _Po_b = new MyPushButton ("Po", 18, 24);
+ connect (_Po_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Po ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Po_b, 6, 16);
+
+ _At_b = new MyPushButton ("At", 18, 24);
+ connect (_At_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_At ()));
+ _periodictable_gc ->gridlayout ->addWidget (_At_b, 6, 17);
+
+ _Rn_b = new MyPushButton ("Rn", 18, 24);
+ connect (_Rn_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Rn ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Rn_b, 6, 18);
+
+ _Fr_b = new MyPushButton ("Fr", 18, 24);
+ connect (_Fr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Fr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Fr_b, 7, 1);
+
+ _Ra_b = new MyPushButton ("Ra", 18, 24);
+ connect (_Ra_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ra ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ra_b, 7, 2);
+
+ _Lr_b = new MyPushButton ("Lr", 18, 24);
+ connect (_Lr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Lr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Lr_b, 9, 17);
+
+ _Rf_b = new MyPushButton ("Rf", 18, 24);
+ connect (_Rf_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Rf ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Rf_b, 7, 4);
+
+ _Db_b = new MyPushButton ("Db", 18, 24);
+ connect (_Db_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Db ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Db_b, 7, 5);
+
+ _Sg_b = new MyPushButton ("Sg", 18, 24);
+ connect (_Sg_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sg ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sg_b, 7, 6);
+
+ _Bh_b = new MyPushButton ("Bh", 18, 24);
+ connect (_Bh_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Bh ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Bh_b, 7, 7);
+
+ _Hs_b = new MyPushButton ("Hs", 18, 24);
+ connect (_Hs_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Hs ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Hs_b, 7, 8);
+
+ _Mt_b = new MyPushButton ("Mt", 18, 24);
+ connect (_Mt_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Mt ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Mt_b, 7, 9);
+
+ _Ds_b = new MyPushButton ("Ds", 18, 24);
+ connect (_Ds_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ds ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ds_b, 7, 10);
+
+ _Rg_b = new MyPushButton ("Rg", 18, 24);
+ connect (_Rg_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Rg ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Rg_b, 7, 11);
+
+ _Uub_b = new MyPushButton ("Uub", 18, 24);
+ connect (_Uub_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uub ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uub_b, 7, 12);
+
+ _Uut_b = new MyPushButton ("Uut", 18, 24);
+ connect (_Uut_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uut ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uut_b, 7, 13);
+
+ _Uuq_b = new MyPushButton ("Uuq", 18, 24);
+ connect (_Uuq_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uuq ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uuq_b, 7, 14);
+
+ _Uup_b = new MyPushButton ("Uup", 18, 24);
+ connect (_Uup_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uup ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uup_b, 7, 15);
+
+ _Uuh_b = new MyPushButton ("Uuh", 18, 24);
+ connect (_Uuh_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uuh ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uuh_b, 7, 16);
+
+ _Uus_b = new MyPushButton ("Uus", 18, 24);
+ connect (_Uus_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uus ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uus_b, 7, 17);
+
+ _Uuo_b = new MyPushButton ("Uuo", 18, 24);
+ connect (_Uuo_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Uuo ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Uuo_b, 7, 18);
+
+ _La_b = new MyPushButton ("La", 18, 24);
+ connect (_La_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_La ()));
+ _periodictable_gc ->gridlayout ->addWidget (_La_b, 8, 3);
+
+ _Ce_b = new MyPushButton ("Ce", 18, 24);
+ connect (_Ce_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ce ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ce_b, 8, 4);
+
+ _Pr_b = new MyPushButton ("Pr", 18, 24);
+ connect (_Pr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pr ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pr_b, 8, 5);
+
+ _Nd_b = new MyPushButton ("Nd", 18, 24);
+ connect (_Nd_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Nd ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Nd_b, 8, 6);
+
+ _Pm_b = new MyPushButton ("Pm", 18, 24);
+ connect (_Pm_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pm ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pm_b, 8, 7);
+
+ _Sm_b = new MyPushButton ("Sm", 18, 24);
+ connect (_Sm_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Sm ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Sm_b, 8, 8);
+
+ _Eu_b = new MyPushButton ("Eu", 18, 24);
+ connect (_Eu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Eu ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Eu_b, 8, 9);
+
+ _Gd_b = new MyPushButton ("Gd", 18, 24);
+ connect (_Gd_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Gd ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Gd_b, 8, 10);
+
+ _Tb_b = new MyPushButton ("Tb", 18, 24);
+ connect (_Tb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Tb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Tb_b, 8, 11);
+
+ _Dy_b = new MyPushButton ("Dy", 18, 24);
+ connect (_Dy_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Dy ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Dy_b, 8, 12);
+
+ _Ho_b = new MyPushButton ("Ho", 18, 24);
+ connect (_Ho_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ho ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ho_b, 8, 13);
+
+ _Er_b = new MyPushButton ("Er", 18, 24);
+ connect (_Er_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Er ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Er_b, 8, 14);
+
+ _Tm_b = new MyPushButton ("Tm", 18, 24);
+ connect (_Tm_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Tm ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Tm_b, 8, 15);
+
+ _Yb_b = new MyPushButton ("Yb", 18, 24);
+ connect (_Yb_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Yb ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Yb_b, 8, 16);
+
+ _Ac_b = new MyPushButton ("Ac", 18, 24);
+ connect (_Ac_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Ac ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Ac_b, 9, 3);
+
+ _Th_b = new MyPushButton ("Th", 18, 24);
+ connect (_Th_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Th ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Th_b, 9, 4);
+
+ _Pa_b = new MyPushButton ("Pa", 18, 24);
+ connect (_Pa_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pa ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pa_b, 9, 5);
+
+ _U_b = new MyPushButton ("U", 18, 24);
+ connect (_U_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_U ()));
+ _periodictable_gc ->gridlayout ->addWidget (_U_b, 9, 6);
+
+ _Np_b = new MyPushButton ("Np", 18, 24);
+ connect (_Np_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Np ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Np_b, 9, 7);
+
+ _Pu_b = new MyPushButton ("Pu", 18, 24);
+ connect (_Pu_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Pu ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Pu_b, 9, 8);
+
+ _Am_b = new MyPushButton ("Am", 18, 24);
+ connect (_Am_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Am ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Am_b, 9, 9);
+
+ _Cm_b = new MyPushButton ("Cm", 18, 24);
+ connect (_Cm_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cm ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cm_b, 9, 10);
+
+ _Bk_b = new MyPushButton ("Bk", 18, 24);
+ connect (_Bk_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Bk ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Bk_b, 9, 11);
+
+ _Cf_b = new MyPushButton ("Cf", 18, 24);
+ connect (_Cf_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Cf ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Cf_b, 9, 12);
+
+ _Es_b = new MyPushButton ("Es", 18, 24);
+ connect (_Es_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Es ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Es_b, 9, 13);
+
+ _Fm_b = new MyPushButton ("Fm", 18, 24);
+ connect (_Fm_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Fm ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Fm_b, 9, 14);
+
+ _Md_b = new MyPushButton ("Md", 18, 24);
+ connect (_Md_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_Md ()));
+ _periodictable_gc ->gridlayout ->addWidget (_Md_b, 9, 15);
+
+ _No_b = new MyPushButton ("No", 18, 24);
+ connect (_No_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_No ()));
+ _periodictable_gc ->gridlayout ->addWidget (_No_b, 9, 16);
+
+ _H_b ->fbutton ->setFont (font);
+ _Li_b ->fbutton ->setFont (font);
+ _Be_b ->fbutton ->setFont (font);
+ _Na_b ->fbutton ->setFont (font);
+ _Mg_b ->fbutton ->setFont (font);
+ _K_b ->fbutton ->setFont (font);
+ _Ca_b ->fbutton ->setFont (font);
+ _Rb_b ->fbutton ->setFont (font);
+ _Sr_b ->fbutton ->setFont (font);
+ _Cs_b ->fbutton ->setFont (font);
+ _Ba_b ->fbutton ->setFont (font);
+ _Fr_b ->fbutton ->setFont (font);
+ _Ra_b ->fbutton ->setFont (font);
+
+
+ _B_b ->fbutton ->setFont (font);
+ _C_b ->fbutton ->setFont (font);
+ _N_b ->fbutton ->setFont (font);
+ _O_b ->fbutton ->setFont (font);
+ _F_b ->fbutton ->setFont (font);
+ _Al_b ->fbutton ->setFont (font);
+ _Si_b ->fbutton ->setFont (font);
+ _P_b ->fbutton ->setFont (font);
+ _S_b ->fbutton ->setFont (font);
+ _Cl_b ->fbutton ->setFont (font);
+ _Ga_b ->fbutton ->setFont (font);
+ _Ge_b ->fbutton ->setFont (font);
+ _As_b ->fbutton ->setFont (font);
+ _Se_b ->fbutton ->setFont (font);
+ _Br_b ->fbutton ->setFont (font);
+ _In_b ->fbutton ->setFont (font);
+ _Sn_b ->fbutton ->setFont (font);
+ _Sb_b ->fbutton ->setFont (font);
+ _Te_b ->fbutton ->setFont (font);
+ _I_b ->fbutton ->setFont (font);
+ _Tl_b ->fbutton ->setFont (font);
+ _Pb_b ->fbutton ->setFont (font);
+ _Bi_b ->fbutton ->setFont (font);
+ _Po_b ->fbutton ->setFont (font);
+ _At_b ->fbutton ->setFont (font);
+
+ _He_b ->fbutton ->setFont (font);
+ _Ne_b ->fbutton ->setFont (font);
+ _Ar_b ->fbutton ->setFont (font);
+ _Kr_b ->fbutton ->setFont (font);
+ _Xe_b ->fbutton ->setFont (font);
+ _Rn_b ->fbutton ->setFont (font);
+
+ _Uub_b ->fbutton ->setFont (font);
+ _Uut_b ->fbutton ->setFont (font);
+ _Uuq_b ->fbutton ->setFont (font);
+ _Uup_b ->fbutton ->setFont (font);
+ _Uuh_b ->fbutton ->setFont (font);
+ _Uus_b ->fbutton ->setFont (font);
+ _Uuo_b ->fbutton ->setFont (font);
+
+ _Sc_b ->fbutton ->setFont (font);
+ _Ti_b ->fbutton ->setFont (font);
+ _V_b ->fbutton ->setFont (font);
+ _Cr_b ->fbutton ->setFont (font);
+ _Mn_b ->fbutton ->setFont (font);
+ _Fe_b ->fbutton ->setFont (font);
+ _Co_b ->fbutton ->setFont (font);
+ _Ni_b ->fbutton ->setFont (font);
+ _Cu_b ->fbutton ->setFont (font);
+ _Zn_b ->fbutton ->setFont (font);
+ _Y_b ->fbutton ->setFont (font);
+ _Zr_b ->fbutton ->setFont (font);
+ _Nb_b ->fbutton ->setFont (font);
+ _Mo_b ->fbutton ->setFont (font);
+ _Tc_b ->fbutton ->setFont (font);
+ _Ru_b ->fbutton ->setFont (font);
+ _Rh_b ->fbutton ->setFont (font);
+ _Pd_b ->fbutton ->setFont (font);
+ _Ag_b ->fbutton ->setFont (font);
+ _Cd_b ->fbutton ->setFont (font);
+ _Lu_b ->fbutton ->setFont (font);
+ _Hf_b ->fbutton ->setFont (font);
+ _Ta_b ->fbutton ->setFont (font);
+ _W_b ->fbutton ->setFont (font);
+ _Re_b ->fbutton ->setFont (font);
+ _Os_b ->fbutton ->setFont (font);
+ _Ir_b ->fbutton ->setFont (font);
+ _Pt_b ->fbutton ->setFont (font);
+ _Au_b ->fbutton ->setFont (font);
+ _Hg_b ->fbutton ->setFont (font);
+ _Lr_b ->fbutton ->setFont (font);
+ _Rf_b ->fbutton ->setFont (font);
+ _Db_b ->fbutton ->setFont (font);
+ _Sg_b ->fbutton ->setFont (font);
+ _Bh_b ->fbutton ->setFont (font);
+ _Hs_b ->fbutton ->setFont (font);
+ _Mt_b ->fbutton ->setFont (font);
+ _Ds_b ->fbutton ->setFont (font);
+ _Rg_b ->fbutton ->setFont (font);
+
+ _Ac_b ->fbutton ->setFont (font);
+ _Th_b ->fbutton ->setFont (font);
+ _Pa_b ->fbutton ->setFont (font);
+ _U_b ->fbutton ->setFont (font);
+ _Np_b ->fbutton ->setFont (font);
+ _Pu_b ->fbutton ->setFont (font);
+ _Am_b ->fbutton ->setFont (font);
+ _Cm_b ->fbutton ->setFont (font);
+ _Bk_b ->fbutton ->setFont (font);
+ _Cf_b ->fbutton ->setFont (font);
+ _Es_b ->fbutton ->setFont (font);
+ _Fm_b ->fbutton ->setFont (font);
+ _Md_b ->fbutton ->setFont (font);
+ _No_b ->fbutton ->setFont (font);
+ _La_b ->fbutton ->setFont (font);
+ _Ce_b ->fbutton ->setFont (font);
+ _Pr_b ->fbutton ->setFont (font);
+ _Nd_b ->fbutton ->setFont (font);
+ _Pm_b ->fbutton ->setFont (font);
+ _Sm_b ->fbutton ->setFont (font);
+ _Eu_b ->fbutton ->setFont (font);
+ _Gd_b ->fbutton ->setFont (font);
+ _Tb_b ->fbutton ->setFont (font);
+ _Dy_b ->fbutton ->setFont (font);
+ _Ho_b ->fbutton ->setFont (font);
+ _Er_b ->fbutton ->setFont (font);
+ _Tm_b ->fbutton ->setFont (font);
+ _Yb_b ->fbutton ->setFont (font);
+
+
+ _H_b ->fbutton ->setPalette(Qt::yellow);
+ _Li_b ->fbutton ->setPalette(Qt::yellow);
+ _Be_b ->fbutton ->setPalette(Qt::yellow);
+ _Na_b ->fbutton ->setPalette(Qt::yellow);
+ _Mg_b ->fbutton ->setPalette(Qt::yellow);
+ _K_b ->fbutton ->setPalette(Qt::yellow);
+ _Ca_b ->fbutton ->setPalette(Qt::yellow);
+ _Rb_b ->fbutton ->setPalette(Qt::yellow);
+ _Sr_b ->fbutton ->setPalette(Qt::yellow);
+ _Cs_b ->fbutton ->setPalette(Qt::yellow);
+ _Ba_b ->fbutton ->setPalette(Qt::yellow);
+ _Fr_b ->fbutton ->setPalette(Qt::yellow);
+ _Ra_b ->fbutton ->setPalette(Qt::yellow);
+
+
+ _B_b ->fbutton ->setPalette(Qt::cyan);
+ _C_b ->fbutton ->setPalette(Qt::cyan);
+ _N_b ->fbutton ->setPalette(Qt::cyan);
+ _O_b ->fbutton ->setPalette(Qt::cyan);
+ _F_b ->fbutton ->setPalette(Qt::cyan);
+ _Al_b ->fbutton ->setPalette(Qt::cyan);
+ _Si_b ->fbutton ->setPalette(Qt::cyan);
+ _P_b ->fbutton ->setPalette(Qt::cyan);
+ _S_b ->fbutton ->setPalette(Qt::cyan);
+ _Cl_b ->fbutton ->setPalette(Qt::cyan);
+ _Ga_b ->fbutton ->setPalette(Qt::cyan);
+ _Ge_b ->fbutton ->setPalette(Qt::cyan);
+ _As_b ->fbutton ->setPalette(Qt::cyan);
+ _Se_b ->fbutton ->setPalette(Qt::cyan);
+ _Br_b ->fbutton ->setPalette(Qt::cyan);
+ _In_b ->fbutton ->setPalette(Qt::cyan);
+ _Sn_b ->fbutton ->setPalette(Qt::cyan);
+ _Sb_b ->fbutton ->setPalette(Qt::cyan);
+ _Te_b ->fbutton ->setPalette(Qt::cyan);
+ _I_b ->fbutton ->setPalette(Qt::cyan);
+ _Tl_b ->fbutton ->setPalette(Qt::cyan);
+ _Pb_b ->fbutton ->setPalette(Qt::cyan);
+ _Bi_b ->fbutton ->setPalette(Qt::cyan);
+ _Po_b ->fbutton ->setPalette(Qt::cyan);
+ _At_b ->fbutton ->setPalette(Qt::cyan);
+
+ _He_b ->fbutton ->setPalette(Qt::red);
+ _Ne_b ->fbutton ->setPalette(Qt::red);
+ _Ar_b ->fbutton ->setPalette(Qt::red);
+ _Kr_b ->fbutton ->setPalette(Qt::red);
+ _Xe_b ->fbutton ->setPalette(Qt::red);
+ _Rn_b ->fbutton ->setPalette(Qt::red);
+
+ _Uub_b ->fbutton ->setPalette(Qt::white);
+ _Uut_b ->fbutton ->setPalette(Qt::white);
+ _Uuq_b ->fbutton ->setPalette(Qt::white);
+ _Uup_b ->fbutton ->setPalette(Qt::white);
+ _Uuh_b ->fbutton ->setPalette(Qt::white);
+ _Uus_b ->fbutton ->setPalette(Qt::white);
+ _Uuo_b ->fbutton ->setPalette(Qt::white);
+
+ _Sc_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ti_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _V_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Cr_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Mn_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Fe_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Co_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ni_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Cu_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Zn_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Y_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Zr_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Nb_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Mo_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Tc_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ru_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Rh_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Pd_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ag_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Cd_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Hf_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ta_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _W_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Re_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Os_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ir_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Pt_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Au_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Hg_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Rf_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Db_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Sg_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Bh_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Hs_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Mt_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ds_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Rg_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _Ac_b ->fbutton ->setPalette(QColor(250, 153, 0));
+ _La_b ->fbutton ->setPalette(QColor(250, 153, 0));
+
+ _Lu_b ->fbutton ->setPalette(Qt::lightGray);
+ _Lr_b ->fbutton ->setPalette(Qt::lightGray);
+ _Th_b ->fbutton ->setPalette(Qt::lightGray);
+ _Pa_b ->fbutton ->setPalette(Qt::lightGray);
+ _U_b ->fbutton ->setPalette(Qt::lightGray);
+ _Np_b ->fbutton ->setPalette(Qt::lightGray);
+ _Pu_b ->fbutton ->setPalette(Qt::lightGray);
+ _Am_b ->fbutton ->setPalette(Qt::lightGray);
+ _Cm_b ->fbutton ->setPalette(Qt::lightGray);
+ _Bk_b ->fbutton ->setPalette(Qt::lightGray);
+ _Cf_b ->fbutton ->setPalette(Qt::lightGray);
+ _Es_b ->fbutton ->setPalette(Qt::lightGray);
+ _Fm_b ->fbutton ->setPalette(Qt::lightGray);
+ _Md_b ->fbutton ->setPalette(Qt::lightGray);
+ _No_b ->fbutton ->setPalette(Qt::lightGray);
+ _Ce_b ->fbutton ->setPalette(Qt::lightGray);
+ _Pr_b ->fbutton ->setPalette(Qt::lightGray);
+ _Nd_b ->fbutton ->setPalette(Qt::lightGray);
+ _Pm_b ->fbutton ->setPalette(Qt::lightGray);
+ _Sm_b ->fbutton ->setPalette(Qt::lightGray);
+ _Eu_b ->fbutton ->setPalette(Qt::lightGray);
+ _Gd_b ->fbutton ->setPalette(Qt::lightGray);
+ _Tb_b ->fbutton ->setPalette(Qt::lightGray);
+ _Dy_b ->fbutton ->setPalette(Qt::lightGray);
+ _Ho_b ->fbutton ->setPalette(Qt::lightGray);
+ _Er_b ->fbutton ->setPalette(Qt::lightGray);
+ _Tm_b ->fbutton ->setPalette(Qt::lightGray);
+ _Yb_b ->fbutton ->setPalette(Qt::lightGray);
+
+}
+
+void BuilderMenu::add_mol (string str) {
+ _data ->ddwin ->builder ->add_mol (str);
+}
+
+void BuilderMenu::add_fragment (string str) {
+ _data ->ddwin ->builder ->add_fragment (str);
+ /*
+ OBConversion conv;
+ ZNMolecule *mol = new ZNMolecule ();
+ conv.SetInFormat ("SMI");
+ conv.ReadString (mol, str);
+ mol -> AddHydrogens ();
+ mend_coordinates (mol);
+ CreateZNMoleculeCommand *command = new CreateZNMoleculeCommand (mol, builder -> ddwin);
+ builder -> ddwin -> execute (command);
+ */
+}
+
+void BuilderMenu::add_smiles () {
+ string str = smiles ->text ().toStdString ();
+ _data ->ddwin ->builder ->add_fragment (str);
+}
+
+
+void BuilderMenu::add_benzene () {
+ string str = "c1ccccc1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring3 () {
+ string str = "C1CC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring4 () {
+ string str = "C1CCC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring5 () {
+ string str = "C1CCCC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring6 () {
+ string str = "C1CCCCC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring7 () {
+ string str = "C1CCCCCC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_ring8 () {
+ string str = "C1CCCCCCC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_furan () {
+ string str = "c1cccO1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_furanO () {
+ string str = "c1cccC1";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_CO () {
+ string str = "C(=O)";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_NCO () {
+ string str = "NC(=O)";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_COOH () {
+ string str = "C(=O)O";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_CCd () {
+ string str = "C=C";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_CCt () {
+ string str = "C#C";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_NO2 () {
+ string str = "[H]N(=O)(=O)";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_PO3 () {
+ string str = "[H]P(=O)(=O)O";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_SO2 () {
+ string str = "[H]S(=O)([H])=O";
+ add_fragment (str);
+}
+
+void BuilderMenu::add_CN () {
+ string str = "C#N";
+ add_fragment (str);
+}
+
+void BuilderMenu::single_bond () {
+ builder->add_bond (1);
+}
+
+void BuilderMenu::double_bond () {
+ builder->add_bond (2);
+}
+
+void BuilderMenu::triple_bond () {
+ builder->add_bond (3);
+}
+
+void BuilderMenu::no_bond () {
+ // builder->remove_bond ();
+}
+
+
+void BuilderMenu::add_H () {
+ builder->add_atom (1);
+}
+void BuilderMenu::add_He () {
+ builder->add_atom (2);
+}
+void BuilderMenu::add_Li () {
+ builder->add_atom (3);
+}
+void BuilderMenu::add_Be () {
+ builder->add_atom (4);
+}
+void BuilderMenu::add_B () {
+ builder->add_atom (5);
+}
+void BuilderMenu::add_C () {
+ builder->add_atom (6);
+}
+void BuilderMenu::add_N () {
+ builder->add_atom (7);
+}
+void BuilderMenu::add_O () {
+ builder->add_atom (8);
+}
+void BuilderMenu::add_F () {
+ builder->add_atom (9);
+}
+void BuilderMenu::add_Ne () {
+ builder->add_atom (10);
+}
+void BuilderMenu::add_Na () {
+ builder->add_atom (11);
+}
+void BuilderMenu::add_Mg () {
+ builder->add_atom (12);
+}
+void BuilderMenu::add_Al () {
+ builder->add_atom (13);
+}
+void BuilderMenu::add_Si () {
+ builder->add_atom (14);
+}
+void BuilderMenu::add_P () {
+ builder->add_atom (15);
+}
+void BuilderMenu::add_S () {
+ builder->add_atom (16);
+}
+void BuilderMenu::add_Cl () {
+ builder->add_atom (17);
+}
+void BuilderMenu::add_Ar () {
+ builder->add_atom (18);
+}
+void BuilderMenu::add_K () {
+ builder->add_atom (19);
+}
+void BuilderMenu::add_Ca () {
+ builder->add_atom (20);
+}
+void BuilderMenu::add_Sc () {
+ builder->add_atom (21);
+}
+void BuilderMenu::add_Ti () {
+ builder->add_atom (22);
+}
+void BuilderMenu::add_V () {
+ builder->add_atom (23);
+}
+void BuilderMenu::add_Cr () {
+ builder->add_atom (24);
+}
+void BuilderMenu::add_Mn () {
+ builder->add_atom (25);
+}
+void BuilderMenu::add_Fe () {
+ builder->add_atom (26);
+}
+void BuilderMenu::add_Co () {
+ builder->add_atom (27);
+}
+void BuilderMenu::add_Ni () {
+ builder->add_atom (28);
+}
+void BuilderMenu::add_Cu () {
+ builder->add_atom (29);
+}
+void BuilderMenu::add_Zn () {
+ builder->add_atom (30);
+}
+void BuilderMenu::add_Ga () {
+ builder->add_atom (31);
+}
+void BuilderMenu::add_Ge () {
+ builder->add_atom (32);
+}
+void BuilderMenu::add_As () {
+ builder->add_atom (33);
+}
+void BuilderMenu::add_Se () {
+ builder->add_atom (34);
+}
+void BuilderMenu::add_Br () {
+ builder->add_atom (35);
+}
+void BuilderMenu::add_Kr () {
+ builder->add_atom (36);
+}
+void BuilderMenu::add_Rb () {
+ builder->add_atom (37);
+}
+void BuilderMenu::add_Sr () {
+ builder->add_atom (38);
+}
+void BuilderMenu::add_Y () {
+ builder->add_atom (39);
+}
+void BuilderMenu::add_Zr () {
+ builder->add_atom (40);
+}
+void BuilderMenu::add_Nb () {
+ builder->add_atom (41);
+}
+void BuilderMenu::add_Mo () {
+ builder->add_atom (42);
+}
+void BuilderMenu::add_Tc () {
+ builder->add_atom (43);
+}
+void BuilderMenu::add_Ru () {
+ builder->add_atom (44);
+}
+void BuilderMenu::add_Rh () {
+ builder->add_atom (45);
+}
+void BuilderMenu::add_Pd () {
+ builder->add_atom (46);
+}
+void BuilderMenu::add_Ag () {
+ builder->add_atom (47);
+}
+void BuilderMenu::add_Cd () {
+ builder->add_atom (48);
+}
+void BuilderMenu::add_In () {
+ builder->add_atom (49);
+}
+void BuilderMenu::add_Sn () {
+ builder->add_atom (50);
+}
+void BuilderMenu::add_Sb () {
+ builder->add_atom (51);
+}
+void BuilderMenu::add_Te () {
+ builder->add_atom (52);
+}
+void BuilderMenu::add_I () {
+ builder->add_atom (53);
+}
+void BuilderMenu::add_Xe () {
+ builder->add_atom (54);
+}
+void BuilderMenu::add_Cs () {
+ builder->add_atom (55);
+}
+void BuilderMenu::add_Ba () {
+ builder->add_atom (56);
+}
+void BuilderMenu::add_La () {
+ builder->add_atom (57);
+}
+void BuilderMenu::add_Ce () {
+ builder->add_atom (58);
+}
+void BuilderMenu::add_Pr () {
+ builder->add_atom (59);
+}
+void BuilderMenu::add_Nd () {
+ builder->add_atom (60);
+}
+void BuilderMenu::add_Pm () {
+ builder->add_atom (61);
+}
+void BuilderMenu::add_Sm () {
+ builder->add_atom (62);
+}
+void BuilderMenu::add_Eu () {
+ builder->add_atom (63);
+}
+void BuilderMenu::add_Gd () {
+ builder->add_atom (64);
+}
+void BuilderMenu::add_Tb () {
+ builder->add_atom (65);
+}
+void BuilderMenu::add_Dy () {
+ builder->add_atom (66);
+}
+void BuilderMenu::add_Ho () {
+ builder->add_atom (67);
+}
+void BuilderMenu::add_Er () {
+ builder->add_atom (68);
+}
+void BuilderMenu::add_Tm () {
+ builder->add_atom (69);
+}
+void BuilderMenu::add_Yb () {
+ builder->add_atom (70);
+}
+void BuilderMenu::add_Lu () {
+ builder->add_atom (71);
+}
+void BuilderMenu::add_Hf () {
+ builder->add_atom (72);
+}
+void BuilderMenu::add_Ta () {
+ builder->add_atom (73);
+}
+void BuilderMenu::add_W () {
+ builder->add_atom (74);
+}
+void BuilderMenu::add_Re () {
+ builder->add_atom (75);
+}
+void BuilderMenu::add_Os () {
+ builder->add_atom (76);
+}
+void BuilderMenu::add_Ir () {
+ builder->add_atom (77);
+}
+void BuilderMenu::add_Pt () {
+ builder->add_atom (78);
+}
+void BuilderMenu::add_Au () {
+ builder->add_atom (79);
+}
+void BuilderMenu::add_Hg () {
+ builder->add_atom (80);
+}
+void BuilderMenu::add_Tl () {
+ builder->add_atom (81);
+}
+void BuilderMenu::add_Pb () {
+ builder->add_atom (82);
+}
+void BuilderMenu::add_Bi () {
+ builder->add_atom (83);
+}
+void BuilderMenu::add_Po () {
+ builder->add_atom (84);
+}
+void BuilderMenu::add_At () {
+ builder->add_atom (85);
+}
+void BuilderMenu::add_Rn () {
+ builder->add_atom (86);
+}
+void BuilderMenu::add_Fr () {
+ builder->add_atom (87);
+}
+void BuilderMenu::add_Ra () {
+ builder->add_atom (88);
+}
+void BuilderMenu::add_Ac () {
+ builder->add_atom (89);
+}
+void BuilderMenu::add_Th () {
+ builder->add_atom (90);
+}
+void BuilderMenu::add_Pa () {
+ builder->add_atom (91);
+}
+void BuilderMenu::add_U () {
+ builder->add_atom (92);
+}
+void BuilderMenu::add_Np () {
+ builder->add_atom (93);
+}
+void BuilderMenu::add_Pu () {
+ builder->add_atom (94);
+}
+void BuilderMenu::add_Am () {
+ builder->add_atom (95);
+}
+void BuilderMenu::add_Cm () {
+ builder->add_atom (96);
+}
+void BuilderMenu::add_Bk () {
+ builder->add_atom (97);
+}
+void BuilderMenu::add_Cf () {
+ builder->add_atom (98);
+}
+void BuilderMenu::add_Es () {
+ builder->add_atom (99);
+}
+void BuilderMenu::add_Fm () {
+ builder->add_atom (100);
+}
+void BuilderMenu::add_Md () {
+ builder->add_atom (101);
+}
+void BuilderMenu::add_No () {
+ builder->add_atom (102);
+}
+void BuilderMenu::add_Lr () {
+ builder->add_atom (103);
+}
+void BuilderMenu::add_Rf () {
+ builder->add_atom (104);
+}
+void BuilderMenu::add_Db () {
+ builder->add_atom (105);
+}
+void BuilderMenu::add_Sg () {
+ builder->add_atom (106);
+}
+void BuilderMenu::add_Bh () {
+ builder->add_atom (107);
+}
+void BuilderMenu::add_Hs () {
+ builder->add_atom (108);
+}
+void BuilderMenu::add_Mt () {
+ builder->add_atom (109);
+}
+void BuilderMenu::add_Ds () {
+ builder->add_atom (110);
+}
+void BuilderMenu::add_Rg () {
+ builder->add_atom (111);
+}
+void BuilderMenu::add_Uub () {
+ builder->add_atom (112);
+}
+void BuilderMenu::add_Uut () {
+ builder->add_atom (113);
+}
+void BuilderMenu::add_Uuq () {
+ builder->add_atom (114);
+}
+void BuilderMenu::add_Uup () {
+ builder->add_atom (115);
+}
+void BuilderMenu::add_Uuh () {
+ builder->add_atom (116);
+}
+void BuilderMenu::add_Uus () {
+ builder->add_atom (117);
+}
+void BuilderMenu::add_Uuo () {
+ builder->add_atom (118);
+}
+
+void BuilderMenu::add_Ala () {
+ string str = "C[C at H](N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Arg () {
+ string str = "N[C@@H](CCCNC(N)=N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Asn () {
+ string str = "N[C@@H](CC(N)=O)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Asp () {
+ string str = "N[C@@H](CC(O)=O)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Cys () {
+ string str = "C([C@@H](C(=O)O)N)S";
+ add_fragment (str);
+}
+void BuilderMenu::add_Glu () {
+ string str = "N[C@@H](CCC(O)=O)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Cln () {
+ string str = "N[C@@H](CCC(N)=O)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Gly () {
+ string str = "NCC(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_His () {
+ string str = "N[C@@H](Cc1[nH]cnc1)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Ile () {
+ string str = "CC[C at H](C)[C at H](N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Leu () {
+ string str = "CC(C)C[C at H](N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Lys () {
+ string str = "C(CCN)CC(C(=O)O)N";
+ add_fragment (str);
+}
+void BuilderMenu::add_Met () {
+ string str = "CSCC[C at H](N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Phe () {
+ string str = "C1=CC=C(C=C1)CC(C(=O)O)N";
+ add_fragment (str);
+}
+void BuilderMenu::add_Pro () {
+ string str = "OC(=O)[C@@H]1CCCN1";
+ add_fragment (str);
+}
+void BuilderMenu::add_Ser () {
+ string str = "OCC(N)C(=O)O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Thr () {
+ string str = "C[C@@H](O)[C at H](N)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Trp () {
+ string str = "N[C@@H](Cc1c2ccccc2n([H])c1)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Tyr () {
+ string str = "N[C@@H](Cc1ccc(O)cc1)C(O)=O";
+ add_fragment (str);
+}
+void BuilderMenu::add_Val () {
+ string str = "CC(C)C(N)C(=O)O";
+ add_fragment (str);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+HapticMenu::HapticMenu (QWidget *parent, Data *dat )
+ : ZNMenu (parent, dat, true, true)
+{
+ haptic_thread = NULL;
+ mult = 1.;
+ restrain_lock = new QReadWriteLock;
+ last_atom = false;
+ last_k = 1.;
+ last_dist = 1.5;
+ label = new QLabel;
+ label ->setText ("");
+
+ ZNAdvancedWidget *settings_widget = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (settings_widget, "Settings");
+
+ ZNAdvancedWidget *restrains_widget = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (restrains_widget, "Restrains");
+
+ ZNAdvancedWidget *energy_widget = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (energy_widget, "Energy");
+
+ restrains_widget ->layout() ->addWidget(label);
+
+ minimize = _data ->minimize;
+ this->setWindowTitle("Haptic");
+
+ // QWidget *settings_widget = new QWidget (this);
+ QLayout *setmainlayout = settings_widget ->layout ();
+
+
+ dofmode = new QComboBox;
+ dofmode -> insertItem(0, "6" );
+ dofmode -> insertItem(1, "3 N" );
+ dofmode -> setCurrentIndex(1);
+ setmainlayout -> addWidget (dofmode);
+
+ interff = new QComboBox();
+ interff->insertItem(1, "MMFF" );
+// interff->insertItem(2, "PLP" );
+ interff->insertItem(2, "Chemscore" );
+ interff->insertItem(3, "MMFF+Chemscore");
+ setmainlayout -> addWidget (interff);
+ automove_b = true;
+ color_by_score_b = false;
+ cluster_RMSD = 0.5;
+ E_tolerance = 2.f;
+ saving = true;
+ MyCheckBox *automove = new MyCheckBox (setmainlayout,automove_b, "automove");
+ MyCheckBox *color_by_scor = new MyCheckBox (setmainlayout, color_by_score_b, "color by score");
+ MyCheckBox *saving_cb = new MyCheckBox (setmainlayout, saving, "auto save results");
+ MyFloatEditLine *rmsd_line = new MyFloatEditLine (setmainlayout, "cluster RMSD", cluster_RMSD, 0, 5);
+ MyFloatEditLine *Egap_line = new MyFloatEditLine (setmainlayout, "Energy tolerance", E_tolerance, 0, 100);
+ MyFloatEditLine *mult_line = new MyFloatEditLine (setmainlayout, "Haptic feedback scaling", mult, 0, 100);
+ //MyIntegerEditLine *number_of_threads_edit_line = new MyIntegerEditLine (setmainlayout, "number of threads", minimize ->haptic_number_of_threads);
+
+ MyPushButton *add_restr_b = new MyPushButton (restrains_widget ->layout (), "Add restrain");
+
+ connect (add_restr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (add_restrain ()));
+
+
+ restrain_list = new MyListView (restrains_widget ->layout (), 0, 0, false);
+
+ restrain_dist = new MyFloatEditLine (restrains_widget ->layout(), "rest value",last_dist, 0, 1000);
+ restrain_k = new MyFloatEditLine (restrains_widget ->layout(), "Strength",last_k, -1000, 1000);
+ connect (restrain_k ->spinbox, SIGNAL (valueChanged (double )) ,SLOT (update_k (double)));
+ connect (restrain_dist ->spinbox, SIGNAL (valueChanged (double)) ,SLOT (update_dist (double)));
+
+ MyPushButton *clear_restr_b = new MyPushButton (restrains_widget ->layout (), "Clear restrains");
+ connect (restrain_list, SIGNAL (deleting (int)), SLOT (delete_restrain (int)));
+ connect (restrain_list ->_lw, SIGNAL (currentRowChanged (int)), SLOT (update_spinboxes (int)));
+ connect (clear_restr_b ->fbutton, SIGNAL (clicked ()) ,SLOT (clear_restrains ()));
+
+ QHBoxLayout *button_lay = new QHBoxLayout;
+ QWidget *butt_widg = new QWidget;
+ butt_widg ->setLayout (button_lay);
+ setmainlayout -> addWidget (butt_widg);
+ QPushButton *Ok_b = new QPushButton ("Start");
+ connect (Ok_b, SIGNAL (clicked ()) ,SLOT (Ok ()));
+ button_lay -> addWidget (Ok_b);
+
+ QPushButton *end_b = new QPushButton ("Stop");
+ connect (end_b, SIGNAL (clicked ()) ,SLOT (end ()));
+
+
+ button_lay -> addWidget (end_b);
+
+ // addTab( settings_widget, "Settings" );
+
+
+
+ // total_E = new MyLabelf(energy_widget, "Total Energy", &minimize->total_E);
+ interaction_E = new MyLabelf(energy_widget ->layout (), "Interaction Energy", _data->total_energy_haptic);
+ // interaction_E = new MyLabelf(energy_widget, "Interaction Energy", &minimize->total_interaction_E);
+ QPushButton *savepose_b = new QPushButton ("Save Current Pose");
+ energy_widget ->layout() ->addWidget(savepose_b);
+ connect (savepose_b, SIGNAL (clicked ()) ,SLOT (user_save_current_pose ()));
+}
+void HapticMenu::add_restrain_atom (Atom *a) {
+ if (!last_atom) {
+ last_atom = a;
+ label ->setText ("Choose second Atom");
+ }
+ else if (last_atom != a) {
+ label ->setText ("");
+ restrain_lock ->lockForWrite ();
+ ElasticRestrain *restrain = new ElasticRestrain;
+ restrain ->at2 = a;
+ restrain ->at1 = last_atom;
+ restrain ->k = last_k;
+ restrain ->dist0 = dist (get_coordinates (restrain ->at1),get_coordinates ( restrain->at2));
+ restrains.push_back (restrain);
+ stringstream ss;
+ ss << " "<<restrain ->at1 ->GetType ()<<"\t"<<restrain ->at2 ->GetType ()<<"\t" <<restrain ->dist0<<"\t"<<restrain->k;
+ restrain_list ->_lw ->addItem(tr( ss.str ().c_str () ));
+ last_atom = 0;
+ _data ->ddwin ->adding_restrains = false;
+ restrain_lock ->unlock ();
+
+ }
+}
+
+void HapticMenu::update_k (double) {
+ restrain_lock ->lockForWrite ();
+
+ if (restrain_list ->_lw ->currentRow()>-1) {
+ int n = restrain_list ->_lw ->currentRow();
+ ElasticRestrain *rest = ((ElasticRestrain *)restrains[n]);
+ rest->k = last_k;
+ stringstream ss;
+ ss << " "<<rest ->at1 ->GetType ()<<"\t"<<rest ->at2 ->GetType ()<<"\t" <<rest ->dist0<<"\t"<<rest->k;
+ restrain_list ->_lw ->item (n) -> setText(ss.str().c_str());
+
+ }
+ restrain_lock ->unlock ();
+}
+
+void HapticMenu::update_spinboxes (int i) {
+ if (i > -1) {
+ ElasticRestrain *rest = ((ElasticRestrain *)restrains[i]);
+ restrain_dist ->spinbox ->setValue (rest ->dist0);
+ restrain_k ->spinbox ->setValue (rest ->k);
+ }
+}
+
+void HapticMenu::update_dist (double) {
+ restrain_lock ->lockForWrite ();
+
+ if (restrain_list ->_lw ->currentRow()>-1) {
+ int n = restrain_list ->_lw ->currentRow();
+ ElasticRestrain *rest = ((ElasticRestrain *)restrains[n]);
+ rest->dist0 = last_dist;
+ stringstream ss;
+ ss << " "<<rest ->at1 ->GetType ()<<"\t"<<rest ->at2 ->GetType ()<<"\t" <<rest ->dist0<<"\t"<<rest->k;
+ restrain_list ->_lw ->item (n) -> setText(ss.str().c_str());
+
+ }
+ restrain_lock ->unlock ();
+}
+
+void HapticMenu::clear_restrains () {
+ restrain_lock ->lockForWrite ();
+ restrain_list ->_lw ->clear ();
+ for (unsigned int i = 0; i < restrains.size (); i ++) {
+ delete restrains [i];
+ }
+ restrains.clear ();
+ restrain_lock ->unlock ();
+
+}
+
+void HapticMenu::delete_restrain (int i) {
+ restrain_lock ->lockForWrite ();
+ delete restrains [i];
+ restrains.erase (restrains.begin () + i);
+ restrain_lock ->unlock ();
+}
+
+void HapticMenu::add_restrain () {
+ _data ->ddwin ->adding_restrains = true;
+ label ->setText ("Choose first Atom");
+}
+
+void HapticMenu::user_save_current_pose () {
+ haptic_thread ->user_save_result = true;
+}
+
+void HapticMenu::Ok () {
+ if (_data ->ddwin ->current_target) {
+ if (!haptic_thread) {
+ haptic_thread = new HapticThread (0, _data ->ddwin);
+ haptic_thread ->automove = automove_b;
+ haptic_thread ->color_by_score = color_by_score_b;
+ for (unsigned int i =0; i< minimize ->interaction_ffs.size (); i++) {
+ delete minimize ->interaction_ffs [i];
+ }
+ minimize->interaction_ffs.clear ();
+ string iff = interff->currentText ().toStdString ();
+ if (iff == "MMFF") minimize->interaction_ffs.push_back (new MMFF ());
+ else if (iff == "Chemscore") minimize->interaction_ffs.push_back ( new Chemscore ());
+ else if (iff == "MMFF+Chemscore") {
+ minimize->interaction_ffs.push_back ( new MMFF ());
+ minimize->interaction_ffs.push_back ( new Chemscore ());
+ }
+ else minimize->interaction_ffs.push_back (new MMFF ());
+
+ string dofm =dofmode->currentText ().toStdString ();
+ if (dofm == "6") minimize -> haptic_dof_mode = 0;
+ else if (dofm == "3 N") minimize -> haptic_dof_mode = 1;
+ else minimize -> haptic_dof_mode = 1;
+ minimize -> start_haptic_mode ();
+ }
+ }
+}
+
+
+
+void HapticMenu::end () {
+ if (haptic_thread) {
+ ZNMolecule *mol = haptic_thread ->molecule;
+ Database *dat = haptic_thread ->results;
+ haptic_thread -> stop ();
+ haptic_thread -> wait ();
+ haptic_thread = 0;
+ MoveAtomsCommand *command = new MoveAtomsCommand (_data -> ddwin -> gl, 0);
+ FOR_ATOMS_OF_MOL(a, mol) {
+ command -> add (&*a, get_coordinates (&*a));
+ }
+ // command -> name ("haptic simulation");
+ _data -> ddwin -> execute (command);
+ _data -> ddwin -> add_database(dat);
+ _data -> undo_stack -> endMacro ();
+ _data->ddwin->haptic_mode = false;
+ //haptic_molecule = NULL;
+ _data->ddwin ->data ->current_force_x=0.;
+ _data->ddwin ->data ->current_force_y=0.;
+ _data->ddwin ->data ->current_force_z=0.;
+ _data -> ddwin -> unlock_editing ();
+ }
+}
+
+
+
+void HapticMenu::update_energy () {
+ // total_E->update ();
+ // internal_E->update ();
+ interaction_E->update ();
+}
+
+void HapticMenu::maybe_save_result () {
+ if (haptic_thread) {
+ float E = _data ->total_energy_haptic;
+ if (E < haptic_thread ->save_E_threshold + E_tolerance) {
+ if (E > haptic_thread ->save_E_threshold)
+ {
+ haptic_thread ->is_worse = true;
+ }
+ haptic_thread ->save_E_threshold = E;
+ haptic_thread ->save_result = true;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+Clicked_atomMenu::Clicked_atomMenu (QWidget *parent, Data* dat)
+ : ZNMenu (parent, dat, true, true)
+ {
+ setWindowTitle ("Clicked Atom");
+ ZNAdvancedWidget *atom_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (atom_tab, "Atom");
+
+ ZNAdvancedWidget *residue_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (residue_tab, "Residue");
+
+
+ ZNAdvancedWidget *molecule_tab = new ZNAdvancedWidget ("", false);
+ _tabs ->addTab (molecule_tab, "ZNMolecule");
+
+
+ MyPushButton *setascenterb = new MyPushButton (atom_tab ->layout (), "Set As Center of view");
+ connect (setascenterb ->fbutton, SIGNAL (clicked ()),SLOT (set_clicked_atom_as_center_of_view ()));
+ MyPushButton *setasrotcenterb = new MyPushButton (atom_tab ->layout (), "Set As Center of Rotation");
+ connect (setasrotcenterb ->fbutton, SIGNAL (clicked ()),SLOT (set_clicked_atom_as_center_of_rotation ()));
+
+ QWidget *coors_widget = new QWidget ();
+ coors_widget ->setLayout (new QHBoxLayout ());
+ atom_tab ->layout ()->addWidget (coors_widget);
+ idl = new QLabel ("");
+ // coors_widget->setMaximumHeight (25);
+ aplx = new QLineEdit("");
+ aply = new QLineEdit("");
+ aplz = new QLineEdit("");
+ coors_widget ->layout () -> addWidget (new QLabel("coordinates"));
+ coors_widget ->layout ()-> addWidget (aplx);
+ coors_widget ->layout ()-> addWidget (aply);
+ coors_widget ->layout ()-> addWidget (aplz);
+
+
+ QWidget *charge_widget = new QWidget ();
+ charge_widget ->setLayout (new QHBoxLayout ());
+ atom_tab ->layout ()->addWidget (charge_widget);
+ atom_tab ->layout () ->addWidget (idl);
+
+ formal_charge_le = new MyIntegerEditLine (charge_widget ->layout (), "Formal Charge", formal_charge, -8, 8);
+
+/*
+ Q3Grid *atompropts = new Q3Grid (5,atomselpopupv);
+ atompropts->setMaximumSize (350, 60);
+ (void) new QLabel("Atom ID", atompropts );
+ aplid = new QLabel("", atompropts );
+ (void) new QLabel(" ", atompropts );
+ (void) new QLabel("Partial charge", atompropts );
+ aplq = new QLabel("", atompropts );
+ (void) new QLabel("Element", atompropts );
+ aplat = new QLabel("", atompropts );
+ (void) new QLabel(" ", atompropts );
+ (void) new QLabel("Formal charge", atompropts );
+ aplfc = new QLineEdit("", atompropts );
+
+
+ Q3HBox *coors = new Q3HBox (atomselpopupv);
+ coors->setMaximumHeight (25);
+ (void) new QLabel("coordinates", coors );
+ aplx = new QLineEdit("", coors );
+ aply = new QLineEdit("", coors );
+ aplz = new QLineEdit("", coors );
+ aplid->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
+ aplat->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
+ aplq->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
+
+
+
+
+
+ Q3VBox *resv = new Q3VBox (this);
+ Q3Grid *resgrd = new Q3Grid (5,resv);
+ (void) new QLabel("Residue Type", resgrd );
+ resna = new QLabel("", resgrd );
+ (void) new QLabel(" ", resgrd );
+ (void) new QLabel("Residue Number", resgrd );
+ resnu = new QLabel("", resgrd );
+ (void) new QLabel("Atom role in residue", resgrd );
+ aptype = new QLabel("", resgrd );
+ resna->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
+ resnu->setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken );
+ addTab( resv, "Residue" );
+
+
+ Q3VBox *molv = new Q3VBox (this);
+ QPushButton *addh = new QPushButton ("Add hydrogens", molv);
+ connect (addh, SIGNAL (clicked ()),SLOT (add_Hs ()));
+ addTab( molv, "ZNMolecule" );
+
+ */
+}
+
+
+
+void Clicked_atomMenu::update (){
+
+
+ Atom *at = clicked_atom;
+ Resid *res= at ->GetResidue ();
+
+
+
+ formal_charge = at->GetFormalCharge ();
+ formal_charge_le ->update ();
+
+// set_value (aplid, at -> GetIdx ());
+// set_value (aplat, string (etab.GetSymbol (at -> GetAtomicNum ())));
+// set_value (aplq, at -> GetPartialCharge ());
+// set_value (aplfc, at-> GetFormalCharge ());
+ set_value (aplx, get_coordinates (at).x());
+ set_value (aply, get_coordinates (at).y());
+ set_value (aplz, get_coordinates (at).z());
+ QString atomID = QString(res->GetAtomID(at).c_str());
+ set_value (idl, atomID.trimmed().toStdString());
+// set_value (resnu, at->GetResidue ()->GetNum ());
+// int prop = 0;
+// bool a = at -> GetResidue ()-> GetAtomProperty (at, prop);
+// cerr << a << endl;
+// set_value (aptype, prop);
+// int n = at->GetResidue ()->GetResKey ();
+// set_value (resna, Residue[n]);
+// set_value (resna, at->GetResidue ()->GetName ());
+
+}
+
+
+
+void Clicked_atomMenu::set (Atom *at){
+ clicked_atom = at;
+ update ();
+}
+
+
+
+void Clicked_atomMenu::set_value (QLabel *lab, float val) {
+ stringstream ss;
+ ss << val;
+ lab->setText (QString(ss.str().c_str()));
+}
+
+
+
+void Clicked_atomMenu::set_value (QLabel *lab, string val) {
+ lab->setText (QString(val.c_str()));
+}
+
+
+
+void Clicked_atomMenu::set_value (QLineEdit *lab, float val) {
+ stringstream ss;
+ ss << val;
+ lab->setText (QString(ss.str().c_str()));
+}
+
+
+
+void Clicked_atomMenu::set_clicked_atom_as_center_of_view (){
+
+ _data ->ddwin->gl->set_center_of_view (get_coordinates (clicked_atom));
+}
+
+
+
+void Clicked_atomMenu::set_clicked_atom_as_center_of_rotation () {
+
+ _data ->ddwin->gl->set_center_of_rotation (get_coordinates (clicked_atom));
+
+}
+
+
+
+void Clicked_atomMenu::add_Hs () {
+ ZNMolecule *mol = (ZNMolecule *) clicked_atom -> GetParent ();
+ mol -> DeleteHydrogens ();
+ mol -> AddHydrogens ();
+ finalise_molecule (mol);
+ _data ->ddwin -> gl -> draw_molecule (mol);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+BrowserMenu::BrowserMenu (QWidget *parent, DDWin *ddw)
+ : QWidget (parent)
+{
+ ddwin = ddw;
+ target = NULL;
+ QHBoxLayout *hbox = new QHBoxLayout;
+ setLayout (hbox);
+ // this->setMinimumSize (500, 250);
+ // this->setMaximumSize (500, 250);
+ // this->setMinimumSize (500, 250);
+ // this->setMaximumSize (500, 250);
+ // this->setWindowTitle("Database Browser");
+
+ QPushButton *first = new QPushButton ("<<");
+ connect (first, SIGNAL (clicked ()) ,SLOT (first_slot ()));
+ QPushButton *prev = new QPushButton ("<");
+ connect (prev, SIGNAL (clicked ()) ,SLOT (prev_slot ()));
+
+ QPushButton *next = new QPushButton (">");
+ connect (next, SIGNAL (clicked ()) ,SLOT (next_slot ()));
+
+ QPushButton *last = new QPushButton (">>");
+ connect (last, SIGNAL (clicked ()) ,SLOT (last_slot ()));
+
+ hbox -> addWidget (first);
+ hbox -> addWidget (prev);
+ hbox -> addWidget (next);
+ hbox -> addWidget (last);
+}
+
+
+
+void BrowserMenu::first_slot () {
+ current_number = 0;
+ set_mol ();
+}
+
+
+
+void BrowserMenu::prev_slot () {
+ if (current_number > 0) {
+ current_number--;
+ set_mol ();
+ }
+}
+
+
+
+void BrowserMenu::set_target (Database *db) {
+ target = db;
+}
+
+
+
+void BrowserMenu::next_slot () {
+ if (current_number+1 < target->count_entries ()) {
+ current_number++;
+ set_mol ();
+ }
+}
+
+
+
+void BrowserMenu::last_slot () {
+ current_number = target->count_entries ()-1;
+ set_mol ();
+}
+
+
+
+void BrowserMenu::set_mol () {
+ for (unsigned int i=0; i<ddwin->molecules.size (); i++) {
+ if (ddwin->molecules[i]->multi) {
+ Database_molecule *dm;
+ dm = (Database_molecule *) ddwin->molecules[i];
+ if (dm->database == target) {
+ ddwin->molecules[i] = target->get_molecule (current_number);
+ ddwin->set_current_target (i);
+ ddwin->gl->draw_molecule (ddwin->target_molecule);
+ }
+ }
+ }
+}
+*/
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+DatabaseGrid::DatabaseGrid (QWidget *parent, Database *db, Data *dat)
+:ZNMenu (parent, dat, false, false) {
+ hide_cb = new MyCheckBox (_main_widget ->layout (), db -> get_is_hidden (), "Hide");
+ connect (hide_cb, SIGNAL (toggled (bool)), SLOT (manage_hide (bool)));
+ setup_actions ();
+ ext_bool = false;
+ tab = new QTableWidget();
+ connect (tab, SIGNAL (cellChanged ( int , int )) ,SLOT (update_cell (int, int)));
+ _main_widget ->layout () ->addWidget (tab);
+ tab -> setSortingEnabled (false);
+ set_database(db);
+ MyCheckBox *extend = new MyCheckBox (_main_widget ->layout (), database -> get_extend_enabled (), "Extend actions to database");
+
+ _main_widget ->layout ()-> addWidget (tab);
+
+ current_number = 0;
+ QHBoxLayout *hbox = new QHBoxLayout;
+ ///addLayout (hbox);
+ QPushButton *first = new QPushButton ("<<");
+ connect (first, SIGNAL (clicked ()) ,SLOT (first_slot ()));
+ QPushButton *prev = new QPushButton ("<");
+ connect (prev, SIGNAL (clicked ()) ,SLOT (prev_slot ()));
+
+ le = new QLineEdit ();
+ connect (le, SIGNAL (textEdited (const QString)), SLOT (manage_number_changed (const QString)));
+
+ QPushButton *next = new QPushButton (">");
+ connect (next, SIGNAL (clicked ()) ,SLOT (next_slot ()));
+
+ QPushButton *last = new QPushButton (">>");
+ connect (last, SIGNAL (clicked ()) ,SLOT (last_slot ()));
+
+ hbox -> addWidget (first);
+ hbox -> addWidget (prev);
+ hbox -> addWidget (le);
+ hbox -> addWidget (next);
+ hbox -> addWidget (last);
+
+ QWidget *wid = new QWidget;
+ wid ->setLayout (hbox);
+ _main_widget ->layout ()-> addWidget (wid);
+
+ data = dat;
+ connect (tab, SIGNAL (cellDoubleClicked (int, int)), this, SLOT (manage_double_click (int, int)));
+ add_menu ();
+ add_help ();
+}
+
+
+void DatabaseGrid::add_menu () {
+ QMenu *add = new QMenu(tr("&Add"), this );
+
+ add -> addAction (newFieldAct);
+ add -> addAction (addTargetMolAct);
+ add -> addAction (loadCsvAct);
+ add -> addAction (mergedatabaseAct);
+
+ QMenu *edit = new QMenu (tr("&Edit"), this);
+/*
+ _save_action = new QAction (tr ("&Save"), this);
+ connect (_save_action, SIGNAL (triggered ()), this, SLOT (_save_slot ()));
+ file -> addAction (_save_action);
+
+*/
+
+ edit -> addAction (univocalnamesAct);
+ addMenu (add);
+ addMenu (edit);
+
+/* QMenu *settings = new QMenu(tr("&Settings"), this );
+ _restore_action = new QAction (tr ("&Restore to default"), this);
+ connect (_restore_action, SIGNAL (triggered ()), this, SLOT (_restore_slot ()));
+ settings -> addAction (_restore_action);
+ addMenu (settings);
+ */
+}
+
+void DatabaseGrid::setup_actions () {
+ newFieldAct = new QAction (tr ("&New Field"), this);
+ connect (newFieldAct, SIGNAL (triggered ()), this, SLOT (new_field_slot ()));
+
+ loadCsvAct = new QAction (tr ("Import CSV file"), this);
+ connect (loadCsvAct, SIGNAL (triggered ()), this, SLOT (load_csv_slot ()));
+
+
+ toolbar = new QToolBar ("Main");
+ addToolBar (toolbar);
+ sortupAct = new QAction (tr("Sort up"), this);
+ connect (sortupAct, SIGNAL (triggered ()), this, SLOT (sort_up_slot ()));
+
+ sortdownAct = new QAction (tr("Sort down"), this);
+ connect (sortdownAct, SIGNAL (triggered ()), this, SLOT (sort_down_slot ()));
+
+
+ addTargetMolAct = new QAction (tr("Add target Molecule"), this);
+ connect (addTargetMolAct, SIGNAL (triggered ()), this, SLOT (add_target_molecule_slot ()));
+
+ mergedatabaseAct = new QAction (tr("Merge Database"), this);
+ connect (mergedatabaseAct, SIGNAL (triggered ()), this, SLOT (merge_database_slot ()));
+
+ FiTAct = new QAction (tr("FiT Consensus"), this);
+ connect (FiTAct, SIGNAL (triggered ()), this, SLOT (FiT_slot ()));
+
+ calcAct = new QAction (tr("Calculate descriptors"), this);
+ connect (calcAct, SIGNAL (triggered ()), this, SLOT (calc_slot ()));
+
+ univocalnamesAct = new QAction (tr("Univocal Names"), this);
+ connect (univocalnamesAct, SIGNAL (triggered ()), this, SLOT (univocal_names_slot ()));
+
+
+ toolbar ->addAction (sortupAct);
+ toolbar ->addAction (sortdownAct);
+ toolbar ->addAction (FiTAct);
+ toolbar ->addAction (calcAct);
+}
+
+void DatabaseGrid::manage_number_changed (const QString str) {
+ istringstream ss (str.toStdString ());
+ int i;
+ ss >> i;
+ set_current_molecule (i-1);
+}
+
+
+void DatabaseGrid::update_cell (int r, int c) {
+//cerr <<" update "<< r << " " << c << endl;
+ database ->mutex ->lockForRead ();
+//need to make this undoable
+if (0<r<database->count_fields () && 0<c<database->count_entries ()) {
+ QString st= tab ->item (r, c) ->text ();
+ database ->entries [r] -> cells [c] ->set_value (st.toStdString ());
+}
+
+ database ->mutex ->unlock ();
+ database ->set_needs_redraw (true);
+}
+
+
+void DatabaseGrid::manage_double_click (int r) {
+ set_current_molecule (r);
+}
+
+void DatabaseGrid::manage_hide (bool b) {
+ database ->get_is_hidden () = b;
+ set_mol ();
+}
+
+
+void DatabaseGrid::set_current_molecule (int i) {
+ if (i>-1 && i< database -> count_entries ()) {
+ deselect_row (current_number);
+ stringstream ss;
+ ss << i+1;
+ le -> setText (QString (ss.str ().c_str ()));
+ current_number = i;
+ select_row (current_number);
+ set_mol ();
+ }
+}
+
+
+
+void DatabaseGrid::set_database (Database *db) {
+ database = db;
+ update_graphics ();
+}
+
+
+
+void DatabaseGrid::update_graphics () {
+//needs deleting all previous cells
+ database ->mutex ->lockForRead ();
+ if (!database ->count_entries ()) {
+ hide_cb ->setEnabled (false);
+ hide_cb ->setChecked (true);
+ }
+ else hide_cb ->setEnabled (true);
+// cerr << database ->count_fields () << " fields "<<database ->count_entries ()<<"entries"<<endl;
+ tab -> setColumnCount (database -> count_fields ());
+ tab ->setRowCount (database -> count_entries ());
+// QTableWidgetItem *name = new QTableWidgetItem (QString ("Name"));
+// tab ->setHorizontalHeaderItem (0, name);
+
+ for (unsigned int j = 0; j < database ->field_names.size (); j ++) {
+ QTableWidgetItem *field_name = new QTableWidgetItem (QString (database ->field_names[j].c_str ()));
+ tab ->setHorizontalHeaderItem (j, field_name);
+ }
+
+ for (unsigned int i=0; i< database ->count_entries (); i++) {
+// Database_molecule *mol = database -> molecules [i];
+
+// QTableWidgetItem *num_widget = new QTableWidgetItem ();
+// num_widget ->setData (Qt::DisplayRole, mol -> number);
+// tab -> setItem (i, 0, num_widget);
+ for (unsigned int j = 0; j < database ->count_fields (); j ++) {
+ QTableWidgetItem *value_widget = new QTableWidgetItem ();
+ value_widget ->setData (Qt::DisplayRole, QString (database -> entries[i] ->cells[j] ->get_string ().c_str ()));
+ tab -> setItem (i, j, value_widget);
+// cerr << "insert " << i << " "<<j<<" "<< database -> entries[i] ->cells[j] ->get_string () << endl;
+ }
+ }
+ database ->set_needs_redraw (false);
+ database ->mutex ->unlock ();
+}
+
+void DatabaseGrid::sort_up_slot () {
+ int column = tab ->currentColumn ();
+ database -> safe_sort_up (column);
+}
+
+void DatabaseGrid::sort_down_slot () {
+ int column = tab ->currentColumn ();
+ database -> safe_sort_down (column);
+}
+
+void DatabaseGrid::first_slot () {
+ set_current_molecule (0);
+}
+
+void DatabaseGrid::univocal_names_slot () {
+ database ->mutex ->lockForWrite ();
+ int nf = (int) log10 (database ->count_entries ())+1;
+ for (unsigned int i = 0; i < database ->count_entries (); i++) {
+ stringstream ss;
+ ss << "Molecule_"<<setw(nf) << setfill('0') <<i+1;
+ database ->entries[i] ->cells[0] ->set_value (ss.str ());
+ }
+ database ->set_needs_redraw (true);
+ database ->mutex ->unlock ();
+
+}
+
+void DatabaseGrid::prev_slot () {
+ set_current_molecule (current_number - 1);
+}
+
+
+
+void DatabaseGrid::next_slot () {
+ set_current_molecule (current_number + 1);
+}
+
+
+
+void DatabaseGrid::last_slot () {
+ set_current_molecule ( database->count_entries ()-1);
+}
+
+void DatabaseGrid::new_field_slot () {
+ vector <string> dat (database ->count_entries (), "0");
+ database ->safe_add_field ("New Field", dat);
+}
+
+void DatabaseGrid::add_target_molecule_slot () {
+ if (data ->ddwin ->current_target) {
+ if (!data ->ddwin ->target_molecule ->multi && !data ->ddwin ->target_molecule ->selection) {
+ Database_molecule *new_mol = new Database_molecule (*data ->ddwin ->target_molecule);
+ data ->ddwin ->set_lists (new_mol);
+ database ->safe_add_mol (new_mol);
+ }
+ }
+}
+
+void DatabaseGrid::merge_database_slot () {
+ QString dat_name = QFileDialog::getOpenFileName(this,
+ tr ("Database"), _data ->ddwin ->last_visited_dir, tr("All Files (*)"));
+ if (!dat_name.isEmpty ()) {
+ Database *new_dat =_data ->ddwin ->load_multi_file (dat_name.toStdString ());
+ database ->safe_merge_with (new_dat);
+ }
+}
+
+
+void DatabaseGrid::load_csv_slot () {
+ QString file_name = QFileDialog::getOpenFileName(this,
+ tr ("CSV files"), _data ->ddwin ->last_visited_dir, tr("CSV (*)"));
+ if (!file_name.isEmpty ()) {
+ database ->import_csv (file_name.toStdString ());
+ }
+}
+
+void DatabaseGrid::calc_slot () {
+ cerr << "calc param" << endl;
+
+ database ->mutex ->lockForWrite ();
+ float perc = 0.1;
+ int mols = database ->count_entries ();
+ int top = (int) (mols *perc);
+ vector <string> dat (mols, "0");
+ database ->add_field ("Param", dat);
+/*
+ for (unsigned int i = 0; mols; i++) {
+ OBMol *mol = new OBMol ();
+ int atom = 0;
+ FOR_ATOMS_OF_MOL(a, mol)
+ {
+ atom += a;
+ stringstream ss;
+ ss << atom;
+ string atom_number = ss.str();
+ cerr << "atom number:" << ss.toStdString () << endl;
+ }
+ }
+
+
+
+ vector <int> sel_columns = selected_columns ();
+ if (sel_columns.size ()) {
+ for (unsigned int i = 0; i < sel_columns.size (); i++) {
+ database -> sort_up (sel_columns[i]);
+ for (unsigned int j = 0; j < top; j++) {
+ double d = database ->entries[j] ->cells[database ->count_fields () -1] ->get_double ();
+ database ->entries[j] ->cells[database ->count_fields () -1] ->set_double (d + 1);
+ }
+ }
+ }
+*/
+ database ->set_needs_redraw (true);
+ database ->mutex ->unlock ();
+
+}
+
+void DatabaseGrid::FiT_slot () {
+ database ->mutex ->lockForWrite ();
+ float perc = 0.1;
+ int mols = database ->count_entries ();
+ int top = (int) (mols *perc);
+ vector <string> dat (mols, "0");
+ database ->add_field ("Fit", dat);
+
+ vector <int> sel_columns = selected_columns ();
+ if (sel_columns.size ()) {
+ for (unsigned int i = 0; i < sel_columns.size (); i++) {
+ database -> sort_up (sel_columns[i]);
+ for (unsigned int j = 0; j < top; j++) {
+ double d = database ->entries[j] ->cells[database ->count_fields () -1] ->get_double ();
+ database ->entries[j] ->cells[database ->count_fields () -1] ->set_double (d + 1);
+ }
+ }
+ }
+ database ->set_needs_redraw (true);
+ database ->mutex ->unlock ();
+}
+
+vector <int> DatabaseGrid::selected_columns () {
+ vector <int> out;
+ //database ->mutex ->lockForRead ();
+ vector <bool> bools ( tab ->columnCount (),false);
+ QList<QTableWidgetItem *> indexs = tab ->selectedItems ();
+ for (unsigned int i = 0; i < indexs.size(); i++) {
+ bools[indexs.at (i) ->column ()] = true;
+ }
+// database ->mutex ->unlock ();
+ for (unsigned int i = 0; i < bools.size (); i++) {
+ if (bools[i]) out.push_back (i);
+ }
+ return out;
+}
+
+void DatabaseGrid::set_mol () {
+ ZNMolecule *mol;
+ if (database ->get_is_hidden ()) {mol = database ->dummy_mol; }
+ else mol = database ->get_molecule (current_number);
+ for (unsigned int i=0; i<data -> ddwin->molecules.size (); i++) {
+ if (data -> ddwin->molecules[i]->multi) {
+ Database_molecule *dm;
+ dm = (Database_molecule *) data -> ddwin->molecules[i];
+ if (dm->database == database) {
+ data -> ddwin->molecules[i] = mol;
+ data -> ddwin->set_current_target (i);
+ data -> ddwin->gl->draw_molecule (data -> ddwin->target_molecule);
+ }
+ }
+ }
+}
+
+void DatabaseGrid::set_row_color (int r, color c) {
+ if (r>-1 && r< tab -> rowCount ()) {
+ for (unsigned int i = 0; i< tab -> columnCount (); i++) {
+ tab -> item (r, i) -> setBackground (QBrush (c));
+ }
+ }
+}
+
+
+
+void DatabaseGrid::select_row (int r) {
+ color violet = color (190, 20, 255);
+ set_row_color (r, violet);
+}
+
+
+
+void DatabaseGrid::deselect_row (int r) {
+ color white = color (255, 255, 255);
+ set_row_color (r, white);
+}
+
+
+
+int DatabaseGrid::real_index_of_line (int i) {
+ return i;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ColorSettingsMenu::ColorSettingsMenu (QWidget *parent, DDWin *ddw)
+: QWidget (parent)
+{
+ ddwin = ddw;
+ setWindowTitle ("Color ZNMolecule");
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+ MyColorButton *background_color_edit = new MyColorButton (layout, *ddwin->data->background_color);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BackboneColorMenu::BackboneColorMenu (QWidget *parent, Data *dat)
+: ZNMenu (parent, dat, 0, 0)
+{
+
+ add_help ();
+ setWindowTitle ("Backbone Color");
+ MyHideComboBox *_type_hcb = new MyHideComboBox (main_widget () ->layout (), "Color Scheme");
+ ZNWidget *_plain_color_w = new ZNWidget ();
+ ZNWidget *_secondary_structure_w = new ZNWidget ();
+ main_widget ()->layout () -> addWidget (_plain_color_w);
+ main_widget ()->layout () -> addWidget (_secondary_structure_w);
+
+ helix_color = color (1.f, 0.f, 0.f, 1.f);
+ sheet_color = color (1.f, 1.f, 0.f, 1.f);
+ random_color = color (0.3f, 0.f, 1.f, 1.f);
+
+
+ _type_hcb ->insertItem (_plain_color_w, 0, "Single color", "Single color");
+ _type_hcb ->insertItem (_secondary_structure_w, 1, "Secondary Structure", "Secondary Structure");
+
+
+ MyCompleteColorSettings *solid_color_settings = new MyCompleteColorSettings (_plain_color_w ->layout (), constant_color);
+ QPushButton *color_ok = new QPushButton ("Ok");
+ _plain_color_w->layout () -> addWidget (color_ok);
+ connect (color_ok, SIGNAL (clicked ()), this, SLOT (color_ok_slot ()));
+
+ MyCompleteColorSettings *helix_color_settings = new MyCompleteColorSettings (_secondary_structure_w ->layout (), helix_color);
+ MyCompleteColorSettings *sheet_color_settings = new MyCompleteColorSettings (_secondary_structure_w ->layout (), sheet_color);
+ MyCompleteColorSettings *random_color_settings = new MyCompleteColorSettings (_secondary_structure_w ->layout (), random_color);
+ QPushButton *ss_ok = new QPushButton ("Ok");
+ _secondary_structure_w->layout () -> addWidget (ss_ok);
+ connect (ss_ok, SIGNAL (clicked ()), this, SLOT (ss_ok_slot ()));
+
+}
+
+
+void BackboneColorMenu::ss_ok_slot () {
+ color_backbone_ss (_data ->ddwin ->target_molecule, helix_color, sheet_color, random_color);
+}
+
+void BackboneColorMenu::color_ok_slot () {
+ color_backbone_color (_data ->ddwin ->target_molecule, constant_color);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+GraphicalObjectsColorMenu::GraphicalObjectsColorMenu (QWidget *parent, Data *dat)
+: ZNMenu (parent, dat, 0, 0), target (0)
+{
+
+ add_help ();
+
+ hb_acc_color = color (1.f, 0.f, 0.f, 1.f);
+ hb_don_color = color (0.f, 0.f, 1.f, 1.f);
+ lipo_color = color (0.f, 1.f, 0.f, 1.f);
+
+ setWindowTitle ("Color Graphical Object");
+
+ alpha_multiplier = 100.;
+ alpha_value = 100.;
+ colortype = new QComboBox;
+ main_widget ()->layout () -> addWidget (colortype);
+ colortype -> insertItem (0, "Color" );
+ colortype -> insertItem (1, "Molecule");
+ colortype -> insertItem (2, "Maps");
+ colortype -> insertItem (3, "Potentials" );
+ colortype -> insertItem (4, "Alpha Effects" );
+
+ colortype ->setCurrentItem(0);
+
+
+ options = new QStackedWidget;
+ main_widget ()->layout () -> addWidget (options);
+
+ ZNWidget *color_widget = new ZNWidget ();
+ MyCompleteColorSettings *solid_color_settings = new MyCompleteColorSettings (color_widget ->layout (), constant_color);
+
+ ZNWidget *molecule_widget = new ZNWidget ();
+ ZNWidget *maps_widget = new ZNWidget ();
+
+
+ maps_cb = new QComboBox;
+ maps_widget ->layout() ->addWidget (maps_cb);
+
+ QWidget *square = new QWidget ();
+ QVBoxLayout *mapslay = new QVBoxLayout ();
+ square -> setLayout(mapslay);
+ maps_widget ->layout() ->addWidget (square);
+ QHBoxLayout *score_begin_layout = new QHBoxLayout ();
+ mapslay -> addLayout (score_begin_layout);
+ QHBoxLayout *score_mid_layout = new QHBoxLayout ();
+ mapslay -> addLayout (score_mid_layout);
+ QHBoxLayout *score_end_layout = new QHBoxLayout ();
+ mapslay -> addLayout (score_end_layout);
+
+ score_begin_color = _data ->score_begin_color;
+ score_mid_color = _data ->score_mid_color;
+ score_end_color = _data ->score_end_color;
+ score_begin_f = _data ->score_begin;
+ score_mid_f = _data ->score_mid;
+ score_end_f = _data ->score_end;
+
+ MyFloatEditLine *score_begin_line = new MyFloatEditLine (score_begin_layout, "begin", score_begin_f);
+ MyFloatEditLine *score_mid_line = new MyFloatEditLine (score_mid_layout, "mid", score_mid_f);
+ MyFloatEditLine *score_end_line = new MyFloatEditLine (score_end_layout, "end", score_end_f);
+
+
+ MyCompleteColorSettings *score_begin_colorset = new MyCompleteColorSettings (score_begin_layout, score_begin_color);
+ MyCompleteColorSettings *score_mid_colorset = new MyCompleteColorSettings (score_mid_layout, score_mid_color);
+ MyCompleteColorSettings *score_end_colorset = new MyCompleteColorSettings (score_end_layout, score_end_color);
+
+
+ ZNWidget *potential_widget = new ZNWidget ();
+ MyCompleteColorSettings *lipo_color_settings = new MyCompleteColorSettings (potential_widget ->layout (), lipo_color, "Lipophilic");
+ MyCompleteColorSettings *acc_color_settings = new MyCompleteColorSettings (potential_widget ->layout (), hb_acc_color, "HB acceptor");
+ MyCompleteColorSettings *don_color_settings = new MyCompleteColorSettings (potential_widget ->layout (), hb_don_color, "HB donor");
+
+
+
+
+ ZNWidget *alpha_widget = new ZNWidget ();
+
+ molecule_target_cb = new QComboBox;
+ molecule_target_cb2 = new QComboBox;
+ molecule_target_cb3 = new QComboBox;
+ molecule_widget ->layout () ->addWidget(molecule_target_cb);
+ alpha_widget ->layout () ->addWidget(molecule_target_cb2);
+ potential_widget ->layout () ->addWidget(molecule_target_cb3);
+ options ->addWidget (color_widget);
+ options ->addWidget (molecule_widget);
+ options ->addWidget (maps_widget);
+ options ->addWidget (potential_widget);
+ options ->addWidget (alpha_widget);
+
+ alpha_mol_distance_d = 4.;
+ new MyFloatEditLine (alpha_widget ->layout (), "Fade distance", alpha_mol_distance_d);
+ QPushButton *fade_but = new QPushButton ("Ok");
+ alpha_widget ->layout() ->addWidget (fade_but);
+ connect (fade_but, SIGNAL (clicked ()), this, SLOT (fade_slot ()));
+
+
+
+
+
+ new MyFloatEditLine (alpha_widget ->layout (), "Multiply Alpha by %", alpha_multiplier, 0, 100);
+ QPushButton *perc_mult_but = new QPushButton ("Ok");
+ alpha_widget ->layout() ->addWidget(perc_mult_but);
+ connect (perc_mult_but, SIGNAL (clicked ()), this, SLOT (mult_slot ()));
+
+ new MyFloatEditLine (alpha_widget ->layout (), "Set Alpha", alpha_value, 0, 100);
+ QPushButton *alpha_but = new QPushButton ("Ok");
+ alpha_widget ->layout() ->addWidget(alpha_but);
+ connect (alpha_but, SIGNAL (clicked ()), this, SLOT (alpha_slot ()));
+
+
+
+
+ connect (colortype, SIGNAL(activated(int)), options, SLOT(setCurrentIndex(int)) );
+ connect (_data -> ddwin, SIGNAL (targets_updated ()), this, SLOT (update_mols ()));
+ connect (_data -> ddwin, SIGNAL (go_updated ()), this, SLOT (update_maps ())); //temporary... while maps are still considered gos
+
+
+ QPushButton *ok = new QPushButton ("Ok");
+ ZNWidget *buttons = new ZNWidget ();
+ buttons -> layout () ->addWidget (ok);
+ connect (ok, SIGNAL (clicked ()), this, SLOT (ok_slot ()));
+
+ main_widget ()->layout () -> addWidget (buttons);
+}
+
+
+
+void GraphicalObjectsColorMenu::update_mols () {
+ molecule_target_cb ->clear ();
+ molecule_target_cb2 ->clear ();
+ molecule_target_cb3 ->clear ();
+ for (unsigned int i = 0; i < _data -> ddwin -> target ->count (); i++) {
+ molecule_target_cb ->insertItem (i, _data -> ddwin -> target ->itemText (i));
+ molecule_target_cb2 ->insertItem (i, _data -> ddwin -> target ->itemText (i));
+ molecule_target_cb3 ->insertItem (i, _data -> ddwin -> target ->itemText (i));
+ }
+
+
+
+}
+
+void GraphicalObjectsColorMenu::update_maps () {
+ maps_cb ->clear ();
+ for (unsigned int i = 0; i < _data -> ddwin -> graphical_objects.size (); i++) { //temporary... while maps are still considered gos
+ if (_data -> ddwin -> graphical_objects[i] ->is_map ()) {
+ maps_cb ->insertItem (i, QString (_data -> ddwin -> graphical_objects[i] ->name.c_str ()));
+ }
+ }
+
+
+
+}
+
+void GraphicalObjectsColorMenu::mult_slot () {
+ if (target) {
+ target ->multiply_alpha (alpha_multiplier/100);
+ target ->render ();
+ }
+}
+
+void GraphicalObjectsColorMenu::alpha_slot () {
+ if (target) {
+ target ->set_alpha (alpha_value/100);
+ target ->render ();
+ }
+}
+
+void GraphicalObjectsColorMenu::fade_slot () {
+ if (target) {
+ int indx = molecule_target_cb2 ->currentIndex();
+ if (indx) {
+ ZNMolecule *mol = _data -> ddwin -> molecules [indx];
+ target ->alpha_by_mol_distance (mol, alpha_mol_distance_d);
+ target ->render ();
+ }
+ }
+}
+
+void GraphicalObjectsColorMenu::ok_slot () {
+ if (target) {
+ if ( options -> currentIndex () == 0) {
+ target ->color_by_color (constant_color);
+ target ->render ();
+
+ }
+ else if ( options -> currentIndex () == 1) {
+ int indx = molecule_target_cb ->currentIndex();
+ if (indx) {
+ ZNMolecule *mol = _data -> ddwin -> molecules [indx];
+ target ->color_by_mol (mol);
+ target ->render ();
+ }
+ }
+
+ else if ( options -> currentIndex () == 2) {
+ int indx = maps_cb ->currentIndex();
+
+
+ if (_data -> ddwin -> graphical_objects [indx] ->is_map ()) {
+ Map *map = (Map *) (_data -> ddwin -> graphical_objects [indx]);
+ target ->color_by_map (map, score_begin_color, score_mid_color, score_end_color, score_begin_f, score_mid_f, score_end_f);
+ target ->render ();
+ }
+
+ }
+ else if ( options -> currentIndex () == 3) {
+ int indx = molecule_target_cb3 ->currentIndex();
+ if (indx) {
+ ZNMolecule *mol = _data -> ddwin -> molecules [indx];
+ target ->color_by_potential (mol, lipo_color, hb_acc_color, hb_don_color);
+ target ->render ();
+ }
+ }
+
+
+ }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ColorMenu::ColorMenu (QWidget *parent, DDWin *ddw)
+ : QWidget (parent)
+{
+ ddwin = ddw;
+ setWindowTitle ("Color Molecule");
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+
+
+ colortype = new QComboBox;
+ layout -> addWidget (colortype);
+ colortype -> insertItem (ELEMENT, "Element");
+ colortype -> insertItem (CHARGE, "Charge" );
+ colortype -> insertItem (SCORE, "Score" );
+ colortype -> insertItem (COLOR, "Color" );
+
+ options = new QStackedWidget;
+ layout -> addWidget (options);
+
+ QWidget *element_options = new QWidget ();
+
+
+ QWidget *charge_options = new QWidget ();
+ QVBoxLayout *charge_layout = new QVBoxLayout ();
+ charge_options -> setLayout (charge_layout);
+ QHBoxLayout *charge_begin_layout = new QHBoxLayout ();
+ charge_layout -> addLayout (charge_begin_layout);
+ QHBoxLayout *charge_end_layout = new QHBoxLayout ();
+ charge_layout -> addLayout (charge_end_layout);
+
+ charge_begin_line = new MyFloatEditLine (charge_begin_layout, "begin", ddwin->data->charge_begin);
+ charge_end_line = new MyFloatEditLine (charge_end_layout, "end", ddwin->data->charge_end);
+
+/* unused variable
+ MyColorButton *charge_begin_color = new MyColorButton (charge_begin_layout, ddwin->data->charge_begin_color);
+ MyColorButton *charge_end_color = new MyColorButton (charge_end_layout, ddwin->data->charge_end_color);
+*/
+
+ QWidget *score_options = new QWidget ();
+ QVBoxLayout *score_layout = new QVBoxLayout ();
+ score_options -> setLayout (score_layout);
+ QHBoxLayout *score_begin_layout = new QHBoxLayout ();
+ score_layout -> addLayout (score_begin_layout);
+ QHBoxLayout *score_mid_layout = new QHBoxLayout ();
+ score_layout -> addLayout (score_mid_layout);
+ QHBoxLayout *score_end_layout = new QHBoxLayout ();
+ score_layout -> addLayout (score_end_layout);
+
+ score_begin_line = new MyFloatEditLine (score_begin_layout, "begin", ddwin->data->score_begin);
+ score_mid_line = new MyFloatEditLine (score_mid_layout, "mid", ddwin->data->score_mid);
+ score_end_line = new MyFloatEditLine (score_end_layout, "end", ddwin->data->score_end);
+
+
+ MyCompleteColorSettings *score_begin_color = new MyCompleteColorSettings (score_begin_layout, ddwin->data->score_begin_color);
+ MyCompleteColorSettings *score_mid_color = new MyCompleteColorSettings (score_mid_layout, ddwin->data->score_mid_color);
+ MyCompleteColorSettings *score_end_color = new MyCompleteColorSettings (score_end_layout, ddwin->data->score_end_color);
+
+
+ QWidget *color_options = new QWidget ();
+ QVBoxLayout *color_layout = new QVBoxLayout ();
+ color_options -> setLayout (color_layout);
+
+
+ MyCompleteColorSettings *select_color_buttons = new MyCompleteColorSettings (color_layout, ddwin->data->constant_color);
+
+
+ options -> addWidget (element_options);
+ options -> addWidget (charge_options);
+ options -> addWidget (score_options);
+ options -> addWidget (color_options);
+
+ layout -> addSpacing (5);
+
+ QPushButton *multiple = new QPushButton ("Multiple colors");
+ layout -> addWidget (multiple);
+
+ QListView *list = new QListView ();
+ layout ->addWidget (list);
+
+ QHBoxLayout *buttons = new QHBoxLayout ();
+ layout -> addLayout (buttons);
+
+ QPushButton *ok = new QPushButton ("Ok");
+ buttons -> addWidget (ok);
+
+
+ connect (colortype, SIGNAL(activated(int)), options, SLOT(setCurrentIndex(int)) );
+ connect (ok, SIGNAL (clicked ()), this, SLOT (ok_slot ()));
+}
+
+
+
+void ColorMenu::ok_slot () {
+ score_begin_line -> set ();
+ score_mid_line -> set ();
+ score_end_line -> set ();
+ charge_begin_line -> set ();
+ charge_end_line -> set ();
+
+
+ vector <color_mask> masks;
+ color_mask mask;
+ mask.intensity = 1.0f;
+ mask.only_to = 0;
+ mask.excluding = 0;
+ mask.type = options -> currentIndex ();
+ masks.push_back (mask);
+ if (is_db_extended (ddwin ->target_molecule)) {
+ Database_molecule *dbm = (Database_molecule *) ddwin -> target_molecule;
+ Database *db = dbm ->database;
+ ddwin -> data -> actions -> apply_color_masks (masks, db);
+ }
+ else {
+ ddwin -> data -> actions -> apply_color_masks (masks, ddwin ->target_molecule);
+ }
+}
+
+
+
+GraphicalObjectsMenu::GraphicalObjectsMenu (QWidget *parent, DDWin *ddw)
+ : QWidget (parent)
+{
+ // selected = -1;
+ ddwin = ddw;
+ setWindowTitle ("Graphical Objects");
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+
+ list = new QListWidget ();
+ layout -> addWidget (list);
+
+ QPushButton *del = new QPushButton ("Delete");
+ layout -> addWidget (del);
+
+ connect (del, SIGNAL (clicked ()), this, SLOT (delete_selected_slot ()));
+
+ connect(list,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(show_color_menu(QListWidgetItem*)));
+}
+
+void GraphicalObjectsMenu::show_color_menu (QListWidgetItem *item) {
+ int row = list ->currentIndex ().row ();
+ ddwin ->go_color_menu ->set_target(ddwin ->graphical_objects[row]);
+ ddwin ->go_color_menu ->display ();
+}
+
+
+void GraphicalObjectsMenu::update_slot () {
+ int row = list -> currentRow ();
+ bool selected = list -> isItemSelected (list -> currentItem ());
+ list -> clear ();
+ for (unsigned int i=0; i < ddwin -> graphical_objects.size (); i++) {
+ list -> insertItem (i, tr (ddwin -> graphical_objects [i] -> name .c_str ()));
+ }
+ list -> setCurrentRow (row);
+ list -> setItemSelected (list -> currentItem (), selected);
+}
+
+
+
+void GraphicalObjectsMenu::delete_selected_slot () {
+ int i = list -> currentRow ();
+
+ if (i > -1) {
+ ddwin -> delete_graphical_object (i);
+
+ }
+}
+
+
+
+void GraphicalObjectsMenu::paintEvent (QPaintEvent *e) {
+ QWidget::paintEvent (e);
+ update_slot ();
+}
+
+
+
+DDSettingsMenu::DDSettingsMenu (QWidget *parent, DDWin *ddw)
+ : QWidget (parent)
+{
+ ddwin = ddw;
+ setWindowTitle ("3D Settings");
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+
+ focal_d = ddwin -> gl -> stereo_inter_eye_semi_distance * tan ((90.f -ddwin -> gl -> stereo_toe_in_angle) * PI / 180) ;
+
+
+ inter_eye_distance = new MyFloatEditLine (layout, "inter-eye semi distance", ddwin->gl->stereo_inter_eye_semi_distance);
+ focal_point_distance = new MyFloatEditLine (layout, "focal point distance", focal_d);
+
+ dd_cb = new QComboBox ();
+ layout -> addWidget (dd_cb);
+ dd_cb ->insertItem(0, "No Stereo" );
+ dd_cb ->insertItem(1, "Quad Buffering" );
+ dd_cb ->insertItem(2, "Vertical Interlace" );
+ dd_cb ->insertItem(3, "Horizontal Interlace" );
+
+ // IJG
+ // Need a full set of radio buttons: Use OpenGL, horizontal interlace, vertical interlace, none
+ // See DDWin::StereoMode and DDWin::g_stereoMode
+
+
+ QPushButton *ok = new QPushButton ("Ok");
+ layout -> addWidget (ok);
+
+
+ connect (ok, SIGNAL (clicked ()), this, SLOT (ok_slot ()));
+}
+
+
+
+void DDSettingsMenu::ok_slot () {
+ inter_eye_distance -> set ();
+ focal_point_distance -> set ();
+ ddwin -> gl -> stereo_toe_in_angle = 90.f - atan (focal_d / ddwin -> gl -> stereo_inter_eye_semi_distance) * 180 / PI;
+ switch (dd_cb ->currentIndex ()) {
+ case 0:
+ ddwin->g_stereoMode = DDWin::StereoMode_None;
+ ddwin->g_stencil_mask_needs_redraw = false;
+ break;
+ case 1:
+ ddwin->g_stereoMode = DDWin::StereoMode_ViaOpenGL;
+ ddwin->g_stencil_mask_needs_redraw = false;
+ break;
+ case 2:
+//<<<<<<< menu.cc
+ ddwin->g_stereoMode = DDWin::StereoMode_HorizontalInterlace;
+ ddwin->g_stencil_mask_needs_redraw = true;
+//=======
+ ddwin->g_stereoMode = DDWin::StereoMode_VerticalInterlace;
+//>>>>>>> 1.7
+ break;
+ case 3:
+//<<<<<<< menu.cc
+ ddwin->g_stereoMode = DDWin::StereoMode_VerticalInterlace;
+ ddwin->g_stencil_mask_needs_redraw = true;
+//=======
+ ddwin->g_stereoMode = DDWin::StereoMode_HorizontalInterlace;
+//>>>>>>> 1.7
+ break;
+ default:
+ ddwin->g_stereoMode = DDWin::StereoMode_None;
+ ddwin->g_stencil_mask_needs_redraw = false;
+ break;
+ }
+
+ // Also need to update ddwin - so it sets up the stencil buffer.
+ ddwin -> gl ->refreshStencilBuffer();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// "My" function
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+MyCheckBox::MyCheckBox (QLayout *parent, bool &v, string str) : QCheckBox ( QString (str.c_str ())) {
+ parent -> addWidget (this);
+ var = &v;
+ get ();
+ connect (this, SIGNAL (stateChanged (int)), this, SLOT (set ()) );
+}
+
+
+void MyCheckBox::get () {
+ if (*var) setCheckState (Qt::Checked);
+ else setCheckState (Qt::Unchecked);
+}
+
+
+void MyCheckBox::set () {
+ if (checkState () == Qt::Checked) *var = TRUE;
+ else *var = false;
+}
+
+
+
+MyColorButton::MyColorButton (QLayout *parent, QColor &col) : QPushButton () {
+ parent -> addWidget (this);
+ color = &col;
+ connect (this, SIGNAL (clicked ()), this, SLOT (my_clicked ()) );
+}
+
+
+void MyColorButton::paintEvent (QPaintEvent *e) {
+ QPushButton::paintEvent (e);
+ QPixmap pix(48, 48);
+ pix.fill(*color);
+ this->setIcon(pix);
+
+}
+
+
+void MyColorButton::my_clicked () {
+ QColor new_color = QColorDialog::getColor(*color, this );
+ if ( new_color.isValid () ) {
+ new_color.setAlphaF (color ->alphaF ());
+ *color = new_color;
+ }
+}
+
+
+
+MyComboBox::MyComboBox (QLayout *parent, const char *name) {
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+ QLabel *label = new QLabel (name);
+ layout -> addWidget (label);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+
+ _combo_box = new QComboBox ();
+ layout -> addWidget (_combo_box);
+}
+
+
+
+MyCompleteColorSettings::MyCompleteColorSettings (QLayout *parent, color &col, string name) {
+ setLayout (new QHBoxLayout ());
+ button = new MyColorButton (layout (), col);
+ alpha = (int) col.alphaF () * 100;
+ slider = new MySlider (layout (), "opacity", alpha, 0, 100);
+ if (name!=""){
+ QLabel *name_l = new QLabel (name.c_str ());
+ layout () -> addWidget (name_l);
+ }
+ connect (slider -> pline -> spinbox, SIGNAL (valueChanged(int)), this, SLOT(setAlpha (int)));
+ parent ->addWidget(this);
+}
+
+
+void MyCompleteColorSettings::setAlpha (int i) {
+ double v = (double) i;
+ v /= 100.;
+ button -> color -> setAlphaF (v);
+}
+
+
+
+MyFloatEditLine::MyFloatEditLine (QLayout *parent, const char *name, double& var, double min, double max)
+ : QWidget(){
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+ variable = &var;
+ QLabel *label = new QLabel( name);
+ layout -> addWidget (label);
+// label->setMaximumWidth( 200 );
+ label->setMinimumWidth( 150 );
+ spinbox = new QDoubleSpinBox();
+ spinbox ->setMinimum (min);
+ spinbox ->setMaximum (max);
+ layout -> addWidget (spinbox);
+ spinbox->setValue (*variable);
+ connect (spinbox, SIGNAL (valueChanged (double)), this, SLOT (set (double)));
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+// spinbox ->setMinimumWidth( 150 );
+ spinbox ->setMaximumWidth( 150 );
+}
+
+
+void MyFloatEditLine::set (double d) {
+ *variable = d;
+}
+
+
+void MyFloatEditLine::set () {
+ *variable = spinbox -> value ();
+}
+
+
+void MyFloatEditLine::set_value (double d) {
+ spinbox->setValue (d);
+}
+
+
+
+MyGroupBox::MyGroupBox (QLayout *parent, string str, bool checkbox, bool status) : QGroupBox ( QString (str.c_str ()) ) {
+ parent -> addWidget (this);
+ QVBoxLayout *layout = new QVBoxLayout ();
+ this ->setLayout(layout);
+ if (checkbox) {
+ setCheckable (true);
+ if (status) {
+ setChecked (true);
+ } else {
+ setChecked (false);
+ }
+ }
+ layout ->setContentsMargins (5, 5, 5, 5);
+ layout -> setAlignment (Qt::AlignTop);
+}
+
+MyGroupBox::MyGroupBox (string str, bool checkbox, bool status) : QGroupBox ( QString (str.c_str ()) ) {
+ QVBoxLayout *layout = new QVBoxLayout ();
+ this ->setLayout(layout);
+ if (checkbox) {
+ setCheckable (true);
+ if (status) {
+ setChecked (true);
+ } else {
+ setChecked (false);
+ }
+ }
+ layout ->setContentsMargins (5, 5, 5, 5);
+ layout -> setAlignment (Qt::AlignTop);
+}
+
+
+MyHideCheckBox::MyHideCheckBox (QLayout *parent, QWidget *tar, string str) : QCheckBox ( QString (str.c_str ())) {
+ _group_box = new MyGroupBox (parent -> layout (), str, true, false);
+ _group_box -> hide ();
+ parent -> addWidget (this);
+ target = tar;
+ get ();
+ connect (this, SIGNAL (stateChanged (int)), this, SLOT (set ()) );
+ connect (_group_box, SIGNAL (clicked (bool)), this, SLOT (set_2 ()) );
+ _group_box -> layout () -> addWidget (target);
+ set ();
+}
+
+
+void MyHideCheckBox::get () {
+ if (target ->isVisible ()) set_checked (); //setCheckState (Qt::Checked);
+ else set_unchecked (); //setCheckState (Qt::Unchecked);
+}
+
+
+void MyHideCheckBox::set () {
+ if (checkState () == Qt::Checked) set_checked ();//target -> show ();
+ else set_unchecked (); //target -> hide ();
+}
+
+
+void MyHideCheckBox::set_2 () {
+ set_unchecked ();
+}
+
+
+void MyHideCheckBox::set_checked () {
+ hide ();
+ _group_box -> show ();
+ _group_box ->setChecked (true);
+}
+
+
+void MyHideCheckBox::set_unchecked () {
+ _group_box -> hide ();
+ show ();
+ _group_box -> hide ();
+ setCheckState (Qt::Unchecked);
+}
+
+
+
+MyHideComboBox::MyHideComboBox (QLayout *parent, const char *name) : MyComboBox (parent, name){
+ _widgets.clear ();
+ connect (_combo_box, SIGNAL (currentIndexChanged ( int )), this, SLOT (set ( int )) );
+}
+
+
+void MyHideComboBox::insertItem (QWidget *wid, int i, const char *name, const QVariant &data) {
+
+ unsigned int len = _widgets.size ();
+ vector<QWidget *>::iterator it;
+ it = _widgets.begin();
+ if (i < 1) i = 0;
+ else if(i > len) i = len;
+
+ _widgets.insert (it + i, wid);
+ _combo_box -> insertItem (i, name, data);
+ set (0);
+}
+
+
+void MyHideComboBox::set (int i) {
+ if (_combo_box -> count () == _widgets.size ()) {
+ for (unsigned int n = 0; n < _widgets.size (); n++) {
+ if (n == i) _widgets[n] ->show ();
+ else _widgets[n] -> hide ();
+ }
+ }
+ else cerr << "error in myhidecombobox"<< endl;
+}
+
+
+
+MyIntegerEditLine::MyIntegerEditLine (QLayout *parent, const char *name, int& var, int min, int max)
+ : QWidget(){
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+ variable = &var;
+ QLabel *label = new QLabel( name);
+ layout -> addWidget (label);
+// label->setMaximumWidth( 200 );
+ label->setMinimumWidth( 150 );
+ spinbox = new QSpinBox();
+ spinbox ->setMinimum (min);
+ spinbox ->setMaximum (max);
+ layout -> addWidget (spinbox);
+// stringstream s;
+// s << *variable;
+ spinbox->setValue(*variable);
+ connect (spinbox, SIGNAL (valueChanged (int)), this, SLOT (set (int)));
+ layout ->setContentsMargins (0, 0, 0, 0);
+ spinbox ->setMaximumWidth( 150 );
+}
+
+
+void MyIntegerEditLine::set (int d) {
+// istringstream iss (st.toStdString());
+// int i;
+// iss >> i;
+ *variable = d;
+}
+
+
+void MyIntegerEditLine::set ()
+{
+// istringstream iss (linedit->text().toStdString());
+// int i;
+// iss >> i;
+// *variable = i;
+ *variable = spinbox -> value ();
+}
+
+
+void MyIntegerEditLine::set_value (int d) {
+// stringstream s ;
+// s<<v;
+// linedit->setText (QString(s.str().c_str()));
+// set ();
+ spinbox->setValue (d);
+}
+
+
+
+MyLabelf::MyLabelf (QLayout *parent, const char *name, float& var)
+ : QWidget () {
+ parent -> addWidget (this);
+ setLayout (new QHBoxLayout ());
+ variable = &var;
+ QLabel *name_l = new QLabel ();
+ layout () ->addWidget (name_l);
+ string nam = name;
+ name_l->setText (QString(nam.c_str()));
+ label = new QLabel();
+ layout ()->addWidget (label);
+ //label->setMaximumWidth( 200 );
+ //label->setMinimumWidth( 200 );
+ label->setText (QString(double_to_string (*variable).c_str ()));
+
+ update ();
+}
+
+
+void MyLabelf::update () {
+// cerr << variable<<endl;
+// cerr << *variable<<endl;
+// float v = 30;
+// ss << v;
+// cerr << v<<endl;
+// cerr << label<< endl;
+// label ->setNum (3);
+ label->setText (QString(double_to_string (*variable).c_str ()));
+}
+
+
+void MyLabelf::set_variable (float *f) {
+ variable = f;
+}
+
+MyLineEdit::MyLineEdit (QLayout *parent, const char *name) : QWidget() {
+
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+
+ tag = name;
+ label = new QLabel( name, this );
+ label->setMaximumWidth( 150 );
+ label->setMinimumWidth( 150 );
+
+ linedit = new QLineEdit( this);
+
+ layout -> addWidget (label);
+ layout -> addWidget (linedit);
+
+}
+
+
+MyPushButton::MyPushButton (QLayout *parent, const char *name, int dim, int width) : QWidget() {
+ parent ->addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+ layout -> setAlignment (Qt::AlignTop);
+
+ fbutton = new QPushButton(name, this);
+ fbutton ->setMaximumHeight( 24 );
+ if (dim != 0 ) fbutton ->setMinimumWidth( dim );
+ if (width != 0) fbutton ->setMaximumWidth( width );
+ layout -> addWidget (fbutton);
+}
+
+MyPushButton::MyPushButton (const char *name, int dim, int width) : QWidget() {
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+ layout -> setAlignment (Qt::AlignTop);
+
+ fbutton = new QPushButton(name, this);
+ fbutton ->setMaximumHeight( 24 );
+ if (dim != 0 ) fbutton ->setMinimumWidth( dim );
+ if (width != 0) fbutton ->setMaximumWidth( width );
+ layout -> addWidget (fbutton);
+}
+
+
+MyLineFile::MyLineFile (QLayout *parent, const char *name, int valid) : QWidget() {
+
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+
+ tag = name;
+ label = new QLabel( name, this );
+// label->setMaximumWidth( 150 );
+ label->setMinimumWidth( 150 );
+
+ linedit = new QLineEdit( this);
+ linedit ->setMinimumWidth( 250 );
+// if (valid == 1) {filetype = "Tripos Mol2 File (*.mol2)";};
+// if (valid == 2) {filetype = "PLANTS Config File (*.pcfg);;All files (*)";};
+// if (valid == 3) {filetype = "List File (*)";};
+ fbutton = new QPushButton( "..." , this);
+ fbutton ->setMaximumWidth( 30 );
+ fbutton ->setMaximumHeight( 24 );
+
+ control_yes = new QLabel( this );
+ control_yes ->setPixmap (QPixmap (":icons/V.png") );
+ control_yes -> hide();
+
+ control_no = new QLabel( this );
+ control_no ->setPixmap (QPixmap (":icons/X.png") );
+ control_no -> hide();
+
+ layout -> addWidget (label);
+ layout -> addWidget (control_no);
+ layout -> addWidget (control_yes);
+ layout -> addWidget (linedit);
+ layout -> addWidget (fbutton);
+
+
+
+// connect (fbutton, SIGNAL( clicked() ), SLOT( set_file () ) );
+ if (valid == 1) {
+ connect (fbutton, SIGNAL( clicked() ), SLOT( set_file_a () ) );
+ }
+ if (valid == 2) {
+ connect (fbutton, SIGNAL( clicked() ), SLOT( set_file_b () ) );
+ }
+ if (valid == 3) {
+ connect (fbutton, SIGNAL( clicked() ), SLOT( set_file_c () ) );
+ }
+ if (valid == 4) {
+ connect (fbutton, SIGNAL( clicked() ), SLOT( set_file_d () ) );
+ }
+
+}
+
+void MyLineFile::set_file_a () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("Tripos Mol2 File (*.mol2)"));
+ linedit->clear ();
+ linedit->insert (s);
+// set_line ();
+}
+
+void MyLineFile::set_file_b () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("PLANTS Config File (*.pcfg);;All files (*)"));
+ linedit->clear ();
+ linedit->insert (s);
+// set_line ();
+}
+
+void MyLineFile::set_file_c () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("List File (*)"));
+ linedit->clear ();
+ linedit->insert (s);
+// set_line ();
+}
+
+void MyLineFile::set_file_d () {
+ QString s = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("PLANTS (plants*)"));
+ linedit->clear ();
+ linedit->insert (s);
+// set_line ();
+}
+
+/*
+QString MyLineFile::ask_file() {
+ QString mol_name = QFileDialog::getOpenFileName(this, tr ("Open file"), "",tr("Tripos Mol2 File (*.mol2)"));
+ if (valid == 3) {cerr << "www" << endl;};
+
+ return mol_name;
+}
+
+void MyLineFile::set_file () {
+ QString s = ask_file ();
+ linedit->clear ();
+ linedit->insert (s);
+// set_line ();
+}
+*/
+string MyLineFile::val () {
+ return linedit->text ().toStdString ();
+}
+
+
+MyListView::MyListView (QLayout *parent, int dim, int width, bool button) : QWidget() {
+
+ parent -> addWidget (this);
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+
+ layout -> setAlignment (Qt::AlignTop);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+
+ _lw = new QListWidget ();
+ _lw ->sortItems(Qt::AscendingOrder);
+
+ shortcut1 = new QShortcut (this);
+ shortcut1 ->setKey(Qt::Key_Delete);
+ connect (shortcut1, SIGNAL( activated() ), SLOT( del_list_view_slot() ) );
+
+ shortcut2 = new QShortcut (this);
+ shortcut2 ->setKey(Qt::Key_Backspace);
+ connect (shortcut2, SIGNAL( activated() ), SLOT( del_list_view_slot() ) );
+
+ layout -> addWidget (_lw);
+ if (dim != 0) {
+ _lw ->setMaximumHeight( dim );
+ }
+ else {
+ _lw ->setMaximumHeight( 80 );
+ }
+ if (width != 0) _lw ->setMaximumWidth( width );
+
+ if (button == true) {
+ fbutton = new QPushButton("Delete selected", this);
+ fbutton ->setMaximumHeight( 24 );
+ layout -> addWidget (fbutton);
+
+ connect (fbutton, SIGNAL( clicked() ), SLOT( del_list_view_slot() ) );
+ }
+}
+
+void MyListView::del_list_view_slot () {
+ int _last_row = _lw ->currentRow();
+ _lw ->takeItem (_last_row);
+ deleting (_last_row);
+}
+
+
+MyListButton::MyListButton (QLayout *parent, const char *name) : QWidget() {
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+
+ _combo_box = new QComboBox ();
+ layout -> addWidget (_combo_box);
+
+ fbutton = new QPushButton( name , this);
+// fbutton ->setMaximumWidth( 30 );
+ fbutton ->setMaximumHeight( 24 );
+ layout -> addWidget (fbutton);
+}
+
+
+MySlider::MySlider (QLayout *parent, const char *name, int& var, int vmin, int vmax) : QWidget(){
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+ pline = new MyIntegerEditLine (layout, name, var, vmin, vmax);
+ layout -> addWidget (pline);
+ slider = new QSlider(Qt::Horizontal);
+ layout -> addWidget (slider);
+ slider->setMinimum ( vmin );
+ slider->setMaximum ( vmax );
+ slider ->setValue (var);
+ connect (slider, SIGNAL(valueChanged(int)), pline, SLOT(set_value(int)) );
+ connect (pline ->spinbox, SIGNAL (valueChanged(int)), this, SLOT(setValue (int)));
+}
+
+
+void MySlider::setValue (int i) {
+ slider->setValue (i);
+}
+
+
+MyTwoColumn::MyTwoColumn (QLayout *parent) : QWidget () {
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ _left = new ZNWidget ();
+ _right = new ZNWidget ();
+
+ layout -> addWidget (_left);
+ layout -> addWidget (_right);
+ layout -> setAlignment (Qt::AlignTop);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+ _left ->layout() ->setContentsMargins (0, 0, 5, 0);
+ _left ->layout () -> setAlignment (Qt::AlignTop);
+ _right ->layout() ->setContentsMargins (5, 0, 0, 0);
+ _right ->layout () -> setAlignment (Qt::AlignTop);
+}
+
+
+My3Column::My3Column (QLayout *parent) : QWidget () {
+ parent -> addWidget (this);
+ QHBoxLayout *layout = new QHBoxLayout ();
+ setLayout (layout);
+
+ _left = new ZNWidget ();
+ _center = new ZNWidget ();
+ _right = new ZNWidget ();
+
+ layout -> addWidget (_left);
+ layout -> addWidget (_center);
+ layout -> addWidget (_right);
+ layout -> setAlignment (Qt::AlignTop);
+
+ layout ->setContentsMargins (0, 0, 0, 0);
+ _left ->layout() ->setContentsMargins (0, 0, 5, 0);
+ _left ->layout () -> setAlignment (Qt::AlignTop);
+ _center ->layout() ->setContentsMargins (5, 0, 5, 0);
+ _center ->layout () -> setAlignment (Qt::AlignTop);
+ _right ->layout() ->setContentsMargins (5, 0, 0, 0);
+ _right ->layout () -> setAlignment (Qt::AlignTop);
+}
+
+MyGridColumn::MyGridColumn (QLayout *parent, int row, int col) : QWidget () {
+ parent -> addWidget (this);
+ gridlayout = new QGridLayout ();
+ setLayout (gridlayout);
+
+ gridlayout ->setHorizontalSpacing (5);
+ gridlayout ->setVerticalSpacing (5);
+
+ gridlayout ->setContentsMargins (0, 0, 0, 0);
+}
+
+
+MyTableWidget::MyTableWidget (QLayout *parent, int row, int height) : QWidget () {
+ parent -> addWidget (this);
+ QVBoxLayout *layout = new QVBoxLayout ();
+ setLayout (layout);
+ layout -> setAlignment (Qt::AlignTop);
+
+ table = new QTableWidget ();
+ table ->setColumnCount (row);
+ table ->setMaximumHeight( height );
+ layout -> addWidget (table);
+
+}
+
diff --git a/minimize.cc b/minimize.cc
new file mode 100644
index 0000000..79a7747
--- /dev/null
+++ b/minimize.cc
@@ -0,0 +1,519 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "minimize.h"
+
+
+
+#ifdef WIN32
+#include <float.h>
+#define isnan _isnan
+#endif // WIN32
+
+Minimize::Minimize (Data *dat, ForceField *int_ff, ForceField *inter_ff) :data (dat), target_molecule (NULL) {
+ if (int_ff) {
+ internal_ff = int_ff;
+ }
+ else internal_ff = new MMFF ();
+ if (inter_ff) {
+ interaction_ffs.push_back (inter_ff);
+ }
+ else interaction_ffs.push_back (new Chemscore ());
+ optimiser = new ILS ();
+
+
+// haptic_thread = 0;
+ haptic_dof_mode = 1;
+ haptic_number_of_threads = 1;
+ total_E = 0.f;
+ total_internal_E = 0.f;
+ total_interaction_E = 0.f;
+ clear ();
+ minimising_molecule = NULL;
+ haptic_molecule = NULL;
+
+}
+
+float Minimize::score () {
+ float out = 0;
+ for (unsigned int i = 0; i < interaction_ffs.size (); i++) {
+ interaction_ffs[i] ->update ();
+ out += interaction_ffs[i] ->compute_total_energy ();
+ return out;
+ }
+}
+
+int Minimize::forcefields_sanity_check () {
+ string error_string = "";
+ int out = 1;
+ if (!internal_ff -> is_initialised) {
+ error_string += "Internal Forcefield not correctly initialised.\n";
+ out = 0;
+ }
+ for (unsigned int i = 0; i < interaction_ffs.size (); i++) {
+ if (!interaction_ffs[i] -> is_initialised) {
+ error_string += "Interaction Forcefield not correctly initialised.\n";
+ out = 0;
+ }
+ if (!out) QMessageBox::critical(data->ddwin, "Forcefields sanity check failed" , QString (error_string.c_str ()) );
+ return out;
+ }
+}
+
+
+/*
+void Minimize::initialise_minimisation (ZNMolecule *mol, Forcefield *ff) {
+ clear ();
+
+ ff -> clear_internal_interactions ();
+ ff -> clear_nonbonded_interactions ();
+ minimising_molecule = data -> ddwin -> target_molecule;
+
+
+ data->mmff->initialize (mol, data -> ddwin -> molecules);
+
+
+
+ data -> undo_stack -> beginMacro ("Energy Minimisation");
+ MoveAtomsCommand *command = new MoveAtomsCommand (data -> ddwin -> gl, 1);
+ FOR_ATOMS_OF_MOL(a, minimising_molecule) {
+ command -> add (&*a, (vect &) a -> GetVector ());
+ }
+
+ data -> ddwin -> execute (command);
+
+
+
+}
+*/
+
+void Minimize::deinitialise_minimisation () {
+
+ clear ();
+ minimising_molecule = NULL;
+
+}
+
+
+void Minimize::start_haptic_mode () {
+
+// if (forcefields_sanity_check ()) {
+ initialize (data->ddwin->target_molecule);
+ data->ddwin->haptic_mode = true;
+ data -> ddwin -> lock_editing ();
+// total_E = 0.;
+// total_internal_E = 0.;
+// total_interaction_E = 0.;
+ if (haptic_dof_mode!=0) {
+ internal_ff->initialize_internal (data->ddwin->target_molecule, data->ddwin->molecules);
+ }
+ for (unsigned int i = 0; i < interaction_ffs.size (); i ++) {
+ interaction_ffs [i]->initialize_interaction (data->ddwin->target_molecule, data->ddwin->molecules);
+ }
+ data -> undo_stack -> beginMacro ("Haptic Simulation");
+ MoveAtomsCommand *command = new MoveAtomsCommand (data -> ddwin -> gl, 1);
+ FOR_ATOMS_OF_MOL(a, haptic_molecule) {
+ command -> add (&*a, get_coordinates (&*a));
+ }
+// command -> name ("haptic simulation");
+ data -> ddwin -> execute (command);
+// }
+ data ->ddwin ->haptic_menu ->haptic_thread -> initialise (this);
+ data ->ddwin ->run_thread (data ->ddwin ->haptic_menu ->haptic_thread);
+ // haptic_thread -> start ();
+
+}
+
+void Minimize::initialize (ZNMolecule *mol) {
+ FOR_ATOMS_OF_MOL(a, mol) {
+ // vect *force = (vect *) a -> GetData ("force");
+ // force -> null ();
+ }
+
+ if (haptic_dof_mode ==0) {
+ initialize_6 (mol);
+ }
+ haptic_molecule = mol;
+}
+
+
+void Minimize::initialize_6 (ZNMolecule *mol) {
+/* pFragment frag;
+ frag.translation = mol -> center;
+ frag.rotation_quat [0] = 1.f;
+ frag.rotation_quat [1] = 0.f;
+ frag.rotation_quat [2] = 0.f;
+ frag.rotation_quat [3] = 0.f;
+
+ FOR_ATOMS_OF_MOL(a, mol) {
+ Fragment_Atom fa;
+ fa.coordinates = subtract (get_coordinates (&*a), mol -> center);
+ fa.atom = &*a;
+ frag.atoms.push_back (fa);
+ }
+ fragments.push_back (frag);
+*/
+}
+
+
+void Minimize::clear () {
+ iterations = 0;
+ step = 1;
+ last_E = 0;
+ clear_fragments ();
+}
+
+void Minimize::clear_fragments () {
+ fragments.clear ();
+}
+/*
+void Minimize::haptic_step () {
+ const float maxforce = 200.0f;
+
+ counter ++;
+
+ ZNMolecule * min_mol = haptic_molecule;
+ assert (min_mol);
+
+
+
+ vect haptic_force (0.f, 0.f, 0.f);
+
+ for (unsigned int i=0; i<min_mol->atoms.size (); i++) {
+ min_mol->atoms[i]->score = 0.f;
+ min_mol -> atoms [i] -> force.null ();
+ }
+
+
+
+ if (haptic_dof_mode ==0) { // 6 dofs model
+
+
+ vect tot_force, tot_torque;
+ tot_force.null ();
+ tot_torque.null ();
+ interaction_ff->update ();
+ interaction_ff->compute_forces ();
+
+
+
+
+ for (unsigned int fi=0; fi<fragments.size (); fi++) {
+
+ for (unsigned int i=0; i<fragments[fi].atoms.size (); i++) {
+ tot_force = sum (tot_force, fragments[fi].atoms[i].atom->force);
+ vect to = torque (fragments[fi].atoms[i].atom->force, fragments[fi].atoms[i].atom-> GetVector (), fragments[fi].translation);
+ tot_torque = sum (tot_torque, to);
+ }
+
+ haptic_force = sum (haptic_force, tot_force);
+ if (automove) {
+ vect force = tot_force;
+ force.trunc_at (500.f);
+ force.multiply (STEP_SIZE);
+ fragments[fi].translation = sum (fragments[fi].translation, force);
+ }
+ float cut = 10.f;
+ tot_torque.trunc_at (cut);
+
+ float new_quat [4], mult_quat [4];
+ axis_angle_to_quaternion (tot_torque, tot_torque.module ()*0.001, new_quat);
+
+ multiply_quaternions (new_quat, fragments[fi].rotation_quat, mult_quat);
+ normalize_quaternion (mult_quat);
+ fragments[fi].rotation_quat[0] = mult_quat [0];
+ fragments[fi].rotation_quat[1] = mult_quat [1];
+ fragments[fi].rotation_quat[2] = mult_quat [2];
+ fragments[fi].rotation_quat[3] = mult_quat [3];
+ update_fragment_position (fragments[fi]);
+ }
+
+ }
+
+
+
+ else if (haptic_dof_mode ==1) { // 6+r dofs model
+ }
+ else { //3N model
+ vect lastCenter;
+ lastCenter = min_mol -> center;
+ assert (min_mol->atoms.size ());
+
+
+ internal_ff->compute_forces ();
+ interaction_ff->update ();
+ interaction_ff->compute_forces ();
+ apply_forces (min_mol, maxforce);
+
+ for (unsigned int i=0; i<min_mol->atoms.size (); i++) {
+ vect force = min_mol -> atoms[i] -> force;
+ haptic_force = sum (haptic_force, force);
+ }
+
+
+
+
+ if (!automove) {
+ vect cent = find_mass_center (min_mol->atoms);
+ for (unsigned int i=0; i<min_mol->atoms.size (); i++) {
+ min_mol->atoms[i]-> GetVector () = subtract (min_mol->atoms[i]-> GetVector (), cent);
+ min_mol->atoms[i]-> GetVector () = sum (min_mol->atoms[i]-> GetVector (), lastCenter);
+
+ }
+ }
+ // total_interaction_E = interaction_ff->total_energy;
+ // total_internal_E = internal_ff->total_energy;
+ // total_E = total_interaction_E + total_internal_E;
+
+// data->ddwin->haptic_menu->update ();
+
+
+
+ }
+ if (color_by_score) {
+ // cout << "color_bu"<<endl;
+ vector <color_mask> masks;
+ color_mask mask;
+ mask.intensity = 1.0f;
+ mask.only_to = 0;
+ mask.excluding = 0;
+ mask.type = 2; //score //see menu.cc
+ masks.push_back (mask);
+ data -> ddwin->gl->apply_color_masks (masks, min_mol, false);
+ }
+}
+*/
+//#ifdef HAPTICS
+void Minimize::update_molecule_position_with_haptic_pointer (ZNMolecule *min_mol) {
+ lock_geometry_for_write (min_mol);
+
+ vect haptic_coords, new_coords;
+ float x, y, z;
+ data -> haptic_position_lock ->lockForRead ();
+ x = data -> current_position_x;
+ y = data -> current_position_y;
+ z = data -> current_position_z;
+ data -> haptic_position_lock ->unlock ();
+ float MAX_OUT = 100;
+ float MOVE = 0.02;
+ vect move_screen (0., 0., 0.);
+ if (x < -MAX_OUT) move_screen = sum (move_screen, vect (MOVE, 0., 0.));
+ else if (x > MAX_OUT) move_screen = sum (move_screen, vect (-MOVE, 0., 0.));
+ if (y < -MAX_OUT) move_screen = sum (move_screen, vect (0, MOVE, 0.));
+ else if (y > MAX_OUT) move_screen = sum (move_screen, vect (0,-MOVE, 0.));
+ if (z < -MAX_OUT*0.5) move_screen = sum (move_screen, vect ( 0., 0., MOVE));
+ else if (z > MAX_OUT*0.5) move_screen = sum (move_screen, vect (0., 0., -MOVE));
+
+ data ->ddwin ->gl ->translate_view (move_screen);
+ //cerr << x << endl;
+ /*
+ x = 0;
+ y = 0;
+ z = 5 * sin (counter/100);
+ */
+ haptic_coords.x() = x;
+ haptic_coords.y() = y;
+ haptic_coords.z() = z;
+
+ float minx, maxx, miny, maxy, minz, maxz;
+
+ minx = -250; maxx = 250;
+ miny = -250; maxy = 250;
+ minz = -250; maxz = 250;
+
+ data->ddwin->gl->haptic_to_world_coordinates (haptic_coords, new_coords, minx, maxx, miny, maxy, minz, maxz);
+ vect x_ax = vect (1, 0, 0);
+ vect y_ax = vect (0, 1, 0);
+ vect z_ax = vect (0, 0, -1);
+ x_ax = data ->ddwin ->gl -> apply_world_rotation (x_ax);
+ y_ax = data ->ddwin ->gl -> apply_world_rotation (y_ax);
+ z_ax = data ->ddwin ->gl -> apply_world_rotation (z_ax);
+
+ //quaternion q = yaw_pitch_roll_to_quaternion (data ->current_pitch-data ->last_pitch, data ->current_roll - data ->last_roll, data ->current_yaw - data ->last_yaw);
+// quaternion q = axis_angle_to_quaternion (z_ax, (data ->current_pitch-data ->last_pitch));
+// quaternion q1 = axis_angle_to_quaternion (x_ax, (data ->current_yaw-data ->last_yaw));
+// quaternion q2 = axis_angle_to_quaternion (y_ax, (data ->current_roll-data ->last_roll));
+//cerr << data ->current_pitch << " " << data ->current_yaw << " " << data ->current_roll<<endl;
+
+
+ quaternion q = axis_angle_to_quaternion (z_ax, (data ->current_pitch + 3)* (data ->current_pitch + 3)* (data ->current_pitch + 3)*0.0005);
+ quaternion q1 = axis_angle_to_quaternion (x_ax, (data ->current_yaw +3)*(data ->current_yaw +3)*(data ->current_yaw +3)* 0.004);
+ quaternion q2 = axis_angle_to_quaternion (y_ax, (data ->current_roll+3) *(data ->current_roll+3) *(data ->current_roll+3)* 0.004);
+
+
+ FOR_ATOMS_OF_MOL(a, min_mol) {
+ vect v = get_coordinates(&*a);
+ v = subtract (v, get_center (min_mol));
+
+
+
+ v = rotate_vector_using_quaternion (v, q2);
+ v = rotate_vector_using_quaternion (v, q1);
+ v = rotate_vector_using_quaternion (v, q);
+ v = sum (v, new_coords);
+ set_coordinates (&*a, v);
+ }
+
+ set_center (min_mol, new_coords);
+
+
+
+// data -> last_pitch = data -> current_pitch;
+// data -> last_roll = data -> current_roll;
+// data -> last_yaw = data -> current_yaw;
+ unlock_geometry (min_mol);
+}
+
+
+//#endif //HAPTICS
+
+
+void Minimize::update_fragment_position (pFragment& frag) {
+// for (unsigned int i=0; i<frag.atoms.size (); i++) {
+// vect rotated_coords;
+// rotated_coords = rotate_vector_using_quaternion (frag.atoms[i].coordinates, frag.rotation_quat);
+// frag.atoms[i].atom-> GetVector () = sum (rotated_coords, frag.translation);
+// }
+}
+
+
+void Minimize::apply_force_to_atom (Atom *a, float trunc) {
+ vect force = get_force (a);
+ // cerr << force << "force"<<endl;
+ assert (!isnan (force.x()));
+ assert (!isnan (force.y()));
+ assert (!isnan (force.z()));
+ if (trunc > 0.f) force.trunc_at (trunc);
+ force.multiply (STEP_SIZE);
+ // cerr << force << endl;
+ assert (!isnan (force.x()));
+ assert (!isnan (force.y()));
+ assert (!isnan (force.z()));
+ sum_to_coordinates(&*a, force);
+}
+
+
+void Minimize::apply_forces (ZNMolecule *mol, float trunc) {
+ // assert (mol -> atoms.size ());
+ FOR_ATOMS_OF_MOL(a, mol) {
+ apply_force_to_atom (&*a, trunc);
+ }
+}
+
+
+void Minimize::minimize_energy_step () {
+ bool converged = false;
+ // FOR_ATOMS_OF_MOL(a, data->mmff->target_mol) {
+// vect *force = (vect *) a -> GetData ("force");
+// force -> null ();
+// }
+ iterations ++;
+ data -> mmff -> update ();
+ data -> mmff -> compute_forces ();
+ FOR_ATOMS_OF_MOL(a, data->mmff->target_mol) {
+ flush_forces (&*a);
+ }
+ apply_forces (data -> mmff -> target_mol, 500.f);
+
+ float this_E = compute_energy ();
+
+ if (last_E-this_E<MIN_ENERGY) converged=true;
+ if (iterations ==1) {
+ converged = false;
+ }
+ if (last_E-this_E<0) {
+ converged = false;
+ step /=1.1f;
+ }
+ else step *=1.1f;
+ last_E = this_E;
+ data->ddwin->gl->draw_molecule (data->ddwin->target_molecule);
+
+
+ if (converged || iterations > MAX_ITERATIONS) {
+ deinitialise_minimisation ();
+ }
+}
+
+
+
+/*
+
+
+void Minimize::minimize_energy () {
+int iterations = 0;
+float step =1;
+bool converged = false;
+float last_E, this_E;
+last_E =0;
+this_E =0;
+// cout <<compute_energy ()<<"energy"<<endl;
+while (!converged && iterations<MAX_ITERATIONS) {
+for (unsigned int i=0; i<data->mmff->target_mol->atoms.size (); i++) {
+// ddwin->data->mmff->target_mol->atoms[i]->score = 0.;
+data->mmff->target_mol->atoms[i]->force[0] = 0.;
+data->mmff->target_mol->atoms[i]->force[1] = 0.;
+data->mmff->target_mol->atoms[i]->force[2] = 0.;
+}
+
+iterations ++;
+data->mmff->update ();
+data->mmff->compute_forces ();
+
+for (unsigned int i=0; i<data->mmff->target_mol->atoms.size (); i++) {
+for (unsigned int j=0; j<3; j++) {
+float force = data->mmff->target_mol->atoms[i]->force[j];
+if (force > 500) force = 500;
+if (force < -500) force = -500;
+
+data->mmff->target_mol->atoms[i]-> GetVector ()[j]+=force*STEP_SIZE;
+}
+}
+
+
+this_E = compute_energy ();
+
+if (last_E-this_E<MIN_ENERGY) converged=true;
+if (iterations ==1) {
+converged = false;
+}
+if (last_E-this_E<0) {
+converged = false;
+step /=1.1;
+}
+else step *=1.1;
+last_E = this_E;
+data->ddwin->gl->draw_molecule (data->ddwin->target_molecule);
+}
+}
+*/
+/*
+
+float Minimize::derive (Dof *dof) {
+*dof->value-=DX;
+float E1 = compute_energy ();
+*dof->value+=2*DX;
+float E2 = compute_energy ();
+*dof->value-=DX;
+return (E2-E1)/(2*DX);
+}
+*/
+
+float Minimize::compute_energy () {
+ // cout <<data->mmff->compute_total_energy ();
+ return data->mmff->compute_total_energy ();
+}
diff --git a/molsketch_helium/CMakeLists.txt b/molsketch_helium/CMakeLists.txt
new file mode 100644
index 0000000..50cfdec
--- /dev/null
+++ b/molsketch_helium/CMakeLists.txt
@@ -0,0 +1,58 @@
+# CMakeLists.txt for the main sourcecode of molsKetch
+
+# Including qt4 and OpenBabel
+set(QT_USE_QTASSISTANT TRUE)
+set(QT_USE_QTSVG TRUE)
+include(${QT_USE_FILE})
+include_directories(${OPENBABEL2_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+
+# Set the variable with the .ui files
+set(molsketch_UIS settings.ui)
+qt4_wrap_ui(molsketch_UIS_H ${molsketch_UIS})
+
+# Set the variable with all the sourcecode
+set(molsketch_SRCS main.cpp molecule.cpp atom.cpp bond.cpp element.cpp mollibitem.cpp mainwindow.cpp molview.cpp molscene.cpp settings.cpp fileio.cpp commands.cpp periodictablewidget.cpp)
+
+# Including the resources
+qt4_add_resources(molsketch_SRCS molsketch.qrc)
+
+# Add a program icon for windows
+if(WIN32)
+ set(molsketch_SRCS ${molsketch_SRCS} icon.rc)
+endif(WIN32)
+
+# MOC-ing headers
+set(molsketch_MOC_HDRS mainwindow.h molscene.h molview.h settings.h periodictablewidget.h)
+qt4_wrap_cpp(molsketch_SRCS ${molsketch_MOC_HDRS})
+
+# Take care of the .moc files
+qt4_automoc(${molsketch_SRCS})
+
+# Create an executable from this source
+add_executable(molsketch ${molsketch_SRCS} ${molsketch_UIS_H})
+
+# Link the code against Qt and OpenBabel
+target_link_libraries(molsketch ${QT_LIBRARIES} ${OPENBABEL2_LIBRARIES})
+
+
+# Install the executable
+install(TARGETS molsketch DESTINATION bin)
+
+# Install the library
+install(DIRECTORY ${PROJECT_SOURCE_DIR}/library DESTINATION share/molsketch PATTERN ".svn" EXCLUDE)
+
+# Install the documentation
+install(DIRECTORY ${PROJECT_SOURCE_DIR}/doc DESTINATION share/doc/molsketch PATTERN ".svn" EXCLUDE)
+
+# Install menu entries on Linux
+if(UNIX)
+ install(FILES ${PROJECT_SOURCE_DIR}/src/molsketch.desktop DESTINATION share/applications)
+ install(FILES ${PROJECT_SOURCE_DIR}/src/images/molsketch.xpm DESTINATION share/pixmaps)
+ install(FILES ${PROJECT_SOURCE_DIR}/src/images/molsketch.png DESTINATION share/icons/hicolor/128x128/apps)
+endif(UNIX)
+
+# Check subdirs
+add_subdirectory(i18n)
+if(KDE4_FOUND)
+ add_subdirectory(part)
+endif(KDE4_FOUND)
\ No newline at end of file
diff --git a/molsketch_helium/CVS/Entries b/molsketch_helium/CVS/Entries
new file mode 100644
index 0000000..1b8f14b
--- /dev/null
+++ b/molsketch_helium/CVS/Entries
@@ -0,0 +1,32 @@
+/CMakeLists.txt/1.1/Mon Sep 29 09:10:52 2008//
+/atom.cpp/1.1/Mon Sep 29 09:10:54 2008//
+/atom.h/1.1/Mon Sep 29 09:10:57 2008//
+/bond.cpp/1.1/Mon Sep 29 09:10:59 2008//
+/bond.h/1.1/Mon Sep 29 09:11:02 2008//
+/commands.cpp/1.1/Mon Sep 29 09:11:08 2008//
+/commands.h/1.1/Mon Sep 29 09:11:10 2008//
+/element.cpp/1.1/Mon Sep 29 09:11:12 2008//
+/element.h/1.1/Mon Sep 29 09:11:18 2008//
+/fileio.cpp/1.1/Mon Sep 29 09:11:19 2008//
+/fileio.h/1.1/Mon Sep 29 09:11:21 2008//
+/icon.rc/1.1/Mon Sep 29 09:11:23 2008//
+/mainwindow.cpp/1.2/Mon Nov 3 15:52:20 2008//
+/mainwindow.h/1.2/Mon Nov 3 15:52:20 2008//
+/molecule.cpp/1.1/Mon Sep 29 09:11:46 2008//
+/molecule.h/1.1/Mon Sep 29 09:11:47 2008//
+/mollibitem.cpp/1.1/Mon Sep 29 09:11:49 2008//
+/mollibitem.h/1.1/Mon Sep 29 09:11:51 2008//
+/molsKetch.nsi/1.1/Mon Sep 29 09:12:01 2008//
+/molscene.cpp/1.1/Mon Sep 29 09:12:04 2008//
+/molscene.h/1.1/Mon Sep 29 09:12:07 2008//
+/molsketch.desktop/1.1/Mon Sep 29 09:12:09 2008//
+/molsketch.ico/1.1/Mon Sep 29 09:12:13 2008//
+/molsketch.qrc/1.1/Mon Sep 29 09:12:17 2008//
+/molview.cpp/1.1/Mon Sep 29 09:12:23 2008//
+/molview.h/1.1/Mon Sep 29 09:12:24 2008//
+/periodictablewidget.cpp/1.1/Mon Sep 29 09:12:27 2008//
+/periodictablewidget.h/1.1/Mon Sep 29 09:12:29 2008//
+/settings.cpp/1.1/Mon Sep 29 09:12:32 2008//
+/settings.h/1.1/Mon Sep 29 09:12:48 2008//
+/settings.ui/1.1/Mon Sep 29 09:12:50 2008//
+D
diff --git a/molsketch_helium/CVS/Entries.Extra b/molsketch_helium/CVS/Entries.Extra
new file mode 100644
index 0000000..e0271f7
--- /dev/null
+++ b/molsketch_helium/CVS/Entries.Extra
@@ -0,0 +1,31 @@
+/CMakeLists.txt////*///
+/atom.cpp////*///
+/atom.h////*///
+/bond.cpp////*///
+/bond.h////*///
+/commands.cpp////*///
+/commands.h////*///
+/element.cpp////*///
+/element.h////*///
+/fileio.cpp////*///
+/fileio.h////*///
+/icon.rc////*///
+/mainwindow.cpp////*///
+/mainwindow.h////*///
+/molecule.cpp////*///
+/molecule.h////*///
+/mollibitem.cpp////*///
+/mollibitem.h////*///
+/molsKetch.nsi////*///
+/molscene.cpp////*///
+/molscene.h////*///
+/molsketch.desktop////*///
+/molsketch.ico////*///
+/molsketch.qrc////*///
+/molview.cpp////*///
+/molview.h////*///
+/periodictablewidget.cpp////*///
+/periodictablewidget.h////*///
+/settings.cpp////*///
+/settings.h////*///
+/settings.ui////*///
diff --git a/molsketch_helium/CVS/Entries.Extra.Old b/molsketch_helium/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/CVS/Entries.Log b/molsketch_helium/CVS/Entries.Log
new file mode 100644
index 0000000..b3b1829
--- /dev/null
+++ b/molsketch_helium/CVS/Entries.Log
@@ -0,0 +1,3 @@
+A D/i18n////
+A D/images////
+A D/part////
diff --git a/molsketch_helium/CVS/Entries.Old b/molsketch_helium/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/CVS/Repository b/molsketch_helium/CVS/Repository
new file mode 100644
index 0000000..a7a0288
--- /dev/null
+++ b/molsketch_helium/CVS/Repository
@@ -0,0 +1 @@
+zodiac/molsketch_helium
diff --git a/molsketch_helium/CVS/Root b/molsketch_helium/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/molsketch_helium/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/molsketch_helium/atom.cpp b/molsketch_helium/atom.cpp
new file mode 100644
index 0000000..0b768b7
--- /dev/null
+++ b/molsketch_helium/atom.cpp
@@ -0,0 +1,376 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#define ATOM_SIZE 30
+
+#include <QPainter>
+
+#include "atom.h"
+#include "element.h"
+#include "molscene.h"
+#include "molecule.h"
+
+// Constructor
+
+MsKAtom::MsKAtom(const QPointF &position, const QString &element, bool implicitHydrogens, QGraphicsItem* parent, QGraphicsScene* scene) : QGraphicsItem(parent,scene)
+{
+ //pre: position is a valid position in scene coordinates
+ // Setting initial parameters
+ setPos(position);
+ setZValue(3);
+ // setFlag(QGraphicsItem::ItemIsMovable);
+// setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ if (dynamic_cast<MolScene*>(scene))
+ setFlag(QGraphicsItem::ItemIsSelectable, dynamic_cast<MolScene*>(scene)->editMode()==MolScene::MoveMode);
+
+ // Enabling hovereffects
+ setAcceptsHoverEvents(true);
+ setAcceptedMouseButtons(Qt::LeftButton);
+
+ // Setting private fields
+ m_elementSymbol = element;
+ m_hidden = true;
+ m_drawn = false;
+
+// m_hidden = invisible;// || (m_elementSymbolement == "C" && ((MolScene*)parentItem()->scene())->getShowCarbon()) || (m_elementSymbolement == "H" && ((MolScene*)parentItem()->scene())->getShowHydrogen());
+// m_valency = 0;
+ m_charge = 0; // The initial additional charge is zero
+ m_oxidationState = molsKetch::oxidationStateOfElement(molsKetch::symbol2number(m_elementSymbol));
+ m_valency = molsKetch::valencyOfElement(molsKetch::symbol2number(m_elementSymbol));
+ m_weight = molsKetch::weightOfElement(molsKetch::symbol2number(m_elementSymbol));
+
+ setImplicitHydrogens(implicitHydrogens);
+ m_numberOfImplicitHydrogens = m_implicitHydrogens ? molsKetch::valencyOfElement(molsKetch::symbol2number(m_elementSymbol)) : 0;
+// m_numberOfImplicitHydrogens = 0;
+
+ m_numberOfBonds = m_numberOfImplicitHydrogens;
+ m_oxidationState -= m_numberOfBonds;
+
+ // QPainterPath path;
+ // QFont font;
+ // path.addEllipse(QRectF(position.x(),position.y(),20,20));
+ // path.addText(position + QPointF(-5,5),font,m_elementSymbolement);
+ //
+ // setPath(path);
+}
+
+
+// Inherited methods
+
+QRectF MsKAtom::boundingRect() const
+{
+ // qreal penWidth = 1;
+ // return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
+ // 20 + penWidth / 2, 20 + penWidth / 2);
+ return QRectF(-ATOM_SIZE/2, -ATOM_SIZE/2, ATOM_SIZE, ATOM_SIZE);
+}
+
+QPainterPath MsKAtom::shape() const
+{
+ QPainterPath path;
+ path.addRect(QRectF(-10,-10,20,20));
+ return path;
+}
+
+void MsKAtom::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+ // Save the original painter state
+// painter->save();
+
+ // painter->drawRect(boundingRect());
+ QRectF rect = QRectF(-12,-12,24,24);
+
+ // Check the scene
+ MolScene* molScene = dynamic_cast<MolScene*>(scene());
+ Q_CHECK_PTR(molScene);
+
+ // If element is m_hidden, don't draw the atoms
+ if (m_hidden && !isSelected()) {
+ if (m_elementSymbol == "H" && !molScene->autoAddHydrogen() && (m_oxidationState == 1 || !molScene->chargeVisible())) {
+ m_drawn = false;
+ return;
+ }
+ if (m_elementSymbol == "C" && !molScene->carbonVisible() && ((m_numberOfBonds - m_numberOfImplicitHydrogens) > 2 && charge() == 0 || !molScene->chargeVisible())) {
+ m_drawn = false;
+ return;
+ }
+ }
+
+ m_drawn = true;
+
+ // Drawing background
+ QBrush brush(Qt::white);
+
+ // Use a different color if selected
+ if (this->isSelected()) painter->setPen(Qt::blue);
+
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(brush);
+ painter->drawEllipse(rect);
+ painter->restore();
+
+ painter->setFont(molScene->atomSymbolFont());
+
+ // Check to add implicit hydrogens
+ int hydrogenCount = numberOfImplicitHydrogens();
+ if (hydrogenCount > 0) {
+ // Check if hydrogen
+ if (m_elementSymbol =="H") {
+ painter->drawText(rect, Qt::AlignCenter, "H");
+ hydrogenCount += 1;
+ } else
+ // Draw element + hydrogen
+ painter->drawText(rect, Qt::AlignCenter, m_elementSymbol + "H");
+
+ if (hydrogenCount > 1) {
+ painter->setFont( QFont("",7) );
+ painter->drawText( rect.translated(3,0), Qt::AlignBottom|Qt::AlignRight, QString::number(hydrogenCount));
+ }
+ } else {
+ // Draw element
+ painter->drawText(rect, Qt::AlignCenter, m_elementSymbol);
+ }
+
+ // Draw charge
+ if (molScene->chargeVisible()) {
+ QString chargeId = chargeID();
+ painter->setFont( QFont("",7) );
+ painter->drawText(rect.translated(5,0), Qt::AlignTop|Qt::AlignRight, chargeId);
+ }
+
+
+ // Draw unbound electrons
+ if (0) /*molScene->chargeVisible()*/ {
+ int unboundElectrons = 8;
+ QList<QRectF> layoutList;
+
+ // Loading different layouts
+ layoutList << QRectF(-3,-10,2,2);
+ layoutList << QRectF(3,-10,2,2);
+ layoutList << QRectF(-3,10,2,2);
+ layoutList << QRectF(3,10,2,2);
+ layoutList << QRectF(10,-3,2,2);
+ layoutList << QRectF(10,3,2,2);
+ layoutList << QRectF(-10,-3,2,2);
+ layoutList << QRectF(-10,3,2,2);
+
+ painter->save();
+ painter->setBrush(Qt::black);
+
+ for (int i = 0; i < unboundElectrons; i++)
+ painter->drawEllipse(layoutList[i]);
+
+ painter->restore();
+ }
+
+ // Restore the original painter state
+// painter->restore();
+}
+
+QVariant MsKAtom::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemPositionChange && parentItem())
+ {
+// setTransform(parentItem()->transform().transposed());
+ parentItem()->update();
+ dynamic_cast<Molecule*>(parentItem())->rebuild();
+
+// setGroup(dynamic_cast<Molecule*>(parentItem()));
+ };
+ if (change == ItemSelectedChange && molecule())
+ {
+// molecule()->setSm_elementSymbolected(isSm_elementSymbolected());
+ molecule()->setFlag(ItemIsSelectable,isSelected());
+ }
+
+ return QGraphicsItem::itemChange(change, value);
+}
+
+// Commands
+
+void MsKAtom::setElement(const QString &element)
+{
+ m_elementSymbol = element;
+ update();
+}
+
+void MsKAtom::setValency( int valency )
+{
+ // Adjusting the charge
+// m_charge = m_charge - (valency - m_valency);
+
+ // Setting the new valency
+ m_valency = valency;
+}
+
+void MsKAtom::setOxidationState(int state)
+{
+ m_oxidationState = state;
+}
+
+void MsKAtom::setNumberOfBonds(int number)
+{
+ Q_ASSERT (number >= 0);
+
+ int deltaNoB = number - m_numberOfBonds;
+ m_oxidationState -= deltaNoB;
+
+ if (m_implicitHydrogens) {
+ int oldNoIH = m_numberOfImplicitHydrogens;
+ int newNoIH = oldNoIH - deltaNoB;
+ int deltaNoIH = (newNoIH - oldNoIH > -oldNoIH) ? newNoIH - oldNoIH : -oldNoIH;
+ m_numberOfImplicitHydrogens += deltaNoIH;
+ m_oxidationState -= deltaNoIH;
+ }
+
+ m_numberOfBonds = number;
+}
+
+void MsKAtom::setNumberOfImplicitHydrogens(int number)
+{
+ Q_ASSERT (number >= 0);
+
+ m_implicitHydrogens = true;
+
+ int deltaNoIH = number - m_numberOfImplicitHydrogens;
+ int newNoB = m_numberOfBonds - deltaNoIH;
+ m_numberOfBonds = (newNoB < 0) ? 0 : newNoB;
+
+ m_oxidationState += deltaNoIH;
+
+ m_numberOfImplicitHydrogens = number;
+}
+
+
+// Query methods
+
+int MsKAtom::numberOfBonds() const
+{
+ return m_numberOfBonds;
+}
+
+int MsKAtom::numberOfImplicitHydrogens() const
+{
+ return m_numberOfImplicitHydrogens;
+}
+
+QString MsKAtom::element() const
+{
+ return m_elementSymbol;
+}
+
+int MsKAtom::oxidationState() const
+{
+ return m_oxidationState;
+}
+
+int MsKAtom::valency( ) const // return the number of expected bonds
+{
+ return m_valency;
+}
+
+int MsKAtom::charge( ) const // Return the additional charge of the atom
+{
+ return m_oxidationState;
+}
+
+// int MsKAtom::hydrogenNeeded( ) const // Returs the number of hydrogens needed to make the atom neutral
+// {
+// int needed = molsKetch::valencyOfElement(molsKetch::symbol2number(m_elementSymbol)) - m_valency;
+// if (molsKetch::symbol2number(m_elementSymbol) > 10) needed = 0;
+// // if (needed > -molsKetch::valencyOfElement(molsKetch::symbol2number(m_elementSymbol))) needed = -molsKetch::valencyOfElement(molsKetch::symbol2number(m_elementSymbol));
+// if (needed < 0) needed = 0;
+// if (scene()) return static_cast<MolScene*>(scene())->autoAddHydrogen()?needed:0;
+// return 0;
+// }
+
+QString MsKAtom::chargeID( ) const
+{
+ // Get the charge
+ int c = charge();
+
+ // Drawing text
+ QString chargeId;
+ chargeId.setNum(c);
+ if (c < -1) chargeId = chargeId.remove(0,1) + "-";
+ if (c == -1) chargeId = "-";
+ if (c == 0) chargeId = "";
+ if (c == 1) chargeId = "+";
+ if (c > 1) chargeId = chargeId + "+";
+
+ // Return the charge ID string
+ return chargeId;
+}
+
+qreal MsKAtom::weight( ) const
+{
+ return m_weight + m_numberOfImplicitHydrogens*molsKetch::weightOfElement(1);
+}
+
+Molecule * MsKAtom::molecule() const
+{
+ return dynamic_cast<Molecule*>(this->parentItem());
+}
+
+// Event handlers
+
+void MsKAtom::mousePressEvent( QGraphicsSceneMouseEvent* event )
+{
+ // Execute default behavior
+ QGraphicsItem::mousePressEvent( event );
+}
+
+void MsKAtom::hoverEnterEvent( QGraphicsSceneHoverEvent * event )
+{
+// show();
+ m_hidden = false;
+ // Execute default behavior
+ QGraphicsItem::hoverEnterEvent( event );
+}
+
+void MsKAtom::hoverLeaveEvent( QGraphicsSceneHoverEvent * event )
+{
+ m_hidden = true;
+// if (m_hidden) hide();
+ // Execute default behavior
+ QGraphicsItem::hoverLeaveEvent( event );
+}
+
+bool MsKAtom::implicitHydrogens() const
+{
+ return m_implicitHydrogens;
+}
+
+bool MsKAtom::isDrawn() const
+{
+ return m_drawn;
+}
+
+bool MsKAtom::isHidden() const
+{
+ return m_hidden;
+}
+
+void MsKAtom::setImplicitHydrogens(bool enabled)
+{
+ m_implicitHydrogens = enabled && (m_elementSymbol == "C" || m_elementSymbol == "N" || m_elementSymbol == "O");
+}
+
diff --git a/molsketch_helium/atom.h b/molsketch_helium/atom.h
new file mode 100644
index 0000000..8e5efae
--- /dev/null
+++ b/molsketch_helium/atom.h
@@ -0,0 +1,191 @@
+/***************************************************************************
+ * Copyright (C) 2007-2008 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and defines the class MsKAtom.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+
+
+#ifndef ATOM_H
+#define ATOM_H
+
+#include <QGraphicsItem>
+
+class Molecule;
+
+
+/**
+ * Represents an atom
+ *
+ * @author Harm van Eersel
+ */
+class MsKAtom : public QGraphicsItem
+{
+public:
+ // Constructor
+ /**
+ * Creates a new atom.
+ *
+ * @param position the position of the new atom
+ * @param element the element symbol of the new atom
+ * @param invisible makes the atom invisible if @c true
+ */
+ MsKAtom(const QPointF & position, const QString & element, bool implicitHydrogens, QGraphicsItem* parent = 0, QGraphicsScene* scene = 0);
+
+ // Inherited drawing methods
+ /** Returns the bounding rectangle of the atom. Needed for Qt painting. */
+ virtual QRectF boundingRect() const;
+ /** Returns the shape of the atom. Needed for Qt event handling. */
+ virtual QPainterPath shape() const;
+ /** Paint method to draw the atom onto a QPainter. Needed for Qt painting.*/
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+
+ // Query methods
+ /** Returns whether the atom is drawn. */
+ bool isDrawn() const;
+ /** Returns whether the atom is hidden. */
+ bool isHidden() const;
+ /** Returns whether the atom uses implicit hydrogens */
+ bool implicitHydrogens() const;
+
+
+ /** Returns the element symbol of the atom, including the implicit hydrogens. */
+ QString element() const;
+ /** Returns the weight of the atom. */
+ qreal weight() const;
+ /** Returns the valency of the atom. */
+ int valency() const;
+ /**
+ * Returns the number of bonds to this atom.
+ *
+ * Double bonds count twice, triple thrice, etc.
+ */
+ int numberOfBonds() const;
+ /**
+ * Returns the charge of the atom.
+ *
+ * The charge is calculated on basis of the */
+ int charge() const;
+ /** Returns the oxidation state of the atom. */
+ int oxidationState() const;
+ /**
+ * Returns the number of hydrogen needed to make the atom neutral.
+ *
+ * This is calculated on basis of the valency of the atom, the current
+ * number of bonds and any additional charge applied to the atom.
+ */
+// int hydrogenNeeded() const;
+ /** Returns the number of implicit hydrogens currently associated with the atom. */
+ int numberOfImplicitHydrogens() const;
+ /** Returns the string to identify the atom charge. */
+ QString chargeID() const;
+
+ /** Returns the molecule of the atom or NULL if none. */
+ virtual Molecule* molecule() const;
+
+ // Manupilation methods
+ /** Sets the element symbol of the current atom to @p element. */
+ void setElement(const QString & element);
+ /** Sets the oxidation state of the current atom to @p state. */
+ void setOxidationState(int state);
+ /**
+ * Sets the valency of the current atom to @p valency.
+ *
+ * This function sets the valency of the atom.
+ * It is used to calculate the charge of the atom and the number
+ * of implicit hydrogens associated with this atom.
+ */
+ void setValency(int valency);
+ /**
+ * Sets the number of bonds of the current atom to @p number.
+ *
+ * This sets the number of bonds to the atom. Changing this will
+ * change the number of free valency electrons and consequently
+ * the number of implicit hydrogens.
+ */
+ void setNumberOfBonds(int number);
+ /**
+ * Sets the number of implicit hydrogens of the current atom to @p number.
+ *
+ * Changing the number of implicit hydrogens will also effect the number
+ * of free valency electrons and hence the charge of the atom.
+ */
+ void setNumberOfImplicitHydrogens(int number);
+ /** Sets whether implicit hydrogens should be used */
+ void setImplicitHydrogens(bool enabled);
+
+ // Methods needed for qt typecasting
+ /** Defines the type of the class. Needed for Qt typecasting.*/
+ enum { Type = UserType + 8 };
+ /** Returns the type of the class. Needed fro Qt typecasting. */
+ virtual int type() const {return MsKAtom::Type;};
+
+protected:
+ // Event handlers
+ /** Event handler to show hidden atoms when the mouse hovers over them. */
+ void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
+ /** Event handler to hide hidden atoms again when the mouse stops hovering over them. */
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
+ /** Event handler to handle atom clicks. */
+ void mousePressEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler to handle element changes. */
+ QVariant itemChange(GraphicsItemChange change, const QVariant & value);
+
+private:
+ // Internal representation
+ /** Represents the atom's element symbol. */
+ QString m_elementSymbol;
+ /** Stores whether the atom is hidden. */
+ bool m_hidden;
+ /** Stores whether the atom is drawn. */
+ bool m_drawn;
+ /** Stores the weigth of the atom. */
+ qreal m_weight;
+ /** Stores the charge of the atom. */
+ int m_charge;
+ /** Stores the valency of the atom. */
+ int m_valency;
+ /** Stores the oxidation state of the atom */
+ int m_oxidationState;
+ /**
+ * Stores the number of bonds to this atom
+ *
+ * This number is used to calculate the charge
+ * of the atom. Double bonds count twice, triple thrice, etc.
+ */
+ int m_numberOfBonds;
+ /**
+ * Stores the number of implicit hydrogens
+ *
+ * The number of implicit hydrogens that currently is
+ * associated with this atom is used to calculate
+ * the charge of the atom and to determine the index
+ * of the Hn appended to the atom symbol is this
+ * options is enabled.
+ */
+ int m_numberOfImplicitHydrogens;
+ /** Stores whether implicit hydrogens should be used */
+ bool m_implicitHydrogens;
+};
+
+#endif
diff --git a/molsketch_helium/bond.cpp b/molsketch_helium/bond.cpp
new file mode 100644
index 0000000..a9eed1d
--- /dev/null
+++ b/molsketch_helium/bond.cpp
@@ -0,0 +1,370 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QtGlobal>
+#include <QPainter>
+
+#include "bond.h"
+#include "element.h"
+
+// Constructor
+
+MsKBond::MsKBond(MsKAtom* atomA, MsKAtom* atomB, int order, int type, QGraphicsItem* parent,QGraphicsScene* scene) : QGraphicsItem(parent,scene)
+{
+ Q_CHECK_PTR(atomA);
+ Q_CHECK_PTR(atomB);
+
+ m_bondType = type;
+ m_bondOrder = order;
+ m_firstMsKAtom = atomA;
+ m_lastMsKAtom = atomB;
+ /*
+ // Increasing the valency of the atoms
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() + m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() + m_bondOrder);*/
+
+ setPos(m_firstMsKAtom->scenePos());
+// setFlag(QGraphicsItem::ItemIsSelectable);
+// setAcceptedMouseButtons(Qt::LeftButton);
+}
+
+void MsKBond::redoValency()
+{
+ // Check if the atoms still exist
+ if (!m_firstMsKAtom || !m_lastMsKAtom) return;
+ Q_CHECK_PTR(m_firstMsKAtom);
+ Q_CHECK_PTR(m_lastMsKAtom);
+
+ // Set the new number of bonds of the atoms
+ m_firstMsKAtom->setNumberOfBonds(m_firstMsKAtom->numberOfBonds() + bondOrder());
+ m_lastMsKAtom->setNumberOfBonds(m_lastMsKAtom->numberOfBonds() + bondOrder());
+
+/* // Setting the new valency of the atoms
+ int e1 = molsKetch::valencyOfElement(molsKetch::symbol2number(m_firstMsKAtom->element()));
+ int e2 = molsKetch::valencyOfElement(molsKetch::symbol2number(m_lastMsKAtom->element()));
+ if (e1 < 0 && e2 < 0 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);
+ return;
+ }
+
+ if (e1 > 0 && e2 > 0 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() + m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() + m_bondOrder);
+ return;
+ }
+
+ if ( e1 > e2 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() + m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);
+ return;
+ }
+ if ( e1 < e2 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() + m_bondOrder);
+ return;
+ }
+
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);*/
+}
+
+void MsKBond::undoValency()
+{
+ // Check if the atoms still exist
+ if (!m_firstMsKAtom || !m_lastMsKAtom) return;
+ Q_CHECK_PTR(m_firstMsKAtom);
+ Q_CHECK_PTR(m_lastMsKAtom);
+
+ // Set the new number of bonds of the atoms
+ m_firstMsKAtom->setNumberOfBonds(m_firstMsKAtom->numberOfBonds() - bondOrder());
+ m_lastMsKAtom->setNumberOfBonds(m_lastMsKAtom->numberOfBonds() - bondOrder());
+
+/* // Setting the new valency of the atoms
+ int e1 = -molsKetch::valencyOfElement(molsKetch::symbol2number(m_firstMsKAtom->element()));
+ int e2 = -molsKetch::valencyOfElement(molsKetch::symbol2number(m_lastMsKAtom->element()));
+ if (e1 < 0 && e2 < 0 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);
+ return;
+ }
+
+ if (e1 > 0 && e2 > 0 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() + m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() + m_bondOrder);
+ return;
+ }
+
+ if ( e1 > e2 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() + m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);
+ return;
+ }
+ if ( e1 < e2 )
+ {
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() + m_bondOrder);
+ return;
+ }
+
+ m_firstMsKAtom->setValency(m_firstMsKAtom->valency() - m_bondOrder);
+ m_lastMsKAtom->setValency(m_lastMsKAtom->valency() - m_bondOrder);*/
+}
+
+// Inherited methods
+
+QRectF MsKBond::boundingRect() const
+ {
+ Q_CHECK_PTR(m_firstMsKAtom);
+ Q_CHECK_PTR(m_lastMsKAtom);
+
+ qreal w = m_lastMsKAtom->x()-m_firstMsKAtom->x();
+ qreal h = m_lastMsKAtom->y()-m_firstMsKAtom->y();
+
+ // qreal x = qMax(m_firstMsKAtom->pos().x(),m_lastMsKAtom->pos().x());
+ // qreal y = qMax(m_firstMsKAtom->pos().y(),m_firstMsKAtom->pos().y());
+ return QRectF(mapFromParent(m_firstMsKAtom->pos()) - QPointF(5,5),QSizeF(w+10,h+10));
+ }
+
+void MsKBond::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+ // Check the scene
+ MolScene* molScene = dynamic_cast<MolScene*>(scene());
+ Q_CHECK_PTR(molScene);
+
+ // painter->drawRect(boundingRect());
+ QPointF points[4] =
+ {
+ mapFromParent(m_firstMsKAtom->pos()),
+ shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),3).p2(),
+ shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-3).p2(),
+ mapFromParent(m_firstMsKAtom->pos())
+ };
+ QPointF points2[4] =
+ {
+ mapFromParent(m_lastMsKAtom->pos()),
+ shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),3).p1(),
+ shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-3).p1(),
+ mapFromParent(m_lastMsKAtom->pos())
+ };
+
+ // Set painter defaults
+ painter->save();
+ QPen pen;
+ pen.setWidthF(molScene->bondWidth());
+ painter->setPen(pen);
+
+ // Create dash pattern for dot
+ QVector<qreal> dash;
+ dash << 2 << 5;
+
+ // Create a gradient for down
+ QRadialGradient radialGrad(mapFromScene(m_firstMsKAtom->scenePos()), 5);
+ radialGrad.setColorAt(0, Qt::white);
+ radialGrad.setColorAt(0.3,Qt::white);
+ radialGrad.setColorAt(0.5,Qt::black);
+ radialGrad.setColorAt(0.7, Qt::white);
+ radialGrad.setColorAt(1, Qt::white);
+ radialGrad.setSpread(QGradient::RepeatSpread);
+
+ switch ( m_bondType )
+ {
+ case MsKBond::Down:
+ painter->setPen( Qt::NoPen );
+ painter->setBrush( radialGrad );
+ painter->drawConvexPolygon( points2, 4);
+ break;
+ case MsKBond::DownR:
+ painter->setPen( Qt::NoPen );
+ painter->setBrush( radialGrad );
+ painter->drawConvexPolygon( points, 4);
+ break;
+ case MsKBond::Dot:
+ pen.setDashPattern(dash);
+ painter->setPen(pen);
+ painter->drawLine(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())));
+ break;
+ case MsKBond::Up:
+ painter->setBrush( QBrush(Qt::black) );
+ painter->drawConvexPolygon( points, 4);
+ break;
+ case MsKBond::UpR:
+ painter->setBrush( QBrush(Qt::black) );
+ painter->drawConvexPolygon( points2, 4);
+ break;
+
+ default:
+ switch ( m_bondOrder )
+ {
+ case MsKBond::Single:
+ painter->drawLine(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())));
+ break;
+ case MsKBond::Double:
+ painter->drawLine(shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),2));
+ painter->drawLine(shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-2));
+ break;
+ case MsKBond::Triple:
+ painter->drawLine(shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),3));
+ painter->drawLine(shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-3));
+ painter->drawLine(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())));
+ break;
+ default:
+ painter->drawLine(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())));
+ }
+ }
+
+ // Restore old painter
+ painter->restore();
+}
+
+QVariant MsKBond::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemPositionChange && parentItem()) parentItem()->update();
+ return QGraphicsItem::itemChange(change, value);
+}
+
+QPainterPath MsKBond::shape() const
+ {
+ QPolygonF polygon;
+ polygon << shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),10).p1()
+ << shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),10).p2()
+ << shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-10).p2() << shiftVector(QLineF(mapFromParent(m_firstMsKAtom->pos()),mapFromParent(m_lastMsKAtom->pos())),-10).p1();
+
+ QPainterPath path(mapFromParent(m_firstMsKAtom->pos()));
+// path.quadTo(QPointF(),m_lastMsKAtom->pos());
+ path.addPolygon( polygon );
+ path.closeSubpath();
+
+ return path;
+ }
+
+// Manipulation methods
+
+void MsKBond::setOrder(int order)
+{
+ //pre: order>0
+ //post: m_bondOrder=order
+ Q_ASSERT( order > 0 );
+ undoValency();
+ m_bondOrder = order;
+ redoValency();
+ update();
+}
+
+void MsKBond::incOrder()
+{
+ //pre: true
+ //post: m_bondOrder = oldBondOrder % 3 + 1
+
+ // Calculating the new order
+ setOrder( m_bondOrder % 3 + 1 );
+
+}
+
+void MsKBond::decOrder()
+{
+ //pre: true
+ //post: m_bondOrder = (oldBondOrder + 1) % 3 + 1
+
+ // Calculating the new order
+ setOrder( (m_bondOrder + 1) % 3 + 1 );
+
+}
+
+void MsKBond::setType(int t)
+{
+ //pre: 0 <= t < 6
+ //post: bondType = t
+ Q_ASSERT(0 <= t && t < 6);
+
+ m_bondType = t;
+ update();
+}
+
+void MsKBond::incType()
+{
+ //pre: true
+ //post: bondType = bondType % 6 + 1
+ setType((m_bondType + 1) % 6);
+}
+
+void MsKBond::decType()
+{
+ //pre: true
+ //post: bondType = (bondType + 5) % 6
+ setType( (m_bondType + 5) % 6);
+}
+
+
+// Query methods
+
+int MsKBond::bondOrder() const
+ {
+ return m_bondOrder;
+ }
+
+int MsKBond::bondType() const
+ {
+ return m_bondType;
+ }
+
+MsKAtom* MsKBond::firstMsKAtom() const
+ {
+ return m_firstMsKAtom;
+ }
+
+MsKAtom* MsKBond::lastMsKAtom() const
+ {
+ return m_lastMsKAtom;
+ }
+
+bool MsKBond::hasMsKAtom(MsKAtom* atom) const
+ {
+ return m_firstMsKAtom == atom || m_lastMsKAtom == atom;
+ }
+
+Molecule* MsKBond::molecule() const
+ {
+ return dynamic_cast<Molecule*>(this->parentItem());
+ }
+
+// Auxilary methods
+
+QLineF MsKBond::shiftVector(const QLineF &vector, qreal shift) // Shifts a vector on the perpendicular axis
+{
+ //pre: true
+ //ret:shifted vector
+
+ // Calculating the new coordinates
+ qreal rx1 = vector.x1() + shift*(vector.unitVector().y2()-vector.unitVector().y1());
+ qreal ry1 = vector.y1() + shift*-(vector.unitVector().x2()-vector.unitVector().x1());
+ qreal rx2 = vector.x2() + shift*(vector.unitVector().y2()-vector.unitVector().y1());
+ qreal ry2 = vector.y2() + shift*-(vector.unitVector().x2()-vector.unitVector().x1());
+
+ // Returning the new vector
+ return QLineF(rx1,ry1,rx2,ry2);
+}
diff --git a/molsketch_helium/bond.h b/molsketch_helium/bond.h
new file mode 100644
index 0000000..50624ad
--- /dev/null
+++ b/molsketch_helium/bond.h
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains the bond class.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+
+#ifndef BOND_H
+#define BOND_H
+
+#include <QGraphicsItem>
+
+#include "atom.h"
+#include "molecule.h"
+
+
+/**
+ * Represents a bond.
+ *
+ * @author Harm van Eersel
+ */
+class MsKBond : public QGraphicsItem
+{
+public:
+ // Constructor
+ /**
+ * Creates a new bond.
+ *
+ * @param atomA the origin atom of the bond
+ * @param atomB the target atom of the bond
+ * @param order the bond order (@c MsKBond::Single for single, @c MsKBond::Double for double, @c MsKBond::Triple for tripple)
+ * @param type the bond type (@c MsKBond::Normal, @c MsKBond::Up, @c MsKBond::Down, e.g.)
+ */
+ MsKBond(MsKAtom* atomA, MsKAtom* atomB, int order = 1, int type = 0, QGraphicsItem* parent = 0, QGraphicsScene* scene = 0);
+
+ /** Undos the valency change caused by this bond in the two atoms connected to this bond. */
+ void undoValency();
+ /** Redos the valency change caused by this bond in the two atoms connected to this bond. */
+ void redoValency();
+
+ // Inherited methods
+ /** Method to paint the bond on a QPainter object. Needed for Qt painting. */
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+ /** Event handler for changes in the bond. Needed for Qt painting. */
+ QVariant itemChange(GraphicsItemChange change, const QVariant & value);
+
+ // Inherited query methods
+ /** Returns the shape of the bond. Needed for Qt event handling. */
+ virtual QPainterPath shape() const;
+ /** Returns the bounding rectangle of the bond. Needed for Qt painting. */
+ virtual QRectF boundingRect() const;
+ /** Returns the type of the class. Needed for Qt type casting. */
+ virtual int type() const {return MsKBond::Type;};
+
+ // Manipulation methods
+ /** Sets the bond type to @p type. */
+ void setType(int type);
+ /** Cycle forward through the bond types. */
+ void incType();
+ /** Cycle backward through the bond types. */
+ void decType();
+
+ /** Sets the bond order to @p order. */
+ void setOrder(int order);
+ /** Cycle forward through the bond orders. */
+ void incOrder();
+ /** Cycle backward through the bond orders. */
+ void decOrder();
+
+ // Query methods
+ /** Returns the bond order. */
+ int bondOrder() const;
+ /** Returns the bond type. */
+ int bondType() const;
+
+ /** Returns the origin atom of the bond. */
+ MsKAtom* firstMsKAtom() const;
+ /** Returns the target atom of the bond. */
+ MsKAtom* lastMsKAtom() const;
+ /** Return @c true if @p atom takes part in this bond and @c false otherwise. */
+ bool hasMsKAtom(MsKAtom* atom) const;
+
+ /** Returns the molecule this bond is part of. */
+ Molecule* molecule() const;
+
+ // Public enums
+ /** Defines the class type. Needed for Qt typecasting. */
+ enum { Type = UserType + 4 };
+ /** Enum for the different bond types */
+ enum bondTypes {
+ Normal, /**< Normal bond */
+ Up, /**< A bond from atomA upto atomB */
+ UpR, /**< A bond from atomB upto atomA */
+ Down, /**< A bond from atomA downto atomB */
+ DownR, /**< A bond from atomB downto atomA */
+ Dot /**< A dotted bond */
+ };
+ /** Enum for the different bondorders. */
+ enum bondOrders {
+ Single = 1, /**< Single bond */
+ Double = 2, /**< Double bond */
+ Triple = 3 /**< Triple bond */
+ };
+
+ // Static auxillary methods
+ /**
+ * Auxillary method for shifting a bond perpendicular to the original bond.
+ * Needed for the drawing of multiple bonds.
+ *
+ * @param vector the original vector that is to be shifted
+ * @param shift the amount of shifting
+ *
+ * @return the shifted vector
+ */
+ static QLineF shiftVector(const QLineF & vector, qreal shift);
+
+private:
+
+ // Internal representation
+ /** Stores the bond type as integer. */
+ int m_bondType;
+ /** Stores the bond order as integer. */
+ int m_bondOrder;
+ /** Stores a pointer to the first atom. */
+ MsKAtom* m_firstMsKAtom;
+ /** Stores a pointer to the second atom. */
+ MsKAtom* m_lastMsKAtom;
+
+};
+
+#endif
diff --git a/molsketch_helium/commands.cpp b/molsketch_helium/commands.cpp
new file mode 100644
index 0000000..4eae3aa
--- /dev/null
+++ b/molsketch_helium/commands.cpp
@@ -0,0 +1,368 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QTransform>
+
+#include "commands.h"
+
+#include "atom.h"
+#include "bond.h"
+#include "molecule.h"
+
+using namespace Commands;
+
+// AddAtom
+
+AddAtom::AddAtom(MsKAtom * newAtom, Molecule * newMol, const QString & text) : QUndoCommand(text), m_atom(newAtom), m_molecule(newMol)
+{}
+
+AddAtom::~AddAtom()
+{
+ if (m_undone) delete m_atom;
+}
+
+void AddAtom::undo()
+{
+ m_molecule->delAtom(m_atom);
+ m_undone = true;
+}
+
+void AddAtom::redo()
+{
+ m_molecule->addMsKAtom(m_atom);
+ m_atom->setFlag(QGraphicsItem::ItemIsSelectable, m_molecule->scene()->editMode()==MolScene::MoveMode);
+ m_undone = false;
+}
+
+// Change element
+ChangeElement::ChangeElement(MsKAtom* changeMsKAtom, const QString &newEl, const QString & text) : QUndoCommand(text), m_oldName(changeMsKAtom->element()), m_newName(newEl), m_atom(changeMsKAtom)
+{}
+
+void ChangeElement::undo()
+{
+ m_atom->setElement(m_oldName);
+ m_undone = true;
+}
+
+void ChangeElement::redo()
+{
+ m_atom->setElement(m_newName);
+ m_undone = false;
+}
+
+// IncCharge
+IncCharge::IncCharge(MsKAtom* atom, const QString & text) : QUndoCommand(text), m_atom(atom)
+{};
+void IncCharge::undo()
+{
+ m_atom->setOxidationState(m_atom->oxidationState() - 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = true;
+}
+void IncCharge::redo()
+{
+ m_atom->setOxidationState(m_atom->oxidationState() + 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = false;
+}
+
+// DecCharge
+DecCharge::DecCharge(MsKAtom* atom, const QString & text) : QUndoCommand(text), m_atom(atom)
+{};
+void DecCharge::undo()
+{
+ m_atom->setOxidationState(m_atom->oxidationState() + 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = true;
+}
+void DecCharge::redo()
+{
+ m_atom->setOxidationState(m_atom->oxidationState() - 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = false;
+}
+
+// AddImplicitHydrogen
+AddImplicitHydrogen::AddImplicitHydrogen(MsKAtom* atom, const QString & text) : QUndoCommand(text), m_atom(atom)
+{};
+void AddImplicitHydrogen::undo()
+{
+ m_atom->setNumberOfImplicitHydrogens(m_atom->numberOfImplicitHydrogens() - 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = true;
+}
+void AddImplicitHydrogen::redo()
+{
+ m_atom->setNumberOfImplicitHydrogens(m_atom->numberOfImplicitHydrogens() + 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = false;
+}
+
+// RemoveImplicitHydrogen
+RemoveImplicitHydrogen::RemoveImplicitHydrogen(MsKAtom* atom, const QString & text) : QUndoCommand(text), m_atom(atom)
+{};
+void RemoveImplicitHydrogen::undo()
+{
+ m_atom->setNumberOfImplicitHydrogens(m_atom->numberOfImplicitHydrogens() + 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = true;
+}
+void RemoveImplicitHydrogen::redo()
+{
+ m_atom->setNumberOfImplicitHydrogens(m_atom->numberOfImplicitHydrogens() - 1);
+ if (m_atom->scene()) m_atom->scene()->update();
+ m_undone = false;
+}
+
+// DelAtom
+DelAtom::DelAtom(MsKAtom* delAtom, const QString & text) : QUndoCommand(text), m_atom(delAtom), m_molecule(delAtom->molecule())
+{};
+DelAtom::~DelAtom()
+{
+ if (!m_undone)
+ {
+ foreach(MsKBond* bond, m_bondList) delete bond;
+ delete m_atom;
+ }
+}
+void DelAtom::undo()
+{
+ m_molecule->addMsKAtom(m_atom);
+ m_atom->setFlag(QGraphicsItem::ItemIsSelectable, m_molecule->scene()->editMode()==MolScene::MoveMode);
+ for (int i = 0; i < m_bondList.size(); i++) m_molecule->addBond(m_bondList.at(i));
+ m_undone = true;
+}
+void DelAtom::redo()
+{
+ m_bondList = m_molecule->delAtom(m_atom);
+ m_undone = false;
+}
+
+// MsKBond commands
+
+AddBond::AddBond(MsKBond* newBond, const QString & text) : QUndoCommand(text), m_bond(newBond), m_mol(newBond->firstMsKAtom()->molecule())
+{}
+
+AddBond::~AddBond()
+{
+ if (m_undone) delete m_bond;
+}
+
+void AddBond::undo()
+{
+ m_mol->delBond(m_bond);
+ m_undone = true;
+}
+void AddBond::redo()
+{
+ m_mol->addBond(m_bond);
+ m_undone = false;
+}
+
+
+DelBond::DelBond(MsKBond* delBond, const QString & text) : QUndoCommand(text), m_bond(delBond), m_mol(delBond->molecule())
+{}
+DelBond::~DelBond()
+{
+ if(!m_undone) delete m_bond;
+}
+void DelBond::undo()
+{
+ m_mol->addBond(m_bond);
+ m_undone = true;
+}
+void DelBond::redo()
+{
+ m_mol->delBond(m_bond);
+ m_undone = false;
+}
+
+IncType::IncType(MsKBond* incBond, const QString & text) : QUndoCommand(text), m_bond(incBond)
+{}
+void IncType::undo()
+{
+ m_bond->decType();
+ m_undone = true;
+}
+void IncType::redo()
+{
+ m_bond->incType();
+ m_undone = false;
+}
+
+IncOrder::IncOrder(MsKBond* incBond, const QString & text) : QUndoCommand(text), m_bond(incBond)
+{}
+void IncOrder::undo()
+{
+ m_bond->decOrder();
+ m_undone = true;
+}
+void IncOrder::redo()
+{
+ m_bond->incOrder();
+ m_undone = false;
+}
+
+MergeMol::MergeMol(Molecule* moleculeA, Molecule* moleculeB, Molecule*& mergedMolecule, const QString & text) : QUndoCommand(text), m_molA(moleculeA), m_molB(moleculeB), m_molC(mergedMolecule), m_scene(moleculeA->scene())
+{
+ //pre: molA.scene = molB.scene
+ Q_ASSERT(moleculeA->scene() == moleculeB->scene());
+
+ mergedMolecule = m_molC = m_scene->merge(m_molA,m_molB);
+}
+MergeMol::~MergeMol()
+{
+ if (!m_undone) delete m_molA;
+ if (!m_undone) delete m_molB;
+ if (m_undone) delete m_molC;
+}
+void MergeMol::undo()
+{
+ m_scene->removeItem(m_molC);
+ m_scene->addItem(m_molA);
+ m_molA->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ foreach(MsKAtom* atom, m_molC->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_scene->addItem(m_molB);
+ m_molB->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ foreach(MsKAtom* atom, m_molC->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_undone = true;
+}
+void MergeMol::redo()
+{
+ m_scene->removeItem(m_molA);
+ m_scene->removeItem(m_molB);
+ m_scene->addItem(m_molC);
+ m_molC->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ foreach(MsKAtom* atom, m_molC->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_undone = false;
+}
+
+SplitMol::SplitMol(Molecule* mol, const QString & text) : QUndoCommand(text), m_oldMol(mol), m_scene(mol->scene())
+{
+ m_newMolList = m_oldMol->split();
+}
+SplitMol::~SplitMol()
+{
+ if (!m_undone) delete m_oldMol;
+ if (m_undone) foreach(Molecule* mol,m_newMolList) delete mol;
+}
+void SplitMol::undo()
+{
+ foreach(Molecule* mol,m_newMolList) m_scene->removeItem(mol);
+ m_scene->addItem(m_oldMol);
+ m_oldMol->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ foreach(MsKAtom* atom, m_oldMol->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_undone = true;
+}
+void SplitMol::redo()
+{
+ m_scene->removeItem(m_oldMol);
+ foreach(Molecule* mol,m_newMolList)
+ {
+ m_scene->addItem(mol);
+ mol->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ foreach(MsKAtom* atom, mol->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ }
+ m_undone = false;
+}
+
+// Generic item commands
+
+AddItem::AddItem(QGraphicsItem* newItem, MolScene* addScene, const QString & text) : QUndoCommand(text), m_item(newItem), m_scene(addScene)
+{}
+
+AddItem::~AddItem()
+{
+ if (m_undone) delete m_item;
+}
+
+void AddItem::undo()
+{
+ m_scene->removeItem(m_item);
+ m_undone = true;
+}
+void AddItem::redo()
+{
+ m_scene->addItem(m_item);
+ m_item->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ if (m_item->type() == Molecule::Type) foreach(MsKAtom* atom, dynamic_cast<Molecule*>(m_item)->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_scene->update();
+ m_undone = false;
+}
+
+DelItem::DelItem(QGraphicsItem* delItem, const QString & text) : QUndoCommand(text), m_item(delItem)
+{
+ m_scene = dynamic_cast<MolScene*>(delItem->scene());
+}
+
+DelItem::~DelItem()
+{
+ if (!m_undone) delete m_item;
+}
+
+void DelItem::undo()
+{
+ m_scene->addItem(m_item);
+ m_item->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ if (m_item->type() == Molecule::Type) foreach(MsKAtom* atom, dynamic_cast<Molecule*>(m_item)->atoms())
+ atom->setFlag(QGraphicsItem::ItemIsSelectable, m_scene->editMode()==MolScene::MoveMode);
+ m_scene->update();
+ m_undone = true;
+}
+void DelItem::redo()
+{
+ m_scene->removeItem(m_item);
+ m_undone = false;
+}
+
+MoveItem::MoveItem(QGraphicsItem* moveItem, const QPointF & moveVector, const QString & text) : QUndoCommand(text), m_oldPos(moveItem->pos()), m_newPos(moveItem->pos() + moveVector), m_item(moveItem)
+{}
+void MoveItem::undo()
+{
+ m_item -> setPos(m_oldPos);
+ if (m_item->type()==MsKAtom::Type) dynamic_cast<MsKAtom*>(m_item)->molecule()->rebuild();
+ m_undone = true;
+}
+void MoveItem::redo()
+{
+ m_item -> setPos(m_newPos);
+ if (m_item->type()==MsKAtom::Type) dynamic_cast<MsKAtom*>(m_item)->molecule()->rebuild();
+ m_undone = false;
+}
+
+
+RotateItem::RotateItem(QGraphicsItem* rotateItem, const QTransform & transform, const QString & text) : QUndoCommand(text), m_item(rotateItem), m_transform( transform )
+{}
+void RotateItem::undo()
+{
+ m_item -> setTransform( m_transform.inverted(), true );
+ m_undone = true;
+}
+void RotateItem::redo()
+{
+ m_item -> setTransform( m_transform, true );
+ m_undone = false;
+}
diff --git a/molsketch_helium/commands.h b/molsketch_helium/commands.h
new file mode 100644
index 0000000..2d4fa53
--- /dev/null
+++ b/molsketch_helium/commands.h
@@ -0,0 +1,603 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains the command classes used in
+ * the Qt Redo/Undo system. Each class represents an action on the scene and
+ * contains the code to redo/undo that action.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Deuterium
+ */
+
+
+#ifndef commands_H
+#define commands_H
+
+#include <QUndoCommand>
+#include <QPointF>
+
+class MsKAtom;
+class Molecule;
+class MsKBond;
+class MolScene;
+class QGraphicsItem;
+class QGraphicsScene;
+class QTransform;
+
+namespace Commands
+{
+
+// MsKAtom command
+
+/**
+ * Command to add an atom
+ *
+ * @author Harm van Eersel
+ */
+class AddAtom : public QUndoCommand
+ {
+ public:
+ /**
+ * Creates a new AddAtom command.
+ *
+ * @param newAtom pointer to the atom that should be added
+ * @param molecule pointer to the molecule for the new atom
+ * @param text a description of the command
+ */
+ AddAtom(MsKAtom* newAtom, Molecule* molecule, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_atom if command is destructed in an undone state.
+ */
+ ~AddAtom();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ /** Molecule of this command. */
+ Molecule* m_molecule;
+ };
+
+
+/**
+ * Command to change the element of an atom
+ *
+ * @author Harm van Eersel
+ */
+class ChangeElement : public QUndoCommand
+ {
+ public:
+ /**
+ * Creates a new ChangeElement command.
+ *
+ * @param changeMsKAtom the atom which element symbol should be changed
+ * @param newElementSymbol the new element symbol
+ * @param text a description of the command
+ */
+ ChangeElement(MsKAtom* changeMsKAtom, const QString & newElementSymbol, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** Old element symbol of the atom. */
+ QString m_oldName;
+ /** New element symbol of the atom. */
+ QString m_newName;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ };
+
+/**
+ * Command to decrease the charge of an atom
+ *
+ * @author Harm van Eersel
+ */
+class DecCharge : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param atom the atom to decrease the charge of
+ * @param text a description of the command
+ */
+ DecCharge(MsKAtom* atom, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ };
+
+ /**
+ * Command to increase the charge of an atom
+ *
+ * @author Harm van Eersel
+ */
+class IncCharge : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param atom the atom to increase the charge of
+ * @param text a description of the command
+ */
+ IncCharge(MsKAtom* atom, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ };
+
+/**
+ * Command to add an implicit hydrogen
+ *
+ * @author Harm van Eersel
+ */
+class AddImplicitHydrogen : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param atom the atom to decrease the charge of
+ * @param text a description of the command
+ */
+ AddImplicitHydrogen(MsKAtom* atom, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ };
+
+ /**
+ * Command to remove an implicit hydrogen
+ *
+ * @author Harm van Eersel
+ */
+class RemoveImplicitHydrogen : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param atom the atom to increase the charge of
+ * @param text a description of the command
+ */
+ RemoveImplicitHydrogen(MsKAtom* atom, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ };
+
+/**
+ * Command to delete an atom
+ *
+ * @author Harm van Eersel
+ */
+class DelAtom : public QUndoCommand
+ {
+ public:
+ /**
+ * Creates a new DelAtom command.
+ *
+ * @param delAtom the atom to be removed
+ * @param text a description of the command
+ */
+ DelAtom(MsKAtom* delAtom, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_atom if the command is destructed in a done state.
+ */
+ virtual ~DelAtom();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** MsKAtom of this command. */
+ MsKAtom* m_atom;
+ /** Molecule of this command. */
+ Molecule* m_molecule;
+ /** The list of bonds that were connected to m_atom. */
+ QList<MsKBond*> m_bondList;
+ };
+
+// MsKBond commands
+
+/**
+ * Command to add a bond
+ *
+ * @author Harm van Eersel
+ */
+class AddBond : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param newBond the new bond to add
+ * @param text a description of the command
+ */
+
+ AddBond(MsKBond* newBond, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_bond if the command is in an undone state.
+ */
+ ~AddBond();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The bond of this command. */
+ MsKBond* m_bond;
+ /** Molecule of this command. */
+ Molecule* m_mol;
+ };
+
+
+/**
+ * Command to remove a bond
+ *
+ * @author Harm van Eersel
+ */
+class DelBond : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param delBond the bond that should be removed
+ * @param text a description of the command
+ */
+ DelBond(MsKBond* delBond, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_bond if the command is destructed in a done state.
+ */
+ virtual ~DelBond();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The bond of this command. */
+ MsKBond* m_bond;
+ /** Molecule of this command. */
+ Molecule* m_mol;
+ };
+
+
+/**
+ * Command to increase the bond type
+ *
+ * @author Harm van Eersel
+ */
+class IncType : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param incBond bond of which the type should be changed
+ * @param text a description of the command
+ */
+ IncType(MsKBond* incBond, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The bond of this command. */
+ MsKBond* m_bond;
+ };
+
+
+/**
+ * Command to increase the bond order
+ *
+ * @author Harm van Eersel
+ */
+class IncOrder : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param incBond bond to increase the order of
+ * @param text a description of the command
+ */
+ IncOrder(MsKBond* incBond, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The bond of this command. */
+ MsKBond* m_bond;
+ };
+
+
+// Molecule commands
+
+
+/**
+ * Command to merge two molecules
+ *
+ * @author Harm van Eersel
+ */
+class MergeMol : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param oldMolA pointer to the first of the two molecules that should be merged
+ * @param oldMolB pointer to the second of the two molecules that should be merged
+ * @param newMol pointer to the new merged molecule, passed as reference
+ * @param text a description of the command
+ */
+ MergeMol(Molecule* oldMolA, Molecule* oldMolB, Molecule*& newMol, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes the two unmerged molecules if the command is destucted in a done state
+ * and the merged molecule if destructed in an undone state.
+ */
+ virtual ~MergeMol();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The first of the two molecules that should be merged. */
+ Molecule* m_molA;
+ /** The second of the two molecules that should be merged. */
+ Molecule* m_molB;
+ /** The merged molecule. */
+ Molecule* m_molC;
+ /** The scene of this command. */
+ MolScene* m_scene;
+ };
+
+
+/**
+ * Command to split a molecule
+ *
+ * @author Harm van Eersel
+ */
+class SplitMol : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param molecule the molecule to be split
+ * @param text a description of the command
+ */
+ SplitMol(Molecule* molecule, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes the original molecule if destructed in a done state
+ * and the submolecules if destructed in an undone state.
+ */
+ ~SplitMol();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The molecule before the split. */
+ Molecule* m_oldMol;
+ /** The list of molecules after the split. */
+ QList<Molecule*> m_newMolList;
+ /** The scene of this command. */
+ MolScene* m_scene;
+ };
+
+
+// Generic item commands
+
+/**
+ * Command to add an item to the scene
+ *
+ * @author Harm van Eersel
+ */
+class AddItem : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param newItem the item that should be added to the scene
+ * @param addScene the scene for the new item
+ * @param text a description of the command
+ */
+ AddItem(QGraphicsItem* newItem, MolScene* addScene, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_item if the command is destructed in an undone state.
+ */
+ ~AddItem();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The item of this command. */
+ QGraphicsItem* m_item;
+ /** The scene of this command. */
+ MolScene* m_scene;
+ };
+
+
+/**
+ * Command to remove an item from the scene
+ *
+ * @author Harm van Eersel
+ */
+class DelItem : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param delItem item to be deleted
+ * @param text a description of the command
+ */
+ DelItem(QGraphicsItem* delItem, const QString & text = "");
+ /**
+ * Destructor
+ *
+ * Deletes m_item if the command is destructed in a done state.
+ */
+ ~DelItem();
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The item of this command. */
+ QGraphicsItem* m_item;
+ /** The scene of this command. */
+ MolScene* m_scene;
+ };
+
+
+/**
+ * Command to move an item on the scene
+ *
+ * @author Harm van Eersel
+ */
+class MoveItem : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param moveItem the item to be moved
+ * @param moveVector the vector representation of the move
+ * @param text a description of the command
+ */
+ MoveItem(QGraphicsItem* moveItem, const QPointF & moveVector, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The position of the item before the move. */
+ QPointF m_oldPos;
+ /** The position of the item after the move. */
+ QPointF m_newPos;
+ /** The item of this command. */
+ QGraphicsItem* m_item;
+ };
+
+/**
+ * Command to rotate an item on the scene
+ *
+ * @author Harm van Eersel
+ */
+class RotateItem : public QUndoCommand
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param rotateItem the item to be rotated
+ * @param transform the matrix representation of the rotation
+ * @param text a description of the command
+ */
+ RotateItem(QGraphicsItem* rotateItem, const QTransform & transform, const QString & text = "");
+ /** Undo this command. */
+ virtual void undo();
+ /** Redo this command. */
+ virtual void redo();
+ private:
+ /** Undo state of the command. */
+ bool m_undone;
+ /** The item of this command. */
+ QGraphicsItem* m_item;
+ /** The position of the item before the move. */
+ QTransform m_transform;
+
+ };
+
+}
+
+#endif
diff --git a/molsketch_helium/element.cpp b/molsketch_helium/element.cpp
new file mode 100644
index 0000000..80f9002
--- /dev/null
+++ b/molsketch_helium/element.cpp
@@ -0,0 +1,339 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QString>
+#include <QStringList>
+
+#include "element.h"
+
+#include <openbabel/data.h>
+
+OpenBabel::OBElementTable eTable;
+
+// static const int m_size = 111;
+// const QString symbols[number];
+const QList<double> weights()
+ {
+ // Used the values from Kalzium
+ QList<double> m_weights;
+ m_weights << 0;
+ m_weights << 1.008 << 4.003 << 6.941 << 9.021 << 10.81 << 12.01 << 14.01 << 16 << 19 << 20.18;
+ m_weights << 22.99 << 24.31 << 26.98 << 30.97 << 32.06 << 35.45 << 39.95 << 39.1 << 40.08 << 44.96; // 20
+ m_weights << 44.96 << 47.87 << 50.94 << 52 << 54.94 << 55.85 << 58.93 << 58.69 << 63.55 << 65.39;
+ m_weights << 69.72 << 72.64 << 74.92 << 78.96 << 79.9 << 83.8 << 84.47 << 87.62 << 88.91 << 91.22; // 40
+ m_weights << 92.91 << 95.94 << 98.91 << 101.1 << 102.9 << 106.4 << 107.9 << 112.4 << 114.8 << 118.7;
+ m_weights << 121.8 << 127.6 << 126.9 << 131.3 << 132.9 << 137.2 << 138.9 << 140.1 << 140.9 << 144.2; // 60
+ m_weights << 146.9 << 150.4 << 152 << 157.3 << 158.9 << 162.5 << 164.9 << 167.3 << 168.9 << 173;
+ m_weights << 175 << 178.5 << 180.9 << 183.8 << 186.2 << 190.2 << 192.2 << 195.1 << 197 << 200.6; // 80
+ m_weights << 204.4 << 207.2 << 209 << 209 << 210 << 222 << 223 << 226 << 227 << 232;
+ m_weights << 231 << 238 << 237 << 244.1 << 243.1 << 247.1 << 247.1 << 251.1 << 252.1 << 257.1; //100
+ m_weights << 258.1 << 259.1 << 262.1 << 261.1 << 262.1 << 263.1 << 262.1 << 265.1 << 266.1 << 271;
+ m_weights << 272; //111
+
+ return m_weights;
+ };
+
+const QList<int> oxidation()
+ {
+ QList<int> m_oxidation;
+ m_oxidation << 0;
+ m_oxidation << 1 << 0;
+ m_oxidation << 1 << 2 << 3 << 4 << 4 <<-2 <<-1 << 0;
+ m_oxidation << 1 << 2 << 3 << 4 << 5 << 6 <<-1 << 0;
+ m_oxidation << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 3 << 2 << 2 << 2 << 2 << 3 << 4 << 3 << 4 <<-1 << 0;
+ m_oxidation << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 4 << 4 << 4 << 1 << 2 << 3 << 4 << 3 << 4 <<-1 << 0;
+ m_oxidation << 1 << 2;
+ m_oxidation << 3 << 3 << 3 << 3 << 3 << 3 << 3 << 3 << 4 << 3 << 3 << 3 << 3 << 3 << 3;
+ m_oxidation << 4 << 5 << 6 << 6 << 4 << 4 << 4 << 3 << 2 << 1 << 2 << 3 << 4 <<-1 << 0;
+ m_oxidation << 1 << 2;
+ m_oxidation << 3 << 4 << 5 << 6 << 5 << 4 << 3 << 3 << 4 << 3 << 3 << 3 << 3 << 2 << 3;
+ m_oxidation << 4 << 5 << 6 << 7 << 3 << 3 << 4 << 3 << 2 << 3 << 4 << 3 << 4 << -1 << 0;
+
+ return m_oxidation;
+ }
+
+const QList<int> valency()
+{
+ QList<int> m_valency;
+ m_valency << -1;
+ m_valency << 1 << 0;
+ m_valency << 1 << 2 << 3 <<-4 <<-3 <<-2 <<-1 << 0;
+ m_valency << 1 << 2 << 3 << 4 <<-3 <<-2 <<-1 << 0;
+ m_valency << 1 << 0 << 1 << 2 << 3 << 4 << 5 << 2 << 2 << 2 << 0 << 1 << 2 << 1 << 4 <<-3 <<-2 <<-1;
+ m_valency << 0 << 1 << 2 << 0 << 1 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0 << 1 << 2 << 2 << 2;
+ m_valency << 2 << 2;
+ m_valency << 2 << 2 << 2 << 0 << 1 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0;
+ m_valency << 1 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0; // 80
+ m_valency << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0;
+ m_valency << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0; //100
+ m_valency << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 0;
+ m_valency << 0; //111
+
+ return m_valency;
+ };
+
+const QStringList symbols()
+{
+ QStringList m_symbols;
+ m_symbols.append("R");
+ // 1
+ m_symbols.append("H");
+ m_symbols.append("He");
+ m_symbols.append("Li");
+ m_symbols.append("Be");
+ m_symbols.append("B");
+ m_symbols.append("C");
+ m_symbols.append("N");
+ m_symbols.append("O");
+ m_symbols.append("F");
+ // 10
+ m_symbols.append("Ne");
+ m_symbols.append("Na");
+ m_symbols.append("Mg");
+ m_symbols.append("Al");
+ m_symbols.append("Si");
+ m_symbols.append("P");
+ m_symbols.append("S");
+ m_symbols.append("Cl");
+ m_symbols.append("Ar");
+ m_symbols.append("K");
+ // 20
+ m_symbols.append("Ca");
+ m_symbols.append("Sc");
+ m_symbols.append("Ti");
+ m_symbols.append("V");
+ m_symbols.append("Cr");
+ m_symbols.append("Mn");
+ m_symbols.append("Fe");
+ m_symbols.append("Co");
+ m_symbols.append("Ni");
+ m_symbols.append("Cu");
+ // 30
+ m_symbols.append("Zn");
+ m_symbols.append("Ga");
+ m_symbols.append("Ge");
+ m_symbols.append("As");
+ m_symbols.append("Se");
+ m_symbols.append("Br");
+ m_symbols.append("Kr");
+ m_symbols.append("Rb");
+ m_symbols.append("Sr");
+ m_symbols.append("Y");
+ // 40
+ m_symbols.append("Zr");
+ m_symbols.append("Nb");
+ m_symbols.append("Mo");
+ m_symbols.append("Tc");
+ m_symbols.append("Ru");
+ m_symbols.append("Rh");
+ m_symbols.append("Pd");
+ m_symbols.append("Ag");
+ m_symbols.append("Cd");
+ m_symbols.append("In");
+ // 50
+ m_symbols.append("Sn");
+ m_symbols.append("Sb");
+ m_symbols.append("Te");
+ m_symbols.append("I");
+ m_symbols.append("Xe");
+ m_symbols.append("Cs");
+ m_symbols.append("Ba");
+ m_symbols.append("La");
+ m_symbols.append("Ce");
+ m_symbols.append("Pr");
+ // 60
+ m_symbols.append("Nd");
+ m_symbols.append("Pm");
+ m_symbols.append("Sm");
+ m_symbols.append("Eu");
+ m_symbols.append("Gd");
+ m_symbols.append("Tb");
+ m_symbols.append("Dy");
+ m_symbols.append("Ho");
+ m_symbols.append("Er");
+ m_symbols.append("Tm");
+ // 70
+ m_symbols.append("Yb");
+ m_symbols.append("Lu");
+ m_symbols.append("Hf");
+ m_symbols.append("Ta");
+ m_symbols.append("W");
+ m_symbols.append("Re");
+ m_symbols.append("Os");
+ m_symbols.append("Ir");
+ m_symbols.append("Pt");
+ m_symbols.append("Au");
+ // 80
+ m_symbols.append("Hg");
+ m_symbols.append("Tl");
+ m_symbols.append("Pb");
+ m_symbols.append("Bi");
+ m_symbols.append("Po");
+ m_symbols.append("At");
+ m_symbols.append("Rn");
+ m_symbols.append("Fr");
+ m_symbols.append("Ra");
+ m_symbols.append("Ac");
+ // 90
+ m_symbols.append("Th");
+ m_symbols.append("Pa");
+ m_symbols.append("U");
+ m_symbols.append("Np");
+ m_symbols.append("Pu");
+ m_symbols.append("Am");
+ m_symbols.append("Cm");
+ m_symbols.append("Bk");
+ m_symbols.append("Cf");
+ m_symbols.append("Es");
+ //100
+ m_symbols.append("Fm");
+ m_symbols.append("Md");
+ m_symbols.append("No");
+ m_symbols.append("Lr");
+ m_symbols.append("Rf");
+ m_symbols.append("Db");
+ m_symbols.append("Sg");
+ m_symbols.append("Bh");
+ m_symbols.append("Hs");
+ m_symbols.append("Mt");
+ //110
+ m_symbols.append("Ds");
+ m_symbols.append("Rg");
+
+ return m_symbols;
+}
+
+// bool isName(const QString &name)
+// {
+// return molsKetch::name2number( name ) != -1;
+// }
+
+bool isSymbol(const QString &symbol)
+{
+ return symbols().contains(symbol);
+}
+
+bool isNumber(int number)
+{
+ return (0 <= number) && ( number <= symbols().count());
+}
+
+// QString molsKetch::number2name( int number )
+// {
+// Q_ASSERT(isNumber( number ));
+// return symbols()[number-1];
+// }
+
+QString molsKetch::number2symbol( int number )
+{
+ Q_ASSERT(isNumber( number ));
+ return eTable.GetSymbol(number);
+}
+
+QString molsKetch::position2symbol( int row, int column )
+{
+ switch (row)
+ {
+ case 1 :
+ if (column == 1) return eTable.GetSymbol(1);
+ if (column == 18) return eTable.GetSymbol(2);
+ return "";
+ case 2 :
+ if (column <= 2) return eTable.GetSymbol(2 + column);
+ if (column >= 13) return eTable.GetSymbol(4 + column - 12);
+ return "";
+ case 3 :
+ if (column <= 2) return eTable.GetSymbol(10 + column);
+ if (column >= 13) return eTable.GetSymbol(12 + column - 12);
+ return "";
+ case 4 :
+ return eTable.GetSymbol(18 + column);
+ case 5 :
+ return eTable.GetSymbol(36 + column);
+ case 6 :
+ if (column <= 2) return eTable.GetSymbol(54 + column);
+ if (column >= 4) return eTable.GetSymbol(71 + column - 3);
+ return "";
+ case 7 :
+ if (column <= 2) return eTable.GetSymbol(86 + column);
+ if (column >= 4 and column <= 16) return eTable.GetSymbol(103 + column - 3);
+ return "";
+ case 8 :
+ return "";
+ case 9 :
+ if (column <= 2) return "";
+ if (column >= 3 and column < 18) return eTable.GetSymbol(57 + column - 3);
+ return "";
+ case 10:
+ if (column <= 2) return "";
+ if (column >= 3 and column < 18) return eTable.GetSymbol(89 + column - 3);
+ return "";
+ default:
+ return "";
+ }
+}
+
+// int molsKetch::name2number( const QString &name )
+// {
+// for( int i = 0; i < m_size; i++) if (symbols()[i]==name) return i+1;
+// return -1;
+// }
+
+// QString molsKetch::name2symbol( const QString &name )
+// {
+// for( int i = 0; i < m_size; i++) if (symbols()[i]==name) return symbols()[i];
+// return "";
+// }
+
+int molsKetch::symbol2number( const QString &symbol )
+{
+ return eTable.GetAtomicNum(symbol.toAscii());;
+// for( int i = 0; i < m_size; i++) if (symbols()[i]==symbol) return i+1;
+// return -1;
+}
+
+// QString molsKetch::symbol2name( const QString &symbol )
+// {
+// // for( int i = 0; i<size; i++) if (m_symbols[i]==symbol) return m_names[i];
+// return "";
+// }
+
+double molsKetch::weightOfElement( int number )
+{
+ Q_ASSERT(isNumber( number ));
+ return eTable.GetMass(number);
+}
+
+int molsKetch::valencyOfElement( int number )
+{
+ Q_ASSERT(isNumber( number ));
+ return eTable.GetMaxBonds(number);
+}
+
+int molsKetch::oxidationStateOfElement( int number )
+{
+ Q_ASSERT(isNumber( number ));
+ return oxidation()[number];
+}
+
+int molsKetch::getSize()
+{
+ return symbols().count();
+}
diff --git a/molsketch_helium/element.h b/molsketch_helium/element.h
new file mode 100644
index 0000000..e0c0c01
--- /dev/null
+++ b/molsketch_helium/element.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains some routines to work with
+ * elements and translate between the element name, symbol and number.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+
+
+#ifndef ELEMENT_H
+#define ELEMENT_H
+
+class QString;
+
+/**
+ * Some auxilary functions for elements
+ *
+ * @author Harm van Eersel
+ */
+namespace molsKetch
+{
+/** Returns whether @p symbol is a proper element symbol. */
+bool isElementSymbol(const QString &symbol);
+/** Returns whether @p name is a proper element name. */
+bool isElementName(const QString &name);
+/** Returns whether @p number is a proper atom number. */
+bool isMsKAtomNumber(int number);
+
+/** Returns the name of the element with atom number @p number. */
+// QString number2name(int number);
+/** Returns the symbol of the element with atom number @p number. */
+QString number2symbol(int number);
+/** Returns the symbol of the element with atom number @p number. */
+QString position2symbol(int row, int column);
+/** Returns the atom number of the element with name @p name. */
+// int name2number(const QString &name);
+/** Returns the element symbol of the element with name @p name. */
+// QString name2symbol(const QString &name);
+/** Returns the atom number of the element with symbol @p symbol. */
+int symbol2number(const QString &symbol);
+/** Returns the element name of the element with symbol @p symbol. */
+// QString symbol2name(const QString &symbol);
+
+/** Returns the weight of element with atom number @p number. */
+qreal weightOfElement(int number);
+/** Returns the valency of element with atom number @p number. */
+int valencyOfElement(int number);
+/** Returns the most common oxidation state of element with atom number @p number. */
+int oxidationStateOfElement(int number);
+
+/** Returns the number of known elements. */
+int getSize();
+}
+#endif
diff --git a/molsketch_helium/fileio.cpp b/molsketch_helium/fileio.cpp
new file mode 100644
index 0000000..e339d42
--- /dev/null
+++ b/molsketch_helium/fileio.cpp
@@ -0,0 +1,526 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QtGui>
+#include <QtSvg/QtSvg>
+
+//#include <openbabel/obiter.h>
+#include <openbabel/mol.h>
+#include <openbabel/obconversion.h>
+
+#include "fileio.h"
+#include "molecule.h"
+#include "element.h"
+#include "molscene.h"
+
+QString svgLine(QLineF l, bool dashed = false, QString stroke = "#000000", qreal width = 1)
+{
+ // Create the output object
+ QString line;
+ QTextStream out(&line);
+
+ // Code a SVG line
+ out << "<line x1=\"" << l.x1() << "\" y1=\"" << l.y1() << "\" x2=\"" << l.x2() << "\" y2=\"" << l.y2() << "\" stroke=\"" << stroke << "\" stroke-width=\"" << width << "\" ";
+
+ // Check if the line is dotted
+ if (dashed) out << "stroke-dasharray = \"9, 5\" ";
+
+ // End and return the SVG tag
+ out << "/>" << endl;
+ return line;
+}
+
+QString svgPolygon(QLineF l, bool dashed = false)
+{
+ // Create the output object
+ QString polygon;
+ QTextStream out(&polygon);
+
+ // Get the needed positions
+ QLineF lup = MsKBond::shiftVector(l,3);
+ QLineF ldown = MsKBond::shiftVector(l,-3);
+
+ // Code the SVG polygon
+ out << "<polygon points=\"" << l.x1() << "," << l.y1() << " " << lup.x2() << "," << lup.y2() << " " << ldown.x2() << "," << ldown.y2() << "\" ";
+
+ // Code the correct fill method
+ if (dashed)
+ out << "fill=\"url(#StripedGradient)\" stroke=\"none\" ";
+ else
+ out << "fill=\"black\" stroke=\"black\" ";
+
+ // End and return the SVG tag
+ out << "/>" << endl;
+ return polygon;
+}
+
+QString svgDefs()
+{
+ // Create the output object
+ QString defs;
+ QTextStream out(&defs);
+
+ // Begin tag
+ out << "<defs>" << endl;
+
+ // Code the stripe pattern
+ out << "<pattern id=\"StripedPattern\" x=\"0\" y=\"0\" width=\"100\" height=\"10\" patternUnits=\"userSpaceOnUse\" >" << endl;
+ out << svgLine(QLineF(0,0,100,0));
+ out << "</pattern>" << endl;
+
+ // Code the stripe gradient
+ ///TODO finetuning
+// out << "<radialGradient id=\"StripedGradient\" r=\"5%\" spreadMethod=\"repeat\" >" << endl;
+ out << "<linearGradient id=\"StripedGradient\" x2=\"5%\" spreadMethod=\"repeat\" >" << endl;
+ out << "<stop offset=\"0\" stop-color=\"white\" />" << endl;
+ out << "<stop offset=\"0.3\" stop-color=\"white\" />" << endl;
+ out << "<stop offset=\"0.5\" stop-color=\"black\" />" << endl;
+ out << "<stop offset=\"0.7\" stop-color=\"white\" />" << endl;
+ out << "<stop offset=\"1\" stop-color=\"white\" />" << endl;
+ out << "</linearGradient>" << endl;
+// out << "</radialGradient>" << endl;
+
+ // End tag
+ out << "</defs>" << endl;
+
+ return defs;
+}
+/*
+bool molsKetch::saveToSVG( const QString & fileName, MolScene * scene )
+{
+ QSvgGenerator svgGen;
+ svgGen.setFileName( fileName );
+ QPainter painter(&svgGen);
+
+ // Clear selection
+ QList<QGraphicsItem*> selList(scene->selectedItems());
+ scene->clearSelection();
+
+ scene->render( &painter );
+
+ // Restore selection
+ foreach(QGraphicsItem* item, selList) item->setSelected(true);
+
+}*/
+
+bool molsKetch::saveToSVG( const QString & fileName, MolScene * scene )
+{
+ // Trying to open a file with filename
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false;
+
+ // Making the writeobject
+ QTextStream out(&file);
+
+ // Writing the header
+ out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ out<< "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">" << endl;
+ out << "<svg version=\"1.1\" width=\"" << scene->itemsBoundingRect().width() << "\" height=\"" << scene->itemsBoundingRect().height() << "\" viewBox=\"" << scene->itemsBoundingRect().left() << " " << scene->itemsBoundingRect().top() << " " << scene->itemsBoundingRect().width() << " " << scene->itemsBoundingRect().height() << "\">" << endl;
+
+ out << svgDefs();
+
+ // Writing the molecule
+ for (int i = 0; i < scene->items().count(); i++)
+ {
+ if (scene->items().at(i)->type() == Molecule::Type)
+ {
+ Molecule* mol = (Molecule*)(scene->items().at(i));
+
+ foreach (MsKBond* bond, mol->bonds())
+ {
+ // Get the bond and its attributes
+// MsKBond* bond = mol->bond(j);
+ QPointF p1 = bond->firstMsKAtom()->scenePos();
+ QPointF p2 = bond->lastMsKAtom()->scenePos();
+ QLineF line = QLineF(p1,p2);
+
+ // Check the type and order
+ switch (bond->bondType())
+ {
+ case MsKBond::Up:
+ out << svgPolygon(line);
+ break;
+ case MsKBond::UpR:
+ out << svgPolygon(line);
+ break;
+ case MsKBond::Down:
+ out << svgPolygon(line,true);
+ break;
+ case MsKBond::DownR:
+ out << svgPolygon(line,true);
+ break;
+ case MsKBond::Dot:
+ out << svgLine(line,true);
+ break;
+ default:
+ switch (bond->bondOrder())
+ {
+ case MsKBond::Single:
+ out << svgLine(line);
+ break;
+ case MsKBond::Double:
+ out << svgLine(MsKBond::shiftVector(line,2));
+ out << svgLine(MsKBond::shiftVector(line,-2));
+ break;
+ case MsKBond::Triple:
+ out << svgLine(MsKBond::shiftVector(line,3));
+ out << svgLine(MsKBond::shiftVector(line,-3));
+ out << svgLine(line);
+ break;
+ }
+ }
+ }
+
+ foreach (MsKAtom* atom, mol->atoms())
+ {
+// MsKAtom* atom = mol->atom(j);
+
+ // Check if atom is visible and draw
+ if (atom->isDrawn())
+ {
+ // Mask the bonds under the atom
+// out << "<mask>" << endl;
+ out << "<circle cx=\"" << atom->scenePos().x() << "\" cy=\"" << atom->scenePos().y() << "\" r=\"" << 13 << "\" fill=\"#FFFFFF\"/>" << endl;
+// out << "</mask>" << endl;
+
+ // Draw the element
+ out << "<text x=\"" << atom->scenePos().x() << "\" y=\"" << atom->scenePos().y() + 5 << "\" font-family=\"Helvetica\" font-size=\"12\" fill=\"#000000\">";
+ out << "<tspan text-anchor=\"middle\">" << atom->element();
+ if (atom->numberOfImplicitHydrogens()>0) out << "H";
+ if (atom->numberOfImplicitHydrogens()>1) out << "<tspan dy=\"4\" font-size=\"8\" >" << atom->numberOfImplicitHydrogens() << "</tspan>"; // baseline-shift=\"sub\"
+ out << "<tspan font-size=\"8\" dy=\"-10\" >" << atom->chargeID() << "</tspan>";
+ out << "</tspan>"; //baseline-shift=\"super\"
+ out << "</text>" << endl;
+ }
+ }
+
+ }
+ }
+
+ // Writing the final tag and closing the file
+ out << "</svg>" << endl;
+ file.close();
+
+ return true;
+}
+
+
+
+bool molsKetch::saveFile(const QString &fileName, QGraphicsScene* scene)
+{
+// QMessageBox::warning(this,tr(PROGRAM_NAME),tr("Saving is only partially implemented. You may lose data if you overwrite an existing file."),QMessageBox::Ok,QMessageBox::Ok);
+ using namespace OpenBabel;
+ OBConversion * conversion = new OBConversion;
+
+ if (conversion->SetOutFormat(QFileInfo(fileName).suffix().toAscii()))
+ {
+ // Create the output molecule
+ OBMol* obmol = new OBMol;
+ QHash<MsKAtom*,OpenBabel::OBAtom*> hash;
+
+ // Add all molecules on the scene
+ foreach(QGraphicsItem* item, scene->items())
+ {
+ if (item->type() == Molecule::Type)
+ {
+ Molecule* mol = dynamic_cast<Molecule*>(item);
+
+ hash.clear();
+
+ obmol->BeginModify();
+// obmol->ReserveMsKAtoms(mol->countMsKAtoms());
+ foreach (MsKAtom* atom, mol->atoms())
+ {
+ OpenBabel::OBAtom* obatom = obmol->NewAtom();
+// MsKAtom* atom = mol->atom(j);
+ obatom->SetVector(atom->scenePos().x()/40,atom->scenePos().y()/40,0);
+ std::string element = atom->element().toStdString();
+// obatom->SetType(element);
+ obatom->SetAtomicNum(molsKetch::symbol2number(atom->element()));
+// obmol->AddAtom(*obatom);
+ hash.insert(atom,obatom);
+// cerr << hash.count() << "\n";
+ }
+ foreach (MsKBond* bond, mol->bonds())
+ {
+// MsKBond* bond = mol->bonds[j];
+ MsKAtom* a1 = bond->firstMsKAtom();
+ MsKAtom* a2 = bond->lastMsKAtom();
+
+ OBAtom* oba1 = hash.value(a1);
+ OBAtom* oba2 = hash.value(a2);
+
+ OpenBabel::OBBond* obbond = new OpenBabel::OBBond();
+// OBBond* obbond = obmol->NewBond();
+
+ // Set identifier
+// obbond->SetIdx(j);
+
+ // Set bondorder
+ obbond->SetBO(bond->bondOrder());
+
+ // Setting bondtype
+ switch (bond->bondType())
+ {
+ case MsKBond::Up:
+ obbond->SetWedge();
+ case MsKBond::UpR:
+ obbond->SetBegin(oba2);
+ obbond->SetEnd(oba1);
+ obbond->SetWedge();
+ break;
+ case MsKBond::Down:
+ obbond->SetHash();
+ case MsKBond::DownR:
+ obbond->SetBegin(oba2);
+ obbond->SetEnd(oba1);
+ obbond->SetHash();
+ break;
+ default:
+ obbond->SetBegin(oba1);
+ obbond->SetEnd(oba2);
+ }
+
+ // Adding the bond
+// obmol->AddBond(oba1->GetIdx(),oba2->GetIdx(),bond->getOrder());
+
+ obmol->AddBond(*obbond);
+
+ }
+ obmol->EndModify();
+ }
+ }
+
+ // Checking if the file exists and making a backup
+ if (QFile::exists(fileName))
+ {
+ QFile::remove(fileName + "~");
+ QFile::copy(fileName,fileName + "~");
+ }
+
+ // Writing the final result to the file
+ conversion->WriteFile(obmol,fileName.toStdString());
+// qDebug << "File saved: " << fileName.toStdString() << "\n";
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+Molecule* molsKetch::loadFile(const QString &fileName)
+{
+ // Creating and setting conversion classes
+ using namespace OpenBabel;
+ OBConversion * conversion = new OBConversion;
+ conversion->SetInFormat(conversion->FormatFromExt(fileName.toAscii()));
+ OBMol obmol;
+
+ // Try to load a file
+ if (conversion->ReadFile(&obmol, fileName.toStdString()))
+ {
+ // Create a new molecule
+ Molecule* mol = new Molecule();
+ mol->setPos(QPointF(0,0));
+// cerr << "mol " << "x: " << mol->pos().x() << " y: " << mol->pos().y() << "\n";
+
+ // Initialize normalization factor
+// qreal factor = 1;
+ // molfile.GetInternalCoord(0,0,0);
+
+ // Add atoms one-by-ons
+ for (unsigned int i = 1; i <= obmol.NumAtoms();i++)
+// FOR_ATOMS_OF_MOL(obatom,obmol)
+ {
+ OpenBabel::OBAtom *obatom = obmol.GetAtom(i);
+ // scene->addRect(QRectF(atom->GetX(),atom->GetY(),5,5));
+ MsKAtom* atom = mol->addMsKAtom(molsKetch::number2symbol(obatom->GetAtomicNum()),QPointF(obatom->x()*40,obatom->y()*40), false);
+
+ }
+
+ // Add bonds one-by-one
+ /// Mind the numbering!
+ for (unsigned int i = 0; i < obmol.NumBonds();i++)
+// FOR_BONDS_OF_MOL(obbond,obmol)
+ {
+ // Loading the OpenBabel objects
+ OpenBabel::OBBond *obbond = obmol.GetBond(i);
+ OBAtom *a1 = obbond->GetBeginAtom();
+ OBAtom *a2 = obbond->GetEndAtom();
+
+ // Creating their internal counterparts
+ MsKAtom* atomA = mol->atomAt(QPointF(a1->x()*40,a1->y()*40));
+ MsKAtom* atomB = mol->atomAt(QPointF(a2->x()*40,a2->y()*40));
+ MsKBond* bond = mol->addBond(atomA,atomB,obbond->GetBondOrder());
+
+ // Set special bond types
+ if (obbond->IsWedge()) bond->setType( MsKBond::Up );
+ if (obbond->IsHash()) bond->setType( MsKBond::Down );
+// if (obbond->IsUp()) bond->setType( MsKBond::Up );
+// if (obbond->IsDown()) bond->setType( MsKBond::Down );
+ // if (obbond->IsHash()) bond->setType( MsKBond::Dot );
+
+ // Normalizing
+// factor = scene->getBondLength()/obbond->GetLength();
+ }
+
+ // // Normalizing molecule
+ // mol->scale(factor,factor);
+ // mol->setMsKAtomSize(LABEL_SIZE/factor);
+
+ return mol;
+ }
+ else
+ {
+ return 0;
+ }
+
+}
+
+// Molecule* smiles(QString formula)
+// {
+// Molecule* mol = new Molecule();
+// // QGraphicsScene scene;
+// // scene.addItem(mol);
+//
+// for (int i = 0; i < formula.length();i++)
+// {
+// if (formula.at( i ).isLetter())
+// mol->addMsKAtom( QString(formula.at( i )), QPoint(0,0) );
+// }
+//
+// return mol;
+// }
+
+bool molsKetch::exportFile(const QString &fileName, MolScene * scene)
+{
+ // Clear selection
+ QList<QGraphicsItem*> selList(scene->selectedItems());
+ scene->clearSelection();
+
+ QImage image = scene->renderImage(scene->itemsBoundingRect());
+
+ // Restore selection
+ foreach(QGraphicsItem* item, selList) item->setSelected(true);
+
+ return image.save(fileName);
+}
+
+
+bool molsKetch::printFile(QPrinter &printer, MolScene * scene)
+{
+ // Creating the painter
+ QPainter painter(&printer);
+
+ // Clear selection
+ QList<QGraphicsItem*> selList(scene->selectedItems());
+ scene->clearSelection();
+
+ // Rendering on the printer
+ QRectF rect(scene->itemsBoundingRect());
+ scene->render(&painter,printer.pageRect(),rect);
+
+ // Restore selection
+ foreach(QGraphicsItem* item, selList) item->setSelected(true);
+
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////ZN CODE//////////////////////////////////////
+
+OpenBabel::OBMol *molsKetch::toOBMolecule (QGraphicsItem *item) {
+ using namespace OpenBabel;
+ OpenBabel::OBMol *obmol = new OpenBabel::OBMol ();
+ if (item->type() == Molecule::Type)
+ {
+
+ Molecule* mol = dynamic_cast<Molecule*>(item);
+ QHash<MsKAtom*,OpenBabel::OBAtom*> hash;
+ hash.clear();
+
+ obmol->BeginModify();
+ // obmol->ReserveMsKAtoms(mol->countMsKAtoms());
+ foreach (MsKAtom* atom, mol->atoms())
+ {
+ OpenBabel::OBAtom* obatom = obmol->NewAtom();
+ // MsKAtom* atom = mol->atom(j);
+ obatom->SetVector(atom->scenePos().x()/40*1.5,-atom->scenePos().y()/40*1.5,0);
+ std::string element = atom->element().toStdString();
+ // obatom->SetType(element);
+ obatom->SetAtomicNum(molsKetch::symbol2number(atom->element()));
+ // obmol->AddAtom(*obatom);
+ hash.insert(atom,obatom);
+ // cerr << hash.count() << "\n";
+ }
+ foreach (MsKBond* bond, mol->bonds())
+ {
+ // MsKBond* bond = mol->bonds[j];
+ MsKAtom* a1 = bond->firstMsKAtom();
+ MsKAtom* a2 = bond->lastMsKAtom();
+
+ OBAtom* oba1 = hash.value(a1);
+ OBAtom* oba2 = hash.value(a2);
+
+ OpenBabel::OBBond* obbond = new OpenBabel::OBBond();
+ // OBBond* obbond = obmol->NewBond();
+
+ // Set identifier
+ // obbond->SetIdx(j);
+
+ // Set bondorder
+ obbond->SetBO(bond->bondOrder());
+
+ // Setting bondtype
+ switch (bond->bondType())
+ {
+ case MsKBond::Up:
+ obbond->SetWedge();
+ case MsKBond::UpR:
+ obbond->SetBegin(oba2);
+ obbond->SetEnd(oba1);
+ obbond->SetWedge();
+ break;
+ case MsKBond::Down:
+ obbond->SetHash();
+ case MsKBond::DownR:
+ obbond->SetBegin(oba2);
+ obbond->SetEnd(oba1);
+ obbond->SetHash();
+ break;
+ default:
+ obbond->SetBegin(oba1);
+ obbond->SetEnd(oba2);
+ }
+
+ // Adding the bond
+ // obmol->AddBond(oba1->GetIdx(),oba2->GetIdx(),bond->getOrder());
+
+ obmol->AddBond(*obbond);
+
+ }
+ obmol->EndModify();
+ }
+ return obmol;
+}
+
diff --git a/molsketch_helium/fileio.h b/molsketch_helium/fileio.h
new file mode 100644
index 0000000..acb58d1
--- /dev/null
+++ b/molsketch_helium/fileio.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains routines for loading and
+ * saving files.
+ *
+ * @author Harm van Eersel
+ * @since Hydrogen
+ */
+#include "obabel_includes.h"
+class MolScene;
+class Molecule;
+
+
+/**
+ * Load and save routines
+ *
+ * @author Harm van Eersel
+ */
+namespace molsKetch
+{
+
+/**
+ * Loads file with @p fileName and returns it as pointer to a new Molecule
+ * object.
+ */
+Molecule* loadFile(const QString &fileName);
+/**
+ * Saves the current document under @p fileName and returns @c false if the
+ * save failed.
+ */
+bool saveFile(const QString &fileName, QGraphicsScene * scene);
+
+/**
+ * Exports the document on MolScene @p scene as a bitmap with @p fileName
+ * and returns @c false if the export failed.
+ */
+bool exportFile(const QString &fileName, MolScene * scene);
+/**
+ * Prints the document on MolScene @p scene on QPrinter @p printer and
+ * returns @c false if the print failed.
+ */
+bool printFile(QPrinter &printer, MolScene * scene);
+/**
+ * Exports the current document on MolScene @p scene under @p fileName and
+ * returns @c false if the export failed.
+ */
+bool saveToSVG(const QString &fileName, MolScene * scene);
+
+// Molecule* smiles(QString formula);
+
+/////////////////////////////////////////////ZN CODE//////////////////////////////////////////////
+
+OpenBabel::OBMol *toOBMolecule (QGraphicsItem *item);
+
+}
diff --git a/molsketch_helium/i18n/CMakeLists.txt b/molsketch_helium/i18n/CMakeLists.txt
new file mode 100644
index 0000000..1970cfc
--- /dev/null
+++ b/molsketch_helium/i18n/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Builds the translation files
+# Based on some work of Patrick Noffke
+# http://public.kitware.com/pipermail/cmake/2006-July/010055.html
+
+# QT4_WRAP_TS(lupdate_outputs lrelease_outputs prefix lang1 lang2 ... )
+macro(QT4_WRAP_TS lupdate_outputs lrelease_outputs prefix)
+ foreach(it ${ARGN})
+ set(tsfile ${CMAKE_CURRENT_SOURCE_DIR}/${prefix}_${it}.ts)
+# SET(tsfile ${CMAKE_CURRENT_BINARY_DIR}/translations/${prefix}_${it}.ts)
+ add_custom_command(OUTPUT ${tsfile}
+ COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} -ts ${tsfile}
+ )
+
+ set(qmfile ${CMAKE_CURRENT_BINARY_DIR}/${prefix}_${it}.qm)
+ add_custom_command(OUTPUT ${qmfile}
+ COMMAND ${QT_LRELEASE_EXECUTABLE} ${tsfile} -qm ${qmfile}
+ )
+
+ set(${lupdate_outputs} ${${lupdate_outputs}} ${tsfile})
+ set(${lrelease_outputs} ${${lrelease_outputs}} ${qmfile})
+ endforeach(it)
+endmacro(QT4_WRAP_TS)
+
+# Create the translation files
+qt4_wrap_ts(lupdate_outputs lrelease_outputs molsketch nl cs)
+
+# Add target for updating translation files
+add_custom_target(lupdate DEPENDS ${lupdate_outputs})
+
diff --git a/molsketch_helium/i18n/CVS/Entries b/molsketch_helium/i18n/CVS/Entries
new file mode 100644
index 0000000..6253145
--- /dev/null
+++ b/molsketch_helium/i18n/CVS/Entries
@@ -0,0 +1,5 @@
+/CMakeLists.txt/1.1/Mon Sep 29 09:13:02 2008//
+/molsketch_cs.ts/1.1/Mon Sep 29 09:13:03 2008//
+/molsketch_nl.ts/1.1/Mon Sep 29 09:13:06 2008//
+/molsketch_pt_BR.ts/1.1/Mon Sep 29 09:13:09 2008//
+D
diff --git a/molsketch_helium/i18n/CVS/Entries.Extra b/molsketch_helium/i18n/CVS/Entries.Extra
new file mode 100644
index 0000000..b8916b7
--- /dev/null
+++ b/molsketch_helium/i18n/CVS/Entries.Extra
@@ -0,0 +1,4 @@
+/CMakeLists.txt////*///
+/molsketch_cs.ts////*///
+/molsketch_nl.ts////*///
+/molsketch_pt_BR.ts////*///
diff --git a/molsketch_helium/i18n/CVS/Entries.Extra.Old b/molsketch_helium/i18n/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/i18n/CVS/Entries.Old b/molsketch_helium/i18n/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/i18n/CVS/Repository b/molsketch_helium/i18n/CVS/Repository
new file mode 100644
index 0000000..115748e
--- /dev/null
+++ b/molsketch_helium/i18n/CVS/Repository
@@ -0,0 +1 @@
+zodiac/molsketch_helium/i18n
diff --git a/molsketch_helium/i18n/CVS/Root b/molsketch_helium/i18n/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/molsketch_helium/i18n/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/molsketch_helium/i18n/molsketch_cs.ts b/molsketch_helium/i18n/molsketch_cs.ts
new file mode 100644
index 0000000..b583fb4
--- /dev/null
+++ b/molsketch_helium/i18n/molsketch_cs.ts
@@ -0,0 +1,808 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="cs_CZ">
+<context>
+ <name>Dialog</name>
+ <message>
+ <location filename="../settings.ui" line="13"/>
+ <source>Dialog</source>
+ <translation>Nastavení</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="37"/>
+ <source>Atom settings</source>
+ <translation>Nastavení atomů</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="61"/>
+ <source>Show neutral hydrogen atoms</source>
+ <translation>Nastavení vazeb</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="68"/>
+ <source>Automaticly add hydrogens</source>
+ <translation>Automaticky přidávat vodíky</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="75"/>
+ <source>Show atomic charge</source>
+ <translation>Zobrazovat náboj atomů</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="82"/>
+ <source>Show neutral carbon atoms</source>
+ <translation>Zobrazovat neutrální uhlíky</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="92"/>
+ <source>Bond settings</source>
+ <translation>Nastavení vazeb</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="116"/>
+ <source>Bond angle:</source>
+ <translation>Úhel vazby:</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="129"/>
+ <source>Bond length:</source>
+ <translation>Délka vazby:</translation>
+ </message>
+ <message>
+ <location filename="../settings.ui" line="139"/>
+ <source>Note: the bond angle will be rounded to the nearest whole divisor of 360*</source>
+ <translation>Poznámka: vazební úhel bude zaokrouhlen na nejbližší dělitel 360°</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="../mainwindow.cpp" line="123"/>
+ <source>Open - molsKetch</source>
+ <translation>Otevřít soubor - molsKetch</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="188"/>
+ <source>Error while loading file</source>
+ <translation>Chyba při otevírání souboru</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="156"/>
+ <source>Save as - molsKetch</source>
+ <translation>Uložit soubor - molsKetch</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="178"/>
+ <source>Import - molsKetch</source>
+ <translation>Importovat - molsKetch</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="196"/>
+ <source>Export - molsKetch</source>
+ <translation>Exportovat - molsKetch</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="231"/>
+ <source>Error while printing file</source>
+ <translation>Chyba při tisku souboru</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="287"/>
+ <source>About</source>
+ <translation>O aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="307"/>
+ <source>Left Click: add atom, Drag: add bond, Click on bond: change order, Shift + Left Click on bond: change type, Right Click: remove item</source>
+ <translation>Levý klik: přidat atom, Tažení: přidat vazbu, Klik na vazbu: změnit pořadí, Shift+Levý klik na vazbu: změnit typ, Pravý klik: odstranit položku</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="315"/>
+ <source>Click on an item to delete it. Double click on an molecule to delete it.</source>
+ <translation>Kliknutí na položce ji odstraní. Dvojklik na molekule ji odstraní.</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="323"/>
+ <source>Click on an item to select it. Drag to move selected items.</source>
+ <translation>Kliknutí na položce ji vybere. Tažením se vybrané položky přesunou.</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="340"/>
+ <source>&New</source>
+ <translation>&Nový</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="341"/>
+ <source>Ctrl+N</source>
+ <translation>Ctrl+N</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="342"/>
+ <source>Create a new file</source>
+ <translation>Vytvořit nový soubor</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="345"/>
+ <source>&Open...</source>
+ <translation>&Otevřít...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="346"/>
+ <source>Ctrl+O</source>
+ <translation>Ctrl+O</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="347"/>
+ <source>Open an existing file</source>
+ <translation>Otevřít soubor</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="350"/>
+ <source>&Save</source>
+ <translation>&Uložit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="351"/>
+ <source>Ctrl+S</source>
+ <translation>Ctrl+S</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="352"/>
+ <source>Save the document to disk</source>
+ <translation>Uložit soubor na disk</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="355"/>
+ <source>Save &As...</source>
+ <translation>Uložit j&ako...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="356"/>
+ <source>Save the document under a new name</source>
+ <translation>Uložit soubor pod novým názvem</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="359"/>
+ <source>&Import...</source>
+ <translation>&Importovat...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="360"/>
+ <source>Ctrl+I</source>
+ <translation>Ctrl+I</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="361"/>
+ <source>Insert an existing molecule into the document</source>
+ <translation>Vložit molekulu ze souboru do dokumentu</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="364"/>
+ <source>&Export...</source>
+ <translation>&Exportovat...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="365"/>
+ <source>Ctrl+E</source>
+ <translation>Ctrl+E</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="366"/>
+ <source>Export the current document as a picture</source>
+ <translation>Exportovat současný dokument jako obrázek</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="369"/>
+ <source>&Print...</source>
+ <translation>&Tisknout...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="370"/>
+ <source>Ctrl+P</source>
+ <translation>Ctrl+P</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="371"/>
+ <source>Print the current document</source>
+ <translation>Vytisknout současný dokument</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="374"/>
+ <source>E&xit</source>
+ <translation>U&končit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="375"/>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="376"/>
+ <source>Exit the application</source>
+ <translation>Ukončit aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="382"/>
+ <source>Ctrl+Z</source>
+ <translation>Ctrl+Z</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="383"/>
+ <source>Undo the last action</source>
+ <translation>Vzít zpět poslední akci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="387"/>
+ <source>Ctrl+Shift+Z</source>
+ <translation>Ctrl+Shift+Z</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="388"/>
+ <source>Redo the last action</source>
+ <translation>Provést znovu poslení akci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="390"/>
+ <source>Cu&t</source>
+ <translation>Vyjmou&t</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="391"/>
+ <source>Ctrl+X</source>
+ <translation>Ctrl+X</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="393"/>
+ <source>Cut the current selection's contents to the clipboard</source>
+ <translation>Vyjmout současný výběr a uložit jej do schránky</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="396"/>
+ <source>&Copy</source>
+ <translation>&Kopírovat</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="397"/>
+ <source>Ctrl+C</source>
+ <translation>Ctrl+C</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="399"/>
+ <source>Copy the current selection's contents to the clipboard</source>
+ <translation>Zkopírovat současný výběr do schránky</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="402"/>
+ <source>&Paste</source>
+ <translation>V&ložit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="403"/>
+ <source>Ctrl+V</source>
+ <translation>Ctrl+V</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="405"/>
+ <source>Paste the clipboard's contents into the current selection</source>
+ <translation>Vložit obsah schránky do současného výběru</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="408"/>
+ <source>&Select all</source>
+ <translation>Vybr&at vše</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="409"/>
+ <source>Ctrl+A</source>
+ <translation>Ctrl+A</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="410"/>
+ <source>Selects all elements on the scene</source>
+ <translation>Vybrat všechno zobrazené</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="415"/>
+ <source>F5</source>
+ <translation>F5</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="416"/>
+ <source>Go to the atom addition mode</source>
+ <translation>Zapnout režim vkládání atomů</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="421"/>
+ <source>F6</source>
+ <translation>F6</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="422"/>
+ <source>Go to the atom deletion mode</source>
+ <translation>Zapnout režim mazání atomů</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="425"/>
+ <source>&Move mode</source>
+ <translation>Režim pře&souvání</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="427"/>
+ <source>F7</source>
+ <translation>F7</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="428"/>
+ <source>Go to the molecule move mode</source>
+ <translation>Zapnout režim přesouvání molekul</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="437"/>
+ <source>Align to grid</source>
+ <translation>Přichytit ke mřížce</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="438"/>
+ <source>Align all elements on the scene to the grid</source>
+ <translation>Zarovnat všechno zobrazené ke mřížce</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="441"/>
+ <source>Edit Pre&ferences...</source>
+ <translation>Upravit &nastavení...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="442"/>
+ <source>Ctrl+F</source>
+ <translation>Ctrl+F</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="443"/>
+ <source>Edit your preferences</source>
+ <translation>Upravit nastavení aplikace</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="447"/>
+ <source>Zoom &In</source>
+ <translation>Z&většit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="448"/>
+ <source>Ctrl++</source>
+ <translation>Ctrl++</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="449"/>
+ <source>Zoom in on the canvas</source>
+ <translation>Zvětšit zobrazení</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="452"/>
+ <source>Zoom &Out</source>
+ <translation>Z&menšit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="453"/>
+ <source>Ctrl+-</source>
+ <translation>Ctrl+-</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="454"/>
+ <source>Zoom out on the canvas</source>
+ <translation>Zmenšit zobrazení</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="457"/>
+ <source>Zoom &Reset</source>
+ <translation>&Základní velikost</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="458"/>
+ <source>Ctrl+=</source>
+ <translation>Ctrl+=</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="459"/>
+ <source>Reset the zoom level</source>
+ <translation>Nastavit výchozí velikost zobrazení</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="462"/>
+ <source>Zoom &Fit</source>
+ <translation>Přizpů&sobit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="463"/>
+ <source>Ctrl+*</source>
+ <translation>Ctrl+*</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="464"/>
+ <source>Fit to screen</source>
+ <translation>Přizpůsobit velikost zobrazení oknu</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="468"/>
+ <source>&Help Contents...</source>
+ <translation>&Příručka aplikace 'molsKetch'</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="469"/>
+ <source>F1</source>
+ <translation>F1</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="470"/>
+ <source>Show the application's help contents</source>
+ <translation>Zobrazit příručku aplikace</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="473"/>
+ <source>Submit &Bug...</source>
+ <translation>Na&hlásit chybu...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="474"/>
+ <source>Open the browser with the bug tracker</source>
+ <translation>Otevřít v prohlížeči stránku pro hlášení chyb</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="477"/>
+ <source>&About</source>
+ <translation>O &aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="478"/>
+ <source>Show the application's About box</source>
+ <translation>Zobrazit dialog s informacemi o aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="481"/>
+ <source>About &Qt</source>
+ <translation>O knihovně &Qt</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="482"/>
+ <source>Show the Qt library's About box</source>
+ <translation>Zobrazit dialog s informacemi o knihovně Qt</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="498"/>
+ <source>&File</source>
+ <translation>&Soubor</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="510"/>
+ <source>&Edit</source>
+ <translation>Ú&pravy</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="528"/>
+ <source>&View</source>
+ <translation>Po&hled</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="536"/>
+ <source>&Help</source>
+ <translation>Nápo&věda</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="547"/>
+ <source>File</source>
+ <translation>Soubor</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="556"/>
+ <source>Edit</source>
+ <translation>Úpravy</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="570"/>
+ <source>Zoom</source>
+ <translation>Lupa</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="580"/>
+ <source>Ready</source>
+ <translation>Připraven</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="586"/>
+ <source>Toolbox</source>
+ <translation>Nástroje</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="588"/>
+ <source>Infobox</source>
+ <translation>Informace</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="596"/>
+ <source>Add...</source>
+ <translation>Přidat...</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="597"/>
+ <source>Delete</source>
+ <translation>Odstranit</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="692"/>
+ <source>Recent Items</source>
+ <translation>Nedávné položky</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="693"/>
+ <source>Elements</source>
+ <translation>Prvky</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="694"/>
+ <source>Generic Molecules</source>
+ <translation>Generické molekuly</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="695"/>
+ <source>Custom Molecules</source>
+ <translation>Vlastní molekuly</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="723"/>
+ <source>Enter a name</source>
+ <translation>Vložte jméno</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="723"/>
+ <source>Enter a name for this item:</source>
+ <translation>Zadejte pojmenování položky:</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="735"/>
+ <source>Are you sure?</source>
+ <translation>Jste si jisti?</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="735"/>
+ <source>Do you really want to delete this item?</source>
+ <translation>Opravdu chcete vymazat tuto položku?</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="856"/>
+ <source>This document has been modified.
+Do you want to save your changes?</source>
+ <translation>Dokument byl modifikován.
+Chcete uložit změny?</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="872"/>
+ <source>untitled.mol</source>
+ <translation>Nepojmenovaný.mol</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="877"/>
+ <source>%1[*] - %2</source>
+ <translation>%1[*] - %2</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Total weight: </source>
+ <translation>Celková hmotnost: </translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Total charge: </source>
+ <translation>Celkový náboj: </translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Number of atoms: </source>
+ <translation>Počet atomů: </translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Number of bonds: </source>
+ <translation>Počet vazeb: </translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="288"/>
+ <source><H3>About molsKetch</H3> <P> molsKetch is an program for drawing molecular structures developed by Harm van Eersel at the <A href="http://www.tue.nl">Eindhoven University of Technology</A>.<P> For more info check <A href="http://molsketch.sourceforge.net">http://molsketch.sourceforge.net</A> <P> It is <A href="http://www.gnu.org/philosophy/free-sw.html">free software</A> and a [...]
+ <translation><h3>O aplikaci »molsKetch«</h3>
+<p>molsKetch je program na kreslení molekulárních struktur vyvinutý Harmem van Eerselem na <a href="http://www.tue.nl/">Technické universitě v Eindhovenu</a>.</p>
+<p>Více informací naleznete na <a href="http://molsketch.sourceforge.net">http://molsketch.sourceforge.net/</a></p>
+<p>Je to <a href="http://www.gnu.org/philosophy/free-sw.cs.html">svobodný software</a> dostupný pod licencí <a href="http://www.gnu.org/licenses/gpl.html">GPL</a>.
+<p>Poděkování patří:</p>
+<ul><li>Dr. H. Zantema (vedoucí práce)</li> <li>Davy van der Vaart (tester)</li> <li>Frans Visscher (tester)</li> <li>Carsten Niehaus (revize kódu)</li></ul>
+<p>Copyright 2007 - Harm van Eersel, český překlad <a href="mailto:kavol at seznam.cz">kavol</a></p></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="969"/>
+ <source>Non selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="170"/>
+ <source>Error while saving. Perhaps the name is invalid or the file type is unknown.</source>
+ <translation>Chyba při ukládání. Patrně neplatné jméno nebo neznámý typ souboru.</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="209"/>
+ <source>Error while exporting file as pixmap</source>
+ <translation>Chyba při exportu souboru v rastrovém formátu</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="331"/>
+ <source>Click and move the mouse on an item to rotate it.</source>
+ <translation>Kliknutí a tažení myší na položce ji bude rotovat.</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="413"/>
+ <source>&Add mode</source>
+ <translation>Režim &vkládání</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="419"/>
+ <source>&Delete mode</source>
+ <translation>Režim &mazání</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="431"/>
+ <source>&Rotate mode</source>
+ <translation>Režim &rotace</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="433"/>
+ <source>F8</source>
+ <translation>F8</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="434"/>
+ <source>Go to rotation mode</source>
+ <translation>Zapnout ržim rotace</translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Number of scene items: </source>
+ <translation>Počet objektů na scéně: </translation>
+ </message>
+ <message>
+ <location filename="../mainwindow.cpp" line="972"/>
+ <source>Number of document items: </source>
+ <translation>Počet objektů v dokumentu: </translation>
+ </message>
+</context>
+<context>
+ <name>MolScene</name>
+ <message>
+ <location filename="../molscene.cpp" line="112"/>
+ <source>aligning to grid</source>
+ <translation>zarovnání k mřížce</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="143"/>
+ <source>cutting items</source>
+ <translation>vyjmout</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="195"/>
+ <source>pasting items</source>
+ <translation>vložit</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="299"/>
+ <source>add molecule</source>
+ <translation>přidat molekulu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="1051"/>
+ <source>moving item(s)</source>
+ <translation>přesun</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="808"/>
+ <source>change of bondtype</source>
+ <translation>změnit vazbu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="810"/>
+ <source>change of bondorder</source>
+ <translation>změnit řád vazby</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="883"/>
+ <source>increasing charge</source>
+ <translation>kladnější náboj</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="888"/>
+ <source>decreasing charge</source>
+ <translation>zápornější náboj</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="901"/>
+ <source>changing element</source>
+ <translation>změnit prvek</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="929"/>
+ <source>adding atom</source>
+ <translation>přidat atom</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="952"/>
+ <source>removing atom</source>
+ <translation>smazat atom</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="964"/>
+ <source>removing bond</source>
+ <translation>smazat vazbu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="975"/>
+ <source>removing molecule</source>
+ <translation>smazat molekulu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="990"/>
+ <source>removing item(s)</source>
+ <translation>smazat</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="831"/>
+ <source>Add Molecule</source>
+ <translation>Přidat molekulu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="908"/>
+ <source>adding bond</source>
+ <translation>přidat vazbu</translation>
+ </message>
+ <message>
+ <location filename="../molscene.cpp" line="1132"/>
+ <source>rotating item</source>
+ <translation>rotovat</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <location filename="../settings.cpp" line="36"/>
+ <source>Atom settings</source>
+ <translation>Nastavení atomů</translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="37"/>
+ <source>Bond settings</source>
+ <translation>Nastavení vazeb</translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="40"/>
+ <source>Bond length: </source>
+ <translation>Délka vazby: </translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="41"/>
+ <source>Bond angle: </source>
+ <translation>Úhel vazby: </translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="47"/>
+ <source>Automatic add hydrogens</source>
+ <translation>Automaticky přidávat vodíky</translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="49"/>
+ <source>Show neutral carbon atoms</source>
+ <translation>Zobrazovat neutrální uhlíky</translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="51"/>
+ <source>Show neutral hydrogen atoms</source>
+ <translation>Zobrazovat neutrální vodíky</translation>
+ </message>
+ <message>
+ <location filename="../settings.cpp" line="53"/>
+ <source>Show atom charge</source>
+ <translation>Zobrazovat náboj atomů</translation>
+ </message>
+</context>
+</TS>
diff --git a/molsketch_helium/i18n/molsketch_nl.ts b/molsketch_helium/i18n/molsketch_nl.ts
new file mode 100644
index 0000000..35fae04
--- /dev/null
+++ b/molsketch_helium/i18n/molsketch_nl.ts
@@ -0,0 +1,713 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="mainwindow.cpp" line="250"/>
+ <source>Error while exporting file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="328"/>
+ <source>About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="370"/>
+ <source>&New</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="372"/>
+ <source>Create a new file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="375"/>
+ <source>&Open...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="376"/>
+ <source>Ctrl+O</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="377"/>
+ <source>Open an existing file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="380"/>
+ <source>&Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="381"/>
+ <source>Ctrl+S</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="382"/>
+ <source>Save the document to disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="385"/>
+ <source>Save &As...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="386"/>
+ <source>Save the document under a new name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="396"/>
+ <source>Export the current document as a picture</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="401"/>
+ <source>Print the current document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="404"/>
+ <source>E&xit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="405"/>
+ <source>Ctrl+Q</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="406"/>
+ <source>Exit the application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="420"/>
+ <source>Cu&t</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="421"/>
+ <source>Ctrl+X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="423"/>
+ <source>Cut the current selection's contents to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="426"/>
+ <source>&Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="427"/>
+ <source>Ctrl+C</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="429"/>
+ <source>Copy the current selection's contents to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="432"/>
+ <source>&Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="433"/>
+ <source>Ctrl+V</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="435"/>
+ <source>Paste the clipboard's contents into the current selection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="443"/>
+ <source>&Add Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="439"/>
+ <source>Ctrl+A</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="446"/>
+ <source>Go to the atom addition mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="449"/>
+ <source>&Delete Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="452"/>
+ <source>Go to the atom deletion mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="455"/>
+ <source>&Move mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="458"/>
+ <source>Go to the molecule move mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="471"/>
+ <source>Zoom &In</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="472"/>
+ <source>Ctrl++</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="473"/>
+ <source>Zoom in on the canvas</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="476"/>
+ <source>Zoom &Out</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="477"/>
+ <source>Ctrl+-</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="478"/>
+ <source>Zoom out on the canvas</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="481"/>
+ <source>Zoom &Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="482"/>
+ <source>Ctrl+=</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="483"/>
+ <source>Reset the zoom level</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="486"/>
+ <source>Zoom &Fit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="487"/>
+ <source>Ctrl+*</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="488"/>
+ <source>Fit to screen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="501"/>
+ <source>&About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="502"/>
+ <source>Show the application's About box</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="505"/>
+ <source>About &Qt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="506"/>
+ <source>Show the Qt library's About box</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="522"/>
+ <source>&File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="534"/>
+ <source>&Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="551"/>
+ <source>&View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="559"/>
+ <source>&Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="570"/>
+ <source>File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="579"/>
+ <source>Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="592"/>
+ <source>Zoom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="602"/>
+ <source>Ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="854"/>
+ <source>This document has been modified.
+Do you want to save your changes?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="226"/>
+ <source>Error while loading file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="206"/>
+ <source>Invalid name or unknown file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="870"/>
+ <source>untitled.mol</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="875"/>
+ <source>%1[*] - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="138"/>
+ <source>Open - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="194"/>
+ <source>Save as - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="214"/>
+ <source>Import - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="236"/>
+ <source>Export - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="272"/>
+ <source>Error while printing file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="329"/>
+ <source><H3>About molsKetch</H3> <P> molsKetch is an program for drawing molecular structures developed by Harm van Eersel at the <A href="http://www.tue.nl">Eindhoven University of Technology</A>.<P> For more info check <A href="http://molsketch.sourceforge.net">http://molsketch.sourceforge.net</A> <P> It is <A href="http://www.gnu.org/philosophy/free-sw.html">free software</A> and a [...]
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="347"/>
+ <source>Left Click: add atom, Drag: add bond, Click on bond: change order, Shift + Left Click on bond: change type, Right Click: remove item</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="354"/>
+ <source>Click on an item to delete it. Double click on an molecule to delete it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="361"/>
+ <source>Click on an item to select it. Drag to move selected items.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="371"/>
+ <source>Ctrl+N</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="389"/>
+ <source>&Import...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="390"/>
+ <source>Ctrl+I</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="391"/>
+ <source>Insert an existing molecule into the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="394"/>
+ <source>&Export...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="395"/>
+ <source>Ctrl+E</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="399"/>
+ <source>&Print...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="400"/>
+ <source>Ctrl+P</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="412"/>
+ <source>Ctrl+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="413"/>
+ <source>Undo the last action</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="417"/>
+ <source>Ctrl+Shift+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="418"/>
+ <source>Redo the last action</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="438"/>
+ <source>&Select all</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="440"/>
+ <source>Selects all elements on the scene</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="445"/>
+ <source>F5</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="451"/>
+ <source>F6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="457"/>
+ <source>F7</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="461"/>
+ <source>Align to grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="462"/>
+ <source>Align all elements on the scene to the grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="465"/>
+ <source>Edit Pre&ferences...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="466"/>
+ <source>Ctrl+F</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="467"/>
+ <source>Edit your preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="492"/>
+ <source>&Help Contents...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="493"/>
+ <source>F1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="494"/>
+ <source>Show the application's help contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="497"/>
+ <source>Submit &Bug...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="498"/>
+ <source>Open the browser with the bug tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="608"/>
+ <source>Toolbox</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="610"/>
+ <source>Infobox</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="618"/>
+ <source>Add...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="619"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="714"/>
+ <source>Recent Items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="715"/>
+ <source>Elements</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="716"/>
+ <source>Generic Molecules</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="717"/>
+ <source>Custom Molecules</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="745"/>
+ <source>Enter a name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="745"/>
+ <source>Enter a name for this item:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="753"/>
+ <source>Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="753"/>
+ <source>Do you really want to delete this item?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="965"/>
+ <source>Non selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Number of molecules: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Total weight: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Total charge: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Number of atoms: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Number of bonds: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="mainwindow.cpp" line="968"/>
+ <source>Number of items: </source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MolScene</name>
+ <message>
+ <location filename="molscene.cpp" line="110"/>
+ <source>aligning to grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="141"/>
+ <source>cutting items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="193"/>
+ <source>pasting items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="294"/>
+ <source>add molecule</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="771"/>
+ <source>moving item(s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="788"/>
+ <source>change of bondtype</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="790"/>
+ <source>change of bondorder</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="862"/>
+ <source>increasing charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="867"/>
+ <source>decreasing charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="880"/>
+ <source>changing element</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="908"/>
+ <source>adding atom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="931"/>
+ <source>removing atom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="943"/>
+ <source>removing bond</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="954"/>
+ <source>removing molecule</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="molscene.cpp" line="969"/>
+ <source>removing item(s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <location filename="settings.cpp" line="36"/>
+ <source>Atom settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="37"/>
+ <source>Bond settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="40"/>
+ <source>Bond length: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="41"/>
+ <source>Bond angle: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="47"/>
+ <source>Automatic add hydrogens</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="49"/>
+ <source>Show neutral carbon atoms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="51"/>
+ <source>Show neutral hydrogen atoms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="settings.cpp" line="53"/>
+ <source>Show atom charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/molsketch_helium/i18n/molsketch_pt_BR.ts b/molsketch_helium/i18n/molsketch_pt_BR.ts
new file mode 100644
index 0000000..dd51363
--- /dev/null
+++ b/molsketch_helium/i18n/molsketch_pt_BR.ts
@@ -0,0 +1,580 @@
+<!DOCTYPE TS><TS>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Open - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while loading file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save as - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invalid name or unknown file type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Import - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Export - molsKetch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while exporting file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while printing file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source><H3>About molsKetch</H3> <P> molsKetch is an program for drawing molecular structures developed by Harm van Eersel at the <A href="http://www.tue.nl">Eindhoven University of Technology</A>.<P> For more info check <A href="http://molsketch.sourceforge.net">http://molsketch.sourceforge.net</A> <P> It is <A href="http://www.gnu.org/philosophy/free-sw.html">free software</A> and a [...]
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left Click: add atom, Drag: add bond, Click on bond: change order, Shift + Left Click on bond: change type, Right Click: remove item</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click on an item to delete it. Double click on an molecule to delete it.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click on an item to select it. Drag to move selected items.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&New</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+N</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create a new file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Open...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+O</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open an existing file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save the document to disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save &As...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save the document under a new name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Import...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+I</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Insert an existing molecule into the document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Export...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+E</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Export the current document as a picture</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Print...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+P</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Print the current document</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E&xit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Exit the application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo the last action</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+Shift+Z</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Redo the last action</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cu&t</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+X</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cut the current selection's contents to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+C</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current selection's contents to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Paste</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+V</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Paste the clipboard's contents into the current selection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Select all</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+A</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Selects all elements on the scene</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Add Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>F5</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the atom addition mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Delete Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>F6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the atom deletion mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Move mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>F7</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the molecule move mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Align to grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Align all elements on the scene to the grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit Pre&ferences...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+F</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit your preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom &In</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl++</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom in on the canvas</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom &Out</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+-</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom out on the canvas</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom &Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+=</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset the zoom level</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom &Fit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+*</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fit to screen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Help Contents...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>F1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show the application's help contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Submit &Bug...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the browser with the bug tracker</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show the application's About box</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>About &Qt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show the Qt library's About box</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Zoom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Toolbox</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Infobox</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Recent Items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Elements</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Generic Molecules</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Molecules</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter a name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter a name for this item:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete this item?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This document has been modified.
+Do you want to save your changes?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>untitled.mol</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1[*] - %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Non selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Number of molecules: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Total weight: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Total charge: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Number of atoms: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Number of bonds: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Number of items: </source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MolScene</name>
+ <message>
+ <source>aligning to grid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>cutting items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>pasting items</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>add molecule</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>moving item(s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>change of bondtype</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>change of bondorder</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Molecule</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>increasing charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>decreasing charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>changing element</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>adding bond</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>adding atom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>removing atom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>removing bond</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>removing molecule</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>removing item(s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <source>Atom settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bond settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bond length: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bond angle: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Automatic add hydrogens</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show neutral carbon atoms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show neutral hydrogen atoms</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show atom charge</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/molsketch_helium/icon.rc b/molsketch_helium/icon.rc
new file mode 100644
index 0000000..a2fa772
--- /dev/null
+++ b/molsketch_helium/icon.rc
@@ -0,0 +1 @@
+ IDI_ICON1 ICON DISCARDABLE "molsketch.ico"
\ No newline at end of file
diff --git a/molsketch_helium/images/CVS/Entries b/molsketch_helium/images/CVS/Entries
new file mode 100644
index 0000000..b199e2a
--- /dev/null
+++ b/molsketch_helium/images/CVS/Entries
@@ -0,0 +1,36 @@
+/application-exit.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/configure.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/configure.svg/1.3/Fri Oct 3 23:13:21 2008//
+/document-export.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-import.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-new.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-open.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-open.svg/1.3/Fri Oct 3 23:13:21 2008//
+/document-print.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-save-as.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/document-save.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/draw-eraser.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/draw-freehand.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/draw-freehand.svg/1.3/Fri Oct 3 23:13:21 2008//
+/edit-copy.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/edit-cut.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/edit-paste.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/edit-redo.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/edit-select-all.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/edit-undo.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/help-about.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/help-contents.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/help-contextual.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/help.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/icon.svg/1.3/Fri Oct 3 23:13:21 2008//
+/molsketch.ico/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/molsketch.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/molsketch.svg/1.3/Fri Oct 3 23:13:21 2008//
+/molsketch.xpm/1.3/Fri Oct 3 23:13:21 2008//
+/transform-move.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/transform-rotate.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/zoom-fit-best.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/zoom-in.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/zoom-original.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+/zoom-out.png/1.3/Fri Oct 3 23:13:21 2008/-kb/
+D
diff --git a/molsketch_helium/images/CVS/Entries.Extra b/molsketch_helium/images/CVS/Entries.Extra
new file mode 100644
index 0000000..6ece5ca
--- /dev/null
+++ b/molsketch_helium/images/CVS/Entries.Extra
@@ -0,0 +1,35 @@
+/application-exit.png////*///
+/configure.png////*///
+/configure.svg////*///
+/document-export.png////*///
+/document-import.png////*///
+/document-new.png////*///
+/document-open.png////*///
+/document-open.svg////*///
+/document-print.png////*///
+/document-save-as.png////*///
+/document-save.png////*///
+/draw-eraser.png////*///
+/draw-freehand.png////*///
+/draw-freehand.svg////*///
+/edit-copy.png////*///
+/edit-cut.png////*///
+/edit-paste.png////*///
+/edit-redo.png////*///
+/edit-select-all.png////*///
+/edit-undo.png////*///
+/help-about.png////*///
+/help-contents.png////*///
+/help-contextual.png////*///
+/help.png////*///
+/icon.svg////*///
+/molsketch.ico////*///
+/molsketch.png////*///
+/molsketch.svg////*///
+/molsketch.xpm////*///
+/transform-move.png////*///
+/transform-rotate.png////*///
+/zoom-fit-best.png////*///
+/zoom-in.png////*///
+/zoom-original.png////*///
+/zoom-out.png////*///
diff --git a/molsketch_helium/images/CVS/Entries.Extra.Old b/molsketch_helium/images/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/images/CVS/Entries.Old b/molsketch_helium/images/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/images/CVS/Repository b/molsketch_helium/images/CVS/Repository
new file mode 100644
index 0000000..e06d103
--- /dev/null
+++ b/molsketch_helium/images/CVS/Repository
@@ -0,0 +1 @@
+zodiac/molsketch_helium/images
diff --git a/molsketch_helium/images/CVS/Root b/molsketch_helium/images/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/molsketch_helium/images/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/molsketch_helium/images/application-exit.png b/molsketch_helium/images/application-exit.png
new file mode 100644
index 0000000..ed5f8b2
Binary files /dev/null and b/molsketch_helium/images/application-exit.png differ
diff --git a/molsketch_helium/images/configure.png b/molsketch_helium/images/configure.png
new file mode 100644
index 0000000..c3fee6e
Binary files /dev/null and b/molsketch_helium/images/configure.png differ
diff --git a/molsketch_helium/images/configure.svg b/molsketch_helium/images/configure.svg
new file mode 100644
index 0000000..7626be6
--- /dev/null
+++ b/molsketch_helium/images/configure.svg
@@ -0,0 +1,665 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<svg
+ xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ id="Livello_1"
+ width="128"
+ height="128.00018"
+ viewBox="0 0 119.999 120.061"
+ overflow="visible"
+ enable-background="new 0 0 119.999 120.061"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="configure.svg"
+ sodipodi:docbase="/home/david/Progetti/sandbox"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/Users/david/Desktop/configure.png"
+ inkscape:export-xdpi="11.249984"
+ inkscape:export-ydpi="11.249984"
+ sodipodi:modified="true"><defs
+ id="defs127"><linearGradient
+ id="linearGradient3291"><stop
+ style="stop-color:black;stop-opacity:1"
+ offset="0"
+ id="stop3293" /><stop
+ style="stop-color:black;stop-opacity:0"
+ offset="1"
+ id="stop3295" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3291"
+ id="radialGradient3336"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ cx="63.912209"
+ cy="115.70919"
+ fx="33.953373"
+ fy="115.70919"
+ r="63.912209" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_11_"
+ id="linearGradient9291"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1250507,0.1245433,0.1244801,1.1244802,-2.8257128,-11.708873)"
+ x1="41.188999"
+ y1="80.101601"
+ x2="27.6451"
+ y2="66.557701" /><linearGradient
+ id="linearGradient6141"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop6143" /><stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop6145" /></linearGradient><linearGradient
+ gradientTransform="translate(-3.0255781e-2,3.056501e-4)"
+ id="linearGradient5166"
+ gradientUnits="userSpaceOnUse"
+ x1="77.542931"
+ y1="41.868668"
+ x2="88.108376"
+ y2="31.303225">
+ <stop
+ offset="0"
+ style="stop-color:#323232;stop-opacity:1;"
+ id="stop5168" />
+
+
+
+
+
+
+ <stop
+ offset="0.75739998"
+ style="stop-color:#ffffff;stop-opacity:0;"
+ id="stop5170" />
+ </linearGradient>
+ <linearGradient
+ y2="31.303225"
+ x2="88.108376"
+ y1="41.868668"
+ x1="77.542931"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_16_"
+ gradientTransform="translate(-3.0255781e-2,3.056501e-4)">
+ <stop
+ id="stop92"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0" />
+
+
+
+
+
+
+ <stop
+ id="stop106"
+ style="stop-color:#ffffff;stop-opacity:0.01898734;"
+ offset="0.75739998" />
+ </linearGradient>
+
+<linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_18_"
+ id="linearGradient3295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-18.749172,36.539651)"
+ x1="-6.165"
+ y1="112.5049"
+ x2="11.0181"
+ y2="112.5049" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient3298"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0002442,-2.5378062e-4,-2.5378062e-4,1.0002442,8.6347844,-24.632129)"
+ x1="38.757801"
+ y1="7.4277"
+ x2="63.923302"
+ y2="7.4277" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_16_"
+ id="linearGradient3301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-24.896055,39.032512)"
+ x1="76.281174"
+ y1="43.060352"
+ x2="86.611"
+ y2="31.303225" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_15_"
+ id="linearGradient3304"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-24.895791,39.125846)"
+ x1="76.919403"
+ y1="43.1436"
+ x2="100.6411"
+ y2="19.4214" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_14_"
+ id="linearGradient3307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-18.749172,36.539651)"
+ x1="67.880402"
+ y1="6.4331002"
+ x2="105.3924"
+ y2="43.945599" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_13_"
+ id="linearGradient3310"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.7074656,0.7074656,-0.7071068,-0.7071068,101.2385,185.78751)"
+ x1="-0.47799999"
+ y1="105.0586"
+ x2="6.3157001"
+ y2="111.8523" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_12_"
+ id="linearGradient3313"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.7074656,0.7074656,-0.7071068,-0.7071068,107.38512,183.20132)"
+ x1="1.3501"
+ y1="103.2324"
+ x2="8.1437998"
+ y2="110.0261" />
+
+
+
+ <linearGradient
+ id="XMLID_10_"
+ gradientUnits="userSpaceOnUse"
+ x1="61.9692"
+ y1="88.430702"
+ x2="40.815899"
+ y2="88.430702"
+ gradientTransform="matrix(0.7074589,0.7071,-0.7074589,0.7071,68.76314,-21.373694)">
+ <stop
+ offset="0.0533"
+ style="stop-color:#555555"
+ id="stop10" />
+ <stop
+ offset="0.21113414"
+ style="stop-color:#BBBBBB"
+ id="stop12" />
+ <stop
+ offset="0.36265489"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop14" />
+ <stop
+ offset="0.60322773"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop16" />
+ <stop
+ offset="0.84976584"
+ style="stop-color:#e9e9e9;stop-opacity:1;"
+ id="stop18" />
+ <stop
+ offset="1"
+ style="stop-color:#555555"
+ id="stop20" />
+ </linearGradient>
+
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_10_"
+ id="linearGradient10168"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5628683,-3.9649986e-4,-3.9652886e-4,1.562754,-20.23462,-103.35726)"
+ x1="61.9692"
+ y1="88.430702"
+ x2="40.815899"
+ y2="88.430702" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_10_"
+ id="linearGradient10170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0663866,2.7056218e-4,-2.7056218e-4,-1.0663866,9.2387294,154.26114)"
+ x1="61.9692"
+ y1="88.430702"
+ x2="40.815899"
+ y2="88.430702" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10203"
+ x1="56.03125"
+ y1="121.5"
+ x2="72.031251"
+ y2="121.5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10205"
+ x1="56.03125"
+ y1="110.5"
+ x2="72.031251"
+ y2="110.5"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_10_"
+ id="linearGradient10219"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0663866,2.7056218e-4,-2.7056218e-4,-1.0663866,9.2387294,154.26114)"
+ x1="61.9692"
+ y1="88.430702"
+ x2="40.815899"
+ y2="88.430702" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10221"
+ gradientUnits="userSpaceOnUse"
+ x1="56.03125"
+ y1="110.5"
+ x2="72.031251"
+ y2="110.5" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_14_"
+ id="linearGradient10223"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-18.749172,36.539651)"
+ x1="67.880402"
+ y1="6.4331002"
+ x2="105.3924"
+ y2="43.945599" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_15_"
+ id="linearGradient10225"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-24.895791,39.125846)"
+ x1="76.919403"
+ y1="43.1436"
+ x2="100.6411"
+ y2="19.4214" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_16_"
+ id="linearGradient10227"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-24.895791,39.125846)"
+ x1="76.281174"
+ y1="43.060352"
+ x2="86.611"
+ y2="31.303225" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10229"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0002442,-2.5378062e-4,-2.5378062e-4,1.0002442,8.6347844,-24.632129)"
+ x1="38.757801"
+ y1="7.4277"
+ x2="63.923302"
+ y2="7.4277" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10231"
+ gradientUnits="userSpaceOnUse"
+ x1="56.03125"
+ y1="121.5"
+ x2="72.031251"
+ y2="121.5" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_18_"
+ id="linearGradient10233"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074656,-0.7074656,0.7071068,0.7071068,-18.749172,36.539651)"
+ x1="-6.165"
+ y1="112.5049"
+ x2="11.0181"
+ y2="112.5049" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_18_"
+ id="linearGradient10236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0005075,0,0,1.0000001,6.1427973,2.5178157)"
+ x1="-6.165"
+ y1="112.5049"
+ x2="11.0181"
+ y2="112.5049" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10239"
+ gradientUnits="userSpaceOnUse"
+ x1="56.03125"
+ y1="121.5"
+ x2="72.031251"
+ y2="121.5"
+ gradientTransform="matrix(0.6632486,0.6632486,-0.6632486,0.6632486,45.21604,-10.083813)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074589,0.7071,-0.7074589,0.7071,68.761161,-21.373784)"
+ x1="38.757801"
+ y1="7.4277"
+ x2="63.923302"
+ y2="7.4277" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_16_"
+ id="linearGradient10245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0005075,0,0,1.0000001,-3.223487e-2,2.1565487e-4)"
+ x1="76.281174"
+ y1="43.060352"
+ x2="86.611"
+ y2="31.303225" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_15_"
+ id="linearGradient10248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0005075,0,0,1.0000001,-3.223487e-2,2.1565487e-4)"
+ x1="76.919403"
+ y1="43.1436"
+ x2="100.6411"
+ y2="19.4214" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_14_"
+ id="linearGradient10251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0005075,0,0,1.0000001,6.1427973,2.5178157)"
+ x1="67.880402"
+ y1="6.4331002"
+ x2="105.3924"
+ y2="43.945599" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10254"
+ gradientUnits="userSpaceOnUse"
+ x1="56.03125"
+ y1="110.5"
+ x2="72.031251"
+ y2="110.5"
+ gradientTransform="matrix(0.6632486,0.6632486,-0.6632486,0.6632486,45.21604,-10.083813)" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_10_"
+ id="linearGradient10257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7071,0.7074589,0.7071,-0.7074589,-50.969871,98.357246)"
+ x1="61.9692"
+ y1="88.430702"
+ x2="40.815899"
+ y2="88.430702" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_17_"
+ id="linearGradient10260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7074589,0.7071,-0.7074589,0.7071,68.761161,-21.373784)"
+ x1="51.339096"
+ y1="30.159527"
+ x2="51.326984"
+ y2="-17.582758" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6141"
+ id="linearGradient6147"
+ x1="7.2493796"
+ y1="120.2508"
+ x2="57.625931"
+ y2="69.874252"
+ gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
+ inkscape:window-height="694"
+ inkscape:window-width="898"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ width="128px"
+ height="128.00018px"
+ inkscape:zoom="2"
+ inkscape:cx="29.234459"
+ inkscape:cy="46.128311"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="Livello_1" />
+<metadata
+ id="metadata3">
+ <ns:sfw>
+ <ns:slices />
+ <ns:sliceSourceBounds
+ y="3.97"
+ x="4"
+ height="120.061"
+ width="119.999"
+ bottomLeftOrigin="true" />
+ </ns:sfw>
+<rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata>
+
+<linearGradient
+ id="XMLID_11_"
+ gradientUnits="userSpaceOnUse"
+ x1="41.188999"
+ y1="80.101601"
+ x2="27.6451"
+ y2="66.557701"
+ gradientTransform="translate(8.7075442,3.5814057)">
+ <stop
+ offset="0.40830001"
+ style="stop-color:#f0f0f0;stop-opacity:1;"
+ id="stop25" />
+ <stop
+ offset="0.50628459"
+ style="stop-color:#C3C3C3"
+ id="stop27" />
+ <stop
+ offset="0.56008232"
+ style="stop-color:#8b8b8b;stop-opacity:1;"
+ id="stop29" /><stop
+ id="stop12212"
+ style="stop-color:#393939;stop-opacity:1;"
+ offset="0.67944592" />
+
+</linearGradient>
+
+<linearGradient
+ id="XMLID_12_"
+ gradientUnits="userSpaceOnUse"
+ x1="1.3501"
+ y1="103.2324"
+ x2="8.1437998"
+ y2="110.0261"
+ gradientTransform="matrix(-1,0,0,-1,18.150444,221.94371)">
+ <stop
+ offset="0"
+ style="stop-color:#EEEEEE"
+ id="stop36" />
+ <stop
+ offset="1"
+ style="stop-color:#BBBBBB"
+ id="stop38" />
+</linearGradient>
+
+<linearGradient
+ id="XMLID_13_"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.47799999"
+ y1="105.0586"
+ x2="6.3157001"
+ y2="111.8523"
+ gradientTransform="matrix(-1,0,0,-1,11.978544,219.42611)">
+ <stop
+ offset="0"
+ style="stop-color:#BBBBBB"
+ id="stop43" />
+ <stop
+ offset="1"
+ style="stop-color:#555555"
+ id="stop45" />
+</linearGradient>
+
+<linearGradient
+ id="XMLID_14_"
+ gradientUnits="userSpaceOnUse"
+ x1="67.880402"
+ y1="6.4331002"
+ x2="105.3924"
+ y2="43.945599"
+ gradientTransform="translate(6.1416442,2.5179057)">
+ <stop
+ offset="0.0947"
+ style="stop-color:#666666;stop-opacity:1;"
+ id="stop50" /><stop
+ id="stop3330"
+ style="stop-color:#b7b7b7;stop-opacity:1;"
+ offset="0.40963161" />
+
+
+ <stop
+ offset="0.50530702"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop56" /><stop
+ id="stop3328"
+ style="stop-color:#a3a3a3;stop-opacity:1;"
+ offset="0.63043118" />
+
+
+ <stop
+ offset="0.93489999"
+ style="stop-color:#646464;stop-opacity:1;"
+ id="stop62" />
+</linearGradient>
+
+<linearGradient
+ id="XMLID_15_"
+ gradientUnits="userSpaceOnUse"
+ x1="76.919403"
+ y1="43.1436"
+ x2="100.6411"
+ y2="19.4214"
+ gradientTransform="translate(-3.0255781e-2,3.056501e-4)">
+ <stop
+ offset="0"
+ style="stop-color:#aeaeae;stop-opacity:1;"
+ id="stop67" />
+ <stop
+ offset="0.0602"
+ style="stop-color:#b2b2b2;stop-opacity:1;"
+ id="stop69" />
+ <stop
+ offset="0.18103883"
+ style="stop-color:#d9d9d9;stop-opacity:1;"
+ id="stop71" />
+ <stop
+ offset="0.3195"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop73" />
+ <stop
+ offset="0.43529999"
+ style="stop-color:#f4f4f4;stop-opacity:1;"
+ id="stop75" />
+ <stop
+ offset="0.6028"
+ style="stop-color:#D4D4D4"
+ id="stop77" />
+ <stop
+ offset="0.7633"
+ style="stop-color:#BBBBBB"
+ id="stop79" />
+ <stop
+ offset="0.80790001"
+ style="stop-color:#b9bcc1;stop-opacity:1;"
+ id="stop81" />
+ <stop
+ offset="0.92970002"
+ style="stop-color:#bdc0c3;stop-opacity:1;"
+ id="stop83" />
+ <stop
+ offset="1"
+ style="stop-color:#b5b9bb;stop-opacity:1;"
+ id="stop85" />
+</linearGradient>
+
+
+<linearGradient
+ id="XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ x1="38.757801"
+ y1="7.4277"
+ x2="63.923302"
+ y2="7.4277"
+ gradientTransform="matrix(0.7071,0.7071,-0.7071,0.7071,68.728244,-21.373694)">
+ <stop
+ offset="0"
+ style="stop-color:#3a3a3a;stop-opacity:1;"
+ id="stop111" />
+ <stop
+ offset="0.60194176"
+ style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop113" />
+ <stop
+ offset="1"
+ style="stop-color:#888888"
+ id="stop115" />
+</linearGradient>
+
+<linearGradient
+ id="XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ x1="-6.165"
+ y1="112.5049"
+ x2="11.0181"
+ y2="112.5049"
+ gradientTransform="translate(6.1416442,2.5179057)">
+ <stop
+ offset="0"
+ style="stop-color:#BBBBBB"
+ id="stop120" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop122" />
+</linearGradient>
+<path
+ sodipodi:type="arc"
+ style="opacity:0.38139535;fill:url(#radialGradient3336);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="path1563"
+ sodipodi:cx="63.912209"
+ sodipodi:cy="115.70919"
+ sodipodi:rx="63.912209"
+ sodipodi:ry="12.641975"
+ d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z"
+ transform="matrix(0.939264,0,0,0.3849253,-3.0936658e-2,70.655389)" /><path
+ style="fill:url(#linearGradient10257)"
+ d="M 76.409451,31.804481 C 75.443086,30.924606 74.357677,30.748097 72.740857,32.364097 L 2.6023174,103.87059 C 2.5703077,103.90258 2.569153,103.93922 2.5401379,103.97422 C -0.95363288,107.73022 -0.88972357,113.60492 2.7681296,117.25992 C 6.4259848,120.91592 12.29792,120.98291 16.053828,117.48791 C 16.088848,117.45991 16.126446,117.45673 16.157461,117.42573 L 87.72613,47.307917 C 90.960771,44.076918 86.953486,42.972159 84.679332,40.696158 L 79.373343,35.390169 C 78.234266,34.251669 77. [...]
+ id="path10166" /><path
+ style="fill:url(#linearGradient10254)"
+ d="M 17.380325,102.68918 C 14.447618,99.759506 9.6992784,99.759734 6.7683477,102.68918 C 6.5428061,102.91472 6.3373933,103.14849 6.1465522,103.39388 C 9.0905761,101.11028 13.348454,101.3131 16.053828,104.01567 C 18.759425,106.72134 18.965866,110.98021 16.675624,113.92295 C 16.920967,113.73233 17.15491,113.52645 17.380325,113.30115 C 20.312833,110.3717 20.31148,105.6204 17.380325,102.68918 z "
+ id="path10186" /><path
+ d="M 118.731,16.620217 L 103.19512,32.150217 C 99.80841,35.534217 93.549236,33.235217 90.160517,29.850217 C 86.776801,26.465216 84.475632,20.211217 87.86035,16.825217 L 103.40023,1.2962158 C 92.523716,-2.8617843 79.067889,3.9452161 74.82974,8.1812158 C 63.636062,19.367217 62.837657,34.722217 74.065352,45.942217 C 85.286043,57.160217 100.64883,56.490217 111.84151,45.303218 C 116.07966,41.066217 122.89111,27.489217 118.731,16.620217 z "
+ id="path64"
+ style="fill:url(#linearGradient10251)" /><path
+ d="M 77.659175,11.009216 C 72.74068,15.925216 70.031306,21.867217 70.031306,27.741217 L 70.030305,27.742217 C 70.031306,33.311217 72.404509,38.626217 76.894787,43.113217 C 81.422083,47.639217 86.7778,50.031218 92.381644,50.031217 L 92.381644,50.031217 C 98.22961,50.031218 104.1346,47.348218 109.01107,42.474217 C 111.8225,39.664217 115.5714,32.245217 115.93458,25.071217 C 111.35626,29.647217 106.02356,34.977217 106.02356,34.977217 C 100.96199,40.037217 92.379643,37.724217 87.331082,32. [...]
+ id="path87"
+ style="fill:url(#linearGradient10248);fill-opacity:1.0" /><path
+ d="M 85.387095,16.818216 C 81.792271,20.411216 84.661727,27.477217 88.592721,31.406217 C 92.527718,35.337217 99.594302,38.205217 103.19012,34.613217 C 103.19012,34.613217 118.96412,17.234216 118.73,16.620217 L 103.19412,32.150217 C 99.80741,35.534218 93.548235,33.235217 90.159515,29.850217 C 86.775799,26.465216 84.474633,20.211217 87.85935,16.825217 L 103.39923,1.2962158 L 85.387095,16.818216 z "
+ id="path117"
+ style="fill:url(#linearGradient10260)"
+ sodipodi:nodetypes="csccccccc" /><path
+ style="fill:url(#linearGradient10239)"
+ d="M 4.820055,104.72037 C 4.5726725,104.91226 4.3425471,105.11509 4.1153533,105.34217 C 1.1844093,108.27319 1.1826385,113.02448 4.1153533,115.95415 C 7.0480662,118.88381 11.79796,118.88203 14.727331,115.95415 C 14.952993,115.72872 15.158195,115.49477 15.349126,115.24945 C 12.406133,117.53606 8.148893,117.33187 5.4418505,114.62765 C 2.734806,111.92343 2.5308464,107.66392 4.820055,104.72037 z "
+ id="path10190" /><path
+ d="M 2.7691837,116.26123 C 1.0242958,114.51723 0.10383016,112.26923 -0.011225313,109.98622 C -0.15229878,112.60123 0.76716563,115.26323 2.7691816,117.26123 C 6.4270358,120.91723 12.302016,120.99023 16.057925,117.49522 C 16.092943,117.46722 16.134962,117.44623 16.165977,117.41523 L 17.166488,116.41622 C 13.410582,119.90922 6.427038,119.91723 2.7691837,116.26123 z "
+ id="path124"
+ style="fill:url(#linearGradient10236)" />
+<path
+ style="fill:url(#linearGradient6147);fill-opacity:1.0;fill-rule:nonzero;opacity:0.5"
+ d="M 43.21875 69.5625 L 2.8125 110.75 C 2.7783735 110.78411 2.7809338 110.80644 2.75 110.84375 C -0.97480066 114.84812 -0.93098327 121.10331 2.96875 125 C 6.8684854 128.89776 13.151978 128.97611 17.15625 125.25 C 17.193586 125.22015 17.216934 125.22055 17.25 125.1875 L 57.3125 85.9375 C 53.66929 79.550692 48.861858 73.979783 43.21875 69.5625 z M 11.5 108.5625 C 13.547005 108.56247 15.592932 109.34455 17.15625 110.90625 C 20.281231 114.0313 20.282673 119.09558 17.15625 122.21875 C 14.0 [...]
+ id="path2236"
+ transform="matrix(0.9379752,0,0,0.9379752,-3.0914126e-2,0)" /><path
+ d="M 15.537923,96.062539 C 14.713663,96.978699 14.388162,98.22441 14.530816,99.52305 C 14.682682,100.89492 15.361817,102.33182 16.533505,103.50003 C 18.808146,105.77775 22.084895,106.19602 23.991153,104.45332 C 24.002148,104.47231 67.492075,61.01118 77.726913,50.782827 C 77.294045,50.416137 69.737251,42.875414 69.288707,42.347047 C 66.356033,45.277862 15.537923,96.062539 15.537923,96.062539 z "
+ id="path33"
+ style="fill:url(#linearGradient9291);opacity:0.5" /><path
+ style="fill:url(#linearGradient3301)"
+ id="path108"
+ d="M 94.304331,48.937972 C 88.699488,48.937972 83.344772,46.545972 78.817475,42.019972 C 74.327198,37.532972 71.953994,32.217972 71.952993,26.648972 L 71.953994,26.647972 C 71.953994,20.773972 74.663368,14.831973 79.581863,9.9159745 C 80.407282,9.0909731 81.84201,8.0489732 83.661933,7.0219732 C 80.923544,8.3389732 78.759446,9.8199731 77.661889,10.915974 C 72.743394,15.831973 70.034021,21.773972 70.034021,27.647972 L 70.033021,27.648972 C 70.034021,33.217972 72.407224,38.532972 76.8975 [...]
\ No newline at end of file
diff --git a/molsketch_helium/images/document-export.png b/molsketch_helium/images/document-export.png
new file mode 100644
index 0000000..9f740e3
Binary files /dev/null and b/molsketch_helium/images/document-export.png differ
diff --git a/molsketch_helium/images/document-import.png b/molsketch_helium/images/document-import.png
new file mode 100644
index 0000000..fb21f2a
Binary files /dev/null and b/molsketch_helium/images/document-import.png differ
diff --git a/molsketch_helium/images/document-new.png b/molsketch_helium/images/document-new.png
new file mode 100644
index 0000000..fbb4ce0
Binary files /dev/null and b/molsketch_helium/images/document-new.png differ
diff --git a/molsketch_helium/images/document-open.png b/molsketch_helium/images/document-open.png
new file mode 100644
index 0000000..bc8cfac
Binary files /dev/null and b/molsketch_helium/images/document-open.png differ
diff --git a/molsketch_helium/images/document-open.svg b/molsketch_helium/images/document-open.svg
new file mode 100644
index 0000000..6f9de6e
--- /dev/null
+++ b/molsketch_helium/images/document-open.svg
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="128"
+ height="128"
+ id="svg2811"
+ sodipodi:version="0.32"
+ inkscape:version="0.45.1"
+ sodipodi:docname="document-open.svgz"
+ sodipodi:docbase="/home/david"
+ inkscape:output_extension="org.inkscape.output.svgz.inkscape"
+ inkscape:export-filename="/home/david/document-open.png"
+ inkscape:export-xdpi="22.5"
+ inkscape:export-ydpi="22.5">
+ <metadata
+ id="metadata40">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="736"
+ inkscape:window-width="748"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10000"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ gridspacingx="4px"
+ gridspacingy="4px"
+ gridempspacing="2"
+ showborder="false"
+ inkscape:grid-bbox="true"
+ inkscape:zoom="1"
+ inkscape:cx="64"
+ inkscape:cy="64"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="svg2811"
+ inkscape:grid-points="true" />
+ <defs
+ id="defs2813">
+ <linearGradient
+ x1="122.74438"
+ y1="96.721588"
+ x2="122.39215"
+ y2="20.043535"
+ id="linearGradient2937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0033808,0,0,1,-8.2378002,8)">
+ <stop
+ id="stop2939"
+ style="stop-color:#72b4f4;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2941"
+ style="stop-color:#b3d9ff;stop-opacity:1"
+ offset="0.13053299" />
+ <stop
+ id="stop2943"
+ style="stop-color:#b3d9ff;stop-opacity:1"
+ offset="0.34621301" />
+ <stop
+ id="stop2945"
+ style="stop-color:#71a8f5;stop-opacity:1"
+ offset="0.72006166" />
+ <stop
+ id="stop2947"
+ style="stop-color:#508ed9;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="-178"
+ y1="-228.3945"
+ x2="-178"
+ y2="-304.61469"
+ id="linearGradient2927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(242.00093,332.5)">
+ <stop
+ id="stop2929"
+ style="stop-color:#cfe7ff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2931"
+ style="stop-color:#71a8f5;stop-opacity:1"
+ offset="0.1" />
+ <stop
+ id="stop2933"
+ style="stop-color:#2c72c7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2822">
+ <stop
+ id="stop2824"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2826"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="71.999496"
+ y1="14.2578"
+ x2="71.999496"
+ y2="19.9583"
+ id="XMLID_9_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0033404,0,0,1,-8.2374684,8)">
+ <stop
+ id="stop46"
+ style="stop-color:#71a8f5;stop-opacity:0"
+ offset="0.25" />
+ <stop
+ id="stop48"
+ style="stop-color:#0057ae;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <filter
+ id="filter2807"
+ height="1.768"
+ y="-0.384"
+ width="1.0512"
+ x="-0.025599999">
+ <feGaussianBlur
+ id="feGaussianBlur2809"
+ stdDeviation="1.28"
+ inkscape:collect="always" />
+ </filter>
+ <linearGradient
+ x1="72.000504"
+ y1="96"
+ x2="72.000504"
+ y2="0.00048828119"
+ id="XMLID_6_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6.999995,8)">
+ <stop
+ id="stop7"
+ style="stop-color:#00479e;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop9"
+ style="stop-color:#2c72c7;stop-opacity:1"
+ offset="0.0769" />
+ <stop
+ id="stop11"
+ style="stop-color:#6ea1df;stop-opacity:1"
+ offset="0.58579999" />
+ <stop
+ id="stop13"
+ style="stop-color:#adcbee;stop-opacity:1"
+ offset="0.96450001" />
+ </linearGradient>
+ <linearGradient
+ x1="122.74438"
+ y1="96"
+ x2="122.74438"
+ y2="20"
+ id="linearGradient3109"
+ xlink:href="#linearGradient2937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0033808,0,0,1,-8.2378,8)" />
+ <linearGradient
+ x1="-168.99216"
+ y1="-300.5"
+ x2="-168.99216"
+ y2="-296.48441"
+ id="linearGradient2923"
+ xlink:href="#linearGradient2822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(242.00093,332.5)" />
+ <linearGradient
+ x1="-178"
+ y1="-228.5"
+ x2="-178"
+ y2="-304.61469"
+ id="linearGradient2925"
+ xlink:href="#linearGradient2927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(242.00093,332.5)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2822"
+ id="linearGradient2197"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(242.00093,364.5)"
+ x1="-168.99216"
+ y1="-300.5"
+ x2="-168.99216"
+ y2="-296.48441" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2927"
+ id="linearGradient2201"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7368421,242.00093,284.36842)"
+ x1="-178"
+ y1="-228.5"
+ x2="-178"
+ y2="-304.61469" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_9_"
+ id="linearGradient2204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0033404,0,0,1,-7.2374684,40)"
+ x1="71.999496"
+ y1="14.2578"
+ x2="71.999496"
+ y2="19.9583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient2207"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0033808,0,0,0.7368421,-8.2378,45.263158)"
+ x1="122.74438"
+ y1="96"
+ x2="122.74438"
+ y2="20" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#XMLID_6_"
+ id="linearGradient2212"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6.999995,20)"
+ x1="72.000504"
+ y1="96"
+ x2="72.000504"
+ y2="0.00048828119" />
+ <filter
+ id="filter2770"
+ inkscape:collect="always">
+ <feGaussianBlur
+ id="feGaussianBlur2772"
+ stdDeviation="2.0786429"
+ inkscape:collect="always" />
+ </filter>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="99.254974"
+ x2="91.228737"
+ y1="106.41443"
+ x1="98.617439"
+ id="linearGradient10213"
+ xlink:href="#linearGradient10207"
+ inkscape:collect="always" />
+ <radialGradient
+ r="139.55859"
+ cy="112.3047"
+ cx="102"
+ gradientTransform="matrix(1.295034,1.3831431e-7,-1.3627884e-7,1.2946006,-30.093452,-33.119615)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient9437"
+ xlink:href="#XMLID_8_"
+ inkscape:collect="always"
+ fx="102"
+ fy="112.3047" />
+ <clipPath
+ id="clipPath7084"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path7086"
+ d="M 72,88 L 40,120 L 32,120 L 32,80 L 72,80 L 72,88 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </clipPath>
+ <filter
+ id="filter6697"
+ height="1.3839999"
+ y="-0.19199999"
+ width="1.3839999"
+ x="-0.19200002"
+ inkscape:collect="always">
+ <feGaussianBlur
+ id="feGaussianBlur6699"
+ stdDeviation="1.9447689"
+ inkscape:collect="always" />
+ </filter>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ r="139.55859"
+ cy="112.3047"
+ cx="102"
+ id="XMLID_8_">
+ <stop
+ id="stop41"
+ style="stop-color:#b7b8b9;stop-opacity:1;"
+ offset="0" />
+ <stop
+ id="stop47"
+ style="stop-color:#ECECEC"
+ offset="0.18851049" />
+ <stop
+ id="stop49"
+ style="stop-color:#FAFAFA"
+ offset="0.25718147" />
+ <stop
+ id="stop51"
+ style="stop-color:#FFFFFF"
+ offset="0.30111277" />
+ <stop
+ id="stop53"
+ style="stop-color:#FAFAFA"
+ offset="0.5313" />
+ <stop
+ id="stop55"
+ style="stop-color:#EBECEC"
+ offset="0.8449" />
+ <stop
+ id="stop57"
+ style="stop-color:#E1E2E3"
+ offset="1" />
+ </radialGradient>
+ <linearGradient
+ y2="96.000198"
+ x2="88.000198"
+ y1="104"
+ x1="96"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_12_">
+ <stop
+ id="stop83"
+ style="stop-color:#888A85"
+ offset="0" />
+ <stop
+ id="stop85"
+ style="stop-color:#8C8E89"
+ offset="0.0072" />
+ <stop
+ id="stop87"
+ style="stop-color:#ABACA9"
+ offset="0.0673" />
+ <stop
+ id="stop89"
+ style="stop-color:#C5C6C4"
+ offset="0.1347" />
+ <stop
+ id="stop91"
+ style="stop-color:#DBDBDA"
+ offset="0.2652576" />
+ <stop
+ id="stop93"
+ style="stop-color:#EBEBEB"
+ offset="0.37646064" />
+ <stop
+ id="stop95"
+ style="stop-color:#F7F7F6"
+ offset="0.48740286" />
+ <stop
+ id="stop97"
+ style="stop-color:#FDFDFD"
+ offset="0.6324091" />
+ <stop
+ id="stop99"
+ style="stop-color:#FFFFFF"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10207">
+ <stop
+ id="stop10209"
+ offset="0"
+ style="stop-color:#a2a2a2;stop-opacity:1;" />
+ <stop
+ id="stop10211"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2822"
+ id="linearGradient3385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0172054,0,0,1.5,246.03226,514.75)"
+ x1="-168.99216"
+ y1="-300.5"
+ x2="-168.99216"
+ y2="-296.48441" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2927"
+ id="linearGradient3387"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7368421,242.00093,284.36842)"
+ x1="-178"
+ y1="-232.84966"
+ x2="-178"
+ y2="-304.61469" />
+ </defs>
+ <path
+ style="fill:url(#linearGradient2212)"
+ id="path15"
+ d="M 118.983,31 C 118.992,29.35 117.64999,28 115.99999,28 L 40.961007,28 C 40.961007,28 32.061006,20 30.961,20 L 14.999998,20 C 12.799996,20 10.999999,21.8 10.999999,24 L 10.999999,31 C 10.999999,31 11.999999,116 8,116 L 122,116 C 117.99999,116 118.983,31 118.983,31 z " />
+ <g
+ style="opacity:0.6;filter:url(#filter2807)"
+ id="g17"
+ transform="matrix(1.0033404,0,0,1,-8.2374684,20)">
+ <path
+ id="path19"
+ d="M 132,96 C 132,98.2 128.4,100 124,100 L 20,100 C 15.6,100 12,98.2 12,96 C 12,93.8 15.6,92 20,92 L 124,92 C 128.4,92 132,93.8 132,96 z " />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#linearGradient2204)"
+ id="path50"
+ d="M 10.884862,54 C 10.893892,55.75 10.902922,57.755 10.910952,60 L 119.09511,60 C 119.10414,57.755 119.11317,55.75 119.1212,54 L 10.884862,54 z " />
+ <path
+ style="fill:#5e95e3;fill-opacity:1"
+ id="path2896"
+ d="M 119.99722,31 C 120.00622,29.35 118.66422,28 117.01422,28 L 42.975222,28 L 36.389222,21.414 C 35.611222,20.636 34.075222,20 32.975222,20 L 12.014222,20 C 9.8142222,20 8.0142222,21.8 8.0142222,24 C 8.0142222,24 7.9822222,54.499299 8.0142222,60.031299 L 12.014222,60.031299 C 12.014222,53.222299 12.014222,24 12.014222,24 L 32.901222,23.997 C 33.083222,24.019 33.470222,24.179 33.560222,24.243 L 41.318222,32 C 41.318222,32 114.02722,32 115.99922,32 C 115.99922,32.435 116.00022,56.400 [...]
+ sodipodi:nodetypes="ccccccccccccccccc" />
+ <g
+ id="layer1"
+ inkscape:label="Livello 1"
+ transform="matrix(0.8308491,-8.682967e-8,8.7461072e-8,0.824851,10.82565,1.1777911)">
+ <path
+ transform="matrix(1.0575713,0,0,1.0540507,-3.6845595,-1.7469078)"
+ sodipodi:nodetypes="csccscccc"
+ id="path7865"
+ d="M 16,8 L 16,120 C 16,120 79.15625,120 79.15625,120 L 79.1875,120 C 79.187503,120 91.09375,110.09375 96.59375,104.59375 C 102.09375,99.09375 112,87.1875 112,87.1875 L 112,87.15625 L 112,8 L 16,8 z "
+ style="opacity:0.5;fill:#000000;fill-opacity:1;filter:url(#filter2770)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path34"
+ d="M 16.000001,8 L 16,120 C 16,120 79.146418,120 79.146418,120 L 112,87.14642 L 112,8 L 16.000001,8 z "
+ style="fill:#ffffff;fill-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path59"
+ d="M 18.000002,9.0000034 C 17.449002,9.0000034 17.000002,9.4488534 17.000002,9.9996684 L 17.000002,117.96352 C 17.000002,118.51533 17.449002,118.96318 18.000002,118.96318 L 77.171999,118.96318 C 77.434999,118.96318 79.934679,119.08131 80.12068,118.89438 L 110.707,88.094202 C 110.894,87.907264 111,85.40942 111,85.146508 L 111,9.9996684 C 111,9.4488534 110.552,9.0000034 110,9.0000034 L 18.000002,9.0000034 z "
+ style="fill:url(#radialGradient9437);fill-opacity:1" />
+ <path
+ transform="translate(40,0)"
+ clip-path="url(#clipPath7084)"
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;filter:url(#filter6697)"
+ id="path5540"
+ d="M 41.879531,115.98249 C 41.879531,115.98249 66.18914,91.672876 66.18914,91.672876 C 66.18914,91.672876 56.836,94.586 46.586,94.586 C 46.586,104.836 41.879531,115.98249 41.879531,115.98249 z " />
+ <path
+ sodipodi:nodetypes="csccc"
+ d="M 79.172,120 C 79.172,120 91.086,110.086 96.586,104.586 C 102.086,99.086 112,87.172 112,87.172 C 112,87.172 98.25,96 88,96 C 88,106.25 79.172,120 79.172,120 z "
+ id="path14523"
+ style="fill:url(#linearGradient10213);fill-opacity:1" />
+ </g>
+ <path
+ style="opacity:0.9;fill:url(#linearGradient2207);fill-opacity:1"
+ id="path30"
+ d="M 124.36598,113.79242 C 124.27969,115.00674 122.85389,116 121.19831,116 L 6.812906,116 C 5.157329,116 3.731522,115.00674 3.644228,113.79242 L 0.007982,62.204632 C -0.112423,60.992526 1.143808,60 2.799384,60 L 125.21183,60 C 126.86741,60 128.11762,60.991789 127.9912,62.203895 L 124.36598,113.79242 z " />
+ <path
+ style="fill:url(#linearGradient3387)"
+ id="path2894"
+ d="M 125.21293,60 L 2.7999261,60 C 1.1449261,60 -0.11207393,60.992526 0.0079260701,62.204632 L 3.6439261,113.79242 C 3.7309261,115.00674 5.1569261,116 6.8129261,116 L 121.19793,116 C 122.85393,116 124.27993,115.00674 124.36593,113.79242 L 127.99093,62.203895 C 128.11893,60.991789 126.86793,60 125.21293,60 z M 120.41393,113.05263 C 118.87493,113.05263 9.1349261,113.05263 7.5979261,113.05263 C 7.2299261,107.83726 4.5229261,70.627562 4.0659261,64.149246 C 6.5189261,64.149246 121.45793, [...]
+ sodipodi:nodetypes="cccccccccccccc" />
+ <path
+ style="fill:url(#linearGradient3385);fill-opacity:1;opacity:0.835"
+ id="path2908"
+ d="M 4,64 C 4.0273488,64.775875 4.1802721,68.801119 4.2225137,70 C 7.123925,70 122.78934,70 125.71499,70 C 125.74343,69.191222 125.93026,64.204735 125.9375,64 C 123.41788,64 6.4952049,64 4,64 z " />
+</svg>
diff --git a/molsketch_helium/images/document-print.png b/molsketch_helium/images/document-print.png
new file mode 100644
index 0000000..8eb1c67
Binary files /dev/null and b/molsketch_helium/images/document-print.png differ
diff --git a/molsketch_helium/images/document-save-as.png b/molsketch_helium/images/document-save-as.png
new file mode 100644
index 0000000..0ecb79e
Binary files /dev/null and b/molsketch_helium/images/document-save-as.png differ
diff --git a/molsketch_helium/images/document-save.png b/molsketch_helium/images/document-save.png
new file mode 100644
index 0000000..a81e70d
Binary files /dev/null and b/molsketch_helium/images/document-save.png differ
diff --git a/molsketch_helium/images/draw-eraser.png b/molsketch_helium/images/draw-eraser.png
new file mode 100644
index 0000000..e194513
Binary files /dev/null and b/molsketch_helium/images/draw-eraser.png differ
diff --git a/molsketch_helium/images/draw-freehand.png b/molsketch_helium/images/draw-freehand.png
new file mode 100644
index 0000000..45ddf2c
Binary files /dev/null and b/molsketch_helium/images/draw-freehand.png differ
diff --git a/molsketch_helium/images/draw-freehand.svg b/molsketch_helium/images/draw-freehand.svg
new file mode 100644
index 0000000..7b27c0c
--- /dev/null
+++ b/molsketch_helium/images/draw-freehand.svg
@@ -0,0 +1,1406 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="128"
+ height="128"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ version="1.0"
+ sodipodi:docbase="/home/pinheiro/artwork/Oxygen/theme/svg/actions"
+ sodipodi:docname="pencil2.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient2598">
+ <stop
+ style="stop-color:#252525;stop-opacity:1;"
+ offset="0"
+ id="stop2600" />
+ <stop
+ id="stop2606"
+ offset="0.5"
+ style="stop-color:#252525;stop-opacity:1;" />
+ <stop
+ style="stop-color:#252525;stop-opacity:1;"
+ offset="0.75"
+ id="stop2608" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop2602" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3325">
+ <stop
+ id="stop3327"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3329"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3311">
+ <stop
+ style="stop-color:#2d2d2d;stop-opacity:1;"
+ offset="0"
+ id="stop3313" />
+ <stop
+ id="stop3319"
+ offset="0.5"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop3315" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3303">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.68345326;"
+ offset="0"
+ id="stop3305" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3307" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3291">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3293" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3295" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3273">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.55035973;"
+ offset="0"
+ id="stop3275" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3277" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3259">
+ <stop
+ id="stop3261"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.55035973;" />
+ <stop
+ id="stop3263"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3251">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3253" />
+ <stop
+ style="stop-color:#131313;stop-opacity:0;"
+ offset="1"
+ id="stop3255" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3235">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3237" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3239" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3225">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3227" />
+ <stop
+ style="stop-color:#aeaeae;stop-opacity:1;"
+ offset="1"
+ id="stop3229" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3217">
+ <stop
+ style="stop-color:#252525;stop-opacity:1;"
+ offset="0"
+ id="stop3219" />
+ <stop
+ style="stop-color:#252525;stop-opacity:0;"
+ offset="1"
+ id="stop3221" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3207">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3209" />
+ <stop
+ style="stop-color:#252525;stop-opacity:0;"
+ offset="1"
+ id="stop3211" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2257">
+ <stop
+ style="stop-color:#b4942a;stop-opacity:1;"
+ offset="0"
+ id="stop2259" />
+ <stop
+ style="stop-color:#e4dcc9;stop-opacity:1"
+ offset="1"
+ id="stop2261" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3291"
+ id="radialGradient3297"
+ cx="63.912209"
+ cy="115.70919"
+ fx="14.046639"
+ fy="115.70919"
+ r="63.912209"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3303"
+ id="radialGradient1539"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,7.635218e-17,-1.390307e-18,2.608014e-2,-1.139078e-13,7.26766)"
+ cx="34.677639"
+ cy="7.4622769"
+ fx="34.677639"
+ fy="7.4622769"
+ r="47.595197" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3325"
+ id="radialGradient1541"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5103,2.641273e-3,-1.167078e-4,-9.110224e-3,87.0522,7.438666)"
+ cx="34.677639"
+ cy="7.4622769"
+ fx="34.677639"
+ fy="7.4622769"
+ r="47.595196" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3259"
+ id="radialGradient1547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.853446,3.931539e-16,-5.927715e-17,0.1578,-62.04115,15.05256)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3251"
+ id="linearGradient1550"
+ gradientUnits="userSpaceOnUse"
+ x1="46.051746"
+ y1="3.0999987"
+ x2="46.051746"
+ y2="2.395859"
+ gradientTransform="translate(53.87194,19.35268)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3273"
+ id="radialGradient1553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.860164,-2.860046e-16,6.583289e-17,0.1578,-29.37149,15.05256)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3251"
+ id="linearGradient1556"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.28993,-5.112494e-16,5.140778e-16,1.29707,-46.7271,12.03998)"
+ x1="46.051746"
+ y1="3.0999987"
+ x2="46.051746"
+ y2="2.395859" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3235"
+ id="linearGradient1559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.297068,-1.880044e-3,1.880044e-3,1.297068,-47.04731,12.10823)"
+ x1="48.498562"
+ y1="0.81150496"
+ x2="48.732723"
+ y2="2.3657269" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3207"
+ id="radialGradient1562"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.29707,-4.591755e-16,6.750436e-17,0.1578,-47.06473,15.05256)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3217"
+ id="linearGradient1565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.29707,-3.784064e-16,3.784064e-16,1.29707,-47.06473,12.03998)"
+ x1="48.914677"
+ y1="2.9719031"
+ x2="48.913002"
+ y2="2.5548496" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3225"
+ id="radialGradient1569"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.297068,-1.880044e-3,7.085819e-4,0.48867,-47.03734,18.97582)"
+ cx="49.009884"
+ cy="8.4953122"
+ fx="47.370888"
+ fy="6.7701697"
+ r="3.9750405" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3311"
+ id="radialGradient1576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(6.228741e-2,-3.825032e-4,4.90218e-3,0.798611,15.0605,-17.07621)"
+ cx="95.505852"
+ cy="59.591507"
+ fx="95.505852"
+ fy="59.591507"
+ r="47.746404" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2257"
+ id="radialGradient1580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.520175,8.839467e-2,-0.843351,13.788,55.27677,-1567.892)"
+ cx="42.617531"
+ cy="120.64188"
+ fx="42.617531"
+ fy="120.64188"
+ r="3.406888" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3303"
+ id="radialGradient1695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.999914,-7.841646e-3,5.666079e-4,2.048306e-2,-1.242234e-3,7.581357)"
+ cx="34.677639"
+ cy="7.4622769"
+ fx="34.677639"
+ fy="7.4622769"
+ r="47.595197" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3325"
+ id="radialGradient1697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5103,2.641273e-3,-1.167078e-4,-9.110224e-3,87.0522,7.438666)"
+ cx="34.677639"
+ cy="7.4622769"
+ fx="34.677639"
+ fy="7.4622769"
+ r="47.595196" />
+ <linearGradient
+ id="linearGradient3981">
+ <stop
+ style="stop-color:#664e00;stop-opacity:0.40569395;"
+ offset="0"
+ id="stop3983" />
+ <stop
+ id="stop3991"
+ offset="0.1460177"
+ style="stop-color:#6d5d00;stop-opacity:0;" />
+ <stop
+ id="stop3989"
+ offset="0.5"
+ style="stop-color:white;stop-opacity:0;" />
+ <stop
+ style="stop-color:#7a6300;stop-opacity:0;"
+ offset="0.8761062"
+ id="stop3993" />
+ <stop
+ style="stop-color:#7d6600;stop-opacity:0.51601422;"
+ offset="1"
+ id="stop3985" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3074">
+ <stop
+ style="stop-color:white;stop-opacity:0.73309606;"
+ offset="0"
+ id="stop3076" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop3078" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3058">
+ <stop
+ style="stop-color:#9a7600;stop-opacity:1;"
+ offset="0"
+ id="stop3060" />
+ <stop
+ id="stop3066"
+ offset="0.09292036"
+ style="stop-color:#e3ad00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffcd2c;stop-opacity:1;"
+ offset="0.5043171"
+ id="stop3070" />
+ <stop
+ style="stop-color:#e3ad00;stop-opacity:1;"
+ offset="0.91571385"
+ id="stop3068" />
+ <stop
+ style="stop-color:#b98d00;stop-opacity:1;"
+ offset="1"
+ id="stop3062" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3291"
+ id="radialGradient3616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ cx="63.912209"
+ cy="115.70919"
+ fx="64.958328"
+ fy="124.28876"
+ r="63.912209" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4081"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4083"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3981"
+ id="linearGradient4085"
+ gradientUnits="userSpaceOnUse"
+ x1="7.5175147"
+ y1="86.317051"
+ x2="21.274901"
+ y2="86.317051" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4087"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4089"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3981"
+ id="linearGradient4091"
+ gradientUnits="userSpaceOnUse"
+ x1="7.5175147"
+ y1="86.317051"
+ x2="21.274901"
+ y2="86.317051" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.059482,0,0,1.059482,-3.759048,-7.319988)"
+ x1="119.13187"
+ y1="21.341961"
+ x2="119.13187"
+ y2="49.528854" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3074"
+ id="radialGradient4095"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.149154,-1.412281e-2,1.77308e-3,0.260414,-72.15664,22.14452)"
+ cx="62.803009"
+ cy="-20.893486"
+ fx="62.803009"
+ fy="-20.893486"
+ r="56.328854" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.000484,0.823877,0)"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.000484,0.823877,0)"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3981"
+ id="linearGradient4101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.000484,0.823877,0)"
+ x1="7.5175147"
+ y1="86.317051"
+ x2="21.274901"
+ y2="86.317051" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4103"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient4105"
+ gradientUnits="userSpaceOnUse"
+ x1="16.154255"
+ y1="45.876884"
+ x2="16.841965"
+ y2="123.08778" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3981"
+ id="linearGradient4107"
+ gradientUnits="userSpaceOnUse"
+ x1="7.5175147"
+ y1="86.317051"
+ x2="21.274901"
+ y2="86.317051" />
+ <linearGradient
+ gradientTransform="matrix(1.775536,0,0,1.775536,-35.00337,-50.28567)"
+ gradientUnits="userSpaceOnUse"
+ y2="46.891453"
+ x2="70.085632"
+ y1="23.19372"
+ x1="64.79026"
+ id="linearGradient3899"
+ xlink:href="#linearGradient3893"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(2.545414,2.552713,-0.206676,0.200695,-75.94542,-45.79627)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3889"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(2.545414,2.552713,-0.206676,0.200695,-74.42807,-47.3136)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3885"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(2.545414,2.552713,-0.206676,0.200695,-72.91072,-48.83096)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3881"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(2.545414,2.552713,-0.206676,0.200695,-71.43083,-50.31084)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3877"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.340702,1.340702,-0.399454,0.399454,-51.85495,-10.43977)"
+ r="7.7031354"
+ fy="34.191952"
+ fx="70.903893"
+ cy="34.191952"
+ cx="70.903893"
+ id="radialGradient3871"
+ xlink:href="#linearGradient3865"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1.738793,0,0,1.946172,-32.03542,-29.49248)"
+ gradientUnits="userSpaceOnUse"
+ y2="36.836273"
+ x2="78.870552"
+ y1="36.836273"
+ x1="62.060658"
+ id="linearGradient2972"
+ xlink:href="#linearGradient2966"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.7180846"
+ fx="47.822392"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(8.396801,0,0,0.444365,-321.8168,-50.06649)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2958"
+ xlink:href="#linearGradient3273"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.3657269"
+ x2="48.732723"
+ y1="0.81150496"
+ x1="48.498562"
+ gradientTransform="matrix(-2.584605,-2.579204,2.570482,-2.594686,149.6106,231.5281)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2954"
+ xlink:href="#linearGradient3235"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2.6143965"
+ fy="56.363586"
+ fx="45.812191"
+ cy="56.363586"
+ cx="45.812191"
+ gradientTransform="matrix(2.268604,2.305529,-33.17622,33.13123,1836.068,-1915.404)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2927"
+ xlink:href="#linearGradient2598"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.746404"
+ fy="100.74671"
+ fx="89.454559"
+ cy="100.74671"
+ cx="89.454559"
+ gradientTransform="matrix(7.868166e-2,7.772119e-2,-0.996496,1.008807,51.15363,-62.83914)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2924"
+ xlink:href="#linearGradient3311"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.595197"
+ fy="241.42075"
+ fx="99.251144"
+ cy="238.65808"
+ cx="76.492363"
+ gradientTransform="matrix(6.555536e-2,7.112471e-2,-0.971612,0.971612,285.993,-182.7753)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2917"
+ xlink:href="#linearGradient3303"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.595196"
+ fy="-98.683281"
+ fx="51.432114"
+ cy="-98.683281"
+ cx="51.432114"
+ gradientTransform="matrix(-0.882104,0.882104,-1.627445e-2,-1.603957e-2,116.0249,-0.40137)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2914"
+ xlink:href="#linearGradient3325"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(2.401429,2.434087,-0.913991,0.908319,-6.705864,-102.1712)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2911"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.5548496"
+ x2="48.913002"
+ y1="2.9719031"
+ x1="48.914677"
+ gradientTransform="matrix(3.419307,0,0,3.420243,-77.19778,-85.09237)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2907"
+ xlink:href="#linearGradient3217"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(3.419307,0,0,0.416102,-77.19778,-77.1485)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2904"
+ xlink:href="#linearGradient3207"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.3657269"
+ x2="48.732723"
+ y1="0.81150496"
+ x1="48.498562"
+ gradientTransform="matrix(2.401429,2.434087,-2.425994,2.410936,6.139041,-114.9364)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2901"
+ xlink:href="#linearGradient3235"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.395859"
+ x2="46.051746"
+ y1="3.0999987"
+ x1="46.051746"
+ gradientTransform="matrix(3.400484,0,0,3.420243,-76.30771,-85.09237)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2898"
+ xlink:href="#linearGradient3251"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(2.267545,0,0,0.416102,-30.55525,-77.1485)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2895"
+ xlink:href="#linearGradient3273"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.395859"
+ x2="46.051746"
+ y1="3.0999987"
+ x1="46.051746"
+ gradientTransform="matrix(2.636179,0,0,2.636898,95.14277,-65.80953)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2892"
+ xlink:href="#linearGradient3251"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(2.249836,0,0,0.416102,-210.4246,-77.1485)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2889"
+ xlink:href="#linearGradient3259"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.406888"
+ fy="120.64188"
+ fx="42.617531"
+ cy="120.64188"
+ cx="42.617531"
+ gradientTransform="matrix(1.520175,8.839467e-2,-0.843351,13.788,55.27677,-1567.892)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2262"
+ xlink:href="#linearGradient2257"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.746404"
+ fy="59.591507"
+ fx="95.505852"
+ cy="59.591507"
+ cx="95.505852"
+ gradientTransform="matrix(6.228741e-2,-3.825032e-4,4.90218e-3,0.798611,15.0605,-17.07621)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2260"
+ xlink:href="#linearGradient3311"
+ inkscape:collect="always" />
+ <radialGradient
+ r="3.9750405"
+ fy="6.7701697"
+ fx="47.370888"
+ cy="8.4953122"
+ cx="49.009884"
+ gradientTransform="matrix(1.297068,-1.880044e-3,7.085819e-4,0.48867,-47.03734,18.97582)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2258"
+ xlink:href="#linearGradient3225"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.5548496"
+ x2="48.913002"
+ y1="2.9719031"
+ x1="48.914677"
+ gradientTransform="matrix(1.29707,-3.784064e-16,3.784064e-16,1.29707,-47.06473,12.03998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2256"
+ xlink:href="#linearGradient3217"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(1.29707,-4.591755e-16,6.750436e-17,0.1578,-47.06473,15.05256)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2254"
+ xlink:href="#linearGradient3207"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.3657269"
+ x2="48.732723"
+ y1="0.81150496"
+ x1="48.498562"
+ gradientTransform="matrix(1.297068,-1.880044e-3,1.880044e-3,1.297068,-47.04731,12.10823)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2252"
+ xlink:href="#linearGradient3235"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="2.395859"
+ x2="46.051746"
+ y1="3.0999987"
+ x1="46.051746"
+ gradientTransform="matrix(1.28993,-5.112494e-16,5.140778e-16,1.29707,-46.7271,12.03998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2250"
+ xlink:href="#linearGradient3251"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(0.860164,-2.860046e-16,6.583289e-17,0.1578,-29.37149,15.05256)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2248"
+ xlink:href="#linearGradient3273"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(53.87194,19.35268)"
+ y2="2.395859"
+ x2="46.051746"
+ y1="3.0999987"
+ x1="46.051746"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2246"
+ xlink:href="#linearGradient3251"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.7246193"
+ fy="2.6743078"
+ fx="49.011971"
+ cy="2.6743078"
+ cx="49.011971"
+ gradientTransform="matrix(0.853446,3.931539e-16,-5.927715e-17,0.1578,-62.04115,15.05256)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2244"
+ xlink:href="#linearGradient3259"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.595196"
+ fy="7.4622769"
+ fx="34.677639"
+ cy="7.4622769"
+ cx="34.677639"
+ gradientTransform="matrix(-1.5103,2.641273e-3,-1.167078e-4,-9.110224e-3,87.0522,7.438666)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2242"
+ xlink:href="#linearGradient3325"
+ inkscape:collect="always" />
+ <radialGradient
+ r="47.595197"
+ fy="7.4622769"
+ fx="34.677639"
+ cy="7.4622769"
+ cx="34.677639"
+ gradientTransform="matrix(1,7.635218e-17,-1.390307e-18,2.608014e-2,-1.139078e-13,7.26766)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2240"
+ xlink:href="#linearGradient3303"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.197802,0,92.82166)"
+ r="63.912209"
+ fy="135.33501"
+ fx="28.865602"
+ cy="115.70919"
+ cx="63.912209"
+ id="radialGradient2238"
+ xlink:href="#linearGradient3291"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2232">
+ <stop
+ id="stop2234"
+ offset="0"
+ style="stop-color:#b4942a;stop-opacity:1;" />
+ <stop
+ id="stop2236"
+ offset="1"
+ style="stop-color:#e4dcc9;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2226">
+ <stop
+ id="stop2228"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2230"
+ offset="1"
+ style="stop-color:#252525;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2213">
+ <stop
+ id="stop2215"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#dbdbdb;stop-opacity:1;"
+ offset="0.5"
+ id="stop3978" />
+ <stop
+ id="stop2218"
+ offset="1"
+ style="stop-color:#878787;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2201">
+ <stop
+ id="stop2203"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop2205"
+ offset="1"
+ style="stop-color:#131313;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2195">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.55035973;"
+ offset="0"
+ id="stop2197" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2199" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2189">
+ <stop
+ id="stop2191"
+ offset="0"
+ style="stop-color:white;stop-opacity:0.88086641;" />
+ <stop
+ id="stop2193"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2177">
+ <stop
+ id="stop2179"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0.68345326;" />
+ <stop
+ id="stop2181"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2169">
+ <stop
+ id="stop2171"
+ offset="0"
+ style="stop-color:#2d2d2d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0.5"
+ id="stop2173" />
+ <stop
+ id="stop2175"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2163">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2165" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2167" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2153">
+ <stop
+ id="stop2155"
+ offset="0"
+ style="stop-color:#252525;stop-opacity:1;" />
+ <stop
+ style="stop-color:#252525;stop-opacity:1;"
+ offset="0.5"
+ id="stop2157" />
+ <stop
+ id="stop2159"
+ offset="0.75"
+ style="stop-color:#252525;stop-opacity:1;" />
+ <stop
+ id="stop2161"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2966">
+ <stop
+ id="stop2968"
+ offset="0"
+ style="stop-color:#8b9084;stop-opacity:1;" />
+ <stop
+ style="stop-color:#cacdc7;stop-opacity:1;"
+ offset="0.08241758"
+ id="stop2974" />
+ <stop
+ id="stop2978"
+ offset="0.20341745"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop2976"
+ offset="0.87744886"
+ style="stop-color:#d6d6d6;stop-opacity:1;" />
+ <stop
+ id="stop2970"
+ offset="1"
+ style="stop-color:#8c9185;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3865">
+ <stop
+ id="stop3867"
+ offset="0"
+ style="stop-color:#ecedeb;stop-opacity:1;" />
+ <stop
+ style="stop-color:#e9eae7;stop-opacity:1;"
+ offset="0.5"
+ id="stop3873" />
+ <stop
+ id="stop3869"
+ offset="1"
+ style="stop-color:#babdb6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3893"
+ inkscape:collect="always">
+ <stop
+ id="stop3895"
+ offset="0"
+ style="stop-color:#2e3436;stop-opacity:1;" />
+ <stop
+ id="stop3897"
+ offset="1"
+ style="stop-color:#2e3436;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3972">
+ <stop
+ style="stop-color:#af4e4e;stop-opacity:1;"
+ offset="0"
+ id="stop3974" />
+ <stop
+ style="stop-color:#581f1f;stop-opacity:1;"
+ offset="1"
+ id="stop3976" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3235"
+ id="linearGradient3290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.409651,1.312075,-1.307294,1.414806,56.39167,-62.31585)"
+ x1="48.498562"
+ y1="0.81150496"
+ x2="48.732723"
+ y2="2.3657269" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3207"
+ id="radialGradient3293"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.925789,0,0,0.234353,-0.872908,-79.56166)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3217"
+ id="linearGradient3296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.925788,0,0,1.926317,-0.872907,-84.03571)"
+ x1="48.914677"
+ y1="2.9719031"
+ x2="48.913002"
+ y2="2.5548496" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3225"
+ id="radialGradient3300"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.409651,1.312075,-0.492522,0.533028,49.46995,-54.82486)"
+ cx="49.009884"
+ cy="8.4953122"
+ fx="47.370888"
+ fy="6.7701697"
+ r="3.9750405" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="linearGradient3305"
+ gradientUnits="userSpaceOnUse"
+ x1="11.326384"
+ y1="57.383999"
+ x2="14.493531"
+ y2="57.383999"
+ gradientTransform="matrix(1.085335,1.013149,-1.009457,1.089304,119.6765,-27.83946)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3058"
+ id="radialGradient3311"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(6.674626e-2,6.401262e-2,-1.340407,1.41446,206.1772,-84.36013)"
+ cx="36.675648"
+ cy="95.769279"
+ fx="16.217354"
+ fy="64.141281"
+ r="47.746403" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2598"
+ id="radialGradient3314"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.962254,1.86162,-26.6761,28.74703,1586.344,-1636.472)"
+ cx="15.727077"
+ cy="58.089687"
+ fx="15.727077"
+ fy="58.089687"
+ r="2.6143965" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2257"
+ id="radialGradient3317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.560669,1.636452,-14.83371,14.16488,1762.39,-1679.747)"
+ cx="42.617531"
+ cy="120.64188"
+ fx="42.617531"
+ fy="120.64188"
+ r="3.406888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2232"
+ id="linearGradient3346"
+ x1="49.15303"
+ y1="75.310318"
+ x2="82.484642"
+ y2="75.310318"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3207"
+ id="radialGradient2959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.320714,0,0,0.159681,10.63616,-85.21061)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3207"
+ id="radialGradient2963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.320714,0,0,0.159681,-171.2827,-78.12135)"
+ cx="49.011971"
+ cy="2.6743078"
+ fx="49.011971"
+ fy="2.6743078"
+ r="1.7246193" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.1015625"
+ inkscape:cx="42.779853"
+ inkscape:cy="128.54954"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ guidetolerance="0.1px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1106"
+ inkscape:window-height="958"
+ inkscape:window-x="601"
+ inkscape:window-y="25">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="32.487481"
+ id="guide2204" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Oxygen team</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/LGPL/2.1/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2276"
+ d="M 50.892799,3.2812959 L 50.892799,0.48658747 L 50.892799,3.2812959 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.38139535;fill:url(#radialGradient3297);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="path3289"
+ sodipodi:cx="63.912209"
+ sodipodi:cy="115.70919"
+ sodipodi:rx="63.912209"
+ sodipodi:ry="12.641975"
+ d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z"
+ transform="matrix(1,0,0,0.416667,0,74.87151)" />
+ <path
+ style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 116.42704,0.40599176 C 116.96151,-0.17245438 120.40761,0.16362172 124.02657,3.5320787 C 127.68103,6.9335574 128.37372,10.178062 127.70422,10.902584 C 127.26847,11.374188 126.83271,11.845789 126.39696,12.317392 C 122.63787,8.8185262 118.87881,5.3196634 115.11974,1.820798 C 115.5555,1.3491958 115.99126,0.87759458 116.42704,0.40599176 C 116.42704,0.40599176 116.42704,0.40599176 116.42704,0.40599176"
+ id="path3180"
+ sodipodi:nodetypes="czccccc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path3299"
+ d="M 13.651312,123.15922 L 44.384169,101.24951 L 44.558412,101.06093 L 33.466308,90.363997 L 33.230133,90.619498 L 13.651312,123.15922 z "
+ style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:url(#radialGradient3317);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 15.427626,121.37171 L 44.08734,100.95237 L 44.261572,100.7638 L 33.763148,90.661126 L 33.526961,90.916636 L 15.427626,121.37171 z "
+ id="path2247"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ style="fill:url(#radialGradient3314);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="M 38.007252,96.800445 C 39.398207,98.095109 40.820598,97.609755 41.317806,98.072532 C 41.398156,98.147315 41.451507,98.249432 41.489278,98.35858 L 124.18886,8.6831786 L 118.72233,3.5950484 L 35.865742,93.440344 C 36.115034,93.42024 36.336127,93.435676 36.493385,93.582049 C 36.947846,94.005064 36.609843,95.499757 38.007252,96.800445 z "
+ id="rect2192"
+ sodipodi:nodetypes="csccccsz" />
+ <path
+ id="path2233"
+ d="M 44.441059,94.762294 L 41.202762,98.266896 C 41.637363,98.744857 41.04116,100.06146 41.876526,100.83899 C 42.776793,101.67695 43.754266,100.72718 44.339309,101.26535 L 47.616854,97.718232 L 44.441059,94.762294 z "
+ style="opacity:0.35348834;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ sodipodi:nodetypes="ccsccc" />
+ <path
+ sodipodi:nodetypes="ccsccc"
+ style="fill:url(#radialGradient3311);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="M 123.98928,8.4974286 L 41.352509,98.104846 C 41.789494,98.585052 41.344744,99.74118 42.18439,100.52268 C 43.089248,101.36494 43.917284,100.57744 44.505294,101.11839 L 127.18131,11.468508 L 123.98928,8.4974286 z "
+ id="rect2190" />
+ <path
+ id="path2231"
+ d="M 38.067709,91.879794 L 36.406536,93.677585 L 36.343622,93.744125 C 36.714825,94.112885 36.172676,95.452421 37.363863,96.780953 L 37.433284,96.845554 L 37.927875,97.305908 L 37.997292,97.370526 C 39.420049,98.475054 40.70965,97.807942 41.206841,98.270704 L 42.966156,96.356775 L 38.067709,91.879794 z "
+ style="opacity:0.38604653;fill:#252525;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ id="path2229"
+ d="M 34.90869,88.904126 L 33.227115,90.624218 C 33.244543,90.640365 33.107293,90.790231 33.124784,90.806518 C 33.48161,91.138636 32.986597,92.477518 33.580041,93.259054 L 33.640783,93.315573 L 33.909763,93.565952 L 33.944481,93.598239 C 34.784789,94.160643 35.912787,93.460855 36.343622,93.744125 L 38.084483,91.860102 L 34.90869,88.904126 z "
+ style="opacity:0.35348834;fill:#131313;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ sodipodi:nodetypes="ccsccccccc" />
+ <path
+ style="fill:url(#linearGradient3305);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="M 34.087198,93.104668 C 34.963015,93.900983 36.029765,93.150524 36.493385,93.582049 L 119.13017,3.9746446 L 115.90411,0.97191428 L 33.228077,90.621805 C 33.245787,90.638195 33.263192,90.654483 33.280954,90.671043 C 33.643429,91.008415 33.204836,92.302223 34.087198,93.104668 z "
+ id="rect1315"
+ sodipodi:nodetypes="cccccsz" />
+ <rect
+ style="opacity:1;fill:black;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2069"
+ width="15.402301"
+ height="3.6207759"
+ x="85.578621"
+ y="-78.905174"
+ transform="matrix(0.732512,0.680754,-0.680754,0.732512,0,0)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1695);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="path3301"
+ sodipodi:cx="34.677639"
+ sodipodi:cy="7.4622769"
+ sodipodi:rx="47.495197"
+ sodipodi:ry="0.97142172"
+ d="M 82.172836 7.4622769 A 47.495197 0.97142172 0 1 1 -12.817558,7.4622769 A 47.495197 0.97142172 0 1 1 82.172836 7.4622769 z"
+ transform="matrix(0.713012,-0.771216,-1.464327,-1.358495,70.16317,75.51535)" />
+ <path
+ transform="matrix(0.5904,-0.64083,-1.060653,-0.987999,64.57362,78.67065)"
+ d="M 106.56087,7.4622769 A 71.883232,0.4230493 0 1 1 106.52539,7.448987"
+ sodipodi:ry="0.4230493"
+ sodipodi:rx="71.883232"
+ sodipodi:cy="7.4622769"
+ sodipodi:cx="34.677639"
+ id="path3321"
+ style="fill:url(#radialGradient1697);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ sodipodi:type="arc"
+ sodipodi:start="0"
+ sodipodi:end="6.2517655"
+ sodipodi:open="true" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path2274"
+ d="M 110.64476,6.6737344 C 109.05105,7.6737521 107.54057,9.4168833 106.72916,10.911353 L 115.79509,19.273013 L 119.71068,15.035395 L 110.64476,6.6737344 z M 118.75785,14.148543 L 114.84226,18.38616 L 118.0183,21.342341 C 119.40654,20.507757 120.99939,18.847097 121.9339,17.104726 L 118.75785,14.148543 z "
+ style="fill:url(#radialGradient3300);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ style="fill:black;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 26.866566,113.78159 C 24.804075,113.57876 23.031592,110.45226 21.890943,109.49572 L 13.652941,123.15234 L 26.866566,113.78159 z "
+ id="path2265"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:url(#radialGradient3293);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect3205"
+ width="6.6425061"
+ height="1.4544153"
+ x="90.192551"
+ y="-79.518532"
+ transform="matrix(0.731987,0.681319,-0.678649,0.734463,0,0)" />
+ <path
+ style="fill:url(#linearGradient3290);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 122.89657,2.7781062 C 125.2381,4.6476879 126.89094,7.202444 126.98021,7.4466464 C 127.06946,7.6908503 124.81058,4.8260157 122.87239,3.4992476 C 120.94902,2.182611 118.23255,2.1056257 118.03435,1.9459227 C 117.83615,1.7862208 116.50195,0.3277744 117.73289,0.40111714 C 119.0204,0.47783059 121.08795,1.3353777 122.89657,2.7781062 z "
+ id="path3233"
+ sodipodi:nodetypes="cszsss" />
+ <path
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient3346);fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ d="M 50.521934,90.594282 C 50.267423,90.869439 50.123688,91.132811 50.090694,91.384387 C 50.057704,91.636007 50.138584,91.852523 50.333331,92.033972 C 50.527256,92.214653 50.747992,92.279144 50.995528,92.227476 C 51.243072,92.175754 51.494085,92.012362 51.748586,91.737216 C 52.004549,91.460488 52.149002,91.196343 52.182004,90.944735 C 52.214988,90.693129 52.134507,90.477007 51.940594,90.296316 C 51.745838,90.114858 51.5247,90.049992 51.277164,90.101681 C 51.029623,90.153365 50.777 [...]
+ id="text3284" />
+ <rect
+ transform="matrix(0.685219,0.728337,-0.782272,0.622936,0,0)"
+ y="-85.181229"
+ x="73.08918"
+ height="0.99099517"
+ width="4.5554557"
+ id="rect2956"
+ style="fill:url(#radialGradient2959);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="fill:url(#radialGradient2963);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2961"
+ width="4.5554533"
+ height="0.99099189"
+ x="-108.82972"
+ y="-78.091957"
+ transform="matrix(-0.743171,-0.669101,-0.605652,0.79573,0,0)" />
+ </g>
+</svg>
diff --git a/molsketch_helium/images/edit-copy.png b/molsketch_helium/images/edit-copy.png
new file mode 100644
index 0000000..03ec427
Binary files /dev/null and b/molsketch_helium/images/edit-copy.png differ
diff --git a/molsketch_helium/images/edit-cut.png b/molsketch_helium/images/edit-cut.png
new file mode 100644
index 0000000..472b488
Binary files /dev/null and b/molsketch_helium/images/edit-cut.png differ
diff --git a/molsketch_helium/images/edit-paste.png b/molsketch_helium/images/edit-paste.png
new file mode 100644
index 0000000..df468ce
Binary files /dev/null and b/molsketch_helium/images/edit-paste.png differ
diff --git a/molsketch_helium/images/edit-redo.png b/molsketch_helium/images/edit-redo.png
new file mode 100644
index 0000000..45f0450
Binary files /dev/null and b/molsketch_helium/images/edit-redo.png differ
diff --git a/molsketch_helium/images/edit-select-all.png b/molsketch_helium/images/edit-select-all.png
new file mode 100644
index 0000000..995f468
Binary files /dev/null and b/molsketch_helium/images/edit-select-all.png differ
diff --git a/molsketch_helium/images/edit-undo.png b/molsketch_helium/images/edit-undo.png
new file mode 100644
index 0000000..57abbe1
Binary files /dev/null and b/molsketch_helium/images/edit-undo.png differ
diff --git a/molsketch_helium/images/help-about.png b/molsketch_helium/images/help-about.png
new file mode 100644
index 0000000..7f2b7bf
Binary files /dev/null and b/molsketch_helium/images/help-about.png differ
diff --git a/molsketch_helium/images/help-contents.png b/molsketch_helium/images/help-contents.png
new file mode 100644
index 0000000..a0d60d9
Binary files /dev/null and b/molsketch_helium/images/help-contents.png differ
diff --git a/molsketch_helium/images/help-contextual.png b/molsketch_helium/images/help-contextual.png
new file mode 100644
index 0000000..0b2c31c
Binary files /dev/null and b/molsketch_helium/images/help-contextual.png differ
diff --git a/molsketch_helium/images/help.png b/molsketch_helium/images/help.png
new file mode 100644
index 0000000..644347b
Binary files /dev/null and b/molsketch_helium/images/help.png differ
diff --git a/molsketch_helium/images/icon.svg b/molsketch_helium/images/icon.svg
new file mode 100644
index 0000000..0758a8e
--- /dev/null
+++ b/molsketch_helium/images/icon.svg
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="128"
+ height="128"
+ viewBox="0 0 128 128"
+ id="svg2"
+ xml:space="preserve"><defs
+ id="defs157">
+
+
+ <linearGradient
+ x1="68.906303"
+ y1="80.840797"
+ x2="68.906303"
+ y2="113.9932"
+ id="XMLID_22_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1"
+ offset="0"
+ id="stop64" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop66" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+
+ <linearGradient
+ x1="60.133801"
+ y1="43.399899"
+ x2="60.133801"
+ y2="99.400902"
+ id="XMLID_23_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#57adff;stop-opacity:1"
+ offset="0"
+ id="stop71" />
+ <stop
+ style="stop-color:#428aff;stop-opacity:1"
+ offset="1"
+ id="stop73" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#428AFF" />
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="XMLID_24_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#a20000;stop-opacity:1"
+ offset="0"
+ id="stop84" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop86" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop91" />
+ <stop
+ style="stop-color:#ffe6b0;stop-opacity:1"
+ offset="1"
+ id="stop93" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFE6B0" />
+ </linearGradient>
+
+
+
+
+
+ <radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient579"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient574"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="0.43846199"
+ y1="0.96875"
+ x2="0.42307699"
+ y2="0.328125"
+ id="linearGradient573"
+ xlink:href="#linearGradient570" /><linearGradient
+ id="linearGradient570"><stop
+ style="stop-color:#4c0000;stop-opacity:0.60390002"
+ offset="0"
+ id="stop571" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop572" /></linearGradient><linearGradient
+ id="linearGradient576"><stop
+ style="stop-color:#02000d;stop-opacity:0.60390002"
+ offset="0"
+ id="stop577" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop578" /></linearGradient>
+
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop12" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1"
+ offset="0.25799999"
+ id="stop14" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1"
+ offset="0.7396"
+ id="stop16" />
+ <stop
+ style="stop-color:#c4c4c4;stop-opacity:1"
+ offset="0.85949999"
+ id="stop18" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.258" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.7396" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#C4C4C4"
+ offset="0.8595" />
+ </linearGradient>
+
+
+ <radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop23" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1"
+ id="stop25" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="1" />
+ </radialGradient>
+
+
+ <linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop30" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop32" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+
+ <linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop39" />
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1"
+ offset="1"
+ id="stop41" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CCCCCC"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop46" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop48" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop53" />
+ <stop
+ style="stop-color:#e7e7e7;stop-opacity:1"
+ offset="0.50330001"
+ id="stop55" />
+ <stop
+ style="stop-color:#d4d4d4;stop-opacity:1"
+ offset="1"
+ id="stop57" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5033" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#D4D4D4"
+ offset="1" />
+ </linearGradient>
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="linearGradient2677"
+ xlink:href="#XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2679"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2681"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2683"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="radialGradient2685"
+ xlink:href="#XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2687"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="linearGradient2689"
+ xlink:href="#XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2691"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2693"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2695"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2730"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2733"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2740"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2745"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2765"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /></defs>
+
+
+ <polygon
+ points="121.164,1.052 6.836,1.052 6.836,126.948 87.537,126.948 121.164,93.32 121.164,1.052 "
+ style="fill:#ffffff"
+ id="polygon9" /><polygon
+ points="117.734,4.019 10.266,4.019 10.106,126.673 86.563,126.673 117.734,95.421 117.734,4.019 "
+ style="fill:url(#linearGradient2677)"
+ id="polygon20" /><path
+ d="M 118.006,15.223 L 118.006,3.94 L 10.199,3.94 L 10.103,69.28 C 20.078,73.827 31.254,76.376 43.057,76.376 C 80.402,76.376 111.455,48.876 118.006,15.223 z "
+ style="fill:url(#linearGradient2765)"
+ id="path59" /><g
+ transform="matrix(0.6046674,0,0,0.6046674,-150.33779,-176.14874)"
+ style="font-size:12px"
+ id="g597"><g
+ transform="translate(3.526687,-2.015259)"
+ id="g583"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(72.49998,-36.25)"
+ style="fill:#0000b3;fill-rule:evenodd;stroke-width:1"
+ id="path564" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410152e-2,0.30097,280.1325,205.3008)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path565" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(71.4733,-36.59851)"
+ style="fill:url(#radialGradient2681);fill-rule:evenodd;stroke-width:1"
+ id="path575" /></g><path
+ d="M 350.8661,383.4841 L 306.1411,407.7528 C 306.6755,414.7234 310.5121,419.329 314.994,423.0112 L 359.9215,398.0594 C 359.3197,391.3165 357.2246,387.1034 350.8661,383.4841 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path582" /><g
+ id="g587"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ style="fill-rule:evenodd;stroke-width:1"
+ id="path562" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,206.5758,241.2266)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path568" /></g><path
+ d="M 386.3464,448.6343 L 384.5892,397.7795 C 378.1128,395.1467 372.279,396.5246 366.9836,398.8921 L 369.2618,450.2329 C 375.5645,452.7037 380.2698,452.7091 386.3464,448.6343 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path596" /><g
+ transform="translate(3.02288,2.015137)"
+ id="g590"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:#ab0000;fill-rule:evenodd;stroke-width:1"
+ id="path563" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path566" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path567" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:url(#radialGradient2683);fill-rule:evenodd;stroke-width:1"
+ id="path569" /></g><path
+ d="M 356.3334,448.0147 L 311.4055,424.1236 C 305.8887,428.4177 304.167,434.1594 303.5714,439.9293 L 349.1806,463.6121 C 354.4703,459.3875 356.8263,455.3145 356.3334,448.0147 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path595" /></g><polygon
+ points="85.191,90.977 85.191,126.73 86.984,126.73 120.623,93.091 120.623,90.977 85.191,90.977 "
+ style="opacity:0.1;fill:url(#radialGradient2685);enable-background:new"
+ id="polygon27" /><path
+ d="M 121.164,0.552 L 6.336,0.552 L 6.336,127.448 L 87.744,127.448 L 121.664,93.527 L 121.664,0.552 L 121.164,0.552 z M 120.664,1.552 C 120.664,2.539 120.664,92.704 120.664,93.115 C 120.375,93.403 87.619,126.16 87.33,126.449 C 86.92,126.449 8.32,126.449 7.336,126.449 C 7.336,125.461 7.336,2.54 7.336,1.553 C 8.322,1.552 119.678,1.552 120.664,1.552 z "
+ style="fill:url(#linearGradient2745)"
+ id="path34" /><polygon
+ points="87.537,126.948 121.164,93.32 87.537,93.32 87.537,126.948 "
+ style="fill:#ffffff"
+ id="polygon36" /><polygon
+ points="89.865,125.057 119.459,95.464 89.865,95.464 89.865,125.057 "
+ style="fill:url(#linearGradient2689)"
+ id="polygon43" /><path
+ d="M 87.537,92.82 C 87.26,92.82 87.037,93.044 87.037,93.32 L 87.037,126.948 C 87.037,127.15 87.158,127.333 87.346,127.411 C 87.533,127.486 87.748,127.443 87.891,127.302 L 121.518,93.675 C 121.662,93.53 121.705,93.317 121.627,93.13 C 121.549,92.942 121.367,92.82 121.164,92.82 L 87.537,92.82 L 87.537,92.82 z M 119.957,93.82 C 118.377,95.398 89.615,124.161 88.037,125.741 C 88.037,123.532 88.037,94.755 88.037,93.82 C 88.971,93.82 117.748,93.82 119.957,93.82 z "
+ style="fill:url(#linearGradient2740)"
+ id="path50" /><rect
+ width="128"
+ height="128"
+ x="0"
+ y="0"
+ style="fill:none"
+ id="rect61" /><path
+ d="M 35.369,17.504 C 34.377,17.503 33.495,18.132 33.174,19.074 C 32.856,20.021 33.172,21.059 33.96,21.661 L 110.298,80.083 C 111.001,80.622 111.934,80.713 112.732,80.319 C 113.527,79.93 114.024,79.134 114.024,78.242 L 114.024,19.821 C 114.024,19.201 113.783,18.618 113.345,18.18 C 112.906,17.743 112.324,17.503 111.704,17.504 L 111.704,17.504 L 35.369,17.504 z M 99.061,32.468 C 99.061,34.053 99.059,49.569 99.059,52.639 C 99.059,52.639 76.744,35.56 72.703,32.468 C 77.433,32.468 97.34,32. [...]
+ style="opacity:0.2"
+ id="path77" /><path
+ d="M 34.342,15.451 C 33.35,15.449 32.468,16.079 32.147,17.021 C 31.829,17.969 32.145,19.006 32.933,19.608 L 109.271,78.03 C 109.974,78.569 110.909,78.66 111.707,78.266 C 112.502,77.877 112.999,77.081 112.999,76.189 L 112.999,17.768 C 112.999,17.147 112.758,16.565 112.318,16.127 C 111.88,15.69 111.297,15.45 110.678,15.451 L 110.679,15.451 L 34.342,15.451 L 34.342,15.451 z M 98.033,30.415 C 98.033,32.001 98.033,47.516 98.033,50.586 C 98.033,50.586 75.716,33.507 71.677,30.415 C 76.405,30 [...]
+ style="opacity:0.2"
+ id="path79" /><path
+ d="M 33.316,14.424 C 32.324,14.422 31.442,15.053 31.121,15.994 C 30.803,16.942 31.119,17.979 31.907,18.581 L 108.244,77.002 C 108.949,77.541 109.882,77.632 110.68,77.238 C 111.475,76.849 111.972,76.053 111.972,75.163 L 111.972,16.741 C 111.972,16.121 111.731,15.538 111.293,15.101 C 110.854,14.664 110.271,14.423 109.652,14.424 L 109.652,14.424 L 33.316,14.424 z M 97.008,29.388 C 97.008,30.974 97.006,46.489 97.006,49.559 C 97.006,49.559 74.691,32.48 70.65,29.388 C 75.378,29.388 95.287,2 [...]
+ style="opacity:0.2"
+ id="path81" /><path
+ d="M 33.316,13.397 C 32.324,13.395 31.442,14.025 31.121,14.967 C 30.803,15.915 31.119,16.952 31.907,17.554 L 108.244,75.975 C 108.949,76.516 109.882,76.605 110.68,76.213 C 111.475,75.822 111.972,75.028 111.972,74.136 L 111.972,15.714 C 111.972,15.094 111.731,14.511 111.293,14.074 C 110.854,13.637 110.271,13.397 109.652,13.398 L 109.652,13.398 L 33.316,13.398 L 33.316,13.397 z M 97.008,28.361 C 97.008,29.947 97.006,45.463 97.006,48.532 C 97.006,48.532 74.691,31.453 70.65,28.361 C 75.37 [...]
+ style="fill:url(#linearGradient2733)"
+ id="path88" /><path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:url(#linearGradient2730)"
+ id="path95" /><g
+ style="opacity:0.5"
+ id="g97">
+ <path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 108.362,71.523 C 104.591,68.639 42.553,21.157 37.128,17.003 C 43.885,17.004 105.992,17.004 108.362,17.004 C 108.362,19.362 108.362,66.86 108.362,71.523 M 100.614,55.839 L 100.614,26.042 L 100.614,24.751 L 59.994,24.751 L 100.614,55.839 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:#ffffff"
+ id="path99" />
+ </g><polygon
+ points="33.316,16.61 109.651,75.032 109.651,72.449 36.689,16.61 33.316,16.61 "
+ style="fill:#ffff66"
+ id="polygon101" /><path
+ d="M 109.651,75.032 L 109.651,72.449 L 108.362,71.462 C 108.362,71.861 108.362,72.201 108.362,72.42 C 104.591,69.535 42.553,22.053 37.128,17.899 C 37.433,17.899 37.855,17.9 38.378,17.9 L 36.689,16.61 L 33.316,16.61 L 109.651,75.032 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path103" /><g
+ transform="translate(1.450693,28.664084)"
+ id="g105">
+ <path
+ d="M 59.545,43.092 C 44.665,47.876 41.97,48.742 41.396,49.213 C 41.427,49.164 41.469,49.093 41.469,49.093 L 5.447,81.448 C 3.531,83.176 5.594,87.217 8.32,90.244 C 11.015,93.244 14.817,95.73 16.791,94.103 L 52.848,61.587 L 52.888,61.367 L 60.137,45.811 L 61.112,42.645 L 59.545,43.092 z "
+ style="opacity:0.2"
+ id="path107" />
+ <path
+ d="M 58.528,42.419 C 43.648,47.202 40.953,48.067 40.378,48.54 C 40.409,48.491 40.453,48.42 40.453,48.42 L 4.431,80.772 C 2.515,82.501 4.577,86.543 7.304,89.57 C 9.999,92.57 13.8,95.056 15.774,93.429 L 51.831,60.913 L 51.871,60.693 L 59.119,45.137 L 60.095,41.971 L 58.528,42.419 z "
+ style="opacity:0.2"
+ id="path109" />
+ <path
+ d="M 57.511,41.745 C 42.631,46.529 39.936,47.394 39.361,47.867 C 39.391,47.817 39.435,47.747 39.435,47.747 L 3.413,80.101 C 1.497,81.829 3.56,85.872 6.287,88.897 C 8.982,91.897 12.783,94.383 14.758,92.756 L 50.815,60.241 L 50.854,60.021 L 58.103,44.464 L 59.078,41.298 L 57.511,41.745 z "
+ style="opacity:0.2"
+ id="path111" />
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:#ffffff"
+ id="path113" />
+
+ <linearGradient
+ x1="7.4770999"
+ y1="77.034203"
+ x2="57.502499"
+ y2="48.2841"
+ id="XMLID_26_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#cf0000;stop-opacity:1"
+ offset="0"
+ id="stop116" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop118" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:url(#XMLID_26_)"
+ id="path120" />
+
+ <linearGradient
+ x1="313.06741"
+ y1="-177.2002"
+ x2="321.69031"
+ y2="-168.57651"
+ id="XMLID_27_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#f8f1dc;stop-opacity:1"
+ offset="0"
+ id="stop123" />
+ <stop
+ style="stop-color:#d6a84a;stop-opacity:1"
+ offset="1"
+ id="stop125" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#D6A84A" />
+ </linearGradient>
+ <path
+ d="M 39.683,49.903 L 55.387,44.251 L 48.013,59.231 L 47.951,59.163 C 47.918,59.266 47.876,59.366 47.821,59.452 L 47.87,59.502 L 13.449,90.519 L 13.407,90.468 C 12.381,91.394 9.662,90.043 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 39.389,50.094 L 39.683,49.903 z "
+ style="fill:url(#XMLID_27_)"
+ id="path127" />
+
+ <linearGradient
+ x1="329.35739"
+ y1="-197.62601"
+ x2="333.9407"
+ y2="-203.0881"
+ id="XMLID_28_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop130" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="1"
+ id="stop132" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFAE00" />
+ </linearGradient>
+ <path
+ d="M 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 12.725,74.119 L 23.636,73.644 L 23.959,81.047 L 13.451,90.518 L 13.409,90.467 C 12.381,91.394 9.662,90.043 7.331,87.458 z "
+ style="fill:url(#XMLID_28_)"
+ id="path134" />
+
+ <linearGradient
+ x1="302.5752"
+ y1="-214.1689"
+ x2="321.83981"
+ y2="-171.39861"
+ id="XMLID_29_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ff9200;stop-opacity:1"
+ offset="0"
+ id="stop137" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="0.77530003"
+ id="stop139" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop141" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.7753"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+ <path
+ d="M 13.177,90.633 C 13.907,89.919 13.497,88.163 12.274,86.249 C 11.869,85.613 11.371,84.959 10.796,84.322 C 10.251,83.715 9.684,83.185 9.123,82.727 C 7.315,81.253 5.563,80.63 4.763,81.295 L 4.753,81.284 L 39.4,50.059 C 40.332,49.796 42.077,50.301 43.666,51.604 C 44.208,52.051 44.76,52.568 45.286,53.157 C 45.877,53.81 46.388,54.482 46.8,55.136 C 48.037,57.089 48.529,58.967 47.748,59.673 C 47.567,59.835 46.786,60.537 46.757,60.556 L 13.266,90.73 L 13.177,90.633 z "
+ style="fill:url(#XMLID_29_)"
+ id="path143" />
+
+ <linearGradient
+ x1="56.380402"
+ y1="50.837399"
+ x2="49.402302"
+ y2="50.837399"
+ id="XMLID_30_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="0"
+ id="stop146" />
+ <stop
+ style="stop-color:#663333;stop-opacity:1"
+ offset="1"
+ id="stop148" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#663333" />
+ </linearGradient>
+ <path
+ d="M 48.455,46.795 L 55.096,44.432 L 52.305,50.113 C 52.305,50.113 52.256,49.275 51.055,48.063 C 49.472,46.458 48.455,46.795 48.455,46.795 z "
+ style="opacity:0.8;fill:url(#XMLID_30_)"
+ id="path150" />
+ <path
+ d="M 43.51,51.488 L 9.272,82.854 C 9.223,82.814 9.172,82.766 9.123,82.728 C 8.401,82.14 7.685,81.69 7.04,81.4 L 41.105,50.192 C 41.857,50.419 42.698,50.851 43.51,51.488 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path152" />
+ <path
+ d="M 9.123,82.728 C 8.804,82.467 8.485,82.238 8.175,82.03 L 42.351,50.72 C 42.789,50.957 43.235,51.248 43.666,51.604 C 44.035,51.91 44.409,52.25 44.777,52.619 L 10.509,84.014 C 10.052,83.534 9.586,83.104 9.123,82.728 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path154" />
+ </g></svg>
\ No newline at end of file
diff --git a/molsketch_helium/images/molsketch.ico b/molsketch_helium/images/molsketch.ico
new file mode 100644
index 0000000..3e857ec
Binary files /dev/null and b/molsketch_helium/images/molsketch.ico differ
diff --git a/molsketch_helium/images/molsketch.png b/molsketch_helium/images/molsketch.png
new file mode 100644
index 0000000..ea0fe93
Binary files /dev/null and b/molsketch_helium/images/molsketch.png differ
diff --git a/molsketch_helium/images/molsketch.svg b/molsketch_helium/images/molsketch.svg
new file mode 100644
index 0000000..0758a8e
--- /dev/null
+++ b/molsketch_helium/images/molsketch.svg
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="128"
+ height="128"
+ viewBox="0 0 128 128"
+ id="svg2"
+ xml:space="preserve"><defs
+ id="defs157">
+
+
+ <linearGradient
+ x1="68.906303"
+ y1="80.840797"
+ x2="68.906303"
+ y2="113.9932"
+ id="XMLID_22_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1"
+ offset="0"
+ id="stop64" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop66" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+
+ <linearGradient
+ x1="60.133801"
+ y1="43.399899"
+ x2="60.133801"
+ y2="99.400902"
+ id="XMLID_23_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#57adff;stop-opacity:1"
+ offset="0"
+ id="stop71" />
+ <stop
+ style="stop-color:#428aff;stop-opacity:1"
+ offset="1"
+ id="stop73" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#428AFF" />
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="XMLID_24_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#a20000;stop-opacity:1"
+ offset="0"
+ id="stop84" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop86" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop91" />
+ <stop
+ style="stop-color:#ffe6b0;stop-opacity:1"
+ offset="1"
+ id="stop93" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFE6B0" />
+ </linearGradient>
+
+
+
+
+
+ <radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient579"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient574"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="0.43846199"
+ y1="0.96875"
+ x2="0.42307699"
+ y2="0.328125"
+ id="linearGradient573"
+ xlink:href="#linearGradient570" /><linearGradient
+ id="linearGradient570"><stop
+ style="stop-color:#4c0000;stop-opacity:0.60390002"
+ offset="0"
+ id="stop571" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop572" /></linearGradient><linearGradient
+ id="linearGradient576"><stop
+ style="stop-color:#02000d;stop-opacity:0.60390002"
+ offset="0"
+ id="stop577" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop578" /></linearGradient>
+
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop12" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1"
+ offset="0.25799999"
+ id="stop14" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1"
+ offset="0.7396"
+ id="stop16" />
+ <stop
+ style="stop-color:#c4c4c4;stop-opacity:1"
+ offset="0.85949999"
+ id="stop18" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.258" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.7396" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#C4C4C4"
+ offset="0.8595" />
+ </linearGradient>
+
+
+ <radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop23" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1"
+ id="stop25" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="1" />
+ </radialGradient>
+
+
+ <linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop30" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop32" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+
+ <linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop39" />
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1"
+ offset="1"
+ id="stop41" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CCCCCC"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop46" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop48" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop53" />
+ <stop
+ style="stop-color:#e7e7e7;stop-opacity:1"
+ offset="0.50330001"
+ id="stop55" />
+ <stop
+ style="stop-color:#d4d4d4;stop-opacity:1"
+ offset="1"
+ id="stop57" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5033" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#D4D4D4"
+ offset="1" />
+ </linearGradient>
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="linearGradient2677"
+ xlink:href="#XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2679"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2681"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2683"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="radialGradient2685"
+ xlink:href="#XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2687"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="linearGradient2689"
+ xlink:href="#XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2691"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2693"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2695"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2730"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2733"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2740"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2745"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2765"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /></defs>
+
+
+ <polygon
+ points="121.164,1.052 6.836,1.052 6.836,126.948 87.537,126.948 121.164,93.32 121.164,1.052 "
+ style="fill:#ffffff"
+ id="polygon9" /><polygon
+ points="117.734,4.019 10.266,4.019 10.106,126.673 86.563,126.673 117.734,95.421 117.734,4.019 "
+ style="fill:url(#linearGradient2677)"
+ id="polygon20" /><path
+ d="M 118.006,15.223 L 118.006,3.94 L 10.199,3.94 L 10.103,69.28 C 20.078,73.827 31.254,76.376 43.057,76.376 C 80.402,76.376 111.455,48.876 118.006,15.223 z "
+ style="fill:url(#linearGradient2765)"
+ id="path59" /><g
+ transform="matrix(0.6046674,0,0,0.6046674,-150.33779,-176.14874)"
+ style="font-size:12px"
+ id="g597"><g
+ transform="translate(3.526687,-2.015259)"
+ id="g583"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(72.49998,-36.25)"
+ style="fill:#0000b3;fill-rule:evenodd;stroke-width:1"
+ id="path564" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410152e-2,0.30097,280.1325,205.3008)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path565" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(71.4733,-36.59851)"
+ style="fill:url(#radialGradient2681);fill-rule:evenodd;stroke-width:1"
+ id="path575" /></g><path
+ d="M 350.8661,383.4841 L 306.1411,407.7528 C 306.6755,414.7234 310.5121,419.329 314.994,423.0112 L 359.9215,398.0594 C 359.3197,391.3165 357.2246,387.1034 350.8661,383.4841 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path582" /><g
+ id="g587"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ style="fill-rule:evenodd;stroke-width:1"
+ id="path562" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,206.5758,241.2266)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path568" /></g><path
+ d="M 386.3464,448.6343 L 384.5892,397.7795 C 378.1128,395.1467 372.279,396.5246 366.9836,398.8921 L 369.2618,450.2329 C 375.5645,452.7037 380.2698,452.7091 386.3464,448.6343 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path596" /><g
+ transform="translate(3.02288,2.015137)"
+ id="g590"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:#ab0000;fill-rule:evenodd;stroke-width:1"
+ id="path563" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path566" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path567" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:url(#radialGradient2683);fill-rule:evenodd;stroke-width:1"
+ id="path569" /></g><path
+ d="M 356.3334,448.0147 L 311.4055,424.1236 C 305.8887,428.4177 304.167,434.1594 303.5714,439.9293 L 349.1806,463.6121 C 354.4703,459.3875 356.8263,455.3145 356.3334,448.0147 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path595" /></g><polygon
+ points="85.191,90.977 85.191,126.73 86.984,126.73 120.623,93.091 120.623,90.977 85.191,90.977 "
+ style="opacity:0.1;fill:url(#radialGradient2685);enable-background:new"
+ id="polygon27" /><path
+ d="M 121.164,0.552 L 6.336,0.552 L 6.336,127.448 L 87.744,127.448 L 121.664,93.527 L 121.664,0.552 L 121.164,0.552 z M 120.664,1.552 C 120.664,2.539 120.664,92.704 120.664,93.115 C 120.375,93.403 87.619,126.16 87.33,126.449 C 86.92,126.449 8.32,126.449 7.336,126.449 C 7.336,125.461 7.336,2.54 7.336,1.553 C 8.322,1.552 119.678,1.552 120.664,1.552 z "
+ style="fill:url(#linearGradient2745)"
+ id="path34" /><polygon
+ points="87.537,126.948 121.164,93.32 87.537,93.32 87.537,126.948 "
+ style="fill:#ffffff"
+ id="polygon36" /><polygon
+ points="89.865,125.057 119.459,95.464 89.865,95.464 89.865,125.057 "
+ style="fill:url(#linearGradient2689)"
+ id="polygon43" /><path
+ d="M 87.537,92.82 C 87.26,92.82 87.037,93.044 87.037,93.32 L 87.037,126.948 C 87.037,127.15 87.158,127.333 87.346,127.411 C 87.533,127.486 87.748,127.443 87.891,127.302 L 121.518,93.675 C 121.662,93.53 121.705,93.317 121.627,93.13 C 121.549,92.942 121.367,92.82 121.164,92.82 L 87.537,92.82 L 87.537,92.82 z M 119.957,93.82 C 118.377,95.398 89.615,124.161 88.037,125.741 C 88.037,123.532 88.037,94.755 88.037,93.82 C 88.971,93.82 117.748,93.82 119.957,93.82 z "
+ style="fill:url(#linearGradient2740)"
+ id="path50" /><rect
+ width="128"
+ height="128"
+ x="0"
+ y="0"
+ style="fill:none"
+ id="rect61" /><path
+ d="M 35.369,17.504 C 34.377,17.503 33.495,18.132 33.174,19.074 C 32.856,20.021 33.172,21.059 33.96,21.661 L 110.298,80.083 C 111.001,80.622 111.934,80.713 112.732,80.319 C 113.527,79.93 114.024,79.134 114.024,78.242 L 114.024,19.821 C 114.024,19.201 113.783,18.618 113.345,18.18 C 112.906,17.743 112.324,17.503 111.704,17.504 L 111.704,17.504 L 35.369,17.504 z M 99.061,32.468 C 99.061,34.053 99.059,49.569 99.059,52.639 C 99.059,52.639 76.744,35.56 72.703,32.468 C 77.433,32.468 97.34,32. [...]
+ style="opacity:0.2"
+ id="path77" /><path
+ d="M 34.342,15.451 C 33.35,15.449 32.468,16.079 32.147,17.021 C 31.829,17.969 32.145,19.006 32.933,19.608 L 109.271,78.03 C 109.974,78.569 110.909,78.66 111.707,78.266 C 112.502,77.877 112.999,77.081 112.999,76.189 L 112.999,17.768 C 112.999,17.147 112.758,16.565 112.318,16.127 C 111.88,15.69 111.297,15.45 110.678,15.451 L 110.679,15.451 L 34.342,15.451 L 34.342,15.451 z M 98.033,30.415 C 98.033,32.001 98.033,47.516 98.033,50.586 C 98.033,50.586 75.716,33.507 71.677,30.415 C 76.405,30 [...]
+ style="opacity:0.2"
+ id="path79" /><path
+ d="M 33.316,14.424 C 32.324,14.422 31.442,15.053 31.121,15.994 C 30.803,16.942 31.119,17.979 31.907,18.581 L 108.244,77.002 C 108.949,77.541 109.882,77.632 110.68,77.238 C 111.475,76.849 111.972,76.053 111.972,75.163 L 111.972,16.741 C 111.972,16.121 111.731,15.538 111.293,15.101 C 110.854,14.664 110.271,14.423 109.652,14.424 L 109.652,14.424 L 33.316,14.424 z M 97.008,29.388 C 97.008,30.974 97.006,46.489 97.006,49.559 C 97.006,49.559 74.691,32.48 70.65,29.388 C 75.378,29.388 95.287,2 [...]
+ style="opacity:0.2"
+ id="path81" /><path
+ d="M 33.316,13.397 C 32.324,13.395 31.442,14.025 31.121,14.967 C 30.803,15.915 31.119,16.952 31.907,17.554 L 108.244,75.975 C 108.949,76.516 109.882,76.605 110.68,76.213 C 111.475,75.822 111.972,75.028 111.972,74.136 L 111.972,15.714 C 111.972,15.094 111.731,14.511 111.293,14.074 C 110.854,13.637 110.271,13.397 109.652,13.398 L 109.652,13.398 L 33.316,13.398 L 33.316,13.397 z M 97.008,28.361 C 97.008,29.947 97.006,45.463 97.006,48.532 C 97.006,48.532 74.691,31.453 70.65,28.361 C 75.37 [...]
+ style="fill:url(#linearGradient2733)"
+ id="path88" /><path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:url(#linearGradient2730)"
+ id="path95" /><g
+ style="opacity:0.5"
+ id="g97">
+ <path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 108.362,71.523 C 104.591,68.639 42.553,21.157 37.128,17.003 C 43.885,17.004 105.992,17.004 108.362,17.004 C 108.362,19.362 108.362,66.86 108.362,71.523 M 100.614,55.839 L 100.614,26.042 L 100.614,24.751 L 59.994,24.751 L 100.614,55.839 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:#ffffff"
+ id="path99" />
+ </g><polygon
+ points="33.316,16.61 109.651,75.032 109.651,72.449 36.689,16.61 33.316,16.61 "
+ style="fill:#ffff66"
+ id="polygon101" /><path
+ d="M 109.651,75.032 L 109.651,72.449 L 108.362,71.462 C 108.362,71.861 108.362,72.201 108.362,72.42 C 104.591,69.535 42.553,22.053 37.128,17.899 C 37.433,17.899 37.855,17.9 38.378,17.9 L 36.689,16.61 L 33.316,16.61 L 109.651,75.032 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path103" /><g
+ transform="translate(1.450693,28.664084)"
+ id="g105">
+ <path
+ d="M 59.545,43.092 C 44.665,47.876 41.97,48.742 41.396,49.213 C 41.427,49.164 41.469,49.093 41.469,49.093 L 5.447,81.448 C 3.531,83.176 5.594,87.217 8.32,90.244 C 11.015,93.244 14.817,95.73 16.791,94.103 L 52.848,61.587 L 52.888,61.367 L 60.137,45.811 L 61.112,42.645 L 59.545,43.092 z "
+ style="opacity:0.2"
+ id="path107" />
+ <path
+ d="M 58.528,42.419 C 43.648,47.202 40.953,48.067 40.378,48.54 C 40.409,48.491 40.453,48.42 40.453,48.42 L 4.431,80.772 C 2.515,82.501 4.577,86.543 7.304,89.57 C 9.999,92.57 13.8,95.056 15.774,93.429 L 51.831,60.913 L 51.871,60.693 L 59.119,45.137 L 60.095,41.971 L 58.528,42.419 z "
+ style="opacity:0.2"
+ id="path109" />
+ <path
+ d="M 57.511,41.745 C 42.631,46.529 39.936,47.394 39.361,47.867 C 39.391,47.817 39.435,47.747 39.435,47.747 L 3.413,80.101 C 1.497,81.829 3.56,85.872 6.287,88.897 C 8.982,91.897 12.783,94.383 14.758,92.756 L 50.815,60.241 L 50.854,60.021 L 58.103,44.464 L 59.078,41.298 L 57.511,41.745 z "
+ style="opacity:0.2"
+ id="path111" />
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:#ffffff"
+ id="path113" />
+
+ <linearGradient
+ x1="7.4770999"
+ y1="77.034203"
+ x2="57.502499"
+ y2="48.2841"
+ id="XMLID_26_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#cf0000;stop-opacity:1"
+ offset="0"
+ id="stop116" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop118" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:url(#XMLID_26_)"
+ id="path120" />
+
+ <linearGradient
+ x1="313.06741"
+ y1="-177.2002"
+ x2="321.69031"
+ y2="-168.57651"
+ id="XMLID_27_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#f8f1dc;stop-opacity:1"
+ offset="0"
+ id="stop123" />
+ <stop
+ style="stop-color:#d6a84a;stop-opacity:1"
+ offset="1"
+ id="stop125" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#D6A84A" />
+ </linearGradient>
+ <path
+ d="M 39.683,49.903 L 55.387,44.251 L 48.013,59.231 L 47.951,59.163 C 47.918,59.266 47.876,59.366 47.821,59.452 L 47.87,59.502 L 13.449,90.519 L 13.407,90.468 C 12.381,91.394 9.662,90.043 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 39.389,50.094 L 39.683,49.903 z "
+ style="fill:url(#XMLID_27_)"
+ id="path127" />
+
+ <linearGradient
+ x1="329.35739"
+ y1="-197.62601"
+ x2="333.9407"
+ y2="-203.0881"
+ id="XMLID_28_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop130" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="1"
+ id="stop132" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFAE00" />
+ </linearGradient>
+ <path
+ d="M 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 12.725,74.119 L 23.636,73.644 L 23.959,81.047 L 13.451,90.518 L 13.409,90.467 C 12.381,91.394 9.662,90.043 7.331,87.458 z "
+ style="fill:url(#XMLID_28_)"
+ id="path134" />
+
+ <linearGradient
+ x1="302.5752"
+ y1="-214.1689"
+ x2="321.83981"
+ y2="-171.39861"
+ id="XMLID_29_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ff9200;stop-opacity:1"
+ offset="0"
+ id="stop137" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="0.77530003"
+ id="stop139" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop141" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.7753"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+ <path
+ d="M 13.177,90.633 C 13.907,89.919 13.497,88.163 12.274,86.249 C 11.869,85.613 11.371,84.959 10.796,84.322 C 10.251,83.715 9.684,83.185 9.123,82.727 C 7.315,81.253 5.563,80.63 4.763,81.295 L 4.753,81.284 L 39.4,50.059 C 40.332,49.796 42.077,50.301 43.666,51.604 C 44.208,52.051 44.76,52.568 45.286,53.157 C 45.877,53.81 46.388,54.482 46.8,55.136 C 48.037,57.089 48.529,58.967 47.748,59.673 C 47.567,59.835 46.786,60.537 46.757,60.556 L 13.266,90.73 L 13.177,90.633 z "
+ style="fill:url(#XMLID_29_)"
+ id="path143" />
+
+ <linearGradient
+ x1="56.380402"
+ y1="50.837399"
+ x2="49.402302"
+ y2="50.837399"
+ id="XMLID_30_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="0"
+ id="stop146" />
+ <stop
+ style="stop-color:#663333;stop-opacity:1"
+ offset="1"
+ id="stop148" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#663333" />
+ </linearGradient>
+ <path
+ d="M 48.455,46.795 L 55.096,44.432 L 52.305,50.113 C 52.305,50.113 52.256,49.275 51.055,48.063 C 49.472,46.458 48.455,46.795 48.455,46.795 z "
+ style="opacity:0.8;fill:url(#XMLID_30_)"
+ id="path150" />
+ <path
+ d="M 43.51,51.488 L 9.272,82.854 C 9.223,82.814 9.172,82.766 9.123,82.728 C 8.401,82.14 7.685,81.69 7.04,81.4 L 41.105,50.192 C 41.857,50.419 42.698,50.851 43.51,51.488 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path152" />
+ <path
+ d="M 9.123,82.728 C 8.804,82.467 8.485,82.238 8.175,82.03 L 42.351,50.72 C 42.789,50.957 43.235,51.248 43.666,51.604 C 44.035,51.91 44.409,52.25 44.777,52.619 L 10.509,84.014 C 10.052,83.534 9.586,83.104 9.123,82.728 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path154" />
+ </g></svg>
\ No newline at end of file
diff --git a/molsketch_helium/images/molsketch.xpm b/molsketch_helium/images/molsketch.xpm
new file mode 100644
index 0000000..61ae338
--- /dev/null
+++ b/molsketch_helium/images/molsketch.xpm
@@ -0,0 +1,465 @@
+/* XPM */
+static char *dummy[]={
+"32 32 430 2",
+"Qt c None",
+"bs c #000000",
+"az c #0100b2",
+"bO c #020000",
+"cz c #030202",
+"be c #040000",
+"aX c #050014",
+"ao c #0505b3",
+"bB c #060009",
+"c. c #060202",
+"b. c #060606",
+"aA c #0700aa",
+"br c #080808",
+"bN c #090909",
+"aB c #0a0095",
+"aJ c #0a00a4",
+"bf c #0b002f",
+"bC c #0b0031",
+"ap c #0c0389",
+"cN c #0c0707",
+"aK c #0f009c",
+"cl c #0f0b0b",
+"aY c #110076",
+"aL c #120095",
+"aM c #13008c",
+"bz c #130159",
+"bA c #140068",
+"bi c #14006e",
+"b4 c #140c0c",
+"bd c #151111",
+"bw c #151515",
+"bh c #160074",
+"bj c #160077",
+"aZ c #160087",
+"bg c #17007a",
+"a1 c #170080",
+"a0 c #170082",
+"bk c #170170",
+"b2 c #171717",
+"by c #19141e",
+"cw c #1a1616",
+"co c #1a1a1a",
+"bD c #1c0980",
+"bU c #1e193b",
+"bx c #1e1a1a",
+"ba c #212121",
+"a2 c #22055f",
+"b# c #282828",
+"bP c #291e1e",
+"cV c #2c2a2a",
+"b3 c #2c2c2c",
+"a9 c #2e2e2e",
+"bK c #323232",
+"db c #3a1f1f",
+"bT c #3c2f86",
+"aN c #3d0f4c",
+"dL c #400000",
+"aW c #403b5e",
+"bJ c #414141",
+"cx c #494646",
+"bb c #4b4b4b",
+"dK c #4c3b3b",
+"bt c #4f4f4f",
+"cm c #504d4d",
+"bv c #555555",
+"cJ c #560000",
+"c# c #575454",
+"cM c #585858",
+"dt c #5b5858",
+"cI c #5f1313",
+"cK c #612b2b",
+"aI c #6260cb",
+"b5 c #6c3b3b",
+"bM c #707070",
+"ae c #72577d",
+"bL c #737373",
+"bu c #747474",
+"aC c #753440",
+"cf c #753e3d",
+"eG c #810000",
+"ay c #8383d7",
+"eH c #840000",
+"cy c #868686",
+"eF c #870000",
+"bc c #878585",
+"eu c #8d0000",
+"ev c #8e0000",
+"et c #900000",
+"cp c #904641",
+"bl c #904b3e",
+"eE c #910101",
+"du c #930000",
+"ew c #933939",
+"es c #960000",
+"ei c #970000",
+"da c #97433e",
+"ej c #980000",
+"ek c #983939",
+"eh c #990000",
+"dc c #9a0000",
+"eI c #9a5050",
+"bQ c #9c7777",
+"eg c #9d0000",
+"d6 c #9e3b3b",
+"d5 c #9f0000",
+"d4 c #a00000",
+"b8 c #a05352",
+"ef c #a10000",
+"cU c #a1463b",
+"d3 c #a30000",
+"dR c #a33d3d",
+"b7 c #a35249",
+"#M c #a39490",
+"b6 c #a45754",
+"#L c #a49591",
+"#K c #a59692",
+"dO c #a60000",
+"ck c #a69090",
+"#J c #a69793",
+"dN c #a70000",
+"ee c #a70404",
+"dM c #a80000",
+"cA c #a84d43",
+"cu c #a85048",
+"cG c #a88787",
+"d2 c #a90000",
+"dv c #aa0000",
+"cn c #aaa7a5",
+"cZ c #ab0000",
+"#I c #ac7363",
+"dP c #ad1717",
+"bF c #ad836f",
+"dQ c #af1c1c",
+"#n c #af806f",
+"bE c #afadcf",
+"cj c #b06a55",
+"a# c #b14c3d",
+"#6 c #b17b62",
+"bS c #b2acd0",
+"cW c #b3b2b2",
+"eO c #b46969",
+"dr c #b4706e",
+"dI c #b47c7c",
+"dd c #b51f1f",
+"c3 c #b52d2d",
+"dZ c #b58989",
+"aj c #b592aa",
+"aq c #b66f4c",
+"eb c #b79696",
+"bX c #b8a79e",
+"eR c #b8b8b8",
+"dz c #ba7b7b",
+"eq c #baa2a2",
+"cO c #bb5342",
+"#C c #bba6a0",
+"df c #bc7474",
+".6 c #bc7654",
+"ds c #bcbbbb",
+"eB c #bdafaf",
+"eD c #be5e5e",
+"eQ c #bebebe",
+"#4 c #c0c0c0",
+"ad c #c1c1c1",
+"am c #c2c2c2",
+"c2 c #c34848",
+"eN c #c37f7f",
+"#Q c #c3c3c3",
+"aT c #c4c4c4",
+"a7 c #c5c5c5",
+"c0 c #c65252",
+"#S c #c67f53",
+"bp c #c6c6c6",
+"#B c #c7c7c7",
+"cY c #c86363",
+"a3 c #c8834c",
+"b1 c #c8c8c8",
+"#N c #c9623a",
+"er c #c97171",
+"aa c #c9bcd5",
+"cd c #c9c9c9",
+"cb c #ca864e",
+"dA c #cacaca",
+"ca c #cbc9c7",
+".I c #cc6b52",
+".H c #cc6b53",
+"cg c #cc7859",
+"eL c #ccc5c5",
+"dJ c #cccbcb",
+"#m c #cccccc",
+".G c #cd6c54",
+".F c #cd6d55",
+".E c #cd6e55",
+".J c #cd7a67",
+"a8 c #cdcdcd",
+"an c #cdcded",
+".D c #ce6f57",
+"cF c #ce7846",
+"ex c #ce9090",
+"bV c #cecde1",
+"cv c #cecece",
+".C c #cf7059",
+".B c #cf705a",
+"dS c #cf8989",
+"#2 c #d06d43",
+"dg c #d0b1b1",
+"c6 c #d15f45",
+".A c #d17360",
+"c1 c #d17373",
+"dw c #d17777",
+"ai c #d26d40",
+"ab c #d27044",
+"#X c #d2856d",
+".L c #d38559",
+"eK c #d38989",
+"eP c #d3a4a4",
+"#R c #d3cecd",
+"ak c #d47244",
+"av c #d48f7a",
+"aw c #d57444",
+"b9 c #d5d5d5",
+"bq c #d6d6d6",
+"dj c #d7d7d7",
+"el c #d8382e",
+"di c #d8d8d8",
+".h c #d9d9d9",
+"dl c #da6540",
+".g c #dadada",
+"#H c #db7747",
+".f c #dbdbdb",
+"dh c #dcdada",
+".e c #dcdcdc",
+".d c #dddddd",
+".c c #dedede",
+".4 c #df8048",
+".b c #dfdfdf",
+"ey c #e0502f",
+".5 c #e0dedd",
+".a c #e0e0e0",
+"#l c #e18046",
+"#A c #e18146",
+"#D c #e1a665",
+"dx c #e1a8a8",
+"dy c #e1a9a9",
+"ch c #e1bead",
+"c4 c #e1c9c9",
+".# c #e1e1e1",
+"aG c #e26f32",
+"dY c #e27427",
+"af c #e2ad67",
+"d1 c #e2b9b9",
+"ce c #e2e2e2",
+"eA c #e36c39",
+"#P c #e38246",
+"cH c #e3c1c1",
+"aU c #e3e3e3",
+"eM c #e4c7c7",
+"#3 c #e58546",
+"bY c #e5a75a",
+"d7 c #e66731",
+"ep c #e67934",
+"dH c #e67b25",
+"ea c #e67c2e",
+"ac c #e68646",
+"de c #e6b3b3",
+"d0 c #e6e6e6",
+"al c #e78746",
+"#y c #e79055",
+"#x c #e79156",
+"#w c #e79158",
+"#v c #e7925b",
+"#u c #e7935c",
+"#t c #e7935e",
+"#s c #e79460",
+"aV c #e7e7e7",
+"dC c #e87f40",
+"ax c #e88946",
+"#5 c #e8e8e8",
+"bR c #e9e9e9",
+"aH c #ea8b46",
+"au c #ea9758",
+"ec c #eaeaea",
+"aS c #eb8c46",
+"#z c #eb9f61",
+"#W c #eba067",
+"aO c #ebbc6d",
+"ct c #ebd5ab",
+"bW c #ebebeb",
+"dq c #ec7c21",
+"a6 c #ec8e46",
+"#1 c #ececec",
+"cc c #ed9d4b",
+"dk c #edd8d8",
+"#0 c #ededed",
+"bo c #ee9046",
+"#r c #eeaf7c",
+"c5 c #eee3e3",
+"cL c #eeebeb",
+"#Y c #eeecec",
+"#Z c #eeeeee",
+"dB c #efcdcd",
+"cX c #efecec",
+".x c #efefef",
+"bI c #f09146",
+".y c #f0f0f0",
+"d# c #f1781d",
+"b0 c #f19548",
+"#o c #f1cd7e",
+"ed c #f1e8e8",
+".w c #f1f1f1",
+".v c #f2f2f2",
+"dT c #f3963f",
+"cq c #f3b150",
+".u c #f3f3f3",
+"bG c #f4cb71",
+"eJ c #f4dddd",
+"ci c #f4e8ce",
+".t c #f4f4f4",
+"cT c #f57617",
+"aF c #f5b56f",
+"a. c #f5be7e",
+"#7 c #f5d580",
+"eC c #f5f2f2",
+".i c #f5f5f5",
+".s c #f6f6f6",
+".r c #f7f7f7",
+"ez c #f8a933",
+"cB c #f8be55",
+".q c #f8f8f8",
+"aD c #f9dc82",
+".7 c #f9e28b",
+".K c #f9f4f3",
+".p c #f9f9f9",
+"bm c #fae081",
+"#T c #fae58b",
+".z c #faf0ee",
+".o c #fafafa",
+".n c #fbfbfb",
+"cs c #fcab5f",
+"cP c #fcc359",
+"ah c #fcce82",
+"#G c #fcd591",
+"a4 c #fce684",
+"ar c #fce689",
+"ag c #fce78a",
+"#E c #fce88f",
+".M c #fced9e",
+".m c #fcfcfc",
+"c7 c #fdc760",
+"aQ c #fdd07e",
+"aP c #fde383",
+"bZ c #fde47f",
+"#p c #fde996",
+".l c #fdfdfd",
+"dm c #feca65",
+"at c #fed47e",
+"bH c #fedf78",
+"#8 c #fee48e",
+".k c #fefefe",
+"cE c #ff6e00",
+"cS c #ff7b00",
+"d. c #ff8900",
+"dp c #ff9700",
+"cD c #ff9828",
+"cR c #ff9f1e",
+"dG c #ffa500",
+"e. c #ffa904",
+"c9 c #ffa917",
+"eo c #ffab06",
+"e# c #ffac02",
+"dW c #ffac07",
+"dX c #ffae01",
+"en c #ffae14",
+"dF c #ffb00b",
+"do c #ffb210",
+"em c #ffbc2d",
+"d8 c #ffc65f",
+"d9 c #ffc966",
+"#k c #ffca5b",
+"#j c #ffcb5f",
+"dD c #ffcb6a",
+"dU c #ffcc70",
+"#i c #ffcd64",
+"#h c #ffce69",
+"dV c #ffce70",
+"cr c #ffce90",
+"aR c #ffcf6a",
+"#O c #ffcf6c",
+"#g c #ffd06d",
+"a5 c #ffd16c",
+".3 c #ffd170",
+"#f c #ffd172",
+".2 c #ffd273",
+"dE c #ffd279",
+".1 c #ffd377",
+"cC c #ffd390",
+".0 c #ffd47c",
+"#e c #ffd57b",
+"dn c #ffd581",
+".Z c #ffd67f",
+"#d c #ffd680",
+"#9 c #ffd782",
+".Y c #ffd784",
+"#c c #ffd885",
+"c8 c #ffd888",
+"cQ c #ffd88d",
+"bn c #ffd972",
+"as c #ffd97e",
+".X c #ffd988",
+"#b c #ffd989",
+".W c #ffda8c",
+"#V c #ffda8d",
+"#a c #ffdb8e",
+".V c #ffdb90",
+"#F c #ffdc92",
+"## c #ffdc93",
+".U c #ffdd94",
+"#. c #ffde97",
+".T c #ffde98",
+"aE c #ffdf81",
+".9 c #ffdf9c",
+"#U c #ffe090",
+".S c #ffe09c",
+".R c #ffe0a1",
+"#q c #ffe2a3",
+".Q c #ffe2a4",
+".P c #ffe3a8",
+".O c #ffe5ad",
+".8 c #ffe7a0",
+".N c #ffe7ae",
+".j c #ffffff",
+"QtQt.#.#.#.#.a.a.b.b.b.c.c.d.d.d.d.e.e.f.f.f.g.g.h.h.h.h.h.hQtQt",
+"QtQt.i.j.j.j.j.j.j.j.j.j.j.k.l.l.m.n.o.p.q.r.s.i.t.u.v.w.w.xQtQt",
+"QtQt.s.j.j.j.j.j.j.j.j.j.j.k.l.m.n.o.p.q.r.s.s.i.t.u.v.w.y.xQtQt",
+"QtQt.s.j.j.j.j.z.A.B.C.C.C.D.D.D.D.E.F.F.G.G.G.H.I.I.I.J.y.xQtQt",
+"QtQt.r.j.j.j.j.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.f.xQtQt",
+"QtQt.r.j.j.j.j.j.5.6.7.8.9#.###a#b#c#d#e.1#f#g#h#i#j#k#l#m.yQtQt",
+"QtQt.r.j.j.j.j.j.j.v#n#o#p#.###q#r#s#t#u#v#w#x#y#z#h#k#A#B.wQtQt",
+"QtQt.r.j.j.j.j.j.j.j.n#C#D#E#F#a#G#H#I#J#K#L#M#M#N#O#k#P#Q.wQtQt",
+"QtQt.q.j.j.j.j.j.j.j.k.l#R#S#T#U#b#V#W#X#Y#Z#0#1#2#O#k#3#4.vQtQt",
+"QtQt.q.j.j.j.j.j.j.k.l.m.n#5#6#7#8#c#9a.a#aa.v.wab#O#kacad.vQtQt",
+"QtQt.q.j.j.j.j.j.j.k.l.m.n.o.taeafag.Z#eahaiaj.wak#O#kalam.uQtQt",
+"QtQt.p.j.j.j.j.j.k.l.m.n.o.panaoapaqaras.1atauavaw#O#kax#Q.uQtQt",
+"QtQt.p.j.j.j.j.j.k.l.m.n.o.payazaAaBaCaDaE#f#faFaG#O#kaH#Q.tQtQt",
+"QtQt.p.j.j.j.j.k.l.m.n.o.p.qaIaJaKaLaMaNaOaP#g#haQaR#kaSaT.tQtQt",
+"QtQt.o.j.j.jaUaT#1.m.n.o.paVaWaXaYaZa0a1a2a3a4a5#i#j#ka6a7.iQtQt",
+"QtQt.o.ja8a9b.b#babb.#.wbcbdbebebfbgbhbibjbkblbmbn#j#kbobp.iQtQt",
+"QtQt.obqbrbsbtbububvbwbxbebebebybzbAbBbebCbDbEbFbGbH#kbI#B.sQtQt",
+"QtQt.qbJbsbsbKbLbubMbNbObebPbQbRbSbTbebebUbVbW#5bXbYbZb0b1.sQtQt",
+"QtQt.yb.bsbsbsb2b3b2b4b5b6b7b8b9#1#1c.bec##1#1#1#1cacbcccd.rQtQt",
+"QtQtcebsbsbsbsbsbscfcgchcicjckbW#Z#Zclbecm#Z#Z#Z#Z#Z.acnbq.qQtQt",
+"QtQt.qcobsbsbsbscpcqcrcsctcucv.x.x.xcwbecx.x.x.x.x.x.x#Z#Z.qQtQt",
+"QtQt.qcybsbsczcAcBcCcDcEcFcGbW.y.ycHcIcJcKcL.y.y.y.y.y.y.y.qQtQt",
+"QtQt.p.xcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4bWbWbWbWbWbW.uQtQt",
+"QtQt.p.vc5c6c7c8c9d.d#dabebebedbdcdddedededfdgdh.gdidjdjdjb1QtQt",
+"QtQt.pdkdldmdndodpdqdrdsdtc.bebedudvdwdxdydz.m.m.l.k.j.j.ydAQtQt",
+"QtQtdBdCdDdEdFdGdHdI.b.u.udJdKdLdMdNdOdPdQdR.o.r.q.p.o#1cdQtQtQt",
+"QtdSdTdUdVdWdXdYdZd0.t.t.t.td1d2dOd3d4d5d4d6.r.w.u.taV#BQtQtQtQt",
+"Qtd7d8d9e.e#eaebec.i.i.i.i.iedeeefegeheiejek.t#1#Z.#a7QtQtQtQtQt",
+"Qtelemeneoepeq.x.s.s.s.s.s.s.seregeseteuevew.vaV.e#QQtQtQtQtQtQt",
+"QtexeyezeAeB.u.r.r.r.r.r.r.r.reCeDeEeFeGeHeI.xbq#4QtQtQtQtQtQtQt",
+"QtQteJeKeL.s.q.q.q.q.q.q.q.q.q.q.qeMeNeOePcv.beQQtQtQtQtQtQtQtQt",
+"QtQt.h.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.gameRQtQtQtQtQtQtQtQtQt"};
diff --git a/molsketch_helium/images/transform-move.png b/molsketch_helium/images/transform-move.png
new file mode 100644
index 0000000..ef04038
Binary files /dev/null and b/molsketch_helium/images/transform-move.png differ
diff --git a/molsketch_helium/images/transform-rotate.png b/molsketch_helium/images/transform-rotate.png
new file mode 100644
index 0000000..ead9cf4
Binary files /dev/null and b/molsketch_helium/images/transform-rotate.png differ
diff --git a/molsketch_helium/images/zoom-fit-best.png b/molsketch_helium/images/zoom-fit-best.png
new file mode 100644
index 0000000..d364c62
Binary files /dev/null and b/molsketch_helium/images/zoom-fit-best.png differ
diff --git a/molsketch_helium/images/zoom-in.png b/molsketch_helium/images/zoom-in.png
new file mode 100644
index 0000000..8393e28
Binary files /dev/null and b/molsketch_helium/images/zoom-in.png differ
diff --git a/molsketch_helium/images/zoom-original.png b/molsketch_helium/images/zoom-original.png
new file mode 100644
index 0000000..a268a99
Binary files /dev/null and b/molsketch_helium/images/zoom-original.png differ
diff --git a/molsketch_helium/images/zoom-out.png b/molsketch_helium/images/zoom-out.png
new file mode 100644
index 0000000..f66575e
Binary files /dev/null and b/molsketch_helium/images/zoom-out.png differ
diff --git a/molsketch_helium/mainwindow.cpp b/molsketch_helium/mainwindow.cpp
new file mode 100644
index 0000000..ec55f0f
--- /dev/null
+++ b/molsketch_helium/mainwindow.cpp
@@ -0,0 +1,1250 @@
+/***************************************************************************
+ * Copyright (C) 2007-2008 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QtGui>
+#include <QtAssistant/QAssistantClient>
+
+#include "molecule.h"
+#include "mainwindow.h"
+#include "molview.h"
+#include "molscene.h"
+#include "element.h"
+#include "settings.h"
+#include "fileio.h"
+#include "mollibitem.h"
+#include "periodictablewidget.h"
+
+#define PROGRAM_NAME "molsKetch"
+#define PROGRAM_VERSION "Helium"
+
+#define ALT_DOC_PATH ""
+#define ALT_LIB_PATH ""
+#define ALT_CUSTOM_LIB_PATH ""
+
+#define OB_FILE_FORMATS "All supported types (*.*);;SMILES (*.smi);;MDL Molfile (*.mdl *.mol *.sd *.sdf);;XYZ (*.xyz);;ChemDraw Connection Table (*.ct);;Ghemical (*.gpr)"
+#define OB_DEFAULT_FORMAT "MDL Molfile (*.mdl *.mol *.sd *.sdf)"
+#define GRAPHIC_FILE_FORMATS "Scalable Vector Graphics (*.svg);;Portable Network Graphics (*.png);;Windows Bitmap (*.bmp);;Joint Photo Expert Group (*.jpeg)"
+#define GRAPHIC_DEFAULT_FORMAT "Scalable Vector Graphics (*.svg)"
+
+// Constructor
+using namespace std;
+MainWindow::MainWindow()
+{
+ // Creating the menus and actions
+ createView();
+ createToolBoxes();
+ createActions();
+ createMenus();
+ createToolBars();
+ createStatusBar();
+ initializeAssistant();
+
+ // Set icon
+ QIcon icon;
+ icon.addFile(":/images/molsketch.svg");
+ icon.addFile(":/images/molsketch.png");
+ setWindowIcon(icon);
+
+ // Loading settings
+ readSettings();
+
+ QStringList args = qApp->arguments();
+ args.removeFirst();
+ QRegExp rx("^[^\\-]");
+ QStringList loadedFiles;
+
+ foreach(QString fileName, args.filter(rx)) {
+ Molecule* mol = molsKetch::loadFile(fileName);
+ if (mol)
+ {
+ m_scene->addMolecule(mol);
+ loadedFiles << fileName;
+ }
+ else
+ {
+ // Display error message if load fails
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Error while loading file"),QMessageBox::Ok,QMessageBox::Ok);
+ }
+ }
+ setCurrentFile("");
+ if (loadedFiles.count() == 1) setCurrentFile(loadedFiles.first());
+
+ // Connecting signals and slots
+ connect(m_scene->stack(),SIGNAL(cleanChanged(bool)), this, SLOT(documentWasModified( )));
+ connect(m_scene,SIGNAL(selectionChange()), this, SLOT(updateInfoBox()));
+// connect(m_scene,SIGNAL(newMolecule(QPointF,QString)),this, SLOT(newMolecule(QPointF,QString)));
+ connect(m_scene,SIGNAL(editModeChange(int)),this,SLOT(updateEditMode(int)));
+
+ connect(recentLib,SIGNAL(itemClicked(QListWidgetItem*)),m_scene,SLOT(setElement(QListWidgetItem*)));
+ connect(recentLib,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(updateRecentList(QListWidgetItem*)));
+ connect(periodicTable,SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)),m_scene,SLOT(setElement(QTableWidgetItem*)));
+ connect(periodicTable,SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)),this,SLOT(updateRecentList(QTableWidgetItem*)));
+}
+
+// Molecuul manipulation methods
+// Molecule* MainWindow::newMolecule(const QPointF& position, const QString& element)
+// {
+// // Creating a new molecule object
+// Molecule* mol = new Molecule(0,m_scene);
+//
+// // Adding the molecule to the scene
+// // m_scene->addItem(mol);
+// mol->setPos(position);
+//
+// // Adding a atom to the molecule
+// mol->addMsKAtom(element,position);
+//
+// // cerr << "Molecule added \n";
+//
+// return mol;
+// }
+
+
+// Event handlers
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (maybeSave())
+ {
+ writeSettings();
+ if (assistantClient) assistantClient->closeAssistant();
+ event->accept();
+ }
+ else
+ {
+ event->ignore();
+ }
+}
+
+void MainWindow::newFile()
+{
+ if (maybeSave())
+ {
+ m_scene->clear();
+ // Resetting the view
+ setCurrentFile("");
+ m_molView->resetMatrix();
+// setWindowModified(false);
+ }
+}
+
+void MainWindow::open()
+{
+ if (maybeSave())
+ {
+// QFileDialog dialog(this);
+// dialog.(tr("Open - molsKetch"));
+// dialog.setFilter(tr(OB_FILE_FORMATS));
+// dialog.selectFilter(tr("Chemical Markup Language (*.mol)"));
+// dialog.setFileMode(QFileDialog::ExistingFile);
+// QString fileName;
+// if (dialog.exec()) fileName = dialog.selectedFiles()[0];
+ QString fileName = QFileDialog::getOpenFileName(this,tr("Open - molsKetch"), m_lastAccessedPath,
+ tr(OB_FILE_FORMATS));
+ if (fileName.isEmpty()) return;
+
+ // Save accessed path
+ m_lastAccessedPath = QFileInfo(fileName).path();
+
+ // Start a new document
+ m_scene->clear();
+
+ Molecule* mol = molsKetch::loadFile(fileName);
+
+ if (mol)
+ {
+ // Add molecule to scene
+ if (mol->canSplit())
+ {
+ QList<Molecule*> molList = mol->split();
+ foreach(Molecule* mol,molList) m_scene->addItem(mol);
+ }
+ else
+ {
+ m_scene->addItem(mol);
+ }
+
+ // Updating view
+ setCurrentFile(fileName);
+// setWindowModified(false);
+ }
+ else
+ {
+ // Display error message if load fails
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Error while loading file"),QMessageBox::Ok,QMessageBox::Ok);
+ }
+ }
+}
+
+bool MainWindow::save()
+{
+ if (m_curFile.isEmpty())
+ {
+ return saveAs();
+ }
+ else
+ {
+ if (molsKetch::saveFile(m_curFile, m_scene))
+ {
+ m_scene->stack()->setClean();
+ }
+ else
+ return false;
+ }
+// setWindowModified(false);
+}
+
+bool MainWindow::autoSave()
+{
+ QFileInfo fileName(m_curFile);
+
+ // Do nothing if there is nothing to save
+ if(m_scene->stack()->isClean()) return true;
+
+ // Else construct the filename
+ if (!fileName.exists())
+ {
+ fileName = QDir::homePath() + tr("/untitled.backup.mdl");
+ }
+ else
+ {
+ fileName = QFileInfo(m_curFile).path() + QFileInfo(m_curFile).baseName() + ".backup." + QFileInfo(m_curFile).completeSuffix();
+ }
+
+ // And save the file
+ if (molsKetch::saveFile(fileName.absoluteFilePath(), m_scene)) {
+ statusBar()->showMessage(tr("Document autosaved"), 10000);
+ return true;
+ }
+
+ // or display a waring on failure
+ statusBar()->showMessage(tr("Autosave failed!"), 10000);
+ return false;
+}
+
+bool MainWindow::saveAs()
+{
+ // Get the filename to save under
+ QString filter = OB_DEFAULT_FORMAT;
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Save as - molsKetch"), m_lastAccessedPath, tr(OB_FILE_FORMATS), &filter);
+ if (fileName.isEmpty()) return false;
+
+ // Save accessed path
+ m_lastAccessedPath = QFileInfo(fileName).path();
+
+ // Finding the right extension
+ if (QFileInfo(fileName).suffix().isEmpty())
+ {
+ int index = filter.indexOf(QRegExp("\\*."));
+ filter = filter.remove(0, index + 1);
+ index = filter.indexOf(QRegExp("( \\*.)|(\\))"));
+ if (index > 0) filter.truncate(index);
+ fileName = fileName + filter;
+ }
+ qDebug() << "Trying to save as " << fileName << "\n";
+
+ // Try to save the document
+ if (molsKetch::saveFile(fileName,m_scene))
+ {
+ setCurrentFile(fileName);
+ m_scene->stack()->setClean();
+ return true;
+ }
+ else
+ {
+ // Display error message if saving fails
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Invalid name or unknown file type"),QMessageBox::Ok,QMessageBox::Ok);
+ return false;
+ }
+}
+
+bool MainWindow::importDoc()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Import - molsKetch"), m_lastAccessedPath, tr(OB_FILE_FORMATS));
+
+
+ if (!fileName.isEmpty())
+ {
+ // Save accessed path
+ m_lastAccessedPath = QFileInfo(fileName).path();
+
+ Molecule* mol = molsKetch::loadFile(fileName);
+ if (mol)
+ {
+ m_scene->addMolecule(mol);
+ return true;
+ }
+ else
+ {
+ // Display error message if load fails
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Error while loading file"),QMessageBox::Ok,QMessageBox::Ok);
+ return false;
+ }
+ }
+ return false;
+}
+
+bool MainWindow::exportDoc()
+{
+ // Getting the filename
+ QString filter = GRAPHIC_DEFAULT_FORMAT;
+ QString fileName = QFileDialog::getSaveFileName(this,tr("Export - molsKetch"), m_lastAccessedPath,tr(GRAPHIC_FILE_FORMATS), &filter);
+
+ // Abort if filename is empty
+ if (fileName.isEmpty()) return false;
+
+ // Save accessed path
+ m_lastAccessedPath = QFileInfo(fileName).path();
+
+ // Finding the right extension
+ if (QFileInfo(fileName).suffix().isEmpty())
+ {
+ int index = filter.indexOf(QRegExp("\\*."));
+ filter = filter.remove(0, index + 1);
+ index = filter.indexOf(QRegExp("( \\*.)|(\\))"));
+ if (index > 0) filter.truncate(index);
+ fileName = fileName + filter;
+ }
+ qDebug() << "Trying to export as " << fileName << "\n";
+
+ m_lastAccessedPath = QFileInfo(fileName).path();
+
+ // Try to export the file
+ if (fileName.endsWith(".svg")) return molsKetch::saveToSVG(fileName, m_scene);
+
+ if (molsKetch::exportFile(fileName,m_scene))
+ {
+ return true;
+ }
+ else
+ {
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Error while exporting file"),QMessageBox::Ok,QMessageBox::Ok);
+ return false;
+ }
+}
+
+bool MainWindow::print()
+{
+ // Creating a new printerobject
+ QPrinter printer(QPrinter::HighResolution);
+
+ // Prompt for the printoptions
+ QPrintDialog printDialog(&printer, this);
+
+ // Try to print the scene
+ if (printDialog.exec() == QDialog::Accepted)
+ {
+ if (molsKetch::printFile(printer,m_scene))
+ {
+ return true;
+ }
+ else
+ {
+ QMessageBox::critical(this,tr(PROGRAM_NAME),tr("Error while printing file"),QMessageBox::Ok,QMessageBox::Ok);
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+void MainWindow::setAddMode()
+{
+ m_scene->setEditMode(MolScene::AddMode);
+}
+
+void MainWindow::setRemoveMode()
+{
+ m_scene->setEditMode(MolScene::RemoveMode);
+}
+
+void MainWindow::setMoveMode()
+{
+ m_scene->setEditMode(MolScene::MoveMode);
+}
+
+void MainWindow::setRotateMode()
+{
+ m_scene->setEditMode(MolScene::RotateMode);
+}
+
+void MainWindow::zoomIn()
+{
+ m_molView->scale(2,2);
+}
+
+void MainWindow::zoomOut()
+{
+ m_molView->scale(0.5,0.5);
+}
+
+void MainWindow::zoomReset()
+{
+ m_molView->resetMatrix();
+}
+
+void MainWindow::zoomFit()
+{
+ m_molView->fitInView(m_scene->itemsBoundingRect(),Qt::KeepAspectRatio);
+}
+
+void MainWindow::assistant()
+{
+ QFileInfo file(ALT_DOC_PATH + QString("/index.html"));
+ if (!file.exists()) file.setFile(QApplication::applicationDirPath() + "/doc/en/index.html");
+ if (!file.exists()) file.setFile(QApplication::applicationDirPath() + "/../share/doc/molsketch/doc/en/index.html");
+ assistantClient->showPage(file.absoluteFilePath());
+}
+
+void MainWindow::about()
+{
+ QMessageBox::about(this, tr("About"),
+ tr("<H3>About molsKetch</H3> <P> molsKetch is a program for drawing molecular structures developed by Harm van Eersel at the <A href=\"http://www.tue.nl\">Eindhoven University of Technology</A>.<P> For more info check <A href=\"http://molsketch.sourceforge.net\">http://molsketch.sourceforge.net</A> <P> It is <A href=\"http://www.gnu.org/philosophy/free-sw.html\">free software</A> and available under the <A>GPL</A>. <P> Special thanks to: <UL><LI>Dr. H. Zantema (coac [...]
+}
+
+void MainWindow::documentWasModified()
+{
+ setWindowModified(!m_scene->stack()->isClean());
+}
+
+void MainWindow::updateEditMode(int mode)
+{
+ // Change the buttonstates depending on the edit mode
+ switch (mode)
+ {
+ case MolScene::AddMode:
+ addModeAct->setChecked(true);
+ delModeAct->setChecked(false);
+ moveModeAct->setChecked(false);
+ rotateModeAct->setChecked(false);
+ m_molView->setDragMode(QGraphicsView::NoDrag);
+ statusBar()->showMessage(tr("Left Click: add atom, Drag: add bond, Click on bond: change order, Shift + Left Click on bond: change type, Right Click: remove item"));
+ break;
+ case MolScene::RemoveMode:
+ addModeAct->setChecked(false);
+ delModeAct->setChecked(true);
+ moveModeAct->setChecked(false);
+ rotateModeAct->setChecked(false);
+ m_molView->setDragMode(QGraphicsView::NoDrag);
+ statusBar()->showMessage(tr("Click on an item to delete it. Double click on an molecule to delete it."));
+ break;
+ case MolScene::MoveMode:
+ addModeAct->setChecked(false);
+ delModeAct->setChecked(false);
+ moveModeAct->setChecked(true);
+ rotateModeAct->setChecked(false);
+ m_molView->setDragMode(QGraphicsView::RubberBandDrag);
+ statusBar()->showMessage(tr("Click on an item to select it. Drag to move selected items."));
+ break;
+ case MolScene::RotateMode:
+ addModeAct->setChecked(false);
+ delModeAct->setChecked(false);
+ moveModeAct->setChecked(false);
+ rotateModeAct->setChecked(true);
+ m_molView->setDragMode(QGraphicsView::NoDrag);
+ statusBar()->showMessage(tr("Click on an item to select it. Drag: rotate Z axis, Control + drag: rotate X axis, Shift + drag: rotate Y axis"));
+ break;
+ }
+}
+
+// Widget creators
+
+void MainWindow::createActions()
+{
+ newAct = new QAction(QIcon(":/images/document-new.png"), tr("&New"),this);
+ newAct->setShortcut(tr("Ctrl+N"));
+ newAct->setStatusTip(tr("Create a new file"));
+ connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
+
+ openAct = new QAction(QIcon(":/images/document-open.png"),tr("&Open..."), this);
+ openAct->setShortcut(tr("Ctrl+O"));
+ openAct->setStatusTip(tr("Open an existing file"));
+ connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
+
+ saveAct = new QAction(QIcon(":/images/document-save.png"), tr("&Save"), this);
+ saveAct->setShortcut(tr("Ctrl+S"));
+ saveAct->setStatusTip(tr("Save the document to disk"));
+ connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
+
+ saveAsAct = new QAction(QIcon(":/images/document-save-as.png"),tr("Save &As..."), this);
+ saveAsAct->setStatusTip(tr("Save the document under a new name"));
+ connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
+
+ autoSaveAct = new QAction(tr("Autosave document"), this);
+ m_autoSaveTimer = new QTimer(this);
+// m_autoSaveTimer->setInterval(m_autoSaveTime);
+ connect(autoSaveAct, SIGNAL(triggered()), this, SLOT(autoSave()));
+ connect(m_autoSaveTimer, SIGNAL(timeout()), autoSaveAct, SIGNAL(triggered()));
+// m_autoSaveTimer->start();
+
+ importAct = new QAction(QIcon(":/images/document-import.png"),tr("&Import..."), this);
+ importAct->setShortcut(tr("Ctrl+I"));
+ importAct->setStatusTip(tr("Insert an existing molecule into the document"));
+ connect(importAct, SIGNAL(triggered()), this, SLOT(importDoc()));
+
+ exportAct = new QAction(QIcon(":/images/document-export.png"),tr("&Export..."), this);
+ exportAct->setShortcut(tr("Ctrl+E"));
+ exportAct->setStatusTip(tr("Export the current document as a picture"));
+ connect(exportAct, SIGNAL(triggered()), this, SLOT(exportDoc()));
+
+ printAct = new QAction(QIcon(":/images/document-print.png"),tr("&Print..."), this);
+ printAct->setShortcut(tr("Ctrl+P"));
+ printAct->setStatusTip(tr("Print the current document"));
+ connect(printAct, SIGNAL(triggered()), this, SLOT(print()));
+
+ exitAct = new QAction(QIcon(":/images/application-exit.png"),tr("E&xit"), this);
+ exitAct->setShortcut(tr("Ctrl+Q"));
+ exitAct->setStatusTip(tr("Exit the application"));
+ connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
+
+ // Edit actions
+ undoAct = m_scene->stack()->createUndoAction(this);
+ undoAct->setIcon(QIcon(":/images/edit-undo.png"));
+ undoAct->setShortcut(tr("Ctrl+Z"));
+ undoAct->setStatusTip(tr("Undo the last action"));
+
+ redoAct = m_scene->stack()->createRedoAction(this);
+ redoAct->setIcon(QIcon(":/images/edit-redo.png"));
+ redoAct->setShortcut(tr("Ctrl+Shift+Z"));
+ redoAct->setStatusTip(tr("Redo the last action"));
+
+ cutAct = new QAction(QIcon(":/images/edit-cut.png"), tr("Cu&t"), this);
+ cutAct->setShortcut(tr("Ctrl+X"));
+ cutAct->setStatusTip(tr("Cut the current selection's contents to the "
+ "clipboard"));
+ connect(cutAct, SIGNAL(triggered()), m_scene, SLOT(cut()));
+
+ copyAct = new QAction(QIcon(":/images/edit-copy.png"), tr("&Copy"), this);
+ copyAct->setShortcut(tr("Ctrl+C"));
+ copyAct->setStatusTip(tr("Copy the current selection's contents to the "
+ "clipboard"));
+ connect(copyAct, SIGNAL(triggered()), m_scene, SLOT(copy()));
+
+ pasteAct = new QAction(QIcon(":/images/edit-paste.png"), tr("&Paste"), this);
+ pasteAct->setShortcut(tr("Ctrl+V"));
+ pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
+ "selection"));
+ connect(pasteAct, SIGNAL(triggered()), m_scene, SLOT(paste()));
+
+ selectAllAct = new QAction(QIcon(":/images/edit-select-all.png"), tr("&Select all"),this);
+ selectAllAct->setShortcut(tr("Ctrl+A"));
+ selectAllAct->setStatusTip(tr("Selects all elements on the scene"));
+ connect(selectAllAct, SIGNAL(triggered()), m_scene, SLOT(selectAll()));
+
+ addModeAct = new QAction(QIcon(":/images/draw-freehand.png"), tr("&Add Mode"), this);
+ addModeAct->setCheckable(true);
+ addModeAct->setShortcut(tr("F5"));
+ addModeAct->setStatusTip(tr("Go to the atom addition mode"));
+ connect(addModeAct, SIGNAL(triggered()), this, SLOT(setAddMode()));
+
+ delModeAct = new QAction(QIcon(":/images/draw-eraser.png"), tr("&Delete Mode"), this);
+ delModeAct->setCheckable(true);
+ delModeAct->setShortcut(tr("F6"));
+ delModeAct->setStatusTip(tr("Go to the atom deletion mode"));
+ connect(delModeAct, SIGNAL(triggered()), this, SLOT(setRemoveMode()));
+
+ moveModeAct = new QAction(QIcon(":/images/transform-move.png"), tr("&Move mode"), this);
+ moveModeAct->setCheckable(true);
+ moveModeAct->setShortcut(tr("F7"));
+ moveModeAct->setStatusTip(tr("Go to the molecule move mode"));
+ connect(moveModeAct, SIGNAL(triggered()), this, SLOT(setMoveMode()));
+
+ rotateModeAct = new QAction(QIcon(":/images/transform-rotate.png"), tr("&Rotate mode"), this);
+ rotateModeAct->setCheckable(true);
+ rotateModeAct->setShortcut(tr("F8"));
+ rotateModeAct->setStatusTip(tr("Go to the molecule rotate mode"));
+ connect(rotateModeAct, SIGNAL(triggered()), this, SLOT(setRotateMode()));
+
+ alignAct = new QAction(QIcon(""), tr("Align to grid"), this);
+ alignAct->setStatusTip(tr("Align all elements on the scene to the grid"));
+ connect(alignAct, SIGNAL(triggered()), m_scene, SLOT(alignToGrid()));
+
+ prefAct = new QAction(QIcon(":/images/configure.png"),tr("Edit Pre&ferences..."),this);
+ prefAct->setShortcut(tr("Ctrl+F"));
+ prefAct->setStatusTip(tr("Edit your preferences"));
+ connect(prefAct, SIGNAL(triggered()), this, SLOT(editPreferences()));
+
+ // Zoom actions
+ zoomInAct = new QAction(QIcon(":/images/zoom-in.png"),tr("Zoom &In"), this);
+ zoomInAct->setShortcut(tr("Ctrl++"));
+ zoomInAct->setStatusTip(tr("Zoom in on the canvas"));
+ connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn()));
+
+ zoomOutAct = new QAction(QIcon(":/images/zoom-out.png"),tr("Zoom &Out"), this);
+ zoomOutAct->setShortcut(tr("Ctrl+-"));
+ zoomOutAct->setStatusTip(tr("Zoom out on the canvas"));
+ connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut()));
+
+ zoomResetAct = new QAction(QIcon(":/images/zoom-original.png"),tr("Zoom &Reset"), this);
+ zoomResetAct->setShortcut(tr("Ctrl+="));
+ zoomResetAct->setStatusTip(tr("Reset the zoom level"));
+ connect(zoomResetAct, SIGNAL(triggered()), this, SLOT(zoomReset()));
+
+ zoomFitAct = new QAction(QIcon(":/images/zoom-fit-best.png"),tr("Zoom &Fit"), this);
+ zoomFitAct->setShortcut(tr("Ctrl+*"));
+ zoomFitAct->setStatusTip(tr("Fit to screen"));
+ connect(zoomFitAct, SIGNAL(triggered()), this, SLOT(zoomFit()));
+
+ // Help actions
+ helpContentsAct = new QAction(QIcon(":/images/help-contents.png"),tr("&Help Contents..."), this);
+ helpContentsAct->setShortcut(tr("F1"));
+ helpContentsAct->setStatusTip(tr("Show the application's help contents"));
+ connect(helpContentsAct, SIGNAL(triggered()), this, SLOT(assistant()));
+
+ submitBugAct = new QAction(QIcon(""),tr("Submit &Bug..."), this);
+ submitBugAct->setStatusTip(tr("Open the browser with the bug tracker"));
+ connect(submitBugAct, SIGNAL(triggered()), this, SLOT(submitBug()));
+
+ aboutAct = new QAction(QIcon(":/images/help-about.png"),tr("&About"), this);
+ aboutAct->setStatusTip(tr("Show the application's About box"));
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+
+ aboutQtAct = new QAction(tr("About &Qt"), this);
+ aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
+ connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+
+ // Setting actions in their initial states
+ cutAct->setEnabled(false);
+ copyAct->setEnabled(false);
+ pasteAct->setEnabled(false);
+ addModeAct->setChecked(true);
+ connect(m_scene, SIGNAL(copyAvailable(bool)), cutAct, SLOT(setEnabled(bool)));
+ connect(m_scene, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool)));
+ connect(m_scene, SIGNAL(pasteAvailable(bool)), pasteAct, SLOT(setEnabled(bool)));
+
+
+ //////////////////////////// ZN CODE /////////////////////////////////
+
+ to3DAct = new QAction(QIcon(":/images/zeden.png"),tr("&Export to 3D Win"), this);
+ aboutAct->setStatusTip(tr("Export molecules to 3D window"));
+
+
+ /////////////////////////// END ZNCODE //////////////////////////////
+}
+
+
+void MainWindow::createMenus()
+{
+ fileMenu = menuBar()->addMenu(tr("&File"));
+ fileMenu->addAction(newAct);
+ fileMenu->addAction(openAct);
+ fileMenu->addAction(saveAct);
+ fileMenu->addAction(saveAsAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(importAct);
+ fileMenu->addAction(exportAct);
+ fileMenu->addAction(printAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(exitAct);
+
+ editMenu = menuBar()->addMenu(tr("&Edit"));
+ editMenu->addAction(undoAct);
+ editMenu->addAction(redoAct);
+ editMenu->addSeparator();
+ editMenu->addAction(cutAct);
+ editMenu->addAction(copyAct);
+ editMenu->addAction(pasteAct);
+ editMenu->addSeparator();
+ editMenu->addAction(selectAllAct);
+ editMenu->addAction(alignAct);
+ editMenu->addSeparator();
+ editMenu->addAction(addModeAct);
+ editMenu->addAction(delModeAct);
+ editMenu->addAction(moveModeAct);
+ editMenu->addAction(rotateModeAct);
+ editMenu->addSeparator();
+ editMenu->addAction(prefAct);
+
+ viewMenu = menuBar()->addMenu(tr("&View"));
+ viewMenu->addAction(zoomInAct);
+ viewMenu->addAction(zoomOutAct);
+ viewMenu->addAction(zoomResetAct);
+ viewMenu->addAction(zoomFitAct);
+
+ menuBar()->addSeparator();
+
+ helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(helpContentsAct);
+ helpMenu->addSeparator();
+ helpMenu->addAction(submitBugAct);
+ helpMenu->addSeparator();
+ helpMenu->addAction(aboutAct);
+ helpMenu->addAction(aboutQtAct);
+}
+
+void MainWindow::createToolBars()
+{
+ fileToolBar = addToolBar(tr("File"));
+ fileToolBar->setObjectName("file-toolbar");
+ fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ fileToolBar->setIconSize(QSize(22,22));
+ fileToolBar->addAction(newAct);
+ fileToolBar->addAction(openAct);
+ fileToolBar->addAction(saveAct);
+ fileToolBar->addAction(importAct);
+ fileToolBar->addAction(exportAct);
+ fileToolBar->addAction(printAct);
+
+ ////////////////////////////// ZN CODE ////////////////////////////
+ fileToolBar ->addAction(to3DAct);
+ //////////////////////////////////////////////////////////////
+
+ editToolBar = addToolBar(tr("Edit"));
+ editToolBar->setObjectName("edit-toolbar");
+ editToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ editToolBar->setIconSize(QSize(22,22));
+ editToolBar->addAction(undoAct);
+ editToolBar->addAction(redoAct);
+ editToolBar->addSeparator();
+ editToolBar->addAction(cutAct);
+ editToolBar->addAction(copyAct);
+ editToolBar->addAction(pasteAct);
+ editToolBar->addSeparator();
+ editToolBar->addAction(addModeAct);
+ editToolBar->addAction(delModeAct);
+ editToolBar->addAction(moveModeAct);
+ editToolBar->addAction(rotateModeAct);
+
+ zoomToolBar = addToolBar(tr("Zoom"));
+ zoomToolBar->setObjectName("zoom-toolbar");
+ zoomToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ zoomToolBar->setIconSize(QSize(22,22));
+ zoomToolBar->addAction(zoomInAct);
+ zoomToolBar->addAction(zoomOutAct);
+ zoomToolBar->addAction(zoomResetAct);
+ zoomToolBar->addAction(zoomFitAct);
+}
+
+void MainWindow::createStatusBar()
+{
+ statusBar()->showMessage(tr("Ready"));
+}
+
+void MainWindow::createToolBoxes()
+{
+ // Creating the dockwidgets
+ toolBoxDock = new QDockWidget(tr("Toolbox"));
+ toolBoxDock->setObjectName("toolbox-dockwidget");
+ toolBoxDock->setMinimumWidth(270);
+ infoDock = new QDockWidget(tr("Infobox"));
+ infoDock->setObjectName("infobox-dockwidget");
+ periodicTableDock = new QDockWidget(tr("Periodic Table"));
+ periodicTableDock->setObjectName("periodic-table-dockwidget");
+
+ // Create libraries
+ recentLib = new QListWidget;
+ genericLib = new QListWidget;
+ customLib = new QListWidget;
+
+ QPushButton* addButton = new QPushButton(tr("Add..."));
+ QPushButton* delButton = new QPushButton(tr("Delete"));
+
+ // Setting the views
+ recentLib->setViewMode(QListView::IconMode);
+ recentLib->setMovement(QListView::Static);
+ recentLib->setResizeMode(QListWidget::Adjust);
+ recentLib->setAlternatingRowColors(true);
+
+ genericLib->setAlternatingRowColors(true);
+ genericLib->setIconSize(QSize(64,64));
+
+ customLib->setAlternatingRowColors(true);
+ customLib->setIconSize(QSize(64,64));
+
+ // Adding common elements
+ QStringList celements;
+ celements << "H" << "C" << "N" << "O" << "Cl" << "F" << "P" << "R" << "X";
+ recentLib->addItems(celements);
+
+ // Declaring variables
+ QDir dir;
+ Molecule* mol;
+
+ // Loading generic molecules
+ dir.setPath(ALT_LIB_PATH);
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) genericLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QDir::homePath() + "/.molsketch/library");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) genericLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QApplication::applicationDirPath() + "/../share/molsketch/library");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) genericLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QApplication::applicationDirPath() + "/library");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) genericLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ // Loading custom molecules
+ dir.setPath(ALT_CUSTOM_LIB_PATH);
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) customLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QDir::homePath() + "/.molsketch/library/custom");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) customLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QApplication::applicationDirPath() + "/../share/molsketch/library/custom");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) customLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+ dir.setPath(QApplication::applicationDirPath() + "/library/custom");
+ for (unsigned int i = 0; i < dir.count(); i++)
+ {
+ mol = molsKetch::loadFile(dir.filePath(dir[i]));
+ if (mol) customLib->addItem(new MolLibItem(mol,dir.filePath(dir[i])));
+ }
+
+
+ // Composing draw options toolbox
+ QHBoxLayout* hLayoutAS = new QHBoxLayout();
+ QPushButton * pushButtonIncCharge = new QPushButton("+");
+ connect(pushButtonIncCharge, SIGNAL(clicked()), m_scene, SLOT(setIncChargeMode()));
+ hLayoutAS->addWidget(pushButtonIncCharge);
+ QPushButton * pushButtonDecCharge = new QPushButton("-");
+ connect(pushButtonDecCharge, SIGNAL(clicked()), m_scene, SLOT(setDecChargeMode()));
+ hLayoutAS->addWidget(pushButtonDecCharge);
+ QPushButton * pushButtonIncHydrogen = new QPushButton("H+");
+ connect(pushButtonIncHydrogen, SIGNAL(clicked()), m_scene, SLOT(setIncHydrogenMode()));
+ hLayoutAS->addWidget(pushButtonIncHydrogen);
+ QPushButton * pushButtonDecHydrogen = new QPushButton("H-");
+ connect(pushButtonDecHydrogen, SIGNAL(clicked()), m_scene, SLOT(setDecHydrogenMode()));
+ hLayoutAS->addWidget(pushButtonDecHydrogen);
+
+ QGroupBox* groupBoxAtomOptions = new QGroupBox("Atom options");
+ groupBoxAtomOptions->setLayout(hLayoutAS);
+
+ QHBoxLayout* hLayoutBS1 = new QHBoxLayout();
+ hLayoutBS1->addWidget(new QLabel("Bond order"));
+ QSpinBox * spinBoxBondOrder = new QSpinBox;
+ spinBoxBondOrder->setValue(m_scene->bondOrder());
+ spinBoxBondOrder->setMinimum(1);
+ spinBoxBondOrder->setMaximum(3);
+ connect(spinBoxBondOrder, SIGNAL(valueChanged(int)), m_scene, SLOT(setBondOrder(int)));
+ hLayoutBS1->addWidget(spinBoxBondOrder);
+
+ QHBoxLayout* hLayoutBS2 = new QHBoxLayout();
+ hLayoutBS2->addWidget(new QLabel("Bond type"));
+ QComboBox * comboBoxBondType = new QComboBox;
+ comboBoxBondType->addItem("Normal bond");
+ comboBoxBondType->addItem("Up bond");
+ comboBoxBondType->addItem("Up bond reversed");
+ comboBoxBondType->addItem("Down bond");
+ comboBoxBondType->addItem("Down bond reversed");
+ comboBoxBondType->addItem("Striped Bond");
+ connect(comboBoxBondType, SIGNAL(currentIndexChanged(int)), m_scene, SLOT(setBondType(int)));
+ hLayoutBS2->addWidget(comboBoxBondType);
+
+ QHBoxLayout* hLayoutBS3 = new QHBoxLayout();
+ hLayoutBS3->addWidget(new QLabel("Bond angle"));
+ QDoubleSpinBox * doubleSpinBoxBondAngle = new QDoubleSpinBox;
+ doubleSpinBoxBondAngle->setValue(m_scene->bondAngle());
+ doubleSpinBoxBondAngle->setMaximum(180);
+ doubleSpinBoxBondAngle->setSingleStep(6);
+ doubleSpinBoxBondAngle->setDecimals(0);
+ doubleSpinBoxBondAngle->setSuffix("∞");
+ connect(doubleSpinBoxBondAngle, SIGNAL(valueChanged(double)), m_scene, SLOT(setBondAngle(double)));
+ hLayoutBS3->addWidget(doubleSpinBoxBondAngle);
+
+ QHBoxLayout* hLayoutBS4 = new QHBoxLayout();
+ hLayoutBS4->addWidget(new QLabel("Bond length"));
+ QDoubleSpinBox * doubleSpinBoxBondLength = new QDoubleSpinBox;
+ doubleSpinBoxBondLength->setValue(m_scene->bondLength());
+ doubleSpinBoxBondLength->setMaximum(100);
+ doubleSpinBoxBondLength->setSingleStep(10);
+ doubleSpinBoxBondLength->setDecimals(0);
+ doubleSpinBoxBondLength->setSuffix("");
+ connect(doubleSpinBoxBondLength, SIGNAL(valueChanged(double)), m_scene, SLOT(setBondLength(double)));
+ hLayoutBS4->addWidget(doubleSpinBoxBondLength);
+
+ QVBoxLayout* vLayoutBS = new QVBoxLayout;
+ vLayoutBS->addLayout(hLayoutBS1);
+ vLayoutBS->addLayout(hLayoutBS2);
+ vLayoutBS->addLayout(hLayoutBS3);
+ vLayoutBS->addLayout(hLayoutBS4);
+
+ QGroupBox* groupBoxBondOptions = new QGroupBox("Bond options");
+ groupBoxBondOptions->setLayout(vLayoutBS);
+
+ QVBoxLayout* vLayoutDS = new QVBoxLayout;
+ vLayoutDS->addWidget(groupBoxAtomOptions);
+ vLayoutDS->addWidget(groupBoxBondOptions);
+
+ QFrame * frameDrawOptions = new QFrame;
+ frameDrawOptions->setLayout(vLayoutDS);
+
+ // Composing customLib
+ QHBoxLayout* hLayoutCL = new QHBoxLayout;
+ hLayoutCL->addWidget(addButton);
+ hLayoutCL->addWidget(delButton);
+ QVBoxLayout* vLayoutCL = new QVBoxLayout;
+ vLayoutCL->addWidget(customLib);
+ vLayoutCL->addLayout(hLayoutCL);
+
+ QFrame* frameCustomLib = new QFrame;
+ frameCustomLib->setLayout(vLayoutCL);
+
+ // Create a library toolbox and add the libraries
+ toolBox = new QToolBox;
+ toolBox->addItem(recentLib,tr("Recent Items"));
+ toolBox->addItem(frameDrawOptions,tr("Draw options"));
+// toolBox->addItem(elementLib,tr("Elements"));
+ toolBox->addItem(genericLib,tr("Generic Molecules"));
+ toolBox->addItem(frameCustomLib,tr("Custom Molecules"));
+ toolBoxDock->setWidget(toolBox);
+
+ // Create and add a infowidget
+ infoText = new QTextEdit;
+ infoText->setReadOnly(true);
+ infoDock->setWidget(infoText);
+
+ // Create the periodic table at the bottem
+ periodicTable = new PeriodicTableWidget();
+ periodicTableDock->setWidget(periodicTable);
+ periodicTable->setCurrentCell(1,13);
+
+ // Placing the dockwidgets in their default position
+ setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+ addDockWidget(Qt::LeftDockWidgetArea,toolBoxDock);
+ addDockWidget(Qt::LeftDockWidgetArea,infoDock);
+ addDockWidget(Qt::BottomDockWidgetArea, periodicTableDock);
+// periodicTableDock->setFloating(true);
+ periodicTableDock->resize(460,280);
+
+
+ // Connecting signals and slots
+ connect(genericLib,SIGNAL(itemDoubleClicked(QListWidgetItem*)),m_scene,SLOT(addMolecule(QListWidgetItem*)));
+// connect(genericLib,SIGNAL(itemClicked(QTableWidgetItem*)),this,SLOT(updateRecentList(QTableWidgetItem*)));
+ connect(customLib,SIGNAL(itemDoubleClicked(QListWidgetItem*)),m_scene,SLOT(addMolecule(QListWidgetItem*)));
+// connect(customLib,SIGNAL(itemClicked(QTableWidgetItem*)),this,SLOT(updateRecentList(QTableWidgetItem*)));
+ connect(addButton,SIGNAL(released()),this,SLOT(addCustomMol()));
+ connect(delButton,SIGNAL(released()),this,SLOT(delCustomMol()));
+}
+
+void MainWindow::addCustomMol()
+{
+ foreach(QGraphicsItem* item, m_scene->selectedItems())
+ {
+ if (item->type() == Molecule::Type)
+ {
+ Molecule* mol = dynamic_cast<Molecule*>(item);
+ QString name = QInputDialog::getText(this,tr("Enter a name"),tr("Enter a name for this item:"),QLineEdit::Normal,mol->formula());
+ customLib->addItem(new MolLibItem(mol,name));
+ }
+ }
+}
+
+void MainWindow::delCustomMol()
+{
+ //Check whether an item is selected
+ if (!customLib->currentItem()) return;
+
+ if (QMessageBox::warning(this,tr("Are you sure?"),tr("Do you really want to delete this item?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::No) == QMessageBox::Yes)
+ {
+ MolLibItem* item = dynamic_cast<MolLibItem*>(customLib->currentItem());
+ QFile::remove(item->getFileName().filePath());
+ delete item;
+ }
+}
+
+void MainWindow::createView()
+{
+ // Create new scene
+ m_scene = new MolScene(this);
+
+ // Create and set view
+ m_molView = new MolView(m_scene);
+
+ // Placing the view widget
+ setCentralWidget(m_molView);
+ m_molView->show();
+}
+
+void MainWindow::initializeAssistant()
+{
+ assistantClient = new QAssistantClient("", this);
+
+ QStringList arguments;
+ QFileInfo file(ALT_DOC_PATH + QString("/molsketch.adp"));
+ if (!file.exists()) file.setFile(QApplication::applicationDirPath() + "/doc/en/molsketch.adp");
+ if (!file.exists()) file.setFile(QApplication::applicationDirPath() + "/../share/doc/molsketch/doc/en/molsketch.adp");
+
+ arguments << "-profile" << file.absoluteFilePath();
+ assistantClient->setArguments(arguments);
+}
+
+// Auxillary methods
+
+void MainWindow::readSettings()
+{
+ // Reading the settings
+ QSettings settings(PROGRAM_NAME, QString(PROGRAM_NAME) + QString(PROGRAM_VERSION));
+
+ // Setting the window position
+ QPoint pos = settings.value("pos",QPoint(100,100)).toPoint();
+ QSize size = settings.value("size",QSize(800,600)).toSize();
+ resize(size);
+ move(pos);
+
+ // Restoring the state of the toolbars and dockwidgets
+ QByteArray state = settings.value("window-state", QByteArray("\0\0\0\xff\0\0\0\0\xfd\0\0\0\x2\0\0\0\0\0\0\x1\xe\0\0\x2#\xfc\x2\0\0\0\x2\xfb\0\0\0$\0t\0o\0o\0l\0\x62\0o\0x\0-\0\x64\0o\0\x63\0k\0w\0i\0\x64\0g\0\x65\0t\x1\0\0\0\x43\0\0\x1G\0\0\0\xbe\0\xff\xff\xff\xfb\0\0\0$\0i\0n\0\x66\0o\0\x62\0o\0x\0-\0\x64\0o\0\x63\0k\0w\0i\0\x64\0g\0\x65\0t\x1\0\0\x1\x90\0\0\0\xd6\0\0\0R\0\xff\xff\xff\0\0\0\x1\xff\xff\xff\xfa\0\0\x2#\xfc\x2\0\0\0\x1\xfb\0\0\0\x32\0p\0\x65\0r\0i\0o\0\x64\0i\0\x63\0-\0t [...]
+ restoreState(state);
+
+ // Load preferences
+ readPreferences(settings);
+
+}
+
+void MainWindow::readPreferences(const QSettings & settings)
+{
+ // Loading auto-save time
+ m_autoSaveTime = settings.value("auto-save-time", 300000).toInt();
+ m_autoSaveTimer->setInterval(m_autoSaveTime);
+ m_autoSaveTimer->start();
+
+ // Loading paths
+ m_libPath = settings.value("library-path","/usr/share/molsketch/library/").toString();
+ m_lastAccessedPath = settings.value("last-save-path", QDir::homePath()).toString();
+
+ // Load the draw settings
+ m_scene->setMsKAtomSize(settings.value("atom-size",30).toDouble());
+ m_scene->setAutoAddHydrogen(settings.value("auto-add-hydrogen",true).toBool());
+ m_scene->setCarbonVisible(settings.value("carbon-visible",false).toBool());
+ m_scene->setHydrogenVisible(settings.value("hydrogen-visible",true).toBool());
+ m_scene->setChargeVisible(settings.value("charge-visible",true).toBool());
+ m_scene->setAtomSymbolFont(settings.value("atom-symbol-font").value<QFont>());
+
+ m_scene->setBondLength(settings.value("bond-length",40).toDouble());
+ m_scene->setBondWidth(settings.value("bond-width",1).toDouble());
+ m_scene->setBondAngle(settings.value("bond-angle",30).toInt());
+
+ // Update the scene contents
+ m_scene->update();
+}
+
+void MainWindow::writeSettings()
+{
+ // Saving the settings
+ QSettings settings(PROGRAM_NAME, QString(PROGRAM_NAME) + QString(PROGRAM_VERSION));
+
+ // Saving the window position
+ settings.setValue("pos",pos());
+ settings.setValue("size",size());
+
+ // Saving the state of the toolbars and dockwidgets
+ settings.setValue("window-state", saveState());
+
+ // Saving paths
+// settings.setValue("library-path",m_libPath);
+ settings.setValue("last-save-path", m_lastAccessedPath);
+
+ // Saving preferences
+// settings.setValue("atom-size",m_scene->atomSize());
+// settings.setValue("auto-add-hydrogen",m_scene->autoAddHydrogen());
+// settings.setValue("bond-length",m_scene->bondLength());
+// settings.setValue("bond-angle",m_scene->bondAngle());
+// settings.setValue("carbon-visible",m_scene->carbonVisible());
+// settings.setValue("hydrogen-visible",m_scene->hydrogenVisible());
+// settings.setValue("charge-visible",m_scene->chargeVisible());
+}
+
+
+bool MainWindow::maybeSave()
+{
+ ///TODO
+ if (isWindowModified())
+ {
+ QMessageBox::StandardButton ret;
+ ret = QMessageBox::warning(this,tr(PROGRAM_NAME),
+ tr("This document has been modified.\n"
+ "Do you want to save your changes?"),
+ QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
+ if (ret == QMessageBox::Save)
+ return save();
+ else if (ret == QMessageBox::Cancel)
+ return false;
+ }
+ return true;
+}
+
+void MainWindow::setCurrentFile(const QString &fileName)
+{
+ // Synthesizing the correct name
+ m_curFile = fileName;
+ QString shownName;
+ if (m_curFile.isEmpty())
+ shownName = tr("untitled.mol");
+ else
+ shownName = strippedName(m_curFile);
+
+ // Setting the windowtitle
+ setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr(PROGRAM_NAME)));
+}
+
+QString MainWindow::strippedName(const QString &fullFileName)
+{
+ return QFileInfo(fullFileName).fileName();
+}
+
+
+void MainWindow::updateRecentList( QListWidgetItem* element )
+{
+ // recentLib->addItem(element);
+ bool unique = true;
+ for (int i = 0; i < recentLib->count(); i++)
+ if (recentLib->item(i)->text() == element->text()) unique = false;
+ if (unique) recentLib->addItem(element->text());
+}
+
+void MainWindow::updateRecentList( QTableWidgetItem * element )
+{
+ bool unique = true;
+ for (int i = 0; i < recentLib->count(); i++)
+ if (recentLib->item(i)->text() == element->text()) unique = false;
+ if (unique) recentLib->addItem(element->text());
+}
+
+void MainWindow::updateInfoBox( )
+{
+ // Initializing variables
+ QString formula;
+ int molecules = 0;
+ int atoms = 0;
+ int bonds = 0;
+ qreal weight = 0;
+ int charge = 0;
+
+ // Get the selected molecules and load the values
+ QGraphicsItem* item;
+
+ // Check if selected
+ foreach(item,m_scene->selectedItems()) if (item->type() == Molecule::Type)
+ {
+ // Get the molecule
+ Molecule* mol = dynamic_cast<Molecule*>(item);
+
+ // Create formula
+ QString rawFormula = mol->formula();
+ QChar rawChar;
+ foreach (rawChar,rawFormula)
+ if (rawChar.isDigit())formula += "<sub>" + QString(rawChar) + "</sub>";
+ else formula += rawChar;
+
+ // Add charge
+ formula += "<sup>" + mol->chargeID() + "</sup>" + " ";
+
+ // Loading values
+ molecules += 1;
+ weight += mol->weight();
+ atoms += mol->atoms().count();
+ bonds += mol->bonds().count();
+ charge += mol->charge();
+ }
+
+ // Else check for focussed item
+ if (formula.isEmpty() && m_scene->focusItem())
+ {
+ item = m_scene->focusItem();
+
+ // Get the molecule
+ Molecule* mol = dynamic_cast<Molecule*>(item);
+
+ // Create formula
+ QString rawFormula = mol->formula();
+ QChar rawChar;
+ foreach (rawChar,rawFormula)
+ if (rawChar.isDigit())formula += "<sub>" + QString(rawChar) + "</sub>";
+ else formula += rawChar;
+
+ // Add charge
+ formula += "<sup>" + mol->chargeID() + "</sup>" + " ";
+
+ // Loading values
+ molecules += 1;
+ weight += mol->weight();
+ atoms += mol->atoms().count();
+ bonds += mol->bonds().count();
+ charge += mol->charge();
+ }
+
+ // Else failsafe
+ if (formula.isEmpty()) formula = tr("Non selected");
+ infoText->setText("<h1>" + formula + "\n" + "</h1>");
+
+ infoText->append("<h3>" + tr("Number of molecules: ") + QString::number(molecules) + "<P>" + tr("Total weight: ") + QString::number(weight) +"<P>" + tr("Total charge: ")+ QString::number(charge) + "<P>" + tr("Number of atoms: ") + QString::number(atoms) + "<P>" + tr("Number of bonds: ") + QString::number(bonds) + "<P>" + tr("Number of items: ") + QString::number(m_scene->items().count()) + "<P>" + "</h3>");
+
+}
+
+void MainWindow::editPreferences( )
+{
+ QSettings settings(PROGRAM_NAME, QString(PROGRAM_NAME) + QString(PROGRAM_VERSION));
+
+ // Opens the settings dialog
+ SettingsDialog dialog(&settings);
+ dialog.exec();
+ readPreferences(settings);
+}
+
+void MainWindow::submitBug()
+{
+ // Opens a browser with the bug tracker
+ QDesktopServices::openUrl(QUrl("http://sourceforge.net/tracker/?func=add&group_id=191562&atid=937880"));
+}
+
+ //////////////////////////// ZN CODE /////////////////////////////////
+ vector <OpenBabel::OBMol *> MainWindow::get_OB_mols () {
+ vector <OpenBabel::OBMol *> mols;
+ foreach(QGraphicsItem* item, m_scene->items()) {
+ OpenBabel::OBMol *mol = molsKetch::toOBMolecule (item);
+ if (mol ->NumAtoms ()) mols.push_back (mol);
+ }
+ return mols;
+ }
+
+
+ /////////////////////////// END ZNCODE //////////////////////////////
+
diff --git a/molsketch_helium/mainwindow.h b/molsketch_helium/mainwindow.h
new file mode 100644
index 0000000..31d9fa9
--- /dev/null
+++ b/molsketch_helium/mainwindow.h
@@ -0,0 +1,321 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and defines the mainwindow of molsKetch.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <vector>
+#include "obabel_includes.h"
+
+class QAction;
+class QMenu;
+class MolScene;
+class QToolBox;
+class QDockWidget;
+class QTextEdit;
+class QUndoStack;
+class QListWidget;
+class QListWidgetItem;
+class QTableWidget;
+class QTableWidgetItem;
+class QAssistantClient;
+class QSettings;
+class QTimer;
+
+class Molecule;
+class MolView;
+
+
+/**
+ * The main application window of molsKetch.
+ *
+ * @author Harm van Eersel
+ */
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ /** Constructor */
+ MainWindow();
+
+protected:
+ /** Reimplements the close event to asked for a save on exit. */
+ void closeEvent(QCloseEvent *event);
+
+private slots:
+ /** Opens a new empty file. */
+ void newFile();
+ /** Opens a Open file dialog. */
+ void open();
+ /** Saves the current document. */
+ bool save();
+ /** Saves the current document under a new name. */
+ bool saveAs();
+ /** Saves a backup of the current document. */
+ bool autoSave();
+ /** Import a file in the current document. */
+ bool importDoc();
+ /** Export the current document as a picture. */
+ bool exportDoc();
+ /** Prints the current document. */
+ bool print();
+
+ /** Switch to add mode. */
+ void setAddMode();
+ /** Swich to del mode. */
+ void setRemoveMode();
+ /** Switch to move mode. */
+ void setMoveMode();
+ /** Switch to rotate mode. */
+ void setRotateMode();
+
+ /** Open the preferences editor. */
+ void editPreferences();
+
+ /** Open the help window. */
+ void assistant();
+ /** Open a browser with the bugtracker. */
+ void submitBug();
+ /** Open the molsKetch about dialog. */
+ void about();
+
+ /** Add the selected molecule to the custom library. */
+ void addCustomMol();
+ /** Removes the selected item from the custom library. */
+ void delCustomMol();
+
+ /** Mark the current document as modified. */
+ void documentWasModified( );
+
+ /** Zoom in on the current view. */
+ void zoomIn();
+ /** Zoom out on the current view. */
+ void zoomOut();
+ /** Restore the original position and zoom level. */
+ void zoomReset();
+ /** Adjust the zoom leven to fit the whole document in the view. */
+ void zoomFit();
+
+ /** Update the window to match the edit mode @p mode. */
+ void updateEditMode(int mode);
+ /** Update the list of recent elements with @p element. */
+ void updateRecentList(QListWidgetItem* element);
+ /** Update the list of recent elements with @p element. */
+ void updateRecentList(QTableWidgetItem* element);
+ /** Updated the info box with info on the selected item. */
+ void updateInfoBox( );
+
+// /**
+// * Adds a new molecule with one atom to the scene.
+// *
+// * @param position position of the new molecule
+// * @param element the element symbol of the new atom
+// */
+// Molecule* newMolecule(const QPointF& position = QPointF(0,0), const QString& element = "C");
+
+private:
+ /** Creates the QActions of the MainWindow. */
+ void createActions();
+ /** Creates the menus of the MainWindow. */
+ void createMenus();
+ /** Creates the toolbars of the MainWindow. */
+ void createToolBars();
+ /** Creates the status bar of the MainWindow. */
+ void createStatusBar();
+ /** Creates the view of the MainWindow. */
+ void createView();
+ /** Creates the toolboxes of the MainWindow. */
+ void createToolBoxes();
+
+ /** Stores the settings mol the application */
+ QSettings * m_settings;
+ /** Loads the previous settings of molsKetch. */
+ void readSettings();
+ /** Saves the current settings of molsKetch. */
+ void writeSettings();
+ /** Reloads the preferences */
+ void readPreferences(const QSettings & settings);
+
+ /** Ask if the document should be saved. */
+ bool maybeSave();
+ /** Clears the scene. */
+ void clearScene();
+
+ /** Set the current file name to @p fileName. */
+ void setCurrentFile(const QString &fileName);
+ /** Return the stripped file name of @p fullFileName. */
+ QString strippedName(const QString &fullFileName);
+ /** Saves the current document as OpenBabel file under the name @p fileName. */
+ bool saveToOB(const QString &fileName);
+
+ // Global settings
+ /** The path of the molecule library */
+ QString m_libPath;
+ /** Path where the last document was saved */
+ QString m_lastAccessedPath;
+ /** The time between auto-saves in miliseconds */
+ int m_autoSaveTime;
+
+ // Timers
+ /** The timer for the auto-save action */
+ QTimer * m_autoSaveTimer;
+
+ // Documentation classes
+ /** The help client */
+ QAssistantClient* assistantClient;
+ /** Initialize the help client. */
+ void initializeAssistant();
+
+ // Libraries
+ /** The library widget with recently used elements. */
+ QListWidget* recentLib;
+ /** The library widget of elements. */
+ QListWidget* elementLib;
+ /** The library widget with user-added molecules. */
+ QListWidget* customLib;
+ /** The library widget with common molecules. */
+ QListWidget* genericLib;
+
+ // Widgets
+ /** The scene that contains the document's molecules. */
+ MolScene* m_scene;
+ /** The view of the MolScene. */
+ MolView* m_molView;
+ /** The file name of the current document. */
+ QString m_curFile;
+
+ /** The dock widget for the toolbox. */
+ QDockWidget* toolBoxDock;
+ /** The dock widget for the info box. */
+ QDockWidget* infoDock;
+ /** The dock for the periodic table. */
+ QDockWidget* periodicTableDock;
+ /** The toolbox with the libraries. */
+ QToolBox* toolBox;
+ /** The info textbox. */
+ QTextEdit* infoText;
+ /** The periodic table. */
+ QTableWidget* periodicTable;
+
+ // Menus
+ /** The file menu. */
+ QMenu* fileMenu;
+ /** The edit menu. */
+ QMenu* editMenu;
+ /** The view menu. */
+ QMenu* viewMenu;
+ /** The window menu. */
+ QMenu* windowMenu;
+ /** The help menu. */
+ QMenu* helpMenu;
+
+ // Toolbars
+ /** The file toolbar. */
+ QToolBar* fileToolBar;
+ /** The edit toolbar. */
+ QToolBar* editToolBar;
+ /** The zoom toolbar. */
+ QToolBar* zoomToolBar;
+
+ // File actions
+ /** Open a new empty file action. */
+ QAction* newAct;
+ /** Open an existing file action. */
+ QAction* openAct;
+ /** Save the current document action. */
+ QAction* saveAct;
+ /** Save the current document under a new name action. */
+ QAction* saveAsAct;
+ /** Save a backup of the current document. */
+ QAction* autoSaveAct;
+ /** Import an existing file action. */
+ QAction* importAct;
+ /** Export the current document as a picture action. */
+ QAction* exportAct;
+ /** Print the current document action. */
+ QAction* printAct;
+ /** Exit molsKetch action. */
+ QAction* exitAct;
+
+ // Edit actions
+ /** Undo the last command action. */
+ QAction* undoAct;
+ /** Redo the last command action. */
+ QAction* redoAct;
+ /** Cut the selected item action. */
+ QAction* cutAct;
+ /** Copy the selected item action. */
+ QAction* copyAct;
+ /** Paste the contents of the clipboard action. */
+ QAction* pasteAct;
+ /** Select all items on the scene action. */
+ QAction* selectAllAct;
+ /** Align all items to the grid action. */
+ QAction* alignAct;
+ /** Switch to add mode action. */
+ QAction* addModeAct;
+ /** Switch to delete mode action. */
+ QAction* delModeAct;
+ /** Switch to move mode action. */
+ QAction* moveModeAct;
+ /** Switch to move mode action. */
+ QAction* rotateModeAct;
+ /** Open the settings dialog action. */
+ QAction* prefAct;
+
+ // View actions
+ /** Zoom in on the view action. */
+ QAction* zoomInAct;
+ /** Zoom out on the view action. */
+ QAction* zoomOutAct;
+ /** Reset the position and zoom leven of the view action. */
+ QAction* zoomResetAct;
+ /** Adjust the zoom level to fit all items in the view action. */
+ QAction* zoomFitAct;
+
+ // Help actions
+ /** Show the help contents action. */
+ QAction* helpContentsAct;
+ /** Submit a bug action. */
+ QAction* submitBugAct;
+ /** Show the molsKetch about dialog action. */
+ QAction* aboutAct;
+ /** Show the Qt about dialog action. */
+ QAction* aboutQtAct;
+
+ //////////////////////////// ZN CODE /////////////////////////////////
+ public:
+ QAction *to3DAct;
+ std::vector <OpenBabel::OBMol *> get_OB_mols () ;
+
+ /////////////////////////// END ZNCODE //////////////////////////////
+
+};
+
+#endif
diff --git a/molsketch_helium/molecule.cpp b/molsketch_helium/molecule.cpp
new file mode 100644
index 0000000..4746386
--- /dev/null
+++ b/molsketch_helium/molecule.cpp
@@ -0,0 +1,540 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#include <QtGui>
+
+#include "molecule.h"
+#include "molscene.h"
+#include "element.h"
+
+// Constructors
+
+Molecule::Molecule(QGraphicsItem* parent, MolScene* scene) : QGraphicsItemGroup(parent,scene)
+{
+ // Setting properties
+ setFlags(QGraphicsItem::ItemIsFocusable);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptsHoverEvents(true);
+ setHandlesChildEvents(false);
+ if (scene) setFlag(QGraphicsItem::ItemIsSelectable, scene->editMode()==MolScene::MoveMode);
+}
+
+Molecule::Molecule(QSet<MsKAtom*> atomSet, QSet<MsKBond*> bondSet, QGraphicsItem* parent, MolScene* scene) : QGraphicsItemGroup(parent,scene)
+{
+ // Setting properties
+ setFlags(QGraphicsItem::ItemIsFocusable);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptsHoverEvents(true);
+ setHandlesChildEvents(false);
+ if (scene) setFlag(QGraphicsItem::ItemIsSelectable, scene->editMode()==MolScene::MoveMode);
+
+ // Add the new atoms
+ foreach(MsKAtom* atom, atomSet) addMsKAtom(new MsKAtom(atom->scenePos(), atom->element(), atom->implicitHydrogens()));
+
+ // ...and bonds
+ foreach(MsKBond* bond, bondSet) addBond(new MsKBond(atomAt(bond->firstMsKAtom()->scenePos()),atomAt(bond->lastMsKAtom()->scenePos()),bond->bondOrder(),bond->bondType()));
+}
+
+Molecule::Molecule(Molecule* mol, QGraphicsItem* parent, MolScene* scene) : QGraphicsItemGroup(parent,scene)
+{
+ // Setting properties
+ setFlags(QGraphicsItem::ItemIsFocusable);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptsHoverEvents(true);
+ setHandlesChildEvents(false);
+ if (scene) setFlag(QGraphicsItem::ItemIsSelectable, scene->editMode()==MolScene::MoveMode);
+
+ // Add the new atoms
+ foreach(MsKAtom* atom, mol->atoms())
+ {
+ addMsKAtom(new MsKAtom(atom->pos(),atom->element(),atom->implicitHydrogens()));
+ }
+ // ...and bonds
+ foreach(MsKBond* bond, mol->bonds())
+ {
+ addBond(new MsKBond(atomAt(bond->firstMsKAtom()->pos()),atomAt(bond->lastMsKAtom()->pos()),bond->bondOrder(),bond->bondType()));
+ }
+
+ // Set the position
+ setPos(mol->pos());
+}
+
+
+// Manipulation methods
+
+MsKAtom* Molecule::addMsKAtom(const QString &element, const QPointF &point, bool implicitHydrogen)
+{
+ //pre: element is a non-empty string and point is a valid position on the canvas in scene coordinates
+ Q_ASSERT(!element.isEmpty());
+ //post: an atom of element has been added to the molecule
+// MsKAtom* atom = new MsKAtom(point,element,((element == "C") && !(scene()->getShowCarbon() ) || ((element == "H") && !(scene()->getShowHydrogen()))),this);
+ MsKAtom* atom = new MsKAtom(point,element,implicitHydrogen);
+ return addMsKAtom(atom);
+}
+
+MsKAtom* Molecule::addMsKAtom(MsKAtom* atom)
+{
+ // pre: atom is a valid pointer to a atom
+ Q_CHECK_PTR(atom);
+
+ // Add the atom to the molecule
+ m_atomList.append(atom);
+ addToGroup(atom);
+
+// /// Work-around qt-bug
+// if (scene()) scene()->addItem(atom);
+
+ return atom;
+}
+
+MsKBond* Molecule::addBond(MsKAtom* atomA, MsKAtom* atomB, int order, int type)
+{
+ //pre: atomA and atomB are existing different atoms in the molecule
+ Q_ASSERT (m_atomList.contains(atomA));
+ Q_ASSERT (m_atomList.contains(atomB));
+ Q_ASSERT (atomA != atomB);
+ //post: a bond of type has been added between atomA and atomB
+
+ // Creating a new bond
+ MsKBond* bond = new MsKBond(atomA,atomB,order,type);
+ return addBond(bond);
+}
+
+MsKBond* Molecule::addBond(MsKBond* bond)
+{
+ // pre(1): bond is a valid pointer to a bond
+ Q_CHECK_PTR(bond);
+ //pre(2): the bond is between two atoms of this molecule
+ Q_ASSERT(m_atomList.contains(bond->firstMsKAtom()));
+ Q_ASSERT(m_atomList.contains(bond->lastMsKAtom()));
+
+
+ // Checking if and altering when a bond exists
+ MsKBond* bondX = bondBetween(bond->firstMsKAtom(), bond->lastMsKAtom());
+ if (bondX) return bondX;
+// {
+// bondX->incOrder();
+// bondX->setType(bond->getType());
+// return bondX;
+// }
+
+ // Setting the valency
+ bond->redoValency();
+
+ // Adding the bond the the molecule
+ m_bondList.append(bond);
+ addToGroup(bond);
+
+// /// Work-around qt-bug
+// if (scene()) scene()->addItem(bond);
+
+ return bond;
+}
+
+QList<MsKBond*> Molecule::delAtom(MsKAtom* atom)
+{
+ //pre: atom is an existing atom in the molecule
+ Q_ASSERT(m_atomList.contains(atom));
+
+ //post: atom has been removed from the molecule and all bonds to this atom have been removed
+ //ret: the former bonds of this atom
+
+ // Remove all connected bonds from the molecule
+ QList<MsKBond*> delList = bondsOfMsKAtom(atom);
+ foreach(MsKBond* bond, delList) delBond(bond);
+
+ // Remove the atom
+ m_atomList.removeAll(atom);
+ removeFromGroup(atom);
+ if (scene()) scene()->removeItem(atom);
+
+ // Return the list of bonds that were connected for undo
+ return delList;
+
+}
+
+void Molecule::delBond(MsKBond* bond)
+{
+ //pre: bond is an existing bond in the molecule
+ Q_ASSERT(m_bondList.contains(bond));
+
+ //post: bond has been removed from the molecule
+
+ // Removing the bond
+ m_bondList.removeAll(bond);
+ removeFromGroup(bond);
+ if (scene()) scene()->removeItem(bond);
+
+ bond->undoValency();
+// /// Superseded by undo
+// // delete bond;
+}
+
+// void Molecule::addAutoMsKAtom(MsKAtom* startMsKAtom)
+// {
+// //pre: atom is part of the molecule
+// //post: the molecule has a new atom with a bond to startMsKAtom
+// Q_ASSERT(m_atomList.contains(startMsKAtom));
+//
+// // Calculate a conveniant position
+// QPointF pos;
+// pos.setX( startMsKAtom->pos().x() + 5 );
+// pos.setY( startMsKAtom->pos().y() + 5 );
+//
+// // Add a atom at this position
+// MsKAtom* endMsKAtom = addMsKAtom( scene()->curElement, pos);
+// addBond( startMsKAtom, endMsKAtom );
+//
+// }
+
+QList<Molecule*> Molecule::split()
+{
+ //pre: CanSplit
+ //post:
+ //ret: a list with the two parts of the split molecule
+
+ // Create the return list
+ QList<Molecule*> molList;
+
+ // Create sets with the bonds and molcules
+ QSet<MsKAtom*> atomSet(m_atomList.toSet());
+ QSet<MsKBond*> bondSet(m_bondList.toSet());
+ QSet<MsKAtom*> atomSubSet;
+ QSet<MsKBond*> bondSubSet;
+
+ // Declarations
+ int lastSize;
+ MsKAtom* atom;
+ MsKBond* bond;
+
+ // Main loop
+ while (!atomSet.isEmpty())
+ {
+ lastSize = 0;
+ atomSubSet.clear();
+ bondSubSet.clear();
+
+ // Load the first atom
+ atomSubSet << atomSet.toList().first();
+
+ while (atomSubSet.size() != lastSize)
+ {
+ lastSize = atomSubSet.size();
+ foreach (atom,atomSubSet)
+ {
+ foreach(bond,bondSet) if (bond->hasMsKAtom(atom)) bondSubSet << bond;
+ foreach(bond,bondSubSet) atomSubSet << bond->firstMsKAtom() << bond->lastMsKAtom();
+ }
+ }
+
+ atomSet -= atomSubSet;
+ bondSet -= bondSubSet;
+
+ molList.append(new Molecule(atomSubSet,bondSubSet));
+
+ }
+
+ return molList;
+
+}
+
+
+
+// Query methods
+
+MsKAtom* Molecule::atomAt(const QPointF &pos) const
+ {
+ //pre: pos is a valid position on the canvas in scene coordinates
+ //post: return the atom op position pos or nil
+
+ foreach(MsKAtom* atom, m_atomList)
+ {
+ if (atom->contains(atom->mapFromScene(pos))) return atom;
+ }
+
+
+ // for ( int i = 0; i < children().count() ;i++)
+ // {
+ // if ((children()[i]->type() == MsKAtom::Type) && (children()[i]->contains(pos)))
+ // {
+ // return (MsKAtom*)children()[i];
+ // }
+ // }
+
+ return 0;
+ }
+
+// MsKAtom* Molecule::atom(int id) const
+// { //pre: id does not exceed the number of atoms
+// Q_ASSERT(id<m_atomList.size());
+// //post: returns the i-th atom
+//
+// return m_atomList.at(id);
+// }
+
+MsKBond* Molecule::bondAt(const QPointF &pos) const
+ {
+ //pre: pos is a valid position on the canvas in scene coordinates
+ //post: return the first bond on position pos
+ foreach(MsKBond* bond, m_bondList)
+ {
+ if (bond->contains(bond->mapFromScene(pos))) return bond;
+ }
+ return 0;
+ }
+
+
+// MsKBond* Molecule::bond(int id) const
+// {
+// //pre: id does not exceed the number of atoms
+// Q_ASSERT(0 <= id && id < m_bondList.size());
+// //post: returns the i-th atom
+//
+// return m_bondList.at(id);
+// }
+
+QList<MsKAtom*> Molecule::atoms() const
+ {
+ //pre: true
+ //ret: the list of atoms
+
+ return QList<MsKAtom*>(m_atomList);
+ }
+
+QList<MsKBond*> Molecule::bonds() const
+ {
+ //pre: true
+ //ret: the list of bonds
+
+ return QList<MsKBond*>(m_bondList);
+ }
+
+int Molecule::charge( ) const
+ {
+ //pre: true
+ //ret: total charge of the atoms
+
+ MsKAtom* atom;
+ int totalCharge = 0;
+ foreach(atom,m_atomList)
+ totalCharge += atom->charge();
+
+
+ /// TODO can be improved
+ return totalCharge < 0 && scene()->autoAddHydrogen() ? 0 : totalCharge;
+ }
+
+QString Molecule::formula( ) const
+ {
+ //pre: true
+ //ret: formula of the molecule
+
+ // Create the output object
+ QString formula;
+
+ // Analyse the molecule and create a hash with the atoms
+ QHash<QString,int> hash;
+
+// for (int i = 0; i < countMsKAtoms(); i++)
+ foreach(MsKAtom* atom, m_atomList)
+ {
+ QString element = atom->element();
+ hash.insert(element, hash.value(element,0) + 1 );
+
+ // Add implicit hydrogens?
+ int hydrogens = atom->numberOfImplicitHydrogens();
+ if ( hydrogens > 0 ) hash.insert("H", hash.value("H",0) + hydrogens );
+ }
+
+ // First Carbon
+ if (hash.contains("C")) formula += "C" + (hash.value("C") > 1?formula.number(hash.value("C")):"");
+
+ // Then Nitrogen
+ if (hash.contains("N")) formula += "N" + (hash.value("N") > 1?formula.number(hash.value("N")):"");
+
+ // Compose the formula form the hash
+ QHashIterator<QString, int> i(hash);
+
+ // Then other elements
+ while (i.hasNext())
+ {
+ i.next();
+ if (!(i.key() == "C" || i.key() == "N" || i.key() == "H") )
+ {
+ formula += i.key() + (i.value() > 1 ? formula.number(i.value()) : "" );
+ }
+ }
+
+ // Finally Hydrogen
+ if (hash.contains("H")) formula += "H" + (hash.value("H") > 1?formula.number(hash.value("H")):"");
+
+ // Return the formula
+ return formula;
+ }
+
+double Molecule::weight( ) const
+ {
+ //pre: true
+ //ret: weigth of the molecule
+
+ double weight = 0;
+
+ foreach(MsKAtom* atom, m_atomList)
+ {
+ weight += atom->weight();
+ }
+
+ return weight;
+ }
+
+QString Molecule::chargeID( ) const
+ {
+ //pre: true
+ //ret: textual representation of the charge of the molecule
+
+ // Drawing text
+ int c = charge();
+ QString chargeId;
+ chargeId.setNum(c);
+ if (c < -1) chargeId = chargeId.remove(0,1) + "-";
+ if (c == -1) chargeId = "-";
+ if (c == 0) chargeId = "";
+ if (c == 1) chargeId = "+";
+ if (c > 1) chargeId = chargeId + "+";
+
+ return chargeId;
+ }
+
+bool Molecule::canSplit() const
+ {
+ /// TODO Needs improvement
+ // Create the return list
+ QList<Molecule*> molList;
+
+ // Return false if molecule is empty
+ if (m_atomList.isEmpty()) return false;
+ // Create sets with the bonds and molcules
+ QSet<MsKAtom*> atomSet(m_atomList.toSet());
+ QSet<MsKBond*> bondSet(m_bondList.toSet());
+ QSet<MsKAtom*> atomSubSet;
+ QSet<MsKBond*> bondSubSet;
+
+ // Declarations
+ int lastSize = 0;
+ MsKAtom* atom;
+ MsKBond* bond;
+
+ atomSubSet.clear();
+ bondSubSet.clear();
+
+ // Load the first atom
+ atomSubSet << atomSet.toList().first();
+
+ while (atomSubSet.size() != lastSize)
+ {
+ foreach (atom,atomSubSet)
+ {
+ lastSize = atomSubSet.size();
+ foreach(bond,bondSet) if (bond->hasMsKAtom(atom)) bondSubSet << bond;
+ foreach(bond,bondSubSet) atomSubSet << bond->firstMsKAtom() << bond->lastMsKAtom();
+ }
+ }
+
+ atomSet -= atomSubSet;
+ bondSet -= bondSubSet;
+
+ return !atomSet.isEmpty();
+ }
+
+QVariant Molecule::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemTransformHasChanged) rebuild();
+
+ return QGraphicsItem::itemChange(change, value);
+}
+
+void Molecule::rebuild()
+{
+ //pre: true
+ //post: the molecule has been rebuild
+
+ // Remove and then readd all elements
+ prepareGeometryChange();
+ foreach(MsKBond* bond, m_bondList) removeFromGroup(bond);
+ foreach(MsKAtom* atom, m_atomList) removeFromGroup(atom);
+ resetTransform();
+ foreach(MsKAtom* atom, m_atomList) addToGroup(atom);
+ foreach(MsKBond* bond, m_bondList) addToGroup(bond);
+}
+
+
+MsKBond* Molecule::bondBetween(MsKAtom* atomA, MsKAtom* atomB) const
+ {
+// for (int i = 0; i < countBonds(); i++)
+ foreach(MsKBond* bond, m_bondList)
+ if (((bond->firstMsKAtom() == atomA) || (bond->firstMsKAtom() == atomB )) && ((bond->lastMsKAtom() == atomA) || (bond->lastMsKAtom() == atomB ))) return bond;
+
+ return 0;
+ }
+
+// Event handlers
+
+// void Molecule::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
+// {
+// // if (scene() && scene()->getEditMode()==MolScene::MoveMode)
+// // {
+// // setFlag(QGraphicsItem::ItemIsSelectable,false);
+// // setSelected(true);
+// // }
+// QGraphicsItem::mouseReleaseEvent(event);
+// }
+
+// void Molecule::mousePressEvent(QGraphicsSceneMouseEvent * event)
+// {
+// // if (scene() && scene()->getEditMode()==MolScene::MoveMode)
+// // {
+// // setFlag(QGraphicsItem::ItemIsSelectable,true);
+// // setSelected(true);
+// // }
+// QGraphicsItem::mousePressEvent(event);
+// }
+
+// QVariant Molecule::itemChange(GraphicsItemChange change, const QVariant & value)
+// {
+// // if (change == ItemSelectedChange && isSelected())
+// // {
+// // setFlag(QGraphicsItem::ItemIsSelectable,false);
+// // }
+//
+// return QGraphicsItem::itemChange(change, value);
+// }
+
+QList< MsKBond * > Molecule::bondsOfMsKAtom(MsKAtom * atom)
+{
+ QList<MsKBond*> bondList;
+
+ foreach(MsKBond* bond, m_bondList)
+ {
+ if (bond->hasMsKAtom(atom)) bondList << bond;
+ };
+
+ return bondList;
+}
diff --git a/molsketch_helium/molecule.h b/molsketch_helium/molecule.h
new file mode 100644
index 0000000..5b722ad
--- /dev/null
+++ b/molsketch_helium/molecule.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+* This file is part of molsKetch and defines the class Molecule.
+*
+* @author Harm van Eersel <devsciurus at xs4all.nl>
+*/
+
+
+#ifndef MOLECULE_H
+#define MOLECULE_H
+
+#include <QList>
+
+#include "atom.h"
+#include "bond.h"
+#include "molscene.h"
+
+class QString;
+class QPoint;
+class QPainter;
+
+/**
+ * Represents a molecule on the scene. It can be created either as an empty molecule,
+ * with a set of atoms and bonds or as a copy of another molecule.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+class Molecule : public QGraphicsItemGroup
+ {
+ public:
+ // Constructors and destructor
+ /** Creates a molecule with @p parent on MolScene @p scene. */
+ Molecule(QGraphicsItem* parent = 0, MolScene* scene = 0);
+ /** Creates a molecule from the atoms and bonds of the sets with @p parent on MolScene @p scene. */
+ Molecule(QSet<MsKAtom*>, QSet<MsKBond*>, QGraphicsItem* parent = 0, MolScene* scene = 0);
+ /** Creates a copy of molecule @p mol with @p parent on MolScene @p scene. */
+ Molecule(Molecule* mol, QGraphicsItem* parent = 0, MolScene* scene = 0);
+
+ // Enabling typecasting
+ /** Enum with the type of the class. Needed for Qt typecasting. */
+ enum { Type = UserType + 1 };
+ /** Returns the type of the class. Needed for Qt typecasting. */
+ int type() const
+ {
+ return Type;
+ };
+
+ // Manipulation methods
+
+ /**
+ * This method add an atom to the molecule with @p element as element at position @p position.
+ *
+ * @param element element of the atom to be added to the molecule
+ * @param position the position where the atom should be added to the molecules in scene coordinates
+ *
+ * @return return a pointer to the new atom which has been added to the molecule
+ */
+ MsKAtom* addMsKAtom(const QString &element, const QPointF &position, bool implicitHydrogen);
+
+ /**
+ * This method adds an existing atom to the molecule.
+ *
+ * @param atom a pointer to the atom that should be added to the molecule.
+ *
+ * @return return a pointer to the atom just added to the molecule.
+ */
+ MsKAtom* addMsKAtom(MsKAtom* atom);
+
+ /**
+ * This method removes an atom from the molecule. The bonds connected to this atom will be removed as well.
+ * The atom and bonds will be removed from the scene, but the ownership will be passed on to the caller. This
+ * can be neccecary for undo operations.
+ *
+ * @param atom a pointer to the atom that should be removed from the molecule.
+ *
+ * @return a list with the bonds which were connected to the removed atom..
+ */
+ QList<MsKBond*> delAtom(MsKAtom* atom);
+
+ /** Adds a bond between @p atomA and @p atomB with @p order and @p type. */
+ MsKBond* addBond(MsKAtom* atomA, MsKAtom* atomB, int order = 1, int type = 0);
+ /** Adds existing bond @p bond to the molecule. */
+ MsKBond* addBond(MsKBond* bond);
+ /** Deletes @p bond from the molecule. */
+ void delBond(MsKBond* bond);
+
+// /** Automaticly adds an atom with a bond to @p startMsKAtom at a convenient position. */
+// void addAutoMsKAtom(MsKAtom* startMsKAtom);
+
+ /**
+ * Splits the molecule up in different seperate molecules. Used to clean up the molecule after removing the connection
+ * between two or more parts of the molecule.
+ *
+ * @return a list of the submolecules of which this molecule exists.
+ */
+ QList<Molecule*> split();
+
+
+ /**
+ * This method rebuilds the atom by removing all atoms and bonds from the molecule and consequently readding them.
+ * This is a hack to reset the boundingbox of the molecule after moving one of the atoms and is this method is in need
+ * of a proper solution.
+ */
+ void rebuild();
+
+// void normalize();
+// void setMsKAtomSize(qreal pt);
+
+ // Query methods
+ /** Returns a pointer to the atom at position @p pos, or NULL id none. */
+ MsKAtom* atomAt(const QPointF &pos) const;
+// /** Returns a pointer to the atom with @p id. */
+// MsKAtom* atom(int id) const;
+
+ /** Returns a pointer to the bond at position @p pos or NULL id none. */
+ MsKBond* bondAt(const QPointF &pos) const;
+// /** Returns a pointer to bond with @p id. */
+// MsKBond* bond(int id) const;
+ /** Returns a list of the bonds connected to @p atom. */
+ QList<MsKBond*> bondsOfMsKAtom(MsKAtom* atom);
+ /** Returns a pointer to the bond between @p atomA and @p atomB, or a NULL if none. */
+ MsKBond* bondBetween(MsKAtom* atomA, MsKAtom* atomB) const;
+
+ /** Returns @c true if the molecule exists of two seperate submolecules, and @c false otherwise. */
+ bool canSplit() const;
+
+ /** Returns the list of atoms in the molecule. */
+ QList<MsKAtom*> atoms() const;
+ /** Returns the list of bonds in the molecule */
+ QList<MsKBond*> bonds() const;
+
+ /** Returns the MolScene of the molecule. */
+ virtual MolScene* scene() const
+ {
+ return static_cast<MolScene*>(QGraphicsItemGroup::scene());
+ };
+
+ /** Returns the molecule formula. */
+ QString formula() const;
+ /** Returns the weigth of the molecule. */
+ double weight() const;
+ /** Returns the charge of the molecule. */
+ int charge() const;
+ /** Returns the charge as a string with an appropiate + or - sign. */
+ QString chargeID() const;
+
+ protected:
+// /** Event handler for mouse press events on the molecule. */
+// virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
+// /** Event handler for mouse release events on the molecule.*/
+// virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler for changes of the molecule. Needed for rotation handling.*/
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ private:
+ // Internal representation
+ /** A list of pointers to the atoms of the molecule. Used as internal reprentation. */
+ QList<MsKAtom*> m_atomList;
+ /** A list of pointers to the bonds of the molecule. Used as internal representation. */
+ QList<MsKBond*> m_bondList;
+
+ };
+
+
+
+#endif
diff --git a/molsketch_helium/mollibitem.cpp b/molsketch_helium/mollibitem.cpp
new file mode 100644
index 0000000..f9a59f1
--- /dev/null
+++ b/molsketch_helium/mollibitem.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QtGui>
+
+#include "molecule.h"
+#include "mollibitem.h"
+#include "fileio.h"
+
+MolLibItem::MolLibItem( Molecule* molecule, const QString & name )
+{
+ //pre: molecule is a valid molecule
+ Q_CHECK_PTR(molecule);
+// Q_ASSERT(!molecule->atoms().isEmpty());
+
+ // Copying the molecule
+ m_molecule = new Molecule(molecule);
+ m_molecule->setPos(0,0);
+
+ // Creating pixmap
+ MolScene renderScene;
+ renderScene.addItem(m_molecule);
+
+ QBitmap bitmap(renderScene.sceneRect().width(),renderScene.sceneRect().height());
+ bitmap.clear();
+
+ // Creating and setting the painter
+ QPainter painter(&bitmap);
+ painter.setRenderHint(QPainter::Antialiasing);
+ renderScene.render(&painter);
+
+ setIcon(QIcon(bitmap));
+
+ // Checking dir
+ QDir dir;
+ if (!dir.exists(QDir::homePath() + "/.molsketch/library/custom/"))
+ {
+ dir.mkpath(QDir::homePath() + "/.molsketch/library/custom/");
+ }
+
+ // Setting name
+ m_fileName = name;
+ if (!m_fileName.exists())
+ {
+ m_fileName.setFile(QDir::homePath() + "/.molsketch/library/custom/" + name + ".mol");
+ molsKetch::saveFile(m_fileName.filePath(),&renderScene);
+ }
+
+ setText(m_fileName.baseName());
+
+ // Remove the m_molecule before destroying the scene
+ renderScene.removeItem(m_molecule);
+
+}
+
+MolLibItem::~ MolLibItem( )
+{
+ // Delete all bonds and atoms and finally the molecule
+ foreach(MsKBond* bond, m_molecule->bonds()) delete bond;
+ foreach(MsKAtom* atom, m_molecule->atoms()) delete atom;
+ delete m_molecule;
+}
+
+Molecule* MolLibItem::getMolecule( )
+{
+ // Return a copy of the m_molecule
+// Molecule* mol = new Molecule(m_molecule);
+ return new Molecule(m_molecule);
+}
+
+void MolLibItem::setMolecule( Molecule* mol )
+{
+ // Delete the old molecule
+ foreach(MsKBond* bond, m_molecule->bonds()) delete bond;
+ foreach(MsKAtom* atom, m_molecule->atoms()) delete atom;
+ delete m_molecule;
+
+ // Set a copy of mol as the new molecule
+ m_molecule = new Molecule(mol);
+}
+
diff --git a/molsketch_helium/mollibitem.h b/molsketch_helium/mollibitem.h
new file mode 100644
index 0000000..42c175b
--- /dev/null
+++ b/molsketch_helium/mollibitem.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef MOLLIBITEM_H
+#define MOLLIBITEM_H
+
+#include <QListWidgetItem>
+#include <QFileInfo>
+
+
+class Molecule;
+
+// class QTableWidgetItem;
+
+/**
+ * Represents an item in the molecule library
+ *
+ * @author Harm van Eersel
+ */
+class MolLibItem : public QListWidgetItem
+{
+ public:
+ /** Creates a new library item.
+ *
+ * @param molecule a pointer to the molecule that should be copied to the library
+ * @param name the name of the library item
+ */
+ MolLibItem(Molecule* molecule, const QString & name);
+
+ /** Destructor of the library item. */
+ virtual ~MolLibItem();
+
+ /** Sets a copy of @p molecule as the molecule of the library item */
+ void setMolecule(Molecule* molecule);
+
+ /** Returns a pointer to copy of molecule of the library item. */
+ Molecule* getMolecule();
+
+ /** Returns the filename of the library item. */
+ QFileInfo getFileName() { return m_fileName; };
+
+private:
+ /** Stores the molecule of the library item. */
+ Molecule* m_molecule;
+ /** Stores the filename of the library item. */
+ QFileInfo m_fileName;
+};
+
+#endif
diff --git a/molsketch_helium/molsKetch.nsi b/molsketch_helium/molsKetch.nsi
new file mode 100644
index 0000000..47df99f
--- /dev/null
+++ b/molsketch_helium/molsKetch.nsi
@@ -0,0 +1,148 @@
+;NSIS Modern User Interface
+;Derived from the Welcome/Finish Page Example Script
+;Originally written by Joost Verburg
+
+;--------------------------------
+;Include Modern UI
+
+ !include "MUI.nsh"
+
+;--------------------------------
+;General
+
+ ;Name and file
+ Name "molsKetch"
+ OutFile "install.exe"
+
+ ;Default installation folder
+ InstallDir "$PROGRAMFILES\molsKetch"
+
+ ;Get installation folder from registry if available
+ InstallDirRegKey HKCU "Software\molsKetch" ""
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_ABORTWARNING
+
+;--------------------------------
+;Pages
+
+ !insertmacro MUI_PAGE_WELCOME
+ !insertmacro MUI_PAGE_LICENSE "./License.txt"
+ !insertmacro MUI_PAGE_COMPONENTS
+ !insertmacro MUI_PAGE_DIRECTORY
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+
+ !insertmacro MUI_UNPAGE_WELCOME
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+ !insertmacro MUI_UNPAGE_FINISH
+
+;--------------------------------
+;Languages
+
+ !insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+;Installer Sections
+
+Section "Program files" basic
+
+ SetOutPath "$INSTDIR"
+
+ File "mingwm10.dll"
+ File "libopenbabel-2.dll"
+ File "libinchi-0.dll"
+ File "QtGUI4.dll"
+ File "QtAssistantCLient4.dll"
+ File "QtCore4.dll"
+ File "QtNetwork4.dll"
+ File "QtXml4.dll"
+ File "assistant.exe"
+ File "molsKetch.exe"
+ File "molsKetch.ico"
+
+ File /r "doc"
+ File /r "library"
+
+ ;Store installation folder
+ WriteRegStr HKCU "Software\molsKetch" "Install_Dir" $INSTDIR
+
+ ; Write the uninstall keys for Windows
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\molsKetch" "DisplayName" "molsKetch"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\molsKetch" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\molsKetch" "NoModify" 1
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\molsKetch" "NoRepair" 1
+
+ ;Create uninstaller
+ WriteUninstaller "$INSTDIR\Uninstall.exe"
+
+SectionEnd
+
+
+; Optional section (can be disabled by the user)
+Section "Start Menu Shortcuts"
+
+ CreateDirectory "$SMPROGRAMS\molsKetch"
+ CreateShortCut "$SMPROGRAMS\molsKetch\molsKetch.lnk" "$INSTDIR\molsKetch.exe" "" "$INSTDIR\molsKetch.ico" 0
+ CreateShortCut "$SMPROGRAMS\molsKetch\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+
+
+SectionEnd
+
+
+;--------------------------------
+;Descriptions
+
+ ;Language strings
+ LangString DESC_molsKetch ${LANG_ENGLISH} "The basic installation"
+
+ ;Assign language strings to sections
+ !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+ !insertmacro MUI_DESCRIPTION_TEXT ${basic} $(DESC_molsKetch)
+ !insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+
+ Delete "$INSTDIR\mingwm10.dll"
+ Delete "$INSTDIR\libopenbabel-2.dll"
+ Delete "$INSTDIR\libinchi-0.dll"
+ Delete "$INSTDIR\QtGUI4.dll"
+ Delete "$INSTDIR\QtAssistantCLient4.dll"
+ Delete "$INSTDIR\QtCore4.dll"
+ Delete "$INSTDIR\QtNetwork4.dll"
+ Delete "$INSTDIR\QtXml4.dll"
+ Delete "$INSTDIR\assistant.exe"
+ Delete "$INSTDIR\molsKetch.exe"
+ Delete "$INSTDIR\molsKetch.ico"
+
+ Delete "$INSTDIR\Uninstall.exe"
+
+ Delete "$INSTDIR\library\custom\*.*"
+ Delete "$INSTDIR\library\*.*"
+ Delete "$INSTDIR\doc\en\*.*"
+ Delete "$INSTDIR\doc\nl\*.*"
+ Delete "$INSTDIR\doc\*.*"
+
+ ; Remove shortcuts, if any
+ Delete "$SMPROGRAMS\molsKetch\*.*"
+
+ ; Remove directories used
+ RMDir "$INSTDIR\library\custom"
+ RMDir "$INSTDIR\library"
+ RMDir "$INSTDIR\doc\en"
+ RMDir "$INSTDIR\doc\nl"
+ RMDir "$INSTDIR\doc"
+ RMDir "$SMPROGRAMS\molsKetch"
+ RMDir "$INSTDIR"
+
+ ; Remove registry keys
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\molsKetch"
+ DeleteRegKey HKCU "Software\molsKetch"
+
+SectionEnd
diff --git a/molsketch_helium/molscene.cpp b/molsketch_helium/molscene.cpp
new file mode 100644
index 0000000..16f324f
--- /dev/null
+++ b/molsketch_helium/molscene.cpp
@@ -0,0 +1,1168 @@
+/***************************************************************************
+ * Copyright (C) 2007-2008 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <cmath>
+#include <math.h>
+#include <iostream>
+
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QClipboard>
+#include <QApplication>
+#include <QListWidgetItem>
+#include <QTableWidgetItem>
+#include <QKeyEvent>
+#include <QUndoStack>
+#include <QDebug>
+
+#include "molscene.h"
+#include "molecule.h"
+#include "mollibitem.h"
+#include "commands.h"
+
+
+using namespace Commands;
+
+// Constructor & destructor
+
+MolScene::MolScene(QObject* parent) : QGraphicsScene(parent)
+{
+ //Initializing properties
+ m_currentElementSymbol = "C";
+ m_editMode = MolScene::AddMode;
+ m_bondLength = 40;
+ m_bondOrder = 1;
+ m_bondType = 0;
+ m_atomSize = 5;
+ m_bondAngle = 30;
+ m_carbonVisible = false;
+ m_hydrogenVisible = true;
+ m_chargeVisible = true;
+ m_autoAddHydrogen = true;
+
+ // Prepare undo m_stack
+ m_stack = new QUndoStack(this);
+ connect(m_stack, SIGNAL(indexChanged(int)), this, SIGNAL(documentChange()));
+ connect(m_stack, SIGNAL(indexChanged(int)), this, SIGNAL(selectionChange()));
+// connect(m_stack, SIGNAL(indexChanged(int)), this, SIGNAL());
+ connect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(update()));
+
+ // Prepare hinting items
+ initHintItems();
+
+ // Set initial size
+ QRectF sizerect(-5000,-5000,10000,10000);
+ setSceneRect(sizerect);
+}
+
+
+MolScene::~MolScene()
+{
+ // Clear the scene
+ clear();
+
+ // Destroy the hint items
+ foreach(QGraphicsItem* item, m_hintPoints) delete item;
+ delete m_hintLine;
+// delete m_hoverRect;
+}
+
+// Commands
+
+void MolScene::setCarbonVisible( bool value )
+{
+ m_carbonVisible = value;
+}
+
+void MolScene::setHydrogenVisible( bool value )
+{
+ m_hydrogenVisible = value;
+}
+
+void MolScene::setBondLength( double length )
+{
+ //pre: bondlength > 0
+ Q_ASSERT(length > 0);
+// if (m_bondLength <= 0) return;
+
+ // Set the bondlength
+ m_bondLength = length;
+
+ // Reinitialize hintitems
+ foreach (QGraphicsItem* item, m_hintPoints) delete item;
+ m_hintPoints.clear();
+ initHintItems();
+}
+
+void MolScene::setMsKAtomSize( qreal size )
+{
+ m_atomSize = size;
+}
+
+void MolScene::alignToGrid()
+{
+ m_stack->beginMacro(tr("aligning to grid"));
+ foreach(QGraphicsItem* item,items())
+ if (item->type() == Molecule::Type)
+ m_stack->push(new MoveItem(item,toGrid(item->scenePos()) - item->scenePos()));
+ m_stack->endMacro();
+ update();
+}
+
+void MolScene::setEditMode(int mode)
+{
+ // Reset moveflag (movebug)
+ foreach(QGraphicsItem* item, items()) item->setFlag(QGraphicsItem::ItemIsMovable,false);
+
+ foreach(QGraphicsItem* item, items())
+ if (item->type()==Molecule::Type || item->type()==MsKAtom::Type) item->setFlag(QGraphicsItem::ItemIsSelectable,mode == MolScene::MoveMode);
+
+ // Set the new edit mode and signal other components
+ m_editMode = mode;
+ emit editModeChange( mode );
+}
+
+void MolScene::cut()
+{
+ ///TODO
+ // Check if something is selected
+ if (selectedItems().isEmpty()) return;
+
+ // Then do a copy
+ copy();
+
+ // Finally delete the selected items
+ m_stack->beginMacro(tr("cutting items"));
+ foreach (QGraphicsItem* item, selectedItems())
+ if (item->type() == Molecule::Type) m_stack->push(new DelItem(item));
+ m_stack->endMacro();
+}
+
+void MolScene::copy()
+{
+ // Check if something is selected
+ if (selectedItems().isEmpty()) return;
+
+ ///TODO
+ // Access the clipboard
+ QClipboard* clipboard = qApp->clipboard();
+
+ // Calculate total boundingrect
+ QRectF totalRect;
+ foreach(QGraphicsItem* item, selectedItems())
+ {
+ QRectF itemRect = item->boundingRect();
+ itemRect.translate(item->scenePos());
+ totalRect |= itemRect;
+ }
+ // Add to internal clipboard
+ foreach(QGraphicsItem* item, m_clipItems) delete item;
+ m_clipItems.clear();
+ foreach(QGraphicsItem* item, selectedItems())
+ if (item->type() == Molecule::Type)
+ m_clipItems.append(new Molecule(dynamic_cast<Molecule*>(item)));
+
+ // Clear selection
+ QList<QGraphicsItem*> selList(selectedItems());
+ clearSelection();
+
+ // Choose the datatype
+ // clipboard->setText("Test");
+ clipboard->setImage(renderImage(totalRect));
+ // clipboard->mimeData( );
+
+ // Restore selection
+ foreach(QGraphicsItem* item, selList) item->setSelected(true);
+
+ // Emit paste available signal
+ emit pasteAvailable(!m_clipItems.isEmpty());
+}
+
+void MolScene::paste()
+{
+ // Access the clipboard
+ QClipboard* clipboard = qApp->clipboard();
+
+ // Paste all items on the internal clipboard
+ m_stack->beginMacro(tr("pasting items"));
+ foreach(Molecule* item, m_clipItems) m_stack->push(new AddItem(new Molecule(item),this));
+ m_stack->endMacro();
+}
+
+
+void MolScene::clear()
+{
+ // Purge the undom_stack
+ m_stack->clear();
+
+ // Removing all objects from the scene
+ while (!items().isEmpty()) delete items()[0];
+// foreach (QGraphicsItem* item,items()) /// Why doesn't this work?
+// {
+// removeItem(item);
+// delete item;
+// }
+
+ // Reinitialize the scene
+ m_hintPoints.clear();
+ initHintItems();
+ setEditMode(MolScene::AddMode);
+}
+
+
+QImage MolScene::renderImage(const QRectF &rect)
+{
+ // Creating an image
+ QImage image(rect.width(),rect.height(),QImage::Format_RGB32);
+ image.fill(QColor("white").rgb());
+
+ // Creating and setting the painter
+ QPainter painter(&image);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ // Rendering in the image and saving to file
+ render(&painter,QRectF(0,0,rect.width(),rect.height()),rect);
+
+ return image;
+}
+
+void MolScene::setElement( QListWidgetItem * item )
+{
+ if (item->text() != " ")
+ m_currentElementSymbol = item->text();
+ setEditMode(MolScene::AddMode);
+}
+
+void MolScene::setElement( QTableWidgetItem * item )
+{
+ m_currentElementSymbol = item->text();
+ setEditMode(MolScene::AddMode);
+}
+
+Molecule * MolScene::merge( const Molecule * molA, const Molecule* molB )
+{
+ // pre: molA and molB are different molecules
+ Q_CHECK_PTR(molA);
+ Q_CHECK_PTR(molB);
+ Q_ASSERT(molA != molB);
+
+ // Creating a new molecule for the merge
+ Molecule* molC = new Molecule;
+
+ // Adding the bonds and atoms of the first two molecules
+ foreach (MsKAtom* a, molA->atoms())
+ {
+ MsKAtom* a2 = new MsKAtom(a->scenePos(),a->element(),a->implicitHydrogens());
+ molC->addMsKAtom(a2);
+ }
+ foreach (MsKBond* b, molA->bonds())
+ {
+ molC->addBond( molC->atomAt(b->firstMsKAtom()->scenePos()), molC->atomAt(b->lastMsKAtom()->scenePos()), b->bondOrder(), b->bondType());
+ }
+ foreach (MsKAtom* a, molB->atoms())
+ {
+ molC->addMsKAtom( a->element(), a->scenePos(), a->implicitHydrogens());
+ }
+ foreach (MsKBond* b, molB->bonds())
+ {
+ molC->addBond( molC->atomAt(b->firstMsKAtom()->scenePos()), molC->atomAt(b->lastMsKAtom()->scenePos()), b->bondOrder(), b->bondType());
+ }
+
+// molC->setPos(molA->scenePos());
+
+ return molC;
+}
+
+void MolScene::addMolecule(QListWidgetItem* mol )
+{
+ // Extract the molecule and add it to the sceneMolecule* m
+ Molecule * m;
+ if (dynamic_cast<MolLibItem*>(mol))
+ m = dynamic_cast<MolLibItem*>(mol)->getMolecule();
+ else
+ return;
+
+ addMolecule(m);
+}
+
+void MolScene::addMolecule(Molecule* mol)
+{
+ Q_CHECK_PTR(mol);
+ if (!mol) return;
+ m_stack->beginMacro(tr("add molecule"));
+ m_stack->push(new AddItem(mol,this));
+ if (mol->canSplit()) m_stack->push(new SplitMol(mol));
+ m_stack->endMacro();
+}
+
+void MolScene::setBondAngle(double angle)
+{
+ Q_ASSERT (angle > 0 and angle <= 360);
+
+ // Set the new hintPointCount and reinitialize
+ m_bondAngle = angle;
+
+ // Reinitialize hintitems
+ foreach (QGraphicsItem* item, m_hintPoints) delete item;
+ m_hintPoints.clear();
+ initHintItems();
+}
+
+void MolScene::selectAll()
+{
+ // Switch to move mode to make selection posible
+ setEditMode(MolScene::MoveMode);
+
+ // Clear any previous selection
+ clearSelection();
+
+ // Mark all molecules as selected
+ foreach (QGraphicsItem* item, items())
+ {
+ if (item->type() == Molecule::Type)
+ item->setSelected(true);
+ }
+}
+
+// Hinting methods
+
+void MolScene::drawHintPoints(const QPointF &startPos )
+{
+ QPointF position = startPos;
+
+ // If clicked on atom, use that as startpoint
+ MsKAtom* atom = atomAt(position);
+ if (atom) position = atom->scenePos();
+
+ // Draw hintpoints
+ m_hintPointsGroup->setPos(position);
+ addItem(m_hintPointsGroup);
+}
+
+void MolScene::initHintItems()
+{
+ // Initialize hintline
+ m_hintLine = new QGraphicsLineItem(QLineF(0,0,0,0));
+ m_hintLine->setAcceptedMouseButtons(0);
+ m_hintLine->setZValue(-1);
+
+// // Initialize hover feedback
+// m_hoverRect = new QGraphicsPathItem(QPainterPath());
+// m_hoverRect->setZValue(5);
+// m_hoverRect->setAcceptedMouseButtons(0);
+
+ // Initialize hintpoints
+ m_hintPointsGroup = new QGraphicsItemGroup();
+ int parts = 360/m_bondAngle;
+ for (int i = 0; i < parts; i++)
+ {
+ // Calculate dot position
+ double x = 2*3.14*i/parts;
+ QPointF hintPoint = QPointF(sin(x) * m_bondLength, cos(x) * m_bondLength);
+ // Create the dot
+ QGraphicsEllipseItem* dot = new QGraphicsEllipseItem(-2.5,-2.5,5,5);
+ dot->setBrush(Qt::lightGray);
+ dot->setPen(Qt::NoPen);
+ // Add the dot
+ m_hintPoints.append(dot);
+ m_hintPoints[i]->setPos(hintPoint);
+ m_hintPointsGroup->addToGroup(m_hintPoints[i]);
+ // scene()->addRect(QRectF(hintPoint.x()-2.5,hintPoint.y()-2.5,5,5));
+ }
+// m_hintPointsGroup->setVisible(false);
+ m_hintPointsGroup->setAcceptedMouseButtons(0);
+}
+
+void MolScene::setHintLine( const QPointF &startPos, const QPointF &curPos )
+{
+ // Set the hintline between startPos and curPos
+ m_hintLine->setLine(QLineF(startPos,curPos));
+
+ // If not already added, add the hintline to the scene
+ if (!items().contains(m_hintLine)) addItem(m_hintLine);
+}
+
+void MolScene::setHoverRect( QGraphicsItem* item )
+{
+ if (item) {
+ m_hoverRect->setPath(item->shape());
+ m_hoverRect->setPos(item->scenePos());
+// m_hoverRect->setVisible(true);
+ addItem(m_hoverRect);
+ } else {
+// m_hoverRect->setVisible(false);
+ removeItem(m_hoverRect);
+ }
+}
+
+void MolScene::removeHintLine( )
+{
+ // delete hintLine;
+ // scene()->removeItem(hintLine);
+// m_hintLine->setVisible(false);
+ if (items().contains(m_hintLine)) removeItem(m_hintLine);
+ // scene()->update();
+}
+
+void MolScene::removeHintPoints( )
+{
+// m_hintPointsGroup->setVisible(false);
+ if (items().contains(m_hintPointsGroup)) removeItem(m_hintPointsGroup);
+// for (int i = 0; i<m_bondAngle;i++)
+// {
+// // scene()->removeItem(hintPoints[i]);
+// hintPoints[i]->setVisible(false);
+// // delete hintPoints[i];
+// }
+}
+
+// Queries
+
+bool MolScene::carbonVisible( ) const
+ {
+ return m_carbonVisible;
+ }
+
+bool MolScene::hydrogenVisible( ) const
+ {
+ return m_hydrogenVisible;
+ }
+
+qreal MolScene::bondLength( ) const
+ {
+ return m_bondLength;
+ }
+
+qreal MolScene::atomSize( ) const
+ {
+ return m_atomSize;
+ }
+
+int MolScene::editMode() const
+ {
+ return m_editMode;
+ }
+
+
+// Advanced queries
+QPointF MolScene::nearestPoint(const QPointF &curPos)
+{
+ //pre: true
+ //ret: nearest preferred point of curPos
+
+ // Set the maximun length
+ qreal lastLength = m_bondLength / 4;
+ QPointF nPoint = curPos;
+
+ // Check the hinting points
+ for (int i = 0; i < m_hintPoints.size(); i++)
+ {
+ QPointF hPoint = m_hintPoints[i]->scenePos();
+ QLineF iLine(curPos,hPoint);
+ if (iLine.length() < lastLength)
+ {
+ nPoint = hPoint;
+ lastLength = iLine.length();
+ }
+ }
+
+ // Look whether a atom is nearby
+ MsKAtom* atom = atomAt(curPos);
+ if (atom) nPoint = atom->scenePos();
+
+ return nPoint;
+}
+
+QPointF MolScene::toGrid(const QPointF &position)
+{
+ QPointF p = position;
+// p.rx() = floor(p.x() / 100) * 100;
+// p.ry() = floor(p.y() / 100) * 100;
+// m_bondLength;
+ int factor = 40;
+ p.rx() = floor(p.x() / factor) * factor;
+ p.ry() = floor(p.y() / factor) * factor;
+// p.rx() = (p.x() / 10) * 10;
+// p.ry() = (p.y() / 10) * 10;
+
+ return p;
+}
+
+
+Molecule* MolScene::moleculeAt(const QPointF &pos)
+{
+ // Check if there is a molecule at this position
+ foreach(QGraphicsItem* item,items(pos))
+ if (item->type() == Molecule::Type) return dynamic_cast<Molecule*>(item);
+
+ // Else return NULL
+ return 0;
+
+}
+
+MsKAtom* MolScene::atomAt(const QPointF &pos)
+{
+ // Check if there is a atom at this position
+ foreach(QGraphicsItem* item,items(pos))
+ if (item->type() == MsKAtom::Type) return dynamic_cast<MsKAtom*>(item);
+// // Maybe the atom is hidden, try an alternative detection
+// for (int i = 0; i < items(pos).size(); i++)
+// {
+// QGraphicsItem* item = items(pos).at(i);
+// MsKAtom* atom;
+// if (item->type() == Molecule::Type) atom = dynamic_cast<Molecule*>(item)->getMsKAtom(pos);
+// if (atom) return atom;
+// }
+
+ // Can't find an atom at that location
+ return 0;
+}
+
+MsKBond* MolScene::bondAt(const QPointF &pos)
+{
+ // Check if there is a bond at this position
+ foreach( QGraphicsItem* item,items(pos))
+ if (item->type() == MsKBond::Type) return dynamic_cast<MsKBond*>(item);
+
+ // Else return NULL
+ return 0;
+}
+
+// Event handlers
+
+bool MolScene::event(QEvent* event)
+{
+ // Execute default behaivior
+ bool accepted = QGraphicsScene::event(event);
+
+ // Check whether copying is available
+ if ((event->type() == QEvent::GraphicsSceneMouseRelease) || (event->type() == QEvent::KeyRelease))
+ {
+ emit copyAvailable(!selectedItems().isEmpty());
+// emit pasteAvailable(!m_clipItems.isEmpty());
+ emit selectionChange( );
+ }
+
+ // Execute default behavior
+ return accepted;
+}
+
+void MolScene::mousePressEvent(QGraphicsSceneMouseEvent* event)
+{
+ // // Execute default behavior
+ // QGraphicsScene::mousePressEvent(event);
+
+ // Execute extended behavior depending on edit mode and mouse button
+ switch (event->button())
+ {
+ case Qt::RightButton:
+ delModePress( event );
+ break;
+ case Qt::MidButton:
+ moveModePress( event );
+ break;
+ case Qt::LeftButton:
+ switch (m_editMode)
+ {
+ case MolScene::AddMode:
+ addModePress( event );
+ break;
+ case MolScene::RemoveMode:
+ delModePress( event );
+ break;
+ case MolScene::MoveMode:
+ moveModePress( event );
+ break;
+ case MolScene::RotateMode:
+ rotateModePress( event );
+ break;
+ default:
+ break;
+ };
+ default:
+ break;
+ }
+
+ // Execute default behavior
+ QGraphicsScene::mousePressEvent(event);
+}
+
+void MolScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
+{
+ // Determin the right action
+ switch (event->button())
+ {
+ case Qt::MidButton:
+ moveModeMove(event);
+ break;
+ default:
+ switch (m_editMode)
+ {
+ case MolScene::AddMode:
+ addModeMove(event);
+ break;
+// case MolScene::MoveMode:
+// moveModeMove(event);
+// break;
+ case MolScene::RotateMode:
+ rotateModeMove(event);
+ break;
+ }
+ }
+
+ // Execute default behavior
+ QGraphicsScene::mouseMoveEvent(event);
+}
+
+
+void MolScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
+{
+
+ // Determin the right action
+ switch (event->button())
+ {
+ case Qt::RightButton:
+ break;
+ case Qt::MidButton:
+ moveModeRelease(event);
+ break;
+ default:
+ switch (m_editMode)
+ {
+ case MolScene::AddMode:
+ addModeRelease(event);
+ clearSelection();
+ break;
+ case MolScene::MoveMode:
+ moveModeRelease(event);
+ break;
+ case MolScene::RotateMode:
+ rotateModeRelease(event);
+ break;
+ }
+ }
+
+ // Execute the normal behavior
+ QGraphicsScene::mouseReleaseEvent(event);
+}
+
+
+void MolScene::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * event )
+{
+
+ // Determin the corresponding action
+ switch (event->button())
+ {
+ case Qt::RightButton:
+ delModeDoubleClick(event);
+ break;
+ default:
+ switch (m_editMode)
+ {
+ case MolScene::AddMode:
+ break;
+ case MolScene::RemoveMode:
+ delModeDoubleClick(event);
+ break;
+ case MolScene::MoveMode:
+ break;
+ }
+ }
+
+ // Execute default behavior
+ QGraphicsScene::mouseDoubleClickEvent( event );
+}
+
+void MolScene::moveModePress(QGraphicsSceneMouseEvent* event)
+{
+ ///TODO Improve
+ // Execute default behavior
+ QGraphicsScene::mousePressEvent(event);
+
+ // Flag the selected items as moveable
+ clearFocus();
+ foreach(QGraphicsItem* item,selectedItems()) item->setFlag(QGraphicsItem::ItemIsMovable,true);
+ emit copyAvailable(!selectedItems().isEmpty());
+}
+
+void MolScene::moveModeMove(QGraphicsSceneMouseEvent* event)
+{
+
+}
+
+void MolScene::moveModeRelease(QGraphicsSceneMouseEvent* event)
+{
+
+ QPointF moveVector = event->scenePos() - event->buttonDownScenePos(event->button());
+ if(moveVector.isNull())
+ {
+ clearFocus();
+ return;
+ }
+
+ m_stack->beginMacro(tr("moving item(s)"));
+
+ foreach(QGraphicsItem* item,selectedItems())
+ {
+ item->moveBy(-moveVector.x(), -moveVector.y());
+ if (!moveVector.isNull()) m_stack->push(new MoveItem(item,moveVector,tr("moving item(s)")));
+ item->setFlag(QGraphicsItem::ItemIsMovable,false);
+ }
+ m_stack->endMacro();
+ clearFocus();
+
+}
+
+void MolScene::rotateModePress(QGraphicsSceneMouseEvent* event)
+{
+ // Execute default behavior
+ QGraphicsScene::mousePressEvent(event);
+}
+
+void MolScene::rotateModeMove(QGraphicsSceneMouseEvent* event)
+{
+ // Do nothing if no buttons are pressed
+ if (!(event->buttons() & Qt::LeftButton)) return;
+
+ // Find the item to rotate and it's rotation point
+ QGraphicsItem * item = itemAt(event->buttonDownScenePos(Qt::LeftButton));
+ if (!item) return;
+ if (item->type() == MsKAtom::Type) item = item->parentItem();
+ if (item->type() == MsKBond::Type) item = item->parentItem();
+ QPointF rotatePoint = item->boundingRect().center();
+
+ // Calculate the rotation angle
+ QPointF vec1 = event->buttonDownScenePos(Qt::LeftButton) - item->mapToScene(rotatePoint);
+ QPointF vec2 = event->scenePos() - item->mapToScene(rotatePoint);
+ qreal alpha = std::atan2(vec1.y(), vec1.x());
+ qreal beta = std::atan2(vec2.y(), vec2.x());
+ qreal rotateAngle = beta - alpha;
+// if (event->modifiers() != Qt::AltModifier) rotateAngle = toRoundedAngle(rotateAngle);
+ if (rotateAngle == 0) return;
+
+ // Temporary rotate the item
+ QTransform transform;
+ transform.translate(rotatePoint.x(), rotatePoint.y());
+ switch (event->modifiers()) {
+ case Qt::ControlModifier: transform.rotate(rotateAngle, Qt::XAxis); break;
+ case Qt::ShiftModifier: transform.rotate(rotateAngle, Qt::YAxis); break;
+ default: transform.rotate(rotateAngle, Qt::ZAxis);
+ };
+ transform.translate(-rotatePoint.x(), -rotatePoint.y());
+ item->setTransform(transform, true);
+// item->rotate(rotateAngle);
+}
+
+void MolScene::rotateModeRelease(QGraphicsSceneMouseEvent* event)
+{
+ // Find the item to rotate find the rotate point
+ QGraphicsItem * item = itemAt(event->buttonDownScenePos(Qt::LeftButton));
+ if (!item) return;
+ if (item->type() == MsKAtom::Type) item = item->parentItem();
+ if (item->type() == MsKBond::Type) item = item->parentItem();
+ QPointF rotatePoint = item->boundingRect().center();
+
+ // Calculate the rotation angle
+ QPointF vec1 = event->buttonDownScenePos(Qt::LeftButton) - item->mapToScene(rotatePoint);
+ QPointF vec2 = event->scenePos() - item->mapToScene(rotatePoint);
+ qreal alpha = std::atan2(vec1.y(), vec1.x());
+ qreal beta = std::atan2(vec2.y(), vec2.x());
+ qreal rotateAngle = beta - alpha;
+// if (event->modifiers() != Qt::AltModifier) rotateAngle = toRoundedAngle(rotateAngle);
+ if (rotateAngle == 0) return;
+
+ // Rotate the item
+ QTransform transform;
+ transform.translate(rotatePoint.x(), rotatePoint.y());
+ switch (event->modifiers()) {
+ case Qt::ControlModifier: transform.rotate(rotateAngle, Qt::XAxis); break;
+ case Qt::ShiftModifier: transform.rotate(rotateAngle, Qt::YAxis); break;
+ default: transform.rotate(rotateAngle, Qt::ZAxis);
+ };
+ transform.translate(-rotatePoint.x(), -rotatePoint.y());
+ item->setTransform(transform.inverted(), true);
+// item->rotate(-rotateAngle/(2*M_PI)*360);
+
+ m_stack->beginMacro(tr("rotating item(s)"));
+ m_stack->push(new RotateItem(item, transform, tr("rotating item(s)")));
+ m_stack->endMacro();
+}
+
+void MolScene::addModePress(QGraphicsSceneMouseEvent* event)
+{
+ // Get the position
+ QPointF downPos = event->buttonDownScenePos(event->button());
+
+ // Check for bond click
+ if (bondAt(downPos) && !atomAt(downPos))
+ {
+// if (bondAt(downPos)->bondOrder() != m_bondOrder or bondAt(downPos)->bondType() != m_bondType) {
+// m_stack->beginMacro("Change bond style");
+// MsKBond * bond = bondAt(downPos);
+// while (bond->bondOrder() != m_bondOrder)
+// m_stack->push(new IncOrder(bond));
+// while (bond->bondType() != m_bondType)
+// m_stack->push(new IncType(bond));
+// m_stack->endMacro();
+// return;
+// } else {
+ if (event->modifiers() == Qt::SHIFT)
+ m_stack->push(new IncType(bondAt(downPos),tr("change of bondtype")));
+ else
+ m_stack->push(new IncOrder(bondAt(downPos),tr("change of bondorder")));
+ return;
+// }
+ }
+
+ // Show hinting
+ if (m_currentElementSymbol != "+" && m_currentElementSymbol != "-" && m_currentElementSymbol != "H+" && m_currentElementSymbol != "H-")
+ {
+ drawHintPoints(downPos);
+ setHintLine(downPos,event->scenePos());
+ m_hintLine->setVisible(true);
+ }
+
+ // Check which molecule has been clicked on
+ MsKAtom* atom = atomAt(downPos);
+
+ // Add a new molecule if necesarry
+ if (!atom && m_currentElementSymbol!="+" && m_currentElementSymbol!="-" && m_currentElementSymbol != "H+" && m_currentElementSymbol != "H-")
+ {
+ Molecule* mol = new Molecule;
+ mol->setPos(downPos);
+ m_stack->beginMacro("Add Molecule");
+ m_stack->push(new AddItem(mol,this));
+ m_stack->push(new AddAtom(new MsKAtom( downPos, m_currentElementSymbol, m_autoAddHydrogen ), mol));
+ m_stack->endMacro();
+ }
+}
+
+void MolScene::addModeMove(QGraphicsSceneMouseEvent* event)
+{
+ // QPointF startPos = event->buttonDownScenePos(Qt::LeftButton);
+ // QPointF curPos = event->scenePos();
+ // MsKAtom* a1 = getMsKAtom(startPos);
+ // MsKAtom* a2 = getMsKAtom(curPos);
+ // MsKBond* b = getBond(startPos);
+
+ // Check if hovering over an atom
+ MsKAtom* atom = atomAt(event->scenePos());
+
+ // Check hinting conditions
+ if (!(event->buttons() & Qt::LeftButton)) return;
+// if (nearestPoint(event->buttonDownScenePos(Qt::LeftButton))==QPointF(0,0)) return;
+ if (m_currentElementSymbol == "+" || m_currentElementSymbol == "-" || m_currentElementSymbol == "H+" || m_currentElementSymbol == "H-") return;
+ if (!atomAt(event->buttonDownScenePos(Qt::LeftButton))) return;
+
+ // Set hinting
+ setHintLine(nearestPoint(event->buttonDownScenePos(Qt::LeftButton)), nearestPoint(event->scenePos()));
+// setHoverRect(atom);
+}
+
+void MolScene::addModeRelease(QGraphicsSceneMouseEvent* event)
+{
+
+ // Remove the hinting
+ removeHintLine();
+ removeHintPoints();
+
+ // Get position
+ QPointF downPos = event->buttonDownScenePos(event->button());
+ QPointF upPos = nearestPoint(event->scenePos());
+
+ // Check possible targets
+ MsKAtom* a1 = atomAt(downPos);
+ MsKAtom* a2 = atomAt(upPos);
+ MsKBond* b = bondAt(downPos);
+ Molecule* m1 = a1 ? a1->molecule() : 0;
+
+ if (!a1 && !b) return;
+ if (b && !a1) return;
+
+
+ if (m_currentElementSymbol=="+")
+ {
+ m_stack->push(new IncCharge(a1, tr("increasing charge")));
+ return;
+ }
+ if (m_currentElementSymbol=="-")
+ {
+ m_stack->push(new DecCharge(a1,tr("decreasing charge")));
+ return;
+ }
+ if (m_currentElementSymbol=="H+")
+ {
+ m_stack->push(new AddImplicitHydrogen(a1, tr("add implicit hydrogen")));
+ return;
+ }
+ if (m_currentElementSymbol=="H-")
+ {
+ if (a1->numberOfImplicitHydrogens() > 0) m_stack->push(new RemoveImplicitHydrogen(a1,tr("remove implicit hydrogen")));
+ return;
+ }
+
+ // Check for atom release
+ if (a2)
+ {
+ Molecule* m2 = a2->molecule();
+
+ // Check for atom click
+ if (a1==a2)
+ {
+ if (a1->element()!=m_currentElementSymbol)
+ m_stack->push(new ChangeElement(a1,m_currentElementSymbol,tr("changing element")));
+// else
+// m_stack->push(new AddAtom(new MsKAtom(QPointF(0,0),m_currentElementSymbol),a1->molecule()));
+ return;
+ }
+
+ // Begin adding macro
+ m_stack->beginMacro("adding bond");
+
+ // Check for merge
+ if (m1 != m2)
+ {
+ m_stack->push(new MergeMol(m1,m2,m1));
+ a1 = m1->atomAt(downPos);
+ a2 = m1->atomAt(upPos);
+ m1->setFocus();
+ }
+
+ // Adding bond
+ MsKBond* bond = new MsKBond(a1,a2);
+ m_stack->push(new AddBond(bond));
+ for (int i = 0; i < m_bondOrder - 1; i++)
+ m_stack->push(new IncOrder(bond));
+ for (int i = 0; i < m_bondType; i++)
+ m_stack->push(new IncType(bond));
+
+ // End adding macro
+ m_stack->endMacro();
+ return;
+ };
+
+ // Else scene release
+ m_stack->beginMacro(tr("adding atom"));
+ MsKAtom* atom = new MsKAtom(upPos,m_currentElementSymbol,m_autoAddHydrogen);
+ m_stack->push(new AddAtom(atom,m1));
+ MsKBond* bond = new MsKBond(a1,atom);
+ m_stack->push(new AddBond(bond));
+ for (int i = 0; i < m_bondOrder - 1; i++)
+ m_stack->push(new IncOrder(bond));
+ for (int i = 0; i < m_bondType; i++)
+ m_stack->push(new IncType(bond));
+ m_stack->endMacro();
+}
+
+void MolScene::addModeDoubleRelease( QGraphicsSceneMouseEvent * event )
+{
+ ///TODO
+}
+
+void MolScene::delModePress(QGraphicsSceneMouseEvent* event)
+{
+ MsKAtom* a = atomAt(event->scenePos());
+ MsKBond* b = bondAt(event->scenePos());
+ Molecule* mol;
+
+ // Look for atomclick
+ if (a)
+ {
+ mol = a->molecule();
+ m_stack->beginMacro(tr("removing atom"));
+ m_stack->push(new DelAtom(a));
+ if (mol->canSplit()) m_stack->push(new SplitMol(mol));
+ if (mol->atoms().isEmpty()) m_stack->push(new DelItem(mol));
+ m_stack->endMacro();
+ return;
+ }
+
+ // Look for bondclick
+ if (b)
+ {
+ mol = b->molecule();
+ m_stack->beginMacro(tr("removing bond"));
+ m_stack->push(new DelBond(b));
+ if (mol->canSplit()) m_stack->push(new SplitMol(mol));
+ m_stack->endMacro();
+ return;
+ }
+}
+
+void MolScene::delModeDoubleClick( QGraphicsSceneMouseEvent * event )
+{
+ Molecule* item = moleculeAt(event->scenePos());
+ if (item) m_stack->push(new DelItem(item,tr("removing molecule")));
+}
+
+void MolScene::keyPressEvent(QKeyEvent* keyEvent)
+{
+ // Declare item
+ QGraphicsItem* item;
+ MsKAtom* atom;
+// MsKBond* bond;
+// Molecule* mol;
+ QSet<Molecule*> molSet;
+
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ m_stack->beginMacro(tr("removing item(s)"));
+ // First delete all selected molecules
+ foreach (item, selectedItems())
+ if (item->type() == Molecule::Type)
+ {
+ m_stack->push(new DelItem(item));
+ }
+// // Then delete
+// foreach (item, selectedItems())
+// if (item->type() == MsKBond::Type)
+// {
+// bond = dynamic_cast<MsKBond*>(item);
+// mol = bond->molecule();
+// m_stack->push(new DelBond(bond));
+// if (mol->canSplit()) m_stack->push(new SplitMol(mol));
+// };
+
+ // Then delete all selected atoms
+ foreach (item, selectedItems())
+ if (item->type() == MsKAtom::Type)
+ {
+ atom = dynamic_cast<MsKAtom*>(item);
+ molSet << atom->molecule();
+ m_stack->push(new DelAtom(atom));
+ }
+
+ // Cleanup the affected molecules
+ foreach (Molecule* mol, molSet)
+ {
+ if (mol->canSplit()) m_stack->push(new SplitMol(mol));
+ if (mol->atoms().isEmpty()) m_stack->push(new DelItem(mol));
+ }
+
+ // Finally delete all the residues
+ foreach (item, selectedItems()) m_stack->push(new DelItem(item));
+
+ m_stack->endMacro();
+ keyEvent->accept();
+ break;
+ case Qt::Key_Up:
+ m_stack->beginMacro("moving item(s)");
+ foreach (item, selectedItems())
+ m_stack->push(new MoveItem(item,QPointF(0,-10)));
+ m_stack->endMacro();
+ keyEvent->accept();
+ break;
+ case Qt::Key_Down:
+ m_stack->beginMacro("moving item(s)");
+ foreach (item, selectedItems())
+ m_stack->push(new MoveItem(item,QPointF(0,10)));
+ m_stack->endMacro();
+ keyEvent->accept();
+ break;
+ case Qt::Key_Left:
+ m_stack->beginMacro("moving item(s)");
+ foreach (item, selectedItems())
+ m_stack->push(new MoveItem(item,QPointF(-10,0)));
+ m_stack->endMacro();
+ keyEvent->accept();
+ break;
+ case Qt::Key_Right:
+ m_stack->beginMacro("moving item(s)");
+ foreach (item, selectedItems())
+ m_stack->push(new MoveItem(item,QPointF(10,0)));
+ m_stack->endMacro();
+ keyEvent->accept();
+ break;
+ case Qt::Key_Escape:
+ clearSelection();
+ break;
+ default:
+ keyEvent->ignore();
+ }
+}
+
+QUndoStack * MolScene::stack()
+{
+ return m_stack;
+}
+
+int MolScene::toRoundedAngle(int angle)
+{
+ return angle - angle % m_bondAngle;
+}
+
+void MolScene::setBondType(int type)
+{
+ Q_ASSERT( type >= 0 and type < 6);
+ m_bondType = type;
+}
+
+void MolScene::setBondOrder(int order)
+{
+ Q_ASSERT( order > 0 and order < 4);
+ m_bondOrder = order;
+}
+
+void MolScene::setElement(const QString & symbol)
+{
+ m_currentElementSymbol = symbol;
+}
+
+void MolScene::setIncChargeMode()
+{
+ m_currentElementSymbol = "+";
+}
+
+void MolScene::setDecChargeMode()
+{
+ m_currentElementSymbol = "-";
+}
+
+void MolScene::setIncHydrogenMode()
+{
+ m_currentElementSymbol = "H+";
+}
+
+void MolScene::setDecHydrogenMode()
+{
+ m_currentElementSymbol = "H-";
+}
+
+QFont MolScene::atomSymbolFont() const
+{
+ return m_atomSymbolFont;
+}
+
+void MolScene::setAtomSymbolFont(const QFont & font)
+{
+ m_atomSymbolFont = font;
+}
+
+void MolScene::setBondWidth(double width)
+{
+ Q_ASSERT(width > 0);
+ m_bondWidth = width;
+}
+
+qreal MolScene::bondWidth() const
+{
+ return m_bondWidth;
+}
diff --git a/molsketch_helium/molscene.h b/molsketch_helium/molscene.h
new file mode 100644
index 0000000..1003e0c
--- /dev/null
+++ b/molsketch_helium/molscene.h
@@ -0,0 +1,316 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+/** @file
+* This file is part of molsKetch and contains the MolScene class.
+*
+* @author Harm van Eersel <devsciurus at xs4all.nl
+*/
+
+
+#ifndef molscene_H
+#define molscene_H
+
+#include <QGraphicsScene>
+#include <QUndoCommand>
+
+#include "mollibitem.h"
+
+class QString;
+class QImage;
+class QListWidgetItem;
+class QTableWidgetItem;
+class QUndoStack;
+class Molecule;
+class MsKAtom;
+class MsKBond;
+
+
+/**
+ * This class is a subclassed version of QGraphicsScene with addition of some extra methods and
+ * event handling for molecules. In can be used in the same fashion as QGraphicsScene.
+ *
+ * @author Harm van Eersel
+ * @since Hydrogen
+ */
+class MolScene : public QGraphicsScene
+{
+ Q_OBJECT
+
+public:
+ // Constructor & destructor
+ /** Creates a new MolScene with @p parent */
+ MolScene(QObject* parent = 0);
+ /** Cleans up the UndoStack and deletes the molscene. */
+ ~MolScene();
+
+ // Queries
+ /** Returns the EditMode of the scene. */
+ int editMode() const;
+ /** Returns @c true if neutral carbons are visible, return @c false otherwise. */
+ bool carbonVisible() const;
+ /** Returns @c true if hydrogens are visible, return @c false otherwise. */
+ bool hydrogenVisible() const;
+ /** Returns @c true if atom valency is visible, return @c false otherwise. */
+ bool chargeVisible() const { return m_chargeVisible; };
+ /** Returns @c true if hydrogens are automaticly added, return @c false otherwise. */
+ bool autoAddHydrogen() const { return m_autoAddHydrogen; };
+ /** Returns the current bond length. */
+ qreal bondLength() const;
+ /** Returns the current bond width */
+ qreal bondWidth() const;
+ /** Returns the current bond angle. */
+ int bondAngle() const { return m_bondAngle; };
+ /** Returns the current bond order. */
+ int bondOrder() const { return m_bondOrder; };
+ /** Returns the current bond type. */
+ int bondType() const { return m_bondType; };
+ /** Returns the current atom size. */
+ qreal atomSize() const;
+ /** Returns the current atomsymbol font */
+ QFont atomSymbolFont() const;
+ /** Returns the current dynamic grid radius. */
+ int dynamicGridSize() const;
+
+ // Commands
+ /** Renders the @p rect on the scene in a image. */
+ QImage renderImage(const QRectF &rect);
+ /** Sets whether neutral carbons are drawn. */
+ void setCarbonVisible(bool value);
+ /** Sets whether hydrogens are drawn. */
+ void setHydrogenVisible(bool value);
+ /** Sets whether atom charges are drawn. */
+ void setChargeVisible(bool value) { m_chargeVisible = value; };
+ /** Sets whether hydrogens are automaticly added. */
+ void setAutoAddHydrogen(bool value) { m_autoAddHydrogen = value; };
+ /** Sets the atomsymbol font */
+ void setAtomSymbolFont(const QFont & font);
+ /** Sets the atom size. */
+ void setMsKAtomSize(qreal size);
+ /** Sets the number of hint points in the dynamic grid. */
+ void setHintPointSize(int size);
+
+ /** Merges @p molA and @p molB. Used two merge two molecules when connected with a bond. */
+ Molecule* merge(const Molecule* molA, const Molecule* molB);
+
+ /** Access to the stack */
+ QUndoStack * stack();
+
+ // Advanced queries
+ /** Returns the first molecule at position @p pos or NULL if none. */
+ Molecule* moleculeAt(const QPointF &pos);
+ /** Returns the first atom at position @p pos or NULL if none. */
+ MsKAtom* atomAt(const QPointF &pos);
+ /** Returns the first bond at position @p pos or NULL if none. */
+ MsKBond* bondAt(const QPointF &pos);
+
+ /** Enum for the different edit modes. */
+ enum editModes {
+ MoveMode, /**< MsKAtoms and molecules are movable. */
+ AddMode, /**< Mode to add atoms and bonds. */
+ RemoveMode, /**< Mode to remove atoms, bonds and molecules. */
+ RotateMode /**< Mode to rotate molecules. */
+ };
+
+signals:
+ /** Signal emitted if copy becomes available. */
+ void copyAvailable(bool);
+ /** Signal emitted if paste becomes available. */
+ void pasteAvailable(bool);
+ /** Signal emitted if the edit mode changes. */
+ void editModeChange(int);
+ /** Signal emitted if the contents of the scene change. */
+ void documentChange( );
+ /** Signal emitted if the selection on the scene changes. */
+ void selectionChange( );
+// /** Signal emitted if a new molecule is added to the scene. */
+// void newMolecule(QPointF,QString);
+
+public slots:
+ /** Slot to cut the current selection to the clipboard. */
+ void cut();
+ /** Slot to copy the current selection to the clipboard. */
+ void copy();
+ /** Slot to paste the current clipboard contents. */
+ void paste();
+ /** Slot to clear the scene. */
+ void clear();
+ /** Slot to set the edit mode to @p mode. */
+ void setEditMode(int mode);
+ /** Slot to set the edit mode to increase charge mode */
+ void setIncChargeMode();
+ /** Slot to set the edit mode to decrease charge mode */
+ void setDecChargeMode();
+ /** Slot to set the edit mode to increase hydrogen mode */
+ void setIncHydrogenMode();
+ /** Slot to set the edit mode to decrease hydrogen mode */
+ void setDecHydrogenMode();
+ /** Slot to select all contents of the scene. */
+ void selectAll();
+ /** Slot to set the current element to the element of @p item. */
+ void setElement(QListWidgetItem* item);
+ /** Slot to set the current element to the element of @p item. */
+ void setElement(QTableWidgetItem* item);
+ /** Slot to set the current element to the element of @p symbol. */
+ void setElement(const QString & symbol);
+ /** Sets the bond angle. */
+ void setBondAngle(double angle);
+ /** Sets the bond length. */
+ void setBondLength(double length);
+ /** Sets the bond width */
+ void setBondWidth(double width);
+ /** Sets the bond order. */
+ void setBondOrder(int order);
+ /** Sets the bond type. */
+ void setBondType(int type);
+ /** Slot to add a copy of molecule @p mol. */
+ void addMolecule(QListWidgetItem* mol);
+ /** Slot to add a copy of molecule @p mol. */
+ void addMolecule(Molecule* mol);
+ /** Slot to align the molecules of the scene to the grid. */
+ void alignToGrid();
+
+protected:
+ /** Generic event handler. Reimplementation for sceneChanged signals. */
+ bool event (QEvent* event);
+
+ // Event handlers
+ /** Event handler for mouse press events. */
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse move events. */
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler fot mouse release events. */
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler for double click events. */
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
+ /** Event handler for keyboard interaction */
+ virtual void keyPressEvent(QKeyEvent* keyEvent);
+
+ //void contextMenuEvent(Reason reason, );
+
+private:
+
+ // Global properties
+ /** Contains the current element */
+ QString m_currentElementSymbol;
+
+ // Hinting methods and properties
+ /** Shows a hintline from @p startPos to @p curPos. */
+ void setHintLine(const QPointF &startPos,const QPointF &curPos);
+ /** Hides the hintline. */
+ void removeHintLine();
+ /** Draws the dynamic grid around point @p curPos. */
+ void drawHintPoints(const QPointF &curPos );
+ /** Hides the dynamic grid. */
+ void removeHintPoints();
+ /** Shows a highlight rectangle around @p item. */
+ void setHoverRect( QGraphicsItem* item );
+ /** Stores the rotating angle during rotation*/
+ qreal m_tempRotateAngle;
+
+ // Auxillary methods
+ /** Calculates the nearest magnetic point around @p curPos. */
+ QPointF nearestPoint(const QPointF &curPos);
+ /** Returns the nearest grid point, starting from @p position. */
+ QPointF toGrid(const QPointF &position);
+ /** Returns the nearest rounded angle, starting from @p angle. */
+ int toRoundedAngle(int angle);
+
+ // Scene properties
+ /** Stores the edit mode of the scene as an integer. */
+ int m_editMode;
+ /** Stores the current bond length. */
+ qreal m_bondLength;
+ /** Stores the current bond width. */
+ qreal m_bondWidth;
+ /** Stores the current bond order. */
+ int m_bondOrder;
+ /** Stores the current bond type. */
+ int m_bondType;
+ /** Strores the bond angle. */
+ int m_bondAngle;
+ /** Stores the current atom size. */
+ qreal m_atomSize;
+ /** Stores the current atomsymbol font */
+ QFont m_atomSymbolFont;
+ /** Stores whether hydrogens should be visible.*/
+ bool m_hydrogenVisible;
+ /** Stores whether neutral carbons are to be shown.*/
+ bool m_carbonVisible;
+ /** Stores whether the charge of the atoms is to be shown.*/
+ bool m_chargeVisible;
+ /** Stores whether hydrogens are to be added automaticly.*/
+ bool m_autoAddHydrogen;
+
+ // Internal clipboard
+ /** Internal clipboard for scene items.*/
+ QList<Molecule*> m_clipItems;
+
+ // Undo stack
+ /** The undo stack of the commands used to edit the scene. */
+ QUndoStack * m_stack;
+
+ // Event handlers
+ /** Event handler for mouse presses in add mode. */
+ void addModePress(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse moves in add mode.*/
+ void addModeMove(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse releases in add mode.*/
+ void addModeRelease(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse doubleclicks in add mode.*/
+ void addModeDoubleRelease(QGraphicsSceneMouseEvent* event);
+
+ /** Event handler for mouse presses in move mode. */
+ void moveModePress(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse moves in move mode.*/
+ void moveModeMove(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse releases in move mode.*/
+ void moveModeRelease(QGraphicsSceneMouseEvent* event);
+
+ /** Event handler for mouse presses in rotate mode. */
+ void rotateModePress(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse moves in rotate mode.*/
+ void rotateModeMove(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse releases in rotate mode.*/
+ void rotateModeRelease(QGraphicsSceneMouseEvent* event);
+
+ /** Event handler for mouse presses in delete mode.*/
+ void delModePress(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse moves in delete mode.*/
+ void delModeMove(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse releases in delete mode.*/
+ void delModeRelease(QGraphicsSceneMouseEvent* event);
+ /** Event handler for mouse double clicks in delete mode.*/
+ void delModeDoubleClick(QGraphicsSceneMouseEvent* event);
+
+ // Auxillary feedback items
+ /** The highlight rectangle. */
+ QGraphicsPathItem* m_hoverRect;
+ /** The hint line. */
+ QGraphicsLineItem* m_hintLine;
+ /** The list of dynamic grid points. */
+ QList<QGraphicsItem*> m_hintPoints;
+ /** The group of dynamic grid points. */
+ QGraphicsItemGroup* m_hintPointsGroup;
+ /** Method to initialize the hinting.*/
+ void initHintItems();
+
+};
+
+#endif
diff --git a/molsketch_helium/molsketch.desktop b/molsketch_helium/molsketch.desktop
new file mode 100644
index 0000000..880a832
--- /dev/null
+++ b/molsketch_helium/molsketch.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Type=Application
+Name=molsKetch
+TryExec=molsketch
+Exec=molsketch
+Icon=molsketch.png
+DocPath=molsketch/index.html
+MimeType=chemical/x-cml
+Terminal=false
+Categories=Qt;Education;Science;
+GenericName=2D molecular structures editor
+Comment=2D molecular structures editor
+GenericName[cs]=Kreslení molekul
+Comment[cs]=2D editor molekulárních struktur
+GenericName[sk]=Kreslenie molekul
+Comment[sk]=2D editor molekulárnych štruktúr
+GenericName[nl]=Molecuulstructuur bewerker
+Comment[nl]=Programma om molecuulstructuren mee te tekenen
diff --git a/molsketch_helium/molsketch.ico b/molsketch_helium/molsketch.ico
new file mode 100644
index 0000000..bc81448
Binary files /dev/null and b/molsketch_helium/molsketch.ico differ
diff --git a/molsketch_helium/molsketch.qrc b/molsketch_helium/molsketch.qrc
new file mode 100644
index 0000000..4426ca1
--- /dev/null
+++ b/molsketch_helium/molsketch.qrc
@@ -0,0 +1,35 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>images/application-exit.png</file>
+ <file>images/configure.png</file>
+ <file>images/configure.svg</file>
+ <file>images/document-export.png</file>
+ <file>images/document-import.png</file>
+ <file>images/document-new.png</file>
+ <file>images/document-open.png</file>
+ <file>images/document-open.svg</file>
+ <file>images/document-print.png</file>
+ <file>images/document-save-as.png</file>
+ <file>images/document-save.png</file>
+ <file>images/draw-eraser.png</file>
+ <file>images/draw-freehand.png</file>
+ <file>images/draw-freehand.svg</file>
+ <file>images/edit-copy.png</file>
+ <file>images/edit-cut.png</file>
+ <file>images/edit-paste.png</file>
+ <file>images/edit-redo.png</file>
+ <file>images/edit-select-all.png</file>
+ <file>images/edit-undo.png</file>
+ <file>images/help-about.png</file>
+ <file>images/help-contents.png</file>
+ <file>images/help-contextual.png</file>
+ <file>images/molsketch.png</file>
+ <file>images/molsketch.svg</file>
+ <file>images/transform-move.png</file>
+ <file>images/transform-rotate.png</file>
+ <file>images/zoom-fit-best.png</file>
+ <file>images/zoom-in.png</file>
+ <file>images/zoom-original.png</file>
+ <file>images/zoom-out.png</file>
+ </qresource>
+</RCC>
diff --git a/molsketch_helium/molview.cpp b/molsketch_helium/molview.cpp
new file mode 100644
index 0000000..018494f
--- /dev/null
+++ b/molsketch_helium/molview.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#include "molview.h"
+
+#include <QDebug>
+#include <QGraphicsScene>
+#include <QWheelEvent>
+
+#include <math.h>
+
+MolView::MolView(QGraphicsScene* scene) : QGraphicsView(scene)
+{
+ setContextMenuPolicy(Qt::ActionsContextMenu);
+ setMouseTracking(true);
+ setAcceptDrops(true);
+ setRenderHints(QPainter::Antialiasing);
+ setResizeAnchor(QGraphicsView::AnchorViewCenter);
+ setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+}
+
+void MolView::wheelEvent(QWheelEvent* event)
+{
+ scaleView(pow((double)2, -event->delta() / 240.0));
+}
+
+void MolView::scaleView(qreal scaleFactor)
+{
+ qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRect(0,0,1,1)).width();
+ if (factor < 0.07 || factor > 100) return;
+ scale(scaleFactor, scaleFactor);
+}
+
diff --git a/molsketch_helium/molview.h b/molsketch_helium/molview.h
new file mode 100644
index 0000000..34151b1
--- /dev/null
+++ b/molsketch_helium/molview.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains the MolView class.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Hydrogen
+ */
+
+#ifndef molview_H
+#define molview_H
+
+#include <QtGui/QGraphicsView>
+
+
+/**
+ * The view of the molecule scene. This is a subclass of QGraphicsView with
+ * with zooming events added.
+ *
+ * @author Harm van Eersel
+ */
+class MolView : public QGraphicsView
+ {
+ Q_OBJECT
+
+ public:
+ /** Creates a new MolView.*/
+ MolView(QGraphicsScene* scene);
+ /* void itemMoved();*/
+
+ protected:
+ /** Handles the mouse wheel events. */
+ void wheelEvent(QWheelEvent* event);
+ /** Scales the view with factor @p scaleFactor. */
+ void scaleView(qreal scaleFactor);
+ };
+
+#endif
diff --git a/molsketch_helium/part/CMakeLists.txt b/molsketch_helium/part/CMakeLists.txt
new file mode 100644
index 0000000..67377d0
--- /dev/null
+++ b/molsketch_helium/part/CMakeLists.txt
@@ -0,0 +1,27 @@
+# CMakeLists.txt for the sourcecode of the molsKetch KPart
+
+# Include molsKetch source
+include_directories( ${CMAKE_SOURCE_DIR}/src )
+
+# Include KDE4
+include_directories( ${KDE4_INCLUDE_DIR} )
+
+# Set the variable with all the sourcecode
+set(molsketchpart_PART_SRCS molsketchpart.cpp molsketchpart_shell.cpp ../molscene.cpp ../molview.cpp ../commands.cpp ../molecule.cpp ../atom.cpp ../bond.cpp ../element.cpp ../fileio.cpp ../mollibitem.cpp)
+set(molsketchpart_SHELL_SRCS molsketchpart_shell.cpp molsketchpart.cpp ../molscene.cpp ../molview.cpp ../commands.cpp ../molecule.cpp ../atom.cpp ../bond.cpp ../element.cpp ../fileio.cpp ../mollibitem.cpp)
+
+# Including the resources
+qt4_add_resources(molsketchpart_SHELL_SRCS molsketchpart_shell.qrc)
+
+# Adding the targets
+kde4_add_plugin(molsketchpart WITH_PREFIX ${molsketchpart_PART_SRCS})
+target_link_libraries(molsketchpart ${KDE4_KPARTS_LIBS} ${OPENBABEL2_LIBRARIES})
+set_target_properties(molsketchpart PROPERTIES COMPILE_FLAGS -DMSKSRCDIR="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"")
+
+kde4_add_executable(molsketchpartshell ${molsketchpart_SHELL_SRCS})
+target_link_libraries(molsketchpartshell ${KDE4_KPARTS_LIBS} ${OPENBABEL2_LIBRARIES})
+set_target_properties(molsketchpartshell PROPERTIES COMPILE_FLAGS -DMSKSRCDIR="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"")
+
+# Install files
+install(TARGETS molsketchpart DESTINATION ${PLUGIN_INSTALL_DIR})
+install(FILES partshell.rc DESTINATION ${DATA_INSTALL_DIR}/molsketchpart)
diff --git a/molsketch_helium/part/CVS/Entries b/molsketch_helium/part/CVS/Entries
new file mode 100644
index 0000000..ed9a807
--- /dev/null
+++ b/molsketch_helium/part/CVS/Entries
@@ -0,0 +1,13 @@
+/CMakeLists.txt/1.1/Mon Sep 29 09:14:55 2008//
+/molsketch.svg/1.1/Mon Sep 29 09:14:56 2008//
+/molsketch_factory.cpp/1.1/Mon Sep 29 09:14:58 2008//
+/molsketch_factory.h/1.1/Mon Sep 29 09:14:59 2008//
+/molsketch_factory.h~/1.1/Mon Sep 29 09:15:00 2008//
+/molsketchpart.cpp/1.1/Mon Sep 29 09:15:01 2008//
+/molsketchpart.h/1.1/Mon Sep 29 09:15:03 2008//
+/molsketchpart.rc/1.1/Mon Sep 29 09:15:05 2008//
+/molsketchpart_shell.cpp/1.1/Mon Sep 29 09:15:06 2008//
+/molsketchpart_shell.h/1.1/Mon Sep 29 09:15:08 2008//
+/molsketchpart_shell.qrc/1.1/Mon Sep 29 09:15:09 2008//
+/molsketchpart_shell.rc/1.1/Mon Sep 29 09:15:11 2008//
+D
diff --git a/molsketch_helium/part/CVS/Entries.Extra b/molsketch_helium/part/CVS/Entries.Extra
new file mode 100644
index 0000000..a110976
--- /dev/null
+++ b/molsketch_helium/part/CVS/Entries.Extra
@@ -0,0 +1,12 @@
+/CMakeLists.txt////*///
+/molsketch.svg////*///
+/molsketch_factory.cpp////*///
+/molsketch_factory.h////*///
+/molsketch_factory.h~////*///
+/molsketchpart.cpp////*///
+/molsketchpart.h////*///
+/molsketchpart.rc////*///
+/molsketchpart_shell.cpp////*///
+/molsketchpart_shell.h////*///
+/molsketchpart_shell.qrc////*///
+/molsketchpart_shell.rc////*///
diff --git a/molsketch_helium/part/CVS/Entries.Extra.Old b/molsketch_helium/part/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/part/CVS/Entries.Old b/molsketch_helium/part/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/molsketch_helium/part/CVS/Repository b/molsketch_helium/part/CVS/Repository
new file mode 100644
index 0000000..e67e300
--- /dev/null
+++ b/molsketch_helium/part/CVS/Repository
@@ -0,0 +1 @@
+zodiac/molsketch_helium/part
diff --git a/molsketch_helium/part/CVS/Root b/molsketch_helium/part/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/molsketch_helium/part/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/molsketch_helium/part/molsketch.svg b/molsketch_helium/part/molsketch.svg
new file mode 100644
index 0000000..0758a8e
--- /dev/null
+++ b/molsketch_helium/part/molsketch.svg
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="128"
+ height="128"
+ viewBox="0 0 128 128"
+ id="svg2"
+ xml:space="preserve"><defs
+ id="defs157">
+
+
+ <linearGradient
+ x1="68.906303"
+ y1="80.840797"
+ x2="68.906303"
+ y2="113.9932"
+ id="XMLID_22_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1"
+ offset="0"
+ id="stop64" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop66" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+
+ <linearGradient
+ x1="60.133801"
+ y1="43.399899"
+ x2="60.133801"
+ y2="99.400902"
+ id="XMLID_23_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#57adff;stop-opacity:1"
+ offset="0"
+ id="stop71" />
+ <stop
+ style="stop-color:#428aff;stop-opacity:1"
+ offset="1"
+ id="stop73" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#57ADFF" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#428AFF" />
+ </linearGradient>
+
+
+
+
+ <linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="XMLID_24_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ style="stop-color:#a20000;stop-opacity:1"
+ offset="0"
+ id="stop84" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop86" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#A20000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop91" />
+ <stop
+ style="stop-color:#ffe6b0;stop-opacity:1"
+ offset="1"
+ id="stop93" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFE6B0" />
+ </linearGradient>
+
+
+
+
+
+ <radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient579"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient574"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="0.43846199"
+ y1="0.96875"
+ x2="0.42307699"
+ y2="0.328125"
+ id="linearGradient573"
+ xlink:href="#linearGradient570" /><linearGradient
+ id="linearGradient570"><stop
+ style="stop-color:#4c0000;stop-opacity:0.60390002"
+ offset="0"
+ id="stop571" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop572" /></linearGradient><linearGradient
+ id="linearGradient576"><stop
+ style="stop-color:#02000d;stop-opacity:0.60390002"
+ offset="0"
+ id="stop577" /><stop
+ style="stop-color:#970000;stop-opacity:0"
+ offset="1"
+ id="stop578" /></linearGradient>
+
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop12" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1"
+ offset="0.25799999"
+ id="stop14" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1"
+ offset="0.7396"
+ id="stop16" />
+ <stop
+ style="stop-color:#c4c4c4;stop-opacity:1"
+ offset="0.85949999"
+ id="stop18" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.258" />
+ <a:midPointStop
+ style="stop-color:#F1F1F1"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.7396" />
+ <a:midPointStop
+ style="stop-color:#CECECE"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#C4C4C4"
+ offset="0.8595" />
+ </linearGradient>
+
+
+ <radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop23" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1"
+ id="stop25" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#000000"
+ offset="1" />
+ </radialGradient>
+
+
+ <linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop30" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop32" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+
+ <linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop39" />
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1"
+ offset="1"
+ id="stop41" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#CCCCCC"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1"
+ offset="0"
+ id="stop46" />
+ <stop
+ style="stop-color:#828282;stop-opacity:1"
+ offset="1"
+ id="stop48" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#B3B3B3"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#828282"
+ offset="1" />
+ </linearGradient>
+
+
+ <linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop53" />
+ <stop
+ style="stop-color:#e7e7e7;stop-opacity:1"
+ offset="0.50330001"
+ id="stop55" />
+ <stop
+ style="stop-color:#d4d4d4;stop-opacity:1"
+ offset="1"
+ id="stop57" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0" />
+ <a:midPointStop
+ style="stop-color:#FFFFFF"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5033" />
+ <a:midPointStop
+ style="stop-color:#E7E7E7"
+ offset="0.5" />
+ <a:midPointStop
+ style="stop-color:#D4D4D4"
+ offset="1" />
+ </linearGradient>
+
+ <linearGradient
+ x1="-178.57961"
+ y1="304.93549"
+ x2="-178.57961"
+ y2="560.43481"
+ id="linearGradient2677"
+ xlink:href="#XMLID_16_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2679"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2681"
+ xlink:href="#linearGradient576"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="297.5"
+ cy="445.79971"
+ r="44.724602"
+ fx="297.5"
+ fy="445.79971"
+ id="radialGradient2683"
+ xlink:href="#linearGradient570"
+ gradientUnits="userSpaceOnUse" /><radialGradient
+ cx="-134.0332"
+ cy="341.25101"
+ r="34.736401"
+ fx="-134.0332"
+ fy="341.25101"
+ id="radialGradient2685"
+ xlink:href="#XMLID_17_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2687"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-138.48241"
+ y1="361.31931"
+ x2="-147.41071"
+ y2="323.70621"
+ id="linearGradient2689"
+ xlink:href="#XMLID_19_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2691"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2693"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2695"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="-174.02049"
+ y1="79.044899"
+ x2="-97.685097"
+ y2="79.044899"
+ id="linearGradient2730"
+ xlink:href="#XMLID_25_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-64.3691,123.9707)" /><linearGradient
+ x1="71.484398"
+ y1="-25.1563"
+ x2="71.484398"
+ y2="111.497"
+ id="linearGradient2733"
+ xlink:href="#XMLID_24_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="-160.1909"
+ y1="371.4082"
+ x2="-146.3952"
+ y2="357.61249"
+ id="linearGradient2740"
+ xlink:href="#XMLID_20_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-268.83249"
+ y1="485.83401"
+ x2="-186.3333"
+ y2="403.33481"
+ id="linearGradient2745"
+ xlink:href="#XMLID_18_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /><linearGradient
+ x1="-199.47659"
+ y1="434.0791"
+ x2="-38.492199"
+ y2="348.4353"
+ id="linearGradient2765"
+ xlink:href="#XMLID_21_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,242.5,459.5)" /></defs>
+
+
+ <polygon
+ points="121.164,1.052 6.836,1.052 6.836,126.948 87.537,126.948 121.164,93.32 121.164,1.052 "
+ style="fill:#ffffff"
+ id="polygon9" /><polygon
+ points="117.734,4.019 10.266,4.019 10.106,126.673 86.563,126.673 117.734,95.421 117.734,4.019 "
+ style="fill:url(#linearGradient2677)"
+ id="polygon20" /><path
+ d="M 118.006,15.223 L 118.006,3.94 L 10.199,3.94 L 10.103,69.28 C 20.078,73.827 31.254,76.376 43.057,76.376 C 80.402,76.376 111.455,48.876 118.006,15.223 z "
+ style="fill:url(#linearGradient2765)"
+ id="path59" /><g
+ transform="matrix(0.6046674,0,0,0.6046674,-150.33779,-176.14874)"
+ style="font-size:12px"
+ id="g597"><g
+ transform="translate(3.526687,-2.015259)"
+ id="g583"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(72.49998,-36.25)"
+ style="fill:#0000b3;fill-rule:evenodd;stroke-width:1"
+ id="path564" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410152e-2,0.30097,280.1325,205.3008)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path565" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(71.4733,-36.59851)"
+ style="fill:url(#radialGradient2681);fill-rule:evenodd;stroke-width:1"
+ id="path575" /></g><path
+ d="M 350.8661,383.4841 L 306.1411,407.7528 C 306.6755,414.7234 310.5121,419.329 314.994,423.0112 L 359.9215,398.0594 C 359.3197,391.3165 357.2246,387.1034 350.8661,383.4841 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path582" /><g
+ id="g587"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ style="fill-rule:evenodd;stroke-width:1"
+ id="path562" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,206.5758,241.2266)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path568" /></g><path
+ d="M 386.3464,448.6343 L 384.5892,397.7795 C 378.1128,395.1467 372.279,396.5246 366.9836,398.8921 L 369.2618,450.2329 C 375.5645,452.7037 380.2698,452.7091 386.3464,448.6343 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path596" /><g
+ transform="translate(3.02288,2.015137)"
+ id="g590"><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:#ab0000;fill-rule:evenodd;stroke-width:1"
+ id="path563" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path566" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="matrix(0.441423,0.123349,-8.410151e-2,0.30097,280.1325,284.0507)"
+ style="fill:#ffffff;fill-opacity:0.45669998;fill-rule:evenodd;stroke-width:1"
+ id="path567" /><ellipse
+ cx="297.5"
+ cy="418.61221"
+ rx="30"
+ ry="30"
+ transform="translate(74.99999,42.49994)"
+ style="fill:url(#radialGradient2683);fill-rule:evenodd;stroke-width:1"
+ id="path569" /></g><path
+ d="M 356.3334,448.0147 L 311.4055,424.1236 C 305.8887,428.4177 304.167,434.1594 303.5714,439.9293 L 349.1806,463.6121 C 354.4703,459.3875 356.8263,455.3145 356.3334,448.0147 z "
+ style="fill:#040000;fill-rule:evenodd;stroke-width:1"
+ id="path595" /></g><polygon
+ points="85.191,90.977 85.191,126.73 86.984,126.73 120.623,93.091 120.623,90.977 85.191,90.977 "
+ style="opacity:0.1;fill:url(#radialGradient2685);enable-background:new"
+ id="polygon27" /><path
+ d="M 121.164,0.552 L 6.336,0.552 L 6.336,127.448 L 87.744,127.448 L 121.664,93.527 L 121.664,0.552 L 121.164,0.552 z M 120.664,1.552 C 120.664,2.539 120.664,92.704 120.664,93.115 C 120.375,93.403 87.619,126.16 87.33,126.449 C 86.92,126.449 8.32,126.449 7.336,126.449 C 7.336,125.461 7.336,2.54 7.336,1.553 C 8.322,1.552 119.678,1.552 120.664,1.552 z "
+ style="fill:url(#linearGradient2745)"
+ id="path34" /><polygon
+ points="87.537,126.948 121.164,93.32 87.537,93.32 87.537,126.948 "
+ style="fill:#ffffff"
+ id="polygon36" /><polygon
+ points="89.865,125.057 119.459,95.464 89.865,95.464 89.865,125.057 "
+ style="fill:url(#linearGradient2689)"
+ id="polygon43" /><path
+ d="M 87.537,92.82 C 87.26,92.82 87.037,93.044 87.037,93.32 L 87.037,126.948 C 87.037,127.15 87.158,127.333 87.346,127.411 C 87.533,127.486 87.748,127.443 87.891,127.302 L 121.518,93.675 C 121.662,93.53 121.705,93.317 121.627,93.13 C 121.549,92.942 121.367,92.82 121.164,92.82 L 87.537,92.82 L 87.537,92.82 z M 119.957,93.82 C 118.377,95.398 89.615,124.161 88.037,125.741 C 88.037,123.532 88.037,94.755 88.037,93.82 C 88.971,93.82 117.748,93.82 119.957,93.82 z "
+ style="fill:url(#linearGradient2740)"
+ id="path50" /><rect
+ width="128"
+ height="128"
+ x="0"
+ y="0"
+ style="fill:none"
+ id="rect61" /><path
+ d="M 35.369,17.504 C 34.377,17.503 33.495,18.132 33.174,19.074 C 32.856,20.021 33.172,21.059 33.96,21.661 L 110.298,80.083 C 111.001,80.622 111.934,80.713 112.732,80.319 C 113.527,79.93 114.024,79.134 114.024,78.242 L 114.024,19.821 C 114.024,19.201 113.783,18.618 113.345,18.18 C 112.906,17.743 112.324,17.503 111.704,17.504 L 111.704,17.504 L 35.369,17.504 z M 99.061,32.468 C 99.061,34.053 99.059,49.569 99.059,52.639 C 99.059,52.639 76.744,35.56 72.703,32.468 C 77.433,32.468 97.34,32. [...]
+ style="opacity:0.2"
+ id="path77" /><path
+ d="M 34.342,15.451 C 33.35,15.449 32.468,16.079 32.147,17.021 C 31.829,17.969 32.145,19.006 32.933,19.608 L 109.271,78.03 C 109.974,78.569 110.909,78.66 111.707,78.266 C 112.502,77.877 112.999,77.081 112.999,76.189 L 112.999,17.768 C 112.999,17.147 112.758,16.565 112.318,16.127 C 111.88,15.69 111.297,15.45 110.678,15.451 L 110.679,15.451 L 34.342,15.451 L 34.342,15.451 z M 98.033,30.415 C 98.033,32.001 98.033,47.516 98.033,50.586 C 98.033,50.586 75.716,33.507 71.677,30.415 C 76.405,30 [...]
+ style="opacity:0.2"
+ id="path79" /><path
+ d="M 33.316,14.424 C 32.324,14.422 31.442,15.053 31.121,15.994 C 30.803,16.942 31.119,17.979 31.907,18.581 L 108.244,77.002 C 108.949,77.541 109.882,77.632 110.68,77.238 C 111.475,76.849 111.972,76.053 111.972,75.163 L 111.972,16.741 C 111.972,16.121 111.731,15.538 111.293,15.101 C 110.854,14.664 110.271,14.423 109.652,14.424 L 109.652,14.424 L 33.316,14.424 z M 97.008,29.388 C 97.008,30.974 97.006,46.489 97.006,49.559 C 97.006,49.559 74.691,32.48 70.65,29.388 C 75.378,29.388 95.287,2 [...]
+ style="opacity:0.2"
+ id="path81" /><path
+ d="M 33.316,13.397 C 32.324,13.395 31.442,14.025 31.121,14.967 C 30.803,15.915 31.119,16.952 31.907,17.554 L 108.244,75.975 C 108.949,76.516 109.882,76.605 110.68,76.213 C 111.475,75.822 111.972,75.028 111.972,74.136 L 111.972,15.714 C 111.972,15.094 111.731,14.511 111.293,14.074 C 110.854,13.637 110.271,13.397 109.652,13.398 L 109.652,13.398 L 33.316,13.398 L 33.316,13.397 z M 97.008,28.361 C 97.008,29.947 97.006,45.463 97.006,48.532 C 97.006,48.532 74.691,31.453 70.65,28.361 C 75.37 [...]
+ style="fill:url(#linearGradient2733)"
+ id="path88" /><path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:url(#linearGradient2730)"
+ id="path95" /><g
+ style="opacity:0.5"
+ id="g97">
+ <path
+ d="M 109.651,74.137 L 109.651,15.714 L 33.316,15.714 L 109.651,74.137 M 108.362,71.523 C 104.591,68.639 42.553,21.157 37.128,17.003 C 43.885,17.004 105.992,17.004 108.362,17.004 C 108.362,19.362 108.362,66.86 108.362,71.523 M 100.614,55.839 L 100.614,26.042 L 100.614,24.751 L 59.994,24.751 L 100.614,55.839 M 99.324,53.224 C 87.231,43.972 79.191,37.818 63.806,26.044 C 80.848,26.044 91.011,26.042 99.324,26.044 C 99.326,33.955 99.324,40.731 99.324,53.224 z "
+ style="fill:#ffffff"
+ id="path99" />
+ </g><polygon
+ points="33.316,16.61 109.651,75.032 109.651,72.449 36.689,16.61 33.316,16.61 "
+ style="fill:#ffff66"
+ id="polygon101" /><path
+ d="M 109.651,75.032 L 109.651,72.449 L 108.362,71.462 C 108.362,71.861 108.362,72.201 108.362,72.42 C 104.591,69.535 42.553,22.053 37.128,17.899 C 37.433,17.899 37.855,17.9 38.378,17.9 L 36.689,16.61 L 33.316,16.61 L 109.651,75.032 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path103" /><g
+ transform="translate(1.450693,28.664084)"
+ id="g105">
+ <path
+ d="M 59.545,43.092 C 44.665,47.876 41.97,48.742 41.396,49.213 C 41.427,49.164 41.469,49.093 41.469,49.093 L 5.447,81.448 C 3.531,83.176 5.594,87.217 8.32,90.244 C 11.015,93.244 14.817,95.73 16.791,94.103 L 52.848,61.587 L 52.888,61.367 L 60.137,45.811 L 61.112,42.645 L 59.545,43.092 z "
+ style="opacity:0.2"
+ id="path107" />
+ <path
+ d="M 58.528,42.419 C 43.648,47.202 40.953,48.067 40.378,48.54 C 40.409,48.491 40.453,48.42 40.453,48.42 L 4.431,80.772 C 2.515,82.501 4.577,86.543 7.304,89.57 C 9.999,92.57 13.8,95.056 15.774,93.429 L 51.831,60.913 L 51.871,60.693 L 59.119,45.137 L 60.095,41.971 L 58.528,42.419 z "
+ style="opacity:0.2"
+ id="path109" />
+ <path
+ d="M 57.511,41.745 C 42.631,46.529 39.936,47.394 39.361,47.867 C 39.391,47.817 39.435,47.747 39.435,47.747 L 3.413,80.101 C 1.497,81.829 3.56,85.872 6.287,88.897 C 8.982,91.897 12.783,94.383 14.758,92.756 L 50.815,60.241 L 50.854,60.021 L 58.103,44.464 L 59.078,41.298 L 57.511,41.745 z "
+ style="opacity:0.2"
+ id="path111" />
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:#ffffff"
+ id="path113" />
+
+ <linearGradient
+ x1="7.4770999"
+ y1="77.034203"
+ x2="57.502499"
+ y2="48.2841"
+ id="XMLID_26_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#cf0000;stop-opacity:1"
+ offset="0"
+ id="stop116" />
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="1"
+ id="stop118" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#CF0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#7C0000" />
+ </linearGradient>
+ <path
+ d="M 56.815,41.887 C 41.935,46.67 39.241,47.535 38.666,48.008 C 38.696,47.959 38.74,47.888 38.74,47.888 L 2.718,80.24 C 0.802,81.969 2.865,86.012 5.592,89.038 C 8.286,92.038 12.089,94.524 14.063,92.897 L 50.12,60.382 L 50.159,60.162 L 57.408,44.606 L 58.382,41.44 L 56.815,41.887 z "
+ style="fill:url(#XMLID_26_)"
+ id="path120" />
+
+ <linearGradient
+ x1="313.06741"
+ y1="-177.2002"
+ x2="321.69031"
+ y2="-168.57651"
+ id="XMLID_27_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#f8f1dc;stop-opacity:1"
+ offset="0"
+ id="stop123" />
+ <stop
+ style="stop-color:#d6a84a;stop-opacity:1"
+ offset="1"
+ id="stop125" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#F8F1DC" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#D6A84A" />
+ </linearGradient>
+ <path
+ d="M 39.683,49.903 L 55.387,44.251 L 48.013,59.231 L 47.951,59.163 C 47.918,59.266 47.876,59.366 47.821,59.452 L 47.87,59.502 L 13.449,90.519 L 13.407,90.468 C 12.381,91.394 9.662,90.043 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 39.389,50.094 L 39.683,49.903 z "
+ style="fill:url(#XMLID_27_)"
+ id="path127" />
+
+ <linearGradient
+ x1="329.35739"
+ y1="-197.62601"
+ x2="333.9407"
+ y2="-203.0881"
+ id="XMLID_28_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ffc957;stop-opacity:1"
+ offset="0"
+ id="stop130" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="1"
+ id="stop132" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFC957" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FFAE00" />
+ </linearGradient>
+ <path
+ d="M 7.331,87.458 C 5.003,84.871 3.946,82.029 4.97,81.105 L 12.725,74.119 L 23.636,73.644 L 23.959,81.047 L 13.451,90.518 L 13.409,90.467 C 12.381,91.394 9.662,90.043 7.331,87.458 z "
+ style="fill:url(#XMLID_28_)"
+ id="path134" />
+
+ <linearGradient
+ x1="302.5752"
+ y1="-214.1689"
+ x2="321.83981"
+ y2="-171.39861"
+ id="XMLID_29_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.35e-2,0.999,0.999,-4.35e-2,195.0785,-254.2708)">
+ <stop
+ style="stop-color:#ff9200;stop-opacity:1"
+ offset="0"
+ id="stop137" />
+ <stop
+ style="stop-color:#ffae00;stop-opacity:1"
+ offset="0.77530003"
+ id="stop139" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1"
+ offset="1"
+ id="stop141" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FF9200" />
+ <a:midPointStop
+ offset="0.7753"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#FFAE00" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#FF6D00" />
+ </linearGradient>
+ <path
+ d="M 13.177,90.633 C 13.907,89.919 13.497,88.163 12.274,86.249 C 11.869,85.613 11.371,84.959 10.796,84.322 C 10.251,83.715 9.684,83.185 9.123,82.727 C 7.315,81.253 5.563,80.63 4.763,81.295 L 4.753,81.284 L 39.4,50.059 C 40.332,49.796 42.077,50.301 43.666,51.604 C 44.208,52.051 44.76,52.568 45.286,53.157 C 45.877,53.81 46.388,54.482 46.8,55.136 C 48.037,57.089 48.529,58.967 47.748,59.673 C 47.567,59.835 46.786,60.537 46.757,60.556 L 13.266,90.73 L 13.177,90.633 z "
+ style="fill:url(#XMLID_29_)"
+ id="path143" />
+
+ <linearGradient
+ x1="56.380402"
+ y1="50.837399"
+ x2="49.402302"
+ y2="50.837399"
+ id="XMLID_30_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98,-0.1991,0.1991,0.98,-9.7802,8.2928)">
+ <stop
+ style="stop-color:#7c0000;stop-opacity:1"
+ offset="0"
+ id="stop146" />
+ <stop
+ style="stop-color:#663333;stop-opacity:1"
+ offset="1"
+ id="stop148" />
+ <a:midPointStop
+ offset="0"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="0.5"
+ style="stop-color:#7C0000" />
+ <a:midPointStop
+ offset="1"
+ style="stop-color:#663333" />
+ </linearGradient>
+ <path
+ d="M 48.455,46.795 L 55.096,44.432 L 52.305,50.113 C 52.305,50.113 52.256,49.275 51.055,48.063 C 49.472,46.458 48.455,46.795 48.455,46.795 z "
+ style="opacity:0.8;fill:url(#XMLID_30_)"
+ id="path150" />
+ <path
+ d="M 43.51,51.488 L 9.272,82.854 C 9.223,82.814 9.172,82.766 9.123,82.728 C 8.401,82.14 7.685,81.69 7.04,81.4 L 41.105,50.192 C 41.857,50.419 42.698,50.851 43.51,51.488 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path152" />
+ <path
+ d="M 9.123,82.728 C 8.804,82.467 8.485,82.238 8.175,82.03 L 42.351,50.72 C 42.789,50.957 43.235,51.248 43.666,51.604 C 44.035,51.91 44.409,52.25 44.777,52.619 L 10.509,84.014 C 10.052,83.534 9.586,83.104 9.123,82.728 z "
+ style="opacity:0.5;fill:#ffffff"
+ id="path154" />
+ </g></svg>
\ No newline at end of file
diff --git a/molsketch_helium/part/molsketch_factory.cpp b/molsketch_helium/part/molsketch_factory.cpp
new file mode 100644
index 0000000..9c869d0
--- /dev/null
+++ b/molsketch_helium/part/molsketch_factory.cpp
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+/*
+#include "molsketch_factory.h"
+
+#include <klocale.h>
+#include <kstddirs.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+
+#include "molsketch_part.h"
+
+extern "C"
+{
+ void* init_libmolsketch()
+ {
+ return new MolsKetchFactory;
+ }
+};
+
+KInstance* MolsKetchFactory::s_instance = 0L;
+KAboutData* MolsKetchFactory::s_about = 0L;
+
+MolsKetchFactory::create( QObject * parent, const char * name, const char * classname, const QStringList & )
+{
+ if ( parent && !parent->inherits("QWidget") )
+ kdError() << "NotepadFactory: parent does not inherit QWidget" << endl;
+ return 0L;
+
+
+ MolsKetchPart * part = new MolsKetchPart( (QWidget*) parent, name );
+
+ // readonly?
+ if (QCString(classname) == "KPart::ReadOnlyPart")
+ part->setReadWrite(false);
+
+ // otherwise, it has to be readwrite
+ else if (QCString(classname) != "KPart::ReadWritePart")
+ {
+ kdError() << "classname isn't ReadOnlyPart nor ReadWritePart !" << endl;
+ return 0L;
+ }
+
+ emit objectCreated( part );
+ return part;
+}
+
+
+Instance* MolsKetchFactory::instance()
+{
+ if ( !s_instance )
+ {
+ s_about = new KAboutData( "molsketchpart", I18N_NOOP( "molsKetch" ), "2.0pre" );
+ s_instance = new KInstance( s_about );
+ }
+ return s_instance;
+}
+
+#include "molsketch_factory.moc"
+*/
\ No newline at end of file
diff --git a/molsketch_helium/part/molsketch_factory.h b/molsketch_helium/part/molsketch_factory.h
new file mode 100644
index 0000000..444e2bc
--- /dev/null
+++ b/molsketch_helium/part/molsketch_factory.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+//#include <KLibLoader>
+/*
+
+class KInstance;
+class KAboutData;
+class MolsKetchFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ MolsKetchFactory( QObject * parent = 0, const char * name = 0 );
+ ~MolsKetchFactory;
+
+ // reimplemented from KLibFactory
+ virtual QObject * create( QObject * parent = 0, const char * name = 0, const char * classname = "QObject", const QStringList &args = QStringList());
+
+ static KInstance * instance();
+
+
+private:
+ static KInstance * s_instance;
+ static KAboutData * s_about;
+};
+*/
diff --git a/molsketch_helium/part/molsketch_factory.h~ b/molsketch_helium/part/molsketch_factory.h~
new file mode 100644
index 0000000..9f6890f
--- /dev/null
+++ b/molsketch_helium/part/molsketch_factory.h~
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+//#include <KLibLoader>
+
+class KInstance;
+class KAboutData;
+class MolsKetchFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ MolsKetchFactory( QObject * parent = 0, const char * name = 0 );
+ ~MolsKetchFactory;
+
+ // reimplemented from KLibFactory
+ virtual QObject * create( QObject * parent = 0, const char * name = 0, const char * classname = "QObject", const QStringList &args = QStringList());
+
+ static KInstance * instance();
+
+
+private:
+ static KInstance * s_instance;
+ static KAboutData * s_about;
+};
diff --git a/molsketch_helium/part/molsketchpart.cpp b/molsketch_helium/part/molsketchpart.cpp
new file mode 100644
index 0000000..e76713a
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart.cpp
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+/*
+#include "molsketchpart.h"
+
+#include "molscene.h"
+#include "molview.h"
+#include "fileio.h"
+
+//#include <kparts/partmanager.h>
+//#include <kparts/mainwindow.h>
+
+#include <QtGui/QSplitter>
+#include <QtCore/QFile>
+#include <QtGui/QPrinter>
+#include <QtCore/QTextStream>
+#include <QtGui/QTextEdit>
+
+//#include <kaboutdata.h>
+//#include <kapplication.h>
+//#include <kdebug.h>
+//#include <kaction.h>
+#include <kactioncollection.h>
+#include <klocale.h>
+#include <kstatusbar.h>
+#include <kstandarddirs.h>
+
+MolsKetchPart::MolsKetchPart( QWidget * parentWidget, QObject * parent, const QStringList & ) : KParts::ReadWritePart ( parent )
+{
+
+ setComponentData( MolsKetchFactory::componentData() );
+ KIcon("logo", iconLoader());
+ emit setWindowCaption("molsKetchPart");
+ emit setStatusBarText("Ready");
+
+ m_scene = new MolScene( parentWidget );
+ m_view = new MolView( m_scene );
+ m_view->setFocus();
+ setWidget( m_view );
+
+ // Add a temporary data location
+ componentData().dirs()->addResourceDir( "data", MSKSRCDIR );
+ setXMLFile( "molsketchpart.rc" );
+
+ // File action
+
+ // Edit actions
+// KAction * undo = new KAction( KIcon( "edit-undo"), i18n("Undo"), this );
+// actionCollection()->addAction( "edit_undo", undo );
+// connect( undo, SIGNAL( triggered() ), this, SLOT( slotUndo() ));
+//
+// KAction * redo = new KAction( KIcon( "edit-redo"), i18n("Redo"), this );
+// actionCollection()->addAction( "edit_redo", redo );
+// connect( redo, SIGNAL( triggered() ), this, SLOT( slotRedo() ));
+//
+// KAction * cut = new KAction( KIcon( "edit-cut"), i18n("Cut"), this );
+// actionCollection()->addAction( "edit_cut", cut );
+// connect( cut, SIGNAL( triggered() ), this, SLOT( slotCut() ));
+//
+// KAction * copy = new KAction( KIcon( "edit-copy"), i18n("Copy"), this );
+// actionCollection()->addAction( "edit_copy", copy );
+// connect( copy, SIGNAL( triggered() ), this, SLOT( slotCopy() ));
+//
+// KAction * paste = new KAction( KIcon( "edit-paste"), i18n("Paste"), this );
+// actionCollection()->addAction( "edit_paste", paste );
+// connect( paste, SIGNAL( triggered() ), this, SLOT( slotPaste() ));
+//
+// KAction * selectAll = new KAction( KIcon( "edit-select-all"), i18n("Select All"), this );
+// actionCollection()->addAction( "edit_selectall", selectAll );
+// connect( selectAll, SIGNAL( triggered() ), this, SLOT( slotSelectAll() ));
+
+ KAction * addMode = new KAction( KIcon( "draw-freehand"), i18n("Add mode"), this );
+ actionCollection()->addAction( "edit_addmode", addMode );
+ connect( addMode, SIGNAL( triggered() ), this, SLOT( slotAddMode() ));
+
+ KAction * delMode = new KAction( KIcon( "draw-eraser"), i18n("Remove mode"), this );
+ actionCollection()->addAction( "edit_delmode", delMode );
+ connect( delMode, SIGNAL( triggered() ), this, SLOT( slotDelMode() ));
+
+ KAction * moveMode = new KAction( KIcon( "transform-move"), i18n("Move mode"), this );
+ actionCollection()->addAction( "edit_movemode", moveMode );
+ connect( moveMode, SIGNAL( triggered() ), this, SLOT( slotMoveMode() ));
+
+ KAction * rotMode = new KAction( KIcon( "transform-rotate"), i18n("Rotate mode"), this );
+ actionCollection()->addAction( "edit_rotmode", rotMode );
+ connect( rotMode, SIGNAL( triggered() ), this, SLOT( slotRotMode() ));
+
+ // View actions
+// KAction * zoomIn = new KAction( KIcon( "zoom-in"), i18n("Zoom in"), this );
+// actionCollection()->addAction( "zoomin", zoomIn );
+// connect( zoomIn, SIGNAL( triggered() ), this, SLOT( slotZoomIn() ));
+//
+// KAction * zoomOut = new KAction( KIcon( "zoom-out"), i18n("Zoom out"), this );
+// actionCollection()->addAction( "zoomout", zoomOut );
+// connect( zoomOut, SIGNAL( triggered() ), this, SLOT( slotZoomOut() ));
+
+// KAction * zoomFit = new KAction( KIcon( "zoom-fit-best"), i18n("Zoom fit"), this );
+// actionCollection()->addAction( "zoomfit", zoomFit );
+// connect( zoomFit, SIGNAL( triggered() ), this, SLOT( slotZoomFit() ));
+//
+// KAction * zoomReset = new KAction( KIcon( "zoom-original"), i18n("Zoom reset"), this );
+// actionCollection()->addAction( "zoomreset", zoomReset );
+// connect( zoomReset, SIGNAL( triggered() ), this, SLOT( slotZoomReset() ));
+
+ setReadWrite( true );
+}
+
+MolsKetchPart::~MolsKetchPart()
+{
+
+}
+
+void MolsKetchPart::setReadWrite( bool rw )
+{
+ m_view->setInteractive( rw );
+ if ( rw )
+ connect( m_scene, SIGNAL( documentChanged() ), this, SLOT( setModified() ) );
+ else
+ disconnect( m_scene, SIGNAL( documentChanged() ), this, SLOT( setModified() ) );
+
+ ReadWritePart::setReadWrite( rw );
+}
+
+bool MolsKetchPart::openFile()
+{
+ kDebug() << "MolsKetchPart: opening " << localFilePath() << endl;
+ QFile f(localFilePath());
+ QString s;
+ if ( f.open( QIODevice::ReadOnly ) )
+ {
+ m_scene->addMolecule(molsKetch::loadFile(localFilePath()));
+ f.close();
+ }
+
+ return true;
+}
+
+bool MolsKetchPart::saveFile()
+{
+ if ( !isReadWrite() )
+ return false;
+ QFile f(localFilePath());
+ if ( f.open(QIODevice::WriteOnly) )
+ {
+ molsKetch::saveFile(localFilePath(), m_scene);
+ f.close();
+ return true;
+ }
+ else
+ return false;
+
+}
+
+// Edit action slots
+
+void MolsKetchPart::slotUndo()
+{
+ m_scene->stack()->undo();
+}
+
+void MolsKetchPart::slotRedo()
+{
+ m_scene->stack()->redo();
+}
+
+void MolsKetchPart::slotCut()
+{
+ m_scene->cut();
+}
+
+void MolsKetchPart::slotCopy()
+{
+ m_scene->copy();
+}
+
+void MolsKetchPart::slotPaste()
+{
+ m_scene->paste();
+}
+
+void MolsKetchPart::slotSelectAll()
+{
+ m_scene->selectAll();
+}
+
+void MolsKetchPart::slotAddMode()
+{
+ m_scene->setEditMode( MolScene::AddMode );
+}
+
+void MolsKetchPart::slotDelMode()
+{
+ m_scene->setEditMode( MolScene::RemoveMode );
+}
+
+void MolsKetchPart::slotMoveMode()
+{
+ m_scene->setEditMode( MolScene::MoveMode );
+}
+
+void MolsKetchPart::slotRotMode()
+{
+ m_scene->setEditMode( MolScene::RotateMode );
+}
+
+
+// View action slots
+
+void MolsKetchPart::slotZoomIn()
+{
+ m_view->scale( 2, 2 );
+}
+
+void MolsKetchPart::slotZoomOut()
+{
+ m_view->scale( 0.5, 0.5 );
+}
+
+void MolsKetchPart::slotZoomFit()
+{
+ m_view->fitInView( m_scene->itemsBoundingRect(), Qt::KeepAspectRatio );
+}
+
+void MolsKetchPart::slotZoomReset()
+{
+ m_view->resetMatrix();
+}
+
+KAboutData * MolsKetchPart::createAboutData()
+{
+ return new KAboutData( "molsketchpart", 0, ki18n( "molsKetch" ), "Helium", ki18n("A KPart to draw 2D molecular structures"), KAboutData::License_GPL, ki18n("Copyright 2008 (c) Harm van Eersel"), ki18n(""), "http://molsketch.sourceforge.net", "devsciurus at xs4all.nl" );
+}
+
+void MolsKetchPart::slotClear()
+{
+ m_scene->clear();
+}
+
+void MolsKetchPart::slotPrint(QPrinter & printer)
+{
+ molsKetch::printFile(printer, m_scene);
+}
+
+*/
diff --git a/molsketch_helium/part/molsketchpart.h b/molsketch_helium/part/molsketchpart.h
new file mode 100644
index 0000000..f0759e2
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef MOLSKETCHPART_H
+#define MOLSKETCHPART_H
+/*
+#include <kparts/genericfactory.h>
+#include <kparts/part.h>
+
+class MolView;
+class KAboutData;
+class MolScene;
+class QPrinter;
+
+class MolsKetchPart : public KParts::ReadWritePart
+{
+ Q_OBJECT
+
+public:
+ MolsKetchPart( QWidget * parentWidget, QObject * parent, const QStringList & args = QStringList() );
+ virtual ~MolsKetchPart();
+
+ virtual void setReadWrite( bool rw );
+
+ static KAboutData * createAboutData();
+
+protected:
+ virtual bool openFile();
+ virtual bool saveFile();
+
+public Q_SLOTS:
+
+ // File action slots
+ void slotClear();
+ void slotPrint(QPrinter & printer);
+
+ // Edit action slots
+ void slotUndo();
+ void slotRedo();
+
+ void slotCut();
+ void slotCopy();
+ void slotPaste();
+
+ void slotSelectAll();
+
+ void slotAddMode();
+ void slotDelMode();
+ void slotMoveMode();
+ void slotRotMode();
+
+ // View action slots
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotZoomFit();
+ void slotZoomReset();
+
+protected:
+ MolView * m_view;
+ MolScene * m_scene;
+};
+
+typedef KParts::GenericFactory<MolsKetchPart> MolsKetchFactory;
+
+*/
+#endif
diff --git a/molsketch_helium/part/molsketchpart.rc b/molsketch_helium/part/molsketchpart.rc
new file mode 100644
index 0000000..8d7effc
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart.rc
@@ -0,0 +1,17 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="MolsKetchPart" version="Helium">
+ <MenuBar>
+<!-- <Menu name="file"><Text>&File</Text>
+ <Action name="file_import"/>
+ <Action name="file_export"/>
+ </Menu>-->
+ <Menu name="edit"><Text>&Edit</Text>
+ <Seperator/>
+ <Action name="edit_addmode"/>
+ <Action name="edit_delmode"/>
+ <Action name="edit_movemode"/>
+ <Action name="edit_rotmode"/>
+ </Menu>
+ </MenuBar>
+ <StatusBar/>
+</kpartgui>
\ No newline at end of file
diff --git a/molsketch_helium/part/molsketchpart_shell.cpp b/molsketch_helium/part/molsketchpart_shell.cpp
new file mode 100644
index 0000000..91e436c
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart_shell.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+/*
+#include "molsketchpart_shell.h"
+#include "molsketchpart.h"
+
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kcmdlineargs.h>
+#include <klibloader.h>
+#include <kicon.h>
+
+#include <QtGui/QWidget>
+#include <QtGui/QSplitter>
+#include <QtGui/QPrintDialog>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtGui/QPrinter>
+
+
+#include <kparts/componentfactory.h>
+#include <klibloader.h>
+
+int main(int argc, char **argv)
+{
+ KCmdLineOptions options;
+ options.add("+file(s)", ki18n("Files to load"));
+
+ const char version[] = "Helium 2008 (c) Harm van Eersel";
+ KLocalizedString description = ki18n("This is a test shell for molsKetch part.");
+
+ KCmdLineArgs::init( argc, argv, "molsketchpartshell", 0, ki18n("molsKetchPart Shell"), version, description );
+ KCmdLineArgs::addCmdLineOptions( options );
+ KApplication app;
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ Shell * shell = new Shell;
+ if ( args->count() == 1 )
+ {
+ KUrl url( QDir::currentPath() + "/", args->arg(0) );
+ shell->openUrl( url );
+ }
+ shell->show();
+ return app.exec();
+}
+
+
+Shell::Shell()
+{
+ // Set window icon
+ QIcon icon;
+ icon.addFile(":/molsketch.svg");
+ setWindowIcon(icon);
+
+ m_mskpart = new MolsKetchPart( this, this );
+
+// setAboutData(m_mskpart->createAboutData());
+
+ // Set tempory data location
+ KGlobal::dirs()->addResourceDir( "data", MSKSRCDIR );
+ setXMLFile( "molsketchpart_shell.rc" );
+
+ // File actions
+ KAction * paNew = new KAction( KIcon( "document-new" ), i18n( "&New file" ), this );
+ actionCollection()->addAction( "file_new", paNew );
+ connect( paNew, SIGNAL( triggered() ), m_mskpart, SLOT( slotClear() ));
+
+ KAction * paOpen = new KAction( KIcon( "document-open" ), i18n( "&Open file" ), this );
+ actionCollection()->addAction( "file_open", paOpen );
+ connect( paOpen, SIGNAL( triggered() ), this, SLOT( slotFileOpen() ));
+
+ KAction * paSave = new KAction( KIcon( "document-save" ), i18n( "&Save file" ), this );
+ actionCollection()->addAction( "file_save", paSave );
+ connect( paSave, SIGNAL( triggered() ), this, SLOT( slotFileSave() ));
+
+ KAction * paSaveAs = new KAction( KIcon( "document-save-as" ), i18n( "&Save file as" ), this );
+ actionCollection()->addAction( "file_save_as", paSaveAs );
+ connect( paSaveAs, SIGNAL( triggered() ), this, SLOT( slotFileSaveAs() ));
+
+ KAction * paPrint = new KAction( KIcon( "document-print" ), i18n( "&Print..." ), this );
+ actionCollection()->addAction( "file_print", paPrint );
+ connect( paPrint, SIGNAL( triggered() ), this, SLOT( slotFilePrint() ));
+
+ KAction * paQuit = new KAction( KIcon( "application-exit" ), i18n( "&Quit" ), this );
+ actionCollection()->addAction( "file_quit", paQuit );
+ connect( paQuit, SIGNAL( triggered() ), this, SLOT( close() ));
+
+ // Edit actions
+ KAction * paUndo = new KAction( KIcon( "edit-undo" ), i18n( "&Undo" ), this );
+ actionCollection()->addAction( "edit_undo", paUndo );
+ connect( paUndo, SIGNAL( triggered() ), m_mskpart, SLOT( slotUndo() ));
+
+ KAction * paRedo = new KAction( KIcon( "edit-redo" ), i18n( "&Redo" ), this );
+ actionCollection()->addAction( "edit_redo", paRedo );
+ connect( paRedo, SIGNAL( triggered() ), m_mskpart, SLOT( slotRedo() ));
+
+ KAction * paCut = new KAction( KIcon( "edit-cut" ), i18n( "&Cut" ), this );
+ actionCollection()->addAction( "edit_cut", paCut );
+ connect( paCut, SIGNAL( triggered() ), m_mskpart, SLOT( slotCut() ));
+
+ KAction * paCopy = new KAction( KIcon( "edit-copy" ), i18n( "&Copy" ), this );
+ actionCollection()->addAction( "edit_copy", paCopy );
+ connect( paCopy, SIGNAL( triggered() ), m_mskpart, SLOT( slotCopy() ));
+
+ KAction * paPaste = new KAction( KIcon( "edit-paste" ), i18n( "&Paste" ), this );
+ actionCollection()->addAction( "edit_paste", paPaste );
+ connect( paPaste, SIGNAL( triggered() ), m_mskpart, SLOT( slotPaste() ));
+
+ KAction * paSelectAll = new KAction( KIcon( "edit-select-all" ), i18n( "&Select all" ), this );
+ actionCollection()->addAction( "edit_select_all", paSelectAll );
+ connect( paSelectAll, SIGNAL( triggered() ), m_mskpart, SLOT( slotSelectAll() ));
+
+
+ // View actions
+ KAction * paZoomIn = new KAction( KIcon( "zoom-in" ), i18n( "&Zoom in" ), this );
+ actionCollection()->addAction( "view_zoom_in", paZoomIn );
+ connect( paZoomIn, SIGNAL( triggered() ), m_mskpart, SLOT( slotZoomIn() ));
+
+ KAction * paZoomOut = new KAction( KIcon( "zoom-out" ), i18n( "&Zoom out" ), this );
+ actionCollection()->addAction( "view_zoom_out", paZoomOut );
+ connect( paZoomOut, SIGNAL( triggered() ), m_mskpart, SLOT( slotZoomOut() ));
+
+ KAction * paZoomFit = new KAction( KIcon( "zoom-fit-best" ), i18n( "&Zoom fit best" ), this );
+ actionCollection()->addAction( "view_fit_to_page", paZoomFit );
+ connect( paZoomFit, SIGNAL( triggered() ), m_mskpart, SLOT( slotZoomFit() ));
+
+ KAction * paZoomOriginal = new KAction( KIcon( "zoom-original" ), i18n( "&Zoom reset" ), this );
+ actionCollection()->addAction( "view_actual_size", paZoomOriginal );
+ connect( paZoomOriginal, SIGNAL( triggered() ), m_mskpart, SLOT( slotZoomReset() ));
+
+// // Try to find a molsKetch part
+// m_mskpart = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadWritePart>( "application", QString(),
+// this, this );
+//
+// // Try to find libmolsketch
+// if ( !m_mskpart )
+// {
+// KLibFactory * factory = KLibLoader::self()->factory( "libmolsketchpart" );
+// if (factory)
+// {
+// // Create the part
+// m_mskpart = factory->create<KParts::ReadWritePart>( this );
+// }
+// else
+// {
+// KMessageBox::error( this, "No libmolsketchpart found !" );
+// }
+// }
+//
+// if ( m_mskpart )
+// {
+// // Set the main widget
+// setCentralWidget( m_mskpart->widget() );
+// // Integrate its GUI
+// createGUI( m_mskpart );
+// }
+
+ setCentralWidget( m_mskpart->widget() );
+ createGUI( m_mskpart );
+
+ resize( 800, 600 );
+}
+
+Shell::~Shell()
+{
+ delete m_mskpart;
+}
+
+void Shell::openUrl( const KUrl & url )
+{
+ m_mskpart->openUrl( url );
+}
+
+void Shell::saveUrl( const KUrl & url )
+{
+ m_mskpart->saveAs( url );
+}
+
+void Shell::slotFileNew()
+{
+ if (m_mskpart->closeUrl(true))
+ m_mskpart->slotClear();
+}
+
+void Shell::slotFileOpen()
+{
+ KUrl url = KFileDialog::getOpenUrl( QString(), "*.mol|Molecule documents (*.mol)", 0L, "file dialog" );
+
+ if ( !url.isEmpty() ) openUrl( url );
+}
+
+void Shell::slotFileSave()
+{
+ m_mskpart->save();
+}
+
+void Shell::slotFileSaveAs()
+{
+ KUrl url = KFileDialog::getSaveUrl( QString(), "*.mol|Molecule documents (*.mol)", 0L, "file dialog" );
+
+ if ( !url.isEmpty() ) saveUrl( url );
+}
+void Shell::slotFilePrint()
+{
+ // Creating a new printerobject
+ QPrinter printer(QPrinter::HighResolution);
+
+ // Prompt for the printoptions
+ QPrintDialog printDialog(&printer, this);
+
+ if (printDialog.exec() == QDialog::Accepted)
+ m_mskpart->slotPrint(printer);
+}
+*/
diff --git a/molsketch_helium/part/molsketchpart_shell.h b/molsketch_helium/part/molsketchpart_shell.h
new file mode 100644
index 0000000..d0475ce
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart_shell.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef MOLSKETCHPART_SHELL_H
+#define MOLSKETCHPART_SHELL_H
+/*
+#include <kparts/partmanager.h>
+#include <kparts/mainwindow.h>
+
+class QWidget;
+class MolsKetchPart;
+
+class Shell : public KParts::MainWindow
+{
+ Q_OBJECT
+public:
+ Shell();
+ virtual ~Shell();
+
+ void openUrl( const KUrl & url );
+ void saveUrl( const KUrl & url );
+
+protected Q_SLOTS:
+ void slotFileNew();
+ void slotFileOpen();
+ void slotFileSave();
+ void slotFileSaveAs();
+ void slotFilePrint();
+
+private:
+ MolsKetchPart * m_mskpart;
+};
+
+*/
+#endif
diff --git a/molsketch_helium/part/molsketchpart_shell.qrc b/molsketch_helium/part/molsketchpart_shell.qrc
new file mode 100644
index 0000000..c2197af
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart_shell.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>./molsketch.svg</file>
+ </qresource>
+</RCC>
diff --git a/molsketch_helium/part/molsketchpart_shell.rc b/molsketch_helium/part/molsketchpart_shell.rc
new file mode 100644
index 0000000..3620763
--- /dev/null
+++ b/molsketch_helium/part/molsketchpart_shell.rc
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="MsKShell" version="Helium">
+ <MenuBar>
+ <Seperator/>
+ <Merge/>
+ </MenuBar>
+ <StatusBar/>
+</kpartgui>
\ No newline at end of file
diff --git a/molsketch_helium/periodictablewidget.cpp b/molsketch_helium/periodictablewidget.cpp
new file mode 100644
index 0000000..dfb184f
--- /dev/null
+++ b/molsketch_helium/periodictablewidget.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "periodictablewidget.h"
+#include "element.h"
+
+#include <QHeaderView>
+#include <QSize>
+
+PeriodicTableWidget::PeriodicTableWidget()
+{
+ // Setting properties
+ setSelectionMode(QTableWidget::SingleSelection);
+ setDragEnabled(false);
+ setEditTriggers(QTableWidget::NoEditTriggers);
+
+ // Setting appereance
+// setMaximumSize(460,260);
+ setRowCount(10);
+ setColumnCount(18);
+ horizontalHeader()->hide();
+ verticalHeader()->hide();
+ qreal cellSize = 25;
+ for (int i = 0; i < rowCount(); i++) setRowHeight(i, cellSize);
+ for (int i = 0; i < columnCount(); i++) setColumnWidth(i, cellSize);
+
+ // Inserting the elements
+ for ( int i = 0; i < rowCount(); i++ )
+ for ( int j = 0; j < columnCount(); j++ ) {
+ QTableWidgetItem * item = new QTableWidgetItem(molsKetch::position2symbol(i + 1, j + 1));
+ item->setTextAlignment(Qt::AlignCenter);
+ setItem( i, j, item);
+ }
+
+ // Set background color
+ for ( int i = 0; i < rowCount(); i++ )
+ for ( int j = 0; j < 2; j++ ) {
+ QTableWidgetItem * tItem = item(i,j);
+ if (!tItem->text().isEmpty()) tItem->setBackground(QBrush(QColor(190, 114, 238)));
+ }
+ for ( int i = 0; i < rowCount(); i++ )
+ for ( int j = 2; j < 12; j++ ) {
+ QTableWidgetItem * tItem = item(i,j);
+ if (!tItem->text().isEmpty()) tItem->setBackground(QBrush(QColor(244, 253, 64)));
+ }
+ for ( int i = 0; i < rowCount(); i++ )
+ for ( int j = 12; j < 18; j++ ) {
+ QTableWidgetItem * tItem = item(i,j);
+ if (!tItem->text().isEmpty()) tItem->setBackground(QBrush(QColor(98, 238, 37)));
+ }
+ for ( int i = 8; i < 10; i++ )
+ for ( int j = 0; j < columnCount(); j++ ) {
+ QTableWidgetItem * tItem = item(i,j);
+ if (!tItem->text().isEmpty()) tItem->setBackground(QBrush(QColor(238, 90, 184)));
+ }
+ QTableWidgetItem * tItem1 = item(5,2);
+ tItem1->setBackground(QBrush(QColor(238, 90, 184)));
+ QTableWidgetItem * tItem2 = item(6,2);
+ tItem2->setBackground(QBrush(QColor(238, 90, 184)));
+
+ // Make sure that only non-empty items can be selected
+ m_previousItem = item(1,13);
+ connect(this, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(checkSelection(QTableWidgetItem*)));
+}
+
+QSize PeriodicTableWidget::sizeHint() const
+{
+ return QSize(460,260);
+}
+
+void PeriodicTableWidget::checkSelection(QTableWidgetItem * tItem)
+{
+ if (tItem->text().isEmpty()) setCurrentItem(m_previousItem);
+ else m_previousItem = tItem;
+}
diff --git a/molsketch_helium/periodictablewidget.h b/molsketch_helium/periodictablewidget.h
new file mode 100644
index 0000000..ba62263
--- /dev/null
+++ b/molsketch_helium/periodictablewidget.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains the PeriodicTableWidget class.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ * @since Deuterium
+ */
+
+#ifndef PERIODICTABLEWIDGET_H
+#define PERIODICTABLEWIDGET_H
+
+#include <QTableWidget>
+
+class QSize;
+
+/**
+ * This class implements a periodic table widget, used for element selection.
+ *
+ * @author Harm van Eersel <devsciurus at xs4all.nl>
+ */
+class PeriodicTableWidget : public QTableWidget
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor
+ */
+ PeriodicTableWidget();
+
+ /** Returns the size hint for the table */
+ virtual QSize sizeHint() const;
+
+ protected:
+ /** Stores the previous selection */
+ QTableWidgetItem * m_previousItem;
+
+ private slots:
+ /** Checks whether the new selection is a valid one */
+ void checkSelection(QTableWidgetItem * item);
+
+
+};
+
+#endif
diff --git a/molsketch_helium/settings.cpp b/molsketch_helium/settings.cpp
new file mode 100644
index 0000000..adcb1a7
--- /dev/null
+++ b/molsketch_helium/settings.cpp
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * Copyright (C) 2007-2008 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QCheckBox>
+#include <QFileDialog>
+#include <QFontDialog>
+#include <QSettings>
+
+#include "settings.h"
+#include "molscene.h"
+
+SettingsDialog::SettingsDialog(QSettings* settings, QWidget * parent, Qt::WindowFlags f ) : QDialog(parent,f), m_settings(settings)
+{
+ // Setup the user interface
+ ui.setupUi(this);
+
+ foreach(QListWidgetItem * item, ui.listWidget->findItems("*",Qt::MatchWildcard))
+ item->setTextAlignment(Qt::AlignHCenter);
+ ui.listWidget->setCurrentRow(0);
+
+ // Connect signals and slots
+ connect(ui.toolButtonBrowseLibraryPath, SIGNAL(clicked()), this, SLOT(browseLibraryPath()));
+ connect(ui.toolButtonBrowseCustomLibraryPath, SIGNAL(clicked()), this, SLOT(browseCustomLibraryPath()));
+ connect(ui.pushButtonFont, SIGNAL(clicked()), this, SLOT(selectFont()));
+ connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
+ connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(showHelp()));
+
+ // Setting translations
+ ui.groupBoxGeneral->setTitle(tr("Save options"));
+ ui.labelAutoSave->setText(tr("Autosave every"));
+ ui.labelDefaultFileType->setText(tr("Default file type"));
+ ui.labelDefaultImageType->setText(tr("Default image type"));
+
+ ui.groupBoxAtom->setTitle(tr("Atom settings"));
+ ui.checkBoxAutoHydrogen->setText(tr("Automaticly add hydrogens"));
+ ui.checkBoxShowCarbon->setText(tr("Show neutral carbon atoms"));
+ ui.checkBoxShowHydrogen->setText(tr("Show neutral hydrogen atoms"));
+ ui.checkBoxShowValency->setText(tr("Show atom charge"));
+ ui.labelAtomSymbolFont->setText(tr("Atom symbol font"));
+
+ ui.groupBoxBond->setTitle(tr("Bond settings"));
+// ui.labelMsKAtomSize->setText(tr("Atom size: "));
+ ui.labelBondLength->setText(tr("Bond length: "));
+ ui.labelBondWidth->setText(tr("Bond width: "));
+ ui.labelBondAngle->setText(tr("Bond angle: "));
+
+ ui.groupBoxLibraries->setTitle(tr("Libraries"));
+ ui.labelLibraryPath->setText(tr("Library path"));
+ ui.labelCustomLibraryPath->setText(tr("Custom library path"));
+
+ // Setting initial values
+ setInitialValues();
+}
+
+SettingsDialog::~ SettingsDialog( )
+{
+
+}
+
+void SettingsDialog::setInitialValues()
+{
+ ui.spinBoxAutoSave->setValue(m_settings->value("auto-save-time", 300000).toInt()/60000);
+
+ if (m_settings->value("auto-add-hydrogen", true).toBool()) ui.checkBoxAutoHydrogen->setCheckState(Qt::Checked);
+ if (m_settings->value("carbon-visble", false).toBool()) ui.checkBoxShowCarbon->setCheckState(Qt::Checked);
+ if (m_settings->value("hydrogen-visible", true).toBool()) ui.checkBoxShowHydrogen->setCheckState(Qt::Checked);
+ if (m_settings->value("charge-visible", true).toBool()) ui.checkBoxShowValency->setCheckState(Qt::Checked);
+ ui.doubleSpinBoxFontSize->setValue((m_settings->value("atom-symbol-font").value<QFont>()).pointSizeF());
+ ui.fontComboBox->setCurrentFont(m_settings->value("atom-symbol-font").value<QFont>());
+
+ ui.lineEditBondLength->setText(QString::number(m_settings->value("bond-length", 40).toDouble()));
+ ui.doubleSpinBoxBondWidth->setValue(m_settings->value("bond-width", 1).toDouble());
+ ui.doubleSpinBoxBondAngle->setValue(m_settings->value("bond-angle", 30).toDouble());
+
+ ui.lineEditLibraryPath->setText(m_settings->value("library-path", "/usr/share/molsketch/library/").toString());
+ ui.lineEditCustomLibraryPath->setText(m_settings->value("custom-library-path", QDir::homePath()).toString());
+}
+
+void SettingsDialog::accept()
+{
+ // Applying changes
+ applyChanges();
+
+ // Close dialog
+ QDialog::accept();
+}
+
+void SettingsDialog::applyChanges()
+{
+ // General settings
+ m_settings->setValue("auto-save-time", ui.spinBoxAutoSave->value()*60000);
+
+ // Atom settings
+// m_scene->setMsKAtomSize(ui.lineEditMsKAtomSize->text().toDouble());
+ m_settings->setValue("auto-add-hydrogen", ui.checkBoxAutoHydrogen->isChecked());
+ m_settings->setValue("carbon-visible", ui.checkBoxShowCarbon->isChecked());
+ m_settings->setValue("hydrogen-visible", ui.checkBoxShowHydrogen->isChecked());
+ m_settings->setValue("charge-visible", ui.checkBoxShowValency->isChecked());
+ QFont font = ui.fontComboBox->currentFont();
+ font.setPointSizeF(ui.doubleSpinBoxFontSize->value());
+ m_settings->setValue("atom-symbol-font", font);
+
+ // MsKBond settings
+ m_settings->setValue("bond-length", ui.lineEditBondLength->text().toDouble());
+ m_settings->setValue("bond-width", ui.doubleSpinBoxBondWidth->value());
+ m_settings->setValue("bond-angle", ui.doubleSpinBoxBondAngle->value());
+
+ // Library settings
+ /*TODO: check if the paths are valid*/
+ m_settings->setValue("library-path", ui.lineEditLibraryPath->text());
+ m_settings->setValue("custom-library-path", ui.lineEditCustomLibraryPath->text());
+}
+
+void SettingsDialog::browseLibraryPath()
+{
+ QString path = QFileDialog::getExistingDirectory(this, "molsKetch - Select library path", ui.lineEditLibraryPath->text());
+ if (!path.isEmpty())
+ ui.lineEditLibraryPath->setText(path);
+}
+
+void SettingsDialog::browseCustomLibraryPath()
+{
+ QString path = QFileDialog::getExistingDirectory(this, "molsKetch - Select custom library path", ui.lineEditCustomLibraryPath->text());
+ if (!path.isEmpty())
+ ui.lineEditCustomLibraryPath->setText(path);
+}
+
+void SettingsDialog::selectFont()
+{
+ bool * ok;
+ QFont previousFont = ui.fontComboBox->currentFont();
+ previousFont.setPointSizeF(ui.doubleSpinBoxFontSize->value());
+ QFont font = QFontDialog::getFont(ok, previousFont, this, "molsKetch - Select atomsymbol font");
+ if (ok) {
+ ui.fontComboBox->setCurrentFont(font);
+ ui.doubleSpinBoxFontSize->setValue(font.pointSizeF());
+ }
+}
+
+void SettingsDialog::buttonClicked(QAbstractButton * button)
+{
+ switch (ui.buttonBox->standardButton(button)) {
+ case QDialogButtonBox::RestoreDefaults:
+ /*TODO: make this really the default values instead of the initial values*/
+ setInitialValues();
+ break;
+ case QDialogButtonBox::Apply:
+ applyChanges();
+ break;
+ default:
+ break;
+ }
+}
+
+void SettingsDialog::showHelp()
+{
+ /*TODO*/
+}
diff --git a/molsketch_helium/settings.h b/molsketch_helium/settings.h
new file mode 100644
index 0000000..f7504f8
--- /dev/null
+++ b/molsketch_helium/settings.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2007-2008 by Harm van Eersel *
+ * devsciurus at xs4all.nl *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+/** @file
+ * This file is part of molsKetch and contains the SettingsDialog class.
+ *
+ * @author Harm van Eersel
+ * @since Hydrogen
+ */
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include "ui_settings.h"
+
+#include <QDialog>
+
+class QSettings;
+
+/**
+ * The settings dialog. Contains the logic of the ui file.
+ *
+ * @author Harm van Eersel
+ */
+class SettingsDialog : public QDialog
+ {
+ Q_OBJECT
+
+ public:
+ /** Creates a new dialog to set preferences.
+ *
+ * @param scene the scene of which the settings should be edited
+ */
+ SettingsDialog(QSettings* settings, QWidget * parent = 0, Qt::WindowFlags f = 0);
+ /** Destructor of the dialog. */
+ ~SettingsDialog();
+
+ private:
+ /** Stores the scene of which the settings should be edited. */
+ QSettings* m_settings;
+ /** The user interface of the dialog. */
+ Ui::SettingsDialog ui;
+
+ private slots:
+ /** Reimplementation of the accept() slot to change the scene settings on exit. */
+ void accept();
+ /** Applies the settings, but does not close the dialog */
+ void applyChanges();
+ /** (Re)set all controls to their initial values */
+ void setInitialValues();
+ /** Slot to handle clicks on the buttons of the buttonbox */
+ void buttonClicked(QAbstractButton * button);
+ /** Slot to show the appropiate help page */
+ void showHelp();
+ /** Shows a dialog to select the library path */
+ void browseLibraryPath();
+ /** Shows a dialog to select the custom library path */
+ void browseCustomLibraryPath();
+ /** Shows dialog to select the font of the atom symbols */
+ void selectFont();
+ };
+
+#endif
diff --git a/molsketch_helium/settings.ui b/molsketch_helium/settings.ui
new file mode 100644
index 0000000..694098b
--- /dev/null
+++ b/molsketch_helium/settings.ui
@@ -0,0 +1,640 @@
+<ui version="4.0" >
+ <author>Harm van Eersel <devsciurus at xs4all.nl></author>
+ <class>SettingsDialog</class>
+ <widget class="QDialog" name="SettingsDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>548</width>
+ <height>459</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>molsKetch - Preferences</string>
+ </property>
+ <property name="windowIcon" >
+ <iconset resource="molsketch.qrc" >:/images/configure.png</iconset>
+ </property>
+ <widget class="QWidget" name="layoutWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>9</x>
+ <y>9</y>
+ <width>531</width>
+ <height>441</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>88</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="iconSize" >
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="movement" >
+ <enum>QListView::Static</enum>
+ </property>
+ <property name="spacing" >
+ <number>12</number>
+ </property>
+ <property name="viewMode" >
+ <enum>QListView::IconMode</enum>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ <property name="currentRow" >
+ <number>-1</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>General</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="molsketch.qrc" >:/images/configure.svg</iconset>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Draw settings</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="molsketch.qrc" >:/images/draw-freehand.svg</iconset>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Libraries</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="molsketch.qrc" >:/images/document-open.svg</iconset>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="generalPage" >
+ <widget class="QGroupBox" name="groupBoxGeneral" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>411</width>
+ <height>391</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>Save options</string>
+ </property>
+ <widget class="QWidget" name="layoutWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>376</width>
+ <height>105</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="labelDefaultFileType" >
+ <property name="text" >
+ <string>Default file type</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBoxFileType" >
+ <item>
+ <property name="text" >
+ <string>MDL (*.mdl)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Chemical Markup Language (*.cml)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="labelDefaultImageType" >
+ <property name="text" >
+ <string>Default image type</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBoxImageType" >
+ <item>
+ <property name="text" >
+ <string>Scalable Vector Graphics (*.svg)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Portable Network Graphics (*.png)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="labelAutoSave" >
+ <property name="text" >
+ <string>Autosave each</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>192</width>
+ <height>25</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxAutoSave" >
+ <property name="suffix" >
+ <string> min</string>
+ </property>
+ <property name="prefix" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="drawingPage" >
+ <widget class="QWidget" name="layoutWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>430</width>
+ <height>381</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QGroupBox" name="groupBoxAtom" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Atom settings</string>
+ </property>
+ <property name="checkable" >
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="2" column="0" >
+ <widget class="QCheckBox" name="checkBoxShowHydrogen" >
+ <property name="text" >
+ <string>Show neutral hydrogen atoms</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="checkBoxAutoHydrogen" >
+ <property name="text" >
+ <string>Automaticly add hydrogens</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QCheckBox" name="checkBoxShowValency" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Show atomic charge</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QCheckBox" name="checkBoxShowCarbon" >
+ <property name="text" >
+ <string>Show neutral carbon atoms</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" >
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QDoubleSpinBox" name="doubleSpinBoxFontSize" >
+ <property name="buttonSymbols" >
+ <enum>QAbstractSpinBox::UpDownArrows</enum>
+ </property>
+ <property name="accelerated" >
+ <bool>true</bool>
+ </property>
+ <property name="correctionMode" >
+ <enum>QAbstractSpinBox::CorrectToNearestValue</enum>
+ </property>
+ <property name="suffix" >
+ <string> pt</string>
+ </property>
+ <property name="decimals" >
+ <number>0</number>
+ </property>
+ <property name="minimum" >
+ <double>8.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>120.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFontComboBox" name="fontComboBox" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonFont" >
+ <property name="text" >
+ <string>Details...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="labelAtomSymbolFont" >
+ <property name="text" >
+ <string>AtomSymbol font</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBoxBond" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>MsKBond settings</string>
+ </property>
+ <widget class="QLabel" name="labelBondLength" >
+ <property name="geometry" >
+ <rect>
+ <x>11</x>
+ <y>30</y>
+ <width>211</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>MsKBond length:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="lineEditBondLength" >
+ <property name="geometry" >
+ <rect>
+ <x>230</x>
+ <y>30</y>
+ <width>171</width>
+ <height>26</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="labelBondWidth" >
+ <property name="geometry" >
+ <rect>
+ <x>11</x>
+ <y>61</y>
+ <width>221</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>MsKBond width:</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="doubleSpinBoxBondWidth" >
+ <property name="geometry" >
+ <rect>
+ <x>230</x>
+ <y>60</y>
+ <width>171</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="suffix" >
+ <string> px</string>
+ </property>
+ <property name="decimals" >
+ <number>0</number>
+ </property>
+ <property name="minimum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="value" >
+ <double>1.000000000000000</double>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="doubleSpinBoxBondAngle" >
+ <property name="geometry" >
+ <rect>
+ <x>230</x>
+ <y>90</y>
+ <width>171</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="suffix" >
+ <string>°</string>
+ </property>
+ <property name="decimals" >
+ <number>0</number>
+ </property>
+ <property name="minimum" >
+ <double>6.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>180.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>6.000000000000000</double>
+ </property>
+ <property name="value" >
+ <double>30.000000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="labelBondAngle" >
+ <property name="geometry" >
+ <rect>
+ <x>11</x>
+ <y>91</y>
+ <width>221</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>MsKBond angle:</string>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <widget class="QWidget" name="librariesPage" >
+ <widget class="QGroupBox" name="groupBoxLibraries" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>411</width>
+ <height>381</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>Libraries</string>
+ </property>
+ <widget class="QWidget" name="layoutWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>371</width>
+ <height>131</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="labelLibraryPath" >
+ <property name="text" >
+ <string>Library path</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditLibraryPath" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolButtonBrowseLibraryPath" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="labelCustomLibraryPath" >
+ <property name="text" >
+ <string>Custom library Path</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditCustomLibraryPath" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolButtonBrowseCustomLibraryPath" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::NoButton|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <tabstops>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources>
+ <include location="molsketch.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SettingsDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>366</x>
+ <y>431</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SettingsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>434</x>
+ <y>431</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>listWidget</sender>
+ <signal>currentRowChanged(int)</signal>
+ <receiver>stackedWidget</receiver>
+ <slot>setCurrentIndex(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>62</x>
+ <y>21</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>260</x>
+ <y>12</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/myline.cc b/myline.cc
new file mode 100644
index 0000000..daebfbf
--- /dev/null
+++ b/myline.cc
@@ -0,0 +1,150 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "myline.h"
+#include <qlineedit.h>
+#include <qvalidator.h>
+#include <qlabel.h>
+#include <qfiledialog.h>
+#include <iostream>
+
+
+using namespace std;
+
+MyLine::MyLine( QWidget *parent, const char *name, int valid)
+ : Q3HBox( parent, name )
+{
+
+
+ QLabel *label = new QLabel( name, this );
+ label->setMaximumWidth( 250 );
+ label->setMinimumWidth( 250 );
+ linedit = new QLineEdit( this);
+ if (valid == 1)
+ linedit->setValidator( new QIntValidator( linedit ) );
+ if (valid == 2)
+ linedit->setValidator( new QDoubleValidator( -999.0, 999.0, 2,linedit ) );
+
+}
+
+ void MyLine::ins (QString s)
+{
+ linedit-> clear ();
+ linedit->insert (s);
+
+}
+
+ string MyLine::val ()
+{
+ return linedit->text ().toStdString ();
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+MyLineF::MyLineF( QWidget *parent, QWidget *master, const char *name, int valid, int butt)
+ : Q3HBox( parent, name )
+{
+static const char * p1_xpm[] = {
+"16 16 3 1",
+" c None",
+". c #000000000000",
+"X c #FFFFFFFF0000",
+" ",
+" ",
+" .... ",
+" .XXXX. ",
+" .............. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .XXXXXXXXXXXX. ",
+" .............. ",
+" "};
+ QPixmap p1( p1_xpm );
+
+ tag = name;
+ QLabel *label = new QLabel( name, this );
+ label->setMaximumWidth( 150 );
+ label->setMinimumWidth( 150 );
+ linedit = new QLineEdit( this);
+ if (valid == 1) {filetype = "Tripos Mol2 File (*.mol2)";};
+ if (valid == 2) {filetype = "PLANTS Config File (*.pcfg);;All files (*)";};
+ if (valid == 3) {filetype = "List File (*)";};
+ QPushButton *fbutt = new QPushButton( "" , this);
+ // fbutt->setPixmap( p1);
+ connect (fbutt, SIGNAL( clicked() ), SLOT( set_file() ) );
+
+ if (butt){
+ adbutt = new QPushButton( "", this );
+
+ adbutt->setMaximumWidth( 20 );
+ }
+
+}
+
+const char* MyLineF::get_value()
+{
+
+ // QString a = linedit->displayText();
+ // return a.latin1 ();
+ return "a";
+
+}
+
+QString MyLineF::ask_file()
+{
+
+ QString mol_name = QFileDialog::getOpenFileName(this,
+ tr ("Open file"), "",tr("Tripos Mol2 File (*.mol2)"));
+
+ return mol_name;
+ }
+ void MyLineF::set_file ()
+{
+ QString s = ask_file ();
+ linedit->clear ();
+ linedit->insert (s);
+ // set_line ();
+}
+
+ void MyLineF::set_line ()
+{ QString st = tag;
+ st.append (" | ");
+ st.append (linedit->displayText ());
+ // master->iflb->insertItem(st);
+
+}
+
+ void MyLineF::ins (QString s)
+{
+ linedit-> clear ();
+ linedit->insert (s);
+
+}
+
+ string MyLineF::val ()
+{
+ return linedit->text ().toStdString ();
+
+}
diff --git a/obabel_includes.h b/obabel_includes.h
new file mode 100644
index 0000000..c880dbb
--- /dev/null
+++ b/obabel_includes.h
@@ -0,0 +1,37 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef OB_INCLUDES
+#define OB_INCLUDES
+
+#include <openbabel/forcefield.h>
+#include <openbabel/data.h>
+
+#include <openbabel/mol.h>
+#include <openbabel/obconversion.h>
+#include <openbabel/groupcontrib.h>
+#include <openbabel/obiter.h>
+#include <openbabel/obutil.h>
+#include <openbabel/molchrg.h>
+#include <openbabel/math/vector3.h>
+#include <openbabel/generic.h>
+#include <openbabel/builder.h>
+
+
+
+#endif //OB_INCLUDES
diff --git a/object_script.Zodiac.Debug b/object_script.Zodiac.Debug
new file mode 100644
index 0000000..ad1dcc6
--- /dev/null
+++ b/object_script.Zodiac.Debug
@@ -0,0 +1,65 @@
+INPUT(
+./debug/actions.o
+./debug/arcball.o
+./debug/builder.o
+./debug/chemscore.o
+./debug/command.o
+./debug/constants.o
+./debug/database.o
+./debug/datagrid.o
+./debug/ddwin.o
+./debug/FF.o
+./debug/graphical_object.o
+./debug/iodevice.o
+./debug/MarchingCubes.o
+./debug/maths.o
+./debug/menu.o
+./debug/minimize.o
+./debug/MMFF.o
+./debug/myline.o
+./debug/plants.o
+./debug/plants_mainwin.o
+./debug/plantsconfig.o
+./debug/PLP.o
+./debug/ply.o
+./debug/povray.o
+./debug/thread.o
+./debug/wiimote.o
+./debug/ZNdata.o
+./debug/ZNmolecule.o
+./debug/Zodiac.o
+./debug/forcefieldghemical.o
+./debug/forcefieldmmff94.o
+./debug/forcefielduff.o
+./debug/atom.o
+./debug/bond.o
+./debug/commands.o
+./debug/element.o
+./debug/fileio.o
+./debug/mainwindow.o
+./debug/molecule.o
+./debug/mollibitem.o
+./debug/molscene.o
+./debug/molview.o
+./debug/periodictablewidget.o
+./debug/settings.o
+./debug/molsketch_factory.o
+./debug/molsketchpart.o
+./debug/molsketchpart_shell.o
+./debug/moc_ddwin.o
+./debug/moc_menu.o
+./debug/moc_myline.o
+./debug/moc_plants.o
+./debug/moc_plants_mainwin.o
+./debug/moc_thread.o
+./debug/moc_ZNdata.o
+./debug/moc_mainwindow.o
+./debug/moc_molscene.o
+./debug/moc_molview.o
+./debug/moc_periodictablewidget.o
+./debug/moc_settings.o
+./debug/qrc_resources.o
+./debug/qrc_zodiac.o
+./debug/qrc_molsketch.o
+./debug/qrc_molsketchpart_shell.o
+);
diff --git a/object_script.Zodiac.Release b/object_script.Zodiac.Release
new file mode 100644
index 0000000..6af41a2
--- /dev/null
+++ b/object_script.Zodiac.Release
@@ -0,0 +1,65 @@
+INPUT(
+./release/actions.o
+./release/arcball.o
+./release/builder.o
+./release/chemscore.o
+./release/command.o
+./release/constants.o
+./release/database.o
+./release/datagrid.o
+./release/ddwin.o
+./release/FF.o
+./release/graphical_object.o
+./release/iodevice.o
+./release/MarchingCubes.o
+./release/maths.o
+./release/menu.o
+./release/minimize.o
+./release/MMFF.o
+./release/myline.o
+./release/plants.o
+./release/plants_mainwin.o
+./release/plantsconfig.o
+./release/PLP.o
+./release/ply.o
+./release/povray.o
+./release/thread.o
+./release/wiimote.o
+./release/ZNdata.o
+./release/ZNmolecule.o
+./release/Zodiac.o
+./release/forcefieldghemical.o
+./release/forcefieldmmff94.o
+./release/forcefielduff.o
+./release/atom.o
+./release/bond.o
+./release/commands.o
+./release/element.o
+./release/fileio.o
+./release/mainwindow.o
+./release/molecule.o
+./release/mollibitem.o
+./release/molscene.o
+./release/molview.o
+./release/periodictablewidget.o
+./release/settings.o
+./release/molsketch_factory.o
+./release/molsketchpart.o
+./release/molsketchpart_shell.o
+./release/moc_ddwin.o
+./release/moc_menu.o
+./release/moc_myline.o
+./release/moc_plants.o
+./release/moc_plants_mainwin.o
+./release/moc_thread.o
+./release/moc_ZNdata.o
+./release/moc_mainwindow.o
+./release/moc_molscene.o
+./release/moc_molview.o
+./release/moc_periodictablewidget.o
+./release/moc_settings.o
+./release/qrc_resources.o
+./release/qrc_zodiac.o
+./release/qrc_molsketch.o
+./release/qrc_molsketchpart_shell.o
+);
diff --git a/parameters/CVS/Entries b/parameters/CVS/Entries
new file mode 100644
index 0000000..bd24d77
--- /dev/null
+++ b/parameters/CVS/Entries
@@ -0,0 +1,17 @@
+/MMFF93SUP.PAR/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/MMFFANG.PAR/1.1.1.1/Wed Aug 20 12:44:08 2008//
+/MMFFAROM.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFBNDK.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFBOND.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFCHG.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFDEF.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFDFSB.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFHDEF.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFOOP.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFPBCI.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFPROP.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFSTBN.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFSYMB.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFTOR.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+/MMFFVDW.PAR/1.1.1.1/Wed Aug 20 12:44:07 2008//
+D
diff --git a/parameters/CVS/Entries.Extra b/parameters/CVS/Entries.Extra
new file mode 100644
index 0000000..0a5bf9f
--- /dev/null
+++ b/parameters/CVS/Entries.Extra
@@ -0,0 +1,16 @@
+/MMFF93SUP.PAR////*///
+/MMFFANG.PAR////*///
+/MMFFAROM.PAR////*///
+/MMFFBNDK.PAR////*///
+/MMFFBOND.PAR////*///
+/MMFFCHG.PAR////*///
+/MMFFDEF.PAR////*///
+/MMFFDFSB.PAR////*///
+/MMFFHDEF.PAR////*///
+/MMFFOOP.PAR////*///
+/MMFFPBCI.PAR////*///
+/MMFFPROP.PAR////*///
+/MMFFSTBN.PAR////*///
+/MMFFSYMB.PAR////*///
+/MMFFTOR.PAR////*///
+/MMFFVDW.PAR////*///
diff --git a/parameters/CVS/Entries.Extra.Old b/parameters/CVS/Entries.Extra.Old
new file mode 100644
index 0000000..e69de29
diff --git a/parameters/CVS/Entries.Old b/parameters/CVS/Entries.Old
new file mode 100644
index 0000000..e69de29
diff --git a/parameters/CVS/Repository b/parameters/CVS/Repository
new file mode 100644
index 0000000..a4b7867
--- /dev/null
+++ b/parameters/CVS/Repository
@@ -0,0 +1 @@
+zodiac/parameters
diff --git a/parameters/CVS/Root b/parameters/CVS/Root
new file mode 100644
index 0000000..0f0465b
--- /dev/null
+++ b/parameters/CVS/Root
@@ -0,0 +1 @@
+:ssh:nicola_zonta at zodiac-zeden.cvs.sourceforge.net:/cvsroot/zodiac-zeden
diff --git a/parameters/MMFF93SUP.PAR b/parameters/MMFF93SUP.PAR
new file mode 100644
index 0000000..1da342d
--- /dev/null
+++ b/parameters/MMFF93SUP.PAR
@@ -0,0 +1,86 @@
+* 16. MMFF93SUP.PAR: This "supplementary parameters" file provides values for
+* two out-of-plane and seventy-one torsion parameters in the
+* earlier MMFF93 version of the MMFF force field that differ
+* from those used in MMFF94.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* This supplementary-paramters file contains two out-of-plane bending
+* parameters and 71 torsion parameters; it supplies values needed to
+* reconstitute the earlier MMFF93 force field
+*
+ 0 0 0 0 0 2 0 71
+ 1 10 1 3 -0.034 C93
+ 1 10 3 28 -0.030 C93
+0 1 1 1 1 0.431 0.400 0.149 C93
+5 1 1 1 1 0.159 -0.585 1.141 C93
+0 1 1 1 5 0.440 -0.470 0.228 C93
+0 1 1 1 6 -0.746 1.834 0.426 C93
+5 1 1 1 6 0.346 -1.239 2.287 C93
+0 3 1 1 5 -0.206 0.032 0.000 C93
+0 3 1 1 6 -0.688 0.021 0.000 C93
+0 5 1 1 5 0.210 -1.296 0.315 C93
+0 5 1 1 6 -0.898 1.385 0.369 C93
+0 5 1 1 10 0.000 0.000 0.417 C93
+0 6 1 1 6 0.423 1.508 0.742 C93
+5 6 1 1 6 0.398 -1.328 2.133 C93
+0 1 1 3 10 -0.969 0.834 0.898 C93
+0 5 1 3 7 0.660 -1.392 0.296 C93
+0 5 1 3 10 -0.351 0.170 0.000 C93
+0 10 1 3 7 0.158 2.228 1.089 C93
+0 10 1 3 10 0.608 0.053 1.325 C93
+0 1 1 6 1 -0.782 0.652 0.794 C93
+5 1 1 6 1 0.105 -0.358 0.609 C93
+0 1 1 6 21 0.000 0.235 0.252 C93
+0 5 1 6 1 0.487 0.251 0.555 C93
+0 5 1 6 21 0.639 -0.239 0.340 C93
+0 6 1 6 1 0.358 -0.581 0.773 C93
+5 6 1 6 1 0.000 -0.096 0.231 C93
+0 1 1 10 3 -1.141 0.491 0.917 C93
+0 1 1 10 6 0.000 -0.534 0.145 C93
+0 1 1 10 28 0.047 -0.100 0.162 C93
+0 3 1 10 3 3.187 -2.055 1.228 C93
+0 3 1 10 28 0.288 0.000 0.000 C93
+0 5 1 10 1 0.000 0.000 0.654 C93
+0 5 1 10 3 -1.958 1.336 -0.101 C93
+0 5 1 10 6 0.000 0.737 0.636 C93
+0 5 1 10 28 -0.454 0.353 0.169 C93
+0 1 2 2 1 0.000 12.000 0.000 C93
+1 1 2 3 10 0.000 1.762 -0.543 C93
+1 2 2 3 10 0.000 2.297 0.477 C93
+1 5 2 3 10 0.000 0.662 0.261 C93
+1 5 3 3 6 0.052 0.184 0.425 C93
+0 2 3 9 27 0.120 16.000 0.120 C93
+0 5 3 9 27 0.186 16.000 -0.135 C93
+0 40 3 9 1 -0.565 18.127 -0.082 C93
+0 40 3 9 27 -0.242 16.000 0.489 C93
+0 1 3 10 1 0.655 5.280 0.391 C93
+0 1 3 10 6 -0.983 8.730 1.080 C93
+0 1 3 10 28 -0.299 5.644 2.307 C93
+2 2 3 10 28 -0.213 7.108 0.272 C93
+0 5 3 10 1 -0.229 7.274 1.760 C93
+0 5 3 10 3 -1.580 3.512 1.425 C93
+0 5 3 10 28 0.000 6.520 0.922 C93
+0 7 3 10 1 -0.424 7.018 -0.774 C93
+0 7 3 10 3 1.624 3.618 -1.349 C93
+0 7 3 10 6 1.027 8.487 -0.281 C93
+0 7 3 10 28 1.417 5.031 -0.289 C93
+0 10 3 10 28 0.000 3.504 1.469 C93
+0 9 3 40 28 1.440 4.254 -0.522 C93
+0 40 3 40 28 0.180 2.985 0.894 C93
+0 7 3 43 18 -0.949 5.082 -0.112 X93
+0 7 3 43 28 0.653 5.280 -0.549 X93
+2 37 3 43 18 -0.586 4.860 1.236 X93
+2 37 3 43 28 -0.253 5.096 0.823 X93
+0 21 6 10 1 1.360 0.584 -1.009 C93
+0 21 6 10 3 1.058 0.387 -1.283 C93
+0 32 18 37 37 -0.182 -0.935 -0.723 X93
+0 43 18 37 37 0.239 -1.846 -0.436 X93
+0 1 18 43 1 -0.914 -0.482 0.179 X93
+0 32 18 43 1 1.635 1.544 1.373 X93
+0 32 18 43 28 0.619 0.404 0.000 X93
+0 32 18 43 37 1.026 1.560 1.257 X93
+0 37 18 43 1 -1.181 -0.767 1.025 X93
+0 37 18 43 28 -2.163 -1.773 -2.043 X93
+0 37 18 43 37 -1.858 -0.388 1.434 X93
diff --git a/parameters/MMFFANG.PAR b/parameters/MMFFANG.PAR
new file mode 100644
index 0000000..6fe6b96
--- /dev/null
+++ b/parameters/MMFFANG.PAR
@@ -0,0 +1,2354 @@
+* 8. MMFFANG.PAR: This file supplies parameters for angle-bending interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF ANGLE PARAMETERS- Rev: 26-Oct-94 Source: MMFF94
+* C94 = CORE MMFF94 parameter - obtained from ab initio data
+* X94 = EXTD MMFF94 parameter - fit to additional ab initio data
+* E94 = theta0 from fit to X-ray data, ka from empirical rule
+* #E94 = theta0 and ka both from empirical rules
+*
+* atom types ka theta0 Comment/origin
+0 0 1 0 0.000 108.900 0:*-1-* MMFF94 DEF
+0 1 1 1 0.851 109.608 C94
+0 1 1 2 0.736 109.445 C94
+0 1 1 3 0.777 107.517 C94
+0 1 1 4 1.006 110.265 E94
+0 1 1 5 0.636 110.549 C94
+0 1 1 6 0.992 108.133 C94
+0 1 1 8 0.777 108.290 C94
+0 1 1 9 1.136 108.194 E94
+0 1 1 10 1.050 109.960 C94
+0 1 1 11 1.225 108.313 C94
+0 1 1 12 1.056 108.679 C94
+0 1 1 13 1.078 106.820 E94
+0 1 1 14 0.980 109.945 E94
+0 1 1 15 0.743 107.397 C94
+0 1 1 17 1.089 108.578 E94
+0 1 1 18 1.093 109.315 E94
+0 1 1 19 0.755 115.436 E94
+0 1 1 20 1.021 108.659 E94
+0 1 1 22 1.001 110.125 E94
+0 1 1 25 0.803 112.356 X94
+0 1 1 26 0.833 109.879 E94
+0 1 1 34 1.179 106.493 C94
+0 1 1 37 0.756 108.617 C94
+0 1 1 39 0.927 109.170 C94
+0 1 1 40 1.130 108.678 E94
+0 1 1 41 0.330 98.422 C94
+0 1 1 43 1.135 108.019 E94
+0 1 1 45 1.197 105.028 E94
+0 1 1 54 1.173 106.424 E94
+0 1 1 55 1.150 107.604 E94
+0 1 1 56 1.199 110.371 C94
+0 1 1 57 1.012 109.900 E94
+0 1 1 58 1.179 106.327 E94
+0 1 1 61 1.125 109.311 E94
+0 1 1 63 1.006 110.058 E94
+0 1 1 64 0.988 111.064 E94
+0 1 1 67 1.216 104.557 E94
+0 1 1 68 1.018 107.195 C94
+0 1 1 73 1.160 104.658 E94
+0 1 1 78 1.012 109.850 E94
+0 1 1 80 0.947 113.327 E94
+0 1 1 81 1.108 109.837 E94
+0 2 1 2 1.113 111.453 C94
+0 2 1 3 0.667 104.829 C94
+0 2 1 4 1.022 109.873 E94
+0 2 1 5 0.632 110.292 C94
+0 2 1 6 1.074 108.699 C94
+0 2 1 8 0.884 111.553 C94
+0 2 1 9 1.118 109.577 E94
+0 2 1 10 1.160 107.963 E94
+0 2 1 11 1.192 110.419 E94
+0 2 1 12 1.070 109.410 E94
+0 2 1 15 1.078 109.560 E94
+0 2 1 17 1.077 109.434 E94
+0 2 1 18 1.188 105.110 E94
+0 2 1 20 1.053 107.448 E94
+0 2 1 22 0.942 114.020 E94
+0 2 1 25 0.893 106.815 E94
+0 2 1 26 1.029 99.065 E94
+0 2 1 34 1.066 111.817 E94
+0 2 1 37 0.985 111.446 E94
+0 2 1 39 1.124 109.513 E94
+0 2 1 40 1.149 108.270 E94
+0 2 1 45 1.232 103.978 E94
+0 2 1 63 0.935 114.692 E94
+0 2 1 67 1.224 104.687 E94
+0 3 1 3 0.974 111.746 E94
+0 3 1 4 1.019 109.850 E94
+0 3 1 5 0.650 108.385 C94
+0 3 1 6 0.528 104.112 C94
+0 3 1 8 1.197 105.837 E94
+0 3 1 9 1.201 105.535 E94
+0 3 1 10 0.634 102.655 C94
+0 3 1 11 1.189 110.328 E94
+0 3 1 12 1.136 106.064 E94
+0 3 1 13 1.147 103.645 E94
+0 3 1 14 1.048 106.404 E94
+0 3 1 15 1.125 107.192 E94
+0 3 1 17 1.092 108.602 E94
+0 3 1 18 1.120 108.119 E94
+0 3 1 20 0.969 111.830 E94
+0 3 1 22 0.999 110.522 E94
+0 3 1 26 0.742 116.555 E94
+0 3 1 34 1.141 107.871 E94
+0 3 1 37 1.011 109.833 E94
+0 3 1 39 1.136 108.751 E94
+0 3 1 40 1.174 106.941 E94
+0 3 1 41 1.033 108.216 E94
+0 3 1 45 1.221 104.281 E94
+0 3 1 63 1.069 107.077 E94
+0 3 1 64 1.028 109.186 E94
+0 3 1 81 1.167 107.327 E94
+0 4 1 4 0.954 114.186 E94
+0 4 1 5 0.615 111.417 X94
+0 4 1 6 1.273 109.977 E94
+0 4 1 8 1.099 111.063 E94
+0 4 1 9 1.187 106.750 E94
+0 4 1 10 1.117 110.488 E94
+0 4 1 13 1.021 110.047 E94
+0 4 1 15 1.028 112.432 E94
+0 4 1 18 1.187 105.351 E94
+0 4 1 22 1.174 102.556 E94
+0 4 1 26 0.853 108.999 E94
+0 4 1 34 1.148 108.160 E94
+0 4 1 37 0.993 111.424 E94
+0 5 1 5 0.516 108.836 C94
+0 5 1 6 0.781 108.577 C94
+0 5 1 8 0.653 110.297 C94
+0 5 1 9 0.733 109.894 C94
+0 5 1 10 0.740 107.646 C94
+0 5 1 11 0.875 107.897 C94
+0 5 1 12 0.698 108.162 C94
+0 5 1 13 0.613 106.049 E94
+0 5 1 14 0.508 113.019 E94
+0 5 1 15 0.576 109.609 C94
+0 5 1 17 0.634 107.944 X94
+0 5 1 18 0.663 106.855 X94
+0 5 1 19 0.450 113.195 X94
+0 5 1 20 0.706 111.000 C94
+0 5 1 22 0.618 110.380 E94
+0 5 1 25 0.487 109.486 X94
+0 5 1 26 0.466 111.172 X94
+0 5 1 34 0.872 106.224 C94
+0 5 1 35 0.644 125.663 X94
+0 5 1 37 0.627 109.491 C94
+0 5 1 39 0.811 106.299 C94
+0 5 1 40 0.719 109.870 C94
+0 5 1 41 0.525 108.904 C94
+0 5 1 43 0.692 109.083 X94
+0 5 1 45 0.741 105.197 X94
+0 5 1 46 0.719 106.735 X94
+0 5 1 54 0.874 106.973 C94
+0 5 1 55 0.861 108.507 C94
+0 5 1 56 0.814 108.223 C94
+0 5 1 57 0.626 110.420 E94
+0 5 1 58 0.750 105.481 E94
+0 5 1 61 0.710 109.227 X94
+0 5 1 62 0.655 113.035 X94
+0 5 1 63 0.621 110.467 E94
+0 5 1 64 0.622 110.457 E94
+0 5 1 67 0.732 106.474 E94
+0 5 1 68 0.748 103.817 C94
+0 5 1 72 0.547 116.576 X94
+0 5 1 73 0.633 107.153 X94
+0 5 1 78 0.640 109.078 E94
+0 5 1 80 0.684 105.144 E94
+0 5 1 81 0.721 107.870 E94
+0 6 1 6 1.156 111.368 C94
+0 6 1 8 1.333 112.223 E94
+0 6 1 9 1.224 116.950 E94
+0 6 1 10 1.432 108.568 E94
+0 6 1 11 1.593 106.900 E94
+0 6 1 15 1.273 112.012 E94
+0 6 1 17 1.348 108.655 E94
+0 6 1 19 0.906 117.214 E94
+0 6 1 20 1.293 108.202 E94
+0 6 1 22 1.287 108.913 E94
+0 6 1 25 1.171 103.598 E94
+0 6 1 26 0.888 118.433 E94
+0 6 1 34 1.257 114.975 E94
+0 6 1 37 0.878 107.978 C94
+0 6 1 39 1.485 106.464 E94
+0 6 1 40 1.371 110.779 E94
+0 6 1 41 1.333 106.467 E94
+0 6 1 45 1.523 104.438 E94
+0 6 1 57 1.308 108.467 E94
+0 6 1 63 1.351 106.535 E94
+0 6 1 64 1.238 111.308 E94
+0 8 1 8 1.203 110.856 E94
+0 8 1 9 1.133 114.080 E94
+0 8 1 10 1.258 108.683 E94
+0 8 1 12 1.217 107.251 E94
+0 8 1 15 1.120 112.356 E94
+0 8 1 20 1.116 109.353 E94
+0 8 1 25 1.143 98.698 E94
+0 8 1 34 1.138 113.412 E94
+0 8 1 37 1.090 110.992 E94
+0 8 1 39 1.364 104.193 E94
+0 8 1 40 0.964 123.962 E94
+0 8 1 41 1.234 103.868 E94
+0 8 1 43 1.137 113.596 E94
+0 8 1 45 1.583 96.139 E94
+0 8 1 57 1.038 114.266 E94
+0 8 1 63 1.104 110.598 E94
+0 8 1 64 1.156 108.127 E94
+0 9 1 10 1.209 110.720 E94
+0 9 1 12 1.173 109.152 E94
+0 9 1 15 1.024 117.465 E94
+0 9 1 25 1.060 102.432 E94
+0 9 1 37 1.077 111.565 E94
+0 9 1 40 1.084 116.728 E94
+0 9 1 80 1.163 107.509 E94
+0 10 1 10 1.191 111.995 E94
+0 10 1 15 1.161 110.502 E94
+0 10 1 17 1.269 105.509 E94
+0 10 1 20 1.220 104.838 E94
+0 10 1 22 1.132 109.262 E94
+0 10 1 25 1.015 104.822 E94
+0 10 1 37 1.107 110.423 E94
+0 10 1 40 1.264 108.536 E94
+0 10 1 41 1.087 110.961 E94
+0 10 1 57 1.268 103.622 E94
+0 11 1 11 1.638 106.081 C94
+0 11 1 15 1.254 109.517 E94
+0 11 1 20 1.243 107.637 E94
+0 11 1 25 1.244 97.532 E94
+0 11 1 34 1.338 108.669 E94
+0 11 1 35 1.556 110.367 E94
+0 11 1 37 1.151 112.278 E94
+0 11 1 41 1.301 105.053 E94
+0 11 1 45 1.550 100.991 E94
+0 11 1 73 1.303 106.569 E94
+0 11 1 75 0.884 114.378 E94
+0 12 1 12 1.096 110.422 C94
+0 12 1 15 1.146 111.064 E94
+0 12 1 18 1.299 104.827 E94
+0 12 1 19 0.932 108.971 E94
+0 12 1 20 1.081 108.605 E94
+0 12 1 22 1.097 108.028 E94
+0 12 1 25 0.989 106.118 E94
+0 12 1 37 1.076 109.030 E94
+0 12 1 39 1.150 110.359 E94
+0 12 1 45 1.353 101.430 E94
+0 12 1 63 1.071 109.474 E94
+0 12 1 64 1.093 108.338 E94
+0 13 1 13 1.093 111.645 E94
+0 13 1 20 1.084 106.534 E94
+0 13 1 22 1.068 107.469 E94
+0 13 1 45 1.305 101.383 E94
+0 14 1 20 1.021 107.718 E94
+0 15 1 15 1.147 111.896 E94
+0 15 1 25 1.059 103.308 E94
+0 15 1 34 1.222 107.318 E94
+0 15 1 37 1.051 110.959 E94
+0 15 1 40 1.149 111.005 E94
+0 15 1 41 1.263 100.981 E94
+0 15 1 63 1.060 110.596 E94
+0 15 1 64 1.059 110.703 E94
+0 15 1 73 1.289 105.029 E94
+0 17 1 37 1.065 110.049 E94
+0 18 1 20 1.121 107.960 E94
+0 18 1 22 1.283 101.125 E94
+0 18 1 37 1.203 104.390 E94
+0 18 1 45 1.287 105.273 E94
+0 18 1 64 1.093 109.683 E94
+0 19 1 54 0.772 119.506 E94
+0 20 1 20 1.229 99.084 E94
+0 20 1 37 1.052 107.428 E94
+0 20 1 45 1.169 106.335 E94
+0 22 1 22 0.990 111.226 E94
+0 22 1 25 0.885 107.293 E94
+0 22 1 34 1.045 112.940 E94
+0 22 1 37 1.037 108.586 E94
+0 22 1 45 1.182 106.181 E94
+0 25 1 25 0.551 127.138 E94
+0 25 1 34 0.779 119.271 E94
+0 25 1 37 0.784 113.945 E94
+0 25 1 40 1.062 102.417 E94
+0 25 1 58 0.916 110.234 E94
+0 26 1 26 0.625 118.700 E94
+0 34 1 34 1.216 109.167 E94
+0 34 1 37 1.075 111.275 E94
+0 34 1 41 1.048 112.238 E94
+0 34 1 63 1.077 111.412 E94
+0 34 1 73 1.142 110.240 E94
+0 37 1 37 0.986 111.315 E94
+0 37 1 40 1.129 109.188 E94
+0 37 1 43 1.074 111.478 E94
+0 37 1 45 1.259 102.800 E94
+0 37 1 57 0.981 112.047 E94
+0 37 1 64 1.175 102.239 E94
+0 37 1 68 1.100 109.983 E94
+0 37 1 78 1.005 110.638 E94
+0 37 1 81 1.176 107.040 E94
+0 39 1 39 1.260 108.547 E94
+0 40 1 40 1.182 112.005 E94
+0 40 1 55 1.322 105.786 E94
+0 40 1 63 1.032 114.505 E94
+0 40 1 64 1.000 116.376 E94
+0 41 1 41 1.082 105.400 E94
+0 41 1 63 1.061 107.112 E94
+0 41 1 81 1.093 110.553 E94
+0 45 1 45 1.391 102.088 E94
+0 0 2 0 0.000 119.400 0:*-2-* MMFF94 DEF
+1 0 2 0 0.000 118.200 0:*-2-* MMFF94 DEF
+2 0 2 0 0.000 120.800 2::*-2-* MMFF94 DEF
+3 0 2 0 0.000 62.600 3::*-2-* MMFF94 DEF
+6 0 2 0 0.000 60.500 6:*-2-* MMFF94 DEF
+0 1 2 1 0.752 118.043 C94
+0 1 2 2 0.672 122.141 C94
+1 1 2 2 0.684 116.929 C94
+1 1 2 3 0.698 116.104 C94
+0 1 2 4 0.828 125.045 E94
+1 1 2 4 0.846 121.613 E94
+0 1 2 5 0.446 120.108 C94
+0 1 2 6 1.160 115.518 E94
+0 1 2 10 1.015 116.707 E94
+0 1 2 12 0.983 115.343 E94
+0 1 2 13 0.964 115.395 E94
+0 1 2 15 0.939 119.465 E94
+0 1 2 17 0.883 121.868 E94
+0 1 2 18 0.961 117.918 E94
+0 1 2 20 0.880 118.310 E94
+0 1 2 22 0.873 119.114 E94
+0 1 2 30 0.826 124.605 E94
+1 1 2 37 0.721 116.064 C94
+0 1 2 40 0.982 118.515 E94
+0 1 2 45 1.121 109.921 E94
+0 1 2 56 1.006 117.192 E94
+1 1 2 63 0.768 127.945 E94
+1 1 2 64 0.966 113.884 E94
+1 1 2 67 1.115 110.185 E94
+1 2 2 2 0.747 121.550 C94
+2 2 2 2 0.796 126.284 E94
+6 2 2 2 0.173 60.549 E94
+1 2 2 3 0.545 111.297 C94
+2 2 2 3 0.893 118.456 E94
+5 2 2 3 0.184 59.145 E94
+1 2 2 4 0.902 121.053 E94
+2 2 2 4 0.889 119.794 E94
+0 2 2 5 0.535 121.004 C94
+1 2 2 5 0.463 118.442 C94
+0 2 2 6 1.117 121.267 C94
+1 2 2 6 1.204 114.538 E94
+1 2 2 9 0.960 123.536 E94
+2 2 2 9 1.045 116.273 E94
+0 2 2 10 1.003 120.828 E94
+1 2 2 10 1.026 117.324 E94
+0 2 2 11 1.089 119.100 X94
+1 2 2 11 1.090 116.828 E94
+0 2 2 12 0.931 120.132 X94
+1 2 2 12 0.957 117.526 E94
+0 2 2 13 0.867 122.717 E94
+0 2 2 14 0.818 122.584 E94
+1 2 2 14 0.819 122.344 E94
+0 2 2 15 0.931 121.553 E94
+1 2 2 15 0.949 119.466 E94
+0 2 2 17 0.977 117.167 E94
+0 2 2 18 1.044 114.561 E94
+0 2 2 19 0.668 124.721 E94
+0 2 2 20 0.931 117.784 E94
+0 2 2 22 0.809 126.820 E94
+3 2 2 22 0.149 66.165 E94
+0 2 2 25 0.700 123.830 E94
+0 2 2 34 1.066 116.151 E94
+0 2 2 35 0.911 137.103 X94
+1 2 2 37 0.598 117.508 C94
+2 2 2 37 0.817 124.229 E94
+1 2 2 39 0.976 122.360 E94
+0 2 2 40 0.773 126.830 C94
+1 2 2 40 0.976 120.132 E94
+0 2 2 41 0.432 110.442 C94
+0 2 2 43 1.144 111.808 E94
+0 2 2 45 1.194 109.231 X94
+1 2 2 45 1.062 113.984 E94
+0 2 2 46 1.005 121.534 E94
+0 2 2 55 0.995 121.154 E94
+0 2 2 56 1.234 108.879 E94
+0 2 2 62 0.808 135.269 X94
+1 2 2 63 0.948 118.277 E94
+1 2 2 64 0.866 123.528 E94
+2 2 2 64 0.859 121.998 E94
+1 2 2 67 1.132 112.136 E94
+0 2 2 72 0.770 134.269 X94
+1 2 2 81 1.078 116.541 E94
+2 3 2 3 0.853 120.370 E94
+2 3 2 4 0.878 119.739 E94
+1 3 2 5 0.487 117.291 C94
+1 3 2 6 1.142 116.738 E94
+2 3 2 9 1.005 117.648 E94
+1 3 2 10 1.039 115.698 E94
+1 3 2 11 1.150 112.876 E94
+1 3 2 12 0.997 114.732 E94
+1 3 2 13 0.946 116.643 E94
+1 3 2 14 0.891 117.111 E94
+1 3 2 15 1.023 114.635 E94
+1 3 2 20 0.870 119.265 E94
+1 3 2 22 0.816 123.510 E94
+1 3 2 30 1.025 112.209 E94
+1 3 2 34 1.099 111.723 E94
+1 3 2 35 1.141 118.767 E94
+2 3 2 37 0.868 119.758 E94
+1 3 2 40 1.024 116.408 E94
+1 3 2 41 0.855 119.505 E94
+1 3 2 43 1.046 114.257 E94
+1 3 2 45 1.077 112.401 E94
+1 3 2 46 1.066 114.841 E94
+2 4 2 4 0.832 124.158 E94
+0 4 2 5 0.573 121.000 #E94
+1 4 2 5 0.545 120.000 #E94
+2 4 2 9 0.973 120.845 E94
+1 4 2 15 0.906 122.447 E94
+1 4 2 18 0.947 119.537 E94
+1 4 2 30 0.819 126.938 E94
+2 4 2 37 0.864 121.093 E94
+1 4 2 40 1.083 114.355 E94
+1 4 2 45 1.158 109.426 E94
+2 4 2 63 0.860 122.442 E94
+0 5 2 5 0.365 119.523 C94
+0 5 2 6 0.589 108.757 C94
+1 5 2 9 0.643 117.000 #E94
+0 5 2 10 0.667 114.859 E94
+0 5 2 11 0.795 108.186 X94
+0 5 2 12 0.622 110.650 X94
+0 5 2 13 0.566 113.513 E94
+0 5 2 15 0.546 119.562 E94
+0 5 2 17 0.492 124.000 #E94
+0 5 2 18 0.548 119.053 E94
+0 5 2 22 0.534 120.000 #E94
+0 5 2 25 0.395 124.000 #E94
+0 5 2 30 0.572 120.000 #E94
+0 5 2 35 0.682 124.164 X94
+1 5 2 37 0.491 117.423 C94
+1 5 2 39 0.655 115.724 E94
+0 5 2 40 0.568 112.322 C94
+0 5 2 41 0.294 123.706 C94
+0 5 2 45 0.728 107.774 X94
+0 5 2 55 0.651 116.000 #E94
+0 5 2 62 0.568 125.344 X94
+1 5 2 63 0.550 120.000 #E94
+1 5 2 64 0.546 120.000 #E94
+0 5 2 72 0.531 122.009 X94
+1 5 2 81 0.665 115.000 #E94
+1 6 2 9 1.214 120.520 E94
+0 6 2 10 1.311 115.921 E94
+0 6 2 22 1.080 120.560 E94
+0 6 2 35 1.172 132.391 E94
+1 6 2 37 1.198 114.441 E94
+0 6 2 40 1.239 119.073 E94
+0 6 2 45 1.637 102.438 E94
+1 9 2 10 1.098 119.802 E94
+1 9 2 15 0.915 127.574 E94
+2 9 2 37 0.981 119.536 E94
+1 9 2 40 0.922 130.521 E94
+0 10 2 12 1.144 112.723 E94
+0 10 2 15 1.078 117.519 E94
+0 10 2 25 1.144 100.818 E94
+1 10 2 37 1.021 117.139 E94
+0 10 2 40 0.988 126.034 E94
+0 10 2 41 0.951 120.000 E94
+0 12 2 12 1.012 119.105 E94
+0 12 2 17 1.110 114.206 E94
+0 12 2 18 1.201 110.553 E94
+0 12 2 19 0.704 126.646 E94
+0 12 2 20 0.903 120.563 E94
+0 12 2 30 0.892 122.753 E94
+1 12 2 37 0.976 116.136 E94
+0 12 2 45 1.076 115.543 E94
+0 13 2 18 1.132 113.616 E94
+0 15 2 15 0.996 123.027 E94
+0 15 2 35 0.950 133.654 E94
+1 15 2 37 1.007 115.757 E94
+0 15 2 40 0.895 128.924 E94
+0 17 2 17 1.051 117.955 E94
+1 18 2 37 1.183 106.608 E94
+0 22 2 22 0.841 122.108 E94
+3 22 2 22 0.180 58.963 E94
+1 22 2 37 0.806 124.693 E94
+1 30 2 37 0.849 123.816 E94
+1 35 2 37 0.991 128.032 E94
+0 40 2 40 0.949 128.436 E94
+0 40 2 56 1.072 120.987 E94
+1 40 2 63 0.922 124.268 E94
+1 40 2 64 0.955 121.881 E94
+0 40 2 72 0.820 135.317 E94
+0 45 2 45 1.284 108.095 E94
+2 64 2 64 0.888 120.342 E94
+0 0 3 0 0.000 117.300 0:*-3-* MMFF94 DEF
+1 0 3 0 0.000 115.800 1:*-3-* MMFF94 DEF
+4 0 3 0 0.000 90.800 4:*-3-* MMFF94 DEF
+7 0 3 0 0.000 91.100 7:*-3-* MMFF94 DEF
+8 0 3 0 0.000 88.900 7:*-3-* MMFF94 DEF
+0 1 3 1 1.151 118.016 C94
+1 1 3 2 1.106 116.853 C94
+1 1 3 3 1.214 114.612 C94
+0 1 3 5 0.808 117.280 C94
+0 1 3 6 1.043 109.716 C94
+0 1 3 7 0.938 124.410 C94
+0 1 3 9 0.978 119.788 E94
+1 1 3 9 1.038 115.132 E94
+0 1 3 10 0.984 112.735 C94
+0 1 3 12 1.007 113.972 E94
+0 1 3 15 1.024 113.612 E94
+0 1 3 16 0.949 119.986 E94
+0 1 3 18 0.732 134.097 E94
+0 1 3 20 0.830 120.312 E94
+0 1 3 22 0.928 115.001 E94
+0 1 3 35 1.058 122.808 E94
+1 1 3 37 1.051 115.191 C94
+1 1 3 39 1.178 107.895 E94
+0 1 3 40 0.979 118.457 E94
+0 1 3 41 0.897 116.681 E94
+0 1 3 43 1.046 113.731 X94
+0 1 3 45 1.132 109.019 E94
+0 1 3 51 1.160 116.573 X94
+0 1 3 53 1.052 115.065 X94
+0 1 3 54 1.135 111.322 E94
+1 1 3 58 1.162 108.129 E94
+0 1 3 62 1.119 111.523 E94
+1 1 3 63 0.909 117.001 E94
+1 1 3 64 0.887 118.253 E94
+0 1 3 67 1.142 110.666 E94
+0 1 3 74 1.010 116.851 X94
+0 1 3 75 0.646 128.037 X94
+2 2 3 2 0.976 112.562 E94
+6 2 3 2 0.157 62.792 E94
+2 2 3 3 0.957 113.239 E94
+1 2 3 5 0.901 115.350 C94
+1 2 3 6 0.932 106.510 C94
+1 2 3 7 0.936 122.623 C94
+1 2 3 9 0.831 122.253 C94
+2 2 3 9 1.120 111.408 E94
+1 2 3 10 1.042 111.721 C94
+1 2 3 12 0.901 120.769 E94
+1 2 3 15 1.057 112.105 E94
+1 2 3 16 0.881 124.850 E94
+1 2 3 22 0.969 113.027 E94
+1 2 3 25 0.853 109.794 E94
+2 2 3 37 0.973 112.935 E94
+2 2 3 39 1.197 107.592 E94
+1 2 3 40 0.910 123.437 E94
+1 2 3 43 1.105 111.169 E94
+1 2 3 53 1.082 114.032 E94
+1 2 3 54 1.012 118.588 E94
+1 2 3 55 1.186 107.278 E94
+1 2 3 56 1.151 108.909 E94
+2 2 3 63 0.918 116.947 E94
+2 2 3 64 1.033 110.084 E94
+1 2 3 67 1.022 117.597 E94
+2 3 3 3 0.822 121.775 E94
+8 3 3 3 1.280 89.965 E94
+1 3 3 5 0.943 113.762 C94
+1 3 3 6 0.935 103.030 C94
+1 3 3 7 0.919 117.024 C94
+1 3 3 9 1.050 115.704 E94
+1 3 3 10 1.129 110.421 E94
+1 3 3 12 1.053 111.492 E94
+1 3 3 15 1.390 97.562 E94
+1 3 3 16 1.092 111.888 E94
+1 3 3 20 0.977 110.910 E94
+1 3 3 22 1.010 110.295 E94
+8 3 3 30 1.353 87.789 E94
+2 3 3 37 0.932 114.949 E94
+2 3 3 39 1.237 105.384 E94
+1 3 3 40 1.003 117.124 E94
+1 3 3 41 0.790 124.361 E94
+1 3 3 45 0.919 121.023 E94
+1 3 3 53 1.170 109.169 E94
+2 3 3 63 0.981 112.685 E94
+2 3 3 64 0.880 118.840 E94
+1 3 3 67 1.119 111.860 E94
+1 4 3 6 1.269 111.750 E94
+1 4 3 7 1.126 120.852 E94
+1 4 3 9 1.192 109.833 E94
+2 4 3 37 0.964 114.081 E94
+0 5 3 5 0.594 116.699 C94
+0 5 3 6 0.819 108.253 C94
+0 5 3 7 0.670 123.439 C94
+0 5 3 9 0.623 119.491 C94
+1 5 3 9 0.638 117.168 E94
+0 5 3 10 0.874 111.761 C94
+0 5 3 16 0.522 124.405 E94
+1 5 3 37 0.564 116.400 E94
+0 5 3 40 0.959 111.684 C94
+0 5 3 53 0.644 118.000 #E94
+0 5 3 54 0.816 115.471 C94
+1 5 3 63 0.559 118.000 #E94
+1 5 3 64 0.566 117.000 #E94
+0 5 3 67 0.700 113.698 E94
+0 6 3 6 1.678 109.094 E94
+0 6 3 7 1.155 124.425 C94
+0 6 3 9 1.275 119.478 E94
+1 6 3 9 1.416 111.868 E94
+0 6 3 10 1.405 112.187 E94
+0 6 3 16 1.269 116.317 E94
+0 6 3 20 1.182 113.581 E94
+4 6 3 20 1.495 93.130 E94
+0 6 3 22 1.276 110.826 E94
+7 6 3 30 1.530 93.191 E94
+1 6 3 37 0.808 102.881 C94
+1 6 3 39 1.611 104.655 E94
+0 6 3 40 1.371 113.565 E94
+0 6 3 41 1.477 102.658 E94
+0 6 3 43 1.330 114.183 E94
+0 6 3 48 1.315 115.328 E94
+0 6 3 51 1.409 120.427 E94
+0 6 3 54 1.495 110.510 E94
+0 6 3 62 1.421 112.542 E94
+1 6 3 63 1.339 109.082 E94
+1 6 3 64 1.267 111.993 E94
+1 6 3 80 1.256 113.698 E94
+1 7 3 9 1.147 127.084 E94
+0 7 3 10 0.907 127.152 C94
+0 7 3 12 0.984 130.049 E94
+0 7 3 15 1.101 123.313 E94
+0 7 3 20 0.713 129.492 C94
+0 7 3 22 1.093 121.851 E94
+1 7 3 30 0.972 129.010 E94
+1 7 3 37 0.734 119.968 C94
+1 7 3 39 1.352 116.727 E94
+0 7 3 41 1.281 112.087 E94
+0 7 3 43 1.163 124.549 X94
+0 7 3 48 1.114 127.879 E94
+1 7 3 54 1.288 114.184 E94
+0 7 3 55 1.258 120.056 E94
+0 7 3 56 1.175 123.854 E94
+1 7 3 58 1.323 117.081 E94
+0 7 3 62 1.129 129.349 E94
+1 7 3 63 1.036 126.456 E94
+1 7 3 64 1.071 124.133 E94
+1 7 3 78 0.955 132.047 E94
+1 9 3 9 1.119 120.094 E94
+2 9 3 9 1.021 124.131 E94
+0 9 3 10 1.105 120.697 E94
+1 9 3 10 1.154 116.608 E94
+0 9 3 12 1.056 118.046 E94
+0 9 3 15 1.036 119.679 E94
+1 9 3 15 1.042 118.787 E94
+1 9 3 16 0.936 127.665 E94
+0 9 3 17 1.035 117.902 E94
+0 9 3 18 1.121 114.698 E94
+0 9 3 20 0.951 120.437 E94
+0 9 3 22 1.040 116.861 E94
+0 9 3 25 0.955 109.442 E94
+0 9 3 35 1.054 134.470 E94
+1 9 3 37 0.997 119.569 E94
+2 9 3 37 1.060 114.740 E94
+0 9 3 40 0.844 128.078 C94
+1 9 3 40 1.018 124.152 E94
+0 9 3 41 1.114 112.513 E94
+0 9 3 45 1.497 102.140 E94
+2 9 3 54 1.244 108.056 E94
+1 9 3 57 1.038 118.096 E94
+1 9 3 63 1.004 120.054 E94
+1 9 3 64 1.053 117.060 E94
+1 9 3 80 0.959 124.150 E94
+0 10 3 10 1.612 114.923 C94
+0 10 3 15 1.167 112.206 E94
+0 10 3 16 1.005 123.150 E94
+0 10 3 18 1.299 106.052 E94
+0 10 3 20 1.019 115.213 E94
+4 10 3 20 1.338 92.724 E94
+0 10 3 22 1.076 113.651 E94
+7 10 3 30 1.438 90.508 E94
+0 10 3 35 1.223 122.649 E94
+1 10 3 37 1.101 112.495 E94
+1 10 3 39 1.434 104.419 E94
+0 10 3 40 1.093 119.697 E94
+0 10 3 43 1.144 115.929 E94
+0 10 3 51 1.375 114.685 E94
+0 10 3 55 1.286 109.590 E94
+0 10 3 56 1.200 113.168 E94
+1 10 3 63 1.075 114.623 E94
+1 10 3 64 1.098 113.233 E94
+1 10 3 78 1.182 109.543 E94
+0 11 3 40 1.296 113.244 E94
+0 11 3 75 0.850 120.964 E94
+0 12 3 40 1.095 115.284 E94
+1 12 3 63 0.965 117.217 E94
+0 12 3 74 1.110 116.502 E94
+0 15 3 15 1.109 115.620 E94
+0 15 3 16 0.981 124.329 E94
+0 15 3 17 1.191 110.607 E94
+0 15 3 18 1.061 118.034 E94
+4 15 3 20 1.345 91.041 E94
+1 15 3 30 1.026 113.753 E94
+1 15 3 37 1.037 113.305 E94
+0 15 3 40 1.066 117.388 E94
+1 15 3 57 0.896 122.260 E94
+0 15 3 67 1.407 102.583 E94
+0 15 3 74 1.076 119.117 E94
+1 16 3 30 0.991 117.695 E94
+0 16 3 35 1.030 130.230 E94
+1 16 3 37 0.934 121.415 E94
+1 16 3 39 1.004 123.196 E94
+0 16 3 62 0.963 126.347 E94
+1 16 3 63 1.006 117.454 E94
+1 16 3 64 1.064 114.110 E94
+0 17 3 17 0.939 123.528 E94
+1 18 3 37 0.948 118.188 E94
+4 20 3 20 1.495 94.800 C94
+4 20 3 22 1.286 89.459 E94
+7 20 3 37 1.282 89.733 E94
+4 20 3 43 1.384 90.526 E94
+0 22 3 22 0.932 115.334 E94
+4 22 3 22 1.496 83.915 E94
+1 22 3 37 0.940 114.995 E94
+1 25 3 37 0.677 123.404 E94
+0 25 3 67 0.661 131.520 E94
+2 37 3 37 0.933 115.566 E94
+1 37 3 40 0.987 118.790 E94
+1 37 3 41 0.864 119.565 E94
+1 37 3 43 1.125 110.383 X94
+1 37 3 45 1.120 110.268 E94
+1 37 3 54 1.033 117.645 E94
+1 37 3 62 1.085 114.132 E94
+2 37 3 63 0.934 116.163 E94
+2 37 3 64 0.955 114.701 E94
+1 37 3 67 1.084 114.460 E94
+2 39 3 39 1.231 112.582 E94
+0 40 3 40 1.146 117.002 C94
+1 40 3 63 0.888 126.089 E94
+1 40 3 64 1.145 110.889 E94
+0 40 3 75 0.790 122.163 E94
+0 45 3 53 1.382 105.849 E94
+1 55 3 64 1.267 104.747 E94
+2 64 3 64 0.989 113.280 E94
+0 0 4 0 0.000 180.000 0:*-4-* MMFF94 DEF
+1 0 4 0 0.000 180.000 1:*-4-* MMFF94 DEF
+0 1 4 4 0.423 180.000 E94
+0 1 4 42 0.463 180.000 E94
+0 2 4 2 0.442 180.000 E94
+1 2 4 4 0.432 180.000 E94
+0 2 4 30 0.444 180.000 E94
+1 2 4 42 0.474 180.000 E94
+1 3 4 4 0.427 180.000 E94
+1 3 4 42 0.469 180.000 E94
+0 4 4 5 0.281 180.000 E94
+0 4 4 6 0.551 180.000 E94
+0 4 4 10 0.486 180.000 E94
+1 4 4 37 0.430 180.000 E94
+0 7 4 9 0.648 180.000 E94
+1 9 4 42 0.537 180.000 E94
+0 15 4 42 0.487 180.000 E94
+0 20 4 42 0.469 180.000 E94
+0 22 4 42 0.472 180.000 E94
+1 37 4 42 0.472 180.000 E94
+0 42 4 43 0.541 180.000 E94
+1 42 4 63 0.474 180.000 E94
+1 42 4 64 0.473 180.000 E94
+0 0 6 0 0.000 110.400 0:*-6-* MMFF94 DEF
+3 0 6 0 0.000 57.900 3::*-6-* MMFF94 DEF
+4 0 6 0 0.000 90.200 4:*-6-* MMFF94 DEF
+0 1 6 1 1.197 106.926 C94
+0 1 6 2 0.967 103.614 C94
+0 1 6 3 0.923 108.055 C94
+0 1 6 6 1.884 103.905 E94
+0 1 6 8 1.629 105.422 E94
+0 1 6 9 1.628 106.496 E94
+0 1 6 10 1.656 105.317 E94
+0 1 6 15 1.480 111.230 E94
+0 1 6 17 1.493 111.951 E94
+0 1 6 18 1.370 116.346 E94
+0 1 6 19 1.093 114.943 E94
+0 1 6 20 1.316 112.833 E94
+0 1 6 21 0.793 106.503 C94
+0 1 6 22 1.391 109.759 E94
+0 1 6 25 1.095 115.581 X94
+0 1 6 26 1.170 112.081 E94
+0 1 6 37 1.075 102.846 C94
+0 1 6 40 1.719 103.733 E94
+0 1 6 41 1.454 109.046 E94
+0 1 6 43 1.642 105.462 E94
+0 1 6 45 1.642 105.875 X94
+0 1 6 63 1.449 109.545 E94
+0 1 6 64 1.512 106.848 E94
+0 2 6 2 1.354 113.339 E94
+0 2 6 3 0.671 98.438 C94
+0 2 6 18 1.365 117.169 E94
+0 2 6 25 1.025 120.078 E94
+0 2 6 29 0.816 105.727 C94
+0 2 6 37 1.418 110.694 E94
+0 2 6 57 1.341 114.785 E94
+0 3 6 3 1.455 110.067 E94
+0 3 6 4 1.409 112.404 E94
+0 3 6 8 1.648 105.872 E94
+0 3 6 10 1.596 108.437 E94
+0 3 6 18 1.274 121.468 E94
+0 3 6 19 1.019 119.840 E94
+0 3 6 20 1.379 111.381 E94
+4 3 6 20 1.748 91.216 E94
+0 3 6 22 1.328 113.491 E94
+0 3 6 24 0.583 111.948 C94
+0 3 6 25 1.006 121.410 E94
+0 3 6 29 0.876 111.417 E94
+0 3 6 37 0.614 95.300 C94
+0 3 6 64 1.424 111.483 E94
+0 4 6 18 1.423 115.233 E94
+0 6 6 21 1.362 95.697 E94
+0 8 6 21 0.832 99.409 C94
+0 9 6 21 1.115 101.592 E94
+0 10 6 21 0.923 99.688 C94
+0 18 6 18 1.334 125.242 E94
+0 18 6 33 0.812 115.364 X94
+0 18 6 37 1.429 114.473 E94
+0 18 6 39 1.558 114.152 E94
+0 18 6 43 1.710 108.479 E94
+0 19 6 19 0.642 141.096 E94
+0 19 6 21 0.597 118.204 X94
+0 19 6 37 0.941 124.421 E94
+4 20 6 20 1.339 89.100 C94
+0 20 6 21 0.944 104.587 E94
+0 20 6 37 1.394 110.394 E94
+0 21 6 40 1.124 101.417 E94
+0 21 6 43 1.058 103.253 E94
+0 21 6 54 1.175 100.000 #E94
+0 21 6 55 1.139 101.000 #E94
+3 22 6 22 0.242 58.680 E94
+3 22 6 43 0.279 57.087 E94
+0 24 6 25 0.607 118.533 X94
+0 25 6 25 0.777 129.375 E94
+0 25 6 37 1.099 115.923 E94
+0 26 6 37 1.090 116.692 E94
+0 29 6 30 0.986 108.000 #E94
+0 29 6 37 0.726 105.409 C94
+0 29 6 64 0.923 108.922 E94
+0 37 6 37 1.462 108.967 E94
+0 37 6 58 1.607 108.274 E94
+0 0 8 0 0.000 110.400 0:*-8-* MMFF94 DEF
+3 0 8 0 0.000 58.500 3::*-8-* MMFF94 DEF
+4 0 8 0 0.000 95.000 4:*-8-* MMFF94 DEF
+0 1 8 1 1.090 107.018 C94
+0 1 8 6 1.297 102.829 C94
+0 1 8 8 1.347 105.708 E94
+0 1 8 9 1.182 114.240 E94
+0 1 8 10 1.307 108.079 E94
+0 1 8 15 1.085 118.283 E94
+0 1 8 17 1.096 117.478 E94
+0 1 8 19 0.779 122.759 E94
+0 1 8 20 1.221 105.873 E94
+0 1 8 22 1.147 109.200 E94
+0 1 8 23 0.763 109.062 C94
+0 1 8 25 0.865 117.482 E94
+0 1 8 26 0.926 112.630 E94
+0 1 8 40 1.363 105.609 E94
+0 1 8 45 1.266 110.149 E94
+0 1 8 46 1.265 111.092 E94
+0 6 8 6 1.776 107.296 E94
+0 6 8 17 1.664 105.334 E94
+0 6 8 22 1.456 107.100 E94
+0 6 8 23 0.861 100.510 C94
+3 8 8 8 0.230 60.000 E94
+0 8 8 23 0.792 108.917 E94
+0 8 8 25 1.068 110.595 E94
+0 8 8 26 1.047 110.816 E94
+0 9 8 23 0.832 108.864 E94
+4 10 8 20 1.805 84.690 E94
+0 10 8 23 0.846 106.788 E94
+0 12 8 22 1.227 107.439 E94
+0 15 8 19 0.845 125.674 E94
+4 17 8 17 1.198 110.056 E94
+0 17 8 23 0.647 116.842 E94
+0 19 8 23 0.542 112.000 #E94
+4 20 8 20 1.103 90.370 C94
+0 20 8 23 0.684 113.359 C94
+3 22 8 22 0.209 57.087 E94
+0 22 8 23 0.697 110.033 E94
+0 22 8 25 0.896 115.361 E94
+0 23 8 23 0.595 105.998 C94
+0 23 8 25 0.510 117.000 #E94
+0 23 8 26 0.553 110.959 E94
+0 23 8 34 0.808 109.000 #E94
+0 23 8 39 0.757 111.820 E94
+0 23 8 40 0.819 108.120 E94
+0 23 8 43 0.857 106.222 E94
+0 23 8 55 0.868 106.000 #E94
+0 23 8 56 0.876 105.092 E94
+0 0 9 0 0.000 111.500 0:*-9-* MMFF94 DEF
+1 0 9 0 0.000 109.100 1:*-9-* MMFF94 DEF
+0 1 9 3 0.878 106.409 C94
+0 1 9 9 1.306 110.005 E94
+0 1 9 53 1.216 113.995 X94
+0 1 9 67 1.391 106.413 E94
+1 2 9 3 1.242 109.856 E94
+1 2 9 9 1.306 112.528 E94
+1 3 9 3 1.204 111.488 E94
+1 3 9 4 1.194 113.272 E94
+0 3 9 6 1.579 106.872 E94
+0 3 9 8 1.386 108.822 E94
+1 3 9 9 1.390 108.355 E94
+0 3 9 10 1.365 109.548 E94
+0 3 9 12 1.373 103.303 E94
+0 3 9 15 1.265 110.780 E94
+0 3 9 18 1.205 114.743 E94
+0 3 9 20 1.198 109.751 E94
+0 3 9 25 0.873 119.927 E94
+0 3 9 27 0.818 108.779 C94
+0 3 9 34 1.355 108.199 E94
+0 3 9 35 1.511 109.907 E94
+1 3 9 37 1.185 111.663 E94
+1 3 9 39 1.396 108.538 E94
+0 3 9 40 1.365 109.440 E94
+0 3 9 41 1.169 112.551 E94
+0 3 9 45 1.369 109.796 E94
+1 3 9 53 1.351 110.578 E94
+1 3 9 54 1.643 98.943 E94
+0 3 9 55 1.431 106.195 E94
+0 3 9 56 1.375 109.289 E94
+1 3 9 57 1.125 115.780 E94
+1 3 9 63 1.247 109.989 E94
+1 3 9 64 1.302 106.461 E94
+1 3 9 78 1.323 106.641 E94
+1 3 9 81 1.567 101.581 E94
+0 4 9 19 0.456 161.741 E94
+1 4 9 67 1.402 108.868 E94
+0 6 9 67 1.794 105.043 E94
+0 9 9 10 1.518 109.154 E94
+1 9 9 37 1.397 108.014 E94
+0 9 9 40 1.594 106.413 E94
+0 9 9 62 1.390 114.417 E94
+1 9 9 63 1.320 112.325 E94
+1 9 9 64 1.352 109.711 E94
+1 37 9 53 1.343 110.162 E94
+1 37 9 67 1.296 111.871 E94
+0 40 9 67 1.538 108.056 E94
+1 53 9 64 1.318 111.149 E94
+0 0 10 0 0.000 117.500 0:*-10-* MMFF94 DEF
+3 0 10 0 0.000 58.900 3::*-10-* MMFF94 DEF
+4 0 10 0 0.000 92.900 4:*-10-* MMFF94 DEF
+0 1 10 1 1.117 117.909 C94
+0 1 10 2 1.004 118.916 E94
+0 1 10 3 0.821 119.600 C94
+0 1 10 6 1.179 108.865 C94
+0 1 10 8 1.137 116.189 E94
+0 1 10 9 1.132 117.005 E94
+0 1 10 10 1.247 111.009 E94
+0 1 10 17 1.014 122.388 E94
+0 1 10 20 0.960 119.679 E94
+0 1 10 25 0.745 125.390 E94
+0 1 10 28 0.552 120.066 C94
+0 1 10 37 1.038 116.332 E94
+0 1 10 39 1.060 120.838 E94
+0 1 10 40 1.194 113.314 E94
+0 1 10 41 1.031 118.033 E94
+0 1 10 45 1.268 109.599 E94
+0 1 10 63 0.949 122.185 E94
+0 1 10 64 0.960 121.315 E94
+0 2 10 2 1.146 112.878 E94
+0 2 10 3 1.000 120.703 E94
+0 2 10 6 1.405 111.609 E94
+0 2 10 20 1.132 111.544 E94
+0 2 10 28 0.638 118.553 E94
+0 2 10 37 0.977 121.506 E94
+0 3 10 3 0.709 120.274 C94
+0 3 10 4 0.864 130.236 E94
+0 3 10 6 0.960 110.133 C94
+0 3 10 8 1.168 116.075 E94
+4 3 10 8 1.527 93.608 E94
+0 3 10 9 1.174 116.443 E94
+0 3 10 10 1.184 115.377 E94
+0 3 10 13 0.998 118.867 E94
+0 3 10 14 0.871 124.162 E94
+0 3 10 15 1.076 118.969 E94
+0 3 10 17 1.132 116.612 E94
+0 3 10 20 0.936 122.540 E94
+4 3 10 20 1.371 93.349 E94
+0 3 10 22 0.975 120.929 E94
+0 3 10 25 0.794 122.157 E94
+0 3 10 26 0.848 117.912 E94
+0 3 10 28 0.575 120.277 C94
+0 3 10 34 1.251 112.201 E94
+0 3 10 35 1.395 112.633 E94
+0 3 10 37 1.023 118.596 E94
+0 3 10 40 1.216 113.680 E94
+0 3 10 41 1.098 115.913 E94
+0 3 10 45 1.212 113.447 E94
+0 3 10 63 1.091 115.381 E94
+0 3 10 64 1.048 117.574 E94
+0 4 10 20 0.816 131.702 E94
+0 6 10 28 0.829 113.214 E94
+0 6 10 37 1.393 111.476 E94
+0 8 10 28 0.703 117.160 E94
+0 8 10 37 1.167 115.599 E94
+0 9 10 26 0.847 123.206 E94
+0 9 10 28 0.751 114.501 E94
+0 9 10 37 1.222 113.553 E94
+0 9 10 39 1.310 115.309 E94
+0 10 10 28 0.735 114.715 E94
+0 10 10 41 1.237 113.743 E94
+0 15 10 28 0.614 119.033 E94
+4 20 10 20 1.381 91.694 E94
+0 20 10 28 0.555 123.394 E94
+0 20 10 37 1.006 117.703 E94
+3 22 10 22 0.202 58.894 E94
+0 22 10 28 0.605 119.583 E94
+0 25 10 28 0.447 122.785 E94
+0 28 10 28 0.435 115.630 C94
+0 28 10 34 0.757 113.000 #E94
+0 28 10 35 0.836 114.000 #E94
+0 28 10 37 0.628 118.227 E94
+0 28 10 40 0.754 113.000 #E94
+0 28 10 41 0.560 128.067 E94
+0 28 10 63 0.640 118.099 E94
+0 28 10 64 0.643 117.575 E94
+0 37 10 40 1.232 112.412 E94
+0 0 15 0 0.000 97.900 0:*-15-* MMFF94 DEF
+4 0 15 0 0.000 80.200 4:*-15-* MMFF94 DEF
+0 1 15 1 1.654 97.335 C94
+0 1 15 2 1.321 97.853 E94
+0 1 15 3 1.325 97.326 E94
+0 1 15 4 1.344 97.370 E94
+0 1 15 9 1.725 89.814 E94
+0 1 15 15 1.377 100.316 C94
+0 1 15 18 1.309 101.641 E94
+0 1 15 19 1.007 102.069 E94
+0 1 15 20 1.366 94.913 E94
+0 1 15 22 1.268 99.768 E94
+0 1 15 25 0.967 104.732 E94
+0 1 15 30 1.379 95.613 E94
+0 1 15 37 1.439 97.111 C94
+0 1 15 40 1.555 94.643 E94
+0 1 15 57 1.301 98.686 E94
+0 1 15 63 1.304 98.330 E94
+0 1 15 64 1.306 98.066 E94
+0 1 15 71 0.931 96.494 C94
+0 2 15 2 1.434 95.108 E94
+0 2 15 3 1.318 98.813 E94
+0 2 15 4 1.426 95.780 E94
+0 2 15 15 1.457 97.789 E94
+0 2 15 37 1.362 96.942 E94
+0 2 15 43 1.709 90.872 E94
+0 3 15 3 1.402 95.424 E94
+0 3 15 6 1.804 94.075 E94
+0 3 15 15 1.403 99.399 E94
+4 3 15 20 1.666 79.842 E94
+0 3 15 37 1.308 98.541 E94
+0 3 15 63 1.390 96.051 E94
+0 3 15 71 0.830 97.000 #E94
+0 6 15 37 1.679 97.231 E94
+0 8 15 8 1.444 105.143 E94
+0 8 15 37 1.446 98.976 E94
+0 9 15 9 1.626 98.524 E94
+0 9 15 64 1.504 97.105 E94
+0 10 15 15 1.415 103.715 E94
+0 12 15 37 1.428 97.534 E94
+0 15 15 15 1.413 104.893 E94
+0 15 15 18 1.563 99.173 E94
+0 15 15 37 1.361 100.790 E94
+0 15 15 64 1.332 102.040 E94
+0 15 15 71 0.787 99.239 C94
+4 20 15 30 1.978 73.428 E94
+0 20 15 37 1.361 95.589 E94
+0 25 15 25 0.947 99.505 E94
+4 25 15 25 1.030 87.982 E94
+0 25 15 26 1.002 96.851 E94
+0 25 15 37 1.172 95.428 E94
+0 26 15 37 1.144 96.710 E94
+4 30 15 30 1.732 79.546 E94
+0 37 15 37 1.295 98.802 E94
+0 37 15 63 1.379 96.197 E94
+0 37 15 64 1.286 99.423 E94
+0 37 15 71 0.813 96.222 C94
+0 71 15 71 0.734 93.377 C94
+0 0 17 0 0.000 99.400 0:*-17-* MMFF94 DEF
+4 0 17 0 0.000 78.400 4:*-17-* MMFF94 DEF
+0 1 17 1 1.415 93.266 X94
+0 1 17 2 1.387 94.732 E94
+0 1 17 3 1.430 92.852 E94
+0 1 17 6 1.863 92.132 E94
+0 1 17 7 1.408 107.104 X94
+0 1 17 8 1.661 91.498 E94
+0 1 17 10 1.547 94.839 E94
+0 1 17 20 1.453 91.368 E94
+0 1 17 22 1.423 92.591 E94
+0 1 17 37 1.376 94.911 E94
+0 2 17 2 1.313 97.901 E94
+0 2 17 7 1.478 105.412 E94
+0 2 17 43 1.207 108.882 E94
+0 3 17 7 1.513 103.431 E94
+0 6 17 6 2.164 97.766 E94
+0 6 17 7 1.850 107.431 E94
+0 7 17 8 1.438 113.808 E94
+0 7 17 10 1.525 110.549 E94
+0 7 17 20 1.442 104.737 E94
+0 7 17 22 1.449 104.928 E94
+0 7 17 37 1.500 104.313 E94
+4 8 17 20 1.891 78.354 E94
+0 8 17 37 1.687 91.169 E94
+0 37 17 37 1.487 91.633 E94
+0 0 18 0 0.000 104.600 0:*-18-* MMFF94 DEF
+4 0 18 0 0.000 80.300 4:*-18-* MMFF94 DEF
+0 1 18 1 1.230 101.166 X94
+0 1 18 2 1.264 100.420 E94
+0 1 18 3 1.242 100.883 E94
+0 1 18 6 1.744 95.671 X94
+0 1 18 9 1.438 99.465 E94
+0 1 18 20 1.224 101.315 E94
+0 1 18 22 1.207 101.417 E94
+0 1 18 32 1.446 107.066 X94
+0 1 18 37 1.234 101.070 E94
+0 1 18 43 1.449 98.014 X94
+0 1 18 48 1.277 106.586 X94
+0 1 18 62 1.374 102.402 X94
+0 2 18 2 1.254 101.492 E94
+0 2 18 6 1.664 98.668 E94
+0 2 18 9 1.539 96.849 E94
+0 2 18 32 1.422 108.979 E94
+0 2 18 37 1.263 100.489 E94
+0 2 18 48 1.083 116.668 E94
+0 3 18 9 1.418 100.361 E94
+0 3 18 32 1.557 103.453 E94
+0 3 18 43 1.350 101.747 E94
+0 6 18 6 1.922 103.052 X94
+0 6 18 9 1.916 97.446 E94
+0 6 18 32 1.837 108.063 X94
+0 6 18 37 1.528 102.229 E94
+0 6 18 43 1.644 103.815 E94
+0 9 18 12 1.464 101.180 E94
+0 9 18 32 1.583 109.945 E94
+0 9 18 37 1.358 102.378 E94
+0 9 18 43 1.323 109.227 E94
+0 12 18 32 1.584 103.959 E94
+0 12 18 37 1.376 98.976 E94
+0 15 18 32 1.497 107.170 E94
+0 15 18 37 1.324 101.399 E94
+0 20 18 32 1.383 109.292 E94
+0 20 18 37 1.108 106.508 E94
+4 20 18 43 1.831 80.297 E94
+0 22 18 32 1.465 105.247 E94
+0 32 18 32 1.569 120.924 X94
+0 32 18 37 1.497 105.280 X94
+0 32 18 39 1.804 101.600 X94
+0 32 18 43 1.569 108.548 X94
+0 32 18 48 1.229 126.841 X94
+0 32 18 55 1.509 112.548 E94
+0 32 18 58 1.592 106.139 E94
+0 32 18 62 1.326 121.426 X94
+0 32 18 63 1.571 103.212 E94
+0 32 18 64 1.634 101.771 E94
+0 32 18 80 1.400 110.401 E94
+0 37 18 37 1.157 104.380 E94
+0 37 18 39 1.404 99.854 X94
+0 37 18 43 1.416 99.200 X94
+0 37 18 48 1.330 104.466 E94
+0 37 18 55 1.397 100.926 E94
+0 37 18 62 1.178 110.665 E94
+0 37 18 63 1.202 102.735 E94
+0 43 18 43 1.545 99.905 X94
+0 43 18 64 1.285 104.868 E94
+0 0 19 0 0.000 108.700 0:*-19-* MMFF94 DEF
+4 0 19 0 0.000 89.900 4:*-19-* MMFF94 DEF
+0 1 19 1 0.616 113.339 E94
+0 1 19 5 0.390 110.795 X94
+0 1 19 6 0.777 113.958 X94
+0 1 19 8 0.716 111.521 E94
+0 1 19 9 0.779 106.380 E94
+0 1 19 12 0.729 108.947 X94
+0 1 19 20 0.656 108.828 E94
+0 1 19 40 0.754 108.858 E94
+0 1 19 63 0.699 106.924 E94
+0 1 19 75 0.530 111.633 E94
+0 2 19 12 0.819 102.981 E94
+0 5 19 5 0.258 108.699 X94
+0 5 19 6 0.520 109.677 X94
+0 5 19 8 0.461 109.070 E94
+0 5 19 12 0.446 106.756 X94
+0 6 19 6 1.051 111.280 E94
+0 6 19 12 0.968 106.022 E94
+0 6 19 37 0.870 108.096 E94
+0 8 19 8 0.862 108.099 E94
+0 8 19 12 0.786 110.683 E94
+0 12 19 12 0.879 104.597 E94
+0 15 19 15 0.816 108.681 E94
+4 20 19 20 0.802 89.931 E94
+0 37 19 37 0.726 105.045 E94
+0 0 20 0 0.000 113.200 0:*-20-* MMFF94 DEF
+4 0 20 0 0.000 88.800 4:*-20-* MMFF94 DEF
+0 1 20 1 0.943 113.131 E94
+0 1 20 3 0.906 114.940 E94
+0 1 20 5 0.417 114.057 C94
+0 1 20 6 1.231 110.677 E94
+0 1 20 8 1.080 111.090 E94
+0 1 20 10 1.100 110.057 E94
+0 1 20 11 1.173 110.993 E94
+0 1 20 12 0.976 114.773 E94
+0 1 20 15 1.035 111.226 E94
+0 1 20 18 0.978 115.383 E94
+0 1 20 20 0.502 113.313 C94
+0 1 20 22 0.915 115.201 E94
+0 1 20 25 0.744 116.096 E94
+0 1 20 26 0.721 117.611 E94
+0 1 20 30 0.908 115.220 E94
+0 1 20 34 1.090 110.505 E94
+0 1 20 37 0.947 112.650 E94
+0 1 20 41 0.973 111.787 E94
+0 1 20 43 1.087 110.187 E94
+0 1 20 45 1.132 108.074 E94
+0 2 20 3 0.982 111.060 E94
+0 2 20 5 0.596 113.035 E94
+0 2 20 6 1.139 115.851 E94
+0 2 20 12 0.951 116.750 E94
+0 2 20 20 0.931 114.138 E94
+0 3 20 3 0.982 109.919 E94
+0 3 20 5 0.624 112.989 C94
+0 3 20 6 1.157 113.611 E94
+4 3 20 8 1.473 87.271 E94
+0 3 20 10 1.016 113.988 E94
+0 3 20 11 1.184 109.849 E94
+0 3 20 12 0.969 114.891 E94
+0 3 20 13 1.008 110.951 E94
+0 3 20 20 0.849 118.273 E94
+4 3 20 20 1.524 88.961 C94
+0 3 20 34 1.137 107.667 E94
+4 3 20 37 1.382 85.619 E94
+0 3 20 43 0.960 116.707 E94
+0 4 20 5 0.584 115.078 E94
+0 4 20 20 0.920 115.312 E94
+0 5 20 5 0.439 109.107 C94
+0 5 20 6 0.818 111.352 C94
+0 5 20 8 0.728 114.011 C94
+0 5 20 9 0.657 112.826 E94
+0 5 20 10 0.663 112.010 E94
+0 5 20 12 0.339 114.117 C94
+0 5 20 15 0.562 114.339 E94
+0 5 20 17 0.561 113.000 #E94
+0 5 20 18 0.605 111.570 E94
+0 5 20 20 0.564 113.940 C94
+0 5 20 26 0.472 109.722 E94
+0 5 20 30 0.688 116.038 C94
+0 5 20 34 0.661 112.000 #E94
+0 5 20 37 0.552 115.670 E94
+0 5 20 40 0.682 111.331 E94
+0 5 20 43 0.655 111.686 E94
+0 6 20 6 1.443 114.408 E94
+0 6 20 10 1.225 116.666 E94
+0 6 20 13 1.162 114.868 E94
+0 6 20 20 1.109 116.117 E94
+4 6 20 20 1.433 93.413 C94
+0 6 20 22 1.106 117.205 E94
+0 6 20 30 1.144 114.705 E94
+4 6 20 30 1.658 87.873 E94
+0 8 20 20 1.185 105.606 E94
+4 8 20 20 1.486 91.244 C94
+0 8 20 26 0.874 111.782 E94
+0 9 20 20 1.103 109.640 E94
+0 10 20 15 1.170 109.525 E94
+0 10 20 17 1.127 110.564 E94
+0 10 20 18 1.404 100.845 E94
+0 10 20 20 1.032 113.170 E94
+4 10 20 20 1.468 87.497 E94
+4 10 20 30 1.507 86.657 E94
+0 10 20 37 0.963 117.360 E94
+0 11 20 11 1.504 108.020 E94
+0 11 20 17 1.221 109.460 E94
+0 11 20 20 1.051 116.673 E94
+0 11 20 30 0.997 120.309 E94
+0 12 20 12 1.020 117.603 E94
+0 12 20 19 0.973 105.821 E94
+0 12 20 20 0.866 118.108 C94
+0 12 20 30 0.887 120.399 E94
+0 13 20 13 1.077 113.361 E94
+0 13 20 20 0.938 115.037 E94
+0 14 20 20 0.837 112.888 E94
+0 15 20 15 1.094 114.048 E94
+0 15 20 20 1.058 109.793 E94
+4 15 20 20 1.324 90.483 E94
+0 15 20 30 0.960 115.468 E94
+4 15 20 30 1.447 86.726 E94
+4 17 20 17 1.309 94.977 E94
+0 17 20 20 0.930 116.108 E94
+0 18 20 20 1.007 113.480 E94
+4 18 20 20 1.355 90.185 E94
+0 18 20 41 1.241 102.656 E94
+0 19 20 19 0.567 122.298 E94
+4 19 20 19 0.921 88.477 E94
+0 20 20 20 1.008 108.644 E94
+4 20 20 20 1.149 90.294 C94
+0 20 20 22 0.840 119.817 E94
+4 20 20 22 1.364 86.669 E94
+4 20 20 25 1.181 84.818 E94
+0 20 20 30 0.994 109.745 E94
+4 20 20 30 1.399 85.303 C94
+0 20 20 34 1.069 111.143 E94
+4 20 20 34 1.382 90.128 E94
+0 20 20 37 0.833 119.709 E94
+4 20 20 37 1.346 86.810 E94
+0 20 20 40 1.097 110.254 E94
+0 20 20 41 0.922 114.408 E94
+0 20 20 43 0.964 116.540 E94
+4 20 20 43 1.290 92.879 E94
+0 20 20 45 1.083 110.090 E94
+0 22 20 22 0.866 118.829 E94
+4 22 20 22 1.649 79.399 E94
+4 26 20 26 0.789 96.811 E94
+0 26 20 34 0.843 113.805 E94
+0 34 20 41 1.070 111.943 E94
+0 37 20 43 0.954 117.365 E94
+0 0 22 0 0.000 116.100 0:*-22-* MMFF94 DEF
+3 0 22 0 0.000 59.400 3::*-22-* MMFF94 DEF
+4 0 22 0 0.000 91.600 4:*-22-* MMFF94 DEF
+0 1 22 1 0.903 116.483 E94
+0 1 22 2 0.884 118.360 E94
+0 1 22 3 0.836 121.424 E94
+0 1 22 4 0.900 117.720 E94
+0 1 22 5 0.604 111.788 E94
+0 1 22 6 1.179 113.545 E94
+0 1 22 8 0.973 117.469 E94
+0 1 22 17 1.070 109.087 E94
+0 1 22 18 1.097 108.265 E94
+0 1 22 22 0.871 118.246 E94
+0 1 22 37 0.882 118.041 E94
+0 1 22 43 1.014 114.899 E94
+3 2 22 2 0.263 48.820 E94
+0 2 22 3 0.956 114.147 E94
+0 2 22 4 0.784 126.957 E94
+0 2 22 5 0.573 115.869 E94
+0 2 22 6 1.012 123.319 E94
+0 2 22 22 0.880 118.260 E94
+3 2 22 22 0.166 60.845 E94
+0 2 22 45 1.009 116.146 E94
+0 3 22 3 0.819 122.977 E94
+0 3 22 4 0.876 119.718 E94
+0 3 22 5 0.559 116.738 E94
+0 3 22 6 1.184 113.646 E94
+0 3 22 8 1.072 112.261 E94
+0 3 22 10 0.987 117.750 E94
+0 3 22 12 0.930 118.047 E94
+4 3 22 20 1.267 90.869 E94
+0 3 22 22 0.861 119.252 E94
+4 3 22 22 1.196 93.287 E94
+4 3 22 30 1.301 89.217 E94
+0 3 22 37 0.852 120.464 E94
+0 3 22 40 1.033 114.288 E94
+0 3 22 43 1.124 109.441 E94
+0 3 22 45 1.117 110.033 E94
+0 4 22 5 0.560 118.000 #E94
+0 4 22 6 1.200 113.650 E94
+0 4 22 8 0.966 119.034 E94
+0 4 22 15 0.931 120.455 E94
+0 4 22 22 0.877 118.890 E94
+0 4 22 45 1.089 112.227 E94
+0 5 22 5 0.242 114.938 C94
+0 5 22 6 0.683 117.836 E94
+0 5 22 8 0.621 115.758 E94
+0 5 22 10 0.658 113.806 E94
+0 5 22 11 0.776 108.296 X94
+0 5 22 12 0.620 109.865 X94
+0 5 22 20 0.623 110.000 #E94
+0 5 22 22 0.583 117.875 C94
+0 5 22 37 0.532 119.438 E94
+0 5 22 40 0.653 112.855 E94
+0 5 22 41 0.519 122.000 #E94
+0 5 22 43 0.658 112.128 E94
+0 5 22 45 0.665 112.000 #E94
+0 6 22 12 1.136 118.409 E94
+0 6 22 17 1.328 108.583 E94
+0 6 22 18 1.381 107.009 E94
+0 6 22 22 1.124 115.942 E94
+3 6 22 22 0.205 60.711 E94
+0 6 22 37 1.093 118.170 E94
+3 6 22 43 0.179 68.138 E94
+0 6 22 45 1.422 108.368 E94
+0 8 22 22 0.925 120.144 E94
+3 8 22 22 0.176 61.507 E94
+0 10 22 22 0.916 121.411 E94
+3 10 22 22 0.184 60.603 E94
+0 11 22 11 1.610 102.859 E94
+0 11 22 22 1.062 116.086 X94
+0 12 22 12 1.067 114.988 E94
+0 12 22 22 0.925 117.971 X94
+0 13 22 13 1.085 113.473 E94
+0 13 22 22 0.908 117.606 E94
+0 15 22 22 0.918 120.404 E94
+0 17 22 22 1.029 111.106 E94
+0 18 22 22 1.078 109.054 E94
+0 20 22 22 0.812 122.430 E94
+4 20 22 22 1.198 92.930 E94
+0 22 22 22 0.787 124.070 E94
+3 22 22 22 0.171 60.000 C94
+4 22 22 22 1.225 91.653 E94
+0 22 22 30 0.777 124.514 E94
+0 22 22 34 0.983 116.415 E94
+0 22 22 37 0.847 120.135 E94
+3 22 22 40 0.178 61.163 E94
+0 22 22 41 0.886 118.045 E94
+3 22 22 43 0.176 61.536 E94
+0 22 22 45 1.022 114.380 E94
+0 34 22 41 1.008 116.095 E94
+0 37 22 37 0.846 120.774 E94
+3 37 22 37 0.237 51.029 E94
+0 37 22 43 0.936 119.789 E94
+0 0 25 0 0.000 106.500 0:*-25-* MMFF94 DEF
+4 0 25 0 0.000 89.100 4:*-25-* MMFF94 DEF
+0 1 25 1 1.072 99.158 X94
+0 1 25 3 1.268 91.423 E94
+0 1 25 6 1.394 98.288 X94
+0 1 25 8 1.150 101.775 E94
+0 1 25 12 1.180 98.890 E94
+0 1 25 15 1.074 103.431 E94
+0 1 25 25 0.852 100.707 E94
+0 1 25 32 1.186 107.891 X94
+0 1 25 37 0.972 104.924 E94
+0 1 25 40 1.358 93.644 E94
+0 1 25 43 1.190 98.760 X94
+0 1 25 71 0.537 109.363 E94
+0 1 25 72 0.976 111.306 X94
+0 2 25 6 1.302 102.892 E94
+0 2 25 8 1.022 109.148 E94
+0 2 25 10 1.629 85.839 E94
+0 2 25 32 0.983 120.127 E94
+0 2 25 72 0.863 119.249 E94
+0 3 25 6 1.277 103.026 E94
+0 3 25 32 1.164 109.307 E94
+0 6 25 6 1.769 99.311 X94
+0 6 25 8 1.419 104.161 E94
+0 6 25 9 1.403 105.407 E94
+0 6 25 10 1.448 102.194 E94
+0 6 25 11 1.680 99.260 E94
+0 6 25 12 1.489 98.818 E94
+0 6 25 32 1.501 109.688 X94
+0 6 25 37 1.312 102.280 E94
+0 6 25 39 1.617 97.314 E94
+0 6 25 40 1.380 105.601 E94
+0 6 25 71 0.844 100.242 E94
+0 6 25 72 1.219 112.058 E94
+0 8 25 8 1.224 105.341 E94
+0 8 25 10 1.214 104.893 E94
+0 8 25 11 1.411 101.655 E94
+0 8 25 20 1.010 108.094 E94
+0 8 25 32 1.217 114.325 E94
+0 8 25 37 1.106 104.742 E94
+0 8 25 40 1.265 103.617 E94
+0 8 25 72 0.977 117.767 E94
+0 9 25 32 1.232 114.493 E94
+0 10 25 10 1.346 98.856 E94
+0 10 25 32 1.273 110.640 E94
+0 10 25 72 1.021 114.624 E94
+0 11 25 32 1.528 106.045 E94
+0 12 25 12 1.303 99.224 E94
+0 12 25 32 1.305 106.320 E94
+0 15 25 15 1.113 107.673 E94
+4 15 25 15 1.264 93.138 E94
+0 15 25 32 1.248 107.964 E94
+0 15 25 72 0.933 119.729 E94
+4 20 25 20 1.220 85.039 E94
+0 20 25 72 0.965 111.595 E94
+0 25 25 72 0.890 106.612 E94
+0 32 25 32 1.248 122.857 X94
+0 32 25 37 1.097 113.430 E94
+0 32 25 39 1.605 99.255 E94
+0 32 25 40 1.122 119.057 E94
+0 32 25 43 1.257 110.308 X94
+0 32 25 57 1.219 108.740 E94
+0 32 25 63 1.211 108.168 E94
+0 32 25 71 0.642 117.733 X94
+0 32 25 72 1.050 121.823 E94
+0 37 25 37 0.947 107.124 E94
+0 37 25 40 0.965 112.107 E94
+0 37 25 72 0.868 118.776 E94
+0 40 25 40 1.496 95.270 E94
+0 40 25 72 1.035 114.441 E94
+0 57 25 57 1.059 102.995 E94
+0 63 25 63 1.032 102.950 E94
+0 71 25 71 0.419 100.483 X94
+0 0 26 0 0.000 98.100 0:*-26-* MMFF94 DEF
+4 0 26 0 0.000 83.600 4:*-26-* MMFF94 DEF
+0 1 26 1 1.085 98.054 E94
+0 1 26 8 1.263 96.331 E94
+0 1 26 10 1.115 102.175 E94
+0 1 26 12 1.147 98.926 X94
+0 1 26 15 1.141 100.260 E94
+0 1 26 20 1.075 98.171 E94
+0 1 26 26 0.997 92.571 E94
+0 1 26 37 1.081 98.754 E94
+0 1 26 71 0.672 97.353 X94
+0 6 26 6 1.833 97.935 E94
+0 6 26 11 1.663 100.061 E94
+0 6 26 12 1.442 99.021 E94
+0 8 26 8 1.189 105.662 E94
+0 8 26 12 1.028 110.069 E94
+0 8 26 34 1.509 93.096 E94
+0 11 26 11 1.757 94.795 E94
+0 12 26 15 1.271 99.730 E94
+0 12 26 34 1.508 90.565 E94
+0 12 26 40 1.165 103.783 E94
+0 12 26 71 0.704 96.577 X94
+0 15 26 26 1.047 96.592 E94
+0 15 26 40 1.543 91.164 E94
+4 20 26 20 1.252 83.624 E94
+0 71 26 71 0.473 94.470 X94
+0 0 30 0 0.000 134.200 0:*-30-* MMFF94 DEF
+1 0 30 0 0.000 131.800 1:*-30-* MMFF94 DEF
+4 0 30 0 0.000 97.700 4:*-30-* MMFF94 DEF
+7 0 30 0 0.000 92.300 7:*-30-* MMFF94 DEF
+1 2 30 3 0.778 128.756 E94
+0 2 30 15 0.805 130.439 E94
+0 2 30 20 0.727 132.187 E94
+0 2 30 22 0.737 131.100 E94
+1 2 30 30 0.751 132.225 E94
+1 3 30 4 0.721 134.566 E94
+1 3 30 5 0.410 135.975 E94
+1 3 30 6 0.845 137.596 E94
+1 3 30 20 0.714 130.677 E94
+7 3 30 20 1.280 89.957 E94
+1 3 30 30 0.857 122.418 E94
+7 3 30 30 1.260 93.102 E94
+0 4 30 20 0.690 136.444 E94
+0 5 30 20 0.390 131.835 C94
+0 5 30 30 0.364 132.652 C94
+0 6 30 30 0.876 139.045 E94
+0 15 30 15 0.876 130.718 E94
+4 15 30 15 1.239 101.359 E94
+0 15 30 30 0.782 132.228 E94
+4 15 30 30 1.141 100.902 E94
+4 20 30 30 1.117 95.513 C94
+7 20 30 30 1.191 93.909 E94
+0 20 30 40 0.769 134.526 E94
+1 20 30 67 0.704 138.631 E94
+4 22 30 22 1.179 93.007 E94
+8 30 30 30 1.230 93.732 E94
+0 30 30 40 0.706 145.470 E94
+1 30 30 67 0.907 125.792 E94
+0 0 34 0 0.000 109.400 0:*-34-* MMFF94 DEF
+4 0 34 0 0.000 89.400 4:*-34-* MMFF94 DEF
+0 1 34 1 0.862 112.251 C94
+0 1 34 2 1.154 109.212 E94
+0 1 34 8 1.330 106.399 E94
+0 1 34 9 1.166 112.989 E94
+0 1 34 10 1.388 104.291 E94
+0 1 34 20 1.201 106.135 E94
+0 1 34 26 0.913 112.004 E94
+0 1 34 36 0.576 111.206 C94
+0 1 34 37 1.141 109.045 E94
+0 2 34 36 0.694 112.000 #E94
+0 8 34 36 0.796 109.753 E94
+0 9 34 36 0.793 108.649 E94
+0 10 34 36 0.828 108.000 #E94
+4 20 34 20 1.448 89.411 E94
+0 20 34 36 0.665 112.526 E94
+0 22 34 36 0.694 110.000 #E94
+0 36 34 36 0.578 107.787 C94
+0 36 34 37 0.717 108.668 E94
+0 36 34 43 0.840 108.000 #E94
+0 0 37 0 0.000 118.800 0:*-37-* MMFF94 DEF
+1 0 37 0 0.000 115.900 1:*-37-* MMFF94 DEF
+3 0 37 0 0.000 64.700 3::*-37-* MMFF94 DEF
+4 0 37 0 0.000 91.800 4:*-37-* MMFF94 DEF
+0 1 37 37 0.803 120.419 C94
+0 1 37 38 0.992 118.432 E94
+0 1 37 58 1.027 116.528 E94
+0 1 37 63 0.837 123.024 E94
+0 1 37 64 0.821 124.073 E94
+0 1 37 69 1.038 115.506 E94
+1 2 37 37 0.712 119.695 C94
+1 2 37 38 1.029 117.220 E94
+1 3 37 37 0.798 114.475 C94
+7 3 37 37 1.320 90.784 E94
+1 3 37 38 1.109 112.724 E94
+1 3 37 58 1.134 111.566 E94
+1 3 37 69 1.119 111.916 E94
+1 4 37 37 0.906 119.614 E94
+1 4 37 38 1.087 114.623 E94
+0 5 37 37 0.563 120.571 C94
+0 5 37 38 0.693 115.588 C94
+0 5 37 58 0.699 113.316 E94
+0 5 37 63 0.702 121.238 C94
+0 5 37 64 0.523 121.446 C94
+0 5 37 69 0.794 111.638 C94
+0 5 37 78 0.563 119.432 E94
+0 6 37 37 0.968 116.495 C94
+0 6 37 38 1.324 115.886 E94
+0 6 37 64 1.139 118.868 E94
+1 9 37 37 0.974 121.003 E94
+1 9 37 38 1.137 117.591 E94
+0 10 37 37 1.025 117.918 E94
+0 10 37 38 1.088 120.135 E94
+0 10 37 58 1.077 120.925 E94
+0 11 37 37 1.094 118.065 E94
+0 11 37 38 1.223 117.328 E94
+0 12 37 37 0.950 118.495 E94
+0 12 37 38 1.126 113.859 E94
+0 12 37 64 1.076 111.320 E94
+0 13 37 37 0.917 118.117 E94
+0 14 37 37 0.861 118.045 E94
+0 15 37 37 0.755 121.037 C94
+0 15 37 38 1.027 119.421 E94
+0 15 37 64 0.976 117.125 E94
+0 17 37 37 0.930 119.408 E94
+0 17 37 38 1.179 110.828 E94
+0 17 37 64 0.946 118.357 E94
+0 18 37 37 1.029 113.991 X94
+0 18 37 38 1.278 106.908 E94
+0 18 37 64 0.975 117.029 E94
+0 19 37 37 0.660 125.278 E94
+0 20 37 37 0.744 129.614 E94
+4 20 37 37 1.217 93.425 E94
+0 22 37 37 0.805 125.777 E94
+3 22 37 37 0.152 64.704 E94
+0 22 37 38 0.904 124.494 E94
+0 25 37 37 0.718 121.600 E94
+0 26 37 37 0.691 122.967 E94
+0 34 37 37 1.030 116.423 E94
+0 34 37 64 1.074 113.905 E94
+0 35 37 37 0.964 131.858 E94
+0 35 37 38 1.187 124.980 E94
+0 37 37 37 0.669 119.977 C94
+1 37 37 37 0.864 122.227 E94
+4 37 37 37 1.380 90.193 E94
+0 37 37 38 0.596 126.139 C94
+1 37 37 38 1.033 117.271 E94
+0 37 37 39 1.038 117.619 E94
+1 37 37 39 1.078 114.622 E94
+0 37 37 40 1.045 121.633 C94
+0 37 37 41 0.892 119.572 E94
+0 37 37 43 1.013 117.860 X94
+0 37 37 45 1.114 112.337 E94
+0 37 37 46 0.999 120.038 E94
+0 37 37 55 1.002 120.163 E94
+0 37 37 56 1.020 117.801 E94
+1 37 37 57 0.881 120.932 E94
+0 37 37 58 1.014 120.052 E94
+1 37 37 58 1.127 112.251 E94
+0 37 37 61 1.072 115.515 E94
+0 37 37 62 0.941 124.384 E94
+0 37 37 63 0.478 111.243 C94
+1 37 37 63 0.894 120.190 E94
+0 37 37 64 0.423 112.567 C94
+1 37 37 64 0.912 118.973 E94
+1 37 37 67 1.064 114.980 E94
+0 37 37 69 0.872 116.778 C94
+1 37 37 69 1.042 116.438 E94
+0 37 37 78 0.974 116.439 E94
+0 37 37 81 1.034 115.664 E94
+1 37 37 81 1.104 111.759 E94
+0 38 37 38 0.725 128.938 C94
+0 38 37 40 1.024 123.755 E94
+0 38 37 43 1.165 115.355 E94
+0 38 37 58 0.979 128.362 E94
+1 38 37 58 1.257 111.356 E94
+0 38 37 62 1.148 118.349 E94
+0 38 37 63 1.095 115.386 E94
+1 38 37 63 1.076 114.910 E94
+0 38 37 64 1.070 116.605 E94
+1 38 37 67 1.289 109.610 E94
+0 40 37 58 1.103 119.417 E94
+0 40 37 63 0.943 122.904 E94
+0 40 37 64 0.931 123.541 E94
+0 40 37 78 0.931 123.604 E94
+0 41 37 58 0.967 120.535 E94
+0 45 37 63 1.031 116.781 E94
+0 45 37 64 1.156 110.199 E94
+0 45 37 69 1.248 111.041 E94
+0 58 37 62 1.016 125.987 E94
+0 58 37 63 1.152 112.628 E94
+0 58 37 64 1.291 106.250 E94
+1 58 37 64 1.108 113.166 E94
+0 58 37 78 1.188 110.842 E94
+0 0 38 0 0.000 113.800 0:*-38-* MMFF94 DEF
+0 37 38 37 1.085 115.406 C94
+0 37 38 38 1.289 112.016 C94
+0 37 38 63 1.230 110.181 E94
+0 37 38 64 1.207 111.032 E94
+0 37 38 69 1.238 114.692 E94
+0 37 38 78 1.118 114.813 E94
+0 38 38 38 1.343 118.516 E94
+0 0 39 0 0.000 120.700 0:*-39-* MMFF94 DEF
+1 0 39 0 0.000 125.400 1:*-39-* MMFF94 DEF
+0 1 39 63 0.854 123.380 C94
+0 1 39 65 1.111 118.049 E94
+1 2 39 63 0.858 130.275 E94
+1 2 39 65 0.900 133.220 E94
+1 3 39 63 0.900 127.045 E94
+1 3 39 65 1.126 118.909 E94
+0 6 39 63 1.166 122.985 E94
+0 6 39 65 1.396 117.707 E94
+0 8 39 63 1.000 124.868 E94
+0 8 39 65 1.057 127.145 E94
+1 9 39 63 0.981 127.725 E94
+1 9 39 65 1.170 122.487 E94
+0 10 39 63 1.109 119.788 E94
+0 10 39 65 1.118 124.961 E94
+0 18 39 63 1.108 117.061 X94
+0 23 39 63 0.551 127.770 C94
+0 23 39 65 0.752 118.352 C94
+0 23 39 78 0.581 124.000 #E94
+0 25 39 63 0.667 134.561 E94
+0 25 39 65 0.944 118.135 E94
+0 37 39 63 0.900 127.009 E94
+1 37 39 63 0.922 125.312 E94
+1 37 39 65 1.080 121.090 E94
+0 40 39 63 0.984 126.832 E94
+0 45 39 63 1.056 121.641 E94
+0 45 39 65 1.354 112.464 E94
+0 63 39 63 1.152 109.599 C94
+1 63 39 63 0.887 128.078 E94
+0 63 39 64 1.004 120.577 E94
+1 63 39 64 0.899 126.936 E94
+0 63 39 65 1.284 112.087 C94
+1 63 39 65 1.146 117.990 E94
+0 63 39 78 1.300 105.800 E94
+0 64 39 65 1.007 126.117 E94
+0 65 39 65 1.462 116.898 C94
+0 0 40 0 0.000 115.000 0:*-40-* MMFF94 DEF
+3 0 40 0 0.000 57.800 3::*-40-* MMFF94 DEF
+0 1 40 1 1.064 113.703 E94
+0 1 40 2 0.998 118.873 E94
+0 1 40 3 1.007 118.319 E94
+0 1 40 6 1.421 109.742 E94
+0 1 40 9 1.203 113.198 E94
+0 1 40 10 1.232 111.320 E94
+0 1 40 11 1.436 104.665 E94
+0 1 40 12 1.202 109.320 E94
+0 1 40 20 1.047 114.970 E94
+0 1 40 25 0.912 114.483 E94
+0 1 40 28 0.689 112.374 C94
+0 1 40 30 1.024 118.604 E94
+0 1 40 37 0.835 107.349 C94
+0 1 40 39 1.254 110.622 E94
+0 1 40 40 1.183 114.011 E94
+0 1 40 45 1.223 112.226 E94
+0 1 40 46 1.025 122.982 E94
+0 1 40 63 1.084 114.473 E94
+0 1 40 64 1.064 115.483 E94
+0 2 40 2 0.997 120.651 E94
+0 2 40 3 0.981 121.660 E94
+0 2 40 6 1.316 115.626 E94
+0 2 40 9 1.118 119.196 E94
+0 2 40 10 1.142 117.260 E94
+0 2 40 19 0.732 128.087 E94
+0 2 40 28 0.767 111.053 C94
+0 2 40 37 1.049 117.022 E94
+0 2 40 39 1.192 115.106 E94
+0 2 40 40 1.060 122.253 E94
+0 2 40 63 1.008 120.447 E94
+0 3 40 3 0.883 128.240 E94
+0 3 40 8 1.259 111.557 E94
+0 3 40 9 1.106 119.822 E94
+0 3 40 10 1.269 111.261 E94
+0 3 40 12 1.146 112.718 E94
+0 3 40 15 1.105 117.871 E94
+0 3 40 20 1.130 112.139 E94
+0 3 40 22 1.072 114.420 E94
+0 3 40 25 0.820 121.724 E94
+0 3 40 28 0.700 114.808 C94
+0 3 40 37 1.056 116.655 E94
+0 3 40 40 1.147 117.511 E94
+0 3 40 64 1.132 113.602 E94
+0 6 40 28 0.889 110.000 #E94
+0 8 40 28 0.764 111.915 E94
+0 8 40 37 1.216 112.920 E94
+0 8 40 63 1.351 108.085 E94
+0 9 40 28 0.774 112.549 E94
+0 9 40 37 1.236 112.751 E94
+0 10 40 28 0.799 109.725 E94
+0 10 40 37 1.316 108.686 E94
+0 11 40 37 1.546 101.687 E94
+0 15 40 15 1.154 121.497 E94
+3 22 40 22 0.204 57.777 E94
+0 22 40 37 1.066 114.220 E94
+0 22 40 63 1.126 112.006 E94
+0 25 40 28 0.485 120.000 #E94
+0 25 40 37 0.868 117.977 E94
+0 26 40 28 0.506 118.000 #E94
+0 26 40 37 0.812 122.336 E94
+0 28 40 28 0.560 109.160 C94
+0 28 40 30 0.656 119.230 E94
+0 28 40 37 0.662 110.288 C94
+0 28 40 39 0.789 110.951 E94
+0 28 40 40 0.782 111.731 E94
+0 28 40 45 0.674 120.000 #E94
+0 28 40 54 0.738 118.714 E94
+0 28 40 63 0.670 116.188 E94
+0 28 40 64 0.659 117.057 E94
+0 28 40 78 0.618 119.829 E94
+0 37 40 37 1.004 119.018 E94
+0 37 40 45 1.376 106.579 E94
+0 37 40 54 1.394 107.777 E94
+0 37 40 63 1.060 116.867 E94
+0 45 40 64 1.283 111.332 E94
+0 45 40 78 1.410 105.678 E94
+0 46 40 64 1.189 116.345 E94
+0 0 41 0 0.000 118.300 0:*-41-* MMFF94 DEF
+0 1 41 32 1.209 114.689 C94
+0 1 41 72 1.024 114.936 X94
+0 2 41 32 1.309 115.461 C94
+0 3 41 32 1.210 114.810 E94
+0 5 41 32 0.912 113.960 C94
+0 6 41 72 1.319 113.899 E94
+0 9 41 72 1.089 117.795 E94
+0 10 41 72 1.039 121.240 E94
+0 20 41 32 1.090 120.965 E94
+0 22 41 32 1.079 122.748 E94
+0 32 41 32 1.181 130.600 C94
+0 32 41 37 1.136 118.871 E94
+0 32 41 41 1.401 107.694 E94
+0 37 41 72 1.035 114.919 E94
+0 55 41 72 0.982 123.972 E94
+0 62 41 72 1.052 120.425 E94
+0 72 41 72 0.912 130.128 X94
+0 72 41 80 1.094 112.175 E94
+0 0 43 0 0.000 113.300 0:*-43-* MMFF94 DEF
+0 1 43 1 1.109 110.353 E94
+0 1 43 2 1.052 114.321 E94
+0 1 43 3 0.938 121.050 E94
+0 1 43 4 0.927 123.204 E94
+0 1 43 18 1.116 115.011 X94
+0 1 43 25 0.853 115.637 X94
+0 1 43 28 0.646 113.739 X94
+0 1 43 37 1.083 112.511 E94
+0 1 43 45 1.140 115.034 E94
+0 1 43 64 1.025 116.188 E94
+0 2 43 18 1.227 110.268 E94
+0 3 43 18 1.011 121.488 X94
+0 3 43 20 1.053 113.913 E94
+4 3 43 20 1.327 93.575 E94
+0 3 43 28 0.626 117.464 X94
+0 4 43 28 0.616 122.000 E94
+0 4 43 45 1.253 112.373 E94
+0 6 43 18 1.673 104.311 E94
+3 6 43 22 0.279 54.827 E94
+0 6 43 28 0.868 110.000 #E94
+0 6 43 37 1.519 105.833 E94
+0 6 43 43 1.603 108.652 E94
+0 8 43 18 1.511 104.036 E94
+0 8 43 28 0.794 110.320 E94
+0 15 43 15 1.558 103.008 E94
+0 15 43 18 1.409 108.458 E94
+0 17 43 18 1.367 111.904 E94
+0 18 43 18 1.144 120.463 E94
+0 18 43 20 0.961 123.768 E94
+4 18 43 20 1.451 92.867 E94
+0 18 43 22 1.171 112.379 E94
+0 18 43 28 0.628 116.881 X94
+0 18 43 34 1.324 111.347 E94
+0 18 43 37 1.185 112.132 X94
+0 18 43 43 1.379 109.036 E94
+0 18 43 64 1.108 116.279 E94
+0 20 43 28 0.626 115.000 #E94
+3 22 43 22 0.209 57.032 E94
+0 25 43 28 0.468 118.274 X94
+0 28 43 28 0.477 112.596 X94
+0 28 43 34 0.810 110.000 #E94
+0 28 43 37 0.669 113.350 X94
+0 28 43 64 0.658 115.293 E94
+0 0 44 0 0.000 91.600 0:*-44-* MMFF94 DEF
+0 63 44 63 1.962 88.495 C94
+0 63 44 65 2.261 94.137 C94
+0 63 44 78 1.738 86.270 E94
+0 63 44 80 1.748 86.194 E94
+0 65 44 65 1.530 101.147 E94
+0 65 44 80 1.629 93.534 E94
+0 78 44 78 0.903 119.401 E94
+0 0 45 0 0.000 116.700 0:*-45-* MMFF94 DEF
+0 1 45 32 1.260 118.182 X94
+0 2 45 32 1.294 118.082 X94
+0 3 45 32 1.343 115.589 E94
+0 6 45 32 1.787 111.682 X94
+0 8 45 32 1.515 115.695 E94
+0 9 45 32 1.339 123.850 E94
+0 10 45 32 1.578 112.194 E94
+0 20 45 32 1.245 118.893 E94
+0 22 45 32 1.293 117.503 E94
+0 32 45 32 1.467 128.036 X94
+0 32 45 37 1.298 117.857 E94
+0 32 45 39 1.715 107.633 E94
+0 32 45 40 1.497 116.432 E94
+0 32 45 43 1.545 113.711 E94
+0 32 45 63 1.335 116.765 E94
+0 32 45 64 1.330 116.908 E94
+0 32 45 78 1.394 114.962 E94
+0 0 46 0 0.000 111.000 0:*-46-* MMFF94 DEF
+0 1 46 7 1.440 110.492 X94
+0 2 46 7 1.489 112.709 E94
+0 7 46 8 1.724 109.817 E94
+0 7 46 37 1.519 110.569 E94
+0 7 46 40 1.650 111.405 E94
+0 0 48 0 0.000 118.400 0:*-48-* MMFF94 DEF
+0 3 48 18 1.065 122.928 E94
+0 18 48 28 0.736 113.969 X94
+0 0 49 0 0.000 111.400 0:*-49-* MMFF94 DEF
+0 50 49 50 0.522 111.433 C94
+0 0 51 0 0.000 111.400 0:*-51-* MMFF94 DEF
+0 3 51 52 0.913 111.360 X94
+0 0 53 0 0.000 180.000 0:*-53-* MMFF94 DEF
+0 3 53 47 0.574 180.000 E94
+0 9 53 47 0.649 180.000 E94
+0 0 54 0 0.000 119.500 0:*-54-* MMFF94 DEF
+1 0 54 0 0.000 115.700 1:*-54-* MMFF94 DEF
+0 1 54 1 0.923 121.439 E94
+0 1 54 3 0.707 124.083 C94
+0 1 54 36 0.294 122.881 C94
+0 3 54 6 1.376 115.398 E94
+1 3 54 9 1.128 114.457 E94
+0 3 54 36 0.685 119.698 C94
+1 3 54 40 1.105 116.439 E94
+0 6 54 36 0.826 115.000 #E94
+0 9 54 40 1.195 123.403 E94
+0 36 54 36 0.300 113.943 C94
+0 0 55 0 0.000 120.800 0:*-55-* MMFF94 DEF
+0 1 55 1 0.951 119.946 E94
+0 1 55 36 0.307 126.448 C94
+0 1 55 37 1.032 117.035 E94
+0 1 55 57 0.751 120.606 C94
+0 1 55 80 0.972 121.082 E94
+0 2 55 3 1.041 116.994 E94
+0 2 55 36 0.621 120.000 #E94
+0 2 55 57 1.047 118.847 E94
+0 3 55 9 1.053 121.298 E94
+0 3 55 36 0.567 124.000 #E94
+0 3 55 57 0.953 123.573 E94
+0 3 55 62 1.041 122.163 E94
+0 6 55 36 0.833 114.000 #E94
+0 6 55 57 1.408 112.958 E94
+0 8 55 36 0.656 122.000 #E94
+0 8 55 57 1.259 113.209 E94
+0 9 55 57 1.001 126.373 E94
+0 18 55 36 0.578 125.000 #E94
+0 18 55 57 1.054 122.320 E94
+0 36 55 36 0.355 117.729 C94
+0 36 55 37 0.623 120.405 E94
+0 36 55 41 0.485 134.689 E94
+0 36 55 57 0.663 119.499 C94
+0 36 55 64 0.632 118.000 #E94
+0 36 55 80 0.684 115.880 E94
+0 37 55 57 1.110 115.816 E94
+0 41 55 57 0.911 126.801 E94
+0 57 55 62 1.054 123.366 E94
+0 57 55 64 1.026 119.465 E94
+0 0 56 0 0.000 119.100 0:*-56-* MMFF94 DEF
+0 1 56 36 0.472 123.585 C94
+0 1 56 57 0.774 119.267 C94
+0 2 56 9 1.181 116.311 E94
+0 2 56 36 0.582 124.037 E94
+0 2 56 57 1.029 118.607 E94
+0 3 56 36 0.585 121.521 E94
+0 3 56 57 0.885 126.567 E94
+0 8 56 36 0.785 111.009 E94
+0 8 56 57 1.288 110.357 E94
+0 9 56 36 0.683 120.258 E94
+0 9 56 57 1.186 115.661 E94
+0 36 56 36 0.450 117.534 C94
+0 36 56 37 0.602 120.000 #E94
+0 36 56 57 0.646 120.649 C94
+0 36 56 63 0.579 123.766 E94
+0 36 56 80 0.625 120.000 #E94
+0 37 56 57 1.058 115.912 E94
+0 57 56 63 1.019 118.915 E94
+0 0 57 0 0.000 120.900 0:*-57-* MMFF94 DEF
+1 0 57 0 0.000 118.100 1:*-57-* MMFF94 DEF
+0 1 57 55 1.017 117.865 E94
+1 3 57 55 1.085 115.034 E94
+0 5 57 55 0.674 116.747 C94
+0 6 57 55 1.279 119.257 E94
+1 9 57 55 0.980 128.143 E94
+0 12 57 55 1.058 118.327 E94
+0 15 57 55 0.983 123.646 E94
+0 25 57 55 0.790 122.889 E94
+1 37 57 55 0.967 121.379 E94
+0 55 57 55 0.855 126.476 C94
+1 55 57 63 1.016 118.800 E94
+1 55 57 64 1.039 117.166 E94
+0 56 57 56 1.342 120.010 C94
+0 0 58 0 0.000 119.000 0:*-58-* MMFF94 DEF
+1 0 58 0 0.000 119.900 1:*-58-* MMFF94 DEF
+0 1 58 37 1.003 119.236 E94
+0 1 58 64 0.961 121.070 E94
+1 3 58 37 0.983 121.506 E94
+0 6 58 37 1.371 114.370 E94
+0 18 58 37 1.005 120.665 E94
+0 36 58 37 0.650 118.713 E94
+0 36 58 63 0.650 118.000 #E94
+0 36 58 64 0.620 120.051 E94
+0 37 58 37 0.996 122.710 E94
+1 37 58 37 1.036 118.260 E94
+0 37 58 63 1.087 116.989 E94
+0 37 58 64 1.061 117.942 E94
+0 0 59 0 0.000 105.600 0:*-59-* MMFF94 DEF
+0 63 59 63 1.273 106.313 C94
+0 63 59 65 1.750 107.755 C94
+0 63 59 78 1.713 101.179 E94
+0 63 59 80 1.599 105.341 E94
+0 65 59 65 1.754 107.683 E94
+0 65 59 78 1.644 107.142 E94
+0 65 59 82 1.864 103.624 E94
+0 0 61 0 0.000 180.000 0:*-61-* MMFF94 DEF
+0 1 61 60 0.475 180.000 E94
+0 37 61 42 0.536 180.000 E94
+0 37 61 60 0.484 180.000 E94
+0 0 62 0 0.000 108.300 0:*-62-* MMFF94 DEF
+0 1 62 18 1.316 109.273 X94
+0 2 62 23 0.817 105.542 X94
+0 3 62 3 1.318 106.821 E94
+0 3 62 18 1.311 111.144 E94
+0 3 62 55 1.528 102.414 E94
+0 9 62 18 1.515 107.660 E94
+0 18 62 37 1.229 114.618 E94
+0 18 62 41 1.366 108.722 E94
+0 18 62 63 1.427 106.284 E94
+0 18 62 64 1.317 110.366 E94
+0 0 63 0 0.000 123.300 0:*-63-* MMFF94 DEF
+1 0 63 0 0.000 124.300 1:*-63-* MMFF94 DEF
+0 1 63 39 0.935 121.832 E94
+0 1 63 44 0.902 122.101 E94
+0 1 63 59 1.175 115.253 E94
+0 1 63 64 0.737 131.378 E94
+0 1 63 66 0.865 127.610 E94
+1 2 63 39 1.027 117.864 E94
+1 2 63 59 0.987 127.524 E94
+1 2 63 64 0.730 133.818 E94
+1 2 63 66 0.828 132.383 E94
+1 3 63 39 0.900 125.395 E94
+1 3 63 44 0.935 120.481 E94
+1 3 63 59 1.158 117.219 E94
+1 3 63 64 0.766 130.065 E94
+1 3 63 66 0.950 123.049 E94
+1 4 63 44 0.848 126.602 E94
+1 4 63 59 1.211 114.804 E94
+1 4 63 64 0.795 127.817 E94
+0 5 63 39 0.617 121.127 C94
+0 5 63 44 0.393 126.141 C94
+0 5 63 59 0.784 114.076 C94
+0 5 63 64 0.577 131.721 C94
+0 5 63 66 0.643 125.134 C94
+0 5 63 78 0.482 130.000 #E94
+0 5 63 81 0.588 124.000 #E94
+0 6 63 39 1.234 120.509 E94
+0 6 63 59 1.564 113.514 E94
+0 6 63 64 0.951 131.301 E94
+1 9 63 39 1.068 121.741 E94
+1 9 63 44 0.963 124.598 E94
+1 9 63 64 0.804 134.237 E94
+1 9 63 66 0.912 133.020 E94
+0 10 63 39 1.084 120.356 E94
+0 10 63 44 1.112 115.732 E94
+0 10 63 59 1.307 116.218 E94
+0 10 63 64 0.867 128.750 E94
+0 10 63 66 0.981 127.617 E94
+0 12 63 39 1.111 114.439 E94
+0 12 63 44 1.035 119.321 E94
+0 12 63 64 0.838 126.226 E94
+0 12 63 66 0.980 122.280 E94
+0 15 63 39 1.064 117.958 E94
+0 15 63 44 0.952 125.654 E94
+0 15 63 64 0.813 129.284 E94
+0 15 63 66 0.962 124.490 E94
+0 18 63 44 1.110 116.077 E94
+0 18 63 64 0.740 135.028 E94
+0 19 63 39 0.647 132.369 E94
+0 19 63 64 0.517 141.986 E94
+0 25 63 39 0.597 139.439 E94
+0 25 63 66 0.776 122.699 E94
+0 35 63 59 1.351 124.475 E94
+0 35 63 64 0.808 145.098 E94
+0 37 63 39 1.011 132.046 C94
+1 37 63 39 0.934 123.481 E94
+0 37 63 44 0.764 133.930 E94
+1 37 63 44 0.915 121.637 E94
+0 37 63 59 1.041 124.836 E94
+1 37 63 59 1.214 114.211 E94
+0 37 63 64 0.679 122.881 C94
+1 37 63 64 0.742 131.784 E94
+0 37 63 66 0.742 140.668 E94
+1 37 63 66 0.871 128.130 E94
+0 38 63 39 1.022 124.814 E94
+0 38 63 64 0.910 126.513 E94
+0 39 63 39 0.910 131.461 E94
+1 39 63 39 1.105 119.174 E94
+0 39 63 40 1.112 119.261 E94
+1 39 63 44 1.144 114.126 E94
+0 39 63 45 1.166 115.115 E94
+1 39 63 57 0.931 123.222 E94
+0 39 63 58 1.042 123.231 E94
+1 39 63 63 0.949 122.353 E94
+0 39 63 64 0.813 107.255 C94
+1 39 63 64 0.943 123.441 E94
+0 39 63 66 1.012 110.865 C94
+1 39 63 66 1.095 120.834 E94
+0 40 63 44 0.943 125.881 E94
+0 40 63 59 1.298 117.078 E94
+0 40 63 64 0.845 130.865 E94
+0 40 63 66 0.940 130.926 E94
+0 44 63 45 1.125 114.633 E94
+0 44 63 56 1.030 120.178 E94
+0 44 63 62 0.991 122.899 E94
+1 44 63 63 0.894 123.341 E94
+0 44 63 64 0.853 108.480 C94
+0 44 63 66 0.854 114.516 C94
+0 44 63 72 0.915 129.129 E94
+0 44 63 78 1.217 106.254 E94
+0 44 63 81 1.278 108.400 E94
+0 45 63 59 1.467 108.824 E94
+0 45 63 64 0.940 122.725 E94
+0 45 63 66 1.164 116.157 E94
+0 56 63 66 0.875 134.888 E94
+1 57 63 66 0.945 123.246 E94
+0 58 63 64 0.965 122.522 E94
+0 59 63 64 1.035 110.108 C94
+0 59 63 66 1.181 115.592 C94
+0 62 63 66 0.976 128.662 E94
+1 63 63 64 0.776 129.499 E94
+1 63 63 66 0.929 124.689 E94
+0 66 63 72 0.911 129.610 E94
+0 0 64 0 0.000 121.400 0:*-64-* MMFF94 DEF
+1 0 64 0 0.000 121.700 1:*-64-* MMFF94 DEF
+0 1 64 63 0.776 128.041 E94
+0 1 64 64 0.766 128.061 E94
+0 1 64 65 0.963 120.640 E94
+0 1 64 66 0.952 120.685 E94
+0 1 64 81 1.050 114.735 E94
+0 1 64 82 1.013 117.414 E94
+1 2 64 63 0.861 122.947 E94
+1 2 64 64 0.816 125.433 E94
+1 2 64 65 0.907 125.781 E94
+1 2 64 66 1.010 118.540 E94
+1 2 64 82 0.923 124.473 E94
+1 3 64 63 0.828 124.890 E94
+1 3 64 64 0.774 128.286 E94
+1 3 64 65 0.973 120.954 E94
+1 3 64 66 0.949 121.821 E94
+1 3 64 81 0.995 118.754 E94
+1 4 64 63 0.845 123.889 E94
+1 4 64 64 0.804 126.131 E94
+1 4 64 65 1.036 117.401 E94
+1 4 64 66 1.010 118.254 E94
+0 5 64 63 0.501 126.170 C94
+0 5 64 64 0.546 127.405 C94
+0 5 64 65 0.664 118.412 C94
+0 5 64 66 0.699 120.478 C94
+0 5 64 78 0.482 127.331 E94
+0 5 64 81 0.605 120.000 #E94
+0 5 64 82 0.597 122.000 #E94
+0 6 64 63 1.112 120.985 E94
+0 6 64 64 1.043 123.922 E94
+0 6 64 65 1.348 115.506 E94
+0 6 64 66 1.156 123.890 E94
+1 9 64 64 0.959 120.924 E94
+1 9 64 65 1.098 119.529 E94
+1 9 64 66 1.013 123.743 E94
+0 10 64 63 0.937 123.695 E94
+0 10 64 64 0.893 125.735 E94
+0 10 64 65 1.016 124.788 E94
+0 10 64 66 1.065 121.125 E94
+0 12 64 63 0.845 126.259 E94
+0 12 64 64 0.869 124.058 E94
+0 12 64 65 1.020 120.198 E94
+0 12 64 66 0.971 122.900 E94
+0 13 64 63 0.845 123.004 E94
+0 13 64 64 0.883 120.111 E94
+0 15 64 63 0.870 124.581 E94
+0 15 64 64 0.882 123.309 E94
+0 15 64 65 1.008 121.049 E94
+0 15 64 66 0.990 121.826 E94
+0 18 64 65 1.065 118.404 E94
+0 18 64 66 1.067 118.002 E94
+0 37 64 63 0.906 117.966 C94
+0 37 64 64 0.854 136.087 C94
+1 37 64 64 0.772 128.673 E94
+0 37 64 65 0.799 134.844 E94
+1 37 64 65 0.942 122.866 E94
+0 37 64 66 0.845 130.337 E94
+0 37 64 78 0.706 135.432 E94
+0 37 64 81 0.917 124.856 E94
+0 37 64 82 0.946 123.684 E94
+1 37 64 82 1.000 119.086 E94
+0 38 64 63 0.988 121.242 E94
+0 38 64 64 0.858 129.014 E94
+0 38 64 65 0.989 127.335 E94
+0 38 64 66 1.022 124.454 E94
+0 39 64 64 1.086 114.312 E94
+0 39 64 65 1.060 122.481 E94
+1 39 64 65 1.204 114.188 E94
+1 39 64 66 1.170 115.157 E94
+0 40 64 63 0.948 123.538 E94
+0 40 64 64 0.928 123.853 E94
+0 40 64 65 0.958 129.125 E94
+0 40 64 81 1.035 123.154 E94
+0 40 64 82 1.183 115.934 E94
+0 43 64 63 0.885 126.749 E94
+0 43 64 64 0.898 124.876 E94
+0 43 64 65 1.024 123.706 E94
+0 43 64 66 1.017 123.409 E94
+0 45 64 63 0.981 120.063 E94
+0 45 64 64 0.921 123.014 E94
+0 45 64 65 1.276 110.521 E94
+0 45 64 66 1.199 113.371 E94
+0 55 64 64 0.907 124.405 E94
+0 55 64 65 1.002 125.220 E94
+1 57 64 65 1.020 117.950 E94
+1 57 64 66 0.959 121.017 E94
+0 58 64 63 1.075 115.646 E94
+0 58 64 64 0.815 131.812 E94
+0 58 64 66 0.978 126.562 E94
+0 62 64 64 0.885 126.560 E94
+0 62 64 65 1.073 121.703 E94
+0 63 64 64 0.866 108.239 C94
+1 63 64 64 0.827 124.584 E94
+0 63 64 66 1.038 111.621 C94
+0 63 64 78 1.172 105.176 E94
+0 63 64 81 1.164 110.895 E94
+0 63 64 82 1.395 101.902 E94
+0 64 64 64 0.967 115.037 E94
+0 64 64 65 0.916 113.570 C94
+1 64 64 66 1.003 118.067 E94
+0 64 64 78 1.194 103.479 E94
+0 64 64 82 1.210 108.553 E94
+0 65 64 66 1.055 115.369 C94
+0 65 64 81 1.168 116.240 E94
+0 66 64 66 0.932 129.624 E94
+0 0 65 0 0.000 104.500 0:*-65-* MMFF94 DEF
+0 39 65 64 1.738 101.550 C94
+0 39 65 66 1.589 106.360 C94
+0 39 65 82 1.740 101.208 E94
+0 44 65 64 1.430 103.829 C94
+0 44 65 66 1.366 110.552 E94
+0 44 65 78 1.419 104.213 E94
+0 59 65 64 1.788 103.452 C94
+0 59 65 81 1.774 104.872 E94
+0 0 66 0 0.000 106.900 0:*-66-* MMFF94 DEF
+0 63 66 64 1.206 103.779 C94
+0 63 66 66 1.406 106.735 C94
+0 63 66 78 1.339 105.365 E94
+0 63 66 81 1.408 106.806 E94
+0 64 66 65 1.709 107.658 C94
+0 65 66 66 1.932 111.306 C94
+0 0 67 0 0.000 119.900 0:*-67-* MMFF94 DEF
+1 0 67 0 0.000 116.600 1:*-67-* MMFF94 DEF
+0 1 67 3 0.982 120.683 E94
+0 1 67 9 1.178 115.581 E94
+0 1 67 32 1.233 119.589 E94
+0 1 67 67 1.257 111.574 E94
+1 2 67 32 1.118 126.320 E94
+1 2 67 67 1.231 113.438 E94
+0 3 67 23 0.567 128.000 #E94
+0 3 67 32 1.290 120.945 E94
+1 3 67 37 1.122 113.631 E94
+1 9 67 30 1.142 118.899 E94
+0 9 67 32 1.325 125.531 E94
+1 9 67 37 1.186 115.979 E94
+0 23 67 32 0.805 120.000 #E94
+1 30 67 32 1.370 114.854 E94
+1 32 67 37 1.240 120.019 E94
+0 32 67 67 1.504 117.327 E94
+1 37 67 67 1.310 110.017 E94
+0 0 68 0 0.000 108.800 0:*-68-* MMFF94 DEF
+0 1 68 1 1.159 108.238 C94
+0 1 68 23 0.772 107.200 C94
+0 1 68 32 0.958 110.757 C94
+0 23 68 23 0.650 104.892 C94
+0 23 68 32 0.659 112.977 C94
+0 0 69 0 0.000 120.300 0:*-69-* MMFF94 DEF
+0 32 69 37 1.123 121.777 C94
+0 32 69 38 1.486 117.217 E94
+0 37 69 37 1.223 116.447 C94
+0 38 69 38 1.122 125.930 E94
+0 31 70 31 0.658 103.978 C94
+0 0 73 0 0.000 106.600 0:*-73-* MMFF94 DEF
+0 1 73 32 1.590 100.180 X94
+0 1 73 72 1.481 96.166 X94
+0 32 73 32 1.665 115.012 X94
+0 32 73 72 1.326 115.134 X94
+0 0 74 0 0.000 113.000 0:*-74-* MMFF94 DEF
+0 3 74 7 1.357 113.010 X94
+0 0 75 0 0.000 94.900 0:*-75-* MMFF94 DEF
+0 1 75 3 1.138 96.779 E94
+0 3 75 19 1.044 91.970 E94
+0 3 75 71 0.729 95.899 X94
+0 0 76 0 0.000 107.600 0:*-76-* MMFF94 DEF
+0 76 76 76 1.434 109.889 X94
+0 76 76 78 1.493 103.519 X94
+0 78 76 78 1.235 109.421 E94
+0 0 77 0 0.000 109.500 0:*-77-* MMFF94 DEF
+0 32 77 32 1.652 109.472 X94
+0 0 78 0 0.000 121.900 0:*-78-* MMFF94 DEF
+1 0 78 0 0.000 126.100 1:*-78-* MMFF94 DEF
+0 1 78 78 0.744 130.960 E94
+0 1 78 81 0.938 121.477 E94
+1 3 78 78 0.827 125.468 E94
+1 3 78 81 0.922 123.748 E94
+0 5 78 76 0.584 123.407 X94
+0 5 78 78 0.546 128.000 C94
+0 5 78 79 0.617 122.000 #E94
+0 5 78 81 0.542 109.881 C94
+1 9 78 78 0.863 129.501 E94
+1 9 78 81 0.991 125.857 E94
+0 37 78 76 0.770 137.282 E94
+0 37 78 78 0.803 128.249 E94
+0 37 78 81 0.864 128.714 E94
+0 38 78 78 0.844 130.617 E94
+0 38 78 81 1.023 123.532 E94
+0 39 78 64 0.734 138.714 E94
+0 39 78 78 1.202 109.426 E94
+0 40 78 76 0.930 130.150 E94
+0 40 78 78 0.778 135.746 E94
+0 40 78 81 1.058 121.251 E94
+0 44 78 63 0.677 141.902 E94
+0 44 78 64 0.663 142.589 E94
+0 44 78 66 0.816 134.701 E94
+0 44 78 78 1.089 111.702 E94
+0 45 78 76 1.199 114.467 E94
+0 45 78 78 0.915 125.050 E94
+0 45 78 81 1.216 112.926 E94
+0 59 78 64 0.963 128.471 E94
+0 59 78 65 1.097 128.375 E94
+0 59 78 78 1.443 105.916 E94
+0 63 78 64 0.942 117.779 E94
+0 64 78 65 0.835 131.530 E94
+0 64 78 78 1.038 111.834 E94
+0 66 78 78 1.030 118.376 E94
+0 76 78 76 1.245 113.179 X94
+0 76 78 78 1.159 111.900 E94
+0 78 78 78 1.336 99.459 E94
+0 78 78 81 1.302 105.130 C94
+0 79 78 81 1.217 114.792 E94
+0 0 79 0 0.000 103.400 0:*-79-* MMFF94 DEF
+0 78 79 81 1.569 102.043 E94
+0 79 79 81 1.625 104.857 E94
+0 0 80 0 0.000 121.900 0:*-80-* MMFF94 DEF
+1 0 80 0 0.000 128.200 1:*-80-* MMFF94 DEF
+0 1 80 81 0.864 127.147 E94
+1 3 80 81 0.886 128.181 E94
+0 5 80 81 0.651 125.682 C94
+0 18 80 81 1.032 120.869 E94
+0 41 80 81 0.909 125.057 E94
+0 44 80 55 0.918 127.755 E94
+0 44 80 81 1.184 112.411 E94
+0 55 80 59 1.254 120.263 E94
+0 55 80 81 0.991 127.612 E94
+0 56 80 81 1.003 126.038 E94
+0 59 80 81 1.439 112.030 E94
+0 81 80 81 1.205 108.609 C94
+0 0 81 0 0.000 119.500 0:*-81-* MMFF94 DEF
+0 1 81 63 0.996 120.129 E94
+0 1 81 64 0.978 119.970 E94
+0 1 81 78 0.879 126.535 E94
+0 1 81 79 1.144 116.113 E94
+0 1 81 80 0.895 126.324 E94
+1 2 81 78 0.927 125.080 E94
+1 2 81 80 0.895 128.399 E94
+1 9 81 78 1.015 124.270 E94
+1 9 81 80 1.106 120.028 E94
+0 36 81 64 0.522 130.295 E94
+0 36 81 66 0.583 128.738 E94
+0 36 81 78 0.578 124.658 C94
+0 36 81 80 0.575 124.787 C94
+0 37 81 64 0.929 122.408 E94
+1 37 81 64 0.983 119.722 E94
+0 37 81 65 1.184 114.158 E94
+1 37 81 65 1.281 110.477 E94
+1 37 81 78 0.884 126.208 E94
+1 37 81 80 0.940 123.333 E94
+0 63 81 64 1.115 114.945 E94
+0 64 81 65 1.075 122.099 E94
+0 64 81 80 1.143 113.176 E94
+0 66 81 80 1.067 122.250 E94
+0 78 81 80 0.957 110.556 C94
+0 79 81 80 1.379 107.936 E94
+0 32 82 59 1.666 114.660 E94
+0 32 82 64 1.075 131.706 E94
+0 32 82 65 1.238 129.293 E94
+0 59 82 64 1.563 105.660 E94
+0 64 82 65 1.281 112.955 E94
diff --git a/parameters/MMFFAROM.PAR b/parameters/MMFFAROM.PAR
new file mode 100644
index 0000000..5b6593d
--- /dev/null
+++ b/parameters/MMFFAROM.PAR
@@ -0,0 +1,56 @@
+* 3. MMFFAROM.PAR: This file relates provisionally assigned atom types to the
+* final aromatic atom types used for aromatic ring systems.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF AROMATIC SYMBOLIC TYPES VS ORIGINALLY ASSIGNED TYPES
+*
+*OLD AROM AT RING IM N5
+*TYPE TYPE NUM SIZE L5 CAT ANION
+C* CB 6 6 0 0 0
+N* NPYD 7 6 0 0 0
+NCN+ NPD+ 7 6 0 0 0
+N+=C NPD+ 7 6 0 0 0
+N=+N NPD+ 7 6 0 0 0
+N2OX NPOX 7 6 0 0 0
+*
+C* C5A 6 5 2 0 0
+C* C5B 6 5 3 0 0
+C* C5 6 5 4 0 0
+N* NPYL 7 5 1 0 0
+N* N5A 7 5 2 0 0
+N* N5B 7 5 3 0 0
+N* N5 7 5 4 0 0
+CNN+ CIM+ 6 5 2 1 0
+CNN+ CIM+ 6 5 3 1 0
+CNN+ CIM+ 6 5 4 1 0
+CGD+ CIM+ 6 5 4 1 0
+C5A C5 6 5 3 0 0
+C5B C5 6 5 2 0 0
+N5A N5 7 5 3 0 0
+N5B N5 7 5 2 0 0
+N2OX N5AX 7 5 2 0 0
+N2OX N5BX 7 5 3 0 0
+N2OX N5OX 7 5 4 0 0
+NCN+ NIM+ 7 5 2 1 0
+NCN+ NIM+ 7 5 3 1 0
+NCN+ NIM+ 7 5 4 1 0
+NGD+ NIM+ 7 5 2 1 0
+NGD+ NIM+ 7 5 3 1 0
+NGD+ NIM+ 7 5 4 1 0
+N+=C N5A+ 7 5 2 0 0
+N+=C N5B+ 7 5 3 0 0
+N+=C N5+ 7 5 4 0 0
+N+=N N5A+ 7 5 2 0 0
+N+=N N5B+ 7 5 3 0 0
+N+=N N5+ 7 5 4 0 0
+NPD+ N5A+ 7 5 2 0 0
+NPD+ N5B+ 7 5 3 0 0
+NPD+ N5+ 7 5 4 0 0
+NM N5M 7 5 1 0 1
+NM N5M 7 5 2 0 1
+NM N5M 7 5 3 0 1
+NM N5M 7 5 4 0 1
+O* OFUR 8 5 1 0 0
+S* STHI 16 5 1 0 0
diff --git a/parameters/MMFFBNDK.PAR b/parameters/MMFFBNDK.PAR
new file mode 100644
index 0000000..e77ca58
--- /dev/null
+++ b/parameters/MMFFBNDK.PAR
@@ -0,0 +1,68 @@
+* 7. MMFFBNDK.PAR: This file supplies parameters employed in the empirical rule used for bond-stretching force constants.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF BOND LENGTH, FORCE CONSTANT DEFAULT-RULE PARAMETERS
+* C94 = Fitted to ab-initio derived core MMFF94 force constants
+* E94 = Based on Herschberg/Laurie parameterization of Badger's rule
+*
+* species r0(ref) kb(ref) Source
+ 1 6 1.084 5.15 C94
+ 1 7 1.001 7.35 C94
+ 1 8 0.947 9.10 C94
+ 1 9 0.92 10.6 E94
+ 1 14 1.48 2.3 E94
+ 1 15 1.415 2.95 C94
+ 1 16 1.326 4.30 C94
+ 1 17 1.28 4.3 E94
+ 1 35 1.41 4.2 E94
+ 1 53 1.60 2.7 E94
+ 6 6 1.512 3.80 C94
+ 6 7 1.439 4.55 C94
+ 6 8 1.393 5.40 C94
+ 6 9 1.353 6.20 C94
+ 6 14 1.86 2.6 E94
+ 6 15 1.84 2.7 E94
+ 6 16 1.812 2.85 C94
+ 6 17 1.781 2.75 C94
+ 6 35 1.94 2.6 E94
+ 6 53 2.16 1.4 E94
+ 7 7 1.283 6.00 C94
+ 7 8 1.333 5.90 C94
+ 7 9 1.36 5.9 E94
+ 7 14 1.74 3.7 E94
+ 7 15 1.65 4.8 E94
+ 7 16 1.674 3.75 C94
+ 7 17 1.75 3.5 E94
+ 7 35 1.90 2.9 E94
+ 7 53 2.10 1.6 E94
+ 8 8 1.48 3.6 E94
+ 8 9 1.42 4.6 E94
+ 8 14 1.63 5.2 E94
+ 8 15 1.66 4.7 E94
+ 8 16 1.470 9.90 C94
+ 8 17 1.70 4.1 E94
+ 8 35 1.85 3.4 E94
+ 8 53 2.05 1.6 E94
+ 9 14 1.57 6.4 E94
+ 9 15 1.54 7.1 E94
+ 9 16 1.55 6.9 E94
+ 14 14 2.32 1.3 E94
+ 14 15 2.25 1.5 E94
+ 14 16 2.15 2.0 E94
+ 14 17 2.02 3.1 E94
+ 14 35 2.19 2.1 E94
+ 14 53 2.44 1.5 E94
+ 15 15 2.21 1.7 E94
+ 15 16 2.10 2.4 E94
+ 15 17 2.03 3.0 E94
+ 15 35 2.21 2.0 E94
+ 15 53 2.47 1.4 E94
+ 16 16 2.052 2.50 C94
+ 16 17 2.04 2.9 E94
+ 16 35 2.24 1.9 E94
+ 16 53 2.40 1.7 E94
+ 17 17 1.99 3.5 E94
+ 35 35 2.28 2.4 E94
+ 53 53 2.67 1.6 E94
diff --git a/parameters/MMFFBOND.PAR b/parameters/MMFFBOND.PAR
new file mode 100644
index 0000000..6ca59f6
--- /dev/null
+++ b/parameters/MMFFBOND.PAR
@@ -0,0 +1,507 @@
+* 6. MMFFBOND.PAR: This file supplies parameters for bond-stretching interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF BOND PARAMETERS- Rev: 26-OCT-94 Source: MMFF94
+* C94 = CORE MMFF94 parameter - obtained from ab initio data
+* X94 = EXTD MMFF94 parameter - fit to additional ab initio data
+* E94 = r0 from fit to X-ray data, kb from empirical rule
+* #C94 = r0 lies between C94 and E94 values, kb from empirical rule
+* #X94 = r0 lies between X94 and E94 values, kb from empirical rule
+* #E94 = r0 and k both from empirical rules
+*
+* types kb r0 Source
+0 1 1 4.258 1.508 C94
+0 1 2 4.539 1.482 C94
+0 1 3 4.190 1.492 C94
+0 1 4 4.707 1.459 X94
+0 1 5 4.766 1.093 C94
+0 1 6 5.047 1.418 C94
+0 1 8 5.084 1.451 C94
+0 1 9 4.763 1.458 C94
+0 1 10 4.664 1.436 C94
+0 1 11 6.011 1.360 #C94
+0 1 12 2.974 1.773 C94
+0 1 13 2.529 1.949 E94
+0 1 14 1.706 2.090 E94
+0 1 15 2.893 1.805 C94
+0 1 17 2.841 1.813 X94
+0 1 18 3.258 1.772 X94
+0 1 19 2.866 1.830 #X94
+0 1 20 4.650 1.504 C94
+0 1 22 4.286 1.482 E94
+0 1 25 2.980 1.810 #X94
+0 1 26 2.790 1.830 #X94
+0 1 34 3.844 1.480 #C94
+0 1 35 7.915 1.307 X94
+0 1 37 4.957 1.486 C94
+0 1 39 6.114 1.445 C94
+0 1 40 4.922 1.446 C94
+0 1 41 3.830 1.510 #C94
+0 1 43 3.971 1.472 X94
+0 1 45 3.844 1.480 X94
+0 1 46 3.813 1.482 X94
+0 1 54 4.267 1.461 C94
+0 1 55 4.646 1.454 C94
+0 1 56 4.166 1.453 C94
+0 1 57 4.669 1.461 E94
+0 1 58 4.329 1.451 E94
+0 1 61 4.845 1.424 X94
+0 1 62 4.456 1.444 X94
+0 1 63 4.481 1.471 E94
+0 1 64 4.518 1.469 E94
+0 1 67 4.188 1.459 E94
+0 1 68 4.217 1.479 C94
+0 1 72 2.956 1.801 X94
+0 1 73 2.608 1.839 X94
+0 1 75 2.547 1.858 E94
+0 1 78 4.593 1.465 E94
+0 1 80 4.373 1.477 E94
+0 1 81 4.512 1.441 E94
+0 2 2 9.505 1.333 C94
+1 2 2 5.310 1.430 #C94
+1 2 3 4.565 1.468 C94
+0 2 4 9.538 1.297 E94
+1 2 4 5.657 1.415 E94
+0 2 5 5.170 1.083 C94
+0 2 6 5.520 1.373 C94
+1 2 9 6.385 1.360 E94
+0 2 10 6.329 1.362 E94
+0 2 11 6.283 1.350 #X94
+0 2 12 3.390 1.720 #X94
+0 2 13 3.413 1.854 E94
+0 2 14 2.062 2.025 E94
+0 2 15 3.896 1.720 E94
+0 2 17 3.247 1.773 E94
+0 2 18 3.789 1.728 E94
+0 2 19 3.052 1.811 E94
+0 2 20 4.593 1.465 E94
+0 2 22 4.926 1.448 E94
+0 2 25 3.750 1.742 E94
+0 2 30 8.166 1.331 E94
+0 2 34 5.207 1.407 E94
+0 2 35 10.343 1.250 #X94
+1 2 37 5.007 1.449 C94
+1 2 39 6.164 1.368 E94
+0 2 40 6.110 1.370 #C94
+0 2 41 3.746 1.505 C94
+0 2 43 4.928 1.420 E94
+0 2 45 4.725 1.430 #X94
+0 2 46 7.466 1.325 E94
+0 2 55 6.164 1.368 E94
+0 2 56 6.246 1.365 E94
+0 2 62 7.105 1.336 X94
+1 2 63 6.030 1.400 E94
+1 2 64 5.754 1.411 E94
+1 2 67 4.685 1.432 E94
+0 2 72 4.179 1.700 #X94
+1 2 81 6.357 1.361 E94
+1 3 3 4.418 1.489 C94
+1 3 4 5.135 1.438 E94
+0 3 5 4.650 1.101 C94
+0 3 6 5.801 1.355 C94
+0 3 7 12.950 1.222 C94
+0 3 9 10.077 1.290 C94
+1 3 9 6.273 1.364 E94
+0 3 10 5.829 1.369 C94
+0 3 11 6.570 1.340 E94
+0 3 12 3.449 1.715 E94
+0 3 15 3.536 1.748 E94
+0 3 16 4.735 1.665 E94
+0 3 17 2.888 1.808 E94
+0 3 18 3.394 1.760 E94
+0 3 20 3.298 1.530 C94
+0 3 22 4.593 1.465 E94
+0 3 25 3.164 1.792 E94
+1 3 30 4.481 1.471 E94
+0 3 35 11.012 1.237 E94
+1 3 37 4.488 1.457 C94
+1 3 39 5.978 1.375 E94
+0 3 40 6.110 1.370 #C94
+0 3 41 4.286 1.482 E94
+0 3 43 4.928 1.420 X94
+0 3 45 4.531 1.440 E94
+0 3 48 5.412 1.398 E94
+0 3 51 8.562 1.290 #X94
+0 3 53 7.637 1.320 #X94
+0 3 54 10.333 1.280 C94
+1 3 54 2.771 1.563 E94
+0 3 55 4.886 1.422 E94
+0 3 56 4.907 1.421 E94
+1 3 57 5.492 1.422 E94
+1 3 58 5.163 1.409 E94
+0 3 62 7.568 1.322 E94
+1 3 63 5.468 1.423 E94
+1 3 64 5.288 1.431 E94
+0 3 67 8.217 1.304 E94
+0 3 74 5.204 1.639 X94
+0 3 75 4.191 1.710 #X94
+1 3 78 5.705 1.413 E94
+1 3 80 6.719 1.375 E94
+0 4 4 15.206 1.200 #X94
+0 4 5 5.726 1.065 X94
+0 4 6 7.193 1.328 E94
+0 4 7 14.916 1.176 E94
+0 4 9 15.589 1.172 E94
+1 4 9 7.041 1.338 E94
+0 4 10 6.824 1.345 E94
+0 4 15 4.330 1.690 E94
+0 4 20 5.178 1.436 E94
+0 4 22 5.400 1.426 E94
+0 4 30 10.227 1.282 E94
+1 4 37 5.445 1.424 E94
+0 4 42 16.582 1.160 #X94
+0 4 43 6.947 1.341 E94
+1 4 63 5.633 1.416 E94
+1 4 64 5.492 1.422 E94
+0 5 19 2.254 1.485 X94
+0 5 20 4.852 1.093 C94
+0 5 22 5.191 1.082 C94
+0 5 30 5.176 1.086 C94
+0 5 37 5.306 1.084 C94
+0 5 41 3.256 1.144 C94
+0 5 57 5.633 1.076 C94
+0 5 63 5.531 1.080 C94
+0 5 64 5.506 1.080 C94
+0 5 78 5.506 1.080 C94
+0 5 80 5.633 1.076 C94
+0 6 6 4.088 1.449 E94
+0 6 8 5.059 1.450 C94
+0 6 9 4.491 1.395 E94
+0 6 10 5.982 1.410 C94
+0 6 15 4.757 1.661 E94
+0 6 17 5.779 1.608 E94
+0 6 18 5.326 1.630 #X94
+0 6 19 4.661 1.660 #X94
+0 6 20 5.623 1.433 C94
+0 6 21 7.794 0.972 C94
+0 6 22 4.556 1.433 E94
+0 6 24 7.403 0.981 C94
+0 6 25 5.243 1.630 #X94
+0 6 26 5.481 1.618 E94
+0 6 29 7.839 0.973 C94
+0 6 30 9.359 1.271 E94
+0 6 33 7.143 0.986 X94
+0 6 37 5.614 1.376 C94
+0 6 39 4.629 1.388 E94
+0 6 40 4.609 1.389 E94
+0 6 41 6.754 1.342 E94
+0 6 43 3.937 1.426 E94
+0 6 45 4.321 1.404 X94
+0 6 54 5.117 1.365 E94
+0 6 55 4.772 1.381 E94
+0 6 57 7.128 1.330 E94
+0 6 58 4.792 1.380 E94
+0 6 63 7.324 1.324 E94
+0 6 64 6.664 1.345 E94
+0 7 17 8.770 1.500 #X94
+0 7 46 9.329 1.235 X94
+0 7 74 9.129 1.490 #X94
+0 8 8 3.264 1.420 E94
+0 8 9 4.581 1.342 E94
+0 8 10 3.909 1.378 E94
+0 8 12 3.371 1.761 E94
+0 8 15 4.060 1.652 E94
+0 8 17 3.901 1.663 E94
+0 8 19 4.254 1.700 E94
+0 8 20 5.107 1.456 C94
+0 8 22 4.223 1.457 E94
+0 8 23 6.490 1.019 C94
+0 8 25 4.629 1.660 E94
+0 8 26 4.027 1.699 E94
+0 8 34 3.775 1.386 E94
+0 8 39 3.435 1.408 E94
+0 8 40 3.710 1.390 E94
+0 8 43 3.977 1.374 E94
+0 8 45 4.267 1.358 E94
+0 8 46 5.519 1.301 E94
+0 8 55 4.229 1.360 E94
+0 8 56 3.995 1.373 E94
+0 9 9 7.256 1.243 E94
+1 9 9 3.808 1.384 E94
+0 9 10 4.480 1.347 E94
+0 9 12 3.635 1.739 E94
+0 9 15 3.791 1.671 E94
+0 9 18 4.465 1.626 E94
+0 9 19 3.687 1.741 E94
+0 9 20 4.401 1.447 E94
+0 9 25 5.379 1.619 E94
+0 9 27 6.230 1.026 C94
+0 9 34 3.223 1.423 E94
+0 9 35 5.095 1.366 E94
+1 9 37 5.529 1.393 E94
+1 9 39 4.685 1.337 E94
+0 9 40 4.382 1.352 E94
+0 9 41 5.650 1.388 E94
+0 9 45 4.857 1.329 E94
+0 9 53 7.291 1.242 X94
+0 9 54 4.991 1.323 E94
+0 9 55 3.825 1.383 E94
+0 9 56 4.602 1.341 E94
+1 9 57 6.824 1.345 E94
+0 9 62 4.749 1.334 E94
+1 9 63 6.824 1.345 E94
+1 9 64 5.458 1.396 E94
+0 9 67 6.752 1.258 E94
+1 9 78 6.644 1.351 E94
+1 9 81 3.909 1.378 E94
+0 10 10 3.977 1.374 E94
+0 10 13 3.110 1.878 E94
+0 10 14 1.967 2.029 E94
+0 10 15 3.593 1.686 E94
+0 10 17 3.930 1.661 E94
+0 10 20 4.240 1.456 E94
+0 10 22 4.970 1.418 E94
+0 10 25 3.820 1.714 E94
+0 10 26 3.651 1.727 E94
+0 10 28 6.663 1.015 C94
+0 10 34 3.960 1.375 E94
+0 10 35 4.898 1.375 E94
+0 10 37 5.482 1.395 E94
+0 10 39 4.382 1.352 E94
+0 10 40 3.841 1.382 E94
+0 10 41 7.466 1.325 E94
+0 10 45 3.524 1.402 E94
+0 10 63 6.137 1.369 E94
+0 10 64 5.952 1.376 E94
+0 11 20 6.339 1.348 E94
+0 11 22 5.296 1.389 X94
+0 11 25 6.019 1.583 E94
+0 11 26 6.204 1.575 E94
+0 11 37 6.511 1.342 E94
+0 11 40 4.187 1.440 E94
+0 12 15 2.978 2.031 E94
+0 12 18 2.808 2.051 E94
+0 12 19 2.838 2.050 #X94
+0 12 20 2.859 1.751 C94
+0 12 22 3.056 1.750 #X94
+0 12 25 3.063 2.023 E94
+0 12 26 2.448 2.100 #X94
+0 12 37 3.378 1.721 E94
+0 12 40 3.737 1.731 E94
+0 12 57 3.714 1.694 E94
+0 12 63 3.413 1.718 E94
+0 12 64 3.649 1.699 E94
+0 13 20 2.767 1.920 E94
+0 13 22 2.928 1.902 E94
+0 13 37 3.031 1.891 E94
+0 13 64 3.031 1.891 E94
+0 14 20 0.884 2.332 E94
+0 14 37 1.781 2.075 E94
+0 15 15 2.531 2.050 C94
+0 15 18 2.214 2.094 E94
+0 15 19 2.022 2.146 E94
+0 15 20 2.757 1.822 E94
+0 15 22 3.802 1.727 E94
+0 15 25 2.319 2.112 E94
+0 15 26 2.359 2.106 E94
+0 15 30 3.750 1.731 E94
+0 15 37 3.565 1.765 C94
+0 15 40 3.859 1.666 E94
+0 15 43 3.221 1.717 E94
+0 15 57 3.993 1.713 E94
+0 15 63 3.724 1.733 E94
+0 15 64 3.548 1.747 E94
+0 15 71 4.014 1.341 C94
+0 17 20 2.397 1.865 E94
+0 17 22 2.566 1.844 E94
+0 17 37 3.098 1.787 E94
+0 17 43 4.900 1.601 E94
+0 18 20 3.172 1.780 E94
+0 18 22 2.757 1.822 E94
+0 18 32 10.748 1.450 #X94
+0 18 37 3.281 1.770 X94
+0 18 39 3.504 1.693 X94
+0 18 43 3.301 1.710 #X94
+0 18 48 6.186 1.540 X94
+0 18 55 4.432 1.628 E94
+0 18 58 2.568 1.783 E94
+0 18 62 5.510 1.570 #X94
+0 18 63 3.524 1.749 E94
+0 18 64 3.856 1.723 E94
+0 18 80 4.150 1.702 E94
+0 19 20 2.288 1.900 E94
+0 19 37 3.072 1.809 E94
+0 19 40 4.470 1.686 E94
+0 19 63 3.219 1.795 E94
+0 19 75 1.600 2.226 E94
+0 20 20 3.663 1.526 C94
+0 20 22 4.251 1.484 E94
+0 20 25 2.718 1.838 E94
+0 20 26 2.588 1.853 E94
+0 20 30 3.977 1.507 C94
+0 20 34 4.171 1.460 E94
+0 20 37 3.740 1.516 E94
+0 20 40 4.784 1.427 E94
+0 20 41 4.286 1.482 E94
+0 20 43 3.737 1.487 E94
+0 20 45 3.844 1.480 E94
+0 22 22 3.969 1.499 C94
+0 22 30 3.785 1.513 E94
+0 22 34 4.103 1.464 E94
+0 22 37 4.481 1.471 E94
+0 22 40 4.188 1.459 E94
+0 22 41 5.071 1.441 E94
+0 22 43 4.070 1.466 E94
+0 22 45 4.311 1.452 E94
+0 23 39 7.112 1.012 C94
+0 23 62 6.339 1.026 X94
+0 23 67 6.610 1.019 #E94
+0 23 68 5.899 1.038 C94
+0 25 25 1.514 2.253 E94
+0 25 32 8.296 1.510 #X94
+0 25 37 3.586 1.755 E94
+0 25 39 4.370 1.676 E94
+0 25 40 4.629 1.660 E94
+0 25 43 3.237 1.762 X94
+0 25 57 4.356 1.699 E94
+0 25 63 3.711 1.745 E94
+0 25 71 3.001 1.411 X94
+0 25 72 3.744 1.950 #X94
+0 26 26 1.414 2.279 E94
+0 26 34 3.395 1.748 E94
+0 26 37 3.207 1.788 E94
+0 26 40 4.870 1.646 E94
+0 26 71 2.959 1.415 C94
+0 28 40 6.576 1.018 C94
+0 28 43 6.265 1.028 X94
+0 28 48 6.413 1.024 X94
+0 30 30 9.579 1.343 C94
+1 30 30 5.355 1.428 E94
+0 30 40 8.447 1.298 E94
+1 30 67 5.274 1.404 E94
+0 31 70 7.880 0.969 C94
+0 32 41 9.756 1.261 C94
+0 32 45 9.420 1.233 X94
+0 32 67 7.926 1.269 E94
+0 32 68 4.398 1.348 C94
+0 32 69 6.098 1.261 C94
+0 32 73 8.427 1.510 #X94
+0 32 77 10.648 1.450 #X94
+0 32 82 8.594 1.252 E94
+0 34 36 6.163 1.028 C94
+0 34 37 4.347 1.450 E94
+0 34 43 4.401 1.351 E94
+0 35 37 9.767 1.262 E94
+0 35 63 12.760 1.207 E94
+0 36 54 6.529 1.022 C94
+0 36 55 6.744 1.014 C94
+0 36 56 6.490 1.017 C94
+0 36 58 6.610 1.019 #E94
+0 36 81 6.980 1.016 C94
+0 37 37 5.573 1.374 C94
+1 37 37 5.178 1.436 E94
+0 37 38 5.737 1.333 C94
+0 37 39 5.978 1.375 E94
+1 37 39 5.650 1.388 E94
+0 37 40 6.168 1.398 C94
+0 37 41 4.537 1.468 E94
+0 37 43 4.764 1.428 X94
+0 37 45 4.705 1.431 E94
+0 37 46 6.191 1.367 E94
+0 37 55 6.615 1.352 E94
+0 37 56 5.055 1.414 E94
+1 37 57 5.092 1.440 E94
+0 37 58 7.432 1.326 E94
+1 37 58 5.055 1.414 E94
+0 37 61 5.724 1.385 E94
+0 37 62 7.137 1.335 E94
+0 37 63 6.095 1.372 C94
+1 37 63 5.178 1.436 E94
+0 37 64 6.161 1.379 C94
+1 37 64 5.265 1.432 E94
+1 37 67 4.725 1.430 E94
+0 37 69 5.396 1.352 C94
+0 37 78 6.719 1.375 E94
+0 37 81 3.987 1.471 E94
+1 37 81 4.531 1.440 E94
+0 38 38 5.002 1.246 C94
+0 38 63 7.299 1.330 E94
+0 38 64 6.978 1.340 E94
+0 38 69 5.036 1.321 E94
+0 38 78 6.218 1.366 E94
+0 39 40 4.101 1.367 E94
+0 39 45 3.524 1.402 E94
+0 39 63 6.301 1.364 C94
+1 39 63 6.137 1.369 E94
+0 39 64 6.357 1.361 E94
+1 39 64 5.482 1.395 E94
+0 39 65 5.513 1.339 C94
+0 39 78 6.137 1.369 E94
+0 40 40 4.248 1.359 E94
+0 40 45 4.305 1.356 E94
+0 40 46 4.727 1.335 E94
+0 40 54 6.817 1.256 E94
+0 40 63 6.733 1.348 E94
+0 40 64 6.644 1.351 E94
+0 40 78 5.900 1.378 E94
+0 41 41 5.029 1.443 E94
+0 41 55 5.577 1.391 E94
+0 41 62 7.137 1.335 E94
+0 41 72 4.519 1.678 X94
+0 41 80 5.222 1.434 E94
+0 42 61 16.223 1.087 E94
+0 43 43 4.211 1.361 E94
+0 43 45 3.710 1.390 E94
+0 43 64 5.389 1.399 E94
+0 44 63 3.589 1.717 C94
+0 44 65 3.374 1.684 C94
+0 44 78 3.711 1.734 E94
+0 44 80 3.910 1.719 E94
+0 45 63 5.119 1.411 E94
+0 45 64 5.076 1.413 E94
+0 45 78 5.724 1.385 E94
+0 47 53 12.192 1.140 #X94
+0 49 50 6.812 0.991 C94
+0 51 52 7.100 0.987 X94
+0 55 57 7.227 1.319 C94
+0 55 62 3.977 1.374 E94
+0 55 64 5.529 1.393 E94
+0 55 80 7.500 1.324 E94
+0 56 57 4.137 1.383 C94
+0 56 63 5.900 1.378 E94
+0 56 80 6.470 1.357 E94
+1 57 63 5.400 1.426 E94
+1 57 64 5.135 1.438 E94
+0 58 63 6.794 1.346 E94
+0 58 64 6.164 1.368 E94
+0 59 63 5.787 1.360 C94
+0 59 65 4.756 1.388 C94
+0 59 78 6.127 1.364 E94
+0 59 80 7.064 1.332 E94
+0 59 82 3.855 1.431 E94
+0 60 61 15.749 1.170 #X94
+0 62 63 6.947 1.341 E94
+0 62 64 6.273 1.364 E94
+1 63 63 5.729 1.412 E94
+0 63 64 7.118 1.377 C94
+0 63 66 8.326 1.313 C94
+0 63 72 4.503 1.679 E94
+0 63 78 7.434 1.352 E94
+0 63 81 7.778 1.316 E94
+0 64 64 4.313 1.418 C94
+1 64 64 4.926 1.448 E94
+0 64 65 8.258 1.335 C94
+0 64 66 4.456 1.369 C94
+0 64 78 5.492 1.422 E94
+0 64 81 5.824 1.381 E94
+0 64 82 6.794 1.346 E94
+0 65 66 7.243 1.323 C94
+0 65 78 8.447 1.298 E94
+0 65 81 5.223 1.313 E94
+0 65 82 5.622 1.297 E94
+0 66 66 3.874 1.368 C94
+0 66 78 6.385 1.360 E94
+0 66 81 3.960 1.375 E94
+0 67 67 6.085 1.280 E94
+0 71 75 2.852 1.423 X94
+0 72 73 2.628 2.035 X94
+0 76 76 4.286 1.357 X94
+0 76 78 6.824 1.345 X94
+0 78 78 5.573 1.374 C94
+0 78 79 8.890 1.287 E94
+0 78 81 5.046 1.381 C94
+0 79 79 6.408 1.269 E94
+0 79 81 4.305 1.356 E94
+0 80 81 8.237 1.335 C94
diff --git a/parameters/MMFFCHG.PAR b/parameters/MMFFCHG.PAR
new file mode 100644
index 0000000..d40a34e
--- /dev/null
+++ b/parameters/MMFFCHG.PAR
@@ -0,0 +1,512 @@
+* 14. MMFFCHG.PAR: This file supplies bond-charge-increment parameters used to construct MMFF94 partial atomic charges.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF BOND-CHARGE INCREMENTS - Rev: 26-OCT-94 Source: MMFF94
+* C94 - CORE MMFF94 parameter, obtained from fit to dipole moments
+* #C94 - CORE MMFF94 parameter, either fixed or adjusted to fit
+* HF/6-31G* interaction energies
+* X94 - EXTD MMFF94 parameter, obtained from fit to dipole moments
+* #X94 - EXTD MMFF94 parameter, fixed in the fit to dipole moments
+* E94 - derived from partial bond charge increments (empirical rule)
+*
+* types bci Source
+0 1 1 0.0000 #C94
+0 1 2 -0.1382 C94
+0 1 3 -0.0610 #C94
+0 1 4 -0.2000 #X94
+0 1 5 0.0000 #C94
+0 1 6 -0.2800 #C94
+0 1 8 -0.2700 #C94
+0 1 9 -0.2460 #C94
+0 1 10 -0.3001 C94
+0 1 11 -0.3400 #C94
+0 1 12 -0.2900 #C94
+0 1 13 -0.2300 #X94
+0 1 14 -0.1900 #X94
+0 1 15 -0.2300 #C94
+0 1 17 -0.1935 X94
+0 1 18 -0.1052 X94
+0 1 19 0.0805 X94
+0 1 20 0.0000 #C94
+0 1 22 -0.0950 E94
+0 1 25 0.0000 #X94
+0 1 26 -0.1669 X94
+0 1 34 -0.5030 C94
+0 1 35 -0.4274 X94
+0 1 37 -0.1435 C94
+0 1 39 -0.2556 C94
+0 1 40 -0.3691 C94
+0 1 41 0.1060 #C94
+0 1 43 -0.3557 X94
+0 1 45 -0.2402 X94
+0 1 46 -0.3332 X94
+0 1 54 -0.3461 C94
+0 1 55 -0.4895 C94
+0 1 56 -0.3276 C94
+0 1 57 -0.1050 E94
+0 1 58 -0.4880 E94
+0 1 61 -0.2657 X94
+0 1 62 -0.2000 #X94
+0 1 63 -0.1800 E94
+0 1 64 -0.1810 E94
+0 1 67 -0.0990 E94
+0 1 68 -0.2560 #C94
+0 1 72 -0.5500 #X94
+0 1 73 -0.0877 X94
+0 1 75 -0.2550 E94
+0 1 78 -0.1680 E94
+0 1 80 -0.1440 E94
+0 1 81 -0.5140 E94
+0 2 2 0.0000 #C94
+1 2 2 0.0000 #C94
+1 2 3 -0.0144 C94
+0 2 4 -0.0650 E94
+1 2 4 -0.0650 E94
+0 2 5 0.1500 #C94
+0 2 6 -0.0767 C94
+1 2 9 -0.1710 E94
+0 2 10 -0.1090 E94
+0 2 11 -0.1495 X94
+0 2 12 -0.1400 #X94
+0 2 13 -0.1100 #X94
+0 2 14 -0.0900 #X94
+0 2 15 -0.1010 E94
+0 2 17 -0.0560 E94
+0 2 18 0.0170 E94
+0 2 19 0.2290 E94
+0 2 20 0.1160 E94
+0 2 22 0.0400 E94
+0 2 25 0.1470 E94
+0 2 30 -0.0310 E94
+0 2 34 -0.3560 E94
+0 2 35 -0.3500 #X94
+1 2 37 0.0284 C94
+1 2 39 0.0310 E94
+0 2 40 -0.1000 #C94
+0 2 41 0.2500 #C94
+0 2 43 -0.1910 E94
+0 2 45 -0.2044 X94
+0 2 46 -0.2940 E94
+0 2 55 -0.3410 E94
+0 2 56 -0.3030 E94
+0 2 62 -0.0500 #X94
+1 2 63 -0.0450 E94
+1 2 64 -0.0460 E94
+1 2 67 0.0360 E94
+0 2 72 -0.4500 #X94
+1 2 81 -0.3790 E94
+1 3 3 0.0000 #C94
+1 3 4 -0.1050 E94
+0 3 5 0.0600 #C94
+0 3 6 -0.1500 #C94
+0 3 7 -0.5700 #C94
+0 3 9 -0.4500 #C94
+1 3 9 -0.2110 E94
+0 3 10 -0.0600 C94
+0 3 11 -0.2220 E94
+0 3 12 -0.2090 E94
+0 3 15 -0.1410 E94
+0 3 16 -0.3800 #X94
+0 3 17 -0.0960 E94
+0 3 18 -0.0230 E94
+0 3 20 0.0530 #C94
+0 3 22 0.0000 E94
+0 3 25 0.1070 E94
+1 3 30 -0.0710 E94
+0 3 35 -0.3610 E94
+1 3 37 0.0862 C94
+1 3 39 -0.0090 E94
+0 3 40 -0.0500 #C94
+0 3 41 0.1470 E94
+0 3 43 -0.2363 X94
+0 3 45 -0.1650 E94
+0 3 48 -0.4300 E94
+0 3 51 -0.9500 #X94
+0 3 53 -0.0134 X94
+0 3 54 -0.4000 #C94
+1 3 54 -0.3290 E94
+0 3 55 -0.3810 E94
+0 3 56 -0.3430 E94
+1 3 57 -0.0100 E94
+1 3 58 -0.3930 E94
+0 3 62 -0.0300 E94
+1 3 63 -0.0850 E94
+1 3 64 -0.0860 E94
+0 3 67 -0.0040 E94
+0 3 74 -0.3190 X94
+0 3 75 -0.2474 X94
+1 3 78 -0.0730 E94
+1 3 80 -0.0490 E94
+0 4 5 0.1770 E94
+0 4 6 -0.0430 E94
+0 4 7 -0.4870 E94
+0 4 9 -0.3000 E94
+1 4 9 -0.1060 E94
+0 4 10 -0.0440 E94
+0 4 15 -0.0360 E94
+0 4 20 0.1810 E94
+0 4 22 0.1050 E94
+0 4 30 0.0340 E94
+1 4 37 0.0730 E94
+0 4 40 -0.0640 E94
+0 4 42 -0.5571 X94
+0 4 43 -0.1260 E94
+1 4 63 0.0200 E94
+1 4 64 0.0190 E94
+0 5 19 0.2000 #X94
+0 5 20 0.0000 #C94
+0 5 22 -0.1000 #C94
+0 5 30 -0.1500 #C94
+0 5 37 -0.1500 #C94
+0 5 41 0.2203 C94
+0 5 57 -0.1500 #C94
+0 5 63 -0.1500 #C94
+0 5 64 -0.1500 #C94
+0 5 78 -0.1500 #C94
+0 5 80 -0.1500 #C94
+0 6 6 0.0000 #C94
+0 6 8 -0.1000 #C94
+0 6 9 -0.0630 E94
+0 6 10 0.0355 C94
+0 6 15 0.0070 E94
+0 6 17 0.0520 E94
+0 6 18 0.1837 X94
+0 6 19 0.2974 X94
+0 6 20 0.2579 C94
+0 6 21 0.4000 #C94
+0 6 22 0.1480 E94
+0 6 24 0.5000 #C94
+0 6 25 0.2712 X94
+0 6 26 0.1010 E94
+0 6 29 0.4500 #C94
+0 6 30 0.0770 E94
+0 6 33 0.5000 #X94
+0 6 37 0.0825 C94
+0 6 39 0.1390 E94
+0 6 40 -0.0210 E94
+0 6 41 0.2950 E94
+0 6 43 -0.0830 E94
+0 6 45 -0.0090 X94
+0 6 54 -0.1810 E94
+0 6 55 -0.2330 E94
+0 6 57 0.1380 E94
+0 6 58 -0.2450 E94
+0 6 63 0.0630 E94
+0 6 64 0.0620 E94
+0 7 17 0.5000 #X94
+0 7 46 0.1618 X94
+0 7 74 0.5000 #X94
+0 8 8 0.0000 #C94
+0 8 9 -0.0530 E94
+0 8 10 0.0090 E94
+0 8 12 -0.0510 E94
+0 8 15 0.0170 E94
+0 8 17 0.0620 E94
+0 8 19 0.3470 E94
+0 8 20 0.2096 C94
+0 8 22 0.1580 E94
+0 8 23 0.3600 #C94
+0 8 25 0.2679 X94
+0 8 26 0.1110 E94
+0 8 34 -0.2380 E94
+0 8 39 0.1490 E94
+0 8 40 -0.0110 E94
+0 8 43 -0.0730 E94
+0 8 45 -0.0070 E94
+0 8 46 -0.1760 E94
+0 8 55 -0.2230 E94
+0 8 56 -0.1850 E94
+0 9 9 0.0000 #C94
+0 9 10 0.0620 E94
+0 9 12 0.0020 E94
+0 9 15 0.0700 E94
+0 9 18 0.1880 E94
+0 9 19 0.4000 E94
+0 9 20 0.2870 E94
+0 9 25 0.3180 E94
+0 9 27 0.4000 #C94
+0 9 34 -0.1850 E94
+0 9 35 -0.1500 E94
+1 9 37 0.1790 E94
+1 9 39 0.2020 E94
+0 9 40 0.0420 E94
+0 9 41 0.3580 E94
+0 9 45 0.0460 E94
+0 9 53 0.3179 X94
+0 9 54 -0.1180 E94
+0 9 55 -0.1700 E94
+0 9 56 -0.1320 E94
+1 9 57 0.2010 E94
+0 9 62 0.1810 E94
+1 9 63 0.1260 E94
+1 9 64 0.1250 E94
+0 9 67 0.2070 E94
+1 9 78 0.1380 E94
+1 9 81 -0.2080 E94
+0 10 10 0.0000 #C94
+0 10 13 0.0060 E94
+0 10 14 0.0360 E94
+0 10 15 0.0080 E94
+0 10 17 0.0530 E94
+0 10 20 0.2250 E94
+0 10 22 0.1490 E94
+0 10 25 0.2560 E94
+0 10 26 0.1020 E94
+0 10 28 0.3700 #C94
+0 10 34 -0.2470 E94
+0 10 35 -0.2120 E94
+0 10 37 0.1170 E94
+0 10 39 0.1400 E94
+0 10 40 -0.0200 E94
+0 10 41 0.2960 E94
+0 10 45 -0.0160 E94
+0 10 63 0.0640 E94
+0 10 64 0.0630 E94
+0 11 20 0.2980 E94
+0 11 22 0.2317 X94
+0 11 25 0.3290 E94
+0 11 26 0.1750 E94
+0 11 37 0.1900 E94
+0 11 40 0.0530 E94
+0 12 15 0.0680 E94
+0 12 18 0.1860 E94
+0 12 19 0.3701 X94
+0 12 20 0.2900 #C94
+0 12 22 0.2273 X94
+0 12 25 0.3160 E94
+0 12 26 0.2112 X94
+0 12 37 0.1770 E94
+0 12 40 0.0400 E94
+0 12 57 0.1990 E94
+0 12 63 0.1240 E94
+0 12 64 0.1230 E94
+0 13 20 0.2190 E94
+0 13 22 0.1430 E94
+0 13 37 0.1110 E94
+0 13 64 0.0570 E94
+0 14 20 0.1890 E94
+0 14 37 0.0810 E94
+0 15 15 0.0000 #C94
+0 15 18 0.1180 E94
+0 15 19 0.3300 E94
+0 15 20 0.2170 E94
+0 15 22 0.1410 E94
+0 15 25 0.2480 E94
+0 15 26 0.0940 E94
+0 15 30 0.0700 E94
+0 15 37 0.1015 C94
+0 15 40 -0.0280 E94
+0 15 43 -0.0900 E94
+0 15 57 0.1310 E94
+0 15 63 0.0560 E94
+0 15 64 0.0550 E94
+0 15 71 0.1800 #C94
+0 16 16 0.0000 #C94
+0 17 17 0.0000 #X94
+0 17 20 0.1720 E94
+0 17 22 0.0960 E94
+0 17 37 0.0640 E94
+0 17 43 -0.1350 E94
+0 18 18 0.0000 #X94
+0 18 20 0.0990 E94
+0 18 22 0.0230 E94
+0 18 32 -0.6500 #X94
+0 18 37 -0.0090 E94
+0 18 39 0.0140 E94
+0 18 43 -0.1380 X94
+0 18 48 -0.5895 X94
+0 18 55 -0.3580 E94
+0 18 58 -0.3700 E94
+0 18 62 0.2099 X94
+0 18 63 -0.0620 E94
+0 18 64 -0.0630 E94
+0 18 80 -0.0260 E94
+0 19 19 0.0000 #X94
+0 19 20 -0.1130 E94
+0 19 37 -0.2210 E94
+0 19 40 -0.3580 E94
+0 19 63 -0.2740 E94
+0 19 75 -0.3490 E94
+0 20 20 0.0000 #C94
+0 20 22 -0.0760 E94
+0 20 25 0.0310 E94
+0 20 26 -0.1230 E94
+0 20 30 -0.1380 #C94
+0 20 34 -0.4720 E94
+0 20 37 -0.1080 E94
+0 20 40 -0.2450 E94
+0 20 41 0.0710 E94
+0 20 43 -0.3070 E94
+0 20 45 -0.2410 E94
+0 22 22 0.0000 #C94
+0 22 30 -0.0710 E94
+0 22 34 -0.3960 E94
+0 22 37 -0.0320 E94
+0 22 40 -0.1690 E94
+0 22 41 0.1470 E94
+0 22 43 -0.2310 E94
+0 22 45 -0.1650 E94
+0 23 39 -0.2700 #C94
+0 23 62 -0.4000 #X94
+0 23 67 -0.2920 E94
+0 23 68 -0.3600 #C94
+0 25 25 0.0000 #X94
+0 25 32 -0.7000 #X94
+0 25 37 -0.1390 E94
+0 25 39 -0.1160 E94
+0 25 40 -0.2760 E94
+0 25 43 -0.3380 E94
+0 25 57 -0.1170 E94
+0 25 63 -0.1920 E94
+0 25 71 -0.0362 X94
+0 25 72 -0.6773 X94
+0 26 26 0.0000 #X94
+0 26 34 -0.3490 E94
+0 26 37 0.0150 E94
+0 26 40 -0.1220 E94
+0 26 71 0.0960 X94
+0 28 40 -0.4000 #C94
+0 28 43 -0.4200 #X94
+0 28 48 -0.4000 #X94
+0 30 30 0.0000 #C94
+0 30 40 -0.0980 E94
+1 30 67 0.0670 E94
+0 31 70 -0.4300 #C94
+0 32 41 0.6500 #C94
+0 32 45 0.5200 #X94
+0 32 67 0.6330 E94
+0 32 68 0.7500 #C94
+0 32 69 0.7500 #C94
+0 32 73 0.3500 #X94
+0 32 77 0.4500 #X94
+0 32 82 0.6330 E94
+0 34 36 0.4500 #C94
+0 34 37 0.3640 E94
+0 34 43 0.1650 E94
+0 35 37 0.3290 E94
+0 35 63 0.2760 E94
+0 36 54 -0.4000 #C94
+0 36 55 -0.4500 #C94
+0 36 56 -0.4500 #C94
+0 36 58 -0.4570 E94
+4 36 58 -0.4500 #C94
+0 36 81 -0.4500 #C94
+0 37 37 0.0000 #C94
+1 37 37 0.0000 #C94
+0 37 38 -0.3100 #C94
+0 37 39 0.0230 E94
+1 37 39 0.0230 E94
+0 37 40 -0.1000 #C94
+0 37 41 0.1790 E94
+0 37 43 -0.1990 E94
+0 37 45 -0.1330 E94
+0 37 46 -0.3020 E94
+0 37 55 -0.3490 E94
+0 37 56 -0.3110 E94
+1 37 57 0.0220 E94
+0 37 58 -0.3610 E94
+1 37 58 -0.3610 E94
+4 37 58 -0.3500 #C94
+0 37 61 -0.1380 E94
+0 37 62 0.0020 E94
+0 37 63 0.0000 #C94
+1 37 63 -0.0530 E94
+0 37 64 0.0000 #C94
+1 37 64 -0.0540 E94
+1 37 67 0.0280 E94
+0 37 69 -0.0895 C94
+0 37 78 -0.0410 E94
+0 37 81 -0.3870 E94
+1 37 81 -0.3870 E94
+0 38 38 0.0000 #C94
+0 38 63 0.2570 E94
+0 38 64 0.2560 E94
+0 38 69 0.3380 E94
+0 38 78 0.2690 E94
+1 39 39 0.0000 #C94
+0 39 40 -0.1600 E94
+0 39 45 -0.1560 E94
+0 39 63 -0.1516 C94
+1 39 63 -0.0760 E94
+0 39 64 -0.0770 E94
+1 39 64 -0.0770 E94
+0 39 65 -0.4180 C94
+0 39 78 -0.0640 E94
+0 40 40 0.0000 #C94
+0 40 45 0.0040 E94
+0 40 46 -0.1650 E94
+0 40 54 -0.1600 E94
+0 40 63 0.0840 E94
+0 40 64 0.0830 E94
+0 40 78 0.0960 E94
+0 41 41 0.0000 #C94
+0 41 55 -0.5280 E94
+0 41 62 -0.1770 E94
+0 41 72 -0.5000 #X94
+0 41 80 -0.1960 E94
+0 42 61 0.4920 E94
+0 43 43 0.0000 #X94
+0 43 45 0.0660 E94
+0 43 64 0.1450 E94
+0 44 63 0.0400 #C94
+0 44 65 -0.2207 C94
+0 44 78 0.0690 E94
+0 44 80 0.0930 E94
+0 45 63 0.0800 E94
+0 45 64 0.0790 E94
+0 45 78 0.0920 E94
+0 47 53 0.3700 #X94
+0 49 50 0.5673 C94
+0 51 52 0.5000 #X94
+0 55 57 0.3544 C94
+0 55 62 0.3510 E94
+0 55 64 0.2950 E94
+0 55 80 0.3320 E94
+0 56 57 0.4000 #C94
+0 56 63 0.2580 E94
+0 56 80 0.2700 E94
+4 57 58 -0.4000 #C94
+1 57 63 -0.0750 E94
+1 57 64 -0.0760 E94
+0 58 63 0.3080 E94
+0 58 64 0.3070 E94
+0 59 63 0.1400 #C94
+0 59 65 -0.1209 C94
+0 59 78 0.1690 E94
+0 59 80 0.1930 E94
+0 59 82 0.2380 E94
+0 60 61 0.3700 #X94
+0 62 63 -0.0550 E94
+0 62 64 -0.0560 E94
+0 63 63 0.0000 #C94
+1 63 63 0.0000 #C94
+0 63 64 0.0000 #C94
+0 63 66 -0.3381 C94
+0 63 72 -0.4000 E94
+0 63 78 0.0120 E94
+0 63 81 -0.3340 E94
+0 64 64 0.0000 #C94
+0 64 65 -0.2888 C94
+0 64 66 -0.2272 C94
+0 64 78 0.0130 E94
+0 64 81 -0.3330 E94
+0 64 82 0.0820 E94
+0 65 66 0.0000 #C94
+0 65 78 0.3070 E94
+0 65 81 -0.0390 E94
+0 65 82 0.3760 E94
+0 66 66 0.0000 #C94
+0 66 78 0.2990 E94
+0 66 81 -0.0470 E94
+0 71 75 -0.0958 X94
+0 72 73 0.4500 #X94
+0 76 76 0.0000 #X94
+0 76 78 0.4000 #X94
+0 78 78 0.0000 #C94
+1 78 78 0.0000 #C94
+0 78 79 -0.3030 E94
+0 78 81 -0.3500 #C94
+0 79 81 -0.0430 E94
+0 80 81 -0.4000 #C94
diff --git a/parameters/MMFFDEF.PAR b/parameters/MMFFDEF.PAR
new file mode 100644
index 0000000..a5c1ac9
--- /dev/null
+++ b/parameters/MMFFDEF.PAR
@@ -0,0 +1,193 @@
+* 2. MMFFDEF.PAR: This file supplies the atom-type equivalences used in the
+* matching of parameters to force-field interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* PRIMARY
+* MMFF MMFF
+*SYMBOL TYPE DEFAULT TYPES DEFINITION
+*
+ CR 1 1 1 1 0 ALKYL CARBON
+ C=C 2 2 2 1 0 VINYLIC
+* CSP2 2 2 2 1 0 GENERIC CSP2
+* CGD 2 2 2 1 0 GUANIDINE CARBON
+ C=O 3 3 3 1 0 GENERAL CARBONYL C
+* C=N 3 3 3 1 0 C=N
+* C=OR 3 3 3 1 0 KETONE OR ALDEHYDE CO
+* C=ON 3 3 3 1 0 AMIDE CARBONYL
+* COO 3 3 3 1 0 CARBOXYLIC ACID OF EST
+* COON 3 3 3 1 0 CARBAMATE CARBONYL
+* COOO 3 3 3 1 0 CARBONIC ACID OR ESTER
+* C=OS 3 3 3 1 0 THIOESTER, C=O
+* C=S 3 3 3 1 0 THIOESTER, C=S
+* C=SN 3 3 3 1 0 THIOAMIDE
+* CSO2 3 3 3 1 0 CARBON IN >C=SO2
+ CSP 4 4 4 1 0 ACETYLENIC C
+* =C= 4 4 4 1 0 ALLENIC C
+ HC 5 5 5 5 0 H-C
+* HSI 5 5 5 5 0 H-SI
+* HP 5 5 5 5 0 H-P
+ OR 6 6 6 6 0 O-CSP3
+* OH2 6 6 6 6 0 OXYGEN IN H2O
+* OC=O 6 6 6 6 0 ESTER OR ACID -O-
+* OC=C 6 6 6 6 0 ENOL OR PHEMOLIC O
+* OC=N 6 6 6 6 0 OXYGEN IN -O-C=N MOIETY
+* OSO3 6 6 6 6 0 DIVALENT O IN SULFATE
+* OSO2 6 6 6 6 0 DIVALENT O IN SULFITE
+* OSO 6 6 6 6 0 PAIR OF DIVALENT O ON S
+* -OS 6 6 6 6 0 OTHER DIVALENT O ON S
+* OPO3 6 6 6 6 0 DIVALENT O IN PHOSPHATE
+* OPO2 6 6 6 6 0 DIVALENT O IN PHOSPHITE
+* OPO 6 6 6 6 0 PAIR OF DIVALENT O ON P
+* -OP 6 6 6 6 0 OTHER DIVALENT O ON P
+* -O- 6 6 6 6 0 GENERAL DIVALENT OX
+ O=C 7 7 7 6 0 O=C, GENERIC
+* O=CN 7 7 7 6 0 O=C IN AMIDES
+* O=CR 7 7 7 6 0 O=C IN KET, ALD
+* O=CO 7 7 7 6 0 O=C IN ACIDS, ESTERS
+* O=S 7 7 7 6 0 TERMINAL O SULFOXIDES
+* O=N 7 7 7 6 0 NITROSO-GROUP OXYGEN
+ NR 8 8 8 8 0 AMINE N
+ N=C 9 9 9 8 0 N=C, IMINES
+* N=N 9 9 9 8 0 N=N, AZO COMPOUNDS
+ NC=O 10 10 10 8 0 N-C=O, AMIDES
+* NC=S 10 10 10 8 0 N-C=S (DELOC LP)
+* NN=C 10 10 10 8 0 N-N=C (DELOC LP)
+* NN=N 10 10 10 8 0 N-N=N (DELOC LP)
+ F 11 11 11 11 0 FLUORINE
+ CL 12 12 12 12 0 CHLORINE
+ BR 13 13 13 13 0 BROMINE
+ I 14 14 14 14 0 IODINE
+ S 15 15 15 15 0 THIOL, SULFIDE
+ S=C 16 16 16 15 0 S DOUBLY BONDED TO C
+ S=O 17 17 17 15 0 SULFOXIDE S
+ SO2 18 18 18 15 0 SULFONE S
+* SO2N 18 18 18 15 0 SULFONAMIDE S
+* SO3 18 18 18 15 0 SULFONATE S
+* =SO2 18 18 18 15 0 OXYGENATED SULFONE S
+* SNO 18 18 18 15 0 NITROGEN ANALOG OF SO2
+ SI 19 19 19 19 0 SILICON
+ CR4R 20 20 1 1 0 C IN CYCLOBUTYL
+ HOR 21 21 21 5 0 H-O, ALCOHOLS
+* HO 21 21 21 5 0 GENERAL H ON O
+ CR3R 22 22 22 1 0 C IN CYCLOPROPLY
+ HNR 23 23 23 5 0 H-N, AMINES
+* H3N 23 23 23 5 0 H, AMMONIA
+* HPYL 23 23 23 5 0 H-N IN PYRROLE
+* HN 23 23 23 5 0 GENERAL H-N
+ HOCO 24 24 24 5 0 H-O, ACIDS
+* HOP 24 21 21 5 0 H-O-P, PHOS ACIDS
+ PO4 25 25 25 25 0 PHOSPHODIESTER
+* PO3 25 25 25 25 0 TETRACRD P, 3 OXYGENS
+* PO2 25 25 25 25 0 TETRACRD P, 2 OXYGENS
+* PO 25 25 25 25 0 TETRACRD P, 2 OXYGENS
+* PTET 25 25 25 25 0 GENERAL TETRACRD P
+ P 26 26 26 25 0 TRICOORDINATE P
+ HN=C 27 27 28 5 0 IMINE N-H
+* HN=N 27 27 28 5 0 AZO N-H
+ HNCO 28 28 28 5 0 H-N, AMIDES
+* HNCC 28 28 28 5 0 H-N, ENAMINES
+* HNCS 28 28 28 5 0 H-N, THIOAMIDES
+* HNCN 28 28 28 5 0 H-N, HN-C=N
+* HNNC 28 28 28 5 0 H-N, HN-N=C
+* HNNN 28 28 28 5 0 H-N, HN-N=N
+* HSP2 28 28 28 5 0 GENERAL H ON SP2 N
+ HOCC 29 29 29 5 0 H-O, ENOLS, PHENOLS
+* HOCN 29 29 29 5 0 H-O IN HO-C=N
+ CE4R 30 30 2 1 0 C=C IN 4-RING
+ HOH 31 31 31 31 0 H-OH
+ O2CM 32 32 7 6 0 O, CARBOXYLATE ANION
+* OXN 32 32 7 6 0 OXIDE ON NITROHGEN
+* O2N 32 32 7 6 0 NITRO-GROUP OXYGEN
+* O2NO 32 32 7 6 0 NITRO-GROUP IN NITRATE
+* O3N 32 32 7 6 0 NITRATE ANION OXYGEN
+* O-S 32 32 7 6 0 SINGLE TERM O ON TET S
+* O2S 32 32 7 6 0 SULFONES, SULFONAMIDES
+* O3S 32 32 7 6 0 SULFONATES, TERM OX
+* O4S 32 32 7 6 0 SO4(3-)
+* OSMS 32 32 7 6 0 THIOSULFINATE O (-1/2)
+* OP 32 32 7 6 0 TERMINAL O, O-P
+* O2P 32 32 7 6 0 TERMINAL O, O2P GROUP
+* O3P 32 32 7 6 0 TERMINAL O, O3P GROUP
+* O4P 32 32 7 6 0 TERMINAL O, PO4(-3)
+* O4CL 32 32 7 6 0 TERMINAL O IN CLO4(-)
+ HOS 33 33 21 5 0 H-O-S, SULF ACIDS
+ NR+ 34 34 8 8 0 N+, QUATERNARY N
+ OM 35 35 6 6 0 OXIDE OXYGEN ON SP3 C
+* OM2 35 35 6 6 0 OXIDE OXYGEN ON SP2 C
+ HNR+ 36 36 36 5 0 H-N+
+* HNN+ 36 36 36 5 0 H ON IMIDAZOLIUM N
+* HNC+ 36 36 36 5 0 H ON PROTONATED N+=C-N
+* HGD+ 36 36 36 5 0 H ON GUANIDINIUM N
+ CB 37 37 2 1 0 AROMATIC C
+ NPYD 38 38 9 8 0 AROMATIC N, PYRIDINE
+ NPYL 39 39 10 8 0 AROMATIC N, PYRROLE
+ NC=C 40 40 10 8 0 N-C=C (DELOC LP)
+* NC=N 40 40 10 8 0 N-C=N (DELOC LP)
+ CO2M 41 41 3 1 0 C IN CO2- ANION
+* CS2M 41 41 3 1 0 THIOCARBOXYLATE C
+ NSP 42 42 42 8 0 N TRIPLE BONDED
+ NSO2 43 43 10 8 0 N, SULFONAMIDES
+ STHI 44 44 16 15 0 S IN THIOPHENE
+ NO2 45 45 10 8 0 NITRO GROUP N
+* NO3 45 45 10 8 0 NITRATE GROUP N
+ N=O 46 46 9 8 0 NITROSO GROUP N
+ NAZT 47 47 42 8 0 TERMINAL N, AZIDE
+ NSO 48 48 9 8 0 DIVAL. N IN S(N)(O) GP
+ O+ 49 49 6 6 0 OXONIUM (TRICOORD) O
+ HO+ 50 50 21 5 0 H ON OXONIUM OXYGEN
+ O=+ 51 51 7 6 0 OXENIUM OXYGEN+
+ HO=+ 52 52 21 5 0 H ON OXENIUM O+
+ =N= 53 53 42 8 0 N TWICE DOUBLE BONDED
+ N+=C 54 54 9 8 0 IMINIUM NITROGEN
+* N+=N 54 54 9 8 0 AZONIUM NITROGEN
+ NCN+ 55 55 10 8 0 N IN +N=C-N: ; Q=1/2
+ NGD+ 56 56 10 8 0 GUANIDINIUM N; Q=1/3
+ CGD+ 57 57 2 1 0 GUANIDINIUM CARBON
+* CNN+ 57 57 2 1 0 C IN +N=C-N RESONANCE
+ NPD+ 58 58 10 8 0 N PYRIDINIUM ION
+ OFUR 59 59 6 6 0 AROMATIC O, FURAN
+ C% 60 60 4 1 0 ISONITRILE CARBON
+ NR% 61 61 42 8 0 ISONITRILE N
+ NM 62 62 10 8 0 SULFONAMIDE N-
+ C5A 63 63 2 1 0 ALPHA AROM 5-RING C
+ C5B 64 64 2 1 0 BETA AROM 5-RING C
+ N5A 65 65 9 8 0 ALPHA AROM 5-RING N
+ N5B 66 66 9 8 0 ALPHA AROM 5-RING N
+ N2OX 67 67 9 8 0 NITROGEN IN N-OXIDE
+ N3OX 68 68 8 8 0 NITROGEN IN N-OXIDE
+ NPOX 69 69 9 8 0 NITROGEN IN N-OXIDE
+ OH2 70 70 70 70 70 OXYGEN IN WATER
+ HS 71 71 5 5 0 H-S
+ S2CM 72 72 16 15 0 THIOCARBOXYLATE S
+* S-P 72 72 16 15 0 TERMINAL SULFUR ON P
+* SM 72 72 16 15 0 TERMINAL SULFUR ON C
+* SSMO 72 72 16 15 0 TERM S, THIOSULFINATE
+ SO2M 73 73 18 15 0 SULFUR IN SULFINATE
+* SSOM 73 73 18 15 0 SULFUR, THIOSULFINATE
+ =S=O 74 74 17 15 0 SULFINYL SULFUR, C=S=O
+ -P=C 75 75 26 25 0 P DOUBLY BONDED TO C
+ N5M 76 76 9 8 0 NEG N IN TETRAZOLE AN
+ CLO4 77 77 12 12 0 CHLORINE IN CLO4(-)
+ C5 78 78 2 1 0 GENERAL AROM 5-RING C
+ N5 79 79 9 8 0 GENERAL AROM 5-RING N
+ CIM+ 80 80 2 1 0 C IN N-C-N, IM+ ION
+ NIM+ 81 81 10 8 0 N IN N-C-N, IM+ ION
+ N5AX 82 82 9 8 0 5R NITROGEN IN N-OXIDE
+* N5BX 82 82 9 8 0 5R NITROGEN IN N-OXIDE
+* N5OX 82 82 9 8 0 5R NITROGEN IN N-OXIDE
+ FE+2 87 87 87 87 87 IRON +2 CATION
+ FE+3 88 88 88 88 88 IRON +3 CATION
+ F- 89 89 89 89 89 FLUORIDE ANION
+ CL- 90 90 90 90 90 CHLORIDE ANION
+ BR- 91 91 91 91 91 BROMIDE ANION
+ LI+ 92 92 92 92 92 LITHIUM CATION
+ NA+ 93 93 93 93 93 SODIUM CATION
+ K+ 94 94 94 94 94 POTASSIUM CATION
+ ZN+2 95 95 95 95 95 DIPOSITIVE ZINC CATION
+* ZINC 95 95 95 95 95 DIPOSITIVE ZINC CATION
+ CA+2 96 96 96 96 96 DIPOSITIVE CALCIUM CATION
+ CU+1 97 97 97 97 97 MONOPOSITIVE COPPER CATION
+ CU+2 98 98 98 98 98 DIPOSITIVE COPPER CATION
+ MG+2 99 99 99 99 99 DIPOSITIVE MAGNESIUM CATION
diff --git a/parameters/MMFFDFSB.PAR b/parameters/MMFFDFSB.PAR
new file mode 100644
index 0000000..b593d5b
--- /dev/null
+++ b/parameters/MMFFDFSB.PAR
@@ -0,0 +1,39 @@
+* 10. MMFFDFSB.PAR: This file supplies default parameters for stretch-bend interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF Default Stretch-Bend Parameters
+* Row in
+* Periodic Table
+* IR JR KR F(I_J,K) F(K_J,I)
+ 0 1 0 0.15 0.15
+ 0 1 1 0.10 0.30
+ 0 1 2 0.05 0.35
+ 0 1 3 0.05 0.35
+ 0 1 4 0.05 0.35
+ 0 2 0 0.00 0.00
+ 0 2 1 0.00 0.15
+ 0 2 2 0.00 0.15
+ 0 2 3 0.00 0.15
+ 0 2 4 0.00 0.15
+ 1 1 1 0.30 0.30
+ 1 1 2 0.30 0.50
+ 1 1 3 0.30 0.50
+ 1 1 4 0.30 0.50
+ 2 1 2 0.50 0.50
+ 2 1 3 0.50 0.50
+ 2 1 4 0.50 0.50
+ 3 1 3 0.50 0.50
+ 3 1 4 0.50 0.50
+ 4 1 4 0.50 0.50
+ 1 2 1 0.30 0.30
+ 1 2 2 0.25 0.25
+ 1 2 3 0.25 0.25
+ 1 2 4 0.25 0.25
+ 2 2 2 0.25 0.25
+ 2 2 3 0.25 0.25
+ 2 2 4 0.25 0.25
+ 3 2 3 0.25 0.25
+ 3 2 4 0.25 0.25
+ 4 2 4 0.25 0.25
diff --git a/parameters/MMFFHDEF.PAR b/parameters/MMFFHDEF.PAR
new file mode 100644
index 0000000..f366f1b
--- /dev/null
+++ b/parameters/MMFFHDEF.PAR
@@ -0,0 +1,114 @@
+* 4. MMFFHDEF.PAR: This file relates symbolic atom types for hydrogen atoms to
+* the atom type of the non-hydrogen parent atom to which each
+* is attached.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF SYMBOLIC TYPES FOR HYDROGEN FOR SPECIFIED PARENT TYPES
+*
+* PARENT HYDROGEN
+* TYPE TYPE
+*
+ CR HC
+ C=C HC
+ CSP2 HC
+ C=O HC
+ C=N HC
+ CGD HC
+ C=OR HC
+ C=ON HC
+ CONN HC
+ COO HC
+ COON HC
+ COOO HC
+ C=OS HC
+ C=S HC
+ C=SN HC
+ CSO2 HC
+ C=SO HC
+ CSS HC
+ C=P HC
+ CSP HC
+ =C= HC
+ OR HOR
+ OC=O HOCO
+ OC=C HOCC
+ OC=N HOCN
+ OC=S HOCS ! NEW
+ ONO2 HON ! NEW
+ ON=O HON ! NEW
+ OSO3 HOS
+ OSO2 HOS
+ OSO HOS
+ OS=O HOS
+ -OS HOS
+ OPO3 HOP
+ OPO2 HOP
+ OPO HOP
+ -OP HOP
+ -O- HO
+ NR HNR
+ N=C HN=C
+ N=N HN=C
+ NC=O HNCO
+ NC%N HNC%
+ NC%C HNC%
+ NC=S HNCS
+ NN=C HNNC
+ NN=N HNNN
+ F HX
+ CL HX
+ BR HX
+ I HX
+ S HS
+ >S=N HS=N
+ SNO HSNO
+ SI HSI
+ CR4R HC
+ CR3R HC
+ PO3 HP
+ PO2 HP
+ PO HP
+ PTET HP
+ P HP
+ CE4R HC
+ NR+ HNR+
+ OM HOM
+ CB HC
+ NPYL HPYL
+ NC=C HNCC
+ NC=N HNCN
+ CO2M HC
+ CS2M HC
+ NSO2 HNSO
+ NSO3 HNSO
+ NPO2 HNPO
+ NPO3 HNPO
+ NO2 HNO2
+ N=O HNO
+ NSO HNSO
+ O+ HO+
+ O=+ HO=+
+ O%+ HO%+
+ N+=C HNC+
+ N+=N HNN+ ! NEW
+ NCN+ HNN+
+ NGD+ HGD+
+ NIM+ HIM+
+ NPD+ HPD+
+ N5A+ HN5+
+ N5B+ HN5+
+ N5+ HN5+
+ NPYL HPYL
+ CIM+ HC
+ CGD+ HC
+ CNN+ HC
+ NM HNM
+ C5A HC
+ C5B HC
+ C5 HC
+ N2OX HNOX
+ N3OX HNOX
+ OH2 HOH
+ -P=C HP
diff --git a/parameters/MMFFOOP.PAR b/parameters/MMFFOOP.PAR
new file mode 100644
index 0000000..b930fe9
--- /dev/null
+++ b/parameters/MMFFOOP.PAR
@@ -0,0 +1,127 @@
+* 11. MMFFOOP.PAR: This file supplies parameters for out-of-plane bending interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF OUT-OF-PLANE PARAMETERS- Rev: 15-OCT-93 Source: MMFF94
+* C94 - CORE MMFF94 parameter, from fits to HF/6-31G* 2nd D's
+* #C94 - Value adjusted from CORE MMFF93 value
+*
+* MMFF atom types koop Source
+ 0 2 0 0 0.020 *-2-*-* C94 DEF
+ 1 2 1 2 0.030 C94
+ 1 2 2 2 0.027 C94
+ 1 2 2 3 0.026 C94
+ 1 2 2 5 0.013 C94
+ 1 2 2 37 0.032 C94
+ 2 2 2 5 0.013 C94
+ 2 2 3 5 0.012 C94
+ 2 2 5 5 0.006 C94
+ 2 2 5 6 0.027 C94
+ 2 2 5 37 0.017 C94
+ 2 2 5 40 0.012 C94
+ 2 2 5 41 0.008 C94
+ 0 3 0 0 0.130 *-3-*-* C94 DEF
+ 1 3 1 7 0.146 C94
+ 1 3 2 7 0.138 C94
+ 1 3 3 7 0.134 C94
+ 1 3 5 7 0.122 C94
+ 1 3 6 7 0.141 C94
+ 1 3 7 10 0.129 C94
+ 1 3 7 37 0.138 C94
+ 2 3 5 7 0.113 C94
+ 2 3 5 9 0.081 C94
+ 2 3 6 7 0.127 C94
+ 2 3 7 10 0.116 C94
+ 3 3 5 7 0.113 C94
+ 3 3 6 7 0.127 C94
+ 5 3 5 7 0.103 C94
+ 5 3 5 9 0.074 C94
+ 5 3 5 54 0.078 C94
+ 5 3 6 7 0.119 C94
+ 5 3 7 10 0.102 C94
+ 5 3 9 40 0.067 C94
+ 6 3 7 37 0.127 C94
+ 7 3 10 10 0.113 C94
+ 7 3 20 20 0.151 C94
+ 9 3 40 40 0.057 C94
+ 0 8 0 0 0.000 *-8-*-* C94 DEF
+ 0 10 0 0 -0.020 *-10-*-* C94 DEF
+ 1 10 1 3 -0.02 #C94 (C93=-0.034)
+ 1 10 3 6 -0.033 C94
+ 1 10 3 28 -0.02 #C94 (C93=-0.030)
+ 3 10 3 28 -0.030 C94
+ 3 10 28 28 -0.019 C94
+ 0 17 0 0 0.000 *-17-*-* E94 DEF
+ 0 26 0 0 0.000 *-26-*-* CE4 DEF
+ 0 30 0 0 0.010 *-30-*-* C94 DEF
+ 5 30 20 30 0.008 C94
+ 0 37 0 0 0.035 *-37-*-* C94 DEF
+ 1 37 37 37 0.040 C94
+ 2 37 37 37 0.031 C94
+ 3 37 37 37 0.027 C94
+ 5 37 37 37 0.015 C94
+ 5 37 37 38 0.046 C94
+ 5 37 37 63 0.008 C94
+ 5 37 37 64 0.012 C94
+ 5 37 37 69 0.016 C94
+ 5 37 38 38 0.084 C94
+ 6 37 37 37 0.048 C94
+ 15 37 37 37 0.025 C94
+ 37 37 37 40 0.046 C94
+ 0 39 0 0 0.020 *-39-*-* C94 DEF
+ 1 39 63 63 0.012 C94
+ 23 39 63 63 -0.014 C94
+ 23 39 63 65 0.021 C94
+ 23 39 65 65 0.062 C94
+ 0 40 0 0 -0.005 *-40-*-* C94 DEF
+ 1 40 28 37 -0.006 C94
+ 2 40 28 28 -0.007 C94
+ 3 40 28 28 -0.007 C94
+ 28 40 28 37 0.004 C94
+ 0 41 0 0 0.180 *-41-*-* C94 DEF
+ 1 41 32 32 0.178 C94
+ 2 41 32 32 0.161 C94
+ 5 41 32 32 0.158 C94
+ 0 43 0 0 0.000 *-43-*-* E94 DEF
+ 0 45 0 0 0.150 *-45-*-* E94 DEF
+ 0 49 0 0 0.000 *-49-*-* E94 DEF
+ 50 49 50 50 0.000 #C94
+ 0 54 0 0 0.020 *-54-*-* C94 DEF
+ 1 54 3 36 0.016 C94
+ 3 54 36 36 0.018 C94
+ 0 55 0 0 0.020 *-55-*-* C94 DEF
+ 1 55 36 57 0.020 #C94
+ 36 55 36 57 0.020 #C94
+ 0 56 0 0 0.020 *-56-*-* C94 DEF
+ 1 56 36 57 0.020 #C94
+ 36 56 36 57 0.020 #C94
+ 0 57 0 0 0.080 *-57-*-* C94 DEF
+ 5 57 55 55 0.038 C94
+ 56 57 56 56 0.158 C94
+ 0 58 0 0 0.025 *-58-*-* E94 DEF
+ 0 63 0 0 0.050 *-63-*-* C94 DEF
+ 5 63 39 64 0.019 C94
+ 5 63 39 66 0.068 C94
+ 5 63 44 64 0.014 C94
+ 5 63 44 66 0.055 C94
+ 5 63 59 64 0.033 C94
+ 5 63 59 66 0.085 C94
+ 37 63 39 64 0.010 C94
+ 0 64 0 0 0.040 *-64-*-* C94 DEF
+ 5 64 63 64 0.006 C94
+ 5 64 63 66 0.043 C94
+ 5 64 64 65 0.052 C94
+ 5 64 65 66 0.094 C94
+ 37 64 63 64 -0.011 C94
+ 0 67 0 0 0.070 *-67-*-* E94 DEF
+ 0 69 0 0 0.070 *-69-*-* C94 DEF
+ 32 69 37 37 0.067 C94
+ 0 73 0 0 0.000 *-73-*-* E94 DEF
+ 0 78 0 0 0.045 *-78-*-* C94 DEF
+ 5 78 78 81 0.046 C94
+ 0 80 0 0 0.080 *-80-*-* C94 DEF
+ 5 80 81 81 0.057 C94
+ 0 81 0 0 0.025 *-81-*-* C94 DEF
+ 36 81 78 80 0.016 C94
+ 0 82 0 0 0.000 *-82-*-* E94 DEF
diff --git a/parameters/MMFFPBCI.PAR b/parameters/MMFFPBCI.PAR
new file mode 100644
index 0000000..380707e
--- /dev/null
+++ b/parameters/MMFFPBCI.PAR
@@ -0,0 +1,112 @@
+* 15. MMFFPBCI.PAR: This file supplies "partial-bond-charge-increment"
+* parameters used in the empirical rule employed to assign
+* missing bond-charge-increment parameters. It also specifies
+* the "formal-charge-sharing" parameters used to assemble the
+* MMFF94 partiial atomic charges for systems or groups
+* that have a negative formal charge.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF Partial Bond Charge Incs and Formal-Charge Adj. Factors: 19-MAY-1994
+*
+* type pbci fcadj Origin/Comment
+0 1 0.000 0.000 E94
+0 2 -0.135 0.000 E94
+0 3 -0.095 0.000 E94
+0 4 -0.200 0.000 E94
+0 5 -0.023 0.000 E94
+0 6 -0.243 0.000 E94
+0 7 -0.687 0.000 E94
+0 8 -0.253 0.000 E94
+0 9 -0.306 0.000 E94
+0 10 -0.244 0.000 E94
+0 11 -0.317 0.000 E94
+0 12 -0.304 0.000 E94
+0 13 -0.238 0.000 E94
+0 14 -0.208 0.000 E94
+0 15 -0.236 0.000 E94
+0 16 -0.475 0.000 E94
+0 17 -0.191 0.000 E94
+0 18 -0.118 0.000 E94
+0 19 0.094 0.000 E94
+0 20 -0.019 0.000 E94
+0 21 0.157 0.000 E94
+0 22 -0.095 0.000 E94
+0 23 0.193 0.000 E94
+0 24 0.257 0.000 E94
+0 25 0.012 0.000 E94
+0 26 -0.142 0.000 E94
+0 27 0.094 0.000 E94
+0 28 0.058 0.000 E94
+0 29 0.207 0.000 E94
+0 30 -0.166 0.000 E94
+0 31 0.161 0.000 E94
+0 32 -0.732 0.500 E94
+0 33 0.257 0.000 E94
+0 34 -0.491 0.000 E94
+0 35 -0.456 0.500 E94
+0 36 -0.031 0.000 E94
+0 37 -0.127 0.000 E94
+0 38 -0.437 0.000 E94
+0 39 -0.104 0.000 E94
+0 40 -0.264 0.000 E94
+0 41 0.052 0.000 E94
+0 42 -0.757 0.000 E94
+0 43 -0.326 0.000 E94
+0 44 -0.237 0.000 E94
+0 45 -0.260 0.000 E94
+0 46 -0.429 0.000 E94
+0 47 -0.418 0.000 E94
+0 48 -0.525 0.000 E94
+0 49 -0.283 0.000 E94
+0 50 0.284 0.000 E94
+0 51 -1.046 0.000 E94
+0 52 -0.546 0.000 E94
+0 53 -0.048 0.000 E94
+0 54 -0.424 0.000 E94
+0 55 -0.476 0.000 E94
+0 56 -0.438 0.000 E94
+0 57 -0.105 0.000 E94
+0 58 -0.488 0.000 E94
+0 59 -0.337 0.000 E94
+0 60 -0.635 0.000 E94
+0 61 -0.265 0.000 E94
+0 62 -0.125 0.250 E94
+0 63 -0.180 0.000 E94
+0 64 -0.181 0.000 E94
+0 65 -0.475 0.000 E94
+0 66 -0.467 0.000 E94
+0 67 -0.099 0.000 == 69
+0 68 -0.135 0.000 E94
+0 69 -0.099 0.000 E94
+0 70 -0.269 0.000 E94
+0 71 -0.071 0.000 E94
+0 72 -0.580 0.500 E94
+0 73 -0.200 0.000 E94
+0 74 -0.301 0.000 E94
+0 75 -0.255 0.000 E94
+0 76 -0.568 0.250 E94
+0 77 -0.282 0.000 E94
+0 78 -0.168 0.000 E94
+0 79 -0.471 0.000 == (65+66)/2
+0 80 -0.144 0.000 E94
+0 81 -0.514 0.000 E94
+0 82 -0.099 0.000 == 69
+0 83 0.000 0.000 Unused
+0 84 0.000 0.000 Unused
+0 85 0.000 0.000 Unused
+0 86 0.000 0.000 Unused
+0 87 2.000 0.000 Ionic charge
+0 88 3.000 0.000 Ionic charge
+0 89 -1.000 0.000 Ionic charge
+0 90 -1.000 0.000 Ionic charge
+0 91 -1.000 0.000 Ionic charge
+0 92 1.000 0.000 Ionic charge
+0 93 1.000 0.000 Ionic charge
+0 94 1.000 0.000 Ionic charge
+0 95 2.000 0.000 Ionic charge
+0 96 2.000 0.000 Ionic charge
+0 97 1.000 0.000 Ionic charge
+0 98 2.000 0.000 Ionic charge
+0 99 2.000 0.000 Ionic charge
diff --git a/parameters/MMFFPROP.PAR b/parameters/MMFFPROP.PAR
new file mode 100644
index 0000000..c85073d
--- /dev/null
+++ b/parameters/MMFFPROP.PAR
@@ -0,0 +1,103 @@
+* 5. MMFFPROP.PAR: This file specifies the chemical, topological, and geometrical properties associated with each of the MMFF atom types.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFFPROP - MMFF atom-type properties
+*
+* atype aspec crd val pilp mltb arom lin sbmb
+ 1 6 4 4 0 0 0 0 0
+ 2 6 3 4 0 2 0 0 1
+ 3 6 3 4 0 2 0 0 1
+ 4 6 2 4 0 3 0 1 1
+ 5 1 1 1 0 0 0 0 0
+ 6 8 2 2 1 0 0 0 0
+ 7 8 1 2 0 2 0 0 0
+ 8 7 3 3 1 0 0 0 0
+ 9 7 2 3 0 2 0 0 1
+ 10 7 3 3 1 1 0 0 0
+ 11 9 1 1 1 0 0 0 0
+ 12 17 1 1 1 0 0 0 0
+ 13 35 1 1 1 0 0 0 0
+ 14 53 1 1 1 0 0 0 0
+ 15 16 2 2 1 0 0 0 0
+ 16 16 1 2 0 2 0 0 0
+ 17 16 3 4 0 2 0 0 0
+ 18 16 4 4 0 0 0 0 0
+ 19 14 4 4 0 0 0 0 0
+ 20 6 4 4 0 0 0 0 0
+ 21 1 1 1 0 0 0 0 0
+ 22 6 4 4 0 0 0 0 0
+ 23 1 1 1 0 0 0 0 0
+ 24 1 1 1 0 0 0 0 0
+ 25 15 4 4 0 0 0 0 0
+ 26 15 3 3 1 0 0 0 0
+ 27 1 1 1 0 0 0 0 0
+ 28 1 1 1 0 0 0 0 0
+ 29 1 1 1 0 0 0 0 0
+ 30 6 3 4 0 2 0 0 1
+ 31 1 1 1 0 0 0 0 0
+ 32 8 1 12 1 1 0 0 0
+ 33 1 1 1 0 0 0 0 0
+ 34 7 4 4 0 0 0 0 0
+ 35 8 1 1 1 1 0 0 0
+ 36 1 1 1 0 0 0 0 0
+ 37 6 3 4 0 2 1 0 1
+ 38 7 2 3 0 2 1 0 0
+ 39 7 3 3 1 1 1 0 1
+ 40 7 3 3 1 0 0 0 0
+ 41 6 3 4 0 1 0 0 0
+ 42 7 1 3 0 3 0 0 0
+ 43 7 3 3 1 0 0 0 0
+ 44 16 2 2 1 1 1 0 0
+ 45 7 3 4 0 2 0 0 0
+ 46 7 2 3 0 2 0 0 0
+ 47 7 1 2 0 2 0 0 0
+ 48 7 2 2 0 0 0 0 0
+ 49 8 3 3 0 0 0 0 0
+ 50 1 1 1 0 0 0 0 0
+ 51 8 2 3 0 2 0 0 0
+ 52 1 1 1 0 0 0 0 0
+ 53 7 2 4 0 2 0 1 0
+ 54 7 3 4 0 2 0 0 1
+ 55 7 3 34 0 1 0 0 0
+ 56 7 3 34 0 1 0 0 0
+ 57 6 3 4 0 2 0 0 1
+ 58 7 3 4 0 1 1 0 1
+ 59 8 2 2 1 1 1 0 0
+ 60 6 1 3 0 3 0 0 0
+ 61 7 2 4 0 3 0 1 0
+ 62 7 2 2 1 0 0 0 0
+ 63 6 3 4 0 2 1 0 1
+ 64 6 3 4 0 2 1 0 1
+ 65 7 2 3 0 2 1 0 0
+ 66 7 2 3 0 2 1 0 0
+ 67 7 3 4 0 2 0 0 1
+ 68 7 4 4 0 0 0 0 0
+ 69 7 3 4 0 1 1 0 0
+ 70 8 2 2 1 0 0 0 0
+ 71 1 1 1 0 0 0 0 0
+ 72 16 1 1 1 1 0 0 0
+ 73 16 3 3 0 0 0 0 0
+ 74 16 2 4 0 2 0 0 0
+ 75 15 2 3 0 2 0 0 1
+ 76 7 2 2 1 0 0 0 0
+ 77 17 4 4 0 0 0 0 0
+ 78 6 3 4 0 2 1 0 1
+ 79 7 2 3 0 2 1 0 0
+ 80 6 3 4 0 2 0 0 1
+ 81 7 3 4 0 1 1 0 1
+ 82 7 3 4 0 1 1 0 0
+ 87 26 0 0 0 0 0 0 0
+ 88 26 0 0 0 0 0 0 0
+ 89 9 0 0 0 0 0 0 0
+ 90 17 0 0 0 0 0 0 0
+ 91 35 0 0 0 0 0 0 0
+ 92 3 0 0 0 0 0 0 0
+ 93 11 0 0 0 0 0 0 0
+ 94 19 0 0 0 0 0 0 0
+ 95 30 0 0 0 0 0 0 0
+ 96 20 0 0 0 0 0 0 0
+ 97 29 0 0 0 0 0 0 0
+ 98 29 0 0 0 0 0 0 0
+ 99 12 0 0 0 0 0 0 0
diff --git a/parameters/MMFFSTBN.PAR b/parameters/MMFFSTBN.PAR
new file mode 100644
index 0000000..c9dba07
--- /dev/null
+++ b/parameters/MMFFSTBN.PAR
@@ -0,0 +1,292 @@
+* 9. MMFFSTBN.PAR:: This file supplies parameters for stretch-bend interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF STRETCH-BEND PARAMETERS- Rev: 23-FEB-93 Source: MMFF94
+* C94 - CORE MMFF94 parameter, from fits to HF/6-31G* 2nd D's
+* X94 - EXTD MMFF94 parameter, also from fits to HF/6-31G* 2nd D's
+*
+* types I, J, K kbaIJK kbaKJI Source
+0 1 1 1 0.206 0.206 C94
+0 1 1 2 0.136 0.197 C94
+0 1 1 3 0.211 0.092 C94
+0 1 1 5 0.227 0.070 C94
+0 1 1 6 0.173 0.417 C94
+0 1 1 8 0.136 0.282 C94
+0 1 1 10 0.187 0.338 C94
+0 1 1 11 0.209 0.633 C94
+0 1 1 12 0.176 0.386 C94
+0 1 1 15 0.139 0.217 C94
+0 1 1 34 0.236 0.436 C94
+0 1 1 37 0.152 0.260 C94
+0 1 1 39 0.144 0.595 C94
+0 1 1 41 0.122 0.051 C94
+0 1 1 56 0.262 0.451 C94
+0 1 1 68 0.186 0.125 C94
+0 2 1 2 0.282 0.282 C94
+0 2 1 3 0.206 0.022 C94
+0 2 1 5 0.234 0.088 C94
+0 2 1 6 0.183 0.387 C94
+0 2 1 8 0.214 0.363 C94
+0 3 1 5 0.157 0.115 C94
+0 3 1 6 -0.036 0.456 C94
+0 3 1 10 0.038 0.195 C94
+0 5 1 5 0.115 0.115 C94
+0 5 1 6 0.013 0.436 C94
+0 5 1 8 0.027 0.358 C94
+0 5 1 9 0.040 0.418 C94
+0 5 1 10 0.043 0.261 C94
+0 5 1 11 0.003 0.452 C94
+0 5 1 12 -0.018 0.380 C94
+0 5 1 15 0.018 0.255 C94
+0 5 1 18 0.121 0.218 X94
+0 5 1 20 0.069 0.327 C94
+0 5 1 22 0.055 0.267 X94
+0 5 1 34 -0.003 0.342 C94
+0 5 1 37 0.074 0.287 C94
+0 5 1 39 0.092 0.607 C94
+0 5 1 40 0.023 0.335 C94
+0 5 1 41 0.093 0.118 C94
+0 5 1 54 0.016 0.343 C94
+0 5 1 55 0.030 0.397 C94
+0 5 1 56 0.031 0.384 C94
+0 5 1 68 0.041 0.216 C94
+0 6 1 6 0.320 0.320 C94
+0 6 1 37 0.310 0.160 C94
+0 11 1 11 0.586 0.586 C94
+0 12 1 12 0.508 0.508 C94
+0 1 2 1 0.250 0.250 C94
+0 1 2 2 0.203 0.207 C94
+2 1 2 2 0.222 0.269 C94
+2 1 2 3 0.244 0.292 C94
+0 1 2 5 0.215 0.128 C94
+2 1 2 37 0.246 0.260 C94
+1 2 2 2 0.250 0.219 C94
+2 2 2 3 0.155 0.112 C94
+0 2 2 5 0.207 0.157 C94
+1 2 2 5 0.267 0.159 C94
+0 2 2 6 0.118 0.576 C94
+2 2 2 37 0.143 0.172 C94
+0 2 2 40 0.289 0.390 C94
+0 2 2 41 0.191 -0.047 C94
+1 3 2 5 0.264 0.156 C94
+0 5 2 5 0.140 0.140 C94
+0 5 2 6 0.213 0.502 C94
+2 5 2 37 0.153 0.288 C94
+0 5 2 40 0.070 0.463 C94
+0 5 2 41 0.191 0.005 C94
+0 1 3 1 0.358 0.358 C94
+2 1 3 2 0.246 0.409 C94
+2 1 3 3 0.303 0.145 C94
+0 1 3 5 0.321 0.183 C94
+0 1 3 6 0.338 0.732 C94
+0 1 3 7 0.154 0.856 C94
+0 1 3 10 0.223 0.732 C94
+2 1 3 37 0.217 0.207 C94
+1 2 3 5 0.407 0.159 C94
+1 2 3 6 0.429 0.473 C94
+1 2 3 7 0.214 0.794 C94
+1 2 3 9 0.227 0.610 C94
+1 2 3 10 0.298 0.600 C94
+1 3 3 5 0.251 0.133 C94
+1 3 3 6 0.066 0.668 C94
+1 3 3 7 -0.093 0.866 C94
+0 5 3 5 0.126 0.126 C94
+0 5 3 6 0.174 0.734 C94
+0 5 3 7 0.032 0.805 C94
+0 5 3 9 0.037 0.669 C94
+0 5 3 10 0.169 0.619 C94
+0 5 3 40 0.087 0.685 C94
+0 5 3 54 0.098 0.210 C94
+0 6 3 7 0.494 0.578 C94
+4 6 3 20 1.179 0.752 X94
+2 6 3 37 0.350 0.175 C94
+0 7 3 10 0.771 0.353 C94
+0 7 3 20 0.865 -0.181 C94
+2 7 3 37 0.707 0.007 C94
+0 9 3 40 0.680 0.260 C94
+0 10 3 10 1.050 1.050 C94
+4 20 3 20 0.536 0.536 C94
+0 40 3 40 0.482 0.482 C94
+0 1 6 1 0.309 0.309 C94
+0 1 6 2 0.157 0.375 C94
+0 1 6 3 -0.153 0.252 C94
+0 1 6 21 0.256 0.143 C94
+0 1 6 37 0.163 0.375 C94
+0 2 6 3 -0.228 0.052 C94
+0 2 6 29 0.259 0.163 C94
+4 3 6 20 0.456 0.379 X94
+0 3 6 24 0.215 0.064 C94
+0 3 6 37 -0.225 -0.320 C94
+0 8 6 21 0.304 0.055 C94
+0 10 6 21 0.419 0.158 C94
+0 18 6 33 0.309 0.120 X94
+4 20 6 20 0.739 0.739 C94
+0 29 6 37 0.130 0.241 C94
+0 31 6 31 0.227 0.227 X94
+0 1 8 1 0.312 0.312 C94
+0 1 8 6 0.212 0.354 C94
+0 1 8 23 0.309 0.135 C94
+0 6 8 23 0.418 0.020 C94
+4 20 8 20 0.653 0.653 C94
+0 20 8 23 0.128 0.122 C94
+0 23 8 23 0.190 0.190 C94
+0 1 9 3 0.326 0.580 C94
+0 3 9 27 0.464 0.222 C94
+0 1 10 1 0.063 0.063 C94
+0 1 10 3 -0.021 0.340 C94
+0 1 10 6 -0.024 0.374 C94
+0 1 10 28 0.155 -0.051 C94
+0 3 10 3 -0.219 -0.219 C94
+0 3 10 6 0.497 0.513 C94
+0 3 10 28 0.137 0.066 C94
+0 28 10 28 0.081 0.081 C94
+0 1 15 1 0.125 0.125 C94
+0 1 15 15 0.012 0.238 C94
+0 1 15 37 0.048 0.229 C94
+0 1 15 71 0.080 -0.012 C94
+0 15 15 71 0.172 -0.068 C94
+0 37 15 71 0.187 -0.027 C94
+0 71 15 71 0.045 0.045 C94
+0 1 18 1 0.023 0.023 X94
+0 1 18 6 0.003 0.213 X94
+0 1 18 32 -0.091 0.390 X94
+0 1 18 43 -0.008 0.607 X94
+0 6 18 6 0.088 0.088 X94
+0 6 18 32 0.123 0.369 X94
+0 32 18 32 0.404 0.404 X94
+0 32 18 43 0.384 0.281 X94
+0 43 18 43 0.428 0.428 X94
+0 1 20 5 0.290 0.098 C94
+0 1 20 20 0.179 0.004 C94
+0 3 20 5 -0.049 0.171 C94
+4 3 20 20 0.607 0.437 C94
+0 5 20 5 0.182 0.182 C94
+0 5 20 6 0.051 0.312 C94
+0 5 20 8 0.072 0.226 C94
+0 5 20 12 0.014 0.597 C94
+0 5 20 20 0.101 0.079 C94
+0 5 20 30 0.108 0.123 C94
+4 6 20 20 0.823 0.396 C94
+4 8 20 20 0.701 0.369 C94
+0 12 20 20 0.310 0.000 C94
+4 20 20 20 0.283 0.283 C94
+4 20 20 30 0.340 0.529 C94
+0 1 22 5 0.067 0.174 X94
+0 1 22 22 0.199 0.039 X94
+0 5 22 5 0.254 0.254 C94
+0 5 22 22 0.181 0.108 C94
+5 22 22 22 0.000 0.000 C94
+0 5 26 5 -0.121 -0.121 X94
+0 5 30 20 0.251 0.007 C94
+0 5 30 30 0.267 0.054 C94
+4 20 30 30 0.413 0.705 C94
+0 1 34 1 0.202 0.202 C94
+0 1 34 36 0.160 -0.009 C94
+0 36 34 36 0.087 0.087 C94
+0 1 37 37 0.485 0.311 C94
+1 2 37 37 0.321 0.235 C94
+1 3 37 37 0.179 0.217 C94
+0 5 37 37 0.279 0.250 C94
+0 5 37 38 0.267 0.389 C94
+0 5 37 63 0.216 0.434 C94
+0 5 37 64 0.167 0.364 C94
+0 5 37 69 0.273 0.391 C94
+0 6 37 37 0.830 0.339 C94
+0 15 37 37 0.650 0.259 C94
+0 37 37 37 -0.411 -0.411 C94
+0 37 37 38 -0.424 -0.466 C94
+0 37 37 40 0.429 0.901 C94
+0 37 37 63 -0.173 -0.215 C94
+0 37 37 64 -0.229 -0.229 C94
+0 37 37 69 -0.244 -0.555 C94
+0 38 37 38 -0.516 -0.516 C94
+0 37 38 37 -0.342 -0.342 C94
+0 37 38 38 -0.164 -1.130 C94
+0 1 39 63 0.313 0.500 C94
+0 23 39 63 -0.131 0.422 C94
+0 23 39 65 -0.122 0.281 C94
+0 63 39 63 0.469 0.469 C94
+0 63 39 65 0.741 0.506 C94
+0 65 39 65 0.706 0.706 C94
+0 1 40 28 0.238 0.091 C94
+0 1 40 37 0.153 0.590 C94
+0 2 40 28 0.342 0.156 C94
+0 3 40 28 0.228 0.104 C94
+0 28 40 28 0.094 0.094 C94
+0 28 40 37 0.186 0.423 C94
+0 1 41 32 0.503 0.943 C94
+0 2 41 32 0.594 0.969 C94
+0 5 41 32 0.276 0.852 C94
+0 32 41 32 0.652 0.652 C94
+0 18 43 23 0.377 0.057 X94
+0 23 43 23 0.082 0.082 X94
+0 63 44 63 0.591 0.591 C94
+0 63 44 65 0.857 0.978 C94
+0 50 49 50 0.072 0.072 C94
+0 1 54 3 0.192 -0.051 C94
+0 1 54 36 0.240 0.079 C94
+0 3 54 36 0.005 0.127 C94
+0 36 54 36 0.148 0.148 C94
+0 1 55 36 0.189 0.033 C94
+0 1 55 57 0.166 0.211 C94
+0 36 55 36 0.106 0.106 C94
+0 36 55 57 0.093 0.080 C94
+0 1 56 36 0.211 -0.040 C94
+0 1 56 57 0.026 0.386 C94
+0 36 56 36 0.101 0.101 C94
+0 36 56 57 0.108 0.068 C94
+0 5 57 55 0.043 0.420 C94
+0 55 57 55 0.125 0.125 C94
+0 56 57 56 0.431 0.431 C94
+0 58 57 58 0.732 0.732 C94
+0 63 59 63 0.497 0.497 C94
+0 63 59 65 0.723 0.874 C94
+0 5 63 39 0.009 0.654 C94
+0 5 63 44 -0.015 0.446 C94
+0 5 63 59 0.067 0.588 C94
+0 5 63 64 0.055 0.370 C94
+0 5 63 66 0.110 0.464 C94
+0 37 63 39 0.178 0.523 C94
+0 37 63 64 -0.045 0.497 C94
+0 39 63 64 0.422 0.409 C94
+0 39 63 66 0.436 0.525 C94
+0 44 63 64 0.581 0.426 C94
+0 44 63 66 0.542 0.365 C94
+0 59 63 64 0.852 0.332 C94
+0 59 63 66 0.775 0.300 C94
+0 5 64 63 0.086 0.345 C94
+0 5 64 64 0.085 0.369 C94
+0 5 64 65 0.051 0.436 C94
+0 5 64 66 0.113 0.452 C94
+0 37 64 63 0.059 0.299 C94
+0 37 64 64 0.277 0.377 C94
+0 63 64 64 0.206 0.030 C94
+0 63 64 66 0.171 0.078 C94
+0 64 64 65 0.079 0.403 C94
+0 65 64 66 0.406 0.066 C94
+0 39 65 64 0.528 0.644 C94
+0 39 65 66 0.397 0.258 C94
+0 44 65 64 0.816 0.543 C94
+0 59 65 64 1.177 0.594 C94
+0 63 66 64 0.213 -0.173 C94
+0 63 66 66 0.234 0.077 C94
+0 64 66 65 -0.149 0.383 C94
+0 65 66 66 0.199 0.101 C94
+0 1 68 1 0.217 0.217 C94
+0 1 68 23 0.285 0.050 C94
+0 1 68 32 -0.047 0.503 C94
+0 23 68 23 0.145 0.145 C94
+0 23 68 32 -0.182 0.504 C94
+0 32 69 37 1.018 0.418 C94
+0 37 69 37 -0.169 -0.169 C94
+0 31 70 31 0.210 0.210 C94
+0 5 78 78 0.279 0.250 C94
+0 5 78 81 0.083 0.250 C94
+0 78 78 81 -0.398 0.314 C94
+0 5 80 81 -0.101 0.691 C94
+0 81 80 81 0.732 0.732 C94
+0 36 81 78 0.021 0.368 C94
+0 36 81 80 0.018 0.422 C94
+0 78 81 80 0.366 0.419 C94
diff --git a/parameters/MMFFSYMB.PAR b/parameters/MMFFSYMB.PAR
new file mode 100644
index 0000000..e2d09e4
--- /dev/null
+++ b/parameters/MMFFSYMB.PAR
@@ -0,0 +1,223 @@
+* 1. MMFFSYMB.PAR: This file specifies the four-character symbolic atom types
+* used in MMFF and defines the numeric atom type to which each
+* corresponds.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+*
+* SYMBOL TYPE DEFINITION
+*
+ CR 1 ALKYL CARBON, SP3
+ C=C 2 VINYLIC CARBON, SP2
+ CSP2 2 GENERIC SP2 CARBON
+ C=O 3 GENERAL CARBONYL CARBON
+ C=N 3 SP2 CARBON IN C=N
+ CGD 3 GUANIDINE CARBON, DOUBLY BONDED TO N
+ C=OR 3 KETONE OR ALDEHYDE CARBONYL CARBON
+ C=ON 3 AMIDE CARBONYL CARBON
+ CONN 3 UREA CARBONYL CARBON
+ COO 3 CARBOXYLIC ACID OR ESTER CARBONYL CARBON
+ COON 3 CARBAMATE CARBONYL CARBON
+ COOO 3 C ARBONIC ACID OR ESTER CARBONYL CARBON
+ C=OS 3 THIOESTER CARBONYL CARBON, DOUBLE BONDED TO O
+ C=S 3 THIOESTER CARBON, DOUBLY BONDED TO S
+ C=SN 3 THIOAMIDE, CARBON, DOUBLY BONDED TO S
+ CSO2 3 CARBON IN >C=SO2
+ CS=O 3 CARBON IN >C=S=O (SULFINYL GROUP)
+ CSS 3 THIOCARBOXYLIC ACID OR ESTER CARBONYL CARBON
+ C=P 3 CARBON DOUBLE BONDED TO PHOSPHOROUS
+ CSP 4 ACETYLENIC CARBON
+ =C= 4 ALLENIC CARBON
+ HC 5 H ATTACHED TO C
+ HSI 5 H ATTACHED TO SI
+ OR 6 ALCOHOL OR ETHER OXYGEN
+ OC=O 6 ESTER OR CARBOXYLIC ACID -O-
+ OC=C 6 ENOLIC OR PHENOLIC OXYGEN
+ OC=N 6 DIVALENT OXYGEN
+ OC=S 6 THIOESTER OR THIOACID -O-
+ ONO2 6 DIVALENT NITRATE "ETHER" OXYGEN
+ ON=O 6 DIVALENT NITRITE "ETHER" OXYGEN
+ OSO3 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+ OSO2 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+ OSO 6 DIVALENT OXYGEN ATTACHED TO SULFUR
+ OS=O 6 DIVALENT OXYGEN ATTACHED TO SULFOXIDE SULFUR
+ -OS 6 GENERAL DIVALENT OX ATTACHED TO S
+ OPO3 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+ OPO2 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+ OPO 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+ -OP 6 DIVALENT OXYGEN ATTACHED TO PHOSPHOROUS
+ -O- 6 GENERAL DIVALENT O
+ O=C 7 GENERAL C=O
+ O=CN 7 CARBONYL OXYGEN, AMIDES
+ O=CR 7 CARBONYL OXYGEN, ALDEHYDES AND KETONES
+ O=CO 7 CARBONYL OXYGEN, CARBOXYLIC ACIDS AND ESTERS
+ O=N 7 NITROSO OXYGEN
+ O=S 7 O=S IN SULFOXIDES
+ O=S= 7 O=S ON SULFUR DOUBLY BONDED TO, E.G., CARBON
+ NR 8 NITROGEN IN ALIPHATIC AMINES
+ N=C 9 NITROGEN IN IMINES
+ N=N 9 NITROGEN IN AZO COMPOUNDS
+ NC=O 10 NITROGEN IN AMIDES
+ NC=S 10 NITROGEN IN N-C=S, THIOAMIDE
+ NN=C 10 NITROGEN IN N-N=C
+ NN=N 10 NITROGEN IN N-N=N
+ F 11 FLUORINE
+ CL 12 CHLORINE
+ BR 13 BROMINE
+ I 14 IODINE
+ S 15 SULFUR IN THIOETHERS AND MERCAPTANS
+ S=C 16 TERMINAL SULFUR DOUBLY BONDED TO CARBON
+ S=O 17 SULFUR IN SULFOXIDES
+ >S=N 17 SULFUR, TRICOORD, DOUBLY BONDED TO N
+ SO2 18 SULFUR IN SULFONES
+ SO2N 18 SULFUR IN SULFONAMIDES
+ SO3 18 SULFONATE SULFUR
+ SO4 18 SULFATE SULFUR
+ =SO2 18 SULFONE SULPHER DOUBLY BONDED TO CARBON
+ SNO 18 SULFUR IN NITROGEN ANALOG OF A SULFONE
+ SI 19 SILICON
+ CR4R 20 CARBON IN 4-MEMBERED RINGS
+ HOR 21 HYDROGEN IN ALCOHOLS
+ HO 21 GENERAL H ON OXYGEN
+ HOM 21 HYDROGEN IN HYDROXIDE ANION
+ CR3R 22 CARBON IN A 3-MEMBERED RING
+ HNR 23 H-N(SP3)
+ H3N 23 H-N(SP3), AMMONIA
+ HPYL 23 H-N IN PYRROLE
+ HNOX 23 H-N IN IN A N-OXIDE
+ HNM 23 H ON DICOORD, NEGATIVELY CHARGED NITROGEN
+ HN 23 GENERAL H ON NITROGEN
+ HOCO 24 H-O IN CARBOXYLIC ACIDS
+ HOP 24 HYDROGEN ON OXYGEN ATTACHED TO PHOSPHOROUS
+ PO4 25 PHOSPHOROUS IN PHOSPHATES AND PHOSPHODIESTERS
+ PO3 25 TETRACOORDINATE P WITH THREE ATTACHED OXYGENS
+ PO2 25 TETRACOORDINATE P WITH TWO ATTACHED OXYGENS
+ PO 25 TETRACOORDINATE P WITH ONE ATTACHED OXYGEN
+ PTET 25 GENERAL TETRACOORDINATE PHOSPHORUS
+ P 26 TRICOORDINATE P, AS IN PHOSPHINES
+ HN=N 27 AZO HYDROGEN
+ HN=C 27 IMINE HYDROGEN
+ HNCO 28 AMIDE HYDROGEN
+ HNCS 28 THIOAMIDE HYDROGEN
+ HNCC 28 H-N IN ENAMINES
+ HNCN 28 H-N IN H-N-C=N
+ HNNC 28 H-N IN H-N-N=C
+ HNNN 28 H-N IN H-N-N=N
+ HNSO 28 H-N IN SULFONAMIDE
+ HNPO 28 H-N IN PHOSPHONAMIDE
+ HNC% 28 HYDROGEN ON N ATTACHED TO TRIPLY BONDED CARBON
+ HSP2 28 GENERAL H ON SP2 NITROGEN
+ HOCC 29 H-O IN ENOLS AND PHENOLS
+ HOCN 29 H-O IN HO-C=N
+ CE4R 30 OLEFINIC CARBON IN 4-MEMBERED RINGS
+ HOH 31 HYDROGEN IN H2O
+ O2CM 32 OXYGEN IN CARBOXYLATE ANION
+ OXN 32 N-OXIDE OXYGEN
+ O2N 32 NITRO OXYGEN
+ O2NO 32 NITRO-GROUP OXYGEN IN NITRATE
+ O3N 32 NITRATE ANION OXYGEN
+ O-S 32 SINGLE TERMINAL OXYGEN ON TETRACOORD SULFUR
+ O2S 32 TERMINAL O-S IN SULFONES AND SULFONAMIDES
+ O3S 32 TERMINAL O IN SULFONATES
+ O4S 32 TERMINAL O IN SO4(-3)
+ OSMS 32 TERM O IN THIOSULFINATE ANION - FORMAL CHARGE=-0.5
+ OP 32 TERMINAL O IN PHOSPHOXIDES
+ O2P 32 TERMINAL O IN PHOSPHINATES
+ O3P 32 TERMINAL OXYGEN IN PHOSPHONATES
+ O4P 32 TERMINAL OXYGEN IN PHOSPHATES AND PHOSPHODIESTERS
+ O4CL 32 OXYGEN IN CLO4(-) ANION - FORMAL CHARGE=-0.25
+ HOS 33 H ON OXYGEN ATTACHED TO SULFUR
+ NR+ 34 QUATERNARY NITROGEN, SP3, POSITIVELY CHARGED
+ OM 35 ALKOXIDE OXYGEN, NEGATIVELY CHARGED
+ OM2 35 OXIDE OXYGEN ON SP2 CARBON, NEGATIVELY CHARGED
+ HNR+ 36 H ON QUATERNARY NITROGEN
+ HIM+ 36 H ON IMIDAZOLIUM-TYPE NITROGEN
+ HPD+ 36 H ON PROTONATED PYRIDINE NITROGEN
+ HNN+ 36 H ON AMIDINIUM-TYPE NITROGEN
+ HNC+ 36 H ON PROTONATED IMINE NITROGEN
+ HGD+ 36 H ON GUANIDINIUM-TYPE NITROGEN
+ HN5+ 36 H ON N5+, N5A+ OR N5B+
+ CB 37 CARBON AS IN BENZENE, PYRROLE
+ NPYD 38 NITROGEN, AS IN PYRIDINE
+ NPYL 39 NITROGEN, AS IN PYRROLE
+ NC=C 40 NITROGEN ON N-C=C
+ NC=N 40 NITROGEN IN N-C=N
+ NC=P 40 NITROGEN IN N-C=P
+ NC%C 40 NITROGEN ATTACHED TO C-C TRIPLE BOND
+ CO2M 41 CARBOXYLATE ANION CARBON
+ CS2M 41 CARBON IN THIOCARBOXYLATE ANION
+ NSP 42 NITROGEN, TRIPLE BONDED
+ NSO2 43 NITROGEN IN SULFONAMIDES
+ NSO3 43 NITROGEN IN SULFONAMIDES, THREE O'S ON S
+ NPO2 43 NITROGEN IN PHOSPHONAMIDES
+ NPO3 43 NITROGEN IN PHOSPHONAMIDES, THREE O'S ON P
+ NC%N 43 NITROGEN ATTACHED TO CYANO GROUP
+ STHI 44 SULFUR AS IN THIOPHENE
+ NO2 45 NITRO GROUP NITROGEN
+ NO3 45 NITRATE GROUP NITROGEN
+ N=O 46 NITROSO NITROGEN
+ NAZT 47 TERMINAL NITROGEN IN AZIDO OR DIAZO GROUP
+ NSO 48 DIVALENT NITROGEN REPLACING MONOVALENT O IN SO2 GROUP
+ O+ 49 POSITIVELY CHARGED OXONIUM (TRICOORDINATE) OXYGEN
+ HO+ 50 HYDROGEN ON O+ OXYGEN
+ O=+ 51 POSITIVELY CHARGED OXENIUM (DICOORDINATE) OXYGEN
+ HO=+ 52 HYDROGEN ON OXENIUM OXYGEN
+ =N= 53 NITROGEN IN C=N=N OR -N=N=N
+ N+=C 54 POSITIVELY CHARGED IMINIUM NITROGEN
+ N+=N 54 POSITIVELY CHARGED NITROGEN DOUBLE-BONDED TO N
+ NCN+ 55 N IN +N=C-N RESONANCE STRUCTURES - FORMAL CHARGE=1/2
+ NGD+ 56 GUANIDINIUM-TYPE NITROGEN - FORMAL CHARGE=1/3
+ CGD+ 57 GUANIDINIUM CARBON
+ CNN+ 57 C IN +N=C-N RESONANCE STRUCTURES
+ NPD+ 58 PYRIDINIUM-TYPE NITROGEN - FORMAL CHARGE=1
+ OFUR 59 AROMATIC OXYGEN AS IN FURAN
+ C% 60 ISONITRILE CARBON
+ NR% 61 ISONITRILE NITROGEN [FC = 0] OR DIAZO NITROGEN [FC = 1]
+ NM 62 DEPROTONATED SULFONAMIDE N-; FORMAL CHARGE=-1
+ C5A 63 ALPHA CARBON IN 5-MEMBERED HETEROAROMATIC RING
+ C5B 64 BETA CARBON IN 5-MEMBERED HETEROAROMATIC RING
+ N5A 65 ALPHA AROM HETEROCYCLIC 5-RING NITROGEN
+ N5B 66 BETA AROM HETEROCYCLIC 5-RING NITROGEN
+ N2OX 67 SP2-HYDRIDIZED N-OXIDE NITROGEN
+ N3OX 68 SP3-HYDRIDIZED N-OXIDE NITROGEN
+ NPOX 69 PYRIDINE N-OXIDE NITROGEN
+ OH2 70 OXYGEN ON WATER
+ HS 71 H ATTACHED TO DIVALENT, DICOORDINATE S
+ HS=N 71 H ATTACHED TO TETRAVALENT, TRICOODR S DBL BONDED TO N
+ HP 71 H ATTACHED TO TRI- OR TETRACOORDINATE PHOSPHORUS
+ S-P 72 TERMINAL SULFUR BONDED TO PHOSPHORUS
+ S2CM 72 TERMINAL SULFUR IN THIOCARBOXYLATE ANION
+ SM 72 TERMINAL SULFUR - FORMAL CHARGE=-1
+ SSMO 72 TERMINAL SULFUR IN THIOSULFINATE GROUP
+ SO2M 73 SULFUR IN NEGATIVELY CHARGED SULFINATE GROUP
+ SSOM 73 TRICOORD SULFUR IN THIOSULFINATE GROUP
+ =S=O 74 SULFINYL SULFUR, EG. IN C=S=O
+ -P=C 75 PHOSPHOROUS DOUBLY BONDED TO CARBON
+ N5M 76 NEGATIVELY CHARGED N IN, E.G, TRI- OR TETRAZOLE ANION
+ CLO4 77 CHLORINE IN PERCHLORATE ANION, CLO4(-)
+ C5 78 GENERAL CARBON IN 5-MEMBERED HETEROAROMATIC RING
+ N5 79 GENERAL NITROGEN IN 5-MEMBERED HETEROCYCLIC RING
+ CIM+ 80 C IN N-C-N IN IMIDAZOLIUM ION
+ NIM+ 81 IMIDAZOLIUM-TYPE NITROGEN - FORMAL CHARGE=1/2
+ N5A+ 81 POSITIVE N5A NITROGEN - FORMAL CHARGE=1
+ N5B+ 81 POSITIVE N5B NITROGEN - FORMAL CHARGE=1
+ N5+ 81 POSITIVE N5 NITROGEN - FORMAL CHARGE=1
+ N5AX 82 N-OXIDE NITROGEN IN 5-RING ALPHA POSITION
+ N5BX 82 N-OXIDE NITROGEN IN 5-RING BETA POSITION
+ N5OX 82 N-OXIDE NITROGEN IN GENERAL 5-RING POSITION
+ FE+2 87 IRON +2 CATION
+ FE+3 88 IRON +3 CATION
+ F- 89 FLUORIDE ANION
+ CL- 90 CHLORIDE ANION
+ BR- 91 BROMIDE ANION
+ LI+ 92 LITHIUM CATION
+ NA+ 93 SODIUM CATION
+ K+ 94 POTASSIUM CATION
+ ZINC 95 DIPOSITIVE ZINC
+ ZN+2 95 DIPOSITIVE ZINC
+ CA+2 96 DIPOSITIVE CALCIUM
+ CU+1 97 MONOPOSITIVE COPPER
+ CU+2 98 DIPOSITIVE COPPER
+ MG+2 99 DIPOSITIVE MAGNESIUM CATION
+$
diff --git a/parameters/MMFFTOR.PAR b/parameters/MMFFTOR.PAR
new file mode 100644
index 0000000..0600b1d
--- /dev/null
+++ b/parameters/MMFFTOR.PAR
@@ -0,0 +1,938 @@
+* 12. MMFFTOR.PAR: This file supplies parameters for torsion interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* MMFF TORSION PARAMETERS- Rev: 26-OCT-94 Source: MMFF94
+* C94 - CORE MMFF94 parameter - from fits to conformational energies
+* X94 - EXTD MMFF94 parameter - also from fits to conformational E's
+* E94 - EXTD MMFF94 parameter - from empirical rule
+* #E94 - Adjusted from empirical rule value
+*
+* atom types V1 V2 V3 Source
+0 0 1 1 0 0.000 0.000 0.300 C94 0:*-1-1-* Def
+5 0 1 1 0 0.200 -0.800 1.500 C94 5:*-1-1-* Def
+0 1 1 1 1 0.103 0.681 0.332 C94
+5 1 1 1 1 0.144 -0.547 1.126 C94
+0 1 1 1 2 -0.295 0.438 0.584 C94
+0 1 1 1 3 0.066 -0.156 0.143 C94
+0 1 1 1 5 0.639 -0.630 0.264 C94
+0 1 1 1 6 -0.688 1.757 0.477 C94
+5 1 1 1 6 0.000 0.000 0.054 C94
+0 1 1 1 8 -1.420 -0.092 1.101 C94
+5 1 1 1 8 0.000 -0.158 0.323 C94
+0 1 1 1 11 0.593 0.662 1.120 C94
+0 1 1 1 12 -0.678 0.417 0.624 C94
+0 1 1 1 15 -0.714 0.698 0.000 C94
+0 1 1 1 34 -0.647 0.550 0.590 C94
+0 2 1 1 5 0.321 -0.411 0.144 C94
+0 3 1 1 3 0.443 0.000 -1.140 C94
+0 3 1 1 5 -0.256 0.058 0.000 C94
+0 3 1 1 6 -0.679 -0.029 0.000 C94
+0 5 1 1 5 0.284 -1.386 0.314 C94
+0 5 1 1 6 -0.654 1.072 0.279 C94
+0 5 1 1 8 -0.744 -1.235 0.337 C94
+0 5 1 1 10 0.000 0.000 0.427 C94
+0 5 1 1 11 0.000 0.516 0.291 C94
+0 5 1 1 12 0.678 -0.602 0.398 C94
+0 5 1 1 15 1.142 -0.644 0.367 C94
+0 5 1 1 25 0.000 0.000 0.295 X94
+0 5 1 1 34 0.692 -0.530 0.278 C94
+0 5 1 1 37 0.000 0.000 0.389 C94
+0 5 1 1 39 0.000 0.000 0.278 C94
+0 5 1 1 41 0.000 0.000 -0.141 C94
+0 5 1 1 56 0.000 0.000 0.324 C94
+0 5 1 1 68 0.000 0.000 0.136 C94
+0 6 1 1 6 0.408 1.397 0.961 C94
+5 6 1 1 6 0.313 -1.035 1.631 C94
+0 8 1 1 8 1.055 0.834 0.000 C94
+0 11 1 1 11 -0.387 -0.543 1.405 C94
+0 12 1 1 12 0.000 0.000 0.893 C94
+0 15 1 1 15 -0.177 0.000 0.049 C94
+0 0 1 2 0 0.000 0.000 0.000 C94 0:*-1-2-* Def
+2 0 1 2 0 0.000 0.000 0.000 E94 2:*1-2-* Def
+5 0 1 2 0 0.000 0.000 0.000 C94 5:*-1-2-* Def
+0 0 1 2 2 0.000 0.000 -0.650 C94 0:*-1-2=2 Def
+5 0 1 2 2 0.000 0.000 -0.650 C94 5:*-1-2=2 Def
+0 1 1 2 1 0.419 0.296 0.282 C94
+0 1 1 2 2 -0.494 0.274 -0.630 C94
+0 1 1 2 5 0.075 0.000 0.358 C94
+0 2 1 2 2 -0.293 0.115 -0.508 C94
+0 2 1 2 5 0.301 0.104 0.507 C94
+0 3 1 2 1 0.565 -0.554 0.234 C94
+0 3 1 2 2 -0.577 -0.482 -0.427 C94
+0 3 1 2 5 0.082 0.000 0.123 C94
+0 5 1 2 1 0.000 -0.184 0.220 C94
+0 5 1 2 2 0.501 -0.410 -0.535 C94
+2 5 1 2 2 0.000 0.000 0.055 C94
+2 5 1 2 3 0.000 0.000 -0.108 C94
+0 5 1 2 5 -0.523 -0.228 0.208 C94
+2 5 1 2 37 0.000 0.000 0.000 C94
+0 6 1 2 1 -0.467 0.000 0.490 C94
+0 6 1 2 2 0.425 0.168 -0.875 C94
+0 6 1 2 5 0.000 0.136 0.396 C94
+0 8 1 2 1 -0.504 0.371 0.557 C94
+0 8 1 2 2 0.541 0.539 -1.009 C94
+0 8 1 2 5 0.000 0.204 0.464 C94
+0 0 1 3 0 0.000 0.400 0.300 C94 0:*-1-3-* Def
+2 0 1 3 0 0.000 0.500 0.350 C94 2:*-1-3-* Def
+5 0 1 3 0 0.000 0.000 0.000 E94 5:*1-3-* Def
+0 0 1 3 1 0.000 0.000 0.550 C94 0:*-1-3-1 Def
+0 0 1 3 5 0.000 0.200 0.700 C94 0:*-1-3-5 Def
+0 0 1 3 7 0.000 0.400 0.400 C94 0:*-1-3-7 Def
+0 1 1 3 1 0.103 0.177 0.545 C94
+0 1 1 3 5 -0.072 0.316 0.674 C94
+0 1 1 3 6 -0.117 -0.333 0.202 C94
+0 1 1 3 7 0.825 0.139 0.325 C94
+0 1 1 3 10 -0.927 1.112 1.388 C94
+0 2 1 3 5 0.663 -0.167 0.426 C94
+0 2 1 3 7 -0.758 0.112 0.563 C94
+0 5 1 3 1 -0.073 0.085 0.531 C94
+2 5 1 3 2 0.000 0.000 0.115 C94
+2 5 1 3 3 0.000 0.000 0.446 C94
+0 5 1 3 5 -0.822 0.501 1.008 C94
+0 5 1 3 6 0.000 -0.624 0.330 C94
+0 5 1 3 7 0.659 -1.407 0.308 C94
+0 5 1 3 10 -0.412 0.693 0.087 C94
+2 5 1 3 37 0.000 0.000 0.056 C94
+0 5 1 3 43 0.000 1.027 0.360 X94
+0 5 1 3 51 0.000 1.543 0.350 X94
+0 5 1 3 53 0.000 0.501 0.000 X94
+0 5 1 3 74 0.000 0.513 -0.344 X94
+0 5 1 3 75 0.000 0.511 -0.186 X94
+0 6 1 3 6 0.447 0.652 0.318 C94
+0 6 1 3 7 -0.395 0.730 -0.139 C94
+0 10 1 3 7 0.338 2.772 2.145 C94
+0 10 1 3 10 0.548 0.000 1.795 C94
+0 0 1 4 0 0.000 0.000 0.000 C94 0:*-1-4-* Def
+0 0 1 6 0 0.000 0.000 0.200 C94 0:*-1-6-* Def
+5 0 1 6 0 0.000 -0.200 0.400 C94 5:*-1-6-* Def
+0 1 1 6 1 -0.681 0.755 0.755 C94
+5 1 1 6 1 0.000 0.243 -0.596 C94
+0 1 1 6 3 -0.547 0.000 0.320 C94
+0 1 1 6 21 0.000 0.270 0.237 C94
+0 2 1 6 21 0.102 0.460 -0.128 C94
+0 3 1 6 21 -1.652 -1.660 0.283 C94
+0 5 1 6 1 0.571 0.319 0.570 C94
+0 5 1 6 2 0.000 0.000 0.306 C94
+0 5 1 6 3 0.572 0.000 -0.304 C94
+0 5 1 6 21 0.596 -0.276 0.346 C94
+0 5 1 6 25 0.000 0.000 0.061 X94
+0 5 1 6 37 0.000 0.000 0.106 C94
+0 5 1 6 45 0.000 0.000 -0.174 X94
+0 6 1 6 1 0.229 -0.710 0.722 C94
+5 6 1 6 1 0.000 0.000 0.040 C94
+0 6 1 6 21 1.488 -3.401 -0.320 C94
+0 37 1 6 21 0.712 1.320 -0.507 C94
+0 0 1 8 0 0.000 -0.300 0.500 C94 0:*-1-8-* Def
+5 0 1 8 0 0.000 0.000 0.297 E94 5:*1-8-* Def
+0 1 1 8 1 -0.439 0.786 0.272 C94
+5 1 1 8 1 0.115 -0.390 0.658 C94
+0 1 1 8 6 -0.608 0.339 1.496 C94
+0 1 1 8 23 -0.428 0.323 0.280 C94
+0 2 1 8 23 0.594 -0.409 0.155 C94
+0 5 1 8 1 0.393 -0.385 0.562 C94
+0 5 1 8 6 0.598 -0.158 0.399 C94
+0 5 1 8 23 -0.152 -0.440 0.357 C94
+0 0 1 9 0 0.000 0.000 0.000 C94 0:*-1-9-* Def
+5 0 1 9 0 0.000 0.000 0.000 E94 5:*1-9-* Def
+0 5 1 9 3 0.204 -0.335 -0.352 C94
+0 5 1 9 53 0.000 0.000 0.097 X94
+0 0 1 10 0 0.000 0.000 0.300 C94 0:*-1-10-* Def
+5 0 1 10 0 0.000 0.000 0.000 E94 5:*1-10-* Def
+0 0 1 10 3 0.000 0.000 1.000 C94 0:*-1-10-3 Def
+0 1 1 10 3 -1.027 0.694 0.948 C94
+0 1 1 10 6 0.159 -0.552 0.198 C94
+0 1 1 10 28 0.552 -0.380 0.326 C94
+0 3 1 10 3 3.100 -2.529 1.494 C94
+0 3 1 10 28 0.079 0.280 0.402 C94
+0 5 1 10 1 0.000 0.000 0.779 C94
+0 5 1 10 3 -2.099 1.363 0.021 C94
+0 5 1 10 6 -0.162 0.832 0.552 C94
+0 5 1 10 28 -0.616 0.000 0.274 C94
+0 0 1 15 0 0.000 0.000 0.400 C94 0:*-1-15-* Def
+5 0 1 15 0 0.000 0.000 0.336 E94 5:*1-15-* Def
+0 1 1 15 1 -1.047 0.170 0.398 C94
+0 1 1 15 15 -1.438 0.263 0.501 C94
+0 1 1 15 71 -0.376 -0.133 0.288 C94
+0 5 1 15 1 1.143 -0.231 0.447 C94
+0 5 1 15 15 1.555 -0.323 0.456 C94
+0 5 1 15 37 0.000 0.000 0.459 C94
+0 5 1 15 71 0.229 0.203 0.440 C94
+0 0 1 17 0 0.000 0.000 0.350 C94 0:*-1-17-* Def
+5 0 1 17 0 0.000 0.000 0.000 E94 5:*1-17-* Def
+0 5 1 17 1 0.000 0.000 0.536 X94
+0 5 1 17 7 0.000 0.000 0.212 X94
+0 0 1 18 0 0.000 0.000 0.100 C94 0:*-1-18-* Def
+5 0 1 18 0 0.000 0.000 0.112 E94 5:*1-18-* Def
+0 5 1 18 1 0.000 0.000 0.000 X94
+0 5 1 18 6 0.000 0.000 0.099 X94
+0 5 1 18 32 0.000 0.585 0.388 X94
+0 5 1 18 43 0.000 -0.412 0.121 X94
+0 5 1 18 48 0.000 0.000 0.195 X94
+0 5 1 18 62 0.000 0.000 -0.088 X94
+0 0 1 19 0 0.000 0.000 0.150 C94 0:*-1-19-* Def
+5 0 1 19 0 0.000 0.000 0.179 E94 5:*1-19-* Def
+0 5 1 19 5 0.000 0.000 0.196 X94
+0 5 1 19 6 0.000 0.000 0.176 X94
+0 5 1 19 12 0.000 0.000 0.152 X94
+0 0 1 20 0 0.000 0.000 0.350 C94 0:*-1-20-* Def
+5 0 1 20 0 0.000 0.000 0.350 C94 5:*-1-20-* Def
+0 5 1 20 5 0.000 0.000 0.344 C94
+0 5 1 20 20 0.000 0.000 0.361 C94
+0 0 1 22 0 0.000 0.000 0.236 E94 0:*1-22-* Def
+5 0 1 22 0 0.000 0.000 0.236 E94 5:*1-22-* Def
+0 0 1 25 0 0.000 0.000 0.300 C94 0:*-1-25-* Def
+5 0 1 25 0 0.000 0.000 0.251 E94 5:*1-25-* Def
+0 1 1 25 1 0.000 -0.207 0.232 X94
+0 1 1 25 32 0.000 0.288 0.218 X94
+0 5 1 25 1 0.000 0.152 0.235 X94
+0 5 1 25 6 0.000 0.000 0.495 X94
+0 5 1 25 32 0.000 -0.130 0.214 X94
+0 5 1 25 43 0.000 0.000 0.466 X94
+0 5 1 25 72 0.000 0.000 0.243 X94
+0 0 1 26 0 0.000 0.000 0.450 C94 0:*-1-26-* Def
+5 0 1 26 0 0.000 0.000 0.376 E94 5:*1-26-* Def
+0 5 1 26 12 0.000 0.000 0.439 X94
+0 5 1 26 71 0.000 0.000 0.472 X94
+0 0 1 34 0 0.000 0.000 0.250 C94 0:*-1-34-* Def
+5 0 1 34 0 0.000 0.000 0.198 E94 5:*1-34-* Def
+0 1 1 34 36 0.000 0.000 0.187 C94
+0 5 1 34 1 0.000 0.000 0.247 C94
+0 5 1 34 36 0.000 0.000 0.259 C94
+0 0 1 37 0 0.000 0.000 0.200 C94 0:*-1-37-* Def
+5 0 1 37 0 0.000 0.000 0.000 E94 5:*1-37-* Def
+0 1 1 37 37 0.000 0.449 0.000 C94
+0 5 1 37 37 0.000 -0.420 0.391 C94
+0 6 1 37 37 0.000 0.000 0.150 C94
+0 0 1 39 0 0.000 0.000 0.000 C94 0:*-1-39-* Def
+5 0 1 39 0 0.000 0.000 0.000 E94 5:*1-39-* Def
+0 1 1 39 63 0.000 -0.080 -0.056 C94
+0 5 1 39 63 0.000 0.000 -0.113 C94
+0 0 1 40 0 0.000 0.000 0.250 C94 0:*-1-40-* Def
+5 0 1 40 0 0.000 0.000 0.297 E94 5:*1-40-* Def
+0 5 1 40 28 0.000 -0.097 0.203 C94
+0 5 1 40 37 0.000 0.000 0.329 C94
+0 0 1 41 0 0.000 0.600 0.000 C94 0:*-1-41-* Def
+0 1 1 41 32 0.000 1.263 0.000 C94
+0 5 1 41 32 0.000 0.000 -0.106 C94
+0 5 1 41 72 0.000 0.632 0.000 X94
+0 0 1 43 0 0.000 0.000 0.150 C94 0:*-1-43-* Def
+5 0 1 43 0 0.000 0.000 0.297 E94 5:*1-43-* Def
+0 5 1 43 18 0.357 -0.918 0.000 X94
+0 5 1 43 25 0.000 0.000 0.061 X94
+0 5 1 43 28 -0.249 0.382 0.343 X94
+0 0 1 45 0 0.000 0.000 0.100 C94 0:*-1-45-* Def
+0 5 1 45 32 0.000 0.000 0.125 X94
+0 0 1 46 0 0.000 0.000 -0.500 C94 0:*-1-46-* Def
+0 5 1 46 7 0.000 0.000 -0.540 X94
+0 0 1 54 0 0.000 0.000 0.000 C94 0:*-1-54-* Def
+2 0 1 54 0 0.000 0.000 0.000 E94 2:*1-54-* Def
+5 0 1 54 0 0.000 0.000 0.000 E94 5:*1-54-* Def
+0 5 1 54 3 0.000 0.000 -0.315 C94
+0 5 1 54 36 0.000 0.000 0.315 C94
+0 0 1 55 0 0.000 0.000 0.000 C94 0:*-1-55-* Def
+5 0 1 55 0 0.000 0.000 0.000 E94 5:*1-55-* Def
+0 5 1 55 36 0.000 -0.058 0.084 C94
+0 5 1 55 57 0.000 -0.058 -0.092 C94
+0 0 1 56 0 0.000 0.000 -0.300 C94 0:*-1-56-* Def
+0 1 1 56 36 0.875 0.668 -0.015 C94
+0 1 1 56 57 -0.870 0.775 -0.406 C94
+0 5 1 56 36 -0.958 -0.629 -0.372 C94
+0 5 1 56 57 0.952 -0.715 -0.483 C94
+0 0 1 57 0 0.000 0.000 0.000 E94 0:*1-57-* Def
+5 0 1 57 0 0.000 0.000 0.000 E94 5:*1-57-* Def
+0 0 1 58 0 0.000 0.000 0.000 E94 0:*1-58-* Def
+0 0 1 62 0 0.000 0.000 0.250 C94 0:*-1-62-* Def
+0 5 1 62 18 0.000 0.000 0.270 X94
+0 0 1 63 0 0.000 0.000 0.000 E94 0:*1-63-* Def
+5 0 1 63 0 0.000 0.000 0.000 E94 5:*1-63-* Def
+0 0 1 64 0 0.000 0.000 0.000 E94 0:*1-64-* Def
+5 0 1 64 0 0.000 0.000 0.000 E94 5:*1-64-* Def
+0 0 1 67 0 0.000 0.000 0.000 E94 0:*1-67-* Def
+5 0 1 67 0 0.000 0.000 0.000 E94 5:*1-67-* Def
+0 0 1 68 0 0.000 0.000 0.400 C94 0:*-1-68-* Def
+0 1 1 68 1 -0.117 0.090 0.751 C94
+0 1 1 68 23 0.373 0.153 0.635 C94
+0 1 1 68 32 -0.090 -0.169 0.075 C94
+0 5 1 68 1 0.134 -0.112 0.329 C94
+0 5 1 68 23 -0.361 -0.202 0.560 C94
+0 5 1 68 32 0.072 0.218 0.093 C94
+0 0 1 73 0 0.000 0.000 0.500 C94 0:*-1-73-* Def
+0 5 1 73 32 0.000 0.000 0.509 X94
+0 5 1 73 72 0.000 0.000 0.443 X94
+0 0 1 75 0 0.000 0.000 0.000 E94 0:*1-75-* Def
+0 0 1 78 0 0.000 0.000 0.000 E94 0:*1-78-* Def
+0 0 1 80 0 0.000 0.000 0.000 E94 0:*1-80-* Def
+0 0 1 81 0 0.000 0.000 0.000 E94 0:*1-81-* Def
+0 0 2 2 0 0.000 12.000 0.000 C94 0:*-2=2-* Def
+1 0 2 2 0 0.000 1.800 0.000 C94 1:*=2-2=* Def
+5 0 2 2 0 0.000 12.000 0.000 C94 5:*-2=2-* Def
+0 1 2 2 1 -0.403 12.000 0.000 C94
+0 1 2 2 2 0.000 12.000 0.000 C94
+1 1 2 2 2 -0.418 2.089 -0.310 C94
+0 1 2 2 5 0.000 12.000 0.000 C94
+1 1 2 2 5 0.412 2.120 0.269 C94
+1 2 2 2 2 0.094 1.621 0.877 C94
+0 2 2 2 5 0.000 12.000 0.000 C94
+1 2 2 2 5 0.317 1.421 -0.870 C94
+0 3 2 2 5 0.000 12.000 0.000 C94
+0 5 2 2 5 0.000 12.000 0.000 C94
+1 5 2 2 5 -0.406 1.767 0.000 C94
+0 5 2 2 6 0.000 12.000 0.000 C94
+0 5 2 2 37 0.000 12.000 0.000 C94
+0 5 2 2 40 0.000 12.000 0.000 C94
+0 5 2 2 41 0.000 12.000 0.000 C94
+0 5 2 2 45 0.000 12.000 0.000 X94
+0 5 2 2 62 0.000 12.000 0.000 X94
+1 0 2 3 0 0.000 2.500 0.000 #E94 0:*-2-3-* Def
+1 1 2 3 1 0.136 1.798 0.630 C94
+1 1 2 3 5 0.497 2.405 0.357 C94
+1 1 2 3 6 -0.211 1.925 -0.131 C94
+1 1 2 3 7 -0.401 2.028 -0.318 C94
+1 1 2 3 10 -0.084 2.214 -0.610 C94
+1 2 2 3 1 -0.325 1.553 -0.487 C94
+1 2 2 3 5 -0.295 2.024 -0.590 C94
+1 2 2 3 6 -0.143 1.466 0.000 C94
+1 2 2 3 7 0.362 1.978 0.000 C94
+1 2 2 3 9 0.296 1.514 0.481 C94
+1 2 2 3 10 0.095 1.583 0.380 C94
+1 5 2 3 1 0.213 1.728 -0.042 C94
+1 5 2 3 5 -0.208 1.622 0.223 C94
+1 5 2 3 6 0.359 1.539 0.194 C94
+1 5 2 3 7 0.000 2.046 0.000 C94
+1 5 2 3 9 -0.290 1.519 -0.470 C94
+1 5 2 3 10 0.000 1.395 0.227 C94
+1 0 2 4 0 0.000 0.000 0.000 C94 0:*-2-4-* Def
+0 0 2 6 0 0.000 3.100 0.000 C94 0:*-2-6-* Def
+2 0 2 6 0 0.000 3.600 0.000 E94 2:*-2-6-* Def
+5 0 2 6 0 0.000 3.600 0.000 E94 5:*-2-6-* Def
+0 2 2 6 1 -1.953 3.953 -1.055 C94
+0 2 2 6 3 -1.712 2.596 -0.330 C94
+0 2 2 6 29 -0.215 2.810 -0.456 C94
+0 5 2 6 1 1.951 3.936 1.130 C94
+0 5 2 6 3 1.719 2.628 0.360 C94
+0 5 2 6 29 0.216 2.808 0.456 C94
+1 0 2 9 0 0.000 1.800 0.000 E94 1:*-2-9-* Def
+0 0 2 10 0 0.000 6.000 0.000 E94 0:*-2-10-* Def
+2 0 2 10 0 0.000 6.000 0.000 E94 2:*-2-10-* Def
+5 0 2 10 0 0.000 6.000 0.000 E94 5:*-2-10-* Def
+0 0 2 15 0 0.000 1.423 0.000 E94 0:*-2-15-* Def
+2 0 2 15 0 0.000 1.423 0.000 E94 2:*-2-15-* Def
+5 0 2 15 0 0.000 1.423 0.000 E94 5:*-2-15-* Def
+0 0 2 17 0 0.000 1.423 0.000 E94 0:*-2-17-* Def
+0 0 2 18 0 0.000 0.000 0.000 E94 0:*-2-18-* Def
+2 0 2 18 0 0.000 0.000 0.000 E94 2:*-2-18-* Def
+5 0 2 18 0 0.000 0.000 0.000 E94 5:*-2-18-* Def
+0 0 2 19 0 0.000 0.000 0.000 E94 0:*-2-19-* Def
+0 0 2 20 0 0.000 0.000 0.000 E94 0:*-2-20-* Def
+2 0 2 20 0 0.000 0.000 0.000 E94 2:*-2-20-* Def
+0 0 2 22 0 0.000 0.000 0.000 E94 0:*-2-22-* Def
+2 0 2 22 0 0.000 0.000 0.000 E94 2:*-2-22-* Def
+5 0 2 22 0 0.000 0.000 0.000 E94 5:*-2-22-* Def
+0 0 2 25 0 0.000 0.000 0.000 E94 0:*-2-25-* Def
+0 0 2 30 0 0.000 12.000 0.000 E94 0:*-2-30-* Def
+0 0 2 34 0 0.000 0.000 0.000 E94 0:*-2-34-* Def
+2 0 2 34 0 0.000 0.000 0.000 E94 2:*-2-34-* Def
+1 0 2 37 0 0.000 2.000 0.000 C94 1:*-2-37-* Def
+1 1 2 37 37 0.000 2.952 -0.079 C94
+1 2 2 37 37 0.000 1.542 0.434 C94
+1 5 2 37 37 0.000 1.308 -0.357 C94
+1 0 2 39 0 0.000 6.000 0.000 E94 1:*-2-39-* Def
+0 0 2 40 0 0.000 3.700 0.000 C94 0:*-2-40-* Def
+2 0 2 40 0 0.000 3.600 0.000 E94 2:*-2-40-* Def
+5 0 2 40 0 0.000 3.600 0.000 E94 5:*-2-40-* Def
+0 2 2 40 28 0.000 3.756 -0.530 C94
+0 5 2 40 28 0.073 3.698 0.291 C94
+0 0 2 41 0 0.000 1.200 0.000 C94 0:*-2-41-* Def
+2 0 2 41 0 0.000 1.800 0.000 E94 2:*-2-41-* Def
+0 2 2 41 32 0.000 1.235 0.000 C94
+0 5 2 41 32 0.000 1.231 0.000 C94
+0 0 2 43 0 0.000 3.600 0.000 E94 0:*-2-43-* Def
+2 0 2 43 0 0.000 3.600 0.000 E94 2:*-2-43-* Def
+0 0 2 45 0 0.000 2.200 0.000 C94 0:*-2-45-* Def
+2 0 2 45 0 0.000 1.800 0.000 E94 2:*-2-45-* Def
+0 2 2 45 32 0.000 2.212 0.000 X94
+0 5 2 45 32 0.000 2.225 0.000 X94
+0 0 2 46 0 0.000 1.800 0.000 E94 0:*-2-46-* Def
+2 0 2 46 0 0.000 1.800 0.000 E94 2:*-2-46-* Def
+0 0 2 55 0 0.000 4.800 0.000 E94 0:*-2-55-* Def
+0 0 2 56 0 0.000 4.800 0.000 E94 0:*-2-56-* Def
+0 0 2 62 0 0.000 8.000 0.000 C94 0:*-2-62-* Def
+0 2 2 62 23 1.693 7.903 0.532 X94
+0 5 2 62 23 -1.696 7.897 -0.482 X94
+1 0 2 63 0 0.000 1.800 0.000 E94 1:*-2-63-* Def
+1 0 2 64 0 0.000 1.800 0.000 E94 1:*-2-64-* Def
+1 0 2 67 0 0.000 1.800 0.000 E94 1:*-2-67-* Def
+1 0 2 81 0 0.000 4.800 0.000 E94 1:*-2-81-* Def
+1 0 3 3 0 0.000 0.600 0.000 C94 0:*-3-3-* Def
+4 0 3 3 0 0.000 1.800 0.000 E94 4:*-3-3-* Def
+1 1 3 3 1 -0.486 0.714 0.000 C94
+1 1 3 3 6 -0.081 -0.125 0.132 C94
+1 1 3 3 7 1.053 1.327 0.000 C94
+1 5 3 3 6 0.000 0.188 0.436 C94
+1 5 3 3 7 0.000 0.177 -0.412 C94
+1 6 3 3 6 0.269 0.437 0.000 C94
+1 6 3 3 7 -0.495 0.793 -0.318 C94
+1 7 3 3 7 -0.260 1.084 0.193 C94
+0 0 3 6 0 0.000 5.500 0.000 C94 0:*-3-6-* Def
+2 0 3 6 0 0.000 5.500 0.000 C94 2:*-3-6-* Def
+4 0 3 6 0 0.000 3.600 0.000 E94 4:*-3-6-* Def
+5 0 3 6 0 0.000 3.600 0.000 E94 5:*-3-6-* Def
+0 1 3 6 1 -1.244 5.482 0.365 C94
+0 1 3 6 24 -1.166 5.078 -0.545 C94
+0 1 3 6 37 -0.677 5.854 0.521 C94
+2 2 3 6 24 0.256 4.519 0.258 C94
+2 3 3 6 24 1.663 4.073 0.094 C94
+0 5 3 6 1 0.526 5.631 0.691 C94
+0 5 3 6 2 0.159 6.586 0.216 C94
+0 5 3 6 24 -2.285 4.737 0.468 C94
+0 7 3 6 0 0.700 6.500 -0.400 C94 0:7-3-6-* Def
+0 7 3 6 1 0.682 7.184 -0.935 C94
+0 7 3 6 2 -0.168 6.572 -0.151 C94
+0 7 3 6 24 1.662 6.152 -0.058 C94
+0 7 3 6 37 0.635 5.890 -0.446 C94
+2 37 3 6 24 0.000 3.892 -0.094 C94
+0 0 3 9 0 0.000 16.000 0.000 C94 0:*-3=9-* Def
+1 0 3 9 0 0.000 1.800 0.000 E94 1:*-3-9-* Def
+5 0 3 9 0 0.000 12.000 0.000 E94 5:*-3-9-* Def
+0 2 3 9 27 0.000 16.000 0.000 C94
+0 5 3 9 1 0.687 16.152 0.894 C94
+0 5 3 9 27 0.000 16.000 0.000 C94
+0 40 3 9 1 -0.758 18.216 -0.188 C94
+0 40 3 9 27 0.000 16.000 0.000 C94
+0 0 3 10 0 0.000 6.000 0.000 C94 0:*-3-10-* Def
+2 0 3 10 0 0.000 6.000 0.000 C94 2:*-3-10-* Def
+4 0 3 10 0 0.000 6.000 0.000 C94 4:*-3-10-* Def
+5 0 3 10 0 0.000 6.000 0.000 E94 5:*-3-10-* Def
+0 1 3 10 1 0.647 6.159 0.507 C94
+0 1 3 10 6 -1.035 8.791 1.464 C94
+0 1 3 10 28 -0.294 5.805 1.342 C94
+2 2 3 10 28 -0.287 7.142 0.120 C94
+0 5 3 10 1 -0.183 6.314 1.753 C94
+0 5 3 10 3 -0.751 5.348 0.209 C94
+0 5 3 10 28 -0.388 5.972 0.459 C94
+0 7 3 10 1 -0.319 6.294 -0.147 C94
+0 7 3 10 3 0.776 -0.585 -0.145 C94
+0 7 3 10 6 1.107 8.631 -0.452 C94
+0 7 3 10 28 1.435 4.975 -0.454 C94
+0 10 3 10 28 0.000 3.495 1.291 C94
+0 0 3 15 0 0.000 1.423 0.000 E94 0:*-3-15-* Def
+2 0 3 15 0 0.000 1.423 0.000 E94 2:*-3-15-* Def
+4 0 3 15 0 0.000 1.423 0.000 E94 4:*-3-15-* Def
+5 0 3 15 0 0.000 1.423 0.000 E94 5:*-3-15-* Def
+0 0 3 17 0 0.000 1.423 0.000 E94 0:*-3-17-* Def
+5 0 3 17 0 0.000 1.423 0.000 E94 5:*-3-17-* Def
+0 0 3 18 0 0.000 0.000 0.000 E94 0:*-3-18-* Def
+2 0 3 18 0 0.000 0.000 0.000 E94 2:*-3-18-* Def
+0 0 3 20 0 0.000 0.000 -0.300 C94 0:*-3-20-* Def
+2 0 3 20 0 0.000 0.000 0.000 E94 2:*-3-20-* Def
+4 0 3 20 0 0.000 0.000 -0.300 C94 4:*-3-20-* Def
+5 0 3 20 0 0.000 0.000 0.000 E94 5:*-3-20-* Def
+0 7 3 20 0 0.000 0.400 0.400 C94 0:7-3-20-* Def
+0 7 3 20 5 0.000 0.000 -0.131 C94
+0 7 3 20 20 0.000 0.000 0.000 C94
+0 20 3 20 5 0.000 0.000 0.085 C94
+0 20 3 20 20 0.000 0.000 0.000 C94
+0 0 3 22 0 0.000 0.000 0.000 E94 0:*-3-22-* Def
+2 0 3 22 0 0.000 0.000 0.000 E94 2:*-3-22-* Def
+4 0 3 22 0 0.000 0.000 0.000 E94 4:*-3-22-* Def
+5 0 3 22 0 0.000 0.000 0.000 E94 5:*-3-22-* Def
+0 7 3 22 0 0.000 0.400 0.400 C94 0:7-3-22-* Def
+0 0 3 25 0 0.000 0.000 0.000 E94 0:*-3-25-* Def
+2 0 3 25 0 0.000 0.000 0.000 E94 2:*-3-25-* Def
+1 0 3 30 0 0.000 1.800 0.000 E94 1:*-3-30-* Def
+4 0 3 30 0 0.000 1.800 0.000 E94 4:*-3-30-* Def
+1 0 3 37 0 0.000 2.500 0.000 #E94 1:*-3-37-* Def
+4 0 3 37 0 0.000 1.800 0.000 E94 4:*-3-37-* Def
+1 1 3 37 37 0.000 2.428 0.000 C94
+1 6 3 37 37 0.000 1.743 0.000 C94
+1 7 3 37 37 0.000 2.256 0.000 C94
+1 43 3 37 37 -0.241 3.385 -0.838 X94
+1 0 3 39 0 0.000 5.500 0.000 #E94 1:*-3-39-* Def
+0 0 3 40 0 0.000 3.900 0.000 C94 0:*-3-40-* Def
+2 0 3 40 0 0.000 3.600 0.000 E94 2:*-3-40-* Def
+5 0 3 40 0 0.000 3.600 0.000 E94 5:*-3-40-* Def
+0 5 3 40 28 -1.477 4.362 0.902 C94
+0 9 3 40 28 1.496 4.369 -0.417 C94
+0 40 3 40 28 0.178 3.149 0.778 C94
+0 0 3 41 0 0.000 1.800 0.000 E94 0:*-3-41-* Def
+2 0 3 41 0 0.000 1.800 0.000 E94 2:*-3-41-* Def
+0 0 3 43 0 0.000 4.500 0.000 C94 0:*-3-43-* Def
+2 0 3 43 0 0.000 3.600 0.000 E94 2:*-3-43-* Def
+4 0 3 43 0 0.000 3.600 0.000 E94 4:*-3-43-* Def
+5 0 3 43 0 0.000 3.600 0.000 E94 5:*-3-43-* Def
+0 1 3 43 18 1.712 3.309 0.233 X94
+0 1 3 43 28 -0.414 4.168 -0.875 X94
+0 7 3 43 18 -0.880 5.091 -0.129 X94
+0 7 3 43 28 0.536 5.276 -0.556 X94
+2 37 3 43 18 -0.701 4.871 1.225 X94
+2 37 3 43 28 -0.086 5.073 0.878 X94
+0 0 3 45 0 0.000 1.800 0.000 E94 0:*-3-45-* Def
+2 0 3 45 0 0.000 1.800 0.000 E94 2:*-3-45-* Def
+0 0 3 48 0 0.000 0.000 0.892 E94 0:*-3-48-* Def
+0 0 3 51 0 0.000 13.500 0.000 C94 0:*-3-51-* Def
+0 1 3 51 52 0.000 13.549 0.000 X94
+0 0 3 54 0 0.000 8.000 0.000 C94 0:*-3-54-* Def
+1 0 3 54 0 0.000 2.500 0.000 #E94 1:*-3-54-* Def
+5 0 3 54 0 0.000 12.000 0.000 E94 5:*-3-54-* Def
+0 5 3 54 1 0.000 8.000 0.000 C94
+0 5 3 54 36 0.000 8.000 0.000 C94
+0 0 3 55 0 0.000 4.800 0.000 E94 0:*-3-55-* Def
+2 0 3 55 0 0.000 4.800 0.000 E94 2:*-3-55-* Def
+0 0 3 56 0 0.000 4.800 0.000 E94 0:*-3-56-* Def
+2 0 3 56 0 0.000 4.800 0.000 E94 2:*-3-56-* Def
+1 0 3 57 0 0.000 2.500 0.000 #E94 1:*-3-57-* Def
+1 0 3 58 0 0.000 4.800 0.000 E94 1:*-3-58-* Def
+0 0 3 62 0 0.000 3.600 0.000 E94 0:*-3-62-* Def
+2 0 3 62 0 0.000 3.600 0.000 E94 2:*-3-62-* Def
+5 0 3 62 0 0.000 3.600 0.000 E94 5:*-3-62-* Def
+1 0 3 63 0 0.000 2.500 0.000 #E94 1:*-3-63-* Def
+1 0 3 64 0 0.000 2.500 0.000 #E94 1:*-3-64-* Def
+0 0 3 67 0 0.000 12.000 0.000 E94 0:*-3-67-* Def
+0 0 3 74 0 0.000 19.000 0.000 C94 0:*-3-74-* Def
+0 1 3 74 7 0.000 19.349 0.000 X94
+0 0 3 75 0 0.000 19.000 0.000 C94 0:*-3-75-* Def
+0 1 3 75 71 0.000 18.751 0.000 X94
+1 0 3 78 0 0.000 2.500 0.000 #E94 1:*-3-78-* Def
+1 0 3 80 0 0.000 2.500 0.000 #E94 1:*-3-80-* Def
+0 0 6 6 0 0.000 -2.000 0.000 E94 0:*-6-6-* Def
+5 0 6 6 0 0.000 -2.000 0.000 E94 5:*-6-6-* Def
+0 0 6 8 0 0.900 -1.100 -0.500 C94 0:*-6-8-* Def
+5 0 6 8 0 0.000 0.000 0.274 E94 5:*-6-8-* Def
+0 21 6 8 1 0.261 -0.330 -0.542 C94
+0 21 6 8 23 1.503 -1.853 -0.476 C94
+0 0 6 9 0 0.000 3.600 0.000 E94 0:*-6-9-* Def
+5 0 6 9 0 0.000 3.600 0.000 E94 5:*-6-9-* Def
+0 0 6 10 0 1.200 0.500 -1.000 C94 0:*-6-10-* Def
+0 21 6 10 1 0.875 0.180 -0.733 C94
+0 21 6 10 3 0.529 0.000 -1.163 C94
+0 0 6 15 0 0.000 -4.000 0.000 E94 0:*-6-15-* Def
+0 0 6 17 0 0.000 1.423 0.000 E94 0:*-6-17-* Def
+5 0 6 17 0 0.000 1.423 0.000 E94 5:*-6-17-* Def
+0 0 6 18 0 0.000 0.000 0.100 C94 0:*-6-18-* Def
+5 0 6 18 0 0.000 0.000 0.103 E94 5:*-6-18-* Def
+0 33 6 18 1 -0.520 -0.471 -0.267 X94
+0 33 6 18 6 -1.623 0.204 0.438 X94
+0 33 6 18 32 1.616 0.425 0.191 X94
+0 0 6 19 0 0.000 0.000 0.150 C94 0:*-6-19-* Def
+5 0 6 19 0 0.000 0.000 0.165 E94 5:*-6-19-* Def
+0 21 6 19 1 -0.620 -0.329 0.303 X94
+0 21 6 19 5 0.683 0.220 0.000 X94
+0 0 6 20 0 0.000 0.000 0.400 C94 0:*-6-20-* Def
+4 0 6 20 0 0.000 0.000 0.217 E94 4:*-6-20-* Def
+5 0 6 20 0 0.000 0.000 0.217 E94 5:*-6-20-* Def
+0 20 6 20 5 0.000 0.000 -0.079 C94
+4 20 6 20 20 0.000 0.000 0.000 C94
+0 0 6 22 0 0.000 0.000 0.217 E94 0:*-6-22-* Def
+0 0 6 25 0 0.000 0.000 0.650 C94 0:*-6-25-* Def
+5 0 6 25 0 0.000 0.000 0.231 E94 5:*-6-25-* Def
+0 1 6 25 1 -1.704 -0.452 0.556 X94
+0 1 6 25 6 0.000 0.000 0.777 X94
+0 1 6 25 32 1.205 0.914 0.612 X94
+0 24 6 25 6 -3.209 -7.622 1.065 X94
+0 24 6 25 32 -5.891 -3.332 0.290 X94
+0 0 6 26 0 0.000 0.000 0.346 E94 0:*-6-26-* Def
+0 0 6 30 0 0.000 3.600 0.000 E94 0:*-6-30-* Def
+2 0 6 30 0 0.000 3.600 0.000 E94 2:*-6-30-* Def
+0 0 6 37 0 0.000 3.200 0.000 C94 0:*-6-37-* Def
+5 0 6 37 0 0.000 3.600 0.000 E94 5:*-6-37-* Def
+0 1 6 37 37 0.000 4.382 0.000 C94
+0 3 6 37 37 0.000 2.576 0.000 C94
+0 29 6 37 37 0.000 2.801 0.000 C94
+0 0 6 39 0 0.000 0.000 0.000 E94 0:*-6-39-* Def
+0 0 6 40 0 0.000 0.000 0.274 E94 0:*-6-40-* Def
+0 0 6 41 0 0.000 3.600 0.000 E94 0:*-6-41-* Def
+0 0 6 43 0 0.000 0.000 0.274 E94 0:*-6-43-* Def
+0 0 6 45 0 0.000 6.000 0.000 C94 0:*-6-45-* Def
+0 1 6 45 32 0.000 6.208 0.000 X94
+0 0 6 54 0 0.000 3.600 0.000 E94 0:*-6-54-* Def
+0 0 6 55 0 0.000 3.600 0.000 E94 0:*-6-55-* Def
+0 0 6 57 0 0.000 3.600 0.000 E94 0:*-6-57-* Def
+0 0 6 58 0 0.000 3.600 0.000 E94 0:*-6-58-* Def
+0 0 6 63 0 0.000 3.600 0.000 E94 0:*-6-63-* Def
+0 0 6 64 0 0.000 3.600 0.000 E94 0:*-6-64-* Def
+0 0 8 8 0 0.000 0.000 0.375 E94 0:*-8-8-* Def
+5 0 8 8 0 0.000 0.000 0.375 E94 5:*-8-8-* Def
+0 0 8 9 0 0.000 3.600 0.000 E94 0:*-8-9-* Def
+5 0 8 9 0 0.000 3.600 0.000 E94 5:*-8-9-* Def
+0 0 8 10 0 0.000 0.000 0.000 E94 0:*-8-10-* Def
+4 0 8 10 0 0.000 0.000 0.000 E94 4:*-8-10-* Def
+0 0 8 15 0 0.000 0.000 0.424 E94 0:*-8-15-* Def
+0 0 8 17 0 0.000 1.423 0.000 E94 0:*-8-17-* Def
+4 0 8 17 0 0.000 1.423 0.000 E94 4:*-8-17-* Def
+5 0 8 17 0 0.000 1.423 0.000 E94 5:*-8-17-* Def
+0 0 8 19 0 0.000 0.000 0.225 E94 0:*-8-19-* Def
+0 0 8 20 0 0.000 0.000 0.350 C94 0:*-8-20-* Def
+4 0 8 20 0 0.000 0.000 0.300 C94 4:*-8-20-* Def
+5 0 8 20 0 0.000 0.000 0.297 E94 5:*-8-20-* Def
+0 20 8 20 5 0.000 0.120 0.472 C94
+4 20 8 20 20 0.000 -0.097 0.200 C94
+0 23 8 20 5 -0.101 -0.324 0.371 C94
+0 23 8 20 20 0.107 0.253 0.151 C94
+0 0 8 22 0 0.000 0.000 0.297 E94 0:*-8-22-* Def
+0 0 8 25 0 0.000 0.000 0.316 E94 0:*-8-25-* Def
+5 0 8 25 0 0.000 0.000 0.316 E94 5:*-8-25-* Def
+0 0 8 26 0 0.000 0.000 0.474 E94 0:*-8-26-* Def
+5 0 8 26 0 0.000 0.000 0.474 E94 5:*-8-26-* Def
+0 0 8 34 0 0.000 0.000 0.250 E94 0:*-8-34-* Def
+0 0 8 39 0 0.000 0.000 0.000 E94 0:*-8-39-* Def
+0 0 8 40 0 0.000 0.000 0.375 E94 0:*-8-40-* Def
+0 0 8 43 0 0.000 0.000 0.375 E94 0:*-8-43-* Def
+0 0 8 45 0 0.000 3.600 0.000 E94 0:*-8-45-* Def
+0 0 8 46 0 0.000 3.600 0.000 E94 0:*-8-46-* Def
+0 0 8 55 0 0.000 3.600 0.000 E94 0:*-8-55-* Def
+0 0 8 56 0 0.000 3.600 0.000 E94 0:*-8-56-* Def
+0 0 9 9 0 0.000 12.000 0.000 E94 0:*-9-9-* Def
+1 0 9 9 0 0.000 1.800 0.000 E94 1:*-9-9-* Def
+5 0 9 9 0 0.000 12.000 0.000 E94 5:*-9-9-* Def
+0 0 9 10 0 0.000 6.000 0.000 E94 0:*-9-10-* Def
+5 0 9 10 0 0.000 6.000 0.000 E94 5:*-9-10-* Def
+0 0 9 15 0 0.000 1.423 0.000 E94 0:*-9-15-* Def
+0 0 9 18 0 0.000 0.000 0.000 E94 0:*-9-18-* Def
+0 0 9 19 0 0.000 0.000 0.000 E94 0:*-9-19-* Def
+0 0 9 20 0 0.000 0.000 0.000 E94 0:*-9-20-* Def
+0 0 9 25 0 0.000 0.000 0.000 E94 0:*-9-25-* Def
+0 0 9 34 0 0.000 0.000 0.000 E94 0:*-9-34-* Def
+5 0 9 34 0 0.000 0.000 0.000 E94 5:*-9-34-* Def
+1 0 9 37 0 0.000 1.800 0.000 E94 1:*-9-37-* Def
+1 0 9 39 0 0.000 6.000 0.000 E94 1:*-9-39-* Def
+0 0 9 40 0 0.000 3.600 0.000 E94 0:*-9-40-* Def
+0 0 9 41 0 0.000 4.800 0.000 E94 0:*-9-41-* Def
+0 0 9 45 0 0.000 1.800 0.000 E94 0:*-9-45-* Def
+0 0 9 54 0 0.000 12.000 0.000 E94 0:*-9-54-* Def
+0 0 9 55 0 0.000 4.800 0.000 E94 0:*-9-55-* Def
+0 0 9 56 0 0.000 4.800 0.000 E94 0:*-9-56-* Def
+1 0 9 57 0 0.000 1.800 0.000 E94 1:*-9-57-* Def
+0 0 9 62 0 0.000 3.600 0.000 E94 0:*-9-62-* Def
+1 0 9 63 0 0.000 1.800 0.000 E94 1:*-9-63-* Def
+1 0 9 64 0 0.000 1.800 0.000 E94 1:*-9-64-* Def
+0 0 9 67 0 0.000 12.000 0.000 E94 0:*-9-67-* Def
+1 0 9 78 0 0.000 1.800 0.000 E94 1:*-9-78-* Def
+1 0 9 81 0 0.000 4.800 0.000 E94 1:*-9-81-* Def
+0 0 10 10 0 0.000 0.000 0.000 E94 0:*-10-10-* Def
+5 0 10 10 0 0.000 0.000 0.000 E94 5:*-10-10-* Def
+0 0 10 15 0 0.000 0.000 0.000 E94 0:*-10-15-* Def
+0 0 10 17 0 0.000 4.743 0.000 E94 0:*-10-17-* Def
+0 0 10 20 0 0.000 0.000 0.000 E94 0:*-10-20-* Def
+4 0 10 20 0 0.000 0.000 0.000 E94 4:*-10-20-* Def
+5 0 10 20 0 0.000 0.000 0.000 E94 5:*-10-20-* Def
+0 0 10 22 0 0.000 0.000 0.000 E94 0:*-10-22-* Def
+0 0 10 25 0 0.000 0.000 0.000 E94 0:*-10-25-* Def
+0 0 10 26 0 0.000 0.000 0.000 E94 0:*-10-26-* Def
+5 0 10 26 0 0.000 0.000 0.000 E94 5:*-10-26-* Def
+0 0 10 34 0 0.000 0.000 0.000 E94 0:*-10-34-* Def
+0 0 10 37 0 0.000 6.000 0.000 E94 0:*-10-37-* Def
+0 0 10 39 0 0.000 0.000 0.000 E94 0:*-10-39-* Def
+0 0 10 40 0 0.000 0.000 0.000 E94 0:*-10-40-* Def
+5 0 10 40 0 0.000 0.000 0.000 E94 5:*-10-40-* Def
+0 0 10 41 0 0.000 6.000 0.000 E94 0:*-10-41-* Def
+0 0 10 45 0 0.000 6.000 0.000 E94 0:*-10-45-* Def
+0 0 10 63 0 0.000 6.000 0.000 E94 0:*-10-63-* Def
+0 0 10 64 0 0.000 6.000 0.000 E94 0:*-10-64-* Def
+0 0 15 15 0 -1.400 -8.300 1.000 C94 0:*-15-15-* Def
+5 0 15 15 0 0.000 -8.000 0.000 E94 5:*-15-15-* Def
+0 1 15 15 1 -1.663 -8.408 1.433 C94
+0 1 15 15 71 -1.088 -8.245 0.411 C94
+0 0 15 18 0 0.000 0.000 0.160 E94 0:*-15-18-* Def
+0 0 15 19 0 0.000 0.000 0.255 E94 0:*-15-19-* Def
+5 0 15 19 0 0.000 0.000 0.255 E94 5:*-15-19-* Def
+0 0 15 20 0 0.000 0.000 0.336 E94 0:*-15-20-* Def
+4 0 15 20 0 0.000 0.000 0.336 E94 4:*-15-20-* Def
+0 0 15 22 0 0.000 0.000 0.336 E94 0:*-15-22-* Def
+0 0 15 25 0 0.000 0.000 0.358 E94 0:*-15-25-* Def
+4 0 15 25 0 0.000 0.000 0.358 E94 4:*-15-25-* Def
+0 0 15 26 0 0.000 0.000 0.537 E94 0:*-15-26-* Def
+0 0 15 30 0 0.000 1.423 0.000 E94 0:*-15-30-* Def
+4 0 15 30 0 0.000 1.423 0.000 E94 4:*-15-30-* Def
+0 0 15 37 0 0.000 1.300 0.000 C94 0:*-15-37-* Def
+5 0 15 37 0 0.000 1.423 0.000 E94 5:*-15-37-* Def
+0 1 15 37 37 0.000 2.177 0.000 C94
+0 71 15 37 37 0.000 0.505 0.333 C94
+0 0 15 40 0 0.000 0.000 0.424 E94 0:*-15-40-* Def
+0 0 15 43 0 0.000 0.000 0.424 E94 0:*-15-43-* Def
+0 0 15 57 0 0.000 1.423 0.000 E94 0:*-15-57-* Def
+0 0 15 63 0 0.000 1.423 0.000 E94 0:*-15-63-* Def
+0 0 15 64 0 0.000 1.423 0.000 E94 0:*-15-64-* Def
+0 0 17 20 0 0.000 0.000 0.000 E94 0:*-17-20-* Def
+4 0 17 20 0 0.000 0.000 0.000 E94 4:*-17-20-* Def
+5 0 17 20 0 0.000 0.000 0.000 E94 5:*-17-20-* Def
+0 0 17 22 0 0.000 0.000 0.000 E94 0:*-17-22-* Def
+0 0 17 37 0 0.000 1.423 0.000 E94 0:*-17-37-* Def
+0 0 17 43 0 0.000 3.795 0.000 E94 0:*-17-43-* Def
+0 0 18 20 0 0.000 0.000 0.112 E94 0:*-18-20-* Def
+4 0 18 20 0 0.000 0.000 0.112 E94 4:*-18-20-* Def
+5 0 18 20 0 0.000 0.000 0.112 E94 5:*-18-20-* Def
+0 0 18 22 0 0.000 0.000 0.112 E94 0:*-18-22-* Def
+0 0 18 37 0 0.000 -1.200 -0.300 C94 0:*-18-37-* Def
+0 32 18 37 37 -0.173 -0.965 -0.610 X94
+0 39 18 37 37 0.000 -0.760 0.227 X94
+0 43 18 37 37 0.228 -1.741 -0.371 X94
+0 0 18 39 0 0.000 0.000 0.500 C94 0:*-18-39-* Def
+0 32 18 39 63 0.000 0.687 0.680 X94
+0 37 18 39 63 0.000 -0.513 0.357 X94
+0 0 18 43 0 0.000 0.000 0.350 C94 0:*-18-43-* Def
+4 0 18 43 0 0.000 0.000 0.141 E94 4:*-18-43-* Def
+5 0 18 43 0 0.000 0.000 0.141 E94 5:*-18-43-* Def
+0 1 18 43 1 -0.914 -0.482 0.179 X94
+0 1 18 43 3 -0.392 -2.724 0.312 X94
+0 1 18 43 28 -1.508 -1.816 -0.175 X94
+0 1 18 43 37 0.823 -1.220 -0.770 X94
+0 32 18 43 1 1.588 1.499 1.410 X94
+0 32 18 43 3 0.653 0.254 0.000 X94
+0 32 18 43 28 0.528 0.342 0.000 X94
+0 32 18 43 37 0.812 1.513 1.266 X94
+0 37 18 43 1 -1.139 -0.703 1.088 X94
+0 37 18 43 28 -2.014 -1.646 -2.068 X94
+0 37 18 43 37 -1.519 -0.328 1.437 X94
+0 43 18 43 28 3.011 -1.405 2.038 X94
+0 0 18 48 0 0.000 0.000 0.400 C94 0:*-18-48-* Def
+0 1 18 48 28 1.767 1.606 0.408 X94
+0 32 18 48 28 -1.463 -2.548 0.310 X94
+0 0 18 55 0 0.000 0.000 0.000 E94 0:*-18-55-* Def
+0 0 18 58 0 0.000 0.000 0.000 E94 0:*-18-58-* Def
+0 0 18 62 0 0.000 0.000 0.500 C94 0:*-18-62-* Def
+0 1 18 62 1 -0.403 -0.273 0.440 X94
+0 32 18 62 1 0.291 0.385 0.582 X94
+0 0 18 63 0 0.000 0.000 0.000 E94 0:*-18-63-* Def
+0 0 18 64 0 0.000 0.000 0.000 E94 0:*-18-64-* Def
+0 0 18 80 0 0.000 0.000 0.000 E94 0:*-18-80-* Def
+0 0 19 20 0 0.000 0.000 0.179 E94 0:*-19-20-* Def
+4 0 19 20 0 0.000 0.000 0.179 E94 4:*-19-20-* Def
+0 0 19 37 0 0.000 0.000 0.000 E94 0:*-19-37-* Def
+0 0 19 40 0 0.000 0.000 0.225 E94 0:*-19-40-* Def
+0 0 19 63 0 0.000 0.000 0.000 E94 0:*-19-63-* Def
+0 0 19 75 0 0.000 0.000 0.000 E94 0:*-19-75-* Def
+0 0 20 20 0 0.000 0.000 0.200 C94 0:*-20-20-* Def
+4 0 20 20 0 0.000 0.000 0.000 C94 4:*-20-20-* Def
+5 0 20 20 0 0.000 0.000 0.236 E94 5:*-20-20-* Def
+0 1 20 20 5 0.067 0.081 0.347 C94
+0 1 20 20 20 -0.063 -0.064 0.140 C94
+0 3 20 20 5 0.000 0.000 0.083 C94
+0 3 20 20 20 0.000 0.000 0.000 C94
+0 5 20 20 5 0.000 0.000 0.424 C94
+0 5 20 20 6 0.000 0.000 -0.080 C94
+0 5 20 20 8 0.000 0.127 0.450 C94
+0 5 20 20 12 -0.072 -0.269 0.439 C94
+0 5 20 20 20 -0.057 0.000 0.307 C94
+4 6 20 20 20 0.000 0.000 0.000 C94
+4 8 20 20 20 0.000 -0.091 0.192 C94
+0 12 20 20 20 0.077 0.202 0.183 C94
+4 20 20 20 20 0.000 0.000 0.000 C94
+0 0 20 22 0 0.000 0.000 0.236 E94 0:*-20-22-* Def
+4 0 20 22 0 0.000 0.000 0.236 E94 4:*-20-22-* Def
+0 0 20 25 0 0.000 0.000 0.251 E94 0:*-20-25-* Def
+4 0 20 25 0 0.000 0.000 0.251 E94 4:*-20-25-* Def
+0 0 20 26 0 0.000 0.000 0.376 E94 0:*-20-26-* Def
+4 0 20 26 0 0.000 0.000 0.376 E94 4:*-20-26-* Def
+5 0 20 26 0 0.000 0.000 0.376 E94 5:*-20-26-* Def
+0 0 20 30 0 0.000 0.000 0.000 E94 0:*-20-30-* Def
+2 0 20 30 0 0.000 0.000 0.000 E94 2:*-20-30-* Def
+4 0 20 30 0 0.000 0.000 0.000 E94 4:*-20-30-* Def
+0 0 20 30 30 0.000 0.000 -0.500 C94 0:*-20-30=30 Def
+0 0 20 34 0 0.000 0.000 0.198 E94 0:*-20-34-* Def
+4 0 20 34 0 0.000 0.000 0.198 E94 4:*-20-34-* Def
+0 0 20 37 0 0.000 0.000 0.000 E94 0:*-20-37-* Def
+4 0 20 37 0 0.000 0.000 0.000 E94 4:*-20-37-* Def
+0 0 20 40 0 0.000 0.000 0.297 E94 0:*-20-40-* Def
+0 0 20 41 0 0.000 0.000 0.000 E94 0:*-20-41-* Def
+0 0 20 43 0 0.000 0.000 0.297 E94 0:*-20-43-* Def
+4 0 20 43 0 0.000 0.000 0.297 E94 4:*-20-43-* Def
+0 0 20 45 0 0.000 0.000 0.000 E94 0:*-20-45-* Def
+0 0 22 22 0 0.000 0.000 0.236 E94 0:*-22-22-* Def
+4 0 22 22 0 0.000 0.000 0.236 E94 4:*-22-22-* Def
+5 0 22 22 0 0.000 0.000 0.236 E94 5:*-22-22-* Def
+0 0 22 30 0 0.000 0.000 0.000 E94 0:*-22-30-* Def
+4 0 22 30 0 0.000 0.000 0.000 E94 4:*-22-30-* Def
+0 0 22 34 0 0.000 0.000 0.198 E94 0:*-22-34-* Def
+0 0 22 37 0 0.000 0.000 0.000 E94 0:*-22-37-* Def
+0 0 22 40 0 0.000 0.000 0.297 E94 0:*-22-40-* Def
+0 0 22 41 0 0.000 0.000 0.000 E94 0:*-22-41-* Def
+0 0 22 43 0 0.000 0.000 0.297 E94 0:*-22-43-* Def
+5 0 22 43 0 0.000 0.000 0.297 E94 5:*-22-43-* Def
+0 0 22 45 0 0.000 0.000 0.000 E94 0:*-22-45-* Def
+0 0 25 25 0 0.000 0.000 0.267 E94 0:*-25-25-* Def
+0 0 25 37 0 0.000 0.000 0.000 E94 0:*-25-37-* Def
+5 0 25 37 0 0.000 0.000 0.000 E94 5:*-25-37-* Def
+0 0 25 39 0 0.000 0.000 0.000 E94 0:*-25-39-* Def
+0 0 25 40 0 0.000 0.000 0.316 E94 0:*-25-40-* Def
+5 0 25 40 0 0.000 0.000 0.316 E94 5:*-25-40-* Def
+0 0 25 43 0 0.000 0.000 0.250 C94 0:*-25-43-* Def
+0 1 25 43 1 -2.686 -1.512 0.591 X94
+0 1 25 43 28 -3.730 -0.531 0.000 X94
+0 32 25 43 1 2.108 1.896 0.965 X94
+0 32 25 43 28 2.977 0.732 -0.502 X94
+0 0 25 57 0 0.000 0.000 0.000 E94 0:*-25-57-* Def
+0 0 25 63 0 0.000 0.000 0.000 E94 0:*-25-63-* Def
+0 0 26 26 0 0.000 0.000 0.600 E94 0:*-26-26-* Def
+5 0 26 26 0 0.000 0.000 0.600 E94 5:*-26-26-* Def
+0 0 26 34 0 0.000 0.000 0.316 E94 0:*-26-34-* Def
+5 0 26 34 0 0.000 0.000 0.316 E94 5:*-26-34-* Def
+0 0 26 37 0 0.000 1.423 0.000 E94 0:*-26-37-* Def
+0 0 26 40 0 0.000 0.000 0.474 E94 0:*-26-40-* Def
+0 0 30 30 0 0.000 12.000 0.000 E94 0:*-30-30-* Def
+1 0 30 30 0 0.000 1.800 0.000 E94 1:*-30-30-* Def
+4 0 30 30 0 0.000 1.800 0.000 E94 4:*-30-30-* Def
+0 0 30 40 0 0.000 3.600 0.000 E94 0:*-30-40-* Def
+1 0 30 67 0 0.000 1.800 0.000 E94 1:*-30-67-* Def
+0 0 34 37 0 0.000 0.000 0.000 E94 0:*-34-37-* Def
+0 0 34 43 0 0.000 0.000 0.250 E94 0:*-34-43-* Def
+0 0 37 37 0 0.000 7.000 0.000 C94 0:*-37-37-* Def
+1 0 37 37 0 0.000 2.000 0.000 #E94 1:*-37-37-* Def
+4 0 37 37 0 0.000 6.000 0.000 E94 4:*-37-37-* Def
+5 0 37 37 0 0.000 6.000 0.000 E94 5:*-37-37-* Def
+0 1 37 37 5 0.000 7.000 0.000 C94
+0 1 37 37 37 0.000 7.000 0.000 C94
+0 2 37 37 5 0.000 7.000 0.000 C94
+0 2 37 37 37 0.000 7.000 0.000 C94
+0 3 37 37 5 0.000 7.000 0.000 C94
+0 3 37 37 37 0.000 7.000 0.000 C94
+0 5 37 37 5 0.000 7.000 0.000 C94
+0 5 37 37 6 0.000 7.000 0.000 C94
+0 5 37 37 15 0.000 7.000 0.000 C94
+0 5 37 37 18 0.000 7.000 0.000 X94
+0 5 37 37 37 0.000 7.000 0.000 C94
+0 5 37 37 40 0.000 7.000 0.000 C94
+0 5 37 37 43 0.000 7.000 0.000 X94
+0 6 37 37 37 0.000 7.000 0.000 C94
+0 15 37 37 37 0.000 7.000 0.000 C94
+0 18 37 37 37 0.000 7.000 0.000 X94
+0 37 37 37 37 0.000 7.000 0.000 C94
+0 37 37 37 40 0.000 7.000 0.000 C94
+0 37 37 37 43 0.000 7.000 0.000 X94
+0 0 37 38 0 0.000 7.000 0.000 C94 0:*-37-38-* Def
+0 0 37 39 0 0.000 3.600 0.000 E94 0:*-37-39-* Def
+1 0 37 39 0 0.000 6.000 0.000 E94 1:*-37-39-* Def
+0 0 37 40 0 0.000 4.000 0.000 C94 0:*-37-40-* Def
+5 0 37 40 0 0.000 3.600 0.000 E94 5:*-37-40-* Def
+0 37 37 40 1 0.000 4.336 0.370 C94
+0 37 37 40 28 0.715 2.628 3.355 C94
+0 0 37 41 0 0.000 1.800 0.000 E94 0:*-37-41-* Def
+0 0 37 43 0 0.000 2.000 1.800 C94 0:*-37-43-* Def
+5 0 37 43 0 0.000 3.600 0.000 E94 5:*-37-43-* Def
+0 37 37 43 18 0.372 2.284 2.034 X94
+0 37 37 43 28 0.000 1.694 1.508 X94
+0 0 37 45 0 0.000 1.800 0.000 E94 0:*-37-45-* Def
+0 0 37 46 0 0.000 1.800 0.000 E94 0:*-37-46-* Def
+0 0 37 55 0 0.000 4.800 0.000 E94 0:*-37-55-* Def
+0 0 37 56 0 0.000 4.800 0.000 E94 0:*-37-56-* Def
+1 0 37 57 0 0.000 1.800 0.000 E94 1:*-37-57-* Def
+0 0 37 58 0 0.000 6.000 0.000 E94 0:*-37-58-* Def
+1 0 37 58 0 0.000 4.800 0.000 E94 1:*-37-58-* Def
+0 0 37 62 0 0.000 3.600 0.000 E94 0:*-37-62-* Def
+0 0 37 63 0 0.000 7.000 0.000 C94 0:*-37-63-* Def
+1 0 37 63 0 0.000 1.800 0.000 E94 1:*-37-63-* Def
+0 0 37 64 0 0.000 7.000 0.000 C94 0:*-37-64-* Def
+1 0 37 64 0 0.000 1.800 0.000 E94 1:*-37-64-* Def
+1 0 37 67 0 0.000 1.800 0.000 E94 1:*-37-67-* Def
+0 0 37 69 0 0.000 7.000 0.000 C94 0:*-37-69-* Def
+0 0 37 78 0 0.000 6.000 0.000 E94 0:*-37-78-* Def
+0 0 37 81 0 0.000 6.000 0.000 E94 0:*-37-81-* Def
+1 0 37 81 0 0.000 4.800 0.000 E94 1:*-37-81-* Def
+0 0 38 38 0 0.000 7.000 0.000 C94 0:*-38-38-* Def
+0 0 38 58 0 0.000 7.000 0.000 C94 0:*-38-58-* Def
+0 0 38 63 0 0.000 7.000 0.000 C94 0:*-38-63-* Def
+0 0 38 64 0 0.000 7.000 0.000 C94 0:*-38-64-* Def
+0 0 38 69 0 0.000 6.000 0.000 E94 0:*-38-69-* Def
+0 0 38 78 0 0.000 6.000 0.000 E94 0:*-38-78-* Def
+0 0 39 40 0 0.000 0.000 0.000 E94 0:*-39-40-* Def
+0 0 39 45 0 0.000 6.000 0.000 E94 0:*-39-45-* Def
+0 0 39 63 0 0.000 4.000 0.000 C94 0:*-39-63-* Def
+1 0 39 63 0 0.000 6.000 0.000 E94 1:*-39-63-* Def
+5 0 39 63 0 0.000 3.600 0.000 E94 5:*-39-63-* Def
+0 1 39 63 5 0.000 4.000 0.000 C94
+0 1 39 63 64 0.000 4.000 0.000 C94
+0 18 39 63 5 0.000 4.000 0.000 X94
+0 18 39 63 64 0.000 4.000 0.000 X94
+0 63 39 63 5 0.000 4.000 0.000 C94
+0 63 39 63 64 0.000 4.000 0.000 C94
+0 0 39 64 0 0.000 3.600 0.000 E94 0:*-39-64-* Def
+1 0 39 64 0 0.000 6.000 0.000 E94 1:*-39-64-* Def
+0 0 39 65 0 0.000 4.000 0.000 C94 0:*-39-65-* Def
+0 0 39 78 0 0.000 3.600 0.000 E94 0:*-39-78-* Def
+0 0 40 40 0 0.000 0.000 0.375 E94 0:*-40-40-* Def
+0 0 40 45 0 0.000 3.600 0.000 E94 0:*-40-45-* Def
+0 0 40 46 0 0.000 3.600 0.000 E94 0:*-40-46-* Def
+0 0 40 54 0 0.000 3.600 0.000 E94 0:*-40-54-* Def
+2 0 40 54 0 0.000 3.600 0.000 E94 2:*-40-54-* Def
+0 0 40 63 0 0.000 3.600 0.000 E94 0:*-40-63-* Def
+0 0 40 64 0 0.000 3.600 0.000 E94 0:*-40-64-* Def
+0 0 40 78 0 0.000 3.600 0.000 E94 0:*-40-78-* Def
+0 0 41 41 0 0.000 1.800 0.000 E94 0:*-41-41-* Def
+0 0 41 55 0 0.000 4.800 0.000 E94 0:*-41-55-* Def
+0 0 41 62 0 0.000 3.600 0.000 E94 0:*-41-62-* Def
+0 0 41 80 0 0.000 1.800 0.000 E94 0:*-41-80-* Def
+0 0 43 43 0 0.000 0.000 0.375 E94 0:*-43-43-* Def
+0 0 43 45 0 0.000 3.600 0.000 E94 0:*-43-45-* Def
+0 0 43 64 0 0.000 3.600 0.000 E94 0:*-43-64-* Def
+0 0 44 57 0 0.000 7.000 0.000 C94 0:*-44-57-* Def
+0 0 44 63 0 0.000 7.000 0.000 C94 0:*-44-63-* Def
+0 0 44 65 0 0.000 7.000 0.000 C94 0:*-44-65-* Def
+0 0 44 78 0 0.000 2.846 0.000 E94 0:*-44-78-* Def
+0 0 44 80 0 0.000 2.846 0.000 E94 0:*-44-80-* Def
+0 0 45 63 0 0.000 1.800 0.000 E94 0:*-45-63-* Def
+0 0 45 64 0 0.000 1.800 0.000 E94 0:*-45-64-* Def
+0 0 45 78 0 0.000 1.800 0.000 E94 0:*-45-78-* Def
+0 0 55 57 0 0.000 10.000 0.000 C94 0:*-55-57-* Def
+2 0 55 57 0 0.000 4.800 0.000 E94 2:*-55-57-* Def
+5 0 55 57 0 0.000 4.800 0.000 E94 5:*-55-57-* Def
+0 1 55 57 5 0.423 12.064 0.090 C94
+0 1 55 57 55 -0.428 12.044 0.000 C94
+0 36 55 57 5 -0.268 8.077 -0.806 C94
+0 36 55 57 55 0.273 8.025 0.692 C94
+0 0 55 62 0 0.000 3.600 0.000 E94 0:*-55-62-* Def
+0 0 55 64 0 0.000 4.800 0.000 E94 0:*-55-64-* Def
+0 0 55 80 0 0.000 4.800 0.000 E94 0:*-55-80-* Def
+0 0 56 57 0 0.000 6.000 0.000 C94 0:*-56-57-* Def
+0 1 56 57 56 0.000 6.886 -0.161 C94
+0 36 56 57 56 0.000 4.688 0.107 C94
+0 0 56 63 0 0.000 4.800 0.000 E94 0:*-56-63-* Def
+0 0 56 80 0 0.000 4.800 0.000 E94 0:*-56-80-* Def
+1 0 57 63 0 0.000 1.800 0.000 E94 1:*-57-63-* Def
+1 0 57 64 0 0.000 1.800 0.000 E94 1:*-57-64-* Def
+0 0 58 63 0 0.000 6.000 0.000 E94 0:*-58-63-* Def
+0 0 58 64 0 0.000 6.000 0.000 E94 0:*-58-64-* Def
+0 0 59 63 0 0.000 7.000 0.000 C94 0:*-59-63-* Def
+0 0 59 65 0 0.000 7.000 0.000 C94 0:*-59-65-* Def
+0 0 59 78 0 0.000 3.600 0.000 E94 0:*-59-78-* Def
+0 0 59 80 0 0.000 3.600 0.000 E94 0:*-59-80-* Def
+0 0 59 82 0 0.000 3.600 0.000 E94 0:*-59-82-* Def
+0 0 62 63 0 0.000 3.600 0.000 E94 0:*-62-63-* Def
+0 0 62 64 0 0.000 3.600 0.000 E94 0:*-62-64-* Def
+1 0 63 63 0 0.000 1.800 0.000 E94 1:*-63-63-* Def
+0 0 63 64 0 0.000 7.000 0.000 C94 0:*-63-64-* Def
+0 5 63 64 5 0.000 7.000 0.000 C94
+0 5 63 64 64 0.000 7.000 0.000 C94
+0 39 63 64 5 0.000 7.000 0.000 C94
+0 39 63 64 64 0.000 7.000 0.000 C94
+0 0 63 66 0 0.000 7.000 0.000 C94 0:*-63-66-* Def
+0 0 63 78 0 0.000 6.000 0.000 E94 0:*-63-78-* Def
+0 0 63 81 0 0.000 6.000 0.000 E94 0:*-63-81-* Def
+0 0 64 64 0 0.000 7.000 0.000 C94 0:*-64-64-* Def
+1 0 64 64 0 0.000 1.800 0.000 E94 1:*-64-64-* Def
+0 5 64 64 5 0.000 7.000 0.000 C94
+0 5 64 64 63 0.000 7.000 0.000 C94
+0 63 64 64 63 0.000 7.000 0.000 C94
+0 0 64 65 0 0.000 7.000 0.000 C94 0:*-64-65-* Def
+0 0 64 66 0 0.000 7.000 0.000 C94 0:*-64-66-* Def
+0 0 64 78 0 0.000 6.000 0.000 E94 0:*-64-78-* Def
+0 0 64 81 0 0.000 6.000 0.000 E94 0:*-64-81-* Def
+5 0 64 81 0 0.000 6.000 0.000 E94 5:*-64-81-* Def
+0 0 64 82 0 0.000 6.000 0.000 E94 0:*-64-82-* Def
+0 0 65 66 0 0.000 7.000 0.000 C94 0:*-65-66-* Def
+0 0 65 78 0 0.000 6.000 0.000 E94 0:*-65-78-* Def
+0 0 65 81 0 0.000 6.000 0.000 E94 0:*-65-81-* Def
+0 0 65 82 0 0.000 6.000 0.000 E94 0:*-65-82-* Def
+0 0 66 66 0 0.000 7.000 0.000 C94 0:*-66-66-* Def
+0 0 66 78 0 0.000 6.000 0.000 E94 0:*-66-78-* Def
+0 0 66 81 0 0.000 6.000 0.000 E94 0:*-66-81-* Def
+0 0 67 67 0 0.000 12.000 0.000 E94 0:*-67-67-* Def
+5 0 67 67 0 0.000 12.000 0.000 E94 5:*-67-67-* Def
+0 0 76 76 0 0.000 3.600 0.000 E94 0:*-76-76-* Def
+0 0 76 78 0 0.000 3.600 0.000 E94 0:*-76-78-* Def
+0 0 78 78 0 0.000 7.000 0.000 C94 0:*-78-78-* Def
+0 0 78 79 0 0.000 6.000 0.000 E94 0:*-78-79-* Def
+0 0 78 81 0 0.000 4.000 0.000 C94 0:*-78-81-* Def
+0 0 79 79 0 0.000 6.000 0.000 E94 0:*-79-79-* Def
+0 0 79 81 0 0.000 6.000 0.000 E94 0:*-79-81-* Def
+0 0 80 81 0 0.000 4.000 0.000 C94 0:*-80-81-* Def
diff --git a/parameters/MMFFVDW.PAR b/parameters/MMFFVDW.PAR
new file mode 100644
index 0000000..5ae3aca
--- /dev/null
+++ b/parameters/MMFFVDW.PAR
@@ -0,0 +1,112 @@
+* 13. MMFFVDW.PAR: This file supplies parameters for van der Waals interactions.
+*
+* Copyright (c) Merck and Co., Inc., 1994, 1995, 1996
+* All Rights Reserved
+*
+* E94 - From empirical rule (JACS 1992, 114, 7827)
+* C94 - Adjusted in fit to HF/6-31G* dimer energies and geometries
+* X94 - Chosen in the extension of the paratererization for MMFF94
+* by analogy to other, similar atom types or, for ions, by
+* fitting to atomic radii (and sometimes to association energies
+* for hydrates)
+*
+* power B Beta DARAD DAEPS
+ 0.25 0.2 12. 0.8 0.5
+*
+* type alpha-i N-i A-i G-i DA Symb Origin
+*------------------------------------------------------------
+ 1 1.050 2.490 3.890 1.282 - CR E94
+ 2 1.350 2.490 3.890 1.282 - C=C E94
+ 3 1.100 2.490 3.890 1.282 - C=O E94
+ 4 1.300 2.490 3.890 1.282 - CSP E94
+ 5 0.250 0.800 4.200 1.209 - HC C94
+ 6 0.70 3.150 3.890 1.282 A OR C94
+ 7 0.65 3.150 3.890 1.282 A O=C C94
+ 8 1.15 2.820 3.890 1.282 A NR C94
+ 9 0.90 2.820 3.890 1.282 A N=C C94
+ 10 1.000 2.820 3.890 1.282 A NC=O E94
+ 11 0.35 3.480 3.890 1.282 A F C94
+ 12 2.300 5.100 3.320 1.345 A CL E94
+ 13 3.400 6.000 3.190 1.359 A BR E94
+ 14 5.500 6.950 3.080 1.404 A I E94
+ 15 3.00 4.800 3.320 1.345 A S C94
+ 16 3.900 4.800 3.320 1.345 A S=C E94
+ 17 2.700 4.800 3.320 1.345 - SO E94
+ 18 2.100 4.800 3.320 1.345 - SO2 E94
+ 19 4.500 4.200 3.320 1.345 - SI E94
+ 20 1.050 2.490 3.890 1.282 - CR3R E94
+ 21 0.150 0.800 4.200 1.209 D HOR C94
+ 22 1.100 2.490 3.890 1.282 - CR3R E94
+ 23 0.150 0.800 4.200 1.209 D HNR C94
+ 24 0.150 0.800 4.200 1.209 D HOCO C94
+ 25 1.600 4.500 3.320 1.345 - PO4 E94
+ 26 3.600 4.500 3.320 1.345 A P E94
+ 27 0.150 0.800 4.200 1.209 D HN=C C94
+ 28 0.150 0.800 4.200 1.209 D HNCO C94
+ 29 0.150 0.800 4.200 1.209 D HOCC C94
+ 30 1.350 2.490 3.890 1.282 - CE4R E94
+ 31 0.150 0.800 4.200 1.209 D HOH C94
+ 32 0.75 3.150 3.890 1.282 A O2CM C94
+ 33 0.150 0.800 4.200 1.209 D HOS C94
+ 34 1.00 2.820 3.890 1.282 - NR+ C94
+ 35 1.50 3.150 3.890 1.282 A OM X94
+ 36 0.150 0.800 4.200 1.209 D HNR+ C94
+ 37 1.350 2.490 3.890 1.282 - CB E94
+ 38 0.85 2.820 3.890 1.282 A NPYD C94
+ 39 1.10 2.820 3.890 1.282 - NPYL C94
+ 40 1.00 2.820 3.890 1.282 A NC=C E94
+ 41 1.100 2.490 3.890 1.282 - CO2M C94
+ 42 1.000 2.820 3.890 1.282 A NSP E94
+ 43 1.000 2.820 3.890 1.282 A NSO2 E94
+ 44 3.00 4.800 3.320 1.345 A STHI C94
+ 45 1.150 2.820 3.890 1.282 - NO2 E94
+ 46 1.300 2.820 3.890 1.282 - N=O E94
+ 47 1.000 2.820 3.890 1.282 A NAZT X94
+ 48 1.200 2.820 3.890 1.282 A NSO X94
+ 49 1.00 3.150 3.890 1.282 - O+ X94
+ 50 0.150 0.800 4.200 1.209 D HO+ C94
+ 51 0.400 3.150 3.890 1.282 - O=+ E94
+ 52 0.150 0.800 4.200 1.209 D HO=+ C94
+ 53 1.000 2.820 3.890 1.282 - =N= X94
+ 54 1.30 2.820 3.890 1.282 - N+=C C94
+ 55 0.80 2.820 3.890 1.282 - NCN+ E94
+ 56 0.80 2.820 3.890 1.282 - NGD+ E94
+ 57 1.000 2.490 3.890 1.282 - CNN+ E94
+ 58 0.80 2.820 3.890 1.282 - NPD+ E94
+ 59 0.65 3.150 3.890 1.282 A OFUR C94
+ 60 1.800 2.490 3.890 1.282 A C%- E94
+ 61 0.800 2.820 3.890 1.282 A NR% E94
+ 62 1.300 2.820 3.890 1.282 A NM X94
+ 63 1.350 2.490 3.890 1.282 - C5A E94
+ 64 1.350 2.490 3.890 1.282 - C5B E94
+ 65 1.000 2.820 3.890 1.282 A N5A E94
+ 66 0.75 2.820 3.890 1.282 A N5B C94
+ 67 0.950 2.82 3.890 1.282 A N2OX X94
+ 68 0.90 2.82 3.890 1.282 A N3OX C94
+ 69 0.950 2.82 3.890 1.282 A NPOX C94
+ 70 0.87 3.150 3.890 1.282 A OH2 C94
+ 71 0.150 0.800 4.200 1.209 D HS C94
+ 72 4.000 4.800 3.320 1.345 A SM X94
+ 73 3.000 4.800 3.320 1.345 - SMO2 X94
+ 74 3.000 4.800 3.320 1.345 - =S=O X94
+ 75 4.000 4.500 3.320 1.345 A -P=C X94
+ 76 1.200 2.820 3.890 1.282 A N5M X94
+ 77 1.500 5.100 3.320 1.345 A CLO4 X94
+ 78 1.350 2.490 3.890 1.282 - C5 X94
+ 79 1.000 2.820 3.890 1.282 A N5 X94
+ 80 1.000 2.490 3.890 1.282 - CIM+ C94
+ 81 0.80 2.820 3.890 1.282 - NIM+ C94
+ 82 0.950 2.82 3.890 1.282 A N5OX X94
+ 87 0.45 6. 4. 1.4 - FE+2 X94
+ 88 0.55 6. 4. 1.4 - FE+3 X94
+ 89 1.4 3.48 3.890 1.282 A F- X94
+ 90 4.5 5.100 3.320 1.345 A CL- X94
+ 91 6.0 6.000 3.190 1.359 A BR- X94
+ 92 0.15 2. 4. 1.3 - LI+ X94
+ 93 0.4 3.5 4. 1.3 - NA+ X94
+ 94 1.0 5. 4. 1.3 - K+ X94
+ 95 0.43 6. 4. 1.4 - ZN+2 X94
+ 96 0.9 5. 4. 1.4 - CA+2 X94
+ 97 0.35 6. 4. 1.4 - CU+1 X94
+ 98 0.40 6. 4. 1.4 - CU+2 X94
+ 99 0.35 3.5 4. 1.3 - MG+2 X94
diff --git a/plants.cc b/plants.cc
new file mode 100644
index 0000000..ee634d1
--- /dev/null
+++ b/plants.cc
@@ -0,0 +1,138 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "plants.h"
+#include <qmenubar.h>
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+#include "constants.h"
+#include "plantsconfig.h"
+
+
+
+
+
+
+Plants::Plants (QWidget *parent, const char *name, Data *dat )
+ : Q3VBox(parent, name)//, filename( _filename ), fileinfo( filename )
+{
+
+
+ create_menu ();
+
+
+ setWindowTitle(QString("PLANTS FE v-") + QString(VERSION.c_str()));
+ data = dat;
+ mainwin = new PlantsMainWin ( this);
+ config = new Configuration (this);
+ config->Default();
+ config->Apply();
+ show ();
+}
+
+
+
+void Plants::create_menu () {
+ create_menu_actions ();
+
+// QPixmap p1 ( );
+// QPixmap p2 ( );
+// QPixmap p3 ( );
+
+
+ QMenu *file = new QMenu(tr("&File"), this );
+ Q_CHECK_PTR( file );
+
+ file -> addAction (openAct);
+ file -> addAction (saveasAct);
+
+ QMenu *settings = new QMenu(tr("&Settings"), this );
+ Q_CHECK_PTR( settings );
+
+ settings -> addAction (resetAct);
+
+ QMenu *about = new QMenu(tr("?"), this );
+ Q_CHECK_PTR( about );
+ about -> addAction (aboutAct);
+
+ QMenuBar *menu = new QMenuBar( this );
+ Q_CHECK_PTR( menu );
+ menu-> addMenu( file );
+ menu-> addMenu( settings );
+ menu-> addMenu( about );
+
+
+}
+
+
+
+void Plants::create_menu_actions () {
+ openAct = new QAction (tr("&Open File"), this);
+ openAct->setShortcut (tr ("Control+O"));
+ connect (openAct, SIGNAL (triggered ()), this, SLOT (load ()));
+
+ saveasAct = new QAction (tr("&Open File"), this);
+ saveasAct->setShortcut (tr ("Control+O"));
+ connect (saveasAct, SIGNAL (triggered ()), this, SLOT (save ()));
+
+ resetAct = new QAction (tr("Reset to &Default"), this);
+ resetAct->setShortcut (tr ("Control+D"));
+ connect (resetAct, SIGNAL (triggered ()), this, SLOT (reset ()));
+
+
+ aboutAct = new QAction (tr("&Open File"), this);
+ aboutAct->setShortcut (tr ("Control+O"));
+ connect (aboutAct, SIGNAL (triggered ()), this, SLOT (about ()));
+
+}
+
+
+
+void Plants::load (){
+ QString s = QFileDialog::getOpenFileName(this,
+ tr ("Open file"), "",tr("PLANTS Config File (*.pcfg);;All files (*)"));
+ if (!s.isNull()) {
+ config->Default();
+ config->Read(s.toStdString ().c_str ());
+ config->Apply();
+ }
+
+}
+
+void Plants::reset (){
+ config->Default();
+ config->Apply();
+
+}
+
+void Plants::save (){
+ QString s = QFileDialog::getSaveFileName(this,
+ tr ("Save configuration"), "",tr("PLANTS Config File (*.pcfg)"));
+
+ config->Get();
+ config->Write(s.toStdString ().c_str ());
+}
+
+void Plants::about ()
+{
+ QMessageBox::about( this, QString("About PLANTS Front End") ,
+ QString("PLANTS FE. Version ") + QString(VERSION.c_str()) + QString("\n")
+ + QString("Code by Nicola Zonta. All rights reserved.\n")
+ + QString("For bug reports, suggestions || any other feedback please email me at zontan at cf.ac.uk\n\nMAY THE ANT BE WITH YOU!") );
+}
+
+
diff --git a/plants_mainwin.cc b/plants_mainwin.cc
new file mode 100644
index 0000000..7075d31
--- /dev/null
+++ b/plants_mainwin.cc
@@ -0,0 +1,939 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "myline.h"
+#include "plants_mainwin.h"
+#include <qvalidator.h>
+#include <Qt3Support/q3vbox.h>
+#include <Qt3Support/q3hbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qdatetime.h>
+#include <Qt3Support/q3buttongroup.h>
+#include <qcheckbox.h>
+#include <Qt3Support/q3groupbox.h>
+
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <Qt3Support/q3grid.h>
+#include <Qt3Support/q3frame.h>
+#include <qlayout.h>
+#include <qfiledialog.h>
+#include <iostream>
+#include <fstream>
+#include "constants.h"
+#include <Qt3Support/q3accel.h>
+#include <qpainter.h>
+#include <qimage.h>
+#include <qstyle.h>
+#include "graphical_object.h"
+
+
+
+
+
+MyListBoxItem::MyListBoxItem(string s, Q3ListBox *par)
+: Q3ListBoxText(QString(s.c_str()))
+{
+ valid=check_mol2 (s);
+ tex = s;
+ parent = par;
+ // setCustomHighlighting( TRUE );
+}
+
+
+bool MyListBoxItem::check_mol2 (string line){
+ istringstream iss (line);
+ string filename;
+ iss >> filename;
+ iss >> filename;
+ return true;
+// ZNMolecule *mol = new ZNMolecule ();
+ //ifstream ifs (filename.c_str ());
+// bool b = false;
+// mol->readMultiMOL2 (filename, ifs, b);
+// unsigned int asize =mol->atoms.size ();
+// if (asize>1) {
+// return true;
+ }
+ //else return false;}
+
+
+
+void MyListBoxItem::paint( QPainter *painter )
+{
+ // evil trick: find out whether we are painted onto our listbox
+ // bool in_list_box = listBox() && listBox()->viewport() == painter->device();
+
+ // QRect r ( 0, 0, -10+width( listBox() ), height( listBox() ) );
+ // if ( in_list_box && isSelected() ) {
+ // painter->fillRect( r, sel_col );
+
+ // }
+ if (!valid) {
+ QBrush br = parent->palette ().brush (ERR_COL);
+ painter->fillRect( 2, 2, -10+width( listBox() ), -4+height( listBox() ), br);
+ // valid=false;
+ }
+
+ painter->drawText(5,-4+height( listBox()), QString(tex.c_str()));
+ // if ( in_list_box && isCurrent() )
+ // listBox()->style().drawPrimitive( QStyle::PE_FocusRect, painter, r, listBox()->colorGroup() );
+}
+
+
+
+
+
+
+
+
+
+
+
+PlantsMainWin::PlantsMainWin( Plants *parent)
+: QTabWidget (parent)
+{
+ window = parent;
+ setupwin();
+
+
+
+
+}
+
+void PlantsMainWin::setupwin()
+{
+
+ /////////////////////////////////////INPUT OUTPUT////////////////////////////////////////
+
+
+ Q3VBox *iotab = new Q3VBox( this );
+ iotab->setMargin( 5 );
+
+ Q3ButtonGroup *inputgr = new Q3ButtonGroup( 1, Qt::Horizontal, "Input Options", iotab );
+
+ pfile = new MyLineF (inputgr, this, "Protein File", 1);
+
+ connect(pfile->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_protein () ));
+ lfile = new MyLineF (inputgr, this, "Ligand File", 1);
+ connect(lfile->linedit, SIGNAL (textChanged(const QString &)), SLOT (load_ligand () ));
+
+
+ llist = new MyLineF (inputgr, this, "Ligand List", 3);
+ connect(lfile->linedit, SIGNAL( returnPressed() ), SLOT( add_lf_slot() )) ;
+ connect(llist->linedit, SIGNAL( returnPressed() ), SLOT( add_ll_slot() )) ;
+
+ // connect(lfile->adbutt, SIGNAL( clicked() ), SLOT( add_lf_slot() )) ;
+ // connect(llist->adbutt, SIGNAL( clicked() ), SLOT( add_ll_slot() )) ;
+ iflb = new Q3ListBox (inputgr);
+
+ check_ligands ();
+ Q3Accel *ifa = new Q3Accel( iflb );
+ ifa->connectItem( ifa->insertItem(Qt::Key_Delete),
+ this,
+ SLOT(del_ifile()) );
+
+ connect (iflb, SIGNAL(selected (int)), SLOT (ligand_selected(int)));
+
+ Q3ButtonGroup *bsgr = new Q3ButtonGroup( 1, Qt::Horizontal, "Binding Site options", inputgr );
+ bsfl = new QPushButton( "Bindingsite From ligand",bsgr);
+ bsfl->setCheckable( FALSE );
+ connect (bsfl, SIGNAL (clicked ()), SLOT (load_bs_from_ligand_slot () ));
+
+ bsx = new MyLine (bsgr, "Binding Site Center X", 2);
+ bsy = new MyLine (bsgr, "Binding Site Center Y", 2);
+ bsz = new MyLine (bsgr, "Binding Site Center Z", 2);
+ bsr = new MyLine (bsgr, "Binding Site Radius", 2);
+
+ connect (bsx->linedit, SIGNAL (textChanged(const QString &)), SLOT (check_bindingsite () ));
+ connect (bsy->linedit, SIGNAL (textChanged(const QString &)), SLOT (check_bindingsite () ));
+ connect (bsz->linedit, SIGNAL (textChanged(const QString &)), SLOT (check_bindingsite () ));
+ connect (bsr->linedit, SIGNAL (textChanged(const QString &)), SLOT (check_bindingsite () ));
+
+
+ Q3ButtonGroup *outputgr = new Q3ButtonGroup( 1, Qt::Horizontal, "Output Options", iotab );
+
+ odir = new MyLine (outputgr, "Output Dir", 0);
+ connect (odir->linedit, SIGNAL (textChanged(const QString &)), SLOT (check_outdir () ));
+ Q3Grid *grid = new Q3Grid( 2, outputgr);
+
+ wpc = new QPushButton( "Write Protein Conformation", grid);
+ wpc->setCheckable( TRUE );
+
+
+ wrs = new QPushButton( "Write Rescored Structures", grid);
+ wrs->setCheckable( TRUE );
+
+
+ wmm2 = new QPushButton( "Write Multi Mol2", grid);
+ wmm2->setCheckable( TRUE );
+
+
+ wrl = new QPushButton( "Write Ranking links", grid);
+ wrl->setCheckable( TRUE );
+
+
+ wrmm2 = new QPushButton( "Write Ranking multi Mol2", grid);
+ wrmm2->setCheckable( TRUE );
+
+
+ wpb = new QPushButton( "Write Protein Bindingsite", grid);
+ wpb->setCheckable( TRUE );
+
+ wps = new QPushButton( "Write Protein Splitted", grid);
+ wps->setCheckable( TRUE );
+
+ wpas = new QPushButton( "Write Per Atom Scores", grid);
+ wpas->setCheckable( TRUE );
+
+
+ addTab( iotab, "Input && Output" );
+
+
+
+ ////////////////////////////////SEARCH ALGORITHM////////////////////////////////////////////
+ Q3VBox *algtab = new Q3VBox( this );
+ algtab->setMargin( 5 );
+
+
+ Q3ButtonGroup *sa = new Q3ButtonGroup( 1, Qt::Horizontal, "Search Algorithm", algtab );
+
+ aants = new MyLine (sa, "Number of Ants ", 1);
+ aevap = new MyLine (sa, "Evaporation Factor", 2);
+ asigma = new MyLine (sa, "Sigma Scaling Factor", 2);
+
+ Q3Grid *sag = new Q3Grid (3, sa);
+ flipab = new QPushButton( "Flip amide bonds", sag);
+ flipab->setCheckable( TRUE );
+
+
+ flipn = new QPushButton( "Flip planar N", sag);
+ flipn->setCheckable( TRUE );
+
+ ffbp = new QPushButton( "Force Flipped ZNBond Planarity", sag);
+ ffbp->setCheckable( TRUE );
+
+
+
+
+ Q3ButtonGroup *sf = new Q3ButtonGroup( 1, Qt::Horizontal, "Scoring Function", algtab );
+
+ Q3Grid *sfg = new Q3Grid (2, sf);
+ sfchoice = new QComboBox( sfg );
+ sfchoice->insertItem(-1, "chemplp" );
+ sfchoice->insertItem(-1, "plp" );
+
+
+
+
+ cho = new QPushButton( "Weak CHO", sfg);
+ cho->setCheckable( TRUE );
+
+ (void) new QLabel("Ligand Internal Clash", sfg );
+
+ lintra = new QComboBox(sfg );
+ lintra->insertItem(-1, "lj" );
+ lintra->insertItem(-1, "clash" );
+
+ rigidl = new QPushButton( "Rigid Ligand", sfg);
+ rigidl->setCheckable( TRUE );
+ rigidl->setChecked( FALSE );
+
+ rigida = new QPushButton( "Rigid All", sfg);
+ rigida->setCheckable( TRUE );
+ rigida->setChecked( FALSE );
+
+ Q3ButtonGroup *cpweights = new Q3ButtonGroup( 1, Qt::Horizontal, "ChemPLP weights", sf );
+
+
+ chbw = new MyLine (cpweights, "Charged HB", 2);
+ cmw = new MyLine (cpweights, "Charged Metal", 2);
+ hbw = new MyLine (cpweights, "HB", 2);
+ hbchow = new MyLine (cpweights, "HB CHO", 2);
+ mw = new MyLine (cpweights, "Metal", 2);
+ plpw = new MyLine (cpweights, "PLP", 2);
+ iw = new MyLine (cpweights, "Intercept", 2);
+
+
+
+ Q3ButtonGroup *ca = new Q3ButtonGroup( 1, Qt::Horizontal, "Cluster Algorithm", algtab );
+
+ crmsd = new MyLine (ca, "Cluster RMSD", 2);
+ cs = new MyLine (ca, "Cluster Structure", 1);
+
+
+
+ addTab( algtab, "Algorithm" );
+
+
+ //////////////////////////////////CONSTRAINTS//////////////////////////////////////////
+
+
+
+
+ Q3VBox *contab = new Q3VBox( this );
+ contab->setMargin( 5 );
+ contab->setSpacing( 5 );
+
+ Q3ButtonGroup *constr = new Q3ButtonGroup( 1, Qt::Horizontal, "Constraints", contab );
+ Q3Grid *cgr = new Q3Grid (2,constr);
+
+ addphbcb = new QPushButton("Add Protein HB Constraint", cgr);
+ connect (addphbcb, SIGNAL( clicked() ), SLOT( addphbc() ) );
+ // frame // // // // // // // // protein hb // // // // // //
+ phbcpopup = new QWidget;
+
+ QVBoxLayout *phbcpopupv = new QVBoxLayout;
+ phbcpopup -> setLayout (phbcpopupv);
+// phbcpopup->setMinimumSize (350, 250);
+// phbcpopup->setMaximumSize (350, 250);
+// phbcpopupv->setMinimumSize (350, 250);
+// phbcpopupv->setMaximumSize (350, 250);
+ QHBoxLayout *anb = new QHBoxLayout;
+ phbcpopupv -> addLayout (anb);
+ QLabel *lab = new QLabel("Atom number");
+ anb -> addWidget (lab);
+ anlined = new QComboBox;
+ anb ->addWidget (anlined);
+ pat.push_back (anlined);
+ anlined->setFocus();
+ // connect( anlined, SIGNAL( returnPressed() ), phbcpopup, SLOT( hide() ) );
+ // tmpE2->setGeometry(10,10, 260, 30);
+ QHBoxLayout *phbwei = new QHBoxLayout;
+ phbcpopupv -> addLayout (phbwei);
+ QLabel *lab2 = new QLabel("Weight");
+ phbwei -> addWidget (lab2);
+ phbweil = new QLineEdit;
+ phbwei -> addWidget (phbweil);
+ phbweil->setValidator( new QDoubleValidator( -999.0, 999.0, 2,phbweil ) );
+ QPushButton *setphbcb = new QPushButton("Set constraint");
+ phbcpopupv -> addWidget (setphbcb);
+ connect ( setphbcb, SIGNAL( clicked() ), SLOT( add_phbc_slot() ) );
+
+
+
+
+
+ addshcb = new QPushButton("Add Shape Constraint", cgr);
+ connect (addshcb, SIGNAL( clicked() ), SLOT( addshc() ) );
+ // frame // // // // // // // // shape // // // // // //
+ shcpopup = new QWidget;
+
+ Q3VBox *shcpopupv = new Q3VBox (shcpopup);
+ shcpopup->setMinimumSize (350, 250);
+ shcpopup->setMaximumSize (350, 250);
+ shcpopupv->setMinimumSize (350, 250);
+ shcpopupv->setMaximumSize (350, 250);
+ Q3HBox *shfilehb = new Q3HBox (shcpopupv);
+ (void) new QLabel("Shape File", shfilehb );
+ shfl = new QLineEdit( shfilehb);
+ QPushButton *shfb = new QPushButton("", shfilehb);
+ shfb->setMaximumWidth (20);
+ shfb->setMinimumWidth (20);
+ connect ( shfb, SIGNAL( clicked() ), SLOT( set_sf_slot() ) );
+ shfl->setFocus();
+ Q3HBox *shwei = new Q3HBox (shcpopupv);
+ (void) new QLabel("Weight", shwei );
+ shweil = new QLineEdit( shwei);
+ shweil->setValidator( new QDoubleValidator( -999.0, 999.0, 2,shweil ) );
+ QPushButton *setshcb = new QPushButton("Set constraint", shcpopupv);
+ connect ( setshcb, SIGNAL( clicked() ), SLOT( add_shc_slot() ) );
+
+
+
+
+ addsdcb = new QPushButton("Add Surface Distance Constraint", cgr);
+ connect (addsdcb, SIGNAL( clicked() ), SLOT( addsdc() ) );
+
+ // frame // // // // // // // // surface distance // // // // // //
+ sdcpopup = new QWidget;
+
+ Q3VBox *sdcpopupv = new Q3VBox (sdcpopup);
+ sdcpopup->setMinimumSize (350, 250);
+ sdcpopup->setMaximumSize (350, 250);
+ sdcpopupv->setMinimumSize (350, 250);
+ sdcpopupv->setMaximumSize (350, 250);
+ Q3HBox *sdmmb = new Q3HBox (sdcpopupv);
+
+ (void) new QLabel("From", sdmmb ); sdbbfl = new QLineEdit( sdmmb);
+ (void) new QLabel("To", sdmmb ); sdbbtl = new QLineEdit( sdmmb);
+ sdbbfl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,sdbbfl ) );
+ sdbbtl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,sdbbtl ) );
+ Q3HBox *sdanb = new Q3HBox (sdcpopupv);
+ (void) new QLabel("Atom Number", sdanb );
+ sdanl = new QComboBox(sdanb);
+ lat.push_back (sdanl);
+ sdanl->setFocus();
+ Q3HBox *sdwei = new Q3HBox (sdcpopupv);
+ (void) new QLabel("Weight", sdwei );
+ sdweil = new QLineEdit( sdwei);
+ sdweil->setValidator( new QDoubleValidator( -999.0, 999.0, 2,sdweil ) );
+ QPushButton *setsdb = new QPushButton("Set constraint", sdcpopupv);
+ connect ( setsdb, SIGNAL( clicked() ), SLOT( add_sdc_slot() ) );
+
+
+
+ addidcb = new QPushButton("Add Intra Distance Constraint", cgr);
+ connect (addidcb, SIGNAL( clicked() ), SLOT( addidc() ) );
+ // frame // // // // // // // // intra distance // // // // // //
+ idcpopup = new QWidget;
+
+ Q3VBox *idcpopupv = new Q3VBox (idcpopup);
+ idcpopup->setMinimumSize (350, 250);
+ idcpopup->setMaximumSize (350, 250);
+ idcpopupv->setMinimumSize (350, 250);
+ idcpopupv->setMaximumSize (350, 250);
+ Q3HBox *idmmb = new Q3HBox (idcpopupv);
+
+ (void) new QLabel("From", idmmb ); idbbfl = new QLineEdit( idmmb);
+ (void) new QLabel("To", idmmb ); idbbtl = new QLineEdit( idmmb);
+ idbbfl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,idbbfl ) );
+ idbbtl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,idbbtl ) );
+ Q3HBox *idanb = new Q3HBox (idcpopupv);
+ (void) new QLabel("Ligand Atom", idanb );
+ idanl = new QComboBox( idanb);
+ idanl->setFocus();
+ lat.push_back (idanl);
+ Q3HBox *idanb2 = new Q3HBox (idcpopupv);
+ (void) new QLabel("Ligand Atom", idanb2 );
+ idanl2 = new QComboBox(idanb2);
+ lat.push_back (idanl2);
+
+ Q3HBox *idwei = new Q3HBox (idcpopupv);
+ (void) new QLabel("Weight", idwei );
+ idweil = new QLineEdit( idwei);
+ idweil->setValidator( new QDoubleValidator( -999.0, 999.0, 2,idweil ) );
+ QPushButton *setidb = new QPushButton("Set constraint", idcpopupv);
+ connect ( setidb, SIGNAL( clicked() ), SLOT( add_idc_slot() ) );
+
+
+ addldcb = new QPushButton("Add Ligand Protein Distance Constraint", cgr);
+ connect (addldcb, SIGNAL( clicked() ), SLOT( addldc() ) );
+ // frame // // // // // // // // ligand protein distance // // // // // //
+ ldcpopup = new QWidget;
+ Q3VBox *ldcpopupv = new Q3VBox (ldcpopup);
+ ldcpopup->setMinimumSize (350, 250);
+ ldcpopup->setMaximumSize (350, 250);
+ ldcpopupv->setMinimumSize (350, 250);
+ ldcpopupv->setMaximumSize (350, 250);
+ Q3HBox *ldmmb = new Q3HBox (ldcpopupv);
+
+ (void) new QLabel("From", ldmmb ); ldbbfl = new QLineEdit( ldmmb);
+ (void) new QLabel("To", ldmmb ); ldbbtl = new QLineEdit( ldmmb);
+ ldbbfl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,ldbbfl ) );
+ ldbbtl->setValidator( new QDoubleValidator( -999.0, 999.0, 2,ldbbtl ) );
+ Q3HBox *ldanb = new Q3HBox (ldcpopupv);
+ (void) new QLabel("Ligand Atom", ldanb );
+ ldanl = new QComboBox(ldanb);
+ lat.push_back (ldanl);
+
+ ldanl->setFocus();
+ Q3HBox *ldanb2 = new Q3HBox (ldcpopupv);
+ (void) new QLabel("Protein Atom", ldanb2 );
+ ldanl2 = new QComboBox( ldanb2);
+ pat.push_back (ldanl2);
+ Q3HBox *ldwei = new Q3HBox (ldcpopupv);
+ (void) new QLabel("Weight", ldwei );
+ ldweil = new QLineEdit( ldwei);
+ ldweil->setValidator( new QDoubleValidator( -999.0, 999.0, 2,ldweil ) );
+ QPushButton *setldb = new QPushButton("Set constraint", ldcpopupv);
+ connect ( setldb, SIGNAL( clicked() ), SLOT( add_ldc_slot() ) );
+
+
+ constrlb = new Q3ListBox (constr);
+
+ Q3Accel *cna = new Q3Accel( constrlb );
+ cna->connectItem( cna->insertItem(Qt::Key_Delete),
+ this,
+ SLOT(del_constr()) );
+
+ addTab( contab, "Constraints" );
+
+ Q3VBox *flextab = new Q3VBox( this );
+ flextab->setMargin( 5 );
+ flextab->setSpacing( 5 );
+
+ Q3ButtonGroup *flex = new Q3ButtonGroup( 1, Qt::Horizontal, "Flexibility", flextab );
+ Q3HBox *flexhb = new Q3HBox (flex); Q3HBox *flexhb2 = new Q3HBox (flex);
+ flscl = new QComboBox( flexhb );
+ pres.push_back (flscl);
+ addflscb = new QPushButton("Add Flexible side chain", flexhb);
+ connect (addflscb, SIGNAL( clicked() ), SLOT( add_flsc_slot() ) );
+
+
+ fixpl = new QComboBox( flexhb2 );
+ addfixpb = new QPushButton("Add Fixed Protein ZNBond", flexhb2);
+ flexlb = new Q3ListBox (flex);
+
+ Q3Accel *fla = new Q3Accel( flexlb );
+ fla->connectItem( fla->insertItem(Qt::Key_Delete),
+ this,
+ SLOT(del_flex()) );
+
+
+ connect (addfixpb, SIGNAL( clicked() ), SLOT( add_fixp_slot() ) );
+
+ ipsw = new MyLine (flex, "Intra Protein Score Weight", 2);
+
+ addTab( flextab, "Flexibility" );
+
+
+ //}
+ //////////////////////////////////WATER//////////////////////////////////////////
+ //void PlantsMainWin::setupWater()
+
+
+ //{
+
+
+ Q3VBox *watertab = new Q3VBox( this );
+ watertab->setMargin( 5 );
+ watertab->setSpacing( 5 );
+ Q3HBox *watercoor = new Q3HBox (watertab);
+ Q3HBox *waterop = new Q3HBox (watertab);
+
+
+ (void) new QLabel("X", watercoor ); xwc = new QLineEdit( watercoor);
+ (void) new QLabel("Y", watercoor ); ywc = new QLineEdit( watercoor);
+ (void) new QLabel("Z", watercoor ); zwc = new QLineEdit( watercoor);
+ (void) new QLabel("Radius", waterop ); wr = new QLineEdit( waterop);
+
+ xwc->setValidator( new QDoubleValidator( -999.0, 999.0, 2,xwc ) );
+ ywc->setValidator( new QDoubleValidator( -999.0, 999.0, 2,ywc ) );
+ zwc->setValidator( new QDoubleValidator( -999.0, 999.0, 2,zwc ) );
+ wr->setValidator( new QDoubleValidator( -999.0, 999.0, 2,wr ) );
+ addwaterb = new QPushButton("Add Water ZNMolecule", waterop);
+ connect ( addwaterb, SIGNAL( clicked() ), SLOT( add_water_slot() ) );
+
+ wref = new MyLineF (watertab, this, "Water Reference", 1);
+
+
+
+ waterlb = new Q3ListBox (watertab);
+ Q3Accel *wta = new Q3Accel( waterlb );
+ wta->connectItem( wta->insertItem(Qt::Key_Delete),
+ this,
+ SLOT(del_water()) );
+
+
+ Q3ButtonGroup *wweights = new Q3ButtonGroup( 1, Qt::Horizontal, "Water molecule weights", watertab );
+
+ wphb = new MyLine (wweights, "Water-Protein HB", 2);
+ wlhb = new MyLine (wweights, "Water-Ligand HB", 2);
+ wwhb = new MyLine (wweights, "Water-Water HB", 2);
+ nwhbp = new MyLine (wweights, "No HB Penalty", 2);
+
+
+ addTab( watertab, "Water" );
+
+
+
+}
+
+
+
+////////////////////////////////POP UP MENU////////////////////////////////////////////////
+
+
+
+
+void PlantsMainWin::addphbc(){
+ phbcpopup->show();
+}
+
+void PlantsMainWin::addshc(){
+ shcpopup->show();
+}
+
+void PlantsMainWin::addsdc(){
+ sdcpopup->show();
+}
+
+void PlantsMainWin::addidc(){
+ idcpopup->show();
+}
+
+void PlantsMainWin::addldc(){
+ ldcpopup->show();
+}
+
+
+////////////////////////////////SLOTS////////////////////////////////////////////////
+
+
+void PlantsMainWin::add_phbc_slot (){
+ string an = anlined->currentText ().toStdString ();
+ string phbw = phbweil->displayText ().toStdString ();
+ if ((an!="") && (phbw!="")){
+ istringstream ss (an);
+ string anone;
+ ss >> anone;
+ QString st = "chemplp_protein_hb_constraint ";
+
+ constrlb->insertItem(st + QString(" ") + QString(anone.c_str()) + QString(" ")
+ + QString(phbw.c_str()));
+ }
+}
+
+void PlantsMainWin::add_shc_slot (){
+ string fil = shfl->displayText ().toStdString ();
+ string we = shweil->displayText ().toStdString ();
+ if (fil!="" && we !=""){
+ QString st = "shape_constraint ";
+ constrlb->insertItem(st + QString(" ") + QString(fil.c_str()) + QString(" ")
+ + QString(we.c_str()));
+ }
+}
+
+void PlantsMainWin::add_sdc_slot (){
+ string from = sdbbfl->displayText ().toStdString ();
+ string to = sdbbtl->displayText ().toStdString ();
+ string at = sdanl->currentText ().toStdString ();
+ string we = sdweil->displayText ().toStdString ();
+ if (from!="" && to!="" && at!="" && we!="") {
+ QString st = "surface_distance_constraint ";
+ istringstream ss (at);
+ string atone;
+ ss >> atone;
+ constrlb->insertItem(st + QString(" ")
+ + QString(from.c_str()) + QString(" ")
+ + QString(to.c_str()) + QString(" ")
+ + QString(atone.c_str()) + QString(" ")
+ + QString(we.c_str()));
+ }
+}
+
+void PlantsMainWin::add_idc_slot (){
+ string from = idbbfl->displayText ().toStdString ();
+ string to = idbbtl->displayText ().toStdString ();
+ string la = idanl->currentText ().toStdString ();
+ string pa = idanl2->currentText ().toStdString ();
+ string we = idweil->displayText ().toStdString ();
+
+ if (from!="" && to !="" && la!="" && pa!="" && we!=""){
+ QString st = "ligand_intra_distance_constraint ";
+ istringstream ss (la);
+ string laone;
+ ss >> laone;
+ istringstream ss2 (pa);
+ string paone;
+ ss2 >> paone;
+
+// constrlb->insertItem(st+" "+from+" "+to+" "+laone+" "+paone+" "+we);
+ }
+}
+
+void PlantsMainWin::add_ldc_slot (){
+ string from = ldbbfl->displayText ().toStdString ();
+ string to = ldbbtl->displayText ().toStdString ();
+ string la = ldanl->currentText ().toStdString ();
+ string pa = ldanl2->currentText ().toStdString ();
+ string we = ldweil->displayText ().toStdString ();
+
+ if (from!="" && to !="" && la!="" && pa!="" && we!=""){
+ QString st = "protein_ligand_distance_constraint ";
+ istringstream ss (la);
+ string laone;
+ ss >> laone;
+ istringstream ss2 (pa);
+ string paone;
+ ss2 >> paone;
+
+// constrlb->insertItem(st+" "+from+" "+to+" "+laone+" "+paone+" "+we);
+ }
+}
+
+void PlantsMainWin::add_flsc_slot (){
+ string res = flscl->currentText ().toStdString ();
+ if (res!=""){
+ istringstream ss (res);
+ string resone;
+ ss >> resone;
+ QString st = "flexible_protein_side_chain_number ";
+ //flexlb->insertItem(st+resone);
+ }
+}
+
+void PlantsMainWin::add_fixp_slot (){
+ QString st = "fixed_protein_bond ";
+ st.append (fixpl->currentText());
+ //flexlb->insertItem(st);
+}
+
+void PlantsMainWin::add_water_slot (){
+ string x = xwc->displayText ().toStdString ();
+ string y = ywc->displayText ().toStdString ();
+ string z = zwc->displayText ().toStdString ();
+ string r = wr->displayText ().toStdString ();
+ if (x!="" && y!="" && z!="" && r!=""){
+
+ QString st = "water_molecule ";
+ //waterlb->insertItem(st+" "+x+" "+y+" "+z+" "+r);
+ }
+}
+
+void PlantsMainWin::set_sf_slot (){
+ QString s = QFileDialog::getOpenFileName(this, tr("open file dialog"), "",
+ tr("Tripos Mol2 File (*.mol2)"));
+ shfl->insert(s);
+
+}
+
+void PlantsMainWin::add_lf_slot (){
+ QString val = lfile->linedit->displayText ();
+ if (val!=""){
+ QString st = "ligand_file ";
+ // MyListBoxItem *a = new MyListBoxItem (st+val);
+// iflb->insertItem(new MyListBoxItem (st+val, iflb));
+ check_ligands ();
+ }
+}
+
+void PlantsMainWin::add_ll_slot (){
+ QString val = llist->linedit->displayText ();
+ if (val!=""){
+ QString st = "ligand_list ";
+// iflb->insertItem(new MyListBoxItem (st+val, iflb));
+ check_ligands ();
+ }
+}
+
+void PlantsMainWin::load_bs_from_ligand_slot (){
+ QString s = QFileDialog::getOpenFileName(this, tr ("open file"), " ",
+ tr ("Tripos Mol2 File (*.mol2)"));
+ ZNMolecule *mol = window->data->check_mol2 (s.toStdString());
+// if (mol->valid) {
+ // vect bs = find_mass_center (mol->atoms); ///readd radius calculation
+ // set_bindingsite (bs.x(), bs.y(), bs.z(), 12.f);
+// }
+}
+
+void PlantsMainWin::load_protein () {
+/* string pname = pfile->val ();
+ vector <string> patlist, preslist;
+ if (pname.find (".mol2")!=string::npos) {
+
+ ZNMolecule *prot;
+ prot = window->data->check_mol2 (pname);
+ if (prot->valid) {
+ // window->data->protein = prot;
+ // window->data->ddwin->load_protein (prot);
+
+ for (unsigned int i=0;i<prot->atoms.size ();i++){
+ int n = prot->atoms[i]->ID;
+ string name = prot->atoms[i]->name;
+ string ssname =prot->atoms[i]->substructureName;
+ int ssnum =prot->atoms[i]->substructureNumber;
+ stringstream s, ssn;
+ s << n; ssn << ssnum;
+ patlist.push_back ( s.str()+" "+name+" "+ssname+ssn.str());
+ pfile->linedit->setBackgroundRole (base);
+ }
+ preslist = prot->res_strings;
+
+ }
+ else {
+ pfile->linedit->setBackgroundRole (ERR_COL);
+ // window->data->ddwin->hide_protein ();
+ }
+
+ }
+ else {
+ pfile->linedit->setBackgroundRole (ERR_COL);
+ // window->data->ddwin->hide_protein ();
+ }
+ update_boxes (pat, patlist);
+ update_boxes (pres, preslist);
+*/
+}
+
+void PlantsMainWin::load_ligand () {
+/* string lname = lfile->val ();
+ vector <string> latlist;
+ if (lname.find (".mol2")!=string::npos) {
+
+ ZNMolecule *lig;
+ lig = window->data->check_mol2 (lname);
+// if (lig->valid) {
+ // window->data->ligand=lig;
+
+ for (unsigned int i=0;i<lig->atoms.size ();i++){
+ int n = lig->atoms[i]->ID;
+ string name = lig->atoms[i]->name;
+ string ssname =lig->atoms[i]->substructureName;
+ int ssnum =lig->atoms[i]->substructureNumber;
+ stringstream s, ssn;
+ s << n; ssn << ssnum;
+ latlist.push_back ( s.str()+" "+name+" "+ssname+ssn.str());
+ }
+ add_lf_slot ();
+ window->data->ligands.push_back (lig);
+ // window->data->ddwin->load_ligand (lig);
+ // }
+
+ }
+ update_boxes (lat, latlist);
+*/
+}
+
+void PlantsMainWin::ligand_selected (int index){
+ // cout <<index <<" "<< window->data->ligands.size ()<<endl;
+ // if ((unsigned int) index < window->data->ligands.size ()){
+ // window->data->ddwin->load_ligand (window->data->ligands[index]);
+ // }
+}
+
+void PlantsMainWin::set_bindingsite (float x, float y, float z, float r) {
+
+/*
+ stringstream ss, ss2, ss3, ss4;
+ ss << x;
+ bsx->ins (ss.str ());
+ ss2 << y;
+ bsy->ins (ss2.str ());
+ ss3 << z;
+ bsz->ins (ss3.str ());
+ ss4 << r;
+ bsr->ins (ss4.str ());
+*/
+}
+
+void PlantsMainWin::set_bindingsite (float x, float y, float z) {
+/*
+ stringstream ss, ss2, ss3;
+ ss << x;
+ bsx->ins (ss.str ());
+ ss2 << y;
+ bsy->ins (ss2.str ());
+ ss3 << z;
+ bsz->ins (ss3.str ());
+*/
+}
+
+
+
+void PlantsMainWin::check_bindingsite () {
+ string x = bsx->val ();
+ string y = bsy->val ();
+ string z = bsz->val ();
+ string r = bsr->val ();
+ if (x=="") { bsx->linedit->setBackgroundRole (ERR_COL);}
+ else {bsx->linedit->setBackgroundRole (base);}
+
+ if (y=="") { bsy->linedit->setBackgroundRole (ERR_COL);}
+ else {bsy->linedit->setBackgroundRole (base);}
+
+ if (z=="") { bsz->linedit->setBackgroundRole (ERR_COL);}
+ else {bsz->linedit->setBackgroundRole (base);}
+
+ if (r=="") { bsr->linedit->setBackgroundRole (ERR_COL);}
+ else {bsr->linedit->setBackgroundRole (base);}
+ if (x!="" && y!="" && z!="" && r!=""){
+
+
+ // window->data->ddwin->load_bindingsite (getfloat (x), getfloat (y), getfloat (z), getfloat (r));
+ Sphere *sph=window->data->ddwin->new_sphere ("Plants bindingsite");
+ sph->set_center (vect (getfloat (x), getfloat (y), getfloat (z)));
+ sph->set_radius (getfloat (r));
+ sph->set_color (1.0f, 1.0f, 1.0f, 0.4f);
+ sph->render_as_surface ();
+ // window->data->ddwin->
+ }
+ else {
+ // window->data->ddwin->hide_bindingsite ();
+ }
+
+
+}
+void PlantsMainWin::check_ligands () {
+
+ int n = iflb->numRows ();
+
+ if (n <1) {
+ iflb->setBackgroundRole (ERR_COL);
+// unsetPalette ();
+
+ }
+ else {
+
+ iflb->setBackgroundRole (QPalette::Base);
+ // for (unsigned int i=0;i<iflb->count();i++) {
+ // cout << iflb->item(iflb->count()-1)->valid;
+
+ // if (iflb->count() == 2) {it->valid =true;}
+
+
+
+ }
+}
+
+void PlantsMainWin::check_outdir () {
+
+ string outdir = odir->val ();
+
+ if (outdir=="") {
+ odir->linedit->setBackgroundRole (ERR_COL);
+
+ }
+ else {
+
+ odir->linedit->setBackgroundRole (QPalette::Base);
+
+ }
+}
+
+void PlantsMainWin::del_ifile () {
+ iflb->removeItem (iflb->currentItem ());
+ check_ligands ();
+}
+
+void PlantsMainWin::del_constr () {
+ constrlb->removeItem (constrlb->currentItem ());
+}
+
+void PlantsMainWin::del_flex () {
+ flexlb->removeItem (flexlb->currentItem ());
+}
+
+void PlantsMainWin::del_water () {
+ waterlb->removeItem (waterlb->currentItem ());
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void PlantsMainWin::update_boxes (vector<QComboBox*> &vec, vector<string>& values){
+ for (unsigned int i=0;i<vec.size (); i++){
+ vec[i]->clear ();
+ for (unsigned int j=0; j<values.size (); j++){
+ vec[i]->insertItem (-1, QString(values[j].c_str()));
+
+
+ }
+
+ }
+}
+
+
+float PlantsMainWin::getfloat (string s) {
+ istringstream iss (s);
+ float f;
+ iss>>f;
+ return f;
+}
diff --git a/plantsconfig.cc b/plantsconfig.cc
new file mode 100644
index 0000000..6535475
--- /dev/null
+++ b/plantsconfig.cc
@@ -0,0 +1,468 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <sstream>
+#include "plantsconfig.h"
+
+#include <string>
+
+
+
+
+Confline::Confline (char ctype, string cfilestr, string cdefval, MyLine* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetl = ctarget; type = ctype;
+
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr,string cdefval, QPushButton* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetb = ctarget;type = ctype;
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr,string cdefval, QComboBox* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetcb = ctarget;type = ctype;
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,QLineEdit* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetle = ctarget;type = ctype;
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,MyLineF* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetlf = ctarget; type = ctype;
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,Q3ListBox* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetlb = ctarget; type = ctype;
+ Default ();
+}
+
+Confline::Confline (char ctype, string cfilestr, string cdefval,PlantsMainWin* ctarget)
+{
+ defval = cdefval;filestr = cfilestr; targetmw = ctarget; type = ctype;
+ Default ();
+}
+
+int Confline::getInt (string mystr){
+ istringstream iss (mystr);
+ int i;
+ iss>>i;
+ return i;
+}
+
+
+void Confline::Default () {
+ current = defval;
+ if (type=='m' || type=='M' ) {vect.clear();};
+}
+
+
+
+void Confline::Apply () {
+ if (type=='l') {
+ targetl->ins ( QString(current.c_str()) );
+
+ }
+
+ if (type=='f') {
+ targetlf->ins ( QString(current.c_str()) );
+
+ }
+ else if (type=='b') {
+
+ targetb->setChecked (getInt (current));
+
+ }
+ else if (type=='c') {
+ int i = targetcb -> findText ( QString(current.c_str()) );
+ if (i > -1) targetcb ->setCurrentIndex (i);
+
+
+ }
+
+ else if (type=='m') {
+ targetlb->clear ();
+ for (unsigned int j=0; j<vect.size(); j++)
+ {
+ targetlb->insertItem( QString(vect[j].c_str()) );
+
+ }
+ }
+
+ else if (type=='M') {
+ targetlb->clear ();
+ for (unsigned int j=0; j<vect.size(); j++){
+ targetlb->insertItem(new MyListBoxItem (vect[j], targetlb));
+
+ }
+ }
+
+
+
+ else if (type=='s') {
+ istringstream line(current);
+ string nbsx, nbsy, nbsz;
+ line >> nbsx >>nbsy >> nbsz;
+ targetmw->bsx->ins ("");
+ targetmw->bsy->ins ("");
+ targetmw->bsz->ins ("");
+ targetmw->bsx->ins ( QString(nbsx.c_str()) );
+ targetmw->bsy->ins ( QString(nbsy.c_str()) );
+ targetmw->bsz->ins ( QString(nbsz.c_str()) );
+
+ }
+
+
+}
+
+
+void Confline::Get () {
+ if (type=='l') {
+ current = targetl->val ();
+
+ }
+
+ if (type=='f') {
+ current = targetlf->val ();
+
+ }
+ else if (type=='b') {
+ current = boolstr (targetb->isChecked ());
+
+
+ }
+ else if (type=='c') {
+
+ QString t = targetcb->currentText (); current = t.toStdString().c_str ();
+
+
+ }
+
+ else if (type=='m') {
+
+ if (targetlb->count ()) {
+ vect.clear ();
+ for (unsigned int j=0; j<targetlb->count() ; j++){
+ vect.push_back (targetlb->text(j).toStdString());
+ }
+ }
+
+ }
+
+ else if (type=='M') {
+
+ if (targetlb->count ()) {
+ vect.clear ();
+ for (unsigned int j=0; j<targetlb->count() ; j++){
+ vect.push_back (targetlb->item (j)->text ().toStdString());
+ cout << "check this" << targetlb->item (j)->text ().toStdString() << endl;
+ }
+ }
+
+
+ }
+
+
+ else if (type=='s') {
+ istringstream line(current);
+ string nbsx, nbsy, nbsz;
+ line >> nbsx >>nbsy >> nbsz;
+ current = targetmw->bsx->val ();
+ current.append (" ");
+ current.append (targetmw->bsy->val ());
+ current.append (" ");
+ current.append (targetmw->bsz->val ());
+ }
+
+
+}
+
+
+
+string Confline ::boolstr (bool boo){
+ if (boo) return "1";
+ else return "0";
+}
+
+
+////////////////////////////////////CONFIGURATION//////////////////////////////////////////////////////////////////
+
+Configuration::Configuration (Plants *plant) {
+ plants = plant;
+ // setdata (dat);
+
+
+
+
+ conf.push_back (new Confline ('l',"aco_ants","20", plants->mainwin->aants));
+ conf.push_back (new Confline ('l',"aco_evap", "0.15", plants->mainwin->aevap));
+ conf.push_back (new Confline ('l',"aco_sigma", "1.0", plants->mainwin->asigma));
+ conf.push_back (new Confline ('b',"flip_amide_bonds", "0", plants->mainwin->flipab));
+ conf.push_back (new Confline ('b',"flip_planar_n", "1", plants->mainwin->flipn));
+ conf.push_back (new Confline ('b',"force_flipped_bonds_planarity", "0", plants->mainwin->ffbp));
+ conf.push_back (new Confline ('c',"scoring_function", "chemplp", plants->mainwin->sfchoice));
+ conf.push_back (new Confline ('b',"chemplp_weak_cho", "1", plants->mainwin->cho));
+ conf.push_back (new Confline ('c',"ligand_intra_score", "clash2", plants->mainwin->lintra));
+ conf.push_back (new Confline ('l',"chemplp_charged_hb_weight", "1.75", plants->mainwin->chbw));
+ conf.push_back (new Confline ('l',"chemplp_charged_metal_weight", "2.0", plants->mainwin->cmw));
+ conf.push_back (new Confline ('l',"chemplp_hbond_weight", "-4.0", plants->mainwin->hbw));
+ conf.push_back (new Confline ('l',"chemplp_hbond_cho_weight", "-2.0", plants->mainwin->hbchow));
+ conf.push_back (new Confline ('l',"chemplp_metal_weight", "-6.0", plants->mainwin->mw));
+ conf.push_back (new Confline ('l',"chemplp_plp_weight", "1.0", plants->mainwin->plpw));
+ conf.push_back (new Confline ('l',"chemplp_intercept_weight", "-20.0", plants->mainwin->iw));
+ conf.push_back (new Confline ('l',"cluster_rmsd", "2.0", plants->mainwin->crmsd));
+ conf.push_back (new Confline ('l',"cluster_structures", "5", plants->mainwin->cs));
+
+
+
+
+ conf.push_back (new Confline ('M',"ifile", "", plants->mainwin->iflb));
+ conf.push_back (new Confline ('f',"protein_file", "", plants->mainwin->pfile));
+ conf.push_back (new Confline ('l',"output_dir", "", plants->mainwin->odir));
+ conf.push_back (new Confline ('s',"bindingsite_center", "", plants->mainwin));
+ conf.push_back (new Confline ('l',"bindingsite_radius", "", plants->mainwin->bsr));
+ conf.push_back (new Confline ('b',"write_protein_conformations", "1", plants->mainwin->wpc));
+ conf.push_back (new Confline ('b',"write_rescored_structures", "0", plants->mainwin->wrs));
+ conf.push_back (new Confline ('b',"write_multi_mol2", "1", plants->mainwin->wmm2));
+ conf.push_back (new Confline ('b',"write_ranking_links", "0", plants->mainwin->wrl));
+ conf.push_back (new Confline ('b',"write_ranking_multi_mol2", "0", plants->mainwin->wrmm2));
+ conf.push_back (new Confline ('b',"write_protein_bindingsite", "1", plants->mainwin->wpb));
+ conf.push_back (new Confline ('b',"write_protein_splitted", "1", plants->mainwin->wps));
+ conf.push_back (new Confline ('b',"write_per_atom_scores", "0", plants->mainwin->wpas));
+
+ conf.push_back (new Confline ('m',"constr", "", plants->mainwin->constrlb));
+
+ conf.push_back (new Confline ('m',"flex", "", plants->mainwin->flexlb));
+ conf.push_back (new Confline ('b',"rigid_ligand", "0", plants->mainwin->rigidl));
+ conf.push_back (new Confline ('b',"rigid_all", "0", plants->mainwin->rigida));
+ conf.push_back (new Confline ('l',"intra_protein_score_weight", "0.4", plants->mainwin->ipsw));
+
+ conf.push_back (new Confline ('f',"water_molecule_definition", "", plants->mainwin->wref));
+ conf.push_back (new Confline ('m',"water", "", plants->mainwin->waterlb));
+ conf.push_back (new Confline ('l',"water_protein_hb_weight", "1.0", plants->mainwin->wphb));
+ conf.push_back (new Confline ('l',"water_ligand_hb_weight", "1.0", plants->mainwin->wlhb));
+ conf.push_back (new Confline ('l',"water_water_hb_weight", "1.0", plants->mainwin->wwhb));
+ conf.push_back (new Confline ('l',"no_water_ligand_hb_penalty", "0.0", plants->mainwin->nwhbp));
+
+
+
+
+
+
+
+
+
+ Default ();
+}
+
+//void Configuration::setdata (Data *datas){
+// data = datas;
+// data->config = this;
+// win->conf = this;
+
+//}
+
+
+void Configuration::Default () {
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Default ();
+
+ }
+
+
+}
+
+
+void Configuration::Apply (){
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Apply ();
+ plants->mainwin->check_ligands ();
+ // data->ddwin->load_waters ();
+ }
+
+
+}
+
+
+void Configuration::Get (){
+
+ for (unsigned i=0; i<conf.size (); i++){
+ conf[i]->Get ();
+ }
+}
+
+
+
+void Configuration::Read (const char * filename){
+ if (filename) {
+ ifstream ifs (filename);
+ string buffer;
+ vector<string> ifiles, vflex, vconstr, vwater;
+ ifiles.clear(); vflex.clear (); vconstr.clear (); vwater.clear ();
+ while (getline(ifs, buffer)) {
+ istringstream line2(buffer);
+ string token;
+ line2 >> token;
+
+
+ if (token == "ligand_list" || token == "ligand_file") {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ ifiles.push_back (s);
+ }
+
+
+
+
+ else if (token == "chemplp_protein_hb_constraint" || token == "shape_constraint" || token == "surface_distance_constraint" || token == "ligand_intra_distance_constraint" || token == "protein_ligand_distance_constraint") {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ vconstr.push_back (s);
+ }
+
+ else if (token == "flexible_protein_side_chain_number" || token == "fixed_protein_bond" || token == "flexible_protein_side_chain_string") {
+ string s = token;
+ while (!line2.eof ()) {
+ string q;
+ line2 >> q;
+ s.append (" ");s.append (q);
+ }
+ vflex.push_back (s);
+ }
+
+ else if (token == "water_molecule") {
+ string s = token;
+ vector <float> wat;
+ wat.clear ();
+ while (!line2.eof ()) {
+
+ float f;
+ string q;
+
+ line2 >> q;
+ istringstream lin (q);
+ lin >> f;
+ wat.push_back (f);
+ s.append (" ");s.append (q);
+ }
+ vwater.push_back (s);
+
+ // data->waters.push_back(wat);
+ }
+
+
+
+ for (unsigned i=0; i<conf.size (); i++){
+ if (token == conf[i]->filestr && conf[i]->type!='s') {
+ line2>>conf[i]->current;
+ break;
+ }
+ if (token == conf[i]->filestr && conf[i]->type=='s') {
+ string x, y, z;
+ line2>>x>>y>>z;
+ conf[i]->current=x;conf[i]->current.append (" ");
+ conf[i]->current.append(y);conf[i]->current.append (" "); conf[i]->current.append(z);
+ }
+
+
+ }
+
+
+
+
+
+ for (unsigned i=0; i<conf.size (); i++){
+ if (conf[i]->filestr == "ifile") {
+ conf[i]->vect = ifiles;
+
+ }
+ if (conf[i]->filestr == "constr") {
+ conf[i]->vect = vconstr;
+
+ }
+ if (conf[i]->filestr == "flex") {
+ conf[i]->vect = vflex;
+
+ }
+ if (conf[i]->filestr == "water") {
+ conf[i]->vect = vwater;
+
+ }
+
+ }
+ }
+
+ }
+}
+
+
+
+
+
+
+void Configuration::Write (const char * filename){
+
+ ofstream *file = new ofstream(filename);
+ *file << "#Generated by PLANTS FE version " <<VERSION<< endl<<endl;
+
+ for (unsigned int i=0;i<conf.size(); i++){
+ if (i == 0){*file << endl << endl << "#ALGORITHM" << endl;};
+ if (i == 17){*file << endl << endl << "#INPUT-OUTPUT" << endl;};
+ if (i == 29){*file << endl << endl << "#CONSTRAINTS && FLEXIBILITY" << endl;};
+ if (i == 33){*file << endl << endl << "#WATER" << endl;};
+ if (conf[i]->type=='m' || conf[i]->type=='M' ){
+ for (unsigned int j=0;j<conf[i]->vect.size(); j++){
+ *file << conf[i]->vect[j] << endl;
+ }
+ }
+ else{
+ *file << conf[i]->filestr << " " << conf[i]->current << endl;
+ }
+ }
+
+
+
+
+
+
+
+ file->close();
+
+}
+
+
diff --git a/ply.c b/ply.c
new file mode 100644
index 0000000..76ee36b
--- /dev/null
+++ b/ply.c
@@ -0,0 +1,6638 @@
+/*
+
+
+
+The interface routines for reading && writing PLY polygon files.
+
+
+
+Greg Turk
+
+
+
+---------------------------------------------------------------
+
+
+
+A PLY file contains a single polygonal _object_.
+
+
+
+An object is composed of lists of _elements_. Typical elements are
+
+vertices, faces, edges && materials.
+
+
+
+Each type of element for a given object has one || more _properties_
+
+associated with the element type. For instance, a vertex element may
+
+have as properties the floating-point values x,y,z && the three unsigned
+
+chars representing red, green && blue.
+
+
+
+-----------------------------------------------------------------------
+
+
+
+Copyright (c) 1998 Georgia Institute of Technology. All rights reserved.
+
+
+
+Permission to use, copy, modify && distribute this software && its
+
+documentation for any purpose is hereby granted without fee, provided
+
+that the above copyright notice && this permission notice appear in
+
+all copies of this software && that you do not sell the software.
+
+
+
+THE SOFTWARE IS PROVIDED "AS IS" && WITHOUT WARRANTY OF ANY KIND,
+
+EXPRESS, IMPLIED || OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+
+WARRANTY OF MERCHANTABILITY || FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+*/
+
+
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include <math.h>
+
+#include <string.h>
+
+#include "ply.h"
+
+
+
+char *type_names[] = { /* names of scalar types */
+
+"invalid",
+
+"int8", "int16", "int32", "uint8", "uint16", "uint32", "float32", "float64",
+
+};
+
+
+
+char *old_type_names[] = { /* old names of types for backward compatability */
+
+"invalid",
+
+"char", "short", "int", "uchar", "ushort", "uint", "float", "double",
+
+};
+
+
+
+int ply_type_size[] = {
+
+0, 1, 2, 4, 1, 2, 4, 4, 8
+
+};
+
+
+
+#define NO_OTHER_PROPS -1
+
+
+
+#define DONT_STORE_PROP 0
+
+#define STORE_PROP 1
+
+
+
+#define OTHER_PROP 0
+
+#define NAMED_PROP 1
+
+
+
+/* returns 1 if strings are equal, 0 if not */
+
+int equal_strings( char * , char * );
+
+
+
+/* find an element in a plyfile's list */
+
+PlyElement *find_element( PlyFile * , char * );
+
+
+
+/* find a property in an element's list */
+
+PlyProperty *find_property( PlyElement * , char * , int * );
+
+
+
+/* write to a file the word describing a PLY file data type */
+
+void write_scalar_type( FILE * , int );
+
+
+
+/* read a line from a file && break it up into separate words */
+
+char* *get_words( FILE * , int * , char ** );
+
+
+
+/* write an item to a file */
+
+void write_binary_item( FILE * , int, unsigned int, double, int );
+
+void write_ascii_item( FILE * , int, unsigned int, double, int );
+
+
+
+/* add information to a PLY file descriptor */
+
+void add_element( PlyFile * , char ** , int );
+
+void add_property( PlyFile * , char ** , int );
+
+void add_comment( PlyFile * , char * );
+
+void add_obj_info( PlyFile * , char * );
+
+
+
+/* copy a property */
+
+void copy_property( PlyProperty * , PlyProperty * );
+
+
+
+/* store a value into where a pointer && a type specify */
+
+void store_item( char * , int, int, unsigned int, double );
+
+
+
+/* return the value of a stored item */
+
+void get_stored_item( void * , int, int * , unsigned int * , double * );
+
+
+
+/* return the value stored in an item, given ptr to it && its type */
+
+double get_item_value( char * , int );
+
+
+
+/* get binary || ascii item && store it according to ptr && type */
+
+void get_ascii_item( char * , int, int * , unsigned int * , double * );
+
+void get_binary_item( FILE * , int, int * , unsigned int * , double * );
+
+
+
+/* get a bunch of elements from a file */
+
+void ascii_get_element( PlyFile * , char * );
+
+void binary_get_element( PlyFile * , char * );
+
+
+
+/* memory allocation */
+
+static char *my_alloc( int, int, char * );
+
+
+
+
+
+/*************/
+
+/* Writing */
+
+/*************/
+
+
+
+
+
+/******************************************************************************
+
+Given a file pointer, get ready to write PLY data to the file.
+
+
+
+Entry:
+
+fp - the given file pointer
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+file_type - file type, either ascii || binary
+
+
+
+Exit:
+
+returns a pointer to a PlyFile, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *ply_write( FILE *fp, int nelems, char **elem_names, int file_type )
+
+{
+
+ int i;
+
+ PlyFile *plyfile;
+
+ PlyElement *elem;
+
+
+
+ /* check for NULL file pointer */
+
+ if ( fp == NULL )
+
+ return ( NULL );
+
+
+
+ /* create a record for this object */
+
+
+
+ plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) );
+
+ plyfile->file_type = file_type;
+
+ plyfile->num_comments = 0;
+
+ plyfile->num_obj_info = 0;
+
+ plyfile->num_elem_types = nelems;
+
+ plyfile->version = 1.0;
+
+ plyfile->fp = fp;
+
+ plyfile->other_elems = NULL;
+
+
+
+ /* tuck aside the names of the elements */
+
+
+
+ plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) * nelems );
+
+ for ( i = 0; i < nelems; i++ )
+
+ {
+
+ elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) );
+
+ plyfile->elems[i] = elem;
+
+ elem->name = strdup ( elem_names[i] );
+
+ elem->num = 0;
+
+ elem->nprops = 0;
+
+ }
+
+
+
+ /* return pointer to the file descriptor */
+
+ return ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Open a polygon file for writing.
+
+
+
+Entry:
+
+filename - name of file to read from
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+file_type - file type, either ascii || binary
+
+
+
+Exit:
+
+returns a file identifier, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *open_for_writing_ply( char *filename, int nelems, char **elem_names, int file_type )
+
+{
+
+ PlyFile *plyfile;
+
+ char *name;
+
+ FILE *fp;
+
+
+
+ /* tack on the extension .ply, if necessary */
+
+
+
+ name = ( char * ) myalloc ( sizeof ( char ) * ( strlen ( filename ) + 5 ) );
+
+ strcpy ( name, filename );
+
+ if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 )
+
+ strcat ( name, ".ply" );
+
+
+
+ /* open the file for writing */
+
+
+
+ fp = fopen ( name, "w" );
+
+ if ( fp == NULL )
+
+ {
+
+ return ( NULL );
+
+ }
+
+
+
+ /* create the actual PlyFile structure */
+
+
+
+ plyfile = ply_write ( fp, nelems, elem_names, file_type );
+
+ if ( plyfile == NULL )
+
+ return ( NULL );
+
+
+
+ /* return pointer to the file descriptor */
+
+ return ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Describe an element, including its properties && how many will be written
+
+to the file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element that information is being specified about
+
+nelems - number of elements of this type to be written
+
+nprops - number of properties contained in the element
+
+prop_list - list of properties
+
+******************************************************************************/
+
+
+
+void element_layout_ply( PlyFile *plyfile, char *elem_name, int nelems, int nprops, PlyProperty *prop_list )
+
+{
+
+ int i;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+
+
+ /* look for appropriate element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr,"element_layout_ply: can't find element '%s'\n",elem_name );
+
+ exit ( -1 );
+
+ }
+
+
+
+ elem->num = nelems;
+
+
+
+ /* copy the list of properties */
+
+
+
+ elem->nprops = nprops;
+
+ elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * nprops );
+
+ elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * nprops );
+
+
+
+ for ( i = 0; i < nprops; i++ )
+
+ {
+
+ prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ elem->props[i] = prop;
+
+ elem->store_prop[i] = NAMED_PROP;
+
+ copy_property ( prop, &prop_list[i] );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Describe a property of an element.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element that information is being specified about
+
+prop - the new property
+
+******************************************************************************/
+
+
+
+void ply_describe_property( PlyFile *plyfile, char *elem_name, PlyProperty *prop )
+
+{
+
+ PlyElement *elem;
+
+ PlyProperty *elem_prop;
+
+
+
+ /* look for appropriate element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr, "ply_describe_property: can't find element '%s'\n",
+
+ elem_name );
+
+ return;
+
+ }
+
+
+
+ /* create room for new property */
+
+
+
+ if ( elem->nprops == 0 )
+
+ {
+
+ elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) );
+
+ elem->store_prop = ( char * ) myalloc ( sizeof ( char ) );
+
+ elem->nprops = 1;
+
+ }
+
+ else
+
+ {
+
+ elem->nprops++;
+
+ elem->props = ( PlyProperty * * )
+
+ realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops );
+
+ elem->store_prop = ( char * )
+
+ realloc ( elem->store_prop, sizeof ( char ) * elem->nprops );
+
+ }
+
+
+
+ /* copy the new property */
+
+
+
+ elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ elem->props[elem->nprops - 1] = elem_prop;
+
+ elem->store_prop[elem->nprops - 1] = NAMED_PROP;
+
+ copy_property ( elem_prop, prop );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+State how many of a given element will be written.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element that information is being specified about
+
+nelems - number of elements of this type to be written
+
+******************************************************************************/
+
+
+
+void element_count_ply( PlyFile *plyfile, char *elem_name, int nelems )
+
+{
+
+ PlyElement *elem;
+
+
+
+ /* look for appropriate element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr,"element_count_ply: can't find element '%s'\n",elem_name );
+
+ exit ( -1 );
+
+ }
+
+
+
+ elem->num = nelems;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Signal that we've described everything a PLY file's header && that the
+
+header should be written to the file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+******************************************************************************/
+
+
+
+void header_complete_ply( PlyFile *plyfile )
+
+{
+
+ int i,j;
+
+ FILE *fp = plyfile->fp;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+
+
+ fprintf ( fp, "ply\n" );
+
+
+
+ switch ( plyfile->file_type )
+
+ {
+
+ case PLY_ASCII:
+
+ fprintf ( fp, "format ascii 1.0\n" );
+
+ break;
+
+ case PLY_BINARY_BE:
+
+ fprintf ( fp, "format binary_big_endian 1.0\n" );
+
+ break;
+
+ case PLY_BINARY_LE:
+
+ fprintf ( fp, "format binary_little_endian 1.0\n" );
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "ply_header_complete: bad file type = %d\n",
+
+ plyfile->file_type );
+
+ exit ( -1 );
+
+ }
+
+
+
+ /* write out the comments */
+
+
+
+ for ( i = 0; i < plyfile->num_comments; i++ )
+
+ fprintf ( fp, "comment %s\n", plyfile->comments[i] );
+
+
+
+ /* write out object information */
+
+
+
+ for ( i = 0; i < plyfile->num_obj_info; i++ )
+
+ fprintf ( fp, "obj_info %s\n", plyfile->obj_info[i] );
+
+
+
+ /* write out information about each element */
+
+
+
+ for ( i = 0; i < plyfile->num_elem_types; i++ )
+
+ {
+
+ elem = plyfile->elems[i];
+
+ fprintf ( fp, "element %s %d\n", elem->name, elem->num );
+
+
+
+ /* write out each property */
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ {
+
+ prop = elem->props[j];
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ fprintf ( fp, "property list " );
+
+ write_scalar_type ( fp, prop->count_external );
+
+ fprintf ( fp, " " );
+
+ write_scalar_type ( fp, prop->external_type );
+
+ fprintf ( fp, " %s\n", prop->name );
+
+ }
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ fprintf ( fp, "property string" );
+
+ fprintf ( fp, " %s\n", prop->name );
+
+ }
+
+ else
+
+ {
+
+ fprintf ( fp, "property " );
+
+ write_scalar_type ( fp, prop->external_type );
+
+ fprintf ( fp, " %s\n", prop->name );
+
+ }
+
+ }
+
+ }
+
+
+
+ fprintf ( fp, "end_header\n" );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify which elements are going to be written. This should be called
+
+before a call to the routine ply_put_element().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element we're talking about
+
+******************************************************************************/
+
+
+
+void put_element_setup_ply( PlyFile *plyfile, char *elem_name )
+
+{
+
+ PlyElement *elem;
+
+
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr, "put_element_setup_ply: can't find element '%s'\n", elem_name );
+
+ exit ( -1 );
+
+ }
+
+
+
+ plyfile->which_elem = elem;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Write an element to the file. This routine assumes that we're
+
+writing the type of element specified in the last call to the routine
+
+put_element_setup_ply().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_ptr - pointer to the element
+
+******************************************************************************/
+
+
+
+void put_element_ply( PlyFile *plyfile, void *elem_ptr )
+
+{
+
+ int j,k;
+
+ FILE *fp = plyfile->fp;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+ char *item;
+
+ char *elem_data;
+
+ char* *item_ptr;
+
+ int list_count;
+
+ int item_size;
+
+ int int_val;
+
+ unsigned int uint_val;
+
+ double double_val;
+
+ char* *other_ptr;
+
+
+
+ elem = plyfile->which_elem;
+
+ elem_data = ( char * ) elem_ptr;
+
+ other_ptr = ( char * * ) ( ( ( char * ) elem_ptr ) + elem->other_offset );
+
+
+
+ /* write out either to an ascii || binary file */
+
+
+
+ if ( plyfile->file_type == PLY_ASCII )
+
+ {
+
+ /* write an ascii file */
+
+
+
+ /* write out each property of the element */
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ {
+
+ prop = elem->props[j];
+
+
+
+ if ( elem->store_prop[j] == OTHER_PROP )
+
+ elem_data = *other_ptr;
+
+ else
+
+ elem_data = ( char * ) elem_ptr;
+
+
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ /* list */
+
+ item = elem_data + prop->count_offset;
+
+ get_stored_item ( ( void * ) item, prop->count_internal,
+
+ &int_val, &uint_val, &double_val );
+
+ write_ascii_item ( fp, int_val, uint_val, double_val,
+
+ prop->count_external );
+
+ list_count = uint_val;
+
+ item_ptr = ( char * * ) ( elem_data + prop->offset );
+
+ item = item_ptr[0];
+
+ item_size = ply_type_size[prop->internal_type];
+
+ for ( k = 0; k < list_count; k++ )
+
+ {
+
+ get_stored_item ( ( void * ) item, prop->internal_type,
+
+ &int_val, &uint_val, &double_val );
+
+ write_ascii_item ( fp, int_val, uint_val, double_val,
+
+ prop->external_type );
+
+ item += item_size;
+
+ }
+
+ }
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ /* string */
+
+ char* *str;
+
+ item = elem_data + prop->offset;
+
+ str = ( char * * ) item;
+
+ fprintf ( fp, "\"%s\"", *str );
+
+ }
+
+ else
+
+ {
+
+ /* scalar */
+
+ item = elem_data + prop->offset;
+
+ get_stored_item ( ( void * ) item, prop->internal_type,
+
+ &int_val, &uint_val, &double_val );
+
+ write_ascii_item ( fp, int_val, uint_val, double_val,
+
+ prop->external_type );
+
+ }
+
+ }
+
+
+
+ fprintf ( fp, "\n" );
+
+ }
+
+ else
+
+ {
+
+ /* write a binary file */
+
+
+
+ /* write out each property of the element */
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ {
+
+ prop = elem->props[j];
+
+ if ( elem->store_prop[j] == OTHER_PROP )
+
+ elem_data = *other_ptr;
+
+ else
+
+ elem_data = ( char * ) elem_ptr;
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ /* list */
+
+ item = elem_data + prop->count_offset;
+
+ item_size = ply_type_size[prop->count_internal];
+
+ get_stored_item ( ( void * ) item, prop->count_internal,
+
+ &int_val, &uint_val, &double_val );
+
+ write_binary_item ( fp, int_val, uint_val, double_val,
+
+ prop->count_external );
+
+ list_count = uint_val;
+
+ item_ptr = ( char * * ) ( elem_data + prop->offset );
+
+ item = item_ptr[0];
+
+ item_size = ply_type_size[prop->internal_type];
+
+ for ( k = 0; k < list_count; k++ )
+
+ {
+
+ get_stored_item ( ( void * ) item, prop->internal_type,
+
+ &int_val, &uint_val, &double_val );
+
+ write_binary_item ( fp, int_val, uint_val, double_val,
+
+ prop->external_type );
+
+ item += item_size;
+
+ }
+
+ }
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ /* string */
+
+ int len;
+
+ char* *str;
+
+ item = elem_data + prop->offset;
+
+ str = ( char * * ) item;
+
+
+
+ /* write the length */
+
+ len = strlen( *str ) + 1;
+
+ fwrite ( &len, sizeof( int ), 1, fp );
+
+
+
+ /* write the string, including the null character */
+
+ fwrite ( *str, len, 1, fp );
+
+ }
+
+ else
+
+ {
+
+ /* scalar */
+
+ item = elem_data + prop->offset;
+
+ item_size = ply_type_size[prop->internal_type];
+
+ get_stored_item ( ( void * ) item, prop->internal_type,
+
+ &int_val, &uint_val, &double_val );
+
+ write_binary_item ( fp, int_val, uint_val, double_val,
+
+ prop->external_type );
+
+ }
+
+ }
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*************/
+
+/* Reading */
+
+/*************/
+
+
+
+
+
+
+
+/******************************************************************************
+
+Given a file pointer, get ready to read PLY data from the file.
+
+
+
+Entry:
+
+fp - the given file pointer
+
+
+
+Exit:
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+returns a pointer to a PlyFile, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *ply_read( FILE *fp, int *nelems, char ***elem_names )
+
+{
+
+ int i,j;
+
+ PlyFile *plyfile;
+
+ int nwords;
+
+ char* *words;
+
+ int found_format = 0;
+
+ char* *elist;
+
+ PlyElement *elem;
+
+ char *orig_line;
+
+
+
+ /* check for NULL file pointer */
+
+ if ( fp == NULL )
+
+ return ( NULL );
+
+
+
+ /* create record for this object */
+
+
+
+ plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) );
+
+ plyfile->num_elem_types = 0;
+
+ plyfile->comments = NULL;
+
+ plyfile->num_comments = 0;
+
+ plyfile->obj_info = NULL;
+
+ plyfile->num_obj_info = 0;
+
+ plyfile->fp = fp;
+
+ plyfile->other_elems = NULL;
+
+ plyfile->rule_list = NULL;
+
+
+
+ /* read && parse the file's header */
+
+
+
+ words = get_words ( plyfile->fp, &nwords, &orig_line );
+
+ if ( !words || !equal_strings ( words[0], "ply" ) )
+
+ return ( NULL );
+
+
+
+ while ( words )
+
+ {
+
+ /* parse words */
+
+
+
+ if ( equal_strings ( words[0], "format" ) )
+
+ {
+
+ if ( nwords != 3 )
+
+ return ( NULL );
+
+ if ( equal_strings ( words[1], "ascii" ) )
+
+ plyfile->file_type = PLY_ASCII;
+
+ else if ( equal_strings ( words[1], "binary_big_endian" ) )
+
+ plyfile->file_type = PLY_BINARY_BE;
+
+ else if ( equal_strings ( words[1], "binary_little_endian" ) )
+
+ plyfile->file_type = PLY_BINARY_LE;
+
+ else
+
+ return ( NULL );
+
+ plyfile->version = ( float ) atof ( words[2] );
+
+ found_format = 1;
+
+ }
+
+ else if ( equal_strings ( words[0], "element" ) )
+
+ add_element ( plyfile, words, nwords );
+
+ else if ( equal_strings ( words[0], "property" ) )
+
+ add_property ( plyfile, words, nwords );
+
+ else if ( equal_strings ( words[0], "comment" ) )
+
+ add_comment ( plyfile, orig_line );
+
+ else if ( equal_strings ( words[0], "obj_info" ) )
+
+ add_obj_info ( plyfile, orig_line );
+
+ else if ( equal_strings ( words[0], "end_header" ) )
+
+ break;
+
+
+
+ /* free up words space */
+
+ free ( words );
+
+
+
+ words = get_words ( plyfile->fp, &nwords, &orig_line );
+
+ }
+
+
+
+ /* create tags for each property of each element, to be used */
+
+ /* later to say whether || not to store each property for the user */
+
+
+
+ for ( i = 0; i < plyfile->num_elem_types; i++ )
+
+ {
+
+ elem = plyfile->elems[i];
+
+ elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * elem->nprops );
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ elem->store_prop[j] = DONT_STORE_PROP;
+
+ elem->other_offset = NO_OTHER_PROPS; /* no "other" props by default */
+
+ }
+
+
+
+ /* set return values about the elements */
+
+
+
+ elist = ( char * * ) myalloc ( sizeof ( char * ) * plyfile->num_elem_types );
+
+ for ( i = 0; i < plyfile->num_elem_types; i++ )
+
+ elist[i] = strdup ( plyfile->elems[i]->name );
+
+
+
+ *elem_names = elist;
+
+ *nelems = plyfile->num_elem_types;
+
+
+
+ /* return a pointer to the file's information */
+
+
+
+ return ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Open a polygon file for reading.
+
+
+
+Entry:
+
+filename - name of file to read from
+
+
+
+Exit:
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+file_type - file type, either ascii || binary
+
+version - version number of PLY file
+
+returns a file identifier, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *ply_open_for_reading( char *filename, int *nelems, char ***elem_names, int *file_type, float *version )
+
+{
+
+ FILE *fp;
+
+ PlyFile *plyfile;
+
+ char *name;
+
+
+
+ /* tack on the extension .ply, if necessary */
+
+
+
+ name = ( char * ) myalloc ( sizeof ( char ) * ( strlen ( filename ) + 5 ) );
+
+ strcpy ( name, filename );
+
+ if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 )
+
+ strcat ( name, ".ply" );
+
+
+
+ /* open the file for reading */
+
+
+
+ fp = fopen ( name, "r" );
+
+ if ( fp == NULL )
+
+ return ( NULL );
+
+
+
+ /* create the PlyFile data structure */
+
+
+
+ plyfile = ply_read ( fp, nelems, elem_names );
+
+
+
+ /* determine the file type && version */
+
+
+
+ *file_type = plyfile->file_type;
+
+ *version = plyfile->version;
+
+
+
+ /* return a pointer to the file's information */
+
+
+
+ return ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Get information about a particular element.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element to get information about
+
+
+
+Exit:
+
+nelems - number of elements of this type in the file
+
+nprops - number of properties
+
+returns a list of properties, || NULL if the file doesn't contain that elem
+
+******************************************************************************/
+
+
+
+PlyProperty **get_element_description_ply( PlyFile *plyfile, char *elem_name, int *nelems, int *nprops )
+
+{
+
+ int i;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+ PlyProperty* *prop_list;
+
+
+
+ /* find information about the element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ return ( NULL );
+
+
+
+ *nelems = elem->num;
+
+ *nprops = elem->nprops;
+
+
+
+ /* make a copy of the element's property list */
+
+ prop_list = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * elem->nprops );
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ {
+
+ prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ copy_property ( prop, elem->props[i] );
+
+ prop_list[i] = prop;
+
+ }
+
+
+
+ /* return this duplicate property list */
+
+ return ( prop_list );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify which properties of an element are to be returned. This should be
+
+called before a call to the routine get_element_ply().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - which element we're talking about
+
+nprops - number of properties
+
+prop_list - list of properties
+
+******************************************************************************/
+
+
+
+void get_element_setup_ply( PlyFile *plyfile, char *elem_name, int nprops, PlyProperty *prop_list )
+
+{
+
+ int i;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+ int index;
+
+
+
+ /* find information about the element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ plyfile->which_elem = elem;
+
+
+
+ /* deposit the property information into the element's description */
+
+ for ( i = 0; i < nprops; i++ )
+
+ {
+
+ /* look for actual property */
+
+ prop = find_property ( elem, prop_list[i].name, &index );
+
+ if ( prop == NULL )
+
+ {
+
+ fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n",
+
+ prop_list[i].name, elem_name );
+
+ continue;
+
+ }
+
+
+
+ /* store its description */
+
+ prop->internal_type = prop_list[i].internal_type;
+
+ prop->offset = prop_list[i].offset;
+
+ prop->count_internal = prop_list[i].count_internal;
+
+ prop->count_offset = prop_list[i].count_offset;
+
+
+
+ /* specify that the user wants this property */
+
+ elem->store_prop[index] = STORE_PROP;
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify a property of an element that is to be returned. This should be
+
+called (usually multiple times) before a call to the routine ply_get_element().
+
+This routine should be used in preference to the less flexible old routine
+
+called ply_get_element_setup().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - which element we're talking about
+
+prop - property to add to those that will be returned
+
+******************************************************************************/
+
+
+
+void ply_get_property( PlyFile *plyfile, char *elem_name, PlyProperty *prop )
+
+{
+
+ PlyElement *elem;
+
+ PlyProperty *prop_ptr;
+
+ int index;
+
+
+
+ /* find information about the element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ plyfile->which_elem = elem;
+
+
+
+ /* deposit the property information into the element's description */
+
+
+
+ prop_ptr = find_property ( elem, prop->name, &index );
+
+ if ( prop_ptr == NULL )
+
+ {
+
+ fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n",
+
+ prop->name, elem_name );
+
+ return;
+
+ }
+
+ prop_ptr->internal_type = prop->internal_type;
+
+ prop_ptr->offset = prop->offset;
+
+ prop_ptr->count_internal = prop->count_internal;
+
+ prop_ptr->count_offset = prop->count_offset;
+
+
+
+ /* specify that the user wants this property */
+
+ elem->store_prop[index] = STORE_PROP;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Read one element from the file. This routine assumes that we're reading
+
+the type of element specified in the last call to the routine
+
+ply_get_element_setup().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_ptr - pointer to location where the element information should be put
+
+******************************************************************************/
+
+
+
+void ply_get_element( PlyFile *plyfile, void *elem_ptr )
+
+{
+
+ if ( plyfile->file_type == PLY_ASCII )
+
+ ascii_get_element ( plyfile, ( char * ) elem_ptr );
+
+ else
+
+ binary_get_element ( plyfile, ( char * ) elem_ptr );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Extract the comments from the header information of a PLY file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+
+
+Exit:
+
+num_comments - number of comments returned
+
+returns a pointer to a list of comments
+
+******************************************************************************/
+
+
+
+char **get_comments_ply( PlyFile *plyfile, int *num_comments )
+
+{
+
+ *num_comments = plyfile->num_comments;
+
+ return ( plyfile->comments );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Extract the object information (arbitrary text) from the header information
+
+of a PLY file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+
+
+Exit:
+
+num_obj_info - number of lines of text information returned
+
+returns a pointer to a list of object info lines
+
+******************************************************************************/
+
+
+
+char **get_obj_info_ply( PlyFile *plyfile, int *num_obj_info )
+
+{
+
+ *num_obj_info = plyfile->num_obj_info;
+
+ return ( plyfile->obj_info );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+ake ready for "other" properties of an element-- those properties that
+
+the user has not explicitly asked for, but that are to be stashed away
+
+in a special structure to be carried along with the element's other
+
+information.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem - element for which we want to save away other properties
+
+******************************************************************************/
+
+
+
+void setup_other_props( PlyFile *plyfile, PlyElement *elem )
+
+{
+
+ int i;
+
+ PlyProperty *prop;
+
+ int size = 0;
+
+ int type_size;
+
+
+
+ /* Examine each property in decreasing order of size. */
+
+ /* We do this so that all data types will be aligned by */
+
+ /* word, half-word, || whatever within the structure. */
+
+
+
+ for ( type_size = 8; type_size > 0; type_size /= 2 )
+
+ {
+
+ /* add up the space taken by each property, && save this information */
+
+ /* away in the property descriptor */
+
+
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ {
+
+ /* don't bother with properties we've been asked to store explicitly */
+
+ if ( elem->store_prop[i] )
+
+ continue;
+
+
+
+ prop = elem->props[i];
+
+
+
+ /* internal types will be same as external */
+
+ prop->internal_type = prop->external_type;
+
+ prop->count_internal = prop->count_external;
+
+
+
+ /* list case */
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ /* pointer to list */
+
+ if ( type_size == sizeof ( void * ) )
+
+ {
+
+ prop->offset = size;
+
+ size += sizeof ( void * ); /* always use size of a pointer here */
+
+ }
+
+
+
+ /* count of number of list elements */
+
+ if ( type_size == ply_type_size[prop->count_external] )
+
+ {
+
+ prop->count_offset = size;
+
+ size += ply_type_size[prop->count_external];
+
+ }
+
+ }
+
+ /* string */
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ /* pointer to string */
+
+ if ( type_size == sizeof ( char * ) )
+
+ {
+
+ prop->offset = size;
+
+ size += sizeof ( char * );
+
+ }
+
+ }
+
+ /* scalar */
+
+ else if ( type_size == ply_type_size[prop->external_type] )
+
+ {
+
+ prop->offset = size;
+
+ size += ply_type_size[prop->external_type];
+
+ }
+
+ }
+
+ }
+
+
+
+ /* save the size for the other_props structure */
+
+ elem->other_size = size;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify that we want the "other" properties of an element to be tucked
+
+away within the user's structure.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem - the element that we want to store other_props in
+
+offset - offset to where other_props will be stored inside user's structure
+
+
+
+Exit:
+
+returns pointer to structure containing description of other_props
+
+******************************************************************************/
+
+
+
+static PlyOtherProp *get_other_properties( PlyFile *plyfile, PlyElement *elem, int offset )
+
+{
+
+ int i;
+
+ PlyOtherProp *other;
+
+ PlyProperty *prop;
+
+ int nprops;
+
+
+
+ /* remember that this is the "current" element */
+
+ plyfile->which_elem = elem;
+
+
+
+ /* save the offset to where to store the other_props */
+
+ elem->other_offset = offset;
+
+
+
+ /* place the appropriate pointers, etc. in the element's property list */
+
+ setup_other_props ( plyfile, elem );
+
+
+
+ /* create structure for describing other_props */
+
+ other = ( PlyOtherProp * ) myalloc ( sizeof ( PlyOtherProp ) );
+
+ other->name = strdup ( elem->name );
+
+#if 0
+
+if (elem->other_offset == NO_OTHER_PROPS) {
+
+other->size = 0;
+
+other->props = NULL;
+
+other->nprops = 0;
+
+return (other);
+
+}
+
+#endif
+
+ other->size = elem->other_size;
+
+ other->props = ( PlyProperty * * ) myalloc ( sizeof( PlyProperty ) * elem->nprops );
+
+
+
+ /* save descriptions of each "other" property */
+
+ nprops = 0;
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ {
+
+ if ( elem->store_prop[i] )
+
+ continue;
+
+ prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ copy_property ( prop, elem->props[i] );
+
+ other->props[nprops] = prop;
+
+ nprops++;
+
+ }
+
+ other->nprops = nprops;
+
+
+
+ /* set other_offset pointer appropriately if there are NO other properties */
+
+ if ( other->nprops == 0 )
+
+ {
+
+ elem->other_offset = NO_OTHER_PROPS;
+
+ }
+
+
+
+ /* return structure */
+
+ return ( other );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify that we want the "other" properties of an element to be tucked
+
+away within the user's structure. The user needn't be concerned for how
+
+these properties are stored.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element that we want to store other_props in
+
+offset - offset to where other_props will be stored inside user's structure
+
+
+
+Exit:
+
+returns pointer to structure containing description of other_props
+
+******************************************************************************/
+
+
+
+PlyOtherProp *ply_get_other_properties( PlyFile *plyfile, char *elem_name, int offset )
+
+{
+
+ PlyElement *elem;
+
+ PlyOtherProp *other;
+
+
+
+ /* find information about the element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf ( stderr, "ply_get_other_properties: Can't find element '%s'\n",
+
+ elem_name );
+
+ return ( NULL );
+
+ }
+
+
+
+ other = get_other_properties ( plyfile, elem, offset );
+
+ return ( other );
+
+}
+
+
+
+
+
+
+
+
+
+/*************************/
+
+/* Other Element Stuff */
+
+/*************************/
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+
+Grab all the data for the current element that a user does not want to
+
+explicitly read in. Stores this in the PLY object's data structure.
+
+
+
+Entry:
+
+plyfile - pointer to file
+
+
+
+Exit:
+
+returns pointer to ALL the "other" element data for this PLY file
+
+******************************************************************************/
+
+
+
+PlyOtherElems *get_other_element_ply( PlyFile *plyfile )
+
+{
+
+ int i;
+
+ PlyElement *elem;
+
+ char *elem_name;
+
+ int elem_count;
+
+ PlyOtherElems *other_elems;
+
+ OtherElem *other;
+
+
+
+ elem = plyfile->which_elem;
+
+ elem_name = elem->name;
+
+ elem_count = elem->num;
+
+
+
+ /* create room for the new "other" element, initializing the */
+
+ /* other data structure if necessary */
+
+
+
+ if ( plyfile->other_elems == NULL )
+
+ {
+
+ plyfile->other_elems = ( PlyOtherElems * ) myalloc ( sizeof ( PlyOtherElems ) );
+
+ other_elems = plyfile->other_elems;
+
+ other_elems->other_list = ( OtherElem * ) myalloc ( sizeof ( OtherElem ) );
+
+ other = &( other_elems->other_list[0] );
+
+ other_elems->num_elems = 1;
+
+ }
+
+ else
+
+ {
+
+ other_elems = plyfile->other_elems;
+
+ other_elems->other_list = ( OtherElem * ) realloc ( other_elems->other_list,
+
+ sizeof ( OtherElem ) * other_elems->num_elems + 1 );
+
+ other = &( other_elems->other_list[other_elems->num_elems] );
+
+ other_elems->num_elems++;
+
+ }
+
+
+
+ /* count of element instances in file */
+
+ other->elem_count = elem_count;
+
+
+
+ /* save name of element */
+
+ other->elem_name = strdup ( elem_name );
+
+
+
+ /* create a list to hold all the current elements */
+
+ other->other_data = ( OtherData * * )
+
+ malloc ( sizeof ( OtherData * ) * other->elem_count );
+
+
+
+ /* set up for getting elements */
+
+ other->other_props = ply_get_other_properties ( plyfile, elem_name,
+
+ offsetof( OtherData,other_props ) );
+
+
+
+ /* grab all these elements */
+
+ for ( i = 0; i < other->elem_count; i++ )
+
+ {
+
+ /* grab && element from the file */
+
+ other->other_data[i] = ( OtherData * ) malloc ( sizeof ( OtherData ) );
+
+ ply_get_element ( plyfile, ( void * ) other->other_data[i] );
+
+ }
+
+
+
+ /* return pointer to the other elements data */
+
+ return ( other_elems );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Write out the "other" elements specified for this PLY file.
+
+
+
+Entry:
+
+plyfile - pointer to PLY file to write out other elements for
+
+******************************************************************************/
+
+
+
+void put_other_elements_ply( PlyFile *plyfile )
+
+{
+
+ int i,j;
+
+ OtherElem *other;
+
+
+
+ /* make sure we have other elements to write */
+
+ if ( plyfile->other_elems == NULL )
+
+ return;
+
+
+
+ /* write out the data for each "other" element */
+
+
+
+ for ( i = 0; i < plyfile->other_elems->num_elems; i++ )
+
+ {
+
+ other = &( plyfile->other_elems->other_list[i] );
+
+ put_element_setup_ply ( plyfile, other->elem_name );
+
+
+
+ /* write out each instance of the current element */
+
+ for ( j = 0; j < other->elem_count; j++ )
+
+ put_element_ply ( plyfile, ( void * ) other->other_data[j] );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Free up storage used by an "other" elements data structure.
+
+
+
+Entry:
+
+other_elems - data structure to free up
+
+******************************************************************************/
+
+
+
+void free_other_elements_ply( PlyOtherElems *other_elems )
+
+{
+
+}
+
+
+
+
+
+
+
+/*******************/
+
+/* Miscellaneous */
+
+/*******************/
+
+
+
+
+
+
+
+/******************************************************************************
+
+Close a PLY file.
+
+
+
+Entry:
+
+plyfile - identifier of file to close
+
+******************************************************************************/
+
+
+
+void ply_close( PlyFile *plyfile )
+
+{
+
+ fclose ( plyfile->fp );
+
+
+
+ /* free up memory associated with the PLY file */
+
+ free ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Get version number && file type of a PlyFile.
+
+
+
+Entry:
+
+ply - pointer to PLY file
+
+
+
+Exit:
+
+version - version of the file
+
+file_type - PLY_ASCII, PLY_BINARY_BE, || PLY_BINARY_LE
+
+******************************************************************************/
+
+
+
+void get_info_ply( PlyFile *ply, float *version, int *file_type )
+
+{
+
+ if ( ply == NULL )
+
+ return;
+
+
+
+ *version = ply->version;
+
+ *file_type = ply->file_type;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Compare two strings. Returns 1 if they are the same, 0 if not.
+
+******************************************************************************/
+
+
+
+int equal_strings( char *s1, char *s2 )
+
+{
+
+ while ( *s1 && *s2 )
+
+ if ( *s1++ != *s2++ )
+
+ return ( 0 );
+
+
+
+ if ( *s1 != *s2 )
+
+ return ( 0 );
+
+ else
+
+ return ( 1 );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Re-create the command line that was used to invoke this program.
+
+
+
+Entry:
+
+argc - number of words in argv
+
+argv - array of words in command line
+
+******************************************************************************/
+
+
+
+char *recreate_command_line( int argc, char *argv[] )
+
+{
+
+ int i;
+
+ char *line;
+
+ int len = 0;
+
+
+
+ /* count total number of characters needed, including separating spaces */
+
+ for ( i = 0; i < argc; i++ )
+
+ len += strlen( argv[i] ) + 1;
+
+
+
+ /* create empty line */
+
+ line = ( char * ) malloc ( sizeof( char ) * len );
+
+ line[0] = '\0';
+
+
+
+ /* repeatedly append argv */
+
+ for ( i = 0; i < argc; i++ )
+
+ {
+
+ strcat ( line, argv[i] );
+
+ if ( i != argc - 1 )
+
+ strcat ( line, " " );
+
+ }
+
+
+
+ return ( line );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Find an element from the element list of a given PLY object.
+
+
+
+Entry:
+
+plyfile - file id for PLY file
+
+element - name of element we're looking for
+
+
+
+Exit:
+
+returns the element, || NULL if not found
+
+******************************************************************************/
+
+
+
+PlyElement *find_element( PlyFile *plyfile, char *element )
+
+{
+
+ int i;
+
+
+
+ for ( i = 0; i < plyfile->num_elem_types; i++ )
+
+ if ( equal_strings ( element, plyfile->elems[i]->name ) )
+
+ return ( plyfile->elems[i] );
+
+
+
+ return ( NULL );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Find a property in the list of properties of a given element.
+
+
+
+Entry:
+
+elem - pointer to element in which we want to find the property
+
+prop_name - name of property to find
+
+
+
+Exit:
+
+index - index to position in list
+
+returns a pointer to the property, || NULL if not found
+
+******************************************************************************/
+
+
+
+PlyProperty *find_property( PlyElement *elem, char *prop_name, int *index )
+
+{
+
+ int i;
+
+
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ if ( equal_strings ( prop_name, elem->props[i]->name ) )
+
+ {
+
+ *index = i;
+
+ return ( elem->props[i] );
+
+ }
+
+
+
+ *index = -1;
+
+ return ( NULL );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Read an element from an ascii file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_ptr - pointer to element
+
+******************************************************************************/
+
+
+
+void ascii_get_element( PlyFile *plyfile, char *elem_ptr )
+
+{
+
+ int j,k;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+ char* *words;
+
+ int nwords;
+
+ int which_word;
+
+ char *elem_data,*item;
+
+ char *item_ptr;
+
+ int item_size;
+
+ int int_val;
+
+ unsigned int uint_val;
+
+ double double_val;
+
+ int list_count;
+
+ int store_it;
+
+ char* *store_array;
+
+ char *orig_line;
+
+ char *other_data;
+
+ int other_flag;
+
+
+
+ /* the kind of element we're reading currently */
+
+ elem = plyfile->which_elem;
+
+
+
+ /* do we need to setup for other_props? */
+
+
+
+ if ( elem->other_offset != NO_OTHER_PROPS )
+
+ {
+
+ char* *ptr;
+
+ other_flag = 1;
+
+ /* make room for other_props */
+
+ other_data = ( char * ) myalloc ( elem->other_size );
+
+ /* store pointer in user's structure to the other_props */
+
+ ptr = ( char * * ) ( elem_ptr + elem->other_offset );
+
+ *ptr = other_data;
+
+ }
+
+ else
+
+ other_flag = 0;
+
+
+
+ /* read in the element */
+
+
+
+ words = get_words ( plyfile->fp, &nwords, &orig_line );
+
+ if ( words == NULL )
+
+ {
+
+ fprintf ( stderr, "ply_get_element: unexpected end of file\n" );
+
+ exit ( -1 );
+
+ }
+
+
+
+ which_word = 0;
+
+
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ {
+
+ prop = elem->props[j];
+
+ store_it = ( elem->store_prop[j] | other_flag );
+
+
+
+ /* store either in the user's structure || in other_props */
+
+ if ( elem->store_prop[j] )
+
+ elem_data = elem_ptr;
+
+ else
+
+ elem_data = other_data;
+
+
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ /* a list */
+
+
+
+ /* get && store the number of items in the list */
+
+ get_ascii_item ( words[which_word++], prop->count_external,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ item = elem_data + prop->count_offset;
+
+ store_item( item, prop->count_internal, int_val, uint_val, double_val );
+
+ }
+
+
+
+ /* allocate space for an array of items && store a ptr to the array */
+
+ list_count = int_val;
+
+ item_size = ply_type_size[prop->internal_type];
+
+ store_array = ( char * * ) ( elem_data + prop->offset );
+
+
+
+ if ( list_count == 0 )
+
+ {
+
+ if ( store_it )
+
+ *store_array = NULL;
+
+ }
+
+ else
+
+ {
+
+ if ( store_it )
+
+ {
+
+ item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count );
+
+ item = item_ptr;
+
+ *store_array = item_ptr;
+
+ }
+
+
+
+ /* read items && store them into the array */
+
+ for ( k = 0; k < list_count; k++ )
+
+ {
+
+ get_ascii_item ( words[which_word++], prop->external_type,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ store_item ( item, prop->internal_type,
+
+ int_val, uint_val, double_val );
+
+ item += item_size;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ /* a string */
+
+ if ( store_it )
+
+ {
+
+ char *str;
+
+ char* *str_ptr;
+
+ str = strdup ( words[which_word++] );
+
+ item = elem_data + prop->offset;
+
+ str_ptr = ( char * * ) item;
+
+ *str_ptr = str;
+
+ }
+
+ else
+
+ {
+
+ which_word++;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ /* a scalar */
+
+ get_ascii_item ( words[which_word++], prop->external_type,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ item = elem_data + prop->offset;
+
+ store_item ( item, prop->internal_type, int_val, uint_val, double_val );
+
+ }
+
+ }
+
+ }
+
+
+
+ free ( words );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Read an element from a binary file.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_ptr - pointer to an element
+
+******************************************************************************/
+
+
+
+void binary_get_element( PlyFile *plyfile, char *elem_ptr )
+
+{
+
+ int j,k;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+ FILE *fp = plyfile->fp;
+
+ char *elem_data;
+
+ char *item;
+
+ char *item_ptr;
+
+ int item_size;
+
+ int int_val;
+
+ unsigned int uint_val;
+
+ double double_val;
+
+ int list_count;
+
+ int store_it;
+
+ char* *store_array;
+
+ char *other_data;
+
+ int other_flag;
+
+
+
+ /* the kind of element we're reading currently */
+
+ elem = plyfile->which_elem;
+
+
+
+ /* do we need to setup for other_props? */
+
+
+
+ if ( elem->other_offset != NO_OTHER_PROPS )
+
+ {
+
+ char* *ptr;
+
+ other_flag = 1;
+
+ /* make room for other_props */
+
+ other_data = ( char * ) myalloc ( elem->other_size );
+
+ /* store pointer in user's structure to the other_props */
+
+ ptr = ( char * * ) ( elem_ptr + elem->other_offset );
+
+ *ptr = other_data;
+
+ }
+
+ else
+
+ other_flag = 0;
+
+
+
+ /* read in a number of elements */
+
+
+
+ for ( j = 0; j < elem->nprops; j++ )
+
+ {
+
+ prop = elem->props[j];
+
+ store_it = ( elem->store_prop[j] | other_flag );
+
+
+
+ /* store either in the user's structure || in other_props */
+
+ if ( elem->store_prop[j] )
+
+ elem_data = elem_ptr;
+
+ else
+
+ elem_data = other_data;
+
+
+
+ if ( prop->is_list == PLY_LIST )
+
+ {
+
+ /* list */
+
+
+
+ /* get && store the number of items in the list */
+
+ get_binary_item ( fp, prop->count_external,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ item = elem_data + prop->count_offset;
+
+ store_item( item, prop->count_internal, int_val, uint_val, double_val );
+
+ }
+
+
+
+ /* allocate space for an array of items && store a ptr to the array */
+
+ list_count = int_val;
+
+ item_size = ply_type_size[prop->internal_type];
+
+ store_array = ( char * * ) ( elem_data + prop->offset );
+
+ if ( list_count == 0 )
+
+ {
+
+ if ( store_it )
+
+ *store_array = NULL;
+
+ }
+
+ else
+
+ {
+
+ if ( store_it )
+
+ {
+
+ item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count );
+
+ item = item_ptr;
+
+ *store_array = item_ptr;
+
+ }
+
+
+
+ /* read items && store them into the array */
+
+ for ( k = 0; k < list_count; k++ )
+
+ {
+
+ get_binary_item ( fp, prop->external_type,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ store_item ( item, prop->internal_type,
+
+ int_val, uint_val, double_val );
+
+ item += item_size;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ else if ( prop->is_list == PLY_STRING )
+
+ {
+
+ /* string */
+
+ int len;
+
+ char *str;
+
+ fread ( &len, sizeof( int ), 1, fp );
+
+ str = ( char * ) myalloc ( len );
+
+ fread ( str, len, 1, fp );
+
+ if ( store_it )
+
+ {
+
+ char* *str_ptr;
+
+ item = elem_data + prop->offset;
+
+ str_ptr = ( char * * ) item;
+
+ *str_ptr = str;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ /* scalar */
+
+ get_binary_item ( fp, prop->external_type,
+
+ &int_val, &uint_val, &double_val );
+
+ if ( store_it )
+
+ {
+
+ item = elem_data + prop->offset;
+
+ store_item ( item, prop->internal_type, int_val, uint_val, double_val );
+
+ }
+
+ }
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Write to a file the word that represents a PLY data type.
+
+
+
+Entry:
+
+fp - file pointer
+
+code - code for type
+
+******************************************************************************/
+
+
+
+void write_scalar_type( FILE *fp, int code )
+
+{
+
+ /* make sure this is a valid code */
+
+
+
+ if ( code <= StartType || code >= EndType )
+
+ {
+
+ fprintf ( stderr, "write_scalar_type: bad data code = %d\n", code );
+
+ exit ( -1 );
+
+ }
+
+
+
+ /* write the code to a file */
+
+
+
+ fprintf ( fp, "%s", type_names[code] );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Get a text line from a file && break it up into words.
+
+
+
+IMPORTANT: The calling routine should call "free" on the returned pointer once
+
+finished with it.
+
+
+
+Entry:
+
+fp - file to read from
+
+
+
+Exit:
+
+nwords - number of words returned
+
+orig_line - the original line of characters
+
+returns a list of words from the line, || NULL if end-of-file
+
+******************************************************************************/
+
+
+
+char **get_words( FILE *fp, int *nwords, char **orig_line )
+
+{
+
+#define BIG_STRING 4096
+
+ static char str[BIG_STRING];
+
+ static char str_copy[BIG_STRING];
+
+ char* *words;
+
+ int max_words = 10;
+
+ int num_words = 0;
+
+ char *ptr,*ptr2;
+
+ char *result;
+
+
+
+ words = ( char * * ) myalloc ( sizeof ( char * ) * max_words );
+
+
+
+ /* read in a line */
+
+ result = fgets ( str, BIG_STRING, fp );
+
+ if ( result == NULL )
+
+ {
+
+ *nwords = 0;
+
+ *orig_line = NULL;
+
+ return ( NULL );
+
+ }
+
+
+
+ /* convert line-feed && tabs into spaces */
+
+ /* (this guarentees that there will be a space before the */
+
+ /* null character at the end of the string) */
+
+
+
+ str[BIG_STRING - 2] = ' ';
+
+ str[BIG_STRING - 1] = '\0';
+
+
+
+ for ( ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++ )
+
+ {
+
+ *ptr2 = *ptr;
+
+ if ( *ptr == '\t' )
+
+ {
+
+ *ptr = ' ';
+
+ *ptr2 = ' ';
+
+ }
+
+ else if ( *ptr == '\n' )
+
+ {
+
+ *ptr = ' ';
+
+ *ptr2 = ' ';
+
+ break;
+
+ }
+
+ else if ( *ptr == '\r' )
+
+ {
+
+ *ptr = ' ';
+
+ *ptr2 = '\0';
+
+ }
+
+ }
+
+
+
+ /* find the words in the line */
+
+
+
+ ptr = str;
+
+ while ( *ptr != '\0' )
+
+ {
+
+ /* jump over leading spaces */
+
+ while ( *ptr == ' ' )
+
+ ptr++;
+
+
+
+ /* break if we reach the end */
+
+ if ( *ptr == '\0' )
+
+ break;
+
+
+
+ /* allocate more room for words if necessary */
+
+ if ( num_words >= max_words )
+
+ {
+
+ max_words += 10;
+
+ words = ( char * * ) realloc ( words, sizeof ( char * ) * max_words );
+
+ }
+
+
+
+ if ( *ptr == '\"' )
+
+ {
+
+ /* a quote indidicates that we have a string */
+
+
+
+ /* skip over leading quote */
+
+ ptr++;
+
+
+
+ /* save pointer to beginning of word */
+
+ words[num_words++] = ptr;
+
+
+
+ /* find trailing quote || end of line */
+
+ while ( *ptr != '\"' && *ptr != '\0' )
+
+ ptr++;
+
+
+
+ /* replace quote with a null character to mark the end of the word */
+
+ /* if we are not already at the end of the line */
+
+ if ( *ptr != '\0' )
+
+ *ptr++ = '\0';
+
+ }
+
+ else
+
+ {
+
+ /* non-string */
+
+
+
+ /* save pointer to beginning of word */
+
+ words[num_words++] = ptr;
+
+
+
+ /* jump over non-spaces */
+
+ while ( *ptr != ' ' )
+
+ ptr++;
+
+
+
+ /* place a null character here to mark the end of the word */
+
+ *ptr++ = '\0';
+
+ }
+
+ }
+
+
+
+ /* return the list of words */
+
+ *nwords = num_words;
+
+ *orig_line = str_copy;
+
+ return ( words );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Return the value of an item, given a pointer to it && its type.
+
+
+
+Entry:
+
+item - pointer to item
+
+type - data type that "item" points to
+
+
+
+Exit:
+
+returns a double-precision float that contains the value of the item
+
+******************************************************************************/
+
+
+
+double get_item_value( char *item, int type )
+
+{
+
+ unsigned char *puchar;
+
+ char *pchar;
+
+ short int *pshort;
+
+ unsigned short int *pushort;
+
+ int *pint;
+
+ unsigned int *puint;
+
+ float *pfloat;
+
+ double *pdouble;
+
+ int int_value;
+
+ unsigned int uint_value;
+
+ double double_value;
+
+
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ pchar = ( char * ) item;
+
+ int_value = *pchar;
+
+ return ( ( double ) int_value );
+
+ case Uint8:
+
+ puchar = ( unsigned char * ) item;
+
+ int_value = *puchar;
+
+ return ( ( double ) int_value );
+
+ case Int16:
+
+ pshort = ( short int * ) item;
+
+ int_value = *pshort;
+
+ return ( ( double ) int_value );
+
+ case Uint16:
+
+ pushort = ( unsigned short int * ) item;
+
+ int_value = *pushort;
+
+ return ( ( double ) int_value );
+
+ case Int32:
+
+ pint = ( int * ) item;
+
+ int_value = *pint;
+
+ return ( ( double ) int_value );
+
+ case Uint32:
+
+ puint = ( unsigned int * ) item;
+
+ uint_value = *puint;
+
+ return ( ( double ) uint_value );
+
+ case Float32:
+
+ pfloat = ( float * ) item;
+
+ double_value = *pfloat;
+
+ return ( double_value );
+
+ case Float64:
+
+ pdouble = ( double * ) item;
+
+ double_value = *pdouble;
+
+ return ( double_value );
+
+ default:
+
+ fprintf ( stderr, "get_item_value: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+
+
+ return ( 0.0 ); /* never actually gets here */
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Write out an item to a file as raw binary bytes.
+
+
+
+Entry:
+
+fp - file to write to
+
+int_val - integer version of item
+
+uint_val - unsigned integer version of item
+
+double_val - double-precision float version of item
+
+type - data type to write out
+
+******************************************************************************/
+
+
+
+void write_binary_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type )
+
+{
+
+ unsigned char uchar_val;
+
+ char char_val;
+
+ unsigned short ushort_val;
+
+ short short_val;
+
+ float float_val;
+
+
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ char_val = int_val;
+
+ fwrite ( &char_val, 1, 1, fp );
+
+ break;
+
+ case Int16:
+
+ short_val = int_val;
+
+ fwrite ( &short_val, 2, 1, fp );
+
+ break;
+
+ case Int32:
+
+ fwrite ( &int_val, 4, 1, fp );
+
+ break;
+
+ case Uint8:
+
+ uchar_val = uint_val;
+
+ fwrite ( &uchar_val, 1, 1, fp );
+
+ break;
+
+ case Uint16:
+
+ ushort_val = uint_val;
+
+ fwrite ( &ushort_val, 2, 1, fp );
+
+ break;
+
+ case Uint32:
+
+ fwrite ( &uint_val, 4, 1, fp );
+
+ break;
+
+ case Float32:
+
+ float_val = ( float ) double_val;
+
+ fwrite ( &float_val, 4, 1, fp );
+
+ break;
+
+ case Float64:
+
+ fwrite ( &double_val, 8, 1, fp );
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "write_binary_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Write out an item to a file as ascii characters.
+
+
+
+Entry:
+
+fp - file to write to
+
+int_val - integer version of item
+
+uint_val - unsigned integer version of item
+
+double_val - double-precision float version of item
+
+type - data type to write out
+
+******************************************************************************/
+
+
+
+void write_ascii_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type )
+
+{
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ case Int16:
+
+ case Int32:
+
+ fprintf ( fp, "%d ", int_val );
+
+ break;
+
+ case Uint8:
+
+ case Uint16:
+
+ case Uint32:
+
+ fprintf ( fp, "%u ", uint_val );
+
+ break;
+
+ case Float32:
+
+ case Float64:
+
+ fprintf ( fp, "%12f ", double_val );
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "write_ascii_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Get the value of an item that is in memory, && place the result
+
+into an integer, an unsigned integer && a double.
+
+
+
+Entry:
+
+ptr - pointer to the item
+
+type - data type supposedly in the item
+
+
+
+Exit:
+
+int_val - integer value
+
+uint_val - unsigned integer value
+
+double_val - double-precision floating point value
+
+******************************************************************************/
+
+
+
+void get_stored_item( void *ptr, int type, int *int_val, unsigned int *uint_val, double *double_val )
+
+{
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ *int_val = *( ( char * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint8:
+
+ *uint_val = *( ( unsigned char * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Int16:
+
+ *int_val = *( ( short int * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint16:
+
+ *uint_val = *( ( unsigned short int * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Int32:
+
+ *int_val = *( ( int * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint32:
+
+ *uint_val = *( ( unsigned int * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Float32:
+
+ *double_val = *( ( float * ) ptr );
+
+ *int_val = ( int ) *double_val;
+
+ *uint_val = ( unsigned int ) *double_val;
+
+ break;
+
+ case Float64:
+
+ *double_val = *( ( double * ) ptr );
+
+ *int_val = ( int ) *double_val;
+
+ *uint_val = ( unsigned int ) *double_val;
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "get_stored_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Get the value of an item from a binary file, && place the result
+
+into an integer, an unsigned integer && a double.
+
+
+
+Entry:
+
+fp - file to get item from
+
+type - data type supposedly in the word
+
+
+
+Exit:
+
+int_val - integer value
+
+uint_val - unsigned integer value
+
+double_val - double-precision floating point value
+
+******************************************************************************/
+
+
+
+void get_binary_item( FILE *fp, int type, int *int_val, unsigned int *uint_val, double *double_val )
+
+{
+
+ char c[8];
+
+ void *ptr;
+
+
+
+ ptr = ( void * ) c;
+
+
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ fread ( ptr, 1, 1, fp );
+
+ *int_val = *( ( char * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint8:
+
+ fread ( ptr, 1, 1, fp );
+
+ *uint_val = *( ( unsigned char * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Int16:
+
+ fread ( ptr, 2, 1, fp );
+
+ *int_val = *( ( short int * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint16:
+
+ fread ( ptr, 2, 1, fp );
+
+ *uint_val = *( ( unsigned short int * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Int32:
+
+ fread ( ptr, 4, 1, fp );
+
+ *int_val = *( ( int * ) ptr );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+ case Uint32:
+
+ fread ( ptr, 4, 1, fp );
+
+ *uint_val = *( ( unsigned int * ) ptr );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+ case Float32:
+
+ fread ( ptr, 4, 1, fp );
+
+ *double_val = *( ( float * ) ptr );
+
+ *int_val = ( int ) *double_val;
+
+ *uint_val = ( unsigned int ) *double_val;
+
+ break;
+
+ case Float64:
+
+ fread ( ptr, 8, 1, fp );
+
+ *double_val = *( ( double * ) ptr );
+
+ *int_val = ( int ) *double_val;
+
+ *uint_val = ( unsigned int ) *double_val;
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "get_binary_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Extract the value of an item from an ascii word, && place the result
+
+into an integer, an unsigned integer && a double.
+
+
+
+Entry:
+
+word - word to extract value from
+
+type - data type supposedly in the word
+
+
+
+Exit:
+
+int_val - integer value
+
+uint_val - unsigned integer value
+
+double_val - double-precision floating point value
+
+******************************************************************************/
+
+
+
+void get_ascii_item( char *word, int type, int *int_val, unsigned int *uint_val, double *double_val )
+
+{
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ case Uint8:
+
+ case Int16:
+
+ case Uint16:
+
+ case Int32:
+
+ *int_val = atoi ( word );
+
+ *uint_val = *int_val;
+
+ *double_val = *int_val;
+
+ break;
+
+
+
+ case Uint32:
+
+ *uint_val = strtoul ( word, ( char * * ) NULL, 10 );
+
+ *int_val = *uint_val;
+
+ *double_val = *uint_val;
+
+ break;
+
+
+
+ case Float32:
+
+ case Float64:
+
+ *double_val = atof ( word );
+
+ *int_val = ( int ) *double_val;
+
+ *uint_val = ( unsigned int ) *double_val;
+
+ break;
+
+
+
+ default:
+
+ fprintf ( stderr, "get_ascii_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Store a value into a place being pointed to, guided by a data type.
+
+
+
+Entry:
+
+item - place to store value
+
+type - data type
+
+int_val - integer version of value
+
+uint_val - unsigned integer version of value
+
+double_val - double version of value
+
+
+
+Exit:
+
+item - pointer to stored value
+
+******************************************************************************/
+
+
+
+void store_item( char *item, int type, int int_val, unsigned int uint_val, double double_val )
+
+{
+
+ unsigned char *puchar;
+
+ short int *pshort;
+
+ unsigned short int *pushort;
+
+ int *pint;
+
+ unsigned int *puint;
+
+ float *pfloat;
+
+ double *pdouble;
+
+
+
+ switch ( type )
+
+ {
+
+ case Int8:
+
+ *item = int_val;
+
+ break;
+
+ case Uint8:
+
+ puchar = ( unsigned char * ) item;
+
+ *puchar = uint_val;
+
+ break;
+
+ case Int16:
+
+ pshort = ( short * ) item;
+
+ *pshort = int_val;
+
+ break;
+
+ case Uint16:
+
+ pushort = ( unsigned short * ) item;
+
+ *pushort = uint_val;
+
+ break;
+
+ case Int32:
+
+ pint = ( int * ) item;
+
+ *pint = int_val;
+
+ break;
+
+ case Uint32:
+
+ puint = ( unsigned int * ) item;
+
+ *puint = uint_val;
+
+ break;
+
+ case Float32:
+
+ pfloat = ( float * ) item;
+
+ *pfloat = ( float ) double_val;
+
+ break;
+
+ case Float64:
+
+ pdouble = ( double * ) item;
+
+ *pdouble = double_val;
+
+ break;
+
+ default:
+
+ fprintf ( stderr, "store_item: bad type = %d\n", type );
+
+ exit ( -1 );
+
+ }
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Add an element to a PLY file descriptor.
+
+
+
+Entry:
+
+plyfile - PLY file descriptor
+
+words - list of words describing the element
+
+nwords - number of words in the list
+
+******************************************************************************/
+
+
+
+void add_element( PlyFile *plyfile, char **words, int nwords )
+
+{
+
+ PlyElement *elem;
+
+
+
+ /* create the new element */
+
+ elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) );
+
+ elem->name = strdup ( words[1] );
+
+ elem->num = atoi ( words[2] );
+
+ elem->nprops = 0;
+
+
+
+ /* make room for new element in the object's list of elements */
+
+ if ( plyfile->num_elem_types == 0 )
+
+ plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) );
+
+ else
+
+ plyfile->elems = ( PlyElement * * ) realloc ( plyfile->elems,
+
+ sizeof ( PlyElement * ) * ( plyfile->num_elem_types + 1 ) );
+
+
+
+ /* add the new element to the object's list */
+
+ plyfile->elems[plyfile->num_elem_types] = elem;
+
+ plyfile->num_elem_types++;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Return the type of a property, given the name of the property.
+
+
+
+Entry:
+
+name - name of property type
+
+
+
+Exit:
+
+returns integer code for property, || 0 if not found
+
+******************************************************************************/
+
+
+
+int get_prop_type( char *type_name )
+
+{
+
+ int i;
+
+
+
+ /* try to match the type name */
+
+ for ( i = StartType + 1; i < EndType; i++ )
+
+ if ( equal_strings ( type_name, type_names[i] ) )
+
+ return ( i );
+
+
+
+ /* see if we can match an old type name */
+
+ for ( i = StartType + 1; i < EndType; i++ )
+
+ if ( equal_strings ( type_name, old_type_names[i] ) )
+
+ return ( i );
+
+
+
+ /* if we get here, we didn't find the type */
+
+ return ( 0 );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Add a property to a PLY file descriptor.
+
+
+
+Entry:
+
+plyfile - PLY file descriptor
+
+words - list of words describing the property
+
+nwords - number of words in the list
+
+******************************************************************************/
+
+
+
+void add_property( PlyFile *plyfile, char **words, int nwords )
+
+{
+
+ PlyProperty *prop;
+
+ PlyElement *elem;
+
+
+
+ /* create the new property */
+
+
+
+ prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+
+
+ if ( equal_strings ( words[1], "list" ) )
+
+ {
+
+ /* list */
+
+ prop->count_external = get_prop_type ( words[2] );
+
+ prop->external_type = get_prop_type ( words[3] );
+
+ prop->name = strdup ( words[4] );
+
+ prop->is_list = PLY_LIST;
+
+ }
+
+ else if ( equal_strings ( words[1], "string" ) )
+
+ {
+
+ /* string */
+
+ prop->count_external = Int8;
+
+ prop->external_type = Int8;
+
+ prop->name = strdup ( words[2] );
+
+ prop->is_list = PLY_STRING;
+
+ }
+
+ else
+
+ {
+
+ /* scalar */
+
+ prop->external_type = get_prop_type ( words[1] );
+
+ prop->name = strdup ( words[2] );
+
+ prop->is_list = PLY_SCALAR;
+
+ }
+
+
+
+ /* add this property to the list of properties of the current element */
+
+
+
+ elem = plyfile->elems[plyfile->num_elem_types - 1];
+
+
+
+ if ( elem->nprops == 0 )
+
+ elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) );
+
+ else
+
+ elem->props = ( PlyProperty * * ) realloc ( elem->props,
+
+ sizeof ( PlyProperty * ) * ( elem->nprops + 1 ) );
+
+
+
+ elem->props[elem->nprops] = prop;
+
+ elem->nprops++;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Add a comment to a PLY file descriptor.
+
+
+
+Entry:
+
+plyfile - PLY file descriptor
+
+line - line containing comment
+
+******************************************************************************/
+
+
+
+void add_comment( PlyFile *plyfile, char *line )
+
+{
+
+ int i;
+
+
+
+ /* skip over "comment" && leading spaces && tabs */
+
+ i = 7;
+
+ while ( line[i] == ' ' || line[i] == '\t' )
+
+ i++;
+
+
+
+ append_comment_ply ( plyfile, &line[i] );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Add a some object information to a PLY file descriptor.
+
+
+
+Entry:
+
+plyfile - PLY file descriptor
+
+line - line containing text info
+
+******************************************************************************/
+
+
+
+void add_obj_info( PlyFile *plyfile, char *line )
+
+{
+
+ int i;
+
+
+
+ /* skip over "obj_info" && leading spaces && tabs */
+
+ i = 8;
+
+ while ( line[i] == ' ' || line[i] == '\t' )
+
+ i++;
+
+
+
+ append_obj_info_ply ( plyfile, &line[i] );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Copy a property.
+
+******************************************************************************/
+
+
+
+void copy_property( PlyProperty *dest, PlyProperty *src )
+
+{
+
+ dest->name = strdup ( src->name );
+
+ dest->external_type = src->external_type;
+
+ dest->internal_type = src->internal_type;
+
+ dest->offset = src->offset;
+
+
+
+ dest->is_list = src->is_list;
+
+ dest->count_external = src->count_external;
+
+ dest->count_internal = src->count_internal;
+
+ dest->count_offset = src->count_offset;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Allocate some memory.
+
+
+
+Entry:
+
+size - amount of memory requested (in bytes)
+
+lnum - line number from which memory was requested
+
+fname - file name from which memory was requested
+
+******************************************************************************/
+
+
+
+static char *my_alloc( int size, int lnum, char *fname )
+
+{
+
+ char *ptr;
+
+
+
+ ptr = ( char * ) malloc ( size );
+
+
+
+ if ( ptr == 0 )
+
+ {
+
+ fprintf( stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname );
+
+ }
+
+
+
+ return ( ptr );
+
+}
+
+
+
+
+
+/**** NEW STUFF ****/
+
+/**** NEW STUFF ****/
+
+/**** NEW STUFF ****/
+
+/**** NEW STUFF ****/
+
+
+
+
+
+
+
+/******************************************************************************
+
+Given a file pointer, get ready to read PLY data from the file.
+
+
+
+Entry:
+
+fp - the given file pointer
+
+
+
+Exit:
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+returns a pointer to a PlyFile, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *read_ply( FILE *fp )
+
+{
+
+ PlyFile *ply;
+
+ int num_elems;
+
+ char* *elem_names;
+
+
+
+ ply = ply_read ( fp, &num_elems, &elem_names );
+
+
+
+ return ( ply );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Given a file pointer, get ready to write PLY data to the file.
+
+
+
+Entry:
+
+fp - the given file pointer
+
+nelems - number of elements in object
+
+elem_names - list of element names
+
+file_type - file type, either ascii || binary
+
+
+
+Exit:
+
+returns a pointer to a PlyFile, used to refer to this file, || NULL if error
+
+******************************************************************************/
+
+
+
+PlyFile *write_ply( FILE *fp, int nelems, char **elem_names, int file_type )
+
+{
+
+ PlyFile *ply;
+
+
+
+ ply = ply_write ( fp, nelems, elem_names, file_type );
+
+
+
+ return ( ply );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Return a list of the names of the elements in a particular PLY file.
+
+
+
+Entry:
+
+ply - PLY file whose element name list we want
+
+
+
+Exit:
+
+num_elems - the number of element names in the list
+
+returns the list of names
+
+******************************************************************************/
+
+
+
+char **get_element_list_ply( PlyFile *ply, int *num_elems )
+
+{
+
+ int i;
+
+ char* *elist;
+
+
+
+ /* create the list of element names */
+
+
+
+ elist = ( char * * ) myalloc ( sizeof ( char * ) * ply->num_elem_types );
+
+ for ( i = 0; i < ply->num_elem_types; i++ )
+
+ elist[i] = strdup ( ply->elems[i]->name );
+
+
+
+ /* return the number of elements && the list of element names */
+
+ *num_elems = ply->num_elem_types;
+
+ return ( elist );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Append a comment to a PLY file.
+
+
+
+Entry:
+
+ply - file to append comment to
+
+comment - the comment to append
+
+******************************************************************************/
+
+
+
+void append_comment_ply( PlyFile *ply, char *comment )
+
+{
+
+ /* (re)allocate space for new comment */
+
+ if ( ply->num_comments == 0 )
+
+ ply->comments = ( char * * ) myalloc ( sizeof ( char * ) );
+
+ else
+
+ ply->comments = ( char * * ) realloc ( ply->comments,
+
+ sizeof ( char * ) * ( ply->num_comments + 1 ) );
+
+
+
+ /* add comment to list */
+
+ ply->comments[ply->num_comments] = strdup ( comment );
+
+ ply->num_comments++;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Copy the comments from one PLY file to another.
+
+
+
+Entry:
+
+out_ply - destination file to copy comments to
+
+in_ply - the source of the comments
+
+******************************************************************************/
+
+
+
+void copy_comments_ply( PlyFile *out_ply, PlyFile *in_ply )
+
+{
+
+ int i;
+
+
+
+ for ( i = 0; i < in_ply->num_comments; i++ )
+
+ append_comment_ply ( out_ply, in_ply->comments[i] );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Append object information (arbitrary text) to a PLY file.
+
+
+
+Entry:
+
+ply - file to append object info to
+
+obj_info - the object info to append
+
+******************************************************************************/
+
+
+
+void append_obj_info_ply( PlyFile *ply, char *obj_info )
+
+{
+
+ /* (re)allocate space for new info */
+
+ if ( ply->num_obj_info == 0 )
+
+ ply->obj_info = ( char * * ) myalloc ( sizeof ( char * ) );
+
+ else
+
+ ply->obj_info = ( char * * ) realloc ( ply->obj_info,
+
+ sizeof ( char * ) * ( ply->num_obj_info + 1 ) );
+
+
+
+ /* add info to list */
+
+ ply->obj_info[ply->num_obj_info] = strdup ( obj_info );
+
+ ply->num_obj_info++;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Copy the object information from one PLY file to another.
+
+
+
+Entry:
+
+out_ply - destination file to copy object information to
+
+in_ply - the source of the object information
+
+******************************************************************************/
+
+
+
+void copy_obj_info_ply( PlyFile *out_ply, PlyFile *in_ply )
+
+{
+
+ int i;
+
+
+
+ for ( i = 0; i < in_ply->num_obj_info; i++ )
+
+ append_obj_info_ply ( out_ply, in_ply->obj_info[i] );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Close a PLY file.
+
+
+
+Entry:
+
+plyfile - identifier of file to close
+
+******************************************************************************/
+
+
+
+void close_ply( PlyFile *plyfile )
+
+{
+
+ fclose ( plyfile->fp );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Free the memory used by a PLY file.
+
+
+
+Entry:
+
+plyfile - identifier of file
+
+******************************************************************************/
+
+
+
+void free_ply( PlyFile *plyfile )
+
+{
+
+ /* free up memory associated with the PLY file */
+
+ free ( plyfile );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify the index of the next element to be read in from a PLY file.
+
+
+
+Entry:
+
+ply - file to read from
+
+index - index of the element to be read
+
+
+
+Exit:
+
+elem_count - the number of elements in the file
+
+returns pointer to the name of this next element
+
+******************************************************************************/
+
+
+
+char *setup_element_read_ply( PlyFile *ply, int index, int *elem_count )
+
+{
+
+ PlyElement *elem;
+
+
+
+ if ( index < 0 || index > ply->num_elem_types )
+
+ {
+
+ fprintf ( stderr, "Warning: No element with index %d\n", index );
+
+ return ( 0 );
+
+ }
+
+
+
+ elem = ply->elems[index];
+
+
+
+ /* set this to be the current element */
+
+ ply->which_elem = elem;
+
+
+
+ /* return the number of such elements in the file && the element's name */
+
+ *elem_count = elem->num;
+
+ return ( elem->name );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Read one element from the file. This routine assumes that we're reading
+
+the type of element specified in the last call to the routine
+
+setup_element_read_ply().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_ptr - pointer to location where the element information should be put
+
+******************************************************************************/
+
+
+
+void get_element_ply( PlyFile *plyfile, void *elem_ptr )
+
+{
+
+ if ( plyfile->file_type == PLY_ASCII )
+
+ ascii_get_element ( plyfile, ( char * ) elem_ptr );
+
+ else
+
+ binary_get_element ( plyfile, ( char * ) elem_ptr );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify one of several properties of the current element that is to be
+
+read from a file. This should be called (usually multiple times) before a
+
+call to the routine get_element_ply().
+
+
+
+Entry:
+
+plyfile - file identifier
+
+prop - property to add to those that will be returned
+
+
+
+Exit:
+
+0 if the property has not been found
+
+1 if the property has been found
+
+******************************************************************************/
+
+
+
+int setup_property_ply( PlyFile *plyfile, PlyProperty *prop )
+
+{
+
+ PlyElement *elem;
+
+ PlyProperty *prop_ptr;
+
+ int index;
+
+
+
+ elem = plyfile->which_elem;
+
+
+
+ /* deposit the property information into the element's description */
+
+
+
+ prop_ptr = find_property ( elem, prop->name, &index );
+
+ if ( prop_ptr == NULL )
+
+ {
+
+ fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n",
+
+ prop->name, elem->name );
+
+ return 0;
+
+ }
+
+ prop_ptr->internal_type = prop->internal_type;
+
+ prop_ptr->offset = prop->offset;
+
+ prop_ptr->count_internal = prop->count_internal;
+
+ prop_ptr->count_offset = prop->count_offset;
+
+
+
+ /* specify that the user wants this property */
+
+ elem->store_prop[index] = STORE_PROP;
+
+ return 1 ;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Specify that we want the "other" properties of the current element to be tucked
+
+away within the user's structure.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+offset - offset to where other_props will be stored inside user's structure
+
+
+
+Exit:
+
+returns pointer to structure containing description of other_props
+
+******************************************************************************/
+
+
+
+PlyOtherProp *get_other_properties_ply( PlyFile *plyfile, int offset )
+
+{
+
+ PlyOtherProp *other;
+
+
+
+ other = get_other_properties ( plyfile, plyfile->which_elem, offset );
+
+ return ( other );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Describe which element is to be written next && state how many of them will
+
+be written.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+elem_name - name of element that information is being described
+
+nelems - number of elements of this type to be written
+
+******************************************************************************/
+
+
+
+void describe_element_ply( PlyFile *plyfile, char *elem_name, int nelems )
+
+{
+
+ PlyElement *elem;
+
+
+
+ /* look for appropriate element */
+
+ elem = find_element ( plyfile, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr,"describe_element_ply: can't find element '%s'\n",elem_name );
+
+ exit ( -1 );
+
+ }
+
+
+
+ elem->num = nelems;
+
+
+
+ /* now this element is the current element */
+
+ plyfile->which_elem = elem;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Describe a property of an element.
+
+
+
+Entry:
+
+plyfile - file identifier
+
+prop - the new property
+
+******************************************************************************/
+
+
+
+void describe_property_ply( PlyFile *plyfile, PlyProperty *prop )
+
+{
+
+ PlyElement *elem;
+
+ PlyProperty *elem_prop;
+
+
+
+ elem = plyfile->which_elem;
+
+
+
+ /* create room for new property */
+
+
+
+ if ( elem->nprops == 0 )
+
+ {
+
+ elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) );
+
+ elem->store_prop = ( char * ) myalloc ( sizeof ( char ) );
+
+ elem->nprops = 1;
+
+ }
+
+ else
+
+ {
+
+ elem->nprops++;
+
+ elem->props = ( PlyProperty * * )
+
+ realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops );
+
+ elem->store_prop = ( char * )
+
+ realloc ( elem->store_prop, sizeof ( char ) * elem->nprops );
+
+ }
+
+
+
+ /* copy the new property */
+
+
+
+ elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ elem->props[elem->nprops - 1] = elem_prop;
+
+ elem->store_prop[elem->nprops - 1] = NAMED_PROP;
+
+ copy_property ( elem_prop, prop );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Describe what the "other" properties are that are to be stored, && where
+
+they are in an element.
+
+******************************************************************************/
+
+
+
+void describe_other_properties_ply( PlyFile *plyfile, PlyOtherProp *other, int offset )
+
+{
+
+ int i;
+
+ PlyElement *elem;
+
+ PlyProperty *prop;
+
+
+
+ /* look for appropriate element */
+
+ elem = find_element ( plyfile, other->name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf( stderr, "describe_other_properties_ply: can't find element '%s'\n",
+
+ other->name );
+
+ return;
+
+ }
+
+
+
+ /* create room for other properties */
+
+
+
+ if ( elem->nprops == 0 )
+
+ {
+
+ elem->props = ( PlyProperty * * )
+
+ myalloc ( sizeof ( PlyProperty * ) * other->nprops );
+
+ elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * other->nprops );
+
+ elem->nprops = 0;
+
+ }
+
+ else
+
+ {
+
+ int newsize;
+
+ newsize = elem->nprops + other->nprops;
+
+ elem->props = ( PlyProperty * * )
+
+ realloc ( elem->props, sizeof ( PlyProperty * ) * newsize );
+
+ elem->store_prop = ( char * )
+
+ realloc ( elem->store_prop, sizeof ( char ) * newsize );
+
+ }
+
+
+
+ /* copy the other properties */
+
+
+
+ for ( i = 0; i < other->nprops; i++ )
+
+ {
+
+ prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) );
+
+ copy_property ( prop, other->props[i] );
+
+ elem->props[elem->nprops] = prop;
+
+ elem->store_prop[elem->nprops] = OTHER_PROP;
+
+ elem->nprops++;
+
+ }
+
+
+
+ /* save other info about other properties */
+
+ elem->other_size = other->size;
+
+ elem->other_offset = offset;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Pass along a pointer to "other" elements that we want to save in a given
+
+PLY file. These other elements were presumably read from another PLY file.
+
+
+
+Entry:
+
+plyfile - file pointer in which to store this other element info
+
+other_elems - info about other elements that we want to store
+
+******************************************************************************/
+
+
+
+void describe_other_elements_ply( PlyFile *plyfile, PlyOtherElems *other_elems )
+
+{
+
+ int i;
+
+ OtherElem *other;
+
+
+
+ /* ignore this call if there is no other element */
+
+ if ( other_elems == NULL )
+
+ return;
+
+
+
+ /* save pointer to this information */
+
+ plyfile->other_elems = other_elems;
+
+
+
+ /* describe the other properties of this element */
+
+
+
+ for ( i = 0; i < other_elems->num_elems; i++ )
+
+ {
+
+ other = &( other_elems->other_list[i] );
+
+ element_count_ply ( plyfile, other->elem_name, other->elem_count );
+
+ describe_other_properties_ply ( plyfile, other->other_props,
+
+ offsetof( OtherData,other_props ) );
+
+ }
+
+}
+
+
+
+
+
+
+
+/**** Property Propagation Rules ****/
+
+
+
+
+
+typedef struct RuleName {
+
+int code;
+
+char *name;
+
+} RuleName;
+
+
+
+RuleName rule_name_list[] = {
+
+{AVERAGE_RULE, "avg"},
+
+{RANDOM_RULE, "rnd"},
+
+{MINIMUM_RULE, "max"},
+
+{MAXIMUM_RULE, "min"},
+
+{MAJORITY_RULE, "major"},
+
+{SAME_RULE, "same"},
+
+{-1, "end_marker"},
+
+};
+
+
+
+
+
+
+
+/******************************************************************************
+
+Initialize the property propagation rules for an element. Default is to
+
+use averaging (AVERAGE_RULE) for creating all new properties.
+
+
+
+Entry:
+
+ply - PLY object that this is for
+
+elem_name - name of the element that we're making the rules for
+
+
+
+Exit:
+
+returns pointer to the default rules
+
+******************************************************************************/
+
+
+
+PlyPropRules *init_rule_ply( PlyFile *ply, char *elem_name )
+
+{
+
+ int i,j;
+
+ PlyElement *elem;
+
+ PlyPropRules *rules;
+
+ PlyRuleList *list;
+
+ int found_prop;
+
+
+
+ elem = find_element ( ply, elem_name );
+
+ if ( elem == NULL )
+
+ {
+
+ fprintf ( stderr, "init_rule_ply: Can't find element '%s'\n", elem_name );
+
+ exit ( -1 );
+
+ }
+
+
+
+ rules = ( PlyPropRules * ) myalloc ( sizeof ( PlyPropRules ) );
+
+ rules->elem = elem;
+
+ rules->rule_list = ( int * ) myalloc ( sizeof( int ) * elem->nprops );
+
+ rules->max_props = 0;
+
+ rules->nprops = 0;
+
+
+
+ /* default is to use averaging rule */
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ rules->rule_list[i] = AVERAGE_RULE;
+
+
+
+ /* see if there are other rules we should use */
+
+
+
+ if ( ply->rule_list == NULL )
+
+ return ( rules );
+
+
+
+ /* try to match the element, property && rule name */
+
+
+
+ for ( list = ply->rule_list; list != NULL; list = list->next )
+
+ {
+
+ if ( !equal_strings ( list->element, elem->name ) )
+
+ continue;
+
+
+
+ found_prop = 0;
+
+
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ if ( equal_strings ( list->property, elem->props[i]->name ) )
+
+ {
+
+ found_prop = 1;
+
+
+
+ /* look for matching rule name */
+
+ for ( j = 0; rule_name_list[j].code != -1; j++ )
+
+ if ( equal_strings ( list->name, rule_name_list[j].name ) )
+
+ {
+
+ rules->rule_list[i] = rule_name_list[j].code;
+
+ break;
+
+ }
+
+ }
+
+
+
+ if ( !found_prop )
+
+ {
+
+ fprintf ( stderr, "Can't find property '%s' for rule '%s'\n",
+
+ list->property, list->name );
+
+ continue;
+
+ }
+
+ }
+
+
+
+ return ( rules );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+odify a property propagation rule.
+
+
+
+Entry:
+
+rules - rules for the element
+
+prop_name - name of the property whose rule we're modifying
+
+rule_type - type of rule (MAXIMUM_RULE, MINIMUM_RULE, MAJORITY_RULE, etc.)
+
+******************************************************************************/
+
+
+
+void modify_rule_ply( PlyPropRules *rules, char *prop_name, int rule_type )
+
+{
+
+ int i;
+
+ PlyElement *elem = rules->elem;
+
+
+
+ /* find the property && modify its rule type */
+
+
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ if ( equal_strings ( elem->props[i]->name, prop_name ) )
+
+ {
+
+ rules->rule_list[i] = rule_type;
+
+ return;
+
+ }
+
+
+
+ /* we didn't find the property if we get here */
+
+ fprintf ( stderr, "modify_rule_ply: Can't find property '%s'\n", prop_name );
+
+ exit ( -1 );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Begin to create a set of properties from a set of propagation rules.
+
+
+
+Entry:
+
+ply - PLY object whose rules we're preparing to use
+
+rules - rules for the element
+
+******************************************************************************/
+
+
+
+void start_props_ply( PlyFile *ply, PlyPropRules *rules )
+
+{
+
+ /* PlyElement *elem = rules->elem; */
+
+
+
+ /* save pointer to the rules in the PLY object */
+
+ ply->current_rules = rules;
+
+
+
+ /* get ready for new sets of properties to combine */
+
+ rules->nprops = 0;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Remember a set of properties && their weights for creating a new set of
+
+properties.
+
+
+
+Entry:
+
+weight - weights for this set of properties
+
+other_props - the properties to use
+
+******************************************************************************/
+
+
+
+void weight_props_ply( PlyFile *ply, float weight, void *other_props )
+
+{
+
+ PlyPropRules *rules = ply->current_rules;
+
+
+
+ /* allocate space for properties && weights, if necessary */
+
+ if ( rules->max_props == 0 )
+
+ {
+
+ rules->max_props = 6;
+
+ rules->props = ( void * * ) myalloc ( sizeof ( void * ) * rules->max_props );
+
+ rules->weights = ( float * ) myalloc ( sizeof ( float ) * rules->max_props );
+
+ }
+
+ if ( rules->nprops == rules->max_props )
+
+ {
+
+ rules->max_props *= 2;
+
+ rules->props = ( void * * ) realloc ( rules->props,
+
+ sizeof ( void * ) * rules->max_props );
+
+ rules->weights = ( float * ) realloc ( rules->weights,
+
+ sizeof ( float ) * rules->max_props );
+
+ }
+
+
+
+ /* remember these new properties && their weights */
+
+
+
+ rules->props[rules->nprops] = other_props;
+
+ rules->weights[rules->nprops] = weight;
+
+ rules->nprops++;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Return a pointer to a new set of properties that have been created using
+
+a specified set of property combination rules && a given collection of
+
+"other" properties.
+
+
+
+Exit:
+
+returns a pointer to the new properties
+
+******************************************************************************/
+
+
+
+void *get_new_props_ply( PlyFile *ply )
+
+{
+
+ int i,j;
+
+ static double *vals;
+
+ static int max_vals = 0;
+
+ PlyPropRules *rules = ply->current_rules;
+
+ PlyElement *elem = rules->elem;
+
+ PlyProperty *prop;
+
+ char *data;
+
+ char *new_data;
+
+ void *ptr;
+
+ int offset;
+
+ int type;
+
+ double double_val;
+
+ int int_val;
+
+ unsigned int uint_val;
+
+ int random_pick;
+
+
+
+ /* return NULL if we've got no "other" properties */
+
+ if ( elem->other_size == 0 )
+
+ {
+
+ return ( NULL );
+
+ }
+
+
+
+ /* create room for combined other properties */
+
+ new_data = ( char * ) myalloc ( sizeof ( char ) * elem->other_size );
+
+
+
+ /* make sure there is enough room to store values we're to combine */
+
+
+
+ if ( max_vals == 0 )
+
+ {
+
+ max_vals = rules->nprops;
+
+ vals = ( double * ) myalloc ( sizeof ( double ) * rules->nprops );
+
+ }
+
+ if ( rules->nprops >= max_vals )
+
+ {
+
+ max_vals = rules->nprops;
+
+ vals = ( double * ) realloc ( vals, sizeof ( double ) * rules->nprops );
+
+ }
+
+
+
+ /* in case we need a random choice */
+
+ random_pick = ( int ) floor ( rules->nprops ); //* drand48());
+
+
+
+ /* calculate the combination for each "other" property of the element */
+
+
+
+ for ( i = 0; i < elem->nprops; i++ )
+
+ {
+
+ /* don't bother with properties we've been asked to store explicitly */
+
+ if ( elem->store_prop[i] )
+
+ continue;
+
+
+
+ prop = elem->props[i];
+
+ offset = prop->offset;
+
+ type = prop->external_type;
+
+
+
+ /* collect together all the values we're to combine */
+
+
+
+ for ( j = 0; j < rules->nprops; j++ )
+
+ {
+
+ data = ( char * ) rules->props[j];
+
+ ptr = ( void * ) ( data + offset );
+
+ get_stored_item ( ( void * ) ptr, type, &int_val, &uint_val, &double_val );
+
+ vals[j] = double_val;
+
+ }
+
+
+
+ /* calculate the combined value */
+
+
+
+ switch ( rules->rule_list[i] )
+
+ {
+
+ case AVERAGE_RULE:
+
+ {
+
+ double sum = 0;
+
+ double weight_sum = 0;
+
+ for ( j = 0; j < rules->nprops; j++ )
+
+ {
+
+ sum += vals[j] * rules->weights[j];
+
+ weight_sum += rules->weights[j];
+
+ }
+
+ double_val = sum / weight_sum;
+
+ break;
+
+ }
+
+ case MINIMUM_RULE:
+
+ {
+
+ double_val = vals[0];
+
+ for ( j = 1; j < rules->nprops; j++ )
+
+ if ( double_val > vals[j] )
+
+ double_val = vals[j];
+
+ break;
+
+ }
+
+ case MAXIMUM_RULE:
+
+ {
+
+ double_val = vals[0];
+
+ for ( j = 1; j < rules->nprops; j++ )
+
+ if ( double_val < vals[j] )
+
+ double_val = vals[j];
+
+ break;
+
+ }
+
+ case RANDOM_RULE:
+
+ {
+
+ double_val = vals[random_pick];
+
+ break;
+
+ }
+
+ case SAME_RULE:
+
+ {
+
+ double_val = vals[0];
+
+ for ( j = 1; j < rules->nprops; j++ )
+
+ if ( double_val != vals[j] )
+
+ {
+
+ fprintf ( stderr,
+
+ "get_new_props_ply: Error combining properties that should be the same.\n" );
+
+ exit ( -1 );
+
+ }
+
+ break;
+
+ }
+
+ default:
+
+ fprintf ( stderr, "get_new_props_ply: Bad rule = %d\n",
+
+ rules->rule_list[i] );
+
+ exit ( -1 );
+
+ }
+
+
+
+ /* store the combined value */
+
+
+
+ int_val = ( int ) double_val;
+
+ uint_val = ( unsigned int ) double_val;
+
+ ptr = ( void * ) ( new_data + offset );
+
+ store_item ( ( char * ) ptr, type, int_val, uint_val, double_val );
+
+ }
+
+
+
+ return ( ( void * ) new_data );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Set the list of user-specified property combination rules.
+
+******************************************************************************/
+
+
+
+void set_prop_rules_ply( PlyFile *ply, PlyRuleList *prop_rules )
+
+{
+
+ ply->rule_list = prop_rules;
+
+}
+
+
+
+
+
+/******************************************************************************
+
+Append a property rule to a growing list of user-specified rules.
+
+
+
+Entry:
+
+rule_list - current rule list
+
+name - name of property combination rule
+
+property - "element.property" says which property the rule affects
+
+
+
+Exit:
+
+returns pointer to the new rule list
+
+******************************************************************************/
+
+
+
+PlyRuleList *append_prop_rule( PlyRuleList *rule_list, char *name, char *property )
+
+{
+
+ PlyRuleList *rule;
+
+ PlyRuleList *rule_ptr;
+
+ char *str,*str2;
+
+ char *ptr;
+
+
+
+ /* find . */
+
+ str = strdup ( property );
+
+ for ( ptr = str; *ptr != '\0' && *ptr != '.'; ptr++ )
+
+ ;
+
+
+
+ /* split string at . */
+
+ if ( *ptr == '.' )
+
+ {
+
+ *ptr = '\0';
+
+ str2 = ptr + 1;
+
+ }
+
+ else
+
+ {
+
+ fprintf ( stderr, "Can't find property '%s' for rule '%s'\n",
+
+ property, name );
+
+ return ( rule_list );
+
+ }
+
+
+
+ rule = ( PlyRuleList * ) malloc ( sizeof ( PlyRuleList ) );
+
+ rule->name = name;
+
+ rule->element = str;
+
+ rule->property = str2;
+
+ rule->next = NULL;
+
+
+
+ /* either start rule list || append to it */
+
+
+
+ if ( rule_list == NULL )
+
+ rule_list = rule;
+
+ else
+
+ {
+
+ /* append new rule to current list */
+
+ rule_ptr = rule_list;
+
+ while ( rule_ptr->next != NULL )
+
+ rule_ptr = rule_ptr->next;
+
+ rule_ptr->next = rule;
+
+ }
+
+
+
+ /* return pointer to list */
+
+
+
+ return ( rule_list );
+
+}
+
+
+
+
+
+/******************************************************************************
+
+See if a name matches the name of any property combination rules.
+
+
+
+Entry:
+
+name - name of rule we're trying to match
+
+
+
+Exit:
+
+returns 1 if we find a match, 0 if not
+
+******************************************************************************/
+
+
+
+int matches_rule_name( char *name )
+
+{
+
+ int i;
+
+
+
+ for ( i = 0; rule_name_list[i].code != -1; i++ )
+
+ if ( equal_strings ( rule_name_list[i].name, name ) )
+
+ return ( 1 );
+
+
+
+ return ( 0 );
+
+}
+
+
+
diff --git a/povray.cc b/povray.cc
new file mode 100644
index 0000000..fe44720
--- /dev/null
+++ b/povray.cc
@@ -0,0 +1,616 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "ddwin.h"
+
+#define WIREFRAME 0
+#define STICK 1
+#define CPK 2
+#define BALLANDSTICK 3
+#define BALLANDLINE 4
+
+#define NO_ATOMS 0
+#define SPHERES 1
+#define CPK_SPHERES 2
+#define SCALED_CPK_SPHERES 3
+
+#define NO_BONDS 0
+#define LINES 1
+#define STICKS 2
+
+#define BACKBONE_LINE 0
+#define BACKBONE_STICK 1
+
+#define AROMATIC_RINGS 0
+#define KEKULE 1
+#define AROMATIC_BONDS 2
+
+
+
+string DDWin::POV_bond (ZNBond *bo, bool clippable) {
+ stringstream out;
+ bool vis = get_visible (bo);
+ int ds = get_ds (bo);
+ color col1 = get_color (bo -> GetBeginAtom ());
+ color col2 = get_color (bo -> GetEndAtom ());
+ double vdw1 = get_vdw (bo -> GetBeginAtom ());
+ double vdw2 = get_vdw (bo -> GetEndAtom ());
+ if (vis) {
+
+
+ if (ds != NO_BONDS) {
+ if (ds == STICKS || ds == LINES) {
+ double a0size = vdw1 * *data ->vdw_scale;
+ double a1size = vdw2 * *data ->vdw_scale;
+ float stick_rad = *data ->stick_radius;
+ if (ds == LINES) stick_rad = 0.03f;
+ int order;
+ if (gl->aromatic_display_style==KEKULE) order=bo->GetBondOrder ();
+ else order = bo -> GetBondOrder ();
+ if (order == 1 || order == 4 || order == 5) {
+ vect c1 = get_coordinates(bo->GetBeginAtom ());
+ vect c2 = get_coordinates(bo->GetEndAtom ());
+ out <<POV_stick(c1, c2, col1, col2, stick_rad, a0size, a1size, clippable);
+ }
+ else if (order == 2) {
+ float verts [4][3];
+ gl->compute_double_bond_vertexes (bo, verts);
+
+
+
+
+ float x1 = verts[0][0];
+ float y1 = verts[0][1];
+ float z1 = verts[0][2];
+ float x2 = verts[2][0];
+ float y2 = verts[2][1];
+ float z2 = verts[2][2];
+ out << POV_stick (vect (x1, y1, z1), vect (x2, y2, z2), col1, col2, stick_rad/2, a0size, a1size, clippable );
+ /* out << "merge {"<<endl;
+ out << " sphere {";
+ out << "<"<<x1<<","<<y1<<","<<z1<<">,"<<stick_rad/2<<endl;
+ out << "pigment { "<<POV_color (col1)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+ out << " sphere {";
+ out << "<"<<x2<<","<<y2<<","<<z2<<">,"<<stick_rad/2<<endl;
+ out << "pigment { "<<POV_color (col2)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+ out << " cylinder {"<<endl;
+ out << "<"<<x1<<","<<y1<<","<<z1<<">,";
+ out << "<"<<x2<<","<<y2<<","<<z2<<">,"<<stick_rad/2<<endl;
+
+ float gradx, grady, gradz, dist;
+ gradx = x2 - x1;
+ grady = y2 - y1;
+ gradz = z2 - z1;
+ dist = sqrt (gradx*gradx + grady*grady + gradz*gradz);
+ out << "pigment {gradient <"<< gradx/dist<<","<< grady/dist<<","<< gradz/dist<<">\n color_map {["<<a0size/dist<<" "<<POV_color (col1)<<"] ["<<1-a1size/dist<<" "<<POV_color (col2)<<"]} scale "<<dist<<" translate < "<<x1<<","<<y1<<","<<z1<<">}finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+ out << "no_shadow" << endl;
+ out << "}"<<endl;
+
+
+*/
+ x1 = verts[1][0];
+ y1 = verts[1][1];
+ z1 = verts[1][2];
+ x2 = verts[3][0];
+ y2 = verts[3][1];
+ z2 = verts[3][2];
+ out << POV_stick (vect (x1, y1, z1), vect (x2, y2, z2), col1, col2, stick_rad/2, a0size, a1size, clippable );
+ /*
+ out << "merge {"<<endl;
+ out << " sphere {";
+ out << "<"<<x1<<","<<y1<<","<<z1<<">,"<<stick_rad/2<<endl;
+ out << "pigment { "<<POV_color (col1)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+ out << " sphere {";
+ out << "<"<<x2<<","<<y2<<","<<z2<<">,"<<stick_rad/2<<endl;
+ out << "pigment { "<<POV_color (col2)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+ out << " cylinder {"<<endl;
+ out << "<"<<x1<<","<<y1<<","<<z1<<">,";
+ out << "<"<<x2<<","<<y2<<","<<z2<<">,"<<stick_rad/2<<endl;
+
+// float gradx, grady, gradz, dist;
+ gradx = x2 - x1;
+ grady = y2 - y1;
+ gradz = z2 - z1;
+ dist = sqrt (gradx*gradx + grady*grady + gradz*gradz);
+ out << "pigment {gradient <"<< gradx/dist<<","<< grady/dist<<","<< gradz/dist<<">\n color_map {["<<a0size/dist<<" "<<POV_color (col1)<<"] ["<<1-a1size/dist<<" "<<POV_color (col2)<<"]} scale "<<dist<<" translate < "<<x1<<","<<y1<<","<<z1<<">}finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+ out << "no_shadow" << endl;
+ out << "}"<<endl;
+ */
+
+ }
+
+ }
+ }
+
+ }
+ return out.str ();
+}
+
+string DDWin::POV_stick (vect v1, vect v2, color c1, color c2, float rad, float a0size, float a1size, bool clippable) {
+ stringstream out;
+ out << "merge {"<<endl;
+ out << " sphere {";
+ out << POV_vector (v1)<<","<<rad<<endl;
+ out << "pigment { "<<POV_color (c1)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+ out << " sphere {";
+ out << POV_vector (v2)<<","<<rad<<endl;
+ out << "pigment { "<<POV_color (c2)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+ out << " cylinder {"<<endl;
+ out <<POV_vector (v1)<<","<<POV_vector (v2)<<","<<rad<<endl;
+
+ float gradx, grady, gradz, dist;
+ gradx = v2.x() - v1.x();
+ grady = v2.y() - v1.y();
+ gradz = v2.z() - v1.z();
+ dist = sqrt (gradx*gradx + grady*grady + gradz*gradz);
+ out << "pigment {gradient <"<< gradx/dist<<","<< grady/dist<<","<< gradz/dist<<">\n color_map {["<<a0size/dist<<" "<<POV_color (c1)<<"] ["<<1-a1size/dist<<" "<<POV_color (c2)<<"]} scale "<<dist<<" translate "<< POV_vector (v1)<<"}finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+ out << "no_shadow" << endl;
+ if (clippable) out << "clipped_by { plane <z>0}"<<endl;
+ out << "}"<<endl;
+ return out.str ();
+
+}
+
+
+string DDWin::POV_color (color c) {
+ stringstream out;
+ float r = c.redF ();
+ float g = c.greenF ();
+ float b = c.blueF ();
+ float a = 1.f - c.alphaF ();
+ out <<"color rgbt <"<<r<< ","<<g<<","<<b<<","<<a<<">";
+ return out.str ();
+}
+
+
+string DDWin::POV_vector (vect v) {
+ stringstream out;
+ float x = v.x();
+ float y = v.y();
+ float z = v.z();
+ out << "<"<<x<<","<<y<<","<<z<<"> ";
+ return out.str ();
+
+}
+
+
+string DDWin::POV_atom (Atom *at, bool clippable){
+ stringstream out;
+ bool vis = get_visible (at);
+ int ds = get_ds (at);
+ double vdw = get_vdw (at);
+ color col = get_color (at);
+ if (ds != NO_ATOMS && vis) {
+ float rad;
+ if (ds == CPK_SPHERES) rad = vdw;
+ else if (ds == SCALED_CPK_SPHERES) rad = vdw* *data ->vdw_scale;
+ else rad = 0;
+ vect v = get_coordinates(at);
+ out << "sphere {"<<endl;
+ out << POV_vector (v)<<","<<rad<<endl;
+ out << "pigment { "<< POV_color (col)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30}"<<endl;
+ out << "}"<<endl;
+
+ }
+ return out.str ();
+}
+
+string DDWin::POV_backbone (ZNMolecule *mol, bool clippable){
+ if (get_backbone_display_style (mol) == 2) {
+ Surface *surf = new Surface;
+ gl ->backbone_to_surface (mol, surf);
+ string s = POV_surface(surf, clippable);
+ delete surf;
+ return s;
+ }
+ return "";
+}
+
+
+void DDWin::write_POV_source (string filename) {
+ ofstream *file = new ofstream(filename.c_str());
+ GLint viewport [4];
+
+
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ float width = (float)viewport[2];
+ float height = (float)viewport [3];
+ *file << "//Generated by Zodiac version " <<VERSION<< endl<<endl;
+
+ *file << "#declare Move = transform {matrix <" << endl;
+
+ GLdouble m[16];
+ glGetDoublev(GL_MODELVIEW_MATRIX, m);
+
+ double norm = sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+ *file << "\t\t" << m[0] / norm << ", " << m[1] / norm << ", " << m[2] / norm << "," << endl;
+ // m_[0] = m[0] / norm;
+ // m_[1] = m[1] / norm;
+ // m_[2] = m[2] / norm;
+ norm = sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+ *file << "\t\t" << m[4] / norm << ", " << m[5] / norm << ", " << m[6] / norm << "," << endl;
+
+// m_[3] = m[4] / norm;
+// m_[4] = m[5] / norm;
+// m_[5] = m[6] / norm;
+ norm = sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+ *file << "\t\t" << m[8] / norm << ", " << m[9] / norm << ", " << m[10] / norm << "," << endl;
+
+// m_[6] = m[8] / norm;
+// m_[7] = m[9] / norm;
+// m_[8] = m[10] / norm;
+ *file << "\t\t" << m[12] << ", " << m[13] << ", " << m[14] << endl;
+// m_[9] = m[12];
+// m_[10] = m[13];
+// m_[11] = m[14];
+ *file << "\t\t>" << endl;
+ *file << "\tinverse }" << endl;
+
+
+ // *file << "#declare Backbone_pigment = pigment{ color rgbt <0.2, 0.0, 0.8, 0>}";
+ // *file <<"#declare Backbone_finish = finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 specular 0.8 crand 0.1}"<< endl;
+ // *file << "#declare Backbone_rad = 0.1;"<<endl;
+
+
+
+
+ *file << "camera {" << endl
+ << "\tperspective" << endl
+ << "\tdirection <0.0, 0.0, -1.0>" << endl
+ << "\tright " << width / height << " * x" << endl
+ << "\tangle 83.0" << endl
+ << "\ttransform {Move}}" << endl;
+
+
+ *file << "global_settings { ambient_light rgb <1.3,1.3,1.3> ";
+// *file << "radiosity { brightness 0.6 }";
+ *file <<"}"<<endl<<endl;
+ *file << "background {"<< POV_color (*data -> background_color)<<"}"<<endl;
+ // *file << "camera { location <"<<camerax<<","<<cameray<<","<<cameraz<<"> look_at <"<<lookx<<","<<looky<<","<<lookz<<"> up <"<<upx<<","<<upy<<","<<upz<<"> right <"<<rightx<<","<<righty<<","<<rightz<<">}"<<endl;
+ *file <<"fog { distance 150 "<<POV_color (*data -> background_color)<<"}"<<endl;
+
+
+ *file << "light_source {<0, 0, 0> color rgbt <1.3,1.3,1.3,0.3> transform {Move}}"<<endl<<endl;
+
+ for (unsigned int i=0;i<molecules.size(); i++){
+ ZNMolecule *mol = molecules[i];
+ bool clippable = get_clippable (mol);
+ FOR_BONDS_OF_MOL (b, mol) {
+ *file <<POV_bond (&*b, clippable);
+ }
+ FOR_ATOMS_OF_MOL (a, mol) {
+ *file <<POV_atom (&*a, clippable);
+ }
+ *file << POV_backbone (mol);
+ /* vector<OBRing*>::iterator i;
+ vector<OBRing*> *rlist = (vector<OBRing*>*)mol -> GetData("RingList");
+ for (i = rlist->begin();i != rlist->end();++i) {
+
+ if (gl->aromatic_display_style == AROMATIC_RINGS && (*i) -> IsAromatic ()) {
+ *file <<POV_ring ((*i));
+ }
+ }
+*/
+
+ /* for (unsigned int r=0; r<mol->residues.size(); r++){
+ if (mol->residues[r]->backbone_list.size()>1) {
+ Point a = mol->residues[r]->backbone_list[0];
+ *file << "merge {"<<endl;
+ *file << "sphere {<"<<a.x()<<","<<a.y() <<","<<a.z() <<">,Backbone_rad}"<<endl;
+ for (unsigned int p=0; p<mol->residues[r]->backbone_list.size ()-1; p++) {
+ Point b, c;
+ b = mol->residues[r]->backbone_list[p];
+ c = mol->residues[r]->backbone_list[p+1];
+ *file << "cylinder {<"<<b.x()<<","<<b.y() <<","<<b.z() <<">,<"<<c.x()<<","<<c.y() <<","<<c.z() <<">,Backbone_rad}"<<endl;
+ *file << "sphere {<"<<c.x()<<","<<c.y() <<","<<c.z() <<">,Backbone_rad}"<<endl;
+ }
+ *file << "pigment { Backbone_pigment}"<<endl;
+ *file << "finish { Backbone_finish}"<<endl;
+ *file << "}"<<endl;
+ }
+ } */
+ }
+ for (unsigned int i=0;i<graphical_objects.size(); i++){
+ if (graphical_objects[i] -> is_surface ()) {
+ *file << POV_surface ((Surface *) graphical_objects[i]);
+ }
+ else if (graphical_objects[i] -> is_sphere ()) {
+ *file << POV_sphere ((Sphere *) graphical_objects[i]);
+ }
+ else if (graphical_objects[i] -> is_map ()) {
+ *file << POV_map ((Map *) graphical_objects[i]);
+ }
+ }
+ file->close ();
+
+}
+
+string DDWin::POV_ring (Ring *ring) {
+
+ return 0;
+
+/*
+ stringstream out;
+ vect center, pointO;
+ center = ring -> center;
+ pointO.null ();
+
+ float rad = dist (ring->bonds[0]->GetBeginAtom ()->GetVector (), center) * cos (PI/ring->bonds.size ()) - gl -> aromatic_bond_inter_distance * 2;
+
+ float color_a, angle_b;
+ bool invert_c = false;
+ vect pointA, pointB, pointC;
+ pointC = ring -> center;
+ pointA = subtract (ring->bonds[0]->GetBeginAtom ()->GetVector (), pointC);
+ pointB = subtract (ring->bonds[0]->GetEndAtom ()->GetVector (), pointC);
+ pointC = ring -> center;
+
+ // glTranslatef (pointC[0], pointC[1], pointC[2]);
+ float A, B, C;
+
+ Atom *next_atom, *last_atom;
+ ZNBond *next_b, *last_b;
+ float tot_a, rotaxang=0.f, rangle=0.f;
+ int side = -1;
+ //equation of plane Ax + By + Cz = 0
+
+
+ last_b = ring->bonds[0];
+ last_atom = last_b->GetEndAtom ();
+ tot_a = angle (ring->bonds[0]->GetBeginAtom ()->GetVector (), center, ring->bonds[0]->GetEndAtom ()->GetVector ());
+
+
+
+
+
+
+
+
+ if (!pointA.z() && !pointB.z()) { //all three points on z=0 plane... we're already there
+ vect orang (1.f, 0.f, 0.f);
+ if (pointA.y()>0 && pointB.y()>0) {
+ color_a = angle (pointA, pointO, orang);
+ angle_b = angle (pointB, pointO, orang);
+ if (angle_b>color_a) invert_c = true;
+ color_a*=-1;
+ }
+ else if (pointA.y()<0 && pointB.y()<0) {
+ color_a = angle (pointA, pointO, orang);
+ angle_b = angle (pointB, pointO, orang);
+ if (angle_b<color_a) invert_c = true;
+ }
+ else if (pointA.y()>0 && pointB.y()<0) {
+ color_a = -angle (pointA, pointO, orang);
+ if (pointA.x()<0) invert_c = true;
+ }
+ else {
+ color_a = angle (pointA, pointO, orang);
+ if (pointA.x()>0) invert_c = true;
+ }
+
+ }
+ else if (pointA.x() && pointB.x() && (pointA.y()*pointB.x()-pointA.x()*pointB.y())){
+ //equation (A/C)*x + (B/C)*y +z = 0
+ C = 1;
+ B = (pointA.x()*pointB.z()-pointB.x()*pointA.z())/(pointA.y()*pointB.x()-pointA.x()*pointB.y());
+ A = (-pointA.z()-B*pointA.y())/pointA.x();
+
+ //rotation axis A*x + B*y
+
+
+
+ if (B) {
+ vect fixpoint (1.f, -A/B, 0.f);
+
+
+ if (pointA.y()>=-A/B*pointA.x() && pointB.y()>=-A/B*pointB.x()) {
+ color_a = angle (pointA, pointO, fixpoint);
+ angle_b = angle (pointB, pointO, fixpoint);
+ if (angle_b>color_a) invert_c = true;
+ color_a*=-1;
+ cout <<"case 1"<<endl;
+ }
+ else if (pointA.y()<-A/B*pointA.x() && pointB.y()<-A/B*pointB.x()) {
+ color_a = angle (pointA, pointO, fixpoint);
+ angle_b = angle (pointB, pointO, fixpoint);
+ if (angle_b<color_a) invert_c = true;
+ cout <<"case 2"<<endl;
+ }
+ else if (pointA.y()>=-A/B*pointA.x() && pointB.y()<-A/B*pointB.x()) {
+ color_a = -angle (pointA, pointO, fixpoint);
+ cout <<"case 3"<<endl;
+ if (pointA.y()<pointA.x()*B/(A+0.001)) invert_c = true;
+ }
+ else if (pointA.y()<-A/B*pointA.x() && pointB.y()>=-A/B*pointB.x()){
+ color_a = angle (pointA, pointO, fixpoint);
+ if (pointA.y()>=pointA.x()*B/(A+0.001)) invert_c = true;
+ cout <<"case 4"<<endl;
+ }
+
+
+
+ if ((pointA.z()>0 && pointA.y()>-A/B*pointA.x()) || (pointA.z()<0 && pointA.y()<-A/B*pointA.x())) side = -1;
+ else side = 1;
+
+
+ float d = sqrt (1+(-A/B)*(-A/B));
+ rotaxang = asin ((-A/B)/d);
+ ///// if (rotaxang<0) rotaxang= PI-rotaxang;
+
+ }
+
+ //perpendicular aA + bB = 0
+
+
+ //perpendicular -B*x + A*y = 0
+ //point x=1 y=B/A
+ //point on the plane z= -(A + B*B/A)
+ float xp, yp, zp;
+ xp = 1;
+ yp = B/A;
+ zp = -(A + B*B/A);
+
+ float dist = sqrt(xp*xp+ yp*yp+zp*zp);
+
+ rangle = asin (zp / dist);
+
+ if (rangle<0) {
+ rangle = -rangle;
+
+ }
+
+
+
+
+
+
+ }
+
+
+
+
+
+
+ out <<"torus {\n";
+ out <<rad<<", "<<gl->stick_rad/2<<endl;
+ out<<"rotate <90,0,0>"<<endl;
+ out<<"rotate <0,0,"<<-rotaxang*180/PI<<">"<<endl;
+
+ out <<"pigment { radial \n color_map { "<<endl;
+
+
+ out <<"[ 0 "<< POV_color (ring -> bonds[0] -> GetBeginAtom () -> col) <<"]"<<endl;
+
+ out <<"[ "<<tot_a/360<<" "<<POV_color (ring -> bonds[0] -> GetEndAtom () ->col)<<"]"<<endl;
+
+ for (unsigned int i=0; i<ring->bonds.size ()-2; i++) {
+ for (unsigned int b=0; b<last_atom->bonds.size (); b++) {
+ next_b = last_atom->bonds[b];
+ if (next_b->is_in_ring (ring) && next_b!=last_b) break;
+ }
+ if (next_b->GetBeginAtom ()!= last_atom) next_atom = next_b->GetBeginAtom ();
+ else next_atom = next_b->GetEndAtom ();
+
+ tot_a += angle (last_atom->GetVector (), center, next_atom->GetVector ());
+ out <<"[ "<<tot_a/360<<" "<<POV_color (next_atom ->col)<<"]"<<endl;
+
+ last_atom = next_atom;
+ }
+
+ out <<"[ 1 color rgb <1,1,0>]"<<endl;
+ out << "}"<<endl;
+ out<<"rotate <90,0,0>"<<endl;
+ if (invert_c) out<<"rotate <180,0,0>"<<endl;
+ out<<"rotate <0,0,"<<-color_a <<">"<<endl;
+ out << "}"<<endl;
+
+
+ out<<"rotate <"<<-rangle*side*180/PI<<",0,0>"<<endl;
+ out<<"rotate <0,0,"<<rotaxang*180/PI<<">"<<endl;
+
+ out<<"translate < "<<ring->center.x()<<","<<ring->center.y()<<","<<ring->center.z()<<">"<<endl;
+ out <<"}"<<endl<<endl;
+ return out.str ();
+*/
+}
+
+
+
+string DDWin::POV_surface (Surface *surf, bool clippable) {
+ if (!surf->vertices.size ()) return "";
+ stringstream out;
+ out << "mesh2 {\n" <<endl;
+ out << " vertex_vectors {"<<endl;
+ out << surf->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<surf->vertices.size (); i++) {
+
+ out <<"<"<<surf->vertices[i]->GetVector ().x()<<","<<surf->vertices[i]->GetVector ().y()<<","<<surf->vertices[i]->GetVector ().z()<<">,"<<endl;
+ }
+ out <<"}"<<endl;
+ out << " normal_vectors {"<<endl;
+ out << surf->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<surf->vertices.size (); i++) {
+ out <<"<"<<surf->vertices[i]->normal.x()<<","<<surf->vertices[i]->normal.y()<<","<<surf->vertices[i]->normal.z()<<">,"<<endl;
+ }
+ out <<"}"<<endl;
+ out <<" texture_list {"<<endl;
+ out << surf->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<surf->vertices.size (); i++) {
+ out <<"texture {pigment {"<<POV_color (surf -> vertices[i] ->col)<<endl;
+ out<<"}finish {ambient 0.1 diffuse 0.8 phong 0.1 phong_size 30 }}"<<endl;
+ }
+ out <<"}"<<endl;
+ out << " face_indices {"<<endl;
+ out << surf->faces.size ()<<", "<<endl;
+ for (unsigned int i=0; i<surf->faces.size (); i++) {
+ out <<"<"<<surf->faces[i]->v1->n<<","<<surf->faces[i]->v2->n<<","<<surf->faces[i]->v3->n<<">,"<<surf->faces[i]->v1->n<<","<<surf->faces[i]->v2->n<<","<<surf->faces[i]->v3->n<<","<<endl;
+ }
+ out <<"}"<<endl;
+ out <<"}"<<endl;
+ return out.str ();
+}
+
+string DDWin::POV_map (Map *map, bool clippable) {
+
+ stringstream out;
+ out << "mesh2 {\n" <<endl;
+ out << " vertex_vectors {"<<endl;
+ out << map->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<map->vertices.size (); i++) {
+
+ out <<POV_vector (map->vertices[i]->GetVector ()) <<endl;
+ }
+ out <<"}"<<endl;
+ out << " normal_vectors {"<<endl;
+ out << map->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<map->vertices.size (); i++) {
+ out <<POV_vector (map->vertices[i]->normal)<<endl;
+ }
+ out <<"}"<<endl;
+ out <<" texture_list {"<<endl;
+ out << map->vertices.size ()<<", "<<endl;
+ for (unsigned int i=0; i<map->vertices.size (); i++) {
+ out <<"texture {pigment {"<<POV_color (map -> vertices[i] ->col)<<endl;
+ out<<"}finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+ }
+ out <<"}"<<endl;
+ out << " face_indices {"<<endl;
+ out << map->faces.size ()<<", "<<endl;
+ for (unsigned int i=0; i<map->faces.size (); i++) {
+ out <<"<"<<map->faces[i]->v1->n<<","<<map->faces[i]->v2->n<<","<<map->faces[i]->v3->n<<">,"<<map->faces[i]->v1->n<<","<<map->faces[i]->v2->n<<","<<map->faces[i]->v3->n<<","<<endl;
+ }
+ out <<"}"<<endl;
+ out <<"}"<<endl;
+ return out.str ();
+}
+
+
+string DDWin::POV_sphere (Sphere *sphere, bool clippable) {
+
+ stringstream out;
+ out << " sphere {";
+ out << POV_vector (sphere -> center)<<","<< sphere->radius << endl;
+ out << "pigment { "<<POV_color (sphere -> col)<<"} finish {ambient 0.1 diffuse 0.7 phong 0.3 phong_size 30 }}"<<endl;
+
+
+ return out.str ();
+}
diff --git a/resources.qrc b/resources.qrc
new file mode 100644
index 0000000..af77e3b
--- /dev/null
+++ b/resources.qrc
@@ -0,0 +1,22 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>icons/undo.png</file>
+ <file>icons/redo.png</file>
+ <file>parameters/MMFF93SUP.PAR</file>
+ <file>parameters/MMFFANG.PAR</file>
+ <file>parameters/MMFFAROM.PAR</file>
+ <file>parameters/MMFFBNDK.PAR</file>
+ <file>parameters/MMFFBOND.PAR</file>
+ <file>parameters/MMFFCHG.PAR</file>
+ <file>parameters/MMFFDEF.PAR</file>
+ <file>parameters/MMFFDFSB.PAR</file>
+ <file>parameters/MMFFHDEF.PAR</file>
+ <file>parameters/MMFFOOP.PAR</file>
+ <file>parameters/MMFFPBCI.PAR</file>
+ <file>parameters/MMFFPROP.PAR</file>
+ <file>parameters/MMFFSTBN.PAR</file>
+ <file>parameters/MMFFSYMB.PAR</file>
+ <file>parameters/MMFFTOR.PAR</file>
+ <file>parameters/MMFFVDW.PAR</file>
+ </qresource>
+ </RCC>
diff --git a/thread.cc b/thread.cc
new file mode 100644
index 0000000..c71cbef
--- /dev/null
+++ b/thread.cc
@@ -0,0 +1,1462 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#include "thread.h"
+#ifdef HAPTICS
+#include <HD/hd.h>
+#endif// HAPTICS
+
+
+float anti_gravity = 2.0;
+
+
+Thread::Thread (QObject *parent) : QThread (parent), is_running (true), _name ("Thread"), _doing ("running"), _min_step (0), _max_step (0), _current_step (0){}
+
+void Thread::stop () {
+ is_running = false;
+}
+
+
+MapThread::MapThread (QObject *parent, Map *mp, DDWin *ddw): Thread (parent) {
+ ddwin = ddw;
+ map = mp;
+ _name = "Computing map values";
+}
+
+
+void MapThread::run () {
+ compute_map_data ();
+}
+
+
+void MapThread::compute_map_data () {
+ _doing = "computing map";
+ MarchingCubes *cube;
+ if (!map ->cube) {
+ map ->cube = new MarchingCubes ();
+ cube = map ->cube;
+ float res = map ->resolution;
+
+
+
+ Chemscore *chemscore = new Chemscore;
+ ZNMolecule *mol = new ZNMolecule;
+ chemscore ->load_environment (ddwin ->molecules, mol);
+
+
+
+
+
+ int xm, ym, zm;
+
+
+ float x, y, z;
+
+ float xmin, ymin, zmin, xmax, ymax, zmax;
+
+
+ // find_limits (map ->molecule);
+
+
+ vect c = map ->site_center;
+ float r = map ->site_radius;
+
+ xmin = c.x() -r ;
+ ymin = c.y() -r ;
+ zmin = c.z() -r ;
+
+ xmax = c.x() +r ;
+ ymax = c.y() +r ;
+ zmax = c.z() +r ;
+
+
+
+
+
+ if ((xmin < xmax) && (ymin < ymax) && (zmin < zmax)) {
+ /* xmin -= distance;
+ ymin -= distance;
+ zmin -= distance;
+ xmax += distance;
+ ymax += distance;
+ zmax += distance;*/
+
+ xm = (int)((xmax-xmin)* res);
+ ym = (int)((ymax-ymin)* res);
+ zm = (int)((zmax-zmin)* res);
+ // cout <<xm<<" "<<ym<<" "<<zm<<endl;
+
+
+ cube->set_resolution( xm, ym, zm) ;
+ cube->set_method (false); //use original MC algo?
+ cube->set_limits (xmin, ymin, zmin, xmax, ymax, zmax);
+ cube->init_all() ;
+ _max_step = zm -1;
+ for (unsigned int k=0; k<zm; k++) {
+ _current_step = k;
+ z = cube->to_real_z (k);
+ for (unsigned int j=0; j<ym; j++) {
+ y = cube->to_real_y (j);
+ for (unsigned int i=0; i<xm; i++) {
+
+ x = cube->to_real_x (i);
+ vect p (x, y, z);
+ float value;
+ switch (map ->type) {
+ case 0:
+ value = chemscore -> Clvalue (p) + chemscore ->Livalue (p);
+ break;
+ case 1:
+ value = chemscore -> Clvalue (p) + chemscore ->Acceptorvalue (p);
+ break;
+ case 2:
+ value = chemscore -> Clvalue (p) + chemscore ->Donorvalue (p);
+ break;
+ case 3:
+ value = chemscore ->Electrostatic_potential (p);
+ break;
+ default:
+ value = chemscore -> Clvalue (p) + chemscore ->Livalue (p);
+ break;
+ }
+ // cerr << value << endl;
+ cube->set_data(value, i, j, k );
+ }
+ }
+ }
+ }
+ }
+ else { cube = map ->cube;}
+ cube->run(map ->threshold, &_current_step, &_max_step) ;
+
+
+ _doing = "finalising";
+ _max_step = 0;
+ int count = 0;
+ map -> clean ();
+ for (unsigned int i=0; i<cube->ntrigs (); i++) {
+ int n1, n2, n3;
+ n1 = cube->trig(i)->v1;
+ n2 = cube->trig(i)->v2;
+ n3 = cube->trig(i)->v3;
+
+
+ bool accept = true;
+ float x1 = cube->to_real_x (cube->vert(n1)->x);
+ float y1 = cube->to_real_y (cube->vert(n1)->y);
+ float z1 = cube->to_real_z (cube->vert(n1)->z);
+
+ float x2 = cube->to_real_x (cube->vert(n2)->x);
+ float y2 = cube->to_real_y (cube->vert(n2)->y);
+ float z2 = cube->to_real_z (cube->vert(n2)->z);
+
+ float x3 = cube->to_real_x (cube->vert(n3)->x);
+ float y3 = cube->to_real_y (cube->vert(n3)->y);
+ float z3 = cube->to_real_z (cube->vert(n3)->z);
+
+
+
+
+ if (accept) {
+ SurfFace *face = new SurfFace;
+
+ SurfVertex *vert1 = new SurfVertex;
+ vert1->n = count*3;
+ vert1->normal.x() = cube->vert (n1)->nx;
+ vert1->normal.y() = cube->vert (n1)->ny;
+ vert1->normal.z() = cube->vert (n1)->nz;
+ vert1->coordinates.x() = x1;
+ vert1->coordinates.y() = y1;
+ vert1->coordinates.z() = z1;
+ vert1 ->col = map ->solid_color;
+ map->vertices.push_back (vert1);
+
+ SurfVertex *vert2 = new SurfVertex;
+ vert2->n = count*3+1;
+ vert2->normal.x() = cube->vert (n2)->nx;
+ vert2->normal.y() = cube->vert (n2)->ny;
+ vert2->normal.z() = cube->vert (n2)->nz;
+ vert2->coordinates.x() = x2;
+ vert2->coordinates.y() = y2;
+ vert2->coordinates.z() = z2;
+ vert2 ->col = map ->solid_color;
+ map->vertices.push_back (vert2);
+
+ SurfVertex *vert3 = new SurfVertex;
+ vert3->n = count*3+2;
+ vert3->normal.x() = cube->vert (n3)->nx;
+ vert3->normal.y() = cube->vert (n3)->ny;
+ vert3->normal.z() = cube->vert (n3)->nz;
+ vert3->coordinates.x() = x3;
+ vert3->coordinates.y() = y3;
+ vert3->coordinates.z() = z3;
+ vert3 ->col = map ->solid_color;
+ map->vertices.push_back (vert3);
+
+
+ face->v1 = vert1;
+ face->v2 = vert2;
+ face->v3 = vert3;
+
+ map->faces.push_back (face);
+ count ++;
+ }
+ }
+ // surface->color_by_atom (alph);
+
+
+
+ cube ->clean_mesh ();
+ cube ->init_mesh ();
+
+
+}
+
+
+
+SurfaceThread::SurfaceThread (QObject *parent, Surface *surf, DDWin *ddw): Thread (parent) {
+ _name = "Computing molecular surface";
+ ddwin = ddw;
+ surface = surf;
+ alph = 1.f;
+ res = 1.f;
+}
+
+
+
+
+void SurfaceThread::run() {
+ compute_surface_data ();
+
+}
+
+
+
+
+void SurfaceThread::compute_surface_data () {
+ _doing = "computing surface";
+ bool near_bool = true;
+ if ((! surface ->near_to )|| (surface ->near_to == surface ->molecule)) near_bool = false;
+ cutoffGrid<Atom*> *grid = surface -> grid;
+ MarchingCubes *cube = new MarchingCubes ();
+
+
+
+ int xm, ym, zm;
+
+
+ float x, y, z;
+ float rad = 1.4f;
+ float threshold = rad;
+ float xmin, ymin, zmin, xmax, ymax, zmax;
+
+ float distance = 4.f;
+ if (surface ->near_to_dist > distance) distance = surface ->near_to_dist;
+ float ratio = 1; //grid resolution ratio between cube2 && cube
+ find_limits (surface ->molecule);
+
+
+ if (near_bool) {
+ find_limits (surface ->near_to);
+ vect min_c = get_min_corner(surface -> molecule);
+ vect min_c1 = get_min_corner(surface -> near_to);
+ if (min_c.x() > min_c1.x()) xmin = min_c.x();
+ else xmin = min_c1.x();
+
+ if (min_c.y() > min_c1.y()) ymin = min_c.y();
+ else ymin = min_c1.y();
+
+ if (min_c.z() > min_c1.z()) zmin = min_c.z();
+ else zmin = min_c1.z();
+
+
+ vect max_c = get_max_corner(surface -> molecule);
+ vect max_c1 = get_max_corner(surface -> near_to);
+
+ if (max_c.x() < max_c1.x()) xmax = max_c.x();
+ else xmax = max_c1.x();
+
+ if (max_c.y() < max_c1.y()) ymax = max_c.y();
+ else ymax = max_c1.y();
+
+ if (max_c.z() < max_c1.z()) zmax = max_c.z();
+ else zmax = max_c1.z();
+
+
+
+ }
+ else {
+ vect min_c = get_min_corner(surface ->molecule);
+ vect max_c = get_max_corner(surface ->molecule);
+ xmin = min_c.x();
+ ymin = min_c.y();
+ zmin = min_c.z();
+
+ xmax = max_c.x();
+ ymax = max_c.y();
+ zmax = max_c.z();
+
+ }
+
+ xmin -= distance;
+ ymin -= distance;
+ zmin -= distance;
+ xmax += distance;
+ ymax += distance;
+ zmax += distance;
+
+ if ((xmin < xmax) && (ymin < ymax) && (zmin < zmax)) {
+
+
+
+ xm = (int)((xmax-xmin)* res/ratio);
+ ym = (int)((ymax-ymin)* res/ratio);
+ zm = (int)((zmax-zmin)* res/ratio);
+ // cout <<xm<<" "<<ym<<" "<<zm<<endl;
+
+
+ cube->set_resolution( xm, ym, zm) ;
+ cube->set_method (false); //use original MC algo?
+ cube->set_limits (xmin, ymin, zmin, xmax, ymax, zmax);
+ cube->init_all() ;
+ for (unsigned int k=0; k<zm; k++) {
+ z = cube->to_real_z (k);
+ for (unsigned int j=0; j<ym; j++) {
+ y = cube->to_real_y (j);
+ for (unsigned int i=0; i<xm; i++) {
+ float value = 1000;
+ x = cube->to_real_x (i);
+ vect p (x, y, z);
+ objectList<Atom*>* nbAtoms = grid->getNeighborObjects(p);
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int a =0; a<neighbours.size (); a++) {
+ double vdw = etab.GetVdwRad (neighbours[a] -> GetAtomicNum ());
+ float dis = subtract (get_coordinates (neighbours[a]), p).module () - vdw;
+ if ( dis < value) {
+ value = dis;
+ }
+ }
+ }
+ cube->set_data(value, i, j, k );
+ }
+ }
+ }
+
+ cube->run(threshold, &_current_step, &_max_step) ;
+
+
+
+ _max_step = 0;
+
+ MarchingCubes *cube2 = new MarchingCubes ();
+ vector<SurfVertex*> myverts;
+ for (unsigned int i=0; i<cube->nverts (); i++) {
+ SurfVertex *vert = new SurfVertex;
+ vert->coordinates.x() = cube->to_real_x (cube->vert (i)->x);
+ vert->coordinates.y() = cube->to_real_y (cube->vert (i)->y);
+ vert->coordinates.z() = cube->to_real_z (cube->vert (i)->z);;
+ myverts.push_back (vert);
+ }
+ // cube->clean_all() ;
+ cutoffGrid<SurfVertex*>* vgrid = new cutoffGrid<SurfVertex*>(myverts, 2);
+
+
+ int xm2= (int)((xmax-xmin)* res);
+ int ym2 = (int)((ymax-ymin)* res);
+ int zm2 = (int)((zmax-zmin)* res);
+
+ cube2->set_resolution( xm2, ym2, zm2 ) ;
+ cube2->set_method (false); //use original MC algo?
+ cube2->set_limits (xmin, ymin, zmin, xmax, ymax, zmax);
+ cube2->init_all() ;
+ _max_step = zm2 -1;
+ for (unsigned int k=0; k<zm2; k++) {
+ _current_step = k;
+ z = cube2->to_real_z (k);
+ for (unsigned int j=0; j<ym2; j++) {
+ y = cube2->to_real_y (j);
+ for (unsigned int i=0; i<xm2; i++) {
+ x = cube2->to_real_x (i);
+ float value = 1000;
+
+ vect p (x, y, z);
+ objectList<SurfVertex*>* nbAtoms = vgrid->getNeighborObjects(p);
+ if (cube->get_data (cube->to_cube_i(x),cube->to_cube_j(y), cube->to_cube_k(z))>threshold+0.1) value =0.;
+ else {
+ if (nbAtoms) {
+ vector <SurfVertex *> neighbours = nbAtoms->objects;
+ for (unsigned int a =0; a<neighbours.size (); a++) {
+ float dis = subtract (get_coordinates (neighbours[a]), p).module ();
+ if ( dis < value) {
+ value = dis;
+ }
+ }
+ }
+ }
+ // if (value<1.4) cout << value<<endl;
+ cube2->set_data(value, i, j, k );
+ }
+ }
+ }
+
+ cube2->run(threshold, &_current_step, &_max_step) ;
+ _doing = "finalising";
+ int count = 0;
+ for (unsigned int i=0; i<cube2->ntrigs (); i++) {
+ int n1, n2, n3;
+ n1 = cube2->trig(i)->v1;
+ n2 = cube2->trig(i)->v2;
+ n3 = cube2->trig(i)->v3;
+
+ float dist_f = surface -> near_to_dist;
+ bool accept = false;
+ float x1 = cube2->to_real_x (cube2->vert(n1)->x);
+ float y1 = cube2->to_real_y (cube2->vert(n1)->y);
+ float z1 = cube2->to_real_z (cube2->vert(n1)->z);
+
+ float x2 = cube2->to_real_x (cube2->vert(n2)->x);
+ float y2 = cube2->to_real_y (cube2->vert(n2)->y);
+ float z2 = cube2->to_real_z (cube2->vert(n2)->z);
+
+ float x3 = cube2->to_real_x (cube2->vert(n3)->x);
+ float y3 = cube2->to_real_y (cube2->vert(n3)->y);
+ float z3 = cube2->to_real_z (cube2->vert(n3)->z);
+
+ if (!near_bool) {accept = true;}
+ else {
+
+
+ float xm = (x1 +x2+x3) / 3;
+ float ym = (y1 +y2+y3) / 3;
+ float zm = (z1 +z2+z3) / 3;
+ vect p (xm, ym, zm);
+
+ objectList<Atom*>* nbAtoms = surface -> near_to_grid->getNeighborObjects(p);
+ if (nbAtoms) {
+ vector <Atom *> neighbours = nbAtoms->objects;
+ for (unsigned int a =0; a<neighbours.size (); a++) {
+ vect v1 = get_coordinates (neighbours[a]);
+ double dis_c = dist (v1, p);
+ // cerr << dis_c <<" "<<v1<<" "<<p<< endl;
+ if ( dis_c < dist_f) {
+ accept = true;
+ break;
+ }
+ }
+ }
+ else cerr << "no neighbours" << endl;
+ }
+ if (accept) {
+ SurfFace *face = new SurfFace;
+
+ SurfVertex *vert1 = new SurfVertex;
+ vert1->n = count*3;
+ vert1->normal.x() = cube2->vert (n1)->nx;
+ vert1->normal.y() = cube2->vert (n1)->ny;
+ vert1->normal.z() = cube2->vert (n1)->nz;
+ vert1->coordinates.x() = x1;
+ vert1->coordinates.y() = y1;
+ vert1->coordinates.z() = z1;
+ surface->vertices.push_back (vert1);
+
+ SurfVertex *vert2 = new SurfVertex;
+ vert2->n = count*3+1;
+ vert2->normal.x() = cube2->vert (n2)->nx;
+ vert2->normal.y() = cube2->vert (n2)->ny;
+ vert2->normal.z() = cube2->vert (n2)->nz;
+ vert2->coordinates.x() = x2;
+ vert2->coordinates.y() = y2;
+ vert2->coordinates.z() = z2;
+ surface->vertices.push_back (vert2);
+
+ SurfVertex *vert3 = new SurfVertex;
+ vert3->n = count*3+2;
+ vert3->normal.x() = cube2->vert (n3)->nx;
+ vert3->normal.y() = cube2->vert (n3)->ny;
+ vert3->normal.z() = cube2->vert (n3)->nz;
+ vert3->coordinates.x() = x3;
+ vert3->coordinates.y() = y3;
+ vert3->coordinates.z() = z3;
+ surface->vertices.push_back (vert3);
+
+ // cout << cube2->trig(i)->v1<<endl;
+
+ face->v1 = vert1;
+ face->v2 = vert2;
+ face->v3 = vert3;
+
+ surface->faces.push_back (face);
+ count ++;
+ }
+ }
+ color c (1., 1., 1., alph);
+ surface->color_by_color (c);
+ for (unsigned int ii=0; ii<myverts.size (); ii++) {
+ delete myverts[ii];
+ }
+ cube->clean_all() ;
+ cube2->clean_all();
+ // cerr << "faces " << surface->faces.size () << endl;
+ }
+ else cerr << "molecules do not overlap" << endl;
+
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SystematicConformationThread::SystematicConformationThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw) : Thread (parent), ddwin (ddw), molecule (mol), database (dat) {
+ _name = "systematic conformational search";
+}
+
+void SystematicConformationThread::run () {
+ int nstep = 10;
+ vector <double> dihedrals = get_dihedrals (molecule);
+ if (dihedrals.size ()) generate_conformation (dihedrals, 0);
+}
+
+
+
+void SystematicConformationThread::generate_conformation (vector <double> &dofs, int level) {
+ int nstep = 10;
+ for (unsigned int i = 0; i < nstep; i ++) {
+ dofs[level] = M_PI/nstep*2*i;
+ if (level < dofs.size ()-1) {
+ generate_conformation (dofs, level+1);
+ }
+ else {
+ set_dihedrals (molecule, dofs);
+ Database_molecule *new_mol = new Database_molecule (*molecule);
+ database ->safe_add_mol (new_mol);
+ }
+ }
+
+}
+
+
+
+StochasticConformationThread::StochasticConformationThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw) : Thread (parent), ddwin (ddw), database (dat), molecule (mol), _results_number (10), _time_limit (60) {
+ _name = "stochastic conformational search";
+ _doing = "exploring conformational space";
+}
+
+void StochasticConformationThread::run () {
+ build_kinematic_chain(molecule);
+ Minimize *min = new Minimize (ddwin ->data);
+ min ->set_molecule (molecule);
+ min ->internal_ff ->initialize_internal (molecule, ddwin ->molecules);
+
+ min ->interaction_ffs[0] ->initialize_interaction (molecule, ddwin ->molecules);
+
+ ScoreMolecule *function = new ScoreMolecule (min, false);
+
+ PSO *optimiser = new PSO (function);
+ // ILS *optimiser = new ILS (function);
+ optimiser ->set_time_limit (_time_limit);
+
+ optimiser ->run ();
+
+ vector <conformation *> confs = optimiser ->get_results ();
+ int limit = _results_number;
+ if (confs.size () < _results_number) limit = confs.size ();
+ for (unsigned int i = 0; i < limit; i++) {
+ build_molecule_from_dofs (molecule, confs[i] ->state);
+ Database_molecule *new_mol = new Database_molecule (*molecule);
+ database ->safe_add_mol (new_mol);
+ }
+
+}
+
+DockingThread::DockingThread (QObject *parent, ZNMolecule *mol, Database *dat, DDWin *ddw) : Thread (parent), ddwin (ddw), database (dat), molecule (mol), _results_number (10), _time_limit (60),
+_bindingsite_radius (10), _bindingsite_center (vect (0., 0., 0.)){
+ _name = "molecular docking";
+}
+
+void DockingThread::run () {
+ MMFF *mmff = new MMFF;
+ Chemscore *chemscore = new Chemscore;
+ build_kinematic_chain(molecule);
+ Minimize *min = new Minimize (ddwin ->data, mmff, chemscore);
+ min ->set_molecule (molecule);
+ min ->internal_ff ->initialize_internal (molecule, ddwin ->molecules);
+ min ->interaction_ffs[0] ->initialize_interaction (molecule, ddwin ->molecules, _bindingsite_center, _bindingsite_radius);
+ ScoreMolecule *function = new ScoreMolecule (min, true, _bindingsite_center, _bindingsite_radius);
+ // ILS *optimiser = new ILS (function);
+ PSO *optimiser = new PSO (function);
+ optimiser ->set_time_limit (_time_limit);
+ optimiser ->set_iteration_limit(0);
+ msleep (10);
+ optimiser ->run ();
+ vector <conformation *> confs = optimiser ->get_results ();
+ int limit = _results_number;
+ if (confs.size () < _results_number) limit = confs.size ();
+ for (unsigned int i = 0; i < limit; i++) {
+ build_molecule_from_dofs (molecule, confs[i] ->state, true);
+ Database_molecule *new_mol = new Database_molecule (*molecule);
+ ddwin ->set_lists (new_mol);
+ database ->safe_add_mol (new_mol);
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+MinimiseThread::MinimiseThread (QObject *parent, DDWin *ddw) : Thread (parent){
+ _name = "energy minimisation";
+ ddwin = ddw;
+
+ molecule = NULL;
+
+
+}
+
+void MinimiseThread::run () {
+ // cerr << "minimise" << endl;
+ assert (molecule);
+
+ OBForceField *ff;
+ ff = OBForceField::FindForceField( "MMFF94s" );
+ assert (ff);
+ ff -> Setup (*molecule);
+ ff -> SteepestDescentInitialize ();
+ while (ff -> SteepestDescentTakeNSteps(10)) {
+ // ff -> ConjugateGradientsInitialize ();
+ // while (ff -> ConjugateGradientsTakeNSteps(1)) {
+
+ ff -> GetCoordinates (*molecule);
+ ddwin -> gl -> draw_molecule (molecule);
+ }
+ /*
+ MMFF ff;
+ ff.clear_internal_interactions ();
+ ff.clear_nonbonded_interactions ();
+ ff.initialize (molecule, ddwin -> molecules);
+
+ bool converged = false;
+ int iterations = 0;
+ float last_E = 0.f;
+ while (!converged && iterations < MAX_ITERATIONS) {
+ iterations ++;
+ ff.update ();
+ ff.compute_forces ();
+ FOR_ATOMS_OF_MOL(a, molecule) {
+ flush_forces (&*a);
+ }
+ ddwin -> data-> minimize -> apply_forces (molecule, 500.f);
+
+ float this_E = ff.compute_total_energy ();
+
+ if (last_E-this_E<MIN_ENERGY) converged = true;
+ if (iterations < 5) {
+ converged = false;
+ }
+ if (last_E-this_E<0) {
+ converged = false;
+ }
+ last_E = this_E;
+
+ set_needs_redraw (molecule, true);
+ // if (converged || iterations > MAX_ITERATIONS) {
+ // ddwin -> data -> minimize ->deinitialise_minimisation ();
+ // }
+ }
+ */
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+DatabaseMinimiseThread::DatabaseMinimiseThread (QObject *parent, Database *dat, DDWin *ddw) : Thread (parent) {
+ _name = "database energy minimisation";
+ ddwin = ddw;
+ database = dat;
+}
+
+
+void DatabaseMinimiseThread::run () {
+ ddwin -> data -> undo_stack -> beginMacro ("Database Minimisation");
+ _max_step = database -> count_entries () -1;
+ for (unsigned int i=0; i<database -> count_entries (); i++) {
+ _current_step = i;
+ ZNMolecule *mol = database -> get_molecule (i);
+ ddwin -> data -> undo_stack -> beginMacro ("Energy Minimisation");
+ MoveAtomsCommand *command = new MoveAtomsCommand (ddwin -> gl, 1);
+ FOR_ATOMS_OF_MOL(a, mol) {
+ command -> add (&*a, get_coordinates(&*a));
+ }
+ ddwin -> execute (command);
+
+ MinimiseThread *thread = new MinimiseThread (0, ddwin);
+ thread -> set_molecule (mol);
+ thread -> start ();
+ thread -> wait ();
+ delete thread;
+ ddwin -> end_minimisation ();
+ }
+ ddwin -> data -> undo_stack -> endMacro ();
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
+HapticForceThread::HapticForceThread (QObject *parent, DDWin *ddw) : Thread (parent) {
+ ddwin = ddw;
+
+}
+
+void HapticForceThread::run () {
+
+ while (is_running) {
+
+ haptic_callback ((void *) ddwin ->data);
+ msleep (1);
+
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+
+
+
+HapticThread::HapticThread (QObject *parent, DDWin *ddw) : Thread (parent){
+ last_is_user_selected = false;
+ _name = "continuous minimisation";
+ number_of_threads = 1;
+ ddwin = ddw;
+ is_running = true;
+ save_result = false;
+ saving = false;
+ is_worse = false;
+ user_save_result = false;
+ save_E_threshold = 1000.f;
+ mult = 1.f;
+
+ connect (this, SIGNAL (ask_color_by_score (ZNMolecule *)), ddwin, SLOT (recolor_by_score (ZNMolecule *)));
+
+ haptic_dof_mode = 1;
+ molecule = NULL;
+ results = NULL;
+ automove = true;
+ color_by_score = false;
+ next_atom_to_check = 0;
+ number_of_atoms = 0;
+ internal_interaction_counter = 0;
+ //need to load internal interactions first
+}
+
+
+void HapticThread::initialise (Minimize *min) {
+ ncycles = 0;
+ worker_threads.clear ();
+ internal_interactions.clear ();
+
+ ddwin -> vertex_list.clear ();
+ Hbonds.clear ();
+ atoms.clear ();
+ number_of_threads = min -> haptic_number_of_threads;
+ haptic_dof_mode = min -> haptic_dof_mode;
+ set_molecule (min -> haptic_molecule);
+ results = new Database;
+ vector <double> v;
+ results -> safe_add_field ("Energy", v);
+ FOR_ATOMS_OF_MOL (a, molecule) {
+ atoms.push_back (&*a);
+ }
+ number_of_atoms = atoms.size ();
+}
+
+
+void HapticThread::stop () {
+ for (unsigned int i=0; i< worker_threads.size (); i++) {
+ worker_threads [i] -> stop ();
+ }
+ terminate ();
+}
+
+void HapticThread::run () {
+
+ minimise = ddwin -> data -> minimize;
+ if (haptic_dof_mode != 0) {
+ minimise -> internal_ff ->load_internal_interactions (&internal_interactions);
+ }
+ if (number_of_threads < 1) number_of_threads = 1;
+ if (number_of_threads == 1) {
+ HapticWorkerThread *single_thread = new HapticWorkerThread (this, 1, HapticWorkerThread::SINGLE);
+ single_thread -> start ();
+ worker_threads.push_back (single_thread);
+ }
+ else {
+ HapticWorkerThread *internal_thread = new HapticWorkerThread (this, 1, HapticWorkerThread::INTERNAL);
+ internal_thread -> start ();
+ worker_threads.push_back (internal_thread);
+ for (int i = 1; i < number_of_threads; i++) {
+ HapticWorkerThread *worker_thread = new HapticWorkerThread (this, i, HapticWorkerThread::INTERACTION);
+ worker_thread -> start ();
+ worker_threads.push_back (worker_thread);
+ }
+ }
+ worker_threads[0] ->wait ();
+
+}
+
+
+
+
+HapticWorkerThread::HapticWorkerThread (HapticThread *ht, int i, HapticWorkerType t) : Thread (0) {
+ master = ht;
+ number = i;
+ thread_type = t;
+}
+
+void HapticWorkerThread::run () {
+ while (is_running) {
+ master ->automove = master ->ddwin -> haptic_menu ->automove_b;
+ master ->color_by_score = master ->ddwin ->haptic_menu ->color_by_score_b;
+ master ->mult = master ->ddwin ->haptic_menu ->mult;
+ if (thread_type == INTERNAL) {
+ for (unsigned int i = 0; i < master -> internal_interactions.size (); i++) {
+ master -> compute_internal_interaction (i);
+ }
+ // master ->compute_one_internal_interaction ();
+ }
+ else if (thread_type == INTERACTION) {
+ for (unsigned int a = 0; a < master ->atoms.size (); a++) {
+ master ->compute_nonbonded_interactions_for_atom (a);
+ }
+ master -> end_of_cycle ();
+ }
+ else if (thread_type == SINGLE) {
+
+//#pragma omp parallel sections
+
+
+{
+ if (master -> haptic_dof_mode != 0) {
+//#pragma omp for
+ for (unsigned int i = 0; i < master -> internal_interactions.size (); i++) {
+ master -> compute_internal_interaction (i);
+ }
+ }
+//#pragma omp section
+{
+//#pragma omp for
+ for (unsigned int a = 0; a < master ->atoms.size (); a++) {
+ master ->compute_nonbonded_interactions_for_atom (a);
+ }
+}
+//#pragma omp section
+{
+ master ->ddwin ->haptic_menu ->restrain_lock ->lockForRead ();
+ for (unsigned int r = 0; r < master ->ddwin ->haptic_menu ->restrains.size (); r++) {
+ master ->compute_restrain (r);
+ }
+ master ->ddwin ->haptic_menu ->restrain_lock ->unlock ();
+}
+}
+ master -> end_of_cycle ();
+ }
+
+
+ /*
+ if (master -> is_end_of_cycle ()) {
+ // cout << "Thread "<<number<<" end of cycle" << endl;
+ master ->end_of_cycle ();
+
+ }
+ else if (master ->have_to_work_on_internal_interactions ()) {
+ // cout << "Thread "<<number<<" one internal interaction" << endl;
+ master ->compute_one_internal_interaction ();
+
+ }
+ else if (master ->have_to_work_on_nonbonded_interactions ()) {
+ // cout << "Thread "<<number<<" one nonbonded interaction" << endl;
+ master ->compute_one_nonbonded_interaction ();
+
+ }
+ else {
+ // cout << "Thread "<<number<<" new atom" << endl;
+ master ->load_interactions_for_new_atom ();
+
+
+ }
+ */
+ }
+}
+
+
+bool HapticThread::is_end_of_cycle () {
+ if (have_to_work_on_nonbonded_interactions () || !are_atoms_finished ()) return false;
+ else return true;
+}
+
+bool HapticThread::have_to_work_on_nonbonded_interactions () {
+ if (nonbonded_interactions.size () == 0) return false;
+ else return true;
+}
+
+bool HapticThread::have_to_work_on_internal_interactions () {
+ if (internal_interactions.size () <= internal_interaction_counter) return false;
+ else return true;
+}
+
+bool HapticThread::are_atoms_finished () {
+ // cerr << next_atom_to_check<<" "<<number_of_atoms<<endl;
+ if (next_atom_to_check >= number_of_atoms) return true;
+ else return false;
+}
+
+
+void HapticThread::end_of_cycle () {
+ ncycles++;
+ next_atom_to_check = 0;
+ internal_interaction_counter = 0;
+ saving = ddwin ->haptic_menu ->saving;
+ if (haptic_dof_mode == 1) {
+ if (!automove) {
+ vector<Atom*> alist;
+ find_center (molecule);
+ vect cent = get_center (molecule);
+ FOR_ATOMS_OF_MOL (a, molecule) {
+ vect vec = get_coordinates (&*a);
+ vec = subtract (vec, cent);
+ vec = sum (vec, last_center);
+ set_coordinates (&*a, vec);
+ }
+
+
+ }
+ else {
+ last_center = get_center (molecule);
+ }
+ }
+ else if (haptic_dof_mode == 0) {
+
+ if (automove) {
+ vect total_force (0., 0., 0.);
+ FOR_ATOMS_OF_MOL (a, molecule) {
+ vect force = get_force (&*a);
+ total_force = sum (total_force, force);
+ }
+ total_force.trunc_at(200);
+ total_force.multiply(0.001f);
+ ddwin -> gl ->translate_molecule(molecule, total_force);
+ }
+
+ }
+ if (color_by_score) {
+ vector <color_mask> masks;
+ color_mask mask;
+ mask.intensity = 1.0f;
+ mask.only_to = 0;
+ mask.excluding = 0;
+ mask.type = 2; //score //see menu.cc
+ masks.push_back (mask);
+ if (!(molecule -> needs_recolor)) {
+ molecule -> needs_recolor = true;
+ ask_color_by_score (molecule);
+ }
+ }
+ ddwin -> Hbonds = Hbonds;
+ double energy_threshold = 0.;
+ FOR_ATOMS_OF_MOL (a, molecule) {
+ double score = get_score (&*a);
+
+ total_energy += score;
+ }
+ ddwin ->data ->total_energy_haptic = total_energy;
+ if (save_result && saving) {
+ bool save = true;
+ if (results ->count_entries()) {
+ if (!last_is_user_selected) {
+ ZNMolecule *last_mol = results ->get_molecule(results ->count_entries()-1);
+ float RMSD = very_fast_RMSD(molecule, last_mol);
+ if (RMSD < ddwin ->haptic_menu ->cluster_RMSD) {
+ if (is_worse) {
+ save = false;
+ }
+ else results -> delete_entry (results ->count_entries()-1);
+ }
+ }
+ }
+ if (save) {
+ last_is_user_selected = false;
+ Database_molecule *new_mol = new Database_molecule (*molecule);
+ ddwin ->set_lists (new_mol);
+ results ->add_mol (new_mol);
+ results ->set_double (1, results ->count_entries () -1, total_energy);
+ }
+ }
+ if (user_save_result) {
+ Database_molecule *new_mol = new Database_molecule (*molecule);
+ ddwin ->set_lists (new_mol);
+ new_mol ->SetTitle("USER mol");
+ results ->add_mol (new_mol);
+ results ->set_double (1, results ->count_entries () -1, total_energy);
+ last_is_user_selected = true;
+ }
+ save_result = false;
+ is_worse = false;
+ user_save_result = false;
+ //if (total_energy < energy_threshold) {
+ // if (ddwin ->vertex_list.size ()) {
+ // vect c = get_center(molecule);
+ // if (c != ddwin ->vertex_list[ddwin ->vertex_list.size ()-1])
+ // ddwin -> vertex_list.push_back (c);
+ // }
+ // else ddwin -> vertex_list.push_back (get_center (molecule));
+ //}
+ Hbonds.clear ();
+ total_energy = 0.;
+
+ if (haptic_dof_mode == 0) {
+ quaternion quat = axis_angle_to_quaternion(total_torque, total_torque.module()*0.001);
+ rotate_molecule(molecule, quat, get_center (molecule));
+ total_torque = vect (0., 0., 0.);
+
+ }
+
+#ifdef HAPTICS
+ vect haptic_force (0., 0., 0.), actual_force (0., 0., 0.);
+ FOR_ATOMS_OF_MOL (a, molecule) {
+
+ vect force = get_force (&*a);
+ haptic_force = sum (haptic_force, force);
+ }
+ //ddwin->gl->world_to_haptic_coordinates (haptic_force, actual_force, -5, 5, -5, 5, -5, 5);
+ haptic_force = ddwin ->gl ->deapply_world_rotation (haptic_force);
+ //cerr << haptic_force << haptic_force.module ()<< endl;
+ haptic_force.trunc_at (100.);
+ /*
+ viscous_force_x.push_back (haptic_force.x());
+ viscous_force_y.push_back (haptic_force.y());
+ viscous_force_z.push_back (haptic_force.z());
+ int viscosity = 6;
+ while (viscous_force_x.size () > viscosity) {
+ viscous_force_x.erase (viscous_force_x.begin ());
+ viscous_force_y.erase (viscous_force_y.begin ());
+ viscous_force_z.erase (viscous_force_z.begin ());
+ }
+ float x = 0.f;
+ float y = 0.f;
+ float z = 0.f;
+ for (unsigned int i = 0; i < viscous_force_x.size (); i++) {
+ x += viscous_force_x[i];
+ y += viscous_force_y[i];
+ z += viscous_force_z[i];
+ }
+ x /= viscous_force_x.size();
+ y /= viscous_force_y.size();
+ z /= viscous_force_z.size();
+ */
+
+ //temporary
+
+#ifdef IANS_HACK
+ ddwin ->data ->current_force_x=x / 20.0f *mult;
+ ddwin ->data ->current_force_y=y / 20.0f *mult;
+ ddwin ->data ->current_force_z=z / 20.0f *mult;
+#else // IANS_HACK
+ double dBlendFactor = 0.1;
+ ddwin->data->current_force_x = ((1.0-dBlendFactor)*ddwin->data->current_force_x) + (dBlendFactor*(haptic_force.x()/20.0f*mult));
+ ddwin->data->current_force_y = ((1.0-dBlendFactor)*ddwin->data->current_force_y) + (dBlendFactor*(haptic_force.y()/20.0f*mult));
+ ddwin->data->current_force_z = ((1.0-dBlendFactor)*ddwin->data->current_force_z) + (dBlendFactor*(haptic_force.z()/20.0f*mult));
+#endif // IANS_HACK
+
+ // cerr << "current force "<<current_force[0]<<" "<<current_force[1]<<" "<<current_force[2]<<endl;
+
+ // hduVector3Dd force (haptic_force.x() / 5.0f, haptic_force.y() / 5.0f, haptic_force.z() / 5.0f );
+ // hdSetDoublev(HD_CURRENT_FORCE, force);
+
+ /* gHaptics.setForce(
+ haptic_force.x() / 5.0f,
+ haptic_force.y() / 5.0f + anti_gravity,
+ haptic_force.z() / 5.0f
+
+
+ =======
+ gHaptics.setForce(
+ haptic_force.x() / 10.0f,
+ haptic_force.y() / 10.0f + anti_gravity,
+ haptic_force.z() / 10.0f
+ >>>>>>> 1.23
+ );
+ */
+ minimise -> update_molecule_position_with_haptic_pointer (molecule);
+
+#endif //HAPTICS
+
+ QTime curr_time = QTime::currentTime ();
+ stringstream ss;
+ int msecs = last_time.msecsTo (curr_time);
+ if (msecs > 10000) {
+ cerr << ncycles / 10 << " fps; ";
+ cerr << ddwin -> gl ->redraw_counter / 10 << " graphics updates; ";
+
+ cerr << endl;
+ last_time = curr_time;
+ ncycles = 0;
+ ddwin -> gl ->redraw_counter = 0;
+
+
+ }
+ set_needs_redraw(molecule, true);
+}
+
+void HapticThread::end_of_calculation_for_atom (Atom *at) {
+ const float maxforce = 200.0f;
+ flush_forces (at);
+ flush_scores (at);
+ if (haptic_dof_mode == 0) {
+ vect tor;
+ tor = torque (get_force(at), get_coordinates(at), get_center (molecule));
+ total_torque = sum (tor, total_torque);
+ }
+ else minimise ->apply_force_to_atom (at, maxforce);
+}
+
+void HapticThread::compute_restrain (int i) {
+ ddwin ->haptic_menu ->restrains[i] ->set_forces ();
+}
+
+void HapticThread::compute_internal_interaction (int i) {
+ internal_interactions[i] ->set_forces ();
+}
+
+void HapticThread::compute_nonbonded_interactions_for_atom (int a) {
+ queue <ForceFieldInteraction *> interactions;
+ Atom *atom = atoms [a];
+ for (unsigned int i = 0; i < minimise ->interaction_ffs.size (); i++) {
+ minimise ->interaction_ffs[i] ->load_nonbonded_interactions_for_atom (atom, &interactions);
+ while (interactions.size()) {
+ ForceFieldInteraction *interaction = interactions.front ();
+ interactions.pop ();
+ // if (interaction ->isElectrostatic ()) interaction ->set_forces (true);
+ // else
+
+
+ interaction ->set_forces (true);
+
+ if (interaction -> isHbond ()) {
+ vect v1 = get_coordinates (interaction ->at1);
+ vect v2 = get_coordinates (interaction ->at2);
+ float dis = dist (v1, v2);
+ float ref_dis = 2.2f;
+ // float ref_dis = 1.85f;
+ float ref_delta = 0.4f;
+ if ( dis < (ref_delta + ref_dis)) {
+ double perc = 0.;
+ if (dis < ref_dis) perc = 1.;
+ else {
+ float dd = dis - ref_dis;
+ perc = 1- (dd/0.4);
+ }
+ HBond hb;
+ hb.v1 = v1;
+ hb.v2 = v2;
+
+ hb.perc = perc;
+ Hbonds.push_back (hb);
+ }
+ }
+
+ delete interaction;
+ }
+ }
+ end_of_calculation_for_atom (atom);
+}
+
+
+void HapticThread::compute_one_internal_interaction () {
+ ForceFieldInteraction *interaction = 0;
+ // internal_interactions_mutex.lock ();
+ if (internal_interaction_counter < internal_interactions.size ()) {
+ interaction = internal_interactions[internal_interaction_counter];
+ internal_interaction_counter ++;
+ }
+ // internal_interactions_mutex.unlock ();
+ if (interaction) interaction ->set_forces ();
+}
+
+void HapticThread::compute_one_nonbonded_interaction () {
+ nonbonded_interactions_mutex.lock ();
+ ForceFieldInteraction *interaction = nonbonded_interactions.front ();
+ nonbonded_interactions.pop ();
+ nonbonded_interactions_mutex.unlock ();
+ if (interaction ->isElectrostatic ()) interaction ->set_forces (true);
+ else interaction ->set_forces (true);
+ if (interaction -> isHbond ()) {
+ vect v1 = get_coordinates (interaction ->at1);
+ vect v2 = get_coordinates (interaction ->at2);
+ float dis = dist (v1, v2);
+ float ref_dis = 2.2f;
+ // float ref_dis = 1.85f;
+ float ref_delta = 0.4f;
+ if ( dis < (ref_delta + ref_dis)) {
+ double perc = 0.;
+ if (dis < ref_dis) perc = 1.;
+ else {
+ float dd = dis - ref_dis;
+ perc = 1- (dd/0.4);
+ }
+ HBond hb;
+ hb.v1 = v1;
+ hb.v2 = v2;
+
+ hb.perc = perc;
+ Hbonds.push_back (hb);
+ }
+ }
+
+ // delete interaction;
+
+
+}
+
+
+void HapticThread::load_interactions_for_new_atom () {
+ atoms_mutex.lock ();
+ int n = next_atom_to_check;
+ if (n < number_of_atoms) {
+ Atom *atom = atoms [n];
+ next_atom_to_check++;
+ atoms_mutex.unlock ();
+ for (unsigned int i = 0; i < minimise ->interaction_ffs.size (); i++) {
+ minimise ->interaction_ffs[i] ->load_nonbonded_interactions_for_atom (atom, &nonbonded_interactions);
+ }
+ if (n) end_of_calculation_for_atom (atoms [n-1]);
+ }
+ else atoms_mutex.unlock ();
+}
+
+
+
+
+GridThread::GridThread (QObject *parent, Grid *gri, DDWin *ddw) : Thread (parent) {
+ _name = "grid generation";
+ ddwin = ddw;
+ grid = gri;
+
+}
+
+
+void GridThread::run () {
+ grid -> load ();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+
+HeadTrackingThread::HeadTrackingThread (QObject *parent, DDWin *ddw) : Thread (parent) {
+ ddwin = ddw;
+ // lastx = lasty = 500;
+ connect (this, SIGNAL (head_moved (int, int)), ddwin -> gl, SLOT (head_tracking_update (int, int)));
+
+}
+
+
+void HeadTrackingThread::run () {
+
+
+ wiimote = init_wiimote (wiimote);
+
+
+ while (true) {
+ vector <int> x, y;
+ get_IR_data (wiimote, x, y);
+
+ // if (x.size () == 1) {
+ // int currx = x[0];
+ // int curry = y[0];
+ // if (!ddwin -> gl -> needs_GL_update) {
+ // ddwin -> gl -> needs_GL_update = true;
+ // head_moved (currx-500, curry-500);
+ // }
+ // }
+ /*else*/ if (x.size () == 2) {
+ int currx = (x[0] + x[1]) * 0.5;
+ int curry = (y[0] + y[1]) * 0.5;
+ if (!ddwin -> gl -> needs_GL_update) {
+ ddwin -> gl -> needs_GL_update = true;
+ head_moved (currx-500, curry-500);
+ }
+ }
+
+ msleep (10);
+ }
+
+ if (is_wiimote_closed (wiimote)) {
+ fprintf(stderr, "Error on wiimote disconnect\n");
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+WiimoteTrackingThread::WiimoteTrackingThread (QObject *parent, DDWin *ddw) : Thread (parent) {
+ ddwin = ddw;
+ lastx = lasty = 500;
+ lastd = 400;
+ connect (this, SIGNAL (move_target (float, float, float)), ddwin -> gl, SLOT (move_target (float, float, float)));
+ connect (this, SIGNAL (move_camera (float, float, float)), ddwin -> gl, SLOT (move_camera (float, float, float)));
+ connect (this, SIGNAL (rotate_world (double, double, double, double, double, double)), ddwin -> gl, SLOT (map_vector_on_vector_world (double, double, double, double, double, double)));
+ connect (this, SIGNAL (rotate_target (double, double, double, double, double, double)), ddwin -> gl, SLOT (map_vector_on_vector_target (double, double, double, double, double, double)));
+ is_moving = false;
+ is_rotating = false;
+
+}
+
+
+void WiimoteTrackingThread::run () {
+ float scale = 0.01f;
+ float scale2 = 0.05f;
+ wiimote = init_wiimote (wiimote);
+
+
+ //switch_to_mode (1);
+
+
+ while (true) {
+ poll (wiimote);
+
+ vector <int> x, y;
+ get_IR_data (wiimote, x, y);
+ vect current_orientation = get_Acc_data (wiimote);
+
+
+
+
+ bool a = is_A_pressed (wiimote);
+ bool b = is_B_pressed (wiimote);
+ bool one = is_1_pressed (wiimote);
+ bool two = is_2_pressed (wiimote);
+
+
+ if (one) {
+ cerr << "one" << endl;
+ switch_to_mode (1);
+ }
+ else if (two) {
+ switch_to_mode (2);
+ }
+
+ if (mode == 1) {
+ if (x.size () == 2) {
+ if (a && !is_moving) {
+ is_moving = true;
+ lastx = (float (x[0] + x[1])) * 0.5;
+ lasty = (float (y[0] + y[1])) * 0.5;
+ lastd = (x[1] -x[0]) * (x[1] -x[0]) + (y[1] -y[0]) * (y[1] -y[0]);
+
+ }
+ else if ((!a) && is_moving) {
+ is_moving = false;
+ }
+ else if (a && is_moving) {
+ float currx = (float (x[0] + x[1])) * 0.5;
+ float curry = (float (y[0] + y[1])) * 0.5;
+ float currd = (x[1] -x[0]) * (x[1] -x[0]) + (y[1] -y[0]) * (y[1] -y[0]);
+ if (!ddwin -> gl -> needs_GL_update) {
+ ddwin -> gl -> needs_GL_update = true;
+ move_camera (-(currx-lastx)*scale, -(curry-lasty)*scale, -(currd-lastd)*scale*scale2);
+ lastx = currx;
+ lasty = curry;
+ lastd = currd;
+ }
+ }
+
+ }
+ if (b) {
+ cerr << "b"<<endl;
+ double x2 = current_orientation.x();
+ double z2 = -current_orientation.y();
+ double y2 = current_orientation.z();
+ double x1 = last_orientation.x();
+ double z1 = -last_orientation.y();
+ double y1 = last_orientation.z();
+
+ if (is_rotating) {rotate_world (x1, y1, z1, x2, y2, z2);}
+ else is_rotating = true;
+ last_orientation = current_orientation;
+ }
+ else is_rotating = false;
+
+ }
+ else if (mode == 2) {
+ if (b) {
+ double x2 = current_orientation.x();
+ double z2 = -current_orientation.y();
+ double y2 = current_orientation.z();
+ double x1 = last_orientation.x();
+ double z1 = -last_orientation.y();
+ double y1 = last_orientation.z();
+
+ if (is_rotating) {rotate_target (x1, y1, z1, x2, y2, z2);}
+ else is_rotating = true;
+ last_orientation = current_orientation;
+ }
+ else if (a) {
+ if (x.size () == 2) {
+ float currx = (float (x[0] + x[1])) * 0.5;
+ float curry = (float (y[0] + y[1])) * 0.5;
+ float currd = (x[1] -x[0]) * (x[1] -x[0]) + (y[1] -y[0]) * (y[1] -y[0]);
+ if (is_moving) {move_target (-(currx-lastx)*scale, -(curry-lasty)*scale, -(currd-lastd)*scale*scale2);}
+ else is_moving = true;
+ lastx = currx;
+ lasty = curry;
+ lastd = currd;
+ }
+ }
+ else {
+ is_rotating = false;
+ is_moving = false;
+ }
+ }
+
+
+ msleep (100);
+ }
+
+
+ if (is_wiimote_closed(wiimote)) {
+ fprintf(stderr, "Error on wiimote disconnect\n");
+ }
+
+}
+
+
+void WiimoteTrackingThread::switch_to_mode (int i) {
+ switch (i) {
+ case 1:
+ mode = 1;
+ switch_led (wiimote, 1, true);
+ switch_led (wiimote, 2, false);
+ break;
+ case 2:
+ mode = 2;
+ switch_led (wiimote, 2, true);
+ switch_led (wiimote, 1, false);
+ break;
+ }
+
+}
+
diff --git a/wiimote.cc b/wiimote.cc
new file mode 100644
index 0000000..c4e6292
--- /dev/null
+++ b/wiimote.cc
@@ -0,0 +1,322 @@
+/* Zodiac - molecular modelling environment. www.zeden.org
+ Copyright (C) 2008 Nicola Zonta (nicola.zonta(at)zeden.org)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "wiimote.h"
+
+
+#ifdef CWIID
+
+//cwiid_mesg_callback_t cwiid_callback;
+
+#define toggle_bit(bf,b) \
+ (bf) = ((bf) & b) \
+ ? ((bf) & ~(b)) \
+ : ((bf) | (b))
+
+
+void set_rumble (Wiimote *wiimote, bool b) {}
+
+void set_led_state(Wiimote *wiimote, unsigned char led_state);
+void set_rpt_mode(Wiimote *wiimote, unsigned char rpt_mode);
+void print_state(struct cwiid_state *state);
+
+cwiid_err_t err;
+void err(Wiimote *wiimote, const char *s, va_list ap)
+{
+ if (wiimote) printf("%d:", cwiid_get_id(wiimote));
+ else printf("-1:");
+ vprintf(s, ap);
+ printf("\n");
+}
+
+
+Wiimote *init_wiimote (Wiimote *wiimote) {
+ bdaddr_t bdaddr; /* bluetooth device address */
+ unsigned char mesg = 0;
+ unsigned char led_state = 0;
+ unsigned char rpt_mode = 0;
+ unsigned char rumble = 0;
+ int exit = 0;
+
+ cwiid_set_err(err);
+
+ /* Connect to address given on command-line, if present */
+
+ bdaddr = *BDADDR_ANY;
+
+
+ /* Connect to the wiimote */
+ printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
+ if (!(wiimote = cwiid_open(&bdaddr, 0))) {
+ fprintf(stderr, "Unable to connect to wiimote\n");
+ return NULL;
+ }
+// cerr << wiimote << endl;
+
+
+ //turns IR on
+ toggle_bit(rpt_mode, CWIID_RPT_IR);
+ set_rpt_mode(wiimote, rpt_mode);
+
+ //turns ACC on
+ toggle_bit(rpt_mode, CWIID_RPT_ACC);
+ set_rpt_mode(wiimote, rpt_mode);
+
+
+ //enable button reporting
+ toggle_bit(rpt_mode, CWIID_RPT_BTN);
+ set_rpt_mode(wiimote, rpt_mode);
+
+
+ toggle_bit(led_state, CWIID_LED1_ON);
+ set_led_state(wiimote, led_state);
+ return wiimote;
+}
+
+
+void get_IR_data (Wiimote *wiimote, vector <int> &x, vector <int> &y) {
+ struct cwiid_state state; /* wiimote state */
+ vector <int> xx;
+ vector <int> yy;
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+ for (unsigned int i = 0; i < CWIID_IR_SRC_COUNT; i++) {
+ if (state.ir_src[i].valid) {
+ xx.push_back (state.ir_src[i].pos[CWIID_X]);
+ yy.push_back (state.ir_src[i].pos[CWIID_Y]);
+ }
+ }
+
+ x = xx;
+ y = yy;
+}
+
+
+vect get_Acc_data (Wiimote *wiimote) {
+ struct cwiid_state state; /* wiimote state */
+ vector <int> xx;
+ vector <int> yy;
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+ vect out (state.acc[CWIID_X]-125, state.acc[CWIID_Y]-125, state.acc[CWIID_Z]-125);
+ return out;
+}
+
+bool is_A_pressed (Wiimote *wiimote) {
+ struct cwiid_state state; /* wiimote state */
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+
+// cerr << state.buttons << endl;
+ return (state.buttons == CWIID_BTN_A);
+}
+
+
+bool is_1_pressed (Wiimote *wiimote) {
+ struct cwiid_state state; /* wiimote state */
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+
+// cerr << state.buttons << endl;
+ return (state.buttons == CWIID_BTN_1);
+}
+
+
+bool is_2_pressed (Wiimote *wiimote) {
+ struct cwiid_state state; /* wiimote state */
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+
+// cerr << state.buttons << endl;
+ return (state.buttons == CWIID_BTN_2);
+}
+
+
+
+bool is_B_pressed (Wiimote *wiimote) {
+ struct cwiid_state state; /* wiimote state */
+ if (cwiid_get_state(wiimote, &state)) {
+ fprintf(stderr, "Error getting state\n");
+ }
+
+// cerr << state.buttons << endl;
+ return (state.buttons == CWIID_BTN_B);
+}
+
+
+
+void set_led_state (Wiimote *wiimote, unsigned int n) {
+ unsigned char state;
+ switch (n) {
+ case 1:
+ state = CWIID_LED1_ON;
+ break;
+ case 2:
+ state = CWIID_LED2_ON;
+ break;
+ case 3:
+ state = CWIID_LED3_ON;
+ break;
+ case 4:
+ state = CWIID_LED4_ON;
+ break;
+ default:
+ state = CWIID_LED1_ON;
+ break;
+ }
+ unsigned char led_state;
+ toggle_bit(led_state, state);
+ set_led_state(wiimote, led_state);
+
+}
+
+void set_led_state(Wiimote *wiimote, unsigned char led_state)
+{
+ if (cwiid_set_led(wiimote, led_state)) {
+ fprintf(stderr, "Error setting LEDs \n");
+ }
+}
+
+void switch_led (Wiimote *wiimote, unsigned int n, bool on) {}
+
+void set_rpt_mode(Wiimote *wiimote, unsigned char rpt_mode)
+{
+ if (cwiid_set_rpt_mode(wiimote, rpt_mode)) {
+ fprintf(stderr, "Error setting report mode\n");
+ }
+}
+
+bool is_wiimote_closed (Wiimote *wiimote) {
+ return cwiid_close (wiimote);
+}
+
+void poll (Wiimote *wiimote) {};
+
+#elif WIIUSE
+
+void set_rumble (Wiimote *wiimote, bool b) {
+ wiiuse_rumble (wiimote, b);
+}
+
+void switch_led (Wiimote *wiimote, unsigned int n, bool on) {
+ switch (n) {
+ case 1:
+ wiiuse_set_leds(wiimote, WIIMOTE_LED_1);
+ break;
+ case 2:
+ wiiuse_set_leds(wiimote, WIIMOTE_LED_2);
+ break;
+ case 3:
+ wiiuse_set_leds(wiimote, WIIMOTE_LED_3);
+ break;
+ case 4:
+ wiiuse_set_leds(wiimote, WIIMOTE_LED_4);
+ break;
+
+ }
+}
+void get_IR_data (Wiimote *wiimote, vector <int> &x, vector <int> &y) {
+ vector <int> xx, yy;
+ int i = 0;
+
+
+
+ /* go through each of the 4 possible IR sources */
+
+ for (; i < 4; ++i) {
+
+ /* check if the source is visible */
+
+ if (wiimote->ir.dot[i].visible) {
+ xx.push_back (wiimote->ir.dot[i].x);
+ yy.push_back (wiimote->ir.dot[i].y);
+
+
+
+ }
+ }
+ x = xx;
+ y = yy;
+
+}
+
+vect get_Acc_data (Wiimote *wiimote){
+ float roll = wiimote ->orient.roll;
+ float pitch = wiimote ->orient.pitch;
+ float yaw = wiimote ->orient.yaw;
+ return vect (roll, pitch, yaw);
+}
+bool is_A_pressed (Wiimote *wiimote) {return IS_HELD(wiimote, WIIMOTE_BUTTON_A);}
+bool is_B_pressed (Wiimote *wiimote) {return IS_HELD(wiimote, WIIMOTE_BUTTON_B);}
+bool is_1_pressed (Wiimote *wiimote) {return IS_HELD(wiimote, WIIMOTE_BUTTON_ONE);}
+bool is_2_pressed (Wiimote *wiimote) {return IS_HELD(wiimote, WIIMOTE_BUTTON_TWO);}
+bool is_wiimote_closed (Wiimote *wiimote) {return true;};
+
+Wiimote *init_wiimote (Wiimote *wiimote) {
+ Wiimote **wiimotes = wiiuse_init(1);
+ int found = wiiuse_find(wiimotes, 1, 5);
+ if (found) {
+ int connected = wiiuse_connect(wiimotes, 1);
+
+ if (connected) {
+ Wiimote *wiimote = wiimotes[0];
+ wiiuse_motion_sensing (wiimote, 1);
+ return wiimote;
+ }
+ else { return 0;}
+ }
+
+ else {
+
+ printf("Failed to connect to any wiimote.\n");
+
+ return 0;
+ }
+
+};
+
+
+void poll (Wiimote *wiimote) {
+ Wiimote *wiimotes [1];
+ wiimotes [0] = wiimote;
+ wiiuse_poll (wiimotes, 1);
+};
+
+#else //CWIID
+
+void switch_led (Wiimote *wiimote, unsigned int n, bool on) {}
+void get_IR_data (Wiimote *wiimote, vector <int> &x, vector <int> &y) {}
+vect get_Acc_data (Wiimote *wiimote){return vect ();};
+bool is_A_pressed (Wiimote *wiimote) {return false;}
+bool is_B_pressed (Wiimote *wiimote) {return false;}
+bool is_1_pressed (Wiimote *wiimote) {return false;}
+bool is_2_pressed (Wiimote *wiimote) {return false;}
+bool is_wiimote_closed (Wiimote *wiimote) {return true;};
+Wiimote *init_wiimote (Wiimote *wiimote) {return 0;};
+void poll (Wiimote *wiimote) {};
+void set_rumble (Wiimote *wiimote, bool b) {};
+
+#endif //CWIID
diff --git a/win_rc.rc b/win_rc.rc
new file mode 100644
index 0000000..516e6e9
--- /dev/null
+++ b/win_rc.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "icons/favicon.ico"
diff --git a/zodiac.qrc b/zodiac.qrc
new file mode 100644
index 0000000..fc3a379
--- /dev/null
+++ b/zodiac.qrc
@@ -0,0 +1,47 @@
+<RCC>
+ <qresource>
+ <file>icons/undo.png</file>
+ <file>icons/redo.png</file>
+ <file>icons/minimise.png</file>
+ <file>icons/zeden_ico.png</file>
+ <file>icons/haptic.png</file>
+ <file>icons/arrow.png</file>
+ <file>icons/select_square.png</file>
+ <file>icons/invert_selection.png</file>
+ <file>icons/select_H.png</file>
+ <file>icons/select_C.png</file>
+ <file>icons/deselect.png</file>
+ <file>icons/select_all.png</file>
+ <file>icons/builder_C.png</file>
+ <file>icons/builder_S.png</file>
+ <file>icons/builder_O.png</file>
+ <file>icons/builder_N.png</file>
+ <file>icons/builder_1bond.png</file>
+ <file>icons/builder_2bond.png</file>
+ <file>icons/builder_3bond.png</file>
+ <file>icons/builder_Xbond.png</file>
+ <file>icons/builder_del.png</file>
+ <file>icons/builder_pencil.png</file>
+ <file>icons/builder_smile.png</file>
+ <file>icons/select.png</file>
+ <file>icons/builder.png</file>
+ <file>icons/periodic_table.png</file>
+ <file>icons/X.png</file>
+ <file>icons/V.png</file>
+ <file>icons/pencil_C.png</file>
+ <file>icons/pencil_O.png</file>
+ <file>icons/pencil_S.png</file>
+ <file>icons/pencil_N.png</file>
+ <file>icons/pointer_select_square.png</file>
+ <file>icons/pointer_rubber.png</file>
+ <file>icons/ring3.png</file>
+ <file>icons/ring4.png</file>
+ <file>icons/ring5.png</file>
+ <file>icons/ring6.png</file>
+ <file>icons/ring7.png</file>
+ <file>icons/ring8.png</file>
+ <file>icons/benzene.png</file>
+ <file>icons/furan.png</file>
+ <file>icons/furanO.png</file>
+ </qresource>
+</RCC>
diff --git a/zodiac.ui b/zodiac.ui
new file mode 100644
index 0000000..c60ef62
--- /dev/null
+++ b/zodiac.ui
@@ -0,0 +1,27 @@
+<UI version="4.0" stdSetDef="1" >
+ <class>zodiacClass</class>
+ <widget class="QMainWindow" name="zodiacClass" >
+ <property name="objectName" >
+ <string notr="true">zodiacClass</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>zodiac</string>
+ </property>
+ <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections/>
+</UI>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/zodiac-zeden.git
More information about the debian-med-commit
mailing list