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:
30
Apps/VDProgMesh/Analyzer/Analyzer.pro
Normal file
30
Apps/VDProgMesh/Analyzer/Analyzer.pro
Normal file
@@ -0,0 +1,30 @@
|
||||
################################################################################
|
||||
#
|
||||
################################################################################
|
||||
|
||||
contains( OPENFLIPPER , OpenFlipper ){
|
||||
include( $$TOPDIR/qmake/all.include )
|
||||
} else {
|
||||
include( $$TOPDIR/OpenMesh/qmake/all.include )
|
||||
}
|
||||
|
||||
INCLUDEPATH += ../../../..
|
||||
|
||||
CONFIG += glew glut
|
||||
|
||||
Application()
|
||||
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools
|
||||
LIBS += -lglut
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY}
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY}
|
||||
|
||||
DIRECTORIES = .
|
||||
|
||||
# Input
|
||||
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
|
||||
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
|
||||
|
||||
################################################################################
|
||||
1161
Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc
Normal file
1161
Apps/VDProgMesh/Analyzer/vdpmanalyzer.cc
Normal file
File diff suppressed because it is too large
Load Diff
31
Apps/VDProgMesh/Synthesizer/Synthesizer.pro
Normal file
31
Apps/VDProgMesh/Synthesizer/Synthesizer.pro
Normal file
@@ -0,0 +1,31 @@
|
||||
################################################################################
|
||||
#
|
||||
################################################################################
|
||||
|
||||
contains( OPENFLIPPER , OpenFlipper ){
|
||||
include( $$TOPDIR/qmake/all.include )
|
||||
} else {
|
||||
include( $$TOPDIR/OpenMesh/qmake/all.include )
|
||||
}
|
||||
|
||||
INCLUDEPATH += ../../../..
|
||||
|
||||
CONFIG += glew glut
|
||||
|
||||
Application()
|
||||
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools
|
||||
LIBS += -lglut
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY}
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY}
|
||||
|
||||
DIRECTORIES = . ../../QtViewer
|
||||
|
||||
# Input
|
||||
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
|
||||
SOURCES -= ../../QtViewer/meshviewer.cc
|
||||
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
|
||||
|
||||
################################################################################
|
||||
596
Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc
Normal file
596
Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.cc
Normal file
@@ -0,0 +1,596 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable: 4267 4311)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QFileDialog>
|
||||
#include <QDataStream>
|
||||
#include <GL/glut.h>
|
||||
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
#include <OpenMesh/Tools/Utils/Timer.hh>
|
||||
#include <OpenMesh/Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
draw_scene(const std::string &_draw_mode)
|
||||
{
|
||||
if (adaptive_mode_ == true)
|
||||
{
|
||||
adaptive_refinement();
|
||||
}
|
||||
MeshViewerWidget::draw_scene(_draw_mode);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
adaptive_refinement()
|
||||
{
|
||||
update_viewing_parameters();
|
||||
|
||||
VDPMMesh::HalfedgeHandle v0v1;
|
||||
|
||||
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;
|
||||
|
||||
//assert( !vfront_.end() );
|
||||
|
||||
for ( vfront_.begin(); !vfront_.end(); )
|
||||
{
|
||||
VHierarchyNodeHandle
|
||||
node_handle = vfront_.node_handle(),
|
||||
parent_handle = vhierarchy_.parent_handle(node_handle);
|
||||
|
||||
if (vhierarchy_.is_leaf_node(node_handle) != true &&
|
||||
qrefine(node_handle) == true)
|
||||
{
|
||||
force_vsplit(node_handle);
|
||||
}
|
||||
else if (vhierarchy_.is_root_node(node_handle) != true &&
|
||||
ecol_legal(parent_handle, v0v1) == true &&
|
||||
qrefine(parent_handle) != true)
|
||||
{
|
||||
ecol(parent_handle, v0v1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vfront_.next();
|
||||
}
|
||||
}
|
||||
|
||||
// free memories tagged as 'deleted'
|
||||
mesh_.garbage_collection(false, true, true);
|
||||
mesh_.update_face_normals();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VDPMSynthesizerViewerWidget::
|
||||
qrefine(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
VHierarchyNode &node = vhierarchy_.node(_node_handle);
|
||||
Vec3f p = mesh_.point(node.vertex_handle());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
force_vsplit(VHierarchyNodeHandle node_handle)
|
||||
{
|
||||
VDPMMesh::VertexHandle vl, vr;
|
||||
|
||||
get_active_cuts(node_handle, vl, vr);
|
||||
|
||||
while (vl == vr)
|
||||
{
|
||||
force_vsplit(mesh_.data(vl).vhierarchy_node_handle());
|
||||
get_active_cuts(node_handle, vl, vr);
|
||||
}
|
||||
|
||||
vsplit(node_handle, vl, vr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
vsplit(VHierarchyNodeHandle _node_handle,
|
||||
VDPMMesh::VertexHandle vl,
|
||||
VDPMMesh::VertexHandle vr)
|
||||
{
|
||||
// refine
|
||||
VHierarchyNodeHandle
|
||||
lchild_handle = vhierarchy_.lchild_handle(_node_handle),
|
||||
rchild_handle = vhierarchy_.rchild_handle(_node_handle);
|
||||
|
||||
VDPMMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
|
||||
VDPMMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
|
||||
|
||||
mesh_.vertex_split(v0, v1, vl, vr);
|
||||
mesh_.set_normal(v0, vhierarchy_.normal(lchild_handle));
|
||||
mesh_.set_normal(v1, vhierarchy_.normal(rchild_handle));
|
||||
mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
|
||||
mesh_.data(v1).set_vhierarchy_node_handle(rchild_handle);
|
||||
mesh_.status(v0).set_deleted(false);
|
||||
mesh_.status(v1).set_deleted(false);
|
||||
|
||||
vfront_.remove(_node_handle);
|
||||
vfront_.add(lchild_handle);
|
||||
vfront_.add(rchild_handle);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
ecol(VHierarchyNodeHandle _node_handle, const VDPMMesh::HalfedgeHandle& v0v1)
|
||||
{
|
||||
VHierarchyNodeHandle
|
||||
lchild_handle = vhierarchy_.lchild_handle(_node_handle),
|
||||
rchild_handle = vhierarchy_.rchild_handle(_node_handle);
|
||||
|
||||
VDPMMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
|
||||
VDPMMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
|
||||
|
||||
// coarsen
|
||||
mesh_.collapse(v0v1);
|
||||
mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
|
||||
mesh_.data(v0).set_vhierarchy_node_handle(lchild_handle);
|
||||
mesh_.data(v1).set_vhierarchy_node_handle(_node_handle);
|
||||
mesh_.status(v0).set_deleted(false);
|
||||
mesh_.status(v1).set_deleted(false);
|
||||
|
||||
vfront_.add(_node_handle);
|
||||
vfront_.remove(lchild_handle);
|
||||
vfront_.remove(rchild_handle);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VDPMSynthesizerViewerWidget::
|
||||
ecol_legal(VHierarchyNodeHandle _parent_handle, VDPMMesh::HalfedgeHandle& v0v1)
|
||||
{
|
||||
VHierarchyNodeHandle
|
||||
lchild_handle = vhierarchy_.lchild_handle(_parent_handle),
|
||||
rchild_handle = vhierarchy_.rchild_handle(_parent_handle);
|
||||
|
||||
// test whether lchild & rchild present in the current vfront
|
||||
if ( vfront_.is_active(lchild_handle) != true ||
|
||||
vfront_.is_active(rchild_handle) != true)
|
||||
return false;
|
||||
|
||||
VDPMMesh::VertexHandle v0, v1;
|
||||
|
||||
v0 = vhierarchy_.vertex_handle(lchild_handle);
|
||||
v1 = vhierarchy_.vertex_handle(rchild_handle);
|
||||
|
||||
v0v1 = mesh_.find_halfedge(v0, v1);
|
||||
|
||||
return mesh_.is_collapse_ok(v0v1);
|
||||
}
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
get_active_cuts(const VHierarchyNodeHandle _node_handle,
|
||||
VDPMMesh::VertexHandle &vl, VDPMMesh::VertexHandle &vr)
|
||||
{
|
||||
VDPMMesh::VertexVertexIter vv_it;
|
||||
VHierarchyNodeHandle nnode_handle;
|
||||
|
||||
VHierarchyNodeIndex
|
||||
nnode_index,
|
||||
fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle),
|
||||
fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);
|
||||
|
||||
vl = VDPMMesh::InvalidVertexHandle;
|
||||
vr = VDPMMesh::InvalidVertexHandle;
|
||||
|
||||
for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle));
|
||||
vv_it; ++vv_it)
|
||||
{
|
||||
nnode_handle = mesh_.data(vv_it.handle()).vhierarchy_node_handle();
|
||||
nnode_index = vhierarchy_.node_index(nnode_handle);
|
||||
|
||||
if (vl == VDPMMesh::InvalidVertexHandle &&
|
||||
vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) == true)
|
||||
vl = vv_it.handle();
|
||||
|
||||
if (vr == VDPMMesh::InvalidVertexHandle &&
|
||||
vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) == true)
|
||||
vr = vv_it.handle();
|
||||
|
||||
/*if (vl == VDPMMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_lcut_index) == true)
|
||||
vl = vv_it.handle();
|
||||
if (vr == VDPMMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_rcut_index) == true)
|
||||
vr = vv_it.handle();*/
|
||||
|
||||
if (vl != VDPMMesh::InvalidVertexHandle &&
|
||||
vr != VDPMMesh::InvalidVertexHandle)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VDPMSynthesizerViewerWidget::
|
||||
outside_view_frustum(const Vec3f &pos, float radius)
|
||||
{
|
||||
#if 0
|
||||
return
|
||||
(frustum_plane_[0].signed_distance(pos) < -radius) ||
|
||||
(frustum_plane_[1].signed_distance(pos) < -radius) ||
|
||||
(frustum_plane_[2].signed_distance(pos) < -radius) ||
|
||||
(frustum_plane_[3].signed_distance(pos) < -radius);
|
||||
#else
|
||||
|
||||
Plane3d frustum_plane[4];
|
||||
|
||||
viewing_parameters_.frustum_planes(frustum_plane);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (frustum_plane[i].singed_distance(pos) < -radius)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
VDPMSynthesizerViewerWidget::
|
||||
oriented_away(float sin_square, float distance_square, float product_value)
|
||||
{
|
||||
#if 0
|
||||
return (product_value > 0)
|
||||
&& ((product_value * product_value) > (distance_square * sin_square));
|
||||
#else
|
||||
if (product_value > 0 &&
|
||||
product_value * product_value > distance_square * sin_square)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VDPMSynthesizerViewerWidget::
|
||||
screen_space_error(float mue_square, float sigma_square,
|
||||
float distance_square, float product_value)
|
||||
{
|
||||
#if 0
|
||||
float ks_ds = kappa_square_ * distance_square;
|
||||
float pv_pv = product_value * product_value;
|
||||
return (mue_square >= ks_ds)
|
||||
|| (sigma_square*( distance_square - pv_pv) >= ks_ds*distance_square);
|
||||
#else
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
open_vd_prog_mesh(const char* _filename)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int value;
|
||||
unsigned int fvi[3];
|
||||
char fileformat[16];
|
||||
Vec3f p, normal;
|
||||
float radius, sin_square, mue_square, sigma_square;
|
||||
VHierarchyNodeHandleContainer roots;
|
||||
VertexHandle vertex_handle;
|
||||
VHierarchyNodeIndex node_index;
|
||||
VHierarchyNodeIndex lchild_node_index, rchild_node_index;
|
||||
VHierarchyNodeIndex fund_lcut_index, fund_rcut_index;
|
||||
VHierarchyNodeHandle node_handle;
|
||||
VHierarchyNodeHandle lchild_node_handle, rchild_node_handle;
|
||||
|
||||
std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
|
||||
|
||||
std::ifstream ifs(_filename, std::ios::binary);
|
||||
|
||||
if (!ifs)
|
||||
{
|
||||
std::cerr << "read error\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//
|
||||
bool swap = Endian::local() != 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();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
IO::restore(ifs, n_base_vertices_, swap);
|
||||
IO::restore(ifs, n_base_faces_, swap);
|
||||
IO::restore(ifs, n_details_, swap);
|
||||
|
||||
mesh_.clear();
|
||||
vfront_.clear();
|
||||
vhierarchy_.clear();
|
||||
|
||||
vhierarchy_.set_num_roots(n_base_vertices_);
|
||||
|
||||
// load base mesh
|
||||
for (i=0; i<n_base_vertices_; ++i)
|
||||
{
|
||||
IO::restore(ifs, p, swap);
|
||||
IO::restore(ifs, radius, swap);
|
||||
IO::restore(ifs, normal, swap);
|
||||
IO::restore(ifs, sin_square, swap);
|
||||
IO::restore(ifs, mue_square, swap);
|
||||
IO::restore(ifs, sigma_square, swap);
|
||||
|
||||
vertex_handle = mesh_.add_vertex(p);
|
||||
node_index = vhierarchy_.generate_node_index(i, 1);
|
||||
node_handle = vhierarchy_.add_node();
|
||||
|
||||
VHierarchyNode &node = vhierarchy_.node(node_handle);
|
||||
|
||||
node.set_index(node_index);
|
||||
node.set_vertex_handle(vertex_handle);
|
||||
mesh_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
|
||||
|
||||
node.set_radius(radius);
|
||||
node.set_normal(normal);
|
||||
node.set_sin_square(sin_square);
|
||||
node.set_mue_square(mue_square);
|
||||
node.set_sigma_square(sigma_square);
|
||||
mesh_.set_normal(vertex_handle, normal);
|
||||
|
||||
index2handle_map[node_index] = node_handle;
|
||||
roots.push_back(node_handle);
|
||||
}
|
||||
vfront_.init(roots, n_details_);
|
||||
|
||||
for (i=0; i<n_base_faces_; ++i)
|
||||
{
|
||||
IO::restore(ifs, fvi[0], swap);
|
||||
IO::restore(ifs, fvi[1], swap);
|
||||
IO::restore(ifs, fvi[2], swap);
|
||||
|
||||
mesh_.add_face(mesh_.vertex_handle(fvi[0]),
|
||||
mesh_.vertex_handle(fvi[1]),
|
||||
mesh_.vertex_handle(fvi[2]));
|
||||
}
|
||||
|
||||
// load details
|
||||
for (i=0; i<n_details_; ++i)
|
||||
{
|
||||
// position of v0
|
||||
IO::restore(ifs, p, swap);
|
||||
|
||||
// vsplit info.
|
||||
IO::restore(ifs, value, swap);
|
||||
node_index = VHierarchyNodeIndex(value);
|
||||
|
||||
IO::restore(ifs, value, swap);
|
||||
fund_lcut_index = VHierarchyNodeIndex(value);
|
||||
|
||||
IO::restore(ifs, value, swap);
|
||||
fund_rcut_index = VHierarchyNodeIndex(value);
|
||||
|
||||
|
||||
node_handle = index2handle_map[node_index];
|
||||
vhierarchy_.make_children(node_handle);
|
||||
|
||||
VHierarchyNode &node = vhierarchy_.node(node_handle);
|
||||
VHierarchyNode &lchild = vhierarchy_.node(node.lchild_handle());
|
||||
VHierarchyNode &rchild = vhierarchy_.node(node.rchild_handle());
|
||||
|
||||
node.set_fund_lcut(fund_lcut_index);
|
||||
node.set_fund_rcut(fund_rcut_index);
|
||||
|
||||
vertex_handle = mesh_.add_vertex(p);
|
||||
lchild.set_vertex_handle(vertex_handle);
|
||||
rchild.set_vertex_handle(node.vertex_handle());
|
||||
|
||||
index2handle_map[lchild.node_index()] = node.lchild_handle();
|
||||
index2handle_map[rchild.node_index()] = node.rchild_handle();
|
||||
|
||||
// view-dependent parameters
|
||||
IO::restore(ifs, radius, swap);
|
||||
IO::restore(ifs, normal, swap);
|
||||
IO::restore(ifs, sin_square, swap);
|
||||
IO::restore(ifs, mue_square, swap);
|
||||
IO::restore(ifs, sigma_square, swap);
|
||||
lchild.set_radius(radius);
|
||||
lchild.set_normal(normal);
|
||||
lchild.set_sin_square(sin_square);
|
||||
lchild.set_mue_square(mue_square);
|
||||
lchild.set_sigma_square(sigma_square);
|
||||
|
||||
IO::restore(ifs, radius, swap);
|
||||
IO::restore(ifs, normal, swap);
|
||||
IO::restore(ifs, sin_square, swap);
|
||||
IO::restore(ifs, mue_square, swap);
|
||||
IO::restore(ifs, sigma_square, swap);
|
||||
rchild.set_radius(radius);
|
||||
rchild.set_normal(normal);
|
||||
rchild.set_sin_square(sin_square);
|
||||
rchild.set_mue_square(mue_square);
|
||||
rchild.set_sigma_square(sigma_square);
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
|
||||
// update face and vertex normals
|
||||
mesh_.update_face_normals();
|
||||
|
||||
// bounding box
|
||||
VDPMMesh::ConstVertexIter
|
||||
vIt(mesh_.vertices_begin()),
|
||||
vEnd(mesh_.vertices_end());
|
||||
|
||||
VDPMMesh::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_details_ << " detail vertices\n";
|
||||
|
||||
updateGL();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VDPMSynthesizerViewerWidget::keyPressEvent(QKeyEvent* _event)
|
||||
{
|
||||
switch (_event->key())
|
||||
{
|
||||
case Key_Home:
|
||||
updateGL();
|
||||
break;
|
||||
|
||||
case Key_End:
|
||||
updateGL();
|
||||
break;
|
||||
|
||||
case Key_Plus:
|
||||
viewing_parameters_.increase_tolerance();
|
||||
std::cout << "Scree-space error tolerance^2 is increased by "
|
||||
<< viewing_parameters_.tolerance_square() << std::endl;
|
||||
updateGL();
|
||||
break;
|
||||
|
||||
case Key_Minus:
|
||||
viewing_parameters_.decrease_tolerance();
|
||||
std::cout << "Screen-space error tolerance^2 is decreased by "
|
||||
<< viewing_parameters_.tolerance_square() << std::endl;
|
||||
updateGL();
|
||||
break;
|
||||
|
||||
case Key_A:
|
||||
adaptive_mode_ = !(adaptive_mode_);
|
||||
std::cout << "Adaptive refinement mode is "
|
||||
<< (adaptive_mode_ ? "on" : "off") << std::endl;
|
||||
updateGL();
|
||||
break;
|
||||
|
||||
case Key_O:
|
||||
qFilename_ = QFileDialog::getOpenFileName(0,"", "", "*.spm");
|
||||
open_vd_prog_mesh( qFilename_.toStdString().c_str() );
|
||||
break;
|
||||
|
||||
default:
|
||||
MeshViewerWidget::keyPressEvent( _event );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
VDPMSynthesizerViewerWidget::
|
||||
update_viewing_parameters()
|
||||
{
|
||||
viewing_parameters_.set_modelview_matrix(modelview_matrix());
|
||||
viewing_parameters_.set_aspect((float) width()/ (float) height());
|
||||
viewing_parameters_.set_fovy(fovy());
|
||||
|
||||
viewing_parameters_.update_viewing_configurations();
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
181
Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh
Normal file
181
Apps/VDProgMesh/Synthesizer/VDPMSynthesizerViewerWidget.hh
Normal file
@@ -0,0 +1,181 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VDPMSYNTHESIZERVIEWERWIDGET_HH
|
||||
#define OPENMESH_VDPROGMESH_VDPMSYNTHESIZERVIEWERWIDGET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <string>
|
||||
#include <QTimer>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/MeshTraits.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>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \class newClass newClass.hh <OpenMesh/.../newClass.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
typedef TriMesh_ArrayKernelT<VDPM::MeshTraits> VDPMMesh;
|
||||
typedef MeshViewerWidgetT<VDPMMesh> MeshViewerWidget;
|
||||
|
||||
|
||||
// using view dependent progressive mesh
|
||||
|
||||
using VDPM::Plane3d;
|
||||
using VDPM::VFront;
|
||||
using VDPM::VHierarchy;
|
||||
using VDPM::VHierarchyNode;
|
||||
using VDPM::VHierarchyNodeIndex;
|
||||
using VDPM::VHierarchyNodeHandle;
|
||||
using VDPM::VHierarchyNodeHandleContainer;
|
||||
using VDPM::ViewingParameters;
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
class VDPMSynthesizerViewerWidget : public MeshViewerWidget
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MeshViewerWidget Base;
|
||||
|
||||
public:
|
||||
|
||||
VDPMSynthesizerViewerWidget(QWidget* _parent=0, const char* _name=0)
|
||||
: MeshViewerWidget(_parent)
|
||||
{
|
||||
adaptive_mode_ = false;
|
||||
}
|
||||
|
||||
~VDPMSynthesizerViewerWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// open view-dependent progressive mesh
|
||||
void open_vd_prog_mesh(const char* _filename);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
QString qFilename_;
|
||||
VHierarchy vhierarchy_;
|
||||
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 adaptive_refinement();
|
||||
|
||||
bool qrefine(VHierarchyNodeHandle _node_handle);
|
||||
|
||||
void force_vsplit(VHierarchyNodeHandle _node_handle);
|
||||
|
||||
bool ecol_legal(VHierarchyNodeHandle _parent_handle,
|
||||
VDPMMesh::HalfedgeHandle& v0v1);
|
||||
|
||||
void get_active_cuts(VHierarchyNodeHandle _node_handle,
|
||||
VDPMMesh::VertexHandle &vl, VDPMMesh::VertexHandle &vr);
|
||||
|
||||
void vsplit(VHierarchyNodeHandle _node_handle,
|
||||
VDPMMesh::VertexHandle vl, VDPMMesh::VertexHandle vr);
|
||||
|
||||
void ecol(VHierarchyNodeHandle _parent_handle,
|
||||
const VDPMMesh::HalfedgeHandle& v0v1);
|
||||
|
||||
void init_vfront();
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESHAPPS_VDPMSYNTHESIZERVIEWERWIDGET_HH defined
|
||||
//=============================================================================
|
||||
53
Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc
Normal file
53
Apps/VDProgMesh/Synthesizer/vdpmsynthesizer.cc
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable: 4267 4311)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QString>
|
||||
#include <QApplication>
|
||||
|
||||
#include "VDPMSynthesizerViewerWidget.hh"
|
||||
|
||||
#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
|
||||
VDPMSynthesizerViewerWidget*
|
||||
w = new VDPMSynthesizerViewerWidget(0, "VDPMSynthesizerViewer");
|
||||
|
||||
w->resize(400, 400);
|
||||
w->show();
|
||||
|
||||
// load scene
|
||||
if (argc==2)
|
||||
w->open_vd_prog_mesh(argv[1]);
|
||||
else
|
||||
{
|
||||
std::cerr << "Usage: vdpmsynthesizer <vdpm-file.spm>\n";
|
||||
return 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();
|
||||
}
|
||||
320
Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc
Normal file
320
Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.cc
Normal file
@@ -0,0 +1,320 @@
|
||||
// -------------------- STL
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Tools/Utils/getopt.h>
|
||||
#include <OpenMesh/Tools/Utils/Timer.hh>
|
||||
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModProgMeshT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModIndependentSetsT.hh>
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
|
||||
typedef OpenMesh::Decimater::DecimaterT<Mesh> Decimater;
|
||||
typedef OpenMesh::Decimater::ModNormalFlippingT<Decimater> ModNormalFlipping;
|
||||
typedef OpenMesh::Decimater::ModQuadricT<Decimater> ModQuadric;
|
||||
typedef OpenMesh::Decimater::ModProgMeshT<Decimater> ModProgMesh;
|
||||
typedef OpenMesh::Decimater::ModIndependentSetsT<Decimater> ModIndependentSets;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace OpenMesh::Decimater;
|
||||
|
||||
template <class D>
|
||||
class ModBalancerT : public OpenMesh::Decimater::ModQuadricT<D>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef OpenMesh::Decimater::ModQuadricT<D> BaseModQ;
|
||||
|
||||
DECIMATING_MODULE( ModBalancerT, D, Balancer );
|
||||
|
||||
public:
|
||||
|
||||
typedef size_t level_t;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
ModBalancerT( D &_dec )
|
||||
: BaseModQ( _dec ),
|
||||
max_level_(0), n_vertices_(0)
|
||||
{
|
||||
BaseModQ::mesh().add_property( level_ );
|
||||
}
|
||||
|
||||
|
||||
/// Destructor
|
||||
virtual ~ModBalancerT()
|
||||
{
|
||||
BaseModQ::mesh().remove_property( level_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static level_t calc_bits_for_roots( size_t _n_vertices )
|
||||
{
|
||||
return level_t(std::ceil(std::log((double)_n_vertices)*inv_log2_));
|
||||
}
|
||||
|
||||
public: // inherited
|
||||
|
||||
void initialize(void)
|
||||
{
|
||||
BaseModQ::initialize();
|
||||
n_vertices_ = BaseModQ::mesh().n_vertices();
|
||||
n_roots_ = calc_bits_for_roots(n_vertices_);
|
||||
}
|
||||
|
||||
virtual float collapse_priority(const CollapseInfo& _ci)
|
||||
{
|
||||
level_t newlevel = std::max( BaseModQ::mesh().property( level_, _ci.v0 ),
|
||||
BaseModQ::mesh().property( level_, _ci.v1 ) )+1;
|
||||
level_t newroots = calc_bits_for_roots(n_vertices_-1);
|
||||
|
||||
if ( (newroots + newlevel) < 32 )
|
||||
{
|
||||
double err = BaseModQ::collapse_priority( _ci );
|
||||
|
||||
if (err!=BaseModQ::ILLEGAL_COLLAPSE)
|
||||
{
|
||||
return float(newlevel + err/(err+1.0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return BaseModQ::ILLEGAL_COLLAPSE;
|
||||
}
|
||||
|
||||
/// post-process halfedge collapse (accumulate quadrics)
|
||||
void postprocess_collapse(const CollapseInfo& _ci)
|
||||
{
|
||||
BaseModQ::postprocess_collapse( _ci );
|
||||
|
||||
BaseModQ::mesh().property( level_, _ci.v1 ) =
|
||||
std::max( BaseModQ::mesh().property( level_, _ci.v0 ),
|
||||
BaseModQ::mesh().property( level_, _ci.v1 ) ) + 1;
|
||||
|
||||
max_level_ = std::max( BaseModQ::mesh().property( level_, _ci.v1 ), max_level_ );
|
||||
n_roots_ = calc_bits_for_roots(--n_vertices_);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
level_t max_level(void) const { return max_level_; }
|
||||
level_t bits_for_roots(void) const { return n_roots_; }
|
||||
|
||||
private:
|
||||
|
||||
/// hide this method
|
||||
void set_binary(bool _b) {}
|
||||
|
||||
OpenMesh::VPropHandleT<level_t> level_;
|
||||
|
||||
level_t max_level_; // maximum level reached
|
||||
level_t n_roots_; // minimum bits for root nodes
|
||||
size_t n_vertices_;// number of potential root nodes
|
||||
|
||||
static const double inv_log2_;
|
||||
|
||||
};
|
||||
|
||||
template <typename D>
|
||||
const double ModBalancerT<D>::inv_log2_ = 1.0/std::log(2.0);
|
||||
|
||||
typedef ModBalancerT<Decimater> ModBalancer;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
std::string&
|
||||
replace_extension( std::string& _s, const std::string& _e )
|
||||
{
|
||||
std::string::size_type dot = _s.rfind(".");
|
||||
if (dot == std::string::npos)
|
||||
{ _s += "." + _e; }
|
||||
else
|
||||
{ _s = _s.substr(0,dot+1)+_e; }
|
||||
return _s;
|
||||
}
|
||||
|
||||
inline
|
||||
std::string
|
||||
basename(const std::string& _f)
|
||||
{
|
||||
std::string::size_type dot = _f.rfind("/");
|
||||
if (dot == std::string::npos)
|
||||
return _f;
|
||||
return _f.substr(dot+1, _f.length()-(dot+1));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void usage_and_exit(int xcode)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
cout << endl
|
||||
<< "Usage: mkbalancedpm [-n <decimation-steps>] [-o <output>] "
|
||||
<< "<input.ext>\n"
|
||||
<< endl
|
||||
<< " Create a balanced progressive mesh from an input file.\n"
|
||||
<< " By default decimate as much as possible and write the result\n"
|
||||
<< " to <input>.pm\n"
|
||||
<< endl
|
||||
<< "Options:\n"
|
||||
<< endl
|
||||
<< " -n <decimation-steps>\n"
|
||||
<< "\tDetermines the maximum number of decimation steps.\n"
|
||||
<< "\tDecimate as much as possible if the value is equal zero\n"
|
||||
<< "\tDefault value: 0\n"
|
||||
<< endl
|
||||
<< " -o <output>\n"
|
||||
<< "\tWrite resulting progressive mesh to the file named <output>\n"
|
||||
<< endl
|
||||
<< " -N\n"
|
||||
<< "\tEnable Normal Flipping\n"
|
||||
<< endl
|
||||
<< " -I\n"
|
||||
<< "\tEnable Independent Sets\n"
|
||||
<< endl;
|
||||
exit(xcode);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
int c;
|
||||
std::string ifname, ofname;
|
||||
size_t decstep=0;
|
||||
bool enable_modNF = false;
|
||||
bool enable_modIS = false;
|
||||
|
||||
while ((c=getopt(argc, argv, "n:o:NIh"))!=-1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'o': ofname = optarg; break;
|
||||
case 'n': { std::stringstream str; str << optarg; str >> decstep; } break;
|
||||
case 'N': enable_modNF = true; break;
|
||||
case 'I': enable_modIS = true; break;
|
||||
case 'h':
|
||||
usage_and_exit(0);
|
||||
default:
|
||||
usage_and_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
usage_and_exit(1);
|
||||
|
||||
ifname = argv[optind];
|
||||
|
||||
if (!OpenMesh::IO::read_mesh(mesh, ifname))
|
||||
{
|
||||
std::cerr << "Error loading mesh from file '" << ifname << "'!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
OpenMesh::Utils::Timer t;
|
||||
|
||||
Decimater decimater(mesh);
|
||||
|
||||
ModProgMesh::Handle modPM;
|
||||
ModBalancer::Handle modB;
|
||||
ModNormalFlipping::Handle modNF;
|
||||
ModIndependentSets::Handle modIS;
|
||||
|
||||
|
||||
decimater.add(modPM);
|
||||
std::cout << "w/ progressive mesh module\n";
|
||||
decimater.add(modB);
|
||||
std::cout << "w/ balancer module\n";
|
||||
|
||||
if ( enable_modNF )
|
||||
decimater.add(modNF);
|
||||
std::cout << "w/" << (modNF.is_valid() ? ' ' : 'o')
|
||||
<< " normal flipping module\n";
|
||||
|
||||
if ( enable_modIS )
|
||||
decimater.add(modIS);
|
||||
std::cout << "w/" << (modIS.is_valid() ? ' ' : 'o')
|
||||
<< " independent sets module\n";
|
||||
|
||||
std::cout << "Initialize decimater\n";
|
||||
t.start();
|
||||
if ( !decimater.initialize() )
|
||||
{
|
||||
std::cerr << " Initialization failed!\n";
|
||||
return 1;
|
||||
}
|
||||
t.stop();
|
||||
std::cout << " done [" << t.as_string() << "]\n";
|
||||
t.reset();
|
||||
|
||||
int rc;
|
||||
size_t nv = mesh.n_vertices();
|
||||
|
||||
std::cout << "Begin decimation (#V " << nv << ")\n";
|
||||
t.start();
|
||||
do
|
||||
{
|
||||
if (modIS.is_valid())
|
||||
{
|
||||
Mesh::VertexIter v_it;
|
||||
Mesh::FaceIter f_it;
|
||||
|
||||
for (f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it)
|
||||
if ( !mesh.status(f_it).deleted() )
|
||||
mesh.update_normal(f_it);
|
||||
|
||||
for (v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it)
|
||||
if ( !mesh.status(v_it).deleted() )
|
||||
{
|
||||
mesh.status(v_it).set_locked(false);
|
||||
mesh.update_normal(v_it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rc = decimater.decimate(decstep);
|
||||
t.stop();
|
||||
std::cout << '\r'
|
||||
<< (nv-=rc) << " (-" << rc << ") " << std::flush;
|
||||
t.cont();
|
||||
} while (rc > 0);
|
||||
t.stop();
|
||||
|
||||
std::cout << "\n done [" << t.as_string() << "]\n";
|
||||
|
||||
std::cout << "Bits for <tree-id, node-id>: <"
|
||||
<< decimater.module(modB).bits_for_roots() << ", "
|
||||
<< decimater.module(modB).max_level() << ">"
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "Maximum level reached: "
|
||||
<< decimater.module(modB).max_level() << std::endl;
|
||||
|
||||
if (ofname == "." || ofname == ".." )
|
||||
ofname += "/" + basename(ifname);
|
||||
std::string pmfname = ofname.empty() ? ifname : ofname;
|
||||
replace_extension(pmfname, "pm");
|
||||
|
||||
std::cout << "Write progressive mesh data to file "
|
||||
<< pmfname << std::endl;
|
||||
decimater.module(modPM).write( pmfname );
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.pro
Normal file
30
Apps/VDProgMesh/mkbalancedpm/mkbalancedpm.pro
Normal file
@@ -0,0 +1,30 @@
|
||||
################################################################################
|
||||
#
|
||||
################################################################################
|
||||
|
||||
contains( OPENFLIPPER , OpenFlipper ){
|
||||
include( $$TOPDIR/qmake/all.include )
|
||||
} else {
|
||||
include( $$TOPDIR/OpenMesh/qmake/all.include )
|
||||
}
|
||||
|
||||
INCLUDEPATH += ../../../..
|
||||
|
||||
CONFIG += glew glut
|
||||
|
||||
Application()
|
||||
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY} -lCore
|
||||
LIBS += -Wl,-rpath=$${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY} -lTools
|
||||
LIBS += -lglut
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Core/lib/$${BUILDDIRECTORY}
|
||||
QMAKE_LIBDIR += $${TOPDIR}/OpenMesh/Tools/lib/$${BUILDDIRECTORY}
|
||||
|
||||
DIRECTORIES = .
|
||||
|
||||
# Input
|
||||
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
|
||||
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
|
||||
|
||||
################################################################################
|
||||
Reference in New Issue
Block a user