Add the Scene_polygon_soup, and the orient_soup plugin.

This commit is contained in:
Laurent Rineau 2011-06-03 15:50:19 +00:00
parent c0df6c5134
commit c5c6b5f9a8
4 changed files with 219 additions and 27 deletions

View File

@ -6,6 +6,7 @@
#include <QtDebug>
#include "Scene_polygon_soup.h"
#include "Scene_polyhedron_item.h"
#include "Polyhedron_demo_plugin_interface.h"
#include "Messages_interface.h"
@ -46,6 +47,7 @@ void Polyhedron_demo_orient_soup_plugin::init(QMainWindow* mainWindow,
mw = mainWindow;
messages = m;
actionOrient = new QAction(tr("Orient polygon soup"), mainWindow);
actionOrient->setObjectName("actionOrient");
connect(actionOrient, SIGNAL(triggered()),
this, SLOT(orient()));
@ -67,26 +69,41 @@ QList<QAction*> Polyhedron_demo_orient_soup_plugin::actions() const {
void Polyhedron_demo_orient_soup_plugin::orient()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_polygon_soup* item =
qobject_cast<Scene_polygon_soup*>(scene->item(index));
if(item)
Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices())
{
// qDebug() << tr("I have the item %1\n").arg(item->name());
QApplication::setOverrideCursor(Qt::WaitCursor);
if(!item->orient())
messages->warning(tr("The polygon soup \"%1\" is not orientable.")
.arg(item->name()));
// QMessageBox::information(mw, tr("Not orientable"),
// tr("The polygon soup \"%1\" is not orientable.")
// .arg(item->name()));
Scene_polygon_soup* item =
qobject_cast<Scene_polygon_soup*>(scene->item(index));
scene->itemChanged(item);
QApplication::restoreOverrideCursor();
if(item)
{
// qDebug() << tr("I have the item %1\n").arg(item->name());
QApplication::setOverrideCursor(Qt::WaitCursor);
if(!item->orient()) {
messages->warning(tr("The polygon soup \"%1\" is not orientable.")
.arg(item->name()));
// QMessageBox::information(mw, tr("Not orientable"),
// tr("The polygon soup \"%1\" is not orientable.")
// .arg(item->name()));
scene->itemChanged(item);
} else {
Scene_polyhedron_item* poly_item = new Scene_polyhedron_item();
if(item->exportAsPolyhedron(poly_item->polyhedron())) {
poly_item->setName(item->name());
poly_item->setColor(item->color());
poly_item->setRenderingMode(item->renderingMode());
poly_item->setVisible(item->visible());
poly_item->changed();
poly_item->setProperty("source filename", item->property("source filename"));
scene->replaceItem(index, poly_item);
delete item;
} else {
scene->itemChanged(item);
}
}
}
}
QApplication::restoreOverrideCursor();
}
void Polyhedron_demo_orient_soup_plugin::shuffle()
@ -96,9 +113,26 @@ void Polyhedron_demo_orient_soup_plugin::shuffle()
Scene_polygon_soup* item =
qobject_cast<Scene_polygon_soup*>(scene->item(index));
if(item)
if(item) {
item->shuffle_orientations();
scene->itemChanged(item);
scene->itemChanged(item);
}
else {
Scene_polyhedron_item* poly_item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(poly_item) {
item = new Scene_polygon_soup();
item->setName(poly_item->name());
item->setColor(poly_item->color());
item->setRenderingMode(poly_item->renderingMode());
item->setVisible(poly_item->visible());
item->setProperty("source filename", poly_item->property("source filename"));
item->load(poly_item);
item->shuffle_orientations();
scene->replaceItem(index, item);
delete poly_item;
}
}
}
void Polyhedron_demo_orient_soup_plugin::displayNonManifoldEdges()

View File

@ -1,5 +1,8 @@
#include "Scene_polygon_soup.h"
#include "Scene_polyhedron_item.h"
#include <CGAL/IO/Polyhedron_iostream.h>
#include "Polyhedron_type.h"
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <QObject>
#include <QtDebug>
@ -12,11 +15,13 @@
#include <CGAL/IO/File_scanner_OFF.h>
#include <CGAL/IO/File_writer_OFF.h>
#include <CGAL/version.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
struct Polygon_soup {
struct Polygon_soup :
public CGAL::Modifier_base<Polyhedron::HalfedgeDS>
{
typedef std::vector<Point_3> Points;
typedef std::vector<std::size_t> Polygon_3;
typedef std::map<std::pair<std::size_t, std::size_t>, std::set<std::size_t> > Edges_map;
@ -86,8 +91,51 @@ struct Polygon_soup {
void inverse_orientation(const std::size_t index) {
std::reverse(polygons[index].begin(), polygons[index].end());
}
void operator()(Polyhedron::HalfedgeDS& out_hds);
};
struct Polyhedron_to_polygon_soup_writer {
Polygon_soup* soup;
Polygon_soup::Polygon_3 polygon;
Polyhedron_to_polygon_soup_writer(Polygon_soup* soup) : soup(soup), polygon() {
}
void write_header( std::ostream&,
std::size_t vertices,
std::size_t halfedges,
std::size_t facets,
bool normals = false ) {
soup->clear();
}
void write_footer() {
}
void write_vertex( const double& x, const double& y, const double& z) {
soup->points.push_back(Point_3(x, y, z));
}
void write_normal( const double& x, const double& y, const double& z) {
}
void write_facet_header() {
}
void write_facet_begin( std::size_t no) {
polygon.clear();
polygon.reserve(no);
}
void write_facet_vertex_index( std::size_t index) {
polygon.push_back(index);
}
void write_facet_end() {
soup->polygons.push_back(polygon);
polygon.clear();
}
}; // end struct Polyhedron_to_soup_writer
Scene_polygon_soup::Scene_polygon_soup()
: Scene_item_with_display_list(),
soup(0),
@ -111,13 +159,18 @@ Scene_polygon_soup::clone() const {
bool
Scene_polygon_soup::load(std::istream& in)
{
#if CGAL_VERSION_NR >= 1030700091
typedef std::size_t indices_t;
#else
typedef CGAL::Integer32 indices_t;
#endif
if(!soup)
soup = new Polygon_soup;
CGAL::File_scanner_OFF scanner(in);
soup->clear();
soup->points.resize(scanner.size_of_vertices());
soup->polygons.resize(scanner.size_of_facets());
for (std::size_t i = 0; i < scanner.size_of_vertices(); ++i) {
for (indices_t i = 0; i < scanner.size_of_vertices(); ++i) {
double x, y, z, w;
scanner.scan_vertex( x, y, z, w);
soup->points[i] = Point_3(x, y, z, w);
@ -126,12 +179,13 @@ Scene_polygon_soup::load(std::istream& in)
if(!in)
return false;
for (std::size_t i = 0; i < scanner.size_of_facets(); ++i) {
std::size_t no;
for (indices_t i = 0; i < scanner.size_of_facets(); ++i) {
indices_t no;
scanner.scan_facet( no, i);
soup->polygons[i].resize(no);
for(std::size_t j = 0; j < no; ++j) {
std::size_t id;
for(indices_t j = 0; j < no; ++j) {
indices_t id;
scanner.scan_facet_vertex_index(id, i);
if(id < scanner.size_of_vertices())
{
@ -146,6 +200,24 @@ Scene_polygon_soup::load(std::istream& in)
return in;
}
#include <CGAL/IO/generic_print_polyhedron.h>
#include <iostream>
void Scene_polygon_soup::load(Scene_polyhedron_item* poly_item) {
if(!poly_item) return;
if(!poly_item->polyhedron()) return;
if(!soup)
soup = new Polygon_soup;
Polyhedron_to_polygon_soup_writer writer(soup);
CGAL::generic_print_polyhedron(std::cerr,
*poly_item->polyhedron(),
writer);
emit changed();
}
void
Scene_polygon_soup::setDisplayNonManifoldEdges(const bool b)
{
@ -321,6 +393,44 @@ Scene_polygon_soup::save(std::ostream& out) const
return out;
}
void
Polygon_soup::operator()(Polyhedron::HalfedgeDS& out_hds)
{
typedef Polyhedron::HalfedgeDS Output_HDS;
CGAL::Polyhedron_incremental_builder_3<Output_HDS> builder(out_hds);
typedef Polygon_soup::size_type size_type;
builder.begin_surface(points.size(),
polygons.size(),
edges.size() * 2);
for(size_type i = 0, end = points.size();
i < end; ++i)
{
builder.add_vertex(points[i]);
}
for(size_type i = 0, end = polygons.size();
i < end; ++i)
{
const Polygon_soup::Polygon_3& polygon = polygons[i];
const size_type size = polygon.size();
builder.begin_facet();
for(size_type j = 0; j < size; ++j) {
builder.add_vertex_to_facet(polygon[j]);
}
builder.end_facet();
}
builder.end_surface();
}
bool
Scene_polygon_soup::exportAsPolyhedron(Polyhedron* out_polyhedron)
{
orient();
out_polyhedron->delegate(*soup);
return out_polyhedron->size_of_vertices() > 0;
}
QString
Scene_polygon_soup::toolTip() const
{
@ -363,8 +473,11 @@ Scene_polygon_soup::direct_draw() const {
}
if(soup->display_non_manifold_edges) {
double current_color[4];
GLboolean lightning;
::glGetDoublev(GL_CURRENT_COLOR, current_color);
::glColor3d(1., 0., 0.); // red
::glGetBooleanv(GL_LIGHTING, &lightning);
::glDisable(GL_LIGHTING);
for(Polygon_soup::size_type
i = 0,
@ -379,10 +492,24 @@ Scene_polygon_soup::direct_draw() const {
::glVertex3d(b.x(), b.y(), b.z());
::glEnd();
}
if(lightning) glEnable(GL_LIGHTING);
::glColor4dv(current_color);
}
}
void
Scene_polygon_soup::draw_points() const {
if(soup == 0) return;
::glBegin(GL_POINTS);
for(Polygon_soup::Points::const_iterator pit = soup->points.begin(),
end = soup->points.end();
pit != end; ++pit)
{
::glVertex3d(pit->x(), pit->y(), pit->z());
}
::glEnd();
}
bool
Scene_polygon_soup::isEmpty() const {
return (soup == 0 || soup->points.empty());
@ -401,4 +528,24 @@ Scene_polygon_soup::bbox() const {
bbox.xmax(),bbox.ymax(),bbox.zmax());
}
void
Scene_polygon_soup::new_vertex(const double& x,
const double& y,
const double& z)
{
soup->points.push_back(Point_3(x, y, z));
}
void
Scene_polygon_soup::new_triangle(const std::size_t i,
const std::size_t j,
const std::size_t k)
{
Polygon_soup::Polygon_3 new_polygon(3);
new_polygon[0] = i;
new_polygon[1] = j;
new_polygon[2] = k;
soup->polygons.push_back(new_polygon);
}
#include "Scene_polygon_soup.moc"

View File

@ -5,7 +5,10 @@
#include "Scene_item_with_display_list.h"
#include <iostream>
#include "Polyhedron_type_fwd.h"
struct Polygon_soup;
class Scene_polyhedron_item;
class SCENE_POLYGON_SOUP_EXPORT Scene_polygon_soup
: public Scene_item_with_display_list
@ -17,6 +20,7 @@ public:
Scene_polygon_soup* clone() const;
bool load(std::istream& in);
void load(Scene_polyhedron_item*);
bool save(std::ostream& out) const;
QString toolTip() const;
@ -25,17 +29,24 @@ public:
virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud; } // CHECK THIS!
// OpenGL drawing in a display list
void direct_draw() const;
void draw_points() const;
bool isFinite() const { return true; }
bool isEmpty() const;
Bbox bbox() const;
void new_vertex(const double&, const double&, const double&);
void new_triangle(const std::size_t, const std::size_t, const std::size_t);
public slots:
void shuffle_orientations();
bool orient();
bool exportAsPolyhedron(Polyhedron*);
void inside_out();
void setDisplayNonManifoldEdges(const bool);
bool displayNonManifoldEdges() const;
private:
Polygon_soup* soup;
bool oriented;

View File

@ -1,7 +1,7 @@
#ifndef SCENE_POLYGON_SOUP_CONFIG_H
#define SCENE_POLYGON_SOUP_CONFIG_H
#ifdef polygon_soup_EXPORTS
#ifdef scene_polygon_soup_item_EXPORTS
# define SCENE_POLYGON_SOUP_EXPORT Q_DECL_EXPORT
#else
# define SCENE_POLYGON_SOUP_EXPORT Q_DECL_IMPORT