fixed edge display for volume cells
[engrid-github.git] / src / libengrid / utilities.h
blob98dd49abf462b572764b50ce8d77ae312395ab61
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
11 // + +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
16 // + +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #ifndef UTILITIES_H
22 #define UTILITIES_H
24 /** @file utilities.h Contains several utility functions. */
26 #include <QVector>
27 #include <QMap>
28 #include <QObject>
29 #include <QtDebug>
30 #include <QFileDialog>
32 #include <iostream>
33 using namespace std;
35 #include "math/mathvector.h"
36 #include "math/smallsquarematrix.h"
37 #include "math/linsolve.h"
39 #include "vtkUnstructuredGrid.h"
41 #include <complex>
43 #ifdef _MSC_VER
44 #include <float.h>
45 #define isnan(x) _isnan(x)
46 #define isinf(x) !_finite(x)
47 #endif
49 using namespace std;
51 /** Restricts value to the CYCLIC [min,max[ range.
52 * Equivalent to min + modulo(value-min, max-min)
53 * @param value value to restrict
54 * @param min minimum
55 * @param max maximum (if value=max, then min will be returned)
57 inline double restrict_to(double value, double min, double max)
59 return value - floor((value - min) / (max - min))*(max - min);
62 /// Converts degrees to radians
63 inline double RadiansFromDegrees(double a_deg)
65 return(a_deg / 180.0*M_PI);
68 /// Converts radians to degrees
69 inline double DegreesFromRadians(double a_rad)
71 return(a_rad / M_PI*180.0);
74 double toDouble(QString str);///< Equivalent of the QString::toDouble function, but it also replaces "," with "."
76 /** Converts a double to a string.
77 * @param x double value to convert
78 * @param separator symbol to use as decimal separator. It is recommended to always use the default: ".".
80 QString toString(double x, QString separator = QObject::tr("."));
82 /// a modulo function which also works for negative numbers
83 inline int modulo(int a, int b)
85 return((a % b + b) % b);
88 /// a modulo function which also works for negative numbers
89 inline double modulo(double a, double b)
91 while (a < 0) a += b;
92 while (a >= b) a -= b;
93 return a;
96 /** Adds a suffix to a filename if it is missing.
97 * @param filename string to which to add the suffix
98 * @param suffix suffix to add. suffix should be of the form 'ext' without the dot!!!
99 * @param remove_old_suffix If true, any previous suffix of filename will be removed. ex: foo.bar -> foo.png
100 * @return the filename with the new suffix
102 QString addSuffix(QString filename, QString suffix, bool remove_old_suffix);
104 ///////////////////////////////////////////
106 /** Transposes a vector of vectors (matrix)
107 * @param in the matrix to transpose
108 * @param nrows the number of rows of the input matrix
109 * @param ncolumns the number of columns of the input matrix
110 * @return the transposed "matrix"
112 template <class T>
113 QVector < QVector <T> > transpose(QVector < QVector <T> > & in, int nrows, int ncolumns)
115 QVector < QVector <T> > out(ncolumns);
116 QVector <T> col(nrows);
117 out.fill(col);
119 for (int i = 0; i < in.size(); i++) {
120 QVector <T> row = in[i];
121 for (int j = 0; j < row.size(); j++) {
122 out[j][i] = in[i][j];
125 return(out);
128 ///////////////////////////////////////////
130 /// ostream operator for QVectors
131 template <class T>
132 ostream &operator<<(ostream &out, QVector<T> const & vector)
134 int N = vector.size();
135 out << "[";
136 for (int i = 0; i < N; ++i) {
137 out << vector.at(i);
138 if (i != N - 1) out << ",";
140 out << "]";
141 return(out);
144 /// ostream operator for QSets
145 template <class T>
146 ostream &operator<<(ostream &out, QSet<T> const & set)
148 out << "[ ";
149 foreach(T value, set) out << value << " ";
150 out << "]";
151 return(out);
154 /// ostream operator for QVectors of QSets
155 template <class T>
156 ostream &operator<<(ostream &out, QVector<QSet<T> > & vector)
158 int N = vector.size();
159 out << "[";
160 for (int i = 0; i < N; ++i) {
161 QSet<T> set = vector.at(i);
162 out << set;
163 if (i != N - 1) out << ",";
165 out << "]";
166 return(out);
169 /// ostream operator for QVectors of QVectors
170 template <class T>
171 ostream &operator<<(ostream &out, QVector<QVector<T> > & vector)
173 int N = vector.size();
174 out << "[";
175 for (int i = 0; i < N; ++i) {
176 QVector<T> subvector = vector.at(i);
177 out << subvector;
178 if (i != N - 1) out << ",";
180 out << "]";
181 return(out);
184 /// ostream operator for QMaps
185 template <class T1, class T2>
186 ostream &operator<<(ostream &out, QMap<T1, T2> & map)
188 QMapIterator<T1, T2> i(map);
189 out << "[";
190 while (i.hasNext()) {
191 i.next();
192 out << " [" << i.key() << ": " << i.value() << "]";
194 out << "]";
195 return(out);
198 /// ostream operator for a QVector of pairs
199 template <class T1, class T2>
200 ostream &operator<<(ostream &out, QVector < pair<T1, T2> > & vector)
202 int N = vector.size();
203 out << "[";
204 for (int i = 0; i < N; ++i) {
205 out << "<";
206 out << vector.at(i).first;
207 out << ",";
208 out << vector.at(i).second;
209 out << ">";
210 if (i != N - 1) out << ",";
212 out << "]";
213 return(out);
216 ////////////////////////////////////////////////////
218 template <class T>
219 QVector <T> set2Vector(QSet <T> a_set, bool a_sort)
221 QVector <T> l_vector(a_set.size());
222 qCopy(a_set.begin(),a_set.end(),l_vector.begin());
223 if(a_sort) qSort(l_vector.begin(),l_vector.end());
224 return(l_vector);
227 template <class T>
228 QSet <T> vector2Set(QVector <T> a_vector, bool a_sort)
230 QSet <T> l_set;
231 foreach(T element, a_vector) l_set.insert(element);
232 if(a_sort) qSort(l_set.begin(),l_set.end());
233 return(l_set);
236 template <class T>
237 bool duplicates(QVector <T> a_vector)
239 QSet <T> l_set;
240 foreach(T element, a_vector) l_set.insert(element);
241 return l_set.size()!=a_vector.size();
244 ////////////////////////////////////////////////////
246 Qt::CheckState int2CheckState(int a);///< Converts an integer into a Qt::CheckState: Qt::Unchecked=0, Qt::PartiallyChecked=1, Qt::Checked=2
247 int CheckState2int(Qt::CheckState a);///< Converts a Qt::CheckState into an integer: Qt::Unchecked=0, Qt::PartiallyChecked=1, Qt::Checked=2
249 QString vector2csv(QVector <double> vector);///< Converts a vector into a CSV string
250 QVector <double> csv2vector(QString csv);///< Converts a CSV string into a vector
252 /// V(rotated base) = rotationMatrix_X * V(original base)
253 mat3_t rotationMatrix_X(double a_rad);
255 /// V(rotated base) = rotationMatrix_Y * V(original base)
256 mat3_t rotationMatrix_Y(double a_rad);
258 /// V(rotated base) = rotationMatrix_Z * V(original base)
259 mat3_t rotationMatrix_Z(double a_rad);
261 /// V(rotated base) = rotateRelativeZXZ * V(original base)
262 mat3_t rotateRelativeZXZ(double angle_1_rad, double angle_2_rad, double angle_3_rad);
264 /// V(rotated base) = rotateAbsoluteZXY * V(original base)
265 mat3_t rotateAbsoluteZXY(double angle_1_rad, double angle_2_rad, double angle_3_rad);
267 /// returns the polar angle in radians
268 double getGamma(vec3_t V);
270 /// returns the azimuth angle in radians. returns phi from -pi to pi
271 double getPhi(vec3_t V);
273 /// A version of QFileDialog::getExistingDirectory which allows preselecting a directory
274 QString getDirectory(QWidget * parent = 0, const QString & caption = QString(), const QString & selected = QString());
275 // QString getDirectory( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & selected = QString() , Options options = ShowDirsOnly );
278 * Utility function that allows printing selected data from an vtkUnstructuredGrid to any ostream (includes ofstream objects)
279 * @param stream ostream object to print to
280 * @param grid vtkUnstructuredGrid you want to print data from
281 * @param npoints print number of points in the grid
282 * @param ncells print number of cells in the grid
283 * @param points print points in the grid
284 * @param cells print cells in the grid
286 int cout_grid(ostream &stream, vtkUnstructuredGrid *grid, bool npoints=true, bool ncells=true, bool points=false, bool cells=false);
288 ///////////////////////////////////////////
289 int addCell(vtkUnstructuredGrid* a_grid, vtkIdType A, vtkIdType B, vtkIdType C, int bc);
291 ///get number of the shortest side of the cell
292 int getShortestSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
293 ///get number of the longest side of the cell
294 int getLongestSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
295 //sort sides by length
296 //QVector <vtkIdType> sortSidesByLength(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
298 ///get number of the edge corresponding to node1-node2
299 int getSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid,vtkIdType a_id_node1,vtkIdType a_id_node2);
301 // QSet <int> complementary_bcs(QSet <int> &bcs, vtkUnstructuredGrid *a_grid, QVector <vtkIdType> &a_cells);
302 QString cell2str(vtkIdType id_cell,vtkUnstructuredGrid* grid);
304 ///////////////////////////////////////////
305 ///////////////////////////////////////////
306 pair<vtkIdType,vtkIdType> OrderedPair(vtkIdType a, vtkIdType b);
308 const char* VertexType2Str(char T);
309 char Str2VertexType(QString S);
310 QDebug operator<<(QDebug dbg, const vec3_t &v);
311 QDebug operator<<(QDebug dbg, const vec2_t &v);
313 bool checkVector(vec3_t V);
314 bool checkVector(vec2_t V);
315 bool checkReal(double v);
317 /// returns the index of a node in a structured triangle grid
318 inline vtkIdType trigrid_idx(vtkIdType N, int i, int j) {
319 int offset = -i * (i - 2 * N - 1) / 2;
320 return offset + j;
323 /// returns the index of a node in a structured quad grid
324 inline vtkIdType quadgrid_idx(vtkIdType N, int i, int j) {
325 return i*N + j;
328 // solver functions
329 typedef complex<double> dcmplx;
330 QDebug operator<<(QDebug dbg, const dcmplx &c);
331 dcmplx complex_pow(dcmplx base, double power);
332 // x^3 + a x^2 + b x + c = 0
333 int poly_solve_cubic(double a, double b, double c, double * x0, double * x1, double * x2);
334 // a x^2 + b x + c = 0
335 int poly_solve_quadratic(double a, double b, double c, double * x0, double * x1);
337 inline double logarithm(double a, double b)
339 return log(b)/log(a);
342 #endif