From 6b24956d67569870f2a046386be11080d867d22c Mon Sep 17 00:00:00 2001 From: Roderick Kennedy Date: Tue, 18 Jul 2023 22:02:17 +0100 Subject: [PATCH 1/3] Implemented LoadTextBuffer, DecodeFromTextBuffer, and DecodeFromTextBufferToScene to add missing GLTF text format functionality (i.e. load from memory). --- src/draco/io/gltf_decoder.cc | 30 ++++++++++++++++++++++++++++++ src/draco/io/gltf_decoder.h | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/src/draco/io/gltf_decoder.cc b/src/draco/io/gltf_decoder.cc index 521b7524..f93738e7 100644 --- a/src/draco/io/gltf_decoder.cc +++ b/src/draco/io/gltf_decoder.cc @@ -453,6 +453,12 @@ StatusOr> GltfDecoder::DecodeFromBuffer( return BuildMesh(); } +StatusOr> GltfDecoder::DecodeFromTextBuffer( + DecoderBuffer *buffer) { + DRACO_RETURN_IF_ERROR(LoadTextBuffer(*buffer)); + return BuildMesh(); +} + StatusOr> GltfDecoder::DecodeFromFileToScene( const std::string &file_name) { return DecodeFromFileToScene(file_name, nullptr); @@ -474,6 +480,14 @@ StatusOr> GltfDecoder::DecodeFromBufferToScene( return std::move(scene_); } +StatusOr> GltfDecoder::DecodeFromTextBufferToScene( + DecoderBuffer *buffer) { + DRACO_RETURN_IF_ERROR(LoadTextBuffer(*buffer)); + scene_ = std::unique_ptr(new Scene()); + DRACO_RETURN_IF_ERROR(DecodeGltfToScene()); + return std::move(scene_); +} + Status GltfDecoder::LoadFile(const std::string &file_name, std::vector *input_files) { const std::string extension = LowercaseFileExtension(file_name); @@ -525,6 +539,22 @@ Status GltfDecoder::LoadBuffer(const DecoderBuffer &buffer) { return OkStatus(); } +Status GltfDecoder::LoadTextBuffer(const DecoderBuffer &buffer) { + tinygltf::TinyGLTF loader; + std::string err; + std::string warn; + if (!loader.LoadASCIIFromString( + &gltf_model_, &err, &warn, + reinterpret_cast(buffer.data_head()), + buffer.remaining_size(),"")) { + return Status(Status::DRACO_ERROR, + "TinyGLTF failed to load gltf buffer: " + err); + } + DRACO_RETURN_IF_ERROR(CheckUnsupportedFeatures()); + input_file_name_.clear(); + return OkStatus(); +} + StatusOr> GltfDecoder::BuildMesh() { DRACO_RETURN_IF_ERROR(GatherAttributeAndMaterialStats()); if (total_face_indices_count_ > 0 && total_point_indices_count_ > 0) { diff --git a/src/draco/io/gltf_decoder.h b/src/draco/io/gltf_decoder.h index 2ae12106..e33b3bba 100644 --- a/src/draco/io/gltf_decoder.h +++ b/src/draco/io/gltf_decoder.h @@ -49,6 +49,7 @@ class GltfDecoder { StatusOr> DecodeFromFile( const std::string &file_name, std::vector *mesh_files); StatusOr> DecodeFromBuffer(DecoderBuffer *buffer); + StatusOr> DecodeFromTextBuffer(DecoderBuffer *buffer); // Decodes a glTF file stored in the input |file_name| or |buffer| to a Scene. // The second form returns a vector of files used as input to the scene during @@ -59,6 +60,8 @@ class GltfDecoder { const std::string &file_name, std::vector *scene_files); StatusOr> DecodeFromBufferToScene( DecoderBuffer *buffer); + StatusOr> DecodeFromTextBufferToScene( + DecoderBuffer *buffer); // Scene graph can be loaded either as a tree or a general directed acyclic // graph (DAG) that allows multiple parent nodes. By default. we decode the @@ -80,6 +83,9 @@ class GltfDecoder { // Loads |gltf_model_| from |buffer| in GLB format. Status LoadBuffer(const DecoderBuffer &buffer); + // Loads |gltf_model_| from |buffer| in GLTF format. + Status LoadTextBuffer(const DecoderBuffer &buffer); + // Builds mesh from |gltf_model_|. StatusOr> BuildMesh(); From fb548277e2c7a031f3e83dd94644fb594dc91278 Mon Sep 17 00:00:00 2001 From: Roderick Kennedy Date: Mon, 23 Oct 2023 20:05:10 +0100 Subject: [PATCH 2/3] tiny_gltf pointer. --- third_party/tinygltf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/tinygltf b/third_party/tinygltf index a11f6e19..52b73c7f 160000 --- a/third_party/tinygltf +++ b/third_party/tinygltf @@ -1 +1 @@ -Subproject commit a11f6e19399f6af67d7c57909e8ce99d20beb369 +Subproject commit 52b73c7f0b41c54cc7f28cbf62598e6ca7d8e255 From dfe02d4e56aebb67edc6088259a829490497a502 Mon Sep 17 00:00:00 2001 From: Roderick Kennedy Date: Fri, 26 Jul 2024 20:25:29 +0100 Subject: [PATCH 3/3] Fix compilation warnings. --- src/draco/attributes/geometry_attribute.h | 4 ++-- src/draco/compression/entropy/symbol_encoding.cc | 8 +++++++- src/draco/core/bit_utils.cc | 6 +++++- src/draco/core/bit_utils.h | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/draco/attributes/geometry_attribute.h b/src/draco/attributes/geometry_attribute.h index 734bd73e..464bde00 100644 --- a/src/draco/attributes/geometry_attribute.h +++ b/src/draco/attributes/geometry_attribute.h @@ -43,8 +43,8 @@ namespace draco { class GeometryAttribute { public: // Supported attribute types. - enum Type { - INVALID = -1, + enum Type :uint8_t{ + INVALID = 0xFF, // Named attributes start here. The difference between named and generic // attributes is that for named attributes we know their purpose and we // can apply some special methods when dealing with them (e.g. during diff --git a/src/draco/compression/entropy/symbol_encoding.cc b/src/draco/compression/entropy/symbol_encoding.cc index 710c9628..4f0d76ca 100644 --- a/src/draco/compression/entropy/symbol_encoding.cc +++ b/src/draco/compression/entropy/symbol_encoding.cc @@ -59,6 +59,9 @@ static void ComputeBitLengths(const uint32_t *symbols, int num_values, for (int j = 1; j < num_components; ++j) { if (max_component_value < symbols[i + j]) { max_component_value = symbols[i + j]; + if (max_component_value == 0xFFFFFFFF) { + throw std::runtime_error("Failure in ComputeBitLengths."); + } } } int value_msb_pos = 0; @@ -128,7 +131,10 @@ bool EncodeSymbols(const uint32_t *symbols, int num_values, int num_components, uint32_t max_value; ComputeBitLengths(symbols, num_values, num_components, &bit_lengths, &max_value); - + if(max_value==0xFFFFFFFF) + { + throw std::runtime_error("Failure in ComputeBitLengths."); + } // Approximate number of bits needed for storing the symbols using the tagged // scheme. const int64_t tagged_scheme_total_bits = diff --git a/src/draco/core/bit_utils.cc b/src/draco/core/bit_utils.cc index 37119a71..60825f9e 100644 --- a/src/draco/core/bit_utils.cc +++ b/src/draco/core/bit_utils.cc @@ -13,7 +13,8 @@ // limitations under the License. // #include "draco/core/bit_utils.h" - +#include + namespace draco { void ConvertSignedIntsToSymbols(const int32_t *in, int in_values, @@ -23,6 +24,9 @@ void ConvertSignedIntsToSymbols(const int32_t *in, int in_values, // Put the sign bit into LSB pos and shift the rest one bit left. for (int i = 0; i < in_values; ++i) { out[i] = ConvertSignedIntToSymbol(in[i]); + if (out[i] == 0xFFFFFFFF) { + throw std::runtime_error("Failure in ConvertSignedIntsToSymbols."); + } } } diff --git a/src/draco/core/bit_utils.h b/src/draco/core/bit_utils.h index a102095c..66dd0c9c 100644 --- a/src/draco/core/bit_utils.h +++ b/src/draco/core/bit_utils.h @@ -78,7 +78,7 @@ inline int MostSignificantBit(uint32_t n) { // symbols that can be encoded using an entropy encoder. void ConvertSignedIntsToSymbols(const int32_t *in, int in_values, uint32_t *out); - +#pragma optimize("",off) // Converts unsigned integer symbols encoded with an entropy encoder back to // signed values. void ConvertSymbolsToSignedInts(const uint32_t *in, int in_values,