diff --git a/Applications/Utils/MeshEdit/CMakeLists.txt b/Applications/Utils/MeshEdit/CMakeLists.txt index bf0b42ad9fd7b7ac327a2604c5c024e95025b97b..a44be8c211ed01fec82b55734c41877e34c3f8cf 100644 --- a/Applications/Utils/MeshEdit/CMakeLists.txt +++ b/Applications/Utils/MeshEdit/CMakeLists.txt @@ -77,6 +77,10 @@ add_executable(ExtractSurface ExtractSurface.cpp) target_link_libraries(ExtractSurface MeshLib) set_target_properties(ExtractSurface PROPERTIES FOLDER Utilities) +add_executable(swapNodeCoordinateAxes swapNodeCoordinateAxes.cpp) +target_link_libraries(swapNodeCoordinateAxes MeshLib) +set_target_properties(swapNodeCoordinateAxes PROPERTIES FOLDER Utilities) + #################### ### Installation ### #################### @@ -96,5 +100,6 @@ install(TARGETS ResetPropertiesInPolygonalRegion reviseMesh queryMesh + swapNodeCoordinateAxes RUNTIME DESTINATION bin COMPONENT Utilities ) diff --git a/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp b/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f16070c79e8b5f6b69ff1d4accf31908d5c7315 --- /dev/null +++ b/Applications/Utils/MeshEdit/swapNodeCoordinateAxes.cpp @@ -0,0 +1,111 @@ +/** + * @copyright + * Copyright (c) 2012-2016, 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 <memory> +#include <string> + +#include <tclap/CmdLine.h> + +#include "Applications/ApplicationsLib/LogogSetup.h" + +#include "BaseLib/BuildInfo.h" + +#include "MeshLib/Mesh.h" +#include "MeshLib/Node.h" + +#include "MeshLib/IO/readMeshFromFile.h" +#include "MeshLib/IO/writeMeshToFile.h" + +static void swapNodeCoordinateAxes(MeshLib::Mesh &mesh, std::array<int, 3> const& new_axes_indices) +{ + for (MeshLib::Node* node : mesh.getNodes()) + { + for (int i=0; i<3; i++) + (*node)[i] = (*node)[new_axes_indices[i]]; + } +} + +static bool parseNewOrder(std::string const& str_order, std::array<int, 3> &new_axes_indices) +{ + if (str_order.length()!=3) + { + ERR("Invalid argument for the new order. The argument should contain three characters."); + return false; + } + + for (std::size_t i=0; i<new_axes_indices.size(); i++) + new_axes_indices[i] = -1; + + for (int i=0; i<3; i++) + { + if (str_order[i] == 'x') + new_axes_indices[i] = 0; + else if (str_order[i] == 'y') + new_axes_indices[i] = 1; + else if (str_order[i] == 'z') + new_axes_indices[i] = 2; + else { + ERR("Invalid argument for the new order. The given argument contains a character other than \"x\", \"y\", \"z\"."); + return false; + } + } + + bool isAxisSet[3] = {false}; + for (std::size_t i=0; i<new_axes_indices.size(); i++) + { + if (isAxisSet[new_axes_indices[i]]) + { + ERR("Invalid argument for the new order. The argument contains some character used more than once."); + return false; + } + isAxisSet[new_axes_indices[i]] = true; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + ApplicationsLib::LogogSetup logog_setup; + + TCLAP::CmdLine cmd("Swap node coordinate values", ' ', BaseLib::BuildInfo::git_describe); + 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::ValueArg<std::string> new_order_arg("n", "new-order", "the new order of swapped coordinate values " + "(e.g. \"xzy\" for converting XYZ values to XZY values)", + true, "", "string"); + cmd.add( new_order_arg ); + cmd.parse( argc, argv ); + + const std::string str_order = new_order_arg.getValue(); + std::array<int, 3> new_order = {}; + if (!parseNewOrder(str_order, new_order)) + return EXIT_FAILURE; + + std::unique_ptr<MeshLib::Mesh> mesh( + MeshLib::IO::readMeshFromFile(input_arg.getValue())); + if (!mesh) + return EXIT_FAILURE; + + if (mesh->getDimension() == 3) + { + WARN("Swapping coordinate values of 3D elements can result in incorrect node-ordering."); + } + + INFO("Exchange node coordinates from xyz to %s", new_order_arg.getValue().data()); + swapNodeCoordinateAxes(*mesh, new_order); + + INFO("Save the new mesh into a file"); + MeshLib::IO::writeMeshToFile(*mesh, output_arg.getValue()); + + return EXIT_SUCCESS; +}