2
* ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19
* All rights reserved.
21
* The Original Code is: all of this file.
23
* Contributor(s): none yet.
25
* ***** END GPL LICENSE BLOCK *****
28
/** \file decimation/intern/LOD_ManMesh2.cpp
33
#include "LOD_ManMesh2.h"
35
#include "MT_assert.h"
37
#include "LOD_MeshException.h"
38
#include "CTR_TaggedSetOps.h"
39
#include "CTR_UHeap.h"
40
#include "LOD_ExternBufferEditor.h"
58
MEM_SmartPtr<LOD_ManMesh2> output(new LOD_ManMesh2());
59
if (output == NULL) return NULL;
61
// build the vertex, edge and face sets.
63
MEM_SmartPtr<vector<LOD_Vertex> > verts(new vector<LOD_Vertex>);
64
MEM_SmartPtr<vector<LOD_TriFace> > faces(new vector<LOD_TriFace>);
65
MEM_SmartPtr<vector<LOD_Edge> > edges(new vector<LOD_Edge>);
67
if ((faces == NULL) || (edges == NULL) || (verts == NULL)) {
71
output->m_verts = verts.Release();
72
output->m_faces = faces.Release();
73
output->m_edges = edges.Release();
75
return output.Release();
78
// take ownership of the vertices.
83
MEM_SmartPtr<vector<LOD_Vertex> > verts
87
// take ownership of vertices
90
// create a polygon and edge buffer of half the size
91
// and just use the automatic resizing feature of vector<>
92
// to worry about the dynamic array resizing
97
m_faces->reserve(m_verts->size()/2);
98
m_edges->reserve(m_verts->size()/2);
105
// add a triangle to the mesh
113
MT_assert(verts[0] < int(m_verts->size()));
114
MT_assert(verts[1] < int(m_verts->size()));
115
MT_assert(verts[2] < int(m_verts->size()));
118
face.m_verts[0] = verts[0];
119
face.m_verts[1] = verts[1];
120
face.m_verts[2] = verts[2];
122
LOD_FaceInd face_index = m_faces->size();
124
m_faces->push_back(face);
126
// now work out if any of the directed edges or their
127
// companion edges exist already.
128
// We go through the edges associated with each of the given vertices
130
// the safest thing to do is iterate through each of the edge sets
131
// check against each of the 2 other triangle edges to see if they are there
133
vector<LOD_EdgeInd> new_edges;
134
new_edges.reserve(3);
136
InsertEdge(verts[0],verts[1],face_index,new_edges);
137
InsertEdge(verts[1],verts[2],face_index,new_edges);
138
InsertEdge(verts[2],verts[0],face_index,new_edges);
142
// Adds the index of any created edges to new_edges
147
const LOD_VertexInd v1,
148
const LOD_VertexInd v2,
150
vector<LOD_EdgeInd> &new_edges
153
MT_assert(!v1.IsEmpty());
154
MT_assert(!v2.IsEmpty());
155
MT_assert(!f.IsEmpty());
157
vector<LOD_Vertex> &verts = VertexSet();
158
vector<LOD_Edge> &edges = EdgeSet();
165
// This edge does not exist -- make a new one
168
temp_e.m_verts[0] = v1;
169
temp_e.m_verts[1] = v2;
173
// set the face ptr for this half-edge
174
temp_e.m_faces[0] = f;
176
m_edges->push_back(temp_e);
178
// add the edge index to it's vertices
180
verts[v1].AddEdge(e);
181
verts[v2].AddEdge(e);
183
new_edges.push_back(e);
187
// edge already exists
188
// insure that there is no polygon already
189
// attached to the other side of this edge
191
// swap the empty face pointer in edge with f
193
LOD_Edge &edge = edges[e];
195
edge.SwapFace(LOD_FaceInd::Empty(),f);
207
std::vector<LOD_EdgeInd> & new_edges
210
vector<LOD_TriFace> &faces = FaceSet();
212
MT_assert(!faces[fi].Degenerate());
214
LOD_TriFace & face = faces[fi];
216
InsertEdge(face.m_verts[0],face.m_verts[1],fi,new_edges);
217
InsertEdge(face.m_verts[1],face.m_verts[2],fi,new_edges);
218
InsertEdge(face.m_verts[2],face.m_verts[0],fi,new_edges);
231
return m_verts.Ref();
234
vector<LOD_TriFace> &
238
return m_faces.Ref();
245
return m_edges.Ref();
251
//auto ptr takes care of vertex arrays etc.
257
const LOD_VertexInd v1,
258
const LOD_VertexInd v2
261
vector<LOD_Vertex> &verts = VertexSet();
262
vector<LOD_Edge> &edges = EdgeSet();
268
vector<LOD_EdgeInd> &v1_edges = verts[v1].m_edges;
269
vector<LOD_EdgeInd>::const_iterator v1_end = v1_edges.end();
270
vector<LOD_EdgeInd>::iterator v1_begin = v1_edges.begin();
272
for (; v1_begin != v1_end; ++v1_begin) {
273
if (edges[*v1_begin] == e) return *v1_begin;
276
return LOD_EdgeInd::Empty();
286
vector<LOD_VertexInd> &output
288
const vector<LOD_TriFace> &faces = FaceSet();
289
const LOD_TriFace & f = faces[fi];
291
output.push_back(f.m_verts[0]);
292
output.push_back(f.m_verts[1]);
293
output.push_back(f.m_verts[2]);
300
vector<LOD_EdgeInd> &output
302
const vector<LOD_TriFace> &faces = FaceSet();
303
vector<LOD_Edge> &edges = EdgeSet();
304
vector<LOD_Vertex> &verts = VertexSet();
306
const LOD_TriFace & f = faces[fi];
307
// intersect vertex edges
309
vector<LOD_EdgeInd> & v0_edges = verts[f.m_verts[0]].m_edges;
310
vector<LOD_EdgeInd> & v1_edges = verts[f.m_verts[1]].m_edges;
311
vector<LOD_EdgeInd> & v2_edges = verts[f.m_verts[2]].m_edges;
313
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v0_edges,v1_edges,edges,output);
314
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v1_edges,v2_edges,edges,output);
315
CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v2_edges,v0_edges,edges,output);
317
MT_assert(output.size() == 3);
318
if (output.size() != 3) {
319
LOD_MeshException e(LOD_MeshException::e_non_manifold);
332
vector<LOD_VertexInd> &output
334
const vector<LOD_Edge> &edges = EdgeSet();
335
const LOD_Edge & e = edges[ei];
337
output.push_back(e.m_verts[0]);
338
output.push_back(e.m_verts[1]);
345
vector<LOD_FaceInd> &output
347
const vector<LOD_Edge> &edges = EdgeSet();
348
const LOD_Edge & e = edges[ei];
350
if (!e.m_faces[0].IsEmpty()) {
351
output.push_back(e.m_faces[0]);
353
if (!e.m_faces[1].IsEmpty()) {
354
output.push_back(e.m_faces[1]);
365
vector<LOD_EdgeInd> &output
367
// iterate through the edges of v and push them onto the
370
vector<LOD_Vertex> &verts = VertexSet();
372
vector<LOD_EdgeInd> & v_edges = verts[vi].m_edges;
373
vector<LOD_EdgeInd>::iterator v_it = v_edges.begin();
375
for (; v_it != v_edges.end(); ++v_it) {
376
output.push_back(*v_it);
384
vector<LOD_FaceInd> &output
386
const vector<LOD_Vertex> &verts = VertexSet();
387
vector<LOD_Edge> &edges = EdgeSet();
388
vector<LOD_TriFace> &faces = FaceSet();
390
const vector<LOD_EdgeInd> &v_edges = verts[vi].m_edges;
391
vector<LOD_EdgeInd>::const_iterator e_it = v_edges.begin();
393
for (; e_it != v_edges.end(); ++e_it) {
395
LOD_Edge &e = edges[*e_it];
397
if ((!e.m_faces[0].IsEmpty()) && (!faces[e.m_faces[0]].SelectTag())) {
398
output.push_back(e.m_faces[0]);
399
faces[e.m_faces[0]].SetSelectTag(true);
402
if ((!e.m_faces[1].IsEmpty()) && (!faces[e.m_faces[1]].SelectTag())) {
403
output.push_back(e.m_faces[1]);
404
faces[e.m_faces[1]].SetSelectTag(true);
408
vector<LOD_FaceInd>::iterator f_it = output.begin();
410
for (; f_it != output.end(); ++f_it) {
411
faces[*f_it].SetSelectTag(false);
421
m_bbox_min = bbox_min;
422
m_bbox_max = bbox_max;
430
LOD_TriFace face = (*m_faces)[f];
432
// check for unique vertices
435
(face.m_verts[0] == face.m_verts[1]) ||
436
(face.m_verts[1] == face.m_verts[2]) ||
437
(face.m_verts[2] == face.m_verts[0])
450
vector<LOD_Edge> &edges = EdgeSet();
451
vector<LOD_Vertex> &verts = VertexSet();
453
vector<LOD_EdgeInd>::iterator e_it = verts[v].m_edges.begin();
455
for (;e_it != verts[v].m_edges.end(); ++e_it) {
456
MT_assert( (edges[*e_it].m_verts[0] == v) || (edges[*e_it].m_verts[1] == v));
464
LOD_ExternBufferEditor & extern_editor,
468
vector<LOD_Edge> &edges = EdgeSet();
469
vector<LOD_Vertex> &verts = VertexSet();
470
vector<LOD_TriFace> &faces = FaceSet();
472
// need to update all the edge and polygons pointing to
473
// the last vertex in m_verts
475
if (verts.size() == 1) {
480
LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
484
// we asume that v is already disconnected
486
vector<LOD_FaceInd> v_faces;
487
vector<LOD_EdgeInd> v_edges;
492
VertexFaces(last,v_faces);
493
VertexEdges(last,v_edges);
495
// map the faces and edges to look at v
497
vector<LOD_FaceInd>::iterator face_it = v_faces.begin();
499
for(; face_it != v_faces.end(); ++face_it) {
500
faces[*face_it].SwapVertex(last,v);
502
vector<LOD_EdgeInd>::iterator edge_it = v_edges.begin();
504
for (; edge_it != v_edges.end(); ++edge_it) {
505
edges[*edge_it].SwapVertex(last,v);
508
// copy the last vertex onto v and pop off the back.
510
verts[v] = verts[last];
512
// tidy external buffer
513
extern_editor.CopyModifiedFaces(*this,v_faces);
517
extern_editor.CopyBackVertex(v);
526
CTR_UHeap<LOD_Edge> * heap
528
vector<LOD_Edge> &edges = EdgeSet();
529
vector<LOD_Vertex> &verts = VertexSet();
531
if (edges.size() == 1) {
536
LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
539
vector<LOD_EdgeInd> e_verts;
541
EdgeVertices(last,e_verts);
542
// something is wrong if there arent two!
544
verts[e_verts[0]].SwapEdge(last,e);
545
verts[e_verts[1]].SwapEdge(last,e);
547
// edges[e] should already have been removed from the heap
549
MT_assert(edges[e].HeapPos() == -1);
551
edges[e] = edges[last];
552
// also have to swap there heap positions.!!!!!
554
heap->HeapVector()[edges[e].HeapPos()] = e;
564
LOD_ExternBufferEditor & extern_editor,
568
vector<LOD_Edge> &edges = EdgeSet();
569
vector<LOD_TriFace> &faces = FaceSet();
571
if (faces.size() == 1) {
576
LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
580
// we have to update the edges which point to the last
583
vector<LOD_EdgeInd> f_edges;
586
FaceEdges(last,f_edges);
588
vector<LOD_EdgeInd>::iterator edge_it = f_edges.begin();
589
vector<LOD_EdgeInd>::const_iterator edge_end = f_edges.end();
591
for (; edge_it != edge_end; ++edge_it) {
592
edges[*edge_it].SwapFace(last,f);
595
faces[f] = faces[last];
600
// tidy external buffers
601
extern_editor.CopyBackFace(f);