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 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