From 20368df10a55be52c03d3011b37403071f5a74f7 Mon Sep 17 00:00:00 2001 From: Norihiro Watanabe <norihiro.watanabe@ufz.de> Date: Mon, 13 Jul 2015 23:38:58 +0200 Subject: [PATCH] add NodeSearch, ElementSearch, RemoveMeshComponents --- .../DataView/MeshElementRemovalDialog.cpp | 13 +- Applications/Utils/FileConverter/GMSH2OGS.cpp | 7 +- .../Utils/MeshEdit/removeMeshElements.cpp | 7 +- .../BoundaryElementsAlongPolyline.cpp | 6 +- MeshGeoToolsLib/BoundaryElementsOnSurface.cpp | 6 +- MeshGeoToolsLib/BoundaryElementsSearcher.cpp | 1 - MeshLib/CMakeLists.txt | 3 +- MeshLib/MeshEditing/ElementExtraction.cpp | 168 ------------------ MeshLib/MeshEditing/ElementExtraction.h | 84 --------- MeshLib/MeshEditing/RemoveMeshComponents.cpp | 132 ++++++++++++++ MeshLib/MeshEditing/RemoveMeshComponents.h | 42 +++++ MeshLib/MeshEditing/removeMeshNodes.cpp | 74 -------- MeshLib/MeshEditing/removeMeshNodes.h | 31 ---- MeshLib/MeshGenerators/LayeredVolume.cpp | 7 +- MeshLib/MeshQuality/MeshValidation.cpp | 4 +- MeshLib/MeshSearch/ElementSearch.cpp | 123 +++++++++++++ MeshLib/MeshSearch/ElementSearch.h | 63 +++++++ MeshLib/MeshSearch/NodeSearch.cpp | 94 ++++++++++ MeshLib/MeshSearch/NodeSearch.h | 52 ++++++ MeshLib/MeshSearcher.cpp | 73 -------- MeshLib/MeshSearcher.h | 43 ----- ProcessLib/NeumannBc.h | 4 +- Tests/AssemblerLib/LocalToGlobalIndexMap.cpp | 4 +- Tests/MeshLib/TestBoundaryElementSearch.cpp | 14 +- Tests/MeshLib/TestDuplicate.cpp | 16 +- Tests/MeshLib/TestRemove.cpp | 62 +++++++ 26 files changed, 622 insertions(+), 511 deletions(-) delete mode 100644 MeshLib/MeshEditing/ElementExtraction.cpp delete mode 100644 MeshLib/MeshEditing/ElementExtraction.h create mode 100644 MeshLib/MeshEditing/RemoveMeshComponents.cpp create mode 100644 MeshLib/MeshEditing/RemoveMeshComponents.h delete mode 100644 MeshLib/MeshEditing/removeMeshNodes.cpp delete mode 100644 MeshLib/MeshEditing/removeMeshNodes.h create mode 100644 MeshLib/MeshSearch/ElementSearch.cpp create mode 100644 MeshLib/MeshSearch/ElementSearch.h create mode 100644 MeshLib/MeshSearch/NodeSearch.cpp create mode 100644 MeshLib/MeshSearch/NodeSearch.h delete mode 100644 MeshLib/MeshSearcher.cpp delete mode 100644 MeshLib/MeshSearcher.h create mode 100644 Tests/MeshLib/TestRemove.cpp diff --git a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp index f3655e1580e..31c983cb1f7 100644 --- a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp +++ b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp @@ -17,7 +17,8 @@ #include "Mesh.h" #include "Elements/Element.h" #include "MeshLib/Node.h" -#include "MeshEditing/ElementExtraction.h" +#include "MeshLib/MeshSearch/ElementSearch.h" +#include "MeshLib/MeshEditing/RemoveMeshComponents.h" #include "AABB.h" #include "OGSError.h" @@ -60,7 +61,8 @@ void MeshElementRemovalDialog::accept() bool anything_checked (false); - MeshLib::ElementExtraction ex(*_project.getMesh(this->meshNameComboBox->currentText().toStdString())); + const MeshLib::Mesh* msh = _project.getMesh(this->meshNameComboBox->currentText().toStdString()); + MeshLib::ElementSearch ex(*msh); if (this->elementTypeCheckBox->isChecked()) { QList<QListWidgetItem*> items = this->elementTypeListWidget->selectedItems(); @@ -105,15 +107,14 @@ void MeshElementRemovalDialog::accept() if (anything_checked) { - MeshLib::Mesh* new_mesh = ex.removeMeshElements(this->newMeshNameEdit->text().toStdString()); + MeshLib::Mesh* new_mesh = MeshLib::removeElements(*msh, ex.getSearchedElementIDs(), this->newMeshNameEdit->text().toStdString()); if (new_mesh) emit meshAdded(new_mesh); else { - const unsigned error_code (ex.getErrorCode()); - if (error_code == 1) + if (new_mesh == nullptr) OGSError::box("The current selection removes ALL mesh elements.\nPlease change the selection."); - if (error_code == 2) + if (ex.getSearchedElementIDs().empty()) OGSError::box("The current selection removes NO mesh elements."); delete new_mesh; return; diff --git a/Applications/Utils/FileConverter/GMSH2OGS.cpp b/Applications/Utils/FileConverter/GMSH2OGS.cpp index 3dea6a21764..1dd60c566aa 100644 --- a/Applications/Utils/FileConverter/GMSH2OGS.cpp +++ b/Applications/Utils/FileConverter/GMSH2OGS.cpp @@ -36,8 +36,9 @@ #include "FileIO/VtkIO/VtuInterface.h" // MeshLib -#include "MeshLib/MeshEditing/ElementExtraction.h" +#include "MeshLib/MeshSearch/ElementSearch.h" #include "MeshLib/Mesh.h" +#include "MeshLib/MeshEditing/RemoveMeshComponents.h" int main (int argc, char* argv[]) { @@ -96,9 +97,9 @@ int main (int argc, char* argv[]) // *** remove line elements on request if (exclude_lines_arg.getValue()) { - auto ex = MeshLib::ElementExtraction(*mesh); + auto ex = MeshLib::ElementSearch(*mesh); ex.searchByElementType(MeshLib::MeshElemType::LINE); - auto m = ex.removeMeshElements(mesh->getName()+"-withoutLines"); + auto m = MeshLib::removeElements(*mesh, ex.getSearchedElementIDs(), mesh->getName()+"-withoutLines"); if (m != nullptr) { INFO("Removed %d lines.", mesh->getNElements() - m->getNElements()); std::swap(m, mesh); diff --git a/Applications/Utils/MeshEdit/removeMeshElements.cpp b/Applications/Utils/MeshEdit/removeMeshElements.cpp index 4a953ea0cd0..71d1f853a2d 100644 --- a/Applications/Utils/MeshEdit/removeMeshElements.cpp +++ b/Applications/Utils/MeshEdit/removeMeshElements.cpp @@ -29,7 +29,8 @@ #include "MeshLib/Node.h" #include "Elements/Element.h" #include "MeshEnums.h" -#include "MeshEditing/ElementExtraction.h" +#include "MeshSearch/ElementSearch.h" +#include "MeshEditing/RemoveMeshComponents.h" int main (int argc, char* argv[]) { @@ -84,7 +85,7 @@ int main (int argc, char* argv[]) MeshLib::Mesh const*const mesh (FileIO::readMeshFromFile(mesh_in.getValue())); INFO("Mesh read: %d nodes, %d elements.", mesh->getNNodes(), mesh->getNElements()); - MeshLib::ElementExtraction ex(*mesh); + MeshLib::ElementSearch ex(*mesh); // search elements IDs to be removed if (zveArg.isSet()) { @@ -142,7 +143,7 @@ int main (int argc, char* argv[]) } // remove the elements and create a new mesh object. - MeshLib::Mesh const*const new_mesh = ex.removeMeshElements(mesh->getName()); + MeshLib::Mesh const*const new_mesh = MeshLib::removeElements(*mesh, ex.getSearchedElementIDs(), mesh->getName()); // write into a file FileIO::Legacy::MeshIO meshIO; diff --git a/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp index 5398b975c16..c6e24e76aca 100644 --- a/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp +++ b/MeshGeoToolsLib/BoundaryElementsAlongPolyline.cpp @@ -16,7 +16,7 @@ #include "MeshLib/Node.h" #include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Line.h" -#include "MeshLib/MeshSearcher.h" +#include "MeshLib/MeshSearch/ElementSearch.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h" @@ -28,7 +28,9 @@ BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const { // search nodes and elements located along the polyline auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply); - auto ele_ids_near_ply = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_poly); + MeshLib::ElementSearch es(_mesh); + es.searchByNodeIDs(node_ids_on_poly); + auto &ele_ids_near_ply = es.getSearchedElementIDs(); // check all edges of the elements near the polyline for (auto ele_id : ele_ids_near_ply) { diff --git a/MeshGeoToolsLib/BoundaryElementsOnSurface.cpp b/MeshGeoToolsLib/BoundaryElementsOnSurface.cpp index 83c154dfb3f..5bdd855da40 100644 --- a/MeshGeoToolsLib/BoundaryElementsOnSurface.cpp +++ b/MeshGeoToolsLib/BoundaryElementsOnSurface.cpp @@ -12,7 +12,7 @@ #include "MeshLib/Mesh.h" #include "MeshLib/Elements/Element.h" -#include "MeshLib/MeshSearcher.h" +#include "MeshLib/MeshSearch/ElementSearch.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h" @@ -24,7 +24,9 @@ BoundaryElementsOnSurface::BoundaryElementsOnSurface(MeshLib::Mesh const& mesh, { // search elements near the polyline auto node_ids_on_sfc = mshNodeSearcher.getMeshNodeIDsAlongSurface(sfc); - auto ele_ids_near_sfc = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_sfc); + MeshLib::ElementSearch es(_mesh); + es.searchByNodeIDs(node_ids_on_sfc); + auto &ele_ids_near_sfc = es.getSearchedElementIDs(); // get a list of faces made of the nodes for (auto ele_id : ele_ids_near_sfc) { diff --git a/MeshGeoToolsLib/BoundaryElementsSearcher.cpp b/MeshGeoToolsLib/BoundaryElementsSearcher.cpp index 9a9a096f25b..85ef0201c60 100644 --- a/MeshGeoToolsLib/BoundaryElementsSearcher.cpp +++ b/MeshGeoToolsLib/BoundaryElementsSearcher.cpp @@ -14,7 +14,6 @@ #include "MeshLib/Mesh.h" #include "MeshLib/Elements/Element.h" -#include "MeshLib/MeshSearcher.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/BoundaryElementsAlongPolyline.h" diff --git a/MeshLib/CMakeLists.txt b/MeshLib/CMakeLists.txt index 8a41843600c..0ce23cbf767 100644 --- a/MeshLib/CMakeLists.txt +++ b/MeshLib/CMakeLists.txt @@ -9,9 +9,10 @@ endif() GET_SOURCE_FILES(SOURCES_ELEMENTS Elements) GET_SOURCE_FILES(SOURCES_EDITING MeshEditing) GET_SOURCE_FILES(SOURCES_GENERATORS MeshGenerators) +GET_SOURCE_FILES(SOURCES_SEARCH MeshSearch) GET_SOURCE_FILES(SOURCES_QUALITY MeshQuality) -set(SOURCES ${SOURCES_MESHLIB} ${SOURCES_ELEMENTS} ${SOURCES_EDITING} ${SOURCES_GENERATORS} ${SOURCES_QUALITY}) +set(SOURCES ${SOURCES_MESHLIB} ${SOURCES_ELEMENTS} ${SOURCES_EDITING} ${SOURCES_GENERATORS} ${SOURCES_QUALITY} ${SOURCES_SEARCH}) # Create the library add_library(MeshLib STATIC ${SOURCES}) diff --git a/MeshLib/MeshEditing/ElementExtraction.cpp b/MeshLib/MeshEditing/ElementExtraction.cpp deleted file mode 100644 index fbf8d8b83ac..00000000000 --- a/MeshLib/MeshEditing/ElementExtraction.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/** - * \file - * \author Karsten Rink - * \date 2013-04-04 - * \brief Implementation of ElementExtraction. - * - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#include "ElementExtraction.h" - -#include "logog/include/logog.hpp" - -#include "GeoLib/AABB.h" - -#include "MeshLib/Mesh.h" -#include "MeshLib/Elements/Element.h" -#include "MeshLib/MeshQuality/MeshValidation.h" - -#include "DuplicateMeshComponents.h" - -namespace MeshLib { - -ElementExtraction::ElementExtraction(const MeshLib::Mesh &mesh) - : _mesh(mesh), _error_code(0) -{ -} - -ElementExtraction::~ElementExtraction() -{ -} - -MeshLib::Mesh* ElementExtraction::removeMeshElements(const std::string &new_mesh_name) -{ - if (_marked_elements.empty()) - { - INFO("No elements to remove"); - _error_code = 2; - return nullptr; - } - - INFO("Removing total %d elements...", _marked_elements.size()); - std::vector<MeshLib::Element*> tmp_elems = excludeElementCopy( - _mesh.getElements(), - _marked_elements - ); - INFO("%d elements remain in mesh.", tmp_elems.size()); - std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(_mesh.getNodes()); - std::vector<MeshLib::Element*> new_elems = MeshLib::copyElementVector(tmp_elems, new_nodes); - - if (!new_elems.empty()) - { - MeshLib::Mesh* new_mesh = new MeshLib::Mesh(new_mesh_name, - new_nodes, new_elems, - _mesh.getProperties().excludeCopyProperties(_marked_elements) - ); - MeshValidation::removeUnusedMeshNodes(*new_mesh); - return new_mesh; - } - else - { - INFO("Current selection removes all elements."); - _error_code = 1; - return nullptr; - } -} - -std::size_t ElementExtraction::searchByMaterialID(int const matID) -{ - boost::optional<MeshLib::PropertyVector<int> const&> opt_pv( - this->_mesh.getProperties().getPropertyVector<int>("MaterialIDs") - ); - if (!opt_pv) - return 0; - - MeshLib::PropertyVector<int> const& pv(opt_pv.get()); - - std::vector<std::size_t> matchedIDs; - for (std::size_t i(0); i<pv.getNumberOfTuples(); ++i) { - if (pv[i]==matID) - matchedIDs.push_back(i); - } - - this->updateUnion(matchedIDs); - return matchedIDs.size(); -} - -std::size_t ElementExtraction::searchByElementType(MeshElemType eleType) -{ - const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); - std::vector<std::size_t> matchedIDs; - std::size_t i = 0; - for (MeshLib::Element* ele : ele_vec) { - if (ele->getGeomType()==eleType) - matchedIDs.push_back(i); - i++; - } - this->updateUnion(matchedIDs); - return matchedIDs.size(); -} - -std::size_t ElementExtraction::searchByContent(double eps) -{ - const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); - std::vector<std::size_t> matchedIDs; - std::size_t i = 0; - for (MeshLib::Element* ele : ele_vec) { - if (ele->getContent() < eps) - matchedIDs.push_back(i); - i++; - } - this->updateUnion(matchedIDs); - return matchedIDs.size(); -} - -std::size_t ElementExtraction::searchByBoundingBox( - GeoLib::AABB<MathLib::Point3d> const& aabb) -{ - const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); - - std::vector<std::size_t> matchedIDs; - const std::size_t n_elems(ele_vec.size()); - for (std::size_t i = 0; i<n_elems; i++) - { - std::size_t nElemNodes (ele_vec[i]->getNBaseNodes()); - for (std::size_t j=0; j<nElemNodes; ++j) - if (!aabb.containsPoint(*ele_vec[i]->getNode(j))) - { - matchedIDs.push_back(i); - break; - } - } - this->updateUnion(matchedIDs); - return matchedIDs.size(); -} - -std::vector<MeshLib::Element*> ElementExtraction::excludeElementCopy( - std::vector<MeshLib::Element*> const& vec_src_eles, - std::vector<std::size_t> const& vec_removed) const -{ - std::vector<MeshLib::Element*> vec_dest_eles(vec_src_eles.size()-vec_removed.size()); - - unsigned cnt (0); - for (std::size_t i=0; i<vec_removed[0]; ++i) - vec_dest_eles[cnt++] = vec_src_eles[i]; - for (std::size_t i=1; i<vec_removed.size(); ++i) - for (std::size_t j=vec_removed[i-1]+1; j<vec_removed[i]; ++j) - vec_dest_eles[cnt++] = vec_src_eles[j]; - for (std::size_t i=vec_removed.back()+1; i<vec_src_eles.size(); ++i) - vec_dest_eles[cnt++] = vec_src_eles[i]; - - return vec_dest_eles; -} - -void ElementExtraction::updateUnion(const std::vector<std::size_t> &vec) -{ - std::vector<std::size_t> vec_temp(vec.size() + _marked_elements.size()); - auto it = std::set_union(vec.begin(), vec.end(), _marked_elements.begin(), _marked_elements.end(), vec_temp.begin()); - vec_temp.resize(it - vec_temp.begin()); - _marked_elements.assign(vec_temp.begin(), vec_temp.end()); -} - -} // end namespace MeshLib diff --git a/MeshLib/MeshEditing/ElementExtraction.h b/MeshLib/MeshEditing/ElementExtraction.h deleted file mode 100644 index 718419e4fa5..00000000000 --- a/MeshLib/MeshEditing/ElementExtraction.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * \file - * \author Karsten Rink - * \date 2013-04-04 - * \brief Definition of the ElementExtraction - * - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#ifndef ELEMENTEXTRACTION_H -#define ELEMENTEXTRACTION_H - -#include <string> -#include <vector> - -#include "GeoLib/AABB.h" - -#include "MeshLib/MeshEnums.h" -#include "MeshLib/Node.h" - -namespace MeshLib { - -// forward declarations -class Mesh; -class Element; - -class ElementExtraction -{ -public: - ElementExtraction(const MeshLib::Mesh &mesh); - - ~ElementExtraction(); - - /// The error code determined during element extraction - /// (0 = no errors, 1 = all elements selected, 2 = no elements selected) - unsigned getErrorCode() { return _error_code; } - - /// Removes all mesh elements marked by search-methods. - MeshLib::Mesh* removeMeshElements(const std::string &new_mesh_name); - - /// Marks all elements with the given Material ID. - std::size_t searchByMaterialID(int const matID); - - /// Marks all elements of the given element type. - std::size_t searchByElementType(MeshElemType eleType); - - /// Marks all elements with a volume smaller than eps. - std::size_t searchByContent(double eps = std::numeric_limits<double>::epsilon()); - - /// Marks all elements with at least one node outside the bounding box spanned by x1 and x2; - std::size_t searchByBoundingBox(GeoLib::AABB<MathLib::Point3d> const& aabb); - - -private: - /// Updates the vector of marked elements with values from vec. - void updateUnion(const std::vector<std::size_t> &vec); - - /// Returns a vector of shallow copies of the elements in the source vector. - /// The vector vec_removed contains the position of elements within the - /// source vector that should not be copied to the returned vector. - /// @param vec_src_eles vector of source elements which are shallow copied - /// @param vec_removed contains positions of elements in vec_src_eles that - /// should not be copied - /// @return vector of elements (shallow copy!) - std::vector<MeshLib::Element*> excludeElementCopy( - std::vector<MeshLib::Element*> const& vec_src_eles, - std::vector<std::size_t> const& vec_removed) const; - - /// The mesh from which elements should be removed. - const MeshLib::Mesh &_mesh; - /// The vector of element indices that should be removed. - std::vector<std::size_t> _marked_elements; - /// An error code during mesh element extraction for checking the result from outside (0 = no errors). - unsigned _error_code; -}; - -} // end namespace MeshLib - -#endif //ELEMENTEXTRACTION_H diff --git a/MeshLib/MeshEditing/RemoveMeshComponents.cpp b/MeshLib/MeshEditing/RemoveMeshComponents.cpp new file mode 100644 index 00000000000..72505f98a78 --- /dev/null +++ b/MeshLib/MeshEditing/RemoveMeshComponents.cpp @@ -0,0 +1,132 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "RemoveMeshComponents.h" + +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshQuality/MeshValidation.h" +#include "MeshLib/MeshSearch/ElementSearch.h" +#include "MeshLib/MeshSearch/NodeSearch.h" +#include "DuplicateMeshComponents.h" + +namespace MeshLib +{ + +namespace details +{ + +std::vector<MeshLib::Element*> excludeElementCopy( + std::vector<MeshLib::Element*> const& vec_src_eles, + std::vector<std::size_t> const& vec_removed) +{ + std::vector<MeshLib::Element*> vec_dest_eles(vec_src_eles.size()-vec_removed.size()); + + unsigned cnt (0); + for (std::size_t i=0; i<vec_removed[0]; ++i) + vec_dest_eles[cnt++] = vec_src_eles[i]; + for (std::size_t i=1; i<vec_removed.size(); ++i) + for (std::size_t j=vec_removed[i-1]+1; j<vec_removed[i]; ++j) + vec_dest_eles[cnt++] = vec_src_eles[j]; + for (std::size_t i=vec_removed.back()+1; i<vec_src_eles.size(); ++i) + vec_dest_eles[cnt++] = vec_src_eles[i]; + + return vec_dest_eles; +} + +} // details + +MeshLib::Mesh* removeElements(const MeshLib::Mesh& mesh, const std::vector<std::size_t> &removed_element_ids, const std::string &new_mesh_name) +{ + if (removed_element_ids.empty()) + { + INFO("No elements to remove"); + return nullptr; + } + + INFO("Removing total %d elements...", removed_element_ids.size()); + std::vector<MeshLib::Element*> tmp_elems = details::excludeElementCopy( + mesh.getElements(), + removed_element_ids + ); + INFO("%d elements remain in mesh.", tmp_elems.size()); + + // copy node and element objects + std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(mesh.getNodes()); + std::vector<MeshLib::Element*> new_elems = MeshLib::copyElementVector(tmp_elems, new_nodes); + + // delete unused nodes + NodeSearch ns(mesh); + ns.searchByElementIDs(removed_element_ids, true); + auto &removed_node_ids(ns.getSearchedNodeIDs()); + INFO("Removing total %d nodes...", removed_node_ids.size()); + for (auto nodeid : removed_node_ids) + { + delete new_nodes[nodeid]; + new_nodes[nodeid] = nullptr; + } + new_nodes.erase(std::remove(new_nodes.begin(), new_nodes.end(), nullptr), new_nodes.end()); + + if (!new_elems.empty()) + { + MeshLib::Mesh* new_mesh = new MeshLib::Mesh(new_mesh_name, + new_nodes, new_elems, + mesh.getProperties().excludeCopyProperties(removed_element_ids) + ); + return new_mesh; + } + else + { + INFO("Current selection removes all elements."); + return nullptr; + } +} + +MeshLib::Mesh* removeNodes(const MeshLib::Mesh &mesh, const std::vector<std::size_t> &del_nodes_idx, const std::string &new_mesh_name) +{ + if (del_nodes_idx.empty()) + return nullptr; + + // copy node and element objects + std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(mesh.getNodes()); + std::vector<MeshLib::Element*> new_elems = MeshLib::copyElementVector(mesh.getElements(), new_nodes); + + // delete nodes + for (auto nodeid : del_nodes_idx) + { + delete new_nodes[nodeid]; + new_nodes[nodeid] = nullptr; + } + new_nodes.erase(std::remove(new_nodes.begin(), new_nodes.end(), nullptr), new_nodes.end()); + + // delete elements + MeshLib::ElementSearch es(mesh); + es.searchByNodeIDs(del_nodes_idx); + auto& removed_element_ids = es.getSearchedElementIDs(); + for (auto eid : removed_element_ids) + { + delete new_elems[eid]; + new_elems[eid] = nullptr; + } + new_elems.erase(std::remove(new_elems.begin(), new_elems.end(), nullptr), new_elems.end()); + + if (!new_elems.empty()) + { + MeshLib::Mesh* new_mesh = new MeshLib::Mesh(new_mesh_name, + new_nodes, new_elems, + mesh.getProperties().excludeCopyProperties(removed_element_ids) + ); + return new_mesh; + } + else + { + return nullptr; + } +} +} // end namespace MeshLib + diff --git a/MeshLib/MeshEditing/RemoveMeshComponents.h b/MeshLib/MeshEditing/RemoveMeshComponents.h new file mode 100644 index 00000000000..3e78e89f868 --- /dev/null +++ b/MeshLib/MeshEditing/RemoveMeshComponents.h @@ -0,0 +1,42 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#ifndef REMOVEMESHCOMPONENTS_H_ +#define REMOVEMESHCOMPONENTS_H_ + +#include <string> +#include <vector> + +namespace MeshLib +{ +class Mesh; +class Element; + +/** + * Removes mesh elements and returns a new mesh object. The original mesh is kept unchanged. + * @param mesh an original mesh whose elements are removed + * @param removed_element_ids a vector of element indices to be removed + * @param new_mesh_name a new mesh name + * @return a new mesh object + */ +MeshLib::Mesh* removeElements(const MeshLib::Mesh& mesh, + const std::vector<std::size_t> &removed_element_ids, const std::string &new_mesh_name); + +/** + * Removes the mesh nodes (and connected elements) given in the nodes-list from the mesh. + * @param mesh an original mesh whose elements are removed + * @param removed_node_ids a vector of node indices to be removed + * @param new_mesh_name a new mesh name + * @return a new mesh object + */ +MeshLib::Mesh* removeNodes(const MeshLib::Mesh &mesh, const std::vector<std::size_t> &removed_node_ids, const std::string &new_mesh_name); + +} // end namespace MeshLib + +#endif //REMOVEMESHCOMPONENTS_H_ diff --git a/MeshLib/MeshEditing/removeMeshNodes.cpp b/MeshLib/MeshEditing/removeMeshNodes.cpp deleted file mode 100644 index c662bb84074..00000000000 --- a/MeshLib/MeshEditing/removeMeshNodes.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * \file - * \author Karsten Rink - * \date 2013-04-04 - * \brief Implementation of removeMeshNodes. - * - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#include "removeMeshNodes.h" - -#include "MeshLib/Mesh.h" -#include "MeshLib/Node.h" -#include "MeshLib/Elements/Element.h" - -namespace MeshLib { - -void removeMeshNodes(MeshLib::Mesh &mesh, const std::vector<std::size_t> &del_nodes_idx) -{ - const size_t nDelNodes = del_nodes_idx.size(); - if (nDelNodes == 0) - return; - - std::vector<MeshLib::Node*>& nodes (mesh._nodes); - std::vector<MeshLib::Element*>& elements = mesh._elements; - bool elements_removed (false); - - // delete nodes - for (std::size_t i = 0; i < nDelNodes; ++i) - { - const unsigned idx (del_nodes_idx[i]); - std::vector<MeshLib::Element*> conn_elems (nodes[idx]->getElements()); - - // delete elements connected to these nodes - for (std::size_t j = 0; j < conn_elems.size(); ++j) - { - elements_removed = true; - auto del_elem (std::find(elements.begin(), elements.end(), conn_elems[j])); - delete *del_elem; - *del_elem = nullptr; - } - - delete nodes[idx]; - nodes[idx] = nullptr; - } - - // due to element removal neighbourhoods have to be reset and additional nodes - // might need to be deleted as they are no longer part of any element - if (elements_removed) - { - auto elem_vec_end = std::remove(elements.begin(), elements.end(), nullptr); - elements.erase(elem_vec_end, elements.end()); - mesh.resetElementsConnectedToNodes(); - for (auto node = nodes.begin(); node != nodes.end(); ++node) - if ((*node) && (*node)->getNElements() == 0) - { - delete *node; - *node = nullptr; - } - } - - auto node_vec_end = std::remove(nodes.begin(), nodes.end(), nullptr); - nodes.erase(node_vec_end, nodes.end()); - - mesh.resetNodeIDs(); // set new node-IDs -} - - -} // end namespace MeshLib diff --git a/MeshLib/MeshEditing/removeMeshNodes.h b/MeshLib/MeshEditing/removeMeshNodes.h deleted file mode 100644 index 87619353aa2..00000000000 --- a/MeshLib/MeshEditing/removeMeshNodes.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * \file - * \author Karsten Rink - * \date 2013-04-04 - * \brief Definition of the removeMeshNodes - * - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#ifndef REMOVEMESHNODES_H -#define REMOVEMESHNODES_H - -#include <vector> - -namespace MeshLib { - -// forward declarations -class Mesh; - - /// Removes the mesh nodes (and connected elements) given in the nodes-list from the mesh. - /// \warning This function actually modifies the mesh, it might make sense to copy the mesh before using this function. - void removeMeshNodes(MeshLib::Mesh &mesh, const std::vector<std::size_t> &nodes); - -} // end namespace MeshLib - -#endif //REMOVEMESHNODES_H diff --git a/MeshLib/MeshGenerators/LayeredVolume.cpp b/MeshLib/MeshGenerators/LayeredVolume.cpp index f955a5fe389..463006dd3a7 100644 --- a/MeshLib/MeshGenerators/LayeredVolume.cpp +++ b/MeshLib/MeshGenerators/LayeredVolume.cpp @@ -20,9 +20,10 @@ #include "MeshLib/Elements/Tri.h" #include "MeshLib/Elements/Quad.h" -#include "MeshLib/MeshEditing/ElementExtraction.h" #include "MeshLib/MeshEditing/DuplicateMeshComponents.h" +#include "MeshLib/MeshEditing/RemoveMeshComponents.h" #include "MeshLib/MeshGenerators/MeshLayerMapper.h" +#include "MeshLib/MeshSearch/ElementSearch.h" bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, @@ -38,9 +39,9 @@ bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, return false; // remove line elements, only tri + quad remain - MeshLib::ElementExtraction ex(mesh); + MeshLib::ElementSearch ex(mesh); ex.searchByElementType(MeshLib::MeshElemType::LINE); - MeshLib::Mesh* top (ex.removeMeshElements("MeshLayer")); + MeshLib::Mesh* top (removeElements(mesh, ex.getSearchedElementIDs(), "MeshLayer")); if (top==nullptr) top = new MeshLib::Mesh(mesh); diff --git a/MeshLib/MeshQuality/MeshValidation.cpp b/MeshLib/MeshQuality/MeshValidation.cpp index 940461ae573..06cd0a77e1e 100644 --- a/MeshLib/MeshQuality/MeshValidation.cpp +++ b/MeshLib/MeshQuality/MeshValidation.cpp @@ -23,8 +23,8 @@ #include "MeshLib/Mesh.h" #include "MeshLib/Node.h" #include "MeshLib/Elements/Element.h" -#include "MeshLib/MeshEditing/removeMeshNodes.h" #include "MeshLib/MeshEditing/MeshRevision.h" +#include "MeshLib/MeshEditing/RemoveMeshComponents.h" #include "MeshLib/MeshSurfaceExtraction.h" namespace MeshLib { @@ -65,7 +65,7 @@ std::vector<std::size_t> MeshValidation::findUnusedMeshNodes(const MeshLib::Mesh std::vector<std::size_t> MeshValidation::removeUnusedMeshNodes(MeshLib::Mesh &mesh) { std::vector<std::size_t> del_node_idx = MeshValidation::findUnusedMeshNodes(mesh); - MeshLib::removeMeshNodes(mesh, del_node_idx); + MeshLib::removeNodes(mesh, del_node_idx, mesh.getName()); if (!del_node_idx.empty()) INFO("Removed %d unused mesh nodes.", del_node_idx.size()); diff --git a/MeshLib/MeshSearch/ElementSearch.cpp b/MeshLib/MeshSearch/ElementSearch.cpp new file mode 100644 index 00000000000..61441cbdefc --- /dev/null +++ b/MeshLib/MeshSearch/ElementSearch.cpp @@ -0,0 +1,123 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "ElementSearch.h" + +#include <logog/include/logog.hpp> + +#include "MeshLib/Mesh.h" +#include "MeshLib/Node.h" +#include "MeshLib/Elements/Element.h" + +namespace MeshLib { + +ElementSearch::ElementSearch(const MeshLib::Mesh &mesh) + : _mesh(mesh) +{ +} + +ElementSearch::~ElementSearch() +{ +} + +std::size_t ElementSearch::searchByMaterialID(int const matID) +{ + boost::optional<MeshLib::PropertyVector<int> const&> opt_pv( + this->_mesh.getProperties().getPropertyVector<int>("MaterialIDs") + ); + if (!opt_pv) + return 0; + + MeshLib::PropertyVector<int> const& pv(opt_pv.get()); + + std::vector<std::size_t> matchedIDs; + for (std::size_t i(0); i<pv.getNumberOfTuples(); ++i) { + if (pv[i]==matID) + matchedIDs.push_back(i); + } + + this->updateUnion(matchedIDs); + return matchedIDs.size(); +} + +std::size_t ElementSearch::searchByElementType(MeshElemType eleType) +{ + const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); + std::vector<std::size_t> matchedIDs; + std::size_t i = 0; + for (MeshLib::Element* ele : ele_vec) { + if (ele->getGeomType()==eleType) + matchedIDs.push_back(i); + i++; + } + this->updateUnion(matchedIDs); + return matchedIDs.size(); +} + +std::size_t ElementSearch::searchByContent(double eps) +{ + const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); + std::vector<std::size_t> matchedIDs; + std::size_t i = 0; + for (MeshLib::Element* ele : ele_vec) { + if (ele->getContent() < eps) + matchedIDs.push_back(i); + i++; + } + this->updateUnion(matchedIDs); + return matchedIDs.size(); +} + +std::size_t ElementSearch::searchByBoundingBox( + GeoLib::AABB<MathLib::Point3d> const& aabb) +{ + const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); + + std::vector<std::size_t> matchedIDs; + const std::size_t n_elems(ele_vec.size()); + for (std::size_t i = 0; i<n_elems; i++) + { + std::size_t nElemNodes (ele_vec[i]->getNBaseNodes()); + for (std::size_t j=0; j<nElemNodes; ++j) + if (!aabb.containsPoint(*ele_vec[i]->getNode(j))) + { + matchedIDs.push_back(i); + break; + } + } + this->updateUnion(matchedIDs); + return matchedIDs.size(); +} + +std::size_t ElementSearch::searchByNodeIDs(const std::vector<std::size_t> &nodes) +{ + std::vector<std::size_t> connected_elements; + std::for_each(nodes.begin(), nodes.end(), + [&](std::size_t node_id) + { + for (auto* e : _mesh.getNode(node_id)->getElements()) { + connected_elements.push_back(e->getID()); + } + }); + std::sort(connected_elements.begin(), connected_elements.end()); + auto it = std::unique(connected_elements.begin(), connected_elements.end()); + connected_elements.resize(std::distance(connected_elements.begin(),it)); + this->updateUnion(connected_elements); + return connected_elements.size(); +} + +void ElementSearch::updateUnion(const std::vector<std::size_t> &vec) +{ + std::vector<std::size_t> vec_temp(vec.size() + _marked_elements.size()); + auto it = std::set_union(vec.begin(), vec.end(), _marked_elements.begin(), _marked_elements.end(), vec_temp.begin()); + vec_temp.resize(it - vec_temp.begin()); + _marked_elements.assign(vec_temp.begin(), vec_temp.end()); +} + +} // end namespace MeshLib diff --git a/MeshLib/MeshSearch/ElementSearch.h b/MeshLib/MeshSearch/ElementSearch.h new file mode 100644 index 00000000000..85715826feb --- /dev/null +++ b/MeshLib/MeshSearch/ElementSearch.h @@ -0,0 +1,63 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#ifndef ELEMENTSEARCH_H_ +#define ELEMENTSEARCH_H_ + +#include <limits> +#include <vector> + +#include "GeoLib/AABB.h" +#include "MeshLib/MeshEnums.h" + +namespace MeshLib { + +// forward declarations +class Mesh; +class Element; + +/// Element search class +class ElementSearch +{ +public: + explicit ElementSearch(const MeshLib::Mesh &mesh); + + ~ElementSearch(); + + /// return marked elements + const std::vector<std::size_t>& getSearchedElementIDs() const { return _marked_elements; } + + /// Marks all elements with the given Material ID. + std::size_t searchByMaterialID(int const matID); + + /// Marks all elements of the given element type. + std::size_t searchByElementType(MeshElemType eleType); + + /// Marks all elements with a volume smaller than eps. + std::size_t searchByContent(double eps = std::numeric_limits<double>::epsilon()); + + /// Marks all elements with at least one node outside the bounding box spanned by x1 and x2; + std::size_t searchByBoundingBox(GeoLib::AABB<MathLib::Point3d> const& aabb); + + /// Marks all elements connecting to any of the given nodes + std::size_t searchByNodeIDs(const std::vector<std::size_t> &node_ids); + +private: + /// Updates the vector of marked elements with values from vec. + void updateUnion(const std::vector<std::size_t> &vec); + + /// The mesh from which elements should be removed. + const MeshLib::Mesh &_mesh; + /// The vector of element indices that should be removed. + std::vector<std::size_t> _marked_elements; +}; + +} // end namespace MeshLib + +#endif //ELEMENTEXTRACTION_H diff --git a/MeshLib/MeshSearch/NodeSearch.cpp b/MeshLib/MeshSearch/NodeSearch.cpp new file mode 100644 index 00000000000..a697705dd49 --- /dev/null +++ b/MeshLib/MeshSearch/NodeSearch.cpp @@ -0,0 +1,94 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "NodeSearch.h" + +#include <set> + +#include <logog/include/logog.hpp> + +#include "MeshLib/Mesh.h" +#include "MeshLib/Node.h" +#include "MeshLib/Elements/Element.h" + +namespace MeshLib { + +NodeSearch::NodeSearch(const MeshLib::Mesh &mesh) + : _mesh(mesh) +{ +} + +NodeSearch::~NodeSearch() +{ +} + +std::size_t NodeSearch::searchByElementIDs(const std::vector<std::size_t> &elements, bool only_match_all_connected_elements) +{ + std::vector<std::size_t> connected_nodes; + if (only_match_all_connected_elements) + { + std::vector<std::size_t> node_marked_counts(_mesh.getNNodes(), 0); //this approach is not optimum for memory size + std::for_each(elements.begin(), elements.end(), + [&](std::size_t eid) + { + auto* e = _mesh.getElement(eid); + for (unsigned i=0; i<e->getNBaseNodes(); i++) { + node_marked_counts[e->getNodeIndex(i)]++; + } + }); + for (std::size_t i=0; i<node_marked_counts.size(); i++) + { + if (node_marked_counts[i] == _mesh.getNode(i)->getElements().size()) + connected_nodes.push_back(i); + } + } else { + std::for_each(elements.begin(), elements.end(), + [&](std::size_t eid) + { + auto* e = _mesh.getElement(eid); + for (unsigned i=0; i<e->getNBaseNodes(); i++) { + connected_nodes.push_back(e->getNodeIndex(i)); + } + }); + std::sort(connected_nodes.begin(), connected_nodes.end()); + auto it = std::unique(connected_nodes.begin(), connected_nodes.end()); + connected_nodes.resize(std::distance(connected_nodes.begin(),it)); + } + this->updateUnion(connected_nodes); + return connected_nodes.size(); +} + +void NodeSearch::updateUnion(const std::vector<std::size_t> &vec) +{ + std::vector<std::size_t> vec_temp(vec.size() + _marked_nodes.size()); + auto it = std::set_union(vec.begin(), vec.end(), _marked_nodes.begin(), _marked_nodes.end(), vec_temp.begin()); + vec_temp.resize(it - vec_temp.begin()); + _marked_nodes.assign(vec_temp.begin(), vec_temp.end()); +} + +std::vector<Node*> getNodes(std::vector<Element*> const& elements) +{ + std::set<Node*> nodes_set; + for (auto e : elements) + { + Node* const* nodes = e->getNodes(); + unsigned const nnodes = e->getNNodes(); + nodes_set.insert(nodes, nodes + nnodes); + } + + std::vector<Node*> nodes; + nodes.reserve(nodes_set.size()); + + std::move(nodes_set.cbegin(), nodes_set.cend(), + std::back_inserter(nodes)); + + return nodes; +} + +} // end namespace MeshLib diff --git a/MeshLib/MeshSearch/NodeSearch.h b/MeshLib/MeshSearch/NodeSearch.h new file mode 100644 index 00000000000..3dddc285303 --- /dev/null +++ b/MeshLib/MeshSearch/NodeSearch.h @@ -0,0 +1,52 @@ +/** + * \copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#ifndef NODESEARCH_H_ +#define NODESEARCH_H_ + +#include <vector> + +namespace MeshLib +{ + +// forward declarations +class Mesh; +class Element; +class Node; + +/// Node search class +class NodeSearch +{ +public: + explicit NodeSearch(const MeshLib::Mesh &mesh); + + ~NodeSearch(); + + /// return marked node IDs + const std::vector<std::size_t>& getSearchedNodeIDs() const {return _marked_nodes; } + + /// Marks all nodes connecting to any of the given elements + std::size_t searchByElementIDs(const std::vector<std::size_t> &element_ids, bool only_match_all_connected_elements = false); + +private: + /// Updates the vector of marked items with values from vec. + void updateUnion(const std::vector<std::size_t> &vec); + + /// The mesh from which elements should be removed. + const MeshLib::Mesh &_mesh; + /// The vector of element indices that should be removed. + std::vector<std::size_t> _marked_nodes; +}; + +/// Create a vector of unique nodes used by given elements. +std::vector<Node*> getNodes(std::vector<Element*> const& elements); + +} // end namespace MeshLib + +#endif //NODESEARCH_H_ diff --git a/MeshLib/MeshSearcher.cpp b/MeshLib/MeshSearcher.cpp deleted file mode 100644 index a3df803b8e7..00000000000 --- a/MeshLib/MeshSearcher.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#include "MeshSearcher.h" - -#include <algorithm> - -#include "Mesh.h" -#include "Node.h" -#include "Elements/Element.h" - -namespace MeshLib -{ - -std::vector<std::size_t> getConnectedElementIDs(MeshLib::Mesh const& msh, const std::vector<std::size_t> &nodes) -{ - std::vector<std::size_t> connected_elements; - std::for_each(nodes.begin(), nodes.end(), - [&](std::size_t node_id) - { - for (auto* e : msh.getNode(node_id)->getElements()) { - connected_elements.push_back(e->getID()); - } - }); - std::sort(connected_elements.begin(), connected_elements.end()); - auto it = std::unique(connected_elements.begin(), connected_elements.end()); - connected_elements.resize(std::distance(connected_elements.begin(),it)); - return connected_elements; -} - -std::vector<std::size_t> getConnectedNodeIDs(const std::vector<MeshLib::Element*> &elements) -{ - std::vector<std::size_t> connected_nodes; - std::for_each(elements.begin(), elements.end(), - [&](MeshLib::Element* e) - { - for (unsigned i=0; i<e->getNBaseNodes(); i++) - connected_nodes.push_back(e->getNodeIndex(i)); - }); - std::sort(connected_nodes.begin(), connected_nodes.end()); - auto it = std::unique(connected_nodes.begin(), connected_nodes.end()); - connected_nodes.resize(std::distance(connected_nodes.begin(),it)); - return connected_nodes; -} - -std::vector<Node*> -selectNodes(std::vector<Element*> const& elements) -{ - std::set<Node*> nodes_set; - for (auto e : elements) - { - Node* const* nodes = e->getNodes(); - unsigned const nnodes = e->getNNodes(); - nodes_set.insert(nodes, nodes + nnodes); - } - - std::vector<Node*> nodes; - nodes.reserve(nodes_set.size()); - - std::move(nodes_set.cbegin(), nodes_set.cend(), - std::back_inserter(nodes)); - - return nodes; -} - -} // end namespace MeshLib - diff --git a/MeshLib/MeshSearcher.h b/MeshLib/MeshSearcher.h deleted file mode 100644 index 1a211880d73..00000000000 --- a/MeshLib/MeshSearcher.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * \copyright - * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#ifndef MESHSEARCHER_H_ -#define MESHSEARCHER_H_ - -#include <vector> - - -namespace MeshLib -{ -// forward declarations -class Mesh; -class Element; -class Node; - -/** - * get a vector of elements connected to given nodes - * @param msh a mesh object - * @param node_ids a vector of mesh node ids - * @return a vector of element ids which connect to the given nodes - */ -std::vector<std::size_t> getConnectedElementIDs(MeshLib::Mesh const& msh, const std::vector<std::size_t> &node_ids); - -/** - * get a vector of node ID connected to given elements - * @param elements a vector of a pointer to a mesh element object - * @return a vector of node ID - */ -std::vector<std::size_t> getConnectedNodeIDs(const std::vector<MeshLib::Element*> &elements); - -/// Create a vector of unique nodes used by given elements. -std::vector<Node*> selectNodes(std::vector<Element*> const& elements); - -} // end namespace MeshLib - -#endif //MESHSEARCHER_H_ diff --git a/ProcessLib/NeumannBc.h b/ProcessLib/NeumannBc.h index c1349964d11..b31b3d6aea2 100644 --- a/ProcessLib/NeumannBc.h +++ b/ProcessLib/NeumannBc.h @@ -21,10 +21,10 @@ #include "AssemblerLib/LocalDataInitializer.h" #include "AssemblerLib/LocalAssemblerBuilder.h" #include "MeshLib/MeshSubset.h" +#include "MeshLib/MeshSearch/NodeSearch.h" #include "NeumannBcConfig.h" #include "NeumannBcAssembler.h" -#include "MeshLib/MeshSearcher.h" namespace ProcessLib { @@ -64,7 +64,7 @@ public: std::back_inserter(_elements), std::mem_fn(&MeshLib::Element::clone)); - std::vector<MeshLib::Node*> nodes = MeshLib::selectNodes(_elements); + std::vector<MeshLib::Node*> nodes = MeshLib::getNodes(_elements); _mesh_subset_all_nodes = mesh_subset_all_nodes.getIntersectionByNodes(nodes); diff --git a/Tests/AssemblerLib/LocalToGlobalIndexMap.cpp b/Tests/AssemblerLib/LocalToGlobalIndexMap.cpp index b73bdcdf86c..f625863b20a 100644 --- a/Tests/AssemblerLib/LocalToGlobalIndexMap.cpp +++ b/Tests/AssemblerLib/LocalToGlobalIndexMap.cpp @@ -14,7 +14,7 @@ #include "AssemblerLib/LocalToGlobalIndexMap.h" #include "MeshLib/MeshGenerators/MeshGenerator.h" -#include "MeshLib/MeshSearcher.h" +#include "MeshLib/MeshSearch/NodeSearch.h" #include "MeshLib/MeshSubsets.h" #include "MeshLib/Mesh.h" @@ -88,7 +88,7 @@ TEST_F(AssemblerLibLocalToGlobalIndexMapTest, SubsetByComponent) some_elements.push_back(const_cast<MeshLib::Element*>(mesh->getElement(id))); // Find unique node ids of the selected elements for testing. - std::vector<MeshLib::Node*> selected_nodes = MeshLib::selectNodes(some_elements); + std::vector<MeshLib::Node*> selected_nodes = MeshLib::getNodes(some_elements); MeshLib::MeshSubset const* const selected_subset = nodesSubset->getIntersectionByNodes(selected_nodes); diff --git a/Tests/MeshLib/TestBoundaryElementSearch.cpp b/Tests/MeshLib/TestBoundaryElementSearch.cpp index ad27a40a0e8..f5b74b9bd98 100644 --- a/Tests/MeshLib/TestBoundaryElementSearch.cpp +++ b/Tests/MeshLib/TestBoundaryElementSearch.cpp @@ -15,7 +15,7 @@ #include "MeshLib/Node.h" #include "MeshLib/Elements/Element.h" #include "MeshLib/MeshGenerators/MeshGenerator.h" -#include "MeshLib/MeshSearcher.h" +#include "MeshLib/MeshSearch/NodeSearch.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/HeuristicSearchLength.h" #include "MeshGeoToolsLib/BoundaryElementsSearcher.h" @@ -151,7 +151,11 @@ TEST_F(MeshLibBoundaryElementSearchInSimpleHexMesh, SurfaceSearch) double sum_area_b = std::accumulate(found_faces_sfc_b.begin(), found_faces_sfc_b.end(), 0.0, [](double v, MeshLib::Element*e){return v+e->getContent();}); ASSERT_EQ(_geometric_size*_geometric_size, sum_area_b); - auto connected_nodeIDs_b = MeshLib::getConnectedNodeIDs(found_faces_sfc_b); + MeshLib::NodeSearch ns(*_hex_mesh); + std::vector<std::size_t> found_faces_sfc_b_ids; + for (auto e : found_faces_sfc_b) found_faces_sfc_b_ids.push_back(e->getID()); + ns.searchByElementIDs(found_faces_sfc_b_ids); + auto& connected_nodeIDs_b = ns.getSearchedNodeIDs(); ASSERT_EQ(n_nodes_2d, connected_nodeIDs_b.size()); for (auto nodeID : connected_nodeIDs_b) ASSERT_EQ(0.0, (*_hex_mesh->getNode(nodeID))[2]); // check z coordinates @@ -162,7 +166,11 @@ TEST_F(MeshLibBoundaryElementSearchInSimpleHexMesh, SurfaceSearch) double sum_area_f = std::accumulate(found_faces_sfc_f.begin(), found_faces_sfc_f.end(), 0.0, [](double v, MeshLib::Element*e){return v+e->getContent();}); ASSERT_EQ(_geometric_size*_geometric_size, sum_area_f); - auto connected_nodeIDs_f = MeshLib::getConnectedNodeIDs(found_faces_sfc_f); + MeshLib::NodeSearch ns_f(*_hex_mesh); + std::vector<std::size_t> found_faces_sfc_f_ids; + for (auto e : found_faces_sfc_f) found_faces_sfc_f_ids.push_back(e->getID()); + ns_f.searchByElementIDs(found_faces_sfc_f_ids); + auto& connected_nodeIDs_f = ns_f.getSearchedNodeIDs(); ASSERT_EQ(n_nodes_2d, connected_nodeIDs_f.size()); for (auto nodeID : connected_nodeIDs_f) ASSERT_EQ(0.0, (*_hex_mesh->getNode(nodeID))[1]); // check y coordinates diff --git a/Tests/MeshLib/TestDuplicate.cpp b/Tests/MeshLib/TestDuplicate.cpp index 9bd7169e50c..b6f2638aaaa 100644 --- a/Tests/MeshLib/TestDuplicate.cpp +++ b/Tests/MeshLib/TestDuplicate.cpp @@ -19,7 +19,7 @@ #include "MeshLib/Node.h" #include "Elements/Element.h" #include "MeshEditing/DuplicateMeshComponents.h" -#include "MeshEditing/removeMeshNodes.h" +#include "MeshEditing/RemoveMeshComponents.h" #include "MeshGenerators/MeshGenerator.h" #include "MeshQuality/MeshValidation.h" #include "MathTools.h" @@ -38,14 +38,14 @@ TEST(MeshLib, Duplicate) ASSERT_EQ (mesh->getNNodes(), new_mesh.getNNodes()); std::vector<std::size_t> del_idx(1,1); - MeshLib::removeMeshNodes(*mesh, del_idx); + std::unique_ptr<MeshLib::Mesh> mesh2(MeshLib::removeNodes(*mesh, del_idx, "mesh2")); - ASSERT_EQ (mesh->getNElements(), new_mesh.getNElements()-2); - ASSERT_EQ (mesh->getNNodes(), new_mesh.getNNodes()-2); + ASSERT_EQ (mesh2->getNElements(), new_mesh.getNElements()-2); + ASSERT_EQ (mesh2->getNNodes(), new_mesh.getNNodes()-2); - ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh->getNode(0), *new_mesh.getNode(0))); - ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh->getNode(0), *new_mesh.getNode(2))); + ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh2->getNode(0), *new_mesh.getNode(0))); + ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh2->getNode(0), *new_mesh.getNode(2))); - ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh->getElement(0)->getNode(0), *new_mesh.getElement(0)->getNode(0))); - ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh->getElement(0)->getNode(0), *new_mesh.getElement(2)->getNode(0))); + ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh2->getElement(0)->getNode(0), *new_mesh.getElement(0)->getNode(0))); + ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh2->getElement(0)->getNode(0), *new_mesh.getElement(2)->getNode(0))); } diff --git a/Tests/MeshLib/TestRemove.cpp b/Tests/MeshLib/TestRemove.cpp new file mode 100644 index 00000000000..b753a8ebbc3 --- /dev/null +++ b/Tests/MeshLib/TestRemove.cpp @@ -0,0 +1,62 @@ +/** + * @file TestDuplicate.cpp + * @author Karsten Rink + * @date 2013-03-25 + * @brief Tests for Duplicate functions + * + * @copyright + * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ + +#include <memory> + +#include "gtest/gtest.h" + +#include "Mesh.h" +#include "MeshLib/Node.h" +#include "Elements/Element.h" +#include "MeshEditing/RemoveMeshComponents.h" +#include "MeshGenerators/MeshGenerator.h" +#include "MeshQuality/MeshValidation.h" +#include "MathTools.h" + +TEST(MeshLib, RemoveNodes) +{ + auto mesh = std::unique_ptr<MeshLib::Mesh>{ + MeshLib::MeshGenerator::generateLineMesh(1.0, 9)}; + + std::vector<std::size_t> removed_node_ids; + for (std::size_t i=0; i<5; i++) + removed_node_ids.push_back(i); + + auto new_mesh = std::unique_ptr<MeshLib::Mesh>{ + MeshLib::removeNodes(*mesh, removed_node_ids, "")}; + + ASSERT_EQ(5u, new_mesh->getNNodes()); + ASSERT_EQ(5u, new_mesh->getNBaseNodes()); + ASSERT_EQ(4u, new_mesh->getNElements()); + for (std::size_t i=0; i<new_mesh->getNNodes(); i++) + ASSERT_TRUE(*mesh->getNode(5+i) == *new_mesh->getNode(i)); +} + +TEST(MeshLib, RemoveElements) +{ + auto mesh = std::unique_ptr<MeshLib::Mesh>{ + MeshLib::MeshGenerator::generateLineMesh(1.0, 9)}; + + std::vector<std::size_t> removed_ele_ids; + for (std::size_t i=0; i<5; i++) + removed_ele_ids.push_back(i); + + auto new_mesh = std::unique_ptr<MeshLib::Mesh>{ + MeshLib::removeElements(*mesh, removed_ele_ids, "")}; + + ASSERT_EQ(5u, new_mesh->getNNodes()); + ASSERT_EQ(5u, new_mesh->getNBaseNodes()); + ASSERT_EQ(4u, new_mesh->getNElements()); + for (std::size_t i=0; i<new_mesh->getNNodes(); i++) + ASSERT_TRUE(*mesh->getNode(5+i) == *new_mesh->getNode(i)); +} -- GitLab