+ AABB demo: use a moving plane for distance functions

This commit is contained in:
Stéphane Tayeb 2010-05-19 06:35:59 +00:00
parent 1297288d46
commit d8e443c68e
9 changed files with 438 additions and 379 deletions

View File

@ -268,6 +268,7 @@ void MainWindow::on_actionBench_intersections_triggered()
void MainWindow::on_actionUnsigned_distance_function_to_facets_triggered()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
m_pScene->activate_cutting_plane();
m_pScene->unsigned_distance_function();
QApplication::restoreOverrideCursor();
m_pViewer->update();
@ -276,6 +277,7 @@ void MainWindow::on_actionUnsigned_distance_function_to_facets_triggered()
void MainWindow::on_actionUnsigned_distance_function_to_edges_triggered()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
m_pScene->activate_cutting_plane();
m_pScene->unsigned_distance_function_to_edges();
QApplication::restoreOverrideCursor();
m_pViewer->update();
@ -284,20 +286,27 @@ void MainWindow::on_actionUnsigned_distance_function_to_edges_triggered()
void MainWindow::on_actionSigned_distance_function_to_facets_triggered()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
m_pScene->activate_cutting_plane();
m_pScene->signed_distance_function();
QApplication::restoreOverrideCursor();
m_pViewer->update();
}
void MainWindow::on_actionCutting_plane_triggered()
void MainWindow::on_actionIntersection_cutting_plane_triggered()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
m_pScene->activate_cutting_plane();
m_pScene->cutting_plane();
m_pScene->cut_segment_plane();
QApplication::restoreOverrideCursor();
m_pViewer->update();
}
void MainWindow::on_actionCutting_plane_none_triggered()
{
m_pScene->deactivate_cutting_plane();
m_pViewer->update();
}
void MainWindow::on_actionView_polyhedron_triggered()
{
m_pScene->toggle_view_poyhedron();
@ -316,12 +325,6 @@ void MainWindow::on_actionView_segments_triggered()
m_pViewer->update();
}
void MainWindow::on_actionView_distance_function_triggered()
{
m_pScene->toggle_view_distance_function();
m_pViewer->update();
}
void MainWindow::on_actionView_cutting_plane_triggered()
{
m_pScene->toggle_view_plane();
@ -340,12 +343,6 @@ void MainWindow::on_actionClear_segments_triggered()
m_pViewer->update();
}
void MainWindow::on_actionClear_distance_function_triggered()
{
m_pScene->clear_distance_function();
m_pViewer->update();
}
void MainWindow::on_actionClear_cutting_plane_triggered()
{
m_pScene->clear_cutting_plane();

View File

@ -46,7 +46,6 @@ public:
void on_actionCopy_snapshot_triggered();
void on_actionClear_points_triggered();
void on_actionClear_segments_triggered();
void on_actionClear_distance_function_triggered();
void on_actionClear_cutting_plane_triggered();
// algorithm menu
@ -60,7 +59,8 @@ public:
void on_actionSigned_distance_function_to_facets_triggered();
void on_actionUnsigned_distance_function_to_edges_triggered();
void on_actionUnsigned_distance_function_to_facets_triggered();
void on_actionCutting_plane_triggered();
void on_actionIntersection_cutting_plane_triggered();
void on_actionCutting_plane_none_triggered();
// benchmark menu
void on_actionBench_memory_triggered();
@ -76,7 +76,6 @@ public:
void on_actionView_points_triggered();
void on_actionView_segments_triggered();
void on_actionView_polyhedron_triggered();
void on_actionView_distance_function_triggered();
void on_actionView_cutting_plane_triggered();
private:

View File

@ -17,14 +17,14 @@
<normaloff>:/cgal/icons/resources/cgal_logo.xpm</normaloff>:/cgal/icons/resources/cgal_logo.xpm</iconset>
</property>
<property name="locale">
<locale country="UnitedStates" language="English" />
<locale language="English" country="UnitedStates"/>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="Viewer" native="1" name="viewer" >
<widget class="Viewer" name="viewer" native="true">
<property name="locale">
<locale country="UnitedStates" language="English" />
<locale language="English" country="UnitedStates"/>
</property>
</widget>
</item>
@ -36,7 +36,7 @@
<x>0</x>
<y>0</y>
<width>638</width>
<height>21</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -55,7 +55,6 @@
<addaction name="actionView_cutting_plane"/>
<addaction name="actionView_segments"/>
<addaction name="actionView_polyhedron"/>
<addaction name="actionView_distance_function" />
</widget>
<widget class="QMenu" name="menuAlgorithms">
<property name="title">
@ -72,8 +71,8 @@
<property name="title">
<string>Cut plane</string>
</property>
<addaction name="actionNone" />
<addaction name="actionCutting_plane" />
<addaction name="actionCutting_plane_none"/>
<addaction name="actionIntersection_cutting_plane"/>
<addaction name="actionSigned_distance_function_to_facets"/>
<addaction name="actionUnsigned_distance_function_to_facets"/>
<addaction name="actionUnsigned_distance_function_to_edges"/>
@ -110,7 +109,6 @@
</property>
<addaction name="actionClear_points"/>
<addaction name="actionClear_segments"/>
<addaction name="actionClear_distance_function" />
<addaction name="actionClear_cutting_plane"/>
<addaction name="separator"/>
<addaction name="actionCopy_snapshot"/>
@ -268,7 +266,7 @@
<string>Loop subdivision</string>
</property>
</action>
<action name="actionCutting_plane" >
<action name="actionIntersection_cutting_plane">
<property name="text">
<string>Intersection</string>
</property>
@ -283,7 +281,7 @@
<string>Clear cutting plane</string>
</property>
</action>
<action name="actionNone" >
<action name="actionCutting_plane_none">
<property name="text">
<string>None</string>
</property>

View File

@ -16,9 +16,16 @@
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Subdivision_method_3.h>
// constants
const double slow_distance_grid_size = 100;
const double fast_distance_grid_size = 20;
Scene::Scene()
: m_frame (new ManipulatedFrame())
, m_view_plane(false)
, m_grid_size(slow_distance_grid_size)
, m_cut_plane(NONE)
{
m_pPolyhedron = NULL;
@ -26,13 +33,11 @@ Scene::Scene()
m_view_points = true;
m_view_segments = true;
m_view_polyhedron = true;
m_view_distance_function = true;
// distance function
m_red_ramp.build_red();
m_blue_ramp.build_blue();
m_max_distance_function = (FT)0.0;
m_signed_distance_function = false;
}
Scene::~Scene()
@ -122,17 +127,23 @@ void Scene::draw()
if(m_view_segments)
draw_segments();
if(m_view_distance_function)
{
if(m_signed_distance_function)
draw_signed_distance_function();
else
draw_unsigned_distance_function();
}
if (m_view_plane)
{
draw_plane();
switch( m_cut_plane )
{
case UNSIGNED_EDGES:
case UNSIGNED_FACETS:
draw_distance_function(m_thermal_ramp, m_thermal_ramp);
break;
case SIGNED_FACETS:
draw_distance_function(m_red_ramp, m_blue_ramp);
break;
case CUT_SEGMENTS:
draw_cut_segment_plane();
break;
case NONE: // do nothing
break;
}
}
}
@ -188,75 +199,32 @@ void Scene::draw_points()
}
}
void Scene::draw_unsigned_distance_function()
void Scene::draw_distance_function(const Color_ramp& ramp_pos,
const Color_ramp& ramp_neg) const
{
if(m_max_distance_function == (FT)0.0)
return;
::glDisable(GL_LIGHTING);
::glShadeModel(GL_SMOOTH);
if ( m_fast_distance ) { ::glShadeModel(GL_FLAT); }
else { ::glShadeModel(GL_SMOOTH); }
::glBegin(GL_QUADS);
int i,j;
const int nb_quads = 99;
const int nb_quads = m_grid_size-1;
for(i=0;i<nb_quads;i++)
{
for(j=0;j<nb_quads;j++)
{
Point_distance& pd00 = m_distance_function[i][j];
Point_distance& pd01 = m_distance_function[i][j+1];
Point_distance& pd11 = m_distance_function[i+1][j+1];
Point_distance& pd10 = m_distance_function[i+1][j];
Point& p00 = pd00.first;
Point& p01 = pd01.first;
Point& p11 = pd11.first;
Point& p10 = pd10.first;
FT& d00 = pd00.second;
FT& d01 = pd01.second;
FT& d11 = pd11.second;
FT& d10 = pd10.second;
unsigned int i00 = 255-(unsigned int)(255.0 * d00 / m_max_distance_function);
unsigned int i01 = 255-(unsigned int)(255.0 * d01 / m_max_distance_function);
unsigned int i11 = 255-(unsigned int)(255.0 * d11 / m_max_distance_function);
unsigned int i10 = 255-(unsigned int)(255.0 * d10 / m_max_distance_function);
::glColor3ub(m_thermal_ramp.r(i00),m_thermal_ramp.g(i00),m_thermal_ramp.b(i00));
::glVertex3d(p00.x(),p00.y(),p00.z());
::glColor3ub(m_thermal_ramp.r(i01),m_thermal_ramp.g(i01),m_thermal_ramp.b(i01));
::glVertex3d(p01.x(),p01.y(),p01.z());
::glColor3ub(m_thermal_ramp.r(i11),m_thermal_ramp.g(i11),m_thermal_ramp.b(i11));
::glVertex3d(p11.x(),p11.y(),p11.z());
::glColor3ub(m_thermal_ramp.r(i10),m_thermal_ramp.g(i10),m_thermal_ramp.b(i10));
::glVertex3d(p10.x(),p10.y(),p10.z());
}
}
::glEnd();
}
void Scene::draw_signed_distance_function()
{
if(m_max_distance_function == (FT)0.0)
return;
::glDisable(GL_LIGHTING);
::glShadeModel(GL_SMOOTH);
::glBegin(GL_QUADS);
int i,j;
const int nb_quads = 99;
for(i=0;i<nb_quads;i++)
{
for(j=0;j<nb_quads;j++)
{
Point_distance& pd00 = m_distance_function[i][j];
Point_distance& pd01 = m_distance_function[i][j+1];
Point_distance& pd11 = m_distance_function[i+1][j+1];
Point_distance& pd10 = m_distance_function[i+1][j];
Point& p00 = pd00.first;
Point& p01 = pd01.first;
Point& p11 = pd11.first;
Point& p10 = pd10.first;
FT& d00 = pd00.second;
FT& d01 = pd01.second;
FT& d11 = pd11.second;
FT& d10 = pd10.second;
const Point_distance& pd00 = m_distance_function[i][j];
const Point_distance& pd01 = m_distance_function[i][j+1];
const Point_distance& pd11 = m_distance_function[i+1][j+1];
const Point_distance& pd10 = m_distance_function[i+1][j];
const Point& p00 = pd00.first;
const Point& p01 = pd01.first;
const Point& p11 = pd11.first;
const Point& p10 = pd10.first;
const FT& d00 = pd00.second;
const FT& d01 = pd01.second;
const FT& d11 = pd11.second;
const FT& d10 = pd10.second;
// determines grey level
unsigned int i00 = 255-(unsigned)(255.0 * (double)std::fabs(d00) / m_max_distance_function);
@ -266,39 +234,36 @@ void Scene::draw_signed_distance_function()
// assembles one quad
if(d00 > 0.0)
::glColor3ub(m_red_ramp.r(i00),m_red_ramp.g(i00),m_red_ramp.b(i00));
::glColor3ub(ramp_pos.r(i00),ramp_pos.g(i00),ramp_pos.b(i00));
else
::glColor3ub(m_blue_ramp.r(i00),m_blue_ramp.g(i00),m_blue_ramp.b(i00));
::glColor3ub(ramp_neg.r(i00),ramp_neg.g(i00),ramp_neg.b(i00));
::glVertex3d(p00.x(),p00.y(),p00.z());
if(d01 > 0.0)
::glColor3ub(m_red_ramp.r(i01),m_red_ramp.g(i01),m_red_ramp.b(i01));
::glColor3ub(ramp_pos.r(i01),ramp_pos.g(i01),ramp_pos.b(i01));
else
::glColor3ub(m_blue_ramp.r(i01),m_blue_ramp.g(i01),m_blue_ramp.b(i01));
::glColor3ub(ramp_neg.r(i01),ramp_neg.g(i01),ramp_neg.b(i01));
::glVertex3d(p01.x(),p01.y(),p01.z());
if(d11 > 0)
::glColor3ub(m_red_ramp.r(i11),m_red_ramp.g(i11),m_red_ramp.b(i11));
::glColor3ub(ramp_pos.r(i11),ramp_pos.g(i11),ramp_pos.b(i11));
else
::glColor3ub(m_blue_ramp.r(i11),m_blue_ramp.g(i11),m_blue_ramp.b(i11));
::glColor3ub(ramp_neg.r(i11),ramp_neg.g(i11),ramp_neg.b(i11));
::glVertex3d(p11.x(),p11.y(),p11.z());
if(d10 > 0)
::glColor3ub(m_red_ramp.r(i10),m_red_ramp.g(i10),m_red_ramp.b(i10));
::glColor3ub(ramp_pos.r(i10),ramp_pos.g(i10),ramp_pos.b(i10));
else
::glColor3ub(m_blue_ramp.r(i10),m_blue_ramp.g(i10),m_blue_ramp.b(i10));
::glColor3ub(ramp_neg.r(i10),ramp_neg.g(i10),ramp_neg.b(i10));
::glVertex3d(p10.x(),p10.y(),p10.z());
}
}
::glEnd();
}
void Scene::draw_plane()
void Scene::draw_cut_segment_plane() const
{
double dx = m_bbox.xmax()-m_bbox.xmin();
double dy = m_bbox.ymax()-m_bbox.ymin();
double dz = m_bbox.zmax()-m_bbox.zmin();
float diag = .6f * float(std::sqrt(dx*dx + dy*dy + dz*dz));
float diag = .6f * float(bbox_diag());
::glDisable(GL_LIGHTING);
::glLineWidth(1.0f);
@ -314,7 +279,7 @@ void Scene::draw_plane()
::glLineWidth(2.0f);
::glColor3f(1.f, 0.f, 0.f);
::glBegin(GL_LINES);
for ( std::vector<Segment>::iterator it = m_cut_segments.begin(),
for ( std::vector<Segment>::const_iterator it = m_cut_segments.begin(),
end = m_cut_segments.end() ; it != end ; ++it )
{
const Point& a = it->source();
@ -402,6 +367,25 @@ Plane Scene::frame_plane() const
return Plane(n[0], n[1], n[2], - n * pos);
}
Aff_transformation Scene::frame_transformation() const
{
const ::GLdouble* m = m_frame->matrix();
// OpenGL matrices are row-major matrices
return Aff_transformation (m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14]);
}
FT Scene::bbox_diag() const
{
double dx = m_bbox.xmax()-m_bbox.xmin();
double dy = m_bbox.ymax()-m_bbox.ymin();
double dz = m_bbox.zmax()-m_bbox.zmin();
return FT(std::sqrt(dx*dx + dy*dy + dz*dz));
}
void Scene::build_facet_tree()
{
if ( NULL == m_pPolyhedron )
@ -416,27 +400,56 @@ void Scene::build_facet_tree()
// build tree
CGAL::Timer timer;
timer.start();
std::cout << "Construct AABB tree...";
std::cout << "Construct Facet AABB tree...";
m_facet_tree.rebuild(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end());
m_facet_tree.accelerate_distance_queries();
std::cout << "done (" << timer.time() << " s)" << std::endl;
}
void Scene::build_edge_tree()
{
if ( NULL == m_pPolyhedron )
{
std::cerr << "Build edge tree failed: load polyhedron first." << std::endl;
return;
}
// ensure tree is empty
m_edge_tree.clear();
// build tree
CGAL::Timer timer;
timer.start();
std::cout << "Construct Edge AABB tree...";
m_edge_tree.rebuild(m_pPolyhedron->edges_begin(),m_pPolyhedron->edges_end());
m_edge_tree.accelerate_distance_queries();
std::cout << "done (" << timer.time() << " s)" << std::endl;
}
void Scene::clear_internal_data()
{
m_facet_tree.clear();
m_edge_tree.clear();
clear_points();
clear_segments();
clear_distance_function();
clear_cutting_plane();
}
void Scene::clear_cutting_plane()
{
m_cut_segments.clear();
m_cut_plane = NONE;
deactivate_cutting_plane();
}
void Scene::update_grid_size()
{
m_grid_size = m_fast_distance ? fast_distance_grid_size
: slow_distance_grid_size;
}
void Scene::generate_points_in(const unsigned int nb_points,
const double min,
const double max)
@ -679,131 +692,104 @@ void Scene::generate_edge_points(const unsigned int nb_points)
std::cout << nb_planes << " plane queries, " << timer.time() << " s." << std::endl;
}
template <typename Tree>
void Scene::compute_distance_function(const Tree& tree)
{
// Get transformation
Aff_transformation t = frame_transformation();
m_max_distance_function = FT(0);
FT diag = bbox_diag();
const FT dx = diag;
const FT dy = diag;
const FT z (0);
for(int i=0 ; i<m_grid_size ; ++i)
{
FT x = -diag/FT(2) + FT(i)/FT(m_grid_size) * dx;
for(int j=0 ; j<m_grid_size ; ++j)
{
FT y = -diag/FT(2) + FT(j)/FT(m_grid_size) * dy;
Point query = t( Point(x,y,z) );
FT dist = CGAL::sqrt( tree.squared_distance(query) );
m_distance_function[i][j] = Point_distance(query,dist);
m_max_distance_function = (std::max)(dist, m_max_distance_function);
}
}
}
template <typename Tree>
void Scene::sign_distance_function(const Tree& tree)
{
Vector random_vec = random_vector();
for(int i=0 ; i<m_grid_size ; ++i)
{
for(int j=0 ; j<m_grid_size ; ++j)
{
const Point& p = m_distance_function[i][j].first;
const FT unsigned_distance = m_distance_function[i][j].second;
// get sign through ray casting (random vector)
Ray ray(p, random_vec);
unsigned int nbi = tree.number_of_intersected_primitives(ray);
FT sign ( (nbi&1) == 0 ? 1 : -1);
m_distance_function[i][j].second = sign * unsigned_distance;
}
}
}
void Scene::unsigned_distance_function()
{
if(m_pPolyhedron == NULL)
// Build tree if needed
if ( m_facet_tree.empty() )
{
std::cout << "Load polyhedron first." << std::endl;
return;
build_facet_tree();
}
CGAL::Timer timer;
timer.start();
std::cout << "Construct AABB tree...";
Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end());
tree.accelerate_distance_queries();
std::cout << "done (" << timer.time() << " s)" << std::endl;
compute_distance_function(m_facet_tree);
m_max_distance_function = (FT)0.0;
int i,j;
const double dx = m_bbox.xmax() - m_bbox.xmin();
const double dy = m_bbox.ymax() - m_bbox.ymin();
const double z = 0.5 * (m_bbox.zmax() + m_bbox.zmin());
for(i=0;i<100;i++)
{
FT x = m_bbox.xmin() + (FT)((double)i/100.0 * dx);
for(j=0;j<100;j++)
{
FT y = m_bbox.ymin() + (FT)((double)j/100.0 * dy);
Point query(x,y,z);
FT sq_distance = tree.squared_distance(query);
FT distance = std::sqrt(sq_distance);
m_distance_function[i][j] = Point_distance(query,distance);
m_max_distance_function = distance > m_max_distance_function ?
distance : m_max_distance_function;
}
}
m_signed_distance_function = false;
m_cut_plane = UNSIGNED_FACETS;
}
void Scene::unsigned_distance_function_to_edges()
{
if(m_pPolyhedron == NULL)
// Build tree if needed
if ( m_edge_tree.empty() )
{
std::cout << "Load polyhedron first." << std::endl;
return;
build_edge_tree();
}
typedef CGAL::AABB_polyhedron_segment_primitive<Kernel,Polyhedron> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Edge_tree;
compute_distance_function(m_edge_tree);
CGAL::Timer timer;
timer.start();
std::cout << "Construct AABB tree from edges...";
Edge_tree tree(m_pPolyhedron->edges_begin(),m_pPolyhedron->edges_end());
tree.accelerate_distance_queries();
std::cout << "done (" << timer.time() << " s)" << std::endl;
m_cut_plane = UNSIGNED_EDGES;
}
m_max_distance_function = (FT)0.0;
const double dx = m_bbox.xmax() - m_bbox.xmin();
const double dy = m_bbox.ymax() - m_bbox.ymin();
const double z = 0.5 * (m_bbox.zmax() + m_bbox.zmin());
int i,j;
for(i=0;i<100;i++)
{
FT x = m_bbox.xmin() + (FT)((double)i/100.0 * dx);
for(j=0;j<100;j++)
{
FT y = m_bbox.ymin() + (FT)((double)j/100.0 * dy);
Point query(x,y,z);
FT sq_distance = tree.squared_distance(query);
FT distance = std::sqrt(sq_distance);
m_distance_function[i][j] = Point_distance(query,distance);
m_max_distance_function = distance > m_max_distance_function ?
distance : m_max_distance_function;
}
}
m_signed_distance_function = false;
}
void Scene::signed_distance_function()
{
if(m_pPolyhedron == NULL)
// Build tree if needed
if ( m_facet_tree.empty() )
{
std::cout << "Load polyhedron first." << std::endl;
return;
build_facet_tree();
}
CGAL::Timer timer;
timer.start();
std::cout << "Construct AABB tree...";
Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end());
tree.accelerate_distance_queries();
std::cout << "done (" << timer.time() << " s)" << std::endl;
compute_distance_function(m_facet_tree);
sign_distance_function(m_facet_tree);
m_max_distance_function = (FT)0.0;
Vector vec = random_vector();
const double dx = m_bbox.xmax() - m_bbox.xmin();
const double dy = m_bbox.ymax() - m_bbox.ymin();
const double z = 0.5 * (m_bbox.zmax() + m_bbox.zmin());
int i,j;
for(i=0;i<100;i++)
{
FT x = m_bbox.xmin() + (FT)((double)i/100.0 * dx);
for(j=0;j<100;j++)
{
FT y = m_bbox.ymin() + (FT)((double)j/100.0 * dy);
Point query(x,y,z);
FT sq_distance = tree.squared_distance(query);
FT unsigned_distance = std::sqrt(sq_distance);
// get sign through ray casting (random vector)
Ray ray(query,vec);
unsigned int nbi = tree.number_of_intersected_primitives(ray);
FT sign = nbi%2 == 0 ? (FT)1.0 : (FT)-1.0;
FT signed_distance = sign * unsigned_distance;
m_distance_function[i][j] = Point_distance(query,signed_distance);
m_max_distance_function = unsigned_distance > m_max_distance_function ?
unsigned_distance : m_max_distance_function;
}
}
m_signed_distance_function = true;
m_cut_plane = SIGNED_FACETS;
}
void Scene::cutting_plane()
void Scene::cut_segment_plane()
{
// Build tree if needed
if ( m_facet_tree.empty() )
@ -814,12 +800,13 @@ void Scene::cutting_plane()
Plane plane = frame_plane();
// Compute intersections
std::vector<Object_and_primitive_id> intersections;
typedef std::vector<Facet_tree::Object_and_primitive_id> Intersections;
Intersections intersections;
m_facet_tree.all_intersections(plane, std::back_inserter(intersections));
// Fill data structure
m_cut_segments.clear();
for ( std::vector<Object_and_primitive_id>::iterator it = intersections.begin(),
for ( Intersections::iterator it = intersections.begin(),
end = intersections.end() ; it != end ; ++it )
{
const Segment* inter_seg = CGAL::object_cast<Segment>(&(it->first));
@ -829,6 +816,29 @@ void Scene::cutting_plane()
m_cut_segments.push_back(*inter_seg);
}
}
m_cut_plane = CUT_SEGMENTS;
}
void Scene::cutting_plane()
{
switch( m_cut_plane )
{
case UNSIGNED_FACETS:
return unsigned_distance_function();
case SIGNED_FACETS:
return signed_distance_function();
case UNSIGNED_EDGES:
return unsigned_distance_function_to_edges();
case CUT_SEGMENTS:
return cut_segment_plane();
case NONE: // do nothing
return;
}
// Should not be here
std::cerr << "Unknown cut_plane type" << std::endl;
CGAL_assertion(false);
}
void Scene::toggle_view_poyhedron()
@ -846,11 +856,6 @@ void Scene::toggle_view_points()
m_view_points = !m_view_points;
}
void Scene::toggle_view_distance_function()
{
m_view_distance_function = !m_view_distance_function;
}
void Scene::toggle_view_plane()
{
m_view_plane = !m_view_plane;

View File

@ -27,14 +27,22 @@ public:
public:
// types
typedef CGAL::Bbox_3 Bbox;
typedef CGAL::AABB_polyhedron_triangle_primitive<Kernel,Polyhedron> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Facet_tree;
typedef Facet_tree::Object_and_primitive_id Object_and_primitive_id;
typedef Facet_tree::Primitive_id Primitive_id;
private:
typedef CGAL::AABB_polyhedron_triangle_primitive<Kernel,Polyhedron> Facet_Primitive;
typedef CGAL::AABB_traits<Kernel, Facet_Primitive> Facet_Traits;
typedef CGAL::AABB_tree<Facet_Traits> Facet_tree;
typedef CGAL::AABB_polyhedron_segment_primitive<Kernel,Polyhedron> Edge_Primitive;
typedef CGAL::AABB_traits<Kernel, Edge_Primitive> Edge_Traits;
typedef CGAL::AABB_tree<Edge_Traits> Edge_tree;
typedef qglviewer::ManipulatedFrame ManipulatedFrame;
enum Cut_planes_types {
NONE, UNSIGNED_FACETS, SIGNED_FACETS, UNSIGNED_EDGES, CUT_SEGMENTS
};
public:
void draw();
void update_bbox();
@ -54,17 +62,20 @@ private:
Color_ramp m_blue_ramp;
Color_ramp m_thermal_ramp;
FT m_max_distance_function;
bool m_view_distance_function;
bool m_signed_distance_function;
typedef std::pair<Point,FT> Point_distance;
Point_distance m_distance_function[100][100];
// frame
ManipulatedFrame* m_frame;
bool m_view_plane;
int m_grid_size;
bool m_fast_distance;
// An aabb_tree indexing polyhedron facets
// An aabb_tree indexing polyhedron facets/segments
Facet_tree m_facet_tree;
Edge_tree m_edge_tree;
Cut_planes_types m_cut_plane;
private:
// utility functions
@ -76,8 +87,18 @@ private:
Segment random_segment(const Bbox& bbox);
FT random_in(const double a,const double b);
Plane frame_plane() const;
Aff_transformation frame_transformation() const;
FT bbox_diag() const;
void build_facet_tree();
void build_edge_tree();
void clear_internal_data();
void update_grid_size();
template <typename Tree>
void compute_distance_function(const Tree& tree);
template <typename Tree>
void sign_distance_function(const Tree& tree);
public:
// file menu
@ -86,9 +107,11 @@ public:
// edit menu
void clear_points() { m_points.clear(); }
void clear_segments() { m_segments.clear(); }
void clear_distance_function() { m_max_distance_function = 0.0; }
void clear_cutting_plane();
// fast distance setter
void set_fast_distance(bool b) { m_fast_distance = b; update_grid_size(); }
// algorithms
void generate_edge_points(const unsigned int nb_points);
void generate_inside_points(const unsigned int nb_points);
@ -105,12 +128,12 @@ public:
void signed_distance_function();
void unsigned_distance_function();
void unsigned_distance_function_to_edges();
void cut_segment_plane();
// toggle view options
void toggle_view_points();
void toggle_view_segments();
void toggle_view_poyhedron();
void toggle_view_distance_function();
void toggle_view_plane();
// view options
@ -154,9 +177,9 @@ public:
void draw_points();
void draw_segments();
void draw_polyhedron();
void draw_signed_distance_function();
void draw_unsigned_distance_function();
void draw_plane();
void draw_distance_function(const Color_ramp& ramp_pos,
const Color_ramp& ramp_neg) const;
void draw_cut_segment_plane() const;
// cutting plane activation/deactivation
void activate_cutting_plane();

View File

@ -1,9 +1,11 @@
#include "Viewer.h"
#include "Scene.h"
#include <QMouseEvent>
Viewer::Viewer(QWidget* parent)
: QGLViewer(parent),
m_pScene(NULL)
m_pScene(NULL),
m_custom_mouse(false)
{
setBackgroundColor(::Qt::white);
}
@ -28,3 +30,32 @@ void Viewer::initializeGL()
QGLViewer::initializeGL();
}
void Viewer::mousePressEvent(QMouseEvent* e)
{
if ( e->modifiers() == Qt::ControlModifier )
{
m_pScene->set_fast_distance(true);
m_custom_mouse = true;
}
QGLViewer::mousePressEvent(e);
}
void Viewer::mouseReleaseEvent(QMouseEvent* e)
{
if ( m_custom_mouse )
{
m_pScene->set_fast_distance(false);
// Recompute distance function
QApplication::setOverrideCursor(Qt::WaitCursor);
m_pScene->cutting_plane();
QApplication::restoreOverrideCursor();
m_custom_mouse = false;
}
QGLViewer::mouseReleaseEvent(e);
}

View File

@ -19,8 +19,13 @@ public:
void initializeGL();
void setScene(Scene* pScene);
protected:
virtual void mousePressEvent(QMouseEvent* e);
virtual void mouseReleaseEvent(QMouseEvent* e);
private:
Scene* m_pScene;
bool m_custom_mouse;
}; // end class Viewer
#endif // VIEWER_H

View File

@ -204,7 +204,7 @@ void Scene::bench_intersections_vs_nbt()
// calls ray queries
CGAL::Timer timer;
timer.start();
std::list<Object_and_primitive_id> intersections;
std::list<Facet_tree::Object_and_primitive_id> intersections;
for(int i=0;i<nb_queries;i++)
tree.all_intersections(queries[i],std::back_inserter(intersections));
double duration = timer.time();
@ -268,8 +268,8 @@ void Scene::bench_intersection(Facet_tree& tree,
CGAL::Timer timer;
timer.start();
unsigned int nb = 0;
std::list<Primitive_id> primitive_ids;
std::list<Object_and_primitive_id> intersections;
std::list<Facet_tree::Primitive_id> primitive_ids;
std::list<Facet_tree::Object_and_primitive_id> intersections;
while(timer.time() < duration)
{
const Query& query = queries[nb % nb_queries]; // loop over vector

View File

@ -13,6 +13,7 @@ typedef Kernel::Plane_3 Plane;
typedef Kernel::Vector_3 Vector;
typedef Kernel::Segment_3 Segment;
typedef Kernel::Triangle_3 Triangle;
typedef Kernel::Aff_transformation_3 Aff_transformation;
#include <CGAL/Polyhedron_3.h>
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;