From 53174e3a35de1b05117a74859a3b40eb78fd9eda Mon Sep 17 00:00:00 2001 From: Ellen Dekkers Date: Mon, 1 Mar 2010 17:07:39 +0000 Subject: [PATCH] VDProgMesh added git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@281 fdac6126-5c0c-442c-9429-916003d36597 --- src/OpenMesh/Apps/CMakeLists.txt | 1 + src/OpenMesh/Apps/ProgViewer/ACGMakefile | 18 + .../OpenMesh_Apps_ProgViewer.vcproj | 274 +++++++++++++++ .../Apps/ProgViewer/ProgViewerWidget.cc | 332 ++++++++++++++++++ .../Apps/ProgViewer/ProgViewerWidget.hh | 148 ++++++++ src/OpenMesh/Apps/ProgViewer/progviewer.cc | 89 +++++ 6 files changed, 862 insertions(+) create mode 100644 src/OpenMesh/Apps/ProgViewer/ACGMakefile create mode 100644 src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj create mode 100644 src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc create mode 100644 src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh create mode 100644 src/OpenMesh/Apps/ProgViewer/progviewer.cc diff --git a/src/OpenMesh/Apps/CMakeLists.txt b/src/OpenMesh/Apps/CMakeLists.txt index a1ebbd8c..c3a9c71d 100644 --- a/src/OpenMesh/Apps/CMakeLists.txt +++ b/src/OpenMesh/Apps/CMakeLists.txt @@ -18,6 +18,7 @@ if (QT4_FOUND AND OPENGL_FOUND AND GLEW_FOUND AND GLUT_FOUND AND NOT BUILD_APPS add_subdirectory (Decimating/DecimaterGui) add_subdirectory (QtViewer) add_subdirectory (Subdivider/SubdividerGui) + add_subdirectory (ProgViewer) else () if ( BUILD_APPS STREQUAL OFF ) message ("Building Apps disabled by user.") diff --git a/src/OpenMesh/Apps/ProgViewer/ACGMakefile b/src/OpenMesh/Apps/ProgViewer/ACGMakefile new file mode 100644 index 00000000..dd5b34d0 --- /dev/null +++ b/src/OpenMesh/Apps/ProgViewer/ACGMakefile @@ -0,0 +1,18 @@ +#== SYSTEM PART -- DON'T TOUCH ============================================== +include $(ACGMAKE)/Config +#============================================================================== + +CXX_CFLAGS += -DQT_THREAD_SUPPORT + +SUBDIRS = $(call find-subdirs) + +PACKAGES := qt4 glut opengl x11 math + +PROJ_LIBS = OpenMesh/Apps/QtViewer OpenMesh/Tools OpenMesh/Core + +MODULES := moc4 cxx + + +#== SYSTEM PART -- DON'T TOUCH ============================================== +include $(ACGMAKE)/Rules +#============================================================================== diff --git a/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj b/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj new file mode 100644 index 00000000..0ae89add --- /dev/null +++ b/src/OpenMesh/Apps/ProgViewer/OpenMesh_Apps_ProgViewer.vcproj @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc new file mode 100644 index 00000000..8b2df60a --- /dev/null +++ b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.cc @@ -0,0 +1,332 @@ +/*===========================================================================*\ + * * + * OpenMesh * + * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + * * + * OpenMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision$ * + * $Date$ * + * * +\*===========================================================================*/ + + +//== INCLUDES ================================================================= + +#ifdef _MSC_VER +# pragma warning(disable: 4267 4311) +#endif + +#include +#include +// -------------------- +#include +#include +#include +// -------------------- +#include +#include +#include +#include +#include +// -------------------- +#ifdef ARCH_DARWIN +# include +#else +# include +#endif + +using namespace Qt; +//== IMPLEMENTATION ========================================================== + + +void +ProgViewerWidget::open_prog_mesh(const char* _filename) +{ + MyMesh::Point p; + unsigned int i, i0, i1, i2; + unsigned int v1, vl, vr; + char c[10]; + + std::ifstream ifs(_filename, std::ios::binary); + if (!ifs) + { + std::cerr << "read error\n"; + exit(1); + } + + // + bool swap = OpenMesh::Endian::local() != OpenMesh::Endian::LSB; + + // read header + ifs.read(c, 8); c[8] = '\0'; + if (std::string(c) != std::string("ProgMesh")) + { + std::cerr << "Wrong file format.\n"; + exit(1); + } + OpenMesh::IO::binary::restore( ifs, n_base_vertices_, swap ); + OpenMesh::IO::binary::restore( ifs, n_base_faces_, swap ); + OpenMesh::IO::binary::restore( ifs, n_detail_vertices_, swap ); + + n_max_vertices_ = n_base_vertices_ + n_detail_vertices_; + + // load base mesh + mesh_.clear(); + + for (i=0; i::restore( ifs, p, swap ); + mesh_.add_vertex(p); + } + + for (i=0; i::restore( ifs, i0, swap); + OpenMesh::IO::binary::restore( ifs, i1, swap); + OpenMesh::IO::binary::restore( ifs, i2, swap); + mesh_.add_face(mesh_.vertex_handle(i0), + mesh_.vertex_handle(i1), + mesh_.vertex_handle(i2)); + } + + + // load progressive detail + for (i=0; i::restore( ifs, p, swap ); + OpenMesh::IO::binary::restore( ifs, v1, swap ); + OpenMesh::IO::binary::restore( ifs, vl, swap ); + OpenMesh::IO::binary::restore( ifs, vr, swap ); + + PMInfo pminfo; + pminfo.p0 = p; + pminfo.v1 = MyMesh::VertexHandle(v1); + pminfo.vl = MyMesh::VertexHandle(vl); + pminfo.vr = MyMesh::VertexHandle(vr); + pminfos_.push_back(pminfo); + } + pmiter_ = pminfos_.begin(); + + + // update face and vertex normals + mesh_.update_face_normals(); + mesh_.update_vertex_normals(); + + // bounding box + MyMesh::ConstVertexIter + vIt(mesh_.vertices_begin()), + vEnd(mesh_.vertices_end()); + + MyMesh::Point bbMin, bbMax; + + bbMin = bbMax = mesh_.point(vIt); + for (; vIt!=vEnd; ++vIt) + { + bbMin.minimize(mesh_.point(vIt)); + bbMax.maximize(mesh_.point(vIt)); + } + + // set center and radius + set_scene_pos(0.5f*(bbMin + bbMax), 0.5*(bbMin - bbMax).norm()); + + // info + std::cerr << mesh_.n_vertices() << " vertices, " + << mesh_.n_edges() << " edge, " + << mesh_.n_faces() << " faces, " + << n_detail_vertices_ << " detail vertices\n"; + + setWindowTitle( QFileInfo(_filename).fileName() ); +} + + +//----------------------------------------------------------------------------- + + +void ProgViewerWidget::refine(unsigned int _n) +{ + size_t n_vertices = mesh_.n_vertices(); + + while (n_vertices < _n && pmiter_ != pminfos_.end()) + { + pmiter_->v0 = mesh_.add_vertex(pmiter_->p0); + mesh_.vertex_split(pmiter_->v0, + pmiter_->v1, + pmiter_->vl, + pmiter_->vr); + ++pmiter_; + ++n_vertices; + } + + mesh_.update_face_normals(); + mesh_.update_vertex_normals(); + + std::cerr << n_vertices << " vertices\n"; +} + + +//----------------------------------------------------------------------------- + + +void ProgViewerWidget::coarsen(unsigned int _n) +{ + size_t n_vertices = mesh_.n_vertices(); + + while (n_vertices > _n && pmiter_ != pminfos_.begin()) + { + --pmiter_; + + MyMesh::HalfedgeHandle hh = + mesh_.find_halfedge(pmiter_->v0, pmiter_->v1); + + mesh_.collapse(hh); + + --n_vertices; + } + + mesh_.garbage_collection(); + mesh_.update_face_normals(); + mesh_.update_vertex_normals(); + + std::cerr << n_vertices << " vertices\n"; +} + + +//----------------------------------------------------------------------------- + +void ProgViewerWidget::keyPressEvent(QKeyEvent* _event) +{ + switch (_event->key()) + { + case Key_Minus: + if ( _event->modifiers() & ShiftModifier) + coarsen(mesh_.n_vertices()-1); + else + coarsen((unsigned int)(0.9*mesh_.n_vertices())); + updateGL(); + break; + + case Key_Plus: + if (_event->modifiers() & ShiftModifier) + refine(mesh_.n_vertices()+1); + else + refine((unsigned int)(std::max( 1.1*mesh_.n_vertices(), + mesh_.n_vertices()+1.0) )); + updateGL(); + break; + + case Key_Home: + coarsen(n_base_vertices_); + updateGL(); + break; + + case Key_A: + if (timer_->isActive()) + { + timer_->stop(); + std::cout << "animation stopped!" << std::endl; + } + else + { + timer_->setSingleShot(true); + timer_->start(0); + std::cout << "animation started!" << std::endl; + } + break; + + case Key_End: + refine(n_base_vertices_ + n_detail_vertices_); + updateGL(); + break; + + case Key_P: + { + const size_t refine_max = 100000; + const size_t n_loop = 5; + + OpenMesh::Utils::Timer t; + size_t count; + + coarsen(0); count = mesh_.n_vertices(); + refine(refine_max); count = mesh_.n_vertices() - count; + + t.start(); + for (size_t i=0; iBase::keyPressEvent(_event); + } +} + +void ProgViewerWidget::animate( void ) +{ + if (animateRefinement_) + { + refine((unsigned int)( 1.1*(mesh_.n_vertices()+1) )); + if ( mesh_.n_vertices() > n_base_vertices_+(0.5*n_detail_vertices_)) + animateRefinement_ = false; + } + else + { + coarsen((unsigned int)(0.9*(mesh_.n_vertices()-1))); + if ( mesh_.n_vertices() == n_base_vertices_ ) + animateRefinement_ = true; + } + updateGL(); + timer_->setSingleShot(true); + timer_->start(300); +} + +//============================================================================= diff --git a/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh new file mode 100644 index 00000000..36f49ab6 --- /dev/null +++ b/src/OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh @@ -0,0 +1,148 @@ +/*===========================================================================*\ + * * + * OpenMesh * + * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + * * + * OpenMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision$ * + * $Date$ * + * * +\*===========================================================================*/ + + +#ifndef OPENMESHAPPS_PROGVIEWERWIDGET_HH +#define OPENMESHAPPS_PROGVIEWERWIDGET_HH + + +//== INCLUDES ================================================================= + +#include +#include +#include +#include +#include + + + +//== CLASS DEFINITION ========================================================= + + +using namespace OpenMesh; +using namespace OpenMesh::Attributes; + + +struct MyTraits : public OpenMesh::DefaultTraits +{ + VertexAttributes ( OpenMesh::Attributes::Normal | + OpenMesh::Attributes::Status ); + EdgeAttributes ( OpenMesh::Attributes::Status ); + HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge ); + FaceAttributes ( OpenMesh::Attributes::Normal | + OpenMesh::Attributes::Status ); +}; + + +typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; +typedef MeshViewerWidgetT MeshViewerWidget; + + +//== CLASS DEFINITION ========================================================= + + + +class ProgViewerWidget : public MeshViewerWidget +{ + Q_OBJECT + +public: + + typedef MeshViewerWidget Base; + typedef ProgViewerWidget This; + + +public: + /// default constructor + ProgViewerWidget(QWidget* _parent=0) + : MeshViewerWidget(_parent) + { + timer_ = new QTimer(this); + + connect( timer_, SIGNAL(timeout()), SLOT(animate()) ); + } + + /// destructor + ~ProgViewerWidget() + { + delete timer_; + } + + /// open progressive mesh + void open_prog_mesh(const char* _filename); + +protected slots: + +void animate( void ); + +private: + + QTimer *timer_; + + struct PMInfo + { + MyMesh::Point p0; + MyMesh::VertexHandle v0, v1, vl, vr; + }; + typedef std::vector PMInfoContainer; + typedef PMInfoContainer::iterator PMInfoIter; + + /// refine mesh up to _n vertices + void refine(unsigned int _n); + + /// coarsen mesh down to _n vertices + void coarsen(unsigned int _n); + + virtual void keyPressEvent(QKeyEvent* _event); + + // mesh data + bool animateRefinement_; + PMInfoContainer pminfos_; + PMInfoIter pmiter_; + size_t n_base_vertices_, n_base_faces_, n_detail_vertices_; + size_t n_max_vertices_; +}; + + +//============================================================================= +#endif // OPENMESHAPPS_PROGVIEWERWIDGET_HH defined +//============================================================================= + diff --git a/src/OpenMesh/Apps/ProgViewer/progviewer.cc b/src/OpenMesh/Apps/ProgViewer/progviewer.cc new file mode 100644 index 00000000..1367ee11 --- /dev/null +++ b/src/OpenMesh/Apps/ProgViewer/progviewer.cc @@ -0,0 +1,89 @@ +/*===========================================================================*\ + * * + * OpenMesh * + * Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + * * + * OpenMesh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of * + * the License, or (at your option) any later version with the * + * following exceptions: * + * * + * If other files instantiate templates or use macros * + * or inline functions from this file, or you compile this file and * + * link it with other files to produce an executable, this file does * + * not by itself cause the resulting executable to be covered by the * + * GNU Lesser General Public License. This exception does not however * + * invalidate any other reasons why the executable file might be * + * covered by the GNU Lesser General Public License. * + * * + * OpenMesh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU LesserGeneral Public * + * License along with OpenMesh. If not, * + * see . * + * * +\*===========================================================================*/ + +/*===========================================================================*\ + * * + * $Revision$ * + * $Date$ * + * * +\*===========================================================================*/ + +#ifdef _MSC_VER +# pragma warning(disable: 4267 4311) +#endif + +#include +#include + +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + // OpenGL check + QApplication::setColorSpec( QApplication::CustomColor ); + QApplication app(argc,argv); + + glutInit(&argc,argv); + + if ( !QGLFormat::hasOpenGL() ) { + std::cerr << "This system has no OpenGL support.\n"; + return -1; + } + + + // create widget + ProgViewerWidget w(0); + w.resize(400, 400); + w.show(); + + // load scene + if (argc > 1) w.open_prog_mesh(argv[1]); + + + // print usage info + std::cout << "\n\n" + << "Press Minus : Coarsen mesh\n" + << " Plus : Refine mesh\n" + << " Home : Coarsen down to base mesh\n" + << " End : Refine up to finest mesh\n" + << "\n"; + + + return app.exec(); +}