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,37 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
SUBDIRS := $(call find-subdirs)
USE_COIN := no
USE_SOQT := no
ifeq ($(USE_COIN),yes)
USE_SOQT := yes
endif
ifeq ($(USE_SOQT),yes)
CXX_DEFS += -DUSE_SOQT=1
ifeq ($(USE_COIN),yes)
PACKAGES := coin soqt_coin glut opengl qt
else
PACKAGES := Inventor soqt_inventor glut opengl qt
endif
else
PACKAGES := inventor opengl x11
endif
PROJ_LIBS = OpenMesh/Core
MODULES := cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,370 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
//=============================================================================
//
// Class SoOpenMeshNodeT - implementation
//
//=============================================================================
#define OPENMESH_SOOPENMESHNODE_CC
//== INCLUDES =================================================================
#include <GL/gl.h>
#include <Inventor/SbBox.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/misc/SoState.h>
#include <Inventor/elements/SoLightModelElement.h>
#include <Inventor/bundles/SoMaterialBundle.h>
#include "SoOpenMeshNodeT.hh"
// Attention must be included after SoOpenMeshNodeT.hh
// as it redefines several macros!
#include "SoOpenMeshSupport.hh"
#include <OpenMesh/Core/Math/VectorT.hh>
//== NAMESPACES ==============================================================
namespace OpenMesh {
//== IMPLEMENTATION ==========================================================
// Helper functions: draw vertices
inline void glVertex(const OpenMesh::Vec3f& _v) { glVertex3fv(_v); }
inline void glVertex(const OpenMesh::Vec3d& _v) { glVertex3dv(_v); }
// Helper functions: draw normal
inline void glNormal(const OpenMesh::Vec3f& _n) { glNormal3fv(_n); }
inline void glNormal(const OpenMesh::Vec3d& _n) { glNormal3dv(_n); }
// Helper function: convert Vec to SbVec3f
template <class Vec> inline SbVec3f sbvec3f(const Vec& _v) {
return SbVec3f(_v[0], _v[1], _v[2]);
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
SoOpenMeshNodeT<Mesh>::initClass()
{
SO_NODE_INIT_CLASS(SoOpenMeshNodeT<Mesh>, SoShape, "Shape");
}
//-----------------------------------------------------------------------------
template <class Mesh>
SoOpenMeshNodeT<Mesh>::SoOpenMeshNodeT(const Mesh* _mesh) :
mesh_(_mesh)
{
SO_NODE_CONSTRUCTOR(SoOpenMeshNodeT<Mesh>);
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
SoOpenMeshNodeT<Mesh>::GLRender(SoGLRenderAction *action)
{
if (mesh_ && shouldGLRender(action))
{
SoState* state = action->getState();
SbBool send_normals = (SoLightModelElement::get(state) !=
SoLightModelElement::BASE_COLOR);
SoMaterialBundle mb(action);
mb.sendFirst();
drawFaces(send_normals);
}
}
//----------------------------------------------------------------------------
template<class Mesh>
void
SoOpenMeshNodeT<Mesh>::
drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type<true>)
{
typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()),
f_end(mesh_->faces_end());
typename Mesh::ConstFaceVertexIter fv_it;
if (_send_normals)
{
glBegin(GL_TRIANGLES);
for (; f_it!=f_end; ++f_it)
{
glNormal(mesh_->normal(f_it));
fv_it = mesh_->cfv_iter(f_it.handle());
glVertex(mesh_->point(fv_it));
++fv_it;
glVertex(mesh_->point(fv_it));
++fv_it;
glVertex(mesh_->point(fv_it));
}
glEnd();
}
else
{
glBegin(GL_TRIANGLES);
for (; f_it!=f_end; ++f_it)
{
fv_it = mesh_->cfv_iter(f_it.handle());
glVertex(mesh_->point(fv_it));
++fv_it;
glVertex(mesh_->point(fv_it));
++fv_it;
glVertex(mesh_->point(fv_it));
}
glEnd();
}
}
//----------------------------------------------------------------------------
template<class Mesh>
void
SoOpenMeshNodeT<Mesh>::
drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type<false>)
{
typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()),
f_end(mesh_->faces_end());
typename Mesh::ConstFaceVertexIter fv_it;
if (_send_normals)
{
for (; f_it!=f_end; ++f_it)
{
glBegin(GL_POLYGON);
glNormal(mesh_->normal(f_it));
for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it)
glVertex(mesh_->point(fv_it));
glEnd();
}
}
else
{
for (; f_it!=f_end; ++f_it)
{
glBegin(GL_POLYGON);
for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it)
glVertex(mesh_->point(fv_it));
glEnd();
}
}
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
SoOpenMeshNodeT<Mesh>::generatePrimitives(SoAction* _action)
{
if (mesh_)
genPrimitives(_action);
}
//----------------------------------------------------------------------------
template<class Mesh>
void
SoOpenMeshNodeT<Mesh>::
genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type<true>)
{
typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()),
f_end(mesh_->faces_end());
typename Mesh::ConstFaceVertexIter fv_it;
SoPrimitiveVertex pv;
beginShape(_action, TRIANGLES);
for (; f_it!=f_end; ++f_it)
{
pv.setNormal(sbvec3f(mesh_->normal(f_it)));
fv_it = mesh_->cfv_iter(f_it.handle());
pv.setPoint(sbvec3f(mesh_->point(fv_it)));
shapeVertex(&pv);
++fv_it;
pv.setPoint(sbvec3f(mesh_->point(fv_it)));
shapeVertex(&pv);
++fv_it;
pv.setPoint(sbvec3f(mesh_->point(fv_it)));
shapeVertex(&pv);
}
endShape();
}
//----------------------------------------------------------------------------
template<class Mesh>
void
SoOpenMeshNodeT<Mesh>::
genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type<false>)
{
typename Mesh::ConstFaceIter f_it(mesh_->faces_begin()),
f_end(mesh_->faces_end());
typename Mesh::ConstFaceVertexIter fv_it;
SoPrimitiveVertex pv;
for (; f_it!=f_end; ++f_it)
{
beginShape(_action, POLYGON);
pv.setNormal(sbvec3f(mesh_->normal(f_it)));
for (fv_it=mesh_->cfv_iter(f_it.handle()); fv_it; ++fv_it)
{
pv.setPoint(sbvec3f(mesh_->point(fv_it)));
shapeVertex(&pv);
}
endShape();
}
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
SoOpenMeshNodeT<Mesh>::computeBBox(SoAction *action,
SbBox3f &box,
SbVec3f &center)
{
if (mesh_ && mesh_->n_vertices())
{
typename Mesh::ConstVertexIter vIt(mesh_->vertices_begin());
typename Mesh::ConstVertexIter vEnd(mesh_->vertices_end());
typename Mesh::Point min(mesh_->point(vIt));
typename Mesh::Point max(mesh_->point(vIt));
for (++vIt; vIt != vEnd; ++vIt)
{
max.maximize(mesh_->point(vIt));
min.minimize(mesh_->point(vIt));
}
box.setBounds(SbVec3f(min[0],min[1],min[2]),
SbVec3f(max[0],max[1],max[2]));
}
else box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
}
//-----------------------------------------------------------------------------
#if 0
/* As we are using templates, we cannot use the predefined macro
SO_NODE_SOURCE to automatically generate the following piece of
code. Ugly, but necessary.
*/
template <class Mesh>
SoType SoOpenMeshNodeT<Mesh>::classTypeId;
template <class Mesh>
SoFieldData *SoOpenMeshNodeT<Mesh>::fieldData;
template <class Mesh>
const SoFieldData **SoOpenMeshNodeT<Mesh>::parentFieldData;
template <class Mesh>
SbBool SoOpenMeshNodeT<Mesh>::firstInstance = TRUE;
template <class Mesh>
SoType SoOpenMeshNodeT<Mesh>::getTypeId() const {
return classTypeId;
}
template <class Mesh>
const SoFieldData*
SoOpenMeshNodeT<Mesh>::getFieldData() const {
SO__NODE_CHECK_CONSTRUCT("SoOpenMeshNodeT");
return fieldData;
}
template <class Mesh>
void* SoOpenMeshNodeT<Mesh>::createInstance() {
return (void *)(new SoOpenMeshNodeT<Mesh>);
}
#else
SO_NODE_SOURCE(SoOpenMeshNodeT<Mesh>);
#endif
//=============================================================================
} // namespace OpenMesh
//=============================================================================

View File

@@ -0,0 +1,117 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
//=============================================================================
//
// Class SoOpenMeshNode
//
// This class defines an basic inventor node to display an OpenMesh
//
//=============================================================================
#ifndef OPENMESH_SOOPENMESHNODE_HH
#define OPENMESH_SOOPENMESHNODE_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <Inventor/nodes/SoNode.h>
#include <Inventor/nodes/SoShape.h>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
template <class Mesh>
class SoOpenMeshNodeT : public SoShape
{
SO_NODE_HEADER(SoOpenMeshNodeT<Mesh>);
public:
static void initClass();
SoOpenMeshNodeT(const Mesh* _mesh=0);
void setMesh(const Mesh* mesh) { d_mesh = mesh; }
protected:
virtual void GLRender(SoGLRenderAction *action);
virtual void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center);
virtual void generatePrimitives(SoAction *action);
private:
virtual ~SoOpenMeshNodeT() {};
// Draw faces as triangles / polygons
void drawFaces(bool _send_normals) {
typedef typename Mesh::Face Face;
drawFaces(_send_normals, typename Face::IsTriangle());
}
void drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type<true>);
void drawFaces(bool _send_normals, OpenMesh::GenProg::Bool2Type<false>);
// Generate primitives
void genPrimitives(SoAction* _action) {
typedef typename Mesh::Face Face;
genPrimitives(_action, typename Face::IsTriangle());
}
void genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type<true>);
void genPrimitives(SoAction* _action, OpenMesh::GenProg::Bool2Type<false>);
const Mesh* mesh_;
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_SOOPENMESHNODE_CC)
# define OPENMESH_SOOPENMESHMODE_TEMPLATES
# include "SoOpenMeshNodeT.cc"
#endif
//=============================================================================
#endif // OPENMESH_SOOPENMESHNODE_HH
//=============================================================================

View File

@@ -0,0 +1,111 @@
#ifndef SOOPENMESHSUPPORT_H
#define SOOPENMESHSUPPORT_H
//== REDEFINE DEFINES SO THEY WORK WITH TEMPLATES ============================
#define SO_NODE_SOURCE_TEMPLATE template <class Mesh>
// ----------------------------------------------------------------- COIN ----
//
// define __COIN__ is set by coin headers
#ifdef __COIN__
#ifdef PRIVATE_NODE_TYPESYSTEM_SOURCE
# undef PRIVATE_NODE_TYPESYSTEM_SOURCE
#endif
#define PRIVATE_NODE_TYPESYSTEM_SOURCE(_class_) \
SO_NODE_SOURCE_TEMPLATE \
SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \
SO_NODE_SOURCE_TEMPLATE \
SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \
/* Don't set value explicitly to SoType::badType(), to avoid a bug in */ \
/* Sun CC v4.0. (Bitpattern 0x0000 equals SoType::badType()). */ \
SO_NODE_SOURCE_TEMPLATE \
SoType _class_::classTypeId
// FIXME: document. 20000103 mortene.
#ifdef SO_NODE_ABSTRACT_SOURCE
# undef SO_NODE_ABSTRACT_SOURCE
#endif
#define SO_NODE_ABSTRACT_SOURCE(_class_) \
PRIVATE_NODE_TYPESYSTEM_SOURCE(_class_); \
\
SO_NODE_SOURCE_TEMPLATE \
unsigned int _class_::classinstances = 0; \
SO_NODE_SOURCE_TEMPLATE \
const SoFieldData ** _class_::parentFieldData = NULL; \
SO_NODE_SOURCE_TEMPLATE \
SoFieldData * _class_::fieldData = NULL; \
\
SO_NODE_SOURCE_TEMPLATE \
const SoFieldData ** \
_class_::getFieldDataPtr(void) \
{ \
return (const SoFieldData **)(&_class_::fieldData); \
} \
\
SO_NODE_SOURCE_TEMPLATE \
const SoFieldData * \
_class_::getFieldData(void) const \
{ \
return _class_::fieldData; \
}
// FIXME: document. 20000103 mortene.
#ifdef SO_NODE_SOURCE
# undef SO_NODE_SOURCE
#endif
#define SO_NODE_SOURCE(_class_) \
SO_NODE_ABSTRACT_SOURCE(_class_); \
\
SO_NODE_SOURCE_TEMPLATE \
void * \
_class_::createInstance(void) \
{ \
return new _class_; \
}
// ------------------------------------------------------------------ SGI ----
#else
#ifdef SO_NODE_SOURCE
# undef SO_NODE_SOURCE
#endif
#define SO_NODE_SOURCE(_class_) \
SO_NODE_SOURCE_TEMPLATE \
SoType _class_::classTypeId; \
\
SO_NODE_SOURCE_TEMPLATE \
SoFieldData *_class_::fieldData; \
\
SO_NODE_SOURCE_TEMPLATE \
const SoFieldData **_class_::parentFieldData; \
\
SO_NODE_SOURCE_TEMPLATE \
SbBool _class_::firstInstance = TRUE; \
\
SO_NODE_SOURCE_TEMPLATE \
SoType _class_::getTypeId() const { \
return classTypeId; \
} \
\
SO_NODE_SOURCE_TEMPLATE \
const SoFieldData* \
_class_::getFieldData() const { \
SO__NODE_CHECK_CONSTRUCT("SoOpenMeshNodeT"); \
return fieldData; \
} \
\
SO_NODE_SOURCE_TEMPLATE \
void* _class_::createInstance() { \
return (void *)(new _class_); \
} \
#endif
#endif

View File

@@ -0,0 +1,140 @@
//=============================================================================
//
// 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: 4483 $
// $Date: 2009-01-28 11:41:31 +0100 (Mi, 28. Jan 2009) $
//
//=============================================================================
//
#if !defined(USE_SOQT)
# define USE_SOQT 0
#endif
//== INCLUDES =================================================================
#include <cstdlib>
//
// Attention! must include this before including inventor files!
// There some dependencies not solved yet!
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
//
#include <Inventor/SoDB.h>
#if USE_SOQT
# include <qapplication.h>
# include <Inventor/Qt/SoQt.h>
# include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#else
# include <Inventor/Xt/SoXt.h>
# include <Inventor/Xt/viewers/SoXtExaminerViewer.h>
#endif
#include <Inventor/nodes/SoSeparator.h>
//
#include <OpenMesh/Apps/IvViewer/SoOpenMeshNodeT.hh>
//== CLASS DEFINITION =========================================================
struct MyTraits : public OpenMesh::DefaultTraits
{
VertexAttributes(OpenMesh::Attributes::Normal);
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
FaceAttributes(OpenMesh::Attributes::Normal);
};
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
typedef OpenMesh::SoOpenMeshNodeT<MyMesh> MyNode;
//== IMPLEMENTATION ===========================================================
int main(int argc, char **argv)
{
OpenMesh::IO::Options opt;
#if USE_SOQT
QApplication app(argc,argv);
SoQt::init( argv[0] );
MyNode::initClass();
SoQtExaminerViewer *myViewer = new SoQtExaminerViewer();
// Read a mesh
MyMesh mesh;
if (argc > 1 && OpenMesh::IO::read_mesh(mesh, argv[1], opt))
{
if (!opt.check( OpenMesh::IO::Options::FaceNormal))
mesh.update_face_normals();
SoSeparator* root = new SoSeparator();
root->addChild(new MyNode(&mesh));
myViewer->setSceneGraph(root);
}
QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
myViewer->show();
SoQt::mainLoop();
#else
// Inventor stuff
Widget myWindow = SoXt::init(argv[0]);
MyNode::initClass();
SoXtExaminerViewer *myViewer =
new SoXtExaminerViewer(myWindow);
// Read a mesh
MyMesh mesh;
if (argc > 1 && OpenMesh::IO::read_mesh(mesh, argv[1], opt))
{
if (!opt.check( OpenMesh::IO::Options::FaceNormal))
mesh.update_face_normals();
SoSeparator* root = new SoSeparator();
root->addChild(new MyNode(&mesh));
myViewer->setSceneGraph(root);
}
myViewer->show();
SoXt::show(myWindow);
SoXt::mainLoop();
#endif
}
//=============================================================================

View File

@@ -0,0 +1,21 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
#CXX_SRC_EXT := .cc
#CXX_HDR_EXT := .h
CXX_CFLAGS += -DOM_USE_OSG=1
SUBDIRS =
PACKAGES := osg qt glut opengl x11 math
PROJ_LIBS = OpenMesh/Apps/QtViewer OpenMesh/Tools OpenMesh/Core
MODULES := moc cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,11 @@
Usage:
1. osgviewer <model>
Load a model via I/O routines of OpenMesh and save as a OpenSG
binary file in file opensg.bin.
2. osgviewer
Load model previously stored in opensg.bin via OpenSG BINLoader.

View File

@@ -0,0 +1,134 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311)
#endif
#include <iostream>
#include <fstream>
#include <getopt.h>
#include <qapplication.h>
#include <qmessagebox.h>
#include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
#include <OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh>
struct MyTraits : public OpenMesh::Kernel_OSG::Traits
{
VertexAttributes(OpenMesh::Attributes::Normal |
OpenMesh::Attributes::TexCoord );
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
FaceAttributes(OpenMesh::Attributes::Normal);
};
typedef OpenMesh::Kernel_OSG::TriMesh_OSGArrayKernelT<MyTraits> MyMesh;
typedef MeshViewerWidgetT<MyMesh> MeshViewerWidget;
void usage_and_exit(int xcode);
int main(int argc, char **argv)
{
osg::osgInit(argc, argv);
// OpenGL check
QApplication::setColorSpec( QApplication::CustomColor );
QApplication app(argc,argv);
if ( !QGLFormat::hasOpenGL() ) {
QString msg = "System has no OpenGL support!";
QMessageBox::critical( NULL, "OpenGL", msg + argv[1], 0 );
return -1;
}
int c;
OpenMesh::IO::Options opt;
while ( (c=getopt(argc,argv,"s"))!=-1 )
{
switch(c)
{
case 's': opt += OpenMesh::IO::Options::Swap; break;
case 'h':
usage_and_exit(0);
default:
usage_and_exit(1);
}
}
// create widget
MeshViewerWidget* w = new MeshViewerWidget(0, "Viewer");
app.setMainWidget(w);
// static mesh, hence use strips
w->enable_strips();
w->resize(400, 400);
w->show();
// load scene
if ( optind < argc )
{
if ( ! w->open_mesh(argv[optind], opt) )
{
QString msg = "Cannot read mesh from file:\n '";
msg += argv[optind];
msg += "'";
QMessageBox::critical( NULL, w->caption(), msg, 0 );
return 1;
}
}
if ( ++optind < argc )
{
if ( ! w->open_texture( argv[optind] ) )
{
QString msg = "Cannot load texture image from file:\n '";
msg += argv[optind];
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, w->caption(), msg, 0 );
}
}
return app.exec();
}
void usage_and_exit(int xcode)
{
std::cout << "Usage: meshviewer [-s] [mesh] [texture]\n" << std::endl;
std::cout << "Options:\n"
<< " -s\n"
<< " Reverse byte order, when reading binary files.\n"
<< std::endl;
exit(xcode);
}

View File

@@ -0,0 +1,481 @@
// -------------------- STL
#include <memory>
#include <iostream>
#include <iomanip>
#include <stdexcept>
// -------------------- OpenSG
#include <GL/glut.h>
#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGGLUTWindow.h>
#include <OpenSG/OSGSimpleSceneManager.h>
#include <OpenSG/OSGSceneFileHandler.h>
#include <OpenSG/OSGTriangleIterator.h>
#include <OpenSG/OSGFaceIterator.h>
// -------------------- OpenMesh
#include <OpenMesh/Core/IO/MeshIO.hh> // always before kernel type
#include <OpenMesh/Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh>
#include <OpenMesh/Tools/Kernel_OSG/bindT.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/Subdivider/Uniform/LoopT.hh>
// --------------------
#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>
// ----------------------------------------------------------- namespace -----
OSG_USING_NAMESPACE
// ------------------------------------------------------------- OpenMesh ----
struct MeshTraits : public OpenMesh::Kernel_OSG::Traits
{
HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge);
VertexAttributes ( OpenMesh::Attributes::Normal |
OpenMesh::Attributes::Color );
FaceAttributes ( OpenMesh::Attributes::Normal );
};
typedef OpenMesh::Kernel_OSG::TriMesh_OSGArrayKernelT<MeshTraits> mesh_t;
typedef OpenMesh::Subdivider::Uniform::LoopT< mesh_t > loop_t;
typedef OpenMesh::Smoother::JacobiLaplaceSmootherT< mesh_t > smoother_t;
// --------------------------------------------------------------- globals ----
class MeshContainer
{
public:
typedef std::vector<mesh_t*> meshbag_t;
const size_t InvalidIndex;
public:
MeshContainer() : InvalidIndex(size_t(-1))
{ }
~MeshContainer()
{
meshbag_t::iterator it = meshes_.begin();
for(;it != meshes_.end(); ++it)
delete *it;
}
size_t size() const { return meshes_.size(); }
mesh_t& operator [] ( size_t idx )
{
if (idx < meshes_.size())
return *(meshes_[idx]);
throw std::range_error("Invalid index");
}
const mesh_t& operator [] ( size_t idx ) const
{
if (idx < meshes_.size())
return *(meshes_[idx]);
throw std::range_error("Invalid index");
}
bool bind( osg::GeometryPtr geo )
{
std::auto_ptr<mesh_t> obj(new mesh_t);
return (OpenMesh::Kernel_OSG::bind< mesh_t >( *obj, geo))
? (meshes_.push_back(obj.release()), true)
: false;
}
private:
meshbag_t meshes_;
private: // non-copyable
MeshContainer( const MeshContainer& );
MeshContainer& operator = ( const MeshContainer& );
};
struct Globals
{
// OpenSG specific entities
SimpleSceneManager* mgr;
GLUTWindowPtr gwin;
NodePtr root;
std::vector<GeometryPtr> geos;
size_t sel;
bool statistics;
// OpenMesh specific entities
MeshContainer meshes;
} g;
// -------------------------------------------------------------- forwards ----
void display(void);
void reshape(int width, int height);
void mouse(int button, int state, int x, int y);
void keyboard(unsigned char key, int x, int y);
void motion(int x, int y);
// ---------------------------------------------------------------- helper ----
// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("OpenMesh within OpenSG");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
return winid;
}
// -------------------------------------------------- locate geometry node ----
/*
This function uses the fact that ::dcast() acts like dynamic_cast. It tries
to dcast the core to a GeometryPtr, and tests the result to see if it
actually was derived from Geometry.
*/
Action::ResultE bindGeo(NodePtr& node)
{
GeometryPtr geo = GeometryPtr::dcast(node->getCore());
if (geo!=NullFC)
{
if ( g.meshes.bind( geo ) )
{
std::cout << " Geometry connected to OpenMesh object\n";
g.geos.push_back(geo);
g.sel = g.meshes.size()-1;
assert( g.geos.size() == g.meshes.size() );
}
else
std::cerr << " Warning! Could not bind the OpenMesh"
<< " object to the geometry!\n";
}
return Action::Continue;
}
// ------------------------------------------------------------------ main ----
int main(int argc, char **argv)
{
// OSG init
osgInit(argc,argv);
int winid = setupGLUT(&argc, argv);
// the connection between GLUT and OpenSG
g.gwin = GLUTWindow::create();
g.gwin->setId(winid);
g.gwin->init();
// -------------------- create root node with core
std::cout << "Create root node with core\n";
g.root = Node::create();
NodeCorePtr core = Group::create();
osg::beginEditCP(g.root);
{
g.root->setCore(core);
}
osg::endEditCP(g.root);
// -------------------- load the scene
std::cout << "Load a scene from '" << argv[1] << "'\n";
NodePtr node = SceneFileHandler::the().read( argv[1] );
if ( node != NullFC )
{
osg::beginEditCP(g.root);
{
g.root->addChild(node);
}
osg::endEditCP(g.root);
}
else
return 1;
// -------------------- bind all geometry nodes to an OpenMesh
std::cout << "Bind all geometry nodes\n";
traverse(g.root,
osgTypedFunctionFunctor1CPtrRef<Action::ResultE,NodePtr>(bindGeo));
if (!g.meshes.size())
{
std::cerr << " No geometry found. Nothing to do!\n";
return 1;
}
else
std::cout << " Number of bound geometry: " << g.meshes.size() << std::endl;
// -------------------- create the SimpleSceneManager helper
std::cout << "Create simple scene manager\n";
g.mgr = new SimpleSceneManager;
// tell the manager what to manage
g.mgr->setWindow(g.gwin);
g.mgr->setRoot (g.root);
//
g.mgr->useOpenSGLogo();
g.mgr->setStatistics(false);
// -------------------- show the whole scene
std::cout << "Display everything\n";
g.mgr->showAll();
glutMainLoop();
return 0;
}
// --------------------------------------------------------------- display ----
void display(void)
{
g.mgr->redraw();
}
// --------------------------------------------------------------- reshape ----
void reshape(int w, int h)
{
g.mgr->resize(w, h);
glutPostRedisplay();
}
// ----------------------------------------------------------------- mouse ----
void mouse(int button, int state, int x, int y)
{
if (state)
{
g.mgr->mouseButtonRelease(button, x, y);
// if ( g.mode & FLYMODE )
// glutIdleFunc(NULL);
}
else
{
g.mgr->mouseButtonPress(button, x, y);
// if ( g.mode & FLYMODE )
// glutIdleFunc(idle);
}
glutPostRedisplay();
}
// -------------------------------------------------------------- keyboard ----
void keyboard(unsigned char key, int x, int y)
{
#define MESH g.meshes[g.sel]
#define GEO g.geos[g.sel]
#define YN(b) (b?"yes":"no")
OpenMesh::Utils::Timer t;
using namespace std;
switch(key)
{
case 27: // escape
exit(0);
break;
case 'i':
{
cout << "OpenMesh information for obj #" << g.sel << ":\n";
cout << " #Vertices: " << MESH.n_vertices() << endl;
cout << " #Faces: " << MESH.n_faces() << endl;
cout << " #Edges: " << MESH.n_edges() << endl;
cout << " v. normal: " << YN(MESH.has_vertex_normals()) << endl;
cout << " v. color: " << YN(MESH.has_vertex_colors()) << endl;
cout << "v. texcoord: " << YN(MESH.has_vertex_texcoords()) << endl;
cout << " f. normal: " << YN(MESH.has_face_normals()) << endl;
cout << " f. color: " << YN(MESH.has_face_colors()) << endl;
break;
}
case 'I':
cout << "Geometry information for obj #" << g.sel << ":\n";
cout << " #Types: " << GEO->getTypes()->size() << endl;
cout << " #Lengths: " << GEO->getLengths()->size() << endl;
cout << " #Indices: " << GEO->getIndices()->size() << endl;
cout << "#Positions: " << GEO->getPositions()->size() << endl;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if ((size_t(key)-size_t('0')) < g.meshes.size())
{
g.sel = (size_t(key)-size_t('0'));
cout << "Selected geometry #" << g.sel << endl;
}
break;
case '+':
g.sel = ++g.sel % g.meshes.size();
cout << "Selected geometry #" << g.sel << endl;
break;
case '-':
g.sel = (g.sel + g.meshes.size()-1) % g.meshes.size();
cout << "Selected geometry #" << g.sel << endl;
break;
case 'S':
g.mgr->setStatistics( g.statistics=!g.statistics );
g.statistics
? cout << "Statistics enabled.\n"
: cout << "Statistics disabled.\n";
glutPostRedisplay();
break;
case 'w':
{
OpenMesh::IO::Options opt;
if (MESH.has_vertex_colors())
opt += OpenMesh::IO::Options::VertexColor;
if (MESH.has_face_colors())
opt += OpenMesh::IO::Options::FaceColor;
if (MESH.has_vertex_normals())
opt += OpenMesh::IO::Options::VertexNormal;
std::string ofname;
{
std::stringstream ostr;
ostr << "object-" << g.sel << ".om";
ofname = ostr.str();
}
cout << "Writing OpenMesh of geometry #" << g.sel
<< " to " << ofname << std::endl;
t.start();
bool rc = OpenMesh::IO::write_mesh( MESH, ofname, opt);
t.stop();
rc
? cout << " Done (" << t.as_string() << ")\n"
: cout << " Failed to store OpenMesh\n";
break;
}
case 's':
{
cout << "Appyling two smoothing steps on selected geometry..";
t.start();
smoother_t smoother( g.meshes[g.sel] );
smoother.initialize( smoother_t::Tangential, smoother_t::C1 );
beginEditCP(g.geos[g.sel]);
smoother.smooth(2);
endEditCP(g.geos[g.sel]);
t.stop();
cout << "done. " << t.as_string() << endl;
glutPostRedisplay();
break;
}
case 't':
{
cout << "Applying two smoothing steps on all bound geometry..";
t.start();
for(size_t i = 0; i < g.meshes.size(); ++i)
{
smoother_t smoother( g.meshes[i] );
smoother.initialize( smoother_t::Tangential, smoother_t::C1 );
beginEditCP(g.geos[i]);
smoother.smooth(2);
endEditCP(g.geos[i]);
}
t.stop();
cout << "done. " << t.as_string() << endl;
glutPostRedisplay();
break;
}
case 'c':
{
OpenMesh::IO::Options opt;
if (MESH.has_vertex_colors())
opt += OpenMesh::IO::Options::VertexColor;
if (MESH.has_face_colors())
opt += OpenMesh::IO::Options::FaceColor;
if (MESH.has_vertex_normals())
opt += OpenMesh::IO::Options::VertexNormal;
mesh_t m(MESH);
std::string ofname;
{
std::stringstream ostr;
ostr << "copy-" << g.sel << ".om";
ofname = ostr.str();
}
cout << "Writing copy of geometry #" << g.sel
<< " to " << ofname << std::endl;
t.start();
bool rc = OpenMesh::IO::write_mesh( MESH, ofname, opt);
t.stop();
rc
? cout << " Done (" << t.as_string() << ")\n"
: cout << " Failed to store OpenMesh\n";
OpenMesh::IO::write_mesh( m, ofname );
break;
}
case 'u':
{
cout << "Applying one step of loop subdivision..";
t.start();
loop_t loop;
beginEditCP( GEO );
loop( MESH, 1 );
MESH.update_normals();
endEditCP( GEO );
t.stop();
cout << "done. " << t.as_string() << endl;
glutPostRedisplay();
break;
}
default:
cout << "key [0x" << setw(4) << hex << key << dec << "]\n";
}
#undef YN
#undef MESH
}
//----------------------------------------------------------------- motion ----
void motion(int x, int y)
{
g.mgr->mouseMove(x, y);
glutPostRedisplay();
}

View File

@@ -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
#==============================================================================

View File

@@ -0,0 +1,274 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="OpenMesh_Apps_ProgViewer"
ProjectGUID="{6CC92D44-A0AC-47D0-9482-D983B1F27E63}"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="c:\glut\include;C:\glew\include;..\..\..;&quot;$(QTDIR)/include&quot;;&quot;$(QTDIR)/include/QtCore&quot;;&quot;$(QTDIR)/inlcude/Qt&quot;;&quot;$(QTDIR)/include/QtGUI&quot;;&quot;$(QTDIR)/include/QtOpenGL&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_USE_MATH_DEFINES;QT_DLL"
MinimalRebuild="false"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="false"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
ProgramDataBaseFileName="$(IntDir)/vc70.pdb"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="QtCore4.lib QtGUI4.lib QtOpenGL4.lib opengl32.lib"
OutputFile="..\..\bin\progviewer_dbg.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="$(QTDIR)/lib;C:\glut\lib;C:\glew\lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\$(TargetName).pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="c:\glut\include;C:\glew\include;..\..\..;&quot;$(QTDIR)/include&quot;;&quot;$(QTDIR)/include/QtCore&quot;;&quot;$(QTDIR)/inlcude/Qt&quot;;&quot;$(QTDIR)/include/QtGUI&quot;;&quot;$(QTDIR)/include/QtOpenGL&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_USE_MATH_DEFINES;QT_DLL"
RuntimeLibrary="2"
DisableLanguageExtensions="false"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="QtCore4.lib QtGUI4.lib QtOpenGL4.lib opengl32.lib"
OutputFile="..\..\bin\progviewer.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="$(QTDIR)/lib;C:\glut\lib;C:\glew\lib"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Generated Files"
>
<File
RelativePath=".\moc_ProgViewerWidget.cpp"
>
</File>
<File
RelativePath=".\moc_QGLViewerWidget.cpp"
>
</File>
</Filter>
<File
RelativePath="..\QtViewer\MeshViewerWidgetT.cc"
>
</File>
<File
RelativePath="..\QtViewer\QGLViewerWidget.cc"
>
</File>
<File
RelativePath="..\QtViewer\MeshViewerWidgetT.hh"
>
</File>
<File
RelativePath=".\progviewer.cc"
>
</File>
<File
RelativePath=".\ProgViewerWidget.cc"
>
</File>
<File
RelativePath=".\ProgViewerWidget.hh"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC $(InputFileName)"
CommandLine="$(QTDIR)\bin\moc.exe $(InputFileName) -o moc_$(InputName).cpp&#x0D;&#x0A;"
Outputs="moc_$(InputName).cpp"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC $(InputFileName)"
CommandLine="$(QTDIR)\bin\moc.exe $(InputFileName) -o moc_$(InputName).cpp&#x0D;&#x0A;"
Outputs="moc_$(InputName).cpp"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\QtViewer\QGLViewerWidget.hh"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC $(InputFileName)"
CommandLine="$(QTDIR)\bin\moc.exe ..\QtViewer\$(InputFileName) -o moc_$(InputName).cpp&#x0D;&#x0A;"
Outputs="moc_$(InputName).cpp"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC $(InputFileName)"
CommandLine="$(QTDIR)\bin\moc.exe ..\QtViewer\$(InputFileName) -o moc_$(InputName).cpp&#x0D;&#x0A;"
Outputs="moc_$(InputName).cpp"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\test1.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,321 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
//== INCLUDES =================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311)
#endif
#include <iostream>
#include <fstream>
// --------------------
#include <QApplication>
#include <QFileInfo>
#include <QKeyEvent>
// --------------------
#include <OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh>
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
// --------------------
#ifdef ARCH_DARWIN
# include <gl.h>
#else
# include <GL/gl.h>
#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<size_t>::restore( ifs, n_base_vertices_, swap );
OpenMesh::IO::binary<size_t>::restore( ifs, n_base_faces_, swap );
OpenMesh::IO::binary<size_t>::restore( ifs, n_detail_vertices_, swap );
n_max_vertices_ = n_base_vertices_ + n_detail_vertices_;
// load base mesh
mesh_.clear();
for (i=0; i<n_base_vertices_; ++i)
{
OpenMesh::IO::binary<MyMesh::Point>::restore( ifs, p, swap );
mesh_.add_vertex(p);
}
for (i=0; i<n_base_faces_; ++i)
{
OpenMesh::IO::binary<unsigned int>::restore( ifs, i0, swap);
OpenMesh::IO::binary<unsigned int>::restore( ifs, i1, swap);
OpenMesh::IO::binary<unsigned int>::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<n_detail_vertices_; ++i)
{
OpenMesh::IO::binary<MyMesh::Point>::restore( ifs, p, swap );
OpenMesh::IO::binary<unsigned int>::restore( ifs, v1, swap );
OpenMesh::IO::binary<unsigned int>::restore( ifs, vl, swap );
OpenMesh::IO::binary<unsigned int>::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; i<n_loop; ++i)
{
coarsen(0);
refine(100000);
}
t.stop();
std::cout << "# collapses/splits: " << 2*(n_loop+1)*count << " in "
<< t.as_string() << std::endl;
std::cout << "# collapses or splits per seconds: "
<< 2*(n_loop+1)*count/t.seconds() << "\n";
coarsen(0);
updateGL();
break;
}
case Key_S:
if (OpenMesh::IO::write_mesh( mesh_, "result.off" ))
std::clog << "Current mesh stored in 'result.off'\n";
break;
default:
this->Base::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);
}
//=============================================================================

View File

@@ -0,0 +1,137 @@
//=============================================================================
//
// 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_PROGVIEWERWIDGET_HH
#define OPENMESHAPPS_PROGVIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <QTimer>
#include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/Mesh/Attributes.hh>
#include <string>
//== 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<MyTraits> MyMesh;
typedef MeshViewerWidgetT<MyMesh> 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<PMInfo> 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
//=============================================================================

View File

@@ -0,0 +1,78 @@
//=============================================================================
//
// 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: 2096 $
// $Date: 2008-06-26 13:16:48 +0200 (Do, 26. Jun 2008) $
//
//=============================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311)
#endif
#include <iostream>
#include <fstream>
#include <OpenMesh/Apps/ProgViewer/ProgViewerWidget.hh>
#include <QString>
#include <QApplication>
#include <QGLWidget>
#include <GL/glut.h>
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();
}

View File

@@ -0,0 +1,16 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
SUBDIRS = $(call find-subdirs)
PACKAGES :=
PROJ_LIBS :=
MODULES :=
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,19 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
CXX_CFLAGS += -DQT_THREAD_SUPPORT
SUBDIRS = $(call find-subdirs)
PACKAGES := qt4 glut opengl
PROJ_LIBS := OpenMesh/Apps/QtViewer \
OpenMesh/Core OpenMesh/Tools
MODULES := moc4 cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,603 @@
//=============================================================================
//
// 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 (Mon, 19 May 2008) $
//
//=============================================================================
#define OPENMESHAPPS_MESHVIEWERWIDGET_CC
//== INCLUDES =================================================================
#ifdef _MSC_VER
//# pragma warning(disable: 4267 4311)
#endif
//
#include <iostream>
#include <fstream>
#include <QImage>
#include <QKeyEvent>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh>
using namespace OpenMesh;
//== 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_texcoords2D();
if ( IO::read_mesh(mesh_, _filename, _opt ))
{
opt_ = _opt;
// update face and vertex normals
if ( ! opt_.check( IO::Options::FaceNormal ) )
mesh_.update_face_normals();
if ( ! opt_.check( IO::Options::VertexNormal ) )
mesh_.update_vertex_normals();
if ( mesh_.has_vertex_colors() )
add_draw_mode("Colored");
if ( _opt.check( IO::Options::FaceColor ) )
add_draw_mode("Colored Faces");
else
mesh_.release_face_colors();
// 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)));
if ( ! opt_.check( IO::Options::VertexColor ) &&
mesh_.has_vertex_colors() )
{
typename Mesh::Color
c( 54,
(unsigned char)(54.5+200.0*count/mesh_.n_vertices()),
54 );
mesh_.set_color( vIt, c );
}
}
// set center and radius
set_scene_pos( (bbMin+bbMax)*0.5, (bbMin-bbMax).norm()*0.5 );
// info
std::clog << mesh_.n_vertices() << " vertices, "
<< mesh_.n_edges() << " edge, "
<< mesh_.n_faces() << " faces\n";
//
{
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(OM_CC_MSVC)
updateGL();
#endif
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 )
{
std::clog << "set_texture\n";
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
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") // ----------------------------------------
{
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 == "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 == "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());
glDrawArrays( GL_POINTS, 0, mesh_.n_vertices() );
glDisableClientState(GL_VERTEX_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" )
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDepthRange(0.01, 1.0);
draw_openmesh("Solid Smooth");
glDisable(GL_LIGHTING);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
glColor4f( 0.4f, 0.4f, 0.4f, 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" )
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Colored Faces" )
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
}
//-----------------------------------------------------------------------------
#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 Qt::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;
this->QGLViewerWidget::keyPressEvent( _event );
break;
case Qt::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,163 @@
//=============================================================================
//
// 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 (Mon, 19 May 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/Mesh/Attributes.hh>
#include <OpenMesh/Tools/Utils/StripifierT.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/QGLViewerWidget.hh>
//== FORWARDS =================================================================
class QImage;
//== CLASS DEFINITION =========================================================
template <typename M>
class MeshViewerWidgetT : public QGLViewerWidget
{
public:
typedef M Mesh;
typedef OpenMesh::StripifierT<Mesh> MyStripifier;
/// default constructor
MeshViewerWidgetT(QWidget* _parent=0, const char* _name=0)
: QGLViewerWidget(_parent, _name),
f_strips_(false),
tex_id_(0),
tex_mode_(GL_MODULATE),
strips_(mesh_)
{
add_draw_mode("Points");
add_draw_mode("Hidden-Line");
#if defined(OM_USE_OSG) && OM_USE_OSG
add_draw_mode("OpenSG Indices");
#endif
}
void enable_strips() {
f_strips_ = true;
add_draw_mode("Strips'n VertexArrays");
add_draw_mode("Show Strips");
}
void disable_strips() { f_strips_ = false; }
/// destructor
~MeshViewerWidgetT() {}
/// 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 );
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 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] ); }
void glColor( const typename Mesh::FaceHandle fh )
{ glColor3ubv( &mesh_.color(fh)[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_;
};
//=============================================================================
#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,23 @@
#ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH
#define OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH
#include <qthread.h>
#include <qmutex.h>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Tools/VDPM/MeshTraits.hh>
using OpenMesh::VDPM::MeshTraits;
//== CLASS DEFINITION =========================================================
typedef OpenMesh::TriMesh_ArrayKernelT<MeshTraits> MyMesh;
static QMutex mutex_;
//== CLASS DEFINITION =========================================================
#endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH defined

View File

@@ -0,0 +1,621 @@
//=============================================================================
//
// 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 (Mon, 19 May 2008) $
//
//=============================================================================
//== INCLUDES =================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311 4305)
#endif
#include <iomanip>
#include <GL/glut.h>
// #include <qnamespace.h>
#include <QApplication>
#include <QMenu>
#include <QCursor>
#include <QMouseEvent>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/QGLViewerWidget.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#if !defined(M_PI)
# define M_PI 3.1415926535897931
#endif
using namespace OpenMesh;
//== IMPLEMENTATION ==========================================================
QGLViewerWidget::QGLViewerWidget( QWidget* _parent, const char* _name )
: QGLWidget( _parent )
{
// qt stuff
setWindowTitle(_name);
// setBackgroundMode( NoBackground );
setFocusPolicy(Qt::StrongFocus);
setAcceptDrops( true );
setCursor(Qt::PointingHandCursor);
// popup menu
popup_menu_ = new QMenu("Draw Mode Menu", this);
connect( popup_menu_, SIGNAL(activated(int)),
this, SLOT(slotPopupMenu(int)));
// init draw modes
n_draw_modes_ = 0;
add_draw_mode("Wireframe");
add_draw_mode("Solid Flat");
add_draw_mode("Solid Smooth");
// for example
add_draw_mode("Colored");
slotPopupMenu(2);
}
//----------------------------------------------------------------------------
QGLViewerWidget::~QGLViewerWidget()
{
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::initializeGL()
{
// OpenGL state
glClearColor(1.0, 1.0, 1.0, 0.0);
glDisable( GL_DITHER );
glEnable( GL_DEPTH_TEST );
glEnable( GL_CULL_FACE );
// material
GLfloat mat_a[] = {0.7, 0.6, 0.5, 1.0};
GLfloat mat_d[] = {0.8, 0.7, 0.6, 1.0};
GLfloat mat_s[] = {1.0, 1.0, 1.0, 1.0};
GLfloat shine[] = {120.0};
// GLfloat mat_a[] = {0.2, 0.2, 0.2, 1.0};
// GLfloat mat_d[] = {0.4, 0.4, 0.4, 1.0};
// GLfloat mat_s[] = {0.8, 0.8, 0.8, 1.0};
// GLfloat shine[] = {128.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);
// lighting
glLoadIdentity();
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[] = {.05, .05, .4, 1.0};
GLfloat col2[] = {.4, .05, .05, 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);
// Fog
GLfloat fogColor[4] = { 0.4, 0.4, 0.5, 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() == Qt::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();
if ( (newPoint2D.x()<0) || (newPoint2D.x()>width()) ||
(newPoint2D.y()<0) || (newPoint2D.y()>height()) ) return;
// 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->button() == Qt::LeftButton) && (_event->button() == Qt::MidButton))
{
value_y = radius_ * dy * 3.0 / h;
translate(Vec3f(0.0, 0.0, value_y));
}
// move in x,y direction
else if (_event->button() == Qt::MidButton)
{
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->button() == Qt::LeftButton)
{
if (last_point_ok_)
{
if ( (newPoint_hitSphere = map_to_sphere(newPoint2D, newPoint3D)) )
{
Vec3f axis = last_point_3D_ % newPoint3D;
float cos_angle = (last_point_3D_ | newPoint3D);
if ( fabs(cos_angle) < 1.0 )
{
float angle = 2.0 * acos( cos_angle ) * 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 Qt::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 Qt::Key_I:
std::cout << "Radius: " << radius_ << std::endl;
std::cout << "Center: " << center_ << std::endl;
break;
case Qt::Key_Space:
case Qt::Key_M:
{
double fps = performance();
std::cout << "fps: "
#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
<< std::setiosflags (std::ios::fixed)
#else
<< std::setiosflags (std::ios_base::fixed)
#endif
<< fps << std::endl;
}
break;
case Qt::Key_Q:
case Qt::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 )
{
if ( (_v2D.x() >= 0) && (_v2D.x() <= width()) &&
(_v2D.y() >= 0) && (_v2D.y() <= height()) )
{
double x = (double)(_v2D.x() - 0.5*width()) / (double)width();
double y = (double)(0.5*height() - _v2D.y()) / (double)height();
double sinx = sin(M_PI * x * 0.5);
double siny = sin(M_PI * y * 0.5);
double sinx2siny2 = sinx * sinx + siny * siny;
_v3D[0] = sinx;
_v3D[1] = siny;
_v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
return true;
}
else return false;
}
//----------------------------------------------------------------------------
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, _radius );
glFogf( GL_FOG_END, 4.0*_radius );
update_projection_matrix();
view_all();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::add_draw_mode(std::string _s)
{
++n_draw_modes_;
// insert in popup menu
QString str( _s.c_str() );
popup_menu_->addAction( str );
// store draw mode
draw_mode_names_.push_back(_s);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::slotPopupMenu(int _id)
{
// set check status
for (int i=0; i < popup_menu_->actions().count(); ++i)
popup_menu_->actions()[i]->setChecked( i == _id );
// save draw mode
draw_mode_ = _id;
}
//----------------------------------------------------------------------------
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(); }
for (i=0, axis=Vec3f(0,1,0); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
for (i=0, axis=Vec3f(0,0,1); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
glFinish();
timer.stop();
glPopMatrix();
updateGL();
fps = ( (3.0 * frames) / timer.seconds() );
setCursor( Qt::PointingHandCursor );
return fps;
}
//=============================================================================

View File

@@ -0,0 +1,164 @@
//=============================================================================
//
// 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 (Mon, 19 May 2008) $
//
//=============================================================================
#ifndef OPENMESHAPPS_QGLVIEWERWIDGET_HH
#define OPENMESHAPPS_QGLVIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <QGLWidget>
#include <QMenu>
#include <string>
#include <vector>
//== FORWARD DECLARATIONS =====================================================
class QPopupMenu;
//== CLASS DEFINITION =========================================================
class QGLViewerWidget : public QGLWidget
{
Q_OBJECT
public:
// Default constructor.
QGLViewerWidget( QWidget* _parent=0, const char* _name=0 );
// Destructor.
virtual ~QGLViewerWidget();
/* 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
void add_draw_mode(std::string _s);
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_; }
void set_modelview_matrix(const GLdouble _modelview_matrix[16])
{ memcpy(modelview_matrix_, _modelview_matrix, 16*sizeof(GLdouble)); }
void set_projection_matrix(const GLdouble _projection_matrix[16])
{ memcpy(projection_matrix_, _projection_matrix, 16*sizeof(GLdouble)); }
float fovy() const { return 45.0f; }
protected:
// draw the scene: will be called by the painGL() method.
virtual void draw_scene(const std::string& _draw_mode);
double performance(void);
private slots:
// popup menu clicked
void slotPopupMenu(int _id);
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();
protected:
// 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_;
unsigned int draw_mode_;
unsigned int n_draw_modes_;
std::vector<std::string> draw_mode_names_;
// 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
//=============================================================================

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,320 @@
#ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH
#define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <QTimer>
#include <QTcpSocket>
#include <QDataStream>
#include <iostream>
#include <string>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Geometry/Plane3d.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VFront.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MyMesh.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientSession.hh>
typedef MeshViewerWidgetT<MyMesh> MeshViewerWidget;
using OpenMesh::VDPM::VDPMStreamingPhase;
using OpenMesh::VDPM::kVSplitHeader;
using OpenMesh::VDPM::kVSplits;
using OpenMesh::VDPM::kBaseMesh;
using OpenMesh::VDPM::Plane3d;
using OpenMesh::VDPM::VFront;
using OpenMesh::VDPM::VHierarchy;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::ViewingParameters;
using OpenMesh::VDPM::set_debug_print;
//== CLASS DEFINITION =========================================================
class VDPMClientViewerWidget : public MeshViewerWidget
{
Q_OBJECT
public:
VDPMClientViewerWidget(QWidget *_parent=0, const char *_name=0)
: MeshViewerWidget(_parent, _name)
{
set_debug_print(true);
adaptive_mode_ = false;
qSessionTimer_ = new QTimer(this);
qSocket_ = new QTcpSocket(this);
streaming_phase_ = kBaseMesh;
session_running_ = false;
connect(qSessionTimer_, SIGNAL(timeout()),
this, SLOT(session_timer_check()));
connect(qSessionTimer_, SIGNAL(timeout()),
this, SLOT(socketReadyRead()));
// connect signal-slots about QSocket
connect(qSocket_, SIGNAL(connected()),
this, SLOT(socketConnected()));
connect(qSocket_, SIGNAL(connectionClosed()),
this, SLOT(socketConnectionClosed()));
connect(qSocket_, SIGNAL(readyRead()),
this, SLOT(socketReadyRead()));
connect(qSocket_, SIGNAL(error( QAbstractSocket::SocketError )),
this, SLOT(socketError( QAbstractSocket::SocketError )));
look_around_mode_ = false;
frame_ = 0;
n_viewpoints_ = 60;
global_timer_.reset();
global_timer_.start();
render_timer_.reset();
refinement_timer_.reset();
session_timer_.reset();
qAnimationTimer_ = new QTimer(this);
connect(qAnimationTimer_, SIGNAL(timeout()),
this, SLOT(look_around()));
//connect(qAnimationTimer_, SIGNAL(timeout()),
// this, SLOT(print_statistics()));
uplink_file = fopen("uplink.txt", "w");
downlink_file = fopen("downlink.txt", "w");
render_file = fopen("render.txt", "w");
refinement_file = fopen("refinement.txt", "w");
session_file = fopen("session.txt", "w");
vd_streaming_ = true;
max_transmitted_datasize_ = 0;
transmitted_datasize_ = 0;
}
~VDPMClientViewerWidget()
{
fclose(uplink_file);
fclose(downlink_file);
fclose(render_file);
fclose(refinement_file);
fclose(session_file);
}
void connectToServer( std::string& _server_name,
int _port= VDPM_STREAMING_PORT )
{
qSocket_->connectToHost( _server_name.c_str(), _port );
}
void openBaseMesh( std::string& _base_mesh )
{
open_vd_base_mesh( _base_mesh.c_str() );
std::cout << "spm file: " << _base_mesh << std::endl;
}
// socket related slots
private slots:
void closeConnection()
{
close();
if (qSocket_->state() == QAbstractSocket::ClosingState) // we have a delayed close.
{
connect(this, SIGNAL(delayedCloseFinished()), SLOT(socketClosed()));
}
else // the qSocket is closed.
{
socketClosed();
}
}
void socketReadyRead()
{
switch( streaming_phase_)
{
case kVSplits: receive_vsplit_packets(); break;
case kVSplitHeader: receive_vsplit_header(); break;
case kBaseMesh: receive_base_mesh(); break;
}
}
void socketConnected()
{
std::cout << "Connected to server" << std::endl;
}
void socketConnectionClosed()
{
std::cout << "Connection closed by the server" << std::endl;
}
void socketClosed()
{
std::cout << "Connection closed" << std::endl;
}
void socketError(QAbstractSocket::SocketError e)
{
std::cout << "Error number " << e << " occurred" << std::endl;
}
void look_around();
void print_statistics();
void session_timer_check()
{
std::cout << "Session Timer works" << std::endl;
}
// for view-dependent PM
private:
VHierarchy vhierarchy_;
//unsigned char tree_id_bits_;
VFront vfront_;
ViewingParameters viewing_parameters_;
float kappa_square_;
bool adaptive_mode_;
unsigned int n_base_vertices_;
unsigned int n_base_edges_;
unsigned int n_base_faces_;
unsigned int n_details_;
private:
bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius);
bool oriented_away(float sin_square, float distance_square,
float product_value);
bool screen_space_error(float mue_square, float sigma_square,
float distance_square, float product_value);
void update_viewing_parameters();
virtual void keyPressEvent(QKeyEvent *_event);
protected:
/// inherited drawing method
virtual void draw_scene(const std::string& _draw_mode);
public:
void open_vd_prog_mesh(const char* _filename);
unsigned int num_base_vertices() const { return n_base_vertices_; }
unsigned int num_base_edges() const { return n_base_edges_; }
unsigned int num_base_faces() const { return n_base_faces_; }
unsigned int num_details() const { return n_details_; }
void adaptive_refinement();
bool qrefine(VHierarchyNodeHandle _node_handle);
void force_vsplit(VHierarchyNodeHandle _node_handle);
bool ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1);
void get_active_cuts(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr);
void vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr);
void ecol(VHierarchyNodeHandle _parent_handle, const MyMesh::HalfedgeHandle& v0v1);
void init_vfront();
// streaming realted functions
private:
QTimer *qSessionTimer_;
QTcpSocket *qSocket_;
QString qFilename_;
bool session_running_;
VDPMStreamingPhase streaming_phase_;
unsigned int n_vsplit_packets_;
public:
void connect_to_server();
bool request_base_mesh();
bool receive_base_mesh();
void send_viewing_information();
void receive_vsplit_header();
void receive_vsplit_packets();
void open_vd_base_mesh(const char* _filename);
void update_vhierarchy(
const OpenMesh::Vec3f &_pos, // 3D position of v0
const VHierarchyNodeIndex &_v, // vhierarchy index of v1
const VHierarchyNodeIndex &_fund_lcut_index, // vhierarchy index of fundamental lcut
const VHierarchyNodeIndex &_fund_rcut_index, // vhierarchy index of fundamental rcut
const float _radius[2], // radius of lchild & rchild
const OpenMesh::Vec3f _normal[2], // normal of lchild & rchild
const float _sin_square[2], // sin_square of lchild & rchild
const float _mue_square[2], // mue_square of lchild & rchild
const float _sigma_square[2] // sigma_square of lchild & rchild
);
// for example
private:
QTimer *qAnimationTimer_;
QString qCameraFileName_;
MyMesh::Point bbMin_, bbMax_;
unsigned int frame_;
int max_transmitted_datasize_;
int transmitted_datasize_;
bool vd_streaming_;
unsigned int nth_viewpoint_;
unsigned int n_viewpoints_;
bool look_around_mode_;
GLdouble reserved_modelview_matrix_[16];
GLdouble reserved_projection_matrix_[16];
FILE *uplink_file;
FILE *downlink_file;
FILE *render_file;
FILE *refinement_file;
FILE *session_file;
public:
void save_screen(bool _flag);
void save_views();
void load_views(const char *camera_filename);
void screen_capture(const char *_filename);
void current_max_resolution();
OpenMesh::Utils::Timer global_timer_;
OpenMesh::Utils::Timer render_timer_;
OpenMesh::Utils::Timer refinement_timer_;
OpenMesh::Utils::Timer session_timer_;
#ifdef EXAMPLE_CREATION
void increase_max_descendents(const VHierarchyNodeIndex &node_index);
void increase_cur_descendents(VHierarchyNodeHandle _node_handle);
void __add_children(const VHierarchyNodeIndex &node_index, bool update_current = true);
void mesh_coloring();
#endif
};
#endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH defined

View File

@@ -0,0 +1,72 @@
// #ifdef _MSC_VER
// # pragma warning(disable: 4267 4311)
// #endif
#include <iostream>
#include <fstream>
#include <OpenMesh/Tools/Utils/getopt.h>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/ClientMainWindow.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientViewerWidget.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/PropertyWidget.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/OutputWidget.hh>
#include <QString>
#include <QApplication>
#include <QGLWidget>
int main(int argc, char **argv)
{
// OpenGL check
QApplication::setColorSpec( QApplication::CustomColor );
QApplication app(argc,argv);
if ( !QGLFormat::hasOpenGL() ) {
std::cerr << "This system has no OpenGL support.\n";
return -1;
}
//
int c;
int port = -1;
std::string bmesh = "";
std::string sname = "localhost";
while ( (c=getopt(argc, argv, "b:p:s:"))!=-1 )
{
switch(c)
{
case 'b': bmesh = optarg; break;
case 's': sname = optarg; break;
case 'p': { std::istringstream istr(optarg); istr >> port; } break;
}
}
// create widget
VDPMClientViewerWidget* w =
new VDPMClientViewerWidget(0, "VDPMClientViewer");
if (port == -1)
w->connectToServer( sname );
else
w->connectToServer( sname, port );
w->resize(800, 800);
// app.setMainWidget(w);
w->show();
w->openBaseMesh( bmesh );
// 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();
}

View File

@@ -0,0 +1,4 @@
1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.016996 -0.109919 -0.370638 1.000000
2.414214 0.000000 0.000000 0.000000 0.000000 2.414214 0.000000 0.000000 0.000000 0.000000 -1.000200 -1.000000 0.000000 0.000000 -0.002487 0.000000
0.000000 1.000000 0.000000 176744288671350421565538919745292424325033476751523693228169963004884932940091916749086946235466103001193375847224942690972512534721986560.000000 0.000000 nan 425134321045072769729657674081032044702092994459323810191320335465371399515446481741965189098676184821816460416151892487150071042707962836116024422753449790030954505984610613125759424311663740707690994610961772976644207938664290688788945427521964959221153792.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000 0.000000 43138399251230245763880957247161123402511258100486738812232497009688599814651595596323661983776768.000000 0.000000 nan 56217166495396395288300850038172311276865324027010017909696113739489719293525015037327494588529843730643950329227434086235241736485385775424471015442015055292454325203222134784.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

View File

@@ -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
PROJ_LIBS := OpenMesh/Core OpenMesh/Tools
MODULES := moc4 cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,225 @@
#include <iostream>
#include <fstream>
#include <map>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include "ServerSideVDPM.hh"
using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
void
ServerSideVDPM::
clear()
{
points_.clear();
triangles_.clear();
vhierarchy_.clear();
n_base_vertices_ = 0;
n_base_faces_ = 0;
n_details_ = 0;
}
OpenMesh::VertexHandle
ServerSideVDPM::
add_vertex(const OpenMesh::Vec3f &p)
{
points_.push_back(p);
return OpenMesh::VertexHandle(points_.size() - 1);
}
OpenMesh::FaceHandle
ServerSideVDPM::
add_face(const unsigned int _triangle[3])
{
OpenMesh::Vec3ui fvi;
fvi[0] = _triangle[0];
fvi[1] = _triangle[1];
fvi[2] = _triangle[2];
triangles_.push_back(fvi);
return OpenMesh::FaceHandle(triangles_.size() - 1);
}
void
ServerSideVDPM::
vhierarchy_roots(VHierarchyNodeHandleContainer &roots) const
{
unsigned int i;
roots.clear();
for (i=0; i<n_base_vertices_; ++i)
{
roots.push_back(VHierarchyNodeHandle(i));
}
}
bool
ServerSideVDPM::
open_vd_prog_mesh(const char *_filename)
{
unsigned int i;
unsigned int value;
unsigned int fvi[3];
char fileformat[16];
OpenMesh::Vec3f p, normal;
float radius, sin_square, mue_square, sigma_square;
OpenMesh::VertexHandle vertex_handle;
VHierarchyNodeIndex
node_index, lchild_node_index, rchild_node_index,
fund_lcut_index, fund_rcut_index;
VHierarchyNodeHandle
node_handle, lchild_handle, rchild_handle;
std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
std::ifstream ifs(_filename, std::ios::binary);
if (!ifs)
{
std::cerr << "read error\n";
return false;
}
//
bool swap = OpenMesh::Endian::local() != OpenMesh::Endian::LSB;
// read header
ifs.read(fileformat, 10); fileformat[10] = '\0';
if (std::string(fileformat) != std::string("VDProgMesh"))
{
std::cerr << "Wrong file format.\n";
ifs.close();
return false;
}
clear();
OpenMesh::IO::restore(ifs, n_base_vertices_, swap);
OpenMesh::IO::restore(ifs, n_base_faces_, swap);
OpenMesh::IO::restore(ifs, n_details_, swap);
// update tree_id_bits_
vhierarchy_.set_num_roots(n_base_vertices_);
// read base_mesh
for (i=0; i<n_base_vertices_; ++i)
{
OpenMesh::IO::restore(ifs, p, swap);
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vertex_handle = add_vertex(p);
node_index = vhierarchy_.generate_node_index(i, 1);
node_handle = vhierarchy_.add_node();
index2handle_map[node_index] = node_handle;
// VHierarchyNode &node = vhierarchy_.node(node_handle);
vhierarchy_.node(node_handle).set_index(node_index);
vhierarchy_.node(node_handle).set_vertex_handle(vertex_handle);
vhierarchy_.node(node_handle).set_radius(radius);
vhierarchy_.node(node_handle).set_normal(normal);
vhierarchy_.node(node_handle).set_sin_square(sin_square);
vhierarchy_.node(node_handle).set_mue_square(mue_square);
vhierarchy_.node(node_handle).set_sigma_square(sigma_square);
}
for (i=0; i<n_base_faces_; ++i)
{
OpenMesh::IO::restore(ifs, fvi[0], swap);
OpenMesh::IO::restore(ifs, fvi[1], swap);
OpenMesh::IO::restore(ifs, fvi[2], swap);
add_face(fvi);
}
// read details
for (i=0; i<n_details_; ++i)
{
// position of v0
OpenMesh::IO::restore(ifs, p, swap);
// vsplit info.
OpenMesh::IO::restore(ifs, value, swap);
node_index = VHierarchyNodeIndex(value);
OpenMesh::IO::restore(ifs, value, swap);
fund_lcut_index = VHierarchyNodeIndex(value);
OpenMesh::IO::restore(ifs, value, swap);
fund_rcut_index = VHierarchyNodeIndex(value);
node_handle = index2handle_map[node_index];
vhierarchy_.make_children(node_handle);
vhierarchy_.node(node_handle).set_fund_lcut(fund_lcut_index);
vhierarchy_.node(node_handle).set_fund_rcut(fund_rcut_index);
lchild_handle = vhierarchy_.lchild_handle(node_handle);
rchild_handle = vhierarchy_.rchild_handle(node_handle);
vertex_handle = add_vertex(p);
vhierarchy_.node(lchild_handle).set_vertex_handle(vertex_handle);
vhierarchy_.node(rchild_handle).set_vertex_handle(vhierarchy_.node(node_handle).vertex_handle());
index2handle_map[vhierarchy_.node(lchild_handle).node_index()] = lchild_handle;
index2handle_map[vhierarchy_.node(rchild_handle).node_index()] = rchild_handle;
// view-dependent parameters
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vhierarchy_.node(lchild_handle).set_radius(radius);
vhierarchy_.node(lchild_handle).set_normal(normal);
vhierarchy_.node(lchild_handle).set_sin_square(sin_square);
vhierarchy_.node(lchild_handle).set_mue_square(mue_square);
vhierarchy_.node(lchild_handle).set_sigma_square(sigma_square);
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vhierarchy_.node(rchild_handle).set_radius(radius);
vhierarchy_.node(rchild_handle).set_normal(normal);
vhierarchy_.node(rchild_handle).set_sin_square(sin_square);
vhierarchy_.node(rchild_handle).set_mue_square(mue_square);
vhierarchy_.node(rchild_handle).set_sigma_square(sigma_square);
}
ifs.close();
set_name(_filename);
#ifdef DEBUG_COUT
std::cout << "Opening a VDPM file has finisihed" << std::endl;
#endif
return true;
}
std::ostream& operator << ( std::ostream& _os, const ServerSideVDPM& _o )
{
_os << _o.name();
return _os;
}

View File

@@ -0,0 +1,88 @@
#ifndef OPENMESH_APP_SERVERSIDEVDPM_HH
#define OPENMESH_APP_SERVERSIDEVDPM_HH
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <vector>
#include <string>
#include <string.h>
using OpenMesh::VDPM::VHierarchy;
using OpenMesh::VDPM::VHierarchyNodeHandleContainer;
class ServerSideVDPM
{
private:
char name_[256];
std::vector<OpenMesh::Vec3f> points_; // points related to this pm
std::vector<OpenMesh::Vec3ui> triangles_; // base mesh triangles
VHierarchy vhierarchy_;
unsigned int n_base_vertices_;
unsigned int n_base_faces_;
unsigned int n_details_;
unsigned char tree_id_bits_;
public:
ServerSideVDPM() { clear(); }
void clear();
const char* name() const { return name_; }
void get_name(char _name[256]) { strcpy(_name, name_); }
void set_name(const char _name[256]) { strcpy(name_, _name); }
std::string
basename(const std::string& _f)
{
std::string::size_type dot = _f.rfind("/");
if (dot == std::string::npos)
return std::string(_f);
return std::string(_f.substr(dot+1, _f.length()-(dot+1)));
}
bool is_same_name(const char _name[256])
{
return (basename( name_ ) == basename( _name ));
}
OpenMesh::VertexHandle add_vertex(const OpenMesh::Vec3f &p);
OpenMesh::FaceHandle add_face(const unsigned int _triangle[3]);
const OpenMesh::Vec3f& point(OpenMesh::VertexHandle _vertex_handle) const
{
return points_[_vertex_handle.idx()];
}
OpenMesh::Vec3f& point(OpenMesh::VertexHandle _vertex_handle)
{
return points_[_vertex_handle.idx()];
}
const VHierarchy& vhierarchy() const { return vhierarchy_; }
VHierarchy& vhierarchy() { return vhierarchy_; }
void vhierarchy_roots(VHierarchyNodeHandleContainer &roots) const;
unsigned int n_base_vertices() const { return n_base_vertices_; }
unsigned int n_base_faces() const { return n_base_faces_; }
unsigned int n_details() const { return n_details_; }
bool open_vd_prog_mesh(const char *_filename);
};
std::ostream& operator << ( std::ostream& _os, const ServerSideVDPM& _o );
typedef std::vector<ServerSideVDPM> ServerSideVDPMContainer;
typedef std::list<ServerSideVDPM> ServerSideVDPMList;
#endif //OPENMESH_APP_SERVERSIDEVDPM_HH defined

View File

@@ -0,0 +1,475 @@
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
#include <QTextStream>
#include <QByteArray>
using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::Plane3d;
using OpenMesh::VDPM::InvalidVHierarchyNodeHandle;
using OpenMesh::VDPM::debug_print;
bool
VDPMServerSession::
set_vdpm(const char _vdpm_name[256])
{
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "Setting vdpm" << std::endl;
}
#endif
vdpm_ = ((VDPMServerViewerWidget *) ((VDPMServerSocket *) parent())->parent())->get_vdpm(_vdpm_name);
if (vdpm_ == NULL)
return false;
vhierarchy_ = &vdpm_->vhierarchy();
VHierarchyNodeHandleContainer roots;
unsigned int n_details;
vdpm_->vhierarchy_roots(roots);
n_details = vdpm_->n_details();
//vfront_.init(roots, n_details);
// vertex hierarchy window
vhwindow_.set_vertex_hierarchy(vdpm_->vhierarchy());
vhwindow_.init(roots);
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "setting vdpm ended" << std::endl;
}
#endif
return true;
}
void
VDPMServerSession::
sendBaseMeshToClient()
{
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "starting sendBaseMeshToClient()" << std::endl;
}
#endif
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "sendBaseMeshToClient() is done" << std::endl;
}
#endif
}
void
VDPMServerSession::
send_vsplit_packets()
{
viewing_parameters_.update_viewing_configurations();
vsplits_.clear();
if (((VDPMServerViewerWidget *) this->parent()->parent())->vd_streaming())
adaptive_refinement();
else
sequential_refinement();
if (debug_print() == true)
{
std::cout << "adaptive refinement is done on the server side" << std::endl;
}
stream_vsplits();
if (debug_print() == true)
{
std::cout << "streameing vsplits is done" << std::endl;
}
if (transmission_complete_ == true)
{
std::cout << "transmission is completed" << std::endl;
}
if (debug_print() == true)
{
std::cout << "send_vsplit_packets() is done" << std::endl;
}
}
void
VDPMServerSession::
readBaseMeshRequestFromClient()
{
int status;
unsigned int string_length;
QDataStream qTcp(socket_);
QString vdpm_name;
// while (waitForMore(10) < sizeof(int));
while ( socket_->bytesAvailable() < sizeof(int) )
socket_->waitForReadyRead(10);
qTcp >> string_length;
// while (waitForMore(10) < (string_length*sizeof(char)));
while (socket_->bytesAvailable() < string_length*sizeof(char) )
socket_->waitForReadyRead(10);
qTcp >> vdpm_name;
if (set_vdpm( vdpm_name.toStdString().c_str() ) != true) status = 0;
else status = 1;
qTcp << status;
socket_->flush();
if (status == 1)
streaming_phase_ = kVSplits;
}
void
VDPMServerSession::
readViewingParametersFromClient()
{
double modelview_matrix[16];
float fovy;
float aspect;
float tolerance_square;
// while (waitForMore(10) < 16*sizeof(double) + 3*sizeof(float));
while ( socket_->bytesAvailable() < 16*sizeof(double) + 3*sizeof(float) )
socket_->waitForReadyRead(10);
QDataStream qTCP(socket_);
qTCP >> modelview_matrix[0]
>> modelview_matrix[1]
>> modelview_matrix[2]
>> modelview_matrix[3]
>> modelview_matrix[4]
>> modelview_matrix[5]
>> modelview_matrix[6]
>> modelview_matrix[7]
>> modelview_matrix[8]
>> modelview_matrix[9]
>> modelview_matrix[10]
>> modelview_matrix[11]
>> modelview_matrix[12]
>> modelview_matrix[13]
>> modelview_matrix[14]
>> modelview_matrix[15]
>> fovy
>> aspect
>> tolerance_square;
viewing_parameters_.set_modelview_matrix(modelview_matrix);
viewing_parameters_.set_fovy(fovy);
viewing_parameters_.set_aspect(aspect);
viewing_parameters_.set_tolerance_square(tolerance_square);
send_vsplit_packets();
fprintf(mem_file, "%d %d %d\n",
memory_requirements_using_window(true),
memory_requirements_using_window(false),
memory_requirements_using_vfront());
}
void
VDPMServerSession::
PrintOutVFront()
{
}
void
VDPMServerSession::
stream_vsplits()
{
// send header (i.e., # of vsplits)
unsigned int i;
VHierarchyNodeHandle node_handle;
OpenMesh::Vec3f pos;
VHierarchyNodeIndex node_index, fund_lcut_index, fund_rcut_index;
float lchild_radius, rchild_radius;
OpenMesh::Vec3f lchild_normal, rchild_normal;
float lchild_sin_square, rchild_sin_square;
float lchild_mue_square, rchild_mue_square;
float lchild_sigma_square, rchild_sigma_square;
unsigned int n_vsplit_packets = (unsigned int) vsplits_.size();
QDataStream qTcp(socket_);
qTcp << n_vsplit_packets;
socket_->flush();
for (i=0; i<n_vsplit_packets; ++i)
{
node_handle = vsplits_[i];
VHierarchyNodeHandle lchild_handle = vhierarchy_->lchild_handle(node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_->rchild_handle(node_handle);
VHierarchyNode &node = vhierarchy_->node(node_handle);
VHierarchyNode &lchild = vhierarchy_->node(lchild_handle);
VHierarchyNode &rchild = vhierarchy_->node(rchild_handle);
pos = vdpm_->point(lchild.vertex_handle());
node_index = node.node_index();
fund_lcut_index = node.fund_lcut_index();
fund_rcut_index = node.fund_rcut_index();
lchild_radius = lchild.radius(); rchild_radius = rchild.radius();
lchild_normal = lchild.normal(); rchild_normal = rchild.normal();
lchild_sin_square = lchild.sin_square(); rchild_sin_square = rchild.sin_square();
lchild_mue_square = lchild.mue_square(); rchild_mue_square = rchild.mue_square();
lchild_sigma_square = lchild.sigma_square(); rchild_sigma_square = rchild.sigma_square();
qTcp << pos[0] << pos[1] << pos[2]
<< node_index.value()
<< fund_lcut_index.value()
<< fund_rcut_index.value()
<< lchild_radius
<< lchild_normal[0] << lchild_normal[1] << lchild_normal[2]
<< lchild_sin_square
<< lchild_mue_square
<< lchild_sigma_square
<< rchild_radius
<< rchild_normal[0] << rchild_normal[1] << rchild_normal[2]
<< rchild_sin_square
<< rchild_mue_square
<< rchild_sigma_square;
socket_->flush(); // socket flush
if (debug_print() == true)
{
std::cout << "Write to client " << i << "-th vsplit packets: " << std::endl;
}
}
}
void
VDPMServerSession::
adaptive_refinement()
{
float fovy = viewing_parameters_.fovy();
float tolerance_square = viewing_parameters_.tolerance_square();
float tan_value = tanf(fovy / 2.0f);
kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
transmission_complete_ = true;
for (vhwindow_.begin(); vhwindow_.end() != true; vhwindow_.next())
{
VHierarchyNodeHandle node_handle = vhwindow_.node_handle();
if (vhierarchy_->is_leaf_node(node_handle) != true)
{
transmission_complete_ = false;
if (qrefine(node_handle) == true)
{
force_vsplit(node_handle);
}
}
}
}
void
VDPMServerSession::
sequential_refinement()
{
for (vhwindow_.begin(); vhwindow_.end() != true; vhwindow_.next())
{
VHierarchyNodeHandle node_handle = vhwindow_.node_handle();
if (vhierarchy_->is_leaf_node(node_handle) != true)
force_vsplit(node_handle);
if (vsplits_.size() > 10)
break;
}
}
bool
VDPMServerSession::
qrefine(VHierarchyNodeHandle _node_handle)
{
VHierarchyNode &node = vhierarchy_->node(_node_handle);
OpenMesh::Vec3f p = vdpm_->point(node.vertex_handle());
OpenMesh::Vec3f eye_dir = p - viewing_parameters_.eye_pos();
float distance = eye_dir.length();
float distance2 = distance * distance;
float product_value = dot(eye_dir, node.normal());
if (outside_view_frustum(p, node.radius()) == true)
return false;
if (oriented_away(node.sin_square(), distance2, product_value) == true)
return false;
if (screen_space_error(node.mue_square(), node.sigma_square(), distance2, product_value) == true)
return false;
return true;
}
bool
VDPMServerSession::
outside_view_frustum(const OpenMesh::Vec3f &pos, float radius)
{
Plane3d frustum_plane[4];
viewing_parameters_.frustum_planes(frustum_plane);
for (int i = 0; i < 4; i++) {
if (frustum_plane[i].signed_distance(pos) < -radius)
return true;
}
return false;
}
bool
VDPMServerSession::
oriented_away(float sin_square, float distance_square, float product_value)
{
if (product_value > 0 && product_value*product_value > distance_square * sin_square)
return true;
else
return false;
}
bool
VDPMServerSession::
screen_space_error(float mue_square, float sigma_square, float distance_square, float product_value)
{
if ((mue_square >= kappa_square_ * distance_square) ||
(sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
return false;
else
return true;
}
void
VDPMServerSession::
force_vsplit(VHierarchyNodeHandle node_handle)
{
VHierarchyNodeHandle lcut_handle, rcut_handle;
VHierarchyNodeIndex fund_lcut_index, fund_rcut_index;
fund_lcut_index = vhierarchy_->fund_lcut_index(node_handle);
fund_rcut_index = vhierarchy_->fund_rcut_index(node_handle);
lcut_handle = active_ancestor_handle(fund_lcut_index);
rcut_handle = active_ancestor_handle(fund_rcut_index);
assert(lcut_handle != InvalidVHierarchyNodeHandle && rcut_handle != InvalidVHierarchyNodeHandle);
while (lcut_handle == rcut_handle)
{
force_vsplit(lcut_handle);
lcut_handle = active_ancestor_handle(fund_lcut_index);
rcut_handle = active_ancestor_handle(fund_rcut_index);
assert(lcut_handle != InvalidVHierarchyNodeHandle && rcut_handle != InvalidVHierarchyNodeHandle);
}
vsplit(node_handle);
}
void
VDPMServerSession::
vsplit(VHierarchyNodeHandle _node_handle)
{
// refine
VHierarchyNodeHandle lchild_handle = vhierarchy_->lchild_handle(_node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_->rchild_handle(_node_handle);
vhwindow_.inactivate(_node_handle);
vhwindow_.activate(lchild_handle);
vhwindow_.activate(rchild_handle);
//vfront_.remove(_node_handle);
//vfront_.add(lchild_handle);
//vfront_.add(rchild_handle);
vsplits_.push_back(_node_handle);
}
VHierarchyNodeHandle
VDPMServerSession::
active_ancestor_handle(VHierarchyNodeIndex &node_index)
{
if (node_index.is_valid(vhierarchy_->tree_id_bits()) != true)
return InvalidVHierarchyNodeHandle;
VHierarchyNodeHandle node_handle = vhierarchy_->node_handle(node_index);
while (node_handle != InvalidVHierarchyNodeHandle && vhwindow_.is_active(node_handle) != true)
node_handle = vhierarchy_->parent_handle(node_handle);
return node_handle;
}
unsigned int
VDPMServerSession::
memory_requirements_using_window(bool _estimate)
{
unsigned int mem = 0;
// common
mem += sizeof(VHierarchy*);
mem += sizeof(ViewingParameters);
mem += sizeof(float);
if (_estimate)
{
unsigned int min = vhierarchy_->num_nodes();
unsigned int max = 0;
for (unsigned int i = 0; i < vhierarchy_->num_nodes(); ++i)
{
if (vhwindow_.is_active(VHierarchyNodeHandle((int) i)))
{
min = std::min(min, i);
max = std::max(max, i);
}
}
mem += (max - min) / 8;
}
else
{
mem += vhwindow_.buffer_size();
}
return mem;
}
unsigned int
VDPMServerSession::
memory_requirements_using_vfront()
{
unsigned int mem = 0;
std::list<int> dummy_vfront;
mem += (unsigned int) ceil (vhierarchy_->num_nodes() / 8.0);
mem += sizeof(dummy_vfront);
for (unsigned int i = 0; i < vhierarchy_->num_nodes(); ++i)
{
if (vhwindow_.is_active(VHierarchyNodeHandle((int) i)))
mem += 3*sizeof(int);
}
return mem;
}

View File

@@ -0,0 +1,148 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH
#include <QTcpSocket>
#include <QThread>
#include <QDataStream>
#include <QTimer>
#include <iostream>
// #include <QObject>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Geometry/Plane3d.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VFront.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyWindow.hh>
using OpenMesh::VDPM::VDPMStreamingPhase;
using OpenMesh::VDPM::kBaseMesh;
using OpenMesh::VDPM::kVSplits;
using OpenMesh::VDPM::VHierarchyWindow;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::ViewingParameters;
using OpenMesh::VDPM::set_debug_print;
class VDPMServerSession : public QThread
{
Q_OBJECT
public:
VDPMServerSession(QTcpSocket* _socket, QObject *parent=0, const char *name=0)
{
socket_ = _socket;
set_debug_print(true);
streaming_phase_ = kBaseMesh;
transmission_complete_ = false;
connect(socket_, SIGNAL(connected()), this, SLOT(socketConnected()));
QTcpSocket::connect(socket_, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
//connect(this, SIGNAL(connectionClosed()), SLOT(deleteLater()));
QTcpSocket::connect(socket_, SIGNAL(connectionClosed()), this, SLOT(delayedCloseFinished()));
///TODO: find out how to port it from QSocket -> QTcpSocket
// setSocket(sock);
qStatisticsTimer_ = new QTimer(this);
QTcpSocket::connect(qStatisticsTimer_, SIGNAL(timeout()), this, SLOT(print_statistics()));
mem_file = fopen("mem.txt", "w");
start();
}
~VDPMServerSession()
{
fclose(mem_file);
}
// void run()
// {
// exec();
// }
private:
VDPMStreamingPhase streaming_phase_;
bool transmission_complete_;
QTcpSocket* socket_;
private:
void sendBaseMeshToClient();
void send_vsplit_packets();
void readBaseMeshRequestFromClient();
void readViewingParametersFromClient();
void PrintOutVFront();
private slots:
void socketConnected()
{
std::cout << "socket is connected" << std::endl;
}
void socketReadyRead()
{
if (streaming_phase_ == kBaseMesh)
{
readBaseMeshRequestFromClient();
}
else if (streaming_phase_ == kVSplits)
{
readViewingParametersFromClient();
}
}
void print_statistics()
{
//std::cout << memory_requirements(true) << " " << memory_requirements(false) << std::endl;
}
private:
unsigned short tree_id_bits_; // obsolete
ServerSideVDPM* vdpm_;
VHierarchy* vhierarchy_;
VHierarchyWindow vhwindow_;
ViewingParameters viewing_parameters_;
float kappa_square_;
VHierarchyNodeHandleContainer vsplits_;
private:
bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius);
bool oriented_away(float sin_square, float distance_square, float product_value);
bool screen_space_error(float mue_square, float sigma_square, float distance_square, float product_value);
void adaptive_refinement();
void sequential_refinement();
bool qrefine(VHierarchyNodeHandle _node_handle);
void force_vsplit(VHierarchyNodeHandle node_handle);
void vsplit(VHierarchyNodeHandle _node_handle);
VHierarchyNodeHandle active_ancestor_handle(VHierarchyNodeIndex &node_index);
void stream_vsplits();
public:
bool set_vdpm(const char _vdpm_name[256]);
unsigned int memory_requirements_using_window(bool _estimate);
unsigned int memory_requirements_using_vfront();
// for example
private:
QTimer *qStatisticsTimer_;
FILE *mem_file;
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH defined

View File

@@ -0,0 +1,51 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH
#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QVBoxLayout>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <iostream>
class VDPMServerSocket : public QTcpServer
{
Q_OBJECT
public:
VDPMServerSocket(QObject *parent=0)
: QTcpServer(parent)
{
setMaxPendingConnections(1);
if ( !listen(QHostAddress::Any, VDPM_STREAMING_PORT) )
{
std::cerr << "Failed to bind to port " << VDPM_STREAMING_PORT << std::endl;
exit(1);
}
connect(this, SIGNAL(newConnection()),this,SLOT(newConnections()));
}
public slots:
void newConnections()
{
VDPMServerSession *s = new VDPMServerSession(nextPendingConnection(), this);
//s->set_vdpm();
emit newConnect(s);
std::cout << "new connection"<< /*socket << */std::endl;
}
signals:
void newConnect(VDPMServerSession*);
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH defined

View File

@@ -0,0 +1,81 @@
#include <QKeyEvent>
#include <iterator>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
bool
VDPMServerViewerWidget::
open_vd_prog_mesh(const char *_filename)
{
ServerSideVDPMListIter vdpm_it;
vdpm_it = vdpms_.insert(vdpms_.end(), ServerSideVDPM());
ServerSideVDPM &vdpm = *vdpm_it;
return vdpm.open_vd_prog_mesh(_filename);
}
ServerSideVDPM*
VDPMServerViewerWidget::
get_vdpm(const char _vdpm_name[256])
{
ServerSideVDPMListIter vdpm_it;
for (vdpm_it=vdpms_.begin(); vdpm_it!=vdpms_.end(); ++vdpm_it)
{
if (vdpm_it->is_same_name(_vdpm_name) == true)
{
return &(*vdpm_it);
}
}
return NULL;
}
void
VDPMServerViewerWidget::
keyPressEvent(QKeyEvent* _event)
{
bool handled(false);
QString filename;
switch (_event->key())
{
case Qt::Key_D:
set_debug_print(!debug_print());
std::cout << "debug print mode "
<< (debug_print() == true ? "on" : "off") << std::endl;
break;
case Qt::Key_O:
#if defined(OM_CC_MSVC)
filename = QFileDialog::getOpenFileName(0, "", "d:/data/models/spm/", "*.spm");
#else
filename = QFileDialog::getOpenFileName(0, "", "~/data/models/spm/", "*.spm");
#endif
open_vd_prog_mesh( filename.toStdString().c_str() );
break;
case Qt::Key_I:
std::copy( vdpms_.begin(), vdpms_.end(),
std::ostream_iterator<ServerSideVDPM>(std::cout, "\n") );
break;
case Qt::Key_V:
vd_streaming_ = !(vd_streaming_);
if (vd_streaming_)
std::cout << "View-dependent streaming mode" << std::endl;
else
std::cout << "Sequential streaming mode" << std::endl;
break;
case Qt::Key_Q:
case Qt::Key_Escape:
qApp->quit();
}
if (!handled)
_event->ignore();
}

View File

@@ -0,0 +1,72 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH
#include <QApplication>
#include <QWidget>
#include <QFileDialog>
#include <QString>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSocket.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
using OpenMesh::VDPM::set_debug_print;
using OpenMesh::VDPM::debug_print;
class VDPMServerViewerWidget : public QWidget
{
Q_OBJECT
public:
//VDPMServerViewerWidget(QWidget *_parent) : QWidget(_parent)
VDPMServerViewerWidget() : QWidget()
{
server = new VDPMServerSocket(this);
// connect(server,
// SIGNAL(newConnection()),
// SLOT(newConnect()));
vd_streaming_ = true;
}
private:
typedef ServerSideVDPMList::iterator ServerSideVDPMListIter;
ServerSideVDPMList vdpms_;
bool vd_streaming_;
VDPMServerSocket *server;
public:
ServerSideVDPM* get_vdpm(const char _vdpm_name[256]);
public:
bool open_vd_prog_mesh(const char *_filename);
bool vd_streaming() const { return vd_streaming_; }
private slots:
void newConnect(VDPMServerSession *s)
{
std::cout << "New connection" << std::endl;
// connect(s, SIGNAL(connectionClosed()), SLOT(connectionClosed()));
}
void connectionClosed()
{
std::cout << "Client closed connection" << std::endl;
}
protected:
virtual void keyPressEvent(QKeyEvent* _event);
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH defined

View File

@@ -0,0 +1,34 @@
#include <iostream>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMStreamingServer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSocket.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
#include <OpenMesh/Tools/Utils/getopt.h>
#include <QHostAddress>
#include <QApplication>
int main(int argc, char **argv)
{
std::cout << "View-dependent streaming of PM server." << std::endl;
QApplication app(argc, argv);
VDPMServerViewerWidget server_widget;
server_widget.resize(50, 50);
// app.setMainWidget(&server_widget);
server_widget.show();
for (int idx=1; idx < argc; ++idx)
{
std::cout << "loading " << argv[idx] << std::endl;
server_widget.open_vd_prog_mesh( argv[idx] ) ;
}
return app.exec();
}

View File

@@ -0,0 +1,6 @@
#ifndef OPENMESH_APP_VDPMSTREAMINGSERVER_HH
#define OPENMESH_APP_VDPMSTREAMINGSERVER_HH
#endif //OPENMESH_APP_VDPMSTREAMINGSERVER_HH defined

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,16 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
SUBDIRS = $(call find-subdirs)
PACKAGES :=
PROJ_LIBS :=
MODULES :=
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,19 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
CXX_CFLAGS += -DQT_THREAD_SUPPORT
SUBDIRS = $(call find-subdirs)
PACKAGES := qt glut opengl
PROJ_LIBS := OpenMesh/Apps/QtViewer \
OpenMesh/Core OpenMesh/Tools
MODULES := moc cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,602 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
#define OPENMESHAPPS_MESHVIEWERWIDGET_CC
//== INCLUDES =================================================================
#ifdef _MSC_VER
//# pragma warning(disable: 4267 4311)
#endif
//
#include <iostream>
#include <fstream>
#include <qimage.h>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh>
using namespace OpenMesh;
//== 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_texcoords2D();
if ( IO::read_mesh(mesh_, _filename, _opt ))
{
opt_ = _opt;
// update face and vertex normals
if ( ! opt_.check( IO::Options::FaceNormal ) )
mesh_.update_face_normals();
if ( ! opt_.check( IO::Options::VertexNormal ) )
mesh_.update_vertex_normals();
if ( mesh_.has_vertex_colors() )
add_draw_mode("Colored");
if ( _opt.check( IO::Options::FaceColor ) )
add_draw_mode("Colored Faces");
else
mesh_.release_face_colors();
// 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)));
if ( ! opt_.check( IO::Options::VertexColor ) &&
mesh_.has_vertex_colors() )
{
typename Mesh::Color
c( 54,
(unsigned char)(54.5+200.0*count/mesh_.n_vertices()),
54 );
mesh_.set_color( vIt, c );
}
}
// set center and radius
set_scene_pos( (bbMin+bbMax)*0.5, (bbMin-bbMax).norm()*0.5 );
// info
std::clog << mesh_.n_vertices() << " vertices, "
<< mesh_.n_edges() << " edge, "
<< mesh_.n_faces() << " faces\n";
//
{
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(OM_CC_MSVC)
updateGL();
#endif
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 )
{
std::clog << "set_texture\n";
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.smoothScale( tex_w, tex_h );
}
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
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") // ----------------------------------------
{
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 == "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 == "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());
glDrawArrays( GL_POINTS, 0, mesh_.n_vertices() );
glDisableClientState(GL_VERTEX_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" )
{
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDepthRange(0.01, 1.0);
draw_openmesh("Solid Smooth");
glDisable(GL_LIGHTING);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
glColor4f( 0.4f, 0.4f, 0.4f, 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" )
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
else if (_draw_mode == "Colored Faces" )
{
glDisable(GL_LIGHTING);
draw_openmesh(_draw_mode);
}
}
//-----------------------------------------------------------------------------
#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_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;
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,163 @@
//=============================================================================
//
// 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/Mesh/Attributes.hh>
#include <OpenMesh/Tools/Utils/StripifierT.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/QGLViewerWidget.hh>
//== FORWARDS =================================================================
class QImage;
//== CLASS DEFINITION =========================================================
template <typename M>
class MeshViewerWidgetT : public QGLViewerWidget
{
public:
typedef M Mesh;
typedef OpenMesh::StripifierT<Mesh> MyStripifier;
/// default constructor
MeshViewerWidgetT(QWidget* _parent=0, const char* _name=0)
: QGLViewerWidget(_parent, _name),
f_strips_(false),
tex_id_(0),
tex_mode_(GL_MODULATE),
strips_(mesh_)
{
add_draw_mode("Points");
add_draw_mode("Hidden-Line");
#if defined(OM_USE_OSG) && OM_USE_OSG
add_draw_mode("OpenSG Indices");
#endif
}
void enable_strips() {
f_strips_ = true;
add_draw_mode("Strips'n VertexArrays");
add_draw_mode("Show Strips");
}
void disable_strips() { f_strips_ = false; }
/// destructor
~MeshViewerWidgetT() {}
/// 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 );
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 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] ); }
void glColor( const typename Mesh::FaceHandle fh )
{ glColor3ubv( &mesh_.color(fh)[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_;
};
//=============================================================================
#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,23 @@
#ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH
#define OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH
#include <qthread.h>
#include <qmutex.h>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Tools/VDPM/MeshTraits.hh>
using OpenMesh::VDPM::MeshTraits;
//== CLASS DEFINITION =========================================================
typedef OpenMesh::TriMesh_ArrayKernelT<MeshTraits> MyMesh;
static QMutex mutex_;
//== CLASS DEFINITION =========================================================
#endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_MYMESH_HH defined

View File

@@ -0,0 +1,621 @@
//=============================================================================
//
// 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) $
//
//=============================================================================
//== INCLUDES =================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311 4305)
#endif
#include <iomanip>
#include <GL/glut.h>
#include <qnamespace.h>
#include <qapplication.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/QGLViewerWidget.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#if !defined(M_PI)
# define M_PI 3.1415926535897931
#endif
using namespace OpenMesh;
//== IMPLEMENTATION ==========================================================
QGLViewerWidget::QGLViewerWidget( QWidget* _parent, const char* _name )
: QGLWidget( _parent, _name )
{
// qt stuff
setBackgroundMode( NoBackground );
setFocusPolicy(QWidget::StrongFocus);
setAcceptDrops( true );
setCursor(pointingHandCursor);
// popup menu
popup_menu_ = new QPopupMenu(this, "Draw Mode Menu");
popup_menu_->setCheckable(true);
connect( popup_menu_, SIGNAL(activated(int)),
this, SLOT(slotPopupMenu(int)));
// init draw modes
n_draw_modes_ = 0;
add_draw_mode("Wireframe");
add_draw_mode("Solid Flat");
add_draw_mode("Solid Smooth");
// for example
add_draw_mode("Colored");
slotPopupMenu(2);
}
//----------------------------------------------------------------------------
QGLViewerWidget::~QGLViewerWidget()
{
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::initializeGL()
{
// OpenGL state
glClearColor(1.0, 1.0, 1.0, 0.0);
glDisable( GL_DITHER );
glEnable( GL_DEPTH_TEST );
glEnable( GL_CULL_FACE );
// material
GLfloat mat_a[] = {0.7, 0.6, 0.5, 1.0};
GLfloat mat_d[] = {0.8, 0.7, 0.6, 1.0};
GLfloat mat_s[] = {1.0, 1.0, 1.0, 1.0};
GLfloat shine[] = {120.0};
// GLfloat mat_a[] = {0.2, 0.2, 0.2, 1.0};
// GLfloat mat_d[] = {0.4, 0.4, 0.4, 1.0};
// GLfloat mat_s[] = {0.8, 0.8, 0.8, 1.0};
// GLfloat shine[] = {128.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);
// lighting
glLoadIdentity();
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[] = {.05, .05, .4, 1.0};
GLfloat col2[] = {.4, .05, .05, 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);
// Fog
GLfloat fogColor[4] = { 0.4, 0.4, 0.5, 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)
{
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();
if ( (newPoint2D.x()<0) || (newPoint2D.x()>width()) ||
(newPoint2D.y()<0) || (newPoint2D.y()>height()) ) return;
// 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->state() & LeftButton) && (_event->state() & MidButton))
{
value_y = radius_ * dy * 3.0 / h;
translate(Vec3f(0.0, 0.0, value_y));
}
// move in x,y direction
else if (_event->state() & MidButton)
{
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->state() & LeftButton)
{
if (last_point_ok_)
{
if (newPoint_hitSphere = map_to_sphere(newPoint2D, newPoint3D))
{
Vec3f axis = last_point_3D_ % newPoint3D;
float cos_angle = (last_point_3D_ | newPoint3D);
if ( fabs(cos_angle) < 1.0 )
{
float angle = 2.0 * acos( cos_angle ) * 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_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_I:
std::cout << "Radius: " << radius_ << std::endl;
std::cout << "Center: " << center_ << std::endl;
break;
case Key_Space:
case Key_M:
{
double fps = performance();
std::cout << "fps: "
#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
<< std::setiosflags (std::ios::fixed)
#else
<< std::setiosflags (std::ios_base::fixed)
#endif
<< 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 )
{
if ( (_v2D.x() >= 0) && (_v2D.x() <= width()) &&
(_v2D.y() >= 0) && (_v2D.y() <= height()) )
{
double x = (double)(_v2D.x() - 0.5*width()) / (double)width();
double y = (double)(0.5*height() - _v2D.y()) / (double)height();
double sinx = sin(M_PI * x * 0.5);
double siny = sin(M_PI * y * 0.5);
double sinx2siny2 = sinx * sinx + siny * siny;
_v3D[0] = sinx;
_v3D[1] = siny;
_v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
return true;
}
else return false;
}
//----------------------------------------------------------------------------
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, _radius );
glFogf( GL_FOG_END, 4.0*_radius );
update_projection_matrix();
view_all();
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::add_draw_mode(const std::string& _s)
{
++n_draw_modes_;
// insert in popup menu
popup_menu_->insertItem(_s.c_str(), n_draw_modes_);
// store draw mode
draw_mode_names_.push_back(_s);
}
//----------------------------------------------------------------------------
void
QGLViewerWidget::slotPopupMenu(int _id)
{
// un-check all entries
for (size_t i=1; i <= n_draw_modes_; ++i)
popup_menu_->setItemChecked(i, false);
// save draw mode
draw_mode_ = _id;
// check selected draw mode
popup_menu_->setItemChecked(_id, true);
}
//----------------------------------------------------------------------------
double
QGLViewerWidget::performance()
{
setCursor( 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(); }
for (i=0, axis=Vec3f(0,1,0); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
for (i=0, axis=Vec3f(0,0,1); i<frames; ++i)
{ rotate(axis, angle); paintGL(); swapBuffers(); }
glFinish();
timer.stop();
glPopMatrix();
updateGL();
fps = ( (3.0 * frames) / timer.seconds() );
setCursor( pointingHandCursor );
return fps;
}
//=============================================================================

View File

@@ -0,0 +1,163 @@
//=============================================================================
//
// 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 <qgl.h>
#include <string>
#include <vector>
//== FORWARD DECLARATIONS =====================================================
class QPopupMenu;
//== CLASS DEFINITION =========================================================
class QGLViewerWidget : public QGLWidget
{
Q_OBJECT
public:
// Default constructor.
QGLViewerWidget( QWidget* _parent=0, const char* _name=0 );
// Destructor.
virtual ~QGLViewerWidget();
/* 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
void add_draw_mode(const std::string& _s);
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_; }
void set_modelview_matrix(const GLdouble _modelview_matrix[16])
{ memcpy(modelview_matrix_, _modelview_matrix, 16*sizeof(GLdouble)); }
void set_projection_matrix(const GLdouble _projection_matrix[16])
{ memcpy(projection_matrix_, _projection_matrix, 16*sizeof(GLdouble)); }
float fovy() const { return 45.0f; }
protected:
// draw the scene: will be called by the painGL() method.
virtual void draw_scene(const std::string& _draw_mode);
double performance(void);
private slots:
// popup menu clicked
void slotPopupMenu(int _id);
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();
protected:
// 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
QPopupMenu* popup_menu_;
unsigned int draw_mode_;
unsigned int n_draw_modes_;
std::vector<std::string> draw_mode_names_;
// 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
//=============================================================================

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,320 @@
#ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH
#define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH
//== INCLUDES =================================================================
#include <qtimer.h>
#include <qsocket.h>
#include <qdatastream.h>
#include <iostream>
#include <string>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Geometry/Plane3d.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VFront.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MyMesh.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientSession.hh>
typedef MeshViewerWidgetT<MyMesh> MeshViewerWidget;
using OpenMesh::VDPM::VDPMStreamingPhase;
using OpenMesh::VDPM::kVSplitHeader;
using OpenMesh::VDPM::kVSplits;
using OpenMesh::VDPM::kBaseMesh;
using OpenMesh::VDPM::Plane3d;
using OpenMesh::VDPM::VFront;
using OpenMesh::VDPM::VHierarchy;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::ViewingParameters;
using OpenMesh::VDPM::set_debug_print;
//== CLASS DEFINITION =========================================================
class VDPMClientViewerWidget : public MeshViewerWidget
{
Q_OBJECT
public:
VDPMClientViewerWidget(QWidget *_parent=0, const char *_name=0)
: MeshViewerWidget(_parent, _name)
{
set_debug_print(true);
adaptive_mode_ = false;
qSessionTimer_ = new QTimer(this);
qSocket_ = new QSocket(this);
streaming_phase_ = kBaseMesh;
session_running_ = false;
connect(qSessionTimer_, SIGNAL(timeout()),
this, SLOT(session_timer_check()));
connect(qSessionTimer_, SIGNAL(timeout()),
this, SLOT(socketReadyRead()));
// connect signal-slots about QSocket
connect(qSocket_, SIGNAL(connected()),
this, SLOT(socketConnected()));
connect(qSocket_, SIGNAL(connectionClosed()),
this, SLOT(socketConnectionClosed()));
connect(qSocket_, SIGNAL(readyRead()),
this, SLOT(socketReadyRead()));
connect(qSocket_, SIGNAL(error(int)),
this, SLOT(socketError(int)));
look_around_mode_ = false;
frame_ = 0;
n_viewpoints_ = 60;
global_timer_.reset();
global_timer_.start();
render_timer_.reset();
refinement_timer_.reset();
session_timer_.reset();
qAnimationTimer_ = new QTimer(this);
connect(qAnimationTimer_, SIGNAL(timeout()),
this, SLOT(look_around()));
//connect(qAnimationTimer_, SIGNAL(timeout()),
// this, SLOT(print_statistics()));
uplink_file = fopen("uplink.txt", "w");
downlink_file = fopen("downlink.txt", "w");
render_file = fopen("render.txt", "w");
refinement_file = fopen("refinement.txt", "w");
session_file = fopen("session.txt", "w");
vd_streaming_ = true;
max_transmitted_datasize_ = 0;
transmitted_datasize_ = 0;
}
~VDPMClientViewerWidget()
{
fclose(uplink_file);
fclose(downlink_file);
fclose(render_file);
fclose(refinement_file);
fclose(session_file);
}
void connectToServer( std::string& _server_name,
int _port= VDPM_STREAMING_PORT )
{
qSocket_->connectToHost( _server_name.c_str(), _port );
}
void openBaseMesh( std::string& _base_mesh )
{
open_vd_base_mesh( qFilename_ = _base_mesh.c_str() );
std::cout << "spm file: " << qFilename_ << std::endl;
}
// socket related slots
private slots:
void closeConnection()
{
close();
if (qSocket_->state() == QSocket::Closing) // we have a delayed close.
{
connect(this, SIGNAL(delayedCloseFinished()), SLOT(socketClosed()));
}
else // the qSocket is closed.
{
socketClosed();
}
}
void socketReadyRead()
{
switch( streaming_phase_)
{
case kVSplits: receive_vsplit_packets(); break;
case kVSplitHeader: receive_vsplit_header(); break;
case kBaseMesh: receive_base_mesh(); break;
}
}
void socketConnected()
{
std::cout << "Connected to server" << std::endl;
}
void socketConnectionClosed()
{
std::cout << "Connection closed by the server" << std::endl;
}
void socketClosed()
{
std::cout << "Connection closed" << std::endl;
}
void socketError(int e)
{
std::cout << "Error number " << e << " occurred" << std::endl;
}
void look_around();
void print_statistics();
void session_timer_check()
{
std::cout << "Session Timer works" << std::endl;
}
// for view-dependent PM
private:
VHierarchy vhierarchy_;
//unsigned char tree_id_bits_;
VFront vfront_;
ViewingParameters viewing_parameters_;
float kappa_square_;
bool adaptive_mode_;
unsigned int n_base_vertices_;
unsigned int n_base_edges_;
unsigned int n_base_faces_;
unsigned int n_details_;
private:
bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius);
bool oriented_away(float sin_square, float distance_square,
float product_value);
bool screen_space_error(float mue_square, float sigma_square,
float distance_square, float product_value);
void update_viewing_parameters();
virtual void keyPressEvent(QKeyEvent *_event);
protected:
/// inherited drawing method
virtual void draw_scene(const std::string& _draw_mode);
public:
void open_vd_prog_mesh(const char* _filename);
unsigned int num_base_vertices() const { return n_base_vertices_; }
unsigned int num_base_edges() const { return n_base_edges_; }
unsigned int num_base_faces() const { return n_base_faces_; }
unsigned int num_details() const { return n_details_; }
void adaptive_refinement();
bool qrefine(VHierarchyNodeHandle _node_handle);
void force_vsplit(VHierarchyNodeHandle _node_handle);
bool ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1);
void get_active_cuts(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr);
void vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr);
void ecol(VHierarchyNodeHandle _parent_handle, const MyMesh::HalfedgeHandle& v0v1);
void init_vfront();
// streaming realted functions
private:
QTimer *qSessionTimer_;
QSocket *qSocket_;
QString qFilename_;
bool session_running_;
VDPMStreamingPhase streaming_phase_;
unsigned int n_vsplit_packets_;
public:
void connect_to_server();
bool request_base_mesh();
bool receive_base_mesh();
void send_viewing_information();
void receive_vsplit_header();
void receive_vsplit_packets();
void open_vd_base_mesh(const char* _filename);
void update_vhierarchy(
const OpenMesh::Vec3f &_pos, // 3D position of v0
const VHierarchyNodeIndex &_v, // vhierarchy index of v1
const VHierarchyNodeIndex &_fund_lcut_index, // vhierarchy index of fundamental lcut
const VHierarchyNodeIndex &_fund_rcut_index, // vhierarchy index of fundamental rcut
const float _radius[2], // radius of lchild & rchild
const OpenMesh::Vec3f _normal[2], // normal of lchild & rchild
const float _sin_square[2], // sin_square of lchild & rchild
const float _mue_square[2], // mue_square of lchild & rchild
const float _sigma_square[2] // sigma_square of lchild & rchild
);
// for example
private:
QTimer *qAnimationTimer_;
QString qCameraFileName_;
MyMesh::Point bbMin_, bbMax_;
unsigned int frame_;
int max_transmitted_datasize_;
int transmitted_datasize_;
bool vd_streaming_;
unsigned int nth_viewpoint_;
unsigned int n_viewpoints_;
bool look_around_mode_;
GLdouble reserved_modelview_matrix_[16];
GLdouble reserved_projection_matrix_[16];
FILE *uplink_file;
FILE *downlink_file;
FILE *render_file;
FILE *refinement_file;
FILE *session_file;
public:
void save_screen(bool _flag);
void save_views();
void load_views(const char *camera_filename);
void screen_capture(const char *_filename);
void current_max_resolution();
OpenMesh::Utils::Timer global_timer_;
OpenMesh::Utils::Timer render_timer_;
OpenMesh::Utils::Timer refinement_timer_;
OpenMesh::Utils::Timer session_timer_;
#ifdef EXAMPLE_CREATION
void increase_max_descendents(const VHierarchyNodeIndex &node_index);
void increase_cur_descendents(VHierarchyNodeHandle _node_handle);
void __add_children(const VHierarchyNodeIndex &node_index, bool update_current = true);
void mesh_coloring();
#endif
};
#endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH defined

View File

@@ -0,0 +1,73 @@
// #ifdef _MSC_VER
// # pragma warning(disable: 4267 4311)
// #endif
#include <iostream>
#include <fstream>
#include <OpenMesh/Tools/Utils/getopt.h>
#include <Qt3Support>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/ClientMainWindow.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientViewerWidget.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/PropertyWidget.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/OutputWidget.hh>
#include <qstring.h>
#include <qapplication.h>
#include <qgl.h>
int main(int argc, char **argv)
{
// OpenGL check
QApplication::setColorSpec( QApplication::CustomColor );
QApplication app(argc,argv);
if ( !QGLFormat::hasOpenGL() ) {
std::cerr << "This system has no OpenGL support.\n";
return -1;
}
//
int c;
int port = -1;
std::string bmesh = "";
std::string sname = "localhost";
while ( (c=getopt(argc, argv, "b:p:s:"))!=-1 )
{
switch(c)
{
case 'b': bmesh = optarg; break;
case 's': sname = optarg; break;
case 'p': { std::istringstream istr(optarg); istr >> port; } break;
}
}
// create widget
VDPMClientViewerWidget* w =
new VDPMClientViewerWidget(0, "VDPMClientViewer");
if (port == -1)
w->connectToServer( sname );
else
w->connectToServer( sname, port );
w->resize(800, 800);
app.setMainWidget(w);
w->show();
w->openBaseMesh( bmesh );
// 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();
}

View File

@@ -0,0 +1,18 @@
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Config
#==============================================================================
CXX_CFLAGS += -DQT_THREAD_SUPPORT
SUBDIRS = $(call find-subdirs)
PACKAGES := qt glut opengl
PROJ_LIBS := OpenMesh/Core OpenMesh/Tools
MODULES := moc cxx
#== SYSTEM PART -- DON'T TOUCH ==============================================
include $(ACGMAKE)/Rules
#==============================================================================

View File

@@ -0,0 +1,225 @@
#include <iostream>
#include <fstream>
#include <map>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include "ServerSideVDPM.hh"
using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
void
ServerSideVDPM::
clear()
{
points_.clear();
triangles_.clear();
vhierarchy_.clear();
n_base_vertices_ = 0;
n_base_faces_ = 0;
n_details_ = 0;
}
OpenMesh::VertexHandle
ServerSideVDPM::
add_vertex(const OpenMesh::Vec3f &p)
{
points_.push_back(p);
return OpenMesh::VertexHandle(points_.size() - 1);
}
OpenMesh::FaceHandle
ServerSideVDPM::
add_face(const unsigned int _triangle[3])
{
OpenMesh::Vec3ui fvi;
fvi[0] = _triangle[0];
fvi[1] = _triangle[1];
fvi[2] = _triangle[2];
triangles_.push_back(fvi);
return OpenMesh::FaceHandle(triangles_.size() - 1);
}
void
ServerSideVDPM::
vhierarchy_roots(VHierarchyNodeHandleContainer &roots) const
{
unsigned int i;
roots.clear();
for (i=0; i<n_base_vertices_; ++i)
{
roots.push_back(VHierarchyNodeHandle(i));
}
}
bool
ServerSideVDPM::
open_vd_prog_mesh(const char *_filename)
{
unsigned int i;
unsigned int value;
unsigned int fvi[3];
char fileformat[16];
OpenMesh::Vec3f p, normal;
float radius, sin_square, mue_square, sigma_square;
OpenMesh::VertexHandle vertex_handle;
VHierarchyNodeIndex
node_index, lchild_node_index, rchild_node_index,
fund_lcut_index, fund_rcut_index;
VHierarchyNodeHandle
node_handle, lchild_handle, rchild_handle;
std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
std::ifstream ifs(_filename, std::ios::binary);
if (!ifs)
{
std::cerr << "read error\n";
return false;
}
//
bool swap = OpenMesh::Endian::local() != OpenMesh::Endian::LSB;
// read header
ifs.read(fileformat, 10); fileformat[10] = '\0';
if (std::string(fileformat) != std::string("VDProgMesh"))
{
std::cerr << "Wrong file format.\n";
ifs.close();
return false;
}
clear();
OpenMesh::IO::restore(ifs, n_base_vertices_, swap);
OpenMesh::IO::restore(ifs, n_base_faces_, swap);
OpenMesh::IO::restore(ifs, n_details_, swap);
// update tree_id_bits_
vhierarchy_.set_num_roots(n_base_vertices_);
// read base_mesh
for (i=0; i<n_base_vertices_; ++i)
{
OpenMesh::IO::restore(ifs, p, swap);
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vertex_handle = add_vertex(p);
node_index = vhierarchy_.generate_node_index(i, 1);
node_handle = vhierarchy_.add_node();
index2handle_map[node_index] = node_handle;
// VHierarchyNode &node = vhierarchy_.node(node_handle);
vhierarchy_.node(node_handle).set_index(node_index);
vhierarchy_.node(node_handle).set_vertex_handle(vertex_handle);
vhierarchy_.node(node_handle).set_radius(radius);
vhierarchy_.node(node_handle).set_normal(normal);
vhierarchy_.node(node_handle).set_sin_square(sin_square);
vhierarchy_.node(node_handle).set_mue_square(mue_square);
vhierarchy_.node(node_handle).set_sigma_square(sigma_square);
}
for (i=0; i<n_base_faces_; ++i)
{
OpenMesh::IO::restore(ifs, fvi[0], swap);
OpenMesh::IO::restore(ifs, fvi[1], swap);
OpenMesh::IO::restore(ifs, fvi[2], swap);
add_face(fvi);
}
// read details
for (i=0; i<n_details_; ++i)
{
// position of v0
OpenMesh::IO::restore(ifs, p, swap);
// vsplit info.
OpenMesh::IO::restore(ifs, value, swap);
node_index = VHierarchyNodeIndex(value);
OpenMesh::IO::restore(ifs, value, swap);
fund_lcut_index = VHierarchyNodeIndex(value);
OpenMesh::IO::restore(ifs, value, swap);
fund_rcut_index = VHierarchyNodeIndex(value);
node_handle = index2handle_map[node_index];
vhierarchy_.make_children(node_handle);
vhierarchy_.node(node_handle).set_fund_lcut(fund_lcut_index);
vhierarchy_.node(node_handle).set_fund_rcut(fund_rcut_index);
lchild_handle = vhierarchy_.lchild_handle(node_handle);
rchild_handle = vhierarchy_.rchild_handle(node_handle);
vertex_handle = add_vertex(p);
vhierarchy_.node(lchild_handle).set_vertex_handle(vertex_handle);
vhierarchy_.node(rchild_handle).set_vertex_handle(vhierarchy_.node(node_handle).vertex_handle());
index2handle_map[vhierarchy_.node(lchild_handle).node_index()] = lchild_handle;
index2handle_map[vhierarchy_.node(rchild_handle).node_index()] = rchild_handle;
// view-dependent parameters
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vhierarchy_.node(lchild_handle).set_radius(radius);
vhierarchy_.node(lchild_handle).set_normal(normal);
vhierarchy_.node(lchild_handle).set_sin_square(sin_square);
vhierarchy_.node(lchild_handle).set_mue_square(mue_square);
vhierarchy_.node(lchild_handle).set_sigma_square(sigma_square);
OpenMesh::IO::restore(ifs, radius, swap);
OpenMesh::IO::restore(ifs, normal, swap);
OpenMesh::IO::restore(ifs, sin_square, swap);
OpenMesh::IO::restore(ifs, mue_square, swap);
OpenMesh::IO::restore(ifs, sigma_square, swap);
vhierarchy_.node(rchild_handle).set_radius(radius);
vhierarchy_.node(rchild_handle).set_normal(normal);
vhierarchy_.node(rchild_handle).set_sin_square(sin_square);
vhierarchy_.node(rchild_handle).set_mue_square(mue_square);
vhierarchy_.node(rchild_handle).set_sigma_square(sigma_square);
}
ifs.close();
set_name(_filename);
#ifdef DEBUG_COUT
std::cout << "Opening a VDPM file has finisihed" << std::endl;
#endif
return true;
}
std::ostream& operator << ( std::ostream& _os, const ServerSideVDPM& _o )
{
_os << _o.name();
return _os;
}

View File

@@ -0,0 +1,87 @@
#ifndef OPENMESH_APP_SERVERSIDEVDPM_HH
#define OPENMESH_APP_SERVERSIDEVDPM_HH
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <vector>
#include <string>
using OpenMesh::VDPM::VHierarchy;
using OpenMesh::VDPM::VHierarchyNodeHandleContainer;
class ServerSideVDPM
{
private:
char name_[256];
std::vector<OpenMesh::Vec3f> points_; // points related to this pm
std::vector<OpenMesh::Vec3ui> triangles_; // base mesh triangles
VHierarchy vhierarchy_;
unsigned int n_base_vertices_;
unsigned int n_base_faces_;
unsigned int n_details_;
unsigned char tree_id_bits_;
public:
ServerSideVDPM() { clear(); }
void clear();
const char* name() const { return name_; }
void get_name(char _name[256]) { strcpy(_name, name_); }
void set_name(const char _name[256]) { strcpy(name_, _name); }
std::string
basename(const std::string& _f)
{
std::string::size_type dot = _f.rfind("/");
if (dot == std::string::npos)
return std::string(_f);
return std::string(_f.substr(dot+1, _f.length()-(dot+1)));
}
bool is_same_name(const char _name[256])
{
return (basename( name_ ) == basename( _name ));
}
OpenMesh::VertexHandle add_vertex(const OpenMesh::Vec3f &p);
OpenMesh::FaceHandle add_face(const unsigned int _triangle[3]);
const OpenMesh::Vec3f& point(OpenMesh::VertexHandle _vertex_handle) const
{
return points_[_vertex_handle.idx()];
}
OpenMesh::Vec3f& point(OpenMesh::VertexHandle _vertex_handle)
{
return points_[_vertex_handle.idx()];
}
const VHierarchy& vhierarchy() const { return vhierarchy_; }
VHierarchy& vhierarchy() { return vhierarchy_; }
void vhierarchy_roots(VHierarchyNodeHandleContainer &roots) const;
unsigned int n_base_vertices() const { return n_base_vertices_; }
unsigned int n_base_faces() const { return n_base_faces_; }
unsigned int n_details() const { return n_details_; }
bool open_vd_prog_mesh(const char *_filename);
};
std::ostream& operator << ( std::ostream& _os, const ServerSideVDPM& _o );
typedef std::vector<ServerSideVDPM> ServerSideVDPMContainer;
typedef std::list<ServerSideVDPM> ServerSideVDPMList;
#endif //OPENMESH_APP_SERVERSIDEVDPM_HH defined

View File

@@ -0,0 +1,467 @@
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
#include <qtextstream.h>
#include <qcstring.h>
using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::Plane3d;
using OpenMesh::VDPM::InvalidVHierarchyNodeHandle;
using OpenMesh::VDPM::debug_print;
bool
VDPMServerSession::
set_vdpm(const char _vdpm_name[256])
{
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "Setting vdpm" << std::endl;
}
#endif
vdpm_ = ((VDPMServerViewerWidget *) ((VDPMServerSocket *) parent())->parent())->get_vdpm(_vdpm_name);
if (vdpm_ == NULL)
return false;
vhierarchy_ = &vdpm_->vhierarchy();
VHierarchyNodeHandleContainer roots;
unsigned int n_details;
vdpm_->vhierarchy_roots(roots);
n_details = vdpm_->n_details();
//vfront_.init(roots, n_details);
// vertex hierarchy window
vhwindow_.set_vertex_hierarchy(vdpm_->vhierarchy());
vhwindow_.init(roots);
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "setting vdpm ended" << std::endl;
}
#endif
return true;
}
void
VDPMServerSession::
sendBaseMeshToClient()
{
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "starting sendBaseMeshToClient()" << std::endl;
}
#endif
#ifdef DEBUG_COUT
if (debug_print() == true)
{
std::cout << "sendBaseMeshToClient() is done" << std::endl;
}
#endif
}
void
VDPMServerSession::
send_vsplit_packets()
{
viewing_parameters_.update_viewing_configurations();
vsplits_.clear();
if (((VDPMServerViewerWidget *) this->parent()->parent())->vd_streaming())
adaptive_refinement();
else
sequential_refinement();
if (debug_print() == true)
{
std::cout << "adaptive refinement is done on the server side" << std::endl;
}
stream_vsplits();
if (debug_print() == true)
{
std::cout << "streameing vsplits is done" << std::endl;
}
if (transmission_complete_ == true)
{
std::cout << "transmission is completed" << std::endl;
}
if (debug_print() == true)
{
std::cout << "send_vsplit_packets() is done" << std::endl;
}
}
void
VDPMServerSession::
readBaseMeshRequestFromClient()
{
int status;
unsigned int string_length;
QDataStream qTcp(this);
QString vdpm_name;
while (waitForMore(10) < sizeof(int));
qTcp >> string_length;
while (waitForMore(10) < (string_length*sizeof(char)));
qTcp >> vdpm_name;
if (set_vdpm(vdpm_name) != true) status = 0;
else status = 1;
qTcp << status;
flush();
if (status == 1)
streaming_phase_ = kVSplits;
}
void
VDPMServerSession::
readViewingParametersFromClient()
{
double modelview_matrix[16];
float fovy;
float aspect;
float tolerance_square;
while (waitForMore(10) < 16*sizeof(double) + 3*sizeof(float));
QDataStream qTCP(this);
qTCP >> modelview_matrix[0]
>> modelview_matrix[1]
>> modelview_matrix[2]
>> modelview_matrix[3]
>> modelview_matrix[4]
>> modelview_matrix[5]
>> modelview_matrix[6]
>> modelview_matrix[7]
>> modelview_matrix[8]
>> modelview_matrix[9]
>> modelview_matrix[10]
>> modelview_matrix[11]
>> modelview_matrix[12]
>> modelview_matrix[13]
>> modelview_matrix[14]
>> modelview_matrix[15]
>> fovy
>> aspect
>> tolerance_square;
viewing_parameters_.set_modelview_matrix(modelview_matrix);
viewing_parameters_.set_fovy(fovy);
viewing_parameters_.set_aspect(aspect);
viewing_parameters_.set_tolerance_square(tolerance_square);
send_vsplit_packets();
fprintf(mem_file, "%d %d %d\n",
memory_requirements_using_window(true),
memory_requirements_using_window(false),
memory_requirements_using_vfront());
}
void
VDPMServerSession::
PrintOutVFront()
{
}
void
VDPMServerSession::
stream_vsplits()
{
// send header (i.e., # of vsplits)
unsigned int i;
VHierarchyNodeHandle node_handle;
OpenMesh::Vec3f pos;
VHierarchyNodeIndex node_index, fund_lcut_index, fund_rcut_index;
float lchild_radius, rchild_radius;
OpenMesh::Vec3f lchild_normal, rchild_normal;
float lchild_sin_square, rchild_sin_square;
float lchild_mue_square, rchild_mue_square;
float lchild_sigma_square, rchild_sigma_square;
unsigned int n_vsplit_packets = (unsigned int) vsplits_.size();
QDataStream qTcp(this);
qTcp << n_vsplit_packets;
flush();
for (i=0; i<n_vsplit_packets; ++i)
{
node_handle = vsplits_[i];
VHierarchyNodeHandle lchild_handle = vhierarchy_->lchild_handle(node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_->rchild_handle(node_handle);
VHierarchyNode &node = vhierarchy_->node(node_handle);
VHierarchyNode &lchild = vhierarchy_->node(lchild_handle);
VHierarchyNode &rchild = vhierarchy_->node(rchild_handle);
pos = vdpm_->point(lchild.vertex_handle());
node_index = node.node_index();
fund_lcut_index = node.fund_lcut_index();
fund_rcut_index = node.fund_rcut_index();
lchild_radius = lchild.radius(); rchild_radius = rchild.radius();
lchild_normal = lchild.normal(); rchild_normal = rchild.normal();
lchild_sin_square = lchild.sin_square(); rchild_sin_square = rchild.sin_square();
lchild_mue_square = lchild.mue_square(); rchild_mue_square = rchild.mue_square();
lchild_sigma_square = lchild.sigma_square(); rchild_sigma_square = rchild.sigma_square();
qTcp << pos[0] << pos[1] << pos[2]
<< node_index.value()
<< fund_lcut_index.value()
<< fund_rcut_index.value()
<< lchild_radius
<< lchild_normal[0] << lchild_normal[1] << lchild_normal[2]
<< lchild_sin_square
<< lchild_mue_square
<< lchild_sigma_square
<< rchild_radius
<< rchild_normal[0] << rchild_normal[1] << rchild_normal[2]
<< rchild_sin_square
<< rchild_mue_square
<< rchild_sigma_square;
flush(); // socket flush
if (debug_print() == true)
{
std::cout << "Write to client " << i << "-th vsplit packets: " << std::endl;
}
}
}
void
VDPMServerSession::
adaptive_refinement()
{
float fovy = viewing_parameters_.fovy();
float tolerance_square = viewing_parameters_.tolerance_square();
float tan_value = tanf(fovy / 2.0f);
kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
transmission_complete_ = true;
for (vhwindow_.begin(); vhwindow_.end() != true; vhwindow_.next())
{
VHierarchyNodeHandle node_handle = vhwindow_.node_handle();
if (vhierarchy_->is_leaf_node(node_handle) != true)
{
transmission_complete_ = false;
if (qrefine(node_handle) == true)
{
force_vsplit(node_handle);
}
}
}
}
void
VDPMServerSession::
sequential_refinement()
{
for (vhwindow_.begin(); vhwindow_.end() != true; vhwindow_.next())
{
VHierarchyNodeHandle node_handle = vhwindow_.node_handle();
if (vhierarchy_->is_leaf_node(node_handle) != true)
force_vsplit(node_handle);
if (vsplits_.size() > 10)
break;
}
}
bool
VDPMServerSession::
qrefine(VHierarchyNodeHandle _node_handle)
{
VHierarchyNode &node = vhierarchy_->node(_node_handle);
OpenMesh::Vec3f p = vdpm_->point(node.vertex_handle());
OpenMesh::Vec3f eye_dir = p - viewing_parameters_.eye_pos();
float distance = eye_dir.length();
float distance2 = distance * distance;
float product_value = dot(eye_dir, node.normal());
if (outside_view_frustum(p, node.radius()) == true)
return false;
if (oriented_away(node.sin_square(), distance2, product_value) == true)
return false;
if (screen_space_error(node.mue_square(), node.sigma_square(), distance2, product_value) == true)
return false;
return true;
}
bool
VDPMServerSession::
outside_view_frustum(const OpenMesh::Vec3f &pos, float radius)
{
Plane3d frustum_plane[4];
viewing_parameters_.frustum_planes(frustum_plane);
for (int i = 0; i < 4; i++) {
if (frustum_plane[i].signed_distance(pos) < -radius)
return true;
}
return false;
}
bool
VDPMServerSession::
oriented_away(float sin_square, float distance_square, float product_value)
{
if (product_value > 0 && product_value*product_value > distance_square * sin_square)
return true;
else
return false;
}
bool
VDPMServerSession::
screen_space_error(float mue_square, float sigma_square, float distance_square, float product_value)
{
if ((mue_square >= kappa_square_ * distance_square) ||
(sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
return false;
else
return true;
}
void
VDPMServerSession::
force_vsplit(VHierarchyNodeHandle node_handle)
{
VHierarchyNodeHandle lcut_handle, rcut_handle;
VHierarchyNodeIndex fund_lcut_index, fund_rcut_index;
fund_lcut_index = vhierarchy_->fund_lcut_index(node_handle);
fund_rcut_index = vhierarchy_->fund_rcut_index(node_handle);
lcut_handle = active_ancestor_handle(fund_lcut_index);
rcut_handle = active_ancestor_handle(fund_rcut_index);
assert(lcut_handle != InvalidVHierarchyNodeHandle && rcut_handle != InvalidVHierarchyNodeHandle);
while (lcut_handle == rcut_handle)
{
force_vsplit(lcut_handle);
lcut_handle = active_ancestor_handle(fund_lcut_index);
rcut_handle = active_ancestor_handle(fund_rcut_index);
assert(lcut_handle != InvalidVHierarchyNodeHandle && rcut_handle != InvalidVHierarchyNodeHandle);
}
vsplit(node_handle);
}
void
VDPMServerSession::
vsplit(VHierarchyNodeHandle _node_handle)
{
// refine
VHierarchyNodeHandle lchild_handle = vhierarchy_->lchild_handle(_node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_->rchild_handle(_node_handle);
vhwindow_.inactivate(_node_handle);
vhwindow_.activate(lchild_handle);
vhwindow_.activate(rchild_handle);
//vfront_.remove(_node_handle);
//vfront_.add(lchild_handle);
//vfront_.add(rchild_handle);
vsplits_.push_back(_node_handle);
}
VHierarchyNodeHandle
VDPMServerSession::
active_ancestor_handle(VHierarchyNodeIndex &node_index)
{
if (node_index.is_valid(vhierarchy_->tree_id_bits()) != true)
return InvalidVHierarchyNodeHandle;
VHierarchyNodeHandle node_handle = vhierarchy_->node_handle(node_index);
while (node_handle != InvalidVHierarchyNodeHandle && vhwindow_.is_active(node_handle) != true)
node_handle = vhierarchy_->parent_handle(node_handle);
return node_handle;
}
unsigned int
VDPMServerSession::
memory_requirements_using_window(bool _estimate)
{
unsigned int mem = 0;
// common
mem += sizeof(VHierarchy*);
mem += sizeof(ViewingParameters);
mem += sizeof(float);
if (_estimate)
{
unsigned int min = vhierarchy_->num_nodes();
unsigned int max = 0;
for (unsigned int i = 0; i < vhierarchy_->num_nodes(); ++i)
{
if (vhwindow_.is_active(VHierarchyNodeHandle((int) i)))
{
min = std::min(min, i);
max = std::max(max, i);
}
}
mem += (max - min) / 8;
}
else
{
mem += vhwindow_.buffer_size();
}
return mem;
}
unsigned int
VDPMServerSession::
memory_requirements_using_vfront()
{
unsigned int mem = 0;
std::list<int> dummy_vfront;
mem += (unsigned int) ceil (vhierarchy_->num_nodes() / 8.0);
mem += sizeof(dummy_vfront);
for (unsigned int i = 0; i < vhierarchy_->num_nodes(); ++i)
{
if (vhwindow_.is_active(VHierarchyNodeHandle((int) i)))
mem += 3*sizeof(int);
}
return mem;
}

View File

@@ -0,0 +1,146 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH
#include <qsocket.h>
#include <qthread.h>
#include <qdatastream.h>
#include <qtimer.h>
#include <iostream>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Geometry/Plane3d.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VFront.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Tools/VDPM/VHierarchyWindow.hh>
using OpenMesh::VDPM::VDPMStreamingPhase;
using OpenMesh::VDPM::kBaseMesh;
using OpenMesh::VDPM::kVSplits;
using OpenMesh::VDPM::VHierarchyWindow;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::ViewingParameters;
using OpenMesh::VDPM::set_debug_print;
class VDPMServerSession : public QSocket, public QThread
{
Q_OBJECT
public:
VDPMServerSession(int sock, QObject *parent=0, const char *name=0)
: QSocket(parent, name)
{
set_debug_print(true);
streaming_phase_ = kBaseMesh;
transmission_complete_ = false;
connect(this, SIGNAL(connected()), SLOT(socketConnected()));
connect(this, SIGNAL(readyRead()), SLOT(socketReadyRead()));
//connect(this, SIGNAL(connectionClosed()), SLOT(deleteLater()));
connect(this, SIGNAL(connectionClosed()), SLOT(delayedCloseFinished()));
setSocket(sock);
qStatisticsTimer_ = new QTimer(this);
connect(qStatisticsTimer_, SIGNAL(timeout()), this, SLOT(print_statistics()));
mem_file = fopen("mem.txt", "w");
start();
}
~VDPMServerSession()
{
fclose(mem_file);
}
void run()
{
while (true)
{
sleep(1);
}
}
private:
VDPMStreamingPhase streaming_phase_;
bool transmission_complete_;
private:
void sendBaseMeshToClient();
void send_vsplit_packets();
void readBaseMeshRequestFromClient();
void readViewingParametersFromClient();
void PrintOutVFront();
private slots:
void socketConnected()
{
std::cout << "socket is connected" << std::endl;
}
void socketReadyRead()
{
if (streaming_phase_ == kBaseMesh)
{
readBaseMeshRequestFromClient();
}
else if (streaming_phase_ == kVSplits)
{
readViewingParametersFromClient();
}
}
void print_statistics()
{
//std::cout << memory_requirements(true) << " " << memory_requirements(false) << std::endl;
}
private:
unsigned short tree_id_bits_; // obsolete
ServerSideVDPM* vdpm_;
VHierarchy* vhierarchy_;
VHierarchyWindow vhwindow_;
ViewingParameters viewing_parameters_;
float kappa_square_;
VHierarchyNodeHandleContainer vsplits_;
private:
bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius);
bool oriented_away(float sin_square, float distance_square, float product_value);
bool screen_space_error(float mue_square, float sigma_square, float distance_square, float product_value);
void adaptive_refinement();
void sequential_refinement();
bool qrefine(VHierarchyNodeHandle _node_handle);
void force_vsplit(VHierarchyNodeHandle node_handle);
void vsplit(VHierarchyNodeHandle _node_handle);
VHierarchyNodeHandle active_ancestor_handle(VHierarchyNodeIndex &node_index);
void stream_vsplits();
public:
bool set_vdpm(const char _vdpm_name[256]);
unsigned int memory_requirements_using_window(bool _estimate);
unsigned int memory_requirements_using_vfront();
// for example
private:
QTimer *qStatisticsTimer_;
FILE *mem_file;
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSESSION_HH defined

View File

@@ -0,0 +1,47 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH
#include <qobject.h>
#include <qsocket.h>
#include <qserversocket.h>
#include <qvbox.h>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <iostream>
class VDPMServerSocket : public QServerSocket
{
Q_OBJECT
public:
VDPMServerSocket(QObject *parent=0)
: QServerSocket(VDPM_STREAMING_PORT, 1, parent)
{
if (!ok())
{
std::cerr << "Failed to bind to port "
<< VDPM_STREAMING_PORT << std::endl;
exit(1);
}
}
void newConnection(int socket)
{
VDPMServerSession *s = new VDPMServerSession(socket, this);
//s->set_vdpm();
emit newConnect(s);
std::cout << "new connection with: " << socket << std::endl;
}
signals:
void newConnect(VDPMServerSession*);
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSERVERSOCKET_HH defined

View File

@@ -0,0 +1,80 @@
#include <iterator>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
bool
VDPMServerViewerWidget::
open_vd_prog_mesh(const char *_filename)
{
ServerSideVDPMListIter vdpm_it;
vdpm_it = vdpms_.insert(vdpms_.end(), ServerSideVDPM());
ServerSideVDPM &vdpm = *vdpm_it;
return vdpm.open_vd_prog_mesh(_filename);
}
ServerSideVDPM*
VDPMServerViewerWidget::
get_vdpm(const char _vdpm_name[256])
{
ServerSideVDPMListIter vdpm_it;
for (vdpm_it=vdpms_.begin(); vdpm_it!=vdpms_.end(); ++vdpm_it)
{
if (vdpm_it->is_same_name(_vdpm_name) == true)
{
return &(*vdpm_it);
}
}
return NULL;
}
void
VDPMServerViewerWidget::
keyPressEvent(QKeyEvent* _event)
{
bool handled(false);
QString filename;
switch (_event->key())
{
case Key_D:
set_debug_print(!debug_print());
std::cout << "debug print mode "
<< (debug_print() == true ? "on" : "off") << std::endl;
break;
case Key_O:
#if defined(OM_CC_MSVC)
filename = QFileDialog::getOpenFileName("d:/data/models/spm/", "*.spm");
#else
filename = QFileDialog::getOpenFileName("~/data/models/spm/", "*.spm");
#endif
open_vd_prog_mesh(filename);
break;
case Key_I:
std::copy( vdpms_.begin(), vdpms_.end(),
std::ostream_iterator<ServerSideVDPM>(std::cout, "\n") );
break;
case Key_V:
vd_streaming_ = !(vd_streaming_);
if (vd_streaming_)
std::cout << "View-dependent streaming mode" << std::endl;
else
std::cout << "Sequential streaming mode" << std::endl;
break;
case Key_Q:
case Key_Escape:
qApp->quit();
}
if (!handled)
_event->ignore();
}

View File

@@ -0,0 +1,70 @@
#ifndef OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH
#define OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH
#include <qapplication.h>
#include <qwidget.h>
#include <qfiledialog.h>
#include <qstring.h>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSocket.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
using OpenMesh::VDPM::set_debug_print;
using OpenMesh::VDPM::debug_print;
class VDPMServerViewerWidget : public QWidget
{
Q_OBJECT
public:
//VDPMServerViewerWidget(QWidget *_parent) : QWidget(_parent)
VDPMServerViewerWidget() : QWidget()
{
VDPMServerSocket *server = new VDPMServerSocket(this);
connect(server,
SIGNAL(newConnect(VDPMServerSession*)),
SLOT(newConnect(VDPMServerSession*)));
vd_streaming_ = true;
}
private:
typedef ServerSideVDPMList::iterator ServerSideVDPMListIter;
ServerSideVDPMList vdpms_;
bool vd_streaming_;
public:
ServerSideVDPM* get_vdpm(const char _vdpm_name[256]);
public:
bool open_vd_prog_mesh(const char *_filename);
bool vd_streaming() const { return vd_streaming_; }
private slots:
void newConnect(VDPMServerSession *s)
{
std::cout << "New connection" << std::endl;
connect(s, SIGNAL(connectionClosed()), SLOT(connectionClosed()));
}
void connectionClosed()
{
std::cout << "Client closed connection" << std::endl;
}
protected:
virtual void keyPressEvent(QKeyEvent* _event);
};
#endif //OPENMESH_APP_VDPMSTREAMING_SERVER_VDPMSTREAMINGSERVERWIDGET_HH defined

View File

@@ -0,0 +1,34 @@
#include <iostream>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMStreamingServer.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/ServerSideVDPM.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSocket.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerSession.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Server/VDPMServerViewerWidget.hh>
#include <OpenMesh/Tools/Utils/getopt.h>
#include <qhostaddress.h>
#include <qapplication.h>
int main(int argc, char **argv)
{
std::cout << "View-dependent streaming of PM server." << std::endl;
QApplication app(argc, argv);
VDPMServerViewerWidget server_widget;
server_widget.resize(50, 50);
app.setMainWidget(&server_widget);
server_widget.show();
for (int idx=1; idx < argc; ++idx)
{
std::cout << "loading " << argv[idx] << std::endl;
server_widget.open_vd_prog_mesh( argv[idx] ) ;
}
return app.exec();
}

View File

@@ -0,0 +1,6 @@
#ifndef OPENMESH_APP_VDPMSTREAMINGSERVER_HH
#define OPENMESH_APP_VDPMSTREAMINGSERVER_HH
#endif //OPENMESH_APP_VDPMSTREAMINGSERVER_HH defined