├── .clang-format ├── .codedocs ├── .github └── workflows │ └── build.yml ├── .gitignore ├── CMakeLists.txt ├── Doxyfile ├── LICENSE ├── README.md ├── cmake ├── Doxyfile.in ├── cilantroConfig.cmake.in ├── cmake_uninstall.cmake.in └── config.hpp.in ├── docs ├── Makefile ├── about.rst ├── conf.py ├── getting_started.rst ├── index.rst └── make.bat ├── examples ├── CMakeLists.txt ├── connected_component_extraction.cpp ├── convex_hull.cpp ├── flat_convex_hull.cpp ├── fusion.cpp ├── grid_downsampler.cpp ├── image_point_cloud_conversions.cpp ├── image_viewer.cpp ├── kd_tree.cpp ├── kmeans.cpp ├── matrix_io.cpp ├── mean_shift.cpp ├── multidimensional_scaling.cpp ├── non_rigid_icp.cpp ├── normal_estimation.cpp ├── ply_io.cpp ├── principal_component_analysis.cpp ├── ransac_plane_estimator.cpp ├── ransac_transform_estimator.cpp ├── rigid_icp.cpp ├── robust_normal_estimation.cpp ├── space_region_2d.cpp ├── space_region_3d.cpp ├── spectral_clustering.cpp ├── test_clouds │ ├── frame_1.ply │ ├── frame_2.ply │ └── test.ply └── visualizer.cpp ├── format.sh ├── include └── cilantro │ ├── 3rd_party │ ├── Spectra │ │ ├── DavidsonSymEigsSolver.h │ │ ├── GenEigsBase.h │ │ ├── GenEigsComplexShiftSolver.h │ │ ├── GenEigsRealShiftSolver.h │ │ ├── GenEigsSolver.h │ │ ├── JDSymEigsBase.h │ │ ├── LinAlg │ │ │ ├── Arnoldi.h │ │ │ ├── BKLDLT.h │ │ │ ├── DoubleShiftQR.h │ │ │ ├── Lanczos.h │ │ │ ├── Orthogonalization.h │ │ │ ├── RitzPairs.h │ │ │ ├── SearchSpace.h │ │ │ ├── TridiagEigen.h │ │ │ ├── UpperHessenbergEigen.h │ │ │ ├── UpperHessenbergQR.h │ │ │ └── UpperHessenbergSchur.h │ │ ├── MatOp │ │ │ ├── DenseCholesky.h │ │ │ ├── DenseGenComplexShiftSolve.h │ │ │ ├── DenseGenMatProd.h │ │ │ ├── DenseGenRealShiftSolve.h │ │ │ ├── DenseSymMatProd.h │ │ │ ├── DenseSymShiftSolve.h │ │ │ ├── SparseCholesky.h │ │ │ ├── SparseGenComplexShiftSolve.h │ │ │ ├── SparseGenMatProd.h │ │ │ ├── SparseGenRealShiftSolve.h │ │ │ ├── SparseRegularInverse.h │ │ │ ├── SparseSymMatProd.h │ │ │ ├── SparseSymShiftSolve.h │ │ │ ├── SymShiftInvert.h │ │ │ └── internal │ │ │ │ ├── ArnoldiOp.h │ │ │ │ ├── SymGEigsBucklingOp.h │ │ │ │ ├── SymGEigsCayleyOp.h │ │ │ │ ├── SymGEigsCholeskyOp.h │ │ │ │ ├── SymGEigsRegInvOp.h │ │ │ │ └── SymGEigsShiftInvertOp.h │ │ ├── SymEigsBase.h │ │ ├── SymEigsShiftSolver.h │ │ ├── SymEigsSolver.h │ │ ├── SymGEigsShiftSolver.h │ │ ├── SymGEigsSolver.h │ │ ├── Util │ │ │ ├── CompInfo.h │ │ │ ├── GEigsMode.h │ │ │ ├── SelectionRule.h │ │ │ ├── SimpleRandom.h │ │ │ ├── TypeTraits.h │ │ │ └── Version.h │ │ └── contrib │ │ │ ├── LOBPCGSolver.h │ │ │ └── PartialSVDSolver.h │ ├── eigen_quadprog │ │ └── eiquadprog.hpp │ ├── libqhull_r │ │ ├── COPYING.txt │ │ ├── geom_r.h │ │ ├── io_r.h │ │ ├── libqhull_r.h │ │ ├── mem_r.h │ │ ├── merge_r.h │ │ ├── poly_r.h │ │ ├── qhull_ra.h │ │ ├── qset_r.h │ │ ├── random_r.h │ │ ├── stat_r.h │ │ └── user_r.h │ ├── libqhullcpp │ │ ├── COPYING.txt │ │ ├── Coordinates.h │ │ ├── PointCoordinates.h │ │ ├── Qhull.h │ │ ├── QhullError.h │ │ ├── QhullFacet.h │ │ ├── QhullFacetList.h │ │ ├── QhullFacetSet.h │ │ ├── QhullHyperplane.h │ │ ├── QhullIterator.h │ │ ├── QhullLinkedList.h │ │ ├── QhullPoint.h │ │ ├── QhullPointSet.h │ │ ├── QhullPoints.h │ │ ├── QhullQh.h │ │ ├── QhullRidge.h │ │ ├── QhullSet.h │ │ ├── QhullSets.h │ │ ├── QhullStat.h │ │ ├── QhullUser.h │ │ ├── QhullVertex.h │ │ ├── QhullVertexSet.h │ │ ├── RboxPoints.h │ │ ├── RoadError.h │ │ ├── RoadLogEvent.h │ │ └── functionObjects.h │ ├── nanoflann │ │ └── nanoflann.hpp │ └── tinyply │ │ └── tinyply.h │ ├── cilantro.hpp │ ├── clustering.hpp │ ├── clustering │ ├── clustering_base.hpp │ ├── connected_component_extraction.hpp │ ├── kmeans.hpp │ ├── mean_shift.hpp │ └── spectral_clustering.hpp │ ├── core.hpp │ ├── core │ ├── common_accumulators.hpp │ ├── common_pair_evaluators.hpp │ ├── correspondence.hpp │ ├── covariance.hpp │ ├── data_containers.hpp │ ├── grid_accumulator.hpp │ ├── grid_downsampler.hpp │ ├── image_point_cloud_conversions.hpp │ ├── kd_tree.hpp │ ├── nearest_neighbors.hpp │ ├── normal_estimation.hpp │ ├── openmp_reductions.hpp │ ├── principal_component_analysis.hpp │ ├── random.hpp │ ├── space_transformations.hpp │ └── spectral_embedding_base.hpp │ ├── correspondence_search.hpp │ ├── correspondence_search │ ├── common_transformable_feature_adaptors.hpp │ ├── correspondence_search_kd_tree.hpp │ ├── correspondence_search_kd_tree_utilities.hpp │ ├── correspondence_search_oracle.hpp │ └── correspondence_search_projective.hpp │ ├── model_estimation.hpp │ ├── model_estimation │ ├── ransac_base.hpp │ ├── ransac_hyperplane_estimator.hpp │ └── ransac_transform_estimator.hpp │ ├── registration.hpp │ ├── registration │ ├── correspondence_search_combined_metric_adaptor.hpp │ ├── correspondence_search_combined_metric_combiner.hpp │ ├── icp_base.hpp │ ├── icp_common_instances.hpp │ ├── icp_single_transform_combined_metric.hpp │ ├── icp_single_transform_point_to_point_metric.hpp │ ├── icp_warp_field_combined_metric_dense.hpp │ ├── icp_warp_field_combined_metric_sparse.hpp │ ├── transform_estimation.hpp │ ├── warp_field_estimation.hpp │ └── warp_field_utilities.hpp │ ├── spatial.hpp │ ├── spatial │ ├── convex_hull_utilities.hpp │ ├── convex_polytope.hpp │ ├── flat_convex_hull_3d.hpp │ └── space_region.hpp │ ├── utilities.hpp │ ├── utilities │ ├── io_utilities.hpp │ ├── multidimensional_scaling.hpp │ ├── nearest_neighbor_graph_utilities.hpp │ ├── ply_io.hpp │ ├── point_cloud.hpp │ └── timer.hpp │ ├── visualization.hpp │ └── visualization │ ├── colormap.hpp │ ├── common_renderables.hpp │ ├── image_viewer.hpp │ ├── renderable.hpp │ ├── visualizer.hpp │ └── visualizer_handler.hpp └── src ├── 3rd_party ├── libqhull_r │ ├── COPYING.txt │ ├── geom2_r.c │ ├── geom_r.c │ ├── global_r.c │ ├── io_r.c │ ├── libqhull_r.c │ ├── mem_r.c │ ├── merge_r.c │ ├── poly2_r.c │ ├── poly_r.c │ ├── qset_r.c │ ├── random_r.c │ ├── rboxlib_r.c │ ├── stat_r.c │ ├── user_r.c │ ├── usermem_r.c │ ├── userprintf_r.c │ └── userprintf_rbox_r.c ├── libqhullcpp │ ├── COPYING.txt │ ├── Coordinates.cpp │ ├── PointCoordinates.cpp │ ├── Qhull.cpp │ ├── QhullFacet.cpp │ ├── QhullFacetList.cpp │ ├── QhullFacetSet.cpp │ ├── QhullHyperplane.cpp │ ├── QhullPoint.cpp │ ├── QhullPointSet.cpp │ ├── QhullPoints.cpp │ ├── QhullQh.cpp │ ├── QhullRidge.cpp │ ├── QhullSet.cpp │ ├── QhullStat.cpp │ ├── QhullUser.cpp │ ├── QhullVertex.cpp │ ├── QhullVertexSet.cpp │ ├── RboxPoints.cpp │ ├── RoadError.cpp │ └── RoadLogEvent.cpp └── tinyply │ └── tinyply.cpp └── visualization ├── common_renderables.cpp ├── image_viewer.cpp ├── renderable.cpp ├── visualizer.cpp └── visualizer_handler.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | AccessModifierOffset: -2 5 | AlignEscapedNewlines: Left 6 | AlwaysBreakBeforeMultilineStrings: false 7 | ColumnLimit: 100 8 | DerivePointerAlignment: false 9 | IndentCaseLabels: false 10 | PointerAlignment: Left 11 | SortIncludes: false 12 | ... 13 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | cilantro_DIR: ${{github.workspace}}/cilantro 12 | Pangolin_DIR: ${{github.workspace}}/Pangolin 13 | 14 | defaults: 15 | run: 16 | shell: bash 17 | 18 | jobs: 19 | build: 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - name: Clone Pangolin 24 | uses: actions/checkout@v3 25 | with: 26 | repository: stevenlovegrove/Pangolin 27 | submodules: true 28 | path: ${{env.Pangolin_DIR}} 29 | 30 | - name: Install Pangolin dependencies 31 | run: ${{env.Pangolin_DIR}}/scripts/install_prerequisites.sh --package-manager apt recommended 32 | 33 | - name: Configure Pangolin 34 | run: cmake -B ${{env.Pangolin_DIR}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -S ${{env.Pangolin_DIR}} 35 | 36 | - name: Build Pangolin 37 | run: cmake --build ${{env.Pangolin_DIR}}/build --config ${{env.BUILD_TYPE}} -- -j8 38 | 39 | - name: Clone cilantro 40 | uses: actions/checkout@v3 41 | with: 42 | path: ${{env.cilantro_DIR}} 43 | 44 | - name: Configure cilantro 45 | run: cmake -B ${{env.cilantro_DIR}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DPangolin_DIR=${{env.Pangolin_DIR}}/build -S ${{env.cilantro_DIR}} 46 | 47 | - name: Build cilantro 48 | run: cmake --build ${{env.cilantro_DIR}}/build --config ${{env.BUILD_TYPE}} -- -j8 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | # Build/IDE folders 32 | build/* 33 | .idea/* 34 | .vscode/* 35 | cmake-build-release/* 36 | cmake-build-debug/* 37 | *.kdev4* 38 | 39 | # ReadTheDocs 40 | docs/_build/* 41 | docs/build/* 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Konstantinos Zampogiannis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmake/cilantroConfig.cmake.in: -------------------------------------------------------------------------------- 1 | get_filename_component(PROJECT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 2 | 3 | # Library dependencies (contains definitions for IMPORTED targets) 4 | if(NOT TARGET @PROJECT_NAME@ AND NOT @PROJECT_NAME@_BINARY_DIR) 5 | include("${PROJECT_CMAKE_DIR}/@PROJECT_NAME@Targets.cmake") 6 | include(CMakeFindDependencyMacro) 7 | find_dependency(Eigen3) 8 | @DEPENDS_OpenMP@ 9 | @DEPENDS_Pangolin@ 10 | endif() 11 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | -------------------------------------------------------------------------------- /cmake/config.hpp.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #cmakedefine HAVE_PANGOLIN 4 | #cmakedefine ENABLE_NON_DETERMINISTIC_PARALLELISM 5 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = cilantro 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/about.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | About 3 | ===== 4 | 5 | What is cilantro? 6 | ================= 7 | **cilantro** is a lean and fast C++ library for working with point cloud data, with emphasis given to the 3D case. It includes efficient implementations for a variety of common operations, providing a clean API and attempting to minimize the amount of boilerplate code. The library is extensively templated, enabling operations on point data of arbitrary numerical type and dimensionality (where applicable) and featuring a modular/extensible design of the more complex procedures, while, at the same time, providing convenience aliases/wrappers for the most common cases. A high-level description of **cilantro** can be found in our `technical report`_. 8 | 9 | Features 10 | ======== 11 | 12 | **Basic operations:** 13 | - General dimension kd-trees (using bundled nanoflann_) 14 | - Surface normal and curvature estimation from raw point clouds 15 | - General dimension grid-based point cloud resampling 16 | - Principal Component Analysis 17 | - Basic I/O utilities for 3D point clouds (in PLY format, using bundled tinyply_) and Eigen matrices 18 | - RGBD images to/from point cloud utility functions 19 | 20 | **Convex hulls and spatial reasoning tools:** 21 | - A general dimension convex polytope representation that is computed (using bundled Qhull_) from either vertex or half-space intersection input and allows for easy switching between the respective representations 22 | - A representation of generic (general dimension) space regions as unions of convex polytopes that implements set operations 23 | 24 | .. image:: https://kzampog.github.io/images/convex.png 25 | :width: 800 26 | :align: center 27 | 28 | **Clustering:** 29 | - General dimension k-means clustering that supports all distance metrics supported by nanoflann 30 | - Spectral clustering based on various graph Laplacian types (using bundled Spectra) 31 | - Mean-shift clustering with custom kernel support 32 | - Connected component based point cloud segmentation that supports arbitrary point-wise similarity functions 33 | 34 | .. image:: https://kzampog.github.io/images/conn_comp.png 35 | :width: 800 36 | :align: center 37 | 38 | **Geometric registration:** 39 | - Multiple generic Iterative Closest Point implementations that support arbitrary correspondence search methods in arbitrary point feature spaces for: 40 | 41 | * **Rigid** or **affine** alignment under the point-to-point metric (general dimension), point-to-plane metric (2D or 3D), or any combination thereof 42 | * **Non-rigid** alignment of 2D or 3D point sets, by means of a robustly regularized, **locally-rigid** or **locally-affine** deformation field, under any combination of the point-to-point and point-to-plane metrics; implementations for both *densely* and *sparsely* (by means of an Embedded Deformation Graph) supported warp fields are provided 43 | 44 | .. image:: https://kzampog.github.io/images/fusion.png 45 | :width: 800 46 | :align: center 47 | .. image:: https://kzampog.github.io/images/non_rigid.png 48 | :width: 800 49 | :align: center 50 | 51 | **Robust model estimation:** 52 | - A RANSAC estimator template and instantiations thereof for general dimension: 53 | 54 | * Robust hyperplane estimation 55 | * Rigid point cloud registration given noisy correspondences 56 | 57 | **Visualization:** 58 | - Classical Multidimensional Scaling (using bundled Spectra_ for eigendecompositions) 59 | - A powerful, extensible, and easy to use 3D visualizer 60 | 61 | .. _nanoflann: https://github.com/jlblancoc/nanoflann 62 | .. _Spectra: https://github.com/yixuan/spectra 63 | .. _tinyply: https://github.com/ddiakopoulos/tinyply 64 | .. _Qhull: http://www.qhull.org/ 65 | .. _technical report: https://arxiv.org/abs/1807.00399 66 | -------------------------------------------------------------------------------- /docs/getting_started.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Getting started 3 | =============== 4 | 5 | Dependencies 6 | ============ 7 | 8 | * Eigen_ (version 3.3 or newer) [**required**] 9 | * Pangolin_ (built with Eigen enabled) [**optional**; needed for visualization modules and most examples] 10 | 11 | How to build 12 | ============ 13 | **cilantro** is developed and tested on Ubuntu variants (18.04 and newer) using CMake_. To clone and build the library (with bundled examples), execute the following in a terminal: 14 | 15 | .. code-block:: bash 16 | 17 | git clone https://github.com/kzampog/cilantro.git 18 | cd cilantro 19 | mkdir build 20 | cd build 21 | cmake .. 22 | make -j 23 | 24 | .. _Pangolin: https://github.com/stevenlovegrove/Pangolin 25 | .. _Eigen: http://eigen.tuxfamily.org/index.php?title=Main_Page 26 | .. _CMake: https://cmake.org/ -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. cilantro documentation master file, created by 2 | sphinx-quickstart on Sat May 5 14:48:48 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ======== 7 | cilantro 8 | ======== 9 | 10 | .. image:: https://kzampog.github.io/images/cilantro_left.png 11 | :width: 75 12 | 13 | .. toctree:: 14 | :maxdepth: 2 15 | :caption: Contents: 16 | 17 | about 18 | getting_started 19 | 20 | 21 | .. Indices and tables 22 | .. ================== 23 | 24 | .. * :ref:`genindex` 25 | .. * :ref:`modindex` 26 | .. * :ref:`search` 27 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=cilantro 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(Pangolin_FOUND) 2 | file(GLOB example_files ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) 3 | foreach(example_file ${example_files}) 4 | get_filename_component(example_name ${example_file} NAME_WE) 5 | add_executable(${example_name} ${example_file}) 6 | target_link_libraries(${example_name} ${PROJECT_NAME}) 7 | endforeach() 8 | endif() 9 | -------------------------------------------------------------------------------- /examples/connected_component_extraction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char** argv) { 9 | if (argc < 2) { 10 | std::cout << "Please provide path to PLY file." << std::endl; 11 | return 0; 12 | } 13 | 14 | cilantro::PointCloud3f cloud(argv[1]); 15 | cloud.gridDownsample(0.005f).removeInvalidData(); 16 | 17 | if (!cloud.hasNormals()) { 18 | std::cout << "Input cloud does not have normals!" << std::endl; 19 | return 0; 20 | } 21 | 22 | // Perform segmentation 23 | cilantro::Timer timer; 24 | timer.start(); 25 | 26 | cilantro::RadiusNeighborhoodSpecification nh(0.02f * 0.02f); 27 | cilantro::NormalsProximityEvaluator ev(cloud.normals, (float)(2.0 * M_PI / 180.0)); 28 | 29 | cilantro::ConnectedComponentExtraction3f<> cce(cloud.points); 30 | cce.segment(nh, ev, 100, cloud.size()); 31 | 32 | timer.stop(); 33 | 34 | std::cout << "Segmentation time: " << timer.getElapsedTime() << "ms" << std::endl; 35 | std::cout << cce.getNumberOfClusters() << " components found" << std::endl; 36 | 37 | // Build a color map 38 | size_t num_labels = cce.getNumberOfClusters(); 39 | const auto& labels = cce.getPointToClusterIndexMap(); 40 | 41 | cilantro::VectorSet3f color_map(3, num_labels + 1); 42 | for (size_t i = 0; i < num_labels; i++) { 43 | color_map.col(i) = Eigen::Vector3f::Random().cwiseAbs(); 44 | } 45 | // No label 46 | color_map.col(num_labels).setZero(); 47 | 48 | cilantro::VectorSet3f colors(3, labels.size()); 49 | for (size_t i = 0; i < colors.cols(); i++) { 50 | colors.col(i) = color_map.col(labels[i]); 51 | } 52 | 53 | // Create a new colored cloud 54 | cilantro::PointCloud3f cloud_seg(cloud.points, cloud.normals, colors); 55 | 56 | // Visualize result 57 | const std::string window_name = "ConnectedComponentSegmentation demo"; 58 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 59 | pangolin::Display("multi") 60 | .SetBounds(0.0, 1.0, 0.0, 1.0) 61 | .SetLayout(pangolin::LayoutEqual) 62 | .AddDisplay(pangolin::Display("disp1")) 63 | .AddDisplay(pangolin::Display("disp2")); 64 | 65 | cilantro::Visualizer viz1(window_name, "disp1"); 66 | viz1.addObject("cloud", cloud); 67 | 68 | cilantro::Visualizer viz2(window_name, "disp2"); 69 | viz2.addObject("cloud_seg", cloud_seg); 70 | 71 | // Keep viewpoints in sync 72 | viz2.setRenderState(viz1.getRenderState()); 73 | 74 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 75 | viz1.clearRenderArea(); 76 | viz1.render(); 77 | viz2.render(); 78 | pangolin::FinishFrame(); 79 | } 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /examples/flat_convex_hull.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char** argv) { 8 | if (argc < 2) { 9 | std::cout << "Please provide path to PLY file." << std::endl; 10 | return 0; 11 | } 12 | 13 | cilantro::PointCloud3f cloud(argv[1]); 14 | cloud.normals.resize(3, 0); 15 | 16 | if (cloud.size() < 3) { 17 | std::cout << "Input cloud empty or too small!" << std::endl; 18 | return 0; 19 | } 20 | 21 | // PointCloudHullFlat also inherits from PrincipalComponentAnalysis 22 | cilantro::FlatConvexHull3f flat_hull(cloud.points, true, true); 23 | cloud.points = flat_hull.reconstruct<2>(flat_hull.project<2>(cloud.points)); 24 | 25 | const auto& face_v_ind = flat_hull.getFacetVertexIndices(); 26 | cilantro::VectorSet3f src_points(3, face_v_ind.size()); 27 | cilantro::VectorSet3f dst_points(3, face_v_ind.size()); 28 | for (size_t i = 0; i < face_v_ind.size(); i++) { 29 | src_points.col(i) = flat_hull.getVertices3D().col(face_v_ind[i][0]); 30 | dst_points.col(i) = flat_hull.getVertices3D().col(face_v_ind[i][1]); 31 | } 32 | 33 | const std::string window_name = "2D convex hull in 3D space"; 34 | pangolin::CreateWindowAndBind(window_name, 640, 480); 35 | cilantro::Visualizer viz(window_name, "disp"); 36 | viz.addObject("cloud", cloud, 37 | cilantro::RenderingProperties().setOpacity(0.5)); 38 | viz.addObject( 39 | "hull_cloud", flat_hull.getVertices3D(), 40 | cilantro::RenderingProperties().setPointColor(1, 0, 0).setPointSize(10.0)); 41 | viz.addObject("hull_lines", src_points, dst_points, 42 | cilantro::RenderingProperties() 43 | .setLineColor(0, 0, 1) 44 | .setLineWidth(5.0) 45 | .setLineDensityFraction(1.0)); 46 | viz.spin(); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /examples/grid_downsampler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char** argv) { 9 | if (argc < 2) { 10 | std::cout << "Please provide path to PLY file." << std::endl; 11 | return 0; 12 | } 13 | 14 | cilantro::PointCloud3f cloud(argv[1]); 15 | 16 | if (cloud.isEmpty()) { 17 | std::cout << "Input cloud is empty!" << std::endl; 18 | return 0; 19 | } 20 | 21 | cilantro::Timer timer; 22 | timer.start(); 23 | cilantro::PointCloud3f cloud_d(cloud.gridDownsampled(0.01f)); 24 | timer.stop(); 25 | 26 | std::cout << "Before: " << cloud.size() << std::endl; 27 | std::cout << "After: " << cloud_d.size() << std::endl; 28 | 29 | std::cout << "Downsampling time: " << timer.getElapsedTime() << "ms" << std::endl; 30 | 31 | const std::string window_name = "VoxelGrid demo"; 32 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 33 | pangolin::Display("multi") 34 | .SetBounds(0.0, 1.0, 0.0, 1.0) 35 | .SetLayout(pangolin::LayoutEqual) 36 | .AddDisplay(pangolin::Display("disp1")) 37 | .AddDisplay(pangolin::Display("disp2")); 38 | 39 | cilantro::Visualizer viz1(window_name, "disp1"); 40 | viz1.addObject("cloud", cloud, cilantro::RenderingProperties()); 41 | 42 | cilantro::Visualizer viz2(window_name, "disp2"); 43 | viz2.addObject("cloud_d", cloud_d, 44 | cilantro::RenderingProperties()); 45 | 46 | // Keep viewpoints in sync 47 | viz2.setRenderState(viz1.getRenderState()); 48 | 49 | std::cout << "Press 'n' to toggle rendering of normals" << std::endl; 50 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 51 | viz1.clearRenderArea(); 52 | viz1.render(); 53 | viz2.render(); 54 | pangolin::FinishFrame(); 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /examples/image_point_cloud_conversions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | void color_toggle_callback(cilantro::Visualizer& viz, cilantro::RenderingProperties& rp) { 7 | if (rp.pointColor == cilantro::RenderingProperties::noColor) { 8 | rp.setPointColor(0.8f, 0.8f, 0.8f); 9 | } else { 10 | rp.setPointColor(cilantro::RenderingProperties::noColor); 11 | } 12 | viz.setRenderingProperties("cloud", rp); 13 | } 14 | 15 | int main(int argc, char** argv) { 16 | // Intrinsics 17 | Eigen::Matrix3f K; 18 | K << 525, 0, 319.5, 0, 525, 239.5, 0, 0, 1; 19 | 20 | // const std::string uri = 21 | // "files://[/home/kzampog/Desktop/rgbd_sequences/dok_demo/rgb_*.png,/home/kzampog/Desktop/rgbd_sequences/dok_demo/depth_*.png]"; 22 | const std::string uri = "openni2:[img1=rgb,img2=depth_reg,closerange=true,holefilter=true]//"; 23 | 24 | std::unique_ptr dok = pangolin::OpenVideo(uri); 25 | size_t w = 640, h = 480; 26 | unsigned char* img = new unsigned char[dok->SizeBytes()]; 27 | 28 | pangolin::Image rgb_img(img, w, h, 3 * w * sizeof(unsigned char)); 29 | pangolin::Image depth_img((unsigned short*)(img + 3 * w * h), w, h, 30 | w * sizeof(unsigned short)); 31 | 32 | cilantro::PointCloud3f cloud; 33 | pangolin::ManagedImage depthf_img(w, h); 34 | 35 | const std::string window_name = "Image/point cloud conversions demo"; 36 | pangolin::CreateWindowAndBind(window_name, 1280, 960); 37 | pangolin::Display("multi") 38 | .SetBounds(0.0, 1.0, 0.0, 1.0) 39 | .SetLayout(pangolin::LayoutEqual) 40 | .AddDisplay(pangolin::Display("disp1")) 41 | .AddDisplay(pangolin::Display("disp2")) 42 | .AddDisplay(pangolin::Display("disp3")) 43 | .AddDisplay(pangolin::Display("disp4")); 44 | 45 | cilantro::ImageViewer rgbv(window_name, "disp1"); 46 | cilantro::ImageViewer depthv(window_name, "disp2"); 47 | cilantro::Visualizer pcdv(window_name, "disp3"); 48 | cilantro::ImageViewer depthfv(window_name, "disp4"); 49 | 50 | cilantro::RenderingProperties rp; 51 | pcdv.registerKeyboardCallback('c', 52 | std::bind(color_toggle_callback, std::ref(pcdv), std::ref(rp))); 53 | rp.setUseLighting(false); 54 | 55 | std::cout << "Press 'l' to toggle lighting" << std::endl; 56 | std::cout << "Press 'c' to toggle color" << std::endl; 57 | std::cout << "Press 'n' to toggle rendering of normals" << std::endl; 58 | 59 | while (!pcdv.wasStopped() && !rgbv.wasStopped() && !depthv.wasStopped()) { 60 | dok->GrabNext(img, true); 61 | 62 | // Get point cloud from RGBD image pair 63 | cilantro::DepthValueConverter dc1(1000.0f); 64 | cilantro::RGBDImagesToPointsNormalsColors(rgb_img.ptr, depth_img.ptr, dc1, w, h, K, 65 | cloud.points, cloud.normals, cloud.colors, false); 66 | 67 | // Get a depth map back from the point cloud 68 | cilantro::RigidTransform3f cam_pose; 69 | pcdv.getCameraPose(cam_pose); 70 | cilantro::DepthValueConverter dc2(1.0f); 71 | cilantro::pointsToDepthImage(cloud.points, cam_pose, K, dc2, depthf_img.ptr, w, 72 | h); 73 | 74 | rgbv.setImage(rgb_img.ptr, w, h, "RGB24"); 75 | depthv.setImage(depth_img.ptr, w, h, "GRAY16LE"); 76 | pcdv.addObject("cloud", cloud, rp); 77 | depthfv.setImage(depthf_img.ptr, w, h, "GRAY32F"); 78 | 79 | pcdv.clearRenderArea(); 80 | rgbv.render(); 81 | depthv.render(); 82 | pcdv.render(); 83 | depthfv.render(); 84 | pangolin::FinishFrame(); 85 | 86 | // Keep rendering properties on update 87 | rp = pcdv.getRenderingProperties("cloud"); 88 | } 89 | 90 | delete[] img; 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /examples/image_viewer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char* argv[]) { 4 | // const std::string uri = 5 | // "files://[/home/kzampog/Desktop/rgbd_sequences/dok_demo/rgb_*.png,/home/kzampog/Desktop/rgbd_sequences/dok_demo/depth_*.png]"; 6 | const std::string uri = "openni2:[img1=rgb,img2=depth_reg,closerange=true,holefilter=true]//"; 7 | 8 | std::unique_ptr dok = pangolin::OpenVideo(uri); 9 | 10 | const std::string window_name = "ImageViewer demo"; 11 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 12 | pangolin::Display("multi") 13 | .SetBounds(0.0, 1.0, 0.0, 1.0) 14 | .SetLayout(pangolin::LayoutEqual) 15 | .AddDisplay(pangolin::Display("disp1")) 16 | .AddDisplay(pangolin::Display("disp2")); 17 | 18 | cilantro::ImageViewer rgbv(window_name, "disp1"); 19 | cilantro::ImageViewer depthv(window_name, "disp2"); 20 | 21 | size_t w = 640, h = 480; 22 | unsigned char* img = new unsigned char[dok->SizeBytes()]; 23 | while (dok->GrabNext(img, true) && !rgbv.wasStopped() && !depthv.wasStopped()) { 24 | rgbv.clearRenderArea().setImage(img, w, h, "RGB24").render(); 25 | depthv.setImage(img + 3 * w * h, w, h, "GRAY16LE").render(); 26 | pangolin::FinishFrame(); 27 | } 28 | 29 | delete[] img; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /examples/kd_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | int main(int argc, char** argv) { 6 | std::vector points; 7 | points.emplace_back(0, 0, 0); 8 | points.emplace_back(1, 0, 0); 9 | points.emplace_back(0, 1, 0); 10 | points.emplace_back(0, 0, 1); 11 | points.emplace_back(0, 1, 1); 12 | points.emplace_back(1, 0, 1); 13 | points.emplace_back(1, 1, 0); 14 | points.emplace_back(1, 1, 1); 15 | 16 | cilantro::KDTree3f<> tree(points); 17 | 18 | cilantro::NeighborSet nn = 19 | tree.kNNInRadiusSearch(Eigen::Vector3f(0.1, 0.1, 0.4), 2, 1.001); 20 | 21 | std::cout << "Neighbor indices: "; 22 | for (int i = 0; i < nn.size(); i++) { 23 | std::cout << nn[i].index << " "; 24 | } 25 | std::cout << std::endl; 26 | 27 | std::cout << "Neighbor distances: "; 28 | for (int i = 0; i < nn.size(); i++) { 29 | std::cout << nn[i].value << " "; 30 | } 31 | std::cout << std::endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /examples/kmeans.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char** argv) { 9 | if (argc < 2) { 10 | std::cout << "Please provide path to PLY file." << std::endl; 11 | return 0; 12 | } 13 | 14 | cilantro::PointCloud3f cloud(argv[1]); 15 | 16 | if (cloud.isEmpty()) { 17 | std::cout << "Input cloud is empty!" << std::endl; 18 | return 0; 19 | } 20 | 21 | cloud.gridDownsample(0.005f).removeInvalidData(); 22 | 23 | // Eigen::MatrixXf data_points(6, cloud.size()); 24 | // data_points.topRows(3) = cloud.pointsMatrixMap(); 25 | // data_points.bottomRows(3) = 0.15 * cloud.colorsMatrixMap(); 26 | // KMeans kmc(data_points); 27 | // KMeans kmc(cloud.points); 28 | 29 | // k-means on point coordinates 30 | cilantro::KMeans3f<> kmc(cloud.points); 31 | 32 | size_t k = 250; 33 | size_t max_iter = 100; 34 | float tol = std::numeric_limits::epsilon(); 35 | bool use_kd_tree = true; 36 | 37 | cilantro::Timer timer; 38 | timer.start(); 39 | kmc.cluster(k, max_iter, tol, use_kd_tree); 40 | timer.stop(); 41 | 42 | std::cout << "Clustering time: " << timer.getElapsedTime() << "ms" << std::endl; 43 | std::cout << "Performed iterations: " << kmc.getNumberOfPerformedIterations() << std::endl; 44 | 45 | const auto& cpi = kmc.getClusterToPointIndicesMap(); 46 | size_t mins = cloud.size(), maxs = 0; 47 | for (size_t i = 0; i < cpi.size(); i++) { 48 | if (cpi[i].size() < mins) mins = cpi[i].size(); 49 | if (cpi[i].size() > maxs) maxs = cpi[i].size(); 50 | } 51 | std::cout << "Cluster size range is: [" << mins << "," << maxs << "]" << std::endl; 52 | 53 | // Create a color map 54 | cilantro::VectorSet3f color_map(3, k); 55 | for (size_t i = 0; i < k; i++) { 56 | color_map.col(i) = Eigen::Vector3f::Random().cwiseAbs(); 57 | } 58 | 59 | const auto& idx_map = kmc.getPointToClusterIndexMap(); 60 | 61 | cilantro::VectorSet colors(3, idx_map.size()); 62 | for (size_t i = 0; i < colors.cols(); i++) { 63 | colors.col(i) = color_map.col(idx_map[i]); 64 | } 65 | 66 | // Create a new colored cloud 67 | cilantro::PointCloud3f cloud_seg(cloud.points, cloud.normals, colors); 68 | 69 | // Visualize result 70 | const std::string window_name = "KMeans demo"; 71 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 72 | pangolin::Display("multi") 73 | .SetBounds(0.0, 1.0, 0.0, 1.0) 74 | .SetLayout(pangolin::LayoutEqual) 75 | .AddDisplay(pangolin::Display("disp1")) 76 | .AddDisplay(pangolin::Display("disp2")); 77 | 78 | cilantro::Visualizer viz1(window_name, "disp1"); 79 | viz1.addObject("cloud", cloud); 80 | 81 | cilantro::Visualizer viz2(window_name, "disp2"); 82 | viz2.addObject("cloud_seg", cloud_seg); 83 | 84 | // Keep viewpoints in sync 85 | viz2.setRenderState(viz1.getRenderState()); 86 | 87 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 88 | viz1.clearRenderArea(); 89 | viz1.render(); 90 | viz2.render(); 91 | pangolin::FinishFrame(); 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /examples/matrix_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | int main(int argc, char** argv) { 8 | Eigen::MatrixXf mat0(3, 4); 9 | mat0 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 10 | 11 | std::cout << "Before:" << std::endl; 12 | std::cout << mat0 << std::endl; 13 | 14 | bool binary = false; 15 | 16 | cilantro::writeEigenMatrixToFile("mat.dat", mat0, binary); 17 | 18 | Eigen::MatrixXf mat1; 19 | 20 | cilantro::readEigenMatrixFromFile("mat.dat", mat1, binary); 21 | 22 | std::cout << "After:" << std::endl; 23 | std::cout << mat1 << std::endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /examples/mean_shift.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | cilantro::VectorSet3f generate_input_data() { 9 | std::default_random_engine generator; 10 | std::normal_distribution distribution(0.0f, 1.0f); 11 | 12 | size_t cluster_size = 500; 13 | size_t cluster_num = 3; 14 | cilantro::VectorSet points(3, cluster_num * cluster_size); 15 | cilantro::VectorSet offsets(3, cluster_num); 16 | 17 | for (size_t j = 0; j < points.cols(); j++) { 18 | for (size_t i = 0; i < points.rows(); i++) { 19 | points(i, j) = distribution(generator); 20 | } 21 | } 22 | points.row(2).array() += 10.0f; 23 | 24 | for (size_t j = 0; j < offsets.cols(); j++) { 25 | for (size_t i = 0; i < offsets.rows(); i++) { 26 | offsets(i, j) = distribution(generator); 27 | } 28 | offsets.col(j) = 2.5f * offsets.col(j).normalized(); 29 | } 30 | 31 | for (size_t i = 0; i < cluster_num; i++) { 32 | for (size_t j = 0; j < cluster_size; j++) { 33 | points.col(i * cluster_size + j) += offsets.col(i); 34 | } 35 | } 36 | 37 | return points; 38 | } 39 | 40 | int main(int argc, char** argv) { 41 | // Generate random points 42 | cilantro::VectorSet3f points = generate_input_data(); 43 | 44 | std::cout << "Number of points: " << points.cols() << std::endl; 45 | 46 | cilantro::MeanShift3f<> ms(points); 47 | 48 | cilantro::Timer timer; 49 | timer.start(); 50 | // Flat kernel 51 | ms.cluster(2.0f, 5000, 0.2, 1e-7, cilantro::UnityWeightEvaluator()); 52 | timer.stop(); 53 | 54 | std::cout << "Clustering time: " << timer.getElapsedTime() << "ms" << std::endl; 55 | std::cout << "Number of clusters: " << ms.getNumberOfClusters() << std::endl; 56 | std::cout << "Performed mean shift iterations: " << ms.getNumberOfPerformedIterations() 57 | << std::endl; 58 | 59 | const auto& cpi = ms.getClusterToPointIndicesMap(); 60 | size_t mins = points.cols(), maxs = 0; 61 | for (size_t i = 0; i < cpi.size(); i++) { 62 | if (cpi[i].size() < mins) mins = cpi[i].size(); 63 | if (cpi[i].size() > maxs) maxs = cpi[i].size(); 64 | } 65 | std::cout << "Cluster size range is: [" << mins << "," << maxs << "]" << std::endl; 66 | 67 | // Create a color map 68 | cilantro::VectorSet3f color_map(3, cpi.size()); 69 | for (size_t i = 0; i < cpi.size(); i++) { 70 | color_map.col(i) = Eigen::Vector3f::Random().cwiseAbs(); 71 | } 72 | 73 | const auto& idx_map = ms.getPointToClusterIndexMap(); 74 | cilantro::VectorSet3f colors(3, idx_map.size()); 75 | for (size_t i = 0; i < colors.cols(); i++) { 76 | colors.col(i) = color_map.col(idx_map[i]); 77 | } 78 | 79 | // Visualize result 80 | const std::string window_name = "MeanShift demo"; 81 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 82 | pangolin::Display("multi") 83 | .SetBounds(0.0, 1.0, 0.0, 1.0) 84 | .SetLayout(pangolin::LayoutEqual) 85 | .AddDisplay(pangolin::Display("disp1")) 86 | .AddDisplay(pangolin::Display("disp2")); 87 | 88 | cilantro::Visualizer viz1(window_name, "disp1"); 89 | viz1.addObject( 90 | "cloud", points, cilantro::RenderingProperties().setPointSize(5.0f)); 91 | 92 | cilantro::Visualizer viz2(window_name, "disp2"); 93 | viz2.addObject("cloud_seg", points, 94 | cilantro::RenderingProperties().setPointSize(5.0f)) 95 | ->setPointColors(colors); 96 | 97 | viz2.addObject( 98 | "modes", ms.getClusterModes(), cilantro::RenderingProperties().setPointSize(20.0f)) 99 | ->setPointColors(color_map); 100 | 101 | // Keep viewpoints in sync 102 | viz2.setRenderState(viz1.getRenderState()); 103 | 104 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 105 | viz1.clearRenderArea(); 106 | viz1.render(); 107 | viz2.render(); 108 | pangolin::FinishFrame(); 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /examples/multidimensional_scaling.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #ifndef M_PI 8 | #define M_PI 3.14159265358979323846 9 | #endif 10 | 11 | void generate_input_data(cilantro::VectorSet3f& original_points, 12 | cilantro::VectorSet& values, Eigen::MatrixXf& dist_sq) { 13 | size_t num_points = 1000; 14 | original_points.resize(3, num_points); 15 | for (size_t i = 0; i < num_points; i++) { 16 | original_points(0, i) = std::cos((2.0f * M_PI * i) / num_points); 17 | original_points(1, i) = std::sin((2.0f * M_PI * i) / num_points); 18 | original_points(2, i) = 0.1f * std::sin(10.0f * (2.0f * M_PI * i) / num_points); 19 | } 20 | 21 | values = original_points.row(2); 22 | 23 | dist_sq.resize(num_points, num_points); 24 | for (size_t i = 0; i < original_points.cols(); i++) { 25 | for (size_t j = 0; j < original_points.cols(); j++) { 26 | dist_sq(i, j) = (original_points.col(i) - original_points.col(j)).squaredNorm(); 27 | } 28 | } 29 | } 30 | 31 | int main(int argc, char** argv) { 32 | // Prepare input data 33 | cilantro::VectorSet3f points; 34 | cilantro::VectorSet values; 35 | Eigen::MatrixXf distances_sq; 36 | generate_input_data(points, values, distances_sq); 37 | 38 | std::cout << "Number of points: " << distances_sq.rows() << std::endl; 39 | 40 | cilantro::Timer timer; 41 | timer.start(); 42 | 43 | cilantro::MultidimensionalScaling mds(distances_sq); 44 | // cilantro::MultidimensionalScaling mds(distances_sq, 3, true); 45 | 46 | timer.stop(); 47 | std::cout << "Elapsed time: " << timer.getElapsedTime() << "ms" << std::endl; 48 | std::cout << "Embedding dimension: " << mds.getEmbeddedPoints().rows() << std::endl; 49 | 50 | size_t dim = mds.getEmbeddedPoints().rows(); 51 | 52 | // Create a new cloud by re-embedding the embedded points back to 3D 53 | cilantro::VectorSet points_reproj(3, distances_sq.rows()); 54 | points_reproj.topRows(dim) = mds.getEmbeddedPoints(); 55 | points_reproj.bottomRows(3 - dim).setZero(); 56 | 57 | // Visualize result 58 | const std::string window_name = "MultidimensionalScaling demo"; 59 | pangolin::CreateWindowAndBind(window_name, 1280, 480); 60 | pangolin::Display("multi") 61 | .SetBounds(0.0, 1.0, 0.0, 1.0) 62 | .SetLayout(pangolin::LayoutEqual) 63 | .AddDisplay(pangolin::Display("disp1")) 64 | .AddDisplay(pangolin::Display("disp2")); 65 | 66 | cilantro::Visualizer viz1(window_name, "disp1"); 67 | viz1.addObject("cloud", points, 68 | cilantro::RenderingProperties().setPointSize(3.0f)) 69 | ->setPointValues(values); 70 | 71 | cilantro::Visualizer viz2(window_name, "disp2"); 72 | viz2.addObject("cloud_reproj", points_reproj, 73 | cilantro::RenderingProperties().setPointSize(3.0f)) 74 | ->setPointValues(values); 75 | 76 | // Move camera 77 | Eigen::Matrix3f rot; 78 | rot = Eigen::AngleAxisf(0.25f * M_PI, Eigen::Vector3f::UnitX()); 79 | Eigen::Vector3f t(0.0f, 2.0f, -2.0f); 80 | Eigen::Matrix4f cam_pose = Eigen::Matrix4f::Identity(); 81 | cam_pose.topLeftCorner(3, 3) = rot; 82 | cam_pose.topRightCorner(3, 1) = t; 83 | viz1.setCameraPose(cam_pose); 84 | viz1.setDefaultCameraPose(cam_pose); 85 | 86 | // Keep viewpoints in sync 87 | viz2.setRenderState(viz1.getRenderState()); 88 | 89 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 90 | viz1.clearRenderArea(); 91 | viz1.render(); 92 | viz2.render(); 93 | pangolin::FinishFrame(); 94 | } 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /examples/normal_estimation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char** argv) { 9 | if (argc < 2) { 10 | std::cout << "Please provide path to PLY file." << std::endl; 11 | return 0; 12 | } 13 | 14 | cilantro::PointCloud3f cloud(argv[1]); 15 | 16 | if (cloud.isEmpty()) { 17 | std::cout << "Input cloud is empty!" << std::endl; 18 | return 0; 19 | } 20 | 21 | // Clear input normals 22 | cloud.normals.resize(Eigen::NoChange, 0); 23 | 24 | cloud.gridDownsample(0.005f); 25 | 26 | cilantro::Timer tree_timer; 27 | tree_timer.start(); 28 | cilantro::KDTree3f<> tree(cloud.points); 29 | // cilantro::NormalEstimation3f ne(tree); 30 | // cilantro::NormalEstimation3f ne(cloud.points); 31 | tree_timer.stop(); 32 | 33 | cilantro::Timer ne_timer; 34 | ne_timer.start(); 35 | 36 | // cloud.normals = ne.getNormals(cilantro::KNNInRadiusNeighborhoodSpecification(7, 0.01f)); 37 | // cloud.normals = ne.getNormalsKNNInRadius(7, 0.01f); 38 | // cloud.normals = ne.getNormalsRadius(0.01f); 39 | // cloud.normals = ne.getNormalsKNN(7); 40 | 41 | // cloud.estimateNormals(tree, cilantro::KNNInRadiusNeighborhoodSpecification(7, 0.01f)); 42 | // cloud.estimateNormalsKNNInRadius(tree, 7, 0.01f); 43 | // cloud.estimateNormalsRadius(tree, 0.01f); 44 | cloud.estimateNormalsKNN(tree, 7); 45 | 46 | // Search tree argument is optional (automatically built): 47 | // cloud.estimateNormals(cilantro::KNNInRadiusNeighborhoodSpecification(7, 0.01f)); 48 | // cloud.estimateNormalsKNNInRadius(7, 0.01f); 49 | // cloud.estimateNormalsRadius(0.01f); 50 | // cloud.estimateNormalsKNN(7); 51 | 52 | ne_timer.stop(); 53 | 54 | std::cout << "kd-tree time: " << tree_timer.getElapsedTime() << "ms" << std::endl; 55 | std::cout << "Estimation time: " << ne_timer.getElapsedTime() << "ms" << std::endl; 56 | 57 | const std::string window_name = "NormalEstimation example"; 58 | pangolin::CreateWindowAndBind(window_name, 640, 480); 59 | cilantro::Visualizer viz(window_name, "disp"); 60 | 61 | viz.addObject( 62 | "cloud_d", cloud, cilantro::RenderingProperties().setDrawNormals(true)); 63 | 64 | std::cout << "Press 'n' to toggle rendering of normals" << std::endl; 65 | while (!viz.wasStopped()) { 66 | viz.spinOnce(); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /examples/ply_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | int main(int argc, char** argv) { 8 | cilantro::PointCloud3f cloud; 9 | 10 | // Get file paths 11 | std::string fileInPath, fileOutPath; 12 | if (argc < 3) { 13 | std::cout << "No input path provided. Using default test cloud location." << std::endl; 14 | fileInPath = "../examples/test_clouds/test.ply"; 15 | fileOutPath = "./test_copy.ply"; 16 | } else { 17 | fileInPath = std::string(argv[1]); 18 | fileOutPath = std::string(argv[2]); 19 | } 20 | 21 | fileInPath = pangolin::PathExpand(fileInPath); 22 | fileOutPath = pangolin::PathExpand(fileOutPath); 23 | 24 | // Read ply file 25 | std::cout << "Reading file from " << fileInPath << std::endl; 26 | if (!pangolin::FileExists(fileInPath)) { 27 | std::cout << "Input file " << fileInPath << " doesn't exist." << std::endl; 28 | return -1; 29 | } 30 | 31 | cloud.fromPLYFile(fileInPath); 32 | std::cout << cloud.points.cols() << " points read" << std::endl; 33 | std::cout << cloud.normals.cols() << " normals read" << std::endl; 34 | std::cout << cloud.colors.cols() << " colors read" << std::endl; 35 | 36 | // Modify pointcloud 37 | std::vector ind; 38 | for (size_t i = 0; i < cloud.points.cols(); i += 50) { 39 | ind.push_back(i); 40 | } 41 | cilantro::PointCloud3f pc(cloud, ind); 42 | 43 | // Write ply file 44 | std::cout << "Writing pointcloud to " << fileOutPath << std::endl; 45 | if (!pangolin::FileExists(pangolin::PathParent(fileOutPath))) { 46 | std::cout << "Parent directory of output file " << fileOutPath << " doesn't exist." 47 | << std::endl; 48 | return -1; 49 | } 50 | 51 | pc.toPLYFile(fileOutPath); 52 | std::cout << pc.points.cols() << " points written" << std::endl; 53 | std::cout << pc.normals.cols() << " normals written" << std::endl; 54 | std::cout << pc.colors.cols() << " colors written" << std::endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /examples/principal_component_analysis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | int main(int argc, char** argv) { 6 | std::vector points; 7 | points.emplace_back(0, 0, 0); 8 | points.emplace_back(1, 0, 0); 9 | points.emplace_back(0, 100, 0); 10 | points.emplace_back(0, 0, 1000); 11 | points.emplace_back(0, 100, 1000); 12 | points.emplace_back(1, 0, 1000); 13 | points.emplace_back(1, 100, 0); 14 | points.emplace_back(1, 100, 1000); 15 | 16 | cilantro::PrincipalComponentAnalysis3f pca(points); 17 | 18 | std::cout << "Data mean: " << pca.getDataMean().transpose() << std::endl; 19 | std::cout << "Eigenvalues: " << pca.getEigenValues().transpose() << std::endl; 20 | std::cout << "Eigenvectors: " << std::endl << pca.getEigenVectors() << std::endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /examples/ransac_plane_estimator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void callback(bool& re_estimate) { re_estimate = true; } 8 | 9 | int main(int argc, char** argv) { 10 | if (argc < 2) { 11 | std::cout << "Please provide path to PLY file." << std::endl; 12 | return 0; 13 | } 14 | 15 | cilantro::PointCloud3f cloud(argv[1]); 16 | 17 | if (cloud.isEmpty()) { 18 | std::cout << "Input cloud is empty!" << std::endl; 19 | return 0; 20 | } 21 | 22 | const std::string window_name = "HyperplaneRANSACEstimator example"; 23 | pangolin::CreateWindowAndBind(window_name, 640, 480); 24 | cilantro::Visualizer viz(window_name, "disp"); 25 | bool re_estimate = false; 26 | viz.registerKeyboardCallback('a', std::bind(callback, std::ref(re_estimate))); 27 | 28 | std::cout << "Press 'a' for a new estimate" << std::endl; 29 | 30 | cilantro::PointCloud3f planar_cloud; 31 | 32 | viz.addObject("cloud", cloud); 33 | while (!viz.wasStopped()) { 34 | if (re_estimate) { 35 | re_estimate = false; 36 | 37 | cilantro::PlaneRANSACEstimator3f<> pe(cloud.points); 38 | pe.setMaxInlierResidual(0.01f) 39 | .setTargetInlierCount((size_t)(0.15 * cloud.size())) 40 | .setMaxNumberOfIterations(250) 41 | .setReEstimationStep(true); 42 | 43 | Eigen::Hyperplane plane = pe.estimate().getModel(); 44 | const auto& inliers = pe.getModelInliers(); 45 | 46 | std::cout << "RANSAC iterations: " << pe.getNumberOfPerformedIterations() 47 | << ", inlier count: " << pe.getNumberOfInliers() << std::endl; 48 | 49 | planar_cloud = cilantro::PointCloud3f(cloud, inliers); 50 | viz.addObject( 51 | "plane", planar_cloud.points, 52 | cilantro::RenderingProperties().setPointColor(1, 0, 0).setPointSize(3.0)); 53 | 54 | std::cout << "Press 'a' for a new estimate" << std::endl; 55 | } 56 | viz.spinOnce(); 57 | } 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/ransac_transform_estimator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void callback(unsigned char key, bool& re_estimate, bool& randomize) { 8 | if (key == 'a') { 9 | re_estimate = true; 10 | } 11 | if (key == 'd') { 12 | randomize = true; 13 | } 14 | } 15 | 16 | int main(int argc, char** argv) { 17 | if (argc < 2) { 18 | std::cout << "Please provide path to PLY file." << std::endl; 19 | return 0; 20 | } 21 | 22 | cilantro::PointCloud3f dst(argv[1]); 23 | cilantro::PointCloud3f src(dst); 24 | 25 | if (dst.isEmpty()) { 26 | std::cout << "Input cloud is empty!" << std::endl; 27 | return 0; 28 | } 29 | 30 | const std::string window_name = "TransformRANSACEstimator example"; 31 | pangolin::CreateWindowAndBind(window_name, 640, 480); 32 | cilantro::Visualizer viz(window_name, "disp"); 33 | bool re_estimate = false; 34 | bool randomize = true; 35 | viz.registerKeyboardCallback( 36 | 'a', std::bind(callback, 'a', std::ref(re_estimate), std::ref(randomize))); 37 | viz.registerKeyboardCallback( 38 | 'd', std::bind(callback, 'd', std::ref(re_estimate), std::ref(randomize))); 39 | 40 | cilantro::CorrespondenceSet corr(1000); 41 | 42 | viz.addObject( 43 | "dst", dst, cilantro::RenderingProperties().setPointColor(0, 0, 1)); 44 | while (!viz.wasStopped()) { 45 | if (randomize) { 46 | randomize = false; 47 | 48 | // Randomly transform src 49 | cilantro::RigidTransform3f tform; 50 | tform.linear().setRandom(); 51 | tform.linear() = tform.rotation(); 52 | tform.translation().setRandom(); 53 | 54 | // Build noisy correspondences 55 | for (size_t i = 0; i < corr.size(); i++) { 56 | float p = 0 + static_cast(rand()) / (static_cast(RAND_MAX / (1 - 0))); 57 | corr[i].indexInSecond = std::rand() % src.size(); 58 | if (p > 0.75f) { 59 | corr[i].indexInFirst = corr[i].indexInSecond; 60 | } else { 61 | corr[i].indexInFirst = std::rand() % corr.size(); 62 | } 63 | } 64 | 65 | src.transform(tform); 66 | viz.addObject( 67 | "src", src, cilantro::RenderingProperties().setPointColor(1, 0, 0)); 68 | viz.addObject( 69 | "corr", dst, src, corr, cilantro::RenderingProperties().setOpacity(0.5f)); 70 | 71 | std::cout << "Press 'a' for a transform estimate" << std::endl; 72 | } 73 | 74 | if (re_estimate) { 75 | re_estimate = false; 76 | 77 | viz.remove("corr"); 78 | 79 | cilantro::RigidTransformRANSACEstimator3f<> te(dst.points, src.points, corr); 80 | te.setMaxInlierResidual(0.01f) 81 | .setTargetInlierCount((size_t)(0.50 * corr.size())) 82 | .setMaxNumberOfIterations(250) 83 | .setReEstimationStep(true); 84 | 85 | cilantro::RigidTransform3f tform = te.estimate().getModel(); 86 | const auto& inliers = te.getModelInliers(); 87 | 88 | std::cout << "RANSAC iterations: " << te.getNumberOfPerformedIterations() 89 | << ", inlier count: " << te.getNumberOfInliers() << std::endl; 90 | 91 | src.transform(tform); 92 | viz.addObject( 93 | "src", src, cilantro::RenderingProperties().setPointColor(1, 0, 0)); 94 | 95 | std::cout << "Press 'd' for a new random pose" << std::endl; 96 | } 97 | 98 | viz.spinOnce(); 99 | } 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /examples/robust_normal_estimation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // #include 4 | #include 5 | #include 6 | #include 7 | 8 | void toggle_invalid(cilantro::Visualizer& viz) { viz.getObject("cloud_i")->toggleVisibility(); } 9 | 10 | cilantro::PointCloud3f invalidNormalsCloud(const cilantro::PointCloud3f& cloud) { 11 | std::vector ind_to_remove; 12 | ind_to_remove.reserve(cloud.normals.cols()); 13 | for (size_t i = 0; i < cloud.normals.cols(); i++) { 14 | if (!cloud.normals.col(i).allFinite()) ind_to_remove.emplace_back(i); 15 | } 16 | cilantro::PointCloud3f invalid_cloud(cloud, ind_to_remove); 17 | invalid_cloud.normals.resize(Eigen::NoChange, 0); 18 | return invalid_cloud; 19 | } 20 | 21 | int main(int argc, char** argv) { 22 | if (argc < 2) { 23 | std::cout << "Please provide path to PLY file." << std::endl; 24 | return 0; 25 | } 26 | 27 | cilantro::PointCloud3f cloud(argv[1]); 28 | 29 | if (cloud.isEmpty()) { 30 | std::cout << "Input cloud is empty!" << std::endl; 31 | return 0; 32 | } 33 | 34 | // Clear input normals 35 | cloud.normals.resize(Eigen::NoChange, 0); 36 | 37 | cloud.gridDownsample(0.005f); 38 | 39 | cilantro::Timer tree_timer; 40 | tree_timer.start(); 41 | cilantro::KDTree3f<> tree(cloud.points); 42 | tree_timer.stop(); 43 | 44 | cilantro::Timer ne_timer; 45 | ne_timer.start(); 46 | cilantro::NormalEstimation> ne(tree); 47 | ne.setViewPoint(Eigen::Vector3f::Zero()); 48 | ne.covarianceMethod().setChiSquareThreshold(6.25).setNumberOfTrials(2).setNumberOfRefinements( 49 | 1); // 90% confidence ellipsoid 50 | cloud.normals = ne.getNormalsKNN(12); 51 | 52 | cilantro::PointCloud3f invalid_cloud = invalidNormalsCloud(cloud); 53 | cloud.removeInvalidNormals(); 54 | 55 | ne_timer.stop(); 56 | 57 | std::cout << "kd-tree time: " << tree_timer.getElapsedTime() << "ms" << std::endl; 58 | std::cout << "Estimation time: " << ne_timer.getElapsedTime() << "ms" << std::endl; 59 | 60 | const std::string window_name = "NormalEstimation example"; 61 | pangolin::CreateWindowAndBind(window_name, 640, 480); 62 | cilantro::Visualizer viz(window_name, "disp"); 63 | viz.registerKeyboardCallback('i', std::bind(toggle_invalid, std::ref(viz))); 64 | 65 | viz.addObject( 66 | "cloud_d", cloud, cilantro::RenderingProperties().setDrawNormals(true)); 67 | viz.addObject( 68 | "cloud_i", invalid_cloud, cilantro::RenderingProperties().setPointColor(255, 0, 0)); 69 | 70 | std::cout << "Press 'n' to toggle rendering of normals" << std::endl; 71 | std::cout << "Press 'i' to toggle rendering of outliers" << std::endl; 72 | while (!viz.wasStopped()) { 73 | viz.spinOnce(); 74 | } 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /examples/space_region_2d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char** argv) { 5 | std::vector vertices; 6 | vertices.emplace_back(100, 100); 7 | vertices.emplace_back(100, 200); 8 | vertices.emplace_back(200, 100); 9 | vertices.emplace_back(200, 200); 10 | 11 | cilantro::SpaceRegion2f sr1(vertices); 12 | 13 | for (size_t i = 0; i < vertices.size(); i++) { 14 | vertices[i] += Eigen::Vector2f(50, 50); 15 | } 16 | 17 | cilantro::SpaceRegion2f sr2(vertices); 18 | 19 | cilantro::SpaceRegion2f sr3(std::vector(1, Eigen::Vector3f(-1, 1, -70))); 20 | 21 | // SpaceRegion2D sr = sr1.unionWith(sr2).complement(); 22 | cilantro::SpaceRegion2f sr = sr1.intersectionWith(sr2.complement()) 23 | .unionWith(sr2.intersectionWith(sr1.complement())) 24 | .intersectionWith(sr3); 25 | // SpaceRegion2D sr = sr2.relativeComplement(sr1); 26 | 27 | sr.transform(Eigen::Rotation2D(-M_PI / 4.0).toRotationMatrix(), Eigen::Vector2f(80, 220)); 28 | 29 | pangolin::ManagedImage img(640, 480); 30 | for (size_t x = 0; x < img.w; x++) { 31 | for (size_t y = 0; y < img.h; y++) { 32 | img(x, y) = (unsigned char)255 * sr.containsPoint(Eigen::Vector2f(x, y)); 33 | } 34 | } 35 | 36 | const std::string window_name = "SpaceRegion2D example"; 37 | pangolin::CreateWindowAndBind(window_name, 640, 480); 38 | cilantro::ImageViewer viz(window_name, "disp"); 39 | viz.setImage(img, "GRAY8"); 40 | while (!viz.wasStopped()) { 41 | viz.spinOnce(); 42 | } 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /examples/test_clouds/frame_1.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kzampog/cilantro/57ad1a397b73b6f4bbf9604fd75f8fe4363206a7/examples/test_clouds/frame_1.ply -------------------------------------------------------------------------------- /examples/test_clouds/frame_2.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kzampog/cilantro/57ad1a397b73b6f4bbf9604fd75f8fe4363206a7/examples/test_clouds/frame_2.ply -------------------------------------------------------------------------------- /examples/test_clouds/test.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kzampog/cilantro/57ad1a397b73b6f4bbf9604fd75f8fe4363206a7/examples/test_clouds/test.ply -------------------------------------------------------------------------------- /examples/visualizer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void callback(cilantro::Visualizer& viz, const std::string& name) { 8 | std::cout << "Toggling visibility for " << name << std::endl; 9 | viz.toggleVisibility(name); 10 | } 11 | 12 | int main(int argc, char** argv) { 13 | if (argc < 2) { 14 | std::cout << "Please provide path to PLY file." << std::endl; 15 | return 0; 16 | } 17 | 18 | cilantro::PointCloud3f cloud(argv[1]); 19 | 20 | // First 21 | const std::string window_name1 = "Visualizer demo (window 1)"; 22 | pangolin::CreateWindowAndBind(window_name1, 640, 480); 23 | cilantro::Visualizer viz1(window_name1, "disp1"); 24 | 25 | std::vector scalars(cloud.size()); 26 | for (size_t i = 0; i < cloud.size(); i++) { 27 | scalars[i] = cloud.points.col(i).norm(); 28 | } 29 | 30 | viz1.addObject("pcd", cloud, 31 | cilantro::RenderingProperties() 32 | .setColormapType(cilantro::ColormapType::JET) 33 | .setLineDensityFraction(0.2f) 34 | .setUseLighting(false)) 35 | ->setPointValues(scalars); 36 | viz1.addObject( 37 | "axis", Eigen::Matrix4f::Identity(), 0.4f, 38 | cilantro::RenderingProperties().setLineWidth(5.0f)); 39 | viz1.addObject("text", "Coordinate Frame", 0, 0, 0, 40 | cilantro::RenderingProperties() 41 | .setFontSize(20.0f) 42 | .setPointColor(1.0f, 1.0f, 0.0f) 43 | .setTextAnchorPoint(0.5f, -1.0f)); 44 | 45 | // Second 46 | cilantro::PointCloud3f cloud2(cloud); 47 | for (size_t i = 0; i < cloud2.size(); i++) { 48 | cloud2.points.col(i) += Eigen::Vector3f(1.0, 0.0, 1.0); 49 | } 50 | 51 | const std::string window_name2 = "Visualizer demo (window 2)"; 52 | pangolin::CreateWindowAndBind(window_name2, 640, 480); 53 | cilantro::Visualizer viz2(window_name2, "disp2"); 54 | 55 | viz2.addObject( 56 | "pcd1", cloud, 57 | cilantro::RenderingProperties().setPointColor(1.0f, 0.0f, 0.0f).setOpacity(0.4f)); 58 | viz2.addObject( 59 | "pcd2", cloud2, 60 | cilantro::RenderingProperties().setPointColor(0.0f, 0.0f, 1.0f).setOpacity(0.4f)); 61 | viz2.addObject( 62 | "correspondences", cloud2, cloud, 63 | cilantro::RenderingProperties().setLineDensityFraction(0.005).setOpacity(0.3f)); 64 | viz2.addObject( 65 | "axis", Eigen::Matrix4f::Identity(), 0.4f, 66 | cilantro::RenderingProperties().setLineWidth(5.0f)); 67 | 68 | viz2.registerKeyboardCallback('c', std::bind(callback, std::ref(viz2), "correspondences")); 69 | 70 | std::cout << "Press 'n' to toggle rendering of normals" << std::endl; 71 | while (!viz1.wasStopped() && !viz2.wasStopped()) { 72 | viz1.spinOnce(); 73 | viz2.spinOnce(); 74 | } 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This is meant to be run from the repo root. 3 | find . -regex '.*\.\(cpp\|hpp\|cu\|c\|h\)' -not -path "./include/cilantro/3rd_party/*" -not -path "./src/3rd_party/*" -not -path "./build/*" -exec clang-format -i {} \; 4 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/DavidsonSymEigsSolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020 Netherlands eScience Center 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_DAVIDSON_SYM_EIGS_SOLVER_H 8 | #define SPECTRA_DAVIDSON_SYM_EIGS_SOLVER_H 9 | 10 | #include 11 | 12 | #include "JDSymEigsBase.h" 13 | #include "Util/SelectionRule.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup EigenSolver 19 | /// 20 | /// This class implement the DPR correction for the Davidson algorithms. 21 | /// The algorithms in the Davidson family only differ in how the correction 22 | /// vectors are computed and optionally in the initial orthogonal basis set. 23 | /// 24 | /// the DPR correction compute the new correction vector using the following expression: 25 | /// \f[ correction = -(\boldsymbol{D} - \rho \boldsymbol{I})^{-1} \boldsymbol{r} \f] 26 | /// where 27 | /// \f$D\f$ is the diagonal of the target matrix, \f$\rho\f$ the Ritz eigenvalue, 28 | /// \f$I\f$ the identity matrix and \f$r\f$ the residue vector. 29 | /// 30 | template 31 | class DavidsonSymEigsSolver : public JDSymEigsBase, OpType> 32 | { 33 | private: 34 | using Index = Eigen::Index; 35 | using Scalar = typename OpType::Scalar; 36 | using Matrix = Eigen::Matrix; 37 | using Vector = Eigen::Matrix; 38 | 39 | Vector m_diagonal; 40 | 41 | public: 42 | DavidsonSymEigsSolver(OpType& op, Index nev, Index nvec_init, Index nvec_max) : 43 | JDSymEigsBase, OpType>(op, nev, nvec_init, nvec_max) 44 | { 45 | m_diagonal.resize(this->m_matrix_operator.rows()); 46 | for (Index i = 0; i < op.rows(); i++) 47 | { 48 | m_diagonal(i) = op(i, i); 49 | } 50 | } 51 | 52 | DavidsonSymEigsSolver(OpType& op, Index nev) : 53 | DavidsonSymEigsSolver(op, nev, 2 * nev, 10 * nev) {} 54 | 55 | /// Create initial search space based on the diagonal 56 | /// and the spectrum'target (highest or lowest) 57 | /// 58 | /// \param selection Spectrum section to target (e.g. lowest, etc.) 59 | /// \return Matrix with the initial orthonormal basis 60 | Matrix setup_initial_search_space(SortRule selection) const 61 | { 62 | std::vector indices_sorted = argsort(selection, m_diagonal); 63 | 64 | Matrix initial_basis = Matrix::Zero(this->m_matrix_operator.rows(), this->m_initial_search_space_size); 65 | 66 | for (Index k = 0; k < this->m_initial_search_space_size; k++) 67 | { 68 | Index row = indices_sorted[k]; 69 | initial_basis(row, k) = 1.0; 70 | } 71 | return initial_basis; 72 | } 73 | 74 | /// Compute the corrections using the DPR method. 75 | /// 76 | /// \return New correction vectors. 77 | Matrix calculate_correction_vector() const 78 | { 79 | const Matrix& residues = this->m_ritz_pairs.residues(); 80 | const Vector& eigvals = this->m_ritz_pairs.ritz_values(); 81 | Matrix correction = Matrix::Zero(this->m_matrix_operator.rows(), this->m_correction_size); 82 | for (Index k = 0; k < this->m_correction_size; k++) 83 | { 84 | Vector tmp = eigvals(k) - m_diagonal.array(); 85 | correction.col(k) = residues.col(k).array() / tmp.array(); 86 | } 87 | return correction; 88 | } 89 | }; 90 | 91 | } // namespace Spectra 92 | 93 | #endif // SPECTRA_DAVIDSON_SYM_EIGS_SOLVER_H 94 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/GenEigsRealShiftSolver.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_GEN_EIGS_REAL_SHIFT_SOLVER_H 8 | #define SPECTRA_GEN_EIGS_REAL_SHIFT_SOLVER_H 9 | 10 | #include 11 | 12 | #include "GenEigsBase.h" 13 | #include "Util/SelectionRule.h" 14 | #include "MatOp/DenseGenRealShiftSolve.h" 15 | 16 | namespace Spectra { 17 | 18 | /// 19 | /// \ingroup EigenSolver 20 | /// 21 | /// This class implements the eigen solver for general real matrices with 22 | /// a real shift value in the **shift-and-invert mode**. The background 23 | /// knowledge of the shift-and-invert mode can be found in the documentation 24 | /// of the SymEigsShiftSolver class. 25 | /// 26 | /// \tparam OpType The name of the matrix operation class. Users could either 27 | /// use the wrapper classes such as DenseGenRealShiftSolve and 28 | /// SparseGenRealShiftSolve, or define their own that implements the type 29 | /// definition `Scalar` and all the public member functions as in 30 | /// DenseGenRealShiftSolve. 31 | /// 32 | template > 33 | class GenEigsRealShiftSolver : public GenEigsBase 34 | { 35 | private: 36 | using Scalar = typename OpType::Scalar; 37 | using Index = Eigen::Index; 38 | using Complex = std::complex; 39 | using ComplexArray = Eigen::Array; 40 | 41 | using Base = GenEigsBase; 42 | using Base::m_nev; 43 | using Base::m_ritz_val; 44 | 45 | const Scalar m_sigma; 46 | 47 | // First transform back the Ritz values, and then sort 48 | void sort_ritzpair(SortRule sort_rule) override 49 | { 50 | // The eigenvalues we get from the iteration is nu = 1 / (lambda - sigma) 51 | // So the eigenvalues of the original problem is lambda = 1 / nu + sigma 52 | m_ritz_val.head(m_nev) = Scalar(1) / m_ritz_val.head(m_nev).array() + m_sigma; 53 | Base::sort_ritzpair(sort_rule); 54 | } 55 | 56 | public: 57 | /// 58 | /// Constructor to create a eigen solver object using the shift-and-invert mode. 59 | /// 60 | /// \param op The matrix operation object that implements 61 | /// the shift-solve operation of \f$A\f$: calculating 62 | /// \f$(A-\sigma I)^{-1}v\f$ for any vector \f$v\f$. Users could either 63 | /// create the object from the wrapper class such as DenseGenRealShiftSolve, or 64 | /// define their own that implements all the public members 65 | /// as in DenseGenRealShiftSolve. 66 | /// \param nev Number of eigenvalues requested. This should satisfy \f$1\le nev \le n-2\f$, 67 | /// where \f$n\f$ is the size of matrix. 68 | /// \param ncv Parameter that controls the convergence speed of the algorithm. 69 | /// Typically a larger `ncv` means faster convergence, but it may 70 | /// also result in greater memory use and more matrix operations 71 | /// in each iteration. This parameter must satisfy \f$nev+2 \le ncv \le n\f$, 72 | /// and is advised to take \f$ncv \ge 2\cdot nev + 1\f$. 73 | /// \param sigma The real-valued shift. 74 | /// 75 | GenEigsRealShiftSolver(OpType& op, Index nev, Index ncv, const Scalar& sigma) : 76 | Base(op, IdentityBOp(), nev, ncv), 77 | m_sigma(sigma) 78 | { 79 | op.set_shift(m_sigma); 80 | } 81 | }; 82 | 83 | } // namespace Spectra 84 | 85 | #endif // SPECTRA_GEN_EIGS_REAL_SHIFT_SOLVER_H 86 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/LinAlg/SearchSpace.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020 Netherlands eScience Center 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SEARCH_SPACE_H 8 | #define SPECTRA_SEARCH_SPACE_H 9 | 10 | #include 11 | 12 | #include "RitzPairs.h" 13 | #include "Orthogonalization.h" 14 | 15 | namespace Spectra { 16 | 17 | /// This class handles the creation and manipulation of the search space 18 | /// for iterative eigensolvers such as Davidson, Jacobi-Davidson, etc. 19 | template 20 | class SearchSpace 21 | { 22 | private: 23 | using Index = Eigen::Index; 24 | using Matrix = Eigen::Matrix; 25 | 26 | Matrix m_basis_vectors; 27 | Matrix m_op_basis_product; 28 | 29 | /// Append new vector to the basis 30 | /// 31 | /// \param new_vect Matrix of new correction vectors 32 | void append_new_vectors_to_basis(const Matrix& new_vect) 33 | { 34 | Index num_update = new_vect.cols(); 35 | m_basis_vectors.conservativeResize(Eigen::NoChange, m_basis_vectors.cols() + num_update); 36 | m_basis_vectors.rightCols(num_update).noalias() = new_vect; 37 | } 38 | 39 | public: 40 | SearchSpace() = default; 41 | 42 | /// Returns the current size of the search space 43 | Index size() const { return m_basis_vectors.cols(); } 44 | 45 | void initialize_search_space(const Eigen::Ref& initial_vectors) 46 | { 47 | m_basis_vectors = initial_vectors; 48 | m_op_basis_product = Matrix(initial_vectors.rows(), 0); 49 | } 50 | 51 | /// Updates the matrix formed by the operator applied to the search space 52 | /// after the addition of new vectors in the search space. Only the product 53 | /// of the operator with the new vectors is computed and the result is appended 54 | /// to the op_basis_product member variable 55 | /// 56 | /// \param OpType Operator representing the matrix 57 | template 58 | void update_operator_basis_product(OpType& op) 59 | { 60 | Index nvec = m_basis_vectors.cols() - m_op_basis_product.cols(); 61 | m_op_basis_product.conservativeResize(Eigen::NoChange, m_basis_vectors.cols()); 62 | m_op_basis_product.rightCols(nvec).noalias() = op * m_basis_vectors.rightCols(nvec); 63 | } 64 | 65 | /// Restart the search space by reducing the basis vector to the last 66 | /// Ritz eigenvector 67 | /// 68 | /// \param ritz_pair Instance of a RitzPair class 69 | /// \param size Size of the restart 70 | void restart(const RitzPairs& ritz_pairs, Index size) 71 | { 72 | m_basis_vectors = ritz_pairs.ritz_vectors().leftCols(size); 73 | m_op_basis_product = m_op_basis_product * ritz_pairs.small_ritz_vectors().leftCols(size); 74 | } 75 | 76 | /// Append new vectors to the search space and 77 | /// orthogonalize the resulting matrix 78 | /// 79 | /// \param new_vect Matrix of new correction vectors 80 | void extend_basis(const Matrix& new_vect) 81 | { 82 | Index left_cols_to_skip = size(); 83 | append_new_vectors_to_basis(new_vect); 84 | twice_is_enough_orthogonalisation(m_basis_vectors, left_cols_to_skip); 85 | } 86 | 87 | /// Returns the basis vectors 88 | const Matrix& basis_vectors() const { return m_basis_vectors; } 89 | 90 | /// Returns the operator applied to basis vector 91 | const Matrix& operator_basis_product() const { return m_op_basis_product; } 92 | }; 93 | 94 | } // namespace Spectra 95 | 96 | #endif // SPECTRA_SEARCH_SPACE_H 97 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/DenseGenMatProd.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_DENSE_GEN_MAT_PROD_H 8 | #define SPECTRA_DENSE_GEN_MAT_PROD_H 9 | 10 | #include 11 | 12 | namespace Spectra { 13 | 14 | /// 15 | /// \defgroup MatOp Matrix Operations 16 | /// 17 | /// Define matrix operations on existing matrix objects 18 | /// 19 | 20 | /// 21 | /// \ingroup MatOp 22 | /// 23 | /// This class defines the matrix-vector multiplication operation on a 24 | /// general real matrix \f$A\f$, i.e., calculating \f$y=Ax\f$ for any vector 25 | /// \f$x\f$. It is mainly used in the GenEigsSolver and 26 | /// SymEigsSolver eigen solvers. 27 | /// 28 | /// \tparam Scalar_ The element type of the matrix, for example, 29 | /// `float`, `double`, and `long double`. 30 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 31 | /// the storage format of the input matrix. 32 | /// 33 | template 34 | class DenseGenMatProd 35 | { 36 | public: 37 | /// 38 | /// Element type of the matrix. 39 | /// 40 | using Scalar = Scalar_; 41 | 42 | private: 43 | using Index = Eigen::Index; 44 | using Matrix = Eigen::Matrix; 45 | using Vector = Eigen::Matrix; 46 | using MapConstVec = Eigen::Map; 47 | using MapVec = Eigen::Map; 48 | using ConstGenericMatrix = const Eigen::Ref; 49 | 50 | ConstGenericMatrix m_mat; 51 | 52 | public: 53 | /// 54 | /// Constructor to create the matrix operation object. 55 | /// 56 | /// \param mat An **Eigen** matrix object, whose type can be 57 | /// `Eigen::Matrix` (e.g. `Eigen::MatrixXd` and 58 | /// `Eigen::MatrixXf`), or its mapped version 59 | /// (e.g. `Eigen::Map`). 60 | /// 61 | template 62 | DenseGenMatProd(const Eigen::MatrixBase& mat) : 63 | m_mat(mat) 64 | { 65 | static_assert( 66 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(Matrix::IsRowMajor), 67 | "DenseGenMatProd: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 68 | } 69 | 70 | /// 71 | /// Return the number of rows of the underlying matrix. 72 | /// 73 | Index rows() const { return m_mat.rows(); } 74 | /// 75 | /// Return the number of columns of the underlying matrix. 76 | /// 77 | Index cols() const { return m_mat.cols(); } 78 | 79 | /// 80 | /// Perform the matrix-vector multiplication operation \f$y=Ax\f$. 81 | /// 82 | /// \param x_in Pointer to the \f$x\f$ vector. 83 | /// \param y_out Pointer to the \f$y\f$ vector. 84 | /// 85 | // y_out = A * x_in 86 | void perform_op(const Scalar* x_in, Scalar* y_out) const 87 | { 88 | MapConstVec x(x_in, m_mat.cols()); 89 | MapVec y(y_out, m_mat.rows()); 90 | y.noalias() = m_mat * x; 91 | } 92 | 93 | /// 94 | /// Perform the matrix-matrix multiplication operation \f$y=Ax\f$. 95 | /// 96 | Matrix operator*(const Eigen::Ref& mat_in) const 97 | { 98 | return m_mat * mat_in; 99 | } 100 | 101 | /// 102 | /// Extract (i,j) element of the underlying matrix. 103 | /// 104 | Scalar operator()(Index i, Index j) const 105 | { 106 | return m_mat(i, j); 107 | } 108 | }; 109 | 110 | } // namespace Spectra 111 | 112 | #endif // SPECTRA_DENSE_GEN_MAT_PROD_H 113 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/DenseGenRealShiftSolve.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_DENSE_GEN_REAL_SHIFT_SOLVE_H 8 | #define SPECTRA_DENSE_GEN_REAL_SHIFT_SOLVE_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace Spectra { 15 | 16 | /// 17 | /// \ingroup MatOp 18 | /// 19 | /// This class defines the shift-solve operation on a general real matrix \f$A\f$, 20 | /// i.e., calculating \f$y=(A-\sigma I)^{-1}x\f$ for any real \f$\sigma\f$ and 21 | /// vector \f$x\f$. It is mainly used in the GenEigsRealShiftSolver eigen solver. 22 | /// 23 | /// \tparam Scalar_ The element type of the matrix, for example, 24 | /// `float`, `double`, and `long double`. 25 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 26 | /// the storage format of the input matrix. 27 | /// 28 | template 29 | class DenseGenRealShiftSolve 30 | { 31 | public: 32 | /// 33 | /// Element type of the matrix. 34 | /// 35 | using Scalar = Scalar_; 36 | 37 | private: 38 | using Index = Eigen::Index; 39 | using Matrix = Eigen::Matrix; 40 | using Vector = Eigen::Matrix; 41 | using MapConstVec = Eigen::Map; 42 | using MapVec = Eigen::Map; 43 | using ConstGenericMatrix = const Eigen::Ref; 44 | 45 | ConstGenericMatrix m_mat; 46 | const Index m_n; 47 | Eigen::PartialPivLU m_solver; 48 | 49 | public: 50 | /// 51 | /// Constructor to create the matrix operation object. 52 | /// 53 | /// \param mat An **Eigen** matrix object, whose type can be 54 | /// `Eigen::Matrix` (e.g. `Eigen::MatrixXd` and 55 | /// `Eigen::MatrixXf`), or its mapped version 56 | /// (e.g. `Eigen::Map`). 57 | /// 58 | template 59 | DenseGenRealShiftSolve(const Eigen::MatrixBase& mat) : 60 | m_mat(mat), m_n(mat.rows()) 61 | { 62 | static_assert( 63 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(Matrix::IsRowMajor), 64 | "DenseGenRealShiftSolve: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 65 | 66 | if (mat.rows() != mat.cols()) 67 | throw std::invalid_argument("DenseGenRealShiftSolve: matrix must be square"); 68 | } 69 | 70 | /// 71 | /// Return the number of rows of the underlying matrix. 72 | /// 73 | Index rows() const { return m_n; } 74 | /// 75 | /// Return the number of columns of the underlying matrix. 76 | /// 77 | Index cols() const { return m_n; } 78 | 79 | /// 80 | /// Set the real shift \f$\sigma\f$. 81 | /// 82 | void set_shift(const Scalar& sigma) 83 | { 84 | m_solver.compute(m_mat - sigma * Matrix::Identity(m_n, m_n)); 85 | } 86 | 87 | /// 88 | /// Perform the shift-solve operation \f$y=(A-\sigma I)^{-1}x\f$. 89 | /// 90 | /// \param x_in Pointer to the \f$x\f$ vector. 91 | /// \param y_out Pointer to the \f$y\f$ vector. 92 | /// 93 | // y_out = inv(A - sigma * I) * x_in 94 | void perform_op(const Scalar* x_in, Scalar* y_out) const 95 | { 96 | MapConstVec x(x_in, m_n); 97 | MapVec y(y_out, m_n); 98 | y.noalias() = m_solver.solve(x); 99 | } 100 | }; 101 | 102 | } // namespace Spectra 103 | 104 | #endif // SPECTRA_DENSE_GEN_REAL_SHIFT_SOLVE_H 105 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/DenseSymMatProd.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_DENSE_SYM_MAT_PROD_H 8 | #define SPECTRA_DENSE_SYM_MAT_PROD_H 9 | 10 | #include 11 | 12 | namespace Spectra { 13 | 14 | /// 15 | /// \ingroup MatOp 16 | /// 17 | /// This class defines the matrix-vector multiplication operation on a 18 | /// symmetric real matrix \f$A\f$, i.e., calculating \f$y=Ax\f$ for any vector 19 | /// \f$x\f$. It is mainly used in the SymEigsSolver eigen solver. 20 | /// 21 | /// \tparam Scalar_ The element type of the matrix, for example, 22 | /// `float`, `double`, and `long double`. 23 | /// \tparam Uplo Either `Eigen::Lower` or `Eigen::Upper`, indicating which 24 | /// triangular part of the matrix is used. 25 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 26 | /// the storage format of the input matrix. 27 | /// 28 | template 29 | class DenseSymMatProd 30 | { 31 | public: 32 | /// 33 | /// Element type of the matrix. 34 | /// 35 | using Scalar = Scalar_; 36 | 37 | private: 38 | using Index = Eigen::Index; 39 | using Matrix = Eigen::Matrix; 40 | using Vector = Eigen::Matrix; 41 | using MapConstVec = Eigen::Map; 42 | using MapVec = Eigen::Map; 43 | using ConstGenericMatrix = const Eigen::Ref; 44 | 45 | ConstGenericMatrix m_mat; 46 | 47 | public: 48 | /// 49 | /// Constructor to create the matrix operation object. 50 | /// 51 | /// \param mat An **Eigen** matrix object, whose type can be 52 | /// `Eigen::Matrix` (e.g. `Eigen::MatrixXd` and 53 | /// `Eigen::MatrixXf`), or its mapped version 54 | /// (e.g. `Eigen::Map`). 55 | /// 56 | template 57 | DenseSymMatProd(const Eigen::MatrixBase& mat) : 58 | m_mat(mat) 59 | { 60 | static_assert( 61 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(Matrix::IsRowMajor), 62 | "DenseSymMatProd: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 63 | } 64 | 65 | /// 66 | /// Return the number of rows of the underlying matrix. 67 | /// 68 | Index rows() const { return m_mat.rows(); } 69 | /// 70 | /// Return the number of columns of the underlying matrix. 71 | /// 72 | Index cols() const { return m_mat.cols(); } 73 | 74 | /// 75 | /// Perform the matrix-vector multiplication operation \f$y=Ax\f$. 76 | /// 77 | /// \param x_in Pointer to the \f$x\f$ vector. 78 | /// \param y_out Pointer to the \f$y\f$ vector. 79 | /// 80 | // y_out = A * x_in 81 | void perform_op(const Scalar* x_in, Scalar* y_out) const 82 | { 83 | MapConstVec x(x_in, m_mat.cols()); 84 | MapVec y(y_out, m_mat.rows()); 85 | y.noalias() = m_mat.template selfadjointView() * x; 86 | } 87 | 88 | /// 89 | /// Perform the matrix-matrix multiplication operation \f$y=Ax\f$. 90 | /// 91 | Matrix operator*(const Eigen::Ref& mat_in) const 92 | { 93 | return m_mat.template selfadjointView() * mat_in; 94 | } 95 | 96 | /// 97 | /// Extract (i,j) element of the underlying matrix. 98 | /// 99 | Scalar operator()(Index i, Index j) const 100 | { 101 | return m_mat(i, j); 102 | } 103 | }; 104 | 105 | } // namespace Spectra 106 | 107 | #endif // SPECTRA_DENSE_SYM_MAT_PROD_H 108 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/DenseSymShiftSolve.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_DENSE_SYM_SHIFT_SOLVE_H 8 | #define SPECTRA_DENSE_SYM_SHIFT_SOLVE_H 9 | 10 | #include 11 | #include 12 | 13 | #include "../LinAlg/BKLDLT.h" 14 | #include "../Util/CompInfo.h" 15 | 16 | namespace Spectra { 17 | 18 | /// 19 | /// \ingroup MatOp 20 | /// 21 | /// This class defines the shift-solve operation on a real symmetric matrix \f$A\f$, 22 | /// i.e., calculating \f$y=(A-\sigma I)^{-1}x\f$ for any real \f$\sigma\f$ and 23 | /// vector \f$x\f$. It is mainly used in the SymEigsShiftSolver eigen solver. 24 | /// 25 | /// \tparam Scalar_ The element type of the matrix, for example, 26 | /// `float`, `double`, and `long double`. 27 | /// \tparam Uplo Either `Eigen::Lower` or `Eigen::Upper`, indicating which 28 | /// triangular part of the matrix is used. 29 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 30 | /// the storage format of the input matrix. 31 | /// 32 | template 33 | class DenseSymShiftSolve 34 | { 35 | public: 36 | /// 37 | /// Element type of the matrix. 38 | /// 39 | using Scalar = Scalar_; 40 | 41 | private: 42 | using Index = Eigen::Index; 43 | using Matrix = Eigen::Matrix; 44 | using Vector = Eigen::Matrix; 45 | using MapConstVec = Eigen::Map; 46 | using MapVec = Eigen::Map; 47 | using ConstGenericMatrix = const Eigen::Ref; 48 | 49 | ConstGenericMatrix m_mat; 50 | const Index m_n; 51 | BKLDLT m_solver; 52 | 53 | public: 54 | /// 55 | /// Constructor to create the matrix operation object. 56 | /// 57 | /// \param mat An **Eigen** matrix object, whose type can be 58 | /// `Eigen::Matrix` (e.g. `Eigen::MatrixXd` and 59 | /// `Eigen::MatrixXf`), or its mapped version 60 | /// (e.g. `Eigen::Map`). 61 | /// 62 | template 63 | DenseSymShiftSolve(const Eigen::MatrixBase& mat) : 64 | m_mat(mat), m_n(mat.rows()) 65 | { 66 | static_assert( 67 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(Matrix::IsRowMajor), 68 | "DenseSymShiftSolve: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 69 | 70 | if (m_n != mat.cols()) 71 | throw std::invalid_argument("DenseSymShiftSolve: matrix must be square"); 72 | } 73 | 74 | /// 75 | /// Return the number of rows of the underlying matrix. 76 | /// 77 | Index rows() const { return m_n; } 78 | /// 79 | /// Return the number of columns of the underlying matrix. 80 | /// 81 | Index cols() const { return m_n; } 82 | 83 | /// 84 | /// Set the real shift \f$\sigma\f$. 85 | /// 86 | void set_shift(const Scalar& sigma) 87 | { 88 | m_solver.compute(m_mat, Uplo, sigma); 89 | if (m_solver.info() != CompInfo::Successful) 90 | throw std::invalid_argument("DenseSymShiftSolve: factorization failed with the given shift"); 91 | } 92 | 93 | /// 94 | /// Perform the shift-solve operation \f$y=(A-\sigma I)^{-1}x\f$. 95 | /// 96 | /// \param x_in Pointer to the \f$x\f$ vector. 97 | /// \param y_out Pointer to the \f$y\f$ vector. 98 | /// 99 | // y_out = inv(A - sigma * I) * x_in 100 | void perform_op(const Scalar* x_in, Scalar* y_out) const 101 | { 102 | MapConstVec x(x_in, m_n); 103 | MapVec y(y_out, m_n); 104 | y.noalias() = m_solver.solve(x); 105 | } 106 | }; 107 | 108 | } // namespace Spectra 109 | 110 | #endif // SPECTRA_DENSE_SYM_SHIFT_SOLVE_H 111 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/SparseGenMatProd.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SPARSE_GEN_MAT_PROD_H 8 | #define SPECTRA_SPARSE_GEN_MAT_PROD_H 9 | 10 | #include 11 | #include 12 | 13 | namespace Spectra { 14 | /// 15 | /// \ingroup MatOp 16 | /// 17 | /// This class defines the matrix-vector multiplication operation on a 18 | /// sparse real matrix \f$A\f$, i.e., calculating \f$y=Ax\f$ for any vector 19 | /// \f$x\f$. It is mainly used in the GenEigsSolver and SymEigsSolver 20 | /// eigen solvers. 21 | /// 22 | /// \tparam Scalar_ The element type of the matrix, for example, 23 | /// `float`, `double`, and `long double`. 24 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 25 | /// the storage format of the input matrix. 26 | /// \tparam StorageIndex The type of the indices for the sparse matrix. 27 | /// 28 | template 29 | class SparseGenMatProd 30 | { 31 | public: 32 | /// 33 | /// Element type of the matrix. 34 | /// 35 | using Scalar = Scalar_; 36 | 37 | private: 38 | using Index = Eigen::Index; 39 | using Vector = Eigen::Matrix; 40 | using MapConstVec = Eigen::Map; 41 | using MapVec = Eigen::Map; 42 | using Matrix = Eigen::Matrix; 43 | using SparseMatrix = Eigen::SparseMatrix; 44 | using ConstGenericSparseMatrix = const Eigen::Ref; 45 | 46 | ConstGenericSparseMatrix m_mat; 47 | 48 | public: 49 | /// 50 | /// Constructor to create the matrix operation object. 51 | /// 52 | /// \param mat An **Eigen** sparse matrix object, whose type can be 53 | /// `Eigen::SparseMatrix` or its mapped version 54 | /// `Eigen::Map >`. 55 | /// 56 | template 57 | SparseGenMatProd(const Eigen::SparseMatrixBase& mat) : 58 | m_mat(mat) 59 | { 60 | static_assert( 61 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(SparseMatrix::IsRowMajor), 62 | "SparseGenMatProd: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 63 | } 64 | 65 | /// 66 | /// Return the number of rows of the underlying matrix. 67 | /// 68 | Index rows() const { return m_mat.rows(); } 69 | /// 70 | /// Return the number of columns of the underlying matrix. 71 | /// 72 | Index cols() const { return m_mat.cols(); } 73 | 74 | /// 75 | /// Perform the matrix-vector multiplication operation \f$y=Ax\f$. 76 | /// 77 | /// \param x_in Pointer to the \f$x\f$ vector. 78 | /// \param y_out Pointer to the \f$y\f$ vector. 79 | /// 80 | // y_out = A * x_in 81 | void perform_op(const Scalar* x_in, Scalar* y_out) const 82 | { 83 | MapConstVec x(x_in, m_mat.cols()); 84 | MapVec y(y_out, m_mat.rows()); 85 | y.noalias() = m_mat * x; 86 | } 87 | 88 | /// 89 | /// Perform the matrix-matrix multiplication operation \f$y=Ax\f$. 90 | /// 91 | Matrix operator*(const Eigen::Ref& mat_in) const 92 | { 93 | return m_mat * mat_in; 94 | } 95 | 96 | /// 97 | /// Extract (i,j) element of the underlying matrix. 98 | /// 99 | Scalar operator()(Index i, Index j) const 100 | { 101 | return m_mat.coeff(i, j); 102 | } 103 | }; 104 | 105 | } // namespace Spectra 106 | 107 | #endif // SPECTRA_SPARSE_GEN_MAT_PROD_H 108 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/SparseGenRealShiftSolve.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SPARSE_GEN_REAL_SHIFT_SOLVE_H 8 | #define SPECTRA_SPARSE_GEN_REAL_SHIFT_SOLVE_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup MatOp 19 | /// 20 | /// This class defines the shift-solve operation on a sparse real matrix \f$A\f$, 21 | /// i.e., calculating \f$y=(A-\sigma I)^{-1}x\f$ for any real \f$\sigma\f$ and 22 | /// vector \f$x\f$. It is mainly used in the GenEigsRealShiftSolver eigen solver. 23 | /// 24 | /// \tparam Scalar_ The element type of the matrix, for example, 25 | /// `float`, `double`, and `long double`. 26 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 27 | /// the storage format of the input matrix. 28 | /// \tparam StorageIndex The type of the indices for the sparse matrix. 29 | /// 30 | template 31 | class SparseGenRealShiftSolve 32 | { 33 | public: 34 | /// 35 | /// Element type of the matrix. 36 | /// 37 | using Scalar = Scalar_; 38 | 39 | private: 40 | using Index = Eigen::Index; 41 | using Vector = Eigen::Matrix; 42 | using MapConstVec = Eigen::Map; 43 | using MapVec = Eigen::Map; 44 | using SparseMatrix = Eigen::SparseMatrix; 45 | using ConstGenericSparseMatrix = const Eigen::Ref; 46 | 47 | ConstGenericSparseMatrix m_mat; 48 | const Index m_n; 49 | Eigen::SparseLU m_solver; 50 | 51 | public: 52 | /// 53 | /// Constructor to create the matrix operation object. 54 | /// 55 | /// \param mat An **Eigen** sparse matrix object, whose type can be 56 | /// `Eigen::SparseMatrix` or its mapped version 57 | /// `Eigen::Map >`. 58 | /// 59 | template 60 | SparseGenRealShiftSolve(const Eigen::SparseMatrixBase& mat) : 61 | m_mat(mat), m_n(mat.rows()) 62 | { 63 | static_assert( 64 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(SparseMatrix::IsRowMajor), 65 | "SparseGenRealShiftSolve: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 66 | 67 | if (mat.rows() != mat.cols()) 68 | throw std::invalid_argument("SparseGenRealShiftSolve: matrix must be square"); 69 | } 70 | 71 | /// 72 | /// Return the number of rows of the underlying matrix. 73 | /// 74 | Index rows() const { return m_n; } 75 | /// 76 | /// Return the number of columns of the underlying matrix. 77 | /// 78 | Index cols() const { return m_n; } 79 | 80 | /// 81 | /// Set the real shift \f$\sigma\f$. 82 | /// 83 | void set_shift(const Scalar& sigma) 84 | { 85 | SparseMatrix I(m_n, m_n); 86 | I.setIdentity(); 87 | 88 | m_solver.compute(m_mat - sigma * I); 89 | if (m_solver.info() != Eigen::Success) 90 | throw std::invalid_argument("SparseGenRealShiftSolve: factorization failed with the given shift"); 91 | } 92 | 93 | /// 94 | /// Perform the shift-solve operation \f$y=(A-\sigma I)^{-1}x\f$. 95 | /// 96 | /// \param x_in Pointer to the \f$x\f$ vector. 97 | /// \param y_out Pointer to the \f$y\f$ vector. 98 | /// 99 | // y_out = inv(A - sigma * I) * x_in 100 | void perform_op(const Scalar* x_in, Scalar* y_out) const 101 | { 102 | MapConstVec x(x_in, m_n); 103 | MapVec y(y_out, m_n); 104 | y.noalias() = m_solver.solve(x); 105 | } 106 | }; 107 | 108 | } // namespace Spectra 109 | 110 | #endif // SPECTRA_SPARSE_GEN_REAL_SHIFT_SOLVE_H 111 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/SparseSymMatProd.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SPARSE_SYM_MAT_PROD_H 8 | #define SPECTRA_SPARSE_SYM_MAT_PROD_H 9 | 10 | #include 11 | #include 12 | 13 | namespace Spectra { 14 | 15 | /// 16 | /// \ingroup MatOp 17 | /// 18 | /// This class defines the matrix-vector multiplication operation on a 19 | /// sparse real symmetric matrix \f$A\f$, i.e., calculating \f$y=Ax\f$ for any vector 20 | /// \f$x\f$. It is mainly used in the SymEigsSolver eigen solver. 21 | /// 22 | /// \tparam Scalar_ The element type of the matrix, for example, 23 | /// `float`, `double`, and `long double`. 24 | /// \tparam Uplo Either `Eigen::Lower` or `Eigen::Upper`, indicating which 25 | /// triangular part of the matrix is used. 26 | /// \tparam Flags Either `Eigen::ColMajor` or `Eigen::RowMajor`, indicating 27 | /// the storage format of the input matrix. 28 | /// \tparam StorageIndex The type of the indices for the sparse matrix. 29 | /// 30 | template 31 | class SparseSymMatProd 32 | { 33 | public: 34 | /// 35 | /// Element type of the matrix. 36 | /// 37 | using Scalar = Scalar_; 38 | 39 | private: 40 | using Index = Eigen::Index; 41 | using Vector = Eigen::Matrix; 42 | using MapConstVec = Eigen::Map; 43 | using MapVec = Eigen::Map; 44 | using Matrix = Eigen::Matrix; 45 | using SparseMatrix = Eigen::SparseMatrix; 46 | using ConstGenericSparseMatrix = const Eigen::Ref; 47 | 48 | ConstGenericSparseMatrix m_mat; 49 | 50 | public: 51 | /// 52 | /// Constructor to create the matrix operation object. 53 | /// 54 | /// \param mat An **Eigen** sparse matrix object, whose type can be 55 | /// `Eigen::SparseMatrix` or its mapped version 56 | /// `Eigen::Map >`. 57 | /// 58 | template 59 | SparseSymMatProd(const Eigen::SparseMatrixBase& mat) : 60 | m_mat(mat) 61 | { 62 | static_assert( 63 | static_cast(Derived::PlainObject::IsRowMajor) == static_cast(SparseMatrix::IsRowMajor), 64 | "SparseSymMatProd: the \"Flags\" template parameter does not match the input matrix (Eigen::ColMajor/Eigen::RowMajor)"); 65 | } 66 | 67 | /// 68 | /// Return the number of rows of the underlying matrix. 69 | /// 70 | Index rows() const { return m_mat.rows(); } 71 | /// 72 | /// Return the number of columns of the underlying matrix. 73 | /// 74 | Index cols() const { return m_mat.cols(); } 75 | 76 | /// 77 | /// Perform the matrix-vector multiplication operation \f$y=Ax\f$. 78 | /// 79 | /// \param x_in Pointer to the \f$x\f$ vector. 80 | /// \param y_out Pointer to the \f$y\f$ vector. 81 | /// 82 | // y_out = A * x_in 83 | void perform_op(const Scalar* x_in, Scalar* y_out) const 84 | { 85 | MapConstVec x(x_in, m_mat.cols()); 86 | MapVec y(y_out, m_mat.rows()); 87 | y.noalias() = m_mat.template selfadjointView() * x; 88 | } 89 | 90 | /// 91 | /// Perform the matrix-matrix multiplication operation \f$y=Ax\f$. 92 | /// 93 | Matrix operator*(const Eigen::Ref& mat_in) const 94 | { 95 | return m_mat.template selfadjointView() * mat_in; 96 | } 97 | 98 | /// 99 | /// Extract (i,j) element of the underlying matrix. 100 | /// 101 | Scalar operator()(Index i, Index j) const 102 | { 103 | return m_mat.coeff(i, j); 104 | } 105 | }; 106 | } // namespace Spectra 107 | 108 | #endif // SPECTRA_SPARSE_SYM_MAT_PROD_H 109 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/internal/SymGEigsBucklingOp.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SYM_GEIGS_BUCKLING_OP_H 8 | #define SPECTRA_SYM_GEIGS_BUCKLING_OP_H 9 | 10 | #include 11 | 12 | #include "../SymShiftInvert.h" 13 | #include "../SparseSymMatProd.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup Operators 19 | /// 20 | /// This class defines the matrix operation for generalized eigen solver in the 21 | /// buckling mode. It computes \f$y=(K-\sigma K_G)^{-1}Kx\f$ for any 22 | /// vector \f$x\f$, where \f$K\f$ is positive definite, \f$K_G\f$ is symmetric, 23 | /// and \f$\sigma\f$ is a real shift. 24 | /// This class is intended for internal use. 25 | /// 26 | template , 27 | typename BOpType = SparseSymMatProd> 28 | class SymGEigsBucklingOp 29 | { 30 | public: 31 | using Scalar = typename OpType::Scalar; 32 | 33 | private: 34 | using Index = Eigen::Index; 35 | using Vector = Eigen::Matrix; 36 | 37 | OpType& m_op; 38 | const BOpType& m_Bop; 39 | mutable Vector m_cache; // temporary working space 40 | 41 | public: 42 | /// 43 | /// Constructor to create the matrix operation object. 44 | /// 45 | /// \param op The \f$(K-\sigma K_G)^{-1}\f$ matrix operation object. 46 | /// \param Bop The \f$K\f$ matrix operation object. 47 | /// 48 | SymGEigsBucklingOp(OpType& op, const BOpType& Bop) : 49 | m_op(op), m_Bop(Bop), m_cache(op.rows()) 50 | {} 51 | 52 | /// 53 | /// Move constructor. 54 | /// 55 | SymGEigsBucklingOp(SymGEigsBucklingOp&& other) : 56 | m_op(other.m_op), m_Bop(other.m_Bop) 57 | { 58 | // We emulate the move constructor for Vector using Vector::swap() 59 | m_cache.swap(other.m_cache); 60 | } 61 | 62 | /// 63 | /// Return the number of rows of the underlying matrix. 64 | /// 65 | Index rows() const { return m_op.rows(); } 66 | /// 67 | /// Return the number of columns of the underlying matrix. 68 | /// 69 | Index cols() const { return m_op.rows(); } 70 | 71 | /// 72 | /// Set the real shift \f$\sigma\f$. 73 | /// 74 | void set_shift(const Scalar& sigma) 75 | { 76 | m_op.set_shift(sigma); 77 | } 78 | 79 | /// 80 | /// Perform the matrix operation \f$y=(K-\sigma K_G)^{-1}Kx\f$. 81 | /// 82 | /// \param x_in Pointer to the \f$x\f$ vector. 83 | /// \param y_out Pointer to the \f$y\f$ vector. 84 | /// 85 | // y_out = inv(K - sigma * K_G) * K * x_in 86 | void perform_op(const Scalar* x_in, Scalar* y_out) const 87 | { 88 | m_Bop.perform_op(x_in, m_cache.data()); 89 | m_op.perform_op(m_cache.data(), y_out); 90 | } 91 | }; 92 | 93 | } // namespace Spectra 94 | 95 | #endif // SPECTRA_SYM_GEIGS_BUCKLING_OP_H 96 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/internal/SymGEigsCayleyOp.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SYM_GEIGS_CAYLEY_OP_H 8 | #define SPECTRA_SYM_GEIGS_CAYLEY_OP_H 9 | 10 | #include 11 | 12 | #include "../SymShiftInvert.h" 13 | #include "../SparseSymMatProd.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup Operators 19 | /// 20 | /// This class defines the matrix operation for generalized eigen solver in the 21 | /// Cayley mode. It computes \f$y=(A-\sigma B)^{-1}(A+\sigma B)x\f$ for any 22 | /// vector \f$x\f$, where \f$A\f$ is a symmetric matrix, \f$B\f$ is positive definite, 23 | /// and \f$\sigma\f$ is a real shift. 24 | /// This class is intended for internal use. 25 | /// 26 | template , 27 | typename BOpType = SparseSymMatProd> 28 | class SymGEigsCayleyOp 29 | { 30 | public: 31 | using Scalar = typename OpType::Scalar; 32 | 33 | private: 34 | using Index = Eigen::Index; 35 | using Vector = Eigen::Matrix; 36 | using MapConstVec = Eigen::Map; 37 | using MapVec = Eigen::Map; 38 | 39 | OpType& m_op; 40 | const BOpType& m_Bop; 41 | mutable Vector m_cache; // temporary working space 42 | Scalar m_sigma; 43 | 44 | public: 45 | /// 46 | /// Constructor to create the matrix operation object. 47 | /// 48 | /// \param op The \f$(A-\sigma B)^{-1}\f$ matrix operation object. 49 | /// \param Bop The \f$B\f$ matrix operation object. 50 | /// 51 | SymGEigsCayleyOp(OpType& op, const BOpType& Bop) : 52 | m_op(op), m_Bop(Bop), m_cache(op.rows()) 53 | {} 54 | 55 | /// 56 | /// Move constructor. 57 | /// 58 | SymGEigsCayleyOp(SymGEigsCayleyOp&& other) : 59 | m_op(other.m_op), m_Bop(other.m_Bop), m_sigma(other.m_sigma) 60 | { 61 | // We emulate the move constructor for Vector using Vector::swap() 62 | m_cache.swap(other.m_cache); 63 | } 64 | 65 | /// 66 | /// Return the number of rows of the underlying matrix. 67 | /// 68 | Index rows() const { return m_op.rows(); } 69 | /// 70 | /// Return the number of columns of the underlying matrix. 71 | /// 72 | Index cols() const { return m_op.rows(); } 73 | 74 | /// 75 | /// Set the real shift \f$\sigma\f$. 76 | /// 77 | void set_shift(const Scalar& sigma) 78 | { 79 | m_op.set_shift(sigma); 80 | m_sigma = sigma; 81 | } 82 | 83 | /// 84 | /// Perform the matrix operation \f$y=(A-\sigma B)^{-1}(A+\sigma B)x\f$. 85 | /// 86 | /// \param x_in Pointer to the \f$x\f$ vector. 87 | /// \param y_out Pointer to the \f$y\f$ vector. 88 | /// 89 | // y_out = inv(A - sigma * B) * (A + sigma * B) * x_in 90 | void perform_op(const Scalar* x_in, Scalar* y_out) const 91 | { 92 | // inv(A - sigma * B) * (A + sigma * B) * x 93 | // = inv(A - sigma * B) * (A - sigma * B + 2 * sigma * B) * x 94 | // = x + 2 * sigma * inv(A - sigma * B) * B * x 95 | m_Bop.perform_op(x_in, m_cache.data()); 96 | m_op.perform_op(m_cache.data(), y_out); 97 | MapConstVec x(x_in, this->rows()); 98 | MapVec y(y_out, this->rows()); 99 | y.noalias() = x + (Scalar(2) * m_sigma) * y; 100 | } 101 | }; 102 | 103 | } // namespace Spectra 104 | 105 | #endif // SPECTRA_SYM_GEIGS_CAYLEY_OP_H 106 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/internal/SymGEigsCholeskyOp.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SYM_GEIGS_CHOLESKY_OP_H 8 | #define SPECTRA_SYM_GEIGS_CHOLESKY_OP_H 9 | 10 | #include 11 | 12 | #include "../DenseSymMatProd.h" 13 | #include "../DenseCholesky.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup Operators 19 | /// 20 | /// This class defines the matrix operation for generalized eigen solver in the 21 | /// Cholesky decomposition mode. It calculates \f$y=L^{-1}A(L')^{-1}x\f$ for any 22 | /// vector \f$x\f$, where \f$L\f$ is the Cholesky decomposition of \f$B\f$. 23 | /// This class is intended for internal use. 24 | /// 25 | template , 26 | typename BOpType = DenseCholesky> 27 | class SymGEigsCholeskyOp 28 | { 29 | public: 30 | using Scalar = typename OpType::Scalar; 31 | 32 | private: 33 | using Index = Eigen::Index; 34 | using Vector = Eigen::Matrix; 35 | 36 | const OpType& m_op; 37 | const BOpType& m_Bop; 38 | mutable Vector m_cache; // temporary working space 39 | 40 | public: 41 | /// 42 | /// Constructor to create the matrix operation object. 43 | /// 44 | /// \param op The \f$A\f$ matrix operation object. 45 | /// \param Bop The \f$B\f$ matrix operation object. 46 | /// 47 | SymGEigsCholeskyOp(const OpType& op, const BOpType& Bop) : 48 | m_op(op), m_Bop(Bop), m_cache(op.rows()) 49 | {} 50 | 51 | /// 52 | /// Move constructor. 53 | /// 54 | SymGEigsCholeskyOp(SymGEigsCholeskyOp&& other) : 55 | m_op(other.m_op), m_Bop(other.m_Bop) 56 | { 57 | // We emulate the move constructor for Vector using Vector::swap() 58 | m_cache.swap(other.m_cache); 59 | } 60 | 61 | /// 62 | /// Return the number of rows of the underlying matrix. 63 | /// 64 | Index rows() const { return m_Bop.rows(); } 65 | /// 66 | /// Return the number of columns of the underlying matrix. 67 | /// 68 | Index cols() const { return m_Bop.rows(); } 69 | 70 | /// 71 | /// Perform the matrix operation \f$y=L^{-1}A(L')^{-1}x\f$. 72 | /// 73 | /// \param x_in Pointer to the \f$x\f$ vector. 74 | /// \param y_out Pointer to the \f$y\f$ vector. 75 | /// 76 | // y_out = inv(L) * A * inv(L') * x_in 77 | void perform_op(const Scalar* x_in, Scalar* y_out) const 78 | { 79 | m_Bop.upper_triangular_solve(x_in, y_out); 80 | m_op.perform_op(y_out, m_cache.data()); 81 | m_Bop.lower_triangular_solve(m_cache.data(), y_out); 82 | } 83 | }; 84 | 85 | } // namespace Spectra 86 | 87 | #endif // SPECTRA_SYM_GEIGS_CHOLESKY_OP_H 88 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/internal/SymGEigsRegInvOp.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2017-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SYM_GEIGS_REG_INV_OP_H 8 | #define SPECTRA_SYM_GEIGS_REG_INV_OP_H 9 | 10 | #include 11 | 12 | #include "../SparseSymMatProd.h" 13 | #include "../SparseRegularInverse.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup Operators 19 | /// 20 | /// This class defines the matrix operation for generalized eigen solver in the 21 | /// regular inverse mode. This class is intended for internal use. 22 | /// 23 | template , 24 | typename BOpType = SparseRegularInverse> 25 | class SymGEigsRegInvOp 26 | { 27 | public: 28 | using Scalar = typename OpType::Scalar; 29 | 30 | private: 31 | using Index = Eigen::Index; 32 | using Vector = Eigen::Matrix; 33 | 34 | const OpType& m_op; 35 | const BOpType& m_Bop; 36 | mutable Vector m_cache; // temporary working space 37 | 38 | public: 39 | /// 40 | /// Constructor to create the matrix operation object. 41 | /// 42 | /// \param op The \f$A\f$ matrix operation object. 43 | /// \param Bop The \f$B\f$ matrix operation object. 44 | /// 45 | SymGEigsRegInvOp(const OpType& op, const BOpType& Bop) : 46 | m_op(op), m_Bop(Bop), m_cache(op.rows()) 47 | {} 48 | 49 | /// 50 | /// Move constructor. 51 | /// 52 | SymGEigsRegInvOp(SymGEigsRegInvOp&& other) : 53 | m_op(other.m_op), m_Bop(other.m_Bop) 54 | { 55 | // We emulate the move constructor for Vector using Vector::swap() 56 | m_cache.swap(other.m_cache); 57 | } 58 | 59 | /// 60 | /// Return the number of rows of the underlying matrix. 61 | /// 62 | Index rows() const { return m_Bop.rows(); } 63 | /// 64 | /// Return the number of columns of the underlying matrix. 65 | /// 66 | Index cols() const { return m_Bop.rows(); } 67 | 68 | /// 69 | /// Perform the matrix operation \f$y=B^{-1}Ax\f$. 70 | /// 71 | /// \param x_in Pointer to the \f$x\f$ vector. 72 | /// \param y_out Pointer to the \f$y\f$ vector. 73 | /// 74 | // y_out = inv(B) * A * x_in 75 | void perform_op(const Scalar* x_in, Scalar* y_out) const 76 | { 77 | m_op.perform_op(x_in, m_cache.data()); 78 | m_Bop.solve(m_cache.data(), y_out); 79 | } 80 | }; 81 | 82 | } // namespace Spectra 83 | 84 | #endif // SPECTRA_SYM_GEIGS_REG_INV_OP_H 85 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/MatOp/internal/SymGEigsShiftInvertOp.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SYM_GEIGS_SHIFT_INVERT_OP_H 8 | #define SPECTRA_SYM_GEIGS_SHIFT_INVERT_OP_H 9 | 10 | #include 11 | 12 | #include "../SymShiftInvert.h" 13 | #include "../SparseSymMatProd.h" 14 | 15 | namespace Spectra { 16 | 17 | /// 18 | /// \ingroup Operators 19 | /// 20 | /// This class defines the matrix operation for generalized eigen solver in the 21 | /// shift-and-invert mode. It computes \f$y=(A-\sigma B)^{-1}Bx\f$ for any 22 | /// vector \f$x\f$, where \f$A\f$ is a symmetric matrix, \f$B\f$ is positive definite, 23 | /// and \f$\sigma\f$ is a real shift. 24 | /// This class is intended for internal use. 25 | /// 26 | template , 27 | typename BOpType = SparseSymMatProd> 28 | class SymGEigsShiftInvertOp 29 | { 30 | public: 31 | using Scalar = typename OpType::Scalar; 32 | 33 | private: 34 | using Index = Eigen::Index; 35 | using Vector = Eigen::Matrix; 36 | 37 | OpType& m_op; 38 | const BOpType& m_Bop; 39 | mutable Vector m_cache; // temporary working space 40 | 41 | public: 42 | /// 43 | /// Constructor to create the matrix operation object. 44 | /// 45 | /// \param op The \f$(A-\sigma B)^{-1}\f$ matrix operation object. 46 | /// \param Bop The \f$B\f$ matrix operation object. 47 | /// 48 | SymGEigsShiftInvertOp(OpType& op, const BOpType& Bop) : 49 | m_op(op), m_Bop(Bop), m_cache(op.rows()) 50 | {} 51 | 52 | /// 53 | /// Move constructor. 54 | /// 55 | SymGEigsShiftInvertOp(SymGEigsShiftInvertOp&& other) : 56 | m_op(other.m_op), m_Bop(other.m_Bop) 57 | { 58 | // We emulate the move constructor for Vector using Vector::swap() 59 | m_cache.swap(other.m_cache); 60 | } 61 | 62 | /// 63 | /// Return the number of rows of the underlying matrix. 64 | /// 65 | Index rows() const { return m_op.rows(); } 66 | /// 67 | /// Return the number of columns of the underlying matrix. 68 | /// 69 | Index cols() const { return m_op.rows(); } 70 | 71 | /// 72 | /// Set the real shift \f$\sigma\f$. 73 | /// 74 | void set_shift(const Scalar& sigma) 75 | { 76 | m_op.set_shift(sigma); 77 | } 78 | 79 | /// 80 | /// Perform the matrix operation \f$y=(A-\sigma B)^{-1}Bx\f$. 81 | /// 82 | /// \param x_in Pointer to the \f$x\f$ vector. 83 | /// \param y_out Pointer to the \f$y\f$ vector. 84 | /// 85 | // y_out = inv(A - sigma * B) * B * x_in 86 | void perform_op(const Scalar* x_in, Scalar* y_out) const 87 | { 88 | m_Bop.perform_op(x_in, m_cache.data()); 89 | m_op.perform_op(m_cache.data(), y_out); 90 | } 91 | }; 92 | 93 | } // namespace Spectra 94 | 95 | #endif // SPECTRA_SYM_GEIGS_SHIFT_INVERT_OP_H 96 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/Util/CompInfo.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_COMP_INFO_H 8 | #define SPECTRA_COMP_INFO_H 9 | 10 | namespace Spectra { 11 | 12 | /// 13 | /// \ingroup Enumerations 14 | /// 15 | /// The enumeration to report the status of computation. 16 | /// 17 | enum class CompInfo 18 | { 19 | Successful, ///< Computation was successful. 20 | 21 | NotComputed, ///< Used in eigen solvers, indicating that computation 22 | ///< has not been conducted. Users should call 23 | ///< the `compute()` member function of solvers. 24 | 25 | NotConverging, ///< Used in eigen solvers, indicating that some eigenvalues 26 | ///< did not converge. The `compute()` 27 | ///< function returns the number of converged eigenvalues. 28 | 29 | NumericalIssue ///< Used in various matrix factorization classes, for example in 30 | ///< Cholesky decomposition it indicates that the 31 | ///< matrix is not positive definite. 32 | }; 33 | 34 | } // namespace Spectra 35 | 36 | #endif // SPECTRA_COMP_INFO_H 37 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/Util/GEigsMode.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_GEIGS_MODE_H 8 | #define SPECTRA_GEIGS_MODE_H 9 | 10 | namespace Spectra { 11 | 12 | /// 13 | /// \ingroup Enumerations 14 | /// 15 | /// The enumeration to specify the mode of generalized eigenvalue solver. 16 | /// 17 | enum class GEigsMode 18 | { 19 | Cholesky, ///< Using Cholesky decomposition to solve generalized eigenvalues. 20 | RegularInverse, ///< Regular inverse mode for generalized eigenvalue solver. 21 | ShiftInvert, ///< Shift-and-invert mode for generalized eigenvalue solver. 22 | Buckling, ///< Buckling mode for generalized eigenvalue solver. 23 | Cayley ///< Cayley transformation mode for generalized eigenvalue solver. 24 | }; 25 | 26 | } // namespace Spectra 27 | 28 | #endif // SPECTRA_GEIGS_MODE_H 29 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/Util/SimpleRandom.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_SIMPLE_RANDOM_H 8 | #define SPECTRA_SIMPLE_RANDOM_H 9 | 10 | #include 11 | 12 | /// \cond 13 | 14 | namespace Spectra { 15 | 16 | // We need a simple pseudo random number generator here: 17 | // 1. It is used to generate initial and restarted residual vector. 18 | // 2. It is not necessary to be so "random" and advanced. All we hope 19 | // is that the residual vector is not in the space spanned by the 20 | // current Krylov space. This should be met almost surely. 21 | // 3. We don't want to call RNG in C++, since we actually want the 22 | // algorithm to be deterministic. Also, calling RNG in C/C++ is not 23 | // allowed in R packages submitted to CRAN. 24 | // 4. The method should be as simple as possible, so an LCG is enough. 25 | // 5. Based on public domain code by Ray Gardner 26 | // http://stjarnhimlen.se/snippets/rg_rand.c 27 | 28 | template 29 | class SimpleRandom 30 | { 31 | private: 32 | using Index = Eigen::Index; 33 | using Vector = Eigen::Matrix; 34 | 35 | static constexpr unsigned int m_a = 16807; // multiplier 36 | static constexpr unsigned long m_max = 2147483647L; // 2^31 - 1 37 | long m_rand; // RNG state 38 | 39 | inline long next_long_rand(long seed) const 40 | { 41 | unsigned long lo, hi; 42 | 43 | lo = m_a * (long) (seed & 0xFFFF); 44 | hi = m_a * (long) ((unsigned long) seed >> 16); 45 | lo += (hi & 0x7FFF) << 16; 46 | if (lo > m_max) 47 | { 48 | lo &= m_max; 49 | ++lo; 50 | } 51 | lo += hi >> 15; 52 | if (lo > m_max) 53 | { 54 | lo &= m_max; 55 | ++lo; 56 | } 57 | return (long) lo; 58 | } 59 | 60 | public: 61 | SimpleRandom(unsigned long init_seed) : 62 | m_rand(init_seed ? (init_seed & m_max) : 1) 63 | {} 64 | 65 | // Return a single random number, ranging from -0.5 to 0.5 66 | Scalar random() 67 | { 68 | m_rand = next_long_rand(m_rand); 69 | return Scalar(m_rand) / Scalar(m_max) - Scalar(0.5); 70 | } 71 | 72 | // Fill the given vector with random numbers 73 | // Ranging from -0.5 to 0.5 74 | void random_vec(Vector& vec) 75 | { 76 | const Index len = vec.size(); 77 | for (Index i = 0; i < len; i++) 78 | { 79 | m_rand = next_long_rand(m_rand); 80 | vec[i] = Scalar(m_rand); 81 | } 82 | vec.array() = vec.array() / Scalar(m_max) - Scalar(0.5); 83 | } 84 | 85 | // Return a vector of random numbers 86 | // Ranging from -0.5 to 0.5 87 | Vector random_vec(const Index len) 88 | { 89 | Vector res(len); 90 | random_vec(res); 91 | return res; 92 | } 93 | }; 94 | 95 | } // namespace Spectra 96 | 97 | /// \endcond 98 | 99 | #endif // SPECTRA_SIMPLE_RANDOM_H 100 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/Util/TypeTraits.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_TYPE_TRAITS_H 8 | #define SPECTRA_TYPE_TRAITS_H 9 | 10 | #include 11 | #include 12 | 13 | /// \cond 14 | 15 | // Clang-Format will have unintended effects: 16 | // static constexpr Scalar(min)() 17 | // So we turn it off here 18 | // 19 | // clang-format off 20 | 21 | namespace Spectra { 22 | 23 | // For a real value type "Scalar", we want to know its smallest 24 | // positive value, i.e., std::numeric_limits::min(). 25 | // However, we must take non-standard value types into account, 26 | // so we rely on Eigen::NumTraits. 27 | // 28 | // Eigen::NumTraits has defined epsilon() and lowest(), but 29 | // lowest() means negative highest(), which is a very small 30 | // negative value. 31 | // 32 | // Therefore, we manually define this limit, and use eplison()^3 33 | // to mimic it for non-standard types. 34 | 35 | // Generic definition 36 | template 37 | struct TypeTraits 38 | { 39 | static constexpr Scalar epsilon() 40 | { 41 | return Eigen::numext::numeric_limits::epsilon(); 42 | } 43 | static constexpr Scalar (min)() 44 | { 45 | return epsilon() * epsilon() * epsilon(); 46 | } 47 | }; 48 | 49 | // Full specialization 50 | template <> 51 | struct TypeTraits 52 | { 53 | static constexpr float epsilon() 54 | { 55 | return std::numeric_limits::epsilon(); 56 | } 57 | static constexpr float (min)() 58 | { 59 | return (std::numeric_limits::min)(); 60 | } 61 | }; 62 | 63 | template <> 64 | struct TypeTraits 65 | { 66 | static constexpr double epsilon() 67 | { 68 | return std::numeric_limits::epsilon(); 69 | } 70 | static constexpr double (min)() 71 | { 72 | return (std::numeric_limits::min)(); 73 | } 74 | }; 75 | 76 | template <> 77 | struct TypeTraits 78 | { 79 | static constexpr long double epsilon() 80 | { 81 | return std::numeric_limits::epsilon(); 82 | } 83 | static constexpr long double (min)() 84 | { 85 | return (std::numeric_limits::min)(); 86 | } 87 | }; 88 | 89 | // Get the element type of a "scalar" 90 | // ElemType => double 91 | // ElemType> => double 92 | template 93 | using ElemType = typename Eigen::NumTraits::Real; 94 | 95 | } // namespace Spectra 96 | 97 | /// \endcond 98 | 99 | #endif // SPECTRA_TYPE_TRAITS_H 100 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/Spectra/Util/Version.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020-2022 Yixuan Qiu 2 | // 3 | // This Source Code Form is subject to the terms of the Mozilla 4 | // Public License v. 2.0. If a copy of the MPL was not distributed 5 | // with this file, You can obtain one at https://mozilla.org/MPL/2.0/. 6 | 7 | #ifndef SPECTRA_VERSION_H 8 | #define SPECTRA_VERSION_H 9 | 10 | #define SPECTRA_MAJOR_VERSION 1 11 | #define SPECTRA_MINOR_VERSION 0 12 | #define SPECTRA_PATCH_VERSION 1 13 | 14 | #define SPECTRA_VERSION (SPECTRA_MAJOR_VERSION * 10000 + SPECTRA_MINOR_VERSION * 100 + SPECTRA_PATCH_VERSION) 15 | 16 | #endif // SPECTRA_VERSION_H 17 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/libqhull_r/COPYING.txt: -------------------------------------------------------------------------------- 1 | Qhull, Copyright (c) 1993-2020 2 | 3 | C.B. Barber 4 | Arlington, MA 5 | 6 | and 7 | 8 | The National Science and Technology Research Center for 9 | Computation and Visualization of Geometric Structures 10 | (The Geometry Center) 11 | University of Minnesota 12 | 13 | email: qhull@qhull.org 14 | 15 | This software includes Qhull from C.B. Barber and The Geometry Center. 16 | Files derived from Qhull 1.0 are copyrighted by the Geometry Center. The 17 | remaining files are copyrighted by C.B. Barber. Qhull is free software 18 | and may be obtained via http from www.qhull.org. It may be freely copied, 19 | modified, and redistributed under the following conditions: 20 | 21 | 1. All copyright notices must remain intact in all files. 22 | 23 | 2. A copy of this text file must be distributed along with any copies 24 | of Qhull that you redistribute; this includes copies that you have 25 | modified, or copies of programs or other software products that 26 | include Qhull. 27 | 28 | 3. If you modify Qhull, you must include a notice giving the 29 | name of the person performing the modification, the date of 30 | modification, and the reason for such modification. 31 | 32 | 4. When distributing modified versions of Qhull, or other software 33 | products that include Qhull, you must provide notice that the original 34 | source code may be obtained as noted above. 35 | 36 | 5. There is no warranty or other guarantee of fitness for Qhull, it is 37 | provided solely "as is". Bug reports or fixes may be sent to 38 | qhull_bug@qhull.org; the authors may or may not act on them as 39 | they desire. 40 | -------------------------------------------------------------------------------- /include/cilantro/3rd_party/libqhull_r/random_r.h: -------------------------------------------------------------------------------- 1 | /*
  ---------------------------------
 3 | 
 4 |   random_r.h
 5 |     header file for random and utility routines
 6 | 
 7 |    see qh-geom_r.htm and random_r.c
 8 | 
 9 |    Copyright (c) 1993-2020 The Geometry Center.
10 |    $Id: //main/2019/qhull/src/libqhull_r/random_r.h#3 $$Change: 2953 $
11 |    $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
12 | */
13 | 
14 | #ifndef qhDEFrandom
15 | #define qhDEFrandom 1
16 | 
17 | #include 
18 | 
19 | /*============= prototypes in alphabetical order ======= */
20 | 
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 | 
25 | int     qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
26 | int     qh_argv_to_command_size(int argc, char *argv[]);
27 | int     qh_rand(qhT *qh);
28 | void    qh_srand(qhT *qh, int seed);
29 | realT   qh_randomfactor(qhT *qh, realT scale, realT offset);
30 | void    qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
31 | int     qh_strtol(const char *s, char **endp);
32 | double  qh_strtod(const char *s, char **endp);
33 | 
34 | #ifdef __cplusplus
35 | } /* extern "C" */
36 | #endif
37 | 
38 | #endif /* qhDEFrandom */
39 | 
40 | 
41 | 
42 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/COPYING.txt:
--------------------------------------------------------------------------------
 1 |                     Qhull, Copyright (c) 1993-2020
 2 |                     
 3 |                             C.B. Barber
 4 |                            Arlington, MA 
 5 |                           
 6 |                                and
 7 | 
 8 |        The National Science and Technology Research Center for
 9 |         Computation and Visualization of Geometric Structures
10 |                         (The Geometry Center)
11 |                        University of Minnesota
12 | 
13 |                        email: qhull@qhull.org
14 | 
15 | This software includes Qhull from C.B. Barber and The Geometry Center.  
16 | Files derived from Qhull 1.0 are copyrighted by the Geometry Center.  The
17 | remaining files are copyrighted by C.B. Barber.  Qhull is free software 
18 | and may be obtained via http from www.qhull.org.  It may be freely copied, 
19 | modified, and redistributed under the following conditions:
20 | 
21 | 1. All copyright notices must remain intact in all files.
22 | 
23 | 2. A copy of this text file must be distributed along with any copies 
24 |    of Qhull that you redistribute; this includes copies that you have 
25 |    modified, or copies of programs or other software products that 
26 |    include Qhull.
27 | 
28 | 3. If you modify Qhull, you must include a notice giving the
29 |    name of the person performing the modification, the date of
30 |    modification, and the reason for such modification.
31 | 
32 | 4. When distributing modified versions of Qhull, or other software 
33 |    products that include Qhull, you must provide notice that the original 
34 |    source code may be obtained as noted above.
35 | 
36 | 5. There is no warranty or other guarantee of fitness for Qhull, it is 
37 |    provided solely "as is".  Bug reports or fixes may be sent to 
38 |    qhull_bug@qhull.org; the authors may or may not act on them as 
39 |    they desire.
40 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/QhullError.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullError.h#4 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHULLERROR_H
10 | #define QHULLERROR_H
11 | 
12 | #include 
13 | // No dependencies on libqhull
14 | 
15 | #ifndef QHULL_ASSERT
16 | #define QHULL_ASSERT assert
17 | #include 
18 | #endif
19 | 
20 | namespace orgQhull {
21 | 
22 | #//!\name Defined here
23 |     //! QhullError -- std::exception class for Qhull
24 |     class QhullError;
25 | 
26 | class QhullError : public RoadError {
27 | 
28 | public:
29 | #//!\name Constants
30 |     enum {
31 |         QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
32 |         QHULLlastError= 10081,
33 |         NOthrow= 1 //! For flag to indexOf()
34 |     };
35 | 
36 | #//!\name Constructors
37 |     // default constructors
38 |     QhullError() : RoadError() {}
39 |     QhullError(const QhullError &other) : RoadError(other) {}
40 |     QhullError(int code, const std::string &message) : RoadError(code, message) {}
41 |     QhullError(int code, const char *fmt) : RoadError(code, fmt) {}
42 |     QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {}
43 |     QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {}
44 |     QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {}
45 |     QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {}
46 |     QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {}
47 |     QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {}
48 |     QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {}
49 |     QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {}
50 |     QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
51 |     ~QhullError() throw() {}
52 | 
53 | };//class QhullError
54 | 
55 | 
56 | }//namespace orgQhull
57 | 
58 | #//!\name Global
59 | 
60 | inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
61 | 
62 | #endif // QHULLERROR_H
63 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/QhullPointSet.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullPointSet.h#3 $$Change: 3001 $
 5 | ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHULLPOINTSET_H
10 | #define QHULLPOINTSET_H
11 | 
12 | #include 
13 | #include 
14 | #include 
15 | 
16 | #include 
17 | 
18 | namespace orgQhull {
19 | 
20 | #//!\name Used here
21 |     class Qhull;
22 |     class QhullPoint;
23 | 
24 | #//!\name Defined here
25 |     //! QhullPointSet -- a set of coordinate pointers with input dimension
26 |     //! Includes const_iterator and iterator
27 |     class QhullPointSet;
28 | 
29 |     //! QhullPointSetIterator is a Java-style iterator for QhullPoint in a QhullPointSet
30 |     //! QhullPointSetIterator may be used on temporary results.  It copies the pointers in QhullPointSet
31 |     typedef QhullSetIterator  QhullPointSetIterator;
32 | 
33 | class QhullPointSet : public QhullSet {
34 | 
35 | private:
36 | #//!\name Fields
37 |     // no fields
38 | public:
39 | 
40 | #//!\name Construct
41 |                         QhullPointSet(const Qhull &q, setT *s) : QhullSet(q, s) {}
42 |                         //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
43 |                         QhullPointSet(QhullQh *qqh, setT *s) : QhullSet(qqh, s) {}
44 |                         //Copy constructor copies pointer but not contents.  Needed for return by value and parameter passing.
45 |                         QhullPointSet(const QhullPointSet &other) : QhullSet(other) {}
46 |                         //!Assignment copies pointers but not contents.
47 |     QhullPointSet &     operator=(const QhullPointSet &other) { QhullSet::operator=(other); return *this; }
48 |                         ~QhullPointSet() {}
49 | 
50 |                         //!Default constructor disabled.
51 | private:
52 |                         QhullPointSet();
53 | public:
54 | 
55 | #//!\name IO
56 |     struct PrintIdentifiers{
57 |         const QhullPointSet *point_set;
58 |         const char *    print_message; //!< non-null message
59 |         PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), print_message(message) {}
60 |     };//PrintIdentifiers
61 |     PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
62 | 
63 |     struct PrintPointSet{
64 |         const QhullPointSet *point_set;
65 |         const char *    print_message;  //!< non-null message
66 |         PrintPointSet(const char *message, const QhullPointSet &s) : point_set(&s), print_message(message) {}
67 |     };//PrintPointSet
68 |     PrintPointSet       print(const char *message) const { return PrintPointSet(message, *this); }
69 | 
70 | };//QhullPointSet
71 | 
72 | }//namespace orgQhull
73 | 
74 | #//!\name Global
75 | 
76 | std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintIdentifiers &pr);
77 | std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintPointSet &pr);
78 | 
79 | #endif // QHULLPOINTSET_H
80 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/QhullSets.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullSets.h#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHULLSETS_H
10 | #define QHULLSETS_H
11 | 
12 | #include 
13 | 
14 | namespace orgQhull {
15 | 
16 |     //See: QhullFacetSet.h
17 |     //See: QhullPointSet.h
18 |     //See: QhullVertexSet.h
19 | 
20 |     // Avoid circular references between QhullFacet, QhullRidge, and QhullVertex
21 |     class QhullRidge;
22 |     typedef QhullSet  QhullRidgeSet;
23 |     typedef QhullSetIterator  QhullRidgeSetIterator;
24 | 
25 | }//namespace orgQhull
26 | 
27 | #endif // QHULLSETS_H
28 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/QhullStat.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullStat.h#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHULLSTAT_H
10 | #define QHULLSTAT_H
11 | 
12 | #include 
13 | 
14 | #include 
15 | #include 
16 | 
17 | namespace orgQhull {
18 | 
19 | #//!\name defined here
20 |     //! QhullStat -- Qhull's statistics, qhstatT, as a C++ class
21 |     //! Statistics defined with zzdef_() control Qhull's behavior, summarize its result, and report precision problems.
22 |     class QhullStat;
23 | 
24 | class QhullStat : public qhstatT {
25 | 
26 | private:
27 | #//!\name Fields (empty) -- POD type equivalent to qhstatT.  No data or virtual members
28 | 
29 | public:
30 | #//!\name Constants
31 | 
32 | #//!\name class methods
33 | 
34 | #//!\name constructor, assignment, destructor, invariant
35 |                         QhullStat();
36 |                         ~QhullStat();
37 | 
38 | private:
39 |     //!disable copy constructor and assignment
40 |                         QhullStat(const QhullStat &);
41 |     QhullStat &         operator=(const QhullStat &);
42 | public:
43 | 
44 | #//!\name Access
45 | };//class QhullStat
46 | 
47 | }//namespace orgQhull
48 | 
49 | #endif // QHULLSTAT_H
50 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/QhullVertexSet.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullVertexSet.h#4 $$Change: 3001 $
 5 | ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHULLVERTEXSET_H
10 | #define QHULLVERTEXSET_H
11 | 
12 | #include 
13 | #include 
14 | #include 
15 | 
16 | #include 
17 | 
18 | namespace orgQhull {
19 | 
20 | #//!\name Used here
21 | 
22 | #//!\name Defined here
23 |     //! QhullVertexSet -- a set of QhullVertex, as a C++ class.
24 |     //! See Qhull
25 |     class QhullVertexSet;
26 | 
27 |     //! QhullVertexSetIterator is a Java-style iterator for QhullVertex in a QhullVertexSet
28 |     //! QhullVertexSetIterator may be used on temporary results.  It copies the pointers in QhullVertexSet
29 |     typedef QhullSetIterator QhullVertexSetIterator;
30 | 
31 | class QhullVertexSet : public QhullSet {
32 | 
33 | private:
34 | #//!\name Fields
35 |     bool                qhsettemp_defined;  //! Set was allocated with qh_settemp()
36 | 
37 | public:
38 | #//!\name Constructor
39 |                         QhullVertexSet(const Qhull &q, setT *s) : QhullSet(q, s), qhsettemp_defined(false) {}
40 |                         QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets);
41 |                         //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
42 |                         QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet(qqh, s), qhsettemp_defined(false) {}
43 |                         QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets);
44 |                         //Copy constructor and assignment copies pointer but not contents.  Throws error if qhsettemp_defined.  Needed for return by value.
45 |                         QhullVertexSet(const QhullVertexSet &other);
46 |     QhullVertexSet &    operator=(const QhullVertexSet &other);
47 |                         ~QhullVertexSet();
48 | 
49 | private:                //!Default constructor disabled.  Will implement allocation later
50 |                         QhullVertexSet();
51 | public:
52 | 
53 | #//!\name Destructor
54 |     void                freeQhSetTemp();
55 | 
56 | #//!\name Conversion
57 | #ifndef QHULL_NO_STL
58 |     std::vector toStdVector() const;
59 | #endif //QHULL_NO_STL
60 | #ifdef QHULL_USES_QT
61 |     QList   toQList() const;
62 | #endif //QHULL_USES_QT
63 | 
64 | #//!\name Methods
65 | 
66 | #//!\name IO
67 |     struct PrintVertexSet{
68 |         const QhullVertexSet *vertex_set;
69 |         const char *    print_message;     //!< non-null message
70 | 
71 |                         PrintVertexSet(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
72 |     };//PrintVertexSet
73 |     const PrintVertexSet print(const char *message) const { return PrintVertexSet(message, this); }
74 | 
75 |     struct PrintIdentifiers{
76 |         const QhullVertexSet *vertex_set;
77 |         const char *    print_message;    //!< non-null message
78 |                         PrintIdentifiers(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
79 |     };//PrintIdentifiers
80 |     PrintIdentifiers    printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
81 | 
82 | };//class QhullVertexSet
83 | 
84 | }//namespace orgQhull
85 | 
86 | #//!\name Global
87 | 
88 | std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintVertexSet &pr);
89 | std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintIdentifiers &p);
90 | inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet &vs) { os << vs.print(""); return os; }
91 | 
92 | #endif // QHULLVERTEXSET_H
93 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/RboxPoints.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/RboxPoints.h#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef RBOXPOINTS_H
10 | #define RBOXPOINTS_H
11 | 
12 | #include 
13 | #include 
14 | #include 
15 | 
16 | #include 
17 | #include 
18 | #include 
19 | #include 
20 | #include 
21 | #include 
22 | 
23 | namespace orgQhull {
24 | 
25 | #//!\name Defined here
26 |     //! RboxPoints -- generate random PointCoordinates for Qhull
27 |     class RboxPoints;
28 | 
29 | class RboxPoints : public PointCoordinates {
30 | 
31 | private:
32 | #//!\name Fields and friends
33 |                         //! PointCoordinates.qh() is owned by RboxPoints
34 |     countT              rbox_new_count;     //! Number of points for PointCoordinates
35 |     int                 rbox_status;    //! error status from rboxpoints.  qh_ERRnone if none.
36 |     std::string         rbox_message;   //! stderr from rboxpoints
37 | 
38 |     // '::' is required for friend references
39 |     friend void ::qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
40 | 
41 | public:
42 | #//!\name Construct
43 |                         RboxPoints();
44 |     explicit            RboxPoints(const char *rboxCommand);
45 |                         ~RboxPoints();
46 | private:                // Disable copy constructor and assignment.  RboxPoints owns QhullQh.
47 |                         RboxPoints(const RboxPoints &);
48 |                         RboxPoints &operator=(const RboxPoints &);
49 | private:
50 |     void                allocateQhullQh();
51 | 
52 | public:
53 | #//!\name GetSet
54 |     void                clearRboxMessage();
55 |     countT              newCount() const { return rbox_new_count; }
56 |     std::string         rboxMessage() const;
57 |     int                 rboxStatus() const;
58 |     bool                hasRboxMessage() const;
59 |     void                setNewCount(countT pointCount) { QHULL_ASSERT(pointCount>=0); rbox_new_count= pointCount; }
60 | 
61 | #//!\name Modify
62 |     void                appendPoints(const char* rboxCommand);
63 |     using               PointCoordinates::appendPoints;
64 |     void                reservePoints() { reserveCoordinates((count()+newCount())*dimension()); }
65 | };//class RboxPoints
66 | 
67 | }//namespace orgQhull
68 | 
69 | #endif // RBOXPOINTS_H
70 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/RoadError.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/RoadError.h#7 $$Change: 2959 $
 5 | ** $DateTime: 2020/05/28 22:25:29 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef ROADERROR_H
10 | #define ROADERROR_H
11 | 
12 | #include   /* for QHULL_CRTDBG */
13 | #include 
14 | 
15 | #include 
16 | #include 
17 | #include 
18 | #include 
19 | 
20 | using std::endl;
21 | 
22 | namespace orgQhull {
23 | 
24 | #//!\name Defined here
25 |     //! RoadError -- Report and log errors
26 |     //!  See discussion in Saylan, G., "Practical C++ error handling in hybrid environments," Dr. Dobb's Journal, p. 50-55, March 2007.
27 |     //!   He uses an auto_ptr to track a stringstream.  It constructs a string on the fly.  RoadError uses the copy constructor to transform RoadLogEvent into a string
28 |     class RoadError;
29 | 
30 | class RoadError : public std::exception {
31 | 
32 | private:
33 | #//!\name Fields
34 |     int                 error_code;  //! Non-zero code (not logged), maybe returned as program status
35 |     RoadLogEvent        log_event;   //! Format string w/ arguments
36 |     mutable std::string error_message;  //! Formated error message.  Must be after log_event.
37 | 
38 | #//!\name Class fields
39 |     static const char  *  ROADtag;
40 |     static std::ostringstream  global_log; //!< May be replaced with any ostream object
41 |                                     //!< Not reentrant -- only used by RoadError::logErrorLastResort()
42 | 
43 | public:
44 | #//!\name Constants
45 | 
46 | #//!\name Constructors
47 |     RoadError();
48 |     RoadError(const RoadError &other);  //! Called on throw, generates error_message
49 |     RoadError(int code, const std::string &message);
50 |     RoadError(int code, const char *fmt);
51 |     RoadError(int code, const char *fmt, int d);
52 |     RoadError(int code, const char *fmt, int d, int d2);
53 |     RoadError(int code, const char *fmt, int d, int d2, float f);
54 |     RoadError(int code, const char *fmt, int d, int d2, float f, const char *s);
55 |     RoadError(int code, const char *fmt, int d, int d2, float f, const void *x);
56 |     RoadError(int code, const char *fmt, int d, int d2, float f, int i);
57 |     RoadError(int code, const char *fmt, int d, int d2, float f, long long i);
58 |     RoadError(int code, const char *fmt, int d, int d2, float f, double e);
59 | 
60 |     RoadError &         operator=(const RoadError &other);
61 |                         ~RoadError() throw() {}
62 | 
63 | #//!\name Class methods
64 | 
65 |     static void         clearGlobalLog() { global_log.seekp(0); }
66 |     static bool         emptyGlobalLog() { return global_log.tellp()<=0; }
67 |     static std::string  stringGlobalLog() { return global_log.str(); }
68 | 
69 | #//!\name Virtual
70 |     virtual const char *what() const throw();
71 | 
72 | #//!\name GetSet
73 |     bool                isValid() const { return log_event.isValid(); }
74 |     int                 errorCode() const { return error_code; }
75 |    // QH11021 FIX: should RoadError provide errorMessage().  Currently what()
76 |     RoadLogEvent        roadLogEvent() const { return log_event; }
77 | 
78 | #//!\name Update
79 |     void                logErrorLastResort() const;
80 | };//class RoadError
81 | 
82 | }//namespace orgQhull
83 | 
84 | #//!\name Global
85 | 
86 | inline std::ostream &   operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os << e.what(); }
87 | 
88 | #endif // ROADERROR_H
89 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/RoadLogEvent.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/RoadLogEvent.h#3 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef ROADLOGEVENT_H
10 | #define ROADLOGEVENT_H
11 | 
12 | #include 
13 | #include 
14 | #include 
15 | 
16 | namespace orgQhull {
17 | 
18 | #//!\name Defined here
19 |     //! RoadLogEvent -- Record an event for the RoadLog
20 |     struct RoadLogEvent;
21 | 
22 | struct RoadLogEvent {
23 | 
24 | public:
25 | #//!\name Fields
26 |     const char *    format_string; //! Format string (a literal with format codes, for logging)
27 |     int             int_1;       //! Integer argument (%d, for logging)
28 |     int             int_2;       //! Integer argument (%d, for logging)
29 |     float           float_1;     //! Float argument (%f, for logging)
30 |     union {                      //! One additional argument (for logging)
31 |         const char *cstr_1;      //!   Cstr argument (%s) -- type checked at construct-time
32 |         const void *void_1;      //!   Void* argument (%x) -- Use upper-case codes for object types
33 |         long long   int64_1;     //!   signed int64 (%i).  Ambiguous if unsigned is also defined.
34 |         double      double_1;    //!   Double argument (%e)
35 |     };
36 | 
37 | #//!\name Constants
38 | 
39 | #//!\name Constructors
40 |     RoadLogEvent() : format_string(NULL), int_1(0), int_2(0), float_1(0), int64_1(0) {}
41 |     explicit RoadLogEvent(const char *fmt) : format_string(fmt), int_1(0), int_2(0), float_1(0), int64_1(0) {}
42 |     RoadLogEvent(const char *fmt, int d) : format_string(fmt), int_1(d), int_2(0), float_1(0), int64_1(0) {}
43 |     RoadLogEvent(const char *fmt, int d, int d2) : format_string(fmt), int_1(d), int_2(d2), float_1(0), int64_1(0) {}
44 |     RoadLogEvent(const char *fmt, int d, int d2, float f) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(0) {}
45 |     RoadLogEvent(const char *fmt, int d, int d2, float f, const char *s) : format_string(fmt), int_1(d), int_2(d2), float_1(f), cstr_1(s) {}
46 |     RoadLogEvent(const char *fmt, int d, int d2, float f, const void *x) : format_string(fmt), int_1(d), int_2(d2), float_1(f), void_1(x) {}
47 |     RoadLogEvent(const char *fmt, int d, int d2, float f, int i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {}
48 |     RoadLogEvent(const char *fmt, int d, int d2, float f, long long i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {}
49 |     RoadLogEvent(const char *fmt, int d, int d2, float f, double g) : format_string(fmt), int_1(d), int_2(d2), float_1(f), double_1(g) {}
50 |     ~RoadLogEvent() {}
51 |     //! Default copy constructor and assignment
52 | 
53 | #//!\name GetSet
54 |     bool                isValid() const { return format_string!=NULL; }
55 |     int                 int1() const { return int_1; }
56 |     int                 int2() const { return int_2; }
57 |     float               float1() const { return float_1; }
58 |     const char *        format() const { return format_string; }
59 |     const char *        cstr1() const { return cstr_1; }
60 |     const void *        void1() const { return void_1; }
61 |     long long           int64() const { return int64_1; }
62 |     double              double1() const { return double_1; }
63 | 
64 | #//!\name Conversion
65 | 
66 |     std::string        toString(const char* tag, int code) const;
67 | 
68 | private:
69 | #//!\name Class helpers
70 |     static bool         firstExtraCode(std::ostream &os, char c, char *extraCode);
71 | 
72 | 
73 | };//class RoadLogEvent
74 | 
75 | }//namespace orgQhull
76 | 
77 | #endif // ROADLOGEVENT_H
78 | 


--------------------------------------------------------------------------------
/include/cilantro/3rd_party/libqhullcpp/functionObjects.h:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/functionObjects.h#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #ifndef QHFUNCTIONOBJECTS_H
10 | #define QHFUNCTIONOBJECTS_H
11 | 
12 | #include 
13 | #include 
14 | 
15 | namespace orgQhull {
16 | 
17 | #//!\name Defined here
18 | 
19 |     //! Sum of absolute values of the elements in a container
20 |     class AbsoluteSumOf;
21 |     //! Sum of the elements in a container
22 |     class SumOf;
23 |     //! Sum of squares of the elements in a container
24 |     class SumSquaresOf;
25 | 
26 | #//!\name Class
27 | 
28 | //! Absolute sum of the elements in a container
29 | class AbsoluteSumOf
30 | {
31 | private:
32 |     double sum;
33 | public:
34 |     inline AbsoluteSumOf() : sum(0.0) {}
35 |     inline void operator()(double v) { sum += fabs(v); }
36 |     inline operator double() { return sum; }
37 | };//AbsoluteSumOf
38 | 
39 | //! Sum of the elements in a container
40 | class SumOf
41 | {
42 | private:
43 |     double sum;
44 | public:
45 |     inline SumOf() : sum(0.0) {}
46 |     inline void operator()(double v) { sum += v; }
47 |     inline operator double() { return sum; }
48 | };//SumOf
49 | 
50 | 
51 | //! Sum of squares of the elements in a container
52 | class SumSquaresOf
53 | {
54 | private:
55 |     double sum;
56 | public:
57 |     inline SumSquaresOf() : sum(0.0) {}
58 |     inline void operator()(double v) { sum += v*v; }
59 |     inline operator double() { return sum; }
60 | };//SumSquaresOf
61 | 
62 | 
63 | }//orgQhull
64 | 
65 | 
66 | #endif //QHFUNCTIONOBJECTS_H
67 | 
68 | 


--------------------------------------------------------------------------------
/include/cilantro/cilantro.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | #include 
 6 | #include 
 7 | #include 
 8 | #include 
 9 | #include 
10 | #include 
11 | 


--------------------------------------------------------------------------------
/include/cilantro/clustering.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | #include 
7 | #include 
8 | 


--------------------------------------------------------------------------------
/include/cilantro/core.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | #include 
 6 | #include 
 7 | #include 
 8 | #include 
 9 | #include 
10 | #include 
11 | #include 
12 | #include 
13 | #include 
14 | #include 
15 | #include 
16 | #include 
17 | #include 
18 | #include 
19 | 


--------------------------------------------------------------------------------
/include/cilantro/core/nearest_neighbors.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | 
 6 | namespace cilantro {
 7 | 
 8 | template 
 9 | struct Neighbor {
10 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
11 | 
12 |   typedef ScalarT Scalar;
13 |   typedef IndexT Index;
14 | 
15 |   IndexT index;
16 |   ScalarT value;
17 | 
18 |   inline Neighbor() {}
19 | 
20 |   inline Neighbor(IndexT ind, ScalarT dist) : index(ind), value(dist) {}
21 | 
22 |   template 
23 |   inline operator IndT() const {
24 |     return static_cast(index);
25 |   }
26 | 
27 |   struct IndexLessComparator {
28 |     inline bool operator()(const Neighbor& nn1, const Neighbor& nn2) const {
29 |       return nn1.index < nn2.index;
30 |     }
31 |   };
32 | 
33 |   struct IndexGreaterComparator {
34 |     inline bool operator()(const Neighbor& nn1, const Neighbor& nn2) const {
35 |       return nn1.index > nn2.index;
36 |     }
37 |   };
38 | 
39 |   struct ValueLessComparator {
40 |     inline bool operator()(const Neighbor& nn1, const Neighbor& nn2) const {
41 |       return nn1.value < nn2.value;
42 |     }
43 |   };
44 | 
45 |   struct ValueGreaterComparator {
46 |     inline bool operator()(const Neighbor& nn1, const Neighbor& nn2) const {
47 |       return nn1.value > nn2.value;
48 |     }
49 |   };
50 | };
51 | 
52 | template 
53 | using NeighborSet = std::vector>;
54 | 
55 | template 
56 | using Neighborhood = std::vector>;
57 | 
58 | template 
59 | using NeighborhoodSet = std::vector>;
60 | 
61 | template 
62 | struct KNNNeighborhoodSpecification {
63 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
64 | 
65 |   typedef CountT Size;
66 | 
67 |   inline KNNNeighborhoodSpecification(CountT k = (CountT)0) : maxNumberOfNeighbors(k) {}
68 | 
69 |   CountT maxNumberOfNeighbors;
70 | };
71 | 
72 | template 
73 | struct RadiusNeighborhoodSpecification {
74 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
75 | 
76 |   typedef ScalarT Scalar;
77 | 
78 |   inline RadiusNeighborhoodSpecification(ScalarT r = (ScalarT)0) : radius(r) {}
79 | 
80 |   ScalarT radius;
81 | };
82 | 
83 | template 
84 | struct KNNInRadiusNeighborhoodSpecification {
85 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
86 | 
87 |   typedef ScalarT Scalar;
88 |   typedef CountT Size;
89 | 
90 |   inline KNNInRadiusNeighborhoodSpecification(CountT k = 0, ScalarT r = (ScalarT)0)
91 |       : maxNumberOfNeighbors(k), radius(r) {}
92 | 
93 |   CountT maxNumberOfNeighbors;
94 |   ScalarT radius;
95 | };
96 | 
97 | }  // namespace cilantro
98 | 


--------------------------------------------------------------------------------
/include/cilantro/core/openmp_reductions.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #if defined(__clang__)
 4 | #define STRINGIFY(x) #x
 5 | #define DECLARE_MATRIX_SUM_REDUCTION(Scalar, Rows, Cols) \
 6 |   _Pragma(STRINGIFY(omp declare reduction (+: Eigen::Matrix: omp_out = omp_out + omp_in) initializer(omp_priv = Eigen::Matrix::Zero(omp_orig.rows(), omp_orig.cols()))))
 7 | #define MATRIX_SUM_REDUCTION(Scalar, Rows, Cols, var) reduction(+ : var)
 8 | #elif defined(_MSC_VER)
 9 | // Never lose hope... :)
10 | #define DECLARE_MATRIX_SUM_REDUCTION(Scalar, Rows, Cols) \
11 |   __pragma(omp declare reduction (+: Eigen::Matrix: omp_out = omp_out + omp_in) initializer(omp_priv = Eigen::Matrix::Zero(omp_orig.rows(), omp_orig.cols())))
12 | #define MATRIX_SUM_REDUCTION(Scalar, Rows, Cols, var) reduction(+ : var)
13 | #else
14 | #include 
15 | 
16 | namespace cilantro {
17 | namespace internal {
18 | 
19 | template 
20 | struct MatrixReductions {
21 | #pragma omp declare reduction (+: Eigen::Matrix: omp_out = omp_out + omp_in) initializer(omp_priv = Eigen::Matrix::Zero(omp_orig.rows(), omp_orig.cols()))
22 | };
23 | 
24 | }  // namespace internal
25 | }  // namespace cilantro
26 | 
27 | #define DECLARE_MATRIX_SUM_REDUCTION(Scalar, Rows, Cols)
28 | #define MATRIX_SUM_REDUCTION(Scalar, Rows, Cols, var) \
29 |   reduction(cilantro::internal::MatrixReductions::operator+ : var)
30 | #endif
31 | 


--------------------------------------------------------------------------------
/include/cilantro/core/principal_component_analysis.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | 
 6 | namespace cilantro {
 7 | 
 8 | template 
 9 | class PrincipalComponentAnalysis {
10 | public:
11 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
12 | 
13 |   typedef ScalarT Scalar;
14 | 
15 |   enum { Dimension = EigenDim };
16 | 
17 |   typedef Eigen::Matrix CovarianceMatrix;
18 | 
19 |   template >
20 |   PrincipalComponentAnalysis(const ConstVectorSetMatrixMap& data,
21 |                              bool parallel = false, const CovarianceT& cov_eval = CovarianceT()) {
22 |     cov_eval(data, mean_, covariance_, parallel);
23 |     compute_();
24 |   }
25 | 
26 |   template >
27 |   PrincipalComponentAnalysis(const ConstVectorSetMatrixMap& data,
28 |                              const ContainerT& subset, bool parallel = false,
29 |                              const CovarianceT& cov_eval = CovarianceT()) {
30 |     cov_eval(data, subset.begin(), subset.end(), mean_, covariance_, parallel);
31 |     compute_();
32 |   }
33 | 
34 |   ~PrincipalComponentAnalysis() {}
35 | 
36 |   inline const Vector& getDataMean() const { return mean_; }
37 | 
38 |   inline const Eigen::Matrix& getDataCovariance() const {
39 |     return covariance_;
40 |   }
41 | 
42 |   inline const Vector& getEigenValues() const { return eigenvalues_; }
43 | 
44 |   inline const Eigen::Matrix& getEigenVectors() const {
45 |     return eigenvectors_;
46 |   }
47 | 
48 |   inline Eigen::Matrix project(
49 |       const ConstVectorSetMatrixMap& points, size_t target_dim) const {
50 |     return (eigenvectors_.leftCols(target_dim).transpose() * (points.colwise() - mean_));
51 |   }
52 | 
53 |   template 
54 |   inline
55 |       typename std::enable_if>::type
56 |       project(const ConstVectorSetMatrixMap& points) const {
57 |     return (eigenvectors_.template leftCols().transpose() *
58 |             (points.colwise() - mean_));
59 |   }
60 | 
61 |   inline Eigen::Matrix reconstruct(
62 |       const ConstVectorSetMatrixMap& points) const {
63 |     return (eigenvectors_.leftCols(points.rows()) * points).colwise() + mean_;
64 |   }
65 | 
66 |   template 
67 |   inline typename std::enable_if>::type
68 |   reconstruct(const ConstVectorSetMatrixMap& points) const {
69 |     return (eigenvectors_.template leftCols() * points).colwise() + mean_;
70 |   }
71 | 
72 | protected:
73 |   Vector mean_;
74 |   Eigen::Matrix covariance_;
75 |   Vector eigenvalues_;
76 |   Eigen::Matrix eigenvectors_;
77 | 
78 |   inline void compute_() {
79 |     Eigen::SelfAdjointEigenSolver> eig(covariance_);
80 |     eigenvectors_ = eig.eigenvectors().rowwise().reverse();
81 |     if (eigenvectors_.determinant() < ScalarT(0.0)) {
82 |       auto last_col = eigenvectors_.col(mean_.rows() - 1);
83 |       last_col.noalias() = -last_col;
84 |     }
85 |     eigenvalues_ = eig.eigenvalues().reverse();
86 |   }
87 | };
88 | 
89 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysis2f;
90 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysis2d;
91 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysis3f;
92 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysis3d;
93 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysisXf;
94 | typedef PrincipalComponentAnalysis PrincipalComponentAnalysisXd;
95 | 
96 | }  // namespace cilantro
97 | 


--------------------------------------------------------------------------------
/include/cilantro/core/random.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | 
 6 | namespace cilantro {
 7 | 
 8 | // Copied from https://gist.github.com/cbsmith/5538174
 9 | template 
10 | struct RandomElementSelector {
11 |   typedef RandomGeneratorT RandomGenerator;
12 | 
13 |   // On most platforms, you probably want to use
14 |   // std::random_device("/dev/urandom")()
15 |   inline RandomElementSelector(RandomGenerator g = RandomGenerator(std::random_device{}()))
16 |       : gen_(g) {}
17 | 
18 |   template 
19 |   inline Iter select(Iter start, Iter end) {
20 |     std::uniform_int_distribution dis(0, std::distance(start, end) - 1);
21 |     std::advance(start, dis(gen_));
22 |     return start;
23 |   }
24 | 
25 |   template 
26 |   inline Iter operator()(Iter start, Iter end) {
27 |     return select(start, end);
28 |   }
29 | 
30 |   // Convenience function that works on anything with a sensible begin() and
31 |   // end(), and returns with a ref to the value type
32 |   template 
33 |   inline auto operator()(const Container& c) -> decltype(*begin(c))& {
34 |     return *select(begin(c), end(c));
35 |   }
36 | 
37 | private:
38 |   RandomGenerator gen_;
39 | };
40 | 
41 | }  // namespace cilantro
42 | 


--------------------------------------------------------------------------------
/include/cilantro/core/spectral_embedding_base.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | namespace cilantro {
 6 | 
 7 | // CRTP base class that holds computed embedding and accessors
 8 | template 
 9 | class SpectralEmbeddingBase {
10 | public:
11 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
12 | 
13 |   typedef ScalarT Scalar;
14 | 
15 |   enum { Dimension = EigenDim };
16 | 
17 |   inline const VectorSet& getEmbeddedPoints() const { return embedded_points_; }
18 | 
19 |   inline const Vector& getComputedEigenValues() const {
20 |     return computed_eigenvalues_;
21 |   }
22 | 
23 |   inline size_t getEmbeddingDimension() const { return embedded_points_.rows(); }
24 | 
25 | protected:
26 |   VectorSet embedded_points_;
27 |   Vector computed_eigenvalues_;
28 | };
29 | 
30 | }  // namespace cilantro
31 | 


--------------------------------------------------------------------------------
/include/cilantro/correspondence_search.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | #include 
7 | #include 
8 | 


--------------------------------------------------------------------------------
/include/cilantro/correspondence_search/correspondence_search_oracle.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | 
 6 | namespace cilantro {
 7 | 
 8 | template ,
10 |           typename IndexT = size_t>
11 | class CorrespondenceSearchOracle {
12 | public:
13 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
14 | 
15 |   typedef EvaluatorT Evaluator;
16 | 
17 |   typedef typename EvaluatorT::OutputScalar CorrespondenceScalar;
18 | 
19 |   typedef IndexT CorrespondenceIndex;
20 | 
21 |   typedef CorrespondenceSet SearchResult;
22 | 
23 |   typedef CorrespondenceSet OracleCorrespondences;
24 | 
25 |   CorrespondenceSearchOracle(const OracleCorrespondences& correspondences,
26 |                              EvaluationFeatureAdaptorT& src_eval_features, EvaluatorT& evaluator)
27 |       : oracle_correspondences_(correspondences),
28 |         src_evaluation_features_adaptor_(src_eval_features),
29 |         evaluator_(evaluator),
30 |         max_distance_((CorrespondenceScalar)(0.01 * 0.01)),
31 |         inlier_fraction_(1.0) {}
32 | 
33 |   CorrespondenceSearchOracle& findCorrespondences() {
34 |     SearchResult corr_tmp(oracle_correspondences_.size());
35 | #pragma omp parallel for shared(corr_tmp)
36 |     for (size_t i = 0; i < oracle_correspondences_.size(); i++) {
37 |       corr_tmp[i].indexInFirst = oracle_correspondences_[i].indexInFirst;
38 |       corr_tmp[i].indexInSecond = oracle_correspondences_[i].indexInSecond;
39 |       corr_tmp[i].value =
40 |           evaluator_(oracle_correspondences_[i].indexInFirst,
41 |                      oracle_correspondences_[i].indexInSecond, oracle_correspondences_[i].value);
42 |     }
43 | 
44 |     correspondences_.resize(corr_tmp.size());
45 |     size_t count = 0;
46 |     for (size_t i = 0; i < corr_tmp.size(); i++) {
47 |       if (corr_tmp[i].value < max_distance_) correspondences_[count++] = corr_tmp[i];
48 |     }
49 |     correspondences_.resize(count);
50 | 
51 |     filterCorrespondencesFraction(correspondences_, inlier_fraction_);
52 | 
53 |     return *this;
54 |   }
55 | 
56 |   // Interface for ICP use
57 |   template 
58 |   inline CorrespondenceSearchOracle& findCorrespondences(const TransformT& tform) {
59 |     src_evaluation_features_adaptor_.transformFeatures(tform);
60 |     return findCorrespondences();
61 |   }
62 | 
63 |   inline const OracleCorrespondences& getOracleCorrespondences() const {
64 |     return oracle_correspondences_;
65 |   }
66 | 
67 |   inline const SearchResult& getCorrespondences() const { return correspondences_; }
68 | 
69 |   inline Evaluator& evaluator() { return evaluator_; }
70 | 
71 |   inline CorrespondenceScalar getMaxDistance() const { return max_distance_; }
72 | 
73 |   inline CorrespondenceSearchOracle& setMaxDistance(CorrespondenceScalar dist_thresh) {
74 |     max_distance_ = dist_thresh;
75 |     return *this;
76 |   }
77 | 
78 |   inline double getInlierFraction() const { return inlier_fraction_; }
79 | 
80 |   inline CorrespondenceSearchOracle& setInlierFraction(double fraction) {
81 |     inlier_fraction_ = fraction;
82 |     return *this;
83 |   }
84 | 
85 | private:
86 |   const OracleCorrespondences& oracle_correspondences_;
87 | 
88 |   EvaluationFeatureAdaptorT& src_evaluation_features_adaptor_;
89 |   Evaluator& evaluator_;
90 | 
91 |   CorrespondenceScalar max_distance_;
92 |   double inlier_fraction_;
93 | 
94 |   SearchResult correspondences_;
95 | };
96 | 
97 | }  // namespace cilantro
98 | 


--------------------------------------------------------------------------------
/include/cilantro/model_estimation.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | 


--------------------------------------------------------------------------------
/include/cilantro/registration.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | #include 
 6 | #include 
 7 | #include 
 8 | #include 
 9 | #include 
10 | #include 
11 | #include 
12 | #include 
13 | #include 
14 | 


--------------------------------------------------------------------------------
/include/cilantro/registration/correspondence_search_combined_metric_combiner.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | 
 6 | namespace cilantro {
 7 | 
 8 | template 
 9 | class CorrespondenceSearchCombinedMetricCombiner {
10 | public:
11 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
12 | 
13 |   typedef PointToPointCorrespondenceSearchT PointToPointCorrespondenceSearch;
14 | 
15 |   typedef PointToPlaneCorrespondenceSearchT PointToPlaneCorrespondenceSearch;
16 | 
17 |   typedef typename CorrespondenceSearchCombinedMetricAdaptor::
18 |       PointToPointCorrespondenceScalar PointToPointCorrespondenceScalar;
19 | 
20 |   typedef typename CorrespondenceSearchCombinedMetricAdaptor::
21 |       PointToPointCorrespondenceSearchResult PointToPointCorrespondenceSearchResult;
22 | 
23 |   typedef typename CorrespondenceSearchCombinedMetricAdaptor::
24 |       PointToPlaneCorrespondenceScalar PointToPlaneCorrespondenceScalar;
25 | 
26 |   typedef typename CorrespondenceSearchCombinedMetricAdaptor::
27 |       PointToPlaneCorrespondenceSearchResult PointToPlaneCorrespondenceSearchResult;
28 | 
29 |   inline CorrespondenceSearchCombinedMetricCombiner(
30 |       PointToPointCorrespondenceSearch& point_to_point_corr_search,
31 |       PointToPlaneCorrespondenceSearch& point_to_plane_corr_search)
32 |       : point_to_point_corr_search_(point_to_point_corr_search),
33 |         point_to_plane_corr_search_(point_to_plane_corr_search) {}
34 | 
35 |   inline CorrespondenceSearchCombinedMetricCombiner& findCorrespondences() {
36 |     if (std::is_same::value &&
37 |         &point_to_point_corr_search_ ==
38 |             (PointToPointCorrespondenceSearchT*)(&point_to_plane_corr_search_)) {
39 |       point_to_point_corr_search_.findCorrespondences();
40 |     } else {
41 |       point_to_point_corr_search_.findCorrespondences();
42 |       point_to_plane_corr_search_.findCorrespondences();
43 |     }
44 |     return *this;
45 |   }
46 | 
47 |   template 
48 |   inline CorrespondenceSearchCombinedMetricCombiner& findCorrespondences(const TransformT& tform) {
49 |     if (std::is_same::value &&
50 |         &point_to_point_corr_search_ ==
51 |             (PointToPointCorrespondenceSearchT*)(&point_to_plane_corr_search_)) {
52 |       point_to_point_corr_search_.findCorrespondences(tform);
53 |     } else {
54 |       point_to_point_corr_search_.findCorrespondences(tform);
55 |       point_to_plane_corr_search_.findCorrespondences(tform);
56 |     }
57 |     return *this;
58 |   }
59 | 
60 |   inline const PointToPointCorrespondenceSearchResult& getPointToPointCorrespondences() const {
61 |     return CorrespondenceSearchCombinedMetricAdaptor(
62 |                point_to_point_corr_search_)
63 |         .getPointToPointCorrespondences();
64 |   }
65 | 
66 |   inline const PointToPlaneCorrespondenceSearchResult& getPointToPlaneCorrespondences() const {
67 |     return CorrespondenceSearchCombinedMetricAdaptor(
68 |                point_to_plane_corr_search_)
69 |         .getPointToPlaneCorrespondences();
70 |   }
71 | 
72 |   inline PointToPointCorrespondenceSearch& pointToPointCorrespondenceSearchEngine() {
73 |     return point_to_point_corr_search_;
74 |   }
75 | 
76 |   inline PointToPlaneCorrespondenceSearch& pointToPlaneCorrespondenceSearchEngine() {
77 |     return point_to_plane_corr_search_;
78 |   }
79 | 
80 | private:
81 |   PointToPointCorrespondenceSearch& point_to_point_corr_search_;
82 |   PointToPlaneCorrespondenceSearch& point_to_plane_corr_search_;
83 | };
84 | 
85 | }  // namespace cilantro
86 | 


--------------------------------------------------------------------------------
/include/cilantro/registration/icp_base.hpp:
--------------------------------------------------------------------------------
  1 | #pragma once
  2 | 
  3 | #include 
  4 | 
  5 | namespace cilantro {
  6 | 
  7 | // CRTP base class
  8 | template 
 10 | class IterativeClosestPointBase {
 11 | public:
 12 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
 13 | 
 14 |   typedef TransformT Transform;
 15 | 
 16 |   typedef typename TransformT::Scalar Scalar;
 17 | 
 18 |   typedef typename TransformT::Scalar PointScalar;
 19 | 
 20 |   enum { Dim = Transform::Dim };
 21 | 
 22 |   typedef CorrespondenceSearchEngineT CorrespondenceSearchEngine;
 23 | 
 24 |   typedef ResidualVectorT ResidualVector;
 25 | 
 26 |   IterativeClosestPointBase(CorrespondenceSearchEngine& corr_engine, size_t max_iter = 15,
 27 |                             PointScalar conv_tol = (PointScalar)1e-5)
 28 |       : max_iterations_(max_iter),
 29 |         iterations_(0),
 30 |         convergence_tol_(conv_tol),
 31 |         last_delta_norm_(std::numeric_limits::infinity()),
 32 |         correspondence_search_engine_(corr_engine) {}
 33 | 
 34 |   inline const CorrespondenceSearchEngine& correspondenceSearchEngine() const {
 35 |     return correspondence_search_engine_;
 36 |   }
 37 | 
 38 |   inline CorrespondenceSearchEngine& correspondenceSearchEngine() {
 39 |     return correspondence_search_engine_;
 40 |   }
 41 | 
 42 |   inline size_t getMaxNumberOfIterations() const { return max_iterations_; }
 43 | 
 44 |   inline ICPInstanceT& setMaxNumberOfIterations(size_t max_iter) {
 45 |     max_iterations_ = max_iter;
 46 |     return *static_cast(this);
 47 |   }
 48 | 
 49 |   inline size_t getNumberOfPerformedIterations() const { return iterations_; }
 50 | 
 51 |   inline PointScalar getConvergenceTolerance() const { return convergence_tol_; }
 52 | 
 53 |   inline ICPInstanceT& setConvergenceTolerance(PointScalar conv_tol) {
 54 |     convergence_tol_ = conv_tol;
 55 |     return *static_cast(this);
 56 |   }
 57 | 
 58 |   inline const Transform& getInitialTransform() const { return transform_init_; }
 59 | 
 60 |   inline ICPInstanceT& setInitialTransform(const Transform& tform_init) {
 61 |     transform_init_ = tform_init;
 62 |     return *static_cast(this);
 63 |   }
 64 | 
 65 |   inline Transform& initialTransform() { return transform_init_; }
 66 | 
 67 |   inline PointScalar getLastUpdateNorm() const { return last_delta_norm_; }
 68 | 
 69 |   // Main ICP loop
 70 |   ICPInstanceT& estimate() {
 71 |     ICPInstanceT& icp_instance = *static_cast(this);
 72 | 
 73 |     transform_ = transform_init_;
 74 |     iterations_ = 0;
 75 |     last_delta_norm_ = std::numeric_limits::infinity();
 76 |     icp_instance.initializeComputation();
 77 | 
 78 |     while (iterations_ < max_iterations_) {
 79 |       // Update correspondences_
 80 |       icp_instance.updateCorrespondences();
 81 |       // Update transform_ and last_delta_norm_ based on correspondences_
 82 |       icp_instance.updateEstimate();
 83 | 
 84 |       iterations_++;
 85 |       if (last_delta_norm_ < convergence_tol_) break;
 86 |     }
 87 | 
 88 |     return icp_instance;
 89 |   }
 90 | 
 91 |   inline ICPInstanceT& estimate(size_t max_iter, PointScalar conv_tol) {
 92 |     max_iterations_ = max_iter;
 93 |     convergence_tol_ = conv_tol;
 94 |     return estimate();
 95 |   }
 96 | 
 97 |   inline const Transform& getTransform() const { return transform_; }
 98 | 
 99 |   inline const ICPInstanceT& getTransform(Transform& tform) const {
100 |     tform = transform_;
101 |     return *static_cast(this);
102 |   }
103 | 
104 |   inline ResidualVector getResiduals() {
105 |     return static_cast(this)->computeResiduals();
106 |   }
107 | 
108 |   inline bool hasConverged() const { return last_delta_norm_ < convergence_tol_; }
109 | 
110 | protected:
111 |   size_t max_iterations_;
112 |   size_t iterations_;
113 |   PointScalar convergence_tol_;
114 |   PointScalar last_delta_norm_;
115 | 
116 |   CorrespondenceSearchEngine& correspondence_search_engine_;
117 | 
118 |   Transform transform_init_;
119 |   Transform transform_;
120 | 
121 |   // Default implementation
122 |   inline void initializeComputation() {}
123 | };
124 | 
125 | }  // namespace cilantro
126 | 


--------------------------------------------------------------------------------
/include/cilantro/spatial.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | #include 
7 | 


--------------------------------------------------------------------------------
/include/cilantro/spatial/flat_convex_hull_3d.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | namespace cilantro {
 6 | 
 7 | template 
 8 | class FlatConvexHull3 : public PrincipalComponentAnalysis,
 9 |                         public ConvexHull {
10 | public:
11 |   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
12 | 
13 |   FlatConvexHull3(const ConstVectorSetMatrixMap& points, bool compute_topology = false,
14 |                   bool simplicial_facets = false, double merge_tol = 0.0)
15 |       : PrincipalComponentAnalysis(points),
16 |         ConvexHull(this->template project<2>(points), compute_topology,
17 |                                        simplicial_facets, merge_tol),
18 |         vertices_3d_(this->template reconstruct<2>(this->vertices_)) {}
19 | 
20 |   inline const VectorSet& getVertices3D() const { return vertices_3d_; }
21 | 
22 |   FlatConvexHull3& transform(const Eigen::Ref>& rotation,
23 |                              const Eigen::Ref>& translation) {
24 |     if (this->is_empty_) return *this;
25 | 
26 |     vertices_3d_ = (rotation * vertices_3d_).colwise() + translation;
27 | 
28 |     Eigen::Matrix rec_mat;
29 |     rec_mat.topLeftCorner(3, 2) = this->eigenvectors_.leftCols(2);
30 |     rec_mat.topRightCorner(3, 1) = this->mean_;
31 |     rec_mat.row(3).setZero();
32 |     rec_mat(3, 2) = 1.0;
33 | 
34 |     Eigen::Matrix tform;
35 |     tform.topLeftCorner(3, 3) = rotation;
36 |     tform.topRightCorner(3, 1) = translation;
37 |     tform.row(3).setZero();
38 |     tform(3, 3) = 1.0;
39 | 
40 |     this->eigenvectors_ = rotation * this->eigenvectors_;
41 |     this->mean_ = rotation * this->mean_ + translation;
42 | 
43 |     Eigen::Matrix proj_mat;
44 |     proj_mat.topLeftCorner(2, 3) = this->eigenvectors_.leftCols(2).transpose();
45 |     proj_mat.topRightCorner(2, 1).noalias() =
46 |         -this->eigenvectors_.leftCols(2).transpose() * this->mean_;
47 |     proj_mat.row(2).setZero();
48 |     proj_mat(2, 3) = 1.0;
49 | 
50 |     ConvexHull::transform(proj_mat * tform * rec_mat);
51 | 
52 |     return *this;
53 |   }
54 | 
55 |   inline FlatConvexHull3& transform(
56 |       const Eigen::Ref>& rigid_transform) {
57 |     return transform(rigid_transform.topLeftCorner(3, 3), rigid_transform.topRightCorner(3, 1));
58 |   }
59 | 
60 |   inline FlatConvexHull3& transform(const RigidTransform& rigid_transform) {
61 |     return transform(rigid_transform.linear(), rigid_transform.translation());
62 |   }
63 | 
64 | protected:
65 |   VectorSet vertices_3d_;
66 | };
67 | 
68 | typedef FlatConvexHull3 FlatConvexHull3f;
69 | typedef FlatConvexHull3 FlatConvexHull3d;
70 | 
71 | }  // namespace cilantro
72 | 


--------------------------------------------------------------------------------
/include/cilantro/utilities.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | #include 
7 | #include 
8 | #include 
9 | 


--------------------------------------------------------------------------------
/include/cilantro/utilities/io_utilities.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | #include 
 5 | #include 
 6 | #include 
 7 | 
 8 | namespace cilantro {
 9 | 
10 | template 
11 | bool readEigenMatrixFromFile(const std::string& file_path, Matrix& matrix, bool binary = true) {
12 |   if (binary) {
13 |     std::ifstream in(file_path, std::ifstream::binary);
14 |     if (!in) return false;
15 |     typename Matrix::Index rows = 0, cols = 0;
16 |     if (!in.read((char*)(&rows), sizeof(typename Matrix::Index))) return false;
17 |     if (!in.read((char*)(&cols), sizeof(typename Matrix::Index))) return false;
18 |     matrix.resize(rows, cols);
19 |     return !!in.read((char*)matrix.data(), rows * cols * sizeof(typename Matrix::Scalar));
20 |   } else {
21 |     std::ifstream in(file_path.c_str(), std::ios::in);
22 |     if (!in) return false;
23 | 
24 |     // Read file contents into a vector
25 |     std::string line;
26 |     typename Matrix::Scalar d;
27 |     std::vector v;
28 |     size_t n_rows = 0;
29 |     while (getline(in, line)) {
30 |       n_rows++;
31 |       std::stringstream input_line(line);
32 |       while (!input_line.eof()) {
33 |         input_line >> d;
34 |         v.emplace_back(d);
35 |       }
36 |     }
37 | 
38 |     // Construct matrix
39 |     size_t n_cols = v.size() / n_rows;
40 |     matrix.resize(n_rows, n_cols);
41 |     for (size_t i = 0; i < n_rows; i++) {
42 |       for (size_t j = 0; j < n_cols; j++) {
43 |         matrix(i, j) = v[i * n_cols + j];
44 |       }
45 |     }
46 |     return true;
47 |   }
48 | }
49 | 
50 | template 
51 | bool writeEigenMatrixToFile(const std::string& file_path, const Matrix& matrix,
52 |                             bool binary = true) {
53 |   if (binary) {
54 |     std::ofstream out(file_path, std::ofstream::binary);
55 |     if (!out) return false;
56 |     typename Matrix::Index rows = matrix.rows(), cols = matrix.cols();
57 |     if (!out.write((char*)(&rows), sizeof(typename Matrix::Index))) return false;
58 |     if (!out.write((char*)(&cols), sizeof(typename Matrix::Index))) return false;
59 |     return !!out.write((char*)matrix.data(), rows * cols * sizeof(typename Matrix::Scalar));
60 |   } else {
61 |     std::ofstream out(file_path.c_str(), std::ios::out);
62 |     if (!out) return false;
63 |     return !!(out << matrix << "\n");
64 |   }
65 | }
66 | 
67 | inline bool fileExists(const std::string& file_path) { return std::ifstream(file_path).is_open(); }
68 | 
69 | inline size_t getFileSizeInBytes(const std::string& file_path) {
70 |   if (!fileExists(file_path)) return 0;
71 |   return std::ifstream(file_path, std::ifstream::ate | std::ifstream::binary).tellg();
72 | }
73 | 
74 | inline size_t readRawDataFromFile(const std::string& file_path, void* data_ptr,
75 |                                   size_t num_bytes = 0) {
76 |   size_t num_bytes_to_read = (num_bytes == 0) ? getFileSizeInBytes(file_path) : num_bytes;
77 |   std::ifstream in(file_path, std::ios::in | std::ios::binary);
78 |   if (!in) return 0;
79 |   in.read((char*)data_ptr, num_bytes_to_read);
80 |   return in.gcount();
81 | }
82 | 
83 | inline bool writeRawDataToFile(const std::string& file_path, const void* data_ptr,
84 |                                size_t num_bytes) {
85 |   std::ofstream out(file_path, std::ios::out | std::ios::binary);
86 |   if (!out) return false;
87 |   return !!out.write((char*)data_ptr, num_bytes);
88 | }
89 | 
90 | }  // namespace cilantro
91 | 


--------------------------------------------------------------------------------
/include/cilantro/utilities/timer.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | namespace cilantro {
 6 | 
 7 | class Timer {
 8 | public:
 9 |   inline Timer(bool start = false) {
10 |     if (start) start_time_ = std::chrono::high_resolution_clock::now();
11 |   }
12 | 
13 |   inline Timer& start() {
14 |     start_time_ = std::chrono::high_resolution_clock::now();
15 |     return *this;
16 |   }
17 | 
18 |   inline Timer& stop() {
19 |     stop_time_ = std::chrono::high_resolution_clock::now();
20 |     return *this;
21 |   }
22 | 
23 |   template >
24 |   inline typename DurationT::rep getElapsedTimeSinceStart() const {
25 |     return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() -
26 |                                                  start_time_)
27 |         .count();
28 |   }
29 | 
30 |   template >
31 |   inline typename DurationT::rep getElapsedTime() const {
32 |     return std::chrono::duration_cast(stop_time_ - start_time_).count();
33 |   }
34 | 
35 |   template >
36 |   inline typename DurationT::rep stopAndGetElapsedTime() {
37 |     return stop().template getElapsedTime();
38 |   }
39 | 
40 | private:
41 |   std::chrono::time_point start_time_;
42 |   std::chrono::time_point stop_time_;
43 | };
44 | 
45 | }  // namespace cilantro
46 | 


--------------------------------------------------------------------------------
/include/cilantro/visualization.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #include 
4 | #include 
5 | #include 
6 | #include 
7 | #include 
8 | #include 
9 | 


--------------------------------------------------------------------------------
/include/cilantro/visualization/colormap.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | namespace cilantro {
 6 | 
 7 | enum struct ColormapType { JET, GRAY, BLUE2RED };
 8 | 
 9 | template 
10 | VectorSet colormap(const ConstVectorSetMatrixMap& scalars,
11 |                              const ColormapType& colormap_type = ColormapType::JET,
12 |                              ValueT scalar_min = std::numeric_limits::quiet_NaN(),
13 |                              ValueT scalar_max = std::numeric_limits::quiet_NaN()) {
14 |   ValueT scalar_min_used = scalar_min;
15 |   ValueT scalar_max_used = scalar_max;
16 |   if (!std::isfinite(scalar_min_used)) scalar_min_used = scalars.minCoeff();
17 |   if (!std::isfinite(scalar_max_used)) scalar_max_used = scalars.maxCoeff();
18 |   if (!std::isfinite(scalar_min_used) || !std::isfinite(scalar_max_used)) {
19 |     return VectorSet::Zero(3, scalars.cols());
20 |   }
21 | 
22 |   const ValueT scalar_range =
23 |       (scalar_max_used == scalar_min_used) ? (ValueT)1.0 : (scalar_max_used - scalar_min_used);
24 | 
25 |   VectorSet colors(3, scalars.cols());
26 |   switch (colormap_type) {
27 |   case ColormapType::JET:
28 | #pragma omp parallel for
29 |     for (size_t i = 0; i < scalars.cols(); i++) {
30 |       const float scalar_normalized = (scalars[i] - scalar_min_used) / scalar_range;
31 |       if (scalar_normalized < 0.7f)
32 |         colors(0, i) = std::max(std::min(4.0f * scalar_normalized - 1.5f, 1.0f), 0.0f);
33 |       else
34 |         colors(0, i) = std::max(std::min(-4.0f * scalar_normalized + 4.5f, 1.0f), 0.0f);
35 |       if (scalar_normalized < 0.5f)
36 |         colors(1, i) = std::max(std::min(4.0f * scalar_normalized - 0.5f, 1.0f), 0.0f);
37 |       else
38 |         colors(1, i) = std::max(std::min(-4.0f * scalar_normalized + 3.5f, 1.0f), 0.0f);
39 |       if (scalar_normalized < 0.3f)
40 |         colors(2, i) = std::max(std::min(4.0f * scalar_normalized + 0.5f, 1.0f), 0.0f);
41 |       else
42 |         colors(2, i) = std::max(std::min(-4.0f * scalar_normalized + 2.5f, 1.0f), 0.0f);
43 |     }
44 |     break;
45 |   case ColormapType::GRAY:
46 | #pragma omp parallel for
47 |     for (size_t i = 0; i < scalars.cols(); i++) {
48 |       colors.col(i).setConstant(
49 |           std::max(std::min((scalars[i] - scalar_min_used) / scalar_range, 1.0f), 0.0f));
50 |     }
51 |     break;
52 |   case ColormapType::BLUE2RED:
53 | #pragma omp parallel for
54 |     for (size_t i = 0; i < scalars.cols(); i++) {
55 |       const float scalar_normalized = (scalars[i] - scalar_min_used) / scalar_range;
56 |       if (scalar_normalized < 0.5f) {
57 |         const float val = std::max(std::min(2.0f * scalar_normalized, 1.0f), 0.0f);
58 |         colors(0, i) = val;
59 |         colors(1, i) = val;
60 |         colors(2, i) = 1.0f;
61 |       } else {
62 |         const float val = std::max(std::min(2.0f * (1.0f - scalar_normalized), 1.0f), 0.0f);
63 |         colors(0, i) = 1.0f;
64 |         colors(1, i) = val;
65 |         colors(2, i) = val;
66 |       }
67 |     }
68 |     break;
69 |   }
70 | 
71 |   return colors;
72 | }
73 | 
74 | }  // namespace cilantro
75 | 


--------------------------------------------------------------------------------
/include/cilantro/visualization/image_viewer.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | #ifdef HAVE_PANGOLIN
 6 | #include 
 7 | 
 8 | namespace cilantro {
 9 | 
10 | class ImageViewer {
11 | public:
12 |   inline ImageViewer(const std::string& window_name, const std::string& display_name) {
13 |     init_(window_name, display_name);
14 |   }
15 |   inline ~ImageViewer() { pangolin::BindToContext(window_name_); }
16 | 
17 |   ImageViewer& setImage(void* data, size_t w, size_t h, const std::string& fmt);
18 |   ImageViewer& setImage(const pangolin::Image& img, const std::string& fmt);
19 |   ImageViewer& setImage(const pangolin::TypedImage& img);
20 |   ImageViewer& setImage(const pangolin::GlTexture& texture);
21 | 
22 |   ImageViewer& clear();
23 | 
24 |   ImageViewer& clearRenderArea();
25 |   ImageViewer& render();
26 |   inline ImageViewer& finishFrame() {
27 |     pangolin::BindToContext(window_name_);
28 |     pangolin::FinishFrame();
29 |     return *this;
30 |   }
31 |   inline ImageViewer& spinOnce() {
32 |     clearRenderArea();
33 |     render();
34 |     finishFrame();
35 |     return *this;
36 |   }
37 | 
38 |   inline bool wasStopped() {
39 |     pangolin::BindToContext(window_name_);
40 |     return pangolin::ShouldQuit();
41 |   }
42 | 
43 |   inline const std::string& getWindowName() const { return window_name_; }
44 |   inline pangolin::View* getDisplay() const { return display_; }
45 | 
46 | private:
47 |   std::string window_name_;
48 |   pangolin::View* display_;
49 |   pangolin::GlTexture gl_texture_;
50 |   pangolin::GlPixFormat gl_pix_format_;
51 | 
52 |   void init_(const std::string& window_name, const std::string& display_name);
53 | };
54 | 
55 | }  // namespace cilantro
56 | #endif
57 | 


--------------------------------------------------------------------------------
/include/cilantro/visualization/visualizer_handler.hpp:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include 
 4 | 
 5 | #ifdef HAVE_PANGOLIN
 6 | #include 
 7 | 
 8 | namespace cilantro {
 9 | 
10 | class Visualizer;
11 | 
12 | struct VisualizerHandler : pangolin::Handler {
13 |   friend class Visualizer;
14 | 
15 |   VisualizerHandler(Visualizer* visualizer);
16 | 
17 |   virtual bool ValidWinDepth(pangolin::GLprecision depth);
18 | 
19 |   virtual void PixelUnproject(pangolin::View& view, pangolin::GLprecision winx,
20 |                               pangolin::GLprecision winy, pangolin::GLprecision winz,
21 |                               pangolin::GLprecision Pc[3]);
22 | 
23 |   virtual void GetPosNormal(pangolin::View& view, int x, int y, pangolin::GLprecision p[3],
24 |                             pangolin::GLprecision Pw[3], pangolin::GLprecision Pc[3],
25 |                             pangolin::GLprecision nw[3], pangolin::GLprecision default_z = 1.0);
26 | 
27 |   void Keyboard(pangolin::View&, unsigned char key, int x, int y, bool pressed);
28 | 
29 |   void Mouse(pangolin::View&, pangolin::MouseButton button, int x, int y, bool pressed,
30 |              int button_state);
31 | 
32 |   void MouseMotion(pangolin::View&, int x, int y, int button_state);
33 | 
34 |   void Special(pangolin::View&, pangolin::InputSpecial inType, float x, float y, float p1, float p2,
35 |                float p3, float p4, int button_state);
36 | 
37 |   void SetPerspectiveProjectionMatrix(const pangolin::OpenGlMatrix& mat);
38 | 
39 |   void SetOrthographicProjectionMatrix(pangolin::GLprecision left, pangolin::GLprecision right,
40 |                                        pangolin::GLprecision bottom, pangolin::GLprecision top,
41 |                                        pangolin::GLprecision near, pangolin::GLprecision far);
42 | 
43 |   void EnablePerspectiveProjection();
44 | 
45 |   void EnableOrthographicProjection();
46 | 
47 |   void ToggleProjectionMode();
48 | 
49 | #ifdef USE_EIGEN
50 |   // Return selected point in world coordinates
51 |   inline Eigen::Vector3d Selected_P_w() const {
52 |     return Eigen::Map>(Pw).cast();
53 |   }
54 | #endif
55 | 
56 |   float translationFactor;  // translation factor
57 |   float zoomFraction;       // zoom fraction
58 |   float pointSizeStep;
59 |   float minPointSize;
60 |   float lineWidthStep;
61 |   float minLineWidth;
62 | 
63 | protected:
64 |   Visualizer* visualizer;
65 |   bool ortho;
66 |   float ortho_left;
67 |   float ortho_right;
68 |   float ortho_bottom;
69 |   float ortho_top;
70 |   float ortho_near;
71 |   float ortho_far;
72 |   pangolin::OpenGlMatrix perspective_projection;
73 |   pangolin::OpenGlMatrix default_model_view;
74 |   std::map> key_callback_map;
75 | 
76 |   // pangolin::OpenGlRenderState* cam_state;
77 |   const static int hwin = 8;
78 |   pangolin::AxisDirection enforce_up;
79 |   pangolin::CameraSpec cameraspec;
80 |   pangolin::GLprecision last_z;
81 |   float last_pos[2];
82 |   pangolin::GLprecision rot_center[3];
83 | 
84 |   pangolin::GLprecision p[3];
85 |   pangolin::GLprecision Pw[3];
86 |   pangolin::GLprecision Pc[3];
87 |   pangolin::GLprecision n[3];
88 | };
89 | 
90 | }  // namespace cilantro
91 | #endif
92 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhull_r/COPYING.txt:
--------------------------------------------------------------------------------
 1 |                     Qhull, Copyright (c) 1993-2020
 2 |                     
 3 |                             C.B. Barber
 4 |                            Arlington, MA 
 5 |                           
 6 |                                and
 7 | 
 8 |        The National Science and Technology Research Center for
 9 |         Computation and Visualization of Geometric Structures
10 |                         (The Geometry Center)
11 |                        University of Minnesota
12 | 
13 |                        email: qhull@qhull.org
14 | 
15 | This software includes Qhull from C.B. Barber and The Geometry Center.  
16 | Files derived from Qhull 1.0 are copyrighted by the Geometry Center.  The
17 | remaining files are copyrighted by C.B. Barber.  Qhull is free software 
18 | and may be obtained via http from www.qhull.org.  It may be freely copied, 
19 | modified, and redistributed under the following conditions:
20 | 
21 | 1. All copyright notices must remain intact in all files.
22 | 
23 | 2. A copy of this text file must be distributed along with any copies 
24 |    of Qhull that you redistribute; this includes copies that you have 
25 |    modified, or copies of programs or other software products that 
26 |    include Qhull.
27 | 
28 | 3. If you modify Qhull, you must include a notice giving the
29 |    name of the person performing the modification, the date of
30 |    modification, and the reason for such modification.
31 | 
32 | 4. When distributing modified versions of Qhull, or other software 
33 |    products that include Qhull, you must provide notice that the original 
34 |    source code may be obtained as noted above.
35 | 
36 | 5. There is no warranty or other guarantee of fitness for Qhull, it is 
37 |    provided solely "as is".  Bug reports or fixes may be sent to 
38 |    qhull_bug@qhull.org; the authors may or may not act on them as 
39 |    they desire.
40 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhull_r/usermem_r.c:
--------------------------------------------------------------------------------
 1 | /*
  ---------------------------------
 3 | 
 4 |    usermem_r.c
 5 |    user redefinable functions -- qh_exit, qh_free, and qh_malloc
 6 | 
 7 |    See README.txt.
 8 | 
 9 |    If you redefine one of these functions you must redefine all of them.
10 |    If you recompile and load this file, then usermem.o will not be loaded
11 |    from qhull.a or qhull.lib
12 | 
13 |    See libqhull_r.h for data structures, macros, and user-callable functions.
14 |    See user_r.c for qhull-related, redefinable functions
15 |    see user_r.h for user-definable constants
16 |    See userprintf_r.c for qh_fprintf and userprintf_rbox_r.c for qh_fprintf_rbox
17 | 
18 |    Please report any errors that you fix to qhull@qhull.org
19 | */
20 | 
21 | #include 
22 | 
23 | #include 
24 | #include 
25 | 
26 | /*---------------------------------
28 | 
29 |   qh_exit( exitcode )
30 |     exit program
31 |     the exitcode must be 255 or less.  Zero indicates success.
32 |     Note: Exit status ('$?') in bash reports 256 as 0
33 | 
34 |   notes:
35 |     qh_exit() is called when qh_errexit() and longjmp() are not available.
36 | 
37 |     This is the only use of exit() in Qhull
38 |     To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
39 | */
40 | void qh_exit(int exitcode) {
41 |     exit(exitcode);
42 | } /* exit */
43 | 
44 | /*---------------------------------
46 | 
47 |   qh_fprintf_stderr( msgcode, format, list of args )
48 |     fprintf to stderr with msgcode (non-zero)
49 | 
50 |   notes:
51 |     qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
52 |     if msgcode is a MSG_ERROR (6000), caller should set qh.last_errcode (like qh_fprintf) or variable 'last_errcode'
53 | 
54 |     It is typically followed by qh_errexit().
55 | 
56 |     Redefine this function to avoid using stderr
57 | 
58 |     Use qh_fprintf [userprintf_r.c] for normal printing
59 | */
60 | void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
61 |     va_list args;
62 | 
63 |     va_start(args, fmt);
64 |     if(msgcode)
65 |       fprintf(stderr, "QH%.4d ", msgcode);
66 |     vfprintf(stderr, fmt, args);
67 |     va_end(args);
68 | } /* fprintf_stderr */
69 | 
70 | /*---------------------------------
72 | 
73 |   qh_free(qh, mem )
74 |     free memory
75 | 
76 |   notes:
77 |     same as free()
78 |     No calls to qh_errexit()
79 | */
80 | void qh_free(void *mem) {
81 |     free(mem);
82 | } /* free */
83 | 
84 | /*---------------------------------
86 | 
87 |     qh_malloc( mem )
88 |       allocate memory
89 | 
90 |     notes:
91 |       same as malloc()
92 | */
93 | void *qh_malloc(size_t size) {
94 |     return malloc(size);
95 | } /* malloc */
96 | 
97 | 
98 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhull_r/userprintf_r.c:
--------------------------------------------------------------------------------
 1 | /*
  ---------------------------------
 3 | 
 4 |   userprintf_r.c
 5 |   user redefinable function -- qh_fprintf
 6 | 
 7 |   see README.txt  see COPYING.txt for copyright information.
 8 | 
 9 |   If you recompile and load this file, then userprintf_r.o will not be loaded
10 |   from qhull_r.a or qhull_r.lib
11 | 
12 |   See libqhull_r.h for data structures, macros, and user-callable functions.
13 |   See user_r.c for qhull-related, redefinable functions
14 |   see user_r.h for user-definable constants
15 |   See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
16 |   see Qhull.cpp and RboxPoints.cpp for examples.
17 | 
18 |   qh_printf is a good location for debugging traps, checked on each log line
19 | 
20 |   Please report any errors that you fix to qhull@qhull.org
21 | */
22 | 
23 | #include 
24 | #include  /* for qh.tracefacet */
25 | 
26 | #include 
27 | #include 
28 | #include 
29 | 
30 | /*---------------------------------
32 | 
33 |   qh_fprintf(qh, fp, msgcode, format, list of args )
34 |     print arguments to *fp according to format
35 |     Use qh_fprintf_rbox() for rboxlib_r.c
36 | 
37 |   notes:
38 |     sets qh.last_errcode if msgcode is error 6000..6999
39 |     same as fprintf()
40 |     fgets() is not trapped like fprintf()
41 |     exit qh_fprintf via qh_errexit()
42 |     may be called for errors in qh_initstatistics and qh_meminit
43 | */
44 | 
45 | // void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
46 | //   va_list args;
47 | //   facetT *neighbor, **neighborp;
48 | 
49 | //   if (!fp) {
50 | //     if(!qh){
51 | //       qh_fprintf_stderr(6241, "qhull internal error (userprintf_r.c): fp and qh not defined for qh_fprintf '%s'\n", fmt);
52 | //       qh->last_errcode= 6241;
53 | //       qh_exit(qh_ERRqhull);  /* can not use qh_errexit() */
54 | //     }
55 | //     /* could use qh->qhmem.ferr, but probably better to be cautious */
56 | //     qh_fprintf_stderr(6028, "qhull internal error (userprintf_r.c): fp is 0.  Wrong qh_fprintf was called.\n");
57 | //     qh->last_errcode= 6028;
58 | //     qh_errexit(qh, qh_ERRqhull, NULL, NULL);
59 | //   }
60 | //   if ((qh && qh->ANNOTATEoutput) || msgcode < MSG_TRACE4) {
61 | //     fprintf(fp, "[QH%.4d]", msgcode);
62 | //   }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
63 | //     fprintf(fp, "QH%.4d ", msgcode);
64 | //   }
65 | //   va_start(args, fmt);
66 | //   vfprintf(fp, fmt, args);
67 | //   va_end(args);
68 | 
69 | //   if (qh) {
70 | //     if (msgcode >= MSG_ERROR && msgcode < MSG_WARNING)
71 | //       qh->last_errcode= msgcode;
72 | //     /* Place debugging traps here. Use with trace option 'Tn'
73 | //        Set qh.tracefacet_id, qh.traceridge_id, and/or qh.tracevertex_id in global_r.c
74 | //     */
75 | //     if (False) { /* in production skip test for debugging traps */
76 | //       if (qh->tracefacet && qh->tracefacet->tested) {
77 | //         if (qh_setsize(qh, qh->tracefacet->neighbors) < qh->hull_dim)
78 | //           qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
79 | //         FOREACHneighbor_(qh->tracefacet) {
80 | //           if (neighbor != qh_DUPLICATEridge && neighbor != qh_MERGEridge && neighbor->visible)
81 | //             qh_errexit2(qh, qh_ERRdebug, qh->tracefacet, neighbor);
82 | //         }
83 | //       }
84 | //       if (qh->traceridge && qh->traceridge->top->id == 234342223) {
85 | //         qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
86 | //       }
87 | //       if (qh->tracevertex && qh_setsize(qh, qh->tracevertex->neighbors)>3434334) {
88 | //         qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
89 | //       }
90 | //     }
91 | //     if (qh->FLUSHprint)
92 | //       fflush(fp);
93 | //   }
94 | // } /* qh_fprintf */
95 | 
96 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhull_r/userprintf_rbox_r.c:
--------------------------------------------------------------------------------
 1 | /*
  ---------------------------------
 3 | 
 4 |    userprintf_rbox_r.c
 5 |    user redefinable function -- qh_fprintf_rbox
 6 | 
 7 |    see README.txt  see COPYING.txt for copyright information.
 8 | 
 9 |    If you recompile and load this file, then userprintf_rbox_r.o will not be loaded
10 |    from qhull.a or qhull.lib
11 | 
12 |    See libqhull_r.h for data structures, macros, and user-callable functions.
13 |    See user_r.c for qhull-related, redefinable functions
14 |    see user_r.h for user-definable constants
15 |    See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
16 |    see Qhull.cpp and RboxPoints.cpp for examples.
17 | 
18 |    Please report any errors that you fix to qhull@qhull.org
19 | */
20 | 
21 | #include 
22 | 
23 | #include 
24 | #include 
25 | #include 
26 | 
27 | /*---------------------------------
29 | 
30 |    qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
31 |      print arguments to *fp according to format
32 |      Use qh_fprintf_rbox() for rboxlib_r.c
33 | 
34 |    notes:
35 |      same as fprintf()
36 |      fgets() is not trapped like fprintf()
37 |      exit qh_fprintf_rbox via qh_errexit_rbox()
38 | */
39 | 
40 | // void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
41 | //     va_list args;
42 | 
43 | //     if (!fp) {
44 | //       qh_fprintf_stderr(6231, "qhull internal error (userprintf_rbox_r.c): fp is 0.  Wrong qh_fprintf_rbox called.\n");
45 | //       qh_errexit_rbox(qh, qh_ERRqhull);
46 | //     }
47 | //     if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
48 | //       fprintf(fp, "QH%.4d ", msgcode);
49 | //     va_start(args, fmt);
50 | //     vfprintf(fp, fmt, args);
51 | //     va_end(args);
52 | // } /* qh_fprintf_rbox */
53 | 
54 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhullcpp/COPYING.txt:
--------------------------------------------------------------------------------
 1 |                     Qhull, Copyright (c) 1993-2020
 2 |                     
 3 |                             C.B. Barber
 4 |                            Arlington, MA 
 5 |                           
 6 |                                and
 7 | 
 8 |        The National Science and Technology Research Center for
 9 |         Computation and Visualization of Geometric Structures
10 |                         (The Geometry Center)
11 |                        University of Minnesota
12 | 
13 |                        email: qhull@qhull.org
14 | 
15 | This software includes Qhull from C.B. Barber and The Geometry Center.  
16 | Files derived from Qhull 1.0 are copyrighted by the Geometry Center.  The
17 | remaining files are copyrighted by C.B. Barber.  Qhull is free software 
18 | and may be obtained via http from www.qhull.org.  It may be freely copied, 
19 | modified, and redistributed under the following conditions:
20 | 
21 | 1. All copyright notices must remain intact in all files.
22 | 
23 | 2. A copy of this text file must be distributed along with any copies 
24 |    of Qhull that you redistribute; this includes copies that you have 
25 |    modified, or copies of programs or other software products that 
26 |    include Qhull.
27 | 
28 | 3. If you modify Qhull, you must include a notice giving the
29 |    name of the person performing the modification, the date of
30 |    modification, and the reason for such modification.
31 | 
32 | 4. When distributing modified versions of Qhull, or other software 
33 |    products that include Qhull, you must provide notice that the original 
34 |    source code may be obtained as noted above.
35 | 
36 | 5. There is no warranty or other guarantee of fitness for Qhull, it is 
37 |    provided solely "as is".  Bug reports or fixes may be sent to 
38 |    qhull_bug@qhull.org; the authors may or may not act on them as 
39 |    they desire.
40 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhullcpp/QhullPointSet.cpp:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullPointSet.cpp#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #include 
10 | 
11 | #include 
12 | #include 
13 | 
14 | #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
15 | #endif
16 | 
17 | namespace orgQhull {
18 | 
19 | // Implemented via QhullSet.h
20 | 
21 | }//namespace orgQhull
22 | 
23 | #//!\name Global functions
24 | 
25 | using std::endl;
26 | using std::ostream;
27 | using orgQhull::QhullPoint;
28 | using orgQhull::QhullPointSet;
29 | using orgQhull::QhullPointSetIterator;
30 | 
31 | ostream &
32 | operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
33 | {
34 |     os << pr.print_message;
35 |     const QhullPointSet s= *pr.point_set;
36 |     QhullPointSetIterator i(s);
37 |     while(i.hasNext()){
38 |         if(i.hasPrevious()){
39 |             os << " ";
40 |         }
41 |         const QhullPoint point= i.next();
42 |         countT id= point.id();
43 |         os << "p" << id;
44 | 
45 |     }
46 |     os << endl;
47 |     return os;
48 | }//PrintIdentifiers
49 | 
50 | ostream &
51 | operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
52 | {
53 |     os << pr.print_message;
54 |     const QhullPointSet s= *pr.point_set;
55 |     for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
56 |         const QhullPoint point= *i;
57 |         os << point;
58 |     }
59 |     return os;
60 | }//printPointSet
61 | 
62 | 
63 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhullcpp/QhullSet.cpp:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullSet.cpp#4 $$Change: 3009 $
 5 | ** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #//! QhullSet -- Qhull's set structure, setT, as a C++ class
10 | 
11 | #include 
12 | 
13 | #include 
14 | #include 
15 | 
16 | #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
17 | #endif
18 | 
19 | namespace orgQhull {
20 | 
21 | #//!\name Class objects
22 | 
23 | setT QhullSetBase::
24 | s_empty_set;
25 | 
26 | #//!\name Constructors
27 | 
28 | QhullSetBase::
29 | QhullSetBase(const Qhull &q, setT *s)
30 | : qh_set(s ? s : &s_empty_set)
31 | , qh_qh(q.qh())
32 | {
33 | }
34 | 
35 | #//!\name Class methods
36 | 
37 | // Same code for qh_setsize [qset_r.c] and QhullSetBase::count [static]
38 | countT QhullSetBase::
39 | count(const setT *set)
40 | {
41 |     countT size;
42 |     const setelemT *sizep;
43 | 
44 |     if(!set){
45 |         return(0);
46 |     }
47 |     sizep= SETsizeaddr_(set);
48 |     if((size= sizep->i)){
49 |         size--;
50 |         if(size > set->maxsize){
51 |             // QH11022 FIX: How to add additional output to a error? -- qh_setprint(qhmem.ferr, "set: ", set);
52 |             throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n",
53 |                 size, set->maxsize);
54 |         }
55 |     }else{
56 |         size= set->maxsize;
57 |     }
58 |     return size;
59 | }//count
60 | 
61 | }//namespace orgQhull
62 | 
63 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhullcpp/QhullStat.cpp:
--------------------------------------------------------------------------------
 1 | /****************************************************************************
 2 | **
 3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
 4 | ** $Id: //main/2019/qhull/src/libqhullcpp/QhullStat.cpp#2 $$Change: 2953 $
 5 | ** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
 6 | **
 7 | ****************************************************************************/
 8 | 
 9 | #//! QhullStat -- Qhull's global data structure, statT, as a C++ class
10 | 
11 | #include 
12 | 
13 | #include 
14 | 
15 | #include 
16 | #include 
17 | 
18 | using std::cerr;
19 | using std::string;
20 | using std::vector;
21 | using std::ostream;
22 | 
23 | #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
24 | #endif
25 | 
26 | namespace orgQhull {
27 | 
28 | #//!\name Constructor, destructor, etc.
29 | 
30 | //! If qh_QHpointer==0, invoke with placement new on qh_stat;
31 | QhullStat::
32 | QhullStat()
33 | {
34 | }//QhullStat
35 | 
36 | QhullStat::
37 | ~QhullStat()
38 | {
39 | }//~QhullStat
40 | 
41 | }//namespace orgQhull
42 | 
43 | 


--------------------------------------------------------------------------------
/src/3rd_party/libqhullcpp/RoadLogEvent.cpp:
--------------------------------------------------------------------------------
  1 | /****************************************************************************
  2 | **
  3 | ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
  4 | ** $Id: //main/2019/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 2961 $
  5 | ** $Date: 2020/06/01 $$Author: bbarber $
  6 | **
  7 | ****************************************************************************/
  8 | 
  9 | #//! RoadLogEvent -- All exceptions thrown by Qhull are RoadErrors
 10 | 
 11 | #include 
 12 | 
 13 | #include 
 14 | #include 
 15 | #include 
 16 | #include 
 17 | 
 18 | using std::cout;
 19 | using std::endl;
 20 | using std::ostringstream;
 21 | using std::string;
 22 | 
 23 | #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
 24 | #endif
 25 | 
 26 | namespace orgQhull{
 27 | 
 28 | #//!\name Conversion
 29 | string RoadLogEvent::
 30 | toString(const char *tag, int code) const
 31 | {
 32 |     ostringstream os;
 33 |     size_t n= 0;
 34 |     if(tag && code){
 35 |         n= strlen(tag);
 36 |         if(format_string && strlen(format_string)>n+1 && isdigit(format_string[n+1]) && (strncmp(format_string, tag, n)==0 || strncmp(format_string+1, tag, n) == 0)){
 37 |             // format_string already starts with tag and a code, e.g., QH6024 qhull input error, or [QH1049] qh_addpoint...
 38 |         }else{
 39 |             os << tag << code;
 40 |             if(format_string && *format_string!='\0'){
 41 |                 os << " ";
 42 |             }
 43 |         }
 44 |     }
 45 |     if(format_string==NULL || *format_string=='\0'){
 46 |         return os.str();
 47 |     }
 48 |     const char *s= format_string;
 49 |     int dCount= 0;  // Count of %d
 50 |     int fCount= 0;  // Count of %f
 51 |     char extraCode= '\0';
 52 |     while(*s){
 53 |         if(*s!='%'){
 54 |             os << *s++;
 55 |         }else{
 56 |             char c= *++s;
 57 |             s++;
 58 |             switch(c){
 59 |             case 'd':
 60 |                 if(++dCount>2){
 61 |                     os << " ERROR_three_%d_in_format ";
 62 |                 }else if(dCount==2){
 63 |                     os << int_2;
 64 |                 }else{
 65 |                     os << int_1;
 66 |                 }
 67 |                 break;
 68 |             case 'e':
 69 |                 if(firstExtraCode(os, c, &extraCode)){
 70 |                     os << double_1;
 71 |                 }
 72 |                 break;
 73 |             case 'f':
 74 |                 if(++fCount>1){
 75 |                     os << " ERROR_two_%f_in_format ";
 76 |                 }else{
 77 |                     os << float_1;
 78 |                 }
 79 |                 break;
 80 |             case 'i':
 81 |                 if(firstExtraCode(os, c, &extraCode)){
 82 |                     os << int64_1;
 83 |                 }
 84 |                 break;
 85 |             case 's':
 86 |                 if(firstExtraCode(os, c, &extraCode)){
 87 |                     os << cstr_1;
 88 |                 }
 89 |                 break;
 90 |             case 'u':
 91 |                 if(firstExtraCode(os, c, &extraCode)){
 92 |                     os << "0x" << std::hex << int64_1 << std::dec;
 93 |                 }
 94 |                 break;
 95 |             case 'x':
 96 |                 if(firstExtraCode(os, c, &extraCode)){
 97 |                     os << void_1;
 98 |                 }
 99 |                 break;
100 |             case '%':
101 |                 os << c;
102 |                 break;
103 |             default:
104 |                 os << " ERROR_%" << c << "_not_defined_in_format";
105 |                 break;
106 |             }
107 |         }
108 |     }
109 |     if(s[-1]!='\n'){
110 |         os << endl;
111 |     }
112 |     return os.str();
113 | }//toString
114 | 
115 | #//!\name Class helpers (static)
116 | 
117 | //! True if this char is the first extra code
118 | bool RoadLogEvent::
119 | firstExtraCode(std::ostream &os, char c, char *extraCode){
120 |     if(*extraCode){
121 |         os << " ERROR_%" << *extraCode << "_and_%" << c << "_in_format ";
122 |         return false;
123 |     }
124 |     *extraCode= c;
125 |     return true;
126 | }//firstExtraCode
127 | 
128 | }//namespace orgQhull
129 | 
130 | 


--------------------------------------------------------------------------------
/src/3rd_party/tinyply/tinyply.cpp:
--------------------------------------------------------------------------------
1 | // This file exists to create a nice static or shared library via cmake
2 | // but can otherwise be omitted if you prefer to compile tinyply
3 | // directly into your own project.
4 | #define TINYPLY_IMPLEMENTATION
5 | #include 
6 | 


--------------------------------------------------------------------------------
/src/visualization/image_viewer.cpp:
--------------------------------------------------------------------------------
 1 | #include 
 2 | 
 3 | #ifdef HAVE_PANGOLIN
 4 | namespace cilantro {
 5 | 
 6 | ImageViewer& ImageViewer::setImage(void* data, size_t w, size_t h, const std::string& fmt) {
 7 |   pangolin::BindToContext(window_name_);
 8 |   gl_pix_format_ = pangolin::GlPixFormat(pangolin::PixelFormatFromString(fmt));
 9 | 
10 |   // Initialise if it didn't already exist or the size was too small
11 |   if (!gl_texture_.tid || gl_texture_.width != (int)w || gl_texture_.height != (int)h ||
12 |       gl_texture_.internal_format != gl_pix_format_.scalable_internal_format) {
13 |     display_->SetAspect((float)w / (float)h);
14 |     gl_texture_.Reinitialise(w, h, gl_pix_format_.scalable_internal_format, true, 0,
15 |                              gl_pix_format_.glformat, gl_pix_format_.gltype, data);
16 |   } else {
17 |     gl_texture_.Upload(data, gl_pix_format_.glformat, gl_pix_format_.gltype);
18 |   }
19 | 
20 |   return *this;
21 | }
22 | 
23 | ImageViewer& ImageViewer::setImage(const pangolin::Image& img,
24 |                                    const std::string& fmt) {
25 |   return setImage(img.ptr, img.w, img.h, fmt);
26 | }
27 | 
28 | ImageViewer& ImageViewer::setImage(const pangolin::TypedImage& img) {
29 |   return setImage(img.ptr, img.w, img.h, img.fmt.format);
30 | }
31 | 
32 | ImageViewer& ImageViewer::setImage(const pangolin::GlTexture& texture) {
33 |   pangolin::BindToContext(window_name_);
34 |   // Initialise if it didn't already exist or the size was too small
35 |   if (!gl_texture_.tid || gl_texture_.width != texture.width ||
36 |       gl_texture_.height != texture.height ||
37 |       gl_texture_.internal_format != texture.internal_format) {
38 |     display_->SetAspect((float)texture.width / (float)texture.height);
39 |     gl_texture_.Reinitialise(texture.width, texture.height, texture.internal_format, true);
40 |   }
41 |   glCopyImageSubData(texture.tid, GL_TEXTURE_2D, 0, 0, 0, 0, gl_texture_.tid, GL_TEXTURE_2D, 0, 0,
42 |                      0, 0, gl_texture_.width, gl_texture_.height, 1);
43 | 
44 |   return *this;
45 | }
46 | 
47 | ImageViewer& ImageViewer::clear() {
48 |   pangolin::BindToContext(window_name_);
49 |   gl_texture_.Delete();
50 |   return *this;
51 | }
52 | 
53 | ImageViewer& ImageViewer::clearRenderArea() {
54 |   pangolin::BindToContext(window_name_);
55 |   display_->Activate();
56 |   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
57 |   return *this;
58 | }
59 | 
60 | ImageViewer& ImageViewer::render() {
61 |   pangolin::BindToContext(window_name_);
62 |   display_->Activate();
63 |   glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
64 |   gl_texture_.RenderToViewportFlipY();
65 |   return *this;
66 | }
67 | 
68 | void ImageViewer::init_(const std::string& window_name, const std::string& display_name) {
69 |   window_name_ = window_name;
70 |   pangolin::BindToContext(window_name_);
71 |   pangolin::RegisterKeyPressCallback('q', pangolin::Quit);
72 |   pangolin::RegisterKeyPressCallback('Q', pangolin::Quit);
73 |   display_ = &(pangolin::Display(display_name));
74 | }
75 | 
76 | }  // namespace cilantro
77 | #endif
78 | 


--------------------------------------------------------------------------------
/src/visualization/renderable.cpp:
--------------------------------------------------------------------------------
1 | #include 
2 | 
3 | namespace cilantro {
4 | 
5 | Eigen::Vector3f RenderingProperties::defaultColor = Eigen::Vector3f(1.0f, 1.0f, 1.0f);
6 | Eigen::Vector3f RenderingProperties::noColor = Eigen::Vector3f(-1.0f, -1.0f, -1.0f);
7 | 
8 | }  // namespace cilantro
9 | 


--------------------------------------------------------------------------------