Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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 }
00068
00069 Molecule& Molecule::operator=(const Molecule& other)
00070 {
00071 reset();
00072 super::operator=(other);
00073
00074 mMoleculeName = other.mMoleculeName;
00075 *mTags = *other.mTags;
00076 mMoleculeStyle = other.mMoleculeStyle;
00077 mAtomDetail = other.mAtomDetail;
00078 mBondDetail = other.mBondDetail;
00079 mRingOffset = other.mRingOffset;
00080 mAromaticRingColor = other.mAromaticRingColor;
00081 mLineWidth = other.mLineWidth;
00082 mSmoothLines = other.mSmoothLines;
00083
00084 std::map<const Atom*, Atom*> atom_map;
00085 for(unsigned i=0; i<other.atoms().size(); ++i)
00086 {
00087 atoms().push_back( new Atom( *other.atom(i) ) );
00088 atom_map[ other.atom(i) ] = atoms().back().get();
00089 }
00090
00091 for(unsigned i=0; i<other.bonds().size(); ++i)
00092 {
00093 bonds().push_back( new Bond( *other.bond(i) ) );
00094 bonds().back()->setAtom1( atom_map[ other.bond(i)->atom1() ] );
00095 bonds().back()->setAtom2( atom_map[ other.bond(i)->atom2() ] );
00096 }
00097
00098 mCycles.resize( other.mCycles.size() );
00099 for(unsigned i=0; i<other.mCycles.size(); ++i)
00100 {
00101 cycle(i).resize( other.cycle(i).size() );
00102 for(unsigned j=0; j<other.cycle(i).size(); ++j)
00103 cycle(i)[j] = atom_map[ other.cycle(i)[j].get() ];
00104 }
00105 return *this;
00106 }
00107
00108 const Atom* Molecule::atom(int index) const { return mAtoms[index].get(); }
00109
00110 Atom* Molecule::atom(int index) { return mAtoms[index].get(); }
00111
00112 void Molecule::addAtom(Atom* atom)
00113 {
00114 prepareAtomInsert();
00115 atoms().push_back(atom);
00116 }
00117
00118 void Molecule::eraseAllAtoms()
00119 {
00120 mAtoms.clear();
00121 mBonds.clear();
00122 mCycles.clear();
00123 }
00124
00125 void Molecule::eraseAtom(int i)
00126 {
00127 std::vector<Bond*> incident_bonds;
00128 incidentBonds(incident_bonds, atom(i));
00129 for(unsigned j=0; j<incident_bonds.size(); ++j)
00130 eraseBond( incident_bonds[j] );
00131 atoms().erase(atoms().begin() + i);
00132 }
00133
00134 void Molecule::eraseAtom(Atom*a)
00135 {
00136 for(unsigned i=0; i<atoms().size(); ++i)
00137 {
00138 if (atom(i) == a)
00139 {
00140 std::vector<Bond*> incident_bonds;
00141 incidentBonds(incident_bonds, a);
00142 for(unsigned j=0; j<incident_bonds.size(); ++j)
00143 eraseBond( incident_bonds[j] );
00144 atoms().erase(atoms().begin() + i);
00145 return;
00146 }
00147 }
00148 }
00149
00150 Bond* Molecule::addBond(Atom* a1, Atom* a2)
00151 {
00152 prepareBondInsert();
00153 ref<Bond> bond = new Bond;
00154 bond->setAtom1(a1);
00155 bond->setAtom2(a2);
00156 bonds().push_back(bond);
00157 return bond.get();
00158 }
00159
00160 const Bond* Molecule::bond(int index) const { return mBonds[index].get(); }
00161
00162 Bond* Molecule::bond(int index) { return mBonds[index].get(); }
00163
00164 const Bond* Molecule::bond(Atom* a1, Atom* a2) const
00165 {
00166 for(unsigned i=0; i<bonds().size(); ++i)
00167 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) || (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) )
00168 return bonds()[i].get();
00169 return NULL;
00170 }
00171
00172 Bond* Molecule::bond(Atom* a1, Atom* a2)
00173 {
00174 for(unsigned i=0; i<bonds().size(); ++i)
00175 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) || (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) )
00176 return bonds()[i].get();
00177 return NULL;
00178 }
00179
00180 void Molecule::addBond(Bond* bond)
00181 {
00182 prepareBondInsert();
00183 bonds().push_back(bond);
00184 }
00185
00186 void Molecule::eraseBond(Bond*b)
00187 {
00188 for(unsigned i=0; i<bonds().size(); ++i)
00189 {
00190 if (bond(i) == b)
00191 {
00192 bonds().erase(bonds().begin() + i);
00193 return;
00194 }
00195 }
00196 }
00197
00198 void Molecule::eraseBond(int bond) { bonds().erase(bonds().begin() + bond); }
00199
00200 void Molecule::eraseAllBonds() { bonds().clear(); }
00201
00202 void Molecule::eraseBond(Atom* a1, Atom* a2)
00203 {
00204 for(unsigned i=0; i<bonds().size(); ++i)
00205 {
00206 if ( (bond(i)->atom1() == a1 && bond(i)->atom2() == a2) ||
00207 (bond(i)->atom1() == a2 && bond(i)->atom2() == a1) )
00208 {
00209 bonds().erase(bonds().begin() + i);
00210 return;
00211 }
00212 }
00213 }
00214
00215 void Molecule::eraseBond(int a1, int a2) { eraseBond(atom(a1), atom(a2)); }
00216
00217 void Molecule::computeAtomAdjacency()
00218 {
00219 for(int i=0; i<atomCount(); ++i)
00220 atom(i)->adjacentAtoms().clear();
00221 for(int i=0; i<bondCount(); ++i)
00222 {
00223 bond(i)->atom1()->adjacentAtoms().push_back( bond(i)->atom2() );
00224 bond(i)->atom2()->adjacentAtoms().push_back( bond(i)->atom1() );
00225 }
00226 }
00227
00228 void Molecule::incidentBonds(std::vector<Bond*>& incident_bonds, Atom* atom)
00229 {
00230 incident_bonds.clear();
00231 for(int i=0; i<bondCount(); ++i)
00232 if(bond(i)->atom1() == atom || bond(i)->atom2() == atom)
00233 incident_bonds.push_back( bond(i) );
00234 }
00235
00236 void Molecule::setCPKAtomColors()
00237 {
00238 for(unsigned i=0; i<atoms().size(); ++i)
00239 atoms()[i]->setColor( atomInfo(atoms()[i]->atomType()).cpkColor() );
00240 }
00241
00242 void Molecule::setAtomColors(const fvec4& color)
00243 {
00244 for(unsigned i=0; i<atoms().size(); ++i)
00245 atoms()[i]->setColor( color );
00246 }
00247
00248 void Molecule::setCalculatedAtomRadii(float percentage)
00249 {
00250 for(unsigned i=0; i<atoms().size(); ++i)
00251 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).calculatedRadius() * percentage );
00252 }
00253
00254 void Molecule::setEmpiricalAtomRadii(float percentage)
00255 {
00256 for(unsigned i=0; i<atoms().size(); ++i)
00257 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).empiricalRadius() * percentage );
00258 }
00259
00260 void Molecule::setCovalentAtomRadii(float percentage)
00261 {
00262 for(unsigned i=0; i<atoms().size(); ++i)
00263 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).covalentRadius() * percentage );
00264 }
00265
00266 void Molecule::setVanDerWaalsAtomRadii(float percentage)
00267 {
00268 for(unsigned i=0; i<atoms().size(); ++i)
00269 atoms()[i]->setRadius( (float)atomInfo(atoms()[i]->atomType()).vanDerWaalsRadius() * percentage );
00270 }
00271
00272 void Molecule::setAtomRadii(float radius)
00273 {
00274 for(unsigned i=0; i<atoms().size(); ++i)
00275 atoms()[i]->setRadius( radius );
00276 }
00277
00278 void Molecule::setBondRadii(float radius)
00279 {
00280 for(unsigned i=0; i<bonds().size(); ++i)
00281 bonds()[i]->setRadius( radius );
00282 }
00283
00284 void Molecule::setAtomTypeVisible(EAtomType type, bool visible)
00285 {
00286 for(unsigned i=0; i<atoms().size(); ++i)
00287 if (atom(i)->atomType() == type)
00288 atom(i)->setVisible(visible);
00289 }
00290
00291 void Molecule::setAromaticBondsColor(const fvec4& color)
00292 {
00293 for(unsigned i=0; i<bonds().size(); ++i)
00294 {
00295 if(bonds()[i]->bondType() == BT_Aromatic)
00296 bonds()[i]->setColor(color);
00297 }
00298 }
00299