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