Skip to content

Commit 380e045

Browse files
authored
Add check for valid indices in submesh (#667)
Signed-off-by: Ian Chen <[email protected]>
1 parent 25fe977 commit 380e045

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
@@ -405,6 +405,10 @@ namespace gz
405405
/// the primitive type is not TRIANGLES, or there are no triangles.
406406
public: double Volume() const;
407407

408+
/// \brief Verify that all indices point to a valid vertex in the submesh
409+
/// \return True if all values of indices are valid, false otherwise.
410+
public: bool HasValidIndices() const;
411+
408412
/// \brief Private data pointer.
409413
GZ_UTILS_IMPL_PTR(dataPtr)
410414
};

graphics/src/SubMesh.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,12 @@ struct Neighbors
625625
void SubMesh::RecalculateNormals()
626626
{
627627
if (this->dataPtr->primitiveType != SubMesh::TRIANGLES
628-
|| this->dataPtr->indices.empty()
629628
|| this->dataPtr->indices.size() % 3u != 0)
630629
return;
631630

631+
if (!this->HasValidIndices())
632+
return;
633+
632634
// Reset all the normals
633635
for (auto &n : this->dataPtr->normals)
634636
n.Set(0, 0, 0);
@@ -743,6 +745,9 @@ std::string SubMesh::Name() const
743745
//////////////////////////////////////////////////
744746
double SubMesh::Volume() const
745747
{
748+
if (!this->HasValidIndices())
749+
return 0.0;
750+
746751
double volume = 0.0;
747752
if (this->dataPtr->primitiveType == SubMesh::TRIANGLES)
748753
{
@@ -774,6 +779,20 @@ double SubMesh::Volume() const
774779
return volume;
775780
}
776781

782+
//////////////////////////////////////////////////
783+
bool SubMesh::HasValidIndices() const
784+
{
785+
if (this->dataPtr->indices.empty())
786+
return false;
787+
788+
for (unsigned int idx = 0u; idx < this->dataPtr->indices.size(); ++idx)
789+
{
790+
if (this->dataPtr->indices[idx] >= this->dataPtr->vertices.size())
791+
return false;
792+
}
793+
return true;
794+
}
795+
777796
//////////////////////////////////////////////////
778797
NodeAssignment::NodeAssignment()
779798
: 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
@@ -598,3 +598,37 @@ TEST_F(SubMeshTest, NormalsRecalculation)
598598
// because of neighbour vertex
599599
ASSERT_NE(submesh->Normal(0), submesh->Normal(1));
600600
}
601+
602+
/////////////////////////////////////////////////
603+
TEST_F(SubMeshTest, HasValidIndices)
604+
{
605+
// Check empty submesh
606+
auto submesh = std::make_shared<common::SubMesh>();
607+
EXPECT_FALSE(submesh->HasValidIndices());
608+
609+
// Check box submesh
610+
const common::Mesh *unitBox =
611+
common::MeshManager::Instance()->MeshByName("unit_box");
612+
ASSERT_TRUE(unitBox != nullptr);
613+
auto unitBoxSubmesh = unitBox->SubMeshByIndex(0).lock();
614+
615+
// Submesh has valid indices and we should be able to calculate normals
616+
// and volume
617+
EXPECT_TRUE(unitBoxSubmesh->HasValidIndices());
618+
unitBoxSubmesh->RecalculateNormals();
619+
ASSERT_EQ(unitBoxSubmesh->VertexCount(), unitBoxSubmesh->NormalCount());
620+
EXPECT_EQ(24u, unitBoxSubmesh->NormalCount());
621+
EXPECT_DOUBLE_EQ(1.0, unitBoxSubmesh->Volume());
622+
623+
// Add some invalid indices
624+
unitBoxSubmesh->AddIndex(100);
625+
unitBoxSubmesh->AddIndex(101);
626+
unitBoxSubmesh->AddIndex(102);
627+
628+
// Submesh has invalid indices so it is no longer able to update normals or
629+
// compute volume.
630+
EXPECT_FALSE(unitBoxSubmesh->HasValidIndices());
631+
unitBoxSubmesh->RecalculateNormals();
632+
EXPECT_EQ(24u, unitBoxSubmesh->NormalCount());
633+
EXPECT_DOUBLE_EQ(0.0, unitBoxSubmesh->Volume());
634+
}

0 commit comments

Comments
 (0)