Merged from trunk with revision range 36835-37865,
[blender.git] / intern / decimation / intern / LOD_MeshPrimitives.cpp
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file decimation/intern/LOD_MeshPrimitives.cpp
30  *  \ingroup decimation
31  */
32
33
34 #include "LOD_MeshPrimitives.h"
35
36 #include "MT_assert.h"
37 #include "LOD_MeshException.h"
38 #include <algorithm>
39
40 using namespace std;
41
42 // Vertex Methods
43 /////////////////
44
45 LOD_Vertex::
46 LOD_Vertex(
47 ) :
48         pos (MT_Vector3()),
49         m_select_tag(false)
50 {
51 };
52
53         bool
54 LOD_Vertex::
55 RemoveEdge(
56         LOD_EdgeInd e
57 ){
58
59         vector<LOD_EdgeInd>::iterator result = find(m_edges.begin(),m_edges.end(),e);
60         if (result == m_edges.end()) {
61                 return false;
62         }
63
64         std::swap(*result, m_edges.back());
65         m_edges.pop_back();
66         return true;    
67 };      
68
69         void
70 LOD_Vertex::
71 AddEdge(
72         LOD_EdgeInd e
73 ){
74         m_edges.push_back(e);
75 };
76
77         void
78 LOD_Vertex::
79 SwapEdge(
80         LOD_EdgeInd e_old,
81         LOD_EdgeInd e_new
82 ){
83
84         vector<LOD_EdgeInd>::iterator result = 
85                 find(m_edges.begin(),m_edges.end(),e_old);
86         if (result == m_edges.end()) {
87                 MT_assert(false);
88                 LOD_MeshException e(LOD_MeshException::e_search_error);
89                 throw(e);       
90         }
91         
92         *result = e_new;
93 };
94
95         bool
96 LOD_Vertex::
97 SelectTag(
98 ) const {
99         return m_select_tag;
100 };
101
102         void
103 LOD_Vertex::
104 SetSelectTag(
105         bool tag        
106 ){
107         m_select_tag = tag;
108 };
109
110         bool
111 LOD_Vertex::
112 Degenerate(
113 ){
114         return m_edges.empty();
115 }
116
117         void
118 LOD_Vertex::
119 CopyPosition(
120         float *float_ptr
121 ){
122         pos.getValue(float_ptr);
123 }
124
125
126
127 // Edge Methods
128 ///////////////
129
130 LOD_Edge::
131 LOD_Edge (
132 ) {
133         m_verts[0] = m_verts[1] = LOD_VertexInd::Empty();
134         m_faces[0] = m_faces[1] = LOD_FaceInd::Empty();
135 }
136                 
137         bool 
138 LOD_Edge::
139 operator == (
140         LOD_Edge & rhs
141 ) {
142         // edges are the same if their vertex indices are the 
143         // same!!! Other properties are not checked 
144
145         int matches = 0;
146
147         if (this->m_verts[0] == rhs.m_verts[0]) {
148                 ++matches;
149         }
150         if (this->m_verts[1] == rhs.m_verts[0]) {
151                 ++matches;
152         }
153         if (this->m_verts[0] == rhs.m_verts[1]) {
154                 ++matches;
155         }
156         if (this->m_verts[1] == rhs.m_verts[1]) {
157                 ++matches;
158         }
159         
160         if (matches >= 2) {
161                 return true;
162         }
163         return false;
164 }
165
166 // Elementary helper methods
167 ////////////////////////////
168
169         LOD_FaceInd
170 LOD_Edge::
171 OpFace(
172         LOD_FaceInd f
173 ) const {
174         if (f == m_faces[0]) {
175                 return m_faces[1];
176         } else 
177         if (f == m_faces[1]) {
178                 return m_faces[0];
179         } else {
180                 MT_assert(false);
181                 LOD_MeshException e(LOD_MeshException::e_search_error);
182                 throw(e);       
183
184                 return LOD_FaceInd::Empty();
185         }
186 }       
187
188         void
189 LOD_Edge::
190 SwapFace(
191         LOD_FaceInd old_f,
192         LOD_FaceInd new_f
193 ) {
194         if (old_f == m_faces[0]) {
195                 m_faces[0] = new_f;
196         } else 
197         if (old_f == m_faces[1]) {
198                 m_faces[1] = new_f;
199         } else {
200                 LOD_MeshException e(LOD_MeshException::e_search_error);
201                 throw(e);       
202         }
203 }
204
205
206 // return the half edge face - the half edge is defined
207 // by the {vertex,edge} tuple. 
208
209         LOD_FaceInd
210 LOD_Edge::
211 HalfEdgeFace(
212         LOD_VertexInd vi
213 ){
214         if (vi == m_verts[0]) return m_faces[0];
215         if (vi == m_verts[1]) return m_faces[1];
216         MT_assert(false);
217         
218         LOD_MeshException e(LOD_MeshException::e_search_error);
219         throw(e);       
220
221         return LOD_FaceInd::Empty();
222 }       
223
224
225         LOD_VertexInd
226 LOD_Edge::
227 OpVertex(
228         LOD_VertexInd vi
229 ) {
230         if (vi == m_verts[0]) return m_verts[1];
231         if (vi == m_verts[1]) return m_verts[0];
232         MT_assert(false);
233
234         LOD_MeshException e(LOD_MeshException::e_search_error);
235         throw(e);       
236
237         return LOD_VertexInd::Empty();
238 }
239
240 // replace the vertex v_old with vertex v_new
241 // error if v_old is not one of the original vertices
242
243         void
244 LOD_Edge::
245 SwapVertex(
246         LOD_VertexInd v_old,
247         LOD_VertexInd v_new
248 ) {
249         if (v_old == m_verts[0]) {
250                 m_verts[0] = v_new;
251         } else
252         if (v_old == m_verts[1]) {
253                 m_verts[1] = v_new;
254         } else {
255
256                 MT_assert(false);
257
258                 LOD_MeshException e(LOD_MeshException::e_search_error);
259                 throw(e);       
260         }
261         if(m_verts[0] == m_verts[1]) {
262                 MT_assert(false);
263
264                 LOD_MeshException e(LOD_MeshException::e_non_manifold);
265                 throw(e);       
266         }
267
268 }                       
269
270         bool
271 LOD_Edge::
272 SelectTag(
273 ) const {
274         return bool(m_verts[1].Tag() & 0x1);
275 };
276
277         void
278 LOD_Edge::
279 SetSelectTag(
280         bool tag
281 ) {
282         m_verts[1].SetTag(int(tag));
283 };
284
285         int
286 LOD_Edge::
287 OpenTag(
288 ) const {
289         return m_faces[0].Tag();
290 }
291
292         void
293 LOD_Edge::
294 SetOpenTag(
295         int tag
296 ) {
297         m_faces[0].SetTag(tag);
298 }
299
300         bool
301 LOD_Edge::
302 Degenerate(
303 ) const {
304         return (
305                 (m_faces[0].IsEmpty() && m_faces[1].IsEmpty()) ||
306                 (m_verts[0] == m_verts[1])
307         );
308 };
309
310 // TriFace Methods
311 //////////////////
312
313 LOD_TriFace::
314 LOD_TriFace(
315 ) {
316         m_verts[0] = m_verts[1] = m_verts[2] = LOD_VertexInd::Empty();
317 }
318
319 // Elementary helper methods
320 ////////////////////////////
321
322         void
323 LOD_TriFace::
324 SwapVertex(
325         LOD_VertexInd old_v,
326         LOD_VertexInd new_v
327 ) {
328         // could save branching here...
329
330         if (m_verts[0] == old_v) {
331                 m_verts[0] = new_v;
332         } else 
333         if (m_verts[1] == old_v) {
334                 m_verts[1] = new_v;
335         } else 
336         if (m_verts[2] == old_v) {
337                 m_verts[2] = new_v;
338         } else {
339                 MT_assert(false);
340
341                 LOD_MeshException excep(LOD_MeshException::e_search_error);
342                 throw(excep);   
343         }
344 }
345
346         bool
347 LOD_TriFace::
348 SelectTag(
349 ) const {
350         return bool(m_verts[1].Tag() & 0x1);
351 };
352
353         void
354 LOD_TriFace::
355 SetSelectTag(
356         bool tag
357 ) {
358         m_verts[1].SetTag(int(tag));
359 };
360
361         int
362 LOD_TriFace::
363 OpenTag(
364 ) {
365         return m_verts[2].Tag();
366 }
367
368         void
369 LOD_TriFace::
370 SetOpenTag(
371         int tag
372 ) {
373         m_verts[2].SetTag(tag);
374 }
375
376         bool
377 LOD_TriFace::
378 Degenerate(
379 ) {
380
381         return (
382                 (m_verts[0] == m_verts[1]) ||
383                 (m_verts[1] == m_verts[2]) ||
384                 (m_verts[2] == m_verts[0]) 
385         );
386 }
387
388         void
389 LOD_TriFace::
390 CopyVerts(
391         int * index_ptr
392 ){
393         index_ptr[0] = m_verts[0];
394         index_ptr[1] = m_verts[1];
395         index_ptr[2] = m_verts[2];
396 };
397
398
399
400
401
402
403
404
405