xmsgeom  1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
TrAutoFixFourTrianglePts.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
7 //------------------------------------------------------------------------------
8 
9 //----- Included files ---------------------------------------------------------
10 
11 // 1. Precompiled header
12 
13 // 2. My own header
15 
16 // 3. Standard library headers
17 #include <map>
18 
19 // 4. External library headers
20 
21 // 5. Shared code headers
22 #include <xmscore/math/math.h>
23 #include <xmscore/misc/XmError.h>
24 #include <xmscore/misc/Observer.h>
26 
27 // 6. Non-shared code headers
28 
29 //----- Forward declarations ---------------------------------------------------
30 
31 //----- External globals -------------------------------------------------------
32 
33 //----- Namespace declaration --------------------------------------------------
34 
35 namespace xms
36 {
37 //----- Constants / Enumerations -----------------------------------------------
38 
39 //----- Classes / Structs ------------------------------------------------------
40 
43 {
44 public:
47 
48 public:
49  virtual void Fix(BSHP<TrTin> a_tin) override;
52  virtual void SetObserver(BSHP<Observer> a_) override { m_observer = a_; }
55  virtual void SetUndeleteablePtIdxs(VecInt& a_ptIdx) override
56  {
57  m_noDelete.clear();
58  m_noDelete.insert(a_ptIdx.begin(), a_ptIdx.end());
59  }
60 
61  void FillAdjTrisIfNeeded();
62  void GetPtsAndTrisToDelete();
63  std::pair<int, int> EdgeOppositePt(int a_ptIdx, int a_tri, VecInt& a_tris);
64  void MakeTwoNewTriangles(VecPt3d& a_pts, std::map<int, int> a_edges, int a_tris[2][3]);
65  void ReplaceTriangle(int& a_tIdx, int a_newTri[3], VecInt& a_tris);
66  void RenumberPts();
67  void RenumberTris();
68  void RemovePts();
69  void RemoveTris();
70  void ClearAdjTrisIfCreated();
71 
72 private:
73 private:
74  BSHP<TrTin> m_tin;
75  BSHP<Observer> m_observer;
80 }; // class TrOuterTriangleDeleterImpl
81 
82 //----- Internal functions -----------------------------------------------------
83 
84 //----- Class / Function definitions -------------------------------------------
85 
91 //------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------
96 , m_tin()
97 , m_observer()
98 , m_removeAdjTris(false)
99 , m_ptsToDelete()
100 , m_trisToDelete()
101 {
102 } // TrAutoFixFourTrianglePtsImpl::TrAutoFixFourTrianglePtsImpl
103 //------------------------------------------------------------------------------
105 //------------------------------------------------------------------------------
106 TrAutoFixFourTrianglePtsImpl::~TrAutoFixFourTrianglePtsImpl()
107 {
108 }
109 //------------------------------------------------------------------------------
113 //------------------------------------------------------------------------------
114 void TrAutoFixFourTrianglePtsImpl::Fix(BSHP<TrTin> a_tin)
115 {
116  m_tin = a_tin;
119  RenumberPts();
120  RenumberTris();
121  RemovePts();
122  RemoveTris();
124 } // TrOuterTriangleDeleterImpl::Fix
125 //------------------------------------------------------------------------------
127 //------------------------------------------------------------------------------
129 {
130  VecInt2d& adjTris(m_tin->TrisAdjToPts());
131  if (adjTris.empty())
132  {
133  m_tin->BuildTrisAdjToPts();
134  m_removeAdjTris = true;
135  }
136 } // TrAutoFixFourTrianglePtsImpl::FillAdjTrisIfNeeded
137 //------------------------------------------------------------------------------
139 //------------------------------------------------------------------------------
141 {
142  VecInt2d& adjTris(m_tin->TrisAdjToPts());
143  VecInt& tris(m_tin->Triangles());
144  VecPt3d& pts(m_tin->Points());
145  int npts = static_cast<int>(adjTris.size());
146  auto itEnd = m_noDelete.end();
147  for (int i = 0; i < npts; ++i)
148  {
149  auto it = m_noDelete.find(i);
150  if (4 == adjTris[i].size() && it == itEnd)
151  {
152  m_ptsToDelete.insert(i);
153  m_trisToDelete.insert(adjTris[i][2]);
154  m_trisToDelete.insert(adjTris[i][3]);
155  std::map<int, int> mapii;
156  for (int t = 0; t < 4; ++t)
157  {
158  mapii.insert(EdgeOppositePt(i, adjTris[i][t], tris));
159  }
160  int newTris[2][3];
161  MakeTwoNewTriangles(pts, mapii, newTris);
162  ReplaceTriangle(adjTris[i][0], newTris[0], tris);
163  ReplaceTriangle(adjTris[i][1], newTris[1], tris);
164  }
165  }
166 } // TrAutoFixFourTrianglePtsImpl::RemovePts
167 //------------------------------------------------------------------------------
174 //------------------------------------------------------------------------------
175 std::pair<int, int> TrAutoFixFourTrianglePtsImpl::EdgeOppositePt(int a_ptIdx,
176  int a_tri,
177  VecInt& a_tris)
178 {
179  int tIdx = a_tri * 3;
180  int* tPts = &a_tris[tIdx];
181  std::pair<int, int> rval(tPts[0], tPts[1]);
182  if (tPts[0] == a_ptIdx)
183  {
184  rval.first = tPts[1];
185  rval.second = tPts[2];
186  }
187  else if (tPts[1] == a_ptIdx)
188  {
189  rval.first = tPts[2];
190  rval.second = tPts[0];
191  }
192  return rval;
193 } // TrAutoFixFourTrianglePtsImpl::EdgeOppositePt
194 //------------------------------------------------------------------------------
201 //------------------------------------------------------------------------------
203  std::map<int, int> a_edges,
204  int a_tris[2][3])
205 {
206  int bound[4];
207  auto e = a_edges.begin();
208  for (int t = 0; t < 4; ++t)
209  {
210  bound[t] = e->first;
211  e = a_edges.find(e->second);
212  }
213  // is 0,2 closer or 1,3 closer
214  Pt3d &p0(a_pts[bound[0]]), &p1(a_pts[bound[1]]), &p2(a_pts[bound[2]]), &p3(a_pts[bound[3]]);
215  double d2_02 = MdistSq(p0.x, p0.y, p2.x, p2.y);
216  double d2_13 = MdistSq(p1.x, p1.y, p3.x, p3.y);
217  if (d2_02 < d2_13)
218  {
219  a_tris[0][0] = bound[0];
220  a_tris[0][1] = bound[1];
221  a_tris[0][2] = bound[2];
222  a_tris[1][0] = bound[0];
223  a_tris[1][1] = bound[2];
224  a_tris[1][2] = bound[3];
225  }
226  else
227  {
228  a_tris[0][0] = bound[0];
229  a_tris[0][1] = bound[1];
230  a_tris[0][2] = bound[3];
231  a_tris[1][0] = bound[1];
232  a_tris[1][1] = bound[2];
233  a_tris[1][2] = bound[3];
234  }
235 } // TrAutoFixFourTrianglePtsImpl::MakeTwoNewTriangles
236 //------------------------------------------------------------------------------
241 //------------------------------------------------------------------------------
242 void TrAutoFixFourTrianglePtsImpl::ReplaceTriangle(int& a_tIdx, int a_newTri[3], VecInt& a_tris)
243 {
244  int tIdx = a_tIdx * 3;
245  for (int i = 0; i < 3; ++i)
246  a_tris[tIdx + i] = a_newTri[i];
247 } // TrAutoFixFourTrianglePtsImpl::ReplaceTriangle
248 //------------------------------------------------------------------------------
250 //------------------------------------------------------------------------------
252 {
253  VecInt& tris(m_tin->Triangles());
254  VecPt3d& pts(m_tin->Points());
255 
256  VecInt oldToNewPt(pts.size());
257  auto it = m_ptsToDelete.begin();
258  auto itEnd = m_ptsToDelete.end();
259  int cnt(0), npts(static_cast<int>(pts.size()));
260  for (int i = 0; i < npts; ++i)
261  {
262  if (it != itEnd && i == *it)
263  {
264  cnt++;
265  it++;
266  }
267  oldToNewPt[i] = i - cnt;
268  }
269 
270  for (auto& t : tris)
271  t = oldToNewPt[t];
272 } // TrAutoFixFourTrianglePtsImpl::RenumberPts
273 //------------------------------------------------------------------------------
275 //------------------------------------------------------------------------------
277 {
278  if (m_removeAdjTris)
279  return;
280 
281  int ntri = static_cast<int>(m_tin->Triangles().size() / 3);
282  VecInt oldToNewTris(ntri);
283  auto it = m_trisToDelete.begin();
284  auto itEnd = m_trisToDelete.end();
285  int cnt(0);
286  for (int i = 0; i < ntri; ++i)
287  {
288  if (it != itEnd && i == *it)
289  {
290  cnt++;
291  it++;
292  }
293  oldToNewTris[i] = i - cnt;
294  }
295 
296  VecInt2d& adjTris(m_tin->TrisAdjToPts());
297  for (auto& v : adjTris)
298  for (auto& t : v)
299  t = oldToNewTris[t];
300 } // TrAutoFixFourTrianglePtsImpl::RenumberTris
301 //------------------------------------------------------------------------------
303 //------------------------------------------------------------------------------
305 {
306  VecPt3d& pts(m_tin->Points());
307  auto it = m_ptsToDelete.rbegin();
308  auto itEnd = m_ptsToDelete.rend();
309  for (; it != itEnd; ++it)
310  pts.erase(pts.begin() + *it);
311 } // TrAutoFixFourTrianglePtsImpl::RemovePts
312 //------------------------------------------------------------------------------
314 //------------------------------------------------------------------------------
316 {
317  SetInt delTris;
318  for (auto& t : m_trisToDelete)
319  {
320  int tIdx = t * 3;
321  delTris.insert(tIdx + 0);
322  delTris.insert(tIdx + 1);
323  delTris.insert(tIdx + 2);
324  }
325 
326  VecInt& tris(m_tin->Triangles());
327  auto it = delTris.rbegin();
328  auto itEnd = delTris.rend();
329  for (; it != itEnd; ++it)
330  tris.erase(tris.begin() + *it);
331 } // TrAutoFixFourTrianglePtsImpl::RemoveTris
332 //------------------------------------------------------------------------------
334 //------------------------------------------------------------------------------
336 {
337  VecInt2d& adjTris(m_tin->TrisAdjToPts());
338  adjTris.clear();
339  if (m_removeAdjTris)
340  return;
341  m_tin->BuildTrisAdjToPts();
342 } // TrAutoFixFourTrianglePtsImpl::ClearAdjTrisIfCreated
343 
348 //------------------------------------------------------------------------------
351 //------------------------------------------------------------------------------
352 BSHP<TrAutoFixFourTrianglePts> TrAutoFixFourTrianglePts::New()
353 {
354  BSHP<TrAutoFixFourTrianglePts> fixer(new TrAutoFixFourTrianglePtsImpl);
355  return fixer;
356 } // TrAutoFixFourTrianglePts::New
357 //------------------------------------------------------------------------------
359 //------------------------------------------------------------------------------
360 TrAutoFixFourTrianglePts::TrAutoFixFourTrianglePts()
361 {
362 }
363 TrAutoFixFourTrianglePts::~TrAutoFixFourTrianglePts()
364 {
365 }
366 
367 } // namespace xms
368 
369 #if CXX_TEST
370 // UNIT TESTS
373 
374 using namespace xms;
376 
379 
384 //------------------------------------------------------------------------------
386 //------------------------------------------------------------------------------
388 {
389  BSHP<VecPt3d> pts(new VecPt3d());
390  *pts = {{0, 0}, {10, 0}, {0, 10}, {10, 10}, {5, 5}};
391  BSHP<TrTin> tin = TrTin::New();
392  tin->SetPoints(pts);
393  TrTriangulatorPoints client(*pts, tin->Triangles(), &tin->TrisAdjToPts());
394  client.Triangulate();
395 
397  p.Fix(tin);
398 
399  TS_ASSERT_EQUALS(4, tin->Points().size());
400 
401 } // TrOuterTriangleDeleterTests::test1
402 
403 #endif // CXX_TEST
std::pair< int, int > EdgeOppositePt(int a_ptIdx, int a_tri, VecInt &a_tris)
Finds and removes the points connected to 4 triangles.
void RenumberTris()
Renumbers the triangle indexes in the adjacent triangles.
SetInt m_trisToDelete
triangles that will be deleted
virtual void SetObserver(BSHP< Observer > a_) override
Set the observer to use for feedback while processing.
void RemoveTris()
Removes triangles from the triangles vector in the TIN.
std::vector< int > VecInt
std::set< int > SetInt
static BSHP< TrTin > New()
Create a TrTinImpl object.
Definition: TrTin.cpp:1247
SetInt m_noDelete
indexes of points that can't be deleted
bool Triangulate()
Triangulate the points into a tin.
void FillAdjTrisIfNeeded()
Makes sure the adjacent triangles exist in the TIN.
SetInt m_ptsToDelete
points in the TIN that will be deleted
void MakeTwoNewTriangles(VecPt3d &a_pts, std::map< int, int > a_edges, int a_tris[2][3])
Makes 2 new triangles from the 4 edges passed into this method.
std::vector< Pt3d > VecPt3d
static BSHP< TrAutoFixFourTrianglePts > New()
Creates a TrAutoFixFourTrianglePtsImpl object.
void ReplaceTriangle(int &a_tIdx, int a_newTri[3], VecInt &a_tris)
Makes 2 new triangles from the 4 edges passed into this method.
virtual void Fix(BSHP< TrTin > a_tin) override
Removes any points in the tin that are connected to only 4 triangles. These points usually cause poor...
void GetPtsAndTrisToDelete()
Finds and removes the points connected to 4 triangles.
Used to delete points that are connected to 4 triangles and then retriangulate the void...
void test1()
Tests TrAutoFixFourTrianglePts.
void ClearAdjTrisIfCreated()
Clears the adjacent triangles if this class created them.
void RemovePts()
Removes points from the points vector of the TIN.
virtual void SetUndeleteablePtIdxs(VecInt &a_ptIdx) override
Set the indexes of points that can not be deleted.
std::vector< VecInt > VecInt2d
void RenumberPts()
Renumbers the point indexes in the triangles.
double MdistSq(_T x1, _U y1, _V x2, _W y2)
bool m_removeAdjTris
flag to remove adjacent tris when done
Class to triangulate simple points.