gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
GRegion.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 <sstream>
7 #include "GModel.h"
8 #include "GRegion.h"
9 #include "GFace.h"
10 #include "MTetrahedron.h"
11 #include "MHexahedron.h"
12 #include "MPrism.h"
13 #include "MPyramid.h"
14 #include "MTrihedron.h"
15 #include "MElementCut.h"
16 #include "GmshMessage.h"
17 #include "VertexArray.h"
18 #include "boundaryLayersData.h"
19 #include "discreteEdge.h"
20 #include "discreteFace.h"
21 #include "ExtrudeParams.h"
22 #include "GmshDefines.h"
23 
24 #if defined(HAVE_MESH)
25 #include "meshGFace.h"
26 #endif
27 
28 GRegion::GRegion(GModel *model, int tag) : GEntity(model, tag)
29 {
31 }
32 
34 {
35  for(auto gf : l_faces) gf->delRegion(this);
37 }
38 
40 {
41  for(std::size_t i = 0; i < mesh_vertices.size(); i++) delete mesh_vertices[i];
42  mesh_vertices.clear();
43  transfinite_vertices.clear();
44  for(std::size_t i = 0; i < tetrahedra.size(); i++) delete tetrahedra[i];
45  tetrahedra.clear();
46  for(std::size_t i = 0; i < hexahedra.size(); i++) delete hexahedra[i];
47  hexahedra.clear();
48  for(std::size_t i = 0; i < prisms.size(); i++) delete prisms[i];
49  prisms.clear();
50  for(std::size_t i = 0; i < pyramids.size(); i++) delete pyramids[i];
51  pyramids.clear();
52  for(std::size_t i = 0; i < trihedra.size(); i++) delete trihedra[i];
53  trihedra.clear();
54  for(std::size_t i = 0; i < polyhedra.size(); i++) delete polyhedra[i];
55  polyhedra.clear();
58 }
59 
60 std::size_t GRegion::getNumMeshElements() const
61 {
62  return tetrahedra.size() + hexahedra.size() + prisms.size() +
63  pyramids.size() + trihedra.size() + polyhedra.size();
64 }
65 
66 std::size_t GRegion::getNumMeshElementsByType(const int familyType) const
67 {
68  if(familyType == TYPE_TET)
69  return tetrahedra.size();
70  else if(familyType == TYPE_HEX)
71  return hexahedra.size();
72  else if(familyType == TYPE_PRI)
73  return prisms.size();
74  else if(familyType == TYPE_PYR)
75  return pyramids.size();
76  else if(familyType == TYPE_TRIH)
77  return trihedra.size();
78  else if(familyType == TYPE_POLYH)
79  return polyhedra.size();
80 
81  return 0;
82 }
83 
85 {
86  std::size_t n = 0;
87  for(std::size_t i = 0; i < polyhedra.size(); i++)
88  if(polyhedra[i]->ownsParent()) n++;
89  return n;
90 }
91 
92 void GRegion::getNumMeshElements(unsigned *const c) const
93 {
94  c[0] += tetrahedra.size();
95  c[1] += hexahedra.size();
96  c[2] += prisms.size();
97  c[3] += pyramids.size();
98  c[4] += trihedra.size();
99  c[5] += polyhedra.size();
100 }
101 
102 MElement *const *GRegion::getStartElementType(int type) const
103 {
104  switch(type) {
105  case 0:
106  if(tetrahedra.empty()) return nullptr; // msvc would throw an exception
107  return reinterpret_cast<MElement *const *>(&tetrahedra[0]);
108  case 1:
109  if(hexahedra.empty()) return nullptr; // msvc would throw an exception
110  return reinterpret_cast<MElement *const *>(&hexahedra[0]);
111  case 2:
112  if(prisms.empty()) return nullptr; // msvc would throw an exception
113  return reinterpret_cast<MElement *const *>(&prisms[0]);
114  case 3:
115  if(pyramids.empty()) return nullptr; // msvc would throw an exception
116  return reinterpret_cast<MElement *const *>(&pyramids[0]);
117  case 4:
118  if(trihedra.empty()) return nullptr;
119  return reinterpret_cast<MElement *const *>(&trihedra[0]);
120  case 5:
121  if(polyhedra.empty()) return nullptr;
122  return reinterpret_cast<MElement *const *>(&polyhedra[0]);
123  }
124  return nullptr;
125 }
126 
127 MElement *GRegion::getMeshElement(std::size_t index) const
128 {
129  if(index < tetrahedra.size())
130  return tetrahedra[index];
131  else if(index < tetrahedra.size() + hexahedra.size())
132  return hexahedra[index - tetrahedra.size()];
133  else if(index < tetrahedra.size() + hexahedra.size() + prisms.size())
134  return prisms[index - tetrahedra.size() - hexahedra.size()];
135  else if(index < tetrahedra.size() + hexahedra.size() + prisms.size() +
136  pyramids.size())
137  return pyramids[index - tetrahedra.size() - hexahedra.size() -
138  prisms.size()];
139  else if(index < tetrahedra.size() + hexahedra.size() + prisms.size() +
140  pyramids.size() + trihedra.size())
141  return trihedra[index - tetrahedra.size() - hexahedra.size() -
142  prisms.size() - pyramids.size()];
143  else if(index < tetrahedra.size() + hexahedra.size() + prisms.size() +
144  pyramids.size() + trihedra.size() + polyhedra.size())
145  return polyhedra[index - tetrahedra.size() - hexahedra.size() -
146  prisms.size() - pyramids.size() - trihedra.size()];
147 
148  return nullptr;
149 }
150 
152  const std::size_t index) const
153 {
154  if(familyType == TYPE_TET)
155  return tetrahedra[index];
156  else if(familyType == TYPE_HEX)
157  return hexahedra[index];
158  else if(familyType == TYPE_PRI)
159  return prisms[index];
160  else if(familyType == TYPE_PYR)
161  return pyramids[index];
162  else if(familyType == TYPE_TRIH)
163  return trihedra[index];
164  else if(familyType == TYPE_POLYH)
165  return polyhedra[index];
166 
167  return nullptr;
168 }
169 
171 {
172  meshAttributes.recombine3D = 0;
174  meshAttributes.extrude = nullptr;
175  meshAttributes.QuadTri = NO_QUADTRI;
176  meshAttributes.meshSize = MAX_LC;
177 }
178 
180 {
181  SBoundingBox3d res;
183  for(auto gf : l_faces)
184  res += gf->bounds(fast);
185  }
186  else {
187  for(std::size_t i = 0; i < getNumMeshElements(); i++)
188  for(std::size_t j = 0; j < getMeshElement(i)->getNumVertices(); j++)
189  res += getMeshElement(i)->getVertex(j)->point();
190  }
191  return res;
192 }
193 
195 {
196  if(!_obb) {
197  std::vector<SPoint3> vertices;
198  std::vector<GFace *> b_faces = faces();
199  for(auto b_face = b_faces.begin(); b_face != b_faces.end(); b_face++) {
200  if((*b_face)->getNumMeshVertices() > 0) {
201  int N = (*b_face)->getNumMeshVertices();
202  for(int i = 0; i < N; i++) {
203  MVertex *mv = (*b_face)->getMeshVertex(i);
204  vertices.push_back(mv->point());
205  }
206  std::vector<GEdge *> eds = (*b_face)->edges();
207  for(auto ed = eds.begin(); ed != eds.end(); ed++) {
208  int N2 = (*ed)->getNumMeshVertices();
209  for(int i = 0; i < N2; i++) {
210  MVertex *mv = (*ed)->getMeshVertex(i);
211  vertices.push_back(mv->point());
212  }
213  // Don't forget to add the first and last vertices...
214  if((*ed)->getBeginVertex()) {
215  SPoint3 pt1((*ed)->getBeginVertex()->x(),
216  (*ed)->getBeginVertex()->y(),
217  (*ed)->getBeginVertex()->z());
218  vertices.push_back(pt1);
219  }
220  if((*ed)->getEndVertex()) {
221  SPoint3 pt2((*ed)->getEndVertex()->x(), (*ed)->getEndVertex()->y(),
222  (*ed)->getEndVertex()->z());
223  vertices.push_back(pt2);
224  }
225  }
226  }
227  else if((*b_face)->buildSTLTriangulation()) {
228  vertices = (*b_face)->stl_vertices_xyz;
229  }
230  else {
231  int N = 10;
232  std::vector<GEdge *> b_edges = (*b_face)->edges();
233  for(auto b_edge = b_edges.begin(); b_edge != b_edges.end(); b_edge++) {
234  Range<double> tr = (*b_edge)->parBounds(0);
235  for(int j = 0; j < N; j++) {
236  double t =
237  tr.low() + (double)j / (double)(N - 1) * (tr.high() - tr.low());
238  GPoint p = (*b_edge)->point(t);
239  SPoint3 pt(p.x(), p.y(), p.z());
240  vertices.push_back(pt);
241  }
242  }
243  }
244  }
246  }
247  return SOrientedBoundingBox(_obb);
248 }
249 
250 void GRegion::setVisibility(char val, bool recursive)
251 {
253  if(recursive) {
254  for(auto f : l_faces) f->setVisibility(val, recursive);
255  for(auto f : embedded_faces) f->setVisibility(val, recursive);
256  for(auto e : embedded_edges) e->setVisibility(val, recursive);
257  for(auto v : embedded_vertices) v->setVisibility(val);
258  }
259 }
260 
261 void GRegion::setColor(unsigned int val, bool recursive)
262 {
263  GEntity::setColor(val);
264  if(recursive) {
265  for(auto f : l_faces) f->setColor(val, recursive);
266  for(auto f : embedded_faces) f->setColor(val, recursive);
267  for(auto e : embedded_edges) e->setColor(val, recursive);
268  for(auto v : embedded_vertices) v->setColor(val);
269  }
270 }
271 
273 {
274  const auto found = std::find(l_faces.begin(), l_faces.end(), face);
275 
276  if(found != l_faces.end()) { l_faces.erase(found); }
277 
278  const auto pos = std::distance(l_faces.begin(), found);
279 
280  if(l_dirs.empty()) { return 0; }
281 
282  if(l_dirs.size() < static_cast<std::size_t>(pos)) {
283  l_dirs.erase(std::prev(l_dirs.end()));
284  return 0;
285  }
286 
287  const auto orientation = l_dirs.at(pos);
288 
289  l_dirs.erase(std::next(l_dirs.begin(), pos));
290 
291  return orientation;
292 }
293 
294 void GRegion::setBoundFaces(const std::set<int> &tagFaces)
295 {
296  for(auto it = tagFaces.begin(); it != tagFaces.end(); ++it) {
297  GFace *gf = model()->getFaceByTag(*it);
298  if(gf) {
299  if(std::find(l_faces.begin(), l_faces.end(), gf) == l_faces.end()) {
300  l_faces.push_back(gf);
301  gf->addRegion(this);
302  }
303  }
304  else {
305  Msg::Error("Unknown surface %d in volume %d", *it, tag());
306  }
307  }
308 }
309 
310 void GRegion::setBoundFaces(const std::vector<int> &tagFaces,
311  const std::vector<int> &signFaces)
312 {
313  if(tagFaces.size() != signFaces.size()) {
314  Msg::Error("Wrong number of surface signs in volume %d", tag());
315  std::set<int> tags;
316  tags.insert(tagFaces.begin(), tagFaces.end());
318  }
319  for(std::size_t i = 0; i != tagFaces.size(); i++) {
320  GFace *gf = model()->getFaceByTag(tagFaces[i]);
321  if(gf) {
322  if(std::find(l_faces.begin(), l_faces.end(), gf) == l_faces.end()) {
323  l_faces.push_back(gf);
324  gf->addRegion(this);
325  l_dirs.push_back(signFaces[i]);
326  }
327  }
328  else {
329  Msg::Error("Unknown surface %d in volume %d", tagFaces[i], tag());
330  }
331  }
332 }
333 
334 std::string GRegion::getAdditionalInfoString(bool multline)
335 {
336  std::ostringstream sstream;
337  if(l_faces.size()) {
338  sstream << "Boundary surfaces: ";
339  for(auto it = l_faces.begin(); it != l_faces.end(); ++it) {
340  if(it != l_faces.begin()) sstream << ", ";
341  sstream << (*it)->tag();
342  }
343  if(multline)
344  sstream << "\n";
345  else
346  sstream << " ";
347  }
348  if(embedded_faces.size()) {
349  sstream << "Embedded surfaces: ";
350  for(auto it = embedded_faces.begin(); it != embedded_faces.end(); ++it) {
351  if(it != embedded_faces.begin()) sstream << ", ";
352  sstream << (*it)->tag();
353  }
354  if(multline)
355  sstream << "\n";
356  else
357  sstream << " ";
358  }
359  if(embedded_edges.size()) {
360  sstream << "Embedded curves: ";
361  for(auto it = embedded_edges.begin(); it != embedded_edges.end(); ++it) {
362  if(it != embedded_edges.begin()) sstream << ", ";
363  sstream << (*it)->tag();
364  }
365  if(multline)
366  sstream << "\n";
367  else
368  sstream << " ";
369  }
370  if(embedded_vertices.size()) {
371  sstream << "Embedded points: ";
372  for(auto it = embedded_vertices.begin(); it != embedded_vertices.end();
373  ++it) {
374  if(it != embedded_vertices.begin()) sstream << ", ";
375  sstream << (*it)->tag();
376  }
377  if(multline)
378  sstream << "\n";
379  else
380  sstream << " ";
381  }
382 
383  if(meshAttributes.method == MESH_TRANSFINITE ||
384  (meshAttributes.extrude && meshAttributes.extrude->mesh.ExtrudeMesh)) {
385  sstream << "Mesh attributes:";
386  if(meshAttributes.method == MESH_TRANSFINITE) sstream << " transfinite";
387  if(meshAttributes.extrude && meshAttributes.extrude->mesh.ExtrudeMesh)
388  sstream << " extruded";
389  }
390 
391  std::string str = sstream.str();
392  if(str.size() && (str[str.size() - 1] == '\n' || str[str.size() - 1] == ' '))
393  str.resize(str.size() - 1);
394  return str;
395 }
396 
397 void GRegion::writeGEO(FILE *fp)
398 {
399  if(geomType() == DiscreteVolume) return;
400 
401  if(l_faces.size()) {
402  fprintf(fp, "Surface Loop(%d) = ", tag());
403  for(auto it = l_faces.begin(); it != l_faces.end(); it++) {
404  if(it != l_faces.begin())
405  fprintf(fp, ", %d", (*it)->tag());
406  else
407  fprintf(fp, "{%d", (*it)->tag());
408  }
409  fprintf(fp, "};\n");
410  fprintf(fp, "Volume(%d) = {%d};\n", tag(), tag());
411  }
412 
413  for(auto it = embedded_faces.begin(); it != embedded_faces.end(); it++)
414  fprintf(fp, "Surface {%d} In Volume {%d};\n", (*it)->tag(), tag());
415 
416  for(auto it = embedded_edges.begin(); it != embedded_edges.end(); it++)
417  fprintf(fp, "Line {%d} In Volume {%d};\n", (*it)->tag(), tag());
418 
419  for(auto it = embedded_vertices.begin(); it != embedded_vertices.end(); it++)
420  fprintf(fp, "Point {%d} In Volume {%d};\n", (*it)->tag(), tag());
421 
422  if(meshAttributes.method == MESH_TRANSFINITE) {
423  fprintf(fp, "Transfinite Volume {%d}", tag());
424  if(meshAttributes.corners.size()) {
425  fprintf(fp, " = {");
426  for(std::size_t i = 0; i < meshAttributes.corners.size(); i++) {
427  if(i) fprintf(fp, ",");
428  fprintf(fp, "%d", meshAttributes.corners[i]->tag());
429  }
430  fprintf(fp, "}");
431  }
432  fprintf(fp, ";\n");
433 
434  if(meshAttributes.QuadTri != NO_QUADTRI)
435  fprintf(fp, "TransfQuadTri {%d};\n", tag());
436  }
437 }
438 
439 void GRegion::writePY(FILE *fp)
440 {
441  // This is by no means complete - merely a placeholder for a future
442  // implementation
443 
444  if(geomType() == DiscreteVolume) return;
445 
446  const char *factory = getNativeType() == OpenCascadeModel ? "occ" : "geo";
447 
448  if(l_faces.size()) {
449  fprintf(fp, "gmsh.model.%s.addSurfaceLoop([", factory);
450  for(auto it = l_faces.begin(); it != l_faces.end(); it++) {
451  if(it != l_faces.begin()) fprintf(fp, ", ");
452  fprintf(fp, "%d", (*it)->tag());
453  }
454  fprintf(fp, "], %d)\n", tag());
455  fprintf(fp, "gmsh.model.%s.addVolume(%d, %d)\n", factory, tag(), tag());
456  }
457 }
458 
459 std::vector<GEdge *> const &GRegion::edges() const
460 {
461  static std::vector<GEdge *> e;
462  e.clear();
463 
464  for(auto *const face : l_faces) {
465  for(auto *const edge : face->edges()) {
466  if(std::find(e.begin(), e.end(), edge) == e.end()) { e.push_back(edge); }
467  }
468  }
469  return e;
470 }
471 
473 {
474  std::vector<GEdge *> e = edges(), e2 = r->edges();
475 
476  auto it = e.begin();
477  while(it != e.end()) {
478  if(std::find(e2.begin(), e2.end(), *it) != e2.end()) return true;
479  ++it;
480  }
481  return false;
482 }
483 
484 double GRegion::computeSolidProperties(std::vector<double> cg,
485  std::vector<double> inertia)
486 {
487  auto it = l_faces.begin();
488  auto itdir = l_dirs.begin();
489  double volumex = 0;
490  double volumey = 0;
491  double volumez = 0;
492  double surface = 0;
493  cg[0] = cg[1] = cg[2] = 0.0;
494  for(; it != l_faces.end(); ++it, ++itdir) {
495  for(std::size_t i = 0; i < (*it)->triangles.size(); ++i) {
496  MTriangle *e = (*it)->triangles[i];
497  int npt;
498  IntPt *pts;
499  e->getIntegrationPoints(2 * (e->getPolynomialOrder() - 1) + 3, &npt,
500  &pts);
501  for(int j = 0; j < npt; j++) {
502  SPoint3 pt;
503  // compute x,y,z of the integration point
504  e->pnt(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], pt);
505  double jac[3][3];
506  // compute normal
507  double detJ =
508  e->getJacobian(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], jac);
509  SVector3 n(jac[2][0], jac[2][1], jac[2][2]);
510  n.normalize();
511  n *= (double)*itdir;
512  surface += detJ * pts[j].weight;
513  volumex += detJ * n.x() * pt.x() * pts[j].weight;
514  volumey += detJ * n.y() * pt.y() * pts[j].weight;
515  volumez += detJ * n.z() * pt.z() * pts[j].weight;
516  cg[0] += detJ * n.x() * (pt.x() * pt.x()) * pts[j].weight * 0.5;
517  cg[1] += detJ * n.y() * (pt.y() * pt.y()) * pts[j].weight * 0.5;
518  cg[2] += detJ * n.z() * (pt.z() * pt.z()) * pts[j].weight * 0.5;
519  }
520  }
521  }
522 
523  printf("%g -- %g %g %g\n", surface, volumex, volumey, volumez);
524 
525  double volume = volumex;
526 
527  cg[0] /= volume;
528  cg[1] /= volume;
529  cg[2] /= volume;
530 
531  it = l_faces.begin();
532  itdir = l_dirs.begin();
533  inertia[0] = inertia[1] = inertia[2] = inertia[3] = inertia[4] = inertia[5] =
534  0.0;
535 
536  for(; it != l_faces.end(); ++it, ++itdir) {
537  for(std::size_t i = 0; i < (*it)->getNumMeshElements(); ++i) {
538  MElement *e = (*it)->getMeshElement(i);
539  int npt;
540  IntPt *pts;
541  e->getIntegrationPoints(2 * (e->getPolynomialOrder() - 1) + 3, &npt,
542  &pts);
543  for(int j = 0; j < npt; j++) {
544  SPoint3 pt;
545  // compute x,y,z of the integration point
546  e->pnt(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], pt);
547  double jac[3][3];
548  // compute normal
549  double detJ =
550  e->getJacobian(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], jac);
551  SVector3 n(jac[2][0], jac[2][1], jac[2][2]);
552  n *= (double)*itdir;
553  inertia[0] += pts[j].weight * detJ * n.x() * (pt.x() - cg[0]) *
554  (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
555  inertia[1] += pts[j].weight * detJ * n.y() * (pt.y() - cg[1]) *
556  (pt.y() - cg[1]) * (pt.y() - cg[1]) / 3.0;
557  inertia[2] += pts[j].weight * detJ * n.z() * (pt.z() - cg[2]) *
558  (pt.z() - cg[2]) * (pt.z() - cg[2]) / 3.0;
559  inertia[3] += pts[j].weight * detJ * n.x() * (pt.y() - cg[1]) *
560  (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
561  inertia[4] += pts[j].weight * detJ * n.x() * (pt.z() - cg[2]) *
562  (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
563  inertia[5] += pts[j].weight * detJ * n.y() * (pt.z() - cg[2]) *
564  (pt.y() - cg[1]) * (pt.y() - cg[1]) / 3.0;
565  }
566  }
567  }
568  return volume;
569 }
570 
571 std::vector<MVertex *> GRegion::getEmbeddedMeshVertices() const
572 {
573  std::set<MVertex *> tmp;
574  for(auto it = embedded_faces.begin(); it != embedded_faces.end(); it++) {
575  tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
576  std::vector<GEdge *> ed = (*it)->edges();
577  for(auto it2 = ed.begin(); it2 != ed.end(); it2++) {
578  tmp.insert((*it2)->mesh_vertices.begin(), (*it2)->mesh_vertices.end());
579  if((*it2)->getBeginVertex())
580  tmp.insert((*it2)->getBeginVertex()->mesh_vertices.begin(),
581  (*it2)->getBeginVertex()->mesh_vertices.end());
582  if((*it2)->getEndVertex())
583  tmp.insert((*it2)->getEndVertex()->mesh_vertices.begin(),
584  (*it2)->getEndVertex()->mesh_vertices.end());
585  }
586  }
587  for(auto it = embedded_edges.begin(); it != embedded_edges.end(); it++) {
588  tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
589  if((*it)->getBeginVertex())
590  tmp.insert((*it)->getBeginVertex()->mesh_vertices.begin(),
591  (*it)->getBeginVertex()->mesh_vertices.end());
592  if((*it)->getEndVertex())
593  tmp.insert((*it)->getEndVertex()->mesh_vertices.begin(),
594  (*it)->getEndVertex()->mesh_vertices.end());
595  }
596  for(auto it = embedded_vertices.begin(); it != embedded_vertices.end();
597  it++) {
598  tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
599  }
600  return std::vector<MVertex *>(tmp.begin(), tmp.end());
601 }
602 
603 std::vector<GVertex *> GRegion::vertices() const
604 {
605  std::set<GVertex *, GEntityPtrLessThan> v;
606  for(auto gf : l_faces) {
607  std::vector<GVertex *> const &vs = gf->vertices();
608  v.insert(vs.begin(), vs.end());
609  }
610  return std::vector<GVertex *>(v.begin(), v.end());
611 }
612 
613 void GRegion::addElement(int type, MElement *e)
614 {
615  switch(type) {
616  case TYPE_TET: addTetrahedron(reinterpret_cast<MTetrahedron *>(e)); break;
617  case TYPE_HEX: addHexahedron(reinterpret_cast<MHexahedron *>(e)); break;
618  case TYPE_PRI: addPrism(reinterpret_cast<MPrism *>(e)); break;
619  case TYPE_PYR: addPyramid(reinterpret_cast<MPyramid *>(e)); break;
620  case TYPE_TRIH: addTrihedron(reinterpret_cast<MTrihedron *>(e)); break;
621  case TYPE_POLYH: addPolyhedron(reinterpret_cast<MPolyhedron *>(e)); break;
622  default:
623  Msg::Error("Trying to add unsupported element in volume %d", tag());
624  }
625 }
626 
628 {
629  switch(type) {
630  case TYPE_TET: {
631  auto it = std::find(tetrahedra.begin(), tetrahedra.end(),
632  reinterpret_cast<MTetrahedron *>(e));
633  if(it != tetrahedra.end()) tetrahedra.erase(it);
634  } break;
635  case TYPE_HEX: {
636  auto it = std::find(hexahedra.begin(), hexahedra.end(),
637  reinterpret_cast<MHexahedron *>(e));
638  if(it != hexahedra.end()) hexahedra.erase(it);
639  } break;
640  case TYPE_PRI: {
641  auto it =
642  std::find(prisms.begin(), prisms.end(), reinterpret_cast<MPrism *>(e));
643  if(it != prisms.end()) prisms.erase(it);
644  } break;
645  case TYPE_PYR: {
646  auto it = std::find(pyramids.begin(), pyramids.end(),
647  reinterpret_cast<MPyramid *>(e));
648  if(it != pyramids.end()) pyramids.erase(it);
649  } break;
650  case TYPE_TRIH: {
651  auto it = std::find(trihedra.begin(), trihedra.end(),
652  reinterpret_cast<MTrihedron *>(e));
653  if(it != trihedra.end()) trihedra.erase(it);
654  } break;
655  case TYPE_POLYH: {
656  auto it = std::find(polyhedra.begin(), polyhedra.end(),
657  reinterpret_cast<MPolyhedron *>(e));
658  if(it != polyhedra.end()) polyhedra.erase(it);
659  } break;
660  default:
661  Msg::Error("Trying to remove unsupported element in volume %d", tag());
662  }
663 }
664 
666 {
667  switch(type) {
668  case TYPE_TET: tetrahedra.clear(); break;
669  case TYPE_HEX: hexahedra.clear(); break;
670  case TYPE_PRI: prisms.clear(); break;
671  case TYPE_PYR: pyramids.clear(); break;
672  case TYPE_TRIH: trihedra.clear(); break;
673  case TYPE_POLYH: polyhedra.clear(); break;
674  default:
675  Msg::Error("Trying to remove unsupported elements in volume %d", tag());
676  }
677 }
678 
679 bool GRegion::reorder(const int elementType,
680  const std::vector<std::size_t> &ordering)
681 {
682  if(tetrahedra.size() != 0) {
683  if(tetrahedra.front()->getTypeForMSH() == elementType) {
684  if(ordering.size() != tetrahedra.size()) return false;
685 
686  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
687  if(*it >= tetrahedra.size()) return false;
688  }
689 
690  std::vector<MTetrahedron *> newTetrahedraOrder(tetrahedra.size());
691  for(std::size_t i = 0; i < ordering.size(); i++) {
692  newTetrahedraOrder[i] = tetrahedra[ordering[i]];
693  }
694  tetrahedra = std::move(newTetrahedraOrder);
695  return true;
696  }
697  }
698 
699  if(hexahedra.size() != 0) {
700  if(hexahedra.front()->getTypeForMSH() == elementType) {
701  if(ordering.size() != hexahedra.size()) return false;
702 
703  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
704  if(*it >= hexahedra.size()) return false;
705  }
706 
707  std::vector<MHexahedron *> newHexahedraOrder(hexahedra.size());
708  for(std::size_t i = 0; i < ordering.size(); i++) {
709  newHexahedraOrder[i] = hexahedra[ordering[i]];
710  }
711  hexahedra = std::move(newHexahedraOrder);
712  return true;
713  }
714  }
715 
716  if(prisms.size() != 0) {
717  if(prisms.front()->getTypeForMSH() == elementType) {
718  if(ordering.size() != prisms.size()) return false;
719 
720  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
721  if(*it >= prisms.size()) return false;
722  }
723 
724  std::vector<MPrism *> newPrismsOrder(prisms.size());
725  for(std::size_t i = 0; i < ordering.size(); i++) {
726  newPrismsOrder[i] = prisms[ordering[i]];
727  }
728  prisms = std::move(newPrismsOrder);
729  return true;
730  }
731  }
732 
733  if(pyramids.size() != 0) {
734  if(pyramids.front()->getTypeForMSH() == elementType) {
735  if(ordering.size() != pyramids.size()) return false;
736 
737  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
738  if(*it >= pyramids.size()) return false;
739  }
740 
741  std::vector<MPyramid *> newPyramidsOrder(pyramids.size());
742  for(std::size_t i = 0; i < ordering.size(); i++) {
743  newPyramidsOrder[i] = pyramids[ordering[i]];
744  }
745  pyramids = std::move(newPyramidsOrder);
746  return true;
747  }
748  }
749 
750  if(polyhedra.size() != 0) {
751  if(polyhedra.front()->getTypeForMSH() == elementType) {
752  if(ordering.size() != polyhedra.size()) return false;
753 
754  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
755  if(*it >= polyhedra.size()) return false;
756  }
757 
758  std::vector<MPolyhedron *> newPolyhedraOrder(polyhedra.size());
759  for(std::size_t i = 0; i < ordering.size(); i++) {
760  newPolyhedraOrder[i] = polyhedra[ordering[i]];
761  }
762  polyhedra = std::move(newPolyhedraOrder);
763  return true;
764  }
765  }
766 
767  if(trihedra.size() != 0) {
768  if(trihedra.front()->getTypeForMSH() == elementType) {
769  if(ordering.size() != trihedra.size()) return false;
770 
771  for(auto it = ordering.begin(); it != ordering.end(); ++it) {
772  if(*it >= trihedra.size()) return false;
773  }
774 
775  std::vector<MTrihedron *> newTrihedraOrder(trihedra.size());
776  for(std::size_t i = 0; i < ordering.size(); i++) {
777  newTrihedraOrder[i] = trihedra[ordering[i]];
778  }
779  trihedra = std::move(newTrihedraOrder);
780  return true;
781  }
782  }
783 
784  return false;
785 }
786 
787 static void setRand(double r[6])
788 {
789  for(int i = 0; i < 6; i++)
790  r[i] = 0.0001 * ((double)rand() / (double)RAND_MAX);
791 }
792 
793 // X_1 (1-u-v) + X_2 u + X_3 v = P_x + t N_x
794 // Y_1 (1-u-v) + Y_2 u + Y_3 v = P_y + t N_y
795 // Z_1 (1-u-v) + Z_2 u + Z_3 v = P_z + t N_z
796 
797 static int intersectLineTriangle(double X[3], double Y[3], double Z[3],
798  double P[3], double N[3],
799  const double eps_prec)
800 {
801  double mat[3][3], det;
802  double b[3], res[3];
803 
804  mat[0][0] = X[1] - X[0];
805  mat[0][1] = X[2] - X[0];
806  mat[0][2] = N[0];
807 
808  mat[1][0] = Y[1] - Y[0];
809  mat[1][1] = Y[2] - Y[0];
810  mat[1][2] = N[1];
811 
812  mat[2][0] = Z[1] - Z[0];
813  mat[2][1] = Z[2] - Z[0];
814  mat[2][2] = N[2];
815 
816  b[0] = P[0] - X[0];
817  b[1] = P[1] - Y[0];
818  b[2] = P[2] - Z[0];
819 
820  if(!sys3x3_with_tol(mat, b, res, &det)) { return 0; }
821  if(res[0] >= eps_prec && res[0] <= 1.0 - eps_prec && res[1] >= eps_prec &&
822  res[1] <= 1.0 - eps_prec && 1 - res[0] - res[1] >= eps_prec &&
823  1 - res[0] - res[1] <= 1.0 - eps_prec) {
824  // the line clearly intersects the triangle
825  return (res[2] > 0) ? 1 : 0;
826  }
827  else if(res[0] < -eps_prec || res[0] > 1.0 + eps_prec || res[1] < -eps_prec ||
828  res[1] > 1.0 + eps_prec || 1 - res[0] - res[1] < -eps_prec ||
829  1 - res[0] - res[1] > 1.0 + eps_prec) {
830  // the line clearly does NOT intersect the triangle
831  return 0;
832  }
833  else {
834  // the intersection is not robust, try another triangle
835  return -10000;
836  }
837 }
838 
840 {
841  // perform intersection check in normalized coordinates
842  SBoundingBox3d bbox = bounds();
843  double scaling = norm(SVector3(bbox.max(), bbox.min()));
844  if(!scaling) {
845  Msg::Warning("Bad scaling in GRegion::setOutwardOrientationMeshConstraint");
846  scaling = 1.;
847  }
848  double rrr[6];
849  setRand(rrr);
850 
851  std::vector<GFace *> f = faces();
852  auto it = f.begin();
853  while(it != f.end()) {
854  GFace *gf = (*it);
855  gf->buildSTLTriangulation();
856  if(gf->stl_triangles.size() < 3) {
857  Msg::Warning("No valid STL triangulation found for surface %d - skipping "
858  "outward orientation constraint for volume %d",
859  gf->tag(), tag());
860  return false;
861  }
862  int nb_intersect = 0;
863  for(std::size_t i = 0; i < gf->stl_triangles.size(); i += 3) {
864  SPoint3 p1 = gf->stl_vertices_xyz[gf->stl_triangles[i]];
865  SPoint3 p2 = gf->stl_vertices_xyz[gf->stl_triangles[i + 1]];
866  SPoint3 p3 = gf->stl_vertices_xyz[gf->stl_triangles[i + 2]];
867  double X[3] = {p1.x(), p2.x(), p3.x()};
868  double Y[3] = {p1.y(), p2.y(), p3.y()};
869  double Z[3] = {p1.z(), p2.z(), p3.z()};
870  for(int j = 0; j < 3; j++) {
871  X[j] /= scaling;
872  Y[j] /= scaling;
873  Z[j] /= scaling;
874  }
875  double P[3] = {(X[0] + X[1] + X[2]) / 3., (Y[0] + Y[1] + Y[2]) / 3.,
876  (Z[0] + Z[1] + Z[2]) / 3.};
877  double v1[3] = {X[0] - X[1], Y[0] - Y[1], Z[0] - Z[1]};
878  double v2[3] = {X[2] - X[1], Y[2] - Y[1], Z[2] - Z[1]};
879  double N[3];
880  prodve(v1, v2, N);
881  norme(v1);
882  norme(v2);
883  norme(N);
884  N[0] += rrr[0] * v1[0] + rrr[1] * v2[0];
885  N[1] += rrr[2] * v1[1] + rrr[3] * v2[1];
886  N[2] += rrr[4] * v1[2] + rrr[5] * v2[2];
887  norme(N);
888  auto it_b = f.begin();
889  while(it_b != f.end()) {
890  GFace *gf_b = (*it_b);
891  gf_b->buildSTLTriangulation();
892  if(gf_b->stl_triangles.size() < 3) { return false; }
893  for(std::size_t i_b = 0; i_b < gf_b->stl_triangles.size(); i_b += 3) {
894  SPoint3 p1 = gf_b->stl_vertices_xyz[gf_b->stl_triangles[i_b]];
895  SPoint3 p2 = gf_b->stl_vertices_xyz[gf_b->stl_triangles[i_b + 1]];
896  SPoint3 p3 = gf_b->stl_vertices_xyz[gf_b->stl_triangles[i_b + 2]];
897  double X_b[3] = {p1.x(), p2.x(), p3.x()};
898  double Y_b[3] = {p1.y(), p2.y(), p3.y()};
899  double Z_b[3] = {p1.z(), p2.z(), p3.z()};
900  for(int j = 0; j < 3; j++) {
901  X_b[j] /= scaling;
902  Y_b[j] /= scaling;
903  Z_b[j] /= scaling;
904  }
905  if(!(std::abs(X[0] - X_b[0]) < 1e-12 &&
906  std::abs(X[1] - X_b[1]) < 1e-12 &&
907  std::abs(X[2] - X_b[2]) < 1e-12 &&
908  std::abs(Y[0] - Y_b[0]) < 1e-12 &&
909  std::abs(Y[1] - Y_b[1]) < 1e-12 &&
910  std::abs(Y[2] - Y_b[2]) < 1e-12 &&
911  std::abs(Z[0] - Z_b[0]) < 1e-12 &&
912  std::abs(Z[1] - Z_b[1]) < 1e-12 &&
913  std::abs(Z[2] - Z_b[2]) < 1e-12)) {
914  int inters = intersectLineTriangle(X_b, Y_b, Z_b, P, N, 1.e-9);
915  nb_intersect += inters;
916  }
917  }
918  ++it_b;
919  }
920  Msg::Debug("Volume %d, surface %d: %d intersections", tag(), gf->tag(),
921  nb_intersect);
922  if(nb_intersect >= 0)
923  break; // negative value means intersection is not "robust"
924  }
925 
926  if(nb_intersect < 0) { setRand(rrr); }
927  else {
928  if(nb_intersect % 2 == 1) {
929  // odd nb of intersections: the normal points inside the region
930  gf->meshAttributes.reverseMesh = true;
931  Msg::Info("Setting reverse mesh attribute on surface %d", gf->tag());
932  }
933  else {
934  gf->meshAttributes.reverseMesh = false;
935  }
936 #if defined(HAVE_MESH)
937  // if a mesh already exists, reorient it
938  orientMeshGFace o;
939  o(gf);
940 #endif
941  ++it;
942  }
943  }
944 
945  return true;
946 }
947 
949 {
950  if(geomType() != GEntity::DiscreteVolume) return false;
951  if(haveParametrization()) return false;
952  std::vector<GFace *> f = faces();
953  for(std::size_t i = 0; i < f.size(); i++) {
954  if(f[i]->geomType() != GEntity::DiscreteSurface) return false;
955  auto *df = dynamic_cast<discreteFace *>(f[i]);
956  if(df && df->haveParametrization()) return false;
957  }
958  std::vector<GEdge *> e = edges();
959  for(std::size_t i = 0; i < e.size(); i++) {
960  if(e[i]->geomType() != GEntity::DiscreteCurve) return false;
961  auto *de = dynamic_cast<discreteEdge *>(e[i]);
962  if(de && de->haveParametrization()) return false;
963  }
964  return true;
965 }
GRegion::edgeConnected
bool edgeConnected(GRegion *r) const
Definition: GRegion.cpp:472
tags
static std::map< SPoint2, unsigned int > tags
Definition: drawGraph2d.cpp:400
GRegion::l_faces
std::vector< GFace * > l_faces
Definition: GRegion.h:30
MTrihedron.h
GRegion::GRegion
GRegion(GModel *model, int tag)
Definition: GRegion.cpp:28
GRegion::addPyramid
void addPyramid(MPyramid *p)
Definition: GRegion.h:173
GPoint::y
double y() const
Definition: GPoint.h:22
GFace.h
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
NO_QUADTRI
#define NO_QUADTRI
Definition: GmshDefines.h:263
GRegion::getMeshElementByType
MElement * getMeshElementByType(const int familyType, const std::size_t index) const
Definition: GRegion.cpp:151
MTetrahedron
Definition: MTetrahedron.h:34
GFace
Definition: GFace.h:33
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEntity::model
GModel * model() const
Definition: GEntity.h:277
MElement::getIntegrationPoints
virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
Definition: MElement.h:436
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
MESH_TRANSFINITE
#define MESH_TRANSFINITE
Definition: GmshDefines.h:259
GRegion::deleteMesh
virtual void deleteMesh()
Definition: GRegion.cpp:39
MTriangle::getIntegrationPoints
virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
Definition: MTriangle.cpp:353
discreteEdge
Definition: discreteEdge.h:12
MVertex
Definition: MVertex.h:24
GEntity::_obb
SOrientedBoundingBox * _obb
Definition: GEntity.h:52
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
GEntity::OpenCascadeModel
@ OpenCascadeModel
Definition: GEntity.h:82
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GRegion::writeGEO
virtual void writeGEO(FILE *fp)
Definition: GRegion.cpp:397
VertexArray.h
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
GRegion::addPolyhedron
void addPolyhedron(MPolyhedron *p)
Definition: GRegion.h:174
GRegion::getOBB
virtual SOrientedBoundingBox getOBB()
Definition: GRegion.cpp:194
GModel::getFaceByTag
GFace * getFaceByTag(int n) const
Definition: GModel.cpp:326
GFace::meshAttributes
struct GFace::@18 meshAttributes
SBoundingBox3d::min
SPoint3 min() const
Definition: SBoundingBox3d.h:90
Range::high
T high() const
Definition: Range.h:20
SVector3
Definition: SVector3.h:16
GRegion::transfinite_vertices
std::vector< std::vector< std::vector< MVertex * > > > transfinite_vertices
Definition: GRegion.h:161
SOrientedBoundingBox
Definition: SOrientedBoundingBox.h:33
GEntity::getNativeType
virtual ModelType getNativeType() const
Definition: GEntity.h:268
GRegion::getNumMeshElements
std::size_t getNumMeshElements() const
Definition: GRegion.cpp:60
MPyramid
Definition: MPyramid.h:32
GRegion::getNumMeshElementsByType
std::size_t getNumMeshElementsByType(const int familyType) const
Definition: GRegion.cpp:66
MPrism
Definition: MPrism.h:34
MVertex::point
SPoint3 point() const
Definition: MVertex.h:67
GModel::destroyMeshCaches
void destroyMeshCaches()
Definition: GModel.cpp:214
GFace::addRegion
void addRegion(GRegion *r)
Definition: GFace.h:69
GmshMessage.h
MAX_LC
#define MAX_LC
Definition: GEntity.h:19
GRegion::getNumMeshParentElements
std::size_t getNumMeshParentElements()
Definition: GRegion.cpp:84
GEntity
Definition: GEntity.h:31
GRegion::isFullyDiscrete
virtual bool isFullyDiscrete()
Definition: GRegion.cpp:948
GPoint
Definition: GPoint.h:13
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
GEntity::PartitionVolume
@ PartitionVolume
Definition: GEntity.h:124
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
GRegion::removeElements
void removeElements(int type)
Definition: GRegion.cpp:665
GEntity::DiscreteCurve
@ DiscreteCurve
Definition: GEntity.h:104
GRegion::addHexahedron
void addHexahedron(MHexahedron *h)
Definition: GRegion.h:171
GEntity::setColor
virtual void setColor(unsigned color, bool recursive=false)
Definition: GEntity.h:319
GRegion::polyhedra
std::vector< MPolyhedron * > polyhedra
Definition: GRegion.h:168
GPoint::z
double z() const
Definition: GPoint.h:23
GEntity::setVisibility
virtual void setVisibility(char val, bool recursive=false)
Definition: GEntity.h:308
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GRegion::faces
virtual std::vector< GFace * > faces() const
Definition: GRegion.h:64
GFace::stl_vertices_xyz
std::vector< SPoint3 > stl_vertices_xyz
Definition: GFace.h:409
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
GRegion::hexahedra
std::vector< MHexahedron * > hexahedra
Definition: GRegion.h:164
GRegion::setColor
virtual void setColor(unsigned int val, bool recursive=false)
Definition: GRegion.cpp:261
GRegion.h
MTrihedron
Definition: MTrihedron.h:31
IntPt::weight
double weight
Definition: GaussIntegration.h:14
Range
Definition: Range.h:10
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
MElementCut.h
boundaryLayersData.h
MHexahedron.h
GRegion::writePY
virtual void writePY(FILE *fp)
Definition: GRegion.cpp:439
MESH_UNSTRUCTURED
#define MESH_UNSTRUCTURED
Definition: GmshDefines.h:260
GRegion::getEmbeddedMeshVertices
std::vector< MVertex * > getEmbeddedMeshVertices() const
Definition: GRegion.cpp:571
GEntity::DiscreteVolume
@ DiscreteVolume
Definition: GEntity.h:120
norm
void norm(const double *vec, double *norm)
Definition: gmshLevelset.cpp:202
GModel
Definition: GModel.h:44
GRegion::vertices
virtual std::vector< GVertex * > vertices() const
Definition: GRegion.cpp:603
ExtrudeParams.h
MPyramid.h
GEntity::geomType
virtual GeomType geomType() const
Definition: GEntity.h:238
GmshDefines.h
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
GRegion::trihedra
std::vector< MTrihedron * > trihedra
Definition: GRegion.h:167
GRegion::l_dirs
std::vector< int > l_dirs
Definition: GRegion.h:34
MHexahedron
Definition: MHexahedron.h:28
GRegion::edges
virtual std::vector< GEdge * > const & edges() const
Definition: GRegion.cpp:459
GRegion::embedded_faces
std::vector< GFace * > embedded_faces
Definition: GRegion.h:32
MElement
Definition: MElement.h:30
GFace::stl_triangles
std::vector< int > stl_triangles
Definition: GFace.h:412
GEntity::tag
int tag() const
Definition: GEntity.h:280
MPolyhedron
Definition: MElementCut.h:21
GRegion::getAdditionalInfoString
virtual std::string getAdditionalInfoString(bool multline=false)
Definition: GRegion.cpp:334
GRegion::computeSolidProperties
double computeSolidProperties(std::vector< double > cg, std::vector< double > inertia)
Definition: GRegion.cpp:484
discreteFace.h
prodve
void prodve(double a[3], double b[3], double c[3])
Definition: Numeric.h:105
intersectLineTriangle
static int intersectLineTriangle(double X[3], double Y[3], double Z[3], double P[3], double N[3], const double eps_prec)
Definition: GRegion.cpp:797
SVector3::x
double x(void) const
Definition: SVector3.h:30
GRegion
Definition: GRegion.h:28
GRegion::addTetrahedron
void addTetrahedron(MTetrahedron *t)
Definition: GRegion.h:170
GRegion::prisms
std::vector< MPrism * > prisms
Definition: GRegion.h:165
MTriangle
Definition: MTriangle.h:26
GEntity::DiscreteSurface
@ DiscreteSurface
Definition: GEntity.h:117
TYPE_PYR
#define TYPE_PYR
Definition: GmshDefines.h:69
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
MElement::pnt
virtual void pnt(double u, double v, double w, SPoint3 &p) const
Definition: MElement.cpp:1072
LegendrePolynomials::df
void df(int n, double u, double *val)
Definition: orthogonalBasis.cpp:103
GRegion::embedded_vertices
std::vector< GVertex * > embedded_vertices
Definition: GRegion.h:31
meshGFace.h
GRegion::addElement
void addElement(int type, MElement *e)
Definition: GRegion.cpp:613
discreteEdge.h
GRegion::getStartElementType
MElement *const * getStartElementType(int type) const
Definition: GRegion.cpp:102
IntPt
Definition: GaussIntegration.h:12
GRegion::~GRegion
virtual ~GRegion()
Definition: GRegion.cpp:33
MTetrahedron.h
GRegion::setVisibility
virtual void setVisibility(char val, bool recursive=false)
Definition: GRegion.cpp:250
SVector3::y
double y(void) const
Definition: SVector3.h:31
GRegion::reorder
virtual bool reorder(const int elementType, const std::vector< std::size_t > &ordering)
Definition: GRegion.cpp:679
GRegion::meshAttributes
struct GRegion::@20 meshAttributes
GRegion::delFace
int delFace(GFace *face)
Definition: GRegion.cpp:272
GRegion::resetMeshAttributes
virtual void resetMeshAttributes()
Definition: GRegion.cpp:170
orientMeshGFace
Definition: meshGFace.h:42
SVector3::z
double z(void) const
Definition: SVector3.h:32
SOrientedBoundingBox::buildOBB
static SOrientedBoundingBox * buildOBB(std::vector< SPoint3 > &vertices)
Definition: SOrientedBoundingBox.cpp:150
setRand
static void setRand(double r[6])
Definition: GRegion.cpp:787
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
MPrism.h
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
GFace::buildSTLTriangulation
virtual bool buildSTLTriangulation(bool force=false)
Definition: GFace.cpp:1585
TYPE_TRIH
#define TYPE_TRIH
Definition: GmshDefines.h:76
MElement::getJacobian
virtual double getJacobian(const fullMatrix< double > &gsf, double jac[3][3]) const
Definition: MElement.cpp:868
GRegion::addPrism
void addPrism(MPrism *p)
Definition: GRegion.h:172
GModel.h
MElement::getPolynomialOrder
virtual int getPolynomialOrder() const
Definition: MElement.h:78
GRegion::removeElement
void removeElement(int type, MElement *e)
Definition: GRegion.cpp:627
Range::low
T low() const
Definition: Range.h:18
GRegion::embedded_edges
std::vector< GEdge * > embedded_edges
Definition: GRegion.h:33
norme
double norme(double a[3])
Definition: Numeric.h:123
SBoundingBox3d::max
SPoint3 max() const
Definition: SBoundingBox3d.h:91
GRegion::setBoundFaces
void setBoundFaces(const std::set< int > &tagFaces)
Definition: GRegion.cpp:294
GRegion::addTrihedron
void addTrihedron(MTrihedron *t)
Definition: GRegion.h:175
GPoint::x
double x() const
Definition: GPoint.h:21
TYPE_POLYH
#define TYPE_POLYH
Definition: GmshDefines.h:73
GEntity::deleteVertexArrays
void deleteVertexArrays()
Definition: GEntity.cpp:27
SBoundingBox3d
Definition: SBoundingBox3d.h:21
GRegion::bounds
virtual SBoundingBox3d bounds(bool fast=false)
Definition: GRegion.cpp:179
GFace::reverseMesh
bool reverseMesh
Definition: GFace.h:359
GRegion::getMeshElement
MElement * getMeshElement(std::size_t index) const
Definition: GRegion.cpp:127
sys3x3_with_tol
int sys3x3_with_tol(double mat[3][3], double b[3], double res[3], double *det)
Definition: Numeric.cpp:177
GRegion::tetrahedra
std::vector< MTetrahedron * > tetrahedra
Definition: GRegion.h:163
GEntity::haveParametrization
virtual bool haveParametrization()
Definition: GEntity.h:251
SVector3::normalize
double normalize()
Definition: SVector3.h:38
GRegion::setOutwardOrientationMeshConstraint
bool setOutwardOrientationMeshConstraint()
Definition: GRegion.cpp:839
discreteFace
Definition: discreteFace.h:18