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  int64_t index = cur_mesh->m_child_indexer.at(std::string(token));
161  indices.emplace_back(index);
162  cur_mesh = cur_mesh->m_children[index].get();
163  }
164 
165  return indices;
166 }
167 
168 std::vector<int64_t> NamedMultiMesh::get_id(const Mesh& m) const
169 {
171  m_root->absolute_multi_mesh_id(),
172 
174 }
175 
176 void NamedMultiMesh::set_name(const std::string_view& root_name)
177 {
179 }
181 {
182  assert(js.is_object() || js.is_string() || js.is_null());
183  m_name_root = std::make_unique<Node>();
184 
185  if (js.is_null()) {
186  return;
187  } else if (js.is_string()) {
188  m_name_root->name = js.get<std::string>();
189  } else {
190  assert(js.is_object());
191  assert(js.size() == 1);
192  for (const auto& [k, v] : js.items()) {
193  m_name_root->name = k;
194  m_name_root->set_names(v);
195  }
196  }
197 }
198 
199 std::string_view NamedMultiMesh::root_name() const
200 {
201  assert(bool(m_name_root));
202 
203  return m_name_root->name;
204 }
205 std::string NamedMultiMesh::name(const std::vector<int64_t>& id) const
206 {
207  std::vector<std::string_view> names;
208  Node const* cur_mesh = m_name_root.get();
209  names.emplace_back(root_name());
210  for (const auto& index : id) {
211  cur_mesh = cur_mesh->m_children[index].get();
212  names.emplace_back(cur_mesh->name);
213  }
214  return fmt::format("{}", fmt::join(names, "."));
215 }
216 
218  : m_name_root(std::make_unique<Node>())
219 {}
221 // NamedMultiMesh::NamedMultiMesh(NamedMultiMesh&&) = default;
222 // auto NamedMultiMesh::operator=(NamedMultiMesh&&) -> NamedMultiMesh& = default;
224 {
225  m_root = o.m_root;
226  m_name_root = std::make_unique<Node>(*o.m_name_root);
227  return *this;
228 }
230  : m_root(o.m_root)
231  , m_name_root(std::make_unique<Node>(*o.m_name_root))
232 {}
233 
234 
235 std::unique_ptr<nlohmann::json> NamedMultiMesh::get_names_json() const
236 {
237  auto js_ptr = std::make_unique<nlohmann::json>();
238  auto& js = *js_ptr;
239  js = *m_name_root;
240 
241 
242  return js_ptr;
243 }
244 
245 std::map<std::string, const Mesh&> NamedMultiMesh::all_meshes() const
246 // std::map<std::string, std::shared_ptr<const Mesh>> NamedMultiMesh::all_meshes() const
247 {
248  std::map<std::string, const Mesh&> meshes;
249  for (const auto& mptr : m_root->get_all_meshes()) {
250  meshes.emplace(get_name(*mptr), *mptr);
251  }
252  return meshes;
253 }
254 std::string NamedMultiMesh::get_name(const Mesh& m) const
255 {
256  std::vector<std::string_view> toks;
257 
258  const auto id = get_id(m);
259  m_name_root->get_name_tokens(id, toks);
260  return fmt::format("{}", fmt::join(toks, "."));
261 }
263 {
264  const std::vector<int64_t> parent_id = get_id(parent);
265  Node* cur_mesh = m_name_root.get();
266  for (const auto& index : parent_id) {
267  cur_mesh = cur_mesh->m_children[index].get();
268  }
269 
270  const auto child_relid = wmtk::multimesh::MultiMeshManager::relative_id(
271  parent.absolute_multi_mesh_id(),
273  spdlog::error(
274  "{} {} {}",
275  fmt::join(parent.absolute_multi_mesh_id(), ","),
276  fmt::join(o.root().absolute_multi_mesh_id(), ","),
277  fmt::join(child_relid, ","));
278  assert(child_relid.size() == 1);
279 
280  const int64_t& id = child_relid[0];
281  if (const size_t child_size = cur_mesh->m_children.size(); child_size == id) {
282  cur_mesh->m_children.emplace_back(std::make_unique<Node>(*o.m_name_root));
283  } else if (child_size < id) {
284  *cur_mesh->m_children[id] = *o.m_name_root;
285  }
286  cur_mesh->update_child_names();
287 }
288 } // 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="")
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