Skip to content
Snippets Groups Projects
Commit 20368df1 authored by Norihiro Watanabe's avatar Norihiro Watanabe
Browse files

add NodeSearch, ElementSearch, RemoveMeshComponents

parent 745705e6
No related branches found
No related tags found
No related merge requests found
Showing
with 541 additions and 205 deletions
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
#include "Mesh.h" #include "Mesh.h"
#include "Elements/Element.h" #include "Elements/Element.h"
#include "MeshLib/Node.h" #include "MeshLib/Node.h"
#include "MeshEditing/ElementExtraction.h" #include "MeshLib/MeshSearch/ElementSearch.h"
#include "MeshLib/MeshEditing/RemoveMeshComponents.h"
#include "AABB.h" #include "AABB.h"
#include "OGSError.h" #include "OGSError.h"
...@@ -60,7 +61,8 @@ void MeshElementRemovalDialog::accept() ...@@ -60,7 +61,8 @@ void MeshElementRemovalDialog::accept()
bool anything_checked (false); 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()) if (this->elementTypeCheckBox->isChecked())
{ {
QList<QListWidgetItem*> items = this->elementTypeListWidget->selectedItems(); QList<QListWidgetItem*> items = this->elementTypeListWidget->selectedItems();
...@@ -105,15 +107,14 @@ void MeshElementRemovalDialog::accept() ...@@ -105,15 +107,14 @@ void MeshElementRemovalDialog::accept()
if (anything_checked) 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) if (new_mesh)
emit meshAdded(new_mesh); emit meshAdded(new_mesh);
else else
{ {
const unsigned error_code (ex.getErrorCode()); if (new_mesh == nullptr)
if (error_code == 1)
OGSError::box("The current selection removes ALL mesh elements.\nPlease change the selection."); 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."); OGSError::box("The current selection removes NO mesh elements.");
delete new_mesh; delete new_mesh;
return; return;
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "FileIO/VtkIO/VtuInterface.h" #include "FileIO/VtkIO/VtuInterface.h"
// MeshLib // MeshLib
#include "MeshLib/MeshEditing/ElementExtraction.h" #include "MeshLib/MeshSearch/ElementSearch.h"
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/MeshEditing/RemoveMeshComponents.h"
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
...@@ -96,9 +97,9 @@ int main (int argc, char* argv[]) ...@@ -96,9 +97,9 @@ int main (int argc, char* argv[])
// *** remove line elements on request // *** remove line elements on request
if (exclude_lines_arg.getValue()) { if (exclude_lines_arg.getValue()) {
auto ex = MeshLib::ElementExtraction(*mesh); auto ex = MeshLib::ElementSearch(*mesh);
ex.searchByElementType(MeshLib::MeshElemType::LINE); 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) { if (m != nullptr) {
INFO("Removed %d lines.", mesh->getNElements() - m->getNElements()); INFO("Removed %d lines.", mesh->getNElements() - m->getNElements());
std::swap(m, mesh); std::swap(m, mesh);
......
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
#include "MeshLib/Node.h" #include "MeshLib/Node.h"
#include "Elements/Element.h" #include "Elements/Element.h"
#include "MeshEnums.h" #include "MeshEnums.h"
#include "MeshEditing/ElementExtraction.h" #include "MeshSearch/ElementSearch.h"
#include "MeshEditing/RemoveMeshComponents.h"
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
...@@ -84,7 +85,7 @@ 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())); MeshLib::Mesh const*const mesh (FileIO::readMeshFromFile(mesh_in.getValue()));
INFO("Mesh read: %d nodes, %d elements.", mesh->getNNodes(), mesh->getNElements()); 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 // search elements IDs to be removed
if (zveArg.isSet()) { if (zveArg.isSet()) {
...@@ -142,7 +143,7 @@ int main (int argc, char* argv[]) ...@@ -142,7 +143,7 @@ int main (int argc, char* argv[])
} }
// remove the elements and create a new mesh object. // 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 // write into a file
FileIO::Legacy::MeshIO meshIO; FileIO::Legacy::MeshIO meshIO;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "MeshLib/Node.h" #include "MeshLib/Node.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/Elements/Line.h" #include "MeshLib/Elements/Line.h"
#include "MeshLib/MeshSearcher.h" #include "MeshLib/MeshSearch/ElementSearch.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h"
...@@ -28,7 +28,9 @@ BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const ...@@ -28,7 +28,9 @@ BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const
{ {
// search nodes and elements located along the polyline // search nodes and elements located along the polyline
auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply); 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 // check all edges of the elements near the polyline
for (auto ele_id : ele_ids_near_ply) { for (auto ele_id : ele_ids_near_ply) {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshSearcher.h" #include "MeshLib/MeshSearch/ElementSearch.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h"
...@@ -24,7 +24,9 @@ BoundaryElementsOnSurface::BoundaryElementsOnSurface(MeshLib::Mesh const& mesh, ...@@ -24,7 +24,9 @@ BoundaryElementsOnSurface::BoundaryElementsOnSurface(MeshLib::Mesh const& mesh,
{ {
// search elements near the polyline // search elements near the polyline
auto node_ids_on_sfc = mshNodeSearcher.getMeshNodeIDsAlongSurface(sfc); 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 // get a list of faces made of the nodes
for (auto ele_id : ele_ids_near_sfc) { for (auto ele_id : ele_ids_near_sfc) {
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshSearcher.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h"
#include "MeshGeoToolsLib/BoundaryElementsAlongPolyline.h" #include "MeshGeoToolsLib/BoundaryElementsAlongPolyline.h"
......
...@@ -9,9 +9,10 @@ endif() ...@@ -9,9 +9,10 @@ endif()
GET_SOURCE_FILES(SOURCES_ELEMENTS Elements) GET_SOURCE_FILES(SOURCES_ELEMENTS Elements)
GET_SOURCE_FILES(SOURCES_EDITING MeshEditing) GET_SOURCE_FILES(SOURCES_EDITING MeshEditing)
GET_SOURCE_FILES(SOURCES_GENERATORS MeshGenerators) GET_SOURCE_FILES(SOURCES_GENERATORS MeshGenerators)
GET_SOURCE_FILES(SOURCES_SEARCH MeshSearch)
GET_SOURCE_FILES(SOURCES_QUALITY MeshQuality) 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 # Create the library
add_library(MeshLib STATIC ${SOURCES}) add_library(MeshLib STATIC ${SOURCES})
......
/**
* \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
/**
* \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_
/**
* \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
/**
* \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
...@@ -20,9 +20,10 @@ ...@@ -20,9 +20,10 @@
#include "MeshLib/Elements/Tri.h" #include "MeshLib/Elements/Tri.h"
#include "MeshLib/Elements/Quad.h" #include "MeshLib/Elements/Quad.h"
#include "MeshLib/MeshEditing/ElementExtraction.h"
#include "MeshLib/MeshEditing/DuplicateMeshComponents.h" #include "MeshLib/MeshEditing/DuplicateMeshComponents.h"
#include "MeshLib/MeshEditing/RemoveMeshComponents.h"
#include "MeshLib/MeshGenerators/MeshLayerMapper.h" #include "MeshLib/MeshGenerators/MeshLayerMapper.h"
#include "MeshLib/MeshSearch/ElementSearch.h"
bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh,
...@@ -38,9 +39,9 @@ bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, ...@@ -38,9 +39,9 @@ bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh,
return false; return false;
// remove line elements, only tri + quad remain // remove line elements, only tri + quad remain
MeshLib::ElementExtraction ex(mesh); MeshLib::ElementSearch ex(mesh);
ex.searchByElementType(MeshLib::MeshElemType::LINE); ex.searchByElementType(MeshLib::MeshElemType::LINE);
MeshLib::Mesh* top (ex.removeMeshElements("MeshLayer")); MeshLib::Mesh* top (removeElements(mesh, ex.getSearchedElementIDs(), "MeshLayer"));
if (top==nullptr) if (top==nullptr)
top = new MeshLib::Mesh(mesh); top = new MeshLib::Mesh(mesh);
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/Node.h" #include "MeshLib/Node.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshEditing/removeMeshNodes.h"
#include "MeshLib/MeshEditing/MeshRevision.h" #include "MeshLib/MeshEditing/MeshRevision.h"
#include "MeshLib/MeshEditing/RemoveMeshComponents.h"
#include "MeshLib/MeshSurfaceExtraction.h" #include "MeshLib/MeshSurfaceExtraction.h"
namespace MeshLib { namespace MeshLib {
...@@ -65,7 +65,7 @@ std::vector<std::size_t> MeshValidation::findUnusedMeshNodes(const MeshLib::Mesh ...@@ -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> MeshValidation::removeUnusedMeshNodes(MeshLib::Mesh &mesh)
{ {
std::vector<std::size_t> del_node_idx = MeshValidation::findUnusedMeshNodes(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()) if (!del_node_idx.empty())
INFO("Removed %d unused mesh nodes.", del_node_idx.size()); INFO("Removed %d unused mesh nodes.", del_node_idx.size());
......
/** /**
* \file
* \author Karsten Rink
* \date 2013-04-04
* \brief Implementation of ElementExtraction.
*
* \copyright * \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License. * Distributed under a Modified BSD License.
...@@ -12,65 +7,26 @@ ...@@ -12,65 +7,26 @@
* *
*/ */
#include "ElementExtraction.h" #include "ElementSearch.h"
#include "logog/include/logog.hpp"
#include "GeoLib/AABB.h" #include <logog/include/logog.hpp>
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshQuality/MeshValidation.h"
#include "DuplicateMeshComponents.h"
namespace MeshLib { namespace MeshLib {
ElementExtraction::ElementExtraction(const MeshLib::Mesh &mesh) ElementSearch::ElementSearch(const MeshLib::Mesh &mesh)
: _mesh(mesh), _error_code(0) : _mesh(mesh)
{
}
ElementExtraction::~ElementExtraction()
{ {
} }
MeshLib::Mesh* ElementExtraction::removeMeshElements(const std::string &new_mesh_name) ElementSearch::~ElementSearch()
{ {
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) std::size_t ElementSearch::searchByMaterialID(int const matID)
{ {
boost::optional<MeshLib::PropertyVector<int> const&> opt_pv( boost::optional<MeshLib::PropertyVector<int> const&> opt_pv(
this->_mesh.getProperties().getPropertyVector<int>("MaterialIDs") this->_mesh.getProperties().getPropertyVector<int>("MaterialIDs")
...@@ -90,7 +46,7 @@ std::size_t ElementExtraction::searchByMaterialID(int const matID) ...@@ -90,7 +46,7 @@ std::size_t ElementExtraction::searchByMaterialID(int const matID)
return matchedIDs.size(); return matchedIDs.size();
} }
std::size_t ElementExtraction::searchByElementType(MeshElemType eleType) std::size_t ElementSearch::searchByElementType(MeshElemType eleType)
{ {
const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
std::vector<std::size_t> matchedIDs; std::vector<std::size_t> matchedIDs;
...@@ -104,7 +60,7 @@ std::size_t ElementExtraction::searchByElementType(MeshElemType eleType) ...@@ -104,7 +60,7 @@ std::size_t ElementExtraction::searchByElementType(MeshElemType eleType)
return matchedIDs.size(); return matchedIDs.size();
} }
std::size_t ElementExtraction::searchByContent(double eps) std::size_t ElementSearch::searchByContent(double eps)
{ {
const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
std::vector<std::size_t> matchedIDs; std::vector<std::size_t> matchedIDs;
...@@ -118,7 +74,7 @@ std::size_t ElementExtraction::searchByContent(double eps) ...@@ -118,7 +74,7 @@ std::size_t ElementExtraction::searchByContent(double eps)
return matchedIDs.size(); return matchedIDs.size();
} }
std::size_t ElementExtraction::searchByBoundingBox( std::size_t ElementSearch::searchByBoundingBox(
GeoLib::AABB<MathLib::Point3d> const& aabb) GeoLib::AABB<MathLib::Point3d> const& aabb)
{ {
const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements()); const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
...@@ -139,25 +95,24 @@ std::size_t ElementExtraction::searchByBoundingBox( ...@@ -139,25 +95,24 @@ std::size_t ElementExtraction::searchByBoundingBox(
return matchedIDs.size(); return matchedIDs.size();
} }
std::vector<MeshLib::Element*> ElementExtraction::excludeElementCopy( std::size_t ElementSearch::searchByNodeIDs(const std::vector<std::size_t> &nodes)
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()); std::vector<std::size_t> connected_elements;
std::for_each(nodes.begin(), nodes.end(),
unsigned cnt (0); [&](std::size_t node_id)
for (std::size_t i=0; i<vec_removed[0]; ++i) {
vec_dest_eles[cnt++] = vec_src_eles[i]; for (auto* e : _mesh.getNode(node_id)->getElements()) {
for (std::size_t i=1; i<vec_removed.size(); ++i) connected_elements.push_back(e->getID());
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) std::sort(connected_elements.begin(), connected_elements.end());
vec_dest_eles[cnt++] = vec_src_eles[i]; auto it = std::unique(connected_elements.begin(), connected_elements.end());
connected_elements.resize(std::distance(connected_elements.begin(),it));
return vec_dest_eles; this->updateUnion(connected_elements);
return connected_elements.size();
} }
void ElementExtraction::updateUnion(const std::vector<std::size_t> &vec) void ElementSearch::updateUnion(const std::vector<std::size_t> &vec)
{ {
std::vector<std::size_t> vec_temp(vec.size() + _marked_elements.size()); 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()); auto it = std::set_union(vec.begin(), vec.end(), _marked_elements.begin(), _marked_elements.end(), vec_temp.begin());
......
/** /**
* \file
* \author Karsten Rink
* \date 2013-04-04
* \brief Definition of the ElementExtraction
*
* \copyright * \copyright
* Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2015, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License. * Distributed under a Modified BSD License.
...@@ -12,16 +7,14 @@ ...@@ -12,16 +7,14 @@
* *
*/ */
#ifndef ELEMENTEXTRACTION_H #ifndef ELEMENTSEARCH_H_
#define ELEMENTEXTRACTION_H #define ELEMENTSEARCH_H_
#include <string> #include <limits>
#include <vector> #include <vector>
#include "GeoLib/AABB.h" #include "GeoLib/AABB.h"
#include "MeshLib/MeshEnums.h" #include "MeshLib/MeshEnums.h"
#include "MeshLib/Node.h"
namespace MeshLib { namespace MeshLib {
...@@ -29,19 +22,16 @@ namespace MeshLib { ...@@ -29,19 +22,16 @@ namespace MeshLib {
class Mesh; class Mesh;
class Element; class Element;
class ElementExtraction /// Element search class
class ElementSearch
{ {
public: public:
ElementExtraction(const MeshLib::Mesh &mesh); explicit ElementSearch(const MeshLib::Mesh &mesh);
~ElementExtraction(); ~ElementSearch();
/// The error code determined during element extraction /// return marked elements
/// (0 = no errors, 1 = all elements selected, 2 = no elements selected) const std::vector<std::size_t>& getSearchedElementIDs() const { return _marked_elements; }
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. /// Marks all elements with the given Material ID.
std::size_t searchByMaterialID(int const matID); std::size_t searchByMaterialID(int const matID);
...@@ -55,28 +45,17 @@ public: ...@@ -55,28 +45,17 @@ public:
/// Marks all elements with at least one node outside the bounding box spanned by x1 and x2; /// 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); 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: private:
/// Updates the vector of marked elements with values from vec. /// Updates the vector of marked elements with values from vec.
void updateUnion(const std::vector<std::size_t> &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. /// The mesh from which elements should be removed.
const MeshLib::Mesh &_mesh; const MeshLib::Mesh &_mesh;
/// The vector of element indices that should be removed. /// The vector of element indices that should be removed.
std::vector<std::size_t> _marked_elements; 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 } // end namespace MeshLib
......
/**
* \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
...@@ -7,37 +7,46 @@ ...@@ -7,37 +7,46 @@
* *
*/ */
#ifndef MESHSEARCHER_H_ #ifndef NODESEARCH_H_
#define MESHSEARCHER_H_ #define NODESEARCH_H_
#include <vector> #include <vector>
namespace MeshLib namespace MeshLib
{ {
// forward declarations // forward declarations
class Mesh; class Mesh;
class Element; class Element;
class Node; class Node;
/** /// Node search class
* get a vector of elements connected to given nodes class NodeSearch
* @param msh a mesh object {
* @param node_ids a vector of mesh node ids public:
* @return a vector of element ids which connect to the given nodes explicit NodeSearch(const MeshLib::Mesh &mesh);
*/
std::vector<std::size_t> getConnectedElementIDs(MeshLib::Mesh const& msh, const std::vector<std::size_t> &node_ids);
/** ~NodeSearch();
* get a vector of node ID connected to given elements
* @param elements a vector of a pointer to a mesh element object /// return marked node IDs
* @return a vector of node ID const std::vector<std::size_t>& getSearchedNodeIDs() const {return _marked_nodes; }
*/
std::vector<std::size_t> getConnectedNodeIDs(const std::vector<MeshLib::Element*> &elements); /// 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. /// Create a vector of unique nodes used by given elements.
std::vector<Node*> selectNodes(std::vector<Element*> const& elements); std::vector<Node*> getNodes(std::vector<Element*> const& elements);
} // end namespace MeshLib } // end namespace MeshLib
#endif //MESHSEARCHER_H_ #endif //NODESEARCH_H_
/**
* \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
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#include "AssemblerLib/LocalDataInitializer.h" #include "AssemblerLib/LocalDataInitializer.h"
#include "AssemblerLib/LocalAssemblerBuilder.h" #include "AssemblerLib/LocalAssemblerBuilder.h"
#include "MeshLib/MeshSubset.h" #include "MeshLib/MeshSubset.h"
#include "MeshLib/MeshSearch/NodeSearch.h"
#include "NeumannBcConfig.h" #include "NeumannBcConfig.h"
#include "NeumannBcAssembler.h" #include "NeumannBcAssembler.h"
#include "MeshLib/MeshSearcher.h"
namespace ProcessLib namespace ProcessLib
{ {
...@@ -64,7 +64,7 @@ public: ...@@ -64,7 +64,7 @@ public:
std::back_inserter(_elements), std::back_inserter(_elements),
std::mem_fn(&MeshLib::Element::clone)); 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 =
mesh_subset_all_nodes.getIntersectionByNodes(nodes); mesh_subset_all_nodes.getIntersectionByNodes(nodes);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "AssemblerLib/LocalToGlobalIndexMap.h" #include "AssemblerLib/LocalToGlobalIndexMap.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h" #include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshLib/MeshSearcher.h" #include "MeshLib/MeshSearch/NodeSearch.h"
#include "MeshLib/MeshSubsets.h" #include "MeshLib/MeshSubsets.h"
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
...@@ -88,7 +88,7 @@ TEST_F(AssemblerLibLocalToGlobalIndexMapTest, SubsetByComponent) ...@@ -88,7 +88,7 @@ TEST_F(AssemblerLibLocalToGlobalIndexMapTest, SubsetByComponent)
some_elements.push_back(const_cast<MeshLib::Element*>(mesh->getElement(id))); some_elements.push_back(const_cast<MeshLib::Element*>(mesh->getElement(id)));
// Find unique node ids of the selected elements for testing. // 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 = MeshLib::MeshSubset const* const selected_subset =
nodesSubset->getIntersectionByNodes(selected_nodes); nodesSubset->getIntersectionByNodes(selected_nodes);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment