better collision detection
[engrid-github.git] / src / libengrid / fixstl.cpp
blob91aba69c8a5e31793a44534c2142cdfbdd112148
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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "fixstl.h"
22 #include "deletetetras.h"
23 #include "uniquevector.h"
25 #include <vtkDelaunay3D.h>
26 #include <vtkMergePoints.h>
28 FixSTL::FixSTL()
32 void FixSTL::createTriangles(const QList<QVector<vtkIdType> > &triangles, vtkUnstructuredGrid *tetra_grid)
34 QVector<vtkIdType> cells, nodes;
35 QVector<int> _nodes;
36 getAllCells(cells, tetra_grid);
37 getNodesFromCells(cells, nodes, tetra_grid);
38 createNodeMapping(nodes, _nodes, tetra_grid);
39 QVector<bool> active(nodes.size(),false);
40 foreach (QVector<vtkIdType> T, triangles) {
41 active[_nodes[T[0]]] = true;
42 active[_nodes[T[1]]] = true;
43 active[_nodes[T[2]]] = true;
45 int N_nodes = 0;
46 QVector<vtkIdType> old2new(nodes.size());
47 for (int i_nodes = 0; i_nodes < nodes.size(); ++i_nodes) {
48 if (active[i_nodes]) {
49 old2new[i_nodes] = N_nodes;
50 ++N_nodes;
53 allocateGrid(m_Grid, triangles.size(), N_nodes);
54 cout << triangles.size() << ',' << N_nodes << endl;
55 vtkIdType id_node = 0;
56 for (int i_nodes = 0; i_nodes < nodes.size(); ++i_nodes) {
57 if (active[i_nodes]) {
58 vec3_t x;
59 tetra_grid->GetPoint(nodes[i_nodes],x.data());
60 m_Grid->GetPoints()->SetPoint(id_node,x.data());
61 copyNodeData(tetra_grid, nodes[i_nodes], m_Grid, id_node);
62 ++id_node;
65 EG_VTKDCC(vtkIntArray, bc, m_Grid, "cell_code");
66 foreach (QVector<vtkIdType> T, triangles) {
67 vtkIdType pts[3];
68 for (int i_T = 0; i_T < 3; ++i_T) {
69 pts[i_T] = old2new[T[i_T]];
71 vtkIdType id_cell = m_Grid->InsertNextCell(VTK_TRIANGLE,3,pts);
72 bc->SetValue(id_cell,1);
76 void FixSTL::operate()
78 cout << "checking and repairing surface triangulation" << endl;
79 EG_VTKSP(vtkUnstructuredGrid, pts_grid);
80 QVector<vtkIdType> faces, nodes;
81 getAllSurfaceCells(faces, m_Grid);
82 getNodesFromCells(faces, nodes, m_Grid);
83 allocateGrid(pts_grid, 0, nodes.size());
84 foreach (vtkIdType id_node, nodes) {
85 vec3_t x;
86 m_Grid->GetPoint(id_node,x.data());
87 pts_grid->GetPoints()->SetPoint(id_node,x.data());
88 copyNodeData(m_Grid, id_node, pts_grid, id_node);
90 EG_VTKSP(vtkDelaunay3D, delaunay);
91 delaunay->SetInputData(pts_grid);
92 delaunay->Update();
93 EG_VTKSP(vtkUnstructuredGrid, tetra_grid);
94 makeCopy(delaunay->GetOutput(), tetra_grid);
95 QVector<vtkIdType> tetras;
96 getAllCellsOfType(VTK_TETRA, tetras, tetra_grid);
97 QVector<QVector<int> > t2t;
98 QList<QVector<vtkIdType> > triangles;
99 QVector<vtkIdType> T(3);
100 createCellToCell(tetras, t2t, tetra_grid);
101 EG_VTKSP(vtkMergePoints,loc);
102 loc->SetDataSet(pts_grid);
103 loc->BuildLocator();
104 for (int i_tetras = 0; i_tetras < tetras.size(); ++i_tetras) {
105 vtkIdType id_tetra = tetras[i_tetras];
106 vtkIdType *pts, N_pts;
107 tetra_grid->GetCellPoints(id_tetra, N_pts, pts);
108 // face 0
109 if (t2t[i_tetras][0] < i_tetras) {
110 T[0] = pts[2]; T[1] = pts[1]; T[2] = pts[0];
111 triangles.append(T);
113 // face 1
114 if (t2t[i_tetras][1] < i_tetras) {
115 T[0] = pts[1]; T[1] = pts[3]; T[2] = pts[0];
116 triangles.append(T);
118 // face 2
119 if (t2t[i_tetras][2] < i_tetras) {
120 T[0] = pts[3]; T[1] = pts[2]; T[2] = pts[0];
121 triangles.append(T);
123 // face 3
124 if (t2t[i_tetras][3] < i_tetras) {
125 T[0] = pts[2]; T[1] = pts[3]; T[2] = pts[1];
126 triangles.append(T);
129 createTriangles(triangles, tetra_grid);