1 /* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
2  All rights reserved.
3 
4 
5  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 
7  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 
9  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10 
11  3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
12 
13  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  */
15 #include "vhacdManifoldMesh.h"
16 namespace VHACD
17 {
TMMVertex(void)18 TMMVertex::TMMVertex(void)
19 {
20 	Initialize();
21 }
Initialize()22 void TMMVertex::Initialize()
23 {
24 	m_name = 0;
25 	m_id = 0;
26 	m_duplicate = 0;
27 	m_onHull = false;
28 	m_tag = false;
29 }
30 
~TMMVertex(void)31 TMMVertex::~TMMVertex(void)
32 {
33 }
TMMEdge(void)34 TMMEdge::TMMEdge(void)
35 {
36 	Initialize();
37 }
Initialize()38 void TMMEdge::Initialize()
39 {
40 	m_id = 0;
41 	m_triangles[0] = m_triangles[1] = m_newFace = 0;
42 	m_vertices[0] = m_vertices[1] = 0;
43 }
~TMMEdge(void)44 TMMEdge::~TMMEdge(void)
45 {
46 }
Initialize()47 void TMMTriangle::Initialize()
48 {
49 	m_id = 0;
50 	for (int i = 0; i < 3; i++)
51 	{
52 		m_edges[i] = 0;
53 		m_vertices[0] = 0;
54 	}
55 	m_visible = false;
56 }
TMMTriangle(void)57 TMMTriangle::TMMTriangle(void)
58 {
59 	Initialize();
60 }
~TMMTriangle(void)61 TMMTriangle::~TMMTriangle(void)
62 {
63 }
TMMesh()64 TMMesh::TMMesh()
65 {
66 }
~TMMesh(void)67 TMMesh::~TMMesh(void)
68 {
69 }
GetIFS(Vec3<double> * const points,Vec3<int> * const triangles)70 void TMMesh::GetIFS(Vec3<double>* const points, Vec3<int>* const triangles)
71 {
72 	size_t nV = m_vertices.GetSize();
73 	size_t nT = m_triangles.GetSize();
74 
75 	for (size_t v = 0; v < nV; v++)
76 	{
77 		points[v] = m_vertices.GetData().m_pos;
78 		m_vertices.GetData().m_id = v;
79 		m_vertices.Next();
80 	}
81 	for (size_t f = 0; f < nT; f++)
82 	{
83 		TMMTriangle& currentTriangle = m_triangles.GetData();
84 		triangles[f].X() = static_cast<int>(currentTriangle.m_vertices[0]->GetData().m_id);
85 		triangles[f].Y() = static_cast<int>(currentTriangle.m_vertices[1]->GetData().m_id);
86 		triangles[f].Z() = static_cast<int>(currentTriangle.m_vertices[2]->GetData().m_id);
87 		m_triangles.Next();
88 	}
89 }
Clear()90 void TMMesh::Clear()
91 {
92 	m_vertices.Clear();
93 	m_edges.Clear();
94 	m_triangles.Clear();
95 }
Copy(TMMesh & mesh)96 void TMMesh::Copy(TMMesh& mesh)
97 {
98 	Clear();
99 	// updating the id's
100 	size_t nV = mesh.m_vertices.GetSize();
101 	size_t nE = mesh.m_edges.GetSize();
102 	size_t nT = mesh.m_triangles.GetSize();
103 	for (size_t v = 0; v < nV; v++)
104 	{
105 		mesh.m_vertices.GetData().m_id = v;
106 		mesh.m_vertices.Next();
107 	}
108 	for (size_t e = 0; e < nE; e++)
109 	{
110 		mesh.m_edges.GetData().m_id = e;
111 		mesh.m_edges.Next();
112 	}
113 	for (size_t f = 0; f < nT; f++)
114 	{
115 		mesh.m_triangles.GetData().m_id = f;
116 		mesh.m_triangles.Next();
117 	}
118 	// copying data
119 	m_vertices = mesh.m_vertices;
120 	m_edges = mesh.m_edges;
121 	m_triangles = mesh.m_triangles;
122 
123 	// generate mapping
124 	CircularListElement<TMMVertex>** vertexMap = new CircularListElement<TMMVertex>*[nV];
125 	CircularListElement<TMMEdge>** edgeMap = new CircularListElement<TMMEdge>*[nE];
126 	CircularListElement<TMMTriangle>** triangleMap = new CircularListElement<TMMTriangle>*[nT];
127 	for (size_t v = 0; v < nV; v++)
128 	{
129 		vertexMap[v] = m_vertices.GetHead();
130 		m_vertices.Next();
131 	}
132 	for (size_t e = 0; e < nE; e++)
133 	{
134 		edgeMap[e] = m_edges.GetHead();
135 		m_edges.Next();
136 	}
137 	for (size_t f = 0; f < nT; f++)
138 	{
139 		triangleMap[f] = m_triangles.GetHead();
140 		m_triangles.Next();
141 	}
142 
143 	// updating pointers
144 	for (size_t v = 0; v < nV; v++)
145 	{
146 		if (vertexMap[v]->GetData().m_duplicate)
147 		{
148 			vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id];
149 		}
150 	}
151 	for (size_t e = 0; e < nE; e++)
152 	{
153 		if (edgeMap[e]->GetData().m_newFace)
154 		{
155 			edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id];
156 		}
157 		if (nT > 0)
158 		{
159 			for (int f = 0; f < 2; f++)
160 			{
161 				if (edgeMap[e]->GetData().m_triangles[f])
162 				{
163 					edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id];
164 				}
165 			}
166 		}
167 		for (int v = 0; v < 2; v++)
168 		{
169 			if (edgeMap[e]->GetData().m_vertices[v])
170 			{
171 				edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id];
172 			}
173 		}
174 	}
175 	for (size_t f = 0; f < nT; f++)
176 	{
177 		if (nE > 0)
178 		{
179 			for (int e = 0; e < 3; e++)
180 			{
181 				if (triangleMap[f]->GetData().m_edges[e])
182 				{
183 					triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id];
184 				}
185 			}
186 		}
187 		for (int v = 0; v < 3; v++)
188 		{
189 			if (triangleMap[f]->GetData().m_vertices[v])
190 			{
191 				triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id];
192 			}
193 		}
194 	}
195 	delete[] vertexMap;
196 	delete[] edgeMap;
197 	delete[] triangleMap;
198 }
CheckConsistancy()199 bool TMMesh::CheckConsistancy()
200 {
201 	size_t nE = m_edges.GetSize();
202 	size_t nT = m_triangles.GetSize();
203 	for (size_t e = 0; e < nE; e++)
204 	{
205 		for (int f = 0; f < 2; f++)
206 		{
207 			if (!m_edges.GetHead()->GetData().m_triangles[f])
208 			{
209 				return false;
210 			}
211 		}
212 		m_edges.Next();
213 	}
214 	for (size_t f = 0; f < nT; f++)
215 	{
216 		for (int e = 0; e < 3; e++)
217 		{
218 			int found = 0;
219 			for (int k = 0; k < 2; k++)
220 			{
221 				if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead())
222 				{
223 					found++;
224 				}
225 			}
226 			if (found != 1)
227 			{
228 				return false;
229 			}
230 		}
231 		m_triangles.Next();
232 	}
233 	return true;
234 }
235 }  // namespace VHACD