Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.cc
- This file was moved from extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.cc.
| // Copyright 2016 The Draco Authors. | // Copyright 2016 The Draco Authors. | ||||
| // | // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | // You may obtain a copy of the License at | ||||
| // | // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | // | ||||
| // Unless required by applicable law or agreed to in writing, software | // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | // limitations under the License. | ||||
| // | // | ||||
| #include "draco/mesh/mesh_attribute_corner_table.h" | #include "draco/mesh/mesh_attribute_corner_table.h" | ||||
| #include "draco/mesh/corner_table_iterators.h" | #include "draco/mesh/corner_table_iterators.h" | ||||
| #include "draco/mesh/mesh_misc_functions.h" | #include "draco/mesh/mesh_misc_functions.h" | ||||
| namespace draco { | namespace draco { | ||||
| MeshAttributeCornerTable::MeshAttributeCornerTable() | MeshAttributeCornerTable::MeshAttributeCornerTable() | ||||
| : no_interior_seams_(true), corner_table_(nullptr), valence_cache_(*this) {} | : no_interior_seams_(true), corner_table_(nullptr), valence_cache_(*this) {} | ||||
| bool MeshAttributeCornerTable::InitEmpty(const CornerTable *table) { | bool MeshAttributeCornerTable::InitEmpty(const CornerTable *table) { | ||||
| if (table == nullptr) | if (table == nullptr) { | ||||
| return false; | return false; | ||||
| } | |||||
| valence_cache_.ClearValenceCache(); | valence_cache_.ClearValenceCache(); | ||||
| valence_cache_.ClearValenceCacheInaccurate(); | valence_cache_.ClearValenceCacheInaccurate(); | ||||
| is_edge_on_seam_.assign(table->num_corners(), false); | is_edge_on_seam_.assign(table->num_corners(), false); | ||||
| is_vertex_on_seam_.assign(table->num_vertices(), false); | is_vertex_on_seam_.assign(table->num_vertices(), false); | ||||
| corner_to_vertex_map_.assign(table->num_corners(), kInvalidVertexIndex); | corner_to_vertex_map_.assign(table->num_corners(), kInvalidVertexIndex); | ||||
| vertex_to_attribute_entry_id_map_.reserve(table->num_vertices()); | vertex_to_attribute_entry_id_map_.reserve(table->num_vertices()); | ||||
| vertex_to_left_most_corner_map_.reserve(table->num_vertices()); | vertex_to_left_most_corner_map_.reserve(table->num_vertices()); | ||||
| corner_table_ = table; | corner_table_ = table; | ||||
| no_interior_seams_ = true; | no_interior_seams_ = true; | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool MeshAttributeCornerTable::InitFromAttribute(const Mesh *mesh, | bool MeshAttributeCornerTable::InitFromAttribute(const Mesh *mesh, | ||||
| const CornerTable *table, | const CornerTable *table, | ||||
| const PointAttribute *att) { | const PointAttribute *att) { | ||||
| if (!InitEmpty(table)) | if (!InitEmpty(table)) { | ||||
| return false; | return false; | ||||
| } | |||||
| valence_cache_.ClearValenceCache(); | valence_cache_.ClearValenceCache(); | ||||
| valence_cache_.ClearValenceCacheInaccurate(); | valence_cache_.ClearValenceCacheInaccurate(); | ||||
| // Find all necessary data for encoding attributes. For now we check which of | // Find all necessary data for encoding attributes. For now we check which of | ||||
| // the mesh vertices is part of an attribute seam, because seams require | // the mesh vertices is part of an attribute seam, because seams require | ||||
| // special handling. | // special handling. | ||||
| for (CornerIndex c(0); c < corner_table_->num_corners(); ++c) { | for (CornerIndex c(0); c < corner_table_->num_corners(); ++c) { | ||||
| const FaceIndex f = corner_table_->Face(c); | const FaceIndex f = corner_table_->Face(c); | ||||
| if (corner_table_->IsDegenerated(f)) | if (corner_table_->IsDegenerated(f)) { | ||||
| continue; // Ignore corners on degenerated faces. | continue; // Ignore corners on degenerated faces. | ||||
| } | |||||
| const CornerIndex opp_corner = corner_table_->Opposite(c); | const CornerIndex opp_corner = corner_table_->Opposite(c); | ||||
| if (opp_corner == kInvalidCornerIndex) { | if (opp_corner == kInvalidCornerIndex) { | ||||
| // Boundary. Mark it as seam edge. | // Boundary. Mark it as seam edge. | ||||
| is_edge_on_seam_[c.value()] = true; | is_edge_on_seam_[c.value()] = true; | ||||
| // Mark seam vertices. | // Mark seam vertices. | ||||
| VertexIndex v; | VertexIndex v; | ||||
| v = corner_table_->Vertex(corner_table_->Next(c)); | v = corner_table_->Vertex(corner_table_->Next(c)); | ||||
| is_vertex_on_seam_[v.value()] = true; | is_vertex_on_seam_[v.value()] = true; | ||||
| v = corner_table_->Vertex(corner_table_->Previous(c)); | v = corner_table_->Vertex(corner_table_->Previous(c)); | ||||
| is_vertex_on_seam_[v.value()] = true; | is_vertex_on_seam_[v.value()] = true; | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (opp_corner < c) | if (opp_corner < c) { | ||||
| continue; // Opposite corner was already processed. | continue; // Opposite corner was already processed. | ||||
| } | |||||
| CornerIndex act_c(c), act_sibling_c(opp_corner); | CornerIndex act_c(c), act_sibling_c(opp_corner); | ||||
| for (int i = 0; i < 2; ++i) { | for (int i = 0; i < 2; ++i) { | ||||
| // Get the sibling corners. I.e., the two corners attached to the same | // Get the sibling corners. I.e., the two corners attached to the same | ||||
| // vertex but divided by the seam edge. | // vertex but divided by the seam edge. | ||||
| act_c = corner_table_->Next(act_c); | act_c = corner_table_->Next(act_c); | ||||
| act_sibling_c = corner_table_->Previous(act_sibling_c); | act_sibling_c = corner_table_->Previous(act_sibling_c); | ||||
| const PointIndex point_id = mesh->CornerToPointId(act_c.value()); | const PointIndex point_id = mesh->CornerToPointId(act_c.value()); | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (mesh != nullptr && att != nullptr) { | ||||
| RecomputeVerticesInternal<false>(nullptr, nullptr); | RecomputeVerticesInternal<false>(nullptr, nullptr); | ||||
| } | } | ||||
| } | } | ||||
| template <bool init_vertex_to_attribute_entry_map> | template <bool init_vertex_to_attribute_entry_map> | ||||
| void MeshAttributeCornerTable::RecomputeVerticesInternal( | void MeshAttributeCornerTable::RecomputeVerticesInternal( | ||||
| const Mesh *mesh, const PointAttribute *att) { | const Mesh *mesh, const PointAttribute *att) { | ||||
| DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | DRACO_DCHECK(GetValenceCache().IsCacheEmpty()); | ||||
| vertex_to_attribute_entry_id_map_.clear(); | |||||
| vertex_to_left_most_corner_map_.clear(); | |||||
| int num_new_vertices = 0; | int num_new_vertices = 0; | ||||
| for (VertexIndex v(0); v < corner_table_->num_vertices(); ++v) { | for (VertexIndex v(0); v < corner_table_->num_vertices(); ++v) { | ||||
| const CornerIndex c = corner_table_->LeftMostCorner(v); | const CornerIndex c = corner_table_->LeftMostCorner(v); | ||||
| if (c == kInvalidCornerIndex) | if (c == kInvalidCornerIndex) { | ||||
| continue; // Isolated vertex? | continue; // Isolated vertex? | ||||
| } | |||||
| AttributeValueIndex first_vert_id(num_new_vertices++); | AttributeValueIndex first_vert_id(num_new_vertices++); | ||||
| if (init_vertex_to_attribute_entry_map) { | if (init_vertex_to_attribute_entry_map) { | ||||
| const PointIndex point_id = mesh->CornerToPointId(c.value()); | const PointIndex point_id = mesh->CornerToPointId(c.value()); | ||||
| vertex_to_attribute_entry_id_map_.push_back(att->mapped_index(point_id)); | vertex_to_attribute_entry_id_map_.push_back(att->mapped_index(point_id)); | ||||
| } else { | } else { | ||||
| // Identity mapping | // Identity mapping | ||||
| vertex_to_attribute_entry_id_map_.push_back(first_vert_id); | vertex_to_attribute_entry_id_map_.push_back(first_vert_id); | ||||
| } | } | ||||
| Show All 28 Lines | while (act_c != kInvalidCornerIndex && act_c != first_c) { | ||||
| } | } | ||||
| corner_to_vertex_map_[act_c.value()] = VertexIndex(first_vert_id.value()); | corner_to_vertex_map_[act_c.value()] = VertexIndex(first_vert_id.value()); | ||||
| act_c = corner_table_->SwingRight(act_c); | act_c = corner_table_->SwingRight(act_c); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| int MeshAttributeCornerTable::Valence(VertexIndex v) const { | int MeshAttributeCornerTable::Valence(VertexIndex v) const { | ||||
| if (v == kInvalidVertexIndex) | if (v == kInvalidVertexIndex) { | ||||
| return -1; | return -1; | ||||
| } | |||||
| return ConfidentValence(v); | return ConfidentValence(v); | ||||
| } | } | ||||
| int MeshAttributeCornerTable::ConfidentValence(VertexIndex v) const { | int MeshAttributeCornerTable::ConfidentValence(VertexIndex v) const { | ||||
| DRACO_DCHECK_LT(v.value(), num_vertices()); | DRACO_DCHECK_LT(v.value(), num_vertices()); | ||||
| draco::VertexRingIterator<MeshAttributeCornerTable> vi(this, v); | draco::VertexRingIterator<MeshAttributeCornerTable> vi(this, v); | ||||
| int valence = 0; | int valence = 0; | ||||
| for (; !vi.End(); vi.Next()) { | for (; !vi.End(); vi.Next()) { | ||||
| ++valence; | ++valence; | ||||
| } | } | ||||
| return valence; | return valence; | ||||
| } | } | ||||
| } // namespace draco | } // namespace draco | ||||