From 6b346947844ebfc1984ecde276472c23b8883379 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Mon, 12 Oct 2020 21:57:18 -0400 Subject: [PATCH] Replace Primitive vector with Eigen matrices. template Prims = Eigen::Matrix Replaces std::vector> --- vis/include/cgl/buffer.hpp | 6 ++- vis/include/geometry.hpp | 35 ++----------- vis/include/rendering.hpp | 7 +-- vis/include/solver.hpp | 105 +++++++++++++++++-------------------- vis/src/main.cpp | 7 ++- 5 files changed, 65 insertions(+), 95 deletions(-) diff --git a/vis/include/cgl/buffer.hpp b/vis/include/cgl/buffer.hpp index f2d7e8b..de18bc1 100644 --- a/vis/include/cgl/buffer.hpp +++ b/vis/include/cgl/buffer.hpp @@ -54,7 +54,11 @@ namespace cgl { } void put(const std::vector &data, GLenum usage = GL_STATIC_DRAW) { - glNamedBufferData(id, sizeof(T) * data.size(), &data[0], usage); + put(&data[0], data.size(), usage); + } + + void put(const T *data, const size_t &size, GLenum usage = GL_STATIC_DRAW) { + glNamedBufferData(id, sizeof(T) * size, data, usage); } void bound(GLenum target, const std::function &action) const { diff --git a/vis/include/geometry.hpp b/vis/include/geometry.hpp index 808ad2d..a4ced1c 100644 --- a/vis/include/geometry.hpp +++ b/vis/include/geometry.hpp @@ -7,6 +7,9 @@ #include #include "combo_iterator.hpp" +template +using Prims = Eigen::Matrix; + template using vec = Eigen::Matrix; template @@ -33,35 +36,3 @@ mat4 ortho(float left, float right, float bottom, float top, float front, float 0, 0, 0, 1; return res; } - -/** - * An primitive stage N indices. - * @tparam N - */ -template -struct Primitive { - static_assert(N > 0, "Primitives must contain at least one point. Primitive<0> or lower is impossible."); - - std::array inds; - - Primitive() = default; - - Primitive(const Primitive &) = default; - - Primitive(const Primitive &sub, unsigned root) { - std::copy(sub.inds.begin(), sub.inds.end(), inds.begin()); - inds[N - 1] = root; - } - - explicit Primitive(const std::vector &values) { - std::copy(values.begin(), values.begin() + N, inds.begin()); - } - - ~Primitive() = default; - - void apply(const tc::Cosets &table, int gen) { - for (auto &ind : inds) { - ind = table.get(ind, gen); - } - } -}; diff --git a/vis/include/rendering.hpp b/vis/include/rendering.hpp index 3e0fa17..090238d 100644 --- a/vis/include/rendering.hpp +++ b/vis/include/rendering.hpp @@ -38,17 +38,18 @@ private: const tc::Group group; public: - cgl::Buffer> ibo; + cgl::Buffer ibo; cgl::Buffer vbo; cgl::VertexArray vao; template Slice(const tc::Group &g, T all_sg_gens, const std::vector> &exclude) : group(g) { - ibo.put(merge(hull(g, all_sg_gens, exclude))); + const Prims &data = merge(hull(g, all_sg_gens, exclude)); + ibo.put(data.data(), data.size()); vao.ipointer(0, ibo, 4, GL_UNSIGNED_INT); } - void setPoints(const vec5 &root, mat5 transform = mat5::Identity()) { + void setPoints(const vec5 &root, const mat5 &transform = mat5::Identity()) { auto cosets = group.solve(); auto mirrors = mirror<5>(group); diff --git a/vis/include/solver.hpp b/vis/include/solver.hpp index 0d01288..d8afb92 100644 --- a/vis/include/solver.hpp +++ b/vis/include/solver.hpp @@ -60,11 +60,11 @@ tc::Cosets solve( * Apply some context transformation to all primitives of this mesh. */ template -std::vector> apply(std::vector> prims, const tc::Cosets &table, int gen) { - for (auto &prim : prims) { - prim.apply(table, gen); +void apply(const tc::Cosets &table, int gen, Prims &mat) { + auto data = mat.data(); + for (int i = 0; i < mat.size(); ++i) { + data[i] = table.get(data[i], gen); } - return prims; } /** @@ -72,8 +72,8 @@ std::vector> apply(std::vector> prims, const tc::Coset */ template [[nodiscard]] -std::vector> recontext( - std::vector> prims, +Prims recontext( + Prims prims, const tc::Group &context, const std::vector &g_gens, const std::vector &sg_gens @@ -86,11 +86,10 @@ std::vector> recontext( return table.get(coset, gen); }); - std::vector> res(prims); - for (Primitive &prim : res) { - for (auto &ind : prim.inds) { - ind = map[ind]; - } + Prims res(prims); + auto data = res.data(); + for (int i = 0; i < prims.size(); ++i) { + data[i] = map[data[i]]; } return res; @@ -100,16 +99,18 @@ std::vector> recontext( * Union several meshes of the same dimension */ template -std::vector> merge(const std::vector>> &meshes) { - size_t size = 0; +Prims merge(const std::vector> &meshes) { + size_t cols = 0; for (const auto &mesh : meshes) { - size += mesh.size(); + cols += mesh.cols(); } - std::vector> res; - res.reserve(size); - for (const auto &mesh : meshes) { - res.insert(res.end(), mesh.begin(), mesh.end()); + Prims res(N, cols); + + size_t offset = 0; + for (const Prims &mesh : meshes) { + res.middleCols(offset, mesh.cols()) = mesh; + offset += mesh.cols(); } return res; @@ -117,52 +118,42 @@ std::vector> merge(const std::vector>> &me template [[nodiscard]] -std::vector>> each_tile( - std::vector> prims, +std::vector> tile( + Prims prims, const tc::Group &context, const std::vector &g_gens, const std::vector &sg_gens ) { - std::vector> base = recontext(prims, context, g_gens, sg_gens); + Prims base = recontext(prims, context, g_gens, sg_gens); const auto proper_sg_gens = recontext_gens(context, g_gens, sg_gens); const auto table = solve(context, g_gens, {}); const auto path = solve(context, g_gens, sg_gens).path; - auto _gens = generators(context); + std::vector _gens = generators(context); - auto res = path.walk>, int>(base, generators(context), [&](auto from, auto gen) { - return apply(from, table, gen); - }); + std::vector> res = path.walk, int>( + base, _gens, + [&](Prims from, int gen) { + apply(table, gen, from); + return from; + } + ); return res; } -template -[[nodiscard]] -std::vector> tile( - std::vector> prims, - const tc::Group &context, - const std::vector &g_gens, - const std::vector &sg_gens -) { - auto res = each_tile(prims, context, g_gens, sg_gens); - - return merge(res); -} - /** * Produce a mesh of higher dimension by fanning a single point to all primitives in this mesh. */ template [[nodiscard]] -std::vector> fan(std::vector> prims, int root) { - std::vector> res(prims.size()); - std::transform(prims.begin(), prims.end(), res.begin(), - [root](const Primitive &prim) { - return Primitive(prim, root); - } - ); +Prims fan(Prims prims, int root) { + Prims res(N + 1, prims.cols()); + + res.topRows(1) = Prims<1>::Constant(1, prims.cols(), root); + res.bottomRows(N) = prims; + return res; } @@ -170,7 +161,7 @@ std::vector> fan(std::vector> prims, int root) { * Produce a mesh of primitives that fill out the volume of the subgroup generated by generators g_gens within the group context */ template -std::vector> triangulate( +Prims triangulate( const tc::Group &context, const std::vector &g_gens ) { @@ -179,37 +170,37 @@ std::vector> triangulate( const auto &combos = Combos(g_gens, g_gens.size() - 1); - std::vector>> meshes; + std::vector> meshes; for (const auto &sg_gens : combos) { auto base = triangulate(context, sg_gens); - auto raised = tile(base, context, g_gens, sg_gens); - raised.erase(raised.begin(), raised.begin() + base.size()); - meshes.push_back(fan(raised, 0)); + auto parts = tile(base, context, g_gens, sg_gens); + parts.erase(parts.begin(), parts.begin() + 1); + auto raised = merge(parts); + auto fanned = fan(raised, 0); + meshes.push_back(fanned); } - return merge(meshes); + return merge(meshes); } /** * Single-index primitives should not be further triangulated. */ template<> -std::vector> triangulate( +Prims<1> triangulate<1>( const tc::Group &context, const std::vector &g_gens ) { if (not g_gens.empty()) // todo make static assert throw std::logic_error("g_gens must be empty for a trivial Mesh"); - std::vector> res; - res.emplace_back(); - return res; + return Prims<1>::Zero(1, 1); } template auto hull(const tc::Group &group, T all_sg_gens, const std::vector> &exclude) { - std::vector>> parts; + std::vector> parts; auto g_gens = generators(group); for (const std::vector &sg_gens : all_sg_gens) { bool excluded = false; @@ -222,7 +213,7 @@ auto hull(const tc::Group &group, T all_sg_gens, const std::vector(group, sg_gens); - const auto &tiles = each_tile(base, group, g_gens, sg_gens); + const auto &tiles = tile(base, group, g_gens, sg_gens); for (const auto &tile : tiles) { parts.push_back(tile); } diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 0ce42cb..5fc46e7 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -14,13 +14,16 @@ mat5 wander(float time) { mat5 r = mat5::Identity(); - r *= rot<5>(0, 2, time * .21f); -// r *= rot<5>(1, 4, time * .27f); + r *= rot<5>(0, 2, time * .15f); + r *= rot<5>(1, 2, time * .13f); + r *= rot<5>(0, 1, time * .20f); r *= rot<5>(0, 3, time * .17f); r *= rot<5>(1, 3, time * .25f); r *= rot<5>(2, 3, time * .12f); +// r *= rot<5>(1, 4, time * .27f); + return r; }