Merge branch 'master' of ssh://swordfish/srv/www/htdocs/git/engrid
[engrid.git] / src / stlreader.cpp
blob691cb24be0e4218409413d7b5cdeb91ed3133964
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008,2009 Oliver Gloth +
7 // + +
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. +
12 // + +
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. +
17 // + +
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/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "stlreader.h"
24 #include "correctsurfaceorientation.h"
26 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
27 #include <vtkSTLReader.h>
28 #include <vtkCleanPolyData.h>
29 #include <vtkFeatureEdges.h>
31 #include <QFileInfo>
32 #include <QInputDialog>
34 #include "guimainwindow.h"
35 #include "fixcadgeometry.h"
37 StlReader::StlReader()
39 setFormat("STL files(*.stl *.STL)");
42 void StlReader::operate()
44 QFileInfo file_info(GuiMainWindow::pointer()->getFilename());
45 readInputFileName(file_info.completeBaseName() + ".stl");
46 if (isValid()) {
47 vtkSTLReader *stl = vtkSTLReader::New();
48 stl->MergingOn();
49 stl->SetFileName(getCFileName());
50 stl->Update();
51 EG_VTKSP(vtkPolyData, poly);
52 poly->DeepCopy(stl->GetOutput());
53 poly->BuildCells();
54 double L = 1e99;
55 for (vtkIdType cellId = 0; cellId < poly->GetNumberOfCells(); ++cellId) {
56 vtkIdType *pts, Npts;
57 poly->GetCellPoints(cellId, Npts, pts);
58 for (int i = 0; i < Npts; ++i) {
59 vec3_t x1, x2;
60 poly->GetPoints()->GetPoint(pts[i], x1.data());
61 if (i == Npts - 1) {
62 poly->GetPoints()->GetPoint(pts[0], x2.data());
63 } else {
64 poly->GetPoints()->GetPoint(pts[i+1], x2.data());
66 L = min(L, (x1-x2).abs());
69 double tol = 1e-10;//0.01*L;
70 tol = QInputDialog::getText(NULL, "enter STL tolerance", "tolerance", QLineEdit::Normal, "1e-10").toDouble();
71 cout << "cleaning STL geometry:" << endl;
72 EG_VTKSP(vtkCleanPolyData, poly_clean);
73 EG_VTKSP(vtkFeatureEdges, topo_check);
74 double bounds[6];
75 poly->GetBounds(bounds);
76 poly_clean->ToleranceIsAbsoluteOn();
77 poly_clean->ConvertLinesToPointsOn();
78 poly_clean->ConvertPolysToLinesOn();
79 poly_clean->SetInput(poly);
80 topo_check->SetInput(poly_clean->GetOutput());
81 topo_check->BoundaryEdgesOn();
82 topo_check->ManifoldEdgesOff();
83 topo_check->FeatureEdgesOff();
84 topo_check->NonManifoldEdgesOn();
85 bool check_passed;
86 do {
87 cout << " tolerance = " << tol << endl;
88 poly_clean->SetAbsoluteTolerance(tol);
89 topo_check->Update();
90 tol *= 1.5;
91 check_passed = topo_check->GetOutput()->GetNumberOfPoints() == 0;
92 } while (tol < 1 && !check_passed);
93 if (check_passed) {
94 cout << "The STL geometry seems to be clean." << endl;
95 } else {
96 cout << "The STL geometry could not be cleaned." << endl;
98 // with a tolerance of " << 0.5*L << endl;
99 EG_VTKSP(vtkEgPolyDataToUnstructuredGridFilter, poly2ugrid);
100 poly2ugrid->SetInput(poly_clean->GetOutput());
101 poly2ugrid->Update();
103 allocateGrid(m_Grid, poly2ugrid->GetOutput()->GetNumberOfCells(), poly2ugrid->GetOutput()->GetNumberOfPoints());
104 for (vtkIdType id_node = 0; id_node < poly2ugrid->GetOutput()->GetNumberOfPoints(); ++id_node) {
105 vec3_t x;
106 poly2ugrid->GetOutput()->GetPoints()->GetPoint(id_node, x.data());
107 m_Grid->GetPoints()->SetPoint(id_node, x.data());
109 for (vtkIdType id_cell = 0; id_cell < poly2ugrid->GetOutput()->GetNumberOfCells(); ++id_cell) {
110 vtkIdType N_pts, *pts;
111 vtkIdType type_cell = poly2ugrid->GetOutput()->GetCellType(id_cell);
112 poly2ugrid->GetOutput()->GetCellPoints(id_cell, N_pts, pts);
113 m_Grid->InsertNextCell(type_cell, N_pts, pts);
116 EG_VTKDCC(vtkIntArray, bc, m_Grid, "cell_code");
117 EG_VTKDCC(vtkIntArray, orgdir, m_Grid, "cell_orgdir");
118 EG_VTKDCC(vtkIntArray, voldir, m_Grid, "cell_voldir");
119 EG_VTKDCC(vtkIntArray, curdir, m_Grid, "cell_curdir");
120 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
121 bc->SetValue(id_cell, 999);
122 orgdir->SetValue(id_cell, 0);
123 voldir->SetValue(id_cell, 0);
124 curdir->SetValue(id_cell, 0);
126 if (check_passed) {
127 CorrectSurfaceOrientation corr_surf;
128 corr_surf.setGrid(m_Grid);
129 corr_surf();
130 FixCadGeometry cad_fix;
131 cad_fix.setGrid(m_Grid);
132 cad_fix();