Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #include <vlCore/DiskFile.hpp> 00033 #include <vlCore/MemoryFile.hpp> 00034 #include <vlMolecule/Molecule.hpp> 00035 #include <vlMolecule/RingExtractor.hpp> 00036 #include <vlCore/TextStream.hpp> 00037 #include <vlGraphics/Effect.hpp> 00038 #include <vlGraphics/Scissor.hpp> 00039 #include <vlGraphics/Texture.hpp> 00040 #include <vlCore/Image.hpp> 00041 #include <stdio.h> 00042 00043 using namespace vl; 00044 00045 //----------------------------------------------------------------------------- 00046 namespace 00047 { 00048 ref<Molecule> parseStructure(TextStream& text_stream) 00049 { 00050 #define NAME_CHAR_COUNT 128 00051 00052 ref<Molecule> structure = new Molecule; 00053 std::string line; 00054 00055 // find structure start 00056 bool mol2_start = false; 00057 while(text_stream.readLine(line)) 00058 { 00059 if ( strstr(line.c_str(), "@<TRIPOS>MOLECULE") ) 00060 { 00061 mol2_start = true; 00062 break; 00063 } 00064 } 00065 if (!mol2_start) 00066 return NULL; 00067 00068 // parse structure name 00069 text_stream.readLine(line); 00070 structure->setMoleculeName( String::trimStdString(line).c_str() ); 00071 00072 // skip lines until atom coordinates start 00073 while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>ATOM")) { /*skip lines*/ } 00074 00075 // read atoms 00076 char atom_name[NAME_CHAR_COUNT]; 00077 char atom_type[NAME_CHAR_COUNT]; 00078 while(text_stream.readLine(line) && !strstr(line.c_str(), "@<TRIPOS>BOND")) 00079 { 00080 fvec3 pos; 00081 int id = 0; 00082 int tokens = sscanf(line.c_str(), "%d %s %f %f %f %s", &id, atom_name, &pos.x(), &pos.y(), &pos.z(), atom_type); 00083 // make sure they are zero-terminated. 00084 atom_name[NAME_CHAR_COUNT-1] = 0; 00085 atom_type[NAME_CHAR_COUNT-1] = 0; 00086 if (tokens != 6) 00087 continue; 00088 00089 ref<Atom> atom = new Atom; 00090 atom->setCoordinates( pos ); 00091 atom->setAtomName( atom_name ); 00092 00093 // detect atom type 00094 char* ch = strstr(atom_type, "."); 00095 if ( ch != NULL ) 00096 *ch = 0; 00097 EAtomType atype = atomType(atom_type); 00098 if (atype==AT_Unknown) 00099 atype=atomType(atom_name); 00100 atom->setAtomType( atype ); 00101 structure->addAtom( atom.get() ); 00102 } 00103 00104 // read bonds 00105 char bond_type[NAME_CHAR_COUNT]; 00106 unsigned bond_atom1; 00107 unsigned bond_atom2; 00108 while(text_stream.readLine(line)) 00109 { 00110 if ( strstr(line.c_str(), "@<TRIPOS>") ) 00111 { 00112 text_stream.ungetLine(line); 00113 break; 00114 } 00115 int id = 0; 00116 int tokens = sscanf(line.c_str(), "%d %d %d %s", &id, &bond_atom1, &bond_atom2, bond_type); 00117 // make sure it is zero-terminated. 00118 bond_type[NAME_CHAR_COUNT-1] = 0; 00119 if (tokens != 4) 00120 continue; 00121 --bond_atom1; 00122 --bond_atom2; 00123 if ( !(bond_atom1 < structure->atoms().size() && bond_atom2 < structure->atoms().size()) ) 00124 { 00125 Log::error( Say("Bond indices out of range: a1 = %n, a2 = %n, atom count = %n.\n") << bond_atom1 << bond_atom2 << structure->atoms().size() ); 00126 continue; 00127 } 00128 VL_CHECK( bond_atom1 < structure->atoms().size() ) 00129 VL_CHECK( bond_atom2 < structure->atoms().size() ) 00130 ref<Bond> bond = new Bond; 00131 bond->setAtom1( structure->atom(bond_atom1) ); 00132 bond->setAtom2( structure->atom(bond_atom2) ); 00133 bond->setBondType( BT_None ); 00134 if (bond_type[0] == '1') bond->setBondType( BT_Single ); 00135 if (bond_type[0] == '2') bond->setBondType( BT_Double ); 00136 if (bond_type[0] == '3') bond->setBondType( BT_Triple ); 00137 if (strstr(bond_type, "ar")) bond->setBondType( BT_Aromatic ); 00138 if (strstr(bond_type, "am")) bond->setBondType( BT_Amide ); 00139 if (strstr(bond_type, "du")) bond->setBondType( BT_Dummy ); 00140 if (strstr(bond_type, "un")) bond->setBondType( BT_Unknown ); 00141 if (bond->bondType() == BT_Aromatic) 00142 { 00143 bond->setUseAtomColors(false); 00144 bond->setColor(fvec4(0,1.0f,0,1.0f)); 00145 } 00146 else 00147 bond->setUseAtomColors(true); 00148 00149 structure->addBond( bond.get() ); 00150 } 00151 00152 // by default all the atom radii are set to be covalent 00153 structure->setCovalentAtomRadii(); 00154 00155 // by default set cpk colors 00156 structure->setCPKAtomColors(); 00157 00158 // compute adjacent atoms 00159 structure->computeAtomAdjacency(); 00160 00161 // compute aromatic rings 00162 RingExtractor ring_extractor(structure.get()); 00163 ring_extractor.run(); 00164 return structure; 00165 } 00166 } 00167 //----------------------------------------------------------------------------- 00168 bool vl::loadMOL2(const String& path, std::vector< ref<Molecule> >& structures) 00169 { 00170 ref<VirtualFile> dfile = locateFile(path); 00171 ref<MemoryFile> mfile = new MemoryFile; // cache in the memory 00172 mfile->copy(dfile.get()); 00173 if (!mfile->open(OM_ReadOnly)) 00174 { 00175 Log::error( Say("Error opening file %s.\n") << path ); 00176 return false; 00177 } 00178 return loadMOL2(mfile.get(), structures); 00179 } 00180 //----------------------------------------------------------------------------- 00181 bool vl::loadMOL2(VirtualFile* vfile, std::vector< ref<Molecule> >& structures) 00182 { 00183 structures.clear(); 00184 00185 TextStream text_stream; 00186 text_stream.setInputFile(vfile); 00187 std::string line; 00188 00189 // detect tripos mol2 file 00190 bool is_mol2 = false; 00191 while(text_stream.readLine(line)) 00192 { 00193 const char* pos = strstr(line.c_str(), "@<TRIPOS>MOLECULE"); 00194 if ( pos && line == pos ) 00195 { 00196 is_mol2 = true; 00197 break; 00198 } 00199 } 00200 if ( !is_mol2 ) 00201 { 00202 Log::error( Say("Invalid structure file: %s\n") << vfile->path() ); 00203 vfile->close(); 00204 return false; 00205 } 00206 text_stream.seek(0); 00207 00208 // extract multi-mol2 structures 00209 ref<Molecule> structure; 00210 while( (structure = parseStructure(text_stream) ) ) 00211 { 00212 if (structure->atoms().size()) 00213 { 00214 structures.push_back(structure); 00215 structure->tags()->set("MultiMol2Index") = Say("%n") << structures.size() - 1; 00216 structure->tags()->set("FilePath") = vfile->path(); 00217 } 00218 } 00219 00220 vfile->close(); 00221 return true; 00222 } 00223 //-----------------------------------------------------------------------------