Git Product home page Git Product logo

google / draco Goto Github PK

View Code? Open in Web Editor NEW
6.2K 219.0 939.0 220.2 MB

Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.

Home Page: https://google.github.io/draco/

License: Apache License 2.0

CMake 4.82% C++ 92.05% C 0.04% JavaScript 1.31% HTML 0.53% C# 0.57% Python 0.64% Shell 0.04%
point-cloud 3d-graphics compression mesh

draco's Introduction

draco-ci

News

Attention GStatic users: the Draco team strongly recommends using the versioned URLs for accessing Draco GStatic content. If you are using the URLs that include the v1/decoders substring within the URL, edge caching and GStatic propagation delays can result in transient errors that can be difficult to diagnose when new Draco releases are launched. To avoid the issue pin your sites to a versioned release.

Version 1.5.7 release:

Version 1.5.6 release:

  • Using the versioned www.gstatic.com WASM and Javascript decoders continues to be recommended. To use v1.5.6, use this URL:
  • The CMake flag DRACO_DEBUG_MSVC_WARNINGS has been replaced with DRACO_DEBUG_COMPILER_WARNINGS, and the behavior has changed. It is now a boolean flag defined in draco_options.cmake.
  • Bug fixes.
  • Security fixes.

Version 1.5.5 release:

Version 1.5.4 release:

Version 1.5.3 release:

Version 1.5.2 release

  • This is the same as v1.5.1 with the following two bug fixes:
    • Fixes DRACO_TRANSCODER_SUPPORTED enabled builds.
    • ABI version updated.

Version 1.5.1 release

  • Adds assertion enabled Emscripten builds to the release, and a subset of the assertion enabled builds to GStatic. See the file listing below.
  • Custom paths to third party dependencies are now supported. See BUILDING.md for more information.
  • The CMake configuration file draco-config.cmake is now tested and known to work for using Draco in Linux, MacOS, and Windows CMake projects. See the install_test subdirectory of src/draco/tools for more information.
  • Bug fixes.

Version 1.5.0 release

  • Adds the draco_transcoder tool. See the section below on the glTF transcoding tool, and BUILDING.md for build and dependency information.
  • Some changes to configuration variables have been made for this release:
    • The DRACO_GLTF flag has been renamed to DRACO_GLTF_BITSTREAM to help increase understanding of its purpose, which is to limit Draco features to those included in the Draco glTF specification.
    • Variables exported in CMake via draco-config.cmake and find-draco.cmake (formerly FindDraco.cmake) have been renamed. It's unlikely that this impacts any existing projects as the aforementioned files were not formed correctly. See PR775 for full details of the changes.
  • A CMake version file has been added.
  • The CMake install target now uses absolute paths direct from CMake instead of building them using CMAKE_INSTALL_PREFIX. This was done to make Draco easier to use for downstream packagers and should have little to no impact on users picking up Draco from source.
  • Certain MSVC warnings have had their levels changed via compiler flag to reduce the amount of noise output by the MSVC compilers. Set MSVC warning level to 4, or define DRACO_DEBUG_MSVC_WARNINGS at CMake configuration time to restore previous behavior.
  • Bug fixes.

Version 1.4.3 release

Version 1.4.1 release

Version 1.4.0 release

  • WASM and JavaScript decoders are hosted from a static URL.
  • Changed npm modules to use WASM, which increased performance by ~200%.
  • Updated Emscripten to 2.0.
    • This causes the Draco codec modules to return a promise instead of the module directly.
    • Please see the example code on how to handle the promise.
  • Changed NORMAL quantization default to 8.
  • Added new array API to decoder and deprecated DecoderBuffer.
    • See PR #513 for more information.
  • Changed WASM/JavaScript behavior of catching exceptions.
    • See issue #629 for more information.
  • Code cleanup.
  • Emscripten builds now disable NODEJS_CATCH_EXIT and NODEJS_CATCH_REJECTION.
    • Authors of a CLI tool might want to add their own error handlers.
  • Added Maya plugin builds.
  • Unity plugin builds updated.
  • Bug fixes.

Version 1.3.6 release

  • WASM and JavaScript decoders are now hosted from a static URL
  • Changed web examples to pull Draco decoders from static URL
  • Added new API to Draco WASM decoder, which increased performance by ~15%
  • Decreased Draco WASM decoder size by ~20%
  • Added support for generic and multiple attributes to Draco Unity plug-ins
  • Added new API to Draco Unity, which increased decoder performance by ~15%
  • Changed quantization defaults:
    • POSITION: 11
    • NORMAL: 7
    • TEX_COORD: 10
    • COLOR: 8
    • GENERIC: 8
  • Code cleanup
  • Bug fixes

Version 1.3.5 release

  • Added option to build Draco for Universal Scene Description
  • Code cleanup
  • Bug fixes

Version 1.3.4 release

  • Released Draco Animation code
  • Fixes for Unity
  • Various file location and name changes

Version 1.3.3 release

  • Added ExpertEncoder to the Javascript API
    • Allows developers to set quantization options per attribute id
  • Bug fixes

Version 1.3.2 release

  • Bug fixes

Version 1.3.1 release

  • Fix issue with multiple attributes when skipping an attribute transform

Version 1.3.0 release

  • Improved kD-tree based point cloud encoding
    • Now applicable to point clouds with any number of attributes
    • Support for all integer attribute types and quantized floating point types
  • Improved mesh compression up to 10% (on average ~2%)
    • For meshes, the 1.3.0 bitstream is fully compatible with 1.2.x decoders
  • Improved Javascript API
    • Added support for all signed and unsigned integer types
    • Added support for point clouds to our Javascript encoder API
  • Added support for integer properties to the PLY decoder
  • Bug fixes

Previous releases

https://github.com/google/draco/releases

Description

Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.

Draco was designed and built for compression efficiency and speed. The code supports compressing points, connectivity information, texture coordinates, color information, normals, and any other generic attributes associated with geometry. With Draco, applications using 3D graphics can be significantly smaller without compromising visual fidelity. For users, this means apps can now be downloaded faster, 3D graphics in the browser can load quicker, and VR and AR scenes can now be transmitted with a fraction of the bandwidth and rendered quickly.

Draco is released as C++ source code that can be used to compress 3D graphics as well as C++ and Javascript decoders for the encoded data.

Contents

Building

See BUILDING for building instructions.

Usage

Unity

For the best information about using Unity with Draco please visit https://github.com/atteneder/DracoUnity

For a simple example of using Unity with Draco see README in the unity folder.

WASM and JavaScript Decoders

It is recommended to always pull your Draco WASM and JavaScript decoders from:

https://www.gstatic.com/draco/v1/decoders/

Users will benefit from having the Draco decoder in cache as more sites start using the static URL.

Command Line Applications

The default target created from the build files will be the draco_encoder and draco_decoder command line applications. Additionally, draco_transcoder is generated when CMake is run with the DRACO_TRANSCODER_SUPPORTED variable set to ON (see BUILDING for more details). For all applications, if you run them without any arguments or -h, the applications will output usage and options.

Encoding Tool

draco_encoder will read OBJ, STL or PLY files as input, and output Draco-encoded files. We have included Stanford's Bunny mesh for testing. The basic command line looks like this:

./draco_encoder -i testdata/bun_zipper.ply -o out.drc

A value of 0 for the quantization parameter will not perform any quantization on the specified attribute. Any value other than 0 will quantize the input values for the specified attribute to that number of bits. For example:

./draco_encoder -i testdata/bun_zipper.ply -o out.drc -qp 14

will quantize the positions to 14 bits (default is 11 for the position coordinates).

In general, the more you quantize your attributes the better compression rate you will get. It is up to your project to decide how much deviation it will tolerate. In general, most projects can set quantization values of about 11 without any noticeable difference in quality.

The compression level (-cl) parameter turns on/off different compression features.

./draco_encoder -i testdata/bun_zipper.ply -o out.drc -cl 8

In general, the highest setting, 10, will have the most compression but worst decompression speed. 0 will have the least compression, but best decompression speed. The default setting is 7.

Encoding Point Clouds

You can encode point cloud data with draco_encoder by specifying the -point_cloud parameter. If you specify the -point_cloud parameter with a mesh input file, draco_encoder will ignore the connectivity data and encode the positions from the mesh file.

./draco_encoder -point_cloud -i testdata/bun_zipper.ply -o out.drc

This command line will encode the mesh input as a point cloud, even though the input might not produce compression that is representative of other point clouds. Specifically, one can expect much better compression rates for larger and denser point clouds.

Decoding Tool

draco_decoder will read Draco files as input, and output OBJ, STL or PLY files. The basic command line looks like this:

./draco_decoder -i in.drc -o out.obj

glTF Transcoding Tool

draco_transcoder can be used to add Draco compression to glTF assets. The basic command line looks like this:

./draco_transcoder -i in.glb -o out.glb

This command line will add geometry compression to all meshes in the in.glb file. Quantization values for different glTF attributes can be specified similarly to the draco_encoder tool. For example -qp can be used to define quantization of the position attribute:

./draco_transcoder -i in.glb -o out.glb -qp 12

C++ Decoder API

If you'd like to add decoding to your applications you will need to include the draco_dec library. In order to use the Draco decoder you need to initialize a DecoderBuffer with the compressed data. Then call DecodeMeshFromBuffer() to return a decoded mesh object or call DecodePointCloudFromBuffer() to return a decoded PointCloud object. For example:

draco::DecoderBuffer buffer;
buffer.Init(data.data(), data.size());

const draco::EncodedGeometryType geom_type =
    draco::GetEncodedGeometryType(&buffer);
if (geom_type == draco::TRIANGULAR_MESH) {
  unique_ptr<draco::Mesh> mesh = draco::DecodeMeshFromBuffer(&buffer);
} else if (geom_type == draco::POINT_CLOUD) {
  unique_ptr<draco::PointCloud> pc = draco::DecodePointCloudFromBuffer(&buffer);
}

Please see src/draco/mesh/mesh.h for the full Mesh class interface and src/draco/point_cloud/point_cloud.h for the full PointCloud class interface.

Javascript Encoder API

The Javascript encoder is located in javascript/draco_encoder.js. The encoder API can be used to compress mesh and point cloud. In order to use the encoder, you need to first create an instance of DracoEncoderModule. Then use this instance to create MeshBuilder and Encoder objects. MeshBuilder is used to construct a mesh from geometry data that could be later compressed by Encoder. First create a mesh object using new encoderModule.Mesh() . Then, use AddFacesToMesh() to add indices to the mesh and use AddFloatAttributeToMesh() to add attribute data to the mesh, e.g. position, normal, color and texture coordinates. After a mesh is constructed, you could then use EncodeMeshToDracoBuffer() to compress the mesh. For example:

const mesh = {
  indices : new Uint32Array(indices),
  vertices : new Float32Array(vertices),
  normals : new Float32Array(normals)
};

const encoderModule = DracoEncoderModule();
const encoder = new encoderModule.Encoder();
const meshBuilder = new encoderModule.MeshBuilder();
const dracoMesh = new encoderModule.Mesh();

const numFaces = mesh.indices.length / 3;
const numPoints = mesh.vertices.length;
meshBuilder.AddFacesToMesh(dracoMesh, numFaces, mesh.indices);

meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.POSITION,
  numPoints, 3, mesh.vertices);
if (mesh.hasOwnProperty('normals')) {
  meshBuilder.AddFloatAttributeToMesh(
    dracoMesh, encoderModule.NORMAL, numPoints, 3, mesh.normals);
}
if (mesh.hasOwnProperty('colors')) {
  meshBuilder.AddFloatAttributeToMesh(
    dracoMesh, encoderModule.COLOR, numPoints, 3, mesh.colors);
}
if (mesh.hasOwnProperty('texcoords')) {
  meshBuilder.AddFloatAttributeToMesh(
    dracoMesh, encoderModule.TEX_COORD, numPoints, 3, mesh.texcoords);
}

if (method === "edgebreaker") {
  encoder.SetEncodingMethod(encoderModule.MESH_EDGEBREAKER_ENCODING);
} else if (method === "sequential") {
  encoder.SetEncodingMethod(encoderModule.MESH_SEQUENTIAL_ENCODING);
}

const encodedData = new encoderModule.DracoInt8Array();
// Use default encoding setting.
const encodedLen = encoder.EncodeMeshToDracoBuffer(dracoMesh,
                                                   encodedData);
encoderModule.destroy(dracoMesh);
encoderModule.destroy(encoder);
encoderModule.destroy(meshBuilder);

Please see src/draco/javascript/emscripten/draco_web_encoder.idl for the full API.

Javascript Decoder API

The Javascript decoder is located in javascript/draco_decoder.js. The Javascript decoder can decode mesh and point cloud. In order to use the decoder, you must first create an instance of DracoDecoderModule. The instance is then used to create DecoderBuffer and Decoder objects. Set the encoded data in the DecoderBuffer. Then call GetEncodedGeometryType() to identify the type of geometry, e.g. mesh or point cloud. Then call either DecodeBufferToMesh() or DecodeBufferToPointCloud(), which will return a Mesh object or a point cloud. For example:

// Create the Draco decoder.
const decoderModule = DracoDecoderModule();
const buffer = new decoderModule.DecoderBuffer();
buffer.Init(byteArray, byteArray.length);

// Create a buffer to hold the encoded data.
const decoder = new decoderModule.Decoder();
const geometryType = decoder.GetEncodedGeometryType(buffer);

// Decode the encoded geometry.
let outputGeometry;
let status;
if (geometryType == decoderModule.TRIANGULAR_MESH) {
  outputGeometry = new decoderModule.Mesh();
  status = decoder.DecodeBufferToMesh(buffer, outputGeometry);
} else {
  outputGeometry = new decoderModule.PointCloud();
  status = decoder.DecodeBufferToPointCloud(buffer, outputGeometry);
}

// You must explicitly delete objects created from the DracoDecoderModule
// or Decoder.
decoderModule.destroy(outputGeometry);
decoderModule.destroy(decoder);
decoderModule.destroy(buffer);

Please see src/draco/javascript/emscripten/draco_web_decoder.idl for the full API.

Javascript Decoder Performance

The Javascript decoder is built with dynamic memory. This will let the decoder work with all of the compressed data. But this option is not the fastest. Pre-allocating the memory sees about a 2x decoder speed improvement. If you know all of your project's memory requirements, you can turn on static memory by changing CMakeLists.txt accordingly.

Metadata API

Starting from v1.0, Draco provides metadata functionality for encoding data other than geometry. It could be used to encode any custom data along with the geometry. For example, we can enable metadata functionality to encode the name of attributes, name of sub-objects and customized information. For one mesh and point cloud, it can have one top-level geometry metadata class. The top-level metadata then can have hierarchical metadata. Other than that, the top-level metadata can have metadata for each attribute which is called attribute metadata. The attribute metadata should be initialized with the correspondent attribute id within the mesh. The metadata API is provided both in C++ and Javascript. For example, to add metadata in C++:

draco::PointCloud pc;
// Add metadata for the geometry.
std::unique_ptr<draco::GeometryMetadata> metadata =
  std::unique_ptr<draco::GeometryMetadata>(new draco::GeometryMetadata());
metadata->AddEntryString("description", "This is an example.");
pc.AddMetadata(std::move(metadata));

// Add metadata for attributes.
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
             draco::DT_FLOAT32, false, 12, 0);
const uint32_t pos_att_id = pc.AddAttribute(pos_att, false, 0);

std::unique_ptr<draco::AttributeMetadata> pos_metadata =
    std::unique_ptr<draco::AttributeMetadata>(
        new draco::AttributeMetadata(pos_att_id));
pos_metadata->AddEntryString("name", "position");

// Directly add attribute metadata to geometry.
// You can do this without explicitly add |GeometryMetadata| to mesh.
pc.AddAttributeMetadata(pos_att_id, std::move(pos_metadata));

To read metadata from a geometry in C++:

// Get metadata for the geometry.
const draco::GeometryMetadata *pc_metadata = pc.GetMetadata();

// Request metadata for a specific attribute.
const draco::AttributeMetadata *requested_pos_metadata =
  pc.GetAttributeMetadataByStringEntry("name", "position");

Please see src/draco/metadata and src/draco/point_cloud for the full API.

NPM Package

Draco NPM NodeJS package is located in javascript/npm/draco3d. Please see the doc in the folder for detailed usage.

three.js Renderer Example

Here's an example of a geometric compressed with Draco loaded via a Javascript decoder using the three.js renderer.

Please see the javascript/example/README.md file for more information.

GStatic Javascript Builds

Prebuilt versions of the Emscripten-built Draco javascript decoders are hosted on www.gstatic.com in version labeled directories:

https://www.gstatic.com/draco/versioned/decoders/VERSION/*

As of the v1.4.3 release the files available are:

Beginning with the v1.5.1 release assertion enabled builds of the following files are available:

Support

For questions/comments please email [email protected]

If you have found an error in this library, please file an issue at https://github.com/google/draco/issues

Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub. See CONTRIBUTING for more detail.

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

References

Bunny model from Stanford's graphic department https://graphics.stanford.edu/data/3Dscanrep/

draco's People

Contributors

atteneder avatar bjornblissing avatar customlogic avatar davidkorczynski avatar dependabot[bot] avatar donmccurdy avatar ducciolenkowicz avatar eddiz avatar eile avatar fanzhanggoogle avatar fdefelici avatar frankgalligan avatar freddyfunk avatar igorvytyaz avatar jbrettle avatar kinddragon avatar louquillio avatar mattiapezzanoaiv avatar naxostech avatar nh2 avatar nyue avatar ondys avatar pps83 avatar psycotodd avatar ptc-tgamper avatar qmuntal avatar rbuch703 avatar rjotwani avatar spaceim avatar tomfinegan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

draco's Issues

crash in draco::rabs_desc_read(draco::AnsDecoder*, unsigned char)

./draco_encoder -i test015

==23696==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000005950cf bp 0x7ffedc199b70 sp 0x7ffedc199a30 T0)
    #0 0x5950ce in draco::rabs_desc_read(draco::AnsDecoder*, unsigned char) /root/draco/core/ans.h:177:41
    #1 0x5950ce in draco::RAnsBitDecoder::DecodeNextBit() /root/draco/core/rans_coding.cc:140
    #2 0x710b59 in draco::MeshEdgeBreakerTraversalDecoder::DecodeAttributeSeam(int) /root/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h:109:12
    #3 0x710b59 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeAttributeConnectivitiesOnFace(draco::IndexType<int, draco::CornerIndex_tag_type_>) /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:657
    #4 0x704bc6 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeConnectivity() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:271:12
    #5 0x738539 in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:28:8
    #6 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #7 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #8 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #9 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #10 0x7ff9191eb2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #11 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/core/ans.h:177:41 in draco::rabs_desc_read(draco::AnsDecoder*, unsigned char)
==23696==ABORTING

Using AddAttribute()

In the method:

draco::PointCloud::AddAttribute(const` GeometryAttribute &att,  
                                bool identity_mapping,                // << THIS?
                                AttributeValueIndex::ValueType num_attribute_values);

What does the second argument identity_mapping do?
What situations determine if it should it be true/false?

ObjDecoder uses false, PlyDecoder uses true.

Inconsistent types and sizes

I've noticed in multiple places that size_t, int32_t and int64_t are used interchangeably for indexes and sizes.

For example, in mesh/mesh.h:

void SetNumFaces(int64_t num_faces);

while literally right below that:

FaceIndex::ValueType num_faces() const;
const Face &face(FaceIndex face_id);

Where FaceIndex::ValueType is defined as int32_t in mesh/mesh_indices.h

int64_t is not only signed, but may be larger than size_t, which is what all STL containers use for sizes and indexing, and size_t is always bigger than int32_t. These mean it's possible to overflow size_t when calling SetNumFaces, and it's possible to overflow int32_t when accessing faces or even getting the number of faces.

Likewise, in point_cloud/point_cloud.h, and probably other places, num_points returns size_t, while the internal _num_points value is a signed int32_t, which doesn't make any sense, unless it's possible to have negative number of points.

In fact, why even choose signed types for sizes and index values at all? Why have "strongly-typed" (as worded in core/draco_index_type_vector.h) index types at all, when everything should just be size_t?

Additionally, there probably shouldn't be a wrapper for std::vector at all.

Edit: Just found this:

inline int num_vertices() const { return vertex_corners_.size(); }
inline int num_corners() const { return faces_.size() * 3; }
inline int num_faces() const { return faces_.size(); }

which is incredibly dangerous as faces_.size() approaches even a THIRD of the max value of a signed int

I'm going to start trying to fix these, but I don't know how deep they go.

ply loses vertex property

hi

when i compress and decompress my test file

format ascii 1.0
comment Author: CloudCompare (TELECOM PARISTECH/EDF R&D)
obj_info Generated by CloudCompare!
element vertex 1410581
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property float scalar_Scalar_field
end_header

the property float scalar_Scalar_field is not present in decompressed file

Adding support for vtk-js

That seems interesting and I would like to play with it but I'm guessing the JavaScript implementation is only for decoding and I will have to use the C++ one to encode my data.

Although, I'd rather use the command line interface to compress my various files.

Generally speaking a VTK dataset has 3 types of arrays:

  • vtkPoints which would correspond to the coordinates of the geometry
  • vtkCellArray which is the index mapping to create various cells.
  • And then any data associated to the points or cells (float32/64, int...)

In my JavaScript representation, I have a JSON file that describe the dataset and a binary representation for each arrays. So far, I've been bundling the set of files into a zip file.
Some example could be downloaded here: https://data.kitware.com/#collection/586fef9f8d777f05f44a5c86
And you can download a viewer from here: http://kitware.github.io/vtk-js/examples/StandaloneSceneLoader.html

So I was thinking it would be nice if your command line tools could compress a file on the disk that represent any of those binary array with additional informations such as the type of the numbers and which type of array they are.

Then I was hoping to use your decoder to convert those buffer on the fly to the corresponding typed array when reading them back.

Anyway, any help or guidance would be awesome and I'm really curious how much improvement we could get from it.

Thanks,

Seb

draco_encoder problem

Hi,is this encoder compress all mesh in one (e.g. one obj has same meshs), then decoder it just one mesh?

PLY files issues at reading and writing

Hello,

The decoded PLY files generated by the DRACO decoder cannot be read by the famous MeshLab (http://www.meshlab.net/) viewer.

In addition, some PLY files that can be displayed by meshLab is not supported by rthe DRACO encoder, generating the following messages:

[patonyx]: ./draco_encoder -i DATA/PLY/horse.ply -o horse.drc -qp 20
Failed loading the input mesh.

Regards,

PatOnyx

Smaller JavaScript decoder

The Draco encoder / decoder performs really well in my tests (compared to Open3DGC), both from a compression ratio standpoint and from a speed standpoint; however, the current encoder is nearly 900 KB in size and gzips to about 150 KB, which is likely too large to deliver with our web app.

It would be useful to have a more streamlined (size-wise) version of the JavaScript decoder, perhaps one that is not built with Emscripten. Are there any plans for this?

crash in draco::MeshAttributeCornerTable::Vertex(draco::IndexType<int, draco::CornerIndex_tag_type_>) const

./draco_encoder -i test002

==14057==ERROR: AddressSanitizer: SEGV on unknown address 0x61cf0001cc80 (pc 0x000000712658 bp 0x7fff16517a90 sp 0x7fff165178c0 T0)
    #0 0x712657 in draco::MeshAttributeCornerTable::Vertex(draco::IndexType<int, draco::CornerIndex_tag_type_>) const /root/draco/mesh/mesh_attribute_corner_table.h:89:12
    #1 0x712657 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::AssignPointsToCorners() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:727
    #2 0x705924 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeConnectivity() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:312:8
    #3 0x738539 in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:28:8
    #4 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #5 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #6 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #7 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #8 0x7f28efec62b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #9 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/mesh/mesh_attribute_corner_table.h:89:12 in draco::MeshAttributeCornerTable::Vertex(draco::IndexType<int, draco::CornerIndex_tag_type_>) const
==14057==ABORTING

Test building fails

With a googletest directory above the draco clone as shown in CMakeLists.txt, when I configure with -DENABLE_TESTS=ON, I get a compiler error:

/Users/hobu/dev/git/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc:23:10: fatal error:
      'mesh/mesh_are_equivalent.h' file not found
#include "mesh/mesh_are_equivalent.h"

Normals, etc.

As for normals - let's make it separate. The question is following.

We have a set of points and a set of normals, each k-th normal corresponding to k-th point, respectively. Is it possible to preserve the same number of points and the same number of normals with respective order to each other, regardless of the order of faces?

crash in draco::DecoderBuffer::Peek<unsigned char>(unsigned char*)

./draco_encoder -i test107

==28686==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000007386c2 bp 0x0000000005bd sp 0x7ffeb62bb2c0 T0)
    #0 0x7386c1 in bool draco::DecoderBuffer::Peek<unsigned char>(unsigned char*) /root/draco/core/decoder_buffer.h:84:5
    #1 0x7386c1 in bool draco::DecoderBuffer::Decode<unsigned char>(unsigned char*) /root/draco/core/decoder_buffer.h:64
    #2 0x7386c1 in draco::PointCloudDecoder::DecodePointAttributes() /root/draco/compression/point_cloud/point_cloud_decoder.cc:37
    #3 0x73857f in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:30:8
    #4 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #5 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #6 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #7 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #8 0x7fa51e8322b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #9 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/core/decoder_buffer.h:84:5 in bool draco::DecoderBuffer::Peek<unsigned char>(unsigned char*)
==28686==ABORTING

Support for standard game-oriented triangle mesh data?

Very interesting. I am a little active in this space.... and created a mesh compression format for https://Clara.io (which has different needs than a game engine). Was thinking of creating a Three.JS specific mesh compression algorithm as described here: mrdoob/three.js#8851

So the main parts of a game quality triangle mesh are:

  • vertex positions
  • optional vertex normals
  • optional vertex colors (vec3) sets, either numbered or preferrably named.
  • optional vertex uv (vec2) sets, either numbered or preferrably named.
  • optional per face material ids or face groups.
  • optional vertex skin weights (4 usually for games)
  • optional vertex skin done indicies (4 usually for games)
  • optional named blendshape/morph vertex positions (3 x float)
  • optional named blendshape/morph vertex normals (3 x float)

What does this tool support?

crash in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::AssignPointsToCorners()

./draco_encoder -i test097

==6907==ERROR: AddressSanitizer: SEGV on unknown address 0x614f0000f800 (pc 0x0000007116c2 bp 0x7ffeac603b10 sp 0x7ffeac603940 T0)
    #0 0x7116c1 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::AssignPointsToCorners() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:687:13
    #1 0x705924 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeConnectivity() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:312:8
    #2 0x738539 in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:28:8
    #3 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #4 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #5 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #6 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #7 0x7f3833f1d2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #8 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:687:13 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::AssignPointsToCorners()
==6907==ABORTING

How to decode GENERIC Attributes?

How do I decode an attribute of type GENERIC?

The function:

int32_t PointCloud::NumNamedAttributes(GeometryAttribute::Type type) const {
  if (type == GeometryAttribute::INVALID ||
      type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) // == GeometryAttribute::GENERIC
    return 0;
  return named_attribute_index_[type].size();
}

always returns 0.

I saw an issue mentioning custom IDs, but I don't understand how to make these work either.

decoded mesh with texture looks worse with cl=0 vs. the default cl=5

I'm having an issue with a particular mesh where the encoded & decoded mesh shows black spots on the texture. I found out that materials are not yet preserved on OBJ export... so I manually added the line "mtllib ./mesh.obj.mtl" to the OBJ file after I decoded it. What was weirder is that the black spots became more prevalent when I set cl=0. I attached some screenshots of before and after, and also the original model. Also, the decoded mesh file size is bigger than the original. I think it might be because the decoded mesh has a blank line after every entry. (I'm using default cmake settings with VS 2015 Community, x64 Release build of encoder & decoder). Any idea why this mesh in particular doesn't encode & decode well? Thanks!

cl_eq_0
default_cl_eq_5
mesh.zip

obj_decoder: Possible to maintain/export 'usemtl' definitions or group names?

Quick question about the OBJ decoder:

Is it possible to maintain usemtl definitions within the draco-encoded file (specifically for eventual use in THREE.js)?

Similarly, is this possible with polygon groups?

From what I can gather neither is currently supported. Any plans to do so in the future?

Thank you for Draco!

Error compiling draco_decoder.js

I'm trying to compile draco_decoder.js with some parameters in Makefile.emcc changed, as described in the README. make -f Makefile.emcc runs normally at first, printing only warnings about an optimization it can't do:

make -f Makefile.emcc
python /usr/local/opt/emscripten/libexec/tools/webidl_binder.py javascript/emscripten/draco_web.idl glue
em++ -MMD -MP -DDRACO_STANDARD_EDGEBREAKER_SUPPORTED -DDRACO_PREDICTIVE_EDGEBREAKER_SUPPORTED -I../../ -I./ -std=c++11 -O3 -s ALLOW_MEMORY_GROWTH=1 --memory-init-file 0 -Wno-sign-compare -fno-omit-frame-pointer javascript/emscripten/draco_glue_wrapper.cc -o obj/javascript/emscripten/draco_glue_wrapper.o
WARNING:root:not all asm.js optimizations are possible with ALLOW_MEMORY_GROWTH, disabling those
em++ -MMD -MP -DDRACO_STANDARD_EDGEBREAKER_SUPPORTED -DDRACO_PREDICTIVE_EDGEBREAKER_SUPPORTED -I../../ -I./ -std=c++11 -O3 -s ALLOW_MEMORY_GROWTH=1 --memory-init-file 0 -Wno-sign-compare -fno-omit-frame-pointer javascript/emscripten/webidl_wrapper.cc -o obj/javascript/emscripten/webidl_wrapper.o
WARNING:root:not all asm.js optimizations are possible with ALLOW_MEMORY_GROWTH, disabling those
em++ -MMD -MP -DDRACO_STANDARD_EDGEBREAKER_SUPPORTED -DDRACO_PREDICTIVE_EDGEBREAKER_SUPPORTED -I../../ -I./ -std=c++11 -O3 -s ALLOW_MEMORY_GROWTH=1 --memory-init-file 0 -Wno-sign-compare -fno-omit-frame-pointer core/draco_types.cc -o obj/core/draco_types_a.o
WARNING:root:not all asm.js optimizations are possible with ALLOW_MEMORY_GROWTH, disabling those
...

But then eventually crashes with the following error:

make: *** No rule to make target `obj/compression/attributes/mesh_normal_attribute_decoder_a.o', needed by `draco_decoder'.  Stop.

Is using Makefile.emcc still supported, or is the only compile path now cmake . -DCMAKE_TOOLCHAIN_FILE=... && make?

Running: OSX 10.11.6 (El Capitan)
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.37.0
clang version 3.9.0 (emscripten 1.37.0 : 1.37.0)
Target: x86_64-apple-darwin15.6.0

about obj encoder error

when i encoder the obj model with point 237522 and face 712566 crash,
the debug repot: vector subscript out of range

I cannot cmake in centos, who can help me?

/data/arvinhu/draco-master]# cmake /data/arvinhu/draco-master -DCMAKE_BUILD_TYPE=release
-- The C compiler identification is unknown
-- The CXX compiler identification is GNU 4.4.6
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /usr/local/share/cmake-3.7/Modules/CMakeTestCCompiler.cmake:51 (message):
The C compiler "/usr/bin/cc" is not able to compile a simple test program.

It fails with the following output:

Change Dir: /data/arvinhu/draco-master/CMakeFiles/CMakeTmp

Run Build Command:"/usr/bin/gmake" "cmTC_01fd7/fast"

/usr/bin/gmake -f CMakeFiles/cmTC_01fd7.dir/build.make
CMakeFiles/cmTC_01fd7.dir/build

gmake[1]: Entering directory
`/data/arvinhu/draco-master/CMakeFiles/CMakeTmp'

Building C object CMakeFiles/cmTC_01fd7.dir/testCCompiler.c.o

/usr/bin/cc -o CMakeFiles/cmTC_01fd7.dir/testCCompiler.c.o -c
/data/arvinhu/draco-master/CMakeFiles/CMakeTmp/testCCompiler.c

cc1: error: unrecognized command line option '-quiet'

cc1: error: unrecognized command line option '-quiet'

cc1: error: unrecognized command line option '-auxbase-strip
CMakeFiles/cmTC_01fd7.dir/testCCompiler.c.o'

gmake[1]: *** [CMakeFiles/cmTC_01fd7.dir/testCCompiler.c.o] Error 1

gmake[1]: Leaving directory
`/data/arvinhu/draco-master/CMakeFiles/CMakeTmp'

gmake: *** [cmTC_01fd7/fast] Error 2

CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:2 (project)

-- Configuring incomplete, errors occurred!
See also "/data/arvinhu/draco-master/CMakeFiles/CMakeOutput.log".
See also "/data/arvinhu/draco-master/CMakeFiles/CMakeError.log".

Feature: Support for encoding Quads

Below is a simple obj file that represents a single cube.

mtllib twocubes.mtl
o Cube2_Cube.001
v 3.052341 -1.477031 -5.058577
v 3.052341 -1.477031 -3.058577
v 1.052340 -1.477031 -3.058577
v 1.052341 -1.477031 -5.058577
v 3.052341 0.522969 -5.058576
v 3.052340 0.522969 -3.058576
v 1.052340 0.522969 -3.058577
v 1.052341 0.522969 -5.058577
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
usemtl Material
s off
f 1//1 2//1 3//1 4//1
f 5//2 8//2 7//2 6//2
f 1//3 5//3 6//3 2//3
f 2//4 6//4 7//4 3//4
f 3//5 7//5 8//5 4//5
f 5//6 1//6 4//6 8//6

I had it encoded into a drc file (with default encoding settings) and am having them decoded using the Javascript decoder.
Some of the numbers am getting don't seem to make sense.

numFaces = dracoGeometry.num_faces(); //  this returns 6
numPoints = dracoGeometry.num_points(); // this returns 18

And the resultant geometry ends up being like this
image

It seems impossible to me that encoding would go wrong on a simple model like this. What exactly is the problem then? :-/

Comparisons to glTF binary, OpenCTM, etc?

Nice work. I was on the Brotli guys about the insuitability of their stuff for 3D meshes a while back: google/brotli#165 This seems like a good solution.

I am interested in the comparision to OpenCTM (quantization + LZMA), glTF's binary format (https://github.com/KhronosGroup/glTF/wiki/Open-3D-Graphics-Compression) and the old Sun Java3D stuff from the late 1995 (http://web.cse.ohio-state.edu/~hwshen/Su01_888/deering.pdf -- which is now just off patent I believe :). I notice you are using the techniques from http://www.cc.gatech.edu/~jarek/papers/EdgeBreaker.pdf

Untextured triangles become textured

I have an OBJ file with some textured and some untextured triangles. Then I encode OBJ to DRC and decode it back. All untextured triangles become textured, which apparently is not what I want.

order changed after decode?

Hi,

I am intended to test the accuracy loss of draco encoding and decoding. That is encode a point cloud to buffer and then decode the buffer to point cloud. Then check the difference between the two point clouds (both are saved in col-major Eigen matrix). There should be some accuracy loss, because I have used the qunatization to 14 bits.

However, it seems the result are not correct. Maybe the order has changed after decoding?

Below is my code,
the main function

    MatrixXf points = read_laz_file(ifile);
    unique_ptr<draco::PointCloud> draco_cloud = convert_to_draco(points);

    draco::EncoderBuffer encode_buffer;
    draco::DecoderBuffer decode_buffer;

    draco_encode(draco_cloud, encode_buffer);
    decode_buffer.Init(encode_buffer.data(), encode_buffer.size());

    auto decode_cloud = draco_decode(decode_buffer);
    MatrixXf decode_points = convert_to_eigen(decode_cloud);

    MatrixXf points_error = (points - decode_points).cwiseAbs();

and here is the related functions

unique_ptr<draco::PointCloud> convert_to_draco(const MatrixXf &points) {
    using namespace draco;
    unique_ptr<PointCloud> draco_points = std::make_unique<draco::PointCloud>();

    int num_points = points.cols();
    draco_points->set_num_points(num_points);
    GeometryAttribute va;
    va.Init(GeometryAttribute::POSITION, nullptr, 3, DT_FLOAT32, false, sizeof(float) * 3, 0);
    const int id_att = draco_points->AddAttribute(va, true, num_points);

    for (int i = 0; i < num_points; i++) {
        draco_points->attribute(id_att)->SetAttributeValue(AttributeValueIndex(i), points.col(i).data());
    }

    return draco_points;
}
MatrixXf convert_to_eigen(const unique_ptr<draco::PointCloud> &cloud) {
    using namespace draco;
    int id_pos_att = cloud->GetNamedAttributeId(GeometryAttribute::POSITION);
    int num_points = cloud->num_points();
    MatrixXf vertices(3, num_points);
    const auto *const pos_att = cloud->attribute(id_pos_att);

    for (int i = 0; i < num_points; ++i) {
        auto v = pos_att->GetValue<float, 3>(pos_att->mapped_index(draco::PointIndex(i)));
        vertices(0, i) = v[0];
        vertices(1, i) = v[1];
        vertices(2, i) = v[2];
    }

    return vertices;
}

void draco_encode(const unique_ptr<draco::PointCloud> &cloud, draco::EncoderBuffer &buffer) {
    using namespace draco;
    EncoderOptions options = CreateDefaultEncoderOptions();

    SetNamedAttributeQuantization(&options, *cloud, GeometryAttribute::POSITION, 14);
    SetSpeedOptions(&options, 5, 5);

    draco::EncodePointCloudToBuffer(*cloud, options, &buffer);
}

unique_ptr<draco::PointCloud> draco_decode(draco::DecoderBuffer &buffer) {
    const draco::EncodedGeometryType type = draco::GetEncodedGeometryType(&buffer);
    unique_ptr<draco::PointCloud> cloud;
    if (type == draco::POINT_CLOUD) {
        cloud = draco::DecodePointCloudFromBuffer(&buffer);
    }
    return cloud;
}

draco_encoder: crash in draco::PointAttribute::DeduplicateFormattedValues<float, 2>(...)

Hi,

Was running draco_encoder on different objects and on some of them faced a segfault with the same stacktrace:

#0 0x000000010041e287 in draco::PointAttribute::DeduplicateFormattedValues<float, 2> (
this=0x60007d4b0, in_att=..., in_att_offset=...)
at /home/User/Work/draco/point_cloud/point_attribute.cc:174
#1 0x0000000100417307 in draco::PointAttribute::DeduplicateTypedValues (in_att_offset=...,
in_att=..., this=) at /home/User/Work/draco/point_cloud/point_attribute.cc:98
#2 draco::PointAttribute::DeduplicateValues (this=, in_att=..., in_att_offset=...,
in_att_offset@entry=...) at /home/User/Work/draco/point_cloud/point_attribute.cc:57
#3 0x000000010041737c in draco::PointAttribute::DeduplicateValues (this=, in_att=...)
at /home/User/Work/draco/point_cloud/point_attribute.cc:48
#4 0x000000010040f136 in draco::PointCloud::DeduplicateAttributeValues (this=0x60007cb00)
at /home/User/Work/draco/point_cloud/point_cloud.cc:175
#5 0x0000000100406ead in draco::ObjDecoder::DecodeInternal (this=this@entry=0xffffc580)
at /home/User/Work/draco/io/obj_decoder.cc:162
#6 0x00000001004071b0 in draco::ObjDecoder::DecodeFromFile (this=this@entry=0xffffc580,
file_name=..., out_point_cloud=0x60007cb00) at /home/User/Work/draco/io/obj_decoder.cc:66
#7 0x000000010040724c in draco::ObjDecoder::DecodeFromFile (this=this@entry=0xffffc580,
file_name=..., out_mesh=) at /home/User/Work/draco/io/obj_decoder.cc:44
#8 0x00000001004054bc in draco::ReadMeshFromFile (file_name=...)
at /home/User/Work/draco/io/mesh_io.cc:33
#9 0x00000001004943a7 in main (argc=7, argv=0xffffcbb0)
at /home/User/Work/draco/tools/draco_encoder.cc:189

The crash is here, see line 174:

(gdb) l
169 for (int i = 0; i < num_unique_entries_; ++i) {
170 SetPointMapEntry(PointIndex(i), value_map[AttributeValueIndex(i)]);
171 }
172 } else {
173 // Update point to value map using the mapping between old and new values.
174 for (PointIndex i(0); i < indices_map_.size(); ++i) {
175 SetPointMapEntry(i, value_map[indices_map_[i]]);
176 }
177 }
178 num_unique_entries_ = unique_vals.value();

Command line:

draco_encoder.exe -cl 5 -i objname.obj -o objname.drc.

Thanks in advance for your help

Support for streaming mesh compression

Any plans to support progressive encoding of a mesh where the indices only need to be sent once and the attributes can be sent incrementally or with an increased LOD, over time?

If not, could you please provide some guidance on how this would be best achieved in draco?

Global Module var in draco_decoder.js

Hi,

I created a PR adding DRACOLoader.js and draco_decoder.js to the three.js repository:

mrdoob/three.js#10879

Please see @mrdoob's comments regarding the global Module var in draco_decoder.js. It's better to avoid polluting the global namespace if possible.

I also agree that it would be good if DRACOLoader.js were to be maintained within the three.js repo.

PLY Decoder Can't Read Normals?

It looks the the PLY decoder can't read normals? Just positions and colors? I get that custom properties aren't supported yet, but it seems like it should be able to at least read a built-in like normals.

crash in draco::RAnsDecoder<12>::rans_read()

./draco_encoder -i test057

==30255==ERROR: AddressSanitizer: SEGV on unknown address 0x02007bda16b4 (pc 0x000000740c34 bp 0x7ffef6a53040 sp 0x7ffef6a52ea0 T0)
    #0 0x740c33 in draco::RAnsDecoder<12>::rans_read() /root/draco/core/ans.h:457:43
    #1 0x740c33 in draco::RAnsSymbolDecoder<5>::DecodeSymbol() /root/draco/core/rans_symbol_decoder.h:38
    #2 0x740c33 in bool draco::DecodeTaggedSymbols<draco::RAnsSymbolDecoder>(int, int, draco::DecoderBuffer*, unsigned int*) /root/draco/core/symbol_decoding.cc:82
    #3 0x740375 in draco::DecodeSymbols(int, int, draco::DecoderBuffer*, unsigned int*) /root/draco/core/symbol_decoding.cc:57:12
    #4 0x7ff4d2 in draco::SequentialIntegerAttributeDecoder::DecodeIntegerValues(std::vector<draco::IndexType<int, draco::PointIndex_tag_type_>, std::allocator<draco::IndexType<int, draco::PointIndex_tag_type_> > > const&, draco::DecoderBuffer*) /root/draco/compression/attributes/sequential_integer_attribute_decoder.cc:80:10
    #5 0x7fec44 in draco::SequentialIntegerAttributeDecoder::DecodeValues(std::vector<draco::IndexType<int, draco::PointIndex_tag_type_>, std::allocator<draco::IndexType<int, draco::PointIndex_tag_type_> > > const&, draco::DecoderBuffer*) /root/draco/compression/attributes/sequential_integer_attribute_decoder.cc:51:8
    #6 0x7fceeb in draco::SequentialAttributeDecodersController::DecodeAttributes(draco::DecoderBuffer*) /root/draco/compression/attributes/sequential_attribute_decoders_controller.cc:58:10
    #7 0x738d57 in draco::PointCloudDecoder::DecodeAllAttributes() /root/draco/compression/point_cloud/point_cloud_decoder.cc:70:10
    #8 0x738aac in draco::PointCloudDecoder::DecodePointAttributes() /root/draco/compression/point_cloud/point_cloud_decoder.cc:60:8
    #9 0x73857f in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:30:8
    #10 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #11 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #12 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #13 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #14 0x7fc1da5552b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #15 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/core/ans.h:457:43 in draco::RAnsDecoder<12>::rans_read()
==30255==ABORTING

Decoding problem in Android browsers

I really appreciate the idea behind Draco, as it could greatly decrease the required bandwidth for downloading 3D models, which is especially important in case of mobile apps where bandwidth could be a tight bottleneck.
However testing the "three.js Renderer Example" on my Android 5.1 tablet I observed a strange issue with the decoding. I attached the screenshot showing the scrambled appearance of the 3D model. I checked it in both Firefox for Android (version 50.1.0) and Chrome for Android (55.0.2883.91), and found the same result. I also tried to visualize other three.js examples on this tablet to exclude the possibility of a three.js bug, however all other three.js models appeared well.

screenshot_2017-02-05-18-00-13

Interestingly however on an older tablet with Android 4.4 but also with the latest version of Firefox and Chrome, there was no artifact at all, the above three.js example was visualized perfectly.
Could it be related to the Android version or the SoC? For me it does not seem to be a bug in Draco, however unfortunately it could undermine the usability of the library on mobile devices.

2 issues I met when try the javascript sample

  1. Get 2 errors in chrome console for files - DRACOLoader.js and webgl_loader_draco.html.

Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
<<
Add the "use strict" at the beginning of these 2 files can fix it.

  1. Get 1 object undefined error when value the cameraTarget in webgl_loader_draco.html file.

function init() {
container = document.createElement('div');
document.body.appendChild(container);

    camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 15);
    camera.position.set(3, 0.15, 3);
    cameraTarget = new THREE.Vector3(0, 0, 0);

<<
declare it with camera can fix it.

  let camera, cameraTarget, scene, renderer;

<<

draco_encoder: Segmentation fault while encoding a simple OBJ file (52 vertices, 100 triangles)

./draco_encoder breaks down while encoding 'model_mesh.obj' with default options.

OBJ file is attached here (remove .txt extension and make it .obj) - model_mesh_obj.txt

Here is the stack trace:

#0 0x00007ffff728d0ad in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000000000069063b in draco::DataBuffer::Read (this=0x9cef20, byte_pos=-12884901888,
out_data=0x7fffffffde80, data_size=12) at /home/artec/projects/draco/core/data_buffer.h:47
#2 0x00000000006ccb59 in draco::GeometryAttribute::GetValue (this=0x9ce9c0, att_index=...,
out_data=0x7fffffffde80) at /home/artec/projects/draco/point_cloud/geometry_attribute.h:94
#3 0x00000000006cc9f7 in draco::SequentialNormalAttributeEncoder::PrepareValues (this=0x9cab60,
point_ids=...)
at /home/artec/projects/draco/compression/attributes/sequential_normal_attribute_encoder.cc:44
#4 0x00000000006b4dd5 in draco::SequentialIntegerAttributeEncoder::EncodeValues (this=0x9cab60,
point_ids=..., out_buffer=0x7fffffffe180)
at /home/artec/projects/draco/compression/attributes/sequential_integer_attribute_encoder.cc:83
#5 0x000000000072de1f in draco::SequentialAttributeEncoder::Encode (this=0x9cab60, point_ids=...,
out_buffer=0x7fffffffe180)
at /home/artec/projects/draco/compression/attributes/sequential_attribute_encoder.cc:42
#6 0x00000000006b3151 in draco::SequentialAttributeEncodersController::EncodeAttributes (this=0x9ca8f0,
buffer=0x7fffffffe180)
at /home/artec/projects/draco/compression/attributes/sequential_attribute_encoders_controller.cc:61
#7 0x0000000000641733 in draco::PointCloudEncoder::EncodeAllAttributes (this=0x9cf570)
at /home/artec/projects/draco/compression/point_cloud/point_cloud_encoder.cc:104
#8 0x0000000000641552 in draco::PointCloudEncoder::EncodePointAttributes (this=0x9cf570)
at /home/artec/projects/draco/compression/point_cloud/point_cloud_encoder.cc:83
#9 0x00000000006412d9 in draco::PointCloudEncoder::Encode (this=0x9cf570, options=...,
out_buffer=0x7fffffffe180) at /home/artec/projects/draco/compression/point_cloud/point_cloud_encoder.cc:44
#10 0x00000000006201d0 in draco::EncodeGeometryToBuffer (encoder=0x9cf570, options=...,
out_buffer=0x7fffffffe180) at /home/artec/projects/draco/compression/encode.cc:51
#11 0x000000000062070f in draco::EncodeMeshToBuffer (m=..., options=..., out_buffer=0x7fffffffe180)
at /home/artec/projects/draco/compression/encode.cc:120
#12 0x000000000061e5be in (anonymous namespace)::EncodeMeshToFile (mesh=..., options=..., file=...)
at /home/artec/projects/draco/tools/draco_encoder.cc:136
#13 0x000000000061efd9 in main (argc=5, argv=0x7fffffffe618)
at /home/artec/projects/draco/tools/draco_encoder.cc:232

crash in draco::ans_read_init(draco::AnsDecoder*, unsigned char const*, int)

./draco_encoder -i test000

==23044==ERROR: AddressSanitizer: SEGV on unknown address 0x61e02300f0f5 (pc 0x000000594b3b bp 0x7fffe8fe3cf0 sp 0x7fffe8fe3c20 T0)
    #0 0x594b3a in draco::ans_read_init(draco::AnsDecoder*, unsigned char const*, int) /root/draco/core/ans.h:302:7
    #1 0x594b3a in draco::RAnsBitDecoder::StartDecoding(draco::DecoderBuffer*) /root/draco/core/rans_coding.cc:133
    #2 0x71ec37 in draco::MeshEdgeBreakerTraversalPredictiveDecoder::Start() /root/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h:48:5
    #3 0x71bd8f in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalPredictiveDecoder>::DecodeConnectivity() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:255:46
    #4 0x738539 in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:28:8
    #5 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #6 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #7 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #8 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #9 0x7fb7d071a2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #10 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/core/ans.h:302:7 in draco::ans_read_init(draco::AnsDecoder*, unsigned char const*, int)
==23044==ABORTING

Failed loading the input mesh from MagicaVoxel baked PLY export

./draco_encoder -i ../aframe-city-builder/assets/ply/alien_egg2.bake.ply -o ./alien_egg2_bake.drc
returns
Failed loading the input mesh.

You can see some other examples of source files here:
https://github.com/kfarr/aframe-city-builder/tree/master/assets/ply

crash in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::CreateAttributesDecoder(int)

./draco_encoder -i test009

==31846==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000006ffe32 bp 0x7fff2dfb6590 sp 0x7fff2dfb5fc0 T0)
    #0 0x6ffe31 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::CreateAttributesDecoder(int) /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:103:45
    #1 0x73876b in draco::PointCloudDecoder::DecodePointAttributes() /root/draco/compression/point_cloud/point_cloud_decoder.cc:43:10
    #2 0x73857f in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:30:8
    #3 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #4 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #5 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #6 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #7 0x7f5f361842b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #8 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:103:45 in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::CreateAttributesDecoder(int)
==31846==ABORTING

crash in draco::IndexType<int, draco::VertexIndex_tag_type_>::operator=(draco::IndexType<int, draco::VertexIndex_tag_type_> const&)

./draco_encoder -i test053

==5300==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000070957c bp 0x7fff9aa6ae10 sp 0x7fff9aa6abe0 T0)
    #0 0x70957b in draco::IndexType<int, draco::VertexIndex_tag_type_>::operator=(draco::IndexType<int, draco::VertexIndex_tag_type_> const&) /root/draco/core/draco_index_type.h:149:12
    #1 0x70957b in draco::CornerTable::MapCornerToVertex(draco::IndexType<int, draco::CornerIndex_tag_type_>, draco::IndexType<int, draco::VertexIndex_tag_type_>) /root/draco/mesh/corner_table.h:212
    #2 0x70957b in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeConnectivity(int) /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:481
    #3 0x70498a in draco::MeshEdgeBreakerDecoderImpl<draco::MeshEdgeBreakerTraversalDecoder>::DecodeConnectivity() /root/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc:257:38
    #4 0x738539 in draco::PointCloudDecoder::Decode(draco::DecoderBuffer*, draco::PointCloud*) /root/draco/compression/point_cloud/point_cloud_decoder.cc:28:8
    #5 0x6fc463 in draco::DecodeMeshFromBuffer(draco::DecoderBuffer*) /root/draco/compression/decode.cc:117:8
    #6 0x600ca4 in std::basic_ifstream<char, std::char_traits<char> >& draco::ReadMeshFromStream<std::basic_ifstream<char, std::char_traits<char> >&>(std::unique_ptr<draco::Mesh, std::default_delete<draco::Mesh> >*, std::basic_ifstream<char, std::char_traits<char> >&) /root/draco/io/mesh_io.h:66:11
    #7 0x60009d in draco::ReadMeshFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /root/draco/io/mesh_io.cc:50:8
    #8 0x52de2f in main /root/draco/tools/draco_encoder.cc:189:9
    #9 0x7fe74f2fb2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #10 0x459d19 in _start (/root/draco/build/draco_encoder+0x459d19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/draco/core/draco_index_type.h:149:12 in draco::IndexType<int, draco::VertexIndex_tag_type_>::operator=(draco::IndexType<int, draco::VertexIndex_tag_type_> const&)
==5300==ABORTING

Crash on obj with texture

I encounter encoder being crashing on objs with texture(s).

Below is the command output:

./draco_encoder -cl 10 -i ~/Desktop/e.obj -o ~/Desktop/e.draco
Encoder options:
Compression level = 10
Positions: Quantization = 14 bits
Texture coordinates: Quantization = 12 bits
Normals: Quantization = 10 bits'

[1] 39524 segmentation fault ./draco_encoder -cl 10 -i ~/Desktop/e.obj -o ~/Desktop/e.draco

File that can be used to reproduce the problem: model.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.