OGS
moveMeshNodes.cpp
Go to the documentation of this file.
1 
12 #include <memory>
13 #include <string>
14 
15 #include "BaseLib/FileTools.h"
16 #include "GeoLib/AABB.h"
17 #include "InfoLib/GitInfo.h"
18 #include "MathLib/MathTools.h"
21 #include "MeshLib/Mesh.h"
24 #include "MeshLib/Node.h"
25 
27  std::vector<MeshLib::Node*> const& nodes,
28  double const& max_dist)
29 {
30  double sqr_shortest_dist(max_dist);
31  double elevation(p[2]);
32  for (MeshLib::Node* node : nodes)
33  {
34  double sqr_dist = (p[0] - (*node)[0]) * (p[0] - (*node)[0]) +
35  (p[1] - (*node)[1]) * (p[1] - (*node)[1]);
36  if (sqr_dist < sqr_shortest_dist)
37  {
38  sqr_shortest_dist = sqr_dist;
39  elevation = (*node)[2];
40  }
41  }
42  return elevation;
43 }
44 
45 int main(int argc, char* argv[])
46 {
47  std::vector<std::string> keywords;
48  keywords.emplace_back("-ALL");
49  keywords.emplace_back("-MESH");
50  keywords.emplace_back("-LOWPASS");
51 
52  if (argc < 3)
53  {
54  INFO(
55  "Moves mesh nodes and connected elements either by a given value "
56  "or based on a list.\n");
57  INFO("Usage: {:s} <msh-file.msh> <keyword> [<value1>] [<value2>]",
58  argv[0]);
59  INFO("Available keywords:");
60  INFO(
61  "\t-ALL <value1> <value2> : changes the elevation of all mesh "
62  "nodes by <value2> in direction <value1> [x,y,z].");
63  INFO(
64  "\t-MESH <value1> <value2> : changes the elevation of mesh nodes "
65  "based on a second mesh <value1> with a search range of <value2>.");
66  INFO(
67  "\t-LOWPASS : applies a lowpass filter over node elevation using "
68  "directly connected nodes.");
69  return EXIT_FAILURE;
70  }
71 
72  const std::string msh_name(argv[1]);
73  const std::string current_key(argv[2]);
74  std::string const ext(BaseLib::getFileExtension(msh_name));
75  if (!(ext == ".msh" || ext == ".vtu"))
76  {
77  ERR("Error: Parameter 1 must be a mesh-file (*.msh / *.vtu).");
78  INFO("Usage: {:s} <msh-file.gml> <keyword> <value>", argv[0]);
79  return EXIT_FAILURE;
80  }
81 
82  bool const is_keyword = std::any_of(keywords.begin(), keywords.end(),
83  [current_key](auto const& keyword)
84  { return current_key == keyword; });
85 
86  if (!is_keyword)
87  {
88  ERR("Keyword not recognised. Available keywords:");
89  for (auto const& keyword : keywords)
90  INFO("\t{:s}", keyword);
91  return EXIT_FAILURE;
92  }
93 
94  std::unique_ptr<MeshLib::Mesh> mesh(
96  if (mesh == nullptr)
97  {
98  ERR("Error reading mesh file.");
99  return 1;
100  }
101 
102  // Start keyword-specific selection of nodes
103 
104  // moves the elevation of all nodes by value
105  if (current_key == "-ALL")
106  {
107  if (argc < 5)
108  {
109  ERR("Missing parameter...");
110  return EXIT_FAILURE;
111  }
112  const std::string dir(argv[3]);
113  unsigned idx = (dir == "x") ? 0 : (dir == "y") ? 1 : 2;
114  const double value(strtod(argv[4], 0));
115  INFO("Moving all mesh nodes by {:g} in direction {:d} ({:s})...", value,
116  idx, dir);
117  // double value(-10);
118  const std::size_t nNodes(mesh->getNumberOfNodes());
119  std::vector<MeshLib::Node*> nodes(mesh->getNodes());
120  for (std::size_t i = 0; i < nNodes; i++)
121  {
122  (*nodes[i])[idx] += value;
123  }
124  }
125 
126  // maps the elevation of mesh nodes according to a ground truth mesh
127  // whenever nodes exist within max_dist
128  if (current_key == "-MESH")
129  {
130  if (argc < 4)
131  {
132  ERR("Missing parameter...");
133  return EXIT_FAILURE;
134  }
135  const std::string value(argv[3]);
136  double max_dist(pow(strtod(argv[4], 0), 2));
137  std::unique_ptr<MeshLib::Mesh> ground_truth(
139  if (ground_truth == nullptr)
140  {
141  ERR("Error reading mesh file.");
142  return EXIT_FAILURE;
143  }
144 
145  std::vector<MeshLib::Node*> const& nodes = mesh->getNodes();
146  MeshLib::MeshElementGrid const grid(*ground_truth);
147  double const max_edge(mesh->getMaxEdgeLength());
148 
149  for (MeshLib::Node* node : nodes)
150  {
151  MathLib::Point3d min_vol{{(*node)[0] - max_edge,
152  (*node)[1] - max_edge,
153  -std::numeric_limits<double>::max()}};
154  MathLib::Point3d max_vol{{(*node)[0] + max_edge,
155  (*node)[1] + max_edge,
156  std::numeric_limits<double>::max()}};
157  std::vector<const MeshLib::Element*> const& elems =
158  grid.getElementsInVolume(min_vol, max_vol);
159  auto const* element =
161  (*node)[2] =
162  (element != nullptr)
164  : getClosestPointElevation(*node, ground_truth->getNodes(),
165  max_dist);
166  }
167  }
168 
169  // a simple lowpass filter for the elevation of mesh nodes using the
170  // elevation of each node weighted by 2 and the elevation of each connected
171  // node weighted by 1
172  if (current_key == "-LOWPASS")
173  {
174  const std::size_t nNodes(mesh->getNumberOfNodes());
175  std::vector<MeshLib::Node*> nodes(mesh->getNodes());
176 
177  std::vector<double> elevation(nNodes);
178  for (std::size_t i = 0; i < nNodes; i++)
179  {
180  elevation[i] = (*nodes[i])[2];
181  }
182 
183  auto const& connections =
185  for (std::size_t i = 0; i < nNodes; i++)
186  {
187  auto const& conn_nodes(connections[nodes[i]->getID()]);
188  const unsigned nConnNodes(conn_nodes.size());
189  elevation[i] = (2 * (*nodes[i])[2]);
190  for (std::size_t j = 0; j < nConnNodes; ++j)
191  {
192  elevation[i] += (*conn_nodes[j])[2];
193  }
194  elevation[i] /= (nConnNodes + 2);
195  }
196 
197  for (std::size_t i = 0; i < nNodes; i++)
198  {
199  (*nodes[i])[2] = elevation[i];
200  }
201  }
202  /**** add other keywords here ****/
203 
204  std::string const new_mesh_name(msh_name.substr(0, msh_name.length() - 4) +
205  "_new.vtu");
206  if (MeshLib::IO::writeMeshToFile(*mesh, new_mesh_name) != 0)
207  {
208  return EXIT_FAILURE;
209  }
210 
211  INFO("Result successfully written.");
212  return EXIT_SUCCESS;
213 }
Definition of the AABB class.
Filename manipulation routines.
Git information.
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:32
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
Definition of the Mesh class.
Definition of the Node class.
std::vector< MeshLib::Element const * > getElementsInVolume(POINT const &min, POINT const &max) const
int main(int argc, char *argv[])
double getClosestPointElevation(MeshLib::Node const &p, std::vector< MeshLib::Node * > const &nodes, double const &max_dist)
std::string getFileExtension(const std::string &path)
Definition: FileTools.cpp:186
static const double p
MeshLib::Mesh * readMeshFromFile(const std::string &file_name)
int writeMeshToFile(const MeshLib::Mesh &mesh, std::filesystem::path const &file_path, [[maybe_unused]] std::set< std::string > variable_output_names)
double getElevation(Element const &element, Node const &node)
Element const * getProjectedElement(std::vector< const Element * > const &elements, Node const &node)
std::vector< std::vector< Node * > > calculateNodesConnectedByElements(Mesh const &mesh)
Definition: Mesh.cpp:331
Definition of readMeshFromFile function.