diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index 2a75bc26779..d9d647b9d71 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -65,6 +65,18 @@ public: menuFile->insertAction(actionAfterLoad,actionAdd_polylines); } } + + + actionJoin_polylines= new QAction(tr("Join Selected Polylines"), mainWindow); + actionJoin_polylines->setProperty("subMenuName", "Operations on Polylines"); + actionJoin_polylines->setObjectName("actionJoinPolylines"); + + actionSplit_polylines= new QAction(tr("Split Selected Polylines"), mainWindow); + actionSplit_polylines->setProperty("subMenuName", "Operations on Polylines"); + actionSplit_polylines->setObjectName("actionSplitPolylines"); + connect(actionSplit_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::split); + connect(actionJoin_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::join); + } QString name() const { return "polylines_io_plugin"; } QString nameFilters() const { return "Polylines files (*.polylines.txt *.cgal)"; } @@ -73,9 +85,29 @@ public: bool canSave(const CGAL::Three::Scene_item*); bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); - bool applicable(QAction*) const { return true;} + bool applicable(QAction* a) const { + bool all_polylines_selected = true; + Q_FOREACH(int index, scene->selectionIndices()) + { + if (!qobject_cast(scene->item(index))) + { + all_polylines_selected = false; + } + } + + if(a==actionSplit_polylines) + return (all_polylines_selected && + scene->selectionIndices().size() == 1); + else if(a==actionJoin_polylines) + return (all_polylines_selected && + scene->selectionIndices().size() > 1); + else + return false; + } QList actions() const { - return QList(); + + return QList()<close(); } +void Polyhedron_demo_polylines_io_plugin::split() +{ + Scene_polylines_item* item = qobject_cast(scene->item(scene->mainSelectionIndex())); + Scene_group_item* group = new Scene_group_item("Splitted Polylines"); + scene->addItem(group); + group->setColor(item->color()); + int i=0; + Q_FOREACH(Scene_polylines_item::Polyline polyline, item->polylines) + { + Scene_polylines_item::Polylines_container container; + container.push_back(polyline); + Scene_polylines_item *new_polyline = new Scene_polylines_item(); + new_polyline->polylines = container; + new_polyline->setColor(item->color()); + new_polyline->setName(QString("Splitted %1 #%2").arg(item->name()).arg(i++)); + scene->addItem(new_polyline); + scene->changeGroup(new_polyline, group); + } +} + +void Polyhedron_demo_polylines_io_plugin::join() +{ + + std::vector items; + items.resize(scene->selectionIndices().size()); + for(int i = 0; i < scene->selectionIndices().size(); ++i) + items[i] = qobject_cast(scene->item(scene->selectionIndices().at(i))); + + Scene_polylines_item* new_polyline= new Scene_polylines_item(); + Scene_polylines_item::Polylines_container container; + Q_FOREACH(Scene_polylines_item* item, items) + { + for(Scene_polylines_item::Polylines_container::iterator + it = item->polylines.begin(); + it!= item->polylines.end(); + ++it) + { + container.push_back(*it); + } + } + new_polyline->polylines = container; + new_polyline->setColor(QColor(Qt::black)); + new_polyline->setName(QString("Joined from %1 items").arg(items.size())); + scene->addItem(new_polyline); +} + #include "Polylines_io_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index e36eb899b11..c4503f87cd5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -17,6 +17,16 @@ struct Scene_polylines_item_private { spheres_drawn_radius(0) { item = parent; + invalidate_stats(); + } + void invalidate_stats() + { + nb_vertices = 0; + nb_edges = 0; + min_length = std::numeric_limits::max(); + max_length = 0; + mean_length = 0; + computed_stats = false; } enum VAOs { @@ -39,6 +49,12 @@ struct Scene_polylines_item_private { bool draw_extremities; double spheres_drawn_radius; Scene_polylines_item *item; + mutable std::size_t nb_vertices; + mutable std::size_t nb_edges; + mutable double min_length; + mutable double max_length; + mutable double mean_length; + mutable bool computed_stats; }; @@ -72,16 +88,33 @@ Scene_polylines_item_private::computeElements() const { QApplication::setOverrideCursor(Qt::WaitCursor); positions_lines.resize(0); + double mean = 0; //Fills the VBO with the lines for(std::list >::const_iterator it = item->polylines.begin(); it != item->polylines.end(); - ++it){ + ++it) + { if(it->empty()) continue; + nb_vertices += it->size(); for(size_t i = 0, end = it->size()-1; i < end; ++i) { const Point_3& a = (*it)[i]; const Point_3& b = (*it)[i+1]; + if(!computed_stats) + { + ++nb_edges; + double length = CGAL::sqrt( + (a.x()-b.x()) * (a.x()-b.x()) + + (a.y()-b.y()) * (a.y()-b.y()) + + (a.z()-b.z()) * (a.z()-b.z()) ); + if(max_length < length) + max_length = length; + if(min_length > length) + min_length = length; + mean += length; + } + positions_lines.push_back(a.x()); positions_lines.push_back(a.y()); positions_lines.push_back(a.z()); @@ -94,6 +127,9 @@ Scene_polylines_item_private::computeElements() const } } + if(!computed_stats) + mean_length = mean/nb_edges; + computed_stats = true; QApplication::restoreOverrideCursor(); } @@ -392,6 +428,7 @@ QMenu* Scene_polylines_item::contextMenu() void Scene_polylines_item::invalidateOpenGLBuffers() { are_buffers_filled = false; + d->invalidate_stats(); compute_bbox(); @@ -585,3 +622,37 @@ void Scene_polylines_item::smooth(std::vector& polyline){ if (is_closed) polyline[end]=polyline[0]; } + +QString Scene_polylines_item::computeStats(int type) +{ + switch (type) + { + case NB_VERTICES: + return QString::number(d->nb_vertices); + case NB_EDGES: + return QString::number(d->nb_edges); + case MIN_LENGTH: + return QString::number(d->min_length); + case MAX_LENGTH: + return QString::number(d->max_length); + case MEAN_LENGTH: + return QString::number(d->mean_length); + default: + return QString(); + } +} +CGAL::Three::Scene_item::Header_data Scene_polylines_item::header() const +{ + CGAL::Three::Scene_item::Header_data data; + //categories + data.categories.append(std::pair(QString("Properties"),5)); + + + //titles + data.titles.append(QString("#Vertices")); + data.titles.append(QString("#Segment Edges")); + data.titles.append(QString("Shortest Segment Edge Length")); + data.titles.append(QString("Longest Segment Edge Length")); + data.titles.append(QString("Average Segment Edge Length")); + return data; +} diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h index 822705101ea..9a58fd390b6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h @@ -25,6 +25,16 @@ public: Scene_polylines_item(); virtual ~Scene_polylines_item(); + enum STATS { + NB_VERTICES = 0, + NB_EDGES, + MIN_LENGTH, + MAX_LENGTH, + MEAN_LENGTH + }; + bool has_stats()const {return true;} + QString computeStats(int type); + CGAL::Three::Scene_item::Header_data header() const; bool isFinite() const { return true; } bool isEmpty() const;