summaryrefslogtreecommitdiff
path: root/libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h')
-rw-r--r--libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h260
1 files changed, 0 insertions, 260 deletions
diff --git a/libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h b/libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h
deleted file mode 100644
index 262e3c7..0000000
--- a/libs/assimp/contrib/draco/src/draco/mesh/mesh_stripifier.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2017 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_MESH_MESH_STRIPIFIER_H_
-#define DRACO_MESH_MESH_STRIPIFIER_H_
-
-#include "draco/mesh/mesh_misc_functions.h"
-
-namespace draco {
-
-// Class that generates triangle strips from a provided draco::Mesh data
-// structure. The strips represent a more memory efficient storage of triangle
-// connectivity that can be used directly on the GPU (see
-// https://en.wikipedia.org/wiki/Triangle_strip ). In general, a mesh needs to
-// be represented by several triangle strips and it has been proven that finding
-// the optimal set of triangle strips is an NP-complete problem. The algorithm
-// implemented by this class finds this set of triangle strips based on a greedy
-// heuristic that always selects the longest available strip that covers the
-// next unprocessed face. The longest strip is found by analyzing all strips
-// that can cover the given face (three strips corresponding to three
-// directions).
-class MeshStripifier {
- public:
- MeshStripifier()
- : mesh_(nullptr),
- num_strips_(0),
- num_encoded_faces_(0),
- last_encoded_point_(kInvalidPointIndex) {}
-
- // Generate triangle strips for a given mesh and output them to the output
- // iterator |out_it|. In most cases |out_it| stores the values in a buffer
- // that can be used directly on the GPU. Note that the algorithm can generate
- // multiple strips to represent the whole mesh. In such cases multiple strips
- // are separated using a so called primitive restart index that is specified
- // by the |primitive_restart_index| (usually defined as the maximum allowed
- // value for the given type).
- // https://www.khronos.org/opengl/wiki/Vertex_Rendering#Primitive_Restart
- template <typename OutputIteratorT, typename IndexTypeT>
- bool GenerateTriangleStripsWithPrimitiveRestart(
- const Mesh &mesh, IndexTypeT primitive_restart_index,
- OutputIteratorT out_it);
-
- // The same as above but disjoint triangle strips are separated by degenerate
- // triangles instead of the primitive restart index. Degenerate triangles are
- // zero area triangles that are automatically discarded by the GPU. Using
- // degenerate triangles usually results in a slightly longer output indices
- // array compared to the similar triangle strips that use primitive restart
- // index. The advantage of this method is that it is supported by all hardware
- // and all relevant APIs (including WebGL 1.0).
- template <typename OutputIteratorT>
- bool GenerateTriangleStripsWithDegenerateTriangles(const Mesh &mesh,
- OutputIteratorT out_it);
-
- // Returns the number of strips generated by the last call of the
- // GenerateTriangleStrips() method.
- int num_strips() const { return num_strips_; }
-
- private:
- bool Prepare(const Mesh &mesh) {
- mesh_ = &mesh;
- num_strips_ = 0;
- num_encoded_faces_ = 0;
- // TODO(ostava): We may be able to avoid computing the corner table if we
- // already have it stored somewhere.
- corner_table_ = CreateCornerTableFromPositionAttribute(mesh_);
- if (corner_table_ == nullptr) {
- return false;
- }
-
- // Mark all faces as unvisited.
- is_face_visited_.assign(mesh.num_faces(), false);
- return true;
- }
-
- // Returns local id of the longest strip that can be created from the given
- // face |fi|.
- int FindLongestStripFromFace(FaceIndex fi) {
- // There are three possible strip directions that can contain the provided
- // input face. We try all of them and select the direction that result in
- // the longest strip.
- const CornerIndex first_ci = corner_table_->FirstCorner(fi);
- int longest_strip_id = -1;
- int longest_strip_length = 0;
- for (int i = 0; i < 3; ++i) {
- GenerateStripsFromCorner(i, first_ci + i);
- if (strip_faces_[i].size() > longest_strip_length) {
- longest_strip_length = static_cast<int>(strip_faces_[i].size());
- longest_strip_id = i;
- }
- }
- return longest_strip_id;
- }
-
- // Generates strip from the data stored in |strip_faces_| and
- // |strip_start_start_corners_| and stores it to |out_it|.
- template <typename OutputIteratorT>
- void StoreStrip(int local_strip_id, OutputIteratorT out_it) {
- ++num_strips_;
-
- const int num_strip_faces = strip_faces_[local_strip_id].size();
- CornerIndex ci = strip_start_corners_[local_strip_id];
- for (int i = 0; i < num_strip_faces; ++i) {
- const FaceIndex fi = corner_table_->Face(ci);
- is_face_visited_[fi] = true;
- ++num_encoded_faces_;
-
- if (i == 0) {
- // Add the start face (three indices).
- *out_it++ = CornerToPointIndex(ci).value();
- *out_it++ = CornerToPointIndex(corner_table_->Next(ci)).value();
- last_encoded_point_ = CornerToPointIndex(corner_table_->Previous(ci));
- *out_it++ = last_encoded_point_.value();
- } else {
- // Store the point on the newly reached corner.
- last_encoded_point_ = CornerToPointIndex(ci);
- *out_it++ = last_encoded_point_.value();
-
- // Go to the correct source corner to proceed to the next face.
- if (i & 1) {
- ci = corner_table_->Previous(ci);
- } else {
- ci = corner_table_->Next(ci);
- }
- }
- ci = corner_table_->Opposite(ci);
- }
- }
-
- PointIndex CornerToPointIndex(CornerIndex ci) const {
- return mesh_->CornerToPointId(ci);
- }
-
- // Returns the opposite corner in case the opposite triangle does not lie
- // across an attribute seam. Otherwise return kInvalidCornerIndex.
- CornerIndex GetOppositeCorner(CornerIndex ci) const {
- const CornerIndex oci = corner_table_->Opposite(ci);
- if (oci < 0) {
- return kInvalidCornerIndex;
- }
- // Ensure the point ids are same on both sides of the shared edge between
- // the triangles.
- if (CornerToPointIndex(corner_table_->Next(ci)) !=
- CornerToPointIndex(corner_table_->Previous(oci))) {
- return kInvalidCornerIndex;
- }
- if (CornerToPointIndex(corner_table_->Previous(ci)) !=
- CornerToPointIndex(corner_table_->Next(oci))) {
- return kInvalidCornerIndex;
- }
- return oci;
- }
-
- void GenerateStripsFromCorner(int local_strip_id, CornerIndex ci);
-
- const Mesh *mesh_;
- std::unique_ptr<CornerTable> corner_table_;
-
- // Store strip faces for each of three possible directions from a given face.
- std::vector<FaceIndex> strip_faces_[3];
- // Start corner for each direction of the strip containing the processed face.
- CornerIndex strip_start_corners_[3];
- IndexTypeVector<FaceIndex, bool> is_face_visited_;
- // The number of strips generated by this method.
- int num_strips_;
- // The number of encoded triangles.
- int num_encoded_faces_;
- // Last encoded point.
- PointIndex last_encoded_point_;
-};
-
-template <typename OutputIteratorT, typename IndexTypeT>
-bool MeshStripifier::GenerateTriangleStripsWithPrimitiveRestart(
- const Mesh &mesh, IndexTypeT primitive_restart_index,
- OutputIteratorT out_it) {
- if (!Prepare(mesh)) {
- return false;
- }
-
- // Go over all faces and generate strips from the first unvisited one.
- for (FaceIndex fi(0); fi < mesh.num_faces(); ++fi) {
- if (is_face_visited_[fi]) {
- continue;
- }
-
- const int longest_strip_id = FindLongestStripFromFace(fi);
-
- // Separate triangle strips with the primitive restart index.
- if (num_strips_ > 0) {
- *out_it++ = primitive_restart_index;
- }
-
- StoreStrip(longest_strip_id, out_it);
- }
-
- return true;
-}
-
-template <typename OutputIteratorT>
-bool MeshStripifier::GenerateTriangleStripsWithDegenerateTriangles(
- const Mesh &mesh, OutputIteratorT out_it) {
- if (!Prepare(mesh)) {
- return false;
- }
-
- // Go over all faces and generate strips from the first unvisited one.
- for (FaceIndex fi(0); fi < mesh.num_faces(); ++fi) {
- if (is_face_visited_[fi]) {
- continue;
- }
-
- const int longest_strip_id = FindLongestStripFromFace(fi);
-
- // Separate triangle strips by degenerate triangles. There will be either
- // three or four degenerate triangles inserted based on the number of
- // triangles that are already encoded in the output strip (three degenerate
- // triangles for even number of existing triangles, four degenerate
- // triangles for odd number of triangles).
- if (num_strips_ > 0) {
- // Duplicate last encoded index (first degenerate face).
- *out_it++ = last_encoded_point_.value();
-
- // Connect it to the start point of the new triangle strip (second
- // degenerate face).
- const CornerIndex new_start_corner =
- strip_start_corners_[longest_strip_id];
- const PointIndex new_start_point = CornerToPointIndex(new_start_corner);
- *out_it++ = new_start_point.value();
- num_encoded_faces_ += 2;
- // If we have previously encoded number of faces we need to duplicate the
- // point one more time to preserve the correct orientation of the next
- // strip.
- if (num_encoded_faces_ & 1) {
- *out_it++ = new_start_point.value();
- num_encoded_faces_ += 1;
- }
- // The last degenerate face will be added implicitly in the StoreStrip()
- // function below as the first point index is going to be encoded there
- // again.
- }
-
- StoreStrip(longest_strip_id, out_it);
- }
-
- return true;
-}
-
-} // namespace draco
-
-#endif // DRACO_MESH_MESH_STRIPIFIER_H_