Commit 6e903fb8 authored by Matthias Möller's avatar Matthias Möller
Browse files

- speed up cache filling for status node

- reduce memory consumption for polymeshes

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@21134 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 261cbe3a
......@@ -145,75 +145,52 @@ update_cache()
invalidGeometry_ = false;
}
/*
* Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
*/
if (vertexIndexInvalid_ || edgeIndexInvalid_ || halfedgeCacheInvalid_ || faceIndexInvalid_)
if (drawMesh_)
drawMesh_->getVBO();
// Update the indices for selected vertices
if (vertexIndexInvalid_) {
/*
* Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
*/
if (drawMesh_) drawMesh_->getVBO();
v_cache_.clear();
v_cache_.reserve(mesh_.n_vertices()/4);
typename Mesh::ConstVertexIter v_it(mesh_.vertices_sbegin()), v_begin(mesh_.vertices_sbegin()), v_end(mesh_.vertices_end());
// Optimization: get rid of slow push_back() by precounting the number of selected elements
int numSel = 0;
for (v_it = v_begin; v_it != v_end; ++v_it)
if (this->is_vertex_selected(mesh_, *v_it))
++numSel;
v_cache_.resize(numSel);
int offset = 0;
for (v_it = v_begin; v_it != v_end; ++v_it) {
if (this->is_vertex_selected(mesh_, *v_it)) {
unsigned int vertexIndex = v_it->idx();
// use correct index for vbo, if available
if (drawMesh_)
vertexIndex = drawMesh_->mapVertexToVBOIndex(vertexIndex);
v_cache_[offset++] = vertexIndex;
v_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vertexIndex) : vertexIndex);
}
}
std::vector<unsigned int>(v_cache_.begin(), v_cache_.end()).swap(v_cache_);
vertexIndexInvalid_ = false;
}
// Update index list of selected edges
if (edgeIndexInvalid_) {
/*
* Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
*/
if (drawMesh_) drawMesh_->getVBO();
e_cache_.clear();
e_cache_.reserve(mesh_.n_edges()/4);
typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_begin(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
typename Mesh::VertexHandle vh;
// Optimization: get rid of slow push_back() by precounting the number of selected elements
int numSel = 0;
for (e_it = e_begin; e_it != e_end; ++e_it)
if (this->is_edge_selected(mesh_, *e_it))
++numSel;
e_cache_.resize(numSel * 2);
int offset = 0;
for (e_it = e_begin; e_it != e_end; ++e_it) {
if (this->is_edge_selected(mesh_, *e_it)) {
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0));
unsigned int vidx = vh.idx();
e_cache_[offset++] = drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx;
e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1));
vidx = vh.idx();
e_cache_[offset++] = drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx;
e_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
}
}
std::vector<unsigned int>(e_cache_.begin(), e_cache_.end()).swap(e_cache_);
edgeIndexInvalid_ = false;
}
......@@ -221,28 +198,17 @@ update_cache()
// Update index list of selected halfedges
if (halfedgeCacheInvalid_) {
/*
* Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
*/
if (drawMesh_) drawMesh_->getVBO();
he_points_.clear();
he_points_.reserve(mesh_.n_halfedges()/4);
he_normals_.clear();
he_normals_.reserve(he_points_.size());
typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_begin(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
// Optimization: get rid of slow push_back() by precounting the number of selected elements
int numSel = 0;
for (he_it = he_begin; he_it != he_end; ++he_it)
if (this->is_halfedge_selected(mesh_, *he_it))
++numSel;
he_points_.resize(numSel * 2);
he_normals_.resize(numSel * 2);
int offset = 0;
for (he_it = he_begin; he_it != he_end; ++he_it) {
if (this->is_halfedge_selected(mesh_, *he_it)) {
// add vertices
he_points_[offset] = (halfedge_point(*he_it));
he_points_[offset+1] = (halfedge_point(mesh_.prev_halfedge_handle(*he_it)));
he_points_.push_back(halfedge_point(*he_it));
he_points_.push_back(halfedge_point(mesh_.prev_halfedge_handle(*he_it)));
// add normals
FaceHandle fh;
......@@ -251,13 +217,13 @@ update_cache()
else
fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(*he_it));
he_normals_[offset] = (mesh_.normal(fh));
he_normals_[offset+1] = (mesh_.normal(fh));
offset += 2;
he_normals_.push_back(mesh_.normal(fh));
he_normals_.push_back(mesh_.normal(fh));
}
}
std::vector<Point>(he_points_.begin(), he_points_.end()).swap(he_points_);
std::vector<Normal>(he_normals_.begin(), he_normals_.end()).swap(he_normals_);
halfedgeCacheInvalid_ = false;
}
......@@ -265,75 +231,42 @@ update_cache()
// update index list of selected faces
if (faceIndexInvalid_) {
/*
* Hack: Force rebuild of buffers so that mapVertexToVBOIndex call doesn't SEGFAULT.
*/
if (drawMesh_) drawMesh_->getVBO();
fh_cache_.clear(); //constant time, facehandle is trivially destructible
fh_cache_.reserve(mesh_.n_faces()/4);// maximum 2 new allocations will be performed using push_back
typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()), f_begin(mesh_.faces_sbegin()), f_end(mesh_.faces_end());
typename Mesh::ConstFaceVertexIter fv_it;
// Optimization: get rid of slow push_back() by precounting the number of selected elements
int numSel = 0;
for (f_it = f_begin; f_it != f_end; ++f_it)
if (this->is_face_selected(mesh_, *f_it))
++numSel;
if (this->is_face_selected(mesh_, *f_it))
fh_cache_.push_back(*f_it);
f_cache_.resize(numSel * 3);
fh_cache_.resize(numSel);
int offset = 0;
std::vector<FaceHandle>(fh_cache_.begin(), fh_cache_.end()).swap(fh_cache_);//shrink to fit
for (f_it = f_begin; f_it != f_end; ++f_it) {
if (this->is_face_selected(mesh_, *f_it)) {
fv_it = mesh_.cfv_iter(*f_it);
if (mesh_.is_trimesh())
{
f_cache_.resize(fh_cache_.size()*3);
for (size_t i = 0; i < fh_cache_.size(); ++i)
{
typename Mesh::ConstFaceVertexIter fv_it = mesh_.cfv_iter(fh_cache_[i]);
unsigned int vidx = fv_it->idx();
f_cache_[i*3] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
// f_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx); ++fv_it;
// vidx = fv_it->idx();
//
// f_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx); ++fv_it;
// vidx = fv_it->idx();
//
// f_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
// fh_cache_.push_back(*f_it);
f_cache_[offset*3] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx); ++fv_it;
++fv_it;
vidx = fv_it->idx();
f_cache_[i*3+1] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
f_cache_[offset*3+1] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx); ++fv_it;
++fv_it;
vidx = fv_it->idx();
f_cache_[offset*3+2] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
fh_cache_[offset] = (*f_it);
++offset;
f_cache_[i*3+2] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vidx) : vidx);
}
}
if (!mesh_.is_trimesh()) {
else {
// triangulate poly-list
poly_cache_.clear();
poly_cache_.reserve(fh_cache_.size()*4);
typename std::vector<FaceHandle>::const_iterator fh_it(fh_cache_.begin()), fh_end(fh_cache_.end());
typename Mesh::CFVIter fv_it;
// Optimization: get rid of slow push_back() by precounting the number of triangles
int numTris = 0;
for (fh_it = fh_cache_.begin(); fh_it != fh_end; ++fh_it){
fv_it = mesh_.cfv_iter(*fh_it);
for (; fv_it.is_valid(); ++fv_it)
{
++numTris;
}
numTris -= 2;
}
poly_cache.resize(numTris*3);
offset = 0;
for (fh_it = fh_cache_.begin(); fh_it != fh_end; ++fh_it) {
fv_it = mesh_.cfv_iter(*fh_it);
typename Mesh::CFVIter fv_it = mesh_.cfv_iter(*fh_it);
// 1. polygon vertex
unsigned int v0 = fv_it->idx();
......@@ -345,18 +278,15 @@ update_cache()
// create triangle fans pointing towards v0
for (; fv_it.is_valid(); ++fv_it) {
// poly_cache.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(v0) : v0);
// poly_cache.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
//
// vPrev = fv_it->idx();
// poly_cache.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
poly_cache[offset++] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(v0) : v0);
poly_cache[offset++] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(v0) : v0);
poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
vPrev = fv_it->idx();
poly_cache[offset++] = (drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
poly_cache_.push_back(drawMesh_ ? drawMesh_->mapVertexToVBOIndex(vPrev) : vPrev);
}
}
std::vector<unsigned int>(poly_cache_.begin(), poly_cache_.end()).swap(poly_cache_);//shrink to fit
}
......@@ -759,16 +689,16 @@ void StatusNodeT<Mesh, Mod>::getRenderObjects(IRenderer* _renderer,
}
if (faces && !f_cache_.empty())
if (faces)
{
if (mesh_.is_trimesh())
if (mesh_.is_trimesh() && !f_cache_.empty())
{
ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(f_cache_.size()), GL_UNSIGNED_INT, &f_cache_[0]);
_renderer->addRenderObject(&ro);
}
else
else if (!poly_cache_.empty()) //if mesh is not a triangle mesh, poly_cache is always empty
{
ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(poly_cache.size()), GL_UNSIGNED_INT, &poly_cache[0]);
ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(poly_cache_.size()), GL_UNSIGNED_INT, &poly_cache_[0]);
_renderer->addRenderObject(&ro);
}
}
......
......@@ -264,7 +264,7 @@ private:
const Mesh& mesh_;
DrawMeshT<Mesh>* drawMesh_;
std::vector<unsigned int> v_cache_, e_cache_, f_cache_, poly_cache;
std::vector<unsigned int> v_cache_, e_cache_, f_cache_, poly_cache_;
std::vector<FaceHandle> fh_cache_;
std::vector<Point> he_points_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment