/Spectral-Based-Mesh-Segmentation

Spectral Based Mesh Segmentation

Primary LanguageC++

Spectral-Based-Mesh-Segmentation

Spectral Based Mesh Segmentation build on top of a custom simple self-made OpenGL framework

A Graph Theory course term project. Inspired from this paper:

Mejia, D., Ruiz-Salguero, O., & Cadavid, C. A. (2017). Spectral-based mesh segmentation. International Journal on Interactive Design and Manufacturing (IJIDeM), 11, 503-514.

A simple mesh segmentation framework relies on the Laplacian Matrix. Scroll down to see results

How to use?

You can either clone the project and use build/Spectral_Based_Mesh_Segmentation.sln by configuring necessary library directions (Eigen, Spectra, GLFW, GLEW) or configure CMakeList.txt with your own paths to mentioned libraries to create a solution file.

Note that OpenGL stuff (GLFW and GLEW) is not mandatory, you can simply extract Mesh.h and Mesh.cpp with other dependencies (SVertex.h and STriangle.h) and use them independently on your own projects but obviously, you need Eigen and Spectra.

Once you've finished the configuration phase (congrats by the way!); the usage is simple.

    Mesh myMesh; //create mesh object
    myMesh.loadOFF("C:/Cpp_Projects/Spectral_Based_Mesh_Segmentation/3DObjects/125.off"); //Load your 3D Object
    myMesh.segment(5); //call segment method with the desired segmentation count

If you want to make use of the simple OpenGL renderer I've created for this project, you can follow these steps:

    Window window(1280, 1024, "My Window"); //Create a window

    if (glewInit() != GLEW_OK) { //check if everything is OK
        printf("GLEW initialisation failed!");
        glfwDestroyWindow(window.m_Window);
        glfwTerminate();
        return -1;
    }
    Mesh myMesh;
    myMesh.loadOFF("C:/Cpp_Projects/Spectral_Based_Mesh_Segmentation/3DObjects/125.off");

    Camera camera(myMesh.getBestCamPos().value(), glm::vec3(0.0f, 1.0f, 0.0f)); // create a camera and make it look to your mesh
    // Load a shader program
    Shader myShader;
    myShader.Generate("C:/Cpp_Projects/Spectral_Based_Mesh_Segmentation/Shaders/vertexShader.glsl", "C:/Cpp_Projects/Spectral_Based_Mesh_Segmentation/Shaders/fragmentShader.glsl"); //load your shaders so that we can paint stuff
    
    MeshRenderer meshRenderer(myMesh, myShader); //create mesh renderer to link your mesh data with shaders
    myMesh.segment(5); //segment your mesh (you can do it anywhere after loading your 3d object)
    meshRenderer.PaintVertices(); //with the segmentation, you have colored vertex data and you can use it
    meshRenderer.Render(window,camera); //the almighty render loop!
    

As you can see, this repo is very open for future improvements (for example, Mesh class can write to the 3D object file the colors of vertices) and you are always welcome to do so!

How it works?

If you want to dive deep on the topic you definitely should read the paper I uploaded. To summarize, we are creating the Laplacian Matrix of the mesh and then we are finding its second smallest Eigenvalue and corresponding Eigenvector, thanks to amazing Eigen and Spectra libraries,we can store sparse matrices (w/Eigen), which results in efficient memory usage, and can calculate only the first two smallest eigenvectors (w/Spectra) by avoiding spending time on trivial Eigenvectors.

Results