diff --git a/Gui/DataView/MshLayerMapper.cpp b/Gui/DataView/MshLayerMapper.cpp index 7a1bd056bb3c6160ac0ca2e0c7f39092c1d68bc8..e699dc1fd7a42a096d70176f010a81d81e910c77 100644 --- a/Gui/DataView/MshLayerMapper.cpp +++ b/Gui/DataView/MshLayerMapper.cpp @@ -219,7 +219,7 @@ int MshLayerMapper::LayerMapping(MeshLib::Mesh* new_mesh, const std::string &ras if (noData_nodes.size() < (nNodes - 2)) { WARN("MshLayerMapper::LayerMapping(): Removing %d mesh nodes at NoData values.", noData_nodes.size()); - MeshLib::Mesh* red_mesh = MeshLib::removeMeshNodes(new_mesh, noData_nodes); + MeshLib::Mesh* red_mesh = MeshLib::removeMeshNodes(*new_mesh, noData_nodes); if (new_mesh->getNElements() == 0) { delete new_mesh; diff --git a/MeshLib/MeshEditing/removeMeshEntities.cpp b/MeshLib/MeshEditing/removeMeshEntities.cpp index e04e9f8728bdf8d8bb3db44dbc903b7f48cd7a51..c7e5639723040f69f8eeeef411fe138f58c4ef9f 100644 --- a/MeshLib/MeshEditing/removeMeshEntities.cpp +++ b/MeshLib/MeshEditing/removeMeshEntities.cpp @@ -14,17 +14,139 @@ #include "removeMeshEntities.h" #include "Mesh.h" -#include "Node.h" #include "Elements/Element.h" +#include "AABB.h" #include "logog/include/logog.hpp" namespace MeshLib { +MeshElementRemoval::MeshElementRemoval(const MeshLib::Mesh &mesh) + : _mesh(mesh) +{ +} + +MeshElementRemoval::~MeshElementRemoval() +{ +} + +MeshLib::Mesh* MeshElementRemoval::removeMeshElements() const +{ + INFO("Removing total %d elements...", _marked_elements.size()); + std::vector<MeshLib::Element*> tmp_elems = excludeElements(_mesh.getElements(), _marked_elements); + INFO("%d elements remain in mesh.", tmp_elems.size()); + std::vector<MeshLib::Node*> new_nodes; + std::vector<MeshLib::Element*> new_elems; + copyNodesElements(_mesh.getNodes(), tmp_elems, new_nodes, new_elems); + + // create a new mesh object. Unsued nodes are removed during construction + return new MeshLib::Mesh(_mesh.getName(), new_nodes, new_elems); +} + +void MeshElementRemoval::searchByMaterialID(const std::vector<MeshLib::Element*> & ele_vec, unsigned matID) +{ + std::vector<std::size_t> matchedIDs; + std::size_t i = 0; + for (MeshLib::Element* ele : ele_vec) { + if (ele->getValue()==matID) + matchedIDs.push_back(i); + i++; + } + this->updateUnion(matchedIDs); +} -MeshLib::Mesh* removeMeshNodes(MeshLib::Mesh const*const mesh, const std::vector<size_t> &nodes) +void MeshElementRemoval::searchByElementType(const std::vector<MeshLib::Element*> & ele_vec, MeshElemType eleType) { - MeshLib::Mesh* new_mesh (new MeshLib::Mesh(*mesh)); + 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); +} + +void MeshElementRemoval::searchByZeroContent(const std::vector<MeshLib::Element*> & ele_vec) +{ + std::vector<std::size_t> matchedIDs; + std::size_t i = 0; + for (MeshLib::Element* ele : ele_vec) { + if (ele->getContent()<std::numeric_limits<double>::epsilon()) + matchedIDs.push_back(i); + i++; + } + this->updateUnion(matchedIDs); +} + +void MeshElementRemoval::searchByBoundingBox(const std::vector<MeshLib::Element*> & ele_vec, const MeshLib::Node &x1, const MeshLib::Node &x2) +{ + std::vector<MeshLib::Node> extent; + extent.push_back(x1); extent.push_back(x2); + const GeoLib::AABB<MeshLib::Node> aabb(extent.begin(), extent.end()); + + std::vector<std::size_t> matchedIDs; + std::size_t i = 0; + for (MeshLib::Element* ele : ele_vec) + { + std::size_t nElemNodes (ele_vec[i]->getNNodes()); + for (std::size_t j=0; j<nElemNodes; ++j) + if (!aabb.containsPoint(*ele_vec[i]->getNode(j))) + { + matchedIDs.push_back(i); + break; + } + i++; + } + this->updateUnion(matchedIDs); +} + +void MeshElementRemoval::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()); +} + +std::vector<MeshLib::Element*> MeshElementRemoval::excludeElements(const std::vector<MeshLib::Element*> & vec_src_eles, const std::vector<std::size_t> &vec_removed) const +{ + std::vector<MeshLib::Element*> vec_dest_eles(vec_src_eles.size() - vec_removed.size()); + std::size_t k=0; + for (std::size_t i=0; i<vec_src_eles.size(); i++) { + if (std::find(vec_removed.begin(), vec_removed.end(), i) == vec_removed.end()) { + vec_dest_eles[k] = vec_src_eles[i]; + k++; + } + } + return vec_dest_eles; +} + +void MeshElementRemoval::copyNodesElements( const std::vector<MeshLib::Node*> &src_nodes, const std::vector<MeshLib::Element*> &src_elems, + std::vector<MeshLib::Node*> &dst_nodes, std::vector<MeshLib::Element*> &dst_elems) const +{ + // copy nodes + dst_nodes.resize(src_nodes.size()); + for (std::size_t i=0; i<dst_nodes.size(); i++) { + dst_nodes[i] = new MeshLib::Node(*src_nodes[i]); + } + + // copy elements with new nodes + dst_elems.resize(src_elems.size()); + for (std::size_t i=0; i<dst_elems.size(); i++) { + auto* src_elem = src_elems[i]; + auto* dst_elem = src_elem->clone(); + for (unsigned j=0; j<src_elem->getNNodes(); j++) { + dst_elem->setNode(j, dst_nodes[src_elem->getNode(j)->getID()]); + } + dst_elems[i] = dst_elem; + } +} + + +MeshLib::Mesh* removeMeshNodes(const MeshLib::Mesh &mesh, const std::vector<size_t> &nodes) +{ + MeshLib::Mesh* new_mesh (new MeshLib::Mesh(mesh)); // delete nodes and their connected elements and replace them with null pointers const size_t delNodes = nodes.size(); @@ -57,25 +179,5 @@ MeshLib::Mesh* removeMeshNodes(MeshLib::Mesh const*const mesh, const std::vector } -MeshLib::Mesh* removeMeshElements(const MeshLib::Mesh &mesh, MeshElemType t) -{ - MeshLib::Mesh* new_mesh = new MeshLib::Mesh(mesh); - unsigned count(0); - std::vector<MeshLib::Element*> elements (new_mesh->getElements()); - for (auto it = elements.begin(); it != elements.end();) - { - if ((*it)->getGeomType() == t) - { - delete *it; - it = elements.erase(it); - ++count; - } - else - ++it; - } - INFO("Removed %d elements of type %s from mesh.", count, MeshElemType2String(t).c_str()); - - return new_mesh; -} } // end namespace MeshLib diff --git a/MeshLib/MeshEditing/removeMeshEntities.h b/MeshLib/MeshEditing/removeMeshEntities.h index 5d6a9a57d62d86acbf81bff8a3bc633e4462e8e6..b82cd103e18f0d365a3a176898f09e18a99a6e42 100644 --- a/MeshLib/MeshEditing/removeMeshEntities.h +++ b/MeshLib/MeshEditing/removeMeshEntities.h @@ -17,17 +17,54 @@ #include <vector> #include "MeshEnums.h" +#include "Node.h" namespace MeshLib { // forward declarations class Mesh; +class Element; + +class MeshElementRemoval +{ +public: + MeshElementRemoval::MeshElementRemoval(const MeshLib::Mesh &mesh); + + MeshElementRemoval::~MeshElementRemoval(); /// Removes the mesh nodes (and connected elements) given in the nodes-list from the mesh. - MeshLib::Mesh* removeMeshNodes(MeshLib::Mesh const*const mesh, const std::vector<std::size_t> &nodes); + MeshLib::Mesh* removeMeshNodes(const std::vector<std::size_t> &nodes) const; + + /// Removes all mesh elements marked by search-methods. + MeshLib::Mesh* removeMeshElements() const; + + /// Marks all elements with the given Material ID. + void searchByMaterialID(const std::vector<MeshLib::Element*> & ele_vec, unsigned matID); + + /// Marks all elements of the given element type. + void searchByElementType(const std::vector<MeshLib::Element*> & ele_vec, MeshElemType eleType); + + /// Marks all elements with a volume smaller than std::numeric_limits<double>::epsilon(). + void searchByZeroContent(const std::vector<MeshLib::Element*> & ele_vec); + + /// Marks all elements with at least one node outside the bounding box spanned by x1 and x2; + void searchByBoundingBox(const std::vector<MeshLib::Element*> & ele_vec, const MeshLib::Node &x1, const MeshLib::Node &x2); + + +private: + /// Updates the vector of marked elements with values from vec. + void updateUnion(const std::vector<std::size_t> &vec); + + /// Removes elements from vec_removed in vec_src_elems + std::vector<MeshLib::Element*> excludeElements(const std::vector<MeshLib::Element*> & vec_src_elems, const std::vector<std::size_t> &vec_removed) const; + + /// Copies nodes and elements of the original mesh for constructing the new mesh + void copyNodesElements(const std::vector<MeshLib::Node*> &src_nodes, const std::vector<MeshLib::Element*> &src_elems, + std::vector<MeshLib::Node*> &dst_nodes, std::vector<MeshLib::Element*> &dst_elems) const; - /// Removes elements of the given type t from a mesh - MeshLib::Mesh* removeMeshElements(const MeshLib::Mesh &mesh, MeshElemType t); + const MeshLib::Mesh &_mesh; + std::vector<std::size_t> _marked_elements; +}; } // end namespace MeshLib diff --git a/Utils/MeshEdit/removeMeshNodes.cpp b/Utils/MeshEdit/removeMeshNodes.cpp index 8b99e59f97d3a80a25e01c7eb0e98387a9d1a36b..06f6b10267ccd82a211cac5cbb37bbe27c36b79f 100644 --- a/Utils/MeshEdit/removeMeshNodes.cpp +++ b/Utils/MeshEdit/removeMeshNodes.cpp @@ -8,7 +8,7 @@ #include "Legacy/MeshIO.h" #include "Mesh.h" #include "Node.h" -#include "MeshEditing/removeMeshNodes.h" +#include "MeshEditing/removeMeshEntities.h" int main (int argc, char* argv[]) { @@ -82,7 +82,7 @@ int main (int argc, char* argv[]) /**** add other keywords here ****/ // remove nodes and write new file - MeshLib::Mesh* new_mesh = MeshLib::removeMeshNodes(mesh, del_nodes); + MeshLib::Mesh* new_mesh = MeshLib::removeMeshNodes(*mesh, del_nodes); FileIO::MeshIO meshIO; meshIO.setMesh(mesh);