GteTSManifoldMesh.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
9 #include <LowLevel/GteLogger.h>
11 using namespace gte;
12 
14 {
15 }
16 
18  :
19  mTCreator(tCreator ? tCreator : CreateTriangle),
20  mSCreator(sCreator ? sCreator : CreateTetrahedron),
22 {
23 }
24 
26 {
27  *this = mesh;
28 }
29 
31 {
32  Clear();
33 
34  mTCreator = mesh.mTCreator;
35  mSCreator = mesh.mSCreator;
37  for (auto const& element : mesh.mSMap)
38  {
39  Insert(element.first.V[0], element.first.V[1], element.first.V[2], element.first.V[3]);
40  }
41 
42  return *this;
43 }
44 
46 {
47  return mTMap;
48 }
49 
51 {
52  return mSMap;
53 }
54 
55 std::shared_ptr<TSManifoldMesh::Triangle> TSManifoldMesh::CreateTriangle(int v0, int v1, int v2)
56 {
57  return std::make_shared<Triangle>(v0, v1, v2);
58 }
59 
60 std::shared_ptr<TSManifoldMesh::Tetrahedron> TSManifoldMesh::CreateTetrahedron(int v0, int v1, int v2, int v3)
61 {
62  return std::make_shared<Tetrahedron>(v0, v1, v2, v3);
63 }
64 
66 {
68 }
69 
70 std::shared_ptr<TSManifoldMesh::Tetrahedron> TSManifoldMesh::Insert(int v0, int v1, int v2, int v3)
71 {
72  TetrahedronKey<true> skey(v0, v1, v2, v3);
73  if (mSMap.find(skey) != mSMap.end())
74  {
75  // The tetrahedron already exists. Return a null pointer as a signal
76  // to the caller that the insertion failed.
77  return nullptr;
78  }
79 
80  // Add the new tetrahedron.
81  std::shared_ptr<Tetrahedron> tetra = mSCreator(v0, v1, v2, v3);
82  mSMap[skey] = tetra;
83 
84  // Add the faces to the mesh if they do not already exist.
85  for (int i = 0; i < 4; ++i)
86  {
87  auto opposite = TetrahedronKey<true>::oppositeFace[i];
88  TriangleKey<false> tkey(tetra->V[opposite[0]], tetra->V[opposite[1]], tetra->V[opposite[2]]);
89  std::shared_ptr<Triangle> face;
90  auto titer = mTMap.find(tkey);
91  if (titer == mTMap.end())
92  {
93  // This is the first time the face is encountered.
94  face = mTCreator(tetra->V[opposite[0]], tetra->V[opposite[1]], tetra->V[opposite[2]]);
95  mTMap[tkey] = face;
96 
97  // Update the face and tetrahedron.
98  face->T[0] = tetra;
99  tetra->T[i] = face;
100  }
101  else
102  {
103  // This is the second time the face is encountered.
104  face = titer->second;
105  if (!face)
106  {
107  LogError("Unexpected condition.");
108  return nullptr;
109  }
110 
111  // Update the face.
112  if (face->T[1].lock())
113  {
115  {
116  LogInformation("The mesh must be manifold.");
117  }
118  return nullptr;
119  }
120  face->T[1] = tetra;
121 
122  // Update the adjacent tetrahedra.
123  auto adjacent = face->T[0].lock();
124  if (!adjacent)
125  {
126  LogError("Unexpected condition.");
127  return nullptr;
128  }
129  for (int j = 0; j < 4; ++j)
130  {
131  if (adjacent->T[j].lock() == face)
132  {
133  adjacent->S[j] = tetra;
134  break;
135  }
136  }
137 
138  // Update the tetrahedron.
139  tetra->T[i] = face;
140  tetra->S[i] = adjacent;
141  }
142  }
143 
144  return tetra;
145 }
146 
147 bool TSManifoldMesh::Remove(int v0, int v1, int v2, int v3)
148 {
149  TetrahedronKey<true> skey(v0, v1, v2, v3);
150  auto siter = mSMap.find(skey);
151  if (siter == mSMap.end())
152  {
153  // The tetrahedron does not exist.
154  return false;
155  }
156 
157  // Get the tetrahedron.
158  std::shared_ptr<Tetrahedron> tetra = siter->second;
159 
160  // Remove the faces and update adjacent tetrahedra if necessary.
161  for (int i = 0; i < 4; ++i)
162  {
163  // Inform the faces the tetrahedron is being deleted.
164  auto face = tetra->T[i].lock();
165  if (!face)
166  {
167  // The triangle edge should be nonnull.
168  LogError("Unexpected condition.");
169  return false;
170  }
171 
172  if (face->T[0].lock() == tetra)
173  {
174  // One-tetrahedron faces always have pointer at index zero.
175  face->T[0] = face->T[1];
176  face->T[1].reset();
177  }
178  else if (face->T[1].lock() == tetra)
179  {
180  face->T[1].reset();
181  }
182  else
183  {
184  LogError("Unexpected condition.");
185  return false;
186  }
187 
188  // Remove the face if you have the last reference to it.
189  if (!face->T[0].lock() && !face->T[1].lock())
190  {
191  TriangleKey<false> tkey(face->V[0], face->V[1], face->V[2]);
192  mTMap.erase(tkey);
193  }
194 
195  // Inform adjacent tetrahedra the tetrahedron is being deleted.
196  auto adjacent = tetra->S[i].lock();
197  if (adjacent)
198  {
199  for (int j = 0; j < 4; ++j)
200  {
201  if (adjacent->S[j].lock() == tetra)
202  {
203  adjacent->S[j].reset();
204  break;
205  }
206  }
207  }
208  }
209 
210  mSMap.erase(skey);
211  return true;
212 }
213 
215 {
216  mTMap.clear();
217  mSMap.clear();
218 }
219 
221 {
222  for (auto const& element : mSMap)
223  {
224  auto tri = element.second;
225  if (!tri->S[0].lock() || !tri->S[1].lock())
226  {
227  return false;
228  }
229  }
230  return true;
231 }
232 
234 {
235 }
236 
238 {
239  V[0] = v0;
240  V[1] = v1;
241  V[2] = v2;
242 }
243 
245 {
246 }
247 
249 {
250  V[0] = v0;
251  V[1] = v1;
252  V[2] = v2;
253  V[3] = v3;
254 }
std::map< TriangleKey< false >, std::shared_ptr< Triangle > > TMap
bool Remove(int v0, int v1, int v2, int v3)
#define LogInformation(message)
Definition: GteLogger.h:98
void AssertOnNonmanifoldInsertion(bool doAssert)
GLfloat GLfloat v1
Definition: glcorearb.h:812
Triangle(int v0, int v1, int v2)
TSManifoldMesh(TCreator tCreator=nullptr, SCreator sCreator=nullptr)
TSManifoldMesh & operator=(TSManifoldMesh const &mesh)
#define LogError(message)
Definition: GteLogger.h:92
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:814
GLfloat v0
Definition: glcorearb.h:811
std::shared_ptr< Tetrahedron >(* SCreator)(int, int, int, int)
TMap const & GetTriangles() const
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
std::map< TetrahedronKey< true >, std::shared_ptr< Tetrahedron > > SMap
Tetrahedron(int v0, int v1, int v2, int v3)
std::shared_ptr< Tetrahedron > Insert(int v0, int v1, int v2, int v3)
std::shared_ptr< Triangle >(* TCreator)(int, int, int)
static std::shared_ptr< Tetrahedron > CreateTetrahedron(int v0, int v1, int v2, int v3)
static std::shared_ptr< Triangle > CreateTriangle(int v0, int v1, int v2)
GLenum GLuint GLint GLenum face
Definition: glext.h:3311
SMap const & GetTetrahedra() const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01