GteVEManifoldMesh.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  mVCreator(vCreator ? vCreator : CreateVertex),
20  mECreator(eCreator ? eCreator : CreateEdge),
22 {
23 }
24 
26 {
27  return mVMap;
28 }
29 
31 {
32  return mEMap;
33 }
34 
35 std::shared_ptr<VEManifoldMesh::Vertex> VEManifoldMesh::CreateVertex(int v)
36 {
37  return std::make_shared<Vertex>(v);
38 }
39 
40 std::shared_ptr<VEManifoldMesh::Edge> VEManifoldMesh::CreateEdge(int v0, int v1)
41 {
42  return std::make_shared<Edge>(v0, v1);
43 }
44 
46 {
48 }
49 
50 std::shared_ptr<VEManifoldMesh::Edge> VEManifoldMesh::Insert(int v0, int v1)
51 {
52  std::pair<int,int> ekey(v0, v1);
53  if (mEMap.find(ekey) != mEMap.end())
54  {
55  // The edge already exists. Return a null pointer as a signal to
56  // the caller that the insertion failed.
57  return nullptr;
58  }
59 
60  // Add the new edge.
61  std::shared_ptr<Edge> edge = mECreator(v0, v1);
62  mEMap[ekey] = edge;
63 
64  // Add the vertices if they do not already exist.
65  for (int i = 0; i < 2; ++i)
66  {
67  int v = edge->V[i];
68  std::shared_ptr<Vertex> vertex;
69  auto viter = mVMap.find(v);
70  if (viter == mVMap.end())
71  {
72  // This is the first time the vertex is encountered.
73  vertex = mVCreator(v);
74  mVMap[v] = vertex;
75 
76  // Update the vertex.
77  vertex->E[0] = edge;
78  }
79  else
80  {
81  // This is the second time the vertex is encountered.
82  vertex = viter->second;
83  if (!vertex)
84  {
85  LogError("Unexpected condition.");
86  return nullptr;
87  }
88 
89  // Update the vertex.
90  if (vertex->E[1].lock())
91  {
93  {
94  LogInformation("The mesh must be manifold.");
95  }
96  return nullptr;
97  }
98  vertex->E[1] = edge;
99 
100  // Update the adjacent edge.
101  auto adjacent = vertex->E[0].lock();
102  if (!adjacent)
103  {
104  LogError("Unexpected condition.");
105  return nullptr;
106  }
107  for (int j = 0; j < 2; ++j)
108  {
109  if (adjacent->V[j] == v)
110  {
111  adjacent->E[j] = edge;
112  break;
113  }
114  }
115 
116  // Update the edge.
117  edge->E[i] = adjacent;
118  }
119  }
120 
121  return edge;
122 }
123 
125 {
126  std::pair<int,int> ekey(v0, v1);
127  auto eiter = mEMap.find(ekey);
128  if (eiter == mEMap.end())
129  {
130  // The edge does not exist.
131  return false;
132  }
133 
134  // Get the edge.
135  std::shared_ptr<Edge> edge = eiter->second;
136 
137  // Remove the vertices if necessary (when they are not shared).
138  for (int i = 0; i < 2; ++i)
139  {
140  // Inform the vertices the edge is being deleted.
141  auto viter = mVMap.find(edge->V[i]);
142  if (viter == mVMap.end())
143  {
144  // The edge vertices should be in the map.
145  LogError("Unexpected condition.");
146  return false;
147  }
148 
149  std::shared_ptr<Vertex> vertex = viter->second;
150  if (!vertex)
151  {
152  // Any <vkey,vertex> in the map must have a dynamically allocated
153  // Vertex object.
154  LogError("Unexpected condition.");
155  return false;
156  }
157  if (vertex->E[0].lock() == edge)
158  {
159  // One-edge vertices always have pointer at index zero.
160  vertex->E[0] = vertex->E[1];
161  vertex->E[1].reset();
162  }
163  else if (vertex->E[1].lock() == edge)
164  {
165  vertex->E[1].reset();
166  }
167  else
168  {
169  LogError("Unexpected condition.");
170  return false;
171  }
172 
173  // Remove the vertex if you have the last reference to it.
174  if (!vertex->E[0].lock() && !vertex->E[1].lock())
175  {
176  mVMap.erase(vertex->V);
177  }
178 
179  // Inform adjacent edges the edge is being deleted.
180  auto adjacent = edge->E[i].lock();
181  if (adjacent)
182  {
183  for (int j = 0; j < 2; ++j)
184  {
185  if (adjacent->E[j].lock() == edge)
186  {
187  adjacent->E[j].reset();
188  break;
189  }
190  }
191  }
192  }
193 
194  mEMap.erase(ekey);
195  return true;
196 }
197 
199 {
200  for (auto const& element : mVMap)
201  {
202  auto vertex = element.second;
203  if (!vertex->E[0].lock() || !vertex->E[1].lock())
204  {
205  return false;
206  }
207  }
208  return true;
209 }
210 
212 {
213 }
214 
216 {
217  V = v;
218 }
219 
221 {
222 }
223 
225 {
226  V[0] = v0;
227  V[1] = v1;
228 }
EMap const & GetEdges() const
std::shared_ptr< Edge >(* ECreator)(int, int)
#define LogInformation(message)
Definition: GteLogger.h:98
GLfloat GLfloat v1
Definition: glcorearb.h:812
std::shared_ptr< Edge > Insert(int v0, int v1)
std::shared_ptr< Vertex >(* VCreator)(int)
static std::shared_ptr< Vertex > CreateVertex(int v0)
std::map< int, std::shared_ptr< Vertex > > VMap
#define LogError(message)
Definition: GteLogger.h:92
GLfloat v0
Definition: glcorearb.h:811
static std::shared_ptr< Edge > CreateEdge(int v0, int v1)
std::map< std::pair< int, int >, std::shared_ptr< Edge > > EMap
const GLdouble * v
Definition: glcorearb.h:832
VEManifoldMesh(VCreator vCreator=nullptr, ECreator eCreator=nullptr)
void AssertOnNonmanifoldInsertion(bool doAssert)
VMap const & GetVertices() const
bool Remove(int v0, int v1)


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