updated to modern VTK
[engrid-github.git] / src / libengrid / polymolecule.h
blob4b2372c5bbce17337d0290e9c1b2a0effedbafa1
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 #ifndef POLYMOLECULE_H
23 #define POLYMOLECULE_H
25 #include "egvtkobject.h"
26 #include "polymesh.h"
28 #include <QList>
30 class PolyMolecule : public EgVtkObject
33 private: // data types
35 struct edge_t {
36 int node1;
37 int node2;
38 int face1;
39 int face2;
43 private: // attributes
45 PolyMesh* m_PolyMesh;
46 QList<int> m_FacesInPMesh;
47 QList<int> m_Nodes;
48 QVector<QList<int> > m_Faces;
49 QVector<vec3_t> m_FaceNormals;
50 QVector<vec3_t> m_NodeNormals;
51 QVector<QSet<int> > m_N2N;
52 QVector<QSet<int> > m_F2F;
53 QVector<QSet<int> > m_N2BadFaces;
54 PolyMolecule* m_SplitCell1;
55 PolyMolecule* m_SplitCell2;
57 int m_PCell;
58 vec3_t m_CentreOfGravity;
59 double m_MaxPyramidVolume;
60 double m_MinPyramidVolume;
61 bool m_AllPositive;
63 private: // methods
65 void computeCentreOfGravity();
66 void buildNode2Node();
67 void buildFace2Face();
68 void computeNormals();
69 void smooth(bool delaunay = true, bool write = false);
70 void updateFace(int face, int new_cell_index);
73 template <class C> void init(PolyMesh *poly_mesh, const C &faces);
74 template <class C> void setSubMolecules(const C &face_indices1);
76 edge_t getEdge(int node1, int node2);
77 QList<edge_t> findConcaveEdges();
79 public:
81 PolyMolecule();
82 PolyMolecule(PolyMesh *poly_mesh, int i_pcell);
84 vec3_t getXNode(int node) { return m_PolyMesh->nodeVector(m_Nodes[node]); }
85 vec3_t getXFace(int face);
86 void writeVtkFile(QString file_name);
87 void createPolyData(vtkPolyData *poly_data);
88 double minPyramidVolume() { return m_MinPyramidVolume; }
89 double maxPyramidVolume() { return m_MaxPyramidVolume; }
90 void optimise(bool write = false);
91 void centreSplit();
92 void split(bool write = false);
93 bool allPositive() { return m_AllPositive; }
94 void updatePMesh();
98 template <class C>
99 void PolyMolecule::init(PolyMesh *poly_mesh, const C &faces)
101 m_PolyMesh = poly_mesh;
102 QSet<int> nodes;
103 QHash<int,int> node_map;
104 for (int i = 0; i < faces.size(); ++i) {
105 for (int j = 0; j < faces[i].size(); ++j) {
106 nodes.insert(faces[i][j]);
110 int N = 0;
111 foreach (int node, nodes) {
112 m_Nodes.append(node);
113 node_map[node] = N;
114 ++N;
117 m_Faces.resize(faces.size());
118 for (int i = 0; i < faces.size(); ++i) {
119 for (int j = 0; j < faces[i].size(); ++j) {
120 m_Faces[i].append(node_map[faces[i][j]]);
123 if (m_Nodes.size() == 0) {
124 EG_BUG;
126 if (m_Faces.size() == 0) {
127 EG_BUG;
129 computeCentreOfGravity();
130 buildNode2Node();
131 computeNormals();
134 template <class C>
135 void PolyMolecule::setSubMolecules(const C &face_indices1)
137 QList<int> face_indices2;
138 for (int i = 0; i < m_Faces.size(); ++i) {
139 if (!face_indices1.contains(i)) {
140 face_indices2.append(i);
143 QList<QList<int> > faces1;
144 foreach (int i, face_indices1) {
145 QList<int> face;
146 foreach (int node, m_Faces[i]) {
147 face.append(node);
149 faces1.append(face);
151 delete m_SplitCell1;
152 m_SplitCell1 = new PolyMolecule();
153 m_SplitCell1->init(m_PolyMesh, faces1);
154 QList<QList<int> > faces2;
155 foreach (int i, face_indices2) {
156 QList<int> face;
157 foreach (int node, m_Faces[i]) {
158 face.append(node);
160 faces2.append(face);
162 delete m_SplitCell2;
163 m_SplitCell2 = new PolyMolecule();
164 m_SplitCell2->init(m_PolyMesh, faces2);
167 #endif // POLYMOLECULE_H