libMesh
libmesh_poly2tri.C
Go to the documentation of this file.
1 
2 #include "libmesh_cppunit.h"
3 
4 #ifdef LIBMESH_HAVE_POLY2TRI
5 # include "libmesh/ignore_warnings.h" // utf-8 comments should be fine...
6 # include "poly2tri/poly2tri.h"
7 # include "libmesh/restore_warnings.h"
8 #endif
9 
10 #include <numeric>
11 
12 class LibMeshPoly2TriTest : public CppUnit::TestCase {
13 public:
15 
16 #ifdef LIBMESH_HAVE_POLY2TRI
20 #endif
21 
23 
24 private:
25 
26 public:
27  void setUp()
28  {}
29 
30  void tearDown()
31  {}
32 
33 #ifdef LIBMESH_HAVE_POLY2TRI
35  {
36  LOG_UNIT_TEST;
37 
38  std::vector<p2t::Point> pentagon {{0,0},{1,0},{1,1},{.5,1.5},{0,1}};
39 
40  std::vector<p2t::Point *> api_shim(pentagon.size());
41  std::iota(api_shim.begin(), api_shim.end(), pentagon.data());
42 
43  p2t::CDT cdt(api_shim);
44 
45  cdt.Triangulate();
46 
47  auto tris = cdt.GetTriangles();
48 
49  // We mostly wanted to make sure this compiled, but might as well
50  // make sure it gave us the expected triangle count while we're at
51  // it.
52  CPPUNIT_ASSERT_EQUAL(tris.size(), std::size_t(3));
53  }
54 
56  {
57 // const double eps = 0; // This (or negative eps) succeeds
58 // const double eps = 1e-12; // This (or larger eps) succeeds
59  const double eps = 1e-15; // This gave EdgeEvent - null triangle with older Poly2Tri
60 
61  std::vector<p2t::Point> outer_boundary
62  {{0,0},{0.5,eps},{1,0},{1-eps,0.836541},
63  {1,2},{.46,1.46+eps},{0,1},{eps,0.5}};
64 
65  std::vector<p2t::Point *> api_shim(outer_boundary.size());
66  std::iota(api_shim.begin(), api_shim.end(), outer_boundary.data());
67 
68  const double r2o4 = std::sqrt(2.)/4;
69  std::vector<p2t::Point> hole_boundary
70  {{0.5+r2o4,0.5},{0.5,0.5+r2o4},{0.5-r2o4,0.5},{0.5-eps,0.5-r2o4}};
71 
72  std::vector<p2t::Point *> hole_shim(hole_boundary.size());
73  std::iota(hole_shim.begin(), hole_shim.end(), hole_boundary.data());
74 
75  p2t::CDT cdt(api_shim);
76  cdt.AddHole(hole_shim);
77 
78  std::vector<p2t::Point> interior_points
79  {{0.21,0.79},{0.21,0.21},{0.79,0.21}};
80  for (auto & p : interior_points)
81  cdt.AddPoint(&p);
82 
83  cdt.Triangulate();
84 
85  auto tris = cdt.GetTriangles();
86 
87  std::cout << "With perturbation " << eps << " we got " << tris.size() << " triangles!" << std::endl;
88 
89  // We mostly wanted to make sure this compiled, but might as well
90  // make sure it gave us the expected triangle count while we're at
91  // it.
92  CPPUNIT_ASSERT_EQUAL(tris.size(), std::size_t(18));
93  }
94 
96  {
97  // Points from a libMesh Poly2TriTriangulator failure case
98  std::vector<p2t::Point> outer_boundary
99  {{0, 0}, {1, 0}, {1, 2}, {0, 1}};
100 
101  std::vector<p2t::Point *> api_shim(outer_boundary.size());
102  std::iota(api_shim.begin(), api_shim.end(), outer_boundary.data());
103 
104  const double r2o4 = std::sqrt(2.)/4;
105  std::vector<p2t::Point> hole_boundary
106  {{0.5,0.5+r2o4},{0.5-r2o4,0.5},{0.5,0.5}};
107 
108  std::vector<p2t::Point *> hole_shim(hole_boundary.size());
109  std::iota(hole_shim.begin(), hole_shim.end(), hole_boundary.data());
110 
111  p2t::CDT cdt(api_shim);
112  cdt.AddHole(hole_shim);
113 
114  // const double eps = 1e-12; // fails
115  const double eps = 1e-11; // succeeds
116 
117  std::vector<p2t::Point> interior_points
118  {{0.5-(r2o4/2)-eps, 0.5+(r2o4/2)+eps}};
119 
120  for (auto & p : interior_points)
121  cdt.AddPoint(&p);
122 
123  cdt.Triangulate();
124  }
125 
126 #endif
127 };
128 
CPPUNIT_TEST(testLibMeshPoly2Tri)
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota was created back when std::iota was just an SGI STL extension.
Definition: utility.h:229
LIBMESH_CPPUNIT_TEST_SUITE(LibMeshPoly2TriTest)
CPPUNIT_TEST_SUITE_REGISTRATION(LibMeshPoly2TriTest)