1 /******************************************************************************
2 
3   This source file is part of the Avogadro project.
4 
5   Copyright 2008-2009 Marcus D. Hanwell
6   Copyright 2010-2013 Kitware, Inc.
7 
8   This source code is released under the New BSD License, (the "License").
9 
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 
16 ******************************************************************************/
17 
18 #ifndef AVOGADRO_CORE_CUBE_H
19 #define AVOGADRO_CORE_CUBE_H
20 
21 #include "avogadrocore.h"
22 
23 #include "vector.h"
24 
25 #include <vector>
26 
27 namespace Avogadro {
28 namespace Core {
29 
30 class Molecule;
31 class Mutex;
32 
33 /**
34  * @class Cube cube.h <avogadro/core/cube.h>
35  * @brief Provide a data structure for regularly spaced 3D grids.
36  * @author Marcus D. Hanwell
37  */
38 
39 class AVOGADROCORE_EXPORT Cube
40 {
41 public:
42   Cube();
43   ~Cube();
44 
45   /**
46    * \enum Type
47    * Different Cube types relating to the data
48    */
49   enum Type
50   {
51     VdW,
52     ESP,
53     ElectronDensity,
54     MO,
55     FromFile,
56     None
57   };
58 
59   /**
60    * @return The minimum point in the cube.
61    */
min()62   Vector3 min() const { return m_min; }
63 
64   /**
65    * @return The maximum point in the cube.
66    */
max()67   Vector3 max() const { return m_max; }
68 
69   /**
70    * @return The spacing of the grid.
71    */
spacing()72   Vector3 spacing() const { return m_spacing; }
73 
74   /**
75    * @return The x, y and z dimensions of the cube.
76    */
dimensions()77   Vector3i dimensions() const { return m_points; }
78 
79   /**
80    * Set the limits of the cube.
81    * @param min The minimum point in the cube.
82    * @param max The maximum point in the cube.
83    * @param points The number of (integer) points in the cube.
84    */
85   bool setLimits(const Vector3& min, const Vector3& max,
86                  const Vector3i& points);
87 
88   /**
89    * Set the limits of the cube.
90    * @param min The minimum point in the cube.
91    * @param max The maximum point in the cube.
92    * @param spacing The interval between points in the cube.
93    */
94   bool setLimits(const Vector3& min, const Vector3& max, double spacing);
95 
96   /**
97    * Set the limits of the cube.
98    * @param min The minimum point in the cube.
99    * @param dim The integer dimensions of the cube in x, y and z.
100    * @param spacing The interval between points in the cube.
101    */
102   bool setLimits(const Vector3& min, const Vector3i& dim, double spacing);
103 
104   /**
105    * Set the limits of the cube.
106    * @param min The minimum point in the cube.
107    * @param dim The integer dimensions of the cube in x, y and z.
108    * @param spacing The interval between points in the cube.
109    */
110   bool setLimits(const Vector3& min, const Vector3i& dim,
111                  const Vector3& spacing);
112 
113   /**
114    * Set the limits of the cube - copy the limits of an existing Cube.
115    * @param cube Existing Cube to copy the limits from.
116    */
117   bool setLimits(const Cube& cube);
118 
119   /**
120    * Set the limits of the cube.
121    * @param mol Molecule to take limits from
122    * @param spacing The spacing of the regular grid
123    * @param padding Padding around the molecule
124    */
125   bool setLimits(const Molecule& mol, double spacing, double padding);
126 
127   /**
128    * @return Vector containing all the data in a one-dimensional array.
129    */
130   std::vector<double>* data();
131   const std::vector<double>* data() const;
132 
133   /**
134    * Set the values in the cube to those passed in the vector.
135    */
136   bool setData(const std::vector<double>& values);
137 
138   /**
139    * Adds the values in the cube to those passed in the vector.
140    */
141   bool addData(const std::vector<double>& values);
142 
143   /**
144    * @return Index of the point closest to the position supplied.
145    * @param pos Position to get closest index for.
146    */
147   unsigned int closestIndex(const Vector3& pos) const;
148 
149   /**
150    * @param pos Position to get closest index for.
151    * @return The i, j, k index closest to the position supplied.
152    */
153   Vector3i indexVector(const Vector3& pos) const;
154 
155   /**
156    * @param index Index to be translated to a position.
157    * @return Position of the given index.
158    */
159   Vector3 position(unsigned int index) const;
160 
161   /**
162    * This function is very quick as it just returns the value at the point.
163    * @return Cube value at the integer point i, j, k.
164    */
165   double value(int i, int j, int k) const;
166 
167   /**
168    * This function is very quick as it just returns the value at the point.
169    * @return Cube value at the integer point pos.
170    */
171   double value(const Vector3i& pos) const;
172 
173   /**
174    * This function uses trilinear interpolation to find the value at points
175    * between those specified in the cube.
176    * @return Cube value at the specified position.
177    * @warning This function is quite computationally expensive and should be
178    * avoided where possible.
179    */
180   float valuef(const Vector3f& pos) const;
181 
182   /**
183    * This function uses trilinear interpolation to find the value at points
184    * between those specified in the cube.
185    * @return Cube value at the specified position.
186    * @warning This function is quite computationally expensive and should be
187    * avoided where possible.
188    */
189   double value(const Vector3& pos) const;
190 
191   /**
192    * Sets the value at the specified point in the cube.
193    * @param i x component of the position.
194    * @param j y component of the position.
195    * @param k z component of the position.
196    * @param value Value at the specified position.
197    */
198   bool setValue(int i, int j, int k, double value);
199 
200   /**
201    * Sets the value at the specified index in the cube.
202    * @param i 1-dimensional index of the point to set in the cube.
203    */
204   bool setValue(unsigned int i, double value);
205 
206   /**
207    * @return The minimum  value at any point in the Cube.
208    */
minValue()209   double minValue() const { return m_minValue; }
210 
211   /**
212    * @return The maximum  value at any point in the Cube.
213    */
maxValue()214   double maxValue() const { return m_maxValue; }
215 
setName(const std::string & name_)216   void setName(const std::string& name_) { m_name = name_; }
name()217   std::string name() const { return m_name; }
218 
setCubeType(Type type)219   void setCubeType(Type type) { m_cubeType = type; }
cubeType()220   Type cubeType() const { return m_cubeType; }
221 
222   /**
223    * Provides locking.
224    */
lock()225   Mutex* lock() const { return m_lock; }
226 
227 protected:
228   std::vector<double> m_data;
229   Vector3 m_min, m_max, m_spacing;
230   Vector3i m_points;
231   double m_minValue, m_maxValue;
232   std::string m_name;
233   Type m_cubeType;
234   Mutex* m_lock;
235 };
236 
setValue(unsigned int i,double value_)237 inline bool Cube::setValue(unsigned int i, double value_)
238 {
239   if (i < m_data.size()) {
240     m_data[i] = value_;
241     if (value_ > m_maxValue)
242       m_maxValue = value_;
243     if (value_ < m_minValue)
244       m_minValue = value_;
245     return true;
246   } else
247     return false;
248 }
249 
250 } // End Core namespace
251 } // End Avogadro namespace
252 
253 #endif // AVOGADRO_CORE_CUBE_H
254