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