fixed edge display for volume cells
[engrid-github.git] / src / libengrid / brlcadreader.cpp
blob9ccbb12977a2a5d0ac8e838ca5ac1a045fd56a8c
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
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. +
11 // + +
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. +
16 // + +
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/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #ifdef BRLCAD_SUPPORT
24 #include "brlcadreader.h"
25 #include "vtkEgPolyDataToUnstructuredGridFilter.h"
26 #include "setboundarycode.h"
27 #include "facefinder.h"
28 #include "guimainwindow.h"
29 #include "guibrlcadimportdialogue.h"
30 #include "createcadtesselation.h"
31 #include "stlreader.h"
32 #include "brlcadinterface.h"
34 #include <vtkSTLReader.h>
36 BrlcadReader::BrlcadReader()
38 EG_TYPENAME;
39 setFormat("BRL-CAD database files(*.g)");
40 setExtension(".g");
43 void BrlcadReader::processStlFile(QString file_name, bool append_to_list)
45 vtkSTLReader *stl = vtkSTLReader::New();
46 stl->MergingOn();
47 stl->SetFileName(file_name.toAscii().data());
48 stl->Update();
49 EG_VTKSP(vtkPolyData, poly);
50 poly->DeepCopy(stl->GetOutput());
51 poly->BuildCells();
52 double L = 1e99;
53 for (vtkIdType cellId = 0; cellId < poly->GetNumberOfCells(); ++cellId) {
54 vtkIdType *pts, Npts;
55 poly->GetCellPoints(cellId, Npts, pts);
56 for (int i = 0; i < Npts; ++i) {
57 vec3_t x1, x2;
58 poly->GetPoints()->GetPoint(pts[i], x1.data());
59 if (i == Npts - 1) {
60 poly->GetPoints()->GetPoint(pts[0], x2.data());
61 } else {
62 poly->GetPoints()->GetPoint(pts[i+1], x2.data());
64 L = min(L, (x1-x2).abs());
67 EG_VTKSP(vtkEgPolyDataToUnstructuredGridFilter, poly2ugrid);
68 poly2ugrid->SetInput(poly);
69 poly2ugrid->Update();
71 EG_VTKSP(vtkUnstructuredGrid, grid);
72 allocateGrid(grid, poly2ugrid->GetOutput()->GetNumberOfCells(), poly2ugrid->GetOutput()->GetNumberOfPoints());
73 for (vtkIdType id_node = 0; id_node < poly2ugrid->GetOutput()->GetNumberOfPoints(); ++id_node) {
74 vec3_t x;
75 poly2ugrid->GetOutput()->GetPoints()->GetPoint(id_node, x.data());
76 grid->GetPoints()->SetPoint(id_node, x.data());
78 for (vtkIdType id_cell = 0; id_cell < poly2ugrid->GetOutput()->GetNumberOfCells(); ++id_cell) {
79 vtkIdType N_pts, *pts;
80 vtkIdType type_cell = poly2ugrid->GetOutput()->GetCellType(id_cell);
81 poly2ugrid->GetOutput()->GetCellPoints(id_cell, N_pts, pts);
82 grid->InsertNextCell(type_cell, N_pts, pts);
85 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
86 EG_VTKDCC(vtkIntArray, orgdir, grid, "cell_orgdir");
87 EG_VTKDCC(vtkIntArray, voldir, grid, "cell_voldir");
88 EG_VTKDCC(vtkIntArray, curdir, grid, "cell_curdir");
89 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
90 cell_code->SetValue(id_cell, 9999);
91 orgdir->SetValue(id_cell, 0);
92 voldir->SetValue(id_cell, 0);
93 curdir->SetValue(id_cell, 0);
96 if (append_to_list) {
97 SetBoundaryCode set_bc;
98 set_bc.setGrid(grid);
99 set_bc.setAllSurfaceCells();
100 int bc_max = 1;
101 bool done = false;
102 do {
103 vtkIdType id_start = -1;
104 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
105 if (cell_code->GetValue(id_cell) == 9999) {
106 id_start = id_cell;
107 break;
110 if (id_start == -1) {
111 done = true;
112 } else {
113 set_bc.setFeatureAngle(20.0);
114 set_bc.setBC(bc_max);
115 set_bc.setProcessAll(true);
116 set_bc.setSelectAllVisible(false);
117 set_bc.setOnlyPickedCell(false);
118 set_bc.setOnlyPickedCellAndNeighbours(false);
119 set_bc.setStart(id_start);
120 set_bc();
121 ++bc_max;
123 } while (!done);
124 cout << "file: " << qPrintable(file_name) << endl;
125 for (int bc = 1; bc < bc_max; ++bc) {
126 QList<vtkIdType> cells;
127 for (vtkIdType id_cell = 0; id_cell < grid->GetNumberOfCells(); ++id_cell) {
128 if (cell_code->GetValue(id_cell) == bc) {
129 cells.append(id_cell);
132 vtkUnstructuredGrid *new_grid = vtkUnstructuredGrid::New();
133 QString bc_txt;
134 bc_txt.setNum(bc);
135 if (bc_max >= 10) {
136 bc_txt = bc_txt.rightJustified(2, '0');
138 QFileInfo file_info(file_name);
139 m_BCNames[new_grid] = file_info.baseName() + "." + bc_txt;
140 cout << " " << qPrintable(file_info.baseName() + "." + bc_txt) << endl;
141 makeCopy(grid, new_grid, cells);
142 m_Grids.append(new_grid);
144 } else {
145 makeCopy(grid, m_Grid);
149 void BrlcadReader::findBoundaryCodes()
151 int num_grids = m_Grids.size();
152 QVector<vtkUnstructuredGrid*> grids(num_grids);
153 qCopy(m_Grids.begin(), m_Grids.end(), grids.begin());
154 QVector<FaceFinder> finders(num_grids);
155 for (int i_grid = 0; i_grid < num_grids; ++i_grid) {
156 finders[i_grid].setGrid(grids[i_grid]);
158 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
159 bool has_errors = false;
160 QVector<bool> bc_exists(num_grids, false);
161 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
162 int best_grid = -1;
163 double L_min = 1e99;
164 vec3_t x1 = cellCentre(m_Grid, id_cell);
165 for (int i_grid = 0; i_grid < num_grids; ++i_grid) {
166 double L = 1e99;
167 vtkIdType id_closest = finders[i_grid].getClosestFace(x1, L);
168 vec3_t x2(-999,-999,-999);
169 if (id_closest != -1) x2 = cellCentre(m_Grids[i_grid], id_closest);
170 if (id_closest != -1) {
171 if (L < L_min) {
172 best_grid = i_grid;
173 L_min = L;
177 if (best_grid == -1) {
178 has_errors = true;
179 cell_code->SetValue(id_cell, 9999);
180 } else {
181 bc_exists[best_grid] = true;
182 cell_code->SetValue(id_cell, best_grid + 1);
185 GuiMainWindow::pointer()->clearBCs();
186 int bc_max = 1;
187 QVector<int> bc_map(num_grids+1,9999);
188 m_BC2GridIndex.clear();
189 for (int i_grid = 0; i_grid < num_grids; ++i_grid) {
190 if (bc_exists[i_grid]) {
191 bc_map[i_grid+1] = bc_max;
192 GuiMainWindow::pointer()->addBC(bc_max, BoundaryCondition(m_BCNames[grids[i_grid]], "patch"));
193 m_BC2GridIndex[bc_max] = i_grid;
194 ++bc_max;
197 for (vtkIdType id_cell = 0; id_cell < m_Grid->GetNumberOfCells(); ++id_cell) {
198 if (cell_code->GetValue(id_cell) != 9999) {
199 cell_code->SetValue(id_cell, bc_map[cell_code->GetValue(id_cell)]);
202 if (has_errors) {
203 GuiMainWindow::pointer()->addBC(9999, BoundaryCondition("error-faces", "patch"));
205 GuiMainWindow::pointer()->updateBoundaryCodes(true);
208 void BrlcadReader::createBackgroundGeometry()
210 // make a backup of the existing grid
211 EG_VTKSP(vtkUnstructuredGrid, backup_grid);
212 makeCopy(m_Grid, backup_grid);
214 QSet<int> bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
216 // count total number of nodes and faces for background geometry
217 int num_nodes = 0;
218 int num_faces = 0;
219 foreach (int bc, bcs) {
220 int i_grid = m_BC2GridIndex[bc];
221 num_nodes += m_Grids[i_grid]->GetNumberOfPoints();
222 num_faces += m_Grids[i_grid]->GetNumberOfCells();
224 allocateGrid(m_Grid, num_faces, num_nodes);
225 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
227 // copy STL grids into background grid
228 vtkIdType id_node_max = 0;
229 foreach (int bc, bcs) {
230 int i_grid = m_BC2GridIndex[bc];
232 // copy nodes
233 QVector<int> local2global(m_Grids[i_grid]->GetNumberOfPoints());
234 for (vtkIdType id_node = 0; id_node < m_Grids[i_grid]->GetNumberOfPoints(); ++id_node) {
235 local2global[id_node] = id_node_max;
236 vec3_t x;
237 m_Grids[i_grid]->GetPoint(id_node, x.data());
238 m_Grid->GetPoints()->SetPoint(id_node_max, x.data());
239 ++id_node_max;
242 // copy faces
243 for (vtkIdType id_face = 0; id_face < m_Grids[i_grid]->GetNumberOfCells(); ++id_face) {
244 vtkIdType *pts, N_pts;
245 m_Grids[i_grid]->GetCellPoints(id_face, N_pts, pts);
246 QVector<vtkIdType> new_pts(N_pts);
247 for (int i = 0; i < N_pts; ++i) {
248 new_pts[i] = local2global[pts[i]];
250 vtkIdType id_new_face = m_Grid->InsertNextCell(m_Grids[i_grid]->GetCellType(id_face), N_pts, new_pts.data());
251 cell_code->SetValue(id_new_face, bc);
255 // store background grid for surface projection
256 GuiMainWindow::pointer()->storeCadInterfaces();
258 // restore the initial grid from the backup copy
259 makeCopy(backup_grid, m_Grid);
262 void BrlcadReader::operateOld()
264 readInputDirectory("Select BRL-CAD export directory");
265 if (isValid()) {
266 QDir dir(getFileName());
267 QStringList filters;
268 filters << "*.s.stl";
269 QStringList file_names = dir.entryList(filters);
270 foreach (QString file_name, file_names) {
271 processStlFile(dir.path() + "/"+ file_name);
273 processStlFile(dir.path() + "/volume.stl", false);
274 findBoundaryCodes();
275 createBackgroundGeometry();
279 void BrlcadReader::operate()
281 try {
282 QFileInfo file_info(GuiMainWindow::pointer()->getFilename());
283 readInputFileName(file_info.completeBaseName() + ".g");
284 if (isValid()) {
285 GuiBrlCadImportDialogue dlg;
286 dlg.prepare(getFileName());
287 if (dlg.exec()) {
288 BrlCadInterface* brlcad_interface = new BrlCadInterface(getFileName(), dlg.selectedObject());
289 if (dlg.useStlFile()) {
290 StlReader stl;
291 stl.setFileName(dlg.stlFileName());
292 stl();
293 } else if (dlg.hasSelectedObject()) {
294 CreateCadTesselation tess(brlcad_interface);
295 tess.setScanMemory(dlg.scanMemory());
296 tess.setPreservationType(dlg.preservationType());
297 tess.setSmoothingIterations(dlg.smoothingIterations());
298 tess.setSmallestFeatureSize(dlg.smallestFeatureSize());
299 tess.setSmallestResolution(dlg.smallestResolution());
300 tess.setTargetReduction(dlg.reduction());
301 tess();
303 GuiMainWindow::pointer()->setUniversalCadInterface(brlcad_interface);
306 } catch (Error err) {
307 err.display();
311 #endif // BRLCAD_SUPPORT