2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2013 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "utilities.h"
27 #include <QApplication>
28 #include <QPushButton>
29 #include <QHBoxLayout>
30 #include <QFormLayout>
32 #include <QMainWindow>
33 #include <QHBoxLayout>
35 #include <QStringList>
39 // #include <QFileDialogArgs>
43 #include "math/mathvector.h"
44 #include "math/smallsquarematrix.h"
45 #include "math/linsolve.h"
47 #include "vtkIntArray.h"
48 #include "vtkCellData.h"
49 #include "vtkDataSet.h"
50 #include "egvtkobject.h"
53 double toDouble(QString str
) {
54 str
.replace(QString(QObject::tr(",")), QString(QObject::tr(".")));
55 return(str
.toDouble());
58 QString
toString(double x
, QString separator
) {
61 ret
.replace(QString(QObject::tr(".")), separator
);
65 QString
addSuffix(QString filename
, QString suffix
, bool remove_old_suffix
) {
66 QFileInfo
fileinfo(filename
);
67 if (remove_old_suffix
) {
68 return fileinfo
.completeBaseName() + QObject::tr(".") + suffix
;
70 if (fileinfo
.suffix().toLower() == suffix
) {
71 return fileinfo
.absoluteFilePath();
73 return fileinfo
.absoluteFilePath() + QObject::tr(".") + suffix
;
78 Qt::CheckState
int2CheckState(int a
) {
79 if (a
== 0) return(Qt::Unchecked
);
80 if (a
== 1) return(Qt::PartiallyChecked
);
81 else return(Qt::Checked
);
84 int CheckState2int(Qt::CheckState a
) {
85 if (a
== Qt::Unchecked
) return(0);
86 if (a
== Qt::PartiallyChecked
) return(1);
90 QString
vector2csv(QVector
<double> vector
) {
92 for (int i
= 0; i
< vector
.size(); i
++) {
93 csv
+= QString::number(vector
[i
]);
94 if (i
< vector
.size() - 1) csv
+= QObject::tr(";");
99 QVector
<double> csv2vector(QString csv
)
101 QVector
<double> vector
;
102 if (csv
.isEmpty()) return vector
;
103 QStringList list
= csv
.split(QObject::tr(";"));
104 foreach(QString str
, list
) {
105 vector
.push_back(str
.toDouble());
110 mat3_t
rotationMatrix_X(double a_rad
)
113 Rx
[0][0] = 1; Rx
[0][1] = 0; Rx
[0][2] = 0;
114 Rx
[1][0] = 0; Rx
[1][1] = cos(a_rad
); Rx
[1][2] = sin(a_rad
);
115 Rx
[2][0] = 0; Rx
[2][1] = -sin(a_rad
); Rx
[2][2] = cos(a_rad
);
119 mat3_t
rotationMatrix_Y(double a_rad
)
122 Ry
[0][0] = cos(a_rad
); Ry
[0][1] = 0; Ry
[0][2] = -sin(a_rad
);
123 Ry
[1][0] = 0; Ry
[1][1] = 1; Ry
[1][2] = 0;
124 Ry
[2][0] = sin(a_rad
); Ry
[2][1] = 0; Ry
[2][2] = cos(a_rad
);
128 mat3_t
rotationMatrix_Z(double a_rad
)
131 Rz
[0][0] = cos(a_rad
); Rz
[0][1] = sin(a_rad
); Rz
[0][2] = 0;
132 Rz
[1][0] = -sin(a_rad
); Rz
[1][1] = cos(a_rad
); Rz
[1][2] = 0;
133 Rz
[2][0] = 0; Rz
[2][1] = 0; Rz
[2][2] = 1;
137 mat3_t
rotateRelativeZXZ(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
139 return rotationMatrix_Z(angle_3_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Z(angle_1_rad
);
142 mat3_t
rotateAbsoluteZXY(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
144 return rotationMatrix_Z(angle_1_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Y(angle_3_rad
);
147 double getGamma(vec3_t V
) {
148 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]);
151 double getPhi(vec3_t V
) {
152 return V
[0] == 0.0 && V
[1] == 0.0 ? 0.0 : atan2(V
[1], V
[0]);
155 QString
getDirectory(QWidget
* parent
, const QString
& caption
, const QString
& selected
)
157 qDebug() << "selected=" << selected
;
158 QFileInfo
fileinfo(selected
);
159 QString dir
= fileinfo
.absolutePath();
160 qDebug() << "dir=" << dir
;
162 // create a qt dialog
163 QFileDialog
dialog(parent
, caption
, dir
);//(args);
164 dialog
.setFileMode(QFileDialog::Directory
);
165 #if QT_VERSION >= 0x040500
166 dialog
.setOption(QFileDialog::ShowDirsOnly
, true);
168 dialog
.selectFile(selected
);
170 if (dialog
.exec() == QDialog::Accepted
) {
171 return dialog
.selectedFiles().value(0);
176 int cout_grid(ostream
&stream
, vtkUnstructuredGrid
*grid
, bool npoints
, bool ncells
, bool points
, bool cells
) {
177 stream
<< "=============" << endl
;
178 if (npoints
) stream
<< "grid->GetNumberOfPoints()=" << grid
->GetNumberOfPoints() << endl
;
179 if (ncells
) stream
<< "grid->GetNumberOfCells()=" << grid
->GetNumberOfCells() << endl
;
181 for (vtkIdType i
= 0; i
< grid
->GetNumberOfPoints(); ++i
) {
183 grid
->GetPoint(i
, x
.data());
184 stream
<< "Vertex " << i
<< " = " << x
<< endl
;
188 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
189 for (vtkIdType i
= 0; i
< grid
->GetNumberOfCells(); ++i
) {
190 vtkCell
*C
= (vtkCell
*) vtkCell::New();
191 C
= grid
->GetCell(i
);
192 vtkIdType npts
= C
->GetNumberOfPoints();
194 grid
->GetCellPoints(i
, npts
, pts
);
195 stream
<< "Cell " << i
<< " = ";
196 for (int j
= 0; j
< npts
; j
++) stream
<< pts
[j
] << " ";
197 stream
<< "boundary_code=" << cell_code
->GetValue(i
);
201 stream
<< "=============" << endl
;
205 ///////////////////////////////////////////
207 int addCell(vtkUnstructuredGrid
* a_grid
, vtkIdType A
, vtkIdType B
, vtkIdType C
, int bc
) {
213 vtkIdType newCellId
= a_grid
->InsertNextCell(VTK_TRIANGLE
, npts
, pts
);
214 EG_VTKDCC(vtkIntArray
, cell_code
, a_grid
, "cell_code");
215 cell_code
->SetValue(newCellId
, bc
);
219 ///////////////////////////////////////////
221 int getShortestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
222 vtkIdType N_pts
, *pts
;
223 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
224 vec3_t
* x
= new vec3_t
[N_pts
];
225 for (int i
= 0; i
< N_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
227 double minlen
= (x
[1] - x
[0]).abs();
228 for (int i
= 1; i
< N_pts
; i
++) {
229 double len
= (x
[(i
+1)%N_pts
] - x
[i
]).abs();
239 int getLongestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
240 vtkIdType N_pts
, *pts
;
241 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
242 vec3_t
* x
= new vec3_t
[N_pts
];
243 for (int i
= 0; i
< N_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
245 double maxlen
= (x
[1] - x
[0]).abs();
246 cout
<< "maxlen=" << maxlen
<< endl
;
247 for (int i
= 1; i
< N_pts
; i
++) {
248 double len
= (x
[(i
+1)%N_pts
] - x
[i
]).abs();
249 cout
<< "len[" << i
<< "]=" << len
<< endl
;
259 int getSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
, vtkIdType a_id_node1
, vtkIdType a_id_node2
) {
260 vtkIdType N_pts
, *pts
;
261 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
262 QVector
<vtkIdType
> edge(2);
265 for (int i
= 0; i
< N_pts
; i
++) {
266 if (pts
[i
] == a_id_node1
) { edge
[0] = i
; n
++;}
267 if (pts
[i
] == a_id_node2
) { edge
[1] = i
; n
++;}
273 qSort(edge
.begin(), edge
.end());
274 if (edge
[0] == 0 && edge
[1] == N_pts
- 1) return(N_pts
- 1);
275 else return(edge
[0]);
277 ///////////////////////////////////////////
279 QString
cell2str(vtkIdType id_cell
, vtkUnstructuredGrid
* grid
) {
282 QString txt
= "id_cell=" + tmp
;
284 vtkIdType N_pts
, *pts
;
285 grid
->GetCellPoints(id_cell
, N_pts
, pts
);
288 for (int i_pts
= 0; i_pts
< N_pts
; ++i_pts
) {
289 tmp
.setNum(pts
[i_pts
]);
291 if (i_pts
< N_pts
- 1) {
301 ///////////////////////////////////////////
303 pair
<vtkIdType
, vtkIdType
> OrderedPair(vtkIdType a
, vtkIdType b
) {
304 vtkIdType x
= min(a
, b
);
305 vtkIdType y
= max(a
, b
);
306 return(pair
<vtkIdType
, vtkIdType
>(x
, y
));
309 const char* VertexType2Str(char T
) {
310 if (T
== EG_SIMPLE_VERTEX
) return("EG_SIMPLE_VERTEX");
311 if (T
== EG_FIXED_VERTEX
) return("EG_FIXED_VERTEX");
312 if (T
== EG_FEATURE_EDGE_VERTEX
) return("EG_FEATURE_EDGE_VERTEX");
313 if (T
== EG_FEATURE_CORNER_VERTEX
) return("EG_FEATURE_CORNER_VERTEX");
314 if (T
== EG_BOUNDARY_EDGE_VERTEX
) return("EG_BOUNDARY_EDGE_VERTEX");
315 else return("Unknown vertex type");
318 char Str2VertexType(QString S
) {
319 if (S
== "EG_SIMPLE_VERTEX") return(EG_SIMPLE_VERTEX
);
320 if (S
== "EG_FIXED_VERTEX") return(EG_FIXED_VERTEX
);
321 if (S
== "EG_FEATURE_EDGE_VERTEX") return(EG_FEATURE_EDGE_VERTEX
);
322 if (S
== "EG_FEATURE_CORNER_VERTEX") return(EG_FEATURE_CORNER_VERTEX
);
323 if (S
== "EG_BOUNDARY_EDGE_VERTEX") return(EG_BOUNDARY_EDGE_VERTEX
);
324 else return((char) - 1);
327 bool checkVector(vec3_t V
)
329 for (int i
= 0; i
< 3; i
++) {
340 bool checkVector(vec2_t V
)
342 for (int i
= 0; i
< 2; i
++) {
353 QDebug
operator<<(QDebug dbg
, const vec3_t
&v
)
355 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ", " << v
[2] << ")";
359 QDebug
operator<<(QDebug dbg
, const vec2_t
&v
)
361 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ")";
365 QDebug
operator<<(QDebug dbg
, const dcmplx
&c
)
367 dbg
.nospace() << real(c
)<<" + "<<imag(c
)<<" *i";
371 dcmplx
complex_pow(dcmplx base
, double power
)
374 double alpha
= atan2(imag(base
),real(base
));
375 return pow(abs(base
),power
)*exp(power
*alpha
*i
);
378 #define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0)
380 int poly_solve_cubic(double a
, double b
, double c
, double * x0
, double * x1
, double * x2
)
382 double q
= (a
* a
- 3 * b
);
383 double r
= (2 * a
* a
* a
- 9 * a
* b
+ 27 * c
);
388 double Q3
= Q
* Q
* Q
;
391 double CR2
= 729 * r
* r
;
392 double CQ3
= 2916 * q
* q
* q
;
394 if (R
== 0 && Q
== 0)
403 // this test is actually R2 == Q3, written in a form suitable
404 // for exact computation with integers
406 // Due to finite precision some double roots may be missed, and
407 // considered to be a pair of complex roots z = x +/- epsilon i
408 // close to the real axis.
410 double sqrtQ
= sqrt (Q
);
414 *x0
= -2 * sqrtQ
- a
/ 3;
418 *x0
= - sqrtQ
- a
/ 3;
419 *x1
= - sqrtQ
- a
/ 3;
420 *x2
= 2 * sqrtQ
- a
/ 3;
423 } else if (CR2
< CQ3
) { // equivalent to R2 < Q3
424 double sqrtQ
= sqrt (Q
);
425 double sqrtQ3
= sqrtQ
* sqrtQ
* sqrtQ
;
426 double theta
= acos (R
/ sqrtQ3
);
427 double norm
= -2 * sqrtQ
;
428 *x0
= norm
* cos (theta
/ 3) - a
/ 3;
429 *x1
= norm
* cos ((theta
+ 2.0 * M_PI
) / 3) - a
/ 3;
430 *x2
= norm
* cos ((theta
- 2.0 * M_PI
) / 3) - a
/ 3;
432 // Sort *x0, *x1, *x2 into increasing order
447 double sgnR
= (R
>= 0 ? 1 : -1);
448 double A
= -sgnR
* pow (fabs (R
) + sqrt (R2
- Q3
), 1.0/3.0);
455 // a x^2 + b x + c = 0
456 int poly_solve_quadratic(double a
, double b
, double c
, double * x0
, double * x1
)
466 double delta
= pow(b
, 2) - 4 * a
* c
;
470 *x0
= (-b
+ sqrt(delta
)) / (2 * a
);
471 *x1
= (-b
- sqrt(delta
)) / (2 * a
);