diff --git a/Applications/DataExplorer/DataView/GeoTreeView.cpp b/Applications/DataExplorer/DataView/GeoTreeView.cpp index 7fe5c9967ac7eb6ba56acd0e2564d65f0c94c121..d2f6b4e6daed4ad0f9f2ecdf3207ab0c49e7c474 100644 --- a/Applications/DataExplorer/DataView/GeoTreeView.cpp +++ b/Applications/DataExplorer/DataView/GeoTreeView.cpp @@ -125,6 +125,13 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event ) // The current index is a list of points/polylines/surfaces if (list != nullptr) { + QAction* convertToStationAction(nullptr); + if (list->getType() == GeoLib::GEOTYPE::POINT) + { + convertToStationAction = menu.addAction("Convert to Stations"); + connect(convertToStationAction, SIGNAL(triggered()), + this, SLOT(convertPointsToStations())); + } QAction* connectPlyAction(nullptr); if (list->getType() == GeoLib::GEOTYPE::POLYLINE) { @@ -183,6 +190,14 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event ) menu.exec(event->globalPos()); } +void GeoTreeView::convertPointsToStations() +{ + TreeItem const*const item = static_cast<GeoTreeModel*>(model()) + ->getItem(this->selectionModel()->currentIndex()) + ->parentItem(); + emit requestPointToStationConversion(item->data(0).toString().toStdString()); +} + void GeoTreeView::connectPolylines() { TreeItem* item = static_cast<GeoTreeModel*>(model())->getItem( diff --git a/Applications/DataExplorer/DataView/GeoTreeView.h b/Applications/DataExplorer/DataView/GeoTreeView.h index 03e601f484a0c03f263b42a1b0618dcfcdaa10d5..5b2d2df63f82e9664db26d1a2d3b9722e43f0dce 100644 --- a/Applications/DataExplorer/DataView/GeoTreeView.h +++ b/Applications/DataExplorer/DataView/GeoTreeView.h @@ -58,6 +58,7 @@ private slots: void on_Clicked(QModelIndex idx); /// Calls a LineEditDialog. void connectPolylines(); + void convertPointsToStations(); void mapGeometry(); /// Calls a SetNameDialog. void setNameForElement(); @@ -84,5 +85,6 @@ signals: void requestCondSetupDialog(const std::string&, const GeoLib::GEOTYPE, const std::size_t, bool on_points); void requestLineEditDialog(const std::string&); void requestNameChangeDialog(const std::string&, const GeoLib::GEOTYPE, const std::size_t); + void requestPointToStationConversion(std::string const&); //void saveFEMConditionsRequested(QString, QString); }; diff --git a/Applications/DataExplorer/mainwindow.cpp b/Applications/DataExplorer/mainwindow.cpp index 000116abbd4896a27fa936d60b6fae7d671d6742..d3c3ff9df5474a585c9ce58cf29d7c44835ee0ca 100644 --- a/Applications/DataExplorer/mainwindow.cpp +++ b/Applications/DataExplorer/mainwindow.cpp @@ -139,6 +139,8 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/) this, SLOT(mapGeometry(const std::string&))); connect(geoTabWidget->treeView, SIGNAL(saveToFileRequested(QString, QString)), this, SLOT(writeGeometryToFile(QString, QString))); // save geometry to file + connect(geoTabWidget->treeView, SIGNAL(requestPointToStationConversion(std::string const&)), this, + SLOT(convertPointsToStations( std::string const&))); connect(geoTabWidget->treeView, SIGNAL(requestLineEditDialog(const std::string &)), this, SLOT(showLineEditDialog(const std::string &))); // open line edit dialog connect(geoTabWidget->treeView, SIGNAL(requestNameChangeDialog(const std::string&, const GeoLib::GEOTYPE, std::size_t)), @@ -1097,6 +1099,12 @@ void MainWindow::showMeshAnalysisDialog() dlg->exec(); } +void MainWindow::convertPointsToStations(std::string const& geo_name) +{ + std::string const stn_name = geo_name + "Stations"; + _project.getGEOObjects().geoPointsToStation(geo_name, stn_name); +} + void MainWindow::showLineEditDialog(const std::string &geoName) { LineEditDialog lineEdit( diff --git a/Applications/DataExplorer/mainwindow.h b/Applications/DataExplorer/mainwindow.h index 5765f0c6416df39c907ec79bdace24d7b06e9916..8baee849e3b12f01621b4df88c8f8cdd911e2459 100644 --- a/Applications/DataExplorer/mainwindow.h +++ b/Applications/DataExplorer/mainwindow.h @@ -76,6 +76,7 @@ protected slots: void loadPetrelFiles(); void mapGeometry(const std::string &geo_name); void convertMeshToGeometry(const MeshLib::Mesh* mesh); + void convertPointsToStations(std::string const& geo_name); void openRecentFile(); void about(); void showAddPipelineFilterItemDialog(QModelIndex parentIndex); diff --git a/GeoLib/GEOObjects.cpp b/GeoLib/GEOObjects.cpp index ee1d9baa8ef4d55dbdb5c981e59137017c204c50..fb6b4856160db7eb9a8a0501d12888cab89c61bf 100644 --- a/GeoLib/GEOObjects.cpp +++ b/GeoLib/GEOObjects.cpp @@ -554,9 +554,83 @@ void GEOObjects::renameGeometry(std::string const& old_name, } } -const GeoLib::GeoObject* GEOObjects::getGeoObject(const std::string &geo_name, - GeoLib::GEOTYPE type, - const std::string &geo_obj_name) const +void GEOObjects::markPointsAsUsed(std::string const& geo_name, + std::vector<bool>& flags) +{ + GeoLib::PolylineVec const* const ply_obj(getPolylineVecObj(geo_name)); + if (ply_obj) + { + std::vector<GeoLib::Polyline*> const& lines(*ply_obj->getVector()); + for (auto line : lines) + { + std::size_t const n_pnts(line->getNumberOfPoints()); + for (std::size_t i = 0; i < n_pnts; ++i) + flags[line->getPointID(i)] = false; + } + } + + GeoLib::SurfaceVec const* const sfc_obj(getSurfaceVecObj(geo_name)); + if (sfc_obj) + { + std::vector<GeoLib::Surface*> const& surfaces = *sfc_obj->getVector(); + for (auto sfc : surfaces) + { + std::size_t const n_tri(sfc->getNumberOfTriangles()); + for (std::size_t i = 0; i < n_tri; ++i) + { + GeoLib::Triangle const& t = *(*sfc)[i]; + flags[t[0]] = false; + flags[t[1]] = false; + flags[t[2]] = false; + } + } + } +} + +void GEOObjects::geoPointsToStation(std::string const& geo_name, + std::string const& stn_name, + bool only_unused_pnts) +{ + GeoLib::PointVec const* const pnt_obj(getPointVecObj(geo_name)); + if (pnt_obj == nullptr) + { + ERR("Point vector %s not found.", geo_name.c_str()); + return; + } + std::vector<GeoLib::Point*> const& pnts = *pnt_obj->getVector(); + if (pnts.empty()) + { + ERR("Point vector %s is empty.", geo_name.c_str()); + return; + } + std::size_t const n_pnts(pnts.size()); + std::vector<bool> flags(n_pnts, true); + if (only_unused_pnts) + markPointsAsUsed(geo_name, flags); + + std::unique_ptr<std::vector<GeoLib::Point*>> stations( + new std::vector<GeoLib::Point*>); + for (std::size_t i = 0; i < n_pnts; ++i) + { + if (!flags[i]) + continue; + std::string name = pnt_obj->getItemNameByID(i); + if (name.empty()) + name = "Station " + std::to_string(i); + stations->push_back(new GeoLib::Station((*pnts[i])[0], (*pnts[i])[1], + (*pnts[i])[2], name)); + } + std::string vec_name = geo_name + " stations"; + if (!stations->empty()) + addStationVec(std::move(stations), vec_name); + else + WARN("No points found to convert."); +} + +const GeoLib::GeoObject* GEOObjects::getGeoObject( + const std::string& geo_name, + GeoLib::GEOTYPE type, + const std::string& geo_obj_name) const { GeoLib::GeoObject *geo_obj(nullptr); switch (type) { diff --git a/GeoLib/GEOObjects.h b/GeoLib/GEOObjects.h index 15f0ef42bafb7330707e5e29565c74bce786c659..8365b7e563906a785f722542030d1db31221cba7 100644 --- a/GeoLib/GEOObjects.h +++ b/GeoLib/GEOObjects.h @@ -249,6 +249,15 @@ public: void renameGeometry(std::string const& old_name, std::string const& new_name); + /// Constucts a station-vector based on the points of a given geometry. + // @param geo_name name of the geometry + // @param stn_name name of the new station vector + // @param only_usused_pnts if true only points not in a line or surface are + // transferred, otherwise all points + void geoPointsToStation(std::string const& geo_name, + std::string const& stn_name, + bool only_unused_pnts = true); + /// Returns the geo object for a geometric item of the given name and type for the associated geometry. const GeoLib::GeoObject* getGeoObject(const std::string &geo_name, GeoLib::GEOTYPE type, @@ -367,5 +376,8 @@ private: */ void mergeSurfaces(std::vector<std::string> const & geo_names, std::string & merged_geo_name, std::vector<std::size_t> const& pnt_offsets); + + void markPointsAsUsed(std::string const& geo_name, + std::vector<bool>& flags); }; } // end namespace