Skip to content

Commit 8397979

Browse files
committed
Add check for valid indices in submesh (#667)
Signed-off-by: Ian Chen <[email protected]> (cherry picked from commit 380e045)
1 parent a822b8d commit 8397979

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

graphics/include/gz/common/SubMesh.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ namespace gz
411411
/// the primitive type is not TRIANGLES, or there are no triangles.
412412
public: double Volume() const;
413413

414+
/// \brief Verify that all indices point to a valid vertex in the submesh
415+
/// \return True if all values of indices are valid, false otherwise.
416+
public: bool HasValidIndices() const;
417+
414418
/// \brief Private data pointer.
415419
GZ_UTILS_IMPL_PTR(dataPtr)
416420
};

graphics/src/SubMesh.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,12 @@ struct Neighbors
632632
void SubMesh::RecalculateNormals()
633633
{
634634
if (this->dataPtr->primitiveType != SubMesh::TRIANGLES
635-
|| this->dataPtr->indices.empty()
636635
|| this->dataPtr->indices.size() % 3u != 0)
637636
return;
638637

638+
if (!this->HasValidIndices())
639+
return;
640+
639641
// Reset all the normals
640642
for (auto &n : this->dataPtr->normals)
641643
n.Set(0, 0, 0);
@@ -750,6 +752,9 @@ std::string SubMesh::Name() const
750752
//////////////////////////////////////////////////
751753
double SubMesh::Volume() const
752754
{
755+
if (!this->HasValidIndices())
756+
return 0.0;
757+
753758
double volume = 0.0;
754759
if (this->dataPtr->primitiveType == SubMesh::TRIANGLES)
755760
{
@@ -781,6 +786,20 @@ double SubMesh::Volume() const
781786
return volume;
782787
}
783788

789+
//////////////////////////////////////////////////
790+
bool SubMesh::HasValidIndices() const
791+
{
792+
if (this->dataPtr->indices.empty())
793+
return false;
794+
795+
for (unsigned int idx = 0u; idx < this->dataPtr->indices.size(); ++idx)
796+
{
797+
if (this->dataPtr->indices[idx] >= this->dataPtr->vertices.size())
798+
return false;
799+
}
800+
return true;
801+
}
802+
784803
//////////////////////////////////////////////////
785804
NodeAssignment::NodeAssignment()
786805
: vertexIndex(0), nodeIndex(0), weight(0.0)

graphics/src/SubMesh_TEST.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,37 @@ TEST_F(SubMeshTest, NormalsRecalculation)
614614
// because of neighbour vertex
615615
ASSERT_NE(submesh->Normal(0), submesh->Normal(1));
616616
}
617+
618+
/////////////////////////////////////////////////
619+
TEST_F(SubMeshTest, HasValidIndices)
620+
{
621+
// Check empty submesh
622+
auto submesh = std::make_shared<common::SubMesh>();
623+
EXPECT_FALSE(submesh->HasValidIndices());
624+
625+
// Check box submesh
626+
const common::Mesh *unitBox =
627+
common::MeshManager::Instance()->MeshByName("unit_box");
628+
ASSERT_TRUE(unitBox != nullptr);
629+
auto unitBoxSubmesh = unitBox->SubMeshByIndex(0).lock();
630+
631+
// Submesh has valid indices and we should be able to calculate normals
632+
// and volume
633+
EXPECT_TRUE(unitBoxSubmesh->HasValidIndices());
634+
unitBoxSubmesh->RecalculateNormals();
635+
ASSERT_EQ(unitBoxSubmesh->VertexCount(), unitBoxSubmesh->NormalCount());
636+
EXPECT_EQ(24u, unitBoxSubmesh->NormalCount());
637+
EXPECT_DOUBLE_EQ(1.0, unitBoxSubmesh->Volume());
638+
639+
// Add some invalid indices
640+
unitBoxSubmesh->AddIndex(100);
641+
unitBoxSubmesh->AddIndex(101);
642+
unitBoxSubmesh->AddIndex(102);
643+
644+
// Submesh has invalid indices so it is no longer able to update normals or
645+
// compute volume.
646+
EXPECT_FALSE(unitBoxSubmesh->HasValidIndices());
647+
unitBoxSubmesh->RecalculateNormals();
648+
EXPECT_EQ(24u, unitBoxSubmesh->NormalCount());
649+
EXPECT_DOUBLE_EQ(0.0, unitBoxSubmesh->Volume());
650+
}

0 commit comments

Comments
 (0)