1 /******************************************************************************
2
3 This source file is part of the Avogadro project.
4
5 Copyright 2011-2012 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #ifndef AVOGADRO_CORE_ATOM_H
18 #define AVOGADRO_CORE_ATOM_H
19
20 #include "avogadrocore.h"
21 #include "vector.h"
22
23 namespace Avogadro {
24 namespace Core {
25
26 enum AtomHybridization
27 {
28 PerceivedOctaheadral = -6,
29 PerceivedTrigonalBipyramidal = -5,
30 PerceivedSquarePlanar = -4,
31 PerceivedSP3 = -3,
32 PerceivedSP2 = -2,
33 PerceivedSP = -1,
34 HybridizationUnknown = 0,
35 SP = 1,
36 SP2 = 2,
37 SP3 = 3,
38 SquarePlanar = 4,
39 TrigonalBipyramidal = 5,
40 Octahedral = 6
41 };
42
43 /**
44 * @class Atom atom.h <avogadro/core/atom.h>
45 * The atom class represents an atom in a molecule.
46 * To use the appropriate atom implementation for a specific molecule
47 * implementation, use the [MoleculeClass]::AtomType typedef.
48 */
49 template <class Molecule_T>
50 class AtomTemplate
51 {
52 public:
53 typedef Molecule_T MoleculeType;
54
55 /** Creates a new, invalid atom object. */
56 AtomTemplate();
57
58 /**
59 * Creates a new atom object representing the atom at index @p i in molecule
60 * @p m.
61 */
62 AtomTemplate(MoleculeType* m, Index i);
63
64 /**
65 * @return True if @a this and @a other share the same index and molecule.
66 */
67 bool operator==(const AtomTemplate<MoleculeType>& other) const;
68
69 /**
70 * @return True if @a this and @a other do not share the same index or
71 * molecule.
72 */
73 bool operator!=(const AtomTemplate<MoleculeType>& other) const;
74
75 /**
76 * Prefix increment operator. Increment this Atom's index by 1 and return a
77 * self-reference. Check isValid() before calling any other methods.
78 */
79 AtomTemplate<MoleculeType>& operator++();
80
81 /**
82 * Postfix increment operator. Increment this Atom's index by 1 and return a
83 * copy of the current Atom. Check isValid() before calling any other methods.
84 */
85 AtomTemplate<MoleculeType> operator++(int);
86
87 /**
88 * Prefix decrement operator. Decrement this Atom's index by 1 and return a
89 * self-reference. Check isValid() before calling any other methods.
90 */
91 AtomTemplate<MoleculeType>& operator--();
92
93 /**
94 * Postfix decrement operator. Decrement this Atom's index by 1 and return a
95 * copy of the current Atom. Check isValid() before calling any other methods.
96 */
97 AtomTemplate<MoleculeType> operator--(int);
98
99 /**
100 * @return True if the molecule is set and the index is less than the number
101 * of atoms.
102 */
103 bool isValid() const;
104
105 /**
106 * @return The molecule that contains this Atom.
107 */
108 MoleculeType* molecule() const;
109
110 /**
111 * @return The index of this atom in molecule().
112 */
113 Index index() const;
114
115 /**
116 * The proton count of the atom.
117 * @{
118 */
119 void setAtomicNumber(unsigned char num);
120 unsigned char atomicNumber() const;
121 /** @} */
122
123 /**
124 * The 2D position of this atom.
125 * @note Not all molecule types support 2D positions. If the current
126 * MoleculeType class does not, calling this method will result in a
127 * compilation error.
128 * @{
129 */
130 void setPosition2d(const Vector2& pos);
131 Vector2 position2d() const;
132 /** @} */
133
134 /**
135 * The 3D position of this atom.
136 * @{
137 */
138 void setPosition3d(const Vector3& pos);
139 Vector3 position3d() const;
140 /** @} */
141
142 /**
143 * The hybridization / coordination of this atom
144 * @{
145 */
146 void setHybridization(AtomHybridization hyb);
147 AtomHybridization hybridization() const;
148 /** @} */
149
150 /**
151 * The formal charge of this atom
152 * @{
153 */
154 void setFormalCharge(signed char charge);
155 signed char formalCharge() const;
156 /** @} */
157
158 /**
159 * The color of this atom
160 * @{
161 */
162 void setColor(Vector3ub color);
163 Vector3ub color() const;
164 /** @} */
165
166 /**
167 * Is the atom selected.
168 * {@
169 */
170 void setSelected(bool selected);
171 bool selected() const;
172 /** @} */
173
174 /**
175 * The force on this atom.
176 * {@
177 */
178 void setForceVector(const Vector3& force);
179 Vector3 forceVector() const;
180 /** @} */
181
182 private:
183 MoleculeType* m_molecule;
184 Index m_index;
185 };
186
187 template <class Molecule_T>
AtomTemplate()188 AtomTemplate<Molecule_T>::AtomTemplate()
189 : m_molecule(nullptr), m_index(MaxIndex)
190 {}
191
192 template <class Molecule_T>
AtomTemplate(MoleculeType * m,Index i)193 AtomTemplate<Molecule_T>::AtomTemplate(MoleculeType* m, Index i)
194 : m_molecule(m), m_index(i)
195 {}
196
197 template <class Molecule_T>
198 bool AtomTemplate<Molecule_T>::operator==(
199 const AtomTemplate<MoleculeType>& other) const
200 {
201 return m_molecule == other.m_molecule && m_index == other.m_index;
202 }
203
204 template <class Molecule_T>
205 bool AtomTemplate<Molecule_T>::operator!=(
206 const AtomTemplate<MoleculeType>& other) const
207 {
208 return m_molecule != other.m_molecule || m_index != other.m_index;
209 }
210
211 template <class Molecule_T>
212 AtomTemplate<Molecule_T>& AtomTemplate<Molecule_T>::operator++()
213 {
214 ++m_index;
215 return *this;
216 }
217
218 template <class Molecule_T>
219 AtomTemplate<Molecule_T> AtomTemplate<Molecule_T>::operator++(int)
220 {
221 AtomTemplate<MoleculeType> result(m_molecule, m_index++);
222 return result;
223 }
224
225 template <class Molecule_T>
226 AtomTemplate<Molecule_T>& AtomTemplate<Molecule_T>::operator--()
227 {
228 --m_index;
229 return *this;
230 }
231
232 template <class Molecule_T>
233 AtomTemplate<Molecule_T> AtomTemplate<Molecule_T>::operator--(int)
234 {
235 AtomTemplate<MoleculeType> result(m_molecule, m_index--);
236 return result;
237 }
238
239 template <class Molecule_T>
isValid()240 bool AtomTemplate<Molecule_T>::isValid() const
241 {
242 return m_molecule && m_index < m_molecule->atomCount();
243 }
244
245 template <class Molecule_T>
246 typename AtomTemplate<Molecule_T>::MoleculeType*
molecule()247 AtomTemplate<Molecule_T>::molecule() const
248 {
249 return m_molecule;
250 }
251
252 template <class Molecule_T>
index()253 Index AtomTemplate<Molecule_T>::index() const
254 {
255 return m_index;
256 }
257
258 template <class Molecule_T>
setAtomicNumber(unsigned char num)259 void AtomTemplate<Molecule_T>::setAtomicNumber(unsigned char num)
260 {
261 m_molecule->setAtomicNumber(m_index, num);
262 }
263
264 template <class Molecule_T>
atomicNumber()265 unsigned char AtomTemplate<Molecule_T>::atomicNumber() const
266 {
267 return m_molecule->atomicNumber(m_index);
268 }
269
270 template <class Molecule_T>
setPosition2d(const Vector2 & pos)271 void AtomTemplate<Molecule_T>::setPosition2d(const Vector2& pos)
272 {
273 m_molecule->setAtomPosition2d(m_index, pos);
274 }
275
276 template <class Molecule_T>
position2d()277 Vector2 AtomTemplate<Molecule_T>::position2d() const
278 {
279 return m_molecule->atomPositions2d().size() > 0
280 ? m_molecule->atomPositions2d()[m_index]
281 : Vector2::Zero();
282 }
283
284 template <class Molecule_T>
setPosition3d(const Vector3 & pos)285 void AtomTemplate<Molecule_T>::setPosition3d(const Vector3& pos)
286 {
287 m_molecule->setAtomPosition3d(m_index, pos);
288 }
289
290 template <class Molecule_T>
position3d()291 Vector3 AtomTemplate<Molecule_T>::position3d() const
292 {
293 return m_molecule->atomPositions3d().size() > 0
294 ? m_molecule->atomPositions3d()[m_index]
295 : Vector3::Zero();
296 }
297
298 template <class Molecule_T>
setHybridization(AtomHybridization hyb)299 void AtomTemplate<Molecule_T>::setHybridization(AtomHybridization hyb)
300 {
301 m_molecule->setHybridization(m_index, hyb);
302 }
303
304 template <class Molecule_T>
hybridization()305 AtomHybridization AtomTemplate<Molecule_T>::hybridization() const
306 {
307 return m_molecule->hybridization(m_index);
308 }
309
310 template <class Molecule_T>
setFormalCharge(signed char charge)311 void AtomTemplate<Molecule_T>::setFormalCharge(signed char charge)
312 {
313 m_molecule->setFormalCharge(m_index, charge);
314 }
315
316 template <class Molecule_T>
formalCharge()317 signed char AtomTemplate<Molecule_T>::formalCharge() const
318 {
319 return m_molecule->formalCharge(m_index);
320 }
321
322 template <class Molecule_T>
setColor(Vector3ub color)323 void AtomTemplate<Molecule_T>::setColor(Vector3ub color)
324 {
325 m_molecule->setColor(m_index, std::move(color));
326 }
327
328 template <class Molecule_T>
color()329 Vector3ub AtomTemplate<Molecule_T>::color() const
330 {
331 return m_molecule->color(m_index);
332 }
333
334 template <class Molecule_T>
setSelected(bool selected)335 void AtomTemplate<Molecule_T>::setSelected(bool selected)
336 {
337 m_molecule->setAtomSelected(m_index, selected);
338 }
339
340 template <class Molecule_T>
selected()341 bool AtomTemplate<Molecule_T>::selected() const
342 {
343 return m_molecule->atomSelected(m_index);
344 }
345
346 template <class Molecule_T>
setForceVector(const Vector3 & force)347 void AtomTemplate<Molecule_T>::setForceVector(const Vector3& force)
348 {
349 m_molecule->setForceVector(m_index, force);
350 }
351
352 template <class Molecule_T>
forceVector()353 Vector3 AtomTemplate<Molecule_T>::forceVector() const
354 {
355 return m_molecule->forceVectors().size() > 0
356 ? m_molecule->forceVectors()[m_index]
357 : Vector3::Zero();
358 }
359
360 } // namespace Core
361 } // namespace Avogadro
362
363 #endif // AVOGADRO_CORE_ATOM_H
364