mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-07-27 17:42:01 +08:00

- Improved compression for triangular meshes (~10%) - Added WebAssembly decoder - Code cleanup + robustness fixes
102 lines
3.9 KiB
C++
102 lines
3.9 KiB
C++
// Copyright 2016 The Draco Authors.
|
|
//
|
|
// 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.
|
|
//
|
|
#ifndef DRACO_COMPRESSION_ATTRIBUTES_MESH_TRAVERSAL_SEQUENCER_H_
|
|
#define DRACO_COMPRESSION_ATTRIBUTES_MESH_TRAVERSAL_SEQUENCER_H_
|
|
|
|
#include "compression/attributes/mesh_attribute_indices_encoding_data.h"
|
|
#include "compression/attributes/points_sequencer.h"
|
|
#include "mesh/corner_table_indices.h"
|
|
#include "mesh/mesh.h"
|
|
|
|
namespace draco {
|
|
|
|
// Sequencer that generates point sequence in an order given by a deterministic
|
|
// traversal on the mesh surface. Note that all attributes encoded with this
|
|
// sequence must share the same connectivity.
|
|
template <class TraverserT>
|
|
class MeshTraversalSequencer : public PointsSequencer {
|
|
public:
|
|
MeshTraversalSequencer(const Mesh *mesh,
|
|
const MeshAttributeIndicesEncodingData *encoding_data)
|
|
: mesh_(mesh), encoding_data_(encoding_data), corner_order_(nullptr) {}
|
|
void SetTraverser(const TraverserT &t) { traverser_ = t; }
|
|
|
|
// Function that can be used to set an order in which the mesh corners should
|
|
// be processed. This is an optional flag used usually only by the encoder
|
|
// to match the same corner order that is going to be used by the decoder.
|
|
// Note that |corner_order| should contain only one corner per face (it can
|
|
// have all corners but only the first encountered corner for each face is
|
|
// going to be used to start a traversal). If the corner order is not set, the
|
|
// corners are processed sequentially based on their ids.
|
|
void SetCornerOrder(const std::vector<CornerIndex> &corner_order) {
|
|
corner_order_ = &corner_order;
|
|
}
|
|
|
|
bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override {
|
|
const auto *corner_table = traverser_.corner_table();
|
|
attribute->SetExplicitMapping(mesh_->num_points());
|
|
const size_t num_faces = mesh_->num_faces();
|
|
const size_t num_points = mesh_->num_points();
|
|
for (FaceIndex f(0); f < num_faces; ++f) {
|
|
const auto &face = mesh_->face(f);
|
|
for (int p = 0; p < 3; ++p) {
|
|
const PointIndex point_id = face[p];
|
|
const VertexIndex vert_id =
|
|
corner_table->Vertex(CornerIndex(3 * f.value() + p));
|
|
const AttributeValueIndex att_entry_id(
|
|
encoding_data_
|
|
->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
|
|
if (att_entry_id.value() >= num_points) {
|
|
// There cannot be more attribute values than the number of points.
|
|
return false;
|
|
}
|
|
attribute->SetPointMapEntry(point_id, att_entry_id);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
bool GenerateSequenceInternal() override {
|
|
traverser_.OnTraversalStart();
|
|
if (corner_order_) {
|
|
for (uint32_t i = 0; i < corner_order_->size(); ++i) {
|
|
ProcessCorner(corner_order_->at(i));
|
|
}
|
|
} else {
|
|
const int32_t num_faces = traverser_.corner_table()->num_faces();
|
|
for (int i = 0; i < num_faces; ++i) {
|
|
ProcessCorner(CornerIndex(3 * i));
|
|
}
|
|
}
|
|
traverser_.OnTraversalEnd();
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
void ProcessCorner(CornerIndex corner_id) {
|
|
traverser_.TraverseFromCorner(corner_id);
|
|
}
|
|
|
|
TraverserT traverser_;
|
|
const Mesh *mesh_;
|
|
const MeshAttributeIndicesEncodingData *encoding_data_;
|
|
const std::vector<CornerIndex> *corner_order_;
|
|
};
|
|
|
|
} // namespace draco
|
|
|
|
#endif // DRACO_COMPRESSION_ATTRIBUTES_MESH_TRAVERSAL_SEQUENCER_H_
|