17 #pragma warning(disable : 4068 4146 4293)
20 #include <filament/IndexBuffer.h>
21 #include <filament/VertexBuffer.h>
22 #include <geometry/SurfaceOrientation.h>
38 namespace visualization {
40 TGaussianSplatBuffersBuilder::TGaussianSplatBuffersBuilder(
43 std::vector<std::string> check_list = {
"f_dc",
"opacity",
"rot",
"scale",
45 for (
const auto& check_item : check_list) {
52 "Tensor gaussian splat {} must have DType of Float32 not "
55 check_item, check_item_instance.GetDtype().ToString());
68 const size_t n_vertices =
points.GetLength();
73 "Rendering for Gaussian splats with SH degrees higher than 2 "
74 "is not supported. They are processed as SH degree 2.");
78 int f_rest_coeffs_count = sh_degree * (sh_degree + 2) * 3;
79 int f_rest_buffer_count = (f_rest_coeffs_count % 4 == 0)
80 ? (f_rest_coeffs_count / 4)
83 int base_buffer_count = 5;
84 int all_buffer_count = base_buffer_count + f_rest_buffer_count;
88 VertexBuffer::Builder buffer_builder =
89 VertexBuffer::Builder()
90 .bufferCount(all_buffer_count)
91 .vertexCount(uint32_t(n_vertices))
92 .attribute(VertexAttribute::POSITION, 0,
93 VertexBuffer::AttributeType::FLOAT3)
94 .attribute(VertexAttribute::COLOR, 1,
95 VertexBuffer::AttributeType::FLOAT4)
96 .attribute(VertexAttribute::TANGENTS, 2,
97 VertexBuffer::AttributeType::FLOAT)
98 .attribute(VertexAttribute::CUSTOM0, 3,
99 VertexBuffer::AttributeType::FLOAT4)
100 .attribute(VertexAttribute::CUSTOM7, 4,
101 VertexBuffer::AttributeType::FLOAT4);
102 if (sh_degree >= 1) {
103 buffer_builder.attribute(VertexAttribute::CUSTOM1, 5,
104 VertexBuffer::AttributeType::FLOAT4);
105 buffer_builder.attribute(VertexAttribute::CUSTOM2, 6,
106 VertexBuffer::AttributeType::FLOAT4);
107 buffer_builder.attribute(VertexAttribute::CUSTOM3, 7,
108 VertexBuffer::AttributeType::FLOAT4);
110 if (sh_degree == 2) {
111 buffer_builder.attribute(VertexAttribute::CUSTOM4, 8,
112 VertexBuffer::AttributeType::FLOAT4);
113 buffer_builder.attribute(VertexAttribute::CUSTOM5, 9,
114 VertexBuffer::AttributeType::FLOAT4);
115 buffer_builder.attribute(VertexAttribute::CUSTOM6, 10,
116 VertexBuffer::AttributeType::FLOAT4);
123 vb_handle = resource_mgr.AddVertexBuffer(vbuf);
128 const size_t vertex_array_size = n_vertices * 3 *
sizeof(float);
129 float* vertex_array =
static_cast<float*
>(malloc(vertex_array_size));
130 memcpy(vertex_array,
points.GetDataPtr(), vertex_array_size);
131 VertexBuffer::BufferDescriptor pts_descriptor(
132 vertex_array, vertex_array_size,
134 vbuf->setBufferAt(engine, 0, std::move(pts_descriptor));
136 const size_t scale_array_size = n_vertices * 4 *
sizeof(float);
137 float* scale_array =
static_cast<float*
>(malloc(scale_array_size));
138 std::memset(scale_array, 0, scale_array_size);
140 for (
size_t i = 0; i < n_vertices; i++) {
141 std::memcpy(scale_array + i * 4, scale_src + i * 3, 3 *
sizeof(
float));
143 VertexBuffer::BufferDescriptor scale_descriptor(
144 scale_array, scale_array_size,
146 vbuf->setBufferAt(engine, 1, std::move(scale_descriptor));
150 const size_t empty_array_size = n_vertices *
sizeof(float);
151 float* empty_array =
static_cast<float*
>(malloc(empty_array_size));
152 std::memset(empty_array, 0, empty_array_size);
153 VertexBuffer::BufferDescriptor empty_descriptor(
154 empty_array, empty_array_size,
156 vbuf->setBufferAt(engine, 2, std::move(empty_descriptor));
158 const size_t color_array_size = n_vertices * 4 *
sizeof(float);
159 float* color_array =
static_cast<float*
>(malloc(color_array_size));
162 for (
size_t i = 0; i < n_vertices; i++) {
163 std::memcpy(color_array + i * 4, f_dc_ptr + i * 3, 3 *
sizeof(
float));
164 std::memcpy(color_array + i * 4 + 3, opacity_ptr + i,
sizeof(
float));
166 VertexBuffer::BufferDescriptor color_descriptor(
167 color_array, color_array_size,
169 vbuf->setBufferAt(engine, 3, std::move(color_descriptor));
171 const size_t rot_array_size = n_vertices * 4 *
sizeof(float);
172 float* rot_array =
static_cast<float*
>(malloc(rot_array_size));
175 VertexBuffer::BufferDescriptor rot_descriptor(
176 rot_array, rot_array_size,
178 vbuf->setBufferAt(engine, 4, std::move(rot_descriptor));
180 int data_count_in_one_buffer = 4;
181 const size_t f_rest_array_size =
182 n_vertices * data_count_in_one_buffer *
sizeof(float);
183 const size_t custom_buffer_start_index = 5;
185 (f_rest_buffer_count > 0)
188 for (
int i = 0; i < f_rest_buffer_count; i++) {
189 float* f_rest_array =
static_cast<float*
>(malloc(f_rest_array_size));
191 size_t copy_data_size = f_rest_array_size;
192 if (i == f_rest_buffer_count - 1) {
193 int remaining_count_in_last_iter =
194 data_count_in_one_buffer +
195 (f_rest_coeffs_count -
196 f_rest_buffer_count * data_count_in_one_buffer);
198 n_vertices * remaining_count_in_last_iter *
sizeof(float);
199 std::memset(f_rest_array, 0, f_rest_array_size);
202 std::memcpy(f_rest_array,
203 f_rest_src + i * n_vertices * data_count_in_one_buffer,
205 VertexBuffer::BufferDescriptor f_rest_descriptor(
206 f_rest_array, f_rest_array_size,
208 vbuf->setBufferAt(engine, custom_buffer_start_index + i,
209 std::move(f_rest_descriptor));
220 return std::make_tuple(vb_handle, ib_handle, downsampled_handle);
A point cloud contains a list of 3D points.
int GaussianSplatGetSHOrder() const
Returns the order of spherical harmonics used for Gaussian Splatting. Returns 0 if f_rest is not pres...
bool HasPointAttr(const std::string &key) const
core::Tensor & GetPointPositions()
Get the value of the "positions" attribute. Convenience function.
const TensorMap & GetPointAttr() const
Getter for point_attr_ TensorMap. Used in Pybind.
static filament::Engine & GetInstance()
static FilamentResourceManager & GetResourceManager()
size_t downsample_threshold_
static IndexBufferHandle CreateIndexBuffer(size_t max_index, size_t n_subsamples=SIZE_MAX)
static void DeallocateBuffer(void *buffer, size_t size, void *user_ptr)
std::tuple< VertexBufferHandle, IndexBufferHandle, IndexBufferHandle > Buffers
Buffers ConstructBuffers() override
Constructs vertex and index buffers for Gaussian Splat rendering.
t::geometry::PointCloud geometry_
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Generic file read and write utility for python interface.