Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/draco/src/draco/mesh/corner_table.h
- This file was moved from extern/draco/dracoenc/src/draco/mesh/corner_table.h.
| Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | public: | ||||
| inline int num_corners() const { | inline int num_corners() const { | ||||
| return static_cast<int>(corner_to_vertex_map_.size()); | return static_cast<int>(corner_to_vertex_map_.size()); | ||||
| } | } | ||||
| inline int num_faces() const { | inline int num_faces() const { | ||||
| return static_cast<int>(corner_to_vertex_map_.size() / 3); | return static_cast<int>(corner_to_vertex_map_.size() / 3); | ||||
| } | } | ||||
| inline CornerIndex Opposite(CornerIndex corner) const { | inline CornerIndex Opposite(CornerIndex corner) const { | ||||
| if (corner == kInvalidCornerIndex) | if (corner == kInvalidCornerIndex) { | ||||
| return corner; | return corner; | ||||
| } | |||||
| return opposite_corners_[corner]; | return opposite_corners_[corner]; | ||||
| } | } | ||||
| inline CornerIndex Next(CornerIndex corner) const { | inline CornerIndex Next(CornerIndex corner) const { | ||||
| if (corner == kInvalidCornerIndex) | if (corner == kInvalidCornerIndex) { | ||||
| return corner; | return corner; | ||||
| } | |||||
| return LocalIndex(++corner) ? corner : corner - 3; | return LocalIndex(++corner) ? corner : corner - 3; | ||||
| } | } | ||||
| inline CornerIndex Previous(CornerIndex corner) const { | inline CornerIndex Previous(CornerIndex corner) const { | ||||
| if (corner == kInvalidCornerIndex) | if (corner == kInvalidCornerIndex) { | ||||
| return corner; | return corner; | ||||
| } | |||||
| return LocalIndex(corner) ? corner - 1 : corner + 2; | return LocalIndex(corner) ? corner - 1 : corner + 2; | ||||
| } | } | ||||
| inline VertexIndex Vertex(CornerIndex corner) const { | inline VertexIndex Vertex(CornerIndex corner) const { | ||||
| if (corner == kInvalidCornerIndex) | if (corner == kInvalidCornerIndex) { | ||||
| return kInvalidVertexIndex; | return kInvalidVertexIndex; | ||||
| } | |||||
| return ConfidentVertex(corner); | return ConfidentVertex(corner); | ||||
| } | } | ||||
| inline VertexIndex ConfidentVertex(CornerIndex corner) const { | inline VertexIndex ConfidentVertex(CornerIndex corner) const { | ||||
| DRACO_DCHECK_GE(corner.value(), 0); | DRACO_DCHECK_GE(corner.value(), 0); | ||||
| DRACO_DCHECK_LT(corner.value(), num_corners()); | DRACO_DCHECK_LT(corner.value(), num_corners()); | ||||
| return corner_to_vertex_map_[corner]; | return corner_to_vertex_map_[corner]; | ||||
| } | } | ||||
| inline FaceIndex Face(CornerIndex corner) const { | inline FaceIndex Face(CornerIndex corner) const { | ||||
| if (corner == kInvalidCornerIndex) | if (corner == kInvalidCornerIndex) { | ||||
| return kInvalidFaceIndex; | return kInvalidFaceIndex; | ||||
| } | |||||
| return FaceIndex(corner.value() / 3); | return FaceIndex(corner.value() / 3); | ||||
| } | } | ||||
| inline CornerIndex FirstCorner(FaceIndex face) const { | inline CornerIndex FirstCorner(FaceIndex face) const { | ||||
| if (face == kInvalidFaceIndex) | if (face == kInvalidFaceIndex) { | ||||
| return kInvalidCornerIndex; | return kInvalidCornerIndex; | ||||
| } | |||||
| return CornerIndex(face.value() * 3); | return CornerIndex(face.value() * 3); | ||||
| } | } | ||||
| inline std::array<CornerIndex, 3> AllCorners(FaceIndex face) const { | inline std::array<CornerIndex, 3> AllCorners(FaceIndex face) const { | ||||
| const CornerIndex ci = CornerIndex(face.value() * 3); | const CornerIndex ci = CornerIndex(face.value() * 3); | ||||
| return {{ci, ci + 1, ci + 2}}; | return {{ci, ci + 1, ci + 2}}; | ||||
| } | } | ||||
| inline int LocalIndex(CornerIndex corner) const { return corner.value() % 3; } | inline int LocalIndex(CornerIndex corner) const { return corner.value() % 3; } | ||||
| Show All 18 Lines | public: | ||||
| // on a boundary (in which case it has a full 1-ring), this function returns | // on a boundary (in which case it has a full 1-ring), this function returns | ||||
| // any of the corners mapped to the given vertex. | // any of the corners mapped to the given vertex. | ||||
| inline CornerIndex LeftMostCorner(VertexIndex v) const { | inline CornerIndex LeftMostCorner(VertexIndex v) const { | ||||
| return vertex_corners_[v]; | return vertex_corners_[v]; | ||||
| } | } | ||||
| // Returns the parent vertex index of a given corner table vertex. | // Returns the parent vertex index of a given corner table vertex. | ||||
| VertexIndex VertexParent(VertexIndex vertex) const { | VertexIndex VertexParent(VertexIndex vertex) const { | ||||
| if (vertex.value() < static_cast<uint32_t>(num_original_vertices_)) | if (vertex.value() < static_cast<uint32_t>(num_original_vertices_)) { | ||||
| return vertex; | return vertex; | ||||
| } | |||||
| return non_manifold_vertex_parents_[vertex - num_original_vertices_]; | return non_manifold_vertex_parents_[vertex - num_original_vertices_]; | ||||
| } | } | ||||
| // Returns true if the corner is valid. | // Returns true if the corner is valid. | ||||
| inline bool IsValid(CornerIndex c) const { | inline bool IsValid(CornerIndex c) const { | ||||
| return Vertex(c) != kInvalidVertexIndex; | return Vertex(c) != kInvalidVertexIndex; | ||||
| } | } | ||||
| // Returns the valence (or degree) of a vertex. | // Returns the valence (or degree) of a vertex. | ||||
| // Returns -1 if the given vertex index is not valid. | // Returns -1 if the given vertex index is not valid. | ||||
| int Valence(VertexIndex v) const; | int Valence(VertexIndex v) const; | ||||
| // Same as above but does not check for validity and does not return -1 | // Same as above but does not check for validity and does not return -1 | ||||
| int ConfidentValence(VertexIndex v) const; | int ConfidentValence(VertexIndex v) const; | ||||
| // Returns the valence of the vertex at the given corner. | // Returns the valence of the vertex at the given corner. | ||||
| inline int Valence(CornerIndex c) const { | inline int Valence(CornerIndex c) const { | ||||
| if (c == kInvalidCornerIndex) | if (c == kInvalidCornerIndex) { | ||||
| return -1; | return -1; | ||||
| } | |||||
| return ConfidentValence(c); | return ConfidentValence(c); | ||||
| } | } | ||||
| inline int ConfidentValence(CornerIndex c) const { | inline int ConfidentValence(CornerIndex c) const { | ||||
| DRACO_DCHECK_LT(c.value(), num_corners()); | DRACO_DCHECK_LT(c.value(), num_corners()); | ||||
| return ConfidentValence(ConfidentVertex(c)); | return ConfidentValence(ConfidentVertex(c)); | ||||
| } | } | ||||
| // Returns true if the specified vertex is on a boundary. | // Returns true if the specified vertex is on a boundary. | ||||
| inline bool IsOnBoundary(VertexIndex vert) const { | inline bool IsOnBoundary(VertexIndex vert) const { | ||||
| const CornerIndex corner = LeftMostCorner(vert); | const CornerIndex corner = LeftMostCorner(vert); | ||||
| if (SwingLeft(corner) == kInvalidCornerIndex) | if (SwingLeft(corner) == kInvalidCornerIndex) { | ||||
| return true; | return true; | ||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| // *-------* | // *-------* | ||||
| // / \ / \ | // / \ / \ | ||||
| // / \ / \ | // / \ / \ | ||||
| // / sl\c/sr \ | // / sl\c/sr \ | ||||
| // *-------v-------* | // *-------v-------* | ||||
| Show All 12 Lines | public: | ||||
| // below, where L and R are the left and right corners of a corner X. | // below, where L and R are the left and right corners of a corner X. | ||||
| // | // | ||||
| // *-------*-------* | // *-------*-------* | ||||
| // \L /X\ R/ | // \L /X\ R/ | ||||
| // \ / \ / | // \ / \ / | ||||
| // \ / \ / | // \ / \ / | ||||
| // *-------* | // *-------* | ||||
| inline CornerIndex GetLeftCorner(CornerIndex corner_id) const { | inline CornerIndex GetLeftCorner(CornerIndex corner_id) const { | ||||
| if (corner_id == kInvalidCornerIndex) | if (corner_id == kInvalidCornerIndex) { | ||||
| return kInvalidCornerIndex; | return kInvalidCornerIndex; | ||||
| } | |||||
| return Opposite(Previous(corner_id)); | return Opposite(Previous(corner_id)); | ||||
| } | } | ||||
| inline CornerIndex GetRightCorner(CornerIndex corner_id) const { | inline CornerIndex GetRightCorner(CornerIndex corner_id) const { | ||||
| if (corner_id == kInvalidCornerIndex) | if (corner_id == kInvalidCornerIndex) { | ||||
| return kInvalidCornerIndex; | return kInvalidCornerIndex; | ||||
| } | |||||
| return Opposite(Next(corner_id)); | return Opposite(Next(corner_id)); | ||||
| } | } | ||||
| // Returns the number of new vertices that were created as a result of | // Returns the number of new vertices that were created as a result of | ||||
| // splitting of non-manifold vertices of the input geometry. | // splitting of non-manifold vertices of the input geometry. | ||||
| int NumNewVertices() const { return num_vertices() - num_original_vertices_; } | int NumNewVertices() const { return num_vertices() - num_original_vertices_; } | ||||
| int NumOriginalVertices() const { return num_original_vertices_; } | int NumOriginalVertices() const { return num_original_vertices_; } | ||||
| Show All 13 Lines | inline void SetOppositeCorner(CornerIndex corner_id, | ||||
| CornerIndex opp_corner_id) { | CornerIndex opp_corner_id) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| opposite_corners_[corner_id] = opp_corner_id; | opposite_corners_[corner_id] = opp_corner_id; | ||||
| } | } | ||||
| // Sets opposite corners for both input corners. | // Sets opposite corners for both input corners. | ||||
| inline void SetOppositeCorners(CornerIndex corner_0, CornerIndex corner_1) { | inline void SetOppositeCorners(CornerIndex corner_0, CornerIndex corner_1) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| if (corner_0 != kInvalidCornerIndex) | if (corner_0 != kInvalidCornerIndex) { | ||||
| SetOppositeCorner(corner_0, corner_1); | SetOppositeCorner(corner_0, corner_1); | ||||
| if (corner_1 != kInvalidCornerIndex) | } | ||||
| if (corner_1 != kInvalidCornerIndex) { | |||||
| SetOppositeCorner(corner_1, corner_0); | SetOppositeCorner(corner_1, corner_0); | ||||
| } | } | ||||
| } | |||||
| // Updates mapping between a corner and a vertex. | // Updates mapping between a corner and a vertex. | ||||
| inline void MapCornerToVertex(CornerIndex corner_id, VertexIndex vert_id) { | inline void MapCornerToVertex(CornerIndex corner_id, VertexIndex vert_id) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| corner_to_vertex_map_[corner_id] = vert_id; | corner_to_vertex_map_[corner_id] = vert_id; | ||||
| } | } | ||||
| VertexIndex AddNewVertex() { | VertexIndex AddNewVertex() { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| // Add a new invalid vertex. | // Add a new invalid vertex. | ||||
| vertex_corners_.push_back(kInvalidCornerIndex); | vertex_corners_.push_back(kInvalidCornerIndex); | ||||
| return VertexIndex(static_cast<uint32_t>(vertex_corners_.size() - 1)); | return VertexIndex(static_cast<uint32_t>(vertex_corners_.size() - 1)); | ||||
| } | } | ||||
| // Adds a new face connected to three vertices. Note that connectivity is not | |||||
| // automatically updated and all opposite corners need to be set explicitly. | |||||
| FaceIndex AddNewFace(const std::array<VertexIndex, 3> &vertices) { | |||||
| // Add a new invalid face. | |||||
| const FaceIndex new_face_index(num_faces()); | |||||
| for (int i = 0; i < 3; ++i) { | |||||
| corner_to_vertex_map_.push_back(vertices[i]); | |||||
| SetLeftMostCorner(vertices[i], | |||||
| CornerIndex(corner_to_vertex_map_.size() - 1)); | |||||
| } | |||||
| opposite_corners_.resize(corner_to_vertex_map_.size(), kInvalidCornerIndex); | |||||
| return new_face_index; | |||||
| } | |||||
| // Sets a new left most corner for a given vertex. | // Sets a new left most corner for a given vertex. | ||||
| void SetLeftMostCorner(VertexIndex vert, CornerIndex corner) { | void SetLeftMostCorner(VertexIndex vert, CornerIndex corner) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| if (vert != kInvalidVertexIndex) | if (vert != kInvalidVertexIndex) { | ||||
| vertex_corners_[vert] = corner; | vertex_corners_[vert] = corner; | ||||
| } | } | ||||
| } | |||||
| // Updates the vertex to corner map on a specified vertex. This should be | // Updates the vertex to corner map on a specified vertex. This should be | ||||
| // called in cases where the mapping may be invalid (e.g. when the corner | // called in cases where the mapping may be invalid (e.g. when the corner | ||||
| // table was constructed manually). | // table was constructed manually). | ||||
| void UpdateVertexToCornerMap(VertexIndex vert) { | void UpdateVertexToCornerMap(VertexIndex vert) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| const CornerIndex first_c = vertex_corners_[vert]; | const CornerIndex first_c = vertex_corners_[vert]; | ||||
| if (first_c == kInvalidCornerIndex) | if (first_c == kInvalidCornerIndex) { | ||||
| return; // Isolated vertex. | return; // Isolated vertex. | ||||
| } | |||||
| CornerIndex act_c = SwingLeft(first_c); | CornerIndex act_c = SwingLeft(first_c); | ||||
| CornerIndex c = first_c; | CornerIndex c = first_c; | ||||
| while (act_c != kInvalidCornerIndex && act_c != first_c) { | while (act_c != kInvalidCornerIndex && act_c != first_c) { | ||||
| c = act_c; | c = act_c; | ||||
| act_c = SwingLeft(act_c); | act_c = SwingLeft(act_c); | ||||
| } | } | ||||
| if (act_c != first_c) { | if (act_c != first_c) { | ||||
| vertex_corners_[vert] = c; | vertex_corners_[vert] = c; | ||||
| ▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines | |||||