Wildmeshing Toolkit
NamedMultiMesh.cpp
Go to the documentation of this file.
1 #include "NamedMultiMesh.hpp"
2 #include <fmt/ranges.h>
3 #include <spdlog/spdlog.h>
4 #include <nlohmann/json.hpp>
5 #include <span>
6 #include <vector>
7 #include <wmtk/Mesh.hpp>
10 
12 {
13  Node(Node&&) = default;
14  Node() = default;
15  Node(const Node& o)
16  : name(o.name)
18  {
19  std::ranges::transform(
20  o.m_children,
21  std::back_inserter(m_children),
22  [&](const std::unique_ptr<Node>& n) { return std::make_unique<Node>(*n); });
23  }
24  Node& operator=(const Node& o)
25  {
26  m_children.clear();
27  std::ranges::transform(
28  o.m_children,
29  std::back_inserter(m_children),
30  [&](const std::unique_ptr<Node>& n) { return std::make_unique<Node>(*n); });
31 
33  return *this;
34  }
35  std::string name;
36  std::vector<std::unique_ptr<Node>> m_children;
37 
38  std::map<std::string, int64_t> m_child_indexer;
39  void set_names(const nlohmann::json& js)
40  {
41  if (js.is_null()) {
42  return;
43  }
44  if (js.is_string()) {
45  auto& child = m_children.emplace_back(std::make_unique<Node>());
46  child->name = js;
47  } else if (js.is_array()) {
48  for (const auto& value : js) {
49  auto& child = m_children.emplace_back(std::make_unique<Node>());
50  child->name = value;
51  }
52  } else if (js.is_object()) {
53  for (const auto& [key, value] : js.items()) {
54  auto& child = m_children.emplace_back(std::make_unique<Node>());
55  child->name = key;
56  child->set_names(value);
57  }
58  }
60  }
61 
62  void get_name_tokens(const std::span<const int64_t>& t, std::vector<std::string_view>& toks)
63  const
64  {
65  toks.emplace_back(name);
66  if (!t.empty()) {
67  const size_t index = t.front();
68  assert(index < m_children.size());
69  assert(bool(m_children[index]));
70  const auto& child = *m_children[index];
71  child.get_name_tokens(t.subspan<1>(), toks);
72  }
73  }
74 
75 
77  {
78  m_child_indexer.clear();
79  for (size_t j = 0; j < m_children.size(); ++j) {
80  m_child_indexer.emplace(m_children[j]->name, j);
81  }
82  }
83  friend void to_json(
84  nlohmann::json& nlohmann_json_j,
85  const NamedMultiMesh::Node& nlohmann_json_t)
86  {
87  nlohmann::json arr = nlohmann::json::array();
88  for (const auto& c_ptr : nlohmann_json_t.m_children) {
89  arr.emplace_back(*c_ptr);
90  }
91  nlohmann_json_j[nlohmann_json_t.name] = arr;
92  }
93 };
94 
95 NamedMultiMesh::NamedMultiMesh(Mesh& m, const std::string& root_name)
96 {
97  set_mesh(m);
99 }
100 NamedMultiMesh::NamedMultiMesh(Mesh& m, const std::string_view& root_name)
101 {
102  set_mesh(m);
104 }
106 {
107  set_mesh(m);
109 }
110 
112 {
113  m_root = m.shared_from_this();
114 }
115 
117 {
118  set_root(m);
119  // set_root(m.get_multi_mesh_root());
120 }
121 
122 
123 Mesh& NamedMultiMesh::get_mesh(const std::string_view& path) const
124 {
125  const auto id = get_id(path);
126  return m_root->get_multi_mesh_child_mesh(id);
127 }
128 bool NamedMultiMesh::has_mesh(const std::string_view& path) const
129 {
130 #if defined(WMTK_ENABLED_CPP20)
131  std::ranges::view auto split = internal::split_path(path);
132 #else
133  auto split = internal::split_path(path);
134 #endif
135  Node const* cur_mesh = m_name_root.get();
136  assert(*split.begin() == cur_mesh->name || *split.begin() == "");
137  for (const auto& token : std::ranges::views::drop(split, 1)) {
138  auto it = cur_mesh->m_child_indexer.find(std::string(token));
139  if (it == cur_mesh->m_child_indexer.end()) {
140  return false;
141  } else {
142  cur_mesh = cur_mesh->m_children[it->second].get();
143  }
144  }
145  return true;
146 }
147 
148 auto NamedMultiMesh::get_id(const std::string_view& path) const -> std::vector<int64_t>
149 {
150 #if defined(WMTK_ENABLED_CPP20)
151  std::ranges::view auto split = internal::split_path(path);
152 #else
153  auto split = internal::split_path(path);
154 #endif
155 
156  std::vector<int64_t> indices;
157  Node const* cur_mesh = m_name_root.get();
158  assert(*split.begin() == cur_mesh->name || *split.begin() == "");
159  for (const auto& token : std::ranges::views::drop(split, 1)) {
160  // try {
161  int64_t index = cur_mesh->m_child_indexer.at(std::string(token));
162  //} catch(const std::runtime_error& e) {
163  // wmtk::logger().warn("Failed to find mesh named {} in mesh list. Path was ", nmm_name,
164  // path); throw e;
165  //}
166  indices.emplace_back(index);
167  cur_mesh = cur_mesh->m_children[index].get();
168  }
169 
170  return indices;
171 }
172 
173 std::vector<int64_t> NamedMultiMesh::get_id(const Mesh& m) const
174 {
176  m_root->absolute_multi_mesh_id(),
177 
179 }
180 
181 void NamedMultiMesh::set_name(const std::string_view& root_name)
182 {
184 }
186 {
187  assert(js.is_object() || js.is_string() || js.is_null());
188  m_name_root = std::make_unique<Node>();
189 
190  if (js.is_null()) {
191  return;
192  } else if (js.is_string()) {
193  m_name_root->name = js.get<std::string>();
194  } else {
195  assert(js.is_object());
196  assert(js.size() == 1);
197  for (const auto& [k, v] : js.items()) {
198  m_name_root->name = k;
199  m_name_root->set_names(v);
200  }
201  }
202 }
203 
204 std::string_view NamedMultiMesh::root_name() const
205 {
206  assert(bool(m_name_root));
207 
208  return m_name_root->name;
209 }
210 std::string NamedMultiMesh::name(const std::vector<int64_t>& id) const
211 {
212  std::vector<std::string_view> names;
213  Node const* cur_mesh = m_name_root.get();
214  names.emplace_back(root_name());
215  for (const auto& index : id) {
216  cur_mesh = cur_mesh->m_children[index].get();
217  names.emplace_back(cur_mesh->name);
218  }
219  return fmt::format("{}", fmt::join(names, "."));
220 }
221 
223  : m_name_root(std::make_unique<Node>())
224 {}
226 // NamedMultiMesh::NamedMultiMesh(NamedMultiMesh&&) = default;
227 // auto NamedMultiMesh::operator=(NamedMultiMesh&&) -> NamedMultiMesh& = default;
229 {
230  m_root = o.m_root;
231  m_name_root = std::make_unique<Node>(*o.m_name_root);
232  return *this;
233 }
235  : m_root(o.m_root)
236  , m_name_root(std::make_unique<Node>(*o.m_name_root))
237 {}
238 
239 
240 std::unique_ptr<nlohmann::json> NamedMultiMesh::get_names_json() const
241 {
242  auto js_ptr = std::make_unique<nlohmann::json>();
243  auto& js = *js_ptr;
244  js = *m_name_root;
245 
246 
247  return js_ptr;
248 }
249 
250 std::map<std::string, const Mesh&> NamedMultiMesh::all_meshes() const
251 // std::map<std::string, std::shared_ptr<const Mesh>> NamedMultiMesh::all_meshes() const
252 {
253  std::map<std::string, const Mesh&> meshes;
254  for (const auto& mptr : m_root->get_all_meshes()) {
255  meshes.emplace(get_name(*mptr), *mptr);
256  }
257  return meshes;
258 }
259 std::string NamedMultiMesh::get_name(const Mesh& m) const
260 {
261  std::vector<std::string_view> toks;
262 
263  const auto id = get_id(m);
264  m_name_root->get_name_tokens(id, toks);
265  return fmt::format("{}", fmt::join(toks, "."));
266 }
268 {
269  const std::vector<int64_t> parent_id = get_id(parent);
270  Node* cur_mesh = m_name_root.get();
271  for (const auto& index : parent_id) {
272  cur_mesh = cur_mesh->m_children[index].get();
273  }
274 
275  const auto child_relid = wmtk::multimesh::MultiMeshManager::relative_id(
276  parent.absolute_multi_mesh_id(),
278  spdlog::error(
279  "{} {} {}",
280  fmt::join(parent.absolute_multi_mesh_id(), ","),
281  fmt::join(o.root().absolute_multi_mesh_id(), ","),
282  fmt::join(child_relid, ","));
283  assert(child_relid.size() == 1);
284 
285  const int64_t& id = child_relid[0];
286  if (const size_t child_size = cur_mesh->m_children.size(); child_size == id) {
287  cur_mesh->m_children.emplace_back(std::make_unique<Node>(*o.m_name_root));
288  } else if (child_size < id) {
289  *cur_mesh->m_children[id] = *o.m_name_root;
290  }
291  cur_mesh->update_child_names();
292 }
293 } // namespace wmtk::components::multimesh
std::vector< int64_t > absolute_multi_mesh_id() const
returns a unique identifier for this mesh within a single multimesh structure
std::vector< int64_t > get_id(const std::string_view &path) const
auto operator=(const NamedMultiMesh &) -> NamedMultiMesh &
std::map< std::string, const Mesh & > all_meshes() const
void set_mesh(Mesh &m)
Navigates to the root of the multimesh.
bool has_mesh(const std::string_view &path) const
std::string name(const std::vector< int64_t > &id) const
Mesh & get_mesh(const std::string_view &path) const
void append_child_mesh_names(const Mesh &parent, const NamedMultiMesh &o)
void set_names(const nlohmann::json &js)
std::string get_name(const Mesh &m) const
void set_name(const std::string_view &root_name="")
sets just the name of the root mesh, keeping child names the same
std::unique_ptr< nlohmann::json > get_names_json() const
static std::vector< int64_t > relative_id(const std::vector< int64_t > &parent, const std::vector< int64_t > &child)
Definition: autodiff.h:995
auto split_path(const std::string_view &view)
Definition: split_path.hpp:8
std::vector< Simplex > make_unique(const Mesh &m, const std::vector< Simplex > &s)
Definition: make_unique.cpp:8
void get_name_tokens(const std::span< const int64_t > &t, std::vector< std::string_view > &toks) const
friend void to_json(nlohmann::json &nlohmann_json_j, const NamedMultiMesh::Node &nlohmann_json_t)
std::map< std::string, int64_t > m_child_indexer
std::vector< std::unique_ptr< Node > > m_children
nlohmann::json json
Definition: input.cpp:9