MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMesh/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 AffineXf3f getAligningXf( const PointToPlaneAligningTransform & p2pl,
118 ICPMode mode, float angleLimit, float scaleLimit, const Vector3f & fixedRotationAxis );
119
120
122{
124 ICPMethod method = ICPMethod::PointToPlane;
125
127 float p2plAngleLimit = PI_F / 6.0f; // [radians]
128
130 float p2plScaleLimit = 2;
131
133 float cosThreshold = 0.7f; // in [-1,1]
134
136 float distThresholdSq = 1.f; // [distance^2]
137
140 float farDistFactor = 3.f; // dimensionless
141
143 ICPMode icpMode = ICPMode::AnyRigidXf;
144
147
149 int iterLimit = 10;
150
152 int badIterStopCount = 3;
153
155 float exitVal = 0; // [distance]
156
158 bool mutualClosest = false;
159};
160
162MRMESH_API size_t deactivateFarPairs( IPointPairs& pairs, float maxDistSq );
163
166 const MeshOrPointsXf& src, const MeshOrPointsXf& tgt,
167 float cosThreshold, float distThresholdSq, bool mutualClosest );
168
172class [[nodiscard]] ICP
173{
174public:
182 ICP( const MeshOrPoints& flt, const MeshOrPoints& ref, const AffineXf3f& fltXf, const AffineXf3f& refXf,
183 const VertBitSet& fltSamples = {}, const VertBitSet& refSamples = {} ) : ICP( { flt, fltXf }, { ref, refXf }, fltSamples, refSamples ) {}
184 MRMESH_API ICP( const MeshOrPointsXf& flt, const MeshOrPointsXf& ref, const VertBitSet& fltSamples = {}, const VertBitSet& refSamples = {} );
185
192 MRMESH_API ICP( const MeshOrPoints& flt, const MeshOrPoints& ref, const AffineXf3f& fltXf, const AffineXf3f& refXf,
193 float samplingVoxelSize ) : ICP( { flt, fltXf }, { ref, refXf }, samplingVoxelSize ) {}
194 MRMESH_API ICP( const MeshOrPointsXf& flt, const MeshOrPointsXf& ref, float samplingVoxelSize );
195
197 void setParams(const ICPProperties& prop) { prop_ = prop; }
198 MRMESH_API void setCosineLimit(const float cos);
199 MRMESH_API void setDistanceLimit( const float dist );
200 MRMESH_API void setBadIterCount( const int iter );
201 MRMESH_API void setFarDistFactor(const float factor);
202
204 MRMESH_API void setFltSamples( const VertBitSet& fltSamples );
205 MRMESH_API void sampleFltPoints( float samplingVoxelSize );
206
208 MRMESH_API void setRefSamples( const VertBitSet& refSamples );
209 MRMESH_API void sampleRefPoints( float samplingVoxelSize );
210
212 void samplePoints( float samplingVoxelSize ) { sampleFltPoints( samplingVoxelSize ); sampleRefPoints( samplingVoxelSize ); }
213
214 [[deprecated]] MR_BIND_IGNORE void recomputeBitSet( float fltSamplingVoxelSize ) { sampleFltPoints( fltSamplingVoxelSize ); }
215
217 MRMESH_API void setXfs( const AffineXf3f& fltXf, const AffineXf3f& refXf );
218
220 MRMESH_API void setFloatXf( const AffineXf3f& fltXf );
221
226
229
230 [[nodiscard]] const ICPProperties& getParams() const { return prop_; }
231
232 [[nodiscard]] MRMESH_API std::string getStatusInfo() const; // returns status info string
233
235 [[nodiscard]] size_t getNumSamples() const { return MR::getNumSamples( flt2refPairs_ ) + MR::getNumSamples( ref2fltPairs_ ); }
236
238 [[nodiscard]] size_t getNumActivePairs() const { return MR::getNumActivePairs( flt2refPairs_ ) + MR::getNumActivePairs( ref2fltPairs_ ); }
239
241 [[nodiscard]] MRMESH_API float getMeanSqDistToPoint() const;
242
244 [[nodiscard]] MRMESH_API float getMeanSqDistToPlane() const;
245
247 [[nodiscard]] const PointPairs & getFlt2RefPairs() const { return flt2refPairs_; }
248
250 [[nodiscard]] const PointPairs & getRef2FltPairs() const { return ref2fltPairs_; }
251
254 [[nodiscard]] MRMESH_API AffineXf3f calculateTransformation();
255
256private:
257 MeshOrPointsXf flt_;
258 MeshOrPointsXf ref_;
259
260 ICPProperties prop_;
261
262 PointPairs flt2refPairs_;
263 PointPairs ref2fltPairs_;
264
265 ICPExitType resultType_{ ICPExitType::NotStarted };
266
268 void deactivatefarDistPairs_();
269
270 int iter_ = 0;
271 bool p2ptIter_();
272 bool p2plIter_();
273};
274
275} //namespace MR
constexpr A operator+(A a)
Definition MRImGuiVectorOperators.h:97
#define MRMESH_API
Definition MRMesh/MRMeshFwd.h:80
Definition MRMesh/MRBitSet.h:28
Definition MRMesh/MRICP.h:173
size_t getNumSamples() const
computes the number of samples able to form pairs
Definition MRMesh/MRICP.h:235
MRMESH_API void setCosineLimit(const float cos)
const ICPProperties & getParams() const
Definition MRMesh/MRICP.h:230
MRMESH_API AffineXf3f calculateTransformation()
void setParams(const ICPProperties &prop)
tune algorithm params before run calculateTransformation()
Definition MRMesh/MRICP.h:197
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 MRMesh/MRICP.h:212
const PointPairs & getRef2FltPairs() const
returns current pairs formed from samples on reference object and projections on floating object
Definition MRMesh/MRICP.h:250
const PointPairs & getFlt2RefPairs() const
returns current pairs formed from samples on floating object and projections on reference object
Definition MRMesh/MRICP.h:247
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 MRMesh/MRICP.h:238
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 MRMesh/MRICP.h:214
ICP(const MeshOrPoints &flt, const MeshOrPoints &ref, const AffineXf3f &fltXf, const AffineXf3f &refXf, const VertBitSet &fltSamples={}, const VertBitSet &refSamples={})
Definition MRMesh/MRICP.h:182
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 MRMesh/MRICP.h:192
MRMESH_API AffineXf3f autoSelectFloatXf()
MRMESH_API void setDistanceLimit(const float dist)
MRMESH_API void setFarDistFactor(const float factor)
Definition MRMesh/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 MRMesh/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 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 MRMesh/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 MRMesh/MRICP.h:108
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:10
ICPExitType
Definition MRICPEnums.h:29
MRMESH_API AffineXf3f 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...
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 MRMesh/MRICP.h:17
friend bool operator==(const ICPPairData &, const ICPPairData &)=default
Vector3f srcNorm
normal in source point after transforming in world space
Definition MRMesh/MRICP.h:22
Vector3f tgtPoint
coordinates of the closest point on target after transforming in world space
Definition MRMesh/MRICP.h:25
Vector3f tgtNorm
normal in the target point after transforming in world space
Definition MRMesh/MRICP.h:28
float weight
weight of the pair (to prioritize over other pairs)
Definition MRMesh/MRICP.h:34
Vector3f srcPoint
coordinates of the source point after transforming in world space
Definition MRMesh/MRICP.h:19
float distSq
squared distance between source and target points
Definition MRMesh/MRICP.h:31
Definition MRMesh/MRICP.h:122
Vector3f fixedRotationAxis
If this vector is not zero then rotation is allowed relative to this axis only.
Definition MRMesh/MRICP.h:146
Simple interface for pairs holder.
Definition MRMesh/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 MRMesh/MRICP.h:72
IPointPairs & operator=(const IPointPairs &)=default
IPointPairs()=default
an object and its transformation to global space with other objects
Definition MRMesh/MRMeshOrPoints.h:101
Definition MRMesh/MRICP.h:90
float rootMeanSqF() const
Definition MRMesh/MRICP.h:96
double sum
Definition MRMesh/MRICP.h:92
int num
Definition MRMesh/MRICP.h:91
Stores a pair of points: one samples on the source and the closest to it on the target.
Definition MRMesh/MRICP.h:41
float normalsAngleCos
cosine between normals in source and target points
Definition MRMesh/MRICP.h:50
VertId srcVertId
id of the source point
Definition MRMesh/MRICP.h:43
friend bool operator==(const PointPair &, const PointPair &)=default
VertId tgtCloseVert
Definition MRMesh/MRICP.h:47
bool tgtOnBd
true if if the closest point on target is located on the boundary (only for meshes)
Definition MRMesh/MRICP.h:53
Definition MRMesh/MRICP.h:76
virtual size_t size() const override
Definition MRMesh/MRICP.h:79
std::vector< PointPair > vec
vector of all point pairs both active and not
Definition MRMesh/MRICP.h:80
virtual const ICPPairData & operator[](size_t idx) const override
Definition MRMesh/MRICP.h:77
virtual ICPPairData & operator[](size_t idx) override
Definition MRMesh/MRICP.h:78