Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose Vertex & Index raw ptrs for efficient reading #474

Merged
merged 4 commits into from Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions graphics/include/gz/common/SubMesh.hh
Expand Up @@ -157,6 +157,12 @@ namespace gz
/// \sa bool HasVertex(const unsigned int) const
public: gz::math::Vector3d Vertex(const unsigned int _index) const;

/// \brief Get the raw vertex pointer. This is unsafe, it is the
/// caller's responsability to ensure it's not indexed out of bounds.
/// The valid range is [0; VertexCount())
/// \return Raw vertices
public: const gz::math::Vector3d* VertexPtr() const;
mjcarroll marked this conversation as resolved.
Show resolved Hide resolved

/// \brief Set a vertex
/// \param[in] _index Index of the vertex
/// \param[in] _v The new vertex coordinate
Expand Down Expand Up @@ -217,6 +223,12 @@ namespace gz
/// \return The index, or -1 if the _index is out of bounds.
public: int Index(const unsigned int _index) const;

/// \brief Get the raw index pointer. This is unsafe, it is the
/// caller's responsability to ensure it's not indexed out of bounds.
/// The valid range is [0; IndexCount())
/// \return Raw indices
public: const unsigned int* IndexPtr() const;

/// \brief Set an index
/// \param[in] _index Index of the indices
/// \param[in] _i The new index value to set to
Expand Down
4 changes: 4 additions & 0 deletions graphics/src/Mesh_TEST.cc
Expand Up @@ -95,18 +95,21 @@ TEST_F(MeshTest, Mesh)
EXPECT_EQ(submesh.lock()->Vertex(0), v0 * scale);
EXPECT_EQ(submesh.lock()->Normal(0), n0);
EXPECT_EQ(submesh.lock()->TexCoord(0), uv0);
EXPECT_EQ(submesh.lock()->VertexPtr()[0], v0 * scale);

mesh->Scale(scale);
EXPECT_EQ(submesh.lock()->Vertex(0), v0 * scale * scale);
EXPECT_EQ(submesh.lock()->Normal(0), n0);
EXPECT_EQ(submesh.lock()->TexCoord(0), uv0);
EXPECT_EQ(submesh.lock()->VertexPtr()[0], v0 * scale * scale);

// translate
math::Vector3d t0(2, 3, -12);
mesh->Translate(t0);
EXPECT_EQ(submesh.lock()->Vertex(0), v0 * scale * scale + t0);
EXPECT_EQ(submesh.lock()->Normal(0), n0);
EXPECT_EQ(submesh.lock()->TexCoord(0), uv0);
EXPECT_EQ(submesh.lock()->VertexPtr()[0], v0 * scale * scale + t0);

// center
math::Vector3d c0(0.1, 3, 1);
Expand Down Expand Up @@ -151,4 +154,5 @@ TEST_F(MeshTest, Mesh)
EXPECT_TRUE(math::equal(vertices[1], submesh.lock()->Vertex(0).Y()));
EXPECT_TRUE(math::equal(vertices[2], submesh.lock()->Vertex(0).Z()));
EXPECT_EQ(indices[0], submesh.lock()->Index(0));
EXPECT_EQ(indices[0], submesh.lock()->IndexPtr()[0]);
}
12 changes: 12 additions & 0 deletions graphics/src/SubMesh.cc
Expand Up @@ -173,6 +173,12 @@ gz::math::Vector3d SubMesh::Vertex(const unsigned int _index) const
return this->dataPtr->vertices[_index];
}

//////////////////////////////////////////////////
const gz::math::Vector3d* SubMesh::VertexPtr() const
{
return this->dataPtr->vertices.data();
}

//////////////////////////////////////////////////
bool SubMesh::HasVertex(const unsigned int _index) const
{
Expand Down Expand Up @@ -349,6 +355,12 @@ int SubMesh::Index(const unsigned int _index) const
return this->dataPtr->indices[_index];
}

//////////////////////////////////////////////////
const unsigned int* SubMesh::IndexPtr() const
{
return this->dataPtr->indices.data();
}

//////////////////////////////////////////////////
void SubMesh::SetIndex(const unsigned int _index, const unsigned int _i)
{
Expand Down
64 changes: 63 additions & 1 deletion graphics/src/SubMesh_TEST.cc
Expand Up @@ -88,18 +88,21 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_EQ(submesh->Vertex(0u), v0);
EXPECT_TRUE(submesh->HasVertex(v0));
EXPECT_EQ(submesh->IndexOfVertex(v0), 0);
EXPECT_EQ(submesh->VertexPtr()[0], v0);

submesh->AddVertex(v1);
EXPECT_EQ(submesh->VertexCount(), 2u);
EXPECT_EQ(submesh->Vertex(1u), v1);
EXPECT_TRUE(submesh->HasVertex(v1));
EXPECT_EQ(submesh->IndexOfVertex(v1), 1);
EXPECT_EQ(submesh->VertexPtr()[1], v1);

submesh->AddVertex(v2.X(), v2.Y(), v2.Z());
EXPECT_EQ(submesh->VertexCount(), 3u);
EXPECT_EQ(submesh->Vertex(2u), v2);
EXPECT_TRUE(submesh->HasVertex(v2));
EXPECT_EQ(submesh->IndexOfVertex(v2), 2);
EXPECT_EQ(submesh->VertexPtr()[2], v2);

// max / min
math::Vector3d max(2, 3, 3);
Expand Down Expand Up @@ -143,14 +146,17 @@ TEST_F(SubMeshTest, SubMesh)
submesh->AddIndex(0u);
EXPECT_EQ(submesh->IndexCount(), 1u);
EXPECT_EQ(submesh->Index(0), 0);
EXPECT_EQ(submesh->IndexPtr()[0], 0u);

submesh->AddIndex(2u);
EXPECT_EQ(submesh->IndexCount(), 2u);
EXPECT_EQ(submesh->Index(1u), 2);
EXPECT_EQ(submesh->IndexPtr()[1], 2u);

submesh->AddIndex(1u);
EXPECT_EQ(submesh->IndexCount(), 3u);
EXPECT_EQ(submesh->Index(2u), 1);
EXPECT_EQ(submesh->IndexPtr()[2], 1u);

// add node assignment
submesh->AddNodeAssignment(1u, 0u, 0.5f);
Expand All @@ -169,10 +175,16 @@ TEST_F(SubMeshTest, SubMesh)
// test directly setting values and failure cases
submesh->SetVertex(2u, v0);
EXPECT_EQ(submesh->Vertex(2u), v0);
EXPECT_EQ(submesh->VertexPtr()[2u], v0);
submesh->SetVertex(2u, v2);
EXPECT_EQ(submesh->Vertex(2u), v2);
EXPECT_EQ(submesh->VertexPtr()[2u], v2);

// Failure case: write out of bounds should be ignored
submesh->SetVertex(3u, math::Vector3d(0.9, 2, 4));
EXPECT_EQ(submesh->Vertex(3u), math::Vector3d::Zero);
// Out-of-bounds read of a raw pointer is UB. We can't test it.
// EXPECT_EQ(submesh->VertexPtr()[3u], math::Vector3d::Zero);
EXPECT_FALSE(submesh->HasVertex(math::Vector3d(0.9, 2, 4)));
EXPECT_EQ(submesh->IndexOfVertex(math::Vector3d(0.9, 2, 4)), -1);

Expand Down Expand Up @@ -207,6 +219,10 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_EQ(submesh->Vertex(1), v1 * scale);
EXPECT_EQ(submesh->Vertex(2), v2 * scale);

EXPECT_EQ(submesh->VertexPtr()[0], v0 * scale);
EXPECT_EQ(submesh->VertexPtr()[1], v1 * scale);
EXPECT_EQ(submesh->VertexPtr()[2], v2 * scale);

EXPECT_EQ(submesh->Normal(0), n0);
EXPECT_EQ(submesh->Normal(1), n1);
EXPECT_EQ(submesh->Normal(2), n2);
Expand All @@ -222,6 +238,10 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_EQ(submesh->Vertex(1), v1);
EXPECT_EQ(submesh->Vertex(2), v2);

EXPECT_EQ(submesh->VertexPtr()[0], v0);
EXPECT_EQ(submesh->VertexPtr()[1], v1);
EXPECT_EQ(submesh->VertexPtr()[2], v2);

EXPECT_EQ(submesh->Normal(0), n0);
EXPECT_EQ(submesh->Normal(1), n1);
EXPECT_EQ(submesh->Normal(2), n2);
Expand All @@ -238,6 +258,10 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_EQ(submesh->Vertex(1), v1 + t0);
EXPECT_EQ(submesh->Vertex(2), v2 + t0);

EXPECT_EQ(submesh->VertexPtr()[0], v0 + t0);
EXPECT_EQ(submesh->VertexPtr()[1], v1 + t0);
EXPECT_EQ(submesh->VertexPtr()[2], v2 + t0);

EXPECT_EQ(submesh->Normal(0), n0);
EXPECT_EQ(submesh->Normal(1), n1);
EXPECT_EQ(submesh->Normal(2), n2);
Expand All @@ -255,6 +279,10 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_EQ(submesh->Vertex(1), v1 + t0 + t);
EXPECT_EQ(submesh->Vertex(2), v2 + t0 + t);

EXPECT_EQ(submesh->VertexPtr()[0], v0 + t0 + t);
EXPECT_EQ(submesh->VertexPtr()[1], v1 + t0 + t);
EXPECT_EQ(submesh->VertexPtr()[2], v2 + t0 + t);

// copy constructor
common::SubMeshPtr submeshCopy(new common::SubMesh(*(submesh.get())));
ASSERT_NE(nullptr, submeshCopy);
Expand All @@ -270,13 +298,19 @@ TEST_F(SubMeshTest, SubMesh)
submesh->NodeAssignmentsCount());

for (unsigned int i = 0; i < submeshCopy->VertexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Vertex(i), submesh->Vertex(i));
EXPECT_EQ(submeshCopy->VertexPtr()[i], submesh->VertexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->NormalCount(); ++i)
EXPECT_EQ(submeshCopy->Normal(i), submesh->Normal(i));
for (unsigned int i = 0; i < submeshCopy->TexCoordCount(); ++i)
EXPECT_EQ(submeshCopy->TexCoord(i), submesh->TexCoord(i));
for (unsigned int i = 0; i < submeshCopy->IndexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Index(i), submesh->Index(i));
EXPECT_EQ(submeshCopy->IndexPtr()[i], submesh->IndexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->NodeAssignmentsCount(); ++i)
{
common::NodeAssignment nodeCopy =
Expand All @@ -302,21 +336,37 @@ TEST_F(SubMeshTest, SubMesh)
EXPECT_DOUBLE_EQ(vertices[i*3], submesh->Vertex(i).X());
EXPECT_DOUBLE_EQ(vertices[i*3+1], submesh->Vertex(i).Y());
EXPECT_DOUBLE_EQ(vertices[i*3+2], submesh->Vertex(i).Z());

EXPECT_DOUBLE_EQ(vertices[i*3], submesh->VertexPtr()[i].X());
EXPECT_DOUBLE_EQ(vertices[i*3+1], submesh->VertexPtr()[i].Y());
EXPECT_DOUBLE_EQ(vertices[i*3+2], submesh->VertexPtr()[i].Z());
}
for (unsigned int i = 0; i < submeshCopy->IndexCount(); ++i)
{
EXPECT_EQ(indices[i], submesh->Index(i));

EXPECT_EQ(indices[i], submesh->IndexPtr()[i]);
}

// recalculate normal and verify they are different
submesh->RecalculateNormals();

EXPECT_NE(submeshCopy->VertexPtr(), submesh->VertexPtr());
EXPECT_NE(submeshCopy->IndexPtr(), submesh->IndexPtr());

for (unsigned int i = 0; i < submeshCopy->NormalCount(); ++i)
EXPECT_NE(submeshCopy->Normal(i), submesh->Normal(i));
for (unsigned int i = 0; i < submeshCopy->VertexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Vertex(i), submesh->Vertex(i));
EXPECT_EQ(submeshCopy->VertexPtr()[i], submesh->VertexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->TexCoordCount(); ++i)
EXPECT_EQ(submeshCopy->TexCoord(i), submesh->TexCoord(i));
for (unsigned int i = 0; i < submeshCopy->IndexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Index(i), submesh->Index(i));
EXPECT_EQ(submeshCopy->IndexPtr()[i], submesh->IndexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->NodeAssignmentsCount(); ++i)
{
common::NodeAssignment nodeCopy =
Expand All @@ -330,11 +380,17 @@ TEST_F(SubMeshTest, SubMesh)
for (unsigned int i = 0; i < submeshCopy->NormalCount(); ++i)
EXPECT_EQ(submeshCopy->Normal(i), submesh->Normal(i));
for (unsigned int i = 0; i < submeshCopy->VertexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Vertex(i), submesh->Vertex(i));
EXPECT_EQ(submeshCopy->VertexPtr()[i], submesh->VertexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->TexCoordCount(); ++i)
EXPECT_EQ(submeshCopy->TexCoord(i), submesh->TexCoord(i));
for (unsigned int i = 0; i < submeshCopy->IndexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Index(i), submesh->Index(i));
EXPECT_EQ(submeshCopy->IndexPtr()[i], submesh->IndexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->NodeAssignmentsCount(); ++i)
{
common::NodeAssignment nodeCopy =
Expand All @@ -351,9 +407,15 @@ TEST_F(SubMeshTest, SubMesh)
for (unsigned int i = 0; i < submeshCopy->NormalCount(); ++i)
EXPECT_EQ(submeshCopy->Normal(i), submesh->Normal(i));
for (unsigned int i = 0; i < submeshCopy->VertexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Vertex(i), submesh->Vertex(i));
EXPECT_EQ(submeshCopy->VertexPtr()[i], submesh->VertexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->IndexCount(); ++i)
{
EXPECT_EQ(submeshCopy->Index(i), submesh->Index(i));
EXPECT_EQ(submeshCopy->IndexPtr()[i], submesh->IndexPtr()[i]);
}
for (unsigned int i = 0; i < submeshCopy->NodeAssignmentsCount(); ++i)
{
common::NodeAssignment nodeCopy =
Expand Down