2{ MeanNormal* meanNormal = fit.meanNormal();
255 \subsection fitting_newestim Estimator API
257 \subsubsection fitting_newestimbase Minimal requirements
259 In order to make an estimator compatible with Ponca Fitting API,
new estimator should have the following structure:
261 \snippet concepts.hpp ComputationalObjectConcept
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.
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.
271 \subsubsection fitting_newcapabilities Computational objets capabilities and requirements
273 Aggregating small computational objects allows to minimize code duplication, but also to easily combine different techniques.
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:
279 \snippet gls.h example_requirements_usage
281 We encourage macros to express requirements, as they ease definitions. For instance:
282 \snippet gls.h example_requirements
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:
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
292 53 | using type = Ext<P, NF, Aggregate>;
294ponca/Ponca/src/Fitting/
Basket/basket.h:53:19: note: constraints not satisfied
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.
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.
308 \subsubsection fitting_cast Providing cast operations
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:
315 PONCA_EXPLICIT_BASKET_CAST_OPERATORS(ClassName, className);
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.
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)
324 \subsubsection fitting_newdiff New primitive differentiation (BasketDiff API)
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.
329 \snippet concepts.hpp ComputationalDerivativesConcept
331 \note PrimitiveDer is the default entry point to most classes used in
BasketDiff
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 (<Fitting/enums.h>):
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
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.
345 <th>Fitting derivative value</th>
346 <th>Number of derivatives</th>
347 <th> Scalar Array indices </th>
352 <td> [0] is the derivative w.r.t scale </td>
356 <td> DataPoint::Dim </td>
357 <td> [0:DataPoint::Dim] derivatives w.r.t eval position </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>
367 \section fitting_advanced Advanced usage
369 \subsection fitting_factory Iterating over common Baskets
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.
373 \snippet ponca_factory.cpp FactoryBasicForeach
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.
377 \snippet ponca_factory.cpp FactoryFilterPersistent
379 Classical literature methods can also be obtained through the
Factory. For a complete list, see the `Ponca::Method` enumeration.
381 \snippet ponca_factory.cpp FactoryClassicalMethods
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.
385 \subsection fitting_multiprimitive Fitting with multiple primitives
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
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):
403 enable_language(CUDA)
404 add_executable(ponca_ssgls "ponca_ssgls.cu")
405 target_compile_options(ponca_ssgls PRIVATE --expt-relaxed-constexpr)
407 - Automatic CPU/GPU compilation qualifiers. We use the macro
409 PONCA_MULTIARCH void function();
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.
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.
416 <center>[\ref fitting_concepts "Go to concept page"]</center>
417 <center>[\ref user_manual_page "Go back to user manual"]</center>
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,...
Aggregator class used to declare specialized structures using CRTP.
Plane fitting procedure using only points position.
Differentiation of GLSParam.
Growing Least Squares reparametrization of the OrientedSphereFit.
Algebraic Sphere fitting procedure on oriented point sets.
Plane< DataPoint, _NFilter, T > & plane()
Explicit conversion to CLASSNAME, to access methods potentially hidden by heritage.
This Source Code Form is subject to the terms of the Mozilla Public License, v.
@ FitSpaceDer
Flag indicating a space differentiation.
@ FitScaleSpaceDer
Flag indicating a scale-space differentiation.
@ FitScaleDer
Flag indicating a scale differentiation.
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.
Default factory templated on Point, Filter and Derivative.