1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
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. +
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. +
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/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "utilities.h"
25 #include <QApplication>
26 #include <QPushButton>
27 #include <QHBoxLayout>
28 #include <QFormLayout>
30 #include <QMainWindow>
31 #include <QHBoxLayout>
33 #include <QStringList>
37 // #include <QFileDialogArgs>
41 #include "math/mathvector.h"
42 #include "math/smallsquarematrix.h"
43 #include "math/linsolve.h"
45 #include "vtkIntArray.h"
46 #include "vtkCellData.h"
47 #include "vtkDataSet.h"
48 #include "egvtkobject.h"
51 double toDouble(QString str
) {
52 str
.replace(QString(QObject::tr(",")), QString(QObject::tr(".")));
53 return(str
.toDouble());
56 QString
toString(double x
, QString separator
) {
59 ret
.replace(QString(QObject::tr(".")), separator
);
63 QString
addSuffix(QString filename
, QString suffix
, bool remove_old_suffix
) {
64 QFileInfo
fileinfo(filename
);
65 if (remove_old_suffix
) {
66 return fileinfo
.completeBaseName() + QObject::tr(".") + suffix
;
68 if (fileinfo
.suffix().toLower() == suffix
) {
69 return fileinfo
.absoluteFilePath();
71 return fileinfo
.absoluteFilePath() + QObject::tr(".") + suffix
;
76 Qt::CheckState
int2CheckState(int a
) {
77 if (a
== 0) return(Qt::Unchecked
);
78 if (a
== 1) return(Qt::PartiallyChecked
);
79 else return(Qt::Checked
);
82 int CheckState2int(Qt::CheckState a
) {
83 if (a
== Qt::Unchecked
) return(0);
84 if (a
== Qt::PartiallyChecked
) return(1);
88 QString
vector2csv(QVector
<double> vector
) {
90 for (int i
= 0; i
< vector
.size(); i
++) {
91 csv
+= QString::number(vector
[i
]);
92 if (i
< vector
.size() - 1) csv
+= QObject::tr(";");
97 QVector
<double> csv2vector(QString csv
)
99 QVector
<double> vector
;
100 if (csv
.isEmpty()) return vector
;
101 QStringList list
= csv
.split(QObject::tr(";"));
102 foreach(QString str
, list
) {
103 vector
.push_back(str
.toDouble());
108 mat3_t
rotationMatrix_X(double a_rad
)
111 Rx
[0][0] = 1; Rx
[0][1] = 0; Rx
[0][2] = 0;
112 Rx
[1][0] = 0; Rx
[1][1] = cos(a_rad
); Rx
[1][2] = sin(a_rad
);
113 Rx
[2][0] = 0; Rx
[2][1] = -sin(a_rad
); Rx
[2][2] = cos(a_rad
);
117 mat3_t
rotationMatrix_Y(double a_rad
)
120 Ry
[0][0] = cos(a_rad
); Ry
[0][1] = 0; Ry
[0][2] = -sin(a_rad
);
121 Ry
[1][0] = 0; Ry
[1][1] = 1; Ry
[1][2] = 0;
122 Ry
[2][0] = sin(a_rad
); Ry
[2][1] = 0; Ry
[2][2] = cos(a_rad
);
126 mat3_t
rotationMatrix_Z(double a_rad
)
129 Rz
[0][0] = cos(a_rad
); Rz
[0][1] = sin(a_rad
); Rz
[0][2] = 0;
130 Rz
[1][0] = -sin(a_rad
); Rz
[1][1] = cos(a_rad
); Rz
[1][2] = 0;
131 Rz
[2][0] = 0; Rz
[2][1] = 0; Rz
[2][2] = 1;
135 mat3_t
rotateRelativeZXZ(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
137 return rotationMatrix_Z(angle_3_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Z(angle_1_rad
);
140 mat3_t
rotateAbsoluteZXY(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
142 return rotationMatrix_Z(angle_1_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Y(angle_3_rad
);
145 double getGamma(vec3_t V
) {
146 return V
[0] == 0.0 && V
[1] == 0.0 && V
[2] == 0.0 ? 0.0 : atan2(sqrt(V
[0]*V
[0] + V
[1]*V
[1]), V
[2]);
149 double getPhi(vec3_t V
) {
150 return V
[0] == 0.0 && V
[1] == 0.0 ? 0.0 : atan2(V
[1], V
[0]);
153 QString
getDirectory(QWidget
* parent
, const QString
& caption
, const QString
& selected
)
155 qDebug() << "selected=" << selected
;
156 QFileInfo
fileinfo(selected
);
157 QString dir
= fileinfo
.absolutePath();
158 qDebug() << "dir=" << dir
;
160 // create a qt dialog
161 QFileDialog
dialog(parent
, caption
, dir
);//(args);
162 dialog
.setFileMode(QFileDialog::Directory
);
163 #if QT_VERSION >= 0x040500
164 dialog
.setOption(QFileDialog::ShowDirsOnly
, true);
166 dialog
.selectFile(selected
);
168 if (dialog
.exec() == QDialog::Accepted
) {
169 return dialog
.selectedFiles().value(0);
174 int cout_grid(ostream
&stream
, vtkUnstructuredGrid
*grid
, bool npoints
, bool ncells
, bool points
, bool cells
) {
175 stream
<< "=============" << endl
;
176 if (npoints
) stream
<< "grid->GetNumberOfPoints()=" << grid
->GetNumberOfPoints() << endl
;
177 if (ncells
) stream
<< "grid->GetNumberOfCells()=" << grid
->GetNumberOfCells() << endl
;
179 for (vtkIdType i
= 0; i
< grid
->GetNumberOfPoints(); ++i
) {
181 grid
->GetPoint(i
, x
.data());
182 stream
<< "Vertex " << i
<< " = " << x
<< endl
;
186 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
187 for (vtkIdType i
= 0; i
< grid
->GetNumberOfCells(); ++i
) {
188 vtkCell
*C
= (vtkCell
*) vtkCell::New();
189 C
= grid
->GetCell(i
);
190 EG_GET_CELL(i
, grid
);
191 stream
<< "Cell " << i
<< " = ";
192 for (int j
= 0; j
< num_pts
; j
++)
193 stream
<< pts
[j
] << " ";
194 stream
<< "boundary_code=" << cell_code
->GetValue(i
);
198 stream
<< "=============" << endl
;
202 ///////////////////////////////////////////
204 int addCell(vtkUnstructuredGrid
* a_grid
, vtkIdType A
, vtkIdType B
, vtkIdType C
, int bc
) {
210 vtkIdType newCellId
= a_grid
->InsertNextCell(VTK_TRIANGLE
, npts
, pts
);
211 EG_VTKDCC(vtkIntArray
, cell_code
, a_grid
, "cell_code");
212 cell_code
->SetValue(newCellId
, bc
);
216 ///////////////////////////////////////////
218 int getShortestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
219 EG_GET_CELL(a_id_cell
, a_grid
);
220 vec3_t
* x
= new vec3_t
[num_pts
];
221 for (int i
= 0; i
< num_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
223 double minlen
= (x
[1] - x
[0]).abs();
224 for (int i
= 1; i
< num_pts
; i
++) {
225 double len
= (x
[(i
+1)%num_pts
] - x
[i
]).abs();
235 int getLongestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
236 EG_GET_CELL(a_id_cell
, a_grid
);
237 vec3_t
* x
= new vec3_t
[num_pts
];
238 for (int i
= 0; i
< num_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
240 double maxlen
= (x
[1] - x
[0]).abs();
241 cout
<< "maxlen=" << maxlen
<< endl
;
242 for (int i
= 1; i
< num_pts
; i
++) {
243 double len
= (x
[(i
+1)%num_pts
] - x
[i
]).abs();
244 cout
<< "len[" << i
<< "]=" << len
<< endl
;
254 int getSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
, vtkIdType a_id_node1
, vtkIdType a_id_node2
) {
255 EG_GET_CELL(a_id_cell
, a_grid
);
256 QVector
<vtkIdType
> edge(2);
259 for (int i
= 0; i
< num_pts
; i
++) {
260 if (pts
[i
] == a_id_node1
) { edge
[0] = i
; n
++;}
261 if (pts
[i
] == a_id_node2
) { edge
[1] = i
; n
++;}
267 qSort(edge
.begin(), edge
.end());
268 if (edge
[0] == 0 && edge
[1] == num_pts
- 1) return(num_pts
- 1);
269 else return(edge
[0]);
271 ///////////////////////////////////////////
273 QString
cell2str(vtkIdType id_cell
, vtkUnstructuredGrid
* grid
) {
276 QString txt
= "id_cell=" + tmp
;
278 EG_GET_CELL(id_cell
, grid
);
281 for (int i_pts
= 0; i_pts
< num_pts
; ++i_pts
) {
282 tmp
.setNum(pts
[i_pts
]);
284 if (i_pts
< num_pts
- 1) {
294 ///////////////////////////////////////////
296 pair
<vtkIdType
, vtkIdType
> OrderedPair(vtkIdType a
, vtkIdType b
) {
297 vtkIdType x
= min(a
, b
);
298 vtkIdType y
= max(a
, b
);
299 return(pair
<vtkIdType
, vtkIdType
>(x
, y
));
302 const char* VertexType2Str(char T
) {
303 if (T
== EG_SIMPLE_VERTEX
) return("EG_SIMPLE_VERTEX");
304 if (T
== EG_FIXED_VERTEX
) return("EG_FIXED_VERTEX");
305 if (T
== EG_FEATURE_EDGE_VERTEX
) return("EG_FEATURE_EDGE_VERTEX");
306 if (T
== EG_FEATURE_CORNER_VERTEX
) return("EG_FEATURE_CORNER_VERTEX");
307 if (T
== EG_BOUNDARY_EDGE_VERTEX
) return("EG_BOUNDARY_EDGE_VERTEX");
308 else return("Unknown vertex type");
311 char Str2VertexType(QString S
) {
312 if (S
== "EG_SIMPLE_VERTEX") return(EG_SIMPLE_VERTEX
);
313 if (S
== "EG_FIXED_VERTEX") return(EG_FIXED_VERTEX
);
314 if (S
== "EG_FEATURE_EDGE_VERTEX") return(EG_FEATURE_EDGE_VERTEX
);
315 if (S
== "EG_FEATURE_CORNER_VERTEX") return(EG_FEATURE_CORNER_VERTEX
);
316 if (S
== "EG_BOUNDARY_EDGE_VERTEX") return(EG_BOUNDARY_EDGE_VERTEX
);
317 else return((char) - 1);
320 bool checkVector(vec3_t V
)
322 for (int i
= 0; i
< 3; i
++) {
333 bool checkVector(vec2_t V
)
335 for (int i
= 0; i
< 2; i
++) {
346 bool checkReal(double v
)
357 QDebug
operator<<(QDebug dbg
, const vec3_t
&v
)
359 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ", " << v
[2] << ")";
363 QDebug
operator<<(QDebug dbg
, const vec2_t
&v
)
365 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ")";
369 QDebug
operator<<(QDebug dbg
, const dcmplx
&c
)
371 dbg
.nospace() << real(c
)<<" + "<<imag(c
)<<" *i";
375 dcmplx
complex_pow(dcmplx base
, double power
)
378 double alpha
= atan2(imag(base
),real(base
));
379 return pow(abs(base
),power
)*exp(power
*alpha
*i
);
382 #define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0)
384 int poly_solve_cubic(double a
, double b
, double c
, double * x0
, double * x1
, double * x2
)
386 double q
= (a
* a
- 3 * b
);
387 double r
= (2 * a
* a
* a
- 9 * a
* b
+ 27 * c
);
392 double Q3
= Q
* Q
* Q
;
395 double CR2
= 729 * r
* r
;
396 double CQ3
= 2916 * q
* q
* q
;
398 if (R
== 0 && Q
== 0)
407 // this test is actually R2 == Q3, written in a form suitable
408 // for exact computation with integers
410 // Due to finite precision some double roots may be missed, and
411 // considered to be a pair of complex roots z = x +/- epsilon i
412 // close to the real axis.
414 double sqrtQ
= sqrt (Q
);
418 *x0
= -2 * sqrtQ
- a
/ 3;
422 *x0
= - sqrtQ
- a
/ 3;
423 *x1
= - sqrtQ
- a
/ 3;
424 *x2
= 2 * sqrtQ
- a
/ 3;
427 } else if (CR2
< CQ3
) { // equivalent to R2 < Q3
428 double sqrtQ
= sqrt (Q
);
429 double sqrtQ3
= sqrtQ
* sqrtQ
* sqrtQ
;
430 double theta
= acos (R
/ sqrtQ3
);
431 double norm
= -2 * sqrtQ
;
432 *x0
= norm
* cos (theta
/ 3) - a
/ 3;
433 *x1
= norm
* cos ((theta
+ 2.0 * M_PI
) / 3) - a
/ 3;
434 *x2
= norm
* cos ((theta
- 2.0 * M_PI
) / 3) - a
/ 3;
436 // Sort *x0, *x1, *x2 into increasing order
451 double sgnR
= (R
>= 0 ? 1 : -1);
452 double A
= -sgnR
* pow (fabs (R
) + sqrt (R2
- Q3
), 1.0/3.0);
459 // a x^2 + b x + c = 0
460 int poly_solve_quadratic(double a
, double b
, double c
, double * x0
, double * x1
)
470 double delta
= pow(b
, 2) - 4 * a
* c
;
474 *x0
= (-b
+ sqrt(delta
)) / (2 * a
);
475 *x1
= (-b
- sqrt(delta
)) / (2 * a
);