First checkin for OpenMesh 2.0

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Jan Möbius
2009-02-06 13:37:46 +00:00
parent c3321ebdd9
commit 97f515985d
417 changed files with 76182 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1.1 $
// $Date: 2008-03-11 09:19:45 $
//
//=============================================================================
#ifndef OPENMESHAPPS_VIEWERWIDGET_HH
#define OPENMESHAPPS_VIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <QWidget>
#include <QString>
#include <QMessageBox>
#include <QFileDialog>
#include <OpenMesh/Tools/Utils/getopt.h>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
//== CLASS DEFINITION =========================================================
using namespace OpenMesh;
using namespace OpenMesh::Attributes;
struct MyTraits : public OpenMesh::DefaultTraits
{
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
};
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
//== CLASS DEFINITION =========================================================
class MeshViewerWidget : public MeshViewerWidgetT<MyMesh>
{
Q_OBJECT
public:
/// default constructor
MeshViewerWidget(QWidget* parent=0) : MeshViewerWidgetT<MyMesh>(parent)
{}
OpenMesh::IO::Options& options() { return _options; }
const OpenMesh::IO::Options& options() const { return _options; }
void setOptions(const OpenMesh::IO::Options& opts) { _options = opts; }
void open_mesh_gui(QString fname)
{
OpenMesh::Utils::Timer t;
t.start();
if ( fname.isEmpty() || !open_mesh(fname.toLocal8Bit(), _options) )
{
QString msg = "Cannot read mesh from file:\n '";
msg += fname;
msg += "'";
QMessageBox::critical( NULL, windowTitle(), msg);
}
t.stop();
std::cout << "Loaded mesh in ~" << t.as_string() << std::endl;
}
void open_texture_gui(QString fname)
{
if ( fname.isEmpty() || !open_texture( fname.toLocal8Bit() ) )
{
QString msg = "Cannot load texture image from file:\n '";
msg += fname;
msg += "'\n\nPossible reasons:\n";
msg += "- Mesh file didn't provide texture coordinates\n";
msg += "- Texture file does not exist\n";
msg += "- Texture file is not accessible.\n";
QMessageBox::warning( NULL, windowTitle(), msg );
}
}
public slots:
void query_open_mesh_file() {
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open mesh file"),
tr(""),
tr("OBJ Files (*.obj);;"
"OFF Files (*.off);;"
"STL Files (*.stl);;"
"All Files (*)"));
if (!fileName.isEmpty())
open_mesh_gui(fileName);
}
void query_open_texture_file() {
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open texture file"),
tr(""),
tr("PNG Files (*.png);;"
"BMP Files (*.bmp);;"
"GIF Files (*.gif);;"
"JPEG Files (*.jpg);;"
"TIFF Files (*.tif);;"
"All Files (*)"));
if (!fileName.isEmpty())
open_texture_gui(fileName);
}
private:
OpenMesh::IO::Options _options;
};
#endif

View File

@@ -0,0 +1,782 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1832 $
// $Date: 2008-05-23 11:10:37 +0200 (Fr, 23. Mai 2008) $
//
//=============================================================================
#define OPENMESHAPPS_MESHVIEWERWIDGET_CC
//== INCLUDES =================================================================
#ifdef _MSC_VER
//# pragma warning(disable: 4267 4311)
#endif
//
#include <iostream>
#include <fstream>
// --------------------
#include <QImage>
#include <QFileInfo>
#include <QKeyEvent>
// --------------------
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
using namespace OpenMesh;
using namespace Qt;
#if defined(_MSC_VER)
# undef min
# undef max
#endif
using namespace Qt;
//== IMPLEMENTATION ==========================================================
template <typename M>
bool
MeshViewerWidgetT<M>::open_mesh(const char* _filename, IO::Options _opt)
{
// load mesh
// calculate normals
// set scene center and radius
mesh_.request_face_normals();
mesh_.request_face_colors();
mesh_.request_vertex_normals();
mesh_.request_vertex_colors();
mesh_.request_vertex_texcoords2D();
std::cout << "Loading from file '" << _filename << "'\n";
if ( IO::read_mesh(mesh_, _filename, _opt ))
{
// store read option
opt_ = _opt;
// update face and vertex normals
if ( ! opt_.check( IO::Options::FaceNormal ) )
mesh_.update_face_normals();
else
std::cout << "File provides face normals\n";
if ( ! opt_.check( IO::Options::VertexNormal ) )
mesh_.update_vertex_normals();
else
std::cout << "File provides vertex normals\n";
// check for possible color information
if ( opt_.check( IO::Options::VertexColor ) )
{
std::cout << "File provides vertex colors\n";
add_draw_mode("Colored Vertices");
}
else
mesh_.release_vertex_colors();
if ( _opt.check( IO::Options::FaceColor ) )
{
std::cout << "File provides face colors\n";
add_draw_mode("Solid Colored Faces");
add_draw_mode("Smooth Colored Faces");
}
else
mesh_.release_face_colors();
if ( _opt.check( IO::Options::VertexTexCoord ) )
std::cout << "File provides texture coordinates\n";
// bounding box
typename Mesh::ConstVertexIter vIt(mesh_.vertices_begin());
typename Mesh::ConstVertexIter vEnd(mesh_.vertices_end());
typedef typename Mesh::Point Point;
using OpenMesh::Vec3f;
Vec3f bbMin, bbMax;
bbMin = bbMax = OpenMesh::vector_cast<Vec3f>(mesh_.point(vIt));
for (size_t count=0; vIt!=vEnd; ++vIt, ++count)
{
bbMin.minimize( OpenMesh::vector_cast<Vec3f>(mesh_.point(vIt)));
bbMax.maximize( OpenMesh::vector_cast<Vec3f>(mesh_.point(vIt)));
}
// set center and radius
set_scene_pos( (bbMin+bbMax)*0.5, (bbMin-bbMax).norm()*0.5 );
// for normal display
normal_scale_ = (bbMax-bbMin).min()*0.05f;
// info
std::clog << mesh_.n_vertices() << " vertices, "
<< mesh_.n_edges() << " edge, "
<< mesh_.n_faces() << " faces\n";
// base point for displaying face normals
{
OpenMesh::Utils::Timer t;
t.start();
mesh_.add_property( fp_normal_base_ );
typename M::FaceIter f_it = mesh_.faces_begin();
typename M::FaceVertexIter fv_it;
for (;f_it != mesh_.faces_end(); ++f_it)
{
typename Mesh::Point v(0,0,0);
for( fv_it=mesh_.fv_iter(f_it); fv_it; ++fv_it)
v += OpenMesh::vector_cast<typename Mesh::Normal>(mesh_.point(fv_it));
v *= 1.0f/3.0f;
mesh_.property( fp_normal_base_, f_it ) = v;
}
t.stop();
std::clog << "Computed base point for displaying face normals ["
<< t.as_string() << "]" << std::endl;
}
//
{
std::clog << "Computing strips.." << std::flush;
OpenMesh::Utils::Timer t;
t.start();
compute_strips();
t.stop();
std::clog << "done [" << strips_.n_strips()
<< " strips created in " << t.as_string() << "]\n";
}
//
#if defined(WIN32)
updateGL();
#endif
setWindowTitle(QFileInfo(_filename).fileName());
// loading done
return true;
}
return false;
}
//-----------------------------------------------------------------------------
template <typename M>
bool MeshViewerWidgetT<M>::open_texture( const char *_filename )
{
QImage texsrc;
QString fname = _filename;
if (texsrc.load( fname ))
{
return set_texture( texsrc );
}
return false;
}
//-----------------------------------------------------------------------------
template <typename M>
bool MeshViewerWidgetT<M>::set_texture( QImage& _texsrc )
{
if ( !opt_.vertex_has_texcoord() )
return false;
{
// adjust texture size: 2^k * 2^l
int tex_w, w( _texsrc.width() );
int tex_h, h( _texsrc.height() );
for (tex_w=1; tex_w <= w; tex_w <<= 1) {};
for (tex_h=1; tex_h <= h; tex_h <<= 1) {};
tex_w >>= 1;
tex_h >>= 1;
_texsrc = _texsrc.scaled( tex_w, tex_h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
QImage texture( QGLWidget::convertToGLFormat ( _texsrc ) );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
if ( tex_id_ > 0 )
{
glDeleteTextures(1, &tex_id_);
}
glGenTextures(1, &tex_id_);
glBindTexture(GL_TEXTURE_2D, tex_id_);
// glTexGenfv( GL_S, GL_SPHERE_MAP, 0 );
// glTexGenfv( GL_T, GL_SPHERE_MAP, 0 );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, // target
0, // level
GL_RGBA, // internal format
texture.width(), // width (2^n)
texture.height(), // height (2^m)
0, // border
GL_RGBA, // format
GL_UNSIGNED_BYTE, // type
texture.bits() ); // pointer to pixels
std::cout << "Texture loaded\n";
return true;
}
//-----------------------------------------------------------------------------
template <typename M>
void
MeshViewerWidgetT<M>::draw_openmesh(const std::string& _draw_mode)
{
typename Mesh::ConstFaceIter fIt(mesh_.faces_begin()),
fEnd(mesh_.faces_end());
typename Mesh::ConstFaceVertexIter fvIt;
#if defined(OM_USE_OSG) && OM_USE_OSG
if (_draw_mode == "OpenSG Indices") // --------------------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_id_);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
}
glDrawElements(GL_TRIANGLES,
mesh_.osg_indices()->size(),
GL_UNSIGNED_INT,
&mesh_.osg_indices()->getField()[0] );
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
else
#endif
if (_draw_mode == "Wireframe") // -------------------------------------------
{
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
fvIt = mesh_.cfv_iter(fIt.handle());
glVertex3fv( &mesh_.point(fvIt)[0] );
++fvIt;
glVertex3fv( &mesh_.point(fvIt)[0] );
++fvIt;
glVertex3fv( &mesh_.point(fvIt)[0] );
}
glEnd();
}
else if (_draw_mode == "Solid Flat") // -------------------------------------
{
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
glNormal3fv( &mesh_.normal(fIt)[0] );
fvIt = mesh_.cfv_iter(fIt.handle());
glVertex3fv( &mesh_.point(fvIt)[0] );
++fvIt;
glVertex3fv( &mesh_.point(fvIt)[0] );
++fvIt;
glVertex3fv( &mesh_.point(fvIt)[0] );
}
glEnd();
}
else if (_draw_mode == "Solid Smooth") // -----------------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_id_);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
}
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
fvIt = mesh_.cfv_iter(fIt.handle());
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
}
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
{
glDisable(GL_TEXTURE_2D);
}
}
else if (_draw_mode == "Colored Vertices") // --------------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
if ( mesh_.has_vertex_colors() )
{
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer(3, GL_UNSIGNED_BYTE, 0,mesh_.vertex_colors());
}
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
fvIt = mesh_.cfv_iter(fIt.handle());
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
}
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
else if (_draw_mode == "Solid Colored Faces") // -----------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
glColor( fIt.handle() );
fvIt = mesh_.cfv_iter(fIt.handle());
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
}
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
else if (_draw_mode == "Smooth Colored Faces") // ---------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
glBegin(GL_TRIANGLES);
for (; fIt!=fEnd; ++fIt)
{
glMaterial( fIt.handle() );
fvIt = mesh_.cfv_iter(fIt.handle());
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
++fvIt;
glArrayElement(fvIt.handle().idx());
}
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
else if ( _draw_mode == "Strips'n VertexArrays" ) // ------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_id_);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
}
typename MyStripifier::StripsIterator strip_it = strips_.begin();
typename MyStripifier::StripsIterator strip_last = strips_.end();
// Draw all strips
for (; strip_it!=strip_last; ++strip_it)
{
glDrawElements(GL_TRIANGLE_STRIP,
strip_it->size(), GL_UNSIGNED_INT, &(*strip_it)[0] );
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
else if (_draw_mode == "Show Strips" && strips_.is_valid() ) // -------------
{
typename MyStripifier::StripsIterator strip_it = strips_.begin();
typename MyStripifier::StripsIterator strip_last = strips_.end();
float cmax = 256.0f;
int range = 220;
int base = (int)cmax-range;
int drcol = 13;
int dgcol = 31;
int dbcol = 17;
int rcol=0, gcol=dgcol, bcol=dbcol+dbcol;
// Draw all strips
for (; strip_it!=strip_last; ++strip_it)
{
typename MyStripifier::IndexIterator idx_it = strip_it->begin();
typename MyStripifier::IndexIterator idx_last = strip_it->end();
rcol = (rcol+drcol) % range;
gcol = (gcol+dgcol) % range;
bcol = (bcol+dbcol) % range;
glBegin(GL_TRIANGLE_STRIP);
glColor3f((rcol+base)/cmax, (gcol+base)/cmax, (bcol+base)/cmax);
for ( ;idx_it != idx_last; ++idx_it )
glVertex3fv(&mesh_.point( OM_TYPENAME Mesh::VertexHandle(*idx_it))[0]);
glEnd();
}
glColor3f(1.0, 1.0, 1.0);
}
else if( _draw_mode == "Points" ) // -----------------------------------------
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
if (mesh_.has_vertex_colors() && use_color_)
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_UNSIGNED_BYTE, 0, mesh_.vertex_colors());
}
glDrawArrays( GL_POINTS, 0, mesh_.n_vertices() );
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
}
//-----------------------------------------------------------------------------
template <typename M>
void
MeshViewerWidgetT<M>::draw_scene(const std::string& _draw_mode)
{
if ( ! mesh_.n_vertices() )
return;
#if defined(OM_USE_OSG) && OM_USE_OSG
else if ( _draw_mode == "OpenSG Indices")
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
draw_openmesh( _draw_mode );
}
else
#endif
if ( _draw_mode == "Points" )
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Wireframe")
{
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
draw_openmesh(_draw_mode);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else if ( _draw_mode == "Hidden-Line" )
{
glDisable(GL_LIGHTING);
glShadeModel(GL_FLAT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
glDepthRange(0.01, 1.0);
draw_openmesh( "Wireframe" );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glDepthRange( 0.0, 1.0 );
draw_openmesh( "Wireframe" );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
}
else if (_draw_mode == "Solid Flat")
{
glEnable(GL_LIGHTING);
glShadeModel(GL_FLAT);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Solid Smooth" ||
_draw_mode == "Strips'n VertexArrays" )
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Show Strips")
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Colored Vertices" )
{
glDisable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Solid Colored Faces")
{
glDisable(GL_LIGHTING);
glShadeModel(GL_FLAT);
draw_openmesh(_draw_mode);
setDefaultMaterial();
}
else if (_draw_mode == "Smooth Colored Faces" )
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
draw_openmesh(_draw_mode);
setDefaultMaterial();
}
if (show_vnormals_)
{
typename Mesh::VertexIter vit;
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1.000f, 0.803f, 0.027f); // orange
for(vit=mesh_.vertices_begin(); vit!=mesh_.vertices_end(); ++vit)
{
glVertex( vit );
glVertex( mesh_.point( vit ) + normal_scale_*mesh_.normal( vit ) );
}
glEnd();
}
if (show_fnormals_)
{
typename Mesh::FaceIter fit;
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.705f, 0.976f, 0.270f); // greenish
for(fit=mesh_.faces_begin(); fit!=mesh_.faces_end(); ++fit)
{
glVertex( mesh_.property(fp_normal_base_, fit) );
glVertex( mesh_.property(fp_normal_base_, fit) +
normal_scale_*mesh_.normal( fit ) );
}
glEnd();
}
}
//-----------------------------------------------------------------------------
template <typename M>
void
MeshViewerWidgetT<M>::enable_strips()
{
if (!f_strips_)
{
f_strips_ = true;
add_draw_mode("Strips'n VertexArrays");
add_draw_mode("Show Strips");
}
}
//-----------------------------------------------------------------------------
template <typename M>
void
MeshViewerWidgetT<M>::disable_strips()
{
if (f_strips_)
{
f_strips_ = false;
del_draw_mode("Show Strips");
del_draw_mode("Strip'n VertexArrays");
}
}
//-----------------------------------------------------------------------------
#define TEXMODE( Mode ) \
tex_mode_ = Mode; std::cout << "Texture mode set to " << #Mode << std::endl
template <typename M>
void
MeshViewerWidgetT<M>::keyPressEvent( QKeyEvent* _event)
{
switch( _event->key() )
{
case Key_D:
if ( mesh_.has_vertex_colors() && (current_draw_mode()=="Points") )
{
use_color_ = !use_color_;
std::cout << "use color: " << (use_color_?"yes\n":"no\n");
if (!use_color_)
glColor3f(1.0f, 1.0f, 1.0f);
updateGL();
}
break;
case Key_N:
if ( _event->modifiers() & ShiftModifier )
{
show_fnormals_ = !show_fnormals_;
std::cout << "show face normals: " << (show_fnormals_?"yes\n":"no\n");
}
else
{
show_vnormals_ = !show_vnormals_;
std::cout << "show vertex normals: " << (show_vnormals_?"yes\n":"no\n");
}
updateGL();
break;
case Key_I:
std::cout << "\n# Vertices : " << mesh_.n_vertices() << std::endl;
std::cout << "# Edges : " << mesh_.n_edges() << std::endl;
std::cout << "# Faces : " << mesh_.n_faces() << std::endl;
std::cout << "binary input : " << opt_.check(opt_.Binary) << std::endl;
std::cout << "swapped input : " << opt_.check(opt_.Swap) << std::endl;
std::cout << "vertex normal : "
<< opt_.check(opt_.VertexNormal) << std::endl;
std::cout << "vertex texcoord: "
<< opt_.check(opt_.VertexTexCoord) << std::endl;
std::cout << "vertex color : "
<< opt_.check(opt_.VertexColor) << std::endl;
std::cout << "face normal : "
<< opt_.check(opt_.FaceNormal) << std::endl;
std::cout << "face color : "
<< opt_.check(opt_.FaceColor) << std::endl;
this->QGLViewerWidget::keyPressEvent( _event );
break;
case Key_T:
switch( tex_mode_ )
{
case GL_MODULATE: TEXMODE(GL_DECAL); break;
case GL_DECAL: TEXMODE(GL_BLEND); break;
case GL_BLEND: TEXMODE(GL_REPLACE); break;
case GL_REPLACE: TEXMODE(GL_MODULATE); break;
}
updateGL();
break;
default:
this->QGLViewerWidget::keyPressEvent( _event );
}
}
#undef TEXMODE
//=============================================================================

View File

@@ -0,0 +1,187 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1800 $
// $Date: 2008-05-19 11:51:23 +0200 (Mo, 19. Mai 2008) $
//
//=============================================================================
#ifndef OPENMESHAPPS_MESHVIEWERWIDGETT_HH
#define OPENMESHAPPS_MESHVIEWERWIDGETT_HH
//== INCLUDES =================================================================
#include <string>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/IO/Options.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/Mesh/Attributes.hh>
#include <OpenMesh/Tools/Utils/StripifierT.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/QtViewer/QGLViewerWidget.hh>
//== FORWARDS =================================================================
class QImage;
//== CLASS DEFINITION =========================================================
template <typename M>
class MeshViewerWidgetT : public QGLViewerWidget
{
public:
typedef M Mesh;
typedef OpenMesh::StripifierT<Mesh> MyStripifier;
public:
/// default constructor
MeshViewerWidgetT(QWidget* _parent=0)
: QGLViewerWidget(_parent),
f_strips_(false),
tex_id_(0),
tex_mode_(GL_MODULATE),
strips_(mesh_),
use_color_(true),
show_vnormals_(false),
show_fnormals_(false)
{
add_draw_mode("Points");
add_draw_mode("Hidden-Line");
#if defined(OM_USE_OSG) && OM_USE_OSG
add_draw_mode("OpenSG Indices");
#endif
}
/// destructor
~MeshViewerWidgetT() {}
public:
/// open mesh
virtual bool open_mesh(const char* _filename, OpenMesh::IO::Options _opt);
/// load texture
virtual bool open_texture( const char *_filename );
bool set_texture( QImage& _texsrc );
void enable_strips();
void disable_strips();
Mesh& mesh() { return mesh_; }
const Mesh& mesh() const { return mesh_; }
protected:
/// inherited drawing method
virtual void draw_scene(const std::string& _draw_mode);
protected:
/// draw the mesh
virtual void draw_openmesh(const std::string& _drawmode);
void glVertex( const typename Mesh::VertexHandle _vh )
{ glVertex3fv( &mesh_.point( _vh )[0] ); }
void glVertex( const typename Mesh::Point& _p )
{ glVertex3fv( &_p[0] ); }
void glNormal( const typename Mesh::VertexHandle _vh )
{ glNormal3fv( &mesh_.normal( _vh )[0] ); }
void glTexCoord( const typename Mesh::VertexHandle _vh )
{ glTexCoord2fv( &mesh_.texcoord(_vh)[0] ); }
void glColor( const typename Mesh::VertexHandle _vh )
{ glColor3ubv( &mesh_.color(_vh)[0] ); }
// face properties
void glNormal( const typename Mesh::FaceHandle _fh )
{ glNormal3fv( &mesh_.normal( _fh )[0] ); }
void glColor( const typename Mesh::FaceHandle _fh )
{ glColor3ubv( &mesh_.color(_fh)[0] ); }
void glMaterial( const typename Mesh::FaceHandle _fh,
int _f=GL_FRONT_AND_BACK, int _m=GL_DIFFUSE )
{
OpenMesh::Vec3f c=OpenMesh::color_cast<OpenMesh::Vec3f>(mesh_.color(_fh));
OpenMesh::Vec4f m( c[0], c[1], c[2], 1.0f );
glMaterialfv(_f, _m, &m[0]);
}
protected: // Strip support
void compute_strips(void)
{
if (f_strips_)
{
strips_.clear();
strips_.stripify();
}
}
protected: // inherited
virtual void keyPressEvent( QKeyEvent* _event);
protected:
bool f_strips_; // enable/disable strip usage
GLuint tex_id_;
GLint tex_mode_;
OpenMesh::IO::Options opt_; // mesh file contained texcoords?
Mesh mesh_;
MyStripifier strips_;
bool use_color_;
bool show_vnormals_;
bool show_fnormals_;
float normal_scale_;
OpenMesh::FPropHandleT< typename Mesh::Point > fp_normal_base_;
};
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESHAPPS_MESHVIEWERWIDGET_CC)
# define OPENMESH_MESHVIEWERWIDGET_TEMPLATES
# include "MeshViewerWidgetT.cc"
#endif
//=============================================================================
#endif // OPENMESHAPPS_MESHVIEWERWIDGETT_HH defined
//=============================================================================

View File

@@ -0,0 +1,849 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 2095 $
// $Date: 2008-06-26 12:07:09 +0200 (Do, 26. Jun 2008) $
//
//=============================================================================
//== INCLUDES =================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311 4305)
#endif
#include <iomanip>
#include <sstream>
#include <algorithm>
// --------------------
#ifdef ARCH_DARWIN
# include <glut.h>
#else
# include <GL/glut.h>
#endif
// --------------------
#include <qnamespace.h>
#include <qapplication.h>
#include <qmenu.h>
#include <qcursor.h>
#include <qimage.h>
#include <qdatetime.h>
#include <QMouseEvent>
// --------------------
#include <OpenMesh/Apps/QtViewer/QGLViewerWidget.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#if !defined(M_PI)
# define M_PI 3.1415926535897932
#endif
const double TRACKBALL_RADIUS = 0.6;
using namespace Qt;
using namespace OpenMesh;
//== IMPLEMENTATION ==========================================================
std::string QGLViewerWidget::nomode_ = "";
//----------------------------------------------------------------------------
QGLViewerWidget::QGLViewerWidget( QWidget* _parent )
: QGLWidget( _parent )
{
init();
}
//----------------------------------------------------------------------------
QGLViewerWidget::
QGLViewerWidget( QGLFormat& _fmt, QWidget* _parent )
: QGLWidget( _fmt, _parent )
{
init();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::init(void)
{
// qt stuff
setAttribute(Qt::WA_NoSystemBackground, true);
setFocusPolicy(Qt::StrongFocus);
setAcceptDrops( true );
setCursor(PointingHandCursor);
// popup menu
popup_menu_ = new QMenu(this);
draw_modes_group_ = new QActionGroup(this);
connect( draw_modes_group_, SIGNAL(triggered(QAction*)),
this, SLOT(slotDrawMode(QAction*)));
// init draw modes
n_draw_modes_ = 0;
//draw_mode_ = 3;
QAction *a;
a = add_draw_mode("Wireframe");
a->setShortcut(QKeySequence(Key_W));
a = add_draw_mode("Solid Flat");
a = add_draw_mode("Solid Smooth");
a->setShortcut(QKeySequence(Key_S));
a->setChecked(true);
slotDrawMode(a);
}
//----------------------------------------------------------------------------
QGLViewerWidget::~QGLViewerWidget()
{
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::setDefaultMaterial(void)
{
GLfloat mat_a[] = {0.1, 0.1, 0.1, 1.0};
GLfloat mat_d[] = {0.7, 0.7, 0.5, 1.0};
GLfloat mat_s[] = {1.0, 1.0, 1.0, 1.0};
GLfloat shine[] = {120.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_a);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_d);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_s);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::setDefaultLight(void)
{
GLfloat pos1[] = { 0.1, 0.1, -0.02, 0.0};
GLfloat pos2[] = {-0.1, 0.1, -0.02, 0.0};
GLfloat pos3[] = { 0.0, 0.0, 0.1, 0.0};
GLfloat col1[] = { 0.7, 0.7, 0.8, 1.0};
GLfloat col2[] = { 0.8, 0.7, 0.7, 1.0};
GLfloat col3[] = { 1.0, 1.0, 1.0, 1.0};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_POSITION, pos1);
glLightfv(GL_LIGHT0,GL_DIFFUSE, col1);
glLightfv(GL_LIGHT0,GL_SPECULAR, col1);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1,GL_POSITION, pos2);
glLightfv(GL_LIGHT1,GL_DIFFUSE, col2);
glLightfv(GL_LIGHT1,GL_SPECULAR, col2);
glEnable(GL_LIGHT2);
glLightfv(GL_LIGHT2,GL_POSITION, pos3);
glLightfv(GL_LIGHT2,GL_DIFFUSE, col3);
glLightfv(GL_LIGHT2,GL_SPECULAR, col3);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::initializeGL()
{
// OpenGL state
glClearColor(0.0, 0.0, 0.0, 0.0);
glDisable( GL_DITHER );
glEnable( GL_DEPTH_TEST );
// Material
setDefaultMaterial();
// Lighting
glLoadIdentity();
setDefaultLight();
// Fog
GLfloat fogColor[4] = { 0.3, 0.3, 0.4, 1.0 };
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 5.0f);
glFogf(GL_FOG_END, 25.0f);
// scene pos and size
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix_);
set_scene_pos(Vec3f(0.0, 0.0, 0.0), 1.0);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::resizeGL( int _w, int _h )
{
update_projection_matrix();
glViewport(0, 0, _w, _h);
updateGL();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadMatrixd( projection_matrix_ );
glMatrixMode( GL_MODELVIEW );
glLoadMatrixd( modelview_matrix_ );
if (draw_mode_)
{
assert(draw_mode_ <= n_draw_modes_);
draw_scene(draw_mode_names_[draw_mode_-1]);
}
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::draw_scene(const std::string& _draw_mode)
{
if (_draw_mode == "Wireframe")
{
glDisable(GL_LIGHTING);
glutWireTeapot(0.5);
}
else if (_draw_mode == "Solid Flat")
{
glEnable(GL_LIGHTING);
glShadeModel(GL_FLAT);
glutSolidTeapot(0.5);
}
else if (_draw_mode == "Solid Smooth")
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glutSolidTeapot(0.5);
}
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::mousePressEvent( QMouseEvent* _event )
{
// popup menu
if (_event->button() == RightButton && _event->buttons()== RightButton )
{
popup_menu_->exec(QCursor::pos());
}
else
{
last_point_ok_ = map_to_sphere( last_point_2D_=_event->pos(),
last_point_3D_ );
}
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::mouseMoveEvent( QMouseEvent* _event )
{
QPoint newPoint2D = _event->pos();
// Left button: rotate around center_
// Middle button: translate object
// Left & middle button: zoom in/out
float value_y;
Vec3f newPoint3D;
bool newPoint_hitSphere = map_to_sphere( newPoint2D, newPoint3D );
float dx = newPoint2D.x() - last_point_2D_.x();
float dy = newPoint2D.y() - last_point_2D_.y();
float w = width();
float h = height();
// enable GL context
makeCurrent();
// move in z direction
if ( (_event->buttons() == (LeftButton+MidButton)) ||
(_event->buttons() == LeftButton && _event->modifiers() == ControlModifier))
{
value_y = radius_ * dy * 3.0 / h;
translate(Vec3f(0.0, 0.0, value_y));
}
// move in x,y direction
else if ( (_event->buttons() == MidButton) ||
(_event->buttons() == LeftButton && _event->modifiers() == AltModifier) )
{
float z = - (modelview_matrix_[ 2]*center_[0] +
modelview_matrix_[ 6]*center_[1] +
modelview_matrix_[10]*center_[2] +
modelview_matrix_[14]) /
(modelview_matrix_[ 3]*center_[0] +
modelview_matrix_[ 7]*center_[1] +
modelview_matrix_[11]*center_[2] +
modelview_matrix_[15]);
float aspect = w / h;
float near_plane = 0.01 * radius_;
float top = tan(fovy()/2.0f*M_PI/180.0f) * near_plane;
float right = aspect*top;
translate(Vec3f( 2.0*dx/w*right/near_plane*z,
-2.0*dy/h*top/near_plane*z,
0.0f));
}
// rotate
else if (_event->buttons() == LeftButton)
{
if (last_point_ok_)
{
if ( (newPoint_hitSphere = map_to_sphere(newPoint2D, newPoint3D)) )
{
Vec3f axis = last_point_3D_ % newPoint3D;
if (axis.sqrnorm() < 1e-7) {
axis = Vec3f(1,0,0);
} else {
axis.normalize();
}
// find the amount of rotation
Vec3f d = last_point_3D_ - newPoint3D;
float t = 0.5*d.norm()/TRACKBALL_RADIUS;
if (t<-1.0) t=-1.0;
else if (t>1.0) t=1.0;
float phi = 2.0 * asin(t);
float angle = phi * 180.0 / M_PI;
rotate( axis, angle );
}
}
}
// remember this point
last_point_2D_ = newPoint2D;
last_point_3D_ = newPoint3D;
last_point_ok_ = newPoint_hitSphere;
// trigger redraw
updateGL();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::mouseReleaseEvent( QMouseEvent* /* _event */ )
{
last_point_ok_ = false;
}
//-----------------------------------------------------------------------------
void QGLViewerWidget::wheelEvent(QWheelEvent* _event)
{
// Use the mouse wheel to zoom in/out
float d = -(float)_event->delta() / 120.0 * 0.2 * radius_;
translate(Vec3f(0.0, 0.0, d));
updateGL();
_event->accept();
}
//----------------------------------------------------------------------------
void QGLViewerWidget::keyPressEvent( QKeyEvent* _event)
{
switch( _event->key() )
{
case Key_Print:
slotSnapshot();
break;
case Key_H:
std::cout << "Keys:\n";
std::cout << " Print\tMake snapshot\n";
std::cout << " C\tenable/disable back face culling\n";
std::cout << " F\tenable/disable fog\n";
std::cout << " I\tDisplay information\n";
std::cout << " N\tenable/disable display of vertex normals\n";
std::cout << " Shift N\tenable/disable display of face normals\n";
std::cout << " Shift P\tperformance check\n";
break;
case Key_C:
if ( glIsEnabled( GL_CULL_FACE ) )
{
glDisable( GL_CULL_FACE );
std::cout << "Back face culling: disabled\n";
}
else
{
glEnable( GL_CULL_FACE );
std::cout << "Back face culling: enabled\n";
}
updateGL();
break;
case Key_F:
if ( glIsEnabled( GL_FOG ) )
{
glDisable( GL_FOG );
std::cout << "Fog: disabled\n";
}
else
{
glEnable( GL_FOG );
std::cout << "Fog: enabled\n";
}
updateGL();
break;
case Key_I:
std::cout << "Scene radius: " << radius_ << std::endl;
std::cout << "Scene center: " << center_ << std::endl;
break;
case Key_P:
if (_event->modifiers() & ShiftModifier)
{
double fps = performance();
std::cout << "fps: "
<< std::setiosflags (std::ios_base::fixed)
<< fps << std::endl;
}
break;
case Key_Q:
case Key_Escape:
qApp->quit();
}
_event->ignore();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::translate( const Vec3f& _trans )
{
// Translate the object by _trans
// Update modelview_matrix_
makeCurrent();
glLoadIdentity();
glTranslated( _trans[0], _trans[1], _trans[2] );
glMultMatrixd( modelview_matrix_ );
glGetDoublev( GL_MODELVIEW_MATRIX, modelview_matrix_);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::rotate( const Vec3f& _axis, float _angle )
{
// Rotate around center center_, axis _axis, by angle _angle
// Update modelview_matrix_
Vec3f t( modelview_matrix_[0]*center_[0] +
modelview_matrix_[4]*center_[1] +
modelview_matrix_[8]*center_[2] +
modelview_matrix_[12],
modelview_matrix_[1]*center_[0] +
modelview_matrix_[5]*center_[1] +
modelview_matrix_[9]*center_[2] +
modelview_matrix_[13],
modelview_matrix_[2]*center_[0] +
modelview_matrix_[6]*center_[1] +
modelview_matrix_[10]*center_[2] +
modelview_matrix_[14] );
makeCurrent();
glLoadIdentity();
glTranslatef(t[0], t[1], t[2]);
glRotated( _angle, _axis[0], _axis[1], _axis[2]);
glTranslatef(-t[0], -t[1], -t[2]);
glMultMatrixd(modelview_matrix_);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix_);
}
//----------------------------------------------------------------------------
bool
QGLViewerWidget::map_to_sphere( const QPoint& _v2D, Vec3f& _v3D )
{
// This is actually doing the Sphere/Hyperbolic sheet hybrid thing,
// based on Ken Shoemake's ArcBall in Graphics Gems IV, 1993.
double x = (2.0*_v2D.x() - width())/width();
double y = -(2.0*_v2D.y() - height())/height();
double xval = x;
double yval = y;
double x2y2 = xval*xval + yval*yval;
const double rsqr = TRACKBALL_RADIUS*TRACKBALL_RADIUS;
_v3D[0] = xval;
_v3D[1] = yval;
if (x2y2 < 0.5*rsqr) {
_v3D[2] = sqrt(rsqr - x2y2);
} else {
_v3D[2] = 0.5*rsqr/sqrt(x2y2);
}
return true;
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::update_projection_matrix()
{
makeCurrent();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective(45.0, (GLfloat) width() / (GLfloat) height(),
0.01*radius_, 100.0*radius_);
glGetDoublev( GL_PROJECTION_MATRIX, projection_matrix_);
glMatrixMode( GL_MODELVIEW );
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::view_all()
{
translate( Vec3f( -(modelview_matrix_[0]*center_[0] +
modelview_matrix_[4]*center_[1] +
modelview_matrix_[8]*center_[2] +
modelview_matrix_[12]),
-(modelview_matrix_[1]*center_[0] +
modelview_matrix_[5]*center_[1] +
modelview_matrix_[9]*center_[2] +
modelview_matrix_[13]),
-(modelview_matrix_[2]*center_[0] +
modelview_matrix_[6]*center_[1] +
modelview_matrix_[10]*center_[2] +
modelview_matrix_[14] +
3.0*radius_) ) );
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::set_scene_pos( const Vec3f& _cog, float _radius )
{
center_ = _cog;
radius_ = _radius;
glFogf( GL_FOG_START, 1.5*_radius );
glFogf( GL_FOG_END, 3.0*_radius );
update_projection_matrix();
view_all();
}
//----------------------------------------------------------------------------
QAction*
QGLViewerWidget::add_draw_mode(const std::string& _s)
{
++n_draw_modes_;
draw_mode_names_.push_back(_s);
QActionGroup *grp = draw_modes_group_;
QAction* act = new QAction(tr(_s.c_str()), this);
act->setCheckable(true);
act->setData(n_draw_modes_);
grp->addAction(act);
popup_menu_->addAction(act);
addAction(act, _s.c_str());
return act;
}
void QGLViewerWidget::addAction(QAction* act, const char * name)
{
names_to_actions[name] = act;
Super::addAction(act);
}
void QGLViewerWidget::removeAction(QAction* act)
{
ActionMap::iterator it = names_to_actions.begin(), e = names_to_actions.end();
ActionMap::iterator found = e;
for(; it!=e; ++it) {
if (it->second == act) {
found = it;
break;
}
}
if (found != e) {
names_to_actions.erase(found);
}
popup_menu_->removeAction(act);
draw_modes_group_->removeAction(act);
Super::removeAction(act);
}
void QGLViewerWidget::removeAction(const char* name)
{
QString namestr = QString(name);
ActionMap::iterator e = names_to_actions.end();
ActionMap::iterator found = names_to_actions.find(namestr);
if (found != e) {
removeAction(found->second);
}
}
QAction* QGLViewerWidget::findAction(const char* name)
{
QString namestr = QString(name);
ActionMap::iterator e = names_to_actions.end();
ActionMap::iterator found = names_to_actions.find(namestr);
if (found != e) {
return found->second;
}
return 0;
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::del_draw_mode(const std::string& _s)
{
QString cmp = _s.c_str();
QList<QAction*> actions_ = popup_menu_->actions();
QList<QAction*>::iterator it=actions_.begin(), e=actions_.end();
for(; it!=e; ++it) {
if ((*it)->text() == cmp) { break; }
}
#if _DEBUG
assert( it != e );
#else
if ( it == e )
return;
#endif
popup_menu_->removeAction(*it);
QActionGroup *grp = draw_modes_group_;
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::slotDrawMode(QAction* _mode)
{
// save draw mode
draw_mode_ = _mode->data().toInt();
updateGL();
// check selected draw mode
//popup_menu_->setItemChecked(draw_mode_, true);
}
//----------------------------------------------------------------------------
double
QGLViewerWidget::performance()
{
setCursor( Qt::WaitCursor );
double fps(0.0);
makeCurrent();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
OpenMesh::Utils::Timer timer;
unsigned int frames = 60;
const float angle = 360.0/(float)frames;
unsigned int i;
Vec3f axis;
glFinish();
timer.start();
for (i=0, axis=Vec3f(1,0,0); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
timer.stop();
qApp->processEvents();
timer.cont();
for (i=0, axis=Vec3f(0,1,0); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
timer.stop();
qApp->processEvents();
timer.cont();
for (i=0, axis=Vec3f(0,0,1); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
timer.stop();
glFinish();
timer.stop();
glPopMatrix();
updateGL();
fps = ( (3.0 * frames) / timer.seconds() );
setCursor( PointingHandCursor );
return fps;
}
void
QGLViewerWidget::slotSnapshot( void )
{
QImage image;
size_t w(width()), h(height());
GLenum buffer( GL_BACK );
try
{
image = QImage(w, h, QImage::Format_RGB32);
std::vector<GLubyte> fbuffer(3*w*h);
qApp->processEvents();
makeCurrent();
updateGL();
glFinish();
glReadBuffer( buffer );
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
paintGL();
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, &fbuffer[0] );
unsigned int x,y,offset;
for (y=0; y<h; ++y) {
for (x=0; x<w; ++x) {
offset = 3*(y*w + x);
image.setPixel(x, h-y-1, qRgb(fbuffer[offset],
fbuffer[offset+1],
fbuffer[offset+2]));
}
}
QString name = "snapshot-";
#if defined(_MSC_VER)
{
std::stringstream s;
QDateTime dt = QDateTime::currentDateTime();
s << dt.date().year()
<< std::setw(2) << std::setfill('0') << dt.date().month()
<< std::setw(2) << std::setfill('0') << dt.date().day()
<< std::setw(2) << std::setfill('0') << dt.time().hour()
<< std::setw(2) << std::setfill('0') << dt.time().minute()
<< std::setw(2) << std::setfill('0') << dt.time().second();
name += QString(s.str().c_str());
}
#else
name += QDateTime::currentDateTime().toString( "yyMMddhhmmss" );
#endif
name += ".png";
image.save( name, "PNG");
}
catch( std::bad_alloc& )
{
qWarning("Mem Alloc Error");
}
}
//=============================================================================

View File

@@ -0,0 +1,189 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 1800 $
// $Date: 2008-05-19 11:51:23 +0200 (Mo, 19. Mai 2008) $
//
//=============================================================================
#ifndef OPENMESHAPPS_QGLVIEWERWIDGET_HH
#define OPENMESHAPPS_QGLVIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <QtOpenGL/qgl.h>
#include <string>
#include <vector>
#include <map>
//== FORWARD DECLARATIONS =====================================================
class QMenu;
class QActionGroup;
class QAction;
//== CLASS DEFINITION =========================================================
class QGLViewerWidget : public QGLWidget
{
Q_OBJECT
public:
typedef QGLWidget Super;
// Default constructor.
QGLViewerWidget( QWidget* _parent=0 );
//
QGLViewerWidget( QGLFormat& _fmt, QWidget* _parent=0 );
// Destructor.
virtual ~QGLViewerWidget();
private:
void init(void);
public:
/* Sets the center and size of the whole scene.
The _center is used as fixpoint for rotations and for adjusting
the camera/viewer (see view_all()). */
void set_scene_pos( const OpenMesh::Vec3f& _center, float _radius );
/* view the whole scene: the eye point is moved far enough from the
center so that the whole scene is visible. */
void view_all();
/// add draw mode to popup menu, and return the QAction created
QAction *add_draw_mode(const std::string& _s);
/// delete draw mode from popup menu
void del_draw_mode(const std::string& _s);
const std::string& current_draw_mode() const
{ return draw_mode_ ? draw_mode_names_[draw_mode_-1] : nomode_; }
float radius() const { return radius_; }
const OpenMesh::Vec3f& center() const { return center_; }
const GLdouble* modelview_matrix() const { return modelview_matrix_; }
const GLdouble* projection_matrix() const { return projection_matrix_; }
float fovy() const { return 45.0f; }
QAction* findAction(const char *name);
void addAction(QAction* action, const char* name);
void removeAction(const char* name);
void removeAction(QAction* action);
protected:
// draw the scene: will be called by the painGL() method.
virtual void draw_scene(const std::string& _draw_mode);
double performance(void);
void setDefaultMaterial(void);
void setDefaultLight(void);
private slots:
// popup menu clicked
void slotDrawMode(QAction *_mode);
void slotSnapshot( void );
private: // inherited
// initialize OpenGL states (triggered by Qt)
void initializeGL();
// draw the scene (triggered by Qt)
void paintGL();
// handle resize events (triggered by Qt)
void resizeGL( int w, int h );
protected:
// Qt mouse events
virtual void mousePressEvent( QMouseEvent* );
virtual void mouseReleaseEvent( QMouseEvent* );
virtual void mouseMoveEvent( QMouseEvent* );
virtual void wheelEvent( QWheelEvent* );
virtual void keyPressEvent( QKeyEvent* );
private:
// updates projection matrix
void update_projection_matrix();
// translate the scene and update modelview matrix
void translate(const OpenMesh::Vec3f& _trans);
// rotate the scene (around its center) and update modelview matrix
void rotate(const OpenMesh::Vec3f& _axis, float _angle);
OpenMesh::Vec3f center_;
float radius_;
GLdouble projection_matrix_[16],
modelview_matrix_[16];
// popup menu for draw mode selection
QMenu* popup_menu_;
QActionGroup* draw_modes_group_;
typedef std::map<QString,QAction*> ActionMap;
ActionMap names_to_actions;
unsigned int draw_mode_;
unsigned int n_draw_modes_;
std::vector<std::string> draw_mode_names_;
static std::string nomode_;
// virtual trackball: map 2D screen point to unit sphere
bool map_to_sphere(const QPoint& _point, OpenMesh::Vec3f& _result);
QPoint last_point_2D_;
OpenMesh::Vec3f last_point_3D_;
bool last_point_ok_;
};
//=============================================================================
#endif // OPENMESHAPPS_QGLVIEWERWIDGET_HH
//=============================================================================

View File

@@ -0,0 +1,25 @@
################################################################################
#
################################################################################
contains( OPENFLIPPER , OpenFlipper ){
include( $$TOPDIR/qmake/all.include )
} else {
include( $$TOPDIR/OpenMesh/qmake/all.include )
}
INCLUDEPATH += ../../..
Application()
glew()
glut()
openmesh()
DIRECTORIES = .
# Input
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
################################################################################

135
Apps/QtViewer/meshviewer.cc Normal file
View File

@@ -0,0 +1,135 @@
//=============================================================================
//
// OpenMesh
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
// www.openmesh.org
//
//-----------------------------------------------------------------------------
//
// License
//
// This library 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, version 2.1.
//
// This library 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 Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//-----------------------------------------------------------------------------
//
// $Revision: 2051 $
// $Date: 2008-06-20 13:57:08 +0200 (Fr, 20. Jun 2008) $
//
//=============================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311)
#endif
#include <iostream>
#include <fstream>
#include <QApplication>
#include <QMessageBox>
#include <QMainWindow>
#include <QMenuBar>
#include <QFileDialog>
#include <GL/glut.h>
#include "MeshViewerWidget.hh"
void create_menu(QMainWindow &w);
void usage_and_exit(int xcode);
int main(int argc, char **argv)
{
// OpenGL check
QApplication::setColorSpec( QApplication::CustomColor );
QApplication app(argc,argv);
glutInit(&argc,argv);
if ( !QGLFormat::hasOpenGL() ) {
QString msg = "System has no OpenGL support!";
QMessageBox::critical( 0, QString("OpenGL"), msg + QString(argv[1]) );
return -1;
}
int c;
OpenMesh::IO::Options opt;
while ( (c=getopt(argc,argv,"hbs"))!=-1 )
{
switch(c)
{
case 'b': opt += OpenMesh::IO::Options::Binary; break;
case 'h':
usage_and_exit(0);
case 's': opt += OpenMesh::IO::Options::Swap; break;
default:
usage_and_exit(1);
}
}
// create widget
QMainWindow mainWin;
MeshViewerWidget w(&mainWin);
w.setOptions(opt);
mainWin.setCentralWidget(&w);
create_menu(mainWin);
// static mesh, hence use strips
w.enable_strips();
mainWin.resize(640, 480);
mainWin.show();
// load scene if specified on the command line
if ( optind < argc )
{
w.open_mesh_gui(argv[optind]);
}
if ( ++optind < argc )
{
w.open_texture_gui(argv[optind]);
}
return app.exec();
}
void create_menu(QMainWindow &w)
{
using namespace Qt;
QMenu *fileMenu = w.menuBar()->addMenu(w.tr("&File"));
QAction* openAct = new QAction(w.tr("&Open mesh..."), &w);
openAct->setShortcut(w.tr("Ctrl+O"));
openAct->setStatusTip(w.tr("Open a mesh file"));
QObject::connect(openAct, SIGNAL(triggered()), w.centralWidget(), SLOT(query_open_mesh_file()));
fileMenu->addAction(openAct);
QAction* texAct = new QAction(w.tr("Open &texture..."), &w);
texAct->setShortcut(w.tr("Ctrl+T"));
texAct->setStatusTip(w.tr("Open a texture file"));
QObject::connect(texAct, SIGNAL(triggered()), w.centralWidget(), SLOT(query_open_texture_file()));
fileMenu->addAction(texAct);
}
void usage_and_exit(int xcode)
{
std::cout << "Usage: meshviewer [-s] [mesh] [texture]\n" << std::endl;
std::cout << "Options:\n"
<< " -b\n"
<< " Assume input to be binary.\n\n"
<< " -s\n"
<< " Reverse byte order, when reading binary files.\n"
<< std::endl;
exit(xcode);
}