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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComputeAdjacencyList Assignment Open3D #7094

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

adityaranigaon
Copy link

  • Implement C++ function
  • Add gtests
  • Add pybind
  • Add pytests

Copy link

update-docs bot commented Dec 12, 2024

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

@ssheorey ssheorey self-requested a review December 13, 2024 06:14
@ssheorey ssheorey mentioned this pull request Dec 13, 2024
Copy link
Member

@ssheorey ssheorey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @adityaranigaon , this looks good. Some thoughts:

  • Can we change the name to ComputeAdjacencyMatrix() / compute_adjacency_matrix(). The adjacency list uses an equivalent but slightly different format. We have that as part of the Eigen API, so having the same name may confuse users.
  • Do add these as triangle attributes as well. They are needed for other algorithms to be added later (e.g. mesh filtering).


triangle_mesh.def("compute_adjacency_list", &TriangleMesh::ComputeAdjacencyList,
"Return Mesh Adjacency Matrix in CSR format using Triangle indices attribute.");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe returned pair explicitly for users that don't know CSR format.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing that adjst() would be added to vertex attribute and adjv() to triangle attributes ?

However the check HasVertexAttribute will fail because it checks the length of attribute is equal to the number of vertices, however as per CSR format the length of adjv is "num_vertices + 1"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. We need a different container for storing attributes for the TriangleMesh as a whole. I've added a new container to TriangleMesh for this purpose. Can you use that? I'll update the python bindings / tests for the new container later.

EXPECT_TRUE( adjv.GetLength() > 0);
EXPECT_TRUE( adjst.GetLength() > 0);
EXPECT_EQ(adjst.ToFlatVector<int64_t>()[adjst.GetLength()-1], adjv.GetLength());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also add a test for Euler characteristic (n_faces + n_vertices - 2 = n_edges).
face = triangle, n_edges = length of csr_col.

[4, 7, 9],
[5, 6, 10],
[5, 6, 11]
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get this from mesh.triangle.indices.numpy() May need to be lexicographically sorted. (np.lexsort)

}

core::Tensor tris_cpu =
GetTriangleIndices().To(core::Device()).Contiguous();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Also enable on cuda and sycl.

std::unordered_map< size_t, std::set<size_t> > adjacencyList;
auto insertEdge = [&adjacencyList](size_t s, size_t t){
adjacencyList[s].insert(t);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edges are undirected. For a triangle mesh, 2 neighboring faces will share an edge. If they are oriented in-consistently, the directions will be opposite, i.e. if one face is [0, 1, 2], another may be [2, 1, 3]. In this case we will get duplicate entries in the adjacency list. Essentially, we just need the lower triangle of the adjacency matrix - the upper triangle is redundant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, some tri meshes are not manifold (degenerate) - this can lead to situations where an edge is shared by 3 faces. Using a set as the value type does address this.

PS: Why do we need an unordered_map<size_t, set> instead of a simpler vector<set>?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, vector would work. I will update

To store adjacent_vertex and adjacent_index_start keys to represent adjacency matrix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants