Ponca  8e4373a7fc557bbfb1afb9210d70f03872388d04
Point Cloud Analysis library
Loading...
Searching...
No Matches
basket.h
1/*
2 This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7#pragma once
8
9#include "defines.h"
10#include "enums.h"
11#include "primitive.h"
12#include "compute.h"
13
14#include PONCA_MULTIARCH_INCLUDE_STD(iterator)
15
16namespace Ponca
17{
18
19#define BSKNF typename BasketType::NeighborFilter
20#define BSKP typename BasketType::DataPoint
21
22#ifndef PARSED_WITH_DOXYGEN
24namespace internal
25{
35 template <class P, class NF,
36 typename Aggregate,
37 template <class, class, typename> class Ext,
38 template <class, class, typename> class... Exts>
39 struct BasketAggregateImpl
40 {
41 using type = typename BasketAggregateImpl<P, NF, Ext<P, NF, Aggregate>, Exts...>::type;
42 };
43
52 template <class P, class NF,
53 typename Aggregate,
54 template <class, class, typename> class Ext>
55 struct BasketAggregateImpl<P, NF, Aggregate, Ext>
56 {
57 using type = Ext<P, NF, Aggregate>;
58 };
59
68 template <class P, class NF,
69 template <class, class, typename> class... Exts>
70 struct BasketAggregate : BasketAggregateImpl<P, NF, PrimitiveBase<P, NF>, Exts...>
71 {
72 };
73
83 template <int Type,
84 typename BasketType,
85 template <class, class, int, typename> class Ext,
86 template <class, class, int, typename> class... Exts>
87 struct BasketDiffAggregateImpl
88 {
89 using type = typename BasketDiffAggregateImpl<Type, Ext<BSKP, BSKNF, Type, BasketType>, Exts...>::type;
90 };
91
99 template <int Type,
100 typename BasketType,
101 template <class, class, int, typename> class Ext>
102 struct BasketDiffAggregateImpl<Type, BasketType, Ext>
103 {
104 using type = Ext<BSKP, BSKNF, Type, BasketType>;
105 };
106
115 template <typename BasketType, int Type,
116 template <class, class, int, typename> class... Exts>
117 struct BasketDiffAggregate : BasketDiffAggregateImpl<Type, BasketType, PrimitiveDer, Exts...>
118 {
119 };
120}
121#endif
122
144 template<typename _Derived, typename _Base>
145 struct BasketComputeObject : public ComputeObject<_Derived>, public virtual _Base {
146 using Base = _Base;
147 using Derived = _Derived;
148 using Scalar = typename Base::Scalar;
149 protected:
151 public:
152 using ComputeObject<Derived>::compute; // Makes the default compute(container) accessible when using a CPU architecture
153
160 template <typename IteratorBegin, typename IteratorEnd>
161 PONCA_MULTIARCH inline FIT_RESULT compute(const IteratorBegin& begin, const IteratorEnd& end){
162 Base::init();
163 FIT_RESULT res = UNDEFINED;
164
165 do {
166 derived().startNewPass();
167 for (auto it = begin; it != end; ++it){
168 derived().addNeighbor(*it);
169 }
170 res = Base::finalize();
171 } while ( res == NEED_OTHER_PASS );
172
173 return res;
174 }
175
183 template <typename IndexRange, typename PointContainer>
184 PONCA_MULTIARCH inline FIT_RESULT computeWithIds(IndexRange ids, const PointContainer& points){
185 Base::init();
186 FIT_RESULT res = UNDEFINED;
187
188 do {
189 derived().startNewPass();
190 for (const auto& i : ids){
191 derived().addNeighbor(points[i]);
192 }
193 res = Base::finalize();
194 } while ( res == NEED_OTHER_PASS );
195
196 return res;
197 }
198
199 protected:
207 template<typename Func>
208 FIT_RESULT computeMLSImpl(Func&& computeFunc, const int mlsIter, const Scalar epsilon) {
209 FIT_RESULT res = UNDEFINED;
210 auto lastPos = Base::getNeighborFilter().evalPos();
211
212 for (int mm = 0; mm < mlsIter; ++mm) {
213 Base::getNeighborFilter().changeNeighborhoodFrame(lastPos);
214 res = computeFunc();
215
216 if (Base::isStable()) {
217 auto newPos = Base::project(lastPos);
218 if (newPos.isApprox(lastPos, epsilon))
219 return res;
220 lastPos = newPos;
221 } else {
222 return res;
223 }
224 }
225 return res;
226 }
227
228 public:
233 template<typename PointContainer>
235 const PointContainer& points,
236 const int mlsIter = 5,
237 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision()
238 ) {
239 return computeMLSImpl(
240 [&]() { return compute(points); },
241 mlsIter, epsilon
242 );
243 }
244
250 template<typename IndexRange, typename PointContainer>
252 const IndexRange& ids,
253 const PointContainer& points,
254 const int mlsIter = 5,
255 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision()
256 ) {
257 return computeMLSImpl(
258 [&]() { return computeWithIds(ids, points); },
259 mlsIter, epsilon
260 );
261 }
262 };
263
264#define WRITE_COMPUTE_FUNCTIONS \
265 using BasketComputeObject<Self, Base>::compute; \
266 using BasketComputeObject<Self, Base>::computeWithIds; \
267 using BasketComputeObject<Self, Base>::computeMLS; \
268 using BasketComputeObject<Self, Base>::computeWithIdsMLS;
269
278 template <typename BasketType, int Type,
279 template <class, class, int, typename> class Ext0,
280 template <class, class, int, typename> class... Exts>
281 class BasketDiff : public BasketComputeObject<BasketDiff<BasketType, Type, Ext0, Exts...>,
282 typename internal::BasketDiffAggregate<BasketType, Type, Ext0, Exts...>::type>
283 {
284 private:
285 using Self = BasketDiff;
286 public:
287 using Base = typename internal::BasketDiffAggregate<BasketType,Type,Ext0,Exts...>::type;
289 using NeighborFilter = BSKNF;
291 using DataPoint = BSKP;
293 using Scalar = typename BasketType::Scalar;
294 WRITE_COMPUTE_FUNCTIONS
295
297 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint &_nei) {
298 // compute weight
299 auto neiFilterOutput = Base::getNeighborFilter()(_nei);
300 typename Base::ScalarArray dw;
301
302 if (neiFilterOutput.first > Scalar(0.)) {
303 Base::addLocalNeighbor(neiFilterOutput.first, neiFilterOutput.second, _nei, dw);
304 return true;
305 }
306 return false;
307 }
308};
309
318 template <class P, class NF,
319 template <class, class, typename> class Ext0,
320 template <class, class, typename> class... Exts>
321 class Basket : public BasketComputeObject<Basket<P, NF, Ext0, Exts...>,
322 typename internal::BasketAggregate<P, NF, Ext0, Exts...>::type>
323 {
324 private:
325 using Self = Basket;
326 public:
328 using Base = typename internal::BasketAggregate<P, NF, Ext0, Exts...>::type;
330 using Scalar = typename P::Scalar;
331 using VectorType = typename P::VectorType;
333 using DataPoint = P;
335 using NeighborFilter = NF;
336
337 WRITE_COMPUTE_FUNCTIONS
338
345 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint &_nei) {
346 // compute weight
347 auto neiFilterOutput = Base::getNeighborFilter()(_nei);
348
349 if (neiFilterOutput.first > Scalar(0.)) {
350 Base::addLocalNeighbor(neiFilterOutput.first, neiFilterOutput.second, _nei);
351 return true;
352 }
353 return false;
354 }
355
356
357
365 PONCA_MULTIARCH [[nodiscard]] inline VectorType projectDescent (const VectorType& _q, int nbIter = 16) const
366 {
367 PONCA_MULTIARCH_STD_MATH(min)
368
369 // turn to centered basis
370 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
371
372 VectorType grad;
373 VectorType dir = Base::primitiveGradientLocal(lq);
374 Scalar ilg = Scalar(1.)/dir.norm();
375 dir = dir*ilg;
376 Scalar ad = Base::potentialLocal(lq);
377 Scalar delta = -ad*min(ilg,Scalar(1.));
378 VectorType proj = lq + dir*delta;
379
380 for (int i=0; i<nbIter; ++i)
381 {
382 grad = Base::primitiveGradientLocal(proj);
383 ilg = Scalar(1.)/grad.norm();
384 delta = -Base::potentialLocal(proj)*min(ilg,Scalar(1.));
385 proj += dir*delta;
386 }
387 return Base::getNeighborFilter().convertToGlobalBasis( proj );
388 }
389 }; // class Basket
390
391#undef WRITE_COMPUTE_FUNCTIONS
392} //namespace Ponca
393
Aggregator class used to declare specialized structures with derivatives computations,...
Definition basket.h:283
typename BasketType::DataPoint DataPoint
Point type used for computation.
Definition basket.h:291
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:297
typename BasketType::NeighborFilter NeighborFilter
Neighbor Filter.
Definition basket.h:289
typename BasketType::Scalar Scalar
Scalar type used for computation, as defined from Basket.
Definition basket.h:293
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:323
typename internal::BasketAggregate< P, NF, Ext0, Exts... >::type Base
Base type, which aggregates all the computational objects using the CRTP.
Definition basket.h:328
P DataPoint
Point type used for computation.
Definition basket.h:333
VectorType projectDescent(const VectorType &_q, int nbIter=16) const
Project a point on the primitive using Gradient Descent This projection is realized by following the ...
Definition basket.h:365
typename P::Scalar Scalar
Scalar type used for computation, as defined from template parameter P
Definition basket.h:330
NF NeighborFilter
Weighting function.
Definition basket.h:335
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:345
This Source Code Form is subject to the terms of the Mozilla Public License, v.
FIT_RESULT
Enum corresponding to the state of a fitting method (and what the finalize function returns)
Definition enums.h:15
@ UNDEFINED
The fitting is undefined, you can't use it for valid results.
Definition enums.h:22
@ NEED_OTHER_PASS
The fitting procedure needs to analyse the neighborhood another time.
Definition enums.h:25
Base ComputeObject for the Basket classes.
Definition basket.h:145
FIT_RESULT computeWithIds(IndexRange ids, const PointContainer &points)
Convenience function to iterate over a subset of samples in a PointContainer Add neighbors stored in ...
Definition basket.h:184
FIT_RESULT computeMLS(const PointContainer &points, const int mlsIter=5, const Scalar epsilon=Eigen::NumTraits< Scalar >::dummy_precision())
Computes the fit using the MLS iteration process.
Definition basket.h:234
FIT_RESULT computeMLSImpl(Func &&computeFunc, const int mlsIter, const Scalar epsilon)
Computes the fit using the MLS iteration process.
Definition basket.h:208
FIT_RESULT compute(const IteratorBegin &begin, const IteratorEnd &end)
Convenience function for STL-like iterators Add neighbors stored in a container using STL-like iterat...
Definition basket.h:161
FIT_RESULT computeWithIdsMLS(const IndexRange &ids, const PointContainer &points, const int mlsIter=5, const Scalar epsilon=Eigen::NumTraits< Scalar >::dummy_precision())
Computes the fit using the MLS iteration process.
Definition basket.h:251
typename Base::Scalar Scalar
Alias to the Derived type.
Definition basket.h:148
ComputeObject is a virtual object that represents an algorithm which can be used with the compute fun...
Definition compute.h:20
_Derived & derived()
Retrieve the top layer object Returns a reference to the derived class so that we can use its overwri...
Definition compute.h:24