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_QSDecimator.cpp
33
#include "LOD_QSDecimator.h"
35
#include "LOD_ExternBufferEditor.h"
43
LOD_ExternNormalEditor &face_editor,
44
LOD_ExternBufferEditor &extern_editor
47
MEM_SmartPtr<LOD_QSDecimator> output
48
= new LOD_QSDecimator(mesh,face_editor,extern_editor);
50
MEM_SmartPtr<LOD_EdgeCollapser > collapser(LOD_EdgeCollapser::New());
51
MEM_SmartPtr<LOD_QuadricEditor> q_editor(LOD_QuadricEditor::New(mesh));
60
output->m_collapser = collapser.Release();
61
output->m_quadric_editor = q_editor.Release();
62
return output.Release();
71
MT_assert(!m_is_armed);
72
bool heap_result = BuildHeap();
84
return CollapseEdge();
91
LOD_ExternNormalEditor &face_editor,
92
LOD_ExternBufferEditor &extern_editor
96
m_face_editor(face_editor),
97
m_extern_editor(extern_editor)
99
m_deg_edges.reserve(32);
100
m_deg_faces.reserve(32);
101
m_deg_vertices.reserve(32);
102
m_update_faces.reserve(32);
103
m_new_edges.reserve(32);
104
m_update_vertices.reserve(32);
112
// find an edge to collapse
114
// FIXME force an edge collapse
117
std::vector<LOD_Edge> & edges = m_mesh.EdgeSet();
118
std::vector<LOD_Vertex> & verts = m_mesh.VertexSet();
119
std::vector<LOD_Quadric> & quadrics = m_quadric_editor->Quadrics();
120
int size = edges.size();
122
if (size == 0) return false;
124
const int heap_top = m_heap->Top();
126
if (heap_top == -1 || edges[heap_top].HeapKey() <= -MT_INFINITY) {
130
// compute the target position
131
MT_Vector3 new_vertex = m_quadric_editor->TargetVertex(edges[heap_top]);
132
LOD_Quadric & q0 = quadrics[edges[heap_top].m_verts[0]];
133
LOD_Quadric & q1 = quadrics[edges[heap_top].m_verts[1]];
135
LOD_Vertex &v0 = verts[edges[heap_top].m_verts[0]];
136
LOD_Vertex &v1 = verts[edges[heap_top].m_verts[1]];
138
LOD_Quadric sum = q0;
142
if (m_collapser->CollapseEdge(
153
// assign new vertex position
158
// sum the quadrics of v0 and v1
162
// ok update the primitive properties
164
m_face_editor.Update(m_update_faces);
165
m_face_editor.UpdateVertexNormals(m_update_vertices);
167
// update the external vertex buffer
168
m_extern_editor.CopyModifiedVerts(m_mesh,m_update_vertices);
170
// update the external face buffer
171
m_extern_editor.CopyModifiedFaces(m_mesh,m_update_faces);
173
// update the edge heap
174
UpdateHeap(m_deg_edges,m_new_edges);
176
m_quadric_editor->Remove(m_deg_vertices);
177
m_face_editor.Remove(m_deg_faces);
178
m_face_editor.RemoveVertexNormals(m_deg_vertices);
180
// delete the primitives
182
DeletePrimitives(m_deg_edges,m_deg_faces,m_deg_vertices);
185
// the edge could not be collapsed at the moment - so
186
// we adjust it's priority and add it back to the heap.
187
m_heap->Remove(&edges[0],0);
188
edges[heap_top].HeapKey() = - MT_INFINITY;
189
m_heap->Insert(&edges[0],heap_top);
192
//clear all the temporary buffers
196
m_deg_vertices.clear();
198
m_update_faces.clear();
199
m_update_vertices.clear();
209
const vector<LOD_EdgeInd> & degenerate_edges,
210
const vector<LOD_FaceInd> & degenerate_faces,
211
const vector<LOD_VertexInd> & degenerate_vertices
214
// assumes that the 3 vectors are sorted in descending order.
216
// Delete Degnerate primitives
217
//////////////////////////////
220
// delete the old edges - we have to be very careful here
221
// mesh.delete() swaps edges to be deleted with the last edge in
222
// the edge buffer. However the next edge to be deleted may have
223
// been the last edge in the buffer!
225
// One way to solve this is to sort degenerate_edges in descending order.
226
// And then delete them in that order.
228
// it is also vital that degenerate_edges contains no duplicates
230
vector<LOD_EdgeInd>::const_iterator edge_it = degenerate_edges.begin();
231
vector<LOD_EdgeInd>::const_iterator edge_end = degenerate_edges.end();
233
for (; edge_it != edge_end; ++edge_it) {
234
m_mesh.DeleteEdge(*edge_it,m_heap);
239
vector<LOD_FaceInd>::const_iterator face_it = degenerate_faces.begin();
240
vector<LOD_FaceInd>::const_iterator face_end = degenerate_faces.end();
242
for (;face_it != face_end; ++face_it) {
243
m_mesh.DeleteFace(m_extern_editor,*face_it);
246
vector<LOD_VertexInd>::const_iterator vertex_it = degenerate_vertices.begin();
247
vector<LOD_VertexInd>::const_iterator vertex_end = degenerate_vertices.end();
249
for (;vertex_it != vertex_end; ++vertex_it) {
250
m_mesh.DeleteVertex(m_extern_editor,*vertex_it);
259
// build the quadrics
261
if (m_quadric_editor->BuildQuadrics(m_face_editor,true) == false) return false;
264
m_heap = CTR_UHeap<LOD_Edge>::New();
265
// load in edge pointers to the heap
267
std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
270
// std::vector<LOD_Edge>::const_iterator edge_end = edge_set.end();
271
// std::vector<LOD_Edge>::iterator edge_start = edge_set.begin();
273
std::vector<int> & heap_vector = m_heap->HeapVector();
275
for (unsigned int i = 0; i < edge_set.size(); ++i) {
276
edge_set[i].HeapPos() = i;
277
heap_vector.push_back(i);
280
m_heap->MakeHeap(&edge_set[0]);
288
std::vector<LOD_EdgeInd> °_edges,
289
std::vector<LOD_EdgeInd> &new_edges
291
// first of all compute values for the new edges
292
// and bung them on the heap.
294
std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
296
std::vector<LOD_EdgeInd>::const_iterator edge_it = new_edges.begin();
297
std::vector<LOD_EdgeInd>::const_iterator end_it = new_edges.end();
300
// insert all the new edges
301
///////////////////////////
303
// compute edge costs ffor the new edges
305
m_quadric_editor->ComputeEdgeCosts(new_edges);
307
// inser the new elements into the heap
309
for (; edge_it != end_it; ++edge_it) {
310
m_heap->Insert(&edge_set[0],*edge_it);
314
// remove all the old values from the heap
316
edge_it = deg_edges.begin();
317
end_it = deg_edges.end();
319
for (; edge_it != end_it; ++edge_it) {
320
LOD_Edge &e = edge_set[*edge_it];
321
m_heap->Remove(&edge_set[0],e.HeapPos());