fixed edge display for volume cells
[engrid-github.git] / src / libengrid / blenderreader.cpp
blob904ca6ac27eacbb91f550f5299404eb3cd2b510f
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 #include "blenderreader.h"
23 #include "guimainwindow.h"
24 #include "pointfinder.h"
26 BlenderReader::BlenderReader()
28 setFormat("Blender/Engrid files(*.begc *.BEGC)");
29 getSet("General", "tolerance for importing geometries (% of smallest edge length)", 0.1, m_RelativeTolerance);
30 m_RelativeTolerance *= 1e-2;
31 m_Append = false;
34 void BlenderReader::operate()
36 try {
37 QFileInfo file_info(GuiMainWindow::pointer()->getFilename());
38 readInputFileName(file_info.completeBaseName() + ".begc", false);
39 if (isValid()) {
40 // read raw data from exported file
41 QFile file(getFileName());
42 file.open(QIODevice::ReadOnly | QIODevice::Text);
43 QTextStream f(&file);
44 QList<vec3_t> rnodes;
45 QList<QVector<int> > rfaces;
46 int num_parts;
47 f >> num_parts;
48 QVector<QString> part_name(num_parts);
49 for (int i_part = 0; i_part < num_parts; ++i_part) {
50 f >> part_name[i_part];
52 QVector<QString> sorted_part_name = part_name;
53 qSort(sorted_part_name);
54 QVector<int> part_bc(part_name.size());
55 for (int i_part = 0; i_part < num_parts; ++i_part) {
56 part_bc[i_part] = sorted_part_name.indexOf(part_name[i_part]) + 1;
58 for (int i_part = 0; i_part < num_parts; ++i_part) {
59 int num_nodes, num_faces;
60 f >> num_nodes >> num_faces;
61 for (int i = 0; i < num_nodes; ++i) {
62 vec3_t x;
63 f >> x[0] >> x[1] >> x[2];
64 rnodes.push_back(x);
66 for (int i = 0; i < num_faces; ++i) {
67 int N;
68 f >> N;
69 QVector<int> face(N+1);
70 face[0] = i_part;
71 for (int j = 0; j < N; ++j) {
72 f >> face[j+1];
74 rfaces.push_back(face);
77 QVector<vec3_t> nodes(rnodes.size());
78 qCopy(rnodes.begin(), rnodes.end(), nodes.begin());
79 QVector<QVector<int> > faces(rfaces.size());
80 qCopy(rfaces.begin(), rfaces.end(), faces.begin());
82 // find smallest edge length
83 double L = 1e99;
84 foreach (QVector<int> face, faces) {
85 for (int i = 1; i < face.size(); ++i) {
86 int n1 = face[i];
87 int n2 = face[1];
88 if (i < face.size() - 1) {
89 n2 = face[i+1];
91 double l = (nodes[n1] - nodes[n2]).abs();
92 L = min(l, L);
96 cout << "smallest edge length is " << L << endl;
98 // delete duplicate nodes
99 PointFinder finder;
100 finder.setPoints(nodes);
101 QList<vec3_t> non_dup;
102 QVector<int> o2n(nodes.size());
103 int num_non_dup = 0;
104 for (int i = 0; i < nodes.size(); ++i) {
105 o2n[i] = num_non_dup;
106 bool dup = false;
107 QVector<int> close_points;
108 finder.getClosePoints(nodes[i], close_points);
109 foreach (int j, close_points) {
110 if (i > j) {
111 double l = (nodes[i] - nodes[j]).abs();
112 if (l < m_RelativeTolerance*L || l == 0) {
113 o2n[i] = o2n[j];
114 dup = true;
115 break;
119 if (!dup) {
120 non_dup.push_back(nodes[i]);
121 ++num_non_dup;
125 EG_VTKSP(vtkUnstructuredGrid, new_grid);
127 allocateGrid(new_grid, faces.size(), non_dup.size());
128 EG_VTKDCC(vtkIntArray, cell_code, new_grid, "cell_code");
129 EG_VTKDCC(vtkIntArray, orgdir, new_grid, "cell_orgdir");
130 EG_VTKDCC(vtkIntArray, voldir, new_grid, "cell_voldir");
131 EG_VTKDCC(vtkIntArray, curdir, new_grid, "cell_curdir");
132 vtkIdType id_node = 0;
133 foreach (vec3_t x, non_dup) {
134 new_grid->GetPoints()->SetPoint(id_node, x.data());
135 ++id_node;
138 foreach (QVector<int> face, faces) {
139 if (face.size() == 4) {
140 vtkIdType pts[3];
141 pts[0] = o2n[face[1]];
142 pts[1] = o2n[face[2]];
143 pts[2] = o2n[face[3]];
144 vtkIdType id_cell = new_grid->InsertNextCell(VTK_TRIANGLE, 3, pts);
145 cell_code->SetValue(id_cell, part_bc[face[0]]);
146 orgdir->SetValue(id_cell, 0);
147 voldir->SetValue(id_cell, 0);
148 curdir->SetValue(id_cell, 0);
150 if (face.size() == 5) {
151 vtkIdType pts[4];
152 pts[0] = o2n[face[1]];
153 pts[1] = o2n[face[2]];
154 pts[2] = o2n[face[3]];
155 pts[3] = o2n[face[4]];
156 vtkIdType id_cell = new_grid->InsertNextCell(VTK_QUAD, 4, pts);
157 cell_code->SetValue(id_cell, part_bc[face[0]]);
158 orgdir->SetValue(id_cell, 0);
159 voldir->SetValue(id_cell, 0);
160 curdir->SetValue(id_cell, 0);
164 if (m_Append) {
165 EG_BUG;
166 MeshPartition new_part(new_grid);
167 new_part.setAllCells();
168 m_Part.addPartition(new_part);
169 } else {
170 makeCopy(new_grid, m_Grid);
173 UpdateNodeIndex(m_Grid);
174 UpdateCellIndex(m_Grid);
176 // check and set the boundary names if required
177 int update_required = true;
178 QSet<int> old_bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
179 if (old_bcs.size() == part_name.size()) {
180 QSet<QString> old_names;
181 foreach (int bc, old_bcs) {
182 old_names.insert(GuiMainWindow::pointer()->getBC(bc).getName());
184 QSet<QString> new_names;
185 foreach (QString name, part_name) {
186 new_names.insert(name);
188 if (old_names == new_names) {
189 update_required = false;
190 cout << "no update required" << endl;
193 if (update_required) {
194 GuiMainWindow::pointer()->resetXmlDoc();
195 GuiMainWindow::pointer()->clearBCs();
196 for (int i_part = 0; i_part < part_name.size(); ++i_part) {
197 GuiMainWindow::pointer()->addBC(part_bc[i_part], BoundaryCondition(part_name[i_part], "patch"));
202 } catch (Error err) {
203 err.display();