5 #include <QApplication>
10 #include <QMainWindow>
11 #include <QHBoxLayout>
13 #include <QStringList>
17 // #include <QFileDialogArgs>
21 #include "math/mathvector.h"
22 #include "math/smallsquarematrix.h"
23 #include "math/linsolve.h"
25 #include "vtkIntArray.h"
26 #include "vtkCellData.h"
27 #include "vtkDataSet.h"
28 #include "egvtkobject.h"
31 double toDouble(QString str
) {
32 str
.replace(QString(QObject::tr(",")), QString(QObject::tr(".")));
33 return(str
.toDouble());
36 QString
toString(double x
, QString separator
) {
39 ret
.replace(QString(QObject::tr(".")), separator
);
43 QString
addSuffix(QString filename
, QString suffix
, bool remove_old_suffix
) {
44 QFileInfo
fileinfo(filename
);
45 if (remove_old_suffix
) {
46 return fileinfo
.completeBaseName() + QObject::tr(".") + suffix
;
48 if (fileinfo
.suffix().toLower() == suffix
) {
49 return fileinfo
.absoluteFilePath();
51 return fileinfo
.absoluteFilePath() + QObject::tr(".") + suffix
;
56 Qt::CheckState
int2CheckState(int a
) {
57 if (a
== 0) return(Qt::Unchecked
);
58 if (a
== 1) return(Qt::PartiallyChecked
);
59 else return(Qt::Checked
);
62 int CheckState2int(Qt::CheckState a
) {
63 if (a
== Qt::Unchecked
) return(0);
64 if (a
== Qt::PartiallyChecked
) return(1);
68 QString
vector2csv(QVector
<double> vector
) {
70 for (int i
= 0; i
< vector
.size(); i
++) {
71 csv
+= QString::number(vector
[i
]);
72 if (i
< vector
.size() - 1) csv
+= QObject::tr(";");
77 QVector
<double> csv2vector(QString csv
)
79 QVector
<double> vector
;
80 if (csv
.isEmpty()) return vector
;
81 QStringList list
= csv
.split(QObject::tr(";"));
82 foreach(QString str
, list
) {
83 vector
.push_back(str
.toDouble());
88 mat3_t
rotationMatrix_X(double a_rad
)
91 Rx
[0][0] = 1; Rx
[0][1] = 0; Rx
[0][2] = 0;
92 Rx
[1][0] = 0; Rx
[1][1] = cos(a_rad
); Rx
[1][2] = sin(a_rad
);
93 Rx
[2][0] = 0; Rx
[2][1] = -sin(a_rad
); Rx
[2][2] = cos(a_rad
);
97 mat3_t
rotationMatrix_Y(double a_rad
)
100 Ry
[0][0] = cos(a_rad
); Ry
[0][1] = 0; Ry
[0][2] = -sin(a_rad
);
101 Ry
[1][0] = 0; Ry
[1][1] = 1; Ry
[1][2] = 0;
102 Ry
[2][0] = sin(a_rad
); Ry
[2][1] = 0; Ry
[2][2] = cos(a_rad
);
106 mat3_t
rotationMatrix_Z(double a_rad
)
109 Rz
[0][0] = cos(a_rad
); Rz
[0][1] = sin(a_rad
); Rz
[0][2] = 0;
110 Rz
[1][0] = -sin(a_rad
); Rz
[1][1] = cos(a_rad
); Rz
[1][2] = 0;
111 Rz
[2][0] = 0; Rz
[2][1] = 0; Rz
[2][2] = 1;
115 mat3_t
rotateRelativeZXZ(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
117 return rotationMatrix_Z(angle_3_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Z(angle_1_rad
);
120 mat3_t
rotateAbsoluteZXY(double angle_1_rad
, double angle_2_rad
, double angle_3_rad
)
122 return rotationMatrix_Z(angle_1_rad
)*rotationMatrix_X(angle_2_rad
)*rotationMatrix_Y(angle_3_rad
);
125 double getGamma(vec3_t V
) {
126 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]);
129 double getPhi(vec3_t V
) {
130 return V
[0] == 0.0 && V
[1] == 0.0 ? 0.0 : atan2(V
[1], V
[0]);
133 QString
getDirectory(QWidget
* parent
, const QString
& caption
, const QString
& selected
) {
134 qDebug() << "selected=" << selected
;
135 // QFileDialog filedialog;
136 // filedialog.selectFile(selected);
137 QFileInfo
fileinfo(selected
);
138 QString dir
= fileinfo
.absolutePath();
139 qDebug() << "dir=" << dir
;
141 /* QFileDialogArgs args;
142 args.parent = parent;
143 args.caption = caption;
144 args.directory = QFileDialogPrivate::workingDirectory(dir);
145 args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
146 args.options = options;*/
148 // create a qt dialog
149 QFileDialog
dialog(parent
, caption
, dir
);//(args);
150 dialog
.setFileMode(QFileDialog::Directory
);
151 // dialog.setFileMode(QFileDialog::DirectoryOnly);
152 dialog
.setOption(QFileDialog::ShowDirsOnly
, true);
153 /* args.parent = parent;
154 args.caption = caption;
155 args.directory = QFileDialogPrivate::workingDirectory(dir);*/
156 // args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
157 // args.options = options;
159 dialog
.selectFile(selected
);
160 if (dialog
.exec() == QDialog::Accepted
) {
161 return dialog
.selectedFiles().value(0);
165 // return filedialog.getExistingDirectory (parent, caption, dir);
168 int cout_grid(ostream
&stream
, vtkUnstructuredGrid
*grid
, bool npoints
, bool ncells
, bool points
, bool cells
) {
169 stream
<< "=============" << endl
;
170 if (npoints
) stream
<< "grid->GetNumberOfPoints()=" << grid
->GetNumberOfPoints() << endl
;
171 if (ncells
) stream
<< "grid->GetNumberOfCells()=" << grid
->GetNumberOfCells() << endl
;
173 for (vtkIdType i
= 0; i
< grid
->GetNumberOfPoints(); ++i
) {
175 grid
->GetPoint(i
, x
.data());
176 stream
<< "Vertex " << i
<< " = " << x
<< endl
;
180 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
181 for (vtkIdType i
= 0; i
< grid
->GetNumberOfCells(); ++i
) {
182 vtkCell
*C
= (vtkCell
*) vtkCell::New();
183 C
= grid
->GetCell(i
);
184 vtkIdType npts
= C
->GetNumberOfPoints();
186 grid
->GetCellPoints(i
, npts
, pts
);
187 stream
<< "Cell " << i
<< " = ";
188 for (int j
= 0; j
< npts
; j
++) stream
<< pts
[j
] << " ";
189 stream
<< "boundary_code=" << cell_code
->GetValue(i
);
193 stream
<< "=============" << endl
;
197 ///////////////////////////////////////////
199 int addCell(vtkUnstructuredGrid
* a_grid
, vtkIdType A
, vtkIdType B
, vtkIdType C
, int bc
) {
205 vtkIdType newCellId
= a_grid
->InsertNextCell(VTK_TRIANGLE
, npts
, pts
);
206 EG_VTKDCC(vtkIntArray
, cell_code
, a_grid
, "cell_code");
207 cell_code
->SetValue(newCellId
, bc
);
211 ///////////////////////////////////////////
213 int getShortestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
214 vtkIdType N_pts
, *pts
;
215 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
216 vec3_t
* x
= new vec3_t
[N_pts
];
217 for (int i
= 0; i
< N_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
219 double minlen
= (x
[1] - x
[0]).abs();
220 for (int i
= 1; i
< N_pts
; i
++) {
221 double len
= (x
[(i
+1)%N_pts
] - x
[i
]).abs();
231 int getLongestSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
) {
232 vtkIdType N_pts
, *pts
;
233 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
234 vec3_t
* x
= new vec3_t
[N_pts
];
235 for (int i
= 0; i
< N_pts
; i
++) a_grid
->GetPoints()->GetPoint(pts
[i
], x
[i
].data());
237 double maxlen
= (x
[1] - x
[0]).abs();
238 cout
<< "maxlen=" << maxlen
<< endl
;
239 for (int i
= 1; i
< N_pts
; i
++) {
240 double len
= (x
[(i
+1)%N_pts
] - x
[i
]).abs();
241 cout
<< "len[" << i
<< "]=" << len
<< endl
;
251 int getSide(vtkIdType a_id_cell
, vtkUnstructuredGrid
* a_grid
, vtkIdType a_id_node1
, vtkIdType a_id_node2
) {
252 vtkIdType N_pts
, *pts
;
253 a_grid
->GetCellPoints(a_id_cell
, N_pts
, pts
);
254 QVector
<vtkIdType
> edge(2);
257 for (int i
= 0; i
< N_pts
; i
++) {
258 if (pts
[i
] == a_id_node1
) { edge
[0] = i
; n
++;}
259 if (pts
[i
] == a_id_node2
) { edge
[1] = i
; n
++;}
265 qSort(edge
.begin(), edge
.end());
266 if (edge
[0] == 0 && edge
[1] == N_pts
- 1) return(N_pts
- 1);
267 else return(edge
[0]);
269 ///////////////////////////////////////////
271 QString
cell2str(vtkIdType id_cell
, vtkUnstructuredGrid
* grid
) {
274 QString txt
= "id_cell=" + tmp
;
276 vtkIdType N_pts
, *pts
;
277 grid
->GetCellPoints(id_cell
, N_pts
, pts
);
280 for (int i_pts
= 0; i_pts
< N_pts
; ++i_pts
) {
281 tmp
.setNum(pts
[i_pts
]);
283 if (i_pts
< N_pts
- 1) {
293 ///////////////////////////////////////////
295 pair
<vtkIdType
, vtkIdType
> OrderedPair(vtkIdType a
, vtkIdType b
) {
296 vtkIdType x
= min(a
, b
);
297 vtkIdType y
= max(a
, b
);
298 return(pair
<vtkIdType
, vtkIdType
>(x
, y
));
301 const char* VertexType2Str(char T
) {
302 if (T
== VTK_SIMPLE_VERTEX
) return("VTK_SIMPLE_VERTEX");
303 if (T
== VTK_FIXED_VERTEX
) return("VTK_FIXED_VERTEX");
304 if (T
== VTK_FEATURE_EDGE_VERTEX
) return("VTK_FEATURE_EDGE_VERTEX");
305 if (T
== VTK_BOUNDARY_EDGE_VERTEX
) return("VTK_BOUNDARY_EDGE_VERTEX");
306 else return("Unknown vertex type");
309 char Str2VertexType(QString S
) {
310 if (S
== "VTK_SIMPLE_VERTEX") return(VTK_SIMPLE_VERTEX
);
311 if (S
== "VTK_FIXED_VERTEX") return(VTK_FIXED_VERTEX
);
312 if (S
== "VTK_FEATURE_EDGE_VERTEX") return(VTK_FEATURE_EDGE_VERTEX
);
313 if (S
== "VTK_BOUNDARY_EDGE_VERTEX") return(VTK_BOUNDARY_EDGE_VERTEX
);
314 else return((char) - 1);
317 bool checkVector(vec3_t V
)
319 for (int i
= 0; i
< 3; i
++) {
330 bool checkVector(vec2_t V
)
332 for (int i
= 0; i
< 2; i
++) {
343 QDebug
operator<<(QDebug dbg
, const vec3_t
&v
)
345 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ", " << v
[2] << ")";
349 QDebug
operator<<(QDebug dbg
, const vec2_t
&v
)
351 dbg
.nospace() << "(" << v
[0] << ", " << v
[1] << ")";
355 QDebug
operator<<(QDebug dbg
, const dcmplx
&c
)
357 dbg
.nospace() << real(c
)<<" + "<<imag(c
)<<" *i";
361 dcmplx
complex_pow(dcmplx base
, double power
)
364 double alpha
= atan2(imag(base
),real(base
));
365 return pow(abs(base
),power
)*exp(power
*alpha
*i
);
368 #define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0)
370 int poly_solve_cubic(double a
, double b
, double c
, double * x0
, double * x1
, double * x2
)
372 double q
= (a
* a
- 3 * b
);
373 double r
= (2 * a
* a
* a
- 9 * a
* b
+ 27 * c
);
378 double Q3
= Q
* Q
* Q
;
381 double CR2
= 729 * r
* r
;
382 double CQ3
= 2916 * q
* q
* q
;
384 if (R
== 0 && Q
== 0)
393 // this test is actually R2 == Q3, written in a form suitable
394 // for exact computation with integers
396 // Due to finite precision some double roots may be missed, and
397 // considered to be a pair of complex roots z = x +/- epsilon i
398 // close to the real axis.
400 double sqrtQ
= sqrt (Q
);
404 *x0
= -2 * sqrtQ
- a
/ 3;
408 *x0
= - sqrtQ
- a
/ 3;
409 *x1
= - sqrtQ
- a
/ 3;
410 *x2
= 2 * sqrtQ
- a
/ 3;
413 } else if (CR2
< CQ3
) { // equivalent to R2 < Q3
414 double sqrtQ
= sqrt (Q
);
415 double sqrtQ3
= sqrtQ
* sqrtQ
* sqrtQ
;
416 double theta
= acos (R
/ sqrtQ3
);
417 double norm
= -2 * sqrtQ
;
418 *x0
= norm
* cos (theta
/ 3) - a
/ 3;
419 *x1
= norm
* cos ((theta
+ 2.0 * M_PI
) / 3) - a
/ 3;
420 *x2
= norm
* cos ((theta
- 2.0 * M_PI
) / 3) - a
/ 3;
422 // Sort *x0, *x1, *x2 into increasing order
437 double sgnR
= (R
>= 0 ? 1 : -1);
438 double A
= -sgnR
* pow (fabs (R
) + sqrt (R2
- Q3
), 1.0/3.0);
445 // a x^2 + b x + c = 0
446 int poly_solve_quadratic(double a
, double b
, double c
, double * x0
, double * x1
)
456 double delta
= pow(b
, 2) - 4 * a
* c
;
460 *x0
= (-b
+ sqrt(delta
)) / (2 * a
);
461 *x1
= (-b
- sqrt(delta
)) / (2 * a
);