ApproxMVBB

repository·main·Indexed 19 days ago

https://github.com/gabyx/approxmvbb

A high-performance C++11 library for approximating the Minimal Volume Oriented Bounding Box (MVBB) of 3D point clouds. It includes utilities for n-dimensional templated kD-Trees, k-Nearest Neighbors (kNN) search, and statistical outlier filtering. The library is optimized for research in Granular Rigidbody Dynamics and supports OpenMP multithreading, 2D convex hulls, and minimal area rectangles.

Tokens
3.9K
Snippets
11
Records
17
Agent score
67%

What's inside ApproxMVBB

  1. Overview of ApproxMVBB capabilities

    main

    ApproxMVBB is a C++11 library designed to provide fast algorithms for approximating the Minimal Volume Oriented Bounding Box (MVBB) of 3D point clouds. It is optimized for research in Granular Rigidbody Dynamics.

    Key features include:

    • MVBB Approximation: Computing an oriented minimal volume box with OpenMP multithreading support.
    • 2D Geometry: Computing convex hulls and minimal area rectangles for 2D point clouds, and performing 2D projections.
    • kD-Tree Support: Fast building of n-dimensional, templated kD-Trees with optimized splitting techniques.
    • k-Nearest Neighbors (kNN): Searching for the $k$ nearest neighbors using the kD-Tree.
    • Outlier Filtering: Statistical outlier filtering of point clouds via kD-Tree and nearest neighbor search.
  2. Use KdTree for outlier filtering

    main

    The library provides a KdTree implementation with support for outlier filtering using k-nearest neighbor (k-NN) search.

    Outlier Filtering Logic:

    1. For each point p, find k nearest neighbors and calculate the mean distance to p.
    2. Calculate the global sample mean (mean) and standard deviation (stdDev) of these distances.
    3. Points where the mean distance is $\ge \text{mean} + \text{stdDevMult} \times \text{stdDev}$ are classified as outliers.
  3. Install and build ApproxMVBB

    main

    To build ApproxMVBB, you need cmake.

    Dependencies

    • Required: Eigen (version 3 or higher).
    • Required: meta (automatically downloaded during build).
    • Optional: pugixml (required if ApproxMVBB_XML_SUPPORT=ON is set).
    • Optional: python3 (for visualization).

    Build Steps

    1. Clone the repository:

      git clone https://github.com/gabyx/ApproxMVBB.git ApproxMVBB
    2. Create a build directory and enter it:

      mkdir Build
      cd Build
    3. Run CMake:

      cmake ../ApproxMVBB

      Note: To install to a specific location like /usr/local/, use: cmake -DCMAKE_INSTALL_PREFIX="/usr/local/" ../ApproxMVBB

    4. Build and install:

      make all
      make install

    To speed up the build, use the -jN flag with make (e.g., make -j4) to utilize multiple threads.

    git clone https://github.com/gabyx/ApproxMVBB.git ApproxMVBB
    mkdir Build
    cd Build
    cmake ../ApproxMVBB
    make all
    make install
  4. Build and run tests

    main

    To build and run the basic test suite:

    cd ApproxMVBB
    git submodule init
    git submodule update
    cd ../Build
    make build_and_test

    To run the tests specifically:

    cd tests
    ./ApproxMVBBTests

    To visualize test results using an IPython notebook:

    cd Build/tests
    ipython notebook /tests/python/PlotTestResults.ipynb
  5. Integrate ApproxMVBB into a C++ project using CMake

    main

    ApproxMVBB provides CMake configuration files (approxmvbb-config.cmake and approxmvbb-config-version.cmake) to simplify integration.

    Using find_package

    Add the following to your CMakeLists.txt:

    find_package(ApproxMVBB [version] [COMPONENTS [SUPPORT_KDTREE] [SUPPORT_XML] ] [Required] )

    Available Targets

    Once found, you can link against these targets:

    • ApproxMVBB::Core: The main library target.
    • ApproxMVBB::KdTreeSupport: Link this if you need kD-Tree functionality (requires SUPPORT_KDTREE component). This target automatically loads the meta dependency.
    • ApproxMVBB::XMLSupport: Link this if you need XML support (requires SUPPORT_XML component). This target automatically loads the pugixml dependency.

    Non-standard Installation Paths

    If the library is installed in a non-system directory, set the ApproxMVBB_DIR variable before calling find_package:

    set(ApproxMVBB_DIR "path/to/installation/lib/cmake")
    find_package(ApproxMVBB [version] [Required] )
    find_package(ApproxMVBB [version] [COMPONENTS [SUPPORT_KDTREE] [SUPPORT_XML] ] [Required] )
    
    target_link_libraries(my_project PRIVATE ApproxMVBB::Core ApproxMVBB::KdTreeSupport)
  6. Enable High-Performance testing mode

    main

    To run tests on very large point clouds (e.g., 140 million points), you must enable high-performance mode. This requires setting the CMake variable ApproxMVBB_TESTS_HIGH_PERFORMANCE to ON and initializing the additional submodule.

    cd ApproxMVBB
    git submodule init
    git submodule update
    # Extract large test files
    cd additional/tests/files
    cat Lucy* | tar xz

    After these steps, rebuild the tests.

  7. Configure OpenMP multithreading

    main

    The library supports multithreading via OpenMP. You can control thread usage through CMake cache variables:

    • ApproxMVBB_OPENMP_USE_OPENMP: Set to On to enable OpenMP.
    • ApproxMVBB_OPENMP_USE_NTHREADS: Set to On or Off. If Off, the number of threads is determined at runtime (default).
  8. Configure ApproxMVBB build options

    main

    When running cmake, you can control which parts of the project are built using several flags. These can be passed via the command line using -D<VARIABLE>=ON/OFF or configured via cmake-gui.

    Available build flags:

    • ApproxMVBB_BUILD_LIBRARY
    • ApproxMVBB_BUILD_TESTS
    • ApproxMVBB_BUILD_EXAMPLE
    • ApproxMVBB_BUILD_BENCHMARKS
    • ApproxMVBB_XML_SUPPORT: Set to ON to enable pugixml support (defaults to OFF).
  9. Visualize a KdTree using PlotKdTree

    main

    To visualize a KdTree structure (typically parsed from an XML file), use the PlotKdTree class. This class uses vispy to create an interactive 3D scene where you can inspect the axis-aligned bounding boxes (AABBs) of the tree's leaves.

    Workflow

    1. Parse your KdTree XML file using KdTree.parseFromXML(root).
    2. Instantiate PlotKdTree().
    3. Call .plot(kdTree, plotPoints, plotSubDivs) to launch the interactive viewer.

    Parameters

    • kdTree: The parsed KdTree object.
    • plotPoints (bool): Whether to plot individual points (not used in the provided snippet).
    • plotSubDivs (bool): If True, the viewer will draw the bounding boxes for all leaf nodes in the tree.
    import xml.etree.ElementTree as ET
    from Tools.Parsers.KdTreeXMLParser import KdTree
    
    # Load the tree from an XML file
    file = "KdTreeResults.xml"
    tree = ET.parse(file)
    root = tree.getroot()
    
    # Parse and visualize
    kdTree = KdTree.parseFromXML(root)
    p = PlotKdTree()
    p.plot(kdTree, False, True)
  10. Compute an approximate Minimal Volume Oriented Bounding Box (MVBB)

    main

    Use ApproxMVBB::approximateMVBB to find an approximate minimal volume oriented bounding box for a 3D point cloud.

    Important Considerations:

    • Degenerate Boxes: If the input points define a plane or line, the resulting box might have zero volume in some axes. Use oobb.expandToMinExtentRelative(0.1) to enlarge the box by a percentage of its largest extent to avoid zero-width dimensions.
    • Point Coverage: Because the algorithm uses internal sampling for speed, the resulting OOBB might not contain all original points. To ensure all points are enclosed, you must manually iterate through your points and use oobb.unite().
    • Coordinate Frames: The returned oobb object uses a local coordinate frame K. To transform a point from the local frame K back to the world frame I, multiply the local point by the rotation quaternion oobb.m_q_KI.
    #include <iostream>
    #include "ApproxMVBB/ComputeApproxMVBB.hpp"
    
    int main(int argc, char** argv)
    {
          // 1. Setup points (e.g., 10,000 points in 3D)
          ApproxMVBB::Matrix3Dyn points(3, 10000);
          points.setRandom();
    
          // 2. Compute approximate MVBB
          // Params: points, epsilon, pointSamples, gridSize, mvbbDiamOptLoops, mvbbGridSearchOptLoops
          ApproxMVBB::OOBB oobb = ApproxMVBB::approximateMVBB(points, 0.001, 500, 5, 0, 5);
    
          // 3. Handle potential degeneracy
          oobb.expandToMinExtentRelative(0.1);
    
          // 4. Ensure all points are contained (Compensation loop)
          ApproxMVBB::Matrix33 A_KI = oobb.m_q_KI.matrix().transpose();
          auto size = points.cols();
          for( unsigned int i=0; i<size; ++i ) {
              oobb.unite(A_KI * points.col(i));
          }
    
          // 5. Transform local point to world frame
          // ApproxMVBB::Vector3 p_world = oobb.m_q_KI * p_local;
    
          return 0;
    }
  11. Parameters for approximateMVBB

    main

    The ApproxMVBB::approximateMVBB function accepts the following parameters:

    • pts: The input point cloud.
    • epsilon: Absolute tolerance for the diameter approximation (has same units as pts).
    • pointSamples: Number of points used for the exhaustive grid search procedure.
    • gridSize: The x, y, z dimension of the grid defined by the initial bounding box.
    • mvbbDiamOptLoops: Number of optional optimization loops performed on the full point cloud (can be time-consuming).
    • mvbbGridSearchOptLoops: Number of optional optimization loops performed on the representative sample RS during the grid search phase.
    ApproxMVBB::approximateMVBB(pts,
                                epsilon,
                                pointSamples,
                                gridSize,
                                mvbbDiamOptLoops,
                                mvbbGridSearchOptLoops)