Ponca  bab7704293a2c36e5bed9dea40def7ba839bfe08
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
14namespace Ponca
15{
16
17#define BSKNF typename BasketType::NeighborFilter
18#define BSKP typename BasketType::DataPoint
19
20#ifndef PARSED_WITH_DOXYGEN
22 namespace internal
23 {
33 template <class P, class NF, typename Aggregate, template <class, class, typename> class Ext,
34 template <class, class, typename> class... Exts>
35 struct BasketAggregateImpl
36 {
37 using type = typename BasketAggregateImpl<P, NF, Ext<P, NF, Aggregate>, Exts...>::type;
38 };
39
48 template <class P, class NF, typename Aggregate, template <class, class, typename> class Ext>
49 struct BasketAggregateImpl<P, NF, Aggregate, Ext>
50 {
51 using type = Ext<P, NF, Aggregate>;
52 };
53
62 template <class P, class NF, template <class, class, typename> class... Exts>
63 struct BasketAggregate : BasketAggregateImpl<P, NF, PrimitiveBase<P, NF>, Exts...>
64 {
65 };
66
76 template <int Type, typename BasketType, template <class, class, int, typename> class Ext,
77 template <class, class, int, typename> class... Exts>
78 struct BasketDiffAggregateImpl
79 {
80 using type = typename BasketDiffAggregateImpl<Type, Ext<BSKP, BSKNF, Type, BasketType>, Exts...>::type;
81 };
82
90 template <int Type, typename BasketType, template <class, class, int, typename> class Ext>
91 struct BasketDiffAggregateImpl<Type, BasketType, Ext>
92 {
93 using type = Ext<BSKP, BSKNF, Type, BasketType>;
94 };
95
104 template <typename BasketType, int Type, template <class, class, int, typename> class... Exts>
105 struct BasketDiffAggregate : BasketDiffAggregateImpl<Type, BasketType, PrimitiveDer, Exts...>
106 {
107 };
108 } // namespace internal
109#endif
110
132 template <typename _Derived, typename _Base>
133 struct BasketComputeObject : public ComputeObject<_Derived>, public virtual _Base
134 {
135 using Base = _Base;
136 using Derived = _Derived;
137 using Scalar = typename Base::Scalar;
138
139 protected:
141
142 public:
143 using ComputeObject<Derived>::compute; // Makes the default compute(container) accessible when using a CPU
144 // architecture
145
152 template <typename IteratorBegin, typename IteratorEnd>
153 PONCA_MULTIARCH inline FIT_RESULT compute(const IteratorBegin& begin, const IteratorEnd& end)
154 {
155 Base::init();
156 FIT_RESULT res = UNDEFINED;
157
158 do
159 {
160 derived().startNewPass();
161 for (auto it = begin; it != end; ++it)
162 {
163 derived().addNeighbor(*it);
164 }
165 res = Base::finalize();
166 } while (res == NEED_OTHER_PASS);
167
168 return res;
169 }
170
178 template <typename IndexRange, typename PointContainer>
179 PONCA_MULTIARCH inline FIT_RESULT computeWithIds(IndexRange ids, const PointContainer& points)
180 {
181 Base::init();
182 FIT_RESULT res = UNDEFINED;
183
184 do
185 {
186 derived().startNewPass();
187 for (const auto& i : ids)
188 {
189 derived().addNeighbor(points[i]);
190 }
191 res = Base::finalize();
192 } while (res == NEED_OTHER_PASS);
193
194 return res;
195 }
196
197 protected:
205 template <typename Func>
206 PONCA_MULTIARCH FIT_RESULT computeMLSImpl(Func&& computeFunc, const int mlsIter, const Scalar epsilon)
207 {
208 FIT_RESULT res = UNDEFINED;
209 auto lastPos = Base::getNeighborFilter().evalPos();
210
211 for (int mm = 0; mm < mlsIter; ++mm)
212 {
213 Base::m_nFilter.changeNeighborhoodFrame(lastPos);
214 res = computeFunc();
215
216 if (Base::isStable())
217 {
218 auto newPos = Base::project(lastPos);
219 if (newPos.isApprox(lastPos, epsilon))
220 return res;
221 lastPos = newPos;
222 }
223 else
224 {
225 return res;
226 }
227 }
228 return res;
229 }
230
231 public:
236 template <typename PointContainer>
237 PONCA_MULTIARCH FIT_RESULT computeMLS(const PointContainer& points, const int mlsIter = 5,
238 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision())
239 {
240 return computeMLSImpl([&]() { return compute(points); }, mlsIter, epsilon);
241 }
242
248 template <typename IndexRange, typename PointContainer>
249 PONCA_MULTIARCH FIT_RESULT computeWithIdsMLS(const IndexRange& ids, const PointContainer& points,
250 const int mlsIter = 5,
251 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision())
252 {
253 return computeMLSImpl([&]() { return computeWithIds(ids, points); }, mlsIter, epsilon);
254 }
255 };
256
257#define WRITE_COMPUTE_FUNCTIONS \
258 using BasketComputeObject<Self, Base>::compute; \
259 using BasketComputeObject<Self, Base>::computeWithIds; \
260 using BasketComputeObject<Self, Base>::computeMLS; \
261 using BasketComputeObject<Self, Base>::computeWithIdsMLS;
262
271 template <typename BasketType, int Type, template <class, class, int, typename> class Ext0,
272 template <class, class, int, typename> class... Exts>
274 : public BasketComputeObject<BasketDiff<BasketType, Type, Ext0, Exts...>,
275 typename internal::BasketDiffAggregate<BasketType, Type, Ext0, Exts...>::type>
276 {
277 private:
278 using Self = BasketDiff;
279
280 public:
281 using Base = typename internal::BasketDiffAggregate<BasketType, Type, Ext0, Exts...>::type;
283 using NeighborFilter = BSKNF;
285 using DataPoint = BSKP;
287 using Scalar = typename BasketType::Scalar;
288 WRITE_COMPUTE_FUNCTIONS
289
291 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint& _nei)
292 {
293 // compute weight
294 auto neiFilterOutput = Base::getNeighborFilter()(_nei);
295 typename Base::ScalarArray dw;
296
297 if (neiFilterOutput.first > Scalar(0.))
298 {
299 Base::addLocalNeighbor(neiFilterOutput.first, neiFilterOutput.second, _nei, dw);
300 return true;
301 }
302 return false;
303 }
304 };
305
314 template <class P, class NF, template <class, class, typename> class Ext0,
315 template <class, class, typename> class... Exts>
316 class Basket : public BasketComputeObject<Basket<P, NF, Ext0, Exts...>,
317 typename internal::BasketAggregate<P, NF, Ext0, Exts...>::type>
318 {
319 private:
320 using Self = Basket;
321
322 public:
324 using Base = typename internal::BasketAggregate<P, NF, Ext0, Exts...>::type;
326 using Scalar = typename P::Scalar;
327 using VectorType = typename P::VectorType;
329 using DataPoint = P;
331 using NeighborFilter = NF;
332
333 WRITE_COMPUTE_FUNCTIONS
334
341 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint& _nei)
342 {
343 // compute weight
344 auto neiFilterOutput = Base::getNeighborFilter()(_nei);
345
346 if (neiFilterOutput.first > Scalar(0.))
347 {
348 Base::addLocalNeighbor(neiFilterOutput.first, neiFilterOutput.second, _nei);
349 return true;
350 }
351 return false;
352 }
353
361 PONCA_MULTIARCH [[nodiscard]] inline VectorType projectDescent(const VectorType& _q, int nbIter = 16) const
362 {
363 PONCA_MULTIARCH_STD_MATH(min)
364
365 // turn to centered basis
366 const VectorType lq = Base::getNeighborFilter().convertToLocalBasis(_q);
367
368 VectorType grad;
369 VectorType dir = Base::primitiveGradientLocal(lq);
370 Scalar ilg = Scalar(1.) / dir.norm();
371 dir = dir * ilg;
372 Scalar ad = Base::potentialLocal(lq);
373 Scalar delta = -ad * min(ilg, Scalar(1.));
374 VectorType proj = lq + dir * delta;
375
376 for (int i = 0; i < nbIter; ++i)
377 {
378 grad = Base::primitiveGradientLocal(proj);
379 ilg = Scalar(1.) / grad.norm();
380 delta = -Base::potentialLocal(proj) * min(ilg, Scalar(1.));
381 proj += dir * delta;
382 }
383 return Base::getNeighborFilter().convertToGlobalBasis(proj);
384 }
385 }; // class Basket
386
387#undef WRITE_COMPUTE_FUNCTIONS
388} // namespace Ponca
389
Aggregator class used to declare specialized structures with derivatives computations,...
Definition basket.h:276
typename BasketType::DataPoint DataPoint
Point type used for computation.
Definition basket.h:285
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:291
typename BasketType::NeighborFilter NeighborFilter
Neighbor Filter.
Definition basket.h:283
typename BasketType::Scalar Scalar
Scalar type used for computation, as defined from Basket.
Definition basket.h:287
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:318
typename internal::BasketAggregate< P, NF, Ext0, Exts... >::type Base
Base type, which aggregates all the computational objects using the CRTP.
Definition basket.h:324
P DataPoint
Point type used for computation.
Definition basket.h:329
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:361
typename P::Scalar Scalar
Scalar type used for computation, as defined from template parameter P
Definition basket.h:326
NF NeighborFilter
Weighting function.
Definition basket.h:331
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:341
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:134
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:179
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:237
FIT_RESULT computeMLSImpl(Func &&computeFunc, const int mlsIter, const Scalar epsilon)
Computes the fit using the MLS iteration process.
Definition basket.h:206
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:153
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:249
typename Base::Scalar Scalar
Alias to the Derived type.
Definition basket.h:137
ComputeObject is a virtual object that represents an algorithm which can be used with the compute fun...
Definition compute.h:24
_Derived & derived()
Retrieve the top layer object Returns a reference to the derived class so that we can use its overwri...
Definition compute.h:28