+ 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

@ -1,7 +1,7 @@
<ui version="4.0" >
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@ -9,282 +9,280 @@
<height>495</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>CGAL AABB tree demo</string>
</property>
<property name="windowIcon" >
<iconset resource="AABB_demo.qrc" >
<property name="windowIcon">
<iconset resource="AABB_demo.qrc">
<normaloff>:/cgal/icons/resources/cgal_logo.xpm</normaloff>:/cgal/icons/resources/cgal_logo.xpm</iconset>
</property>
<property name="locale" >
<locale country="UnitedStates" language="English" />
<property name="locale">
<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" >
<property name="locale" >
<locale country="UnitedStates" language="English" />
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="Viewer" name="viewer" native="true">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>638</width>
<height>21</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<property name="title" >
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionLoadPolyhedron" />
<addaction name="separator" />
<addaction name="actionQuit" />
<addaction name="actionLoadPolyhedron"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuView" >
<property name="title" >
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="actionView_points" />
<addaction name="actionView_cutting_plane" />
<addaction name="actionView_segments" />
<addaction name="actionView_polyhedron" />
<addaction name="actionView_distance_function" />
<addaction name="actionView_points"/>
<addaction name="actionView_cutting_plane"/>
<addaction name="actionView_segments"/>
<addaction name="actionView_polyhedron"/>
</widget>
<widget class="QMenu" name="menuAlgorithms" >
<property name="title" >
<widget class="QMenu" name="menuAlgorithms">
<property name="title">
<string>Algorithms</string>
</property>
<widget class="QMenu" name="menuRefine" >
<property name="title" >
<widget class="QMenu" name="menuRefine">
<property name="title">
<string>Refine</string>
</property>
<addaction name="actionRefine_bisection" />
<addaction name="actionRefine_loop" />
<addaction name="actionRefine_bisection"/>
<addaction name="actionRefine_loop"/>
</widget>
<widget class="QMenu" name="menuCut_plane" >
<property name="title" >
<widget class="QMenu" name="menuCut_plane">
<property name="title">
<string>Cut plane</string>
</property>
<addaction name="actionNone" />
<addaction name="actionCutting_plane" />
<addaction name="actionSigned_distance_function_to_facets" />
<addaction name="actionUnsigned_distance_function_to_facets" />
<addaction name="actionUnsigned_distance_function_to_edges" />
<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"/>
</widget>
<addaction name="actionEdge_points" />
<addaction name="actionInside_points" />
<addaction name="actionPoints_in_interval" />
<addaction name="actionBoundary_points" />
<addaction name="actionBoundary_segments" />
<addaction name="separator" />
<addaction name="menuCut_plane" />
<addaction name="menuRefine" />
<addaction name="actionEdge_points"/>
<addaction name="actionInside_points"/>
<addaction name="actionPoints_in_interval"/>
<addaction name="actionBoundary_points"/>
<addaction name="actionBoundary_segments"/>
<addaction name="separator"/>
<addaction name="menuCut_plane"/>
<addaction name="menuRefine"/>
</widget>
<widget class="QMenu" name="menuBenchmarks" >
<property name="title" >
<widget class="QMenu" name="menuBenchmarks">
<property name="title">
<string>Benchmark</string>
</property>
<widget class="QMenu" name="menuAgainst_triangles" >
<property name="title" >
<widget class="QMenu" name="menuAgainst_triangles">
<property name="title">
<string>Against #triangles</string>
</property>
<addaction name="actionBench_memory" />
<addaction name="actionBench_construction" />
<addaction name="actionBench_intersections_vs_nbt" />
<addaction name="actionBench_distances_vs_nbt" />
<addaction name="actionBench_memory"/>
<addaction name="actionBench_construction"/>
<addaction name="actionBench_intersections_vs_nbt"/>
<addaction name="actionBench_distances_vs_nbt"/>
</widget>
<addaction name="actionBench_distances" />
<addaction name="actionBench_intersections" />
<addaction name="menuAgainst_triangles" />
<addaction name="actionBench_distances"/>
<addaction name="actionBench_intersections"/>
<addaction name="menuAgainst_triangles"/>
</widget>
<widget class="QMenu" name="menuEdit" >
<property name="title" >
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</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" />
<addaction name="actionSave_snapshot" />
<addaction name="actionClear_points"/>
<addaction name="actionClear_segments"/>
<addaction name="actionClear_cutting_plane"/>
<addaction name="separator"/>
<addaction name="actionCopy_snapshot"/>
<addaction name="actionSave_snapshot"/>
</widget>
<addaction name="menuFile" />
<addaction name="menuEdit" />
<addaction name="menuAlgorithms" />
<addaction name="menuView" />
<addaction name="menuBenchmarks" />
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuAlgorithms"/>
<addaction name="menuView"/>
<addaction name="menuBenchmarks"/>
</widget>
<action name="actionQuit" >
<property name="text" >
<action name="actionQuit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut" >
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionLoadPolyhedron" >
<property name="text" >
<action name="actionLoadPolyhedron">
<property name="text">
<string>Load polyhedron...</string>
</property>
</action>
<action name="actionInside_points" >
<property name="text" >
<action name="actionInside_points">
<property name="text">
<string>Inside points...</string>
</property>
</action>
<action name="actionBench_distances" >
<property name="text" >
<action name="actionBench_distances">
<property name="text">
<string>Distances</string>
</property>
</action>
<action name="actionUnsigned_distance_function_to_facets" >
<property name="text" >
<action name="actionUnsigned_distance_function_to_facets">
<property name="text">
<string>Unsigned distance function to facets</string>
</property>
</action>
<action name="actionUnsigned_distance_function_to_edges" >
<property name="text" >
<action name="actionUnsigned_distance_function_to_edges">
<property name="text">
<string>Unsigned distance function to edges</string>
</property>
</action>
<action name="actionSigned_distance_function_to_facets" >
<property name="text" >
<action name="actionSigned_distance_function_to_facets">
<property name="text">
<string>Signed distance function to facets</string>
</property>
</action>
<action name="actionView_polyhedron" >
<property name="text" >
<action name="actionView_polyhedron">
<property name="text">
<string>Polyhedron</string>
</property>
<property name="shortcut" >
<property name="shortcut">
<string>P</string>
</property>
</action>
<action name="actionView_points" >
<property name="text" >
<action name="actionView_points">
<property name="text">
<string>Points</string>
</property>
</action>
<action name="actionClear_points" >
<property name="text" >
<action name="actionClear_points">
<property name="text">
<string>Clear points</string>
</property>
</action>
<action name="actionBoundary_segments" >
<property name="text" >
<action name="actionBoundary_segments">
<property name="text">
<string>Boundary segments...</string>
</property>
</action>
<action name="actionBoundary_points" >
<property name="text" >
<action name="actionBoundary_points">
<property name="text">
<string>Boundary points...</string>
</property>
</action>
<action name="actionClear_segments" >
<property name="text" >
<action name="actionClear_segments">
<property name="text">
<string>Clear segments</string>
</property>
</action>
<action name="actionView_segments" >
<property name="text" >
<action name="actionView_segments">
<property name="text">
<string>Segments</string>
</property>
</action>
<action name="actionEdge_points" >
<property name="text" >
<action name="actionEdge_points">
<property name="text">
<string>Edge points...</string>
</property>
</action>
<action name="actionBench_intersections" >
<property name="text" >
<action name="actionBench_intersections">
<property name="text">
<string>Intersections</string>
</property>
</action>
<action name="actionView_distance_function" >
<property name="text" >
<action name="actionView_distance_function">
<property name="text">
<string>Distance function</string>
</property>
</action>
<action name="actionClear_distance_function" >
<property name="text" >
<action name="actionClear_distance_function">
<property name="text">
<string>Clear distance function</string>
</property>
</action>
<action name="actionRefine_bisection" >
<property name="text" >
<action name="actionRefine_bisection">
<property name="text">
<string>Longest edge bisection</string>
</property>
</action>
<action name="actionLoop_subdivision" >
<property name="text" >
<action name="actionLoop_subdivision">
<property name="text">
<string>Loop subdivision</string>
</property>
</action>
<action name="actionBench_memory" >
<property name="text" >
<action name="actionBench_memory">
<property name="text">
<string>Memory</string>
</property>
</action>
<action name="actionBench_construction" >
<property name="text" >
<action name="actionBench_construction">
<property name="text">
<string>Construction</string>
</property>
</action>
<action name="actionBench_intersections_vs_nbt" >
<property name="text" >
<action name="actionBench_intersections_vs_nbt">
<property name="text">
<string>Intersections</string>
</property>
</action>
<action name="actionBench_distances_vs_nbt" >
<property name="text" >
<action name="actionBench_distances_vs_nbt">
<property name="text">
<string>Distances</string>
</property>
</action>
<action name="actionPoints_in_interval" >
<property name="text" >
<action name="actionPoints_in_interval">
<property name="text">
<string>Points in interval...</string>
</property>
</action>
<action name="actionSave_snapshot" >
<property name="text" >
<action name="actionSave_snapshot">
<property name="text">
<string>Save snapshot</string>
</property>
</action>
<action name="actionCopy_snapshot" >
<property name="text" >
<action name="actionCopy_snapshot">
<property name="text">
<string>Copy snapshot</string>
</property>
</action>
<action name="actionRefine_loop" >
<property name="text" >
<action name="actionRefine_loop">
<property name="text">
<string>Loop subdivision</string>
</property>
</action>
<action name="actionCutting_plane" >
<property name="text" >
<action name="actionIntersection_cutting_plane">
<property name="text">
<string>Intersection</string>
</property>
</action>
<action name="actionView_cutting_plane" >
<property name="text" >
<action name="actionView_cutting_plane">
<property name="text">
<string>Cut plane</string>
</property>
</action>
<action name="actionClear_cutting_plane" >
<property name="text" >
<action name="actionClear_cutting_plane">
<property name="text">
<string>Clear cutting plane</string>
</property>
</action>
<action name="actionNone" >
<property name="text" >
<action name="actionCutting_plane_none">
<property name="text">
<string>None</string>
</property>
</action>
@ -297,7 +295,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="AABB_demo.qrc" />
<include location="AABB_demo.qrc"/>
</resources>
<connections/>
</ui>

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_view_plane)
{
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,117 +199,71 @@ 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);
unsigned int i01 = 255-(unsigned)(255.0 * (double)std::fabs(d01) / m_max_distance_function);
unsigned int i11 = 255-(unsigned)(255.0 * (double)std::fabs(d11) / m_max_distance_function);
unsigned int i10 = 255-(unsigned)(255.0 * (double)std::fabs(d10) / m_max_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,147 +692,121 @@ void Scene::generate_edge_points(const unsigned int nb_points)
std::cout << nb_planes << " plane queries, " << timer.time() << " s." << std::endl;
}
void Scene::unsigned_distance_function()
template <typename Tree>
void Scene::compute_distance_function(const Tree& tree)
{
if(m_pPolyhedron == NULL)
// 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)
{
std::cout << "Load polyhedron first." << std::endl;
return;
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);
}
}
}
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;
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++)
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)
{
FT x = m_bbox.xmin() + (FT)((double)i/100.0 * dx);
for(j=0;j<100;j++)
for(int j=0 ; j<m_grid_size ; ++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;
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;
}
}
m_signed_distance_function = false;
}
void Scene::unsigned_distance_function_to_edges()
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();
}
compute_distance_function(m_facet_tree);
m_cut_plane = UNSIGNED_FACETS;
}
typedef CGAL::AABB_polyhedron_segment_primitive<Kernel,Polyhedron> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> 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_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++)
void Scene::unsigned_distance_function_to_edges()
{
// Build tree if needed
if ( m_edge_tree.empty() )
{
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;
}
build_edge_tree();
}
m_signed_distance_function = false;
compute_distance_function(m_edge_tree);
m_cut_plane = UNSIGNED_EDGES;
}
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();
}
compute_distance_function(m_facet_tree);
sign_distance_function(m_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;
m_cut_plane = SIGNED_FACETS;
}
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;
}
void Scene::cutting_plane()
void Scene::cut_segment_plane()
{
// Build tree if needed
if ( m_facet_tree.empty() )
{
build_facet_tree();
}
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,8 +816,31 @@ 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()
{
m_view_polyhedron = !m_view_polyhedron;
@ -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,13 +27,21 @@ 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();
@ -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,8 +107,10 @@ 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);
@ -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;