mirror of https://github.com/CGAL/cgal
Add the Scene_polygon_soup, and the orient_soup plugin.
This commit is contained in:
parent
c0df6c5134
commit
c5c6b5f9a8
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue