diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-03-02 18:18:38 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-03-02 18:18:38 +0000 |
commit | 98df33e0a52e086b68df2a62ce2f41cc6b67db63 (patch) | |
tree | 196300dbc07855b130e73b92077ff0e1e701a418 /assetFactory | |
parent | Remove to specify if the Selection pointer type is shared or not (diff) | |
download | ilt-98df33e0a52e086b68df2a62ce2f41cc6b67db63.tar.bz2 ilt-98df33e0a52e086b68df2a62ce2f41cc6b67db63.tar.xz ilt-98df33e0a52e086b68df2a62ce2f41cc6b67db63.zip |
Parse colour values as they're read
Diffstat (limited to 'assetFactory')
-rw-r--r-- | assetFactory/assetFactory.cpp | 32 | ||||
-rw-r--r-- | assetFactory/assetFactory.h | 4 | ||||
-rw-r--r-- | assetFactory/modelFactoryMesh.h | 3 | ||||
-rw-r--r-- | assetFactory/style.cpp | 72 | ||||
-rw-r--r-- | assetFactory/style.h | 18 | ||||
-rw-r--r-- | assetFactory/use.cpp | 3 |
6 files changed, 76 insertions, 56 deletions
diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp index 016f29e..70f5337 100644 --- a/assetFactory/assetFactory.cpp +++ b/assetFactory/assetFactory.cpp @@ -30,12 +30,12 @@ AssetFactory::parseX11RGB(const char * path) { filesystem::FileStar rgb {path, "r"}; Colours out; - glm::u8vec3 colour; + Colour colour; char inname[BUFSIZ]; - while (fscanf(rgb, "%hhu %hhu %hhu %[^\n\r]s", &colour.r, &colour.g, &colour.b, inname) == 4) { + while (fscanf(rgb, "%f %f %f %[^\n\r]s", &colour.r, &colour.g, &colour.b, inname) == 4) { std::string name {inname}; normalizeColourName(name); - out.emplace(std::move(name), colour); + out.emplace(std::move(name), colour / 255.f); } return out; } @@ -49,6 +49,32 @@ AssetFactory::normalizeColourName(std::string & name) }; } +AssetFactory::ColourAlpha +AssetFactory::parseColour(std::string_view in) const +{ + if (in.empty()) { + throw std::runtime_error("Empty colour specification"); + } + if (in[0] == '#') { + if (in.length() > 9 || in.length() % 2 == 0) { + throw std::runtime_error("Invalid hex colour specification"); + } + ColourAlpha out {0, 0, 0, 1}; + std::generate_n(&out.r, (in.length() - 1) / 2, [in = in.data() + 1]() mutable { + uint8_t channel; + std::from_chars(in, in + 2, channel, 16); + in += 2; + return static_cast<float>(channel) / 255.f; + }); + return out; + } + if (auto mf = std::dynamic_pointer_cast<const AssetFactory>(Persistence::sharedObjects.at("assetFactory"))) { + if (const auto colour = mf->colours.find(in); colour != mf->colours.end()) { + return {colour->second, 1}; + } + } + throw std::runtime_error("No such asset factory colour"); +} bool AssetFactory::persist(Persistence::PersistenceStore & store) { diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h index 42082eb..2bd576b 100644 --- a/assetFactory/assetFactory.h +++ b/assetFactory/assetFactory.h @@ -22,11 +22,13 @@ class AssetFactory : public Persistence::Persistable { public: using Shapes = std::map<std::string, Shape::Ptr, std::less<>>; using Assets = std::map<std::string, Asset::Ptr, std::less<>>; - using Colour = glm::u8vec3; + using Colour = glm::vec3; + using ColourAlpha = glm::vec4; using Colours = std::map<std::string, Colour, std::less<>>; AssetFactory(); [[nodiscard]] static std::shared_ptr<AssetFactory> loadXML(const std::filesystem::path &); + [[nodiscard]] ColourAlpha parseColour(std::string_view) const; Shapes shapes; Assets assets; diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h index b4f5254..258913b 100644 --- a/assetFactory/modelFactoryMesh.h +++ b/assetFactory/modelFactoryMesh.h @@ -5,6 +5,7 @@ #include <OpenMesh/Core/Mesh/Traits.hh> #include <glm/geometric.hpp> #include <glm/vec3.hpp> +#include <glm/vec4.hpp> namespace OpenMesh { template<typename Scalar, int DIM> struct glmvec : public VectorT<Scalar, DIM> { @@ -25,7 +26,7 @@ struct ModelFactoryTraits : public OpenMesh::DefaultTraits { VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status); using Point = OpenMesh::glmvec<float, 3>; using Normal = OpenMesh::glmvec<float, 3>; - using Color = OpenMesh::glmvec<float, 4>; + using Color = glm::vec4; }; struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTraits> { diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp index d2977a7..b2a2cf7 100644 --- a/assetFactory/style.cpp +++ b/assetFactory/style.cpp @@ -1,41 +1,16 @@ #include "style.h" #include "assetFactory.h" -ModelFactoryMesh::Color -Style::parseColour(const std::string_view & in) -{ - if (in.empty()) { - throw std::runtime_error("Empty colour specification"); - } - if (in[0] == '#') { - if (in.length() > 9 || in.length() % 2 == 0) { - throw std::runtime_error("Invalid hex colour specification"); - } - ModelFactoryMesh::Color out {0, 0, 0, 1}; - std::generate_n(out.begin(), (in.length() - 1) / 2, [in = in.data() + 1]() mutable { - uint8_t channel; - std::from_chars(in, in + 2, channel, 16); - in += 2; - return static_cast<float>(channel) / 256.F; - }); - return out; - } - if (auto mf = std::dynamic_pointer_cast<const AssetFactory>(Persistence::sharedObjects.at("assetFactory"))) { - if (const auto colour = mf->colours.find(in); colour != mf->colours.end()) { - const auto out = glm::vec3 {colour->second} / 256.F; - return {out.r, out.g, out.b, 1.f}; - } - } - throw std::runtime_error("No such asset factory colour"); -} - void Style::applyStyle(ModelFactoryMesh & mesh, const StyleStack & parents, const Shape::CreatedFaces & faces) const { - if (const auto effectiveColour = getProperty(parents, &Style::colour); !effectiveColour.empty()) { - const auto parsedColour = parseColour(effectiveColour); + if (const auto effectiveColour = getProperty(parents, &Style::colour, + [](auto && style) { + return style->colour.a > 0; + }); + effectiveColour.has_value()) { for (const auto & face : faces) { - mesh.set_color(face.second, parsedColour); + mesh.set_color(face.second, effectiveColour->get()); } } } @@ -43,27 +18,30 @@ Style::applyStyle(ModelFactoryMesh & mesh, const StyleStack & parents, const Sha void Style::applyStyle(ModelFactoryMesh & mesh, const StyleStack & parents, const ModelFactoryMesh::FaceHandle & face) const { - if (const auto effectiveColour = getProperty(parents, &Style::colour); !effectiveColour.empty()) { - const auto parsedColour = parseColour(effectiveColour); - mesh.set_color(face, parsedColour); - } -} - -std::string_view -Style::getProperty(const StyleStack & parents, std::string Style::*member) -{ - if (const auto itr = std::find_if(parents.rbegin(), parents.rend(), - [&member](auto && s) { - return !(s->*member).empty(); + if (const auto effectiveColour = getProperty(parents, &Style::colour, + [](auto && style) { + return style->colour.a > 0; }); - itr != parents.rend()) { - return (*itr)->*member; + effectiveColour.has_value()) { + mesh.set_color(face, effectiveColour->get()); } - return {}; } bool Style::persist(Persistence::PersistenceStore & store) { - return STORE_MEMBER(colour); + struct ColourParser : public Persistence::SelectionV<ColourAlpha> { + using Persistence::SelectionV<ColourAlpha>::SelectionV; + using Persistence::SelectionV<ColourAlpha>::setValue; + void + setValue(std::string && str) override + { + if (auto mf + = std::dynamic_pointer_cast<const AssetFactory>(Persistence::sharedObjects.at("assetFactory"))) { + v = mf->parseColour(str); + } + } + }; + + return STORE_HELPER(colour, ColourParser); } diff --git a/assetFactory/style.h b/assetFactory/style.h index 0c7ad5a..e8fd012 100644 --- a/assetFactory/style.h +++ b/assetFactory/style.h @@ -3,19 +3,31 @@ #include "modelFactoryMesh.h" #include "persistence.h" #include "shape.h" +#include <optional> #include <string> +#include <utility> class Style { public: using StyleStack = std::vector<const Style *>; + using Colour = glm::vec3; + using ColourAlpha = glm::vec4; - static ModelFactoryMesh::Color parseColour(const std::string_view &); void applyStyle(ModelFactoryMesh &, const StyleStack & parents, const Shape::CreatedFaces &) const; void applyStyle(ModelFactoryMesh &, const StyleStack & parents, const ModelFactoryMesh::FaceHandle &) const; - static std::string_view getProperty(const StyleStack & parents, std::string Style::*member); + template<typename T> + static std::optional<std::reference_wrapper<const T>> + getProperty(const StyleStack & parents, T Style::*member, auto && test) + { + if (const auto itr = std::find_if(parents.rbegin(), parents.rend(), std::forward<decltype(test)>(test)); + itr != parents.rend()) { + return (*itr)->*member; + } + return {}; + } - std::string colour; + ColourAlpha colour {}; protected: bool persist(Persistence::PersistenceStore & store); diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp index a6fac5c..53fc9b9 100644 --- a/assetFactory/use.cpp +++ b/assetFactory/use.cpp @@ -18,7 +18,8 @@ struct Lookup : public Persistence::SelectionV<Shape::CPtr> { void setValue(std::string && str) override { - if (auto mf = std::dynamic_pointer_cast<const AssetFactory>(Persistence::sharedObjects.at("assetFactory"))) { + if (auto mf = std::dynamic_pointer_cast<const AssetFactory>( + Persistence::sharedObjects.at("assetFactory"))) { v = mf->shapes.at(str); } } |