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 <vlMolecule/Molecule.hpp> 00033 #include <vlMolecule/RingExtractor.hpp> 00034 00035 using namespace vl; 00036 00037 //----------------------------------------------------------------------------- 00038 Molecule::Molecule(): 00039 mActorTree(new ActorTree), 00040 mTransformTree(new Transform), 00041 mTags(new KeyValues), 00042 mAtomLabelTemplate(new Text), 00043 mAtomLabelEffect(new Effect) 00044 { 00045 VL_DEBUG_SET_OBJECT_NAME() 00046 mAtomLabelEffect->shader()->enable(EN_BLEND); 00047 reset(); 00048 } 00049 //----------------------------------------------------------------------------- 00050 void Molecule::reset() 00051 { 00052 mMoleculeStyle = MS_BallAndStick; 00053 mBondDetail = 20; 00054 mAtomDetail = 2; 00055 mRingOffset = 0.45f; 00056 mAromaticRingColor = fvec4(0,1.0f,0,1.0f); 00057 mId = 0; 00058 mAtoms.clear(); 00059 mBonds.clear(); 00060 mCycles.clear(); 00061 mMoleculeName.clear(); 00062 tags()->clear(); 00063 mActorTree->actors()->clear(); 00064 mLineWidth= 1.0f; 00065 mSmoothLines = false; 00066 mShowAtomNames = false; 00067 // molecule / actor maps 00068 mMoleculeToActorMapEnabled = false; 00069 mActorToMoleculeMapEnabled = false; 00070 mAtomToActorMap.clear(); 00071 mActorToAtomMap.clear(); 00072 mBondToActorMap.clear(); 00073 mActorToBondMap.clear(); 00074 } 00075 //----------------------------------------------------------------------------- 00076 Molecule& Molecule::operator=(const Molecule& other) 00077 { 00078 reset(); 00079 super::operator=(other); 00080 00081 mMoleculeName = other.mMoleculeName; 00082 *mTags = *other.mTags; 00083 mMoleculeStyle = other.mMoleculeStyle; 00084 mAtomDetail = other.mAtomDetail; 00085 mBondDetail = other.mBondDetail; 00086 mRingOffset = other.mRingOffset; 00087 mAromaticRingColor = other.mAromaticRingColor; 00088 mLineWidth = other.mLineWidth; 00089 mSmoothLines = other.mSmoothLines; 00090 00091 std::map<const Atom*, Atom*> atom_map; 00092 for(unsigned i=0; i<other.atoms().size(); ++i) 00093 { 00094 atoms().push_back( new Atom( *other.atom(i) ) ); 00095 atom_map[ other.atom(i) ] = atoms().back().get(); 00096 } 00097 00098 for(unsigned i=0; i<other.bonds().size(); ++i) 00099 { 00100 bonds().push_back( new Bond( *other.bond(i) ) ); 00101 bonds().back()->setAtom1( atom_map[ other.bond(i)->atom1() ] ); 00102 bonds().back()->setAtom2( atom_map[ other.bond(i)->atom2() ] ); 00103 } 00104 00105 mCycles.resize( other.mCycles.size() ); 00106 for(unsigned i=0; i<other.mCycles.size(); ++i) 00107 { 00108 cycle(i).resize( other.cycle(i).size() ); 00109 for(unsigned j=0; j<other.cycle(i).size(); ++j) 00110 cycle(i)[j] = atom_map[ other.cycle(i)[j].get() ]; 00111 } 00112 return *this; 00113 } 00114 //----------------------------------------------------------------------------- 00115 const Atom* Molecule::atom(int index) const { return mAtoms[index].get(); } 00116 //----------------------------------------------------------------------------- 00117 Atom* Molecule::atom(int index) { return mAtoms[index].get(); } 00118 //----------------------------------------------------------------------------- 00119 void Molecule::addAtom(Atom* atom) 00120 { 00121 prepareAtomInsert(); 00122 atoms().push_back(atom); 00123 } 00124 //----------------------------------------------------------------------------- 00125 void Molecule::eraseAllAtoms() 00126 { 00127 mAtoms.clear(); 00128 mBonds.clear(); 00129 mCycles.clear(); 00130 } 00131 //----------------------------------------------------------------------------- 00132 void Molecule::eraseAtom(int i) 00133 { 00134 std::vector<Bond*> incident_bonds; 00135 incidentBonds(incident_bonds, atom(i)); 00136 for(unsigned j=0; j<incident_bonds.size(); ++j) 00137 eraseBond( incident_bonds[j] ); 00138 atoms().erase(atoms().begin() + i); 00139 } 00140 //----------------------------------------------------------------------------- 00141 void Molecule::eraseAtom(Atom*a) 00142 { 00143 for(unsigned i=0; i<atoms().size(); ++i) 00144 { 00145 if (atom(i) == a) 00146 { 00147 std::vector<Bond*> incident_bonds; 00148 incidentBonds(incident_bonds, a); 00149 for(unsigned j=0; j<incident_bonds.size(); ++j) 00150 eraseBond( incident_bonds[j] ); 00151 atoms().erase(atoms().begin() + i); 00152 return; 00153 } 00154 } 00155 } 00156 //----------------------------------------------------------------------------- 00157 Bond* Molecule::addBond(Atom* a1, Atom* a2) 00158 { 00159 prepareBondInsert(); 00160 ref<Bond> bond = new Bond; 00161 bond->setAtom1(a1); 00162 bond->setAtom2(a2); 00163 bonds().push_back(bond); 00164 return bond.get(); 00165 } 00166 //----------------------------------------------------------------------------- 00167 const Bond* Molecule::bond(int index) const { return mBonds[index].get(); } 00168 //----------------------------------------------------------------------------- 00169 Bond* Molecule::bond(int index) { return mBonds[index].get(); } 00170 //----------------------------------------------------------------------------- 00171 const Bond* Molecule::bond(Atom* a1, Atom* a2) const 00172 { 00173 for(unsigned i=0; i<bonds().size(); ++i) 00174 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) || (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) ) 00175 return bonds()[i].get(); 00176 return NULL; 00177 } 00178 //----------------------------------------------------------------------------- 00179 Bond* Molecule::bond(Atom* a1, Atom* a2) 00180 { 00181 for(unsigned i=0; i<bonds().size(); ++i) 00182 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) || (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) ) 00183 return bonds()[i].get(); 00184 return NULL; 00185 } 00186 //----------------------------------------------------------------------------- 00187 void Molecule::addBond(Bond* bond) 00188 { 00189 prepareBondInsert(); 00190 bonds().push_back(bond); 00191 } 00192 //----------------------------------------------------------------------------- 00193 void Molecule::eraseBond(Bond*b) 00194 { 00195 for(unsigned i=0; i<bonds().size(); ++i) 00196 { 00197 if (bond(i) == b) 00198 { 00199 bonds().erase(bonds().begin() + i); 00200 return; 00201 } 00202 } 00203 } 00204 //----------------------------------------------------------------------------- 00205 void Molecule::eraseBond(int bond) { bonds().erase(bonds().begin() + bond); } 00206 //----------------------------------------------------------------------------- 00207 void Molecule::eraseAllBonds() { bonds().clear(); } 00208 //----------------------------------------------------------------------------- 00209 void Molecule::eraseBond(Atom* a1, Atom* a2) 00210 { 00211 for(unsigned i=0; i<bonds().size(); ++i) 00212 { 00213 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) || 00214 (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) ) 00215 { 00216 bonds().erase(bonds().begin() + i); 00217 return; 00218 } 00219 } 00220 } 00221 //----------------------------------------------------------------------------- 00222 void Molecule::eraseBond(int a1, int a2) { eraseBond(atom(a1), atom(a2)); } 00223 //----------------------------------------------------------------------------- 00224 void Molecule::computeAtomAdjacency() 00225 { 00226 for(int i=0; i<atomCount(); ++i) 00227 atom(i)->adjacentAtoms().clear(); 00228 for(int i=0; i<bondCount(); ++i) 00229 { 00230 bond(i)->atom1()->adjacentAtoms().push_back( bond(i)->atom2() ); 00231 bond(i)->atom2()->adjacentAtoms().push_back( bond(i)->atom1() ); 00232 } 00233 } 00234 //----------------------------------------------------------------------------- 00235 void Molecule::incidentBonds(std::vector<Bond*>& incident_bonds, Atom* atom) 00236 { 00237 incident_bonds.clear(); 00238 for(int i=0; i<bondCount(); ++i) 00239 if(bond(i)->atom1() == atom || bond(i)->atom2() == atom) 00240 incident_bonds.push_back( bond(i) ); 00241 } 00242 //----------------------------------------------------------------------------- 00243 void Molecule::setCPKAtomColors() 00244 { 00245 for(unsigned i=0; i<atoms().size(); ++i) 00246 atoms()[i]->setColor( atomInfo(atoms()[i]->atomType()).cpkColor() ); 00247 } 00248 //----------------------------------------------------------------------------- 00249 void Molecule::setAtomColors(const fvec4& color) 00250 { 00251 for(unsigned i=0; i<atoms().size(); ++i) 00252 atoms()[i]->setColor( color ); 00253 } 00254 //----------------------------------------------------------------------------- 00255 void Molecule::setCalculatedAtomRadii(float percentage) 00256 { 00257 for(unsigned i=0; i<atoms().size(); ++i) 00258 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).calculatedRadius() * percentage ); 00259 } 00260 //----------------------------------------------------------------------------- 00261 void Molecule::setEmpiricalAtomRadii(float percentage) 00262 { 00263 for(unsigned i=0; i<atoms().size(); ++i) 00264 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).empiricalRadius() * percentage ); 00265 } 00266 //----------------------------------------------------------------------------- 00267 void Molecule::setCovalentAtomRadii(float percentage) 00268 { 00269 for(unsigned i=0; i<atoms().size(); ++i) 00270 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).covalentRadius() * percentage ); 00271 } 00272 //----------------------------------------------------------------------------- 00273 void Molecule::setVanDerWaalsAtomRadii(float percentage) 00274 { 00275 for(unsigned i=0; i<atoms().size(); ++i) 00276 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).vanDerWaalsRadius() * percentage ); 00277 } 00278 //----------------------------------------------------------------------------- 00279 void Molecule::setAtomRadii(float radius) 00280 { 00281 for(unsigned i=0; i<atoms().size(); ++i) 00282 atoms()[i]->setRadius( radius ); 00283 } 00284 //----------------------------------------------------------------------------- 00285 void Molecule::setBondRadii(float radius) 00286 { 00287 for(unsigned i=0; i<bonds().size(); ++i) 00288 bonds()[i]->setRadius( radius ); 00289 } 00290 //----------------------------------------------------------------------------- 00291 void Molecule::setAtomTypeVisible(EAtomType type, bool visible) 00292 { 00293 for(unsigned i=0; i<atoms().size(); ++i) 00294 if (atom(i)->atomType() == type) 00295 atom(i)->setVisible(visible); 00296 } 00297 //----------------------------------------------------------------------------- 00298 void Molecule::setAromaticBondsColor(const fvec4& color) 00299 { 00300 for(unsigned i=0; i<bonds().size(); ++i) 00301 { 00302 if(bonds()[i]->bondType() == BT_Aromatic) 00303 bonds()[i]->setColor(color); 00304 } 00305 } 00306 //-----------------------------------------------------------------------------