diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp index eab5c9d82d7..555917c4ddc 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp @@ -6,6 +6,7 @@ #include #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 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->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->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->item(index)); - if(item) + if(item) { item->shuffle_orientations(); - scene->itemChanged(item); + scene->itemChanged(item); + } + else { + Scene_polyhedron_item* poly_item = + qobject_cast(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() diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup.cpp index 6f18f295557..f33e6dece1e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup.cpp @@ -1,5 +1,8 @@ #include "Scene_polygon_soup.h" +#include "Scene_polyhedron_item.h" #include +#include "Polyhedron_type.h" +#include #include #include @@ -12,11 +15,13 @@ #include #include +#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -struct Polygon_soup { +struct Polygon_soup : + public CGAL::Modifier_base +{ typedef std::vector Points; typedef std::vector Polygon_3; typedef std::map, std::set > 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 +#include + +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 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" diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup.h index 154b09bc71f..016b327cfc5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup.h @@ -5,7 +5,10 @@ #include "Scene_item_with_display_list.h" #include +#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; diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_config.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_config.h index 5a568ac4da0..47898403aaa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_config.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_config.h @@ -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