Ponca  40f245e28b920cbb763a1c6282156c87c626f24c
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 BSKW typename BasketType::WeightFunction
20#define BSKP typename BasketType::DataPoint
21
22#ifndef PARSED_WITH_DOXYGEN
24namespace internal
25{
35 template <class P, class W,
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, W, Ext<P, W, Aggregate>, Exts...>::type;
42 };
43
52 template <class P, class W,
53 typename Aggregate,
54 template <class, class, typename> class Ext>
55 struct BasketAggregateImpl<P, W, Aggregate, Ext>
56 {
57 using type = Ext<P, W, Aggregate>;
58 };
59
68 template <class P, class W,
69 template <class, class, typename> class... Exts>
70 struct BasketAggregate : BasketAggregateImpl<P, W, PrimitiveBase<P, W>, 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, BSKW, 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, BSKW, 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, int mlsIter, Scalar epsilon) {
209 FIT_RESULT res = UNDEFINED;
210 const auto t = Base::m_w.evalScale();
211 auto lastPos = Base::m_w.evalPos();
212
213 for (int mm = 0; mm < mlsIter; ++mm) {
214 Base::setWeightFunc({lastPos, t});
215 res = computeFunc();
216
217 if (Base::isStable()) {
218 auto newPos = Base::project(lastPos);
219 if (newPos.isApprox(lastPos, epsilon))
220 return res;
221 lastPos = newPos;
222 } else {
223 return res;
224 }
225 }
226 return res;
227 }
228
229 public:
234 template<typename PointContainer>
236 const PointContainer& points,
237 const int mlsIter = 5,
238 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision()
239 ) {
240 return computeMLSImpl(
241 [&]() { return compute(points); },
242 mlsIter, epsilon
243 );
244 }
245
251 template<typename IndexRange, typename PointContainer>
253 const IndexRange& ids,
254 const PointContainer& points,
255 const int mlsIter = 5,
256 const Scalar epsilon = Eigen::NumTraits<Scalar>::dummy_precision()
257 ) {
258 return computeMLSImpl(
259 [&]() { return computeWithIds(ids, points); },
260 mlsIter, epsilon
261 );
262 }
263 };
264
265#define WRITE_COMPUTE_FUNCTIONS \
266 using BasketComputeObject<Self, Base>::compute; \
267 using BasketComputeObject<Self, Base>::computeWithIds; \
268 using BasketComputeObject<Self, Base>::computeMLS; \
269 using BasketComputeObject<Self, Base>::computeWithIdsMLS;
270
279 template <typename BasketType, int Type,
280 template <class, class, int, typename> class Ext0,
281 template <class, class, int, typename> class... Exts>
282 class BasketDiff : public BasketComputeObject<BasketDiff<BasketType, Type, Ext0, Exts...>,
283 typename internal::BasketDiffAggregate<BasketType, Type, Ext0, Exts...>::type>
284 {
285 private:
286 using Self = BasketDiff;
287 public:
288 using Base = typename internal::BasketDiffAggregate<BasketType,Type,Ext0,Exts...>::type;
290 using WeightFunction = typename BasketType::WeightFunction;
292 using DataPoint = typename BasketType::DataPoint;
294 using Scalar = typename BasketType::Scalar;
295 WRITE_COMPUTE_FUNCTIONS
296
298 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint &_nei) {
299 // compute weight
300 auto wres = Base::m_w.w(_nei.pos(), _nei);
301 typename Base::ScalarArray dw;
302
303 if (wres.first > Scalar(0.)) {
304 Base::addLocalNeighbor(wres.first, wres.second, _nei, dw);
305 return true;
306 }
307 return false;
308 }
309};
310
319 template <class P, class W,
320 template <class, class, typename> class Ext0,
321 template <class, class, typename> class... Exts>
322 class Basket : public BasketComputeObject<Basket<P, W, Ext0, Exts...>,
323 typename internal::BasketAggregate<P, W, Ext0, Exts...>::type>
324 {
325 private:
326 using Self = Basket;
327 public:
329 using Base = typename internal::BasketAggregate<P, W, Ext0, Exts...>::type;
331 using Scalar = typename P::Scalar;
332 using VectorType = typename P::VectorType;
334 using DataPoint = P;
336 using WeightFunction = W;
337
338 WRITE_COMPUTE_FUNCTIONS
339
346 PONCA_MULTIARCH inline bool addNeighbor(const DataPoint &_nei) {
347 // compute weight
348 auto wres = Base::m_w.w(_nei.pos(), _nei);
349
350 if (wres.first > Scalar(0.)) {
351 Base::addLocalNeighbor(wres.first, wres.second, _nei);
352 return true;
353 }
354 return false;
355 }
356 }; // class Basket
357
358#undef WRITE_COMPUTE_FUNCTIONS
359} //namespace Ponca
360
Aggregator class used to declare specialized structures with derivatives computations,...
Definition basket.h:284
typename BasketType::DataPoint DataPoint
Point type used for computation.
Definition basket.h:292
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:298
typename BasketType::WeightFunction WeightFunction
Weight function.
Definition basket.h:290
typename BasketType::Scalar Scalar
Scalar type used for computation, as defined from Basket.
Definition basket.h:294
Aggregator class used to declare specialized structures using CRTP.
Definition basket.h:324
W WeightFunction
Weighting function.
Definition basket.h:336
P DataPoint
Point type used for computation.
Definition basket.h:334
typename P::Scalar Scalar
Scalar type used for computation, as defined from template parameter P
Definition basket.h:331
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Definition basket.h:346
typename internal::BasketAggregate< P, W, Ext0, Exts... >::type Base
Base type, which aggregates all the computational objects using the CRTP.
Definition basket.h:329
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:235
FIT_RESULT computeMLSImpl(Func &&computeFunc, int mlsIter, 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:252
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