diff --git a/Applications/Utils/MeshEdit/CMakeLists.txt b/Applications/Utils/MeshEdit/CMakeLists.txt index c222040502c1654fb9461f669a386cf947a14857..d3649ee77f3c2cd256ebd172e9a1d25b1004befe 100644 --- a/Applications/Utils/MeshEdit/CMakeLists.txt +++ b/Applications/Utils/MeshEdit/CMakeLists.txt @@ -103,3 +103,18 @@ ADD_CATALYST_DEPENDENCY(checkMesh) SET_TARGET_PROPERTIES(checkMesh PROPERTIES FOLDER Utilities) + +ADD_EXECUTABLE( reviseMesh reviseMesh.cpp) +TARGET_LINK_LIBRARIES ( reviseMesh + BaseLib + FileIO + MathLib + MeshLib + InSituLib + ${CATALYST_LIBRARIES} +) +ADD_CATALYST_DEPENDENCY(reviseMesh) + +SET_TARGET_PROPERTIES(reviseMesh + PROPERTIES FOLDER Utilities) + \ No newline at end of file diff --git a/Applications/Utils/MeshEdit/editMaterialID.cpp b/Applications/Utils/MeshEdit/editMaterialID.cpp index 1503253f177c9eab613d1c902c016f071fcaf1c0..5ba436ab1d8213633aa33b331916aef1fde32cf7 100644 --- a/Applications/Utils/MeshEdit/editMaterialID.cpp +++ b/Applications/Utils/MeshEdit/editMaterialID.cpp @@ -13,16 +13,17 @@ #include "logog/include/logog.hpp" // BaseLib -#include "LogogSimpleFormatter.h" +#include "BaseLib/LogogSimpleFormatter.h" // FileIO -#include "Legacy/MeshIO.h" -#include "readMeshFromFile.h" +#include "FileIO/Legacy/MeshIO.h" +#include "FileIO/readMeshFromFile.h" +#include "FileIO/writeMeshToFile.h" // MeshLib -#include "Mesh.h" -#include "Elements/Element.h" -#include "MeshEditing/ElementValueModification.h" +#include "MeshLib/Mesh.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshEditing/ElementValueModification.h" int main (int argc, char* argv[]) { @@ -34,7 +35,12 @@ int main (int argc, char* argv[]) TCLAP::CmdLine cmd("Edit material IDs of mesh elements.", ' ', "0.1"); TCLAP::SwitchArg replaceArg("r", "replace", "replace material IDs", false); TCLAP::SwitchArg condenseArg("c", "condense", "condense material IDs", false); - cmd.xorAdd(replaceArg, condenseArg); + TCLAP::SwitchArg specifyArg("s", "specify", "specify material IDs by element types (-e)", false); + std::vector<TCLAP::Arg*> vec_xors; + vec_xors.push_back(&replaceArg); + vec_xors.push_back(&condenseArg); + vec_xors.push_back(&specifyArg); + cmd.xorAdd(vec_xors); TCLAP::ValueArg<std::string> mesh_in("i", "mesh-input-file", "the name of the file containing the input mesh", true, "", "file name"); @@ -49,17 +55,28 @@ int main (int argc, char* argv[]) TCLAP::ValueArg<unsigned> newIDArg("n", "new-material-id", "new material id", false, 0, "number"); cmd.add(newIDArg); + std::vector<std::string> eleList(getMeshElemTypeStringsShort()); + TCLAP::ValuesConstraint<std::string> allowedVals(eleList); + TCLAP::ValueArg<std::string> eleTypeArg("e", "element-type", + "element type", false, "", &allowedVals); + cmd.add(eleTypeArg); + cmd.parse(argc, argv); - if (!replaceArg.isSet() && !condenseArg.isSet()) { - INFO("Please select editing mode: -r or -c"); + if (!replaceArg.isSet() && !condenseArg.isSet() && !specifyArg.isSet()) { + INFO("Please select editing mode: -r or -c or -s"); return 0; } else if (replaceArg.isSet() && condenseArg.isSet()) { - INFO("Please select only one editing mode: -r or -c"); + INFO("Please select only one editing mode: -r or -c or -s"); return 0; } else if (replaceArg.isSet()) { if (!matIDArg.isSet() || !newIDArg.isSet()) { - INFO("current and new material IDs must be provided for relplacement"); + INFO("current and new material IDs must be provided for replacement"); + return 0; + } + } else if (specifyArg.isSet()) { + if (!eleTypeArg.isSet() || !newIDArg.isSet()) { + INFO("element type and new material IDs must be provided to specify elements"); return 0; } } @@ -78,12 +95,17 @@ int main (int argc, char* argv[]) INFO("%d -> %d", oldID, newID); MeshLib::ElementValueModification::replace(*mesh, oldID, newID, true); } + } else if (specifyArg.isSet()) { + INFO("Specifying material ID..."); + const std::string eleTypeName(eleTypeArg.getValue()); + const MeshElemType eleType = String2MeshElemType(eleTypeName); + const unsigned newID = newIDArg.getValue(); + unsigned cnt = MeshLib::ElementValueModification::setByElementType(*mesh, eleType, newID); + INFO("updated %d elements", cnt); } // write into a file - FileIO::Legacy::MeshIO meshIO; - meshIO.setMesh(mesh); - meshIO.writeToFile(mesh_out.getValue()); + FileIO::writeMeshToFile(*mesh, mesh_out.getValue()); delete custom_format; delete logog_cout; diff --git a/Applications/Utils/MeshEdit/reviseMesh.cpp b/Applications/Utils/MeshEdit/reviseMesh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7dc04e72d1a9e73fc95a1fedce9fdfe9beb72ac9 --- /dev/null +++ b/Applications/Utils/MeshEdit/reviseMesh.cpp @@ -0,0 +1,80 @@ +/** + * @copyright + * Copyright (c) 2012-2014, 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 <array> +#include <string> + +#include "logog/include/logog.hpp" +#include "tclap/CmdLine.h" + +#include "BaseLib/BuildInfo.h" +#include "BaseLib/StringTools.h" +#include "BaseLib/LogogSimpleFormatter.h" +#include "BaseLib/FileTools.h" + +#include "MeshLib/Node.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/Mesh.h" +#include "MeshLib/MeshEditing/MeshRevision.h" + +#include "FileIO/readMeshFromFile.h" +#include "FileIO/writeMeshToFile.h" + +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("Mesh revision tool", ' ', BaseLib::BuildInfo::git_version_sha1); + TCLAP::ValueArg<std::string> input_arg("i", "input-mesh-file","input mesh file",true,"","string"); + cmd.add( input_arg ); + TCLAP::ValueArg<std::string> output_arg("o", "output-mesh-file","output mesh file",true,"","string"); + cmd.add( output_arg ); + TCLAP::SwitchArg simplify_arg("s","simplify","simplify the mesh (removing duplicated nodes)"); + cmd.add( simplify_arg ); + TCLAP::ValueArg<double> eps_arg("e", "eps","Minimum distance for nodes not to be collapsed", + false, std::numeric_limits<double>::epsilon(),"float"); + cmd.add( eps_arg ); + TCLAP::ValueArg<unsigned> minDim_arg("d", "min-ele-dim","Minimum dimension of elements to be inserted into new mesh", + false, 1, "unsigned"); + cmd.add( minDim_arg ); + cmd.parse( argc, argv ); + + // read a mesh file + MeshLib::Mesh* org_mesh (FileIO::readMeshFromFile(input_arg.getValue())); + if (!org_mesh) + return 0; + INFO("Mesh read: %d nodes, %d elements.", org_mesh->getNNodes(), org_mesh->getNElements()); + + // revise the mesh + MeshLib::Mesh* new_mesh = nullptr; + if (simplify_arg.getValue()) { + INFO("Simplifying the mesh..."); + MeshLib::MeshRevision rev(const_cast<MeshLib::Mesh&>(*org_mesh)); + unsigned int minDim = (minDim_arg.isSet() ? minDim_arg.getValue() : org_mesh->getDimension()); + new_mesh = rev.simplifyMesh("revised_mesh", eps_arg.getValue(), minDim); + } + + // write into a file + if (new_mesh) { + INFO("Revised mesh: %d nodes, %d elements.", new_mesh->getNNodes(), new_mesh->getNElements()); + FileIO::writeMeshToFile(*new_mesh, output_arg.getValue()); + } + + delete org_mesh; + delete new_mesh; + + delete custom_format; + delete logog_cout; + LOGOG_SHUTDOWN(); + + return 0; +} diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt index 6c9d6c4b9856763fb6ece580b00a3110bf86227e..0f4f665edb519c41b16942e77fad22227eddead3 100644 --- a/FileIO/CMakeLists.txt +++ b/FileIO/CMakeLists.txt @@ -19,6 +19,8 @@ SET( SOURCES TINInterface.cpp Writer.h Writer.cpp + writeMeshToFile.h + writeMeshToFile.cpp ) GET_SOURCE_FILES(SOURCES_LEGACY Legacy) diff --git a/FileIO/writeMeshToFile.cpp b/FileIO/writeMeshToFile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..730e7faa5874d735e0df306f24f88d46a7a98011 --- /dev/null +++ b/FileIO/writeMeshToFile.cpp @@ -0,0 +1,42 @@ +/** + * \copyright + * Copyright (c) 2012-2014, 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 "writeMeshToFile.h" + +// ThirdParty/logog +#include "logog/include/logog.hpp" + +// BaseLib +#include "FileTools.h" +#include "StringTools.h" + +// MeshLib +#include "Mesh.h" + +// FileIO +#include "Legacy/MeshIO.h" +#include "FileIO/VtkIO/VtuInterface.h" + +namespace FileIO +{ +void writeMeshToFile(const MeshLib::Mesh &mesh, const std::string &file_name) +{ + if (BaseLib::hasFileExtension("msh", file_name)) + { + Legacy::MeshIO meshIO; + meshIO.setMesh(&mesh); + meshIO.writeToFile(file_name); + } else if (BaseLib::hasFileExtension("vtu", file_name)) { + FileIO::VtuInterface writer(&mesh); + writer.writeToFile(file_name); + } else { + ERR("writeMeshToFile(): Unknown mesh file format in file %s.", file_name.c_str()); + } +} + +} // end namespace FileIO diff --git a/FileIO/writeMeshToFile.h b/FileIO/writeMeshToFile.h new file mode 100644 index 0000000000000000000000000000000000000000..bab68d434ddb88a7f1d00fbf7126c61557dfcda2 --- /dev/null +++ b/FileIO/writeMeshToFile.h @@ -0,0 +1,24 @@ +/** + * \copyright + * Copyright (c) 2012-2014, 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 WRITEMESHTOFILE_H_ +#define WRITEMESHTOFILE_H_ + +#include <string> + +namespace MeshLib +{ +class Mesh; +} + +namespace FileIO +{ +void writeMeshToFile(const MeshLib::Mesh &mesh, const std::string &file_name); +} + +#endif // WRITEMESHTOFILE_H_ diff --git a/MeshLib/MeshEditing/ElementValueModification.cpp b/MeshLib/MeshEditing/ElementValueModification.cpp index 092cc2f7cc594eb585f0b085b0f97a8d7fbb5740..a9219f686814552e3264d282c8010c9db2d76f3c 100644 --- a/MeshLib/MeshEditing/ElementValueModification.cpp +++ b/MeshLib/MeshEditing/ElementValueModification.cpp @@ -66,7 +66,7 @@ bool ElementValueModification::replace(MeshLib::Mesh &mesh, unsigned old_value, } } const std::size_t nElements (mesh.getNElements()); - std::vector<MeshLib::Element*> elements (mesh.getElements()); + std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); for (unsigned i=0; i<nElements; ++i) { if (elements[i]->getValue() == old_value) @@ -84,11 +84,25 @@ unsigned ElementValueModification::condense(MeshLib::Mesh &mesh) reverse_mapping[value_mapping[i]] = i; const std::size_t nElements (mesh.getNElements()); - std::vector<MeshLib::Element*> elements (mesh.getElements()); + std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); for (unsigned i=0; i<nElements; ++i) elements[i]->setValue(reverse_mapping[elements[i]->getValue()]); return nValues; } +unsigned ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value) +{ + std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); + unsigned nValues = 0; + for (auto e : elements) { + if (e->getGeomType()!=ele_type) + continue; + e->setValue(new_value); + nValues++; + } + + return nValues; +} + } // end namespace MeshLib diff --git a/MeshLib/MeshEditing/ElementValueModification.h b/MeshLib/MeshEditing/ElementValueModification.h index 472fff8eead45aa616a6da08228880a477200f98..6d1b43744f05d950f26ae11b5710274aa2446cb0 100644 --- a/MeshLib/MeshEditing/ElementValueModification.h +++ b/MeshLib/MeshEditing/ElementValueModification.h @@ -17,6 +17,8 @@ #include <vector> +#include "MeshLib/MeshEnums.h" + namespace MeshLib { // forward declarations class Mesh; @@ -35,6 +37,10 @@ public: /// Returns true if successful or false if the value is already taken. static bool replace(MeshLib::Mesh &mesh, unsigned old_value, unsigned new_value, bool replace_if_exists = false); + /// Sets new value for all elements having the given element type + /// Returns the number of elements having the given element type + static unsigned setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value); + private: /// Returns the values of elements within the mesh static std::vector<unsigned> getMeshValues(const MeshLib::Mesh &mesh); diff --git a/MeshLib/MeshEnums.cpp b/MeshLib/MeshEnums.cpp index 8eb465b4c0378a79d8eb17885472ec144c4e195e..00167b95a96473d02f2a9f923ab2290ce40d89b0 100644 --- a/MeshLib/MeshEnums.cpp +++ b/MeshLib/MeshEnums.cpp @@ -33,6 +33,25 @@ const std::string MeshElemType2String(const MeshElemType t) return "none"; } +const std::string MeshElemType2StringShort(const MeshElemType t) +{ + if (t == MeshElemType::LINE) + return "line"; + if (t == MeshElemType::QUAD) + return "quad"; + if (t == MeshElemType::HEXAHEDRON) + return "hex"; + if (t == MeshElemType::TRIANGLE) + return "tri"; + if (t == MeshElemType::TETRAHEDRON) + return "tet"; + if (t == MeshElemType::PRISM) + return "pris"; + if (t == MeshElemType::PYRAMID) + return "pyra"; + return "none"; +} + MeshElemType String2MeshElemType(const std::string &s) { if ((s.compare("line") == 0) || (s.compare("Line") == 0)) @@ -52,6 +71,27 @@ MeshElemType String2MeshElemType(const std::string &s) return MeshElemType::INVALID; } +std::vector<MeshElemType> getMeshElemTypes() +{ + std::vector<MeshElemType> vec; + vec.push_back(MeshElemType::LINE); + vec.push_back(MeshElemType::QUAD); + vec.push_back(MeshElemType::HEXAHEDRON); + vec.push_back(MeshElemType::TRIANGLE); + vec.push_back(MeshElemType::TETRAHEDRON); + vec.push_back(MeshElemType::PRISM); + vec.push_back(MeshElemType::PYRAMID); + return vec; +} + +std::vector<std::string> getMeshElemTypeStringsShort() +{ + std::vector<std::string> vec; + for (MeshElemType eleType : getMeshElemTypes()) + vec.push_back(MeshElemType2StringShort(eleType)); + return vec; +} + const std::string MeshQualityType2String(const MeshQualityType t) { if (t == MeshQualityType::AREA) diff --git a/MeshLib/MeshEnums.h b/MeshLib/MeshEnums.h index 22611565816375063881257a21ae84045aee11fa..d616776c878cb94d86046eed5f9d4cab729a900d 100644 --- a/MeshLib/MeshEnums.h +++ b/MeshLib/MeshEnums.h @@ -16,6 +16,7 @@ #define MESHENUMS_H #include <string> +#include <vector> /** * \brief Types of mesh elements supported by OpenGeoSys. @@ -73,9 +74,18 @@ enum class MeshQualityType /// Given a MeshElemType this returns the appropriate string. const std::string MeshElemType2String(const MeshElemType t); +/// Given a MeshElemType this returns the appropriate string with a short name. +const std::string MeshElemType2StringShort(const MeshElemType t); + /// Given a string of the shortened name of the element type, this returns the corresponding MeshElemType. MeshElemType String2MeshElemType(const std::string &s); +/// Returns a vector of all mesh element types +std::vector<MeshElemType> getMeshElemTypes(); + +/// Returns a vector of strings of mesh element types +std::vector<std::string> getMeshElemTypeStringsShort(); + const std::string MeshQualityType2String(const MeshQualityType t); #endif //MESHENUMS_H