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
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
48
50 float normalsAngleCos = 1.f;
51
53 bool tgtOnBd = false;
54
55 friend bool operator == ( const PointPair&, const PointPair& ) = default;
56};
57
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;
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
117[[nodiscard]] MRMESH_API AffineXf3d getAligningXf( const PointToPlaneAligningTransform & p2pl,
118 ICPMode mode, float angleLimit, float scaleLimit, const Vector3f & fixedRotationAxis );
119
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
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
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
Definition MRMesh/MRBitSet.h:24
size_type size() const noexcept
Definition MRMesh/MRBitSet.h:54
Definition MRICP.h:186
size_t getNumSamples() const
computes the number of samples able to form pairs
Definition MRICP.h:248
MRMESH_API void setCosineLimit(const float cos)
const ICPProperties & getParams() const
Definition MRICP.h:243
MRMESH_API AffineXf3f calculateTransformation()
void setParams(const ICPProperties &prop)
tune algorithm params before run calculateTransformation()
Definition MRICP.h:210
MRMESH_API void sampleRefPoints(float samplingVoxelSize)
MRMESH_API void setFltSamples(const VertBitSet &fltSamples)
select pairs with origin samples on floating object
void samplePoints(float samplingVoxelSize)
select pairs with origin samples on both objects
Definition MRICP.h:225
const PointPairs & getRef2FltPairs() const
returns current pairs formed from samples on reference object and projections on floating object
Definition MRICP.h:263
const PointPairs & getFlt2RefPairs() const
returns current pairs formed from samples on floating object and projections on reference object
Definition MRICP.h:260
MRMESH_API void setFloatXf(const AffineXf3f &fltXf)
sets to-world transformation for the floating object
size_t getNumActivePairs() const
computes the number of active point pairs
Definition MRICP.h:251
MRMESH_API void setRefSamples(const VertBitSet &refSamples)
select pairs with origin samples on reference object
MRMESH_API void sampleFltPoints(float samplingVoxelSize)
MRMESH_API void setBadIterCount(const int iter)
MRMESH_API void updatePointPairs()
recompute point pairs after manual change of transformations or parameters
MRMESH_API void setXfs(const AffineXf3f &fltXf, const AffineXf3f &refXf)
sets to-world transformations both for floating and reference objects
MR_BIND_IGNORE void recomputeBitSet(float fltSamplingVoxelSize)
Definition MRICP.h:227
ICP(const MeshOrPoints &flt, const MeshOrPoints &ref, const AffineXf3f &fltXf, const AffineXf3f &refXf, const VertBitSet &fltSamples={}, const VertBitSet &refSamples={})
Definition MRICP.h:195
MRMESH_API ICP(const MeshOrPointsXf &flt, const MeshOrPointsXf &ref, const VertBitSet &fltSamples={}, const VertBitSet &refSamples={})
MRMESH_API float getMeanSqDistToPlane() const
computes root-mean-square deviation from points to target planes
MRMESH_API float getMeanSqDistToPoint() const
computes root-mean-square deviation between points
MRMESH_API ICP(const MeshOrPointsXf &flt, const MeshOrPointsXf &ref, float samplingVoxelSize)
MRMESH_API std::string getStatusInfo() const
MRMESH_API ICP(const MeshOrPoints &flt, const MeshOrPoints &ref, const AffineXf3f &fltXf, const AffineXf3f &refXf, float samplingVoxelSize)
Definition MRICP.h:205
MRMESH_API AffineXf3f autoSelectFloatXf()
MRMESH_API void setDistanceLimit(const float dist)
MRMESH_API void setFarDistFactor(const float factor)
Definition MRMeshOrPoints.h:18
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
ICPMode
The group of transformations, each with its own degrees of freedom.
Definition MRICPEnums.h:20
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
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:10
ICPExitType
Definition MRICPEnums.h:29
ICPMethod
The method how to update transformation from point pairs.
Definition MRICPEnums.h:6
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
Definition MRICP.h:17
friend bool operator==(const ICPPairData &, const ICPPairData &)=default
Vector3f srcNorm
normal in source point after transforming in world space
Definition MRICP.h:22
Vector3f tgtPoint
coordinates of the closest point on target after transforming in world space
Definition MRICP.h:25
Vector3f tgtNorm
normal in the target point after transforming in world space
Definition MRICP.h:28
float weight
weight of the pair (to prioritize over other pairs)
Definition MRICP.h:34
Vector3f srcPoint
coordinates of the source point after transforming in world space
Definition MRICP.h:19
float distSq
squared distance between source and target points
Definition MRICP.h:31
parameters of ICP algorithm
Definition MRICP.h:122
Vector3f fixedRotationAxis
Additional parameter for ICPMode::OrthogonalAxis and ICPMode::FixedAxis transformation groups.
Definition MRICP.h:155
Simple interface for pairs holder.
Definition MRICP.h:60
virtual size_t size() const =0
IPointPairs(const IPointPairs &)=default
IPointPairs(IPointPairs &&) noexcept=default
BitSet active
whether corresponding pair from vec must be considered during minimization
Definition MRICP.h:72
IPointPairs & operator=(const IPointPairs &)=default
IPointPairs()=default
an object and its transformation to global space with other objects
Definition MRMeshOrPoints.h:106
Definition MRICP.h:90
float rootMeanSqF() const
Definition MRICP.h:96
double sum
Definition MRICP.h:92
int num
Definition MRICP.h:91
Stores a pair of points: one samples on the source and the closest to it on the target.
Definition MRICP.h:41
float normalsAngleCos
cosine between normals in source and target points
Definition MRICP.h:50
VertId srcVertId
id of the source point
Definition MRICP.h:43
friend bool operator==(const PointPair &, const PointPair &)=default
VertId tgtCloseVert
Definition MRICP.h:47
bool tgtOnBd
true if if the closest point on target is located on the boundary (only for meshes)
Definition MRICP.h:53
Definition MRICP.h:76
virtual size_t size() const override
Definition MRICP.h:79
std::vector< PointPair > vec
vector of all point pairs both active and not
Definition MRICP.h:80
virtual const ICPPairData & operator[](size_t idx) const override
Definition MRICP.h:77
virtual ICPPairData & operator[](size_t idx) override
Definition MRICP.h:78