MeshLib C++ Docs
Loading...
Searching...
No Matches
MRICP.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRPch/MRBindingMacros.h"
4#include "MRICPEnums.h"
5#include "MRMeshOrPoints.h"
6#include "MRMatrix3.h"
7#include "MRId.h"
8#include "MRConstants.h"
9#include "MRAffineXf.h"
10#include "MRBitSet.h"
11#include <cfloat>
12
13namespace MR
14{
15
16struct ICPPairData
17{
19 Vector3f srcPoint;
20
22 Vector3f srcNorm;
23
25 Vector3f tgtPoint;
26
28 Vector3f tgtNorm;
29
31 float distSq = 0.f;
32
34 float weight = 1.f;
35
36 friend bool operator == ( const ICPPairData&, const ICPPairData& ) = default;
37};
38
40struct PointPair : public ICPPairData
41{
43 VertId srcVertId;
44
47 VertId tgtCloseVert;
48
50 float normalsAngleCos = 1.f;
51
53 bool tgtOnBd = false;
54
55 friend bool operator == ( const PointPair&, const PointPair& ) = default;
56};
57
59struct IPointPairs
60{
61 // required to declare explicitly to avoid warnings
62 IPointPairs() = default;
63 IPointPairs( const IPointPairs& ) = default;
64 IPointPairs& operator=( const IPointPairs& ) = default;
65 IPointPairs( IPointPairs&& ) noexcept = default;
66 IPointPairs& operator=( IPointPairs&& ) noexcept = default;
67 virtual ~IPointPairs() = default;
68
69 virtual const ICPPairData& operator[]( size_t ) const = 0;
70 virtual ICPPairData& operator[]( size_t ) = 0;
71 virtual size_t size() const = 0;
72 BitSet active;
73};
74
75struct PointPairs : public IPointPairs
76{
77 virtual const ICPPairData& operator[]( size_t idx ) const override { return vec[idx]; }
78 virtual ICPPairData& operator[]( size_t idx ) override { return vec[idx]; }
79 virtual size_t size() const override { return vec.size(); }
80 std::vector<PointPair> vec;
81};
82
84[[nodiscard]] inline size_t getNumSamples( const IPointPairs& pairs ) { return pairs.active.size(); }
85
87[[nodiscard]] MRMESH_API size_t getNumActivePairs( const IPointPairs& pairs );
88
89struct NumSum
90{
91 int num = 0;
92 double sum = 0;
93
94 friend NumSum operator + ( const NumSum & a, const NumSum & b ) { return { a.num + b.num, a.sum + b.sum }; }
95
96 [[nodiscard]] float rootMeanSqF() const { return ( num <= 0 ) ? FLT_MAX : (float)std::sqrt( sum / num ); }
97};
98
101[[nodiscard]] MRMESH_API NumSum getSumSqDistToPoint( const IPointPairs& pairs, std::optional<double> inaccuracy = {} );
102
105[[nodiscard]] MRMESH_API NumSum getSumSqDistToPlane( const IPointPairs& pairs, std::optional<double> inaccuracy = {});
106
108[[nodiscard]] inline float getMeanSqDistToPoint( const IPointPairs& pairs ) { return getSumSqDistToPoint( pairs ).rootMeanSqF(); }
109
111[[nodiscard]] inline float getMeanSqDistToPlane( const IPointPairs& pairs ) { return getSumSqDistToPlane( pairs ).rootMeanSqF(); }
112
114[[nodiscard]] MRMESH_API std::string getICPStatusInfo( int iterations, ICPExitType exitType );
115
118 ICPMode mode, float angleLimit, float scaleLimit, const Vector3f & fixedRotationAxis );
119
121struct ICPProperties
122{
124 ICPMethod method = ICPMethod::PointToPlane;
125
128 float p2plAngleLimit = PI_F / 6.0f; // [radians]
129
132 float p2plScaleLimit = 2;
133
137 float cosThreshold = 0.7f; // in [-1,1]
138
142 float distThresholdSq = 1.f; // [distance^2]
143
148 float farDistFactor = 3.f; // dimensionless
149
152 ICPMode icpMode = ICPMode::AnyRigidXf;
153
155 Vector3f fixedRotationAxis;
156
159 int iterLimit = 10;
160
163 int badIterStopCount = 3;
164
167 float exitVal = 0; // [distance]
168
171 bool mutualClosest = false;
172};
173
175MRMESH_API size_t deactivateFarPairs( IPointPairs& pairs, float maxDistSq );
176
179 const MeshOrPointsXf& src, const MeshOrPointsXf& tgt,
180 float cosThreshold, float distThresholdSq, bool mutualClosest );
181
185class [[nodiscard]] ICP
186{
187public:
195 ICP( const MeshOrPoints& flt, const MeshOrPoints& ref, const AffineXf3f& fltXf, const AffineXf3f& refXf,
196 const VertBitSet& fltSamples = {}, const VertBitSet& refSamples = {} ) : ICP( { flt, fltXf }, { ref, refXf }, fltSamples, refSamples ) {}
197 MRMESH_API ICP( const MeshOrPointsXf& flt, const MeshOrPointsXf& ref, const VertBitSet& fltSamples = {}, const VertBitSet& refSamples = {} );
198
205 MRMESH_API ICP( const MeshOrPoints& flt, const MeshOrPoints& ref, const AffineXf3f& fltXf, const AffineXf3f& refXf,
206 float samplingVoxelSize ) : ICP( { flt, fltXf }, { ref, refXf }, samplingVoxelSize ) {}
207 MRMESH_API ICP( const MeshOrPointsXf& flt, const MeshOrPointsXf& ref, float samplingVoxelSize );
208
210 void setParams(const ICPProperties& prop) { prop_ = prop; }
211 MRMESH_API void setCosineLimit(const float cos);
212 MRMESH_API void setDistanceLimit( const float dist );
213 MRMESH_API void setBadIterCount( const int iter );
214 MRMESH_API void setFarDistFactor(const float factor);
215
217 MRMESH_API void setFltSamples( const VertBitSet& fltSamples );
218 MRMESH_API void sampleFltPoints( float samplingVoxelSize );
219
221 MRMESH_API void setRefSamples( const VertBitSet& refSamples );
222 MRMESH_API void sampleRefPoints( float samplingVoxelSize );
223
225 void samplePoints( float samplingVoxelSize ) { sampleFltPoints( samplingVoxelSize ); sampleRefPoints( samplingVoxelSize ); }
226
227 [[deprecated]] MR_BIND_IGNORE void recomputeBitSet( float fltSamplingVoxelSize ) { sampleFltPoints( fltSamplingVoxelSize ); }
228
230 MRMESH_API void setXfs( const AffineXf3f& fltXf, const AffineXf3f& refXf );
231
233 MRMESH_API void setFloatXf( const AffineXf3f& fltXf );
234
238 MRMESH_API AffineXf3f autoSelectFloatXf();
239
242
243 [[nodiscard]] const ICPProperties& getParams() const { return prop_; }
244
245 [[nodiscard]] MRMESH_API std::string getStatusInfo() const; // returns status info string
246
248 [[nodiscard]] size_t getNumSamples() const { return MR::getNumSamples( flt2refPairs_ ) + MR::getNumSamples( ref2fltPairs_ ); }
249
251 [[nodiscard]] size_t getNumActivePairs() const { return MR::getNumActivePairs( flt2refPairs_ ) + MR::getNumActivePairs( ref2fltPairs_ ); }
252
254 [[nodiscard]] MRMESH_API float getMeanSqDistToPoint() const;
255
257 [[nodiscard]] MRMESH_API float getMeanSqDistToPlane() const;
258
260 [[nodiscard]] const PointPairs & getFlt2RefPairs() const { return flt2refPairs_; }
261
263 [[nodiscard]] const PointPairs & getRef2FltPairs() const { return ref2fltPairs_; }
264
267 [[nodiscard]] MRMESH_API AffineXf3f calculateTransformation();
268
269private:
270 MeshOrPointsXf flt_;
271 MeshOrPointsXf ref_;
272
273 ICPProperties prop_;
274
275 PointPairs flt2refPairs_;
276 PointPairs ref2fltPairs_;
277
278 ICPExitType resultType_{ ICPExitType::NotStarted };
279
281 void deactivatefarDistPairs_();
282
283 int iter_ = 0;
284 bool p2ptIter_();
285 bool p2plIter_();
286
287 void calcGen_( float (ICP::*dist)() const, bool (ICP::*iter)() );
288 void calcP2Pt_();
289 void calcP2Pl_();
290 void calcCombined_();
291};
292
293} //namespace MR
constexpr A operator+(A a)
Definition MRImGuiVectorOperators.h:97
#define MRMESH_API
Definition MRMeshFwd.h:80
new unsafe ref MR.Vector3f srcNorm
new unsafe ref MR.Vector3f srcPoint
new unsafe ref MR.Vector3f tgtNorm
unsafe ICPPairData()
new unsafe ref float distSq
new unsafe ref MR.Vector3f tgtPoint
new unsafe ref float weight
Definition MRICP.h:122
Definition MRICP.h:186
Definition MRICP.h:60
Definition MRMeshOrPoints.h:106
Definition MRMeshOrPoints.h:18
Definition MRICP.h:90
new unsafe ref bool tgtOnBd
new unsafe ref float normalsAngleCos
unsafe PointPair()
new unsafe ref MR.VertId tgtCloseVert
new unsafe ref MR.VertId srcVertId
Definition MRICP.h:76
Definition MRPointToPlaneAligningTransform.h:20
Definition MRCameraOrientationPlugin.h:8
MRMESH_API NumSum getSumSqDistToPoint(const IPointPairs &pairs, std::optional< double > inaccuracy={})
float getMeanSqDistToPlane(const IPointPairs &pairs)
computes root-mean-square deviation from points to target planes
Definition MRICP.h:111
MRMESH_API NumSum getSumSqDistToPlane(const IPointPairs &pairs, std::optional< double > inaccuracy={})
MRMESH_API AffineXf3d getAligningXf(const PointToPlaneAligningTransform &p2pl, ICPMode mode, float angleLimit, float scaleLimit, const Vector3f &fixedRotationAxis)
given prepared (p2pl) object, finds the best transformation from it of given type with given limitati...
MRMESH_API size_t getNumActivePairs(const IPointPairs &pairs)
computes the number of active pairs
size_t getNumSamples(const IPointPairs &pairs)
returns the number of samples able to form pairs
Definition MRICP.h:84
MRMESH_API std::string getICPStatusInfo(int iterations, ICPExitType exitType)
returns status info string
float getMeanSqDistToPoint(const IPointPairs &pairs)
computes root-mean-square deviation between points
Definition MRICP.h:108
MRMESH_API void updatePointPairs(PointPairs &pairs, const MeshOrPointsXf &src, const MeshOrPointsXf &tgt, float cosThreshold, float distThresholdSq, bool mutualClosest)
in each pair updates the target data and performs basic filtering (activation)
MRMESH_API size_t deactivateFarPairs(IPointPairs &pairs, float maxDistSq)
reset active bit if pair distance is further than maxDistSq
float getMeanSqDistToPlane(IPointPairs pairs)
None updatePointPairs(PointPairs pairs, MeshOrPointsXf src, MeshOrPointsXf tgt, float cosThreshold, float distThresholdSq, bool mutualClosest)
float getMeanSqDistToPoint(IPointPairs pairs)
int getNumSamples(IPointPairs pairs)
int getNumActivePairs(IPointPairs pairs)