﻿namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_PolygonalSurfaceReconstruction

\cgalAutoToc

\author Liangliang Nan

\section secIntro Introduction

This package implements a hypothesis-and-selection based method for piecewise planar object
reconstruction from point clouds \cgalCite{nan2017polyfit}. The method takes as input an
unordered point set sampled from a piecewise planar object. The output is a compact and
watertight surface mesh interpolating the input point set. The method assumes that
all necessary major planes are provided (or can be extracted from the input point set using the
shape detection method described in \ref PkgShapeDetection, or any other
alternative methods).

The existing surface reconstruction methods available in \cgal (i.e.,
\ref PkgPoissonSurfaceReconstruction3, \ref PkgAdvancingFrontSurfaceReconstruction, and
\ref PkgScaleSpaceReconstruction3) are
suitable for point set representing objects described by smooth surfaces. For man-made objects
such as buildings, the results are not satisfactory due to the imperfections
and complexity of the reconstructed models (i.e., gigantic meshes, missing regions, noises, and
undesired structures). This is mainly because these methods tend to closely follow the surface
details. The algorithm introduced in this package is intended to produce simplified and watertight
surface meshes. It can recover sharp features of the objects, and it can handle a large amount of
noise and outliers, complementing other surface reconstruction methods.

A mixed integer programming (MIP) solver is required to solve the constrained optimization problem
formulated by the method (see \ref PkgSolverInterface).

\section secAlgo Algorithm

Unlike traditional piecewise planar object reconstruction methods that focus on either extracting good
geometric primitives or obtaining proper arrangements of primitives, the emphasis of this method lies
in intersecting the primitives (i.e. planes) and seeking
for an appropriate combination of them to obtain a manifold and watertight polygonal surface model.

The method casts surface reconstruction as a binary labeling problem based on a hypothesizing-and-selection
strategy. The reconstruction consists in the following steps:
-# extract planes from the input point set (can be skipped if planes are known or provided by other means);
-# generate a set of candidate faces by intersecting the extracted planar primitives;
-# select an optimal subset of the candidate faces through optimization under hard constraints that enforces the final polygonal surface to
be topologically correct.

\cgalFigureBegin{polyfit, polyfit_pipeline.png}
Polygonal surface reconstruction

(a) Input point set; (b) Extracted planar segments; (c) Candidate faces generated by pairwise intersection;
(d) Faces selected through optimization; (e) Reconstructed model.
\cgalFigureEnd





\subsection subsecAlgoEnergyTerms Energy Terms

Given \f$ N \f$  candidate faces \f$F = \{f_i | 1 \leq i \leq N\}\f$ generated by pairwise intersection, the
optimal subset of the candidate faces that best describes the geometry of the object and form a manifold and
watertight polygonal surface is selected through optimization.

Let \f$X = \{x_i | 1 \leq i \leq N\}\f$ denote the selection of the faces (i.e., \f$f_i\f$ is chosen
if \f$x_i = 1\f$ or not chosen if \f$x_i = 0\f$), the objective function consists of three energy terms:
data-fitting, model complexity, and point coverage.

- Data-fitting. This term is intended to evaluate the fitting quality of the faces to the point cloud. It is
defined to measure a confidence-weighted percentage of points that do not contribute to the final reconstruction.

  \f{equation}{
    E_f = 1 - \frac{1}{|P|} \sum_{i=1}^N x_i \cdot support(f_i),
    \label{eq:datafitting}
  \f}

  \f$|P|\f$ is the total number of points in \f$P\f$. \f$support(f_i)\f$ is the number of supporting points
  accounting for an appropriate notion of confidence.


- Model complexity. This term is to encourage simple structures (i.e., large planar regions).
It is defined as the ratio of sharp edges in the model.

  \f{equation}{
    E_m = \frac{1}{|E|}\sum_{i=1}^{|E|} corner(e_i),
    \label{eq:complexity}
  \f}

  \f$|E|\f$ denotes the total number of pairwise intersections in the candidate face set.
  \f$corner(e_i)\f$ is an indicator function whose value is determined by the configuration of the two selected
  faces connected by \f$e_i\f$. \f$corner(e_i)\f$ will have a value of 1 if the faces associated with \f$e_i\f$
  introduce a sharp edge in the final model. Otherwise, \f$corner(e_i)\f$ has a zero value meaning the two faces
  are coplanar.

- Point coverage. This term is intended to handle missing data. The idea is to keep the unsupported regions
  (i.e., regions not covered by points) of the final model as small as possible. This term is defined as the ratio of
  uncovered regions in the model.

  \f{equation}{
    E_c = \frac{1}{area(M)}\sum_{i=1}^N x_i \cdot (area(f_i) - area(M_i^\alpha)),
    \label{eq:coverage}
  \f}

  Here \f$area(M)\f$, \f$area(f_i)\f$, and \f$area(M_i^\alpha)\f$ denote the surface areas of the final model,
  a candidate face \f$f_i\f$, and the \f$\alpha\f$-shape mesh \f$M_i^\alpha\f$ of \f$f_i\f$, respectively.
  The \f$area(M_i^\alpha)\f$ is to approximate the area of the face covered by the 3D points.


  For more details on the energy terms and the formulation, please refer to the original paper \cgalCite{nan2017polyfit}.


\subsection subsecAlgoFaceSelection Face Selection

With the above energy terms, the optimal set of faces can be obtained by minimizing a weighted sum of these terms
under certain hard constraints.

\f{equation}{
    \begin{aligned}
    \underset{\mathbf{X}}{\text{min}} \quad & \lambda_f \cdot E_f + \lambda_m \cdot E_m +  \lambda_c \cdot E_c   \\
    \text{s.t.}                       \quad & \begin{cases}
    \begin{aligned}
    & \sum_{j \in \mathcal{N}(e_i)} {x_j} = 2 \quad \text{or} \quad 0,     && 1 \leq i \leq |E|   \\
    & x_i \in \{0, 1\},                                                && 1 \leq i \leq N
    \end{aligned}
    \end{cases}
    \end{aligned}
    \label{eq:optimization}
\f}

Here \f$ \sum_{j \in \mathcal{N}(e_i)} {x_j} \f$ counts the number of faces connected by an edge \f$ e_i \f$.
This value is enforced to be either 0 or 2, meaning none or two of the faces can be selected. These hard constraints
guarantee that each edge of the final model connects only two adjacent faces.

\cgalFigureBegin{intersection, intersection.png}
Intersection of two planes

Two planes intersect with each other resulting in four parts (a). (b) to (g) show all possible combinations to
ensure a 2-manifold surface. The edge in (b) and (c) connects two co-planar parts, while in (d) to (g) it introduces
sharp edges in the final model.
\cgalFigureEnd


\section secPSRexamples Examples

\subsection subsecExampleNoInputPlane Reconstruction from Point Clouds

The method assumes that all necessary planes can be extracted from the input point set. The following examples
first extract planes from the input point cloud and then reconstruct the surface model. In the first example,
the \ref Shape_detection_RANSAC "Efficient RANSAC approach" is used to extract planes. It is very fast,
but not deterministic, as opposed to the \ref Shape_detection_RegionGrowing "region growing approach" from the second example
that is slower, but more precise and always returns the same result for the same given parameters.

\cgalExample{Polygonal_surface_reconstruction/polyfit_example_without_input_planes.cpp}
\cgalExample{Polygonal_surface_reconstruction/polyfit_example_with_region_growing.cpp}



\subsection subsecExampleUserProvidedPlanes Reconstruction with User-Provided Planes

The following example shows the reconstruction using user-provided planar segments.

\cgalExample{Polygonal_surface_reconstruction/polyfit_example_user_provided_planes.cpp}



\subsection subsecExampleDetailControl Model Complexity Control
In addition to favoring clean and compact reconstruction results by encouraging large planar regions,
the model complexity term also provides control over the model details, i.e., increasing the influence of
this term results in fewer details in the reconstructed 3D models.

\cgalFigureBegin{complexity, complexity.png}
The effect of the model complexity term

Reconstruction by gradually increasing the influence of the model complexity term.
The values under each subfigure are the weights used in the corresponding optimization.
\cgalFigureEnd


The following example shows how to control the model complexity by tuning the weight of the model complexity term.

\remark
This example also shows how to reuse the intermediate results from the candidate generation step.

\cgalExample{Polygonal_surface_reconstruction/polyfit_example_model_complexity_control.cpp}


\section secPerformances Performance

\subsection subsecComplexity The Problem Complexity

The method is intended for reconstructing single objects with reasonable geometric complexity.
The current implementation computes pairwise intersections of the planar segments, which is sufficient
but not necessary to ensure topologically accurate reconstructions. Running on large complex objects
may result in an extremely large number of candidate faces, and thus a huge integer programming problem
to be solved.

The reconstruction time of a single object with moderate complexity is typically within a few seconds.
Among the three steps, the face selection step dominates the reconstruction pipeline when the number
of candidate faces is large (e.g., more than 5,000).





\subsection subsecSolver The Numerical Solver
The current implementation incorporates two open source solvers: \ref thirdpartyGLPK and \ref thirdpartySCIP
(see \ref PkgSolverInterface). It should be noted that GLPK only manages to solve small problems, i.e., objects
with reasonably simple structure.
In case you are reconstructing more complex objects, you may need to consider more efficient open source
solvers (e.g., <a href = "https://github.com/coin-or/Cbc">CBC</a>) or even commercial solvers (e.g.,
<a href = "https://www.gurobi.com/">Gurobi</a>, <a href = "https://www.ibm.com/analytics/cplex-optimizer">CPLEX</a>).
The following table gives a rough idea of the performance of some solvers.

| Model            | Problem Size <br>variables/constraints | Gurobi | CBC | SCIP | GLPK | LP_SOLVE |
| :----:           | :----:       | :----  |     |      |      |          |
| ![ ](model1.png) | 1244/2660    |  0.05 sec    | 0.2 sec     | 0.3 sec  | 9 sec     |  15 min   |
| ![ ](model2.png) | 2582/5420    |  0.2 sec     | 0.6 sec     | 2.6 sec  | 35 min    |  -        |
| ![ ](model3.png) | 21556/442191 |  2 sec       | 7.5 sec     | 9 sec    | -         |  -        |


*/
} /* namespace CGAL */
