From 42a6afcb6e2f6b69fbaa2d5828429b769b18b09d Mon Sep 17 00:00:00 2001 From: Norihiro Watanabe <norihiro.watanabe@ufz.de> Date: Tue, 15 Oct 2013 12:12:00 +0200 Subject: [PATCH] add removeMeshElements tool --- Utils/MeshEdit/removeMeshElements.cpp | 192 ++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 Utils/MeshEdit/removeMeshElements.cpp diff --git a/Utils/MeshEdit/removeMeshElements.cpp b/Utils/MeshEdit/removeMeshElements.cpp new file mode 100644 index 00000000000..64abe499358 --- /dev/null +++ b/Utils/MeshEdit/removeMeshElements.cpp @@ -0,0 +1,192 @@ +/** + * @file removeMeshElements.cpp + * @author Norihiro Watanabe + * @date 2013/10/15 + * @brief Remove mesh elements + * + * @copyright + * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ + +// TCLAP +#include "tclap/CmdLine.h" + +// ThirdParty/logog +#include "logog/include/logog.hpp" + +// BaseLib +#include "LogogSimpleFormatter.h" + +// FileIO +#include "Legacy/MeshIO.h" +#include "readMeshFromFile.h" + +// MeshLib +#include "Mesh.h" +#include "Node.h" +#include "Elements/Element.h" +#include "MeshEnums.h" + +std::vector<std::size_t> 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++; + } + return matchedIDs; +} + +std::vector<std::size_t> searchByElementType(const std::vector<MeshLib::Element*> & ele_vec, MeshElemType eleType) +{ + 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++; + } + return matchedIDs; +} + +std::vector<std::size_t> 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()==.0) + matchedIDs.push_back(i); + i++; + } + return matchedIDs; +} + +void updateUnion(const std::vector<std::size_t> &vec1, std::vector<std::size_t> &vec2) +{ + std::vector<std::size_t> vec_temp(vec1.size() + vec2.size()); + auto it = std::set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec_temp.begin()); + vec_temp.resize(it - vec_temp.begin()); + vec2.assign(vec_temp.begin(), vec_temp.end()); +} + +std::vector<MeshLib::Element*> excludeElements(const std::vector<MeshLib::Element*> & vec_src_eles, const std::vector<std::size_t> &vec_removed) +{ + 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 copyNodesElements( const std::vector<MeshLib::Node*> src_nodes, + const std::vector<MeshLib::Element*> & src_eles, + std::vector<MeshLib::Node*> &dst_nodes, + std::vector<MeshLib::Element*> &dst_eles) +{ + // 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_eles.resize(src_eles.size()); + for (std::size_t i=0; i<dst_eles.size(); i++) { + auto* src_ele = src_eles[i]; + auto* dst_ele = src_ele->clone(); + for (unsigned j=0; j<src_ele->getNNodes(); j++) { + dst_ele->setNode(j, dst_nodes[src_ele->getNode(j)->getID()]); + } + dst_eles[i] = dst_ele; + } +} + +int main (int argc, char* argv[]) +{ + LOGOG_INITIALIZE(); + logog::Cout* logog_cout (new logog::Cout); + BaseLib::LogogSimpleFormatter *custom_format (new BaseLib::LogogSimpleFormatter); + logog_cout->SetFormatter(*custom_format); + + TCLAP::CmdLine cmd("Remove mesh elements.", ' ', "0.1"); + TCLAP::ValueArg<std::string> mesh_in("i", "mesh-input-file", + "the name of the file containing the input mesh", true, + "", "file name of input mesh"); + cmd.add(mesh_in); + TCLAP::ValueArg<std::string> mesh_out("o", "mesh-output-file", + "the name of the file the mesh will be written to", true, + "", "file name of output mesh"); + cmd.add(mesh_out); + TCLAP::SwitchArg zveArg("z", "zero-volume", "remove zero volume elements", false); + cmd.add(zveArg); + TCLAP::MultiArg<std::string> eleTypeArg("t", "element-type", + "element type to be removed", false, "element type"); + cmd.add(eleTypeArg); + TCLAP::MultiArg<unsigned> matIDArg("m", "material-id", + "material id", false, "material id"); + cmd.add(matIDArg); + cmd.parse(argc, argv); + + MeshLib::Mesh* mesh (FileIO::readMeshFromFile(mesh_in.getValue())); + INFO("Mesh read: %d nodes, %d elements.", mesh->getNNodes(), mesh->getNElements()); + + // search elements IDs to be removed + std::vector<std::size_t> vec_elementIDs_removed; + if (zveArg.isSet()) { + std::vector<std::size_t> vec_matched = searchByZeroContent(mesh->getElements()); + updateUnion(vec_matched, vec_elementIDs_removed); + INFO("%d zero volume elements found.", vec_matched.size()); + } + if (eleTypeArg.isSet()) { + std::vector<std::string> eleTypeNames = eleTypeArg.getValue(); + for (auto typeName : eleTypeNames) { + MeshElemType type = String2MeshElemType(typeName); + if (type == MeshElemType::INVALID) continue; + std::vector<std::size_t> vec_matched = searchByElementType(mesh->getElements(), type); + updateUnion(vec_matched, vec_elementIDs_removed); + INFO("%d %s elements found.", vec_matched.size(), typeName.c_str()); + } + } + if (matIDArg.isSet()) { + std::vector<unsigned> vec_matID = matIDArg.getValue(); + for (auto matID : vec_matID) { + std::vector<std::size_t> vec_matched = searchByMaterialID(mesh->getElements(), matID); + updateUnion(vec_matched, vec_elementIDs_removed); + INFO("%d elements with material ID %d found.", vec_matched.size(), matID); + } + } + + // remove the elements + INFO("Removing total %d elements...", vec_elementIDs_removed.size()); + std::vector<MeshLib::Element*> tmp_eles = excludeElements(mesh->getElements(), vec_elementIDs_removed); + INFO("%d elements remained.", tmp_eles.size()); + std::vector<MeshLib::Node*> new_nodes; + std::vector<MeshLib::Element*> new_eles; + copyNodesElements(mesh->getNodes(), tmp_eles, new_nodes, new_eles); + + // create a new mesh object. Unsued nodes are removed while construction + MeshLib::Mesh* new_mesh(new MeshLib::Mesh(mesh->getName(), new_nodes, new_eles)); + + // write into a file + FileIO::MeshIO meshIO; + meshIO.setMesh(new_mesh); + meshIO.writeToFile(mesh_out.getValue()); + + delete custom_format; + delete logog_cout; + LOGOG_SHUTDOWN(); + + return 0; +} + + + -- GitLab