Wildmeshing Toolkit
Loading...
Searching...
No Matches
get_attribute.cpp
Go to the documentation of this file.
1
2#include "get_attribute.hpp"
3#include <ranges>
4#include <wmtk/Mesh.hpp>
6#include "..//MeshCollection.hpp"
7#include "../NamedMultiMesh.hpp"
12#include "get_attribute.hpp"
13#include "wmtk/utils/Logger.hpp"
14
16namespace detail {
17// turns an attribute path mesh.path/attrname to mesh.path attrname
18// std::array<std::string_view, 2>
19auto decompose_attribute_path(std::string_view attribute_path)
20{
21#if defined(WMTK_ENABLED_CPP20)
22 using namespace std;
23 auto tmp = std::ranges::views::split(attribute_path, "/"sv) |
24 std::views::transform([](const auto& r) noexcept -> std::string_view {
25 return std::string_view(r.begin(), r.end());
26 });
27
28 std::array<std::string_view, 2> ret;
29 std::ranges::copy(tmp, ret.begin());
30 if (ret[1].empty()) {
31 std::swap(ret[0], ret[1]);
32 }
33 return ret;
34#else
35
36 std::array<std::string, 2> ret;
37 std::vector<std::string> tmp;
38 if (attribute_path.empty()) {
39 tmp.emplace_back("");
40 tmp.emplace_back("");
41
42 } else {
43 std::string v = std::string(attribute_path);
44 std::istringstream iss(v);
45 std::string token;
46 if (v.size() > 0 && v[0] == '/') {
47 tmp.emplace_back("");
48 }
49 while (std::getline(iss, token, '/')) {
50 if (!token.empty()) tmp.emplace_back(token);
51 }
52 // at most 2 tokens are allowed
53 assert(tmp.size() <= 2);
54 if (tmp.size() == 1) {
55 tmp = {"", tmp[0]};
56 }
57 }
58 return std::array<std::string, 2>{{tmp[0], tmp[1]}};
59#endif
60}
61
62// std::array<std::string_view, 2>
64{
65 return decompose_attribute_path(description.path);
66}
67template <typename T>
69get_attribute(const Mesh& mesh, const std::string_view& name, PrimitiveType pt)
70{
71 if (mesh.has_attribute<T>(std::string(name), pt)) {
72 return mesh.get_attribute_handle<T>(std::string(name), pt);
73 } else {
75 std::string(name),
77 wmtk::attribute ::attribute_type_enum_from_type<T>());
78 }
79}
80
82 const Mesh& mesh,
83 const std::string_view& name,
86{
88 switch (type) {
89#define ENTRY(TYPE) \
90 case TYPE: \
91 return get_attribute<wmtk::attribute::type_from_attribute_type_enum_t<TYPE>>( \
92 mesh, \
93 name, \
94 pt);
95 ENTRY(AT::Char);
96 ENTRY(AT::Double);
97 ENTRY(AT::Int64);
98 ENTRY(AT::Rational);
99#undef ENTRY
100 default: assert(false);
101 }
102 return {};
103}
105 const Mesh& mesh,
106 const std::string_view& name,
107 std::optional<PrimitiveType> pt,
108 std::optional<wmtk::attribute::AttributeType> type)
109{
111 // This order matches wmtk::components::utils::get_attributes
112 constexpr static std::array<AT, 4> types{{AT::Char, AT::Int64, AT::Double, AT::Rational}};
113 // constexpr static std::array<AT, 4> types{{AT::Int64, AT::Double, AT::Char, AT::Rational}};
114 std::vector<AttributeDescription> possibilities;
116 auto add_option = [&](PrimitiveType prim, AT t) {
117 ret = get_attribute(mesh, name, prim, t);
118
119 uint8_t dimension = wmtk::get_primitive_type_id(prim);
120 possibilities.emplace_back(AttributeDescription{name, dimension, t});
121 };
122 if (pt.has_value() && type.has_value()) {
123 add_option(pt.value(), type.value());
124
125 } else if (pt.has_value()) {
126 for (AT at : types) {
127 try {
128 add_option(pt.value(), at);
129 } catch (const attribute_missing_error& e) {
130 continue;
131 }
132 }
133 } else if (type.has_value()) {
135 try {
136 add_option(p, type.value());
137 } catch (const attribute_missing_error& e) {
138 continue;
139 }
140 }
141 } else {
142 for (AT at : types) {
144 try {
145 add_option(p, at);
146 } catch (const attribute_missing_error& e) {
147 continue;
148 }
149 }
150 }
151 }
152
153
154 if (possibilities.empty()) {
155 throw attribute_missing_error::make(name, pt, type);
156 } else if (possibilities.size() > 1) {
157 throw attribute_ambiguous_error::make(possibilities, name,pt,type);
158 }
159
160 assert(ret.is_valid());
161 return ret;
162}
163} // namespace detail
164
166 const NamedMultiMesh& mesh,
167 const AttributeDescription& description)
168{
169 auto [mesh_path, attribute_name] = detail::decompose_attribute_path(description);
171 mesh.get_mesh(mesh_path),
172 attribute_name,
173 description.primitive_type(),
174 description.type);
175}
177 const MeshCollection& mesh,
178 const AttributeDescription& description)
179{
180 auto [mesh_path, attribute_name] = detail::decompose_attribute_path(description);
181
182 const Mesh& nmm = mesh.get_mesh(mesh_path);
184 nmm,
185 attribute_name,
186 description.primitive_type(),
187 description.type);
188}
189
191 const Mesh& mesh,
192 const AttributeDescription& description)
193{
194 auto [mesh_path, attribute_name] = detail::decompose_attribute_path(description);
196 mesh,
197 attribute_name,
198 description.primitive_type(),
199 description.type);
200}
201
202} // namespace wmtk::components::multimesh::utils
attribute::MeshAttributeHandle get_attribute_handle(const std::string &name, const PrimitiveType ptype) const
Definition Mesh.hpp:903
bool has_attribute(const std::string &name, const PrimitiveType ptype) const
Definition Mesh.hpp:923
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
const Mesh & get_mesh(const std::string_view &path) const
Mesh & get_mesh(const std::string_view &path) const
static attribute_ambiguous_error make(const std::vector< AttributeDescription > &possiblities, Args &&... args)
#define ENTRY(TYPE)
auto decompose_attribute_path(std::string_view attribute_path)
wmtk::attribute::MeshAttributeHandle get_attribute(const Mesh &mesh, const std::string_view &name, PrimitiveType pt)
wmtk::attribute::MeshAttributeHandle get_attribute(const NamedMultiMesh &mesh, const AttributeDescription &description)
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.