owensgroup / RXMesh

GPU-accelerated triangle mesh processing
BSD 2-Clause "Simplified" License
226 stars 30 forks source link
3d 3d-graphics cuda data-structure geometry geometry-processing gpu mesh mesh-processing parallel-computing surface-mesh

RXMesh Ubuntu Windows


Contents

About

RXMesh is a surface triangle mesh data structure and programming model for processing static meshes on the GPU. RXMesh aims at provides a high-performance, generic, and compact data structure that can handle meshes regardless of their quality (e.g., non-manifold). The programming model helps to hide the complexity of the data structure and provides an intuitive access model for different use cases. For more details, please check out our paper and GTC talk:

The library also features a sparse and dense matrix infrastructure that is tightly coupled with the mesh data structure. We expose various cuSolver, cuSparse, and cuBlas operations through the sparse and dense matrices, tailored for geometry processing applications.

This repository provides 1) source code to reproduce the results presented in the paper (git tag v0.1.0) and 2) ongoing development of RXMesh.

Compilation

The code can be compiled on Ubuntu, Windows, and WSL providing that CUDA (>=11.1.0) is installed. To run the executable(s), an NVIDIA GPU should be installed on the machine.

Dependencies

All the dependencies are installed automatically! To compile the code:

> git clone https://github.com/owensgroup/RXMesh.git
> cd RXMesh
> mkdir build 
> cd build 
> cmake ../

Depending on the system, this will generate either a .sln project on Windows or a make file for a Linux system.

Organization

RXMesh is a CUDA/C++ header-only library. All unit tests are under the tests/ folder. This includes the unit test for some basic functionalities along with the unit test for the query operations. All applications are under the apps/ folder.

Programming Model

The goal of defining a programming model is to make it easy to write applications using RXMesh without getting into the nuances of the data structure. Applications written using RXMesh are composed of one or more of the high-level building blocks defined under Computation. To use these building blocks, the user would have to interact with data structures specific to RXMesh discussed under Structures. Finally, RXMesh integrates Polyscope as a mesh Viewer which the user can use to render their final results or for debugging purposes.

Structures

Computation

Viewer

Starting v0.2.1, RXMesh integrates Polyscope as a mesh viewer. To use it, make sure to turn on the CMake parameter USE_POLYSCOPE i.e.,

> cd build 
> cmake -DUSE_POLYSCOPE=True ../

By default, the parameter is set to True. RXMesh implements the necessary functionalities to pass attributes to Polyscope—thanks to its data adaptors. However, this needs attributes to be moved to the host first before passing it to Polyscope. For more information about Polyscope's different visualization options, please checkout Polyscope's Surface Mesh documentation.

Matrices and Vectors


RXMeshStatic rx("input.obj");

//Input mesh coordinates as VertexAttribute
std::shared_ptr<VertexAttribute<float>> x = rx.get_input_vertex_coordinates();

//Convert the attributes to a (#vertices x 3) dense matrix 
std::shared_ptr<DenseMatrix<float>> x_mat = x->to_matrix();

//do something with x_mat
//....

//Populate the VertexAttribute coordinates back with the content of the dense matrix
x->from_matrix(x_mat.get());

Dense matrices can be accessed using the usual row and column indices or via the mesh element handle (Vertex/Edge/FaceHandle) as a row index. This allows for easy access to the correct row associated with a specific vertex, edge, or face. Dense matrices support various operations such as absolute sum, AXPY, dot products, norm2, scaling, and swapping.

RXMesh supports sparse matrices, where the sparsity pattern matches the query operations. For example, it is often necessary to build a sparse matrix of size #V x #V with non-zero values at (i, j) only if the vertex corresponding to row i is connected by an edge to the vertex corresponding to column j. Currently, we only support the VV sparsity pattern, but we are working on expanding to all other types of queries.

The sparse matrix can be used to solve a linear system via Cholesky, LU, or QR factorization (relying on cuSolver)). The solver offers two APIs. The high-level API reorders the input sparse matrix (to reduce non-zero fill-in after matrix factorization) and allocates the additional memory needed to solve the system. Repeated calls to this API will reorder the matrix and allocate/deallocate the temporary memory with each call. For scenarios where the matrix remains unchanged but multiple right-hand sides need to be solved, users can utilize the low-level API, which splits the solve method into pre_solve() and solve(). The former reorders the matrix and allocates temporary memory only once. The low-level API is currently only supported for Cholesky-based factorization. Check out the MCF application for an example of how to set up and use the solver.

Similar to dense matrices, sparse matrices also support accessing the matrix using the VertexHandle and multiplication by dense matrices.

Replicability

This repo was awarded the replicability stamp by the Graphics Replicability Stamp Initiative (GRSI) :tada:. Visit git tag v0.1.0 for more information about replicability scripts.

Bibtex

@article{Mahmoud:2021:RAG,
  author       = {Ahmed H. Mahmoud and Serban D. Porumbescu and John D. Owens},
  title        = {{RXM}esh: A {GPU} Mesh Data Structure},
  journal      = {ACM Transactions on Graphics},
  year         = 2021,
  volume       = 40,
  number       = 4,
  month        = aug,
  issue_date   = {August 2021},
  articleno    = 104,
  numpages     = 16,
  pages        = {104:1--104:16},
  url          = {https://escholarship.org/uc/item/8r5848vp},
  full_talk    = {https://youtu.be/Se_cNAol4hY},
  short_talk   = {https://youtu.be/V_SHMXnCVws},
  doi          = {10.1145/3450626.3459748},
  acmauthorize = {https://dl.acm.org/doi/10.1145/3450626.3459748?cid=81100458295},
  acceptance   = {149/444 (33.6\%)},
  ucdcite      = {a140}
}