MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MeshInsertion.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "MeshAccess.hpp"
4#include "NDData.hpp"
5#include "VertexLayout.hpp"
6
7namespace MayaFlux::Kakshya {
8
9/**
10 * @class MeshInsertion
11 * @brief Write counterpart to MeshAccess.
12 *
13 * Parallel to EigenInsertion and DataInsertion: holds mutable references to
14 * two DataVariant targets and populates them with interleaved vertex bytes and
15 * flat uint32_t index data respectively. Callers supply typed spans; the class
16 * handles memcpy into the canonical storage and constructs the VertexLayout.
17 *
18 * Submesh structure is recorded as a RegionGroup whose Regions map to the
19 * index sub-ranges of each submitted batch. Callers accumulate batches via
20 * insert_submesh() and then call build() to obtain a MeshAccess.
21 *
22 * The vertex DataVariant always receives vector<uint8_t> (raw bytes).
23 * The index DataVariant always receives vector<uint32_t>.
24 * Neither variant is touched until insert_submesh() or insert_flat() is called.
25 *
26 * Usage (single mesh, no submeshes):
27 * @code
28 * DataVariant vbuf, ibuf;
29 * MeshInsertion ins(vbuf, ibuf);
30 * ins.insert_flat(
31 * std::span<const uint8_t>{ raw_bytes, byte_count },
32 * std::span<const uint32_t>{ indices, index_count },
33 * VertexLayout::for_meshes(60));
34 * auto access = ins.build();
35 * @endcode
36 *
37 * Usage (multi-submesh, e.g. from assimp):
38 * @code
39 * DataVariant vbuf, ibuf;
40 * MeshInsertion ins(vbuf, ibuf);
41 * for (auto& sub : model.meshes) {
42 * ins.insert_submesh(sub.vertex_bytes, sub.indices,
43 * sub.name, sub.material_name);
44 * }
45 * auto access = ins.build();
46 * @endcode
47 */
48class MAYAFLUX_API MeshInsertion {
49public:
50 /**
51 * @brief Construct with mutable references to the two storage variants.
52 * @param vertex_variant Receives vector<uint8_t> of interleaved vertex data.
53 * @param index_variant Receives vector<uint32_t> of triangle indices.
54 */
55 MeshInsertion(DataVariant& vertex_variant, DataVariant& index_variant);
56
57 // -------------------------------------------------------------------------
58 // Write operations
59 // -------------------------------------------------------------------------
60
61 /**
62 * @brief Insert a single flat mesh (no submesh tracking).
63 *
64 * Replaces any existing content in both variants. layout must have
65 * stride_bytes > 0. vertex_bytes.size() must be a multiple of
66 * layout.stride_bytes. index_data.size() must be a multiple of 3.
67 *
68 * @param vertex_bytes Raw interleaved vertex data.
69 * @param index_data Triangle index list.
70 * @param layout Vertex attribute layout; stride_bytes must be set.
71 */
72 void insert_flat(
73 std::span<const uint8_t> vertex_bytes,
74 std::span<const uint32_t> index_data,
75 const VertexLayout& layout);
76
77 /**
78 * @brief Append one submesh batch, accumulating into the shared buffers.
79 *
80 * Vertex bytes are appended to the existing vector<uint8_t>; indices are
81 * offset by the current vertex count and appended to vector<uint32_t>.
82 * A Region is added to the internal submesh RegionGroup recording the
83 * index sub-range and names.
84 *
85 * layout is taken from the first call; subsequent calls must have the
86 * same stride_bytes and attribute count. Mismatches log an error and
87 * skip the batch.
88 *
89 * @param vertex_bytes Raw interleaved vertex data for this submesh.
90 * @param index_data Triangle indices local to this submesh (0-based).
91 * @param name Submesh name (may be empty).
92 * @param material_name Material name (may be empty).
93 * @param layout Vertex layout; ignored after first call.
94 */
95 void insert_submesh(
96 std::span<const uint8_t> vertex_bytes,
97 std::span<const uint32_t> index_data,
98 std::string_view name = {},
99 std::string_view material_name = {},
100 const VertexLayout& layout = VertexLayout::for_meshes(60));
101
102 /**
103 * @brief Clear both variants and reset all internal state.
104 */
105 void clear();
106
107 // -------------------------------------------------------------------------
108 // Finalise
109 // -------------------------------------------------------------------------
110
111 /**
112 * @brief Produce a MeshAccess over the current variant contents.
113 *
114 * Returns std::nullopt if no data has been inserted or if either variant
115 * holds the wrong type (indicates a programming error, logged as error).
116 * The returned MeshAccess borrows from the two DataVariant references held
117 * by this object; both must remain alive while the MeshAccess is in use.
118 */
119 [[nodiscard]] std::optional<MeshAccess> build() const;
120
121private:
124
126 bool m_layout_set = false;
127 uint32_t m_vertex_count = 0; ///< Running total across all submitted batches
128 uint32_t m_index_count = 0;
129
130 std::optional<RegionGroup> m_submeshes;
131
132 void ensure_vertex_storage();
133 void ensure_index_storage();
134
135 [[nodiscard]] bool validate_layout(const VertexLayout& incoming) const;
136};
137
138} // namespace MayaFlux::Kakshya
std::optional< RegionGroup > m_submeshes
Write counterpart to MeshAccess.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:76
Complete description of vertex data layout in a buffer.