Skip to content

Commit

Permalink
Merge pull request #842 from mtao/mtao/attribute_fetcher
Browse files Browse the repository at this point in the history
Method for using structs / json to access attributes
  • Loading branch information
mtao authored Nov 25, 2024
2 parents 9cd80db + 89002a7 commit e1bdd48
Show file tree
Hide file tree
Showing 27 changed files with 930 additions and 129 deletions.
16 changes: 14 additions & 2 deletions components/multimesh/src/wmtk/components/multimesh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@ set(SRC_FILES

NamedMultiMesh.hpp
NamedMultiMesh.cpp
utils/get_attribute.hpp
utils/get_attribute.cpp
internal/split_path.hpp

MeshCollection.hpp
MeshCollection.cpp

utils/AttributeDescription.hpp
utils/AttributeDescription.cpp

utils/get_attribute.hpp
utils/get_attribute.cpp
utils/detail/attribute_error.hpp

utils/detail/named_error_text.hpp
utils/detail/named_error_text.cpp
utils/detail/attribute_ambiguous_error.hpp
utils/detail/attribute_ambiguous_error.cpp
utils/detail/attribute_missing_error.hpp
utils/detail/attribute_missing_error.cpp
)

include(stb)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
namespace wmtk::components::multimesh {


NamedMultiMesh& MeshCollection::add_mesh(NamedMultiMesh m)
NamedMultiMesh& MeshCollection::add_mesh(NamedMultiMesh&& m)
{
auto mptr = std::make_unique<NamedMultiMesh>(std::move(m));
auto [it, did] = m_meshes.emplace(mptr->root_name(), std::move(mptr));


return *it->second;
}

Expand Down Expand Up @@ -51,6 +52,7 @@ bool MeshCollection::has_mesh(const std::string_view& path) const

const NamedMultiMesh& MeshCollection::get_named_multimesh(const std::string_view& path) const
{
assert(!m_meshes.empty());
using namespace std;
#if defined(WMTK_ENABLED_CPP20)
std::ranges::view auto split = internal::split_path(path);
Expand All @@ -63,6 +65,19 @@ const NamedMultiMesh& MeshCollection::get_named_multimesh(const std::string_view
"assuming that is the right mesh");
return *m_meshes.begin()->second;
}
if (auto it = m_meshes.find(nmm_name); it == m_meshes.end()) {
std::vector<std::string_view> names;
std::transform(
m_meshes.begin(),
m_meshes.end(),
std::back_inserter(names),
[](const auto& pr) { return pr.first; });
wmtk::logger().error(
"Was unable to find root mesh name {} among {} names [{}] in MeshCollection",
nmm_name,
m_meshes.size(),
fmt::join(names, ","));
}
return *m_meshes.at(nmm_name);
}
NamedMultiMesh& MeshCollection::get_named_multimesh(const std::string_view& path)
Expand All @@ -80,7 +95,12 @@ NamedMultiMesh& MeshCollection::get_named_multimesh(const std::string_view& path
"assuming that is the right mesh");
return *m_meshes.begin()->second;
}
return *m_meshes.at(nmm_name);
try {
return *m_meshes.at(nmm_name);
} catch (const std::runtime_error& e) {
wmtk::logger().warn("Failed to find mesh named {} in mesh list. Path was ", nmm_name, path);
throw e;
}
}
std::map<std::string, const Mesh&> MeshCollection::all_meshes() const
// std::map<std::string, std::shared_ptr<const Mesh>> MeshCollection::all_meshes() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class InputOptions;
class MeshCollection
{
public:
NamedMultiMesh& add_mesh(NamedMultiMesh o);
NamedMultiMesh& add_mesh(NamedMultiMesh&& o);
template <typename... Args>
NamedMultiMesh& emplace_mesh(Args&&... args)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,12 @@ auto NamedMultiMesh::get_id(const std::string_view& path) const -> std::vector<i
Node const* cur_mesh = m_name_root.get();
assert(*split.begin() == cur_mesh->name || *split.begin() == "");
for (const auto& token : std::ranges::views::drop(split, 1)) {
// try {
int64_t index = cur_mesh->m_child_indexer.at(std::string(token));
//} catch(const std::runtime_error& e) {
// wmtk::logger().warn("Failed to find mesh named {} in mesh list. Path was ", nmm_name,
// path); throw e;
//}
indices.emplace_back(index);
cur_mesh = cur_mesh->m_children[index].get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@ class NamedMultiMesh
{
public:
NamedMultiMesh();
explicit NamedMultiMesh(Mesh& m, const std::string& root_name);
NamedMultiMesh(Mesh& m, const std::string_view& root_name);
explicit NamedMultiMesh(Mesh& m, const nlohmann::json& root_name);

// Explicit constructors to remove ambiguities between string_view and json constructors
explicit NamedMultiMesh(Mesh& m, const std::string& root_name);
template <size_t N>
explicit NamedMultiMesh(Mesh& m, const char name[N])
: NamedMultiMesh(m, std::string_view(name))
{}
// NamedMultiMesh(NamedMultiMesh&&);
NamedMultiMesh(const NamedMultiMesh&);
~NamedMultiMesh();
// auto operator=(NamedMultiMesh&&) -> NamedMultiMesh&;
auto operator=(const NamedMultiMesh&) -> NamedMultiMesh&;

/// sets just the name of the root mesh, keeping child names the same
void set_name(const std::string_view& root_name = "");
void set_names(const nlohmann::json& js);
void set_root(Mesh& m);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "AttributeDescription.hpp"
#include <nlohmann/json.hpp>

#include <wmtk/components/utils/json_serialize_enum.hpp>
namespace wmtk::attribute {
// TODO: this definitely will cause a conflict someday if someone else wants to serialize
// attributetype
WMTK_NLOHMANN_JSON_SERIALIZE_ENUM(
AttributeType,
{
{AttributeType::Char, "char"},
{AttributeType::Double, "double"},
{AttributeType::Int64, "int"},
{AttributeType::Rational, "rational"},
})
} // namespace wmtk::attribute

namespace wmtk::components::multimesh::utils {
auto AttributeDescription::operator<=>(const AttributeDescription&) const -> std::strong_ordering =
default;
auto AttributeDescription::operator==(const AttributeDescription&) const -> bool = default;

namespace {
NLOHMANN_JSON_SERIALIZE_ENUM(
PrimitiveType,
{
{PrimitiveType::Vertex, 0},
{PrimitiveType::Edge, 1},
{PrimitiveType::Triangle, 2},
{PrimitiveType::Tetrahedron, 3},
})
} // namespace
WMTK_NLOHMANN_JSON_FRIEND_TO_JSON_PROTOTYPE(AttributeDescription)
{
WMTK_NLOHMANN_ASSIGN_TYPE_TO_JSON(path);
if (nlohmann_json_t.dimension.has_value()) {
nlohmann_json_j["dimension"] = nlohmann_json_t.dimension.value();
}
if (nlohmann_json_t.type.has_value()) {
nlohmann_json_j["type"] = nlohmann_json_t.type.value();
}
}
WMTK_NLOHMANN_JSON_FRIEND_FROM_JSON_PROTOTYPE(AttributeDescription)
{
if (nlohmann_json_j.is_string()) {
nlohmann_json_t.path = nlohmann_json_j.get<std::string>();
} else {
nlohmann_json_t.path = nlohmann_json_j["path"];
}
if (nlohmann_json_j.contains("dimension")) {
nlohmann_json_t.dimension = nlohmann_json_j["dimension"];
}
if (nlohmann_json_j.contains("type")) {
nlohmann_json_t.type = nlohmann_json_j["type"];
}
}

std::optional<PrimitiveType> AttributeDescription::primitive_type() const
{
if (this->dimension.has_value()) {
int8_t d = this->dimension.value();
assert(d < 4);

return get_primitive_type_from_id(d);
} else {
return {};
}
}

} // namespace wmtk::components::multimesh::utils
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once
#include <compare>
#include <optional>
#include <wmtk/PrimitiveType.hpp>
#include <wmtk/attribute/AttributeType.hpp>
#include <wmtk/components/utils/json_macros.hpp>

namespace wmtk::attribute {
WMTK_NLOHMANN_JSON_DECLARATION(AttributeType)
}

namespace wmtk::components::multimesh::utils {


// the minimal information to uniquely extract an attribute handle
struct AttributeDescription
{
std::string path;
std::optional<uint8_t> dimension;
std::optional<attribute::AttributeType> type;


AttributeDescription() = default;
AttributeDescription(const AttributeDescription&) = default;
AttributeDescription(AttributeDescription&&) = default;
AttributeDescription& operator=(const AttributeDescription&) = default;
AttributeDescription& operator=(AttributeDescription&&) = default;
~AttributeDescription() = default;

AttributeDescription(
const std::string_view& p,
const std::optional<uint8_t>& dim,
const std::optional<attribute::AttributeType>& t)
: path(p)
, dimension(dim)
, type(t)
{}

explicit AttributeDescription(
const std::string_view& p,
const std::optional<PrimitiveType>& pt,
const std::optional<attribute::AttributeType>& t)
: AttributeDescription(
p,
pt.has_value() ? std::optional<uint8_t>{wmtk::get_primitive_type_id(pt.value())}
: std::optional<uint8_t>{},
t)
{}


std::optional<PrimitiveType> primitive_type() const;

auto operator<=>(const AttributeDescription&) const -> std::strong_ordering;
auto operator==(const AttributeDescription&) const -> bool;


WMTK_NLOHMANN_JSON_FRIEND_DECLARATION(AttributeDescription)
};
} // namespace wmtk::components::multimesh::utils
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#include "attribute_ambiguous_error.hpp"
#include <fmt/format.h>
#include <fmt/ranges.h>
#include <algorithm>
#include <iterator>
#include "named_error_text.hpp"
namespace wmtk::components::multimesh::utils::detail {

std::string attribute_ambiguous_error::make_message(
const AttributeDescription& ad,
const std::vector<AttributeDescription>& possibilities)
{
std::vector<std::string> names;

std::string (*maker)(const AttributeDescription&) = make_named_error_string;
std::transform(possibilities.begin(), possibilities.end(), std::back_inserter(names), maker);
return fmt::format(
"Multiple options for an attribute {} found: [{}]",
make_named_error_string(ad),
fmt::join(names, ","));
}
} // namespace wmtk::components::multimesh::utils::detail
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once
#include "attribute_error.hpp"
namespace wmtk::components::multimesh::utils {
struct AttributeDescription;
}

namespace wmtk::components::multimesh::utils::detail {

class attribute_ambiguous_error : public attribute_error
{
public:
static std::string make_message(
const AttributeDescription& description,
const std::vector<AttributeDescription>& possibilities);
attribute_ambiguous_error(
const AttributeDescription& d,
const std::vector<AttributeDescription>& possibilities)
: attribute_error(make_message(d, possibilities), d)
{}
template <typename... Args>
static attribute_ambiguous_error make(
const std::vector<AttributeDescription>& possiblities,
Args&&... args)
{
return attribute_ambiguous_error(
AttributeDescription{std::forward<Args>(args)...},
possiblities);
}
};


} // namespace wmtk::components::multimesh::utils::detail
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include <optional>
#include <stdexcept>
#include <wmtk/Primitive.hpp>
#include <wmtk/attribute/AttributeType.hpp>
#include "../AttributeDescription.hpp"

namespace wmtk::components::multimesh::utils::detail {

class attribute_error : public std::range_error
{
public:
template <typename... Args>
attribute_error(const std::string_view& message, Args&&... args)
: std::range_error(std::string(message))
, description(std::forward<Args>(args)...)
{}
AttributeDescription description;
};
} // namespace wmtk::components::multimesh::utils::detail
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "attribute_missing_error.hpp"
#include "named_error_text.hpp"
namespace wmtk::components::multimesh::utils::detail {

std::string attribute_missing_error::make_message(const AttributeDescription& ad)
{
return "Could not find attribute " + make_named_error_string(ad);
}
} // namespace wmtk::components::multimesh::utils::detail
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once
#include "attribute_error.hpp"
namespace wmtk::components::multimesh::utils {
struct AttributeDescription;
}

namespace wmtk::components::multimesh::utils::detail {

class attribute_missing_error : public attribute_error
{
public:
static std::string make_message(const AttributeDescription& description);
attribute_missing_error(const AttributeDescription& d)
: attribute_error(make_message(d), d)
{}
template <typename... Args>
static attribute_missing_error make(Args&&... args)
{
return attribute_missing_error(AttributeDescription{std::forward<Args>(args)...});
}
};


} // namespace wmtk::components::multimesh::utils::detail
Loading

0 comments on commit e1bdd48

Please sign in to comment.