Ponca  eb7239a9c07e156fb1edc6faac7fe89e2b256bda
Point Cloud Analysis library
Loading...
Searching...
No Matches
ponca_module_fitting.mdoc
1namespace Ponca
2{ MeanNormal* meanNormal = fit.meanNormal();
252 // Do whatever you want with a 'MeanNormal' instance
253 \endcode
254
255 \subsection fitting_newestim Estimator API
256
257 \subsubsection fitting_newestimbase Minimal requirements
258
259 In order to make an estimator compatible with Ponca Fitting API, new estimator should have the following structure:
260
261 \snippet concepts.hpp ComputationalObjectConcept
262
263 \note The macro PONCA_FITTING_DECLARE_DEFAULT_TYPES defines the `Base` type (alias for T) as well as `Scalar`, `VectorType` and `NeighborFilter` for
264 manipulation of related data. This macro is defined within <Fitting/defines.h>
265 \note If the estimator is expected to be the upmost parent of the hierarchy, do not inherit from T and default it to be void.
266 \warning The macro PONCA_FITTING_DECLARE_DEFAULT_TYPES opens a public section.
267
268 In order for each computation to work properly, the functions `init`, `addLocalNeighbor` and `finalize` should call their Base version (`Base::init`, `Base::addLocalNeighbor`, `Base::finalize`).
269 Presumably, this is among the first thing each of these function does.
270
271 \subsubsection fitting_newcapabilities Computational objets capabilities and requirements
272
273 Aggregating small computational objects allows to minimize code duplication, but also to easily combine different techniques.
274 For instance, GLSDer can be used independently of the fitting technique, e.g. Ponca::OrientedSphereFit or Ponca::UnorientedSphereFit, as long as the fitted \ref PrimitiveBase "Primitive" is an AlgebraicSphere.
275
276 In order to detect if the computational objects are correctly combined, Ponca relies on C++20 concepts. Most concepts provided for Basket extensions and tools can be found within the Fitting/concepts.hpp file.
277 For instance, the GLSParam class is defined as:
278
279 \snippet gls.h example_requirements_usage
280
281 We encourage macros to express requirements, as they ease definitions. For instance:
282 \snippet gls.h example_requirements
283
284 This indicates that the class expects another extention to provide an AlgebraicSphere. If not, a compiler error
285 will be emitted. For instance, gcc emits:
286
287 ```sh
288ponca/tests/src/test.cpp:192:9: required from ‘void callSubTests() [with Scalar = long double; int Dim = 3]’
289ponca/tests/src/test.cpp:252:5: required from here
290ponca/Ponca/src/Fitting/Basket/basket.h:53:19: error: template constraint failure for ‘template<class DataPoint, class _NFi
291lter, class T> requires ProvidesAlgebraicSphere<T> class Ponca::GLSParam’
292 53 | using type = Ext<P, NF, Aggregate>;
293 | ^~~~
294ponca/Ponca/src/Fitting/Basket/basket.h:53:19: note: constraints not satisfied
295 ```
296
297 The whole output can be quite verbose, but is very precise: it tells you exactly what expression of a requirement is invalid and
298 can help you debug the code.
299 Classes do not describe which concept they satisfies, apart perhaps in their documentation.
300
301 \note In its current version, the requirement/capability system offer limited protection over the combination of tools providing the same capabilities.
302 Indeed, it is possible to build ill-formed combinations where two computations attempt to save their results at the same place, e.g. when using two fitting technique for the same primitive:
303 \snippet fit_plane.cpp Conflicting type
304 This case is not detected at compile time, but rather dynamically when calling finalize(), which returns `CONFLICT_ERROR_FOUND`.
305 Internally, this is implemented by checking if the primitive is already valid (ie. it has been computed already) when finalizing the computation.
306 This limitation is expected to be resolved in upcoming releases.
307
308 \subsubsection fitting_cast Providing cast operations
309
310 As explained earlier, the class hierarchy can not reach every function of every through the provided `Base` type due to overloading.
311 The mecanism Ponca implements is a cast operator. Fortunately, this is quite common and a macro helps to define them. Add the following
312 within a public section of your class:
313
314 \code
315 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(ClassName, className);
316 \endcode
317
318 Where the first parameter is the class name and the second is the name of the cast function which is, most of the time, the same as the
319 class name excpet a first lower case letter. Note that this macro requires the template parameter to be named following ponca conventions.
320 A class may provide multiple cast operator.
321
322 In order to respects concepts, a cast operator to a common name is required. This name can be found within the concept declaration (Fitting/concepts.hpp)
323
324 \subsubsection fitting_newdiff New primitive differentiation (BasketDiff API)
325
326 The API for defining new estimator that differentiate the primitive follows the same principle from classical estimator. The base class is BasketDiff which follows the
327 same CRTP / inheritance principle except that a Basket is required as a first parameter.
328
329 \snippet concepts.hpp ComputationalDerivativesConcept
330
331 \note PrimitiveDer is the default entry point to most classes used in BasketDiff
332
333 A few addition should be notted however. First, the class is now templated on a flag (an integer) representing the variables according to which we want to differentiate. For now,
334 Ponca defines only two set of variables (&lt;Fitting/enums.h&gt;):
335
336 - FitScaleDer: The derivatives of the primitive parameters w.r.t the scale (the neig radius)
337 - FitSpaceDer: The derivatives of the primitive parameters w.r.t the position of evaluation
338 - FitScaleSpaceDer: Compute derivative for both types.
339
340 The macro `PONCA_FITTING_DECLARE_DEFAULT_DER_TYPES` defines two additionnal types `ScalarArray` and `VectorArray`. Those types defines storage for derivative result. Note that
341 they are fixed-size array whose size is adapted to the total number of derivatives. Their layout is described below depending on the type of differentiation.
342
343 <table>
344 <tr>
345 <th>Fitting derivative value</th>
346 <th>Number of derivatives</th>
347 <th> Scalar Array indices </th>
348 </tr>
349 <tr>
350 <td>FitScaleDer</td>
351 <td> 1 </td>
352 <td> [0] is the derivative w.r.t scale </td>
353 </tr>
354 <tr>
355 <td> FitSpaceDer </td>
356 <td> DataPoint::Dim </td>
357 <td> [0:DataPoint::Dim] derivatives w.r.t eval position </td>
358 </tr>
359 <tr>
360 <td> FitScaleSpaceDer </td>
361 <td> 1 + DataPoint::Dim </td>
362 <td> [0] derivatives w.r.t scale, <br/> [1:DataPoint::Dim+1) derivatives w.r.t eval position </td>
363 </tr>
364 </table>
365
366
367 \section fitting_advanced Advanced usage
368
369 \subsection fitting_factory Iterating over common Baskets
370
371 In many cases, one may want to compare multiple Baskets or extensions. The classical solution is to write a function that accepts a template type (which would be your Basket) and then call the function manually for each type. For this reason, Ponca provides a Factory that abstracts away the iteration over compute objects for the most common types.
372
373 \snippet ponca_factory.cpp FactoryBasicForeach
374
375 The Factory module also provides the ability to filter by concept. Most Ponca fitting concepts have a corresponding filter. For a concept named "ProvidesXXX", Ponca creates two filters: "XXXProvider" and "NotXXXProvider", which can be used for filtering.
376
377 \snippet ponca_factory.cpp FactoryFilterPersistent
378
379 Classical literature methods can also be obtained through the Factory. For a complete list, see the `Ponca::Method` enumeration.
380
381 \snippet ponca_factory.cpp FactoryClassicalMethods
382
383 \warning Factories may contain different compute objects depending on the given point, filter, or derivative types. For example, Monge Patch fitting is currently only available in 3D; therefore, the Factory will include the corresponding classes only when provided with 3D points.
384
385 \subsection fitting_multiprimitive Fitting with multiple primitives
386 In most cases, only one primitive is included in the Basket, and it is recommended to use the helper classes provided by Ponca for fitting, e.g. CovariancePlaneFitImpl, OrientedSphereFitImpl.
387 However, Ponca also allows to combine multiple primitives, for instance to share intermediate computation results.
388 Using this functionality requires to really understand how the different primitives and fitting techniques are working.
389 In any case, it is recommended to explicitly define the computational arrangement, e.g.:
390 \snippet basket.cpp HybridType
391
392 After fitting, this object provides access to both the plane and the sphere, through the respective cast operators #AlgebraicSphere::algebraicSphere() and #Plane::plane().
393
394 \section fitting_cuda Cuda and SYCL
395 Ponca can be used directly on GPU, thanks to several mechanisms:
396 - Eigen capabilities, see <a href="http://eigen.tuxfamily.org/dox-devel/TopicCUDA.html" target="_blank">Eigen documentation</a> for more details.
397 You *need* to use a consistent `Eigen::Index` on both CPU and GPU if you plan to transfer memory between the computing units.
398 That's why we recommend to set the following preprocessor variable when compiling your project:
399 \code -DEIGEN_DEFAULT_DENSE_INDEX_TYPE=int\endcode
400 You might also need to define the `--expt-relaxed-constexpr` preprocessor option for `NVCC`.
401 Example of working cmake file (see \ref example_cu_ssc_page):
402 \code
403 enable_language(CUDA)
404 add_executable(ponca_ssgls "ponca_ssgls.cu")
405 target_compile_options(ponca_ssgls PRIVATE --expt-relaxed-constexpr)
406 \endcode
407 - Automatic CPU/GPU compilation qualifiers. We use the macro
408 \code
409 PONCA_MULTIARCH void function();
410 \endcode
411 to use the same code for C++ and CUDA. It has no effect when the code is compiled with GCC or Clang, but it will force the compilation for both host and device architectures when compiling with nvcc. A similar macro system is provided for mathematical functions, to switch between STL and CUDA versions.
412
413 Check the \ref cu_ssgl_intro_sec "C++/Cuda", the \ref example_python_ssc_page "Python/Cuda" (using PyCuda), \ref example_sycl_basic and \ref example_sycl_kdtree examples for more details and how-to.
414
415 <hr>
416 <center>[\ref fitting_concepts "Go to concept page"]</center>
417 <center>[\ref user_manual_page "Go back to user manual"]</center>
418 */
419 }
Algebraic Sphere primitive.
AlgebraicSphere< DataPoint, _NFilter, T > & algebraicSphere()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
Aggregator class used to declare specialized structures with derivatives computations,...
Definition basket.h:230
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:294
Plane fitting procedure using only points position.
Differentiation of GLSParam.
Definition gls.h:122
Growing Least Squares reparametrization of the OrientedSphereFit.
Definition gls.h:51
Algebraic Sphere fitting procedure on oriented point sets.
Plane< DataPoint, _NFilter, T > & plane()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
Definition plane.h:50
This Source Code Form is subject to the terms of the Mozilla Public License, v.
Definition concepts.h:11
@ FitSpaceDer
Flag indicating a space differentiation.
Definition enums.h:36
@ FitScaleSpaceDer
Flag indicating a scale-space differentiation.
Definition enums.h:37
@ FitScaleDer
Flag indicating a scale differentiation.
Definition enums.h:35
OrientedSphereFitImpl< DataPoint, _NFilter, MeanPosition< DataPoint, _NFilter, MeanNormal< DataPoint, _NFilter, AlgebraicSphere< DataPoint, _NFilter, T > > > > OrientedSphereFit
Helper alias for Oriented Sphere fitting on 3D points using OrientedSphereFitImpl [OrientedSphereFit ...
UnorientedSphereFitImpl< DataPoint, _NFilter, MeanPosition< DataPoint, _NFilter, AlgebraicSphere< DataPoint, _NFilter, T > > > UnorientedSphereFit
Helper alias for Oriented Sphere fitting on 3D points using UnorientedSphereFitImpl.
@ CONFLICT_ERROR_FOUND
Multiple classes of the fitting procedure initialize the primitive.
Definition enums.h:27
Default factory templated on Point, Filter and Derivative.
Definition factory.h:230