Create Qt Point Set demo from Qt Polyhedron demo and Poisson MFC demo.

Step 5:
- added "Edit >> Convert to Point Set" menu item to convert a mesh to a point set
This commit is contained in:
Laurent Saboret 2009-04-06 15:21:22 +00:00
parent 6fcfa43cd7
commit 88264bc2df
12 changed files with 235 additions and 47 deletions

View File

@ -105,6 +105,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
target_link_libraries(point_set scene_item)
add_definitions(-DQT_STATICPLUGIN)
# if(POINT_SET_DEMO_ENABLE_FORWARD_DECL)
add_definitions(-DUSE_FORWARD_DECL)
add_executable ( Point_set_demo MainWindow.cpp
@ -135,8 +136,8 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
# Link with libQGLViewer, OpenGL
target_link_libraries( Point_set_demo ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
# Link with the scene_item library.
# target_link_libraries( Point_set_demo scene_item )
# Link with the scene_item libraries
target_link_libraries( Point_set_demo scene_item scene_polyhedron_item point_set )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Point_set_demo )

View File

@ -496,6 +496,12 @@ void MainWindow::on_actionDuplicate_triggered()
selectSceneItem(index);
}
void MainWindow::on_actionConvertToPointSet_triggered()
{
int index = scene->convertToPointSet(getSelectedSceneItemIndex());
selectSceneItem(index);
}
void MainWindow::on_actionShowHide_triggered()
{
Q_FOREACH(QModelIndex index, treeView->selectionModel()->selectedRows())

View File

@ -65,6 +65,7 @@ protected slots:
void on_actionFileOpen_triggered();
bool on_actionFileClose_triggered();
void on_actionDuplicate_triggered();
void on_actionConvertToPointSet_triggered();
// Show/Hide
void on_actionShowHide_triggered();

View File

@ -65,8 +65,10 @@
<property name="title" >
<string>&amp;Edit</string>
</property>
<addaction name="actionDuplicate" />
<addaction name="actionShowHide" />
<addaction name="separator" />
<addaction name="actionDuplicate" />
<addaction name="actionConvertToPointSet" />
</widget>
<widget class="QMenu" name="menuOperations" >
<property name="title" >
@ -415,6 +417,14 @@
<string>Draw two sides</string>
</property>
</action>
<action name="actionConvertToPointSet" >
<property name="text" >
<string>Convert to Point Set</string>
</property>
<property name="toolTip" >
<string>Convert Mesh to Point Set</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -1,17 +1,17 @@
#ifndef POINT_SET_DEMO_TYPES_H
#define POINT_SET_DEMO_TYPES_H
// CGAL
// kernel
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
// surface mesh
#include <CGAL/Polyhedron_3.h>
#include "Point_set_3.h"
#include "Point_set_demo_types_fwd.h"
// kernel
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
// simple geometric types
typedef Kernel::FT FT;
typedef Kernel::Line_3 Line;
typedef Kernel::Point_3 Point;
@ -22,6 +22,13 @@ typedef Kernel::Triangle_3 Triangle;
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
typedef Kernel::Plane_3 Plane_3;
// surface mesh
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
// point set
typedef Point_set_3<Kernel> Point_set;
// type of points in Point_set_3
typedef Point_set::UI_point UI_point; // Position + normal + selection flag
#endif // POINT_SET_DEMO_TYPES_H

View File

@ -1,13 +1,13 @@
#ifndef POLYHEDRON_TYPE_FWD_H
#define POLYHEDRON_TYPE_FWD_H
#include <memory>
#ifdef USE_FORWARD_DECL
namespace CGAL {
template <class CK>
struct Filtered_kernel;
@ -30,16 +30,27 @@ namespace CGAL {
class Alloc
>
class Polyhedron_3;
} // end namespace CGAL
// kernel
typedef CGAL::Filtered_kernel< CGAL::Simple_cartesian<double> > Kernel;
// surface mesh
typedef CGAL::Polyhedron_3<Kernel,
CGAL::Polyhedron_items_3,
CGAL::HalfedgeDS_default,
std::allocator<int> > Polyhedron;
// point set
template <class Gt> class Point_set_3;
typedef Point_set_3<Kernel> Point_set;
#else // USE_FORWARD_DECL
#include "Point_set_demo_types.h"
#endif // USE_FORWARD_DECL
#endif // POLYHEDRON_TYPE_FWD_H

View File

@ -1,12 +1,11 @@
#include "Point_set_scene_item.h"
#include "Point_set_demo_types.h"
#include <CGAL/IO/read_off_point_set.h>
#include <CGAL/IO/write_off_point_set.h>
#include <CGAL/IO/read_xyz_point_set.h>
#include <CGAL/IO/write_xyz_point_set.h>
#include <QObject>
#include <QtDebug>
#include <set>
#include <stack>
@ -14,36 +13,110 @@
#include <boost/array.hpp>
// ----------------------------------------------------------------------------
// Private functions
// ----------------------------------------------------------------------------
// compute polyhedron facet's normal
static Vector compute_facet_normal(Polyhedron::Facet_const_handle f)
{
Vector sum = CGAL::NULL_VECTOR;
Polyhedron::Halfedge_around_facet_const_circulator h = f->facet_begin();
do
{
Vector normal = CGAL::cross_product(
h->next()->vertex()->point() - h->vertex()->point(),
h->next()->next()->vertex()->point() - h->next()->vertex()->point());
double sqnorm = normal * normal;
if(sqnorm != 0)
normal = normal / (double)std::sqrt(sqnorm);
sum = sum + normal;
}
while(++h != f->facet_begin());
// Normalize 'sum'
double sqnorm = sum * sum; // dot product
if(sqnorm != 0.0)
sum = sum / std::sqrt(sqnorm);
return sum;
}
// compute polyhedron vertex's normal from connectivity
static Vector compute_vertex_normal(Polyhedron::Vertex_const_handle v)
{
Vector normal = CGAL::NULL_VECTOR;
Polyhedron::Halfedge_around_vertex_const_circulator pHalfedge = v->vertex_begin(),
end = pHalfedge;
CGAL_For_all(pHalfedge,end)
if(!pHalfedge->is_border())
normal = normal + compute_facet_normal(pHalfedge->facet());
// Normalize 'normal'
double sqnorm = normal * normal;
if(sqnorm != 0.0)
normal = normal / std::sqrt(sqnorm);
return normal;
}
// ----------------------------------------------------------------------------
// Class Point_set_scene_item
// ----------------------------------------------------------------------------
Point_set_scene_item::Point_set_scene_item()
: Scene_item_with_display_list()
: Scene_item_with_display_list(),
m_points(new Point_set)
{
}
// Copy constructor
Point_set_scene_item::Point_set_scene_item(const Point_set_scene_item& toCopy)
// do not call superclass' copy constructor
: Scene_item_with_display_list(), // do not call superclass' copy constructor
m_points(new Point_set(*toCopy.m_points))
{
this->m_points = toCopy.m_points;
}
// Convert polyhedron to point set
Point_set_scene_item::Point_set_scene_item(const Polyhedron& input_mesh)
: Scene_item_with_display_list(),
m_points(new Point_set)
{
// Convert Polyhedron vertices to point set.
// Compute vertices' normals from connectivity.
Polyhedron::Vertex_const_iterator v;
for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++)
{
Point p = v->point();
Vector n = compute_vertex_normal(v);
m_points->push_back(UI_point(p,n));
}
}
Point_set_scene_item::~Point_set_scene_item()
{
Q_ASSERT(m_points != NULL);
delete m_points; m_points = NULL;
}
// Duplicate scene item
Point_set_scene_item*
Point_set_scene_item::clone() const
{
Point_set_scene_item* new_item = new Point_set_scene_item(*this);
return new_item;
return new Point_set_scene_item(*this);
}
// Load point set from .OFF file
bool
Point_set_scene_item::read_off_point_set(std::istream& in)
{
m_points.clear();
Q_ASSERT(m_points != NULL);
m_points->clear();
return in &&
CGAL::read_off_point_set(in, std::back_inserter(m_points)) &&
CGAL::read_off_point_set(in, std::back_inserter(*m_points)) &&
!isEmpty();
}
@ -51,17 +124,22 @@ Point_set_scene_item::read_off_point_set(std::istream& in)
bool
Point_set_scene_item::write_off_point_set(std::ostream& out) const
{
return out && !isEmpty() &&
CGAL::write_off_point_set(out, m_points.begin(), m_points.end());
Q_ASSERT(m_points != NULL);
return out &&
!isEmpty() &&
CGAL::write_off_point_set(out, m_points->begin(), m_points->end());
}
// Load point set from .XYZ file
bool
Point_set_scene_item::read_xyz_point_set(std::istream& in)
{
m_points.clear();
Q_ASSERT(m_points != NULL);
m_points->clear();
return in &&
CGAL::read_xyz_point_set(in, std::back_inserter(m_points)) &&
CGAL::read_xyz_point_set(in, std::back_inserter(*m_points)) &&
!isEmpty();
}
@ -69,51 +147,73 @@ Point_set_scene_item::read_xyz_point_set(std::istream& in)
bool
Point_set_scene_item::write_xyz_point_set(std::ostream& out) const
{
return out && !isEmpty() &&
CGAL::write_xyz_point_set(out, m_points.begin(), m_points.end());
Q_ASSERT(m_points != NULL);
return out &&
!isEmpty() &&
CGAL::write_xyz_point_set(out, m_points->begin(), m_points->end());
}
QString
Point_set_scene_item::toolTip() const
{
Q_ASSERT(m_points != NULL);
return QObject::tr("<p><b>%1</b> (color: %4)<br />"
"<i>Point set</i></p>"
"<p>Number of vertices: %2</p>")
.arg(name())
.arg(m_points.size())
.arg(m_points->size())
.arg(color().name());
}
void
Point_set_scene_item::direct_draw() const
{
Sphere region_of_interest = m_points.region_of_interest();
Q_ASSERT(m_points != NULL);
Sphere region_of_interest = m_points->region_of_interest();
// Draw points
m_points.gl_draw_vertices(color().red(),color().blue(),color().green(),
2.0f /*size*/);
m_points->gl_draw_vertices(color().red(),color().blue(),color().green(),
2.0f /*size*/);
// Draw normals
bool points_have_normals = (m_points.begin() != m_points.end() &&
m_points.begin()->normal() != CGAL::NULL_VECTOR);
bool points_have_normals = (m_points->begin() != m_points->end() &&
m_points->begin()->normal() != CGAL::NULL_VECTOR);
if(points_have_normals)
{
float normal_length = (float)sqrt(region_of_interest.squared_radius() / 10000.);
m_points.gl_draw_normals(0,255,0 /*green*/,
normal_length);
m_points->gl_draw_normals(0,255,0 /*green*/,
normal_length);
}
}
// Get wrapped point set
Point_set* Point_set_scene_item::point_set()
{
Q_ASSERT(m_points != NULL);
return m_points;
}
const Point_set* Point_set_scene_item::point_set() const
{
Q_ASSERT(m_points != NULL);
return m_points;
}
bool
Point_set_scene_item::isEmpty() const
{
return m_points.empty();
Q_ASSERT(m_points != NULL);
return m_points->empty();
}
Point_set_scene_item::Bbox
Point_set_scene_item::bbox() const
{
Iso_cuboid bbox = m_points.bounding_box();
Q_ASSERT(m_points != NULL);
Iso_cuboid bbox = m_points->bounding_box();
return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax());
}

View File

@ -2,9 +2,8 @@
#define POINT_SET_ITEM_H
#include "Point_set_scene_item_config.h"
#include "Point_set_3.h"
#include "Scene_item_with_display_list.h"
#include "Point_set_demo_types.h"
#include "Point_set_demo_types_fwd.h"
#include <iostream>
@ -18,6 +17,7 @@ class POINT_SET_ITEM_EXPORT Point_set_scene_item
public:
Point_set_scene_item();
Point_set_scene_item(const Point_set_scene_item& toCopy);
Point_set_scene_item(const Polyhedron& p);
~Point_set_scene_item();
Point_set_scene_item* clone() const;
@ -27,12 +27,16 @@ public:
bool read_xyz_point_set(std::istream& in);
bool write_xyz_point_set(std::ostream& out) const;
// Functions for displaying meta-data of the item
// Function for displaying meta-data of the item
virtual QString toolTip() const;
// OpenGL drawing
virtual void direct_draw() const;
// Get wrapped point set
Point_set* point_set();
const Point_set* point_set() const;
// Get dimensions
bool isFinite() const { return true; }
bool isEmpty() const;
@ -40,7 +44,7 @@ public:
// Data
private:
Point_set_3<Kernel> m_points;
Point_set* m_points;
}; // end class Point_set_scene_item

View File

@ -1,6 +1,8 @@
#include "config.h"
#include "Scene.h"
#include "Scene_item.h"
#include "Scene_polyhedron_item.h"
#include "Point_set_scene_item.h"
#include <QString>
#include <QGLWidget>
@ -79,6 +81,8 @@ Scene::numberOfEntries() const
return entries.size();
}
// Duplicate a scene item.
// Return the ID of the new item (-1 on error).
Scene::Item_id
Scene::duplicate(Item_id index)
{
@ -98,6 +102,35 @@ Scene::duplicate(Item_id index)
return -1;
}
// Convert a polyhedron to a point set.
// Return the ID of the new item (-1 on error).
Scene::Item_id
Scene::convertToPointSet(Item_id index)
{
// Check index
if(index < 0 || index >= entries.size())
return -1;
// Check if scene item is a polyhedron
const Scene_item* item = entries[index];
const Scene_polyhedron_item* poly_item =
qobject_cast<const Scene_polyhedron_item*>(item);
if(poly_item == NULL || poly_item->polyhedron() == NULL)
return -1;
// Convert polyhedron to a point set
Point_set_scene_item* new_item = new Point_set_scene_item(*poly_item->polyhedron());
if(new_item) {
new_item->setName(tr("%1 (point set)").arg(item->name()));
new_item->setColor(item->color());
new_item->setVisible(item->visible());
addItem(new_item);
return entries.size() - 1;
}
else
return -1;
}
void Scene::initializeGL()
{
}

View File

@ -45,7 +45,10 @@ public:
// one that is erased, or just after. Returns -1 if
// the list is empty.
int duplicate(int); // Returns the index of the new polyhedra
// Duplicate a scene item. Return the ID of the new item (-1 on error).
Item_id duplicate(Item_id index);
// Convert a polyhedron to a point set. Return the ID of the new item (-1 on error).
Item_id convertToPointSet(Item_id index);
// Accessors (getters)
size_t numberOfEntries() const;

View File

@ -1,5 +1,6 @@
#include "Scene_polyhedron_item.h"
#include "Point_set_demo_types.h"
#include <CGAL/IO/Polyhedron_iostream.h>
#include <QObject>
@ -83,9 +84,9 @@ Scene_polyhedron_item::direct_draw() const {
}
Polyhedron*
Scene_polyhedron_item::polyhedron() {
return poly;
}
Scene_polyhedron_item::polyhedron() { return poly; }
const Polyhedron*
Scene_polyhedron_item::polyhedron() const { return poly; }
bool
Scene_polyhedron_item::isEmpty() const {

View File

@ -4,8 +4,10 @@
#include "Scene_polyhedron_item_config.h"
#include "Scene_item_with_display_list.h"
#include "Point_set_demo_types_fwd.h"
#include <iostream>
// This class represents a polyhedron in the OpenGL scene
class SCENE_POLYHEDRON_ITEM_EXPORT Scene_polyhedron_item
: public Scene_item_with_display_list {
Q_OBJECT
@ -17,20 +19,29 @@ public:
~Scene_polyhedron_item();
Scene_polyhedron_item* clone() const;
// IO
bool load(std::istream& in);
bool save(std::ostream& out) const;
QString toolTip() const;
// Function for displaying meta-data of the item
virtual QString toolTip() const;
void direct_draw() const;
Polyhedron* polyhedron();
// OpenGL drawing
virtual void direct_draw() const;
// Get wrapped polyhedron
Polyhedron* polyhedron();
const Polyhedron* polyhedron() const;
// Get dimensions
bool isFinite() const { return true; }
bool isEmpty() const;
Bbox bbox() const;
private:
Polyhedron* poly;
}; // end class Scene_polyhedron_item
#endif // SCENE_POLYHEDRON_ITEM_H