dracox 0.0.1__cp39-cp39-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bin/draco_decoder.exe +0 -0
- bin/draco_encoder.exe +0 -0
- dracox/__init__.py +252 -0
- dracox/dracox_ext.cp39-win_amd64.pyd +0 -0
- dracox-0.0.1.dist-info/METADATA +14 -0
- dracox-0.0.1.dist-info/RECORD +214 -0
- dracox-0.0.1.dist-info/WHEEL +5 -0
- include/draco/animation/keyframe_animation.h +107 -0
- include/draco/animation/keyframe_animation_decoder.h +34 -0
- include/draco/animation/keyframe_animation_encoder.h +39 -0
- include/draco/attributes/attribute_octahedron_transform.h +81 -0
- include/draco/attributes/attribute_quantization_transform.h +102 -0
- include/draco/attributes/attribute_transform.h +76 -0
- include/draco/attributes/attribute_transform_data.h +71 -0
- include/draco/attributes/attribute_transform_type.h +30 -0
- include/draco/attributes/geometry_attribute.h +541 -0
- include/draco/attributes/geometry_indices.h +54 -0
- include/draco/attributes/point_attribute.h +196 -0
- include/draco/compression/attributes/attributes_decoder.h +97 -0
- include/draco/compression/attributes/attributes_decoder_interface.h +62 -0
- include/draco/compression/attributes/attributes_encoder.h +154 -0
- include/draco/compression/attributes/kd_tree_attributes_decoder.h +50 -0
- include/draco/compression/attributes/kd_tree_attributes_encoder.h +51 -0
- include/draco/compression/attributes/kd_tree_attributes_shared.h +28 -0
- include/draco/compression/attributes/linear_sequencer.h +51 -0
- include/draco/compression/attributes/mesh_attribute_indices_encoding_data.h +58 -0
- include/draco/compression/attributes/normal_compression_utils.h +372 -0
- include/draco/compression/attributes/point_d_vector.h +288 -0
- include/draco/compression/attributes/points_sequencer.h +63 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h +236 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h +413 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h +34 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h +72 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h +46 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h +46 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h +176 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h +180 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h +117 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h +96 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h +128 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h +133 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h +111 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h +78 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h +372 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h +318 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h +143 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h +136 -0
- include/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h +282 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h +90 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h +194 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h +53 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h +65 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h +65 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h +69 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h +90 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h +134 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h +55 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h +77 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h +85 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h +60 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h +118 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h +116 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h +102 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h +115 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h +105 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h +90 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h +88 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h +81 -0
- include/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h +120 -0
- include/draco/compression/attributes/sequential_attribute_decoder.h +86 -0
- include/draco/compression/attributes/sequential_attribute_decoders_controller.h +61 -0
- include/draco/compression/attributes/sequential_attribute_encoder.h +134 -0
- include/draco/compression/attributes/sequential_attribute_encoders_controller.h +115 -0
- include/draco/compression/attributes/sequential_integer_attribute_decoder.h +76 -0
- include/draco/compression/attributes/sequential_integer_attribute_encoder.h +67 -0
- include/draco/compression/attributes/sequential_normal_attribute_decoder.h +83 -0
- include/draco/compression/attributes/sequential_normal_attribute_encoder.h +82 -0
- include/draco/compression/attributes/sequential_quantization_attribute_decoder.h +52 -0
- include/draco/compression/attributes/sequential_quantization_attribute_encoder.h +52 -0
- include/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h +43 -0
- include/draco/compression/bit_coders/adaptive_rans_bit_decoder.h +54 -0
- include/draco/compression/bit_coders/adaptive_rans_bit_encoder.h +61 -0
- include/draco/compression/bit_coders/direct_bit_decoder.h +89 -0
- include/draco/compression/bit_coders/direct_bit_encoder.h +89 -0
- include/draco/compression/bit_coders/folded_integer_bit_decoder.h +77 -0
- include/draco/compression/bit_coders/folded_integer_bit_encoder.h +82 -0
- include/draco/compression/bit_coders/rans_bit_decoder.h +55 -0
- include/draco/compression/bit_coders/rans_bit_encoder.h +57 -0
- include/draco/compression/bit_coders/symbol_bit_decoder.h +36 -0
- include/draco/compression/bit_coders/symbol_bit_encoder.h +36 -0
- include/draco/compression/config/compression_shared.h +155 -0
- include/draco/compression/config/decoder_options.h +34 -0
- include/draco/compression/config/draco_options.h +249 -0
- include/draco/compression/config/encoder_options.h +101 -0
- include/draco/compression/config/encoding_features.h +39 -0
- include/draco/compression/decode.h +80 -0
- include/draco/compression/draco_compression_options.h +141 -0
- include/draco/compression/encode.h +139 -0
- include/draco/compression/encode_base.h +131 -0
- include/draco/compression/entropy/ans.h +526 -0
- include/draco/compression/entropy/rans_symbol_coding.h +53 -0
- include/draco/compression/entropy/rans_symbol_decoder.h +171 -0
- include/draco/compression/entropy/rans_symbol_encoder.h +290 -0
- include/draco/compression/entropy/shannon_entropy.h +110 -0
- include/draco/compression/entropy/symbol_decoding.h +29 -0
- include/draco/compression/entropy/symbol_encoding.h +47 -0
- include/draco/compression/expert_encode.h +160 -0
- include/draco/compression/mesh/mesh_decoder.h +68 -0
- include/draco/compression/mesh/mesh_edgebreaker_decoder.h +54 -0
- include/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h +228 -0
- include/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h +47 -0
- include/draco/compression/mesh/mesh_edgebreaker_encoder.h +73 -0
- include/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h +209 -0
- include/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h +57 -0
- include/draco/compression/mesh/mesh_edgebreaker_shared.h +129 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h +201 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h +139 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h +134 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h +172 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h +219 -0
- include/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h +226 -0
- include/draco/compression/mesh/mesh_encoder.h +84 -0
- include/draco/compression/mesh/mesh_sequential_decoder.h +39 -0
- include/draco/compression/mesh/mesh_sequential_encoder.h +56 -0
- include/draco/compression/mesh/traverser/depth_first_traverser.h +172 -0
- include/draco/compression/mesh/traverser/max_prediction_degree_traverser.h +226 -0
- include/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h +76 -0
- include/draco/compression/mesh/traverser/mesh_traversal_sequencer.h +113 -0
- include/draco/compression/mesh/traverser/traverser_base.h +87 -0
- include/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h +369 -0
- include/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h +372 -0
- include/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h +141 -0
- include/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h +126 -0
- include/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h +34 -0
- include/draco/compression/point_cloud/algorithms/point_cloud_types.h +76 -0
- include/draco/compression/point_cloud/algorithms/quantize_points_3.h +84 -0
- include/draco/compression/point_cloud/algorithms/queuing_policy.h +75 -0
- include/draco/compression/point_cloud/point_cloud_decoder.h +118 -0
- include/draco/compression/point_cloud/point_cloud_encoder.h +158 -0
- include/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h +31 -0
- include/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h +45 -0
- include/draco/compression/point_cloud/point_cloud_sequential_decoder.h +33 -0
- include/draco/compression/point_cloud/point_cloud_sequential_encoder.h +43 -0
- include/draco/core/bit_utils.h +127 -0
- include/draco/core/bounding_box.h +77 -0
- include/draco/core/constants.h +6 -0
- include/draco/core/cycle_timer.h +51 -0
- include/draco/core/data_buffer.h +82 -0
- include/draco/core/decoder_buffer.h +216 -0
- include/draco/core/divide.h +42 -0
- include/draco/core/draco_index_type.h +184 -0
- include/draco/core/draco_index_type_vector.h +90 -0
- include/draco/core/draco_types.h +52 -0
- include/draco/core/draco_version.h +25 -0
- include/draco/core/encoder_buffer.h +152 -0
- include/draco/core/hash_utils.h +64 -0
- include/draco/core/macros.h +124 -0
- include/draco/core/math_utils.h +79 -0
- include/draco/core/options.h +151 -0
- include/draco/core/quantization_utils.h +82 -0
- include/draco/core/status.h +83 -0
- include/draco/core/status_or.h +81 -0
- include/draco/core/varint_decoding.h +81 -0
- include/draco/core/varint_encoding.h +61 -0
- include/draco/core/vector_d.h +355 -0
- include/draco/draco_features.h +25 -0
- include/draco/io/file_reader_factory.h +34 -0
- include/draco/io/file_reader_interface.h +32 -0
- include/draco/io/file_utils.h +86 -0
- include/draco/io/file_writer_factory.h +34 -0
- include/draco/io/file_writer_interface.h +26 -0
- include/draco/io/file_writer_utils.h +38 -0
- include/draco/io/mesh_io.h +107 -0
- include/draco/io/obj_decoder.h +147 -0
- include/draco/io/obj_encoder.h +107 -0
- include/draco/io/parser_utils.h +66 -0
- include/draco/io/ply_decoder.h +69 -0
- include/draco/io/ply_encoder.h +54 -0
- include/draco/io/ply_property_reader.h +96 -0
- include/draco/io/ply_property_writer.h +94 -0
- include/draco/io/ply_reader.h +155 -0
- include/draco/io/point_cloud_io.h +89 -0
- include/draco/io/stdio_file_reader.h +48 -0
- include/draco/io/stdio_file_writer.h +42 -0
- include/draco/io/stl_decoder.h +38 -0
- include/draco/io/stl_encoder.h +52 -0
- include/draco/mesh/corner_table.h +397 -0
- include/draco/mesh/corner_table_iterators.h +309 -0
- include/draco/mesh/mesh.h +378 -0
- include/draco/mesh/mesh_are_equivalent.h +71 -0
- include/draco/mesh/mesh_attribute_corner_table.h +202 -0
- include/draco/mesh/mesh_cleanup.h +61 -0
- include/draco/mesh/mesh_features.h +93 -0
- include/draco/mesh/mesh_indices.h +37 -0
- include/draco/mesh/mesh_misc_functions.h +105 -0
- include/draco/mesh/mesh_stripifier.h +258 -0
- include/draco/mesh/triangle_soup_mesh_builder.h +134 -0
- include/draco/mesh/valence_cache.h +142 -0
- include/draco/metadata/geometry_metadata.h +142 -0
- include/draco/metadata/metadata.h +209 -0
- include/draco/metadata/metadata_decoder.h +42 -0
- include/draco/metadata/metadata_encoder.h +41 -0
- include/draco/metadata/property_attribute.h +107 -0
- include/draco/metadata/property_table.h +222 -0
- include/draco/metadata/structural_metadata.h +78 -0
- include/draco/metadata/structural_metadata_schema.h +118 -0
- include/draco/point_cloud/point_cloud.h +289 -0
- include/draco/point_cloud/point_cloud_builder.h +101 -0
- lib/draco.lib +0 -0
- lib/pkgconfig/draco.pc +6 -0
- share/cmake/draco/draco-config-version.cmake +43 -0
- share/cmake/draco/draco-config.cmake +27 -0
- share/cmake/draco/draco-targets-release.cmake +19 -0
- share/cmake/draco/draco-targets.cmake +107 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
// Copyright 2016 The Draco Authors.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
#ifndef DRACO_MESH_CORNER_TABLE_H_
|
|
16
|
+
#define DRACO_MESH_CORNER_TABLE_H_
|
|
17
|
+
|
|
18
|
+
#include <array>
|
|
19
|
+
#include <memory>
|
|
20
|
+
|
|
21
|
+
#include "draco/attributes/geometry_indices.h"
|
|
22
|
+
#include "draco/core/draco_index_type_vector.h"
|
|
23
|
+
#include "draco/core/macros.h"
|
|
24
|
+
#include "draco/draco_features.h"
|
|
25
|
+
#include "draco/mesh/valence_cache.h"
|
|
26
|
+
|
|
27
|
+
namespace draco {
|
|
28
|
+
|
|
29
|
+
// CornerTable is used to represent connectivity of triangular meshes.
|
|
30
|
+
// For every corner of all faces, the corner table stores the index of the
|
|
31
|
+
// opposite corner in the neighboring face (if it exists) as illustrated in the
|
|
32
|
+
// figure below (see corner |c| and it's opposite corner |o|).
|
|
33
|
+
//
|
|
34
|
+
// *
|
|
35
|
+
// /c\
|
|
36
|
+
// / \
|
|
37
|
+
// /n p\
|
|
38
|
+
// *-------*
|
|
39
|
+
// \ /
|
|
40
|
+
// \ /
|
|
41
|
+
// \o/
|
|
42
|
+
// *
|
|
43
|
+
//
|
|
44
|
+
// All corners are defined by unique CornerIndex and each triplet of corners
|
|
45
|
+
// that define a single face id always ordered consecutively as:
|
|
46
|
+
// { 3 * FaceIndex, 3 * FaceIndex + 1, 3 * FaceIndex +2 }.
|
|
47
|
+
// This representation of corners allows CornerTable to easily retrieve Next and
|
|
48
|
+
// Previous corners on any face (see corners |n| and |p| in the figure above).
|
|
49
|
+
// Using the Next, Previous, and Opposite corners then enables traversal of any
|
|
50
|
+
// 2-manifold surface.
|
|
51
|
+
// If the CornerTable is constructed from a non-manifold surface, the input
|
|
52
|
+
// non-manifold edges and vertices are automatically split.
|
|
53
|
+
class CornerTable {
|
|
54
|
+
public:
|
|
55
|
+
// Corner table face type.
|
|
56
|
+
typedef std::array<VertexIndex, 3> FaceType;
|
|
57
|
+
|
|
58
|
+
CornerTable();
|
|
59
|
+
static std::unique_ptr<CornerTable> Create(
|
|
60
|
+
const IndexTypeVector<FaceIndex, FaceType> &faces);
|
|
61
|
+
|
|
62
|
+
// Initializes the CornerTable from provides set of indexed faces.
|
|
63
|
+
// The input faces can represent a non-manifold topology, in which case the
|
|
64
|
+
// non-manifold edges and vertices are going to be split.
|
|
65
|
+
bool Init(const IndexTypeVector<FaceIndex, FaceType> &faces);
|
|
66
|
+
|
|
67
|
+
// Resets the corner table to the given number of invalid faces.
|
|
68
|
+
bool Reset(int num_faces);
|
|
69
|
+
|
|
70
|
+
// Resets the corner table to the given number of invalid faces and vertices.
|
|
71
|
+
bool Reset(int num_faces, int num_vertices);
|
|
72
|
+
|
|
73
|
+
inline int num_vertices() const {
|
|
74
|
+
return static_cast<int>(vertex_corners_.size());
|
|
75
|
+
}
|
|
76
|
+
inline int num_corners() const {
|
|
77
|
+
return static_cast<int>(corner_to_vertex_map_.size());
|
|
78
|
+
}
|
|
79
|
+
inline int num_faces() const {
|
|
80
|
+
return static_cast<int>(corner_to_vertex_map_.size() / 3);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
inline CornerIndex Opposite(CornerIndex corner) const {
|
|
84
|
+
if (corner == kInvalidCornerIndex) {
|
|
85
|
+
return corner;
|
|
86
|
+
}
|
|
87
|
+
return opposite_corners_[corner];
|
|
88
|
+
}
|
|
89
|
+
inline CornerIndex Next(CornerIndex corner) const {
|
|
90
|
+
if (corner == kInvalidCornerIndex) {
|
|
91
|
+
return corner;
|
|
92
|
+
}
|
|
93
|
+
return LocalIndex(++corner) ? corner : corner - 3;
|
|
94
|
+
}
|
|
95
|
+
inline CornerIndex Previous(CornerIndex corner) const {
|
|
96
|
+
if (corner == kInvalidCornerIndex) {
|
|
97
|
+
return corner;
|
|
98
|
+
}
|
|
99
|
+
return LocalIndex(corner) ? corner - 1 : corner + 2;
|
|
100
|
+
}
|
|
101
|
+
inline VertexIndex Vertex(CornerIndex corner) const {
|
|
102
|
+
if (corner == kInvalidCornerIndex) {
|
|
103
|
+
return kInvalidVertexIndex;
|
|
104
|
+
}
|
|
105
|
+
return ConfidentVertex(corner);
|
|
106
|
+
}
|
|
107
|
+
inline VertexIndex ConfidentVertex(CornerIndex corner) const {
|
|
108
|
+
DRACO_DCHECK_GE(corner.value(), 0);
|
|
109
|
+
DRACO_DCHECK_LT(corner.value(), num_corners());
|
|
110
|
+
return corner_to_vertex_map_[corner];
|
|
111
|
+
}
|
|
112
|
+
inline FaceIndex Face(CornerIndex corner) const {
|
|
113
|
+
if (corner == kInvalidCornerIndex) {
|
|
114
|
+
return kInvalidFaceIndex;
|
|
115
|
+
}
|
|
116
|
+
return FaceIndex(corner.value() / 3);
|
|
117
|
+
}
|
|
118
|
+
inline CornerIndex FirstCorner(FaceIndex face) const {
|
|
119
|
+
if (face == kInvalidFaceIndex) {
|
|
120
|
+
return kInvalidCornerIndex;
|
|
121
|
+
}
|
|
122
|
+
return CornerIndex(face.value() * 3);
|
|
123
|
+
}
|
|
124
|
+
inline std::array<CornerIndex, 3> AllCorners(FaceIndex face) const {
|
|
125
|
+
const CornerIndex ci = CornerIndex(face.value() * 3);
|
|
126
|
+
return {{ci, ci + 1, ci + 2}};
|
|
127
|
+
}
|
|
128
|
+
inline int LocalIndex(CornerIndex corner) const { return corner.value() % 3; }
|
|
129
|
+
|
|
130
|
+
inline FaceType FaceData(FaceIndex face) const {
|
|
131
|
+
const CornerIndex first_corner = FirstCorner(face);
|
|
132
|
+
FaceType face_data;
|
|
133
|
+
for (int i = 0; i < 3; ++i) {
|
|
134
|
+
face_data[i] = corner_to_vertex_map_[first_corner + i];
|
|
135
|
+
}
|
|
136
|
+
return face_data;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
void SetFaceData(FaceIndex face, FaceType data) {
|
|
140
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
141
|
+
const CornerIndex first_corner = FirstCorner(face);
|
|
142
|
+
for (int i = 0; i < 3; ++i) {
|
|
143
|
+
corner_to_vertex_map_[first_corner + i] = data[i];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Returns the left-most corner of a single vertex 1-ring. If a vertex is not
|
|
148
|
+
// on a boundary (in which case it has a full 1-ring), this function returns
|
|
149
|
+
// any of the corners mapped to the given vertex.
|
|
150
|
+
inline CornerIndex LeftMostCorner(VertexIndex v) const {
|
|
151
|
+
return vertex_corners_[v];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Returns the parent vertex index of a given corner table vertex.
|
|
155
|
+
VertexIndex VertexParent(VertexIndex vertex) const {
|
|
156
|
+
if (vertex.value() < static_cast<uint32_t>(num_original_vertices_)) {
|
|
157
|
+
return vertex;
|
|
158
|
+
}
|
|
159
|
+
return non_manifold_vertex_parents_[vertex - num_original_vertices_];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Returns true if the corner is valid.
|
|
163
|
+
inline bool IsValid(CornerIndex c) const {
|
|
164
|
+
return Vertex(c) != kInvalidVertexIndex;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Returns the valence (or degree) of a vertex.
|
|
168
|
+
// Returns -1 if the given vertex index is not valid.
|
|
169
|
+
int Valence(VertexIndex v) const;
|
|
170
|
+
// Same as above but does not check for validity and does not return -1
|
|
171
|
+
int ConfidentValence(VertexIndex v) const;
|
|
172
|
+
// Returns the valence of the vertex at the given corner.
|
|
173
|
+
inline int Valence(CornerIndex c) const {
|
|
174
|
+
if (c == kInvalidCornerIndex) {
|
|
175
|
+
return -1;
|
|
176
|
+
}
|
|
177
|
+
return ConfidentValence(c);
|
|
178
|
+
}
|
|
179
|
+
inline int ConfidentValence(CornerIndex c) const {
|
|
180
|
+
DRACO_DCHECK_LT(c.value(), num_corners());
|
|
181
|
+
return ConfidentValence(ConfidentVertex(c));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Returns true if the specified vertex is on a boundary.
|
|
185
|
+
inline bool IsOnBoundary(VertexIndex vert) const {
|
|
186
|
+
const CornerIndex corner = LeftMostCorner(vert);
|
|
187
|
+
if (SwingLeft(corner) == kInvalidCornerIndex) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// *-------*
|
|
194
|
+
// / \ / \
|
|
195
|
+
// / \ / \
|
|
196
|
+
// / sl\c/sr \
|
|
197
|
+
// *-------v-------*
|
|
198
|
+
// Returns the corner on the adjacent face on the right that maps to
|
|
199
|
+
// the same vertex as the given corner (sr in the above diagram).
|
|
200
|
+
inline CornerIndex SwingRight(CornerIndex corner) const {
|
|
201
|
+
return Previous(Opposite(Previous(corner)));
|
|
202
|
+
}
|
|
203
|
+
// Returns the corner on the left face that maps to the same vertex as the
|
|
204
|
+
// given corner (sl in the above diagram).
|
|
205
|
+
inline CornerIndex SwingLeft(CornerIndex corner) const {
|
|
206
|
+
return Next(Opposite(Next(corner)));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Get opposite corners on the left and right faces respectively (see image
|
|
210
|
+
// below, where L and R are the left and right corners of a corner X.
|
|
211
|
+
//
|
|
212
|
+
// *-------*-------*
|
|
213
|
+
// \L /X\ R/
|
|
214
|
+
// \ / \ /
|
|
215
|
+
// \ / \ /
|
|
216
|
+
// *-------*
|
|
217
|
+
inline CornerIndex GetLeftCorner(CornerIndex corner_id) const {
|
|
218
|
+
if (corner_id == kInvalidCornerIndex) {
|
|
219
|
+
return kInvalidCornerIndex;
|
|
220
|
+
}
|
|
221
|
+
return Opposite(Previous(corner_id));
|
|
222
|
+
}
|
|
223
|
+
inline CornerIndex GetRightCorner(CornerIndex corner_id) const {
|
|
224
|
+
if (corner_id == kInvalidCornerIndex) {
|
|
225
|
+
return kInvalidCornerIndex;
|
|
226
|
+
}
|
|
227
|
+
return Opposite(Next(corner_id));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Returns the number of new vertices that were created as a result of
|
|
231
|
+
// splitting of non-manifold vertices of the input geometry.
|
|
232
|
+
int NumNewVertices() const { return num_vertices() - num_original_vertices_; }
|
|
233
|
+
int NumOriginalVertices() const { return num_original_vertices_; }
|
|
234
|
+
|
|
235
|
+
// Returns the number of faces with duplicated vertex indices.
|
|
236
|
+
int NumDegeneratedFaces() const { return num_degenerated_faces_; }
|
|
237
|
+
|
|
238
|
+
// Returns the number of isolated vertices (vertices that have
|
|
239
|
+
// vertex_corners_ mapping set to kInvalidCornerIndex.
|
|
240
|
+
int NumIsolatedVertices() const { return num_isolated_vertices_; }
|
|
241
|
+
|
|
242
|
+
bool IsDegenerated(FaceIndex face) const;
|
|
243
|
+
|
|
244
|
+
// Methods that modify an existing corner table.
|
|
245
|
+
// Sets the opposite corner mapping between two corners. Caller must ensure
|
|
246
|
+
// that the indices are valid.
|
|
247
|
+
inline void SetOppositeCorner(CornerIndex corner_id,
|
|
248
|
+
CornerIndex opp_corner_id) {
|
|
249
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
250
|
+
opposite_corners_[corner_id] = opp_corner_id;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Sets opposite corners for both input corners.
|
|
254
|
+
inline void SetOppositeCorners(CornerIndex corner_0, CornerIndex corner_1) {
|
|
255
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
256
|
+
if (corner_0 != kInvalidCornerIndex) {
|
|
257
|
+
SetOppositeCorner(corner_0, corner_1);
|
|
258
|
+
}
|
|
259
|
+
if (corner_1 != kInvalidCornerIndex) {
|
|
260
|
+
SetOppositeCorner(corner_1, corner_0);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Updates mapping between a corner and a vertex.
|
|
265
|
+
inline void MapCornerToVertex(CornerIndex corner_id, VertexIndex vert_id) {
|
|
266
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
267
|
+
corner_to_vertex_map_[corner_id] = vert_id;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
VertexIndex AddNewVertex() {
|
|
271
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
272
|
+
// Add a new invalid vertex.
|
|
273
|
+
vertex_corners_.push_back(kInvalidCornerIndex);
|
|
274
|
+
return VertexIndex(static_cast<uint32_t>(vertex_corners_.size() - 1));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Adds a new face connected to three vertices. Note that connectivity is not
|
|
278
|
+
// automatically updated and all opposite corners need to be set explicitly.
|
|
279
|
+
FaceIndex AddNewFace(const std::array<VertexIndex, 3> &vertices) {
|
|
280
|
+
// Add a new invalid face.
|
|
281
|
+
const FaceIndex new_face_index(num_faces());
|
|
282
|
+
for (int i = 0; i < 3; ++i) {
|
|
283
|
+
corner_to_vertex_map_.push_back(vertices[i]);
|
|
284
|
+
SetLeftMostCorner(vertices[i],
|
|
285
|
+
CornerIndex(corner_to_vertex_map_.size() - 1));
|
|
286
|
+
}
|
|
287
|
+
opposite_corners_.resize(corner_to_vertex_map_.size(), kInvalidCornerIndex);
|
|
288
|
+
return new_face_index;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Sets a new left most corner for a given vertex.
|
|
292
|
+
void SetLeftMostCorner(VertexIndex vert, CornerIndex corner) {
|
|
293
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
294
|
+
if (vert != kInvalidVertexIndex) {
|
|
295
|
+
vertex_corners_[vert] = corner;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Updates the vertex to corner map on a specified vertex. This should be
|
|
300
|
+
// called in cases where the mapping may be invalid (e.g. when the corner
|
|
301
|
+
// table was constructed manually).
|
|
302
|
+
void UpdateVertexToCornerMap(VertexIndex vert) {
|
|
303
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
304
|
+
const CornerIndex first_c = vertex_corners_[vert];
|
|
305
|
+
if (first_c == kInvalidCornerIndex) {
|
|
306
|
+
return; // Isolated vertex.
|
|
307
|
+
}
|
|
308
|
+
CornerIndex act_c = SwingLeft(first_c);
|
|
309
|
+
CornerIndex c = first_c;
|
|
310
|
+
while (act_c != kInvalidCornerIndex && act_c != first_c) {
|
|
311
|
+
c = act_c;
|
|
312
|
+
act_c = SwingLeft(act_c);
|
|
313
|
+
}
|
|
314
|
+
if (act_c != first_c) {
|
|
315
|
+
vertex_corners_[vert] = c;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Sets the new number of vertices. It's a responsibility of the caller to
|
|
320
|
+
// ensure that no corner is mapped beyond the range of the new number of
|
|
321
|
+
// vertices.
|
|
322
|
+
inline void SetNumVertices(int num_vertices) {
|
|
323
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
324
|
+
vertex_corners_.resize(num_vertices, kInvalidCornerIndex);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Makes a vertex isolated (not attached to any corner).
|
|
328
|
+
void MakeVertexIsolated(VertexIndex vert) {
|
|
329
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
330
|
+
vertex_corners_[vert] = kInvalidCornerIndex;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Returns true if a vertex is not attached to any face.
|
|
334
|
+
inline bool IsVertexIsolated(VertexIndex v) const {
|
|
335
|
+
return LeftMostCorner(v) == kInvalidCornerIndex;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Makes a given face invalid (all corners are marked as invalid).
|
|
339
|
+
void MakeFaceInvalid(FaceIndex face) {
|
|
340
|
+
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
|
|
341
|
+
if (face != kInvalidFaceIndex) {
|
|
342
|
+
const CornerIndex first_corner = FirstCorner(face);
|
|
343
|
+
for (int i = 0; i < 3; ++i) {
|
|
344
|
+
corner_to_vertex_map_[first_corner + i] = kInvalidVertexIndex;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Updates mapping between faces and a vertex using the corners mapped to
|
|
350
|
+
// the provided vertex.
|
|
351
|
+
void UpdateFaceToVertexMap(const VertexIndex vertex);
|
|
352
|
+
|
|
353
|
+
// Allows access to an internal object for caching valences. The object can
|
|
354
|
+
// be instructed to cache or uncache all valences and then its interfaces
|
|
355
|
+
// queried directly for valences with differing performance/confidence
|
|
356
|
+
// qualities. If the mesh or table is modified the cache should be discarded
|
|
357
|
+
// and not relied on as it does not automatically update or invalidate for
|
|
358
|
+
// performance reasons.
|
|
359
|
+
const draco::ValenceCache<CornerTable> &GetValenceCache() const {
|
|
360
|
+
return valence_cache_;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
private:
|
|
364
|
+
// Computes opposite corners mapping from the data stored in
|
|
365
|
+
// |corner_to_vertex_map_|.
|
|
366
|
+
bool ComputeOppositeCorners(int *num_vertices);
|
|
367
|
+
|
|
368
|
+
// Finds and breaks non-manifold edges in the 1-ring neighborhood around
|
|
369
|
+
// vertices (vertices themselves will be split in the ComputeVertexCorners()
|
|
370
|
+
// function if necessary).
|
|
371
|
+
bool BreakNonManifoldEdges();
|
|
372
|
+
|
|
373
|
+
// Computes the lookup map for going from a vertex to a corner. This method
|
|
374
|
+
// can handle non-manifold vertices by splitting them into multiple manifold
|
|
375
|
+
// vertices.
|
|
376
|
+
bool ComputeVertexCorners(int num_vertices);
|
|
377
|
+
|
|
378
|
+
// Each three consecutive corners represent one face.
|
|
379
|
+
IndexTypeVector<CornerIndex, VertexIndex> corner_to_vertex_map_;
|
|
380
|
+
IndexTypeVector<CornerIndex, CornerIndex> opposite_corners_;
|
|
381
|
+
IndexTypeVector<VertexIndex, CornerIndex> vertex_corners_;
|
|
382
|
+
|
|
383
|
+
int num_original_vertices_;
|
|
384
|
+
int num_degenerated_faces_;
|
|
385
|
+
int num_isolated_vertices_;
|
|
386
|
+
IndexTypeVector<VertexIndex, VertexIndex> non_manifold_vertex_parents_;
|
|
387
|
+
|
|
388
|
+
draco::ValenceCache<CornerTable> valence_cache_;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// A special case to denote an invalid corner table triangle.
|
|
392
|
+
static constexpr CornerTable::FaceType kInvalidFace(
|
|
393
|
+
{{kInvalidVertexIndex, kInvalidVertexIndex, kInvalidVertexIndex}});
|
|
394
|
+
|
|
395
|
+
} // namespace draco
|
|
396
|
+
|
|
397
|
+
#endif // DRACO_MESH_CORNER_TABLE_H_
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Copyright 2016 The Draco Authors.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
#ifndef DRACO_MESH_CORNER_TABLE_ITERATORS_H_
|
|
16
|
+
#define DRACO_MESH_CORNER_TABLE_ITERATORS_H_
|
|
17
|
+
|
|
18
|
+
#include <iterator>
|
|
19
|
+
|
|
20
|
+
#include "draco/mesh/corner_table.h"
|
|
21
|
+
|
|
22
|
+
namespace draco {
|
|
23
|
+
|
|
24
|
+
// Class for iterating over vertices in a 1-ring around the specified vertex.
|
|
25
|
+
template <class CornerTableT>
|
|
26
|
+
class VertexRingIterator {
|
|
27
|
+
public:
|
|
28
|
+
// Iterator traits expected by std libraries.
|
|
29
|
+
using iterator_category = std::forward_iterator_tag;
|
|
30
|
+
using value_type = VertexIndex;
|
|
31
|
+
using difference_type = std::ptrdiff_t;
|
|
32
|
+
using pointer = VertexIndex *;
|
|
33
|
+
using reference = VertexIndex &;
|
|
34
|
+
|
|
35
|
+
// std::iterator interface requires a default constructor.
|
|
36
|
+
VertexRingIterator()
|
|
37
|
+
: corner_table_(nullptr),
|
|
38
|
+
start_corner_(kInvalidCornerIndex),
|
|
39
|
+
corner_(start_corner_),
|
|
40
|
+
left_traversal_(true) {}
|
|
41
|
+
|
|
42
|
+
// Create the iterator from the provided corner table and the central vertex.
|
|
43
|
+
VertexRingIterator(const CornerTableT *table, VertexIndex vert_id)
|
|
44
|
+
: corner_table_(table),
|
|
45
|
+
start_corner_(table->LeftMostCorner(vert_id)),
|
|
46
|
+
corner_(start_corner_),
|
|
47
|
+
left_traversal_(true) {}
|
|
48
|
+
|
|
49
|
+
// Gets the last visited ring vertex.
|
|
50
|
+
VertexIndex Vertex() const {
|
|
51
|
+
CornerIndex ring_corner = left_traversal_ ? corner_table_->Previous(corner_)
|
|
52
|
+
: corner_table_->Next(corner_);
|
|
53
|
+
return corner_table_->Vertex(ring_corner);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Returns one of the corners opposite to the edge connecting the currently
|
|
57
|
+
// iterated ring vertex with the central vertex.
|
|
58
|
+
CornerIndex EdgeCorner() const {
|
|
59
|
+
return left_traversal_ ? corner_table_->Next(corner_)
|
|
60
|
+
: corner_table_->Previous(corner_);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Returns true when all ring vertices have been visited.
|
|
64
|
+
bool End() const { return corner_ == kInvalidCornerIndex; }
|
|
65
|
+
|
|
66
|
+
// Proceeds to the next ring vertex if possible.
|
|
67
|
+
void Next() {
|
|
68
|
+
if (left_traversal_) {
|
|
69
|
+
corner_ = corner_table_->SwingLeft(corner_);
|
|
70
|
+
if (corner_ == kInvalidCornerIndex) {
|
|
71
|
+
// Open boundary reached.
|
|
72
|
+
corner_ = start_corner_;
|
|
73
|
+
left_traversal_ = false;
|
|
74
|
+
} else if (corner_ == start_corner_) {
|
|
75
|
+
// End reached.
|
|
76
|
+
corner_ = kInvalidCornerIndex;
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
// Go to the right until we reach a boundary there (no explicit check
|
|
80
|
+
// is needed in this case).
|
|
81
|
+
corner_ = corner_table_->SwingRight(corner_);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// std::iterator interface.
|
|
86
|
+
value_type operator*() const { return Vertex(); }
|
|
87
|
+
VertexRingIterator &operator++() {
|
|
88
|
+
Next();
|
|
89
|
+
return *this;
|
|
90
|
+
}
|
|
91
|
+
VertexRingIterator operator++(int) {
|
|
92
|
+
const VertexRingIterator result = *this;
|
|
93
|
+
++(*this);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
bool operator!=(const VertexRingIterator &other) const {
|
|
97
|
+
return corner_ != other.corner_ || start_corner_ != other.start_corner_;
|
|
98
|
+
}
|
|
99
|
+
bool operator==(const VertexRingIterator &other) const {
|
|
100
|
+
return !this->operator!=(other);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Helper function for getting a valid end iterator.
|
|
104
|
+
static VertexRingIterator EndIterator(VertexRingIterator other) {
|
|
105
|
+
VertexRingIterator ret = other;
|
|
106
|
+
ret.corner_ = kInvalidCornerIndex;
|
|
107
|
+
return ret;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private:
|
|
111
|
+
const CornerTableT *corner_table_;
|
|
112
|
+
// The first processed corner.
|
|
113
|
+
CornerIndex start_corner_;
|
|
114
|
+
// The last processed corner.
|
|
115
|
+
CornerIndex corner_;
|
|
116
|
+
// Traversal direction.
|
|
117
|
+
bool left_traversal_;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Class for iterating over faces adjacent to the specified input face.
|
|
121
|
+
template <class CornerTableT>
|
|
122
|
+
class FaceAdjacencyIterator {
|
|
123
|
+
public:
|
|
124
|
+
// Iterator traits expected by std libraries.
|
|
125
|
+
using iterator_category = std::forward_iterator_tag;
|
|
126
|
+
using value_type = FaceIndex;
|
|
127
|
+
using difference_type = std::ptrdiff_t;
|
|
128
|
+
using pointer = FaceIndex *;
|
|
129
|
+
using reference = FaceIndex &;
|
|
130
|
+
|
|
131
|
+
// std::iterator interface requires a default constructor.
|
|
132
|
+
FaceAdjacencyIterator()
|
|
133
|
+
: corner_table_(nullptr),
|
|
134
|
+
start_corner_(kInvalidCornerIndex),
|
|
135
|
+
corner_(start_corner_) {}
|
|
136
|
+
|
|
137
|
+
// Create the iterator from the provided corner table and the central vertex.
|
|
138
|
+
FaceAdjacencyIterator(const CornerTableT *table, FaceIndex face_id)
|
|
139
|
+
: corner_table_(table),
|
|
140
|
+
start_corner_(table->FirstCorner(face_id)),
|
|
141
|
+
corner_(start_corner_) {
|
|
142
|
+
// We need to start with a corner that has a valid opposite face (if
|
|
143
|
+
// there is any such corner).
|
|
144
|
+
if (corner_table_->Opposite(corner_) == kInvalidCornerIndex) {
|
|
145
|
+
FindNextFaceNeighbor();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Gets the last visited adjacent face.
|
|
150
|
+
FaceIndex Face() const {
|
|
151
|
+
return corner_table_->Face(corner_table_->Opposite(corner_));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Returns true when all adjacent faces have been visited.
|
|
155
|
+
bool End() const { return corner_ == kInvalidCornerIndex; }
|
|
156
|
+
|
|
157
|
+
// Proceeds to the next adjacent face if possible.
|
|
158
|
+
void Next() { FindNextFaceNeighbor(); }
|
|
159
|
+
|
|
160
|
+
// std::iterator interface.
|
|
161
|
+
value_type operator*() const { return Face(); }
|
|
162
|
+
FaceAdjacencyIterator &operator++() {
|
|
163
|
+
Next();
|
|
164
|
+
return *this;
|
|
165
|
+
}
|
|
166
|
+
FaceAdjacencyIterator operator++(int) {
|
|
167
|
+
const FaceAdjacencyIterator result = *this;
|
|
168
|
+
++(*this);
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
bool operator!=(const FaceAdjacencyIterator &other) const {
|
|
172
|
+
return corner_ != other.corner_ || start_corner_ != other.start_corner_;
|
|
173
|
+
}
|
|
174
|
+
bool operator==(const FaceAdjacencyIterator &other) const {
|
|
175
|
+
return !this->operator!=(other);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Helper function for getting a valid end iterator.
|
|
179
|
+
static FaceAdjacencyIterator EndIterator(FaceAdjacencyIterator other) {
|
|
180
|
+
FaceAdjacencyIterator ret = other;
|
|
181
|
+
ret.corner_ = kInvalidCornerIndex;
|
|
182
|
+
return ret;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private:
|
|
186
|
+
// Finds the next corner with a valid opposite face.
|
|
187
|
+
void FindNextFaceNeighbor() {
|
|
188
|
+
while (corner_ != kInvalidCornerIndex) {
|
|
189
|
+
corner_ = corner_table_->Next(corner_);
|
|
190
|
+
if (corner_ == start_corner_) {
|
|
191
|
+
corner_ = kInvalidCornerIndex;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (corner_table_->Opposite(corner_) != kInvalidCornerIndex) {
|
|
195
|
+
// Valid opposite face.
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const CornerTableT *corner_table_;
|
|
202
|
+
// The first processed corner.
|
|
203
|
+
CornerIndex start_corner_;
|
|
204
|
+
// The last processed corner.
|
|
205
|
+
CornerIndex corner_;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Class for iterating over corners attached to a specified vertex.
|
|
209
|
+
template <class CornerTableT = CornerTable>
|
|
210
|
+
class VertexCornersIterator {
|
|
211
|
+
public:
|
|
212
|
+
// Iterator traits expected by std libraries.
|
|
213
|
+
using iterator_category = std::forward_iterator_tag;
|
|
214
|
+
using value_type = CornerIndex;
|
|
215
|
+
using difference_type = std::ptrdiff_t;
|
|
216
|
+
using pointer = CornerIndex *;
|
|
217
|
+
using reference = CornerIndex &;
|
|
218
|
+
|
|
219
|
+
// std::iterator interface requires a default constructor.
|
|
220
|
+
VertexCornersIterator()
|
|
221
|
+
: corner_table_(nullptr),
|
|
222
|
+
start_corner_(-1),
|
|
223
|
+
corner_(start_corner_),
|
|
224
|
+
left_traversal_(true) {}
|
|
225
|
+
|
|
226
|
+
// Create the iterator from the provided corner table and the central vertex.
|
|
227
|
+
VertexCornersIterator(const CornerTableT *table, VertexIndex vert_id)
|
|
228
|
+
: corner_table_(table),
|
|
229
|
+
start_corner_(table->LeftMostCorner(vert_id)),
|
|
230
|
+
corner_(start_corner_),
|
|
231
|
+
left_traversal_(true) {}
|
|
232
|
+
|
|
233
|
+
// Create the iterator from the provided corner table and the first corner.
|
|
234
|
+
VertexCornersIterator(const CornerTableT *table, CornerIndex corner_id)
|
|
235
|
+
: corner_table_(table),
|
|
236
|
+
start_corner_(corner_id),
|
|
237
|
+
corner_(start_corner_),
|
|
238
|
+
left_traversal_(true) {}
|
|
239
|
+
|
|
240
|
+
// Gets the last visited corner.
|
|
241
|
+
CornerIndex Corner() const { return corner_; }
|
|
242
|
+
|
|
243
|
+
// Returns true when all ring vertices have been visited.
|
|
244
|
+
bool End() const { return corner_ == kInvalidCornerIndex; }
|
|
245
|
+
|
|
246
|
+
// Proceeds to the next corner if possible.
|
|
247
|
+
void Next() {
|
|
248
|
+
if (left_traversal_) {
|
|
249
|
+
corner_ = corner_table_->SwingLeft(corner_);
|
|
250
|
+
if (corner_ == kInvalidCornerIndex) {
|
|
251
|
+
// Open boundary reached.
|
|
252
|
+
corner_ = corner_table_->SwingRight(start_corner_);
|
|
253
|
+
left_traversal_ = false;
|
|
254
|
+
} else if (corner_ == start_corner_) {
|
|
255
|
+
// End reached.
|
|
256
|
+
corner_ = kInvalidCornerIndex;
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
// Go to the right until we reach a boundary there (no explicit check
|
|
260
|
+
// is needed in this case).
|
|
261
|
+
corner_ = corner_table_->SwingRight(corner_);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// std::iterator interface.
|
|
266
|
+
CornerIndex operator*() const { return Corner(); }
|
|
267
|
+
VertexCornersIterator &operator++() {
|
|
268
|
+
Next();
|
|
269
|
+
return *this;
|
|
270
|
+
}
|
|
271
|
+
VertexCornersIterator operator++(int) {
|
|
272
|
+
const VertexCornersIterator result = *this;
|
|
273
|
+
++(*this);
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
bool operator!=(const VertexCornersIterator &other) const {
|
|
277
|
+
return corner_ != other.corner_ || start_corner_ != other.start_corner_;
|
|
278
|
+
}
|
|
279
|
+
bool operator==(const VertexCornersIterator &other) const {
|
|
280
|
+
return !this->operator!=(other);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Helper function for getting a valid end iterator.
|
|
284
|
+
static VertexCornersIterator EndIterator(VertexCornersIterator other) {
|
|
285
|
+
VertexCornersIterator ret = other;
|
|
286
|
+
ret.corner_ = kInvalidCornerIndex;
|
|
287
|
+
return ret;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
protected:
|
|
291
|
+
const CornerTableT *corner_table() const { return corner_table_; }
|
|
292
|
+
CornerIndex start_corner() const { return start_corner_; }
|
|
293
|
+
CornerIndex &corner() { return corner_; }
|
|
294
|
+
bool is_left_traversal() const { return left_traversal_; }
|
|
295
|
+
void swap_traversal() { left_traversal_ = !left_traversal_; }
|
|
296
|
+
|
|
297
|
+
private:
|
|
298
|
+
const CornerTableT *corner_table_;
|
|
299
|
+
// The first processed corner.
|
|
300
|
+
CornerIndex start_corner_;
|
|
301
|
+
// The last processed corner.
|
|
302
|
+
CornerIndex corner_;
|
|
303
|
+
// Traversal direction.
|
|
304
|
+
bool left_traversal_;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
} // namespace draco
|
|
308
|
+
|
|
309
|
+
#endif // DRACO_MESH_CORNER_TABLE_ITERATORS_H_
|