Wildmeshing Toolkit
Loading...
Searching...
No Matches
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
95NamedMultiMesh::NamedMultiMesh(Mesh& m, const std::string& root_name)
96{
97 set_mesh(m);
99}
100NamedMultiMesh::NamedMultiMesh(Mesh& m, const std::string_view& root_name)
101{
102 set_mesh(m);
104}
105NamedMultiMesh::NamedMultiMesh(Mesh& m, const nlohmann::json& root_name)
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
123Mesh& 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}
128bool 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
148auto 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
173std::vector<int64_t> NamedMultiMesh::get_id(const Mesh& m) const
174{
176 m_root->absolute_multi_mesh_id(),
177
179}
180
181void NamedMultiMesh::set_name(const std::string_view& root_name)
182{
183 set_names(nlohmann::json(root_name));
184}
185void NamedMultiMesh::set_names(const nlohmann::json& js)
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
204std::string_view NamedMultiMesh::root_name() const
205{
206 assert(bool(m_name_root));
207
208 return m_name_root->name;
209}
210std::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
240std::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
250std::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}
259std::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)
auto split_path(const std::string_view &view)
Definition split_path.hpp: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