#include "Scene_polylines_item.h" #include #include #include #include #include #include #include #include using namespace CGAL::Three; class Polyhedron_demo_polylines_io_plugin : public QObject, public Polyhedron_demo_io_plugin_interface, public Polyhedron_demo_plugin_helper { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polylines_io_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") public: // To silent a warning -Woverloaded-virtual // See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings //! Configures the widget void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) { //get the references this->scene = scene_interface; this->mw = mainWindow; //creates and link the actions 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)"; } bool canLoad(QFileInfo fileinfo) const; QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); bool save(QFileInfo fileinfo,QList&); 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()< Polyhedron_demo_polylines_io_plugin:: load(QFileInfo fileinfo, bool& ok, bool add_to_scene){ // Open file std::ifstream ifs(fileinfo.filePath().toUtf8()); if(!ifs) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; ok = false; return QList(); } if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); Scene_polylines_item* item = new Scene_polylines_item; item->setName(fileinfo.completeBaseName()); ok = true; if(add_to_scene) CGAL::Three::Three::scene()->addItem(item); return QList()< > polylines; QStringList polylines_metadata; int counter = 0; std::size_t n; while(ifs >> n) { ++counter; std::vector new_polyline; polylines.push_back(new_polyline); std::vector&polyline = polylines.back(); polyline.reserve(n); while(n--){ Scene_polylines_item::Point_3 p; ifs >> p; polyline.push_back(p); if(!ifs.good()) { ok = false; return QList(); } } std::string line_remainder; std::getline(ifs, line_remainder); QString metadata(line_remainder.c_str()); if(metadata[0].isSpace()) { metadata.remove(0, 1); } polylines_metadata << metadata; if(!metadata.isEmpty()) { std::cerr << " (metadata: \"" << qPrintable(metadata) << "\")\n"; } else { } if(ifs.bad() || ifs.fail()) { ok = false; return QList(); } } if(counter == 0) { ok = false; return QList(); } Scene_polylines_item* item = new Scene_polylines_item; item->polylines = polylines; item->setName(fileinfo.baseName()); item->setColor(Qt::black); item->setProperty("polylines metadata", polylines_metadata); std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl; item->invalidateOpenGLBuffers(); ok = true; if(add_to_scene) CGAL::Three::Three::scene()->addItem(item); return QList()<(item) != 0; } bool Polyhedron_demo_polylines_io_plugin:: save(QFileInfo fileinfo,QList& items) { Scene_item* item = items.front(); const Scene_polylines_item* poly_item = qobject_cast(item); if(!poly_item) return false; std::ofstream out(fileinfo.filePath().toUtf8()); out.precision (std::numeric_limits::digits10 + 2); if(!out) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; return false; } typedef Scene_polylines_item::Polylines_container Polylines_container; typedef Polylines_container::value_type Polyline; typedef Polyline::value_type Point_3; QStringList metadata = item->property("polylines metadata").toStringList(); for(const Polyline& polyline : poly_item->polylines) { out << polyline.size(); for(const Point_3& p : polyline) { out << " " << p.x() << " " << p.y() << " " << p.z(); } if(!metadata.isEmpty()) { out << " " << qPrintable(metadata.front()); metadata.pop_front(); } out << std::endl; } bool res = (bool) out; if(res) items.pop_front(); return res; } 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"