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 "stlreader.h"
22 #include "correctsurfaceorientation.h"
25 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
26 #include <vtkIdList.h>
27 #include <vtkSTLReader.h>
28 #include <vtkCleanPolyData.h>
29 #include <vtkFeatureEdges.h>
32 #include <QInputDialog>
33 #include <vtkSmartPointer.h>
35 #include "guimainwindow.h"
36 #include "fixcadgeometry.h"
38 StlReader::StlReader()
40 setFormat("STL files(*.stl *.STL)");
42 m_FileNameSet
= false;
43 m_MaxNumCleanIter
= 20;
46 void StlReader::setFileName(QString file_name
)
48 m_FileName
= file_name
;
49 cout
<< qPrintable(m_FileName
) << endl
;
53 void StlReader::operate()
55 QFileInfo
file_info(GuiMainWindow::pointer()->getFilename());
58 file_name
= m_FileName
;
60 readInputFileName(file_info
.completeBaseName() + ".stl");
62 file_name
= getFileName();
68 EG_VTKSP(vtkSTLReader
, stl
);
70 stl
->SetFileName(qPrintable(file_name
));
72 EG_VTKSP(vtkPolyData
, poly
);
73 poly
->DeepCopy(stl
->GetOutput());
76 for (vtkIdType cellId
= 0; cellId
< poly
->GetNumberOfCells(); ++cellId
) {
77 EG_GET_CELL(cellId
, poly
);
78 for (int i
= 0; i
< num_pts
; ++i
) {
80 poly
->GetPoints()->GetPoint(pts
[i
], x1
.data());
81 if (i
== num_pts
- 1) {
82 poly
->GetPoints()->GetPoint(pts
[0], x2
.data());
84 poly
->GetPoints()->GetPoint(pts
[i
+1], x2
.data());
86 L
= min(L
, (x1
-x2
).abs());
89 if (m_Tolerance
< 0) {
90 m_Tolerance
= QInputDialog::getText(NULL
, "enter STL tolerance", "tolerance", QLineEdit::Normal
, "1e-10").toDouble();
92 cout
<< "cleaning STL geometry:" << endl
;
93 EG_VTKSP(vtkCleanPolyData
, poly_clean
);
94 EG_VTKSP(vtkFeatureEdges
, topo_check
);
96 poly
->GetBounds(bounds
);
97 poly_clean
->ToleranceIsAbsoluteOn();
98 poly_clean
->ConvertLinesToPointsOn();
99 poly_clean
->ConvertPolysToLinesOn();
100 poly_clean
->SetInputData(poly
);
101 topo_check
->SetInputConnection(poly_clean
->GetOutputPort());
102 topo_check
->BoundaryEdgesOn();
103 topo_check
->ManifoldEdgesOff();
104 topo_check
->FeatureEdgesOff();
105 topo_check
->NonManifoldEdgesOn();
110 cout
<< " tolerance = " << m_Tolerance
<< endl
;
111 poly_clean
->SetAbsoluteTolerance(m_Tolerance
);
112 topo_check
->Update();
114 check_passed
= topo_check
->GetOutput()->GetNumberOfPoints() == 0;
115 } while (m_Tolerance
< 1 && !check_passed
&& count
< m_MaxNumCleanIter
);
117 cout
<< "The STL geometry seems to be clean." << endl
;
119 cout
<< "The STL geometry could not be cleaned." << endl
;
121 // with a tolerance of " << 0.5*L << endl;
122 EG_VTKSP(vtkEgPolyDataToUnstructuredGridFilter
, poly2ugrid
);
123 poly2ugrid
->SetInputConnection(poly_clean
->GetOutputPort());
124 poly2ugrid
->Update();
126 allocateGrid(m_Grid
, poly2ugrid
->GetOutput()->GetNumberOfCells(), poly2ugrid
->GetOutput()->GetNumberOfPoints());
127 for (vtkIdType id_node
= 0; id_node
< poly2ugrid
->GetOutput()->GetNumberOfPoints(); ++id_node
) {
129 poly2ugrid
->GetOutput()->GetPoints()->GetPoint(id_node
, x
.data());
130 m_Grid
->GetPoints()->SetPoint(id_node
, x
.data());
132 for (vtkIdType id_cell
= 0; id_cell
< poly2ugrid
->GetOutput()->GetNumberOfCells(); ++id_cell
) {
133 vtkSmartPointer
<vtkIdList
> pts
= vtkSmartPointer
<vtkIdList
>::New();
134 vtkIdType type_cell
= poly2ugrid
->GetOutput()->GetCellType(id_cell
);
135 poly2ugrid
->GetOutput()->GetCellPoints(id_cell
, pts
);
136 m_Grid
->InsertNextCell(type_cell
, pts
);
139 EG_VTKDCC(vtkIntArray
, bc
, m_Grid
, "cell_code");
140 EG_VTKDCC(vtkIntArray
, orgdir
, m_Grid
, "cell_orgdir");
141 EG_VTKDCC(vtkIntArray
, voldir
, m_Grid
, "cell_voldir");
142 EG_VTKDCC(vtkIntArray
, curdir
, m_Grid
, "cell_curdir");
143 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
144 bc
->SetValue(id_cell
, 1);
145 orgdir
->SetValue(id_cell
, 0);
146 voldir
->SetValue(id_cell
, 0);
147 curdir
->SetValue(id_cell
, 0);
150 CorrectSurfaceOrientation corr_surf
;
151 corr_surf
.setGrid(m_Grid
);
153 FixCadGeometry cad_fix
;
154 cad_fix
.setGrid(m_Grid
);