Skip to content

Commit

Permalink
HnMeshUtils: added ComputeEdgeIndices function
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Sep 24, 2024
1 parent e35e72b commit 838d88e
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 49 deletions.
30 changes: 30 additions & 0 deletions Hydrogent/include/HnMeshUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,32 @@ class HnMeshUtils final
pxr::VtIntArray& SubsetStart) const;


/// Computes the edge indices.
///
/// \param[in] UseFaceVertexIndices - Whether to use face vertex indices.
/// \return The edge indices.
///
/// Example:
/// Input:
/// FaceVertexCounts = {4, 4}
/// FaceVertexIndices= {0, 1, 2, 3, 3, 2, 4, 5}
///
/// V1________V2_______V4
/// |1 2|5 6|
/// | | |
/// | | |
/// |0______3|4______7|
/// V0 V3 V5
///
/// Output:
/// UseFaceVertexIndices == false
/// EdgeIndices = {0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4}
///
/// UseFaceVertexIndices == true
/// EdgeIndices = {0, 1, 1, 2, 2, 3, 3, 0, 3, 2, 2, 4, 4, 5, 5, 3}
pxr::VtVec2iArray ComputeEdgeIndices(bool UseFaceVertexIndices) const;


/// Converts vertex/varying primvar data to face-varying primvar data.
///
/// \param[in] VertexData - The vertex/varying primvar data.
Expand Down Expand Up @@ -108,6 +134,10 @@ class HnMeshUtils final
///
pxr::VtValue ConvertVertexPrimvarToFaceVarying(const pxr::VtValue& VertexData, size_t ValuesPerVertex = 1) const;

private:
template <typename HandleFaceType>
void ProcessFaces(HandleFaceType&& HandleFace) const;

private:
const pxr::HdMeshTopology& m_Topology;
const pxr::SdfPath& m_MeshId;
Expand Down
5 changes: 2 additions & 3 deletions Hydrogent/interface/HnMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,8 @@ class HnMesh final : public pxr::HdMesh
struct StagingIndexData
{
pxr::VtVec3iArray FaceIndices;

std::vector<pxr::GfVec2i> MeshEdgeIndices;
std::vector<Uint32> PointIndices;
pxr::VtVec2iArray EdgeIndices;
pxr::VtIntArray PointIndices;
};
std::unique_ptr<StagingIndexData> m_StagingIndexData;

Expand Down
21 changes: 10 additions & 11 deletions Hydrogent/src/HnMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,10 +920,9 @@ void HnMesh::UpdateIndexData()
m_IndexData.Subsets.clear();
}

//pxr::HdMeshUtil MeshUtil{&m_Topology, Id};
//MeshUtil.EnumerateEdges(&m_StagingIndexData->MeshEdgeIndices);
m_IndexData.NumFaceTriangles = static_cast<Uint32>(m_StagingIndexData->FaceIndices.size());
m_IndexData.NumEdges = static_cast<Uint32>(m_StagingIndexData->MeshEdgeIndices.size());
m_StagingIndexData->EdgeIndices = MeshUtils.ComputeEdgeIndices(!m_HasFaceVaryingPrimvars);
m_IndexData.NumFaceTriangles = static_cast<Uint32>(m_StagingIndexData->FaceIndices.size());
m_IndexData.NumEdges = static_cast<Uint32>(m_StagingIndexData->EdgeIndices.size());
}

void HnMesh::AllocatePooledResources(pxr::HdSceneDelegate& SceneDelegate,
Expand Down Expand Up @@ -991,9 +990,9 @@ void HnMesh::AllocatePooledResources(pxr::HdSceneDelegate& SceneDelegate,
}
}

if (!m_StagingIndexData->MeshEdgeIndices.empty())
if (!m_StagingIndexData->EdgeIndices.empty())
{
for (pxr::GfVec2i& Edge : m_StagingIndexData->MeshEdgeIndices)
for (pxr::GfVec2i& Edge : m_StagingIndexData->EdgeIndices)
{
Edge[0] += StartVertex;
Edge[1] += StartVertex;
Expand All @@ -1002,7 +1001,7 @@ void HnMesh::AllocatePooledResources(pxr::HdSceneDelegate& SceneDelegate,

if (!m_StagingIndexData->PointIndices.empty())
{
for (Uint32& Point : m_StagingIndexData->PointIndices)
for (int& Point : m_StagingIndexData->PointIndices)
{
Point += StartVertex;
}
Expand All @@ -1027,7 +1026,7 @@ void HnMesh::AllocatePooledResources(pxr::HdSceneDelegate& SceneDelegate,
m_IndexData.FaceStartIndex = m_IndexData.FaceAllocation->GetOffset() / sizeof(Uint32);
}

if (!m_StagingIndexData->MeshEdgeIndices.empty())
if (!m_StagingIndexData->EdgeIndices.empty())
{
m_IndexData.EdgeAllocation = ResMgr.AllocateIndices(sizeof(Uint32) * m_IndexData.NumEdges * 2);
m_IndexData.EdgeStartIndex = m_IndexData.EdgeAllocation->GetOffset() / sizeof(Uint32);
Expand Down Expand Up @@ -1158,11 +1157,11 @@ void HnMesh::UpdateIndexBuffer(HnRenderDelegate& RenderDelegate)
m_IndexData.FaceAllocation);
}

if (!m_StagingIndexData->MeshEdgeIndices.empty())
if (!m_StagingIndexData->EdgeIndices.empty())
{
VERIFY_EXPR(m_IndexData.NumEdges == static_cast<Uint32>(m_StagingIndexData->MeshEdgeIndices.size()));
VERIFY_EXPR(m_IndexData.NumEdges == static_cast<Uint32>(m_StagingIndexData->EdgeIndices.size()));
m_IndexData.Edges = PrepareIndexBuffer("Edge Index Buffer",
m_StagingIndexData->MeshEdgeIndices.data(),
m_StagingIndexData->EdgeIndices.data(),
m_IndexData.NumEdges * sizeof(Uint32) * 2,
m_IndexData.EdgeAllocation);
}
Expand Down
127 changes: 92 additions & 35 deletions Hydrogent/src/HnMeshUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,61 +45,75 @@ HnMeshUtils::~HnMeshUtils()
{
}

template <typename HandleFaceType>
void HnMeshUtils::ProcessFaces(HandleFaceType&& HandleFace) const
{
const pxr::VtIntArray& FaceVertCounts = m_Topology.GetFaceVertexCounts();
const size_t NumFaces = FaceVertCounts.size();
VERIFY_EXPR(NumFaces == static_cast<size_t>(m_Topology.GetNumFaces()));

int FaceStartVertex = 0;
for (size_t i = 0; i < NumFaces; ++i)
{
const int VertCount = FaceVertCounts[i];
if (VertCount >= 3)
{
HandleFace(i, FaceStartVertex, VertCount);
}
FaceStartVertex += VertCount;
}
}

void HnMeshUtils::Triangulate(bool UseFaceVertexIndices,
pxr::VtVec3iArray& TriangleIndices,
pxr::VtIntArray& SubsetStart) const
{
const size_t NumFaces = m_Topology.GetNumFaces();
const pxr::VtIntArray& FaceVertCounts = m_Topology.GetFaceVertexCounts();
const pxr::VtIntArray& FaceVertexIndices = m_Topology.GetFaceVertexIndices();
const size_t NumVertexIndices = FaceVertexIndices.size();

auto ProcessFaces = [&](auto HandleFace) {
int CurrVertex = 0;
for (size_t i = 0; i < NumFaces; ++i)
{
const int VertCount = FaceVertCounts[i];
if (VertCount >= 3)
{
HandleFace(i, CurrVertex, VertCount);
}
CurrVertex += VertCount;
}
};
const int NumVertexIndices = static_cast<int>(FaceVertexIndices.size());

// Count the number of triangles
size_t NumTriangles = 0;
ProcessFaces([&](size_t FaceId, int StartVertex, int VertCount) {
NumTriangles += VertCount - 2;
});
ProcessFaces(
[&](size_t FaceId, int StartVertex, int VertCount) {
NumTriangles += VertCount - 2;
});

// Triangulate faces
TriangleIndices.reserve(NumTriangles);
std::vector<size_t> FaceStartTriangle(NumFaces + 1);

ProcessFaces([&](size_t FaceId, int StartVertex, int VertCount) {
FaceStartTriangle[FaceId] = TriangleIndices.size();
for (int i = 0; i < VertCount - 2; ++i)
{
pxr::GfVec3i Triangle{
StartVertex,
StartVertex + i + 1,
StartVertex + i + 2,
};
if (UseFaceVertexIndices)
ProcessFaces(
[&](size_t FaceId, int StartVertex, int VertCount) {
FaceStartTriangle[FaceId] = TriangleIndices.size();
for (int i = 0; i < VertCount - 2; ++i)
{
for (size_t j = 0; j < 3; ++j)
pxr::GfVec3i Triangle{
StartVertex,
StartVertex + i + 1,
StartVertex + i + 2,
};
if (UseFaceVertexIndices)
{
int Idx = Triangle[j];
if (Idx < static_cast<int>(NumVertexIndices))
int& Idx0 = Triangle[0];
int& Idx1 = Triangle[1];
int& Idx2 = Triangle[2];
if (Idx0 < NumVertexIndices && Idx1 < NumVertexIndices && Idx2 < NumVertexIndices)
{
Idx0 = FaceVertexIndices[Idx0];
Idx1 = FaceVertexIndices[Idx1];
Idx2 = FaceVertexIndices[Idx2];
}
else
{
Triangle[j] = FaceVertexIndices[Idx];
Idx0 = 0;
Idx1 = 0;
Idx2 = 0;
}
}
TriangleIndices.push_back(Triangle);
}
TriangleIndices.push_back(Triangle);
}
});
});
VERIFY_EXPR(TriangleIndices.size() == NumTriangles);
FaceStartTriangle.back() = TriangleIndices.size();

Expand Down Expand Up @@ -161,6 +175,49 @@ void HnMeshUtils::Triangulate(bool UseFaceVertexIndices,
}
}

pxr::VtVec2iArray HnMeshUtils::ComputeEdgeIndices(bool UseFaceVertexIndices) const
{
size_t NumEdges = 0;
ProcessFaces(
[&](size_t FaceId, int StartVertex, int VertCount) {
NumEdges += VertCount;
});

pxr::VtVec2iArray EdgeIndices;
EdgeIndices.reserve(NumEdges);

ProcessFaces(
[&](size_t FaceId, int StartVertex, int VertCount) {
for (int v = 0; v < VertCount - 1; ++v)
EdgeIndices.push_back({StartVertex + v, StartVertex + (v + 1)});
EdgeIndices.push_back({StartVertex + VertCount - 1, StartVertex});
});
VERIFY_EXPR(EdgeIndices.size() == NumEdges);

if (UseFaceVertexIndices)
{
const pxr::VtIntArray& FaceVertexIndices = m_Topology.GetFaceVertexIndices();
const size_t NumVertexIndices = FaceVertexIndices.size();
for (pxr::GfVec2i& Edge : EdgeIndices)
{
int& Idx0 = Edge[0];
int& Idx1 = Edge[1];
if (Idx0 < NumVertexIndices && Idx1 < NumVertexIndices)
{
Idx0 = FaceVertexIndices[Idx0];
Idx1 = FaceVertexIndices[Idx1];
}
else
{
Idx0 = 0;
Idx1 = 0;
}
}
}

return EdgeIndices;
}

template <typename T>
pxr::VtValue ConvertVertexArrayToFaceVaryingArray(const pxr::VtIntArray& FaceVertexIndices, const pxr::VtArray<T>& VertexData, size_t ValuesPerVertex)
{
Expand Down

0 comments on commit 838d88e

Please sign in to comment.