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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 #include "egvtkobject.h"
27 #include "meshpartition.h"
28 #include "eghashset.h"
30 class PolyMesh
: public EgVtkObject
33 friend class PolyMolecule
;
36 protected: // data types
43 int operator[](int i
);
44 bool operator<(const face_t
&F
) const;
45 bool operator==(const face_t
&F
) const;
47 face_t(int N
, int o
, int n
, vec3_t rv
, int b
= 0);
51 QVector
<vtkIdType
> id
;
53 node_t(const QVector
<vtkIdType
> &ids
);
54 node_t(vtkIdType id1
);
55 node_t(vtkIdType id1
, vtkIdType id2
);
56 node_t(vtkIdType id1
, vtkIdType id2
, vtkIdType id3
);
57 node_t(vtkIdType id1
, vtkIdType id2
, vtkIdType id3
, vtkIdType id4
);
58 bool operator<(const node_t
&N
) const;
59 bool operator>(const node_t
&N
) const;
60 bool operator==(const node_t
&N
) const;
61 int hash() const { return id
.first(); }
65 protected: // attributes
67 vtkUnstructuredGrid
*m_Grid
;
69 QVector
<int> m_Cell2PCell
;
70 QVector
<int> m_Node2PCell
;
71 QList
<face_t
> m_Faces
;
73 EgHashSet
<node_t
> m_Nodes
;
74 QVector
<vec3_t
> m_Points
;
76 QVector
<double> m_PointWeights
;
77 QVector
<QList
<int> > m_Point2Face
;
78 QVector
<QList
<int> > m_PCell2Face
;
79 QVector
<vec3_t
> m_CellCentre
;
80 QVector
<bool> m_IsBadCell
;
82 double m_AttractorWeight
;
83 double m_PullInFactor
;
84 bool m_OptimiseConvexity
;
87 bool m_CreateDualMesh
;
92 bool isHexCoreNode(vtkIdType
) { return false; }
93 bool isHexCoreCell(vtkIdType
) { return false; }
96 * Get internal indices of adjacent faces of an edge.
97 * See http://engits.eu/wiki/index.php/Manual/Element_Types for details about the internal indices.
98 * @param id_cell global id of the cell (only tetras allowed)
99 * @param id_node1 global id of the first node of the edge
100 * @param id_node2 global id of the second node of the edge
101 * @param face1 (return value) will hold the internal index of the first face (0,1,2,3)
102 * @param face2 (return value) will hold the internal index of the second face (0,1,2,3)
104 void getFacesOfEdgeInsideCell(vtkIdType id_cell
, vtkIdType id_node1
, vtkIdType id_node2
, int &face1
, int &face2
);
107 * Find all cells around an edge.
108 * This method will find all tetra cells around an edge in the mesh.
109 * It can either be a closed loop of tetras or a list which is terminated by surface elements.
110 * @param id_node1 first node of the edge
111 * @param id_node2 second node of the edge
112 * @param cells list of tetras/faces around the edge
114 void getSortedEdgeCells(vtkIdType id_node1
, vtkIdType id_node2
, QList
<vtkIdType
> &cells
, bool &is_loop
);
116 bool isDualFace(vtkIdType id_face
);
117 void getSortedPointFaces(vtkIdType id_node
, int bc
, QList
<vtkIdType
> &faces
, bool &is_loop
);
119 void findPolyCells();
120 void createFace(QList
<node_t
> nodes
, int owner
, int neighbour
, vec3_t ref_vec
, int bc
);
121 void createCornerFace(vtkIdType id_cell
, int i_face
, vtkIdType id_node
);
122 void createEdgeFace(vtkIdType id_node1
, vtkIdType id_node2
);
123 void createFaceFace(vtkIdType id_cell
, int i_face
);
124 void createPointFace(vtkIdType id_node
, int bc
);
125 void splitConcaveFaces();
126 void createNodesAndFaces();
127 void checkFaceOrientation();
128 void computePoints();
129 void buildPoint2Face();
130 void buildPCell2Face();
131 void triangulateBadFaces();
132 //void splitConcaveFaces();
133 void collectBoundaryConditions();
134 void invertFace(int i
);
137 vec3_t
faceNormal(int i
);
141 PolyMesh(vtkUnstructuredGrid
*grid
,
142 bool dualise
= false,
143 double pull_in
= 0.0,
144 bool optimise
= false,
145 bool split_faces
= false,
146 bool split_cells
= false);
148 void setNodeVector(int i
, vec3_t x
) { m_Points
[i
] = x
; }
150 int totalNumNodes() const { return m_Points
.size(); }
151 vec3_t
nodeVector(int i
) const { return m_Points
[i
]; }
152 int numNodes(int i
) const { return m_Faces
[i
].node
.size(); }
153 int nodeIndex(int i
, int j
) const { return m_Faces
[i
].node
[j
]; }
154 int numFaces() const { return m_Faces
.size(); }
155 int owner(int i
) const { return m_Faces
[i
].owner
; }
156 int neighbour(int i
) const { return m_Faces
[i
].neighbour
; }
157 int boundaryCode(int i
) const { return m_Faces
[i
].bc
; }
158 int numBCs() const { return m_BCs
.size(); }
159 int numCells() const { return m_NumPolyCells
; }
160 int numFacesOfPCell(int i
) { return m_PCell2Face
[i
].size(); }
161 int pcell2Face(int i
, int j
) { return m_PCell2Face
[i
][j
]; }
162 int numPolyCells() { return m_NumPolyCells
; }
164 void merge(PolyMesh
* poly
);
171 inline int PolyMesh::face_t::operator[](int i
)
176 while (i
>= node
.size()) {
182 inline bool PolyMesh::face_t::operator<(const face_t
&F
) const
187 } else if (bc
== F
.bc
) {
188 if (owner
< F
.owner
) {
190 } else if (owner
== F
.owner
) {
191 if (neighbour
< F
.neighbour
) {
199 inline bool PolyMesh::face_t::operator==(const face_t
&F
) const
203 if (owner
== F
.owner
) {
204 if (neighbour
== F
.neighbour
) {