namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_Kinetic_Surface_Reconstruction
\cgalAutoToc

\authors Sven Oesau and Florent Lafarge

\section ksrIntroduction Introduction
Reconstruction of man-made objects from point clouds pose a challenge to traditional surface reconstruction methods that often produce a smooth surface, e.g., by meshing a fitted implicit function, see \ref Chapter_Poisson_Surface_Reconstruction "Poisson Surface Reconstruction", or by interpolation, see \ref Chapter_Advancing_Front_Surface_Reconstruction "Advancing Front Surface Reconstruction" and \ref Chapter_Scale_space_reconstruction "Scale Space Surface Reconstruction".
The kinetic surface reconstruction package implements the pipeline proposed by Bauchet et. al \cgalCite{bauchet2020kinetic}. At the core is the \ref PkgKineticSpacePartition "Kinetic space partition" which efficiently decomposes the bounding box into a set of convex polyhedra. The decomposition is guided by a set of planar shapes which are aforehand abstracted from an input point cloud. The final surface is obtained via an energy formulation trading data faithfulness for low complexity which is solved via min-cut.  The output is a polygonal watertight mesh.

The method overcomes the major limitation of similar approaches which decompose the bounding box using planar shapes. By partitioning the space into fewer cells using the kinetic approach and aforehand splitting of input data via an adaptive octree the method beats the common full decomposition of the bounding box which has a complexity of \cgalBigO{n^3}. This allows for effective handling of large scenes. At the same time the kinetic approach of decomposing the bounding box limits the number of tiny cells in the partition. Tiny cells are often responsible for small artifacts and at the same time increase the memory requirements and running time.

\section ksrAlgorithm Algorithm
The method takes as input a point cloud with oriented normals, see \cgalFigureRef{Ksr_pipelinefig}. In a first step, \ref PkgShapeDetection "Shape Detection" is used to abstract planar shapes from the point cloud. The optional regularization of shapes, see \ref PkgShapeRegularization "Shape regularization", can not just improve the accuracy of the data by aligning parallel, coplanar and orthogonal shapes, but provides in the same time a reduction in complexity.
Before inserting the planar shapes into the kinetic space partition, coplanar shapes are merged into a single shape and the 2d convex hull of each shape is constructed.
The reconstruction is posed as an energy minimization labeling the convex volumes of the kinetic space partition as inside or outside. The optimal surface separating the differently labeled volumes is found via min-cut. A graph is embedded into the kinetic partition representing every volume by a vertex and every face between to volumes by an edge connecting the corresponding vertices.
<center>
<table class="center-table" border="0">
<tr><td>
\f$\operatorname*{arg\,min}\limits_{l \in {\{0, 1\}}^n} E(l) = (1 - \lambda) D(l) + \lambda U(l)\f$

\f$D(l) = \sum\limits_{i \in C}\sum\limits_{p \in I_i}d_i(p, l_i)\f$

\f$U(l) = \frac{I}{A}\sum\limits_{i\mathtt{\sim} j}a_{ij} \cdot (1-\delta_{l_i,l_j})\f$
    </td>
    <td>The energy function trads data term for regularization term via parameter \f$\lambda\f$

    The data term counts votes from the points \f$p \in I_i\f$ based on their associated normal pointing towards or away from each volume \f$i \in C\f$.

    The regularization term penalizes the total surface area and thus favors surfaces with low complexity.
    </td>
  </tr>
</table>
</center>

The labels \f$l \in {\{0, 1\}}^n\f$ denote the label for the \f$n\f$ volumes of the kinetic space partition. The data term measures the coherence of the labeled volumes with the orientation of normals of the input points. The preferred label for a volume is determined by a voting of the input points and their associated normals.
For each volume \f$i \in C\f$ the inliers from the shape detection associated with the faces of the volume \f$I_i\f$ either vote inside or outside for the volume. The vote is inside \f$d_i(p, inside) = 1\f$ and \f$d_i(p, outside = 0)\f$ if the normal associated to the point is directed to the outwards of the volume or outside \f$d_i(p, inside) = 0\f$ and \f$d_i(p, outside = 1)\f$ if the normal is oriented inwards.
The regularization term is penalizing the total surface area of the surface and thus favoring less complex surfaces. To put the data term and regularization term into balance, area of each face is normalized by the total area of all faces \f$A\f$ and scaled by twice the total number of inliners \f$I\f$ from the shape detection as each inlier counts as one *inside* and one *outside* vote.

Thus the reconstruction is guaranteed to be watertight as it equals a union of volumes. However, the reconstruction may consist of several components and is not guaranteed to be 2-manifold as different components may share a vertex or an edge.

\cgalFigureAnchor{Ksr_pipelinefig}
<center>
<img src="ksr_pipeline_small.png" style="max-width:80%;"/>
</center>
\cgalFigureCaptionBegin{Ksr_pipelinefig}
Kinetic surface reconstruction pipeline.\n From left to right: 1. input point cloud with 382k points 2. 98 detected planar shapes 3. 63 regularized convex shapes 4. kinetic space partition with 1,487 cells 5. reconstructed polygonal mesh with 131 faces.
\cgalFigureCaptionEnd

\section ksrParameters Parameters
The parameters of the method include the parameters from other packages which are used internally:
- \ref Shape_detection_RegionGrowingPoints_parameters "Shape detection": *k_neighbors*, *maximum_distance*, *maximum_angle* and *minimum_region_size*
- \ref CGAL::Shape_regularization::Planes::regularize_planes "Shape Regularization": *maximum_offset*, *angle_tolerance*, *regularize_parallelism*, *regularize_coplanarity*, *regularize_orthogonality*, *regularize_axis_symmetry* and *symmetry_direction*
 - *angle_tolerance* is replacing *maximum_angle* from Shape regularization due to a name collision with Shape detection
- \ref Ksp_parameters "Kinetic space partition": *k*, *reorient_bbox* and *bbox_dilation_ratio*

The reconstruction adds two new parameters:
- *external_nodes*:
The min-cut formulation embeds a vertex into each volume and connects all vertices if the corresponding volumes share a common face. While each face inside the kinetic space partition is exactly between two volumes, faces on the boundary do not. Thus, 6 external vertices are inserted into the graph representing a volume on each side of the bounding box. The parameter *external_nodes* allows the user to either provide a fixed label *inside* or *outside* for each node or leave the label up to the energy minimization. Typical choices for this parameter are to choose all external nodes as outside for scanned objects, e.g., as in \cgalFigureRef{Ksr_pipelinefig}, or the *ZMIN* node *inside* and all other nodes *outside* as for exterior scans of buildings, e.g., as in \cgalFigureRef{Ksr_parametersfig}. The default value for this parameter is to leave the labels of the external nodes up to the energy minimization. The alternative method `reconstruct_with_ground` estimates a ground plane within the detected shapes and sets up all faces on the bounding box below that ground plane to be connected to an external node set as *inside* while all other faces on the outside are connected to external nodes set to *outside*. It assumes the z-axis to be the upward pointing vertical direction.

- *lambda*:
The *lambda* parameter trades the data faithfulness of the energy minimization for low complexity. The parameter has to be chosen in the range of \f$[0,1)\f$. \f$0\f$ indicates maximal data faithfulness, while the default value of \f$0.5\f$ gives an equal weight to data faithfulness and low complexity. The value should be chosen according to the quality of the input data. If the point cloud is accurate, low in noise and complete a low value can be chosen.

\section ksrParameterChoice Choice of Parameters
The kinetic space partition determines all possible reconstructions as the energy formulation only decides about the labels for the volumes, but cannot change the volumes themselves. Thus, the first stages of the pipeline, \ref PkgShapeDetection "Shape Detection" and \ref PkgShapeRegularization "Shape Regularization", have a large impact on the final reconstruction. In the simple case of a cube, one missing side would depending on the chosen *lambda* parameter either make the cube expand on that side towards the bounding box or make the full cube disappear. A proper parameterization of the \ref PkgShapeDetection "Shape Detection" to detect all relevant shapes may have a large impact. The *debug* parameter allows to export intermediate results for inspection. This is especially helpful for larger scenes, where the time for the whole reconstruction requires more computational effort.

However, in many cases a point cloud may be incomplete and not cover all shapes. The method offers two parameters to handle missing data. The *k* parameter of the kinetic space partition can extend the convex polygons further in the partition and thus may make up for missing shapes.  The *external_nodes* parameter allows to preset an *inside* or *outside* label for bounding box sides. This is especially helpful for scanned buildings, where no points have been collect on the bottom side of the building, partial scans or scans where the orientation is inverted, e.g., inside an apartment.

The *lambda* parameter allows to trade data faithfulness for low complexity. The best choice depends on the individual point cloud and the sampled object. \cgalFigureRef{Ksr_parametersfig} shows the lower complexity of the reconstruction with a higher *lambda* value.
However, the actual reconstruction using min-cut only makes up a small fraction from the whole pipeline. Performing several reconstructions with different values of *lambda* is a reasonal approach, see \ref ksrParametersExample.

\cgalFigureAnchor{Ksr_parametersfig}
<center>
<img src="ksr_parameters_gray_small.png" style="max-width:80%;"/>
</center>
\cgalFigureCaptionBegin{Ksr_parametersfig}
Impact of parameters on the reconstruction of the rotated lans model.\n From left to right: 1. & 2. Reconstruction with using \f$\lambda = 0.7\f$ and \f$\lambda = 0.8\f$. A higher value of lambda removes some details on the roof as well as the chimney. As no planar shape was detected at the top of the chimney, the kinetic space partition does not offer a volume that well covers the point cloud. The volume of the chimney is either too large for \f$\lambda = 0.7\f$ or gets cut completely for \f$\lambda = 0.8\f$ 3. Reconstruction of the model without reorienting the bbox. For the reconstruction to succeed it is necessary to set the external_node for *ZMIN* to *inside* as the point cloud does not close the church from below. 4. Reconstruction as in 3., but without setting external_node for *ZMIN*.
\cgalFigureCaptionEnd

\section ksrExamples Examples

\subsection ksrBasicExample Basic Example
This minimal example shows the import of a simple synthetic point cloud and an reconstruction using mostly default parameters.

\cgalExample{Kinetic_surface_reconstruction/ksr_basic.cpp}

\subsection ksrBuildingExample Building Example
This example shows the import of an acquired point cloud of a building and a reconstruction using a common choice of parameters for building reconstruction. The input point cloud is reoriented to be axis-aligned and regularization is used to simplify the detected shapes before reconstruction.
The actual reconstruction method is actually fast. To avoid running the full shape detection and kinetic partition just to try different values for beta, several reconstructions are performed and exported into ply format.

\cgalExample{Kinetic_surface_reconstruction/ksr_building.cpp}

\subsection ksrParametersExample Parameters Example
This example provides a command line version of the kinetic surface reconstruction allowing to configure the input point cloud filename and most parameters.

\cgalExample{Kinetic_surface_reconstruction/ksr_parameters.cpp}

\section ksrPerformance Performance

Kinetic surface reconstruction is aimed at reconstructing piece-wise planar objects, e.g., man-made objects and architecture. Reconstruction results on point clouds acquired from architecture in different qualities are shown in figure \cgalFigureRef{ksr_result_small} in the first and last row. Synthetic point clouds from a CAD model and a fractal object are shown in rows 2 and three. The datasets used here are available at https://files.inria.fr/titane/KSR42_dataset.zip.

However, also smooth surfaces can be reconstructed to a certain level of detail as is shown on the fourth row. While the scales of the dragon are not replicated with their smooth boundary, each scale can still be recognized in the final model.

\cgalFigureAnchor{ksr_result_small}
<center>
<img src="ksr_result_small.jpg" style="max-width:90%;"/>
</center>
\cgalFigureCaptionBegin{ksr_result_small}
Results of kinetic surface reconstruction.\n From left to right: 1. input point cloud 2. reconstructed polygon mesh 3. overlay of input and result 4. detail view.\n
From top to bottom: 1. *Meeting room*. Reconstruction of the roof framework is not perfect due to missing data. 2. *Full Thing*. Synthetic point cloud sampled from a CAD model. All details are well reconstructed 3. *Hilbert cube*. Synthetic point cloud from a fractal object. 4. *Asian Dragon*. Acquired point cloud from the Stanford 3D Scanning Repository. 5. *Building_C*. Point Cloud from multi view stereo.
\cgalFigureCaptionEnd

The running time of the method depends mostly on the shape detection and the kinetic space partition steps. While running time of the shape detection scales with the complexity of the point cloud, the kinetic space partition depends on the number of input polygons. The running time of the shape regularization and the min-cut have not been listed, as they are <1 seconds in all cases besides the Asian Dragon with 2,75s for the min-cut.

<TABLE CELLSPACING=5 >
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
<TR>
<TD class="math" ALIGN=CENTER NOWRAP>
Data set
<TD class="math" ALIGN=CENTER NOWRAP>
Points
<TD class="math" ALIGN=CENTER NOWRAP>
Detected shapes
<TD class="math" ALIGN=CENTER NOWRAP>
Regularized shapes
<TD class="math" ALIGN=CENTER NOWRAP>
Volumes in partition
<TD class="math" ALIGN=CENTER NOWRAP>
Polygons in reconstruction
<TD class="math" ALIGN=CENTER NOWRAP>
Vertices in reconstruction
<TD class="math" ALIGN=CENTER NOWRAP>
Shape Detection
<TD class="math" ALIGN=CENTER NOWRAP>
Kinetic Space Partition
<TD class="math" ALIGN=CENTER NOWRAP>
Total Time
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Foam_box
<TD class="math" ALIGN=RIGHT NOWRAP>
382.059
<TD class="math" ALIGN=RIGHT NOWRAP>
103
<TD class="math" ALIGN=RIGHT NOWRAP>
60
<TD class="math" ALIGN=RIGHT NOWRAP>
998
<TD class="math" ALIGN=RIGHT NOWRAP>
97
<TD class="math" ALIGN=RIGHT NOWRAP>
444
<TD class="math" ALIGN=RIGHT NOWRAP>
6.4
<TD class="math" ALIGN=RIGHT NOWRAP>
3.4
<TD class="math" ALIGN=RIGHT NOWRAP>
9.9
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Lans
<TD class="math" ALIGN=RIGHT NOWRAP>
1.220.459
<TD class="math" ALIGN=RIGHT NOWRAP>
324
<TD class="math" ALIGN=RIGHT NOWRAP>
169
<TD class="math" ALIGN=RIGHT NOWRAP>
3.338
<TD class="math" ALIGN=RIGHT NOWRAP>
330
<TD class="math" ALIGN=RIGHT NOWRAP>
1.175
<TD class="math" ALIGN=RIGHT NOWRAP>
27,2
<TD class="math" ALIGN=RIGHT NOWRAP>
11,1
<TD class="math" ALIGN=RIGHT NOWRAP>
38,4
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Meeting Room
<TD class="math" ALIGN=RIGHT NOWRAP>
3.074.625
<TD class="math" ALIGN=RIGHT NOWRAP>
1.652
<TD class="math" ALIGN=RIGHT NOWRAP>
777
<TD class="math" ALIGN=RIGHT NOWRAP>
29.737
<TD class="math" ALIGN=RIGHT NOWRAP>
2.876
<TD class="math" ALIGN=RIGHT NOWRAP>
11.839
<TD class="math" ALIGN=RIGHT NOWRAP>
41,4
<TD class="math" ALIGN=RIGHT NOWRAP>
100,7
<TD class="math" ALIGN=RIGHT NOWRAP>
142,1
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Full Thing
<TD class="math" ALIGN=RIGHT NOWRAP>
1.377.666
<TD class="math" ALIGN=RIGHT NOWRAP>
1.947
<TD class="math" ALIGN=RIGHT NOWRAP>
1.790
<TD class="math" ALIGN=RIGHT NOWRAP>
21.845
<TD class="math" ALIGN=RIGHT NOWRAP>
2.656
<TD class="math" ALIGN=RIGHT NOWRAP>
12.980
<TD class="math" ALIGN=RIGHT NOWRAP>
9,9
<TD class="math" ALIGN=RIGHT NOWRAP>
279,8
<TD class="math" ALIGN=RIGHT NOWRAP>
289,7
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Hilbert cube
<TD class="math" ALIGN=RIGHT NOWRAP>
144.092
<TD class="math" ALIGN=RIGHT NOWRAP>
968
<TD class="math" ALIGN=RIGHT NOWRAP>
48
<TD class="math" ALIGN=RIGHT NOWRAP>
5.778
<TD class="math" ALIGN=RIGHT NOWRAP>
986
<TD class="math" ALIGN=RIGHT NOWRAP>
4.124
<TD class="math" ALIGN=RIGHT NOWRAP>
0,6
<TD class="math" ALIGN=RIGHT NOWRAP>
10,2
<TD class="math" ALIGN=RIGHT NOWRAP>
10,9
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Asian Dragon
<TD class="math" ALIGN=RIGHT NOWRAP>
3.609.455
<TD class="math" ALIGN=RIGHT NOWRAP>
2.842
<TD class="math" ALIGN=RIGHT NOWRAP>
2.842
<TD class="math" ALIGN=RIGHT NOWRAP>
101.651
<TD class="math" ALIGN=RIGHT NOWRAP>
11.158
<TD class="math" ALIGN=RIGHT NOWRAP>
35.776
<TD class="math" ALIGN=RIGHT NOWRAP>
31,7
<TD class="math" ALIGN=RIGHT NOWRAP>
869,9
<TD class="math" ALIGN=RIGHT NOWRAP>
903,5
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Building_C
<TD class="math" ALIGN=RIGHT NOWRAP>
1.000.000
<TD class="math" ALIGN=RIGHT NOWRAP>
221
<TD class="math" ALIGN=RIGHT NOWRAP>
172
<TD class="math" ALIGN=RIGHT NOWRAP>
3.468
<TD class="math" ALIGN=RIGHT NOWRAP>
370
<TD class="math" ALIGN=RIGHT NOWRAP>
1.468
<TD class="math" ALIGN=RIGHT NOWRAP>
41,9
<TD class="math" ALIGN=RIGHT NOWRAP>
14,5
<TD class="math" ALIGN=RIGHT NOWRAP>
56,5
<TR>
<TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
</TABLE>

The parameters to reconstruct these models are available in the following table:

<TABLE CELLSPACING=5 >
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
<TR>
<TD class="math" ALIGN=CENTER NOWRAP>
Data set
<TD class="math" ALIGN=CENTER NOWRAP>
Maximum distance
<TD class="math" ALIGN=CENTER NOWRAP>
Maximum angle
<TD class="math" ALIGN=CENTER NOWRAP>
Minimum region size
<TD class="math" ALIGN=CENTER NOWRAP>
K nearest neighbors
<TD class="math" ALIGN=CENTER NOWRAP>
Regularize parallelism<br>
Angle tolerance
<TD class="math" ALIGN=CENTER NOWRAP>
Regularize coplanarity<br>
Maximum offset
<TD class="math" ALIGN=CENTER NOWRAP>
K
<TD class="math" ALIGN=CENTER NOWRAP>
Lambda
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Foam_box
<TD class="math" ALIGN=RIGHT NOWRAP>
0,05
<TD class="math" ALIGN=RIGHT NOWRAP>
15
<TD class="math" ALIGN=RIGHT NOWRAP>
250
<TD class="math" ALIGN=RIGHT NOWRAP>
12
<TD class="math" ALIGN=RIGHT NOWRAP>
10
<TD class="math" ALIGN=RIGHT NOWRAP>
0,01
<TD class="math" ALIGN=RIGHT NOWRAP>
2
<TD class="math" ALIGN=RIGHT NOWRAP>
0,7
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Lans
<TD class="math" ALIGN=RIGHT NOWRAP>
0,15
<TD class="math" ALIGN=RIGHT NOWRAP>
20
<TD class="math" ALIGN=RIGHT NOWRAP>
300
<TD class="math" ALIGN=RIGHT NOWRAP>
12
<TD class="math" ALIGN=RIGHT NOWRAP>
8
<TD class="math" ALIGN=RIGHT NOWRAP>
0,08
<TD class="math" ALIGN=RIGHT NOWRAP>
2
<TD class="math" ALIGN=RIGHT NOWRAP>
0,7
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Meeting Room
<TD class="math" ALIGN=RIGHT NOWRAP>
0,03
<TD class="math" ALIGN=RIGHT NOWRAP>
19
<TD class="math" ALIGN=RIGHT NOWRAP>
100
<TD class="math" ALIGN=RIGHT NOWRAP>
15
<TD class="math" ALIGN=RIGHT NOWRAP>
10
<TD class="math" ALIGN=RIGHT NOWRAP>
0,03
<TD class="math" ALIGN=RIGHT NOWRAP>
3
<TD class="math" ALIGN=RIGHT NOWRAP>
0,5
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Full Thing
<TD class="math" ALIGN=RIGHT NOWRAP>
0,3
<TD class="math" ALIGN=RIGHT NOWRAP>
36
<TD class="math" ALIGN=RIGHT NOWRAP>
30
<TD class="math" ALIGN=RIGHT NOWRAP>
12
<TD class="math" ALIGN=RIGHT NOWRAP>
3
<TD class="math" ALIGN=RIGHT NOWRAP>
0,05
<TD class="math" ALIGN=RIGHT NOWRAP>
1
<TD class="math" ALIGN=RIGHT NOWRAP>
0,5
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Hilbert cube
<TD class="math" ALIGN=RIGHT NOWRAP>
0,3
<TD class="math" ALIGN=RIGHT NOWRAP>
10
<TD class="math" ALIGN=RIGHT NOWRAP>
10
<TD class="math" ALIGN=RIGHT NOWRAP>
12
<TD class="math" ALIGN=RIGHT NOWRAP>
5
<TD class="math" ALIGN=RIGHT NOWRAP>
0,03
<TD class="math" ALIGN=RIGHT NOWRAP>
4
<TD class="math" ALIGN=RIGHT NOWRAP>
0,5
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Asian Dragon
<TD class="math" ALIGN=RIGHT NOWRAP>
0,7
<TD class="math" ALIGN=RIGHT NOWRAP>
26
<TD class="math" ALIGN=RIGHT NOWRAP>
150
<TD class="math" ALIGN=RIGHT NOWRAP>
10
<TD class="math" ALIGN=RIGHT NOWRAP>
0
<TD class="math" ALIGN=RIGHT NOWRAP>
0
<TD class="math" ALIGN=RIGHT NOWRAP>
1
<TD class="math" ALIGN=RIGHT NOWRAP>
0,75
<TR>

<TD class="math" ALIGN=CENTER NOWRAP>
Building_C
<TD class="math" ALIGN=RIGHT NOWRAP>
1,1
<TD class="math" ALIGN=RIGHT NOWRAP>
26
<TD class="math" ALIGN=RIGHT NOWRAP>
500
<TD class="math" ALIGN=RIGHT NOWRAP>
15
<TD class="math" ALIGN=RIGHT NOWRAP>
3
<TD class="math" ALIGN=RIGHT NOWRAP>
0,5
<TD class="math" ALIGN=RIGHT NOWRAP>
2
<TD class="math" ALIGN=RIGHT NOWRAP>
0,77
<TR>
<TD ALIGN=LEFT NOWRAP COLSPAN=10><HR>
</TABLE>
\section Ksurfp_history Design and Implementation History

This package is an implementation of Bauchet et. al \cgalCite{bauchet2020kinetic}.
A proof of concept of the kinetic surface reconstruction was developed by Dmitry Anisimov.

*/
} /* namespace CGAL */
