diff --git a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp index dd8cc1c32569b19d6119cd8f7b4e758c9343e2d3..688b50882266f3dd1b2a5f198130230d06db762e 100644 --- a/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp +++ b/Applications/DataExplorer/DataView/MeshElementRemovalDialog.cpp @@ -74,7 +74,7 @@ void MeshElementRemovalDialog::accept() { QList<QListWidgetItem*> items = this->materialListWidget->selectedItems(); for (int i=0; i<items.size(); ++i) - ex.searchByMaterialID(items[i]->text().toInt()); + ex.searchByPropertyValue(items[i]->text().toInt()); anything_checked = true; } if (this->boundingBoxCheckBox->isChecked()) diff --git a/Applications/Utils/MeshEdit/removeMeshElements.cpp b/Applications/Utils/MeshEdit/removeMeshElements.cpp index 05b42215517f97d53626a5605e2aedea3d169db0..3d3dc01d9af622b6640e00034195d240a664b444 100644 --- a/Applications/Utils/MeshEdit/removeMeshElements.cpp +++ b/Applications/Utils/MeshEdit/removeMeshElements.cpp @@ -11,35 +11,44 @@ * http://www.opengeosys.org/LICENSE.txt */ +#include <memory> + // TCLAP #include "tclap/CmdLine.h" -// ThirdParty/logog -#include "logog/include/logog.hpp" - -// BaseLib -#include "LogogSimpleFormatter.h" +#include "Applications/ApplicationsLib/LogogSetup.h" -// FileIO -#include "Legacy/MeshIO.h" -#include "readMeshFromFile.h" +#include "FileIO/readMeshFromFile.h" +#include "FileIO/writeMeshToFile.h" -// MeshLib -#include "Mesh.h" +#include "MeshLib/Mesh.h" #include "MeshLib/Node.h" -#include "Elements/Element.h" -#include "MeshEnums.h" -#include "MeshSearch/ElementSearch.h" -#include "MeshEditing/RemoveMeshComponents.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshEnums.h" +#include "MeshLib/MeshSearch/ElementSearch.h" +#include "MeshLib/MeshEditing/RemoveMeshComponents.h" + +template <typename PROPERTY_TYPE> +void searchByProperty(std::string const& property_name, + std::vector<PROPERTY_TYPE> const& property_values, + MeshLib::ElementSearch& searcher) +{ + for (auto const& property_value : property_values) { + const std::size_t n_marked_elements = + searcher.searchByPropertyValue(property_value, property_name); + INFO("%d elements with property value %s found.", n_marked_elements, + std::to_string(property_value).c_str()); + } +} 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); + ApplicationsLib::LogogSetup logog_setup; - TCLAP::CmdLine cmd("Remove mesh elements.", ' ', "0.1"); + TCLAP::CmdLine cmd( + "Remove mesh elements. The documentation is available at " + "https://docs.opengeosys.org/docs/tools/meshing/remove-mesh-elements.", + ' ', "0.1"); // Bounding box params TCLAP::ValueArg<double> zLargeArg("", "z-max", "largest allowed extent in z-dimension", @@ -67,9 +76,15 @@ int main (int argc, char* argv[]) 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); + + TCLAP::MultiArg<int> int_property_arg("", "int-property-value", + "new property value (data type int)", + false, "number"); + cmd.add(int_property_arg); + TCLAP::ValueArg<std::string> property_name_arg( + "n", "property-name", "name of property in the mesh", false, + "MaterialIDs", "string"); + cmd.add(property_name_arg); // I/O params TCLAP::ValueArg<std::string> mesh_out("o", "mesh-output-file", @@ -83,13 +98,14 @@ int main (int argc, char* argv[]) cmd.parse(argc, argv); - MeshLib::Mesh const*const mesh (FileIO::readMeshFromFile(mesh_in.getValue())); + std::unique_ptr<MeshLib::Mesh const> mesh( + FileIO::readMeshFromFile(mesh_in.getValue())); INFO("Mesh read: %d nodes, %d elements.", mesh->getNNodes(), mesh->getNElements()); - MeshLib::ElementSearch ex(*mesh); + MeshLib::ElementSearch searcher(*mesh); // search elements IDs to be removed if (zveArg.isSet()) { - const std::size_t n_removed_elements = ex.searchByContent(); + const std::size_t n_removed_elements = searcher.searchByContent(); INFO("%d zero volume elements found.", n_removed_elements); } if (eleTypeArg.isSet()) { @@ -97,16 +113,14 @@ int main (int argc, char* argv[]) for (auto typeName : eleTypeNames) { const MeshLib::MeshElemType type = MeshLib::String2MeshElemType(typeName); if (type == MeshLib::MeshElemType::INVALID) continue; - const std::size_t n_removed_elements = ex.searchByElementType(type); + const std::size_t n_removed_elements = searcher.searchByElementType(type); INFO("%d %s elements found.", n_removed_elements, typeName.c_str()); } } - if (matIDArg.isSet()) { - const std::vector<unsigned> vec_matID = matIDArg.getValue(); - for (auto matID : vec_matID) { - const std::size_t n_removed_elements = ex.searchByMaterialID(matID); - INFO("%d elements with material ID %d found.", n_removed_elements, matID); - } + + if (int_property_arg.isSet()) { + searchByProperty(property_name_arg.getValue(), + int_property_arg.getValue(), searcher); } if (xSmallArg.isSet() || xLargeArg.isSet() || @@ -130,31 +144,26 @@ int main (int argc, char* argv[]) aabb_error = true; } if (aabb_error) - return 1; + return EXIT_FAILURE; std::array<MathLib::Point3d, 2> extent({{ MathLib::Point3d(std::array<double,3>{{xSmallArg.getValue(), ySmallArg.getValue(), zSmallArg.getValue()}}), MathLib::Point3d(std::array<double,3>{{xLargeArg.getValue(), yLargeArg.getValue(), zLargeArg.getValue()}})}}); - const std::size_t n_removed_elements = ex.searchByBoundingBox( + const std::size_t n_removed_elements = searcher.searchByBoundingBox( GeoLib::AABB(extent.begin(), extent.end())); INFO("%d elements found.", n_removed_elements); } // remove the elements and create a new mesh object. - MeshLib::Mesh const*const new_mesh = MeshLib::removeElements(*mesh, ex.getSearchedElementIDs(), mesh->getName()); + std::unique_ptr<MeshLib::Mesh const> new_mesh(MeshLib::removeElements( + *mesh, searcher.getSearchedElementIDs(), mesh->getName())); // write into a file - FileIO::Legacy::MeshIO meshIO; - meshIO.setMesh(new_mesh); - meshIO.writeToFile(mesh_out.getValue()); - - delete custom_format; - delete logog_cout; - LOGOG_SHUTDOWN(); + FileIO::writeMeshToFile(*new_mesh, mesh_out.getValue()); - return 0; + return EXIT_SUCCESS; } diff --git a/MeshLib/MeshSearch/ElementSearch.cpp b/MeshLib/MeshSearch/ElementSearch.cpp index 8a035b8b15a35418efb6702f90b86e07d7600100..f8d30092812a372b52566b60e9f9940cfb61bf06 100644 --- a/MeshLib/MeshSearch/ElementSearch.cpp +++ b/MeshLib/MeshSearch/ElementSearch.cpp @@ -11,7 +11,6 @@ #include <logog/include/logog.hpp> -#include "MeshLib/Mesh.h" #include "MeshLib/Node.h" #include "MeshLib/Elements/Element.h" @@ -22,26 +21,6 @@ ElementSearch::ElementSearch(const MeshLib::Mesh &mesh) { } -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(); -} - template <typename Container, typename Predicate> std::vector<std::size_t> filter(Container const& container, Predicate const& p) { diff --git a/MeshLib/MeshSearch/ElementSearch.h b/MeshLib/MeshSearch/ElementSearch.h index db26a7e8756771ad73b6332744c0606946db61d2..98e38e60cfd458949aa49072a8473faaddc10b13 100644 --- a/MeshLib/MeshSearch/ElementSearch.h +++ b/MeshLib/MeshSearch/ElementSearch.h @@ -14,6 +14,7 @@ #include <vector> #include "GeoLib/AABB.h" +#include "MeshLib/Mesh.h" #include "MeshLib/MeshEnums.h" namespace MeshLib { @@ -31,8 +32,46 @@ public: /// 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); + /// @tparam PROPERTY_TYPE integral type of the property + /// Different properties can be assigned to the elements of the mesh. These + /// properties can be accessed by the name of the property. The method marks + /// all elements of the mesh for the property \c property_name with the + /// given property value \c property_value. + /// @param property_value the value of the property the elements have to + /// have to be marked + /// @param property_name the name of the property the searching/marking is + /// based on + /// @return The number of marked elements will be returned. The concrete + /// element ids can be requested by getSearchedElementIDs(). + template <typename PROPERTY_TYPE> + std::size_t searchByPropertyValue( + PROPERTY_TYPE const property_value, + std::string const& property_name = "MaterialIDs") + { + boost::optional<MeshLib::PropertyVector<PROPERTY_TYPE> const&> opt_pv( + _mesh.getProperties().getPropertyVector<PROPERTY_TYPE>( + property_name)); + if (!opt_pv) { + WARN("Property \"%s\" not found in mesh.", property_name.c_str()); + return 0; + } + + MeshLib::PropertyVector<PROPERTY_TYPE> const& pv(opt_pv.get()); + if (pv.getMeshItemType() != MeshLib::MeshItemType::Cell) { + WARN("The property \"%s\" is not assigned to mesh elements.", + property_name.c_str()); + return 0; + } + + std::vector<std::size_t> matchedIDs; + for (std::size_t i(0); i < pv.getNumberOfTuples(); ++i) { + if (pv[i] == property_value) + matchedIDs.push_back(i); + } + + updateUnion(matchedIDs); + return matchedIDs.size(); + } /// Marks all elements of the given element type. std::size_t searchByElementType(MeshElemType eleType);