17 #pragma warning(disable : 4068 4146 4293)
20 #include <filament/IndexBuffer.h>
21 #include <filament/VertexBuffer.h>
22 #include <geometry/SurfaceOrientation.h>
39 namespace visualization {
43 struct ColoredVertex {
49 math::float4
color = {0.5f, 0.5f, 0.5f, 1.f};
50 math::quatf
tangent = {0.f, 0.f, 0.f, 1.f};
51 math::float2
uv = {0.f, 0.f};
53 static std::uint32_t GetPositionOffset() {
56 static std::uint32_t GetColorOffset() {
59 static std::uint32_t GetTangentOffset() {
62 static std::uint32_t GetUVOffset() {
return offsetof(ColoredVertex,
uv); }
63 void SetVertexPosition(
const Eigen::Vector3d& pos) {
64 auto float_pos = pos.cast<
float>();
70 float sRGBToLinear(
float color) {
72 : pow((
color + 0.055f) / 1.055f, 2.4f);
75 void SetVertexColor(
const Eigen::Vector3d& c,
bool adjust_for_srgb) {
76 auto float_color = c.cast<
float>();
77 if (adjust_for_srgb) {
78 color.x = sRGBToLinear(float_color(0));
79 color.y = sRGBToLinear(float_color(1));
80 color.z = sRGBToLinear(float_color(2));
82 color.x = float_color(0);
83 color.y = float_color(1);
84 color.z = float_color(2);
91 size_t max_index,
size_t n_subsamples ) {
94 auto& resource_mgr = EngineInstance::GetResourceManager();
96 size_t n_indices =
std::min(max_index, n_subsamples);
100 double step = double(max_index) / double(n_indices);
102 const size_t n_bytes = n_indices *
sizeof(
IndexType);
103 auto* uint_indices =
static_cast<IndexType*
>(malloc(n_bytes));
108 std::iota(uint_indices, uint_indices + n_indices, 0);
110 for (
size_t i = 0; i < n_indices; ++i) {
115 uint_indices[idx++] = 0;
118 for (i = 1; i < max_index; ++i) {
122 if (idx > n_indices) {
130 if (i < max_index - 1) {
136 resource_mgr.CreateIndexBuffer(n_indices,
sizeof(
IndexType));
142 auto ibuf = resource_mgr.GetIndexBuffer(ib_handle).lock();
146 IndexBuffer::BufferDescriptor indices_descriptor(uint_indices, n_bytes);
147 indices_descriptor.setCallback(GeometryBuffersBuilder::DeallocateBuffer);
148 ibuf->setBuffer(engine, std::move(indices_descriptor));
152 PointCloudBuffersBuilder::PointCloudBuffersBuilder(
const ccPointCloud& geometry)
153 : geometry_(geometry) {}
157 return RenderableManager::PrimitiveType::POINTS;
164 const size_t n_vertices = geometry_.
size();
172 .vertexCount(std::uint32_t(n_vertices))
173 .attribute(VertexAttribute::POSITION, 0,
174 VertexBuffer::AttributeType::FLOAT3,
175 ColoredVertex::GetPositionOffset(),
176 sizeof(ColoredVertex))
177 .normalized(VertexAttribute::COLOR)
178 .attribute(VertexAttribute::COLOR, 0,
179 VertexBuffer::AttributeType::FLOAT4,
180 ColoredVertex::GetColorOffset(),
181 sizeof(ColoredVertex))
182 .normalized(VertexAttribute::TANGENTS)
183 .attribute(VertexAttribute::TANGENTS, 0,
184 VertexBuffer::AttributeType::FLOAT4,
185 ColoredVertex::GetTangentOffset(),
186 sizeof(ColoredVertex))
187 .attribute(VertexAttribute::CUSTOM0, 0,
188 VertexBuffer::AttributeType::FLOAT4,
189 ColoredVertex::GetTangentOffset(),
190 sizeof(ColoredVertex))
191 .attribute(VertexAttribute::UV0, 0,
192 VertexBuffer::AttributeType::FLOAT2,
193 ColoredVertex::GetUVOffset(),
194 sizeof(ColoredVertex))
199 vb_handle = resource_mgr.AddVertexBuffer(vbuf);
204 math::quatf* float4v_tagents =
nullptr;
207 std::vector<Eigen::Vector3f>
normals;
209 for (
size_t i = 0; i < n_vertices; ++i) {
214 const size_t tangents_byte_count = n_vertices * 4 *
sizeof(float);
216 static_cast<math::quatf*
>(malloc(tangents_byte_count));
217 auto orientation = filament::geometry::SurfaceOrientation::Builder()
218 .vertexCount(n_vertices)
219 .normals(
reinterpret_cast<math::float3*
>(
222 orientation->getQuats(float4v_tagents, n_vertices);
225 const size_t vertices_byte_count = n_vertices *
sizeof(ColoredVertex);
226 auto* vertices =
static_cast<ColoredVertex*
>(malloc(vertices_byte_count));
227 const ColoredVertex kDefault;
228 for (
size_t i = 0; i < geometry_.
size(); ++i) {
229 ColoredVertex& element = vertices[i];
235 element.color = kDefault.color;
238 if (float4v_tagents) {
239 element.tangent = float4v_tagents[i];
241 element.tangent = kDefault.tangent;
243 element.uv = kDefault.uv;
246 free(float4v_tagents);
250 VertexBuffer::BufferDescriptor vb_descriptor(vertices, vertices_byte_count);
252 vbuf->setBufferAt(engine, 0, std::move(vb_descriptor));
262 return std::make_tuple(vb_handle, ib_handle, downsampled_handle);
268 const filament::math::float3
min(geometry_aabb.minCorner().x,
269 geometry_aabb.minCorner().y,
270 geometry_aabb.minCorner().z);
271 const filament::math::float3
max(geometry_aabb.maxCorner().x,
272 geometry_aabb.maxCorner().y,
273 geometry_aabb.maxCorner().z);
283 : geometry_(geometry) {
288 "GPU resident point clouds are not currently supported for "
289 "visualization. Copying data to CPU.");
296 "Tensor point cloud points must have DType of Float32 not {}. "
298 pts.GetDtype().ToString());
305 "Tensor point cloud normals must have DType of Float32 not {}. "
307 normals.GetDtype().ToString());
314 "Tensor point cloud colors must have DType of Float32 not {}. "
316 colors.GetDtype().ToString());
326 return RenderableManager::PrimitiveType::POINTS;
334 const size_t n_vertices =
points.GetLength();
342 .vertexCount(uint32_t(n_vertices))
343 .attribute(VertexAttribute::POSITION, 0,
344 VertexBuffer::AttributeType::FLOAT3)
345 .normalized(VertexAttribute::COLOR)
346 .attribute(VertexAttribute::COLOR, 1,
347 VertexBuffer::AttributeType::FLOAT3)
348 .normalized(VertexAttribute::TANGENTS)
349 .attribute(VertexAttribute::TANGENTS, 2,
350 VertexBuffer::AttributeType::FLOAT4)
351 .attribute(VertexAttribute::CUSTOM0, 2,
352 VertexBuffer::AttributeType::FLOAT4)
353 .attribute(VertexAttribute::UV0, 3,
354 VertexBuffer::AttributeType::FLOAT2)
359 vb_handle = resource_mgr.AddVertexBuffer(vbuf);
364 const size_t vertex_array_size = n_vertices * 3 *
sizeof(float);
365 float* vertex_array =
static_cast<float*
>(malloc(vertex_array_size));
366 memcpy(vertex_array,
points.GetDataPtr(), vertex_array_size);
367 VertexBuffer::BufferDescriptor pts_descriptor(
368 vertex_array, vertex_array_size,
370 vbuf->setBufferAt(engine, 0, std::move(pts_descriptor));
372 const size_t color_array_size = n_vertices * 3 *
sizeof(float);
374 float* color_array =
static_cast<float*
>(malloc(color_array_size));
377 VertexBuffer::BufferDescriptor color_descriptor(
378 color_array, color_array_size,
380 vbuf->setBufferAt(engine, 1, std::move(color_descriptor));
382 float* color_array =
static_cast<float*
>(malloc(color_array_size));
383 for (
size_t i = 0; i < n_vertices * 3; ++i) {
384 color_array[i] = 1.f;
386 VertexBuffer::BufferDescriptor color_descriptor(
387 color_array, color_array_size,
389 vbuf->setBufferAt(engine, 1, std::move(color_descriptor));
392 const size_t normal_array_size = n_vertices * 4 *
sizeof(float);
397 auto float4v_tangents =
398 static_cast<math::quatf*
>(malloc(normal_array_size));
400 filament::geometry::SurfaceOrientation::Builder()
401 .vertexCount(n_vertices)
402 .normals(
reinterpret_cast<const math::float3*
>(
405 orientation->getQuats(float4v_tangents, n_vertices);
406 VertexBuffer::BufferDescriptor normals_descriptor(
407 float4v_tangents, normal_array_size,
409 vbuf->setBufferAt(engine, 2, std::move(normals_descriptor));
412 float* normal_array =
static_cast<float*
>(malloc(normal_array_size));
413 float* normal_ptr = normal_array;
414 for (
size_t i = 0; i < n_vertices; ++i) {
420 VertexBuffer::BufferDescriptor normals_descriptor(
421 normal_array, normal_array_size,
423 vbuf->setBufferAt(engine, 2, std::move(normals_descriptor));
426 const size_t uv_array_size = n_vertices * 2 *
sizeof(float);
427 float* uv_array =
static_cast<float*
>(malloc(uv_array_size));
429 const float* uv_src =
431 memcpy(uv_array, uv_src, uv_array_size);
434 memset(uv_array, 0, uv_array_size);
437 const float* src = vis_scalars.GetDataPtr<
const float>();
438 const size_t n = 2 * n_vertices;
439 for (
size_t i = 0; i < n; i += 2) {
440 uv_array[i] = *src++;
443 memset(uv_array, 0, uv_array_size);
445 VertexBuffer::BufferDescriptor uv_descriptor(
447 vbuf->setBufferAt(engine, 3, std::move(uv_descriptor));
457 return std::make_tuple(vb_handle, ib_handle, downsampled_handle);
463 auto* min_bounds_float = min_bounds.
GetDataPtr<
float>();
464 auto* max_bounds_float = max_bounds.GetDataPtr<
float>();
466 filament::math::float3
min(min_bounds_float[0], min_bounds_float[1],
467 min_bounds_float[2]);
468 filament::math::float3
max(max_bounds_float[0], max_bounds_float[1],
469 max_bounds_float[2]);
473 if (aabb.isEmpty()) {
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
Eigen::Vector3d getEigenNormal(size_t index) const
bool hasNormals() const override
Returns whether normals are enabled or not.
virtual ccBBox GetAxisAlignedBoundingBox() const override
Returns an axis-aligned bounding box of the geometry.
bool hasColors() const override
Returns whether colors are enabled or not.
Eigen::Vector3d getEigenColor(size_t index) const
unsigned size() const override
Eigen::Vector3d getEigenPoint(size_t index) const
Tensor To(Dtype dtype, bool copy=false) const
A point cloud contains a list of 3D points.
core::Tensor & GetPointNormals()
Get the value of the "normals" attribute. Convenience function.
bool HasPointAttr(const std::string &key) const
core::Tensor GetMaxBound() const
Returns the max bound for point coordinates.
core::Tensor GetMinBound() const
Returns the min bound for point coordinates.
core::Tensor & GetPointPositions()
Get the value of the "positions" attribute. Convenience function.
PointCloud To(const core::Device &device, bool copy=false) const
bool HasPointNormals() const
const TensorMap & GetPointAttr() const
Getter for point_attr_ TensorMap. Used in Pybind.
core::Tensor & GetPointColors()
Get the value of the "colors" attribute. Convenience function.
bool HasPointColors() const
TensorMap Contiguous() const
static filament::Engine & GetInstance()
static FilamentResourceManager & GetResourceManager()
bool adjust_colors_for_srgb_tonemapping_
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
filament::RenderableManager::PrimitiveType GetPrimitiveType() const override
filament::Box ComputeAABB() override
Buffers ConstructBuffers() override
filament::RenderableManager::PrimitiveType GetPrimitiveType() const override
TPointCloudBuffersBuilder(const t::geometry::PointCloud &geometry)
Buffers ConstructBuffers() override
filament::Box ComputeAABB() override
t::geometry::PointCloud geometry_
static double dist(double x1, double y1, double x2, double y2)
ccGuiPythonInstance * GetInstance() noexcept
MiniVec< float, N > floor(const MiniVec< float, N > &a)
REHandle< EntityType::IndexBuffer > IndexBufferHandle
Generic file read and write utility for python interface.
#define offsetof(STRUCTURE, FIELD)