gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
meshGRegionCarveHole.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <set>
7 #include "GmshConfig.h"
8 #include "GmshMessage.h"
9 #include "GModel.h"
10 #include "MTriangle.h"
11 #include "MQuadrangle.h"
12 #include "MTetrahedron.h"
13 #include "MHexahedron.h"
14 #include "MPrism.h"
15 #include "MPyramid.h"
16 
17 #if !defined(HAVE_ANN)
18 
19 void carveHole(GRegion *gr, int num, double distance,
20  std::vector<int> &surfaces)
21 {
22  Msg::Error("Gmsh must be compiled with ANN support to carve holes in meshes");
23 }
24 
25 #else
26 
27 #include "ANN/ANN.h"
28 
29 template <class T>
30 void carveHole(std::vector<T *> &elements, double distance, ANNkd_tree *kdtree)
31 {
32  // delete all elements that have at least one vertex closer than
33  // 'distance' from the carving surface vertices
34  ANNidxArray index = new ANNidx[1];
35  ANNdistArray dist = new ANNdist[1];
36  std::vector<T *> temp;
37  for(std::size_t i = 0; i < elements.size(); i++) {
38  for(std::size_t j = 0; j < elements[i]->getNumVertices(); j++) {
39  MVertex *v = elements[i]->getVertex(j);
40  double xyz[3] = {v->x(), v->y(), v->z()};
41  kdtree->annkSearch(xyz, 1, index, dist);
42  double d = std::sqrt(dist[0]);
43  if(d < distance) {
44  delete elements[i];
45  break;
46  }
47  else if(j == elements[i]->getNumVertices() - 1) {
48  temp.push_back(elements[i]);
49  }
50  }
51  }
52  elements = temp;
53  delete[] index;
54  delete[] dist;
55 }
56 
57 template <class T>
58 void addFaces(std::vector<T *> &elements, std::set<MFace, MFaceLessThan> &faces)
59 {
60  for(std::size_t i = 0; i < elements.size(); i++) {
61  for(int j = 0; j < elements[i]->getNumFaces(); j++) {
62  MFace f = elements[i]->getFace(j);
63  auto it = faces.find(f);
64  if(it == faces.end())
65  faces.insert(f);
66  else
67  faces.erase(it);
68  }
69  }
70 }
71 
72 void carveHole(GRegion *gr, int num, double distance,
73  std::vector<int> &surfaces)
74 {
75  Msg::Info("Carving hole %d from surface %d at distance %g", num, surfaces[0],
76  distance);
77  GModel *m = gr->model();
78 
79  // add all points from carving surfaces into kdtree
80  int numnodes = 0;
81  for(std::size_t i = 0; i < surfaces.size(); i++) {
82  GFace *gf = m->getFaceByTag(surfaces[i]);
83  if(!gf) {
84  Msg::Error("Unknown carving surface %d", surfaces[i]);
85  return;
86  }
87  numnodes += gf->mesh_vertices.size();
88  }
89 
90  ANNpointArray kdnodes = annAllocPts(numnodes, 3);
91  int k = 0;
92  for(std::size_t i = 0; i < surfaces.size(); i++) {
93  GFace *gf = m->getFaceByTag(surfaces[i]);
94  for(std::size_t j = 0; j < gf->mesh_vertices.size(); j++) {
95  kdnodes[k][0] = gf->mesh_vertices[j]->x();
96  kdnodes[k][1] = gf->mesh_vertices[j]->y();
97  kdnodes[k][2] = gf->mesh_vertices[j]->z();
98  k++;
99  }
100  }
101  ANNkd_tree *kdtree = new ANNkd_tree(kdnodes, numnodes, 3);
102 
103  // remove the volume elements that are within 'distance' of the
104  // carved surface
105  carveHole(gr->tetrahedra, distance, kdtree);
106  carveHole(gr->hexahedra, distance, kdtree);
107  carveHole(gr->prisms, distance, kdtree);
108  carveHole(gr->pyramids, distance, kdtree);
109 
110  delete kdtree;
111  annDeallocPts(kdnodes);
112 
113  // TODO: remove any interior elements left inside the carved surface
114  // (could shoot a line from each element's barycenter and count
115  // intersections o see who's inside)
116 
117  // generate discrete boundary mesh of the carved hole
118  GFace *gf = m->getFaceByTag(num);
119  if(!gf) return;
120  std::set<MFace, MFaceLessThan> faces;
121  std::vector<GFace *> f = gr->faces();
122  for(auto it = f.begin(); it != f.end(); it++) {
123  addFaces((*it)->triangles, faces);
124  addFaces((*it)->quadrangles, faces);
125  }
126  addFaces(gr->tetrahedra, faces);
127  addFaces(gr->hexahedra, faces);
128  addFaces(gr->prisms, faces);
129  addFaces(gr->pyramids, faces);
130 
131  std::set<MVertex *> verts;
132  for(auto it = faces.begin(); it != faces.end(); it++) {
133  for(std::size_t i = 0; i < it->getNumVertices(); i++) {
134  it->getVertex(i)->setEntity(gf);
135  verts.insert(it->getVertex(i));
136  }
137  if(it->getNumVertices() == 3)
138  gf->triangles.push_back(
139  new MTriangle(it->getVertex(0), it->getVertex(1), it->getVertex(2)));
140  else if(it->getNumVertices() == 4)
141  gf->quadrangles.push_back(
142  new MQuadrangle(it->getVertex(0), it->getVertex(1), it->getVertex(2),
143  it->getVertex(3)));
144  }
145 }
146 
147 #endif
MTriangle.h
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
GFace
Definition: GFace.h:33
GFace::triangles
std::vector< MTriangle * > triangles
Definition: GFace.h:428
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::model
GModel * model() const
Definition: GEntity.h:277
MVertex
Definition: MVertex.h:24
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
MVertex::z
double z() const
Definition: MVertex.h:62
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
GModel::getFaceByTag
GFace * getFaceByTag(int n) const
Definition: GModel.cpp:326
GmshMessage.h
GFace::quadrangles
std::vector< MQuadrangle * > quadrangles
Definition: GFace.h:429
GRegion::faces
virtual std::vector< GFace * > faces() const
Definition: GRegion.h:64
GRegion::hexahedra
std::vector< MHexahedron * > hexahedra
Definition: GRegion.h:164
MFace
Definition: MFace.h:20
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
MHexahedron.h
GModel
Definition: GModel.h:44
MPyramid.h
carveHole
void carveHole(GRegion *gr, int num, double distance, std::vector< int > &surfaces)
Definition: meshGRegionCarveHole.cpp:19
GRegion
Definition: GRegion.h:28
GRegion::prisms
std::vector< MPrism * > prisms
Definition: GRegion.h:165
MTriangle
Definition: MTriangle.h:26
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
MTetrahedron.h
MQuadrangle.h
MPrism.h
GModel.h
MVertex::y
double y() const
Definition: MVertex.h:61
ElementType::getNumVertices
int getNumVertices(int type)
Definition: ElementType.cpp:456
MQuadrangle
Definition: MQuadrangle.h:26
GRegion::tetrahedra
std::vector< MTetrahedron * > tetrahedra
Definition: GRegion.h:163
MVertex::x
double x() const
Definition: MVertex.h:60
faces
static int faces[4][3]
Definition: meshGRegionDelaunayInsertion.cpp:165