1 /********************************************************************************
2 QuadTriUtils.h
3 
4 The code in this file was written by Dr. Trevor S. Strickler.
5 email: <trevor.strickler@gmail.com>
6 
7 This file is part of the QuadTri contribution to Gmsh. QuadTri allows the
8 conformal interface of quadrangle faces to triangle faces using pyramids and
9 other mesh elements.
10 
11 Trevor S. Strickler hereby transfers copyright of QuadTri files to Christophe
12 Geuzaine and J.-F. Remacle with the understanding that his contribution shall be
13 cited appropriately. See the README.txt file for license information.
14 ********************************************************************************/
15 
16 #ifndef QUADTRIUTILS_H
17 #define QUADTRIUTILS_H
18 
19 #include <stdlib.h>
20 #include "ExtrudeParams.h"
21 #include "GEntity.h"
22 #include "GFace.h"
23 #include "GRegion.h"
24 #include "GEdge.h"
25 #include "GModel.h"
26 #include "GmshDefines.h"
27 #include "MVertex.h"
28 #include "MVertexRTree.h"
29 #include "Context.h"
30 #include "GModel.h"
31 #include "meshGFace.h"
32 #include "MLine.h"
33 #include "MTriangle.h"
34 #include "MQuadrangle.h"
35 #include "MTetrahedron.h"
36 #include "MPyramid.h"
37 #include "MPrism.h"
38 #include "MHexahedron.h"
39 #include "Numeric.h"
40 #include <map>
41 #include <cmath>
42 
43 // CategorizedSourceElements: This is a data structure to hold categorized
44 // source element info for extruded regions. In addition to the region and
45 // source face pointers, there are sets and a vector that are set by the
46 // constructor. All containers except for the bool vectors contain indices to
47 // the source face's vectors of mesh elements:
48 //
49 // three_bnd_pt_tri : triangle vector indices for triangles with three vertices
50 // on a surface boundary edge four_bnd_pt_quad : quadrangle vector indices for
51 // quads with four vertices on a surface boundary edge other_bnd_pt_tri,
52 // other_bnd_pt_quad : vector indices of the respective elements that have some
53 //                                       but not all vertices on a boundary
54 //                                       edge.
55 // internal_quad_touch_one_bnd_pt_quad : quad vector indices of quads that share
56 // a vertex with a
57 //                                       one boundary point quad.
58 // internal_tri_touch_one_bnd_pt_quad  : triangle vector indices of triangles
59 // that share a vertex with a
60 //                                       one boundary point quad.
61 // two_pt_bnd_quad_touch_one_bnd_pt_quad : set of indices to quads with two
62 // points on a boundary that also touch quads
63 //                                         with one point on a boundary.
64 // internal_tri, internal_quad : The indices for the internal elements that
65 // don't touch a boundary...
66 //                               NOTE: These DO include the
67 //                               internal_[tri,quad]_touch_one_bnd_pt_quad
68 //                               elements.
69 //
70 // The vectors:
71 //
72 // tri_bool, quad_bool : These vectors hold bits to tell which vertices in which
73 // elements are on the boundary, OR
74 //             in the case of the [*]_touch_one_bnd_pt_quad elements, what
75 //             vertex is the non-boundary 'pivot' vertex shared with a quad
76 //             having one point on a boundary (diagonals are drawn to the pivot
77 //             vertex in the single layer quadToTri method). Format: In
78 //             tri_bool, there are 4*(number of triangles) elements. Each source
79 //             triangle of index i has four consecutive bool in tri_bool,
80 //             beginning at i*4.  The first bool is true if the triangle touches
81 //             an edge boundary (or touches a one boundary point quad). The
82 //             other bools correspond to triangle vertices, in order of
83 //             appearance in the triangle's own vertex vector, and are true if
84 //             the corresponding vertex is on the boundary. Everything about
85 //             tri_bool applies to quad_bool, but there are 5 bool per quad,
86 //             accessed starting at i*5.
87 //
88 
89 struct CategorizedSourceElements {
90 public:
91   GRegion *region;
92   GFace *source_face;
93   bool valid;
94   std::set<unsigned int> three_bnd_pt_tri, four_bnd_pt_quad, other_bnd_tri,
95     other_bnd_quad;
96   std::set<unsigned int> internal_tri_touch_one_bnd_pt_quad,
97     internal_quad_touch_one_bnd_pt_quad, two_bnd_pt_quad_touch_one_bnd_pt_quad;
98 
99   std::set<unsigned int> internal_tri, internal_quad;
100   std::vector<bool> tri_bool, quad_bool;
101   // constructor
102   CategorizedSourceElements(GRegion *gr);
103 };
104 
105 // this determines if a face is a non-lateral face in a structured toroidal
106 // volume extrusion with at least one QuadToTri region...
107 int IsInToroidalQuadToTri(GFace *face);
108 
109 // replace boundary quads in a source surface for toroidal quadtri extrusion
110 void ReplaceBndQuadsInFace(GFace *face);
111 
112 // This is a member function for the element map in ExtrudeParams.
113 // This allows insertion of a whole vector at once.
114 /*void ExtrudeParams::
115 ExtrusionElementMap::addExtrudedElemVector(MElement* source,
116 std::vector<MElement*> *extrudedVector );
117 */
118 
119 // Insert all vertices on a region's source edge, including corners,
120 // into pos_src_edge set.
121 // Added 2010-01-09
122 void QuadToTriInsertSourceEdgeVertices(GRegion *gr, MVertexRTree &pos_src_edge);
123 
124 // Insert all vertices on a faces edges, including corners,
125 // into pos_edges set.
126 // Added 2010-01-18
127 void QuadToTriInsertFaceEdgeVertices(GFace *face, MVertexRTree &pos_edges);
128 
129 // Find centroid of vertices in vector v, return in vector
130 std::vector<double> QtFindVertsCentroid(std::vector<MVertex *> v);
131 
132 // Add a new vertex at the centroid of a vector of vertices (this goes into a
133 // region Added 2010-02-06
134 MVertex *QtMakeCentroidVertex(const std::vector<MVertex *> &v,
135                               std::vector<MVertex *> *target, GEntity *entity,
136                               MVertexRTree &pos);
137 
138 // Finds the index of the lowest valued pointer in a vector of MVertex pointers
139 // Added 2011-03-10
140 int getIndexForLowestVertexPointer(std::vector<MVertex *> v);
141 
142 // Given 4 verts on a face, find an existent diagonal, if any.
143 // Two possible methods:  If the 'index_guess' argument is the index of the
144 // correct triangle, finding it is simple. If not, have to do a complete
145 // pedantic search. Added 2010-01-26
146 std::pair<int, int> FindDiagonalEdgeIndices(std::vector<MVertex *> verts,
147                                             GFace *face, bool lateral,
148                                             unsigned int index_guess = 0);
149 
150 // Get number of regions neighboring a face
151 int GetNeighborRegionsOfFace(GFace *face, std::vector<GRegion *> &neighbors);
152 
153 // Tests whether a surface is a lateral of a region
154 // Added 12/09/10
155 int IsSurfaceALateralForRegion(GRegion *region, GFace *face);
156 
157 // Function to determine if a face is a top surface for a region.  It returns 1
158 // if the face is COPIED_ENTITY with source = region's source and if face
159 // belongs to region. Otherwise, return 0 (NOTE: ReplaceDuplicateSurfaces() can
160 // remove a top surface and replace it.  If that happens, this will return 0.
161 // That is INTENDED for THIS function. Added 2010-12-13
162 int IsSurfaceATopForRegion(GRegion *region, GFace *face);
163 
164 // Find the bottom root source surface of an extruded surface (source of source
165 // of source, etc.)
166 GFace *findRootSourceFaceForFace(GFace *face);
167 
168 // Input is vert_bnd[], which describes some 2D element: vert_bnd[i] is true if
169 // the ith vertex the element touches a lateral edge boundary of the surface the
170 // element is in.
171 // Output is touch_bnd[]: Each element of touch_bnd[] corresponds to an edge of
172 // the element described by vert_bnd[].  Edge i of touch_bnd[] is formed by
173 // vertices i and (i+1)%element_size of the element. The value of touch_bnd[i]
174 // is non-zero if that edge touches a boundary edge of the surface that the
175 // element is in. Added 2011-03-10
176 void fill_touch_bnd(int touch_bnd[], std::vector<bool> vert_bnd, int n_lat);
177 
178 #endif
179