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