⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdpmclientviewerwidget.cc

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 CC
📖 第 1 页 / 共 3 页
字号:

//== INCLUDES =================================================================

#ifdef _MSC_VER
#  pragma warning(disable: 4267 4311)
#endif

#include <iostream>
#include <fstream>
#include <map>

#include <qapplication.h>
#include <qdatetime.h>
#include <qfiledialog.h>
#include <qdatastream.h>
#ifdef ARCH_DARWIN#  include <glut.h>#else#  include <GL/glut.h>#endif

#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientViewerWidget.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>

// #include "ImageData.h"


using OpenMesh::VDPM::debug_print;
using OpenMesh::VDPM::set_debug_print;

using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::VHierarchyNodeHandleContainer;



#ifdef EXAMPLE_CREATION

static OpenMesh::Vec3uc myYellow  = OpenMesh::Vec3uc(255, 255, 0);
static OpenMesh::Vec3uc myBlue    = OpenMesh::Vec3uc(0, 0, 255);
std::map<VHierarchyNodeIndex, unsigned int> g_index2numdesc_map;

void VDPMClientViewerWidget::increase_max_descendents(const VHierarchyNodeIndex &_node_index)
{
  g_index2numdesc_map[_node_index] = 2 + g_index2numdesc_map[_node_index];

  unsigned char tree_id_bits = vhierarchy_.tree_id_bits();
  VHierarchyNodeIndex parent_index 
    = VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), _node_index.node_id(tree_id_bits) / 2, tree_id_bits);

  if (parent_index.is_valid(tree_id_bits) == true)
    increase_max_descendents(parent_index);
}

void VDPMClientViewerWidget::increase_cur_descendents(VHierarchyNodeHandle _node_handle)
{
  unsigned int cur_desc = vhierarchy_.node(_node_handle).cur_descendents();
 
  vhierarchy_.node(_node_handle).set_cur_descendents(2 + cur_desc);

  VHierarchyNodeHandle  parent_handle = vhierarchy_.parent_handle(_node_handle);
  if (parent_handle.is_valid())
    increase_cur_descendents(parent_handle);
}

void VDPMClientViewerWidget::__add_children(const VHierarchyNodeIndex &_node_index, bool update_current)
{
  if (update_current == true)
  {
    increase_cur_descendents(vhierarchy_.node_handle(_node_index));
  }
  else
  {
    unsigned char tree_id_bits = vhierarchy_.tree_id_bits();

    VHierarchyNodeIndex lchild_index 
      = VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), 2*_node_index.node_id(tree_id_bits), tree_id_bits);
    VHierarchyNodeIndex rchild_index 
      = VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), 1+2*_node_index.node_id(tree_id_bits), tree_id_bits);

    g_index2numdesc_map[lchild_index] = 1;
    g_index2numdesc_map[rchild_index] = 1;

    increase_max_descendents(_node_index);
  }
}

void VDPMClientViewerWidget::mesh_coloring()
{
  MyMesh::VertexIter  vIt(mesh_.vertices_begin()), 
                      vEnd(mesh_.vertices_end());

  VHierarchyNodeHandle  node_handle;
  float                 ratio;
  unsigned char         r, g, b;

  for (; vIt!=vEnd; ++vIt)
  {
    node_handle = mesh_.vertex(vIt.handle()).vhierarchy_node_handle(); 
    ratio = vhierarchy_.node(node_handle).ratio();
    
    r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]);
    g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]);
    b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]);

    mesh_.set_color(vIt.handle(), OpenMesh::Vec3uc(r,g,b));
  }
}

#endif



void
VDPMClientViewerWidget::
draw_scene(const std::string &_draw_mode)
{
  //std::cout << frame_ << "-th frame statistics" << std::endl;

  if (adaptive_mode_ == true)  
  {

    refinement_timer_.start();
    adaptive_refinement();
    refinement_timer_.stop();
    fprintf(refinement_file, "%d %d\n", frame_, (int) refinement_timer_.mseconds());

#ifdef EXAMPLE_CREATION
    mesh_coloring();
#endif
  }

  render_timer_.start();
  MeshViewerWidget::draw_scene(_draw_mode);  
  render_timer_.stop();
  fprintf(render_file, "%d %d %d\n", frame_, (int) render_timer_.mseconds(), mesh_.n_faces());

  ++frame_;
}


void
VDPMClientViewerWidget::
adaptive_refinement()
{
  update_viewing_parameters();

  MyMesh::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;


  for (vfront_.begin(); vfront_.end() != true;)
  {
    VHierarchyNodeHandle  
      node_handle   = vfront_.node_handle(),
      parent_handle = vhierarchy_.parent_handle(node_handle);

    if (qrefine(node_handle) == true)
    {
      if (vhierarchy_.is_leaf_node(node_handle) != true)
      {
        force_vsplit(node_handle);
      }
      else
      {
        //if (qSocket_->bytesAvailable() == 0)
        if (session_running_ != true)
        {
          session_running_ = true;
          send_viewing_information();
        }
        vfront_.next();
      }
    }
    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 taged as 'deleted'
  mesh_.garbage_collection(false, true, true); 
  mesh_.update_face_normals();
}


void
VDPMClientViewerWidget::
current_max_resolution()
{
  for (vfront_.begin(); vfront_.end() != true;)
  {
    VHierarchyNodeHandle
      node_handle   = vfront_.node_handle();
    if (vhierarchy_.is_leaf_node(node_handle) != true)
      force_vsplit(node_handle);
    else
      vfront_.next();
  }

  // free memories taged as 'deleted'
  mesh_.garbage_collection(false, true, true); 
  mesh_.update_face_normals();
}


bool
VDPMClientViewerWidget::
qrefine(VHierarchyNodeHandle _node_handle)
{
  VHierarchyNode &node = vhierarchy_.node(_node_handle);
  OpenMesh::Vec3f p = mesh_.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;
}


void 
VDPMClientViewerWidget::
force_vsplit(VHierarchyNodeHandle node_handle)
{
  MyMesh::VertexHandle  vl, vr;

  get_active_cuts(node_handle, vl, vr);

  while (vl == vr) {
    force_vsplit(mesh_.vertex(vl).vhierarchy_node_handle());
    get_active_cuts(node_handle, vl, vr);
  }
  
  vsplit(node_handle, vl, vr);
}



void
VDPMClientViewerWidget::
vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr)
{
  // refine
  VHierarchyNodeHandle  lchild_handle = vhierarchy_.lchild_handle(_node_handle);
  VHierarchyNodeHandle  rchild_handle = vhierarchy_.rchild_handle(_node_handle);
  MyMesh::VertexHandle  v0 = vhierarchy_.vertex_handle(lchild_handle);
  MyMesh::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_.vertex(v0).set_vhierarchy_node_handle(lchild_handle);
  mesh_.vertex(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 
VDPMClientViewerWidget::
ecol(VHierarchyNodeHandle _node_handle, const MyMesh::HalfedgeHandle& v0v1)
{
  VHierarchyNodeHandle  lchild_handle = vhierarchy_.lchild_handle(_node_handle);
  VHierarchyNodeHandle  rchild_handle = vhierarchy_.rchild_handle(_node_handle);
  MyMesh::VertexHandle  v0 = vhierarchy_.vertex_handle(lchild_handle);
  MyMesh::VertexHandle  v1 = vhierarchy_.vertex_handle(rchild_handle);

  // coarsen
  mesh_.collapse(v0v1);
  mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
  mesh_.vertex(v0).set_vhierarchy_node_handle(lchild_handle);
  mesh_.vertex(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
VDPMClientViewerWidget::
ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1)
{
  VHierarchyNodeHandle  lchild_handle = vhierarchy_.lchild_handle(_parent_handle);
  VHierarchyNodeHandle  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;  

  MyMesh::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
VDPMClientViewerWidget::
get_active_cuts(const VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr)
{
  MyMesh::VertexVertexIter  vv_it;
  VHierarchyNodeHandle      nnode_handle;
  VHierarchyNodeIndex       nnode_index;
  VHierarchyNodeIndex       fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle);
  VHierarchyNodeIndex       fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);

  vl = MyMesh::InvalidVertexHandle;
	vr = MyMesh::InvalidVertexHandle;
  
  for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle)); vv_it; ++vv_it)
	{
    nnode_handle = mesh_.vertex(vv_it.handle()).vhierarchy_node_handle();
    nnode_index = vhierarchy_.node_index(nnode_handle);

    if (vl == MyMesh::InvalidVertexHandle && vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) == true)
      vl = vv_it.handle();
    if (vr == MyMesh::InvalidVertexHandle && vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) == true)
      vr = vv_it.handle();

    /*if (vl == MyMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_lcut_index) == true)
      vl = vv_it.handle();
    if (vr == MyMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_rcut_index) == true)
      vr = vv_it.handle();*/

    if (vl != MyMesh::InvalidVertexHandle && vr != MyMesh::InvalidVertexHandle)
      break;
	}
}

bool 
VDPMClientViewerWidget::
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 
VDPMClientViewerWidget::
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 
VDPMClientViewerWidget::
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
VDPMClientViewerWidget::
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;
  VHierarchyNodeHandleContainer   roots;
  OpenMesh::VertexHandle          vertex_handle;  
  VHierarchyNodeIndex             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";
    exit(1);
  }

  //
  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();
    exit(1);
  }
  OpenMesh::IO::restore(ifs, n_base_vertices_, swap);
  OpenMesh::IO::restore(ifs, n_base_faces_, swap);
  OpenMesh::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)
  {
    OpenMesh::IO::restore(ifs, p, swap);
    OpenMesh::IO::restore(ifs, radius, swap);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -