Files
openmesh/Apps/Deprecated/Streaming/Server/VDPMServerSession.cc
Jan Möbius 97f515985d First checkin for OpenMesh 2.0
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
2009-02-06 13:37:46 +00:00

468 lines
12 KiB
C++

#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;
}