Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.h
- This file was added.
| // 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_MESH_MESH_ATTRIBUTE_CORNER_TABLE_H_ | |||||
| #define DRACO_MESH_MESH_ATTRIBUTE_CORNER_TABLE_H_ | |||||
| #include "draco/core/macros.h" | |||||
| #include "draco/mesh/corner_table.h" | |||||
| #include "draco/mesh/mesh.h" | |||||
| #include "draco/mesh/valence_cache.h" | |||||
| namespace draco { | |||||
| // Class for storing connectivity of mesh attributes. The connectivity is stored | |||||
| // as a difference from the base mesh's corner table, where the differences are | |||||
| // represented by attribute seam edges. This class provides a basic | |||||
| // functionality for detecting the seam edges for a given attribute and for | |||||
| // traversing the constrained corner table with the seam edges. | |||||
| class MeshAttributeCornerTable { | |||||
| public: | |||||
| MeshAttributeCornerTable(); | |||||
| bool InitEmpty(const CornerTable *table); | |||||
| bool InitFromAttribute(const Mesh *mesh, const CornerTable *table, | |||||
| const PointAttribute *att); | |||||
| void AddSeamEdge(CornerIndex opp_corner); | |||||
| // Recomputes vertices using the newly added seam edges (needs to be called | |||||
| // whenever the seam edges are updated). | |||||
| // |mesh| and |att| can be null, in which case mapping between vertices and | |||||
| // attribute value ids is set to identity. | |||||
| void RecomputeVertices(const Mesh *mesh, const PointAttribute *att); | |||||
| inline bool IsCornerOppositeToSeamEdge(CornerIndex corner) const { | |||||
| return is_edge_on_seam_[corner.value()]; | |||||
| } | |||||
| inline CornerIndex Opposite(CornerIndex corner) const { | |||||
| if (corner == kInvalidCornerIndex || IsCornerOppositeToSeamEdge(corner)) | |||||
| return kInvalidCornerIndex; | |||||
| return corner_table_->Opposite(corner); | |||||
| } | |||||
| inline CornerIndex Next(CornerIndex corner) const { | |||||
| return corner_table_->Next(corner); | |||||
| } | |||||
| inline CornerIndex Previous(CornerIndex corner) const { | |||||
| return corner_table_->Previous(corner); | |||||
| } | |||||
| // Returns true when a corner is attached to any attribute seam. | |||||
| inline bool IsCornerOnSeam(CornerIndex corner) const { | |||||
| return is_vertex_on_seam_[corner_table_->Vertex(corner).value()]; | |||||
| } | |||||
| // Similar to CornerTable::GetLeftCorner and CornerTable::GetRightCorner, but | |||||
| // does not go over seam edges. | |||||
| inline CornerIndex GetLeftCorner(CornerIndex corner) const { | |||||
| return Opposite(Previous(corner)); | |||||
| } | |||||
| inline CornerIndex GetRightCorner(CornerIndex corner) const { | |||||
| return Opposite(Next(corner)); | |||||
| } | |||||
| // Similar to CornerTable::SwingRight, but it does not go over seam edges. | |||||
| inline CornerIndex SwingRight(CornerIndex corner) const { | |||||
| return Previous(Opposite(Previous(corner))); | |||||
| } | |||||
| // Similar to CornerTable::SwingLeft, but it does not go over seam edges. | |||||
| inline CornerIndex SwingLeft(CornerIndex corner) const { | |||||
| return Next(Opposite(Next(corner))); | |||||
| } | |||||
| int num_vertices() const { | |||||
| return static_cast<int>(vertex_to_attribute_entry_id_map_.size()); | |||||
| } | |||||
| int num_faces() const { return static_cast<int>(corner_table_->num_faces()); } | |||||
| VertexIndex Vertex(CornerIndex corner) const { | |||||
| DRACO_DCHECK_LT(corner.value(), corner_to_vertex_map_.size()); | |||||
| return ConfidentVertex(corner); | |||||
| } | |||||
| VertexIndex ConfidentVertex(CornerIndex corner) const { | |||||
| return corner_to_vertex_map_[corner.value()]; | |||||
| } | |||||
| // Returns the attribute entry id associated to the given vertex. | |||||
| VertexIndex VertexParent(VertexIndex vert) const { | |||||
| return VertexIndex(vertex_to_attribute_entry_id_map_[vert.value()].value()); | |||||
| } | |||||
| inline CornerIndex LeftMostCorner(VertexIndex v) const { | |||||
| return vertex_to_left_most_corner_map_[v.value()]; | |||||
| } | |||||
| inline bool IsOnBoundary(VertexIndex vert) const { | |||||
| const CornerIndex corner = LeftMostCorner(vert); | |||||
| if (corner == kInvalidCornerIndex) | |||||
| return true; | |||||
| return IsCornerOnSeam(corner); | |||||
| } | |||||
| bool no_interior_seams() const { return no_interior_seams_; } | |||||
| const CornerTable *corner_table() const { return corner_table_; } | |||||
| // TODO(draco-eng): extract valence functions into a reusable class/object | |||||
| // also from 'corner_table.*' | |||||
| // Returns the valence (or degree) of a vertex. | |||||
| // Returns -1 if the given vertex index is not valid. | |||||
| int Valence(VertexIndex v) const; | |||||
| // Same as above but does not check for validity and does not return -1 | |||||
| int ConfidentValence(VertexIndex v) const; | |||||
| // Returns the valence of the vertex at the given corner. | |||||
| inline int Valence(CornerIndex c) const { | |||||
| DRACO_DCHECK_LT(c.value(), corner_table_->num_corners()); | |||||
| if (c == kInvalidCornerIndex) | |||||
| return -1; | |||||
| return ConfidentValence(c); | |||||
| } | |||||
| inline int ConfidentValence(CornerIndex c) const { | |||||
| DRACO_DCHECK_LT(c.value(), corner_table_->num_corners()); | |||||
| return ConfidentValence(Vertex(c)); | |||||
| } | |||||
| // Allows access to an internal object for caching valences. The object can | |||||
| // be instructed to cache or uncache all valences and then its interfaces | |||||
| // queried directly for valences with differing performance/confidence | |||||
| // qualities. If the mesh or table is modified the cache should be discarded | |||||
| // and not relied on as it does not automatically update or invalidate for | |||||
| // performance reasons. | |||||
| const ValenceCache<MeshAttributeCornerTable> &GetValenceCache() const { | |||||
| return valence_cache_; | |||||
| } | |||||
| private: | |||||
| template <bool init_vertex_to_attribute_entry_map> | |||||
| void RecomputeVerticesInternal(const Mesh *mesh, const PointAttribute *att); | |||||
| std::vector<bool> is_edge_on_seam_; | |||||
| std::vector<bool> is_vertex_on_seam_; | |||||
| // If this is set to true, it means that there are no attribute seams between | |||||
| // two faces. This can be used to speed up some algorithms. | |||||
| bool no_interior_seams_; | |||||
| std::vector<VertexIndex> corner_to_vertex_map_; | |||||
| // Map between vertices and their associated left most corners. A left most | |||||
| // corner is a corner that is adjacent to a boundary or an attribute seam from | |||||
| // right (i.e., SwingLeft from that corner will return an invalid corner). If | |||||
| // no such corner exists for a given vertex, then any corner attached to the | |||||
| // vertex can be used. | |||||
| std::vector<CornerIndex> vertex_to_left_most_corner_map_; | |||||
| // Map between vertex ids and attribute entry ids (i.e. the values stored in | |||||
| // the attribute buffer). The attribute entry id can be retrieved using the | |||||
| // VertexParent() method. | |||||
| std::vector<AttributeValueIndex> vertex_to_attribute_entry_id_map_; | |||||
| const CornerTable *corner_table_; | |||||
| ValenceCache<MeshAttributeCornerTable> valence_cache_; | |||||
| }; | |||||
| } // namespace draco | |||||
| #endif // DRACO_MESH_MESH_ATTRIBUTE_CORNER_TABLE_H_ | |||||