44 class VertexPtrWrapper
49 bool operator==(
const VertexPtrWrapper& other)
const 51 return mVertex == other.mVertex;
54 bool operator!=(
const VertexPtrWrapper& other)
const 56 return mVertex == other.mVertex;
59 bool operator<(
const VertexPtrWrapper& other)
const 61 if ( mVertex->collapseCost() != other.mVertex->collapseCost() )
62 return mVertex->collapseCost() < other.mVertex->collapseCost();
64 return mVertex < other.mVertex;
74 Log::error(
"PolygonSimplifier::simplify() : no input Geometry specified.\n");
82 problem |= mInput->vertexAttribArray(i) !=
NULL;
84 Log::warning(
"PolygonSimplifier::simplify() simplifies only the position array of a Geometry, the other attibutes will be discarded.\n");
90 if ( removeDoubles() )
96 std::vector<fvec3> verts;
97 std::vector<int> indices;
98 indices.reserve(1000);
102 for(
size_t i=0; i<mInput->drawCalls().size(); ++i )
104 DrawCall* prim = mInput->drawCalls().at(i);
107 indices.push_back( trit.a() );
108 indices.push_back( trit.b() );
109 indices.push_back( trit.c() );
115 Log::warning(
"PolygonSimplifier::simplify() : no triangles found in input Geometry.\n");
123 Log::warning(
"PolygonSimplifier::simplify() : no vertices found in input Geometry.\n");
128 verts.resize( posarr->
size() );
129 for(
size_t i=0; i< posarr->
size(); ++i )
134 Log::warning(
"PolygonSimplifier::simplify() : no vertices found in input Geometry.\n");
138 simplify(verts, indices);
147 Log::print(
"PolygonSimplifier::simplify() starting ... \n");
153 std::sort(mTargets.begin(), mTargets.end());
154 std::reverse(mTargets.begin(), mTargets.end());
156 mSimplifiedVertices.clear();
157 mSimplifiedTriangles.clear();
158 mProtectedVerts.clear();
159 mTriangleLump.clear();
163 mTriangleLump.resize(in_tris.size()/3);
164 mVertexLump.resize(in_verts.size());
166 int polys_before = (int)in_tris.size() / 3;
167 int verts_before = (int)in_verts.size();
169 mSimplifiedTriangles.resize( in_tris.size() / 3 );
170 mSimplifiedVertices.resize( in_verts.size() );
172 #define SHUFFLE_VERTICES 0 175 std::vector<Vertex*> vertex_pool;
176 vertex_pool.resize( in_verts.size() );
177 for(
int i=0; i<(int)mVertexLump.size(); ++i)
178 vertex_pool[i] = &mVertexLump[i];
181 for(
int i=0; i<(int)vertex_pool.size(); ++i)
183 int a = int( (
float)rand() / (RAND_MAX+1) * vertex_pool.size() );
184 int b = int( (
float)rand() / (RAND_MAX+1) * vertex_pool.size() );
185 Vertex* tmp = vertex_pool[a];
186 vertex_pool[a] = vertex_pool[b];
187 vertex_pool[b] = tmp;
192 for(
int ivert=0; ivert<(int)in_verts.size(); ++ivert)
195 mSimplifiedVertices[ivert] = vertex_pool[ivert];
197 mSimplifiedVertices[ivert] = &mVertexLump[ivert];
199 mSimplifiedVertices[ivert]->mPosition = in_verts[ivert];
202 mSimplifiedVertices[ivert]->mOriginalIndex = ivert;
205 mSimplifiedVertices[ivert]->mProtected =
false;
208 mSimplifiedVertices[ivert]->mIncidentTriangles.reserve(12);
209 mSimplifiedVertices[ivert]->mAdjacentVerts.reserve(12);
213 for(
int idx=0, itri=0; idx<(int)in_tris.size(); idx+=3, ++itri)
215 mSimplifiedTriangles[itri] = &mTriangleLump[itri];
216 mSimplifiedTriangles[itri]->mVertices[0] = mSimplifiedVertices[ in_tris[idx+0] ];
217 mSimplifiedTriangles[itri]->mVertices[1] = mSimplifiedVertices[ in_tris[idx+1] ];
218 mSimplifiedTriangles[itri]->mVertices[2] = mSimplifiedVertices[ in_tris[idx+2] ];
222 for(
int itri=0; itri<(int)mSimplifiedTriangles.size(); ++itri)
225 mSimplifiedTriangles[itri]->mVertices[0]->mIncidentTriangles.push_back( mSimplifiedTriangles[itri] );
226 mSimplifiedTriangles[itri]->mVertices[1]->mIncidentTriangles.push_back( mSimplifiedTriangles[itri] );
227 mSimplifiedTriangles[itri]->mVertices[2]->mIncidentTriangles.push_back( mSimplifiedTriangles[itri] );
229 mSimplifiedTriangles[itri]->mVertices[0]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[1] );
230 mSimplifiedTriangles[itri]->mVertices[0]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[2] );
231 mSimplifiedTriangles[itri]->mVertices[1]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[0] );
232 mSimplifiedTriangles[itri]->mVertices[1]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[2] );
233 mSimplifiedTriangles[itri]->mVertices[2]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[0] );
234 mSimplifiedTriangles[itri]->mVertices[2]->addAdjacentVertex( mSimplifiedTriangles[itri]->mVertices[1] );
236 mSimplifiedTriangles[itri]->computeNormal();
238 QErr qerr = mSimplifiedTriangles[itri]->computeQErr();
239 mSimplifiedTriangles[itri]->mVertices[0]->addQErr(qerr);
240 mSimplifiedTriangles[itri]->mVertices[1]->addQErr(qerr);
241 mSimplifiedTriangles[itri]->mVertices[2]->addQErr(qerr);
247 for(
int ivert=(
int)mSimplifiedVertices.size(); ivert--; )
249 if ( mSimplifiedVertices[ivert]->incidentTrianglesCount() == 0 )
250 mSimplifiedVertices.erase( mSimplifiedVertices.begin() + ivert );
253 mSimplifiedVertices[ivert]->computeEdgePenalty();
254 computeCollapseInfo( mSimplifiedVertices[ivert] );
259 for(
int i=0; i<(int)mProtectedVerts.size(); ++i)
261 VL_CHECK(mProtectedVerts[i] < (
int)mSimplifiedVertices.size() )
262 mSimplifiedVertices[ mProtectedVerts[i] ]->mProtected =
true;
268 std::set<VertexPtrWrapper> vertex_set;
269 for(
int ivert=0; ivert<(int)mSimplifiedVertices.size(); ++ivert)
270 if ( !mSimplifiedVertices[ivert]->mProtected )
271 vertex_set.insert( mSimplifiedVertices[ivert] );
277 for(
size_t itarget=0, remove_order=0; itarget<mTargets.size(); ++itarget)
279 const int target_vertex_count = mTargets[itarget];
281 if (target_vertex_count < 3)
283 Log::print(
Say(
"Invalid target_vertex_count = %n\n") << target_vertex_count);
289 std::vector< PolygonSimplifier::Vertex* > adj_verts;
290 for( ; (int)vertex_set.size()>target_vertex_count; ++remove_order )
292 std::set<VertexPtrWrapper>::iterator it = vertex_set.begin();
295 vertex_set.erase(it);
305 adj_verts.back()->mAlreadyProcessed =
true;
325 for(
int i=(
int)adj_verts.size(); i--; )
327 adj_verts[i]->mAlreadyProcessed =
false;
329 if ( adj_verts[i]->removed() )
332 computeCollapseInfo( adj_verts[i] );
334 VL_CHECK( adj_verts[i]->checkTriangles() )
335 VL_CHECK( adj_verts[i]->collapseVertex() != v )
336 VL_CHECK( !adj_verts[i]->collapseVertex()->removed() )
338 vertex_set.insert( adj_verts[i] );
345 outputSimplifiedGeometry();
348 if (verbose() && !output().empty())
350 float elapsed = (float)timer.
elapsed();
351 int polys_after = output().back()->drawCalls().at(0)->countTriangles();
352 int verts_after = output().back()->vertexArray() ? (int)output().back()->vertexArray()->size() : 0;
353 Log::print(
Say(
"POLYS: %n -> %n, %.2n%%, %.1nT/s\n") << polys_before << polys_after << 100.0f*verts_after/verts_before << (polys_before - polys_after)/elapsed );
354 Log::print(
Say(
"VERTS: %n -> %n, %.2n%%, %.1nV/s\n") << verts_before << verts_after << 100.0f*verts_after/verts_before << (verts_before - verts_after)/elapsed );
361 size_t vert_count = 0;
362 for(
int i=0; i<(int)mSimplifiedVertices.size(); ++i)
363 vert_count += mSimplifiedVertices[i]->mRemoved ? 0 : 1;
367 arr_f3->
resize(vert_count);
368 for(
int i=0, vert_index=0; i<(int)mSimplifiedVertices.size(); ++i)
370 if (!mSimplifiedVertices[i]->mRemoved)
372 arr_f3->
at(vert_index) = mSimplifiedVertices[i]->mPosition;
373 mSimplifiedVertices[i]->mSimplifiedIndex = vert_index++;
378 size_t index_count = 0;
379 for(
size_t i=0; i<mSimplifiedTriangles.size(); ++i)
380 index_count += mSimplifiedTriangles[i]->mRemoved ? 0 : 3;
386 for(
size_t i=0; i<mSimplifiedTriangles.size(); ++i)
388 if(!mSimplifiedTriangles[i]->mRemoved)
390 VL_CHECK( !mSimplifiedTriangles[i]->mVertices[0]->mRemoved )
391 VL_CHECK( !mSimplifiedTriangles[i]->mVertices[1]->mRemoved )
392 VL_CHECK( !mSimplifiedTriangles[i]->mVertices[2]->mRemoved )
394 ptr[0] = mSimplifiedTriangles[i]->mVertices[0]->mSimplifiedIndex;
395 ptr[1] = mSimplifiedTriangles[i]->mVertices[1]->mSimplifiedIndex;
396 ptr[2] = mSimplifiedTriangles[i]->mVertices[2]->mSimplifiedIndex;
404 mOutput.back()->setVertexArray( arr_f3.
get() );
405 mOutput.back()->drawCalls().push_back( de.
get() );
410 mSimplifiedVertices.clear();
411 mSimplifiedTriangles.clear();
412 mProtectedVerts.clear();
413 mTriangleLump.clear();
The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a Buf...
bool hasNext()
Returns false if the iterator has reached the end of the triangle list.
real elapsed(int index=0) const
bool mAlreadyProcessed
internally used
const T_VectorType * end() const
A simple String formatting class.
static void warning(const String &message)
Use this function to provide information about situations that might lead to errors or loss of data...
void outputSimplifiedGeometry()
bool removed() const
has the vertex been removed
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
int mRemoveOrder
when the vertex has collapsed
Removes from a Geometry the vertices with the same attributes.
void removeDoubles(Geometry *geom)
Vertex * collapseVertex() const
vertex to which collapse
virtual vec3 getAsVec3(size_t vector_index) const =0
Returns a vector from the buffer as a vec3 value.
const T_VectorType * begin() const
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Visualization Library main namespace.
bool operator!=(const ref< T1 > &o1, const ref< T2 > &o2)
ArrayUInt1 ::scalar_type index_type
Simple class to be used as a timer and to retrieve the current time and date.
virtual TriangleIterator triangleIterator() const =0
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
static void print(const String &message)
Application message for the user.
A Vertex as defined by PolygonSimplifier.
Iterator used to extract the indices of every single triangle of a DrawCall regardless of the primiti...
int adjacentVerticesCount() const
ajacent vertices
arr_type * indexBuffer()
The BufferObject containing the indices used to render.
T_VectorType & at(size_t i)
The quadric error metric as defined by PolygonSimplifier.
The base class of DrawArrays, DrawElements, MultiDrawElements and DrawRangeElements.
virtual size_t size() const =0
Returns the number of elements of an array.
bool operator==(const ref< T1 > &o1, const ref< T2 > &o2)
The ref<> class is used to reference-count an Object.
void clearTrianglesAndVertices()
Vertex * adjacentVertex(int index) const