Skip to content

Commit e8b1662

Browse files
committed
Add Cloud2CloudDistance
1 parent 5fd6533 commit e8b1662

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

wrapper/cccorelib/src/DistanceComputationTools.cpp

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <pybind11/pybind11.h>
1919

2020
#include <DistanceComputationTools.h>
21+
#include <ReferenceCloud.h>
22+
#include <ScalarField.h>
23+
#include <GenericIndexedCloudPersist.h>
24+
#include <PointCloud.h>
2125

2226
namespace py = pybind11;
2327
using namespace pybind11::literals;
@@ -27,6 +31,227 @@ void define_DistanceComputationTools(py::module &cccorelib)
2731
py::class_<CCCoreLib::DistanceComputationTools> DistanceComputationTools(cccorelib,
2832
"DistanceComputationTools");
2933

34+
py::class_<CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams>(
35+
DistanceComputationTools, "Cloud2CloudDistancesComputationParams")
36+
.def(py::init<>())
37+
.def_readwrite(
38+
"octreeLevel",
39+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::octreeLevel,
40+
R"doc(
41+
Level of subdivision of the octree at witch to apply the distance computation algorithm
42+
If set to 0 (default) the algorithm will try to guess the best level automatically.
43+
)doc")
44+
.def_readwrite(
45+
"maxSearchDist",
46+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::maxSearchDist,
47+
R"doc(
48+
Maximum search distance (true distance won't be computed if greater)
49+
Set to -1 to deactivate (default).
50+
51+
Not compatible with closest point set determination (see CPSet)
52+
)doc")
53+
.def_readwrite(
54+
"multiThread",
55+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::multiThread,
56+
R"doc(
57+
Whether to use multi-thread or single thread mode
58+
59+
If maxSearchDist > 0, single thread mode will be forced.
60+
)doc")
61+
.def_readwrite(
62+
"maxThreadCount",
63+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::maxThreadCount,
64+
R"doc(
65+
Maximum number of threads to use (0 = max)
66+
)doc")
67+
.def_readwrite(
68+
"localModel",
69+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::localModel,
70+
R"doc(
71+
Type of local 3D modeling to use
72+
73+
Default: NO_MODEL. Otherwise see CC_LOCAL_MODEL_TYPES.
74+
)doc")
75+
.def_readwrite("useSphericalSearchForLocalModel",
76+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::
77+
useSphericalSearchForLocalModel,
78+
R"doc(
79+
Whether to use a fixed number of neighbors or a (sphere) radius for nearest neighbors search
80+
81+
For local models only (i.e. ignored if localModel = NO_MODEL).
82+
)doc")
83+
.def_readwrite(
84+
"kNNForLocalModel",
85+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::kNNForLocalModel,
86+
R"doc(
87+
Number of neighbors for nearest neighbors search (local model)
88+
89+
For local models only (i.e. ignored if localModel = NO_MODEL).
90+
Ignored if useSphericalSearchForLocalModel is true.
91+
)doc")
92+
.def_readwrite(
93+
"radiusForLocalModel",
94+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::radiusForLocalModel,
95+
R"doc(
96+
Radius for nearest neighbors search (local model)
97+
98+
For local models only (i.e. ignored if localModel = NO_MODEL).
99+
Ignored if useSphericalSearchForLocalModel is true.
100+
)doc")
101+
.def_readwrite("reuseExistingLocalModels",
102+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::
103+
reuseExistingLocalModels,
104+
R"doc(
105+
Whether to use an approximation for local model computation
106+
107+
For local models only (i.e. ignored if localModel = NO_MODEL).
108+
Ignored if useSphericalSearchForLocalModel is true.
109+
)doc")
110+
.def_readwrite("CPSet",
111+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::CPSet,
112+
R"doc(
113+
Container of (references to) points to store the "Closest Point Set"
114+
115+
The Closest Point Set corresponds to (the reference to) each compared point's closest neighbor.
116+
Not compatible with max search distance (see maxSearchDist)
117+
)doc")
118+
.def_property(
119+
"splitDistances",
120+
[](CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams &self) {
121+
return py::make_tuple(self.splitDistances[0], self.splitDistances[1], self.splitDistances[2]);
122+
},
123+
[](CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams &self,
124+
const py::sequence &list)
125+
{
126+
self.splitDistances[0] = list[0].cast<CCCoreLib::ScalarField *>();
127+
self.splitDistances[1] = list[1].cast<CCCoreLib::ScalarField *>();
128+
self.splitDistances[2] = list[2].cast<CCCoreLib::ScalarField *>();
129+
},
130+
R"doc(Split distances (one scalar field per dimension: X, Y and Z))doc")
131+
.def_readwrite(
132+
"resetFormerDistances",
133+
&CCCoreLib::DistanceComputationTools::Cloud2CloudDistancesComputationParams::resetFormerDistances,
134+
R"doc(
135+
Whether to keep the existing distances as is (if any) or not
136+
137+
By default, any previous distances/scalar values stored in the 'enabled' scalar field will be
138+
reset before computing them again.
139+
)doc");
140+
141+
DistanceComputationTools.def_static("computeCloud2CloudDistances",
142+
&CCCoreLib::DistanceComputationTools::computeCloud2CloudDistances,
143+
"compareCloud"_a,
144+
"referenceCloud"_a,
145+
"params"_a,
146+
"progressCb"_a = nullptr,
147+
"compOctree"_a = nullptr,
148+
"refOctree"_a = nullptr,
149+
R"doc(
150+
Computes the 'nearest neighbor' distances between two point clouds (formerly named "Hausdorff distance")
151+
152+
The main algorithm and its different versions (with or without local modeling) are described in
153+
Daniel Girardeau-Montaut's PhD manuscript (Chapter 2, section 2.3). It is the standard way to compare
154+
directly two dense point clouds.
155+
156+
The current scalar field of the compared cloud should be enabled. By default it will be reset to
157+
NAN_VALUE but one can avoid this by defining the Cloud2CloudDistancesComputationParams::resetFormerDistances
158+
parameters to false. But even in this case, only values above Cloud2CloudDistancesComputationParams::maxSearchDist
159+
will remain untouched.
160+
161+
Max search distance (Cloud2CloudDistancesComputationParams::maxSearchDist > 0) is not compatible with the
162+
determination of the Closest Point Set (Cloud2CloudDistancesComputationParams::CPSet)
163+
164+
Parameters
165+
----------
166+
comparedCloud:the compared cloud (the distances will be computed for each point of this cloud)
167+
referenceCloud: the reference cloud (the nearest neigbhor will be determined among these points)
168+
params: distance computation parameters
169+
progressCb:the client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback)
170+
compOctree:the pre-computed octree of the compared cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0)
171+
refOctree: the pre-computed octree of the reference cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0)
172+
173+
Returns
174+
-------
175+
0 if ok, a negative value otherwise
176+
)doc");
177+
178+
179+
py::class_<CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams>(cccorelib, "Cloud2MeshDistancesComputationParams", R"doc(
180+
Cloud-to-mesh distances computation parameters
181+
)doc")
182+
.def_readwrite("octreeLevel", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::octreeLevel, R"doc(
183+
The level of subdivision of the octree at witch to apply the algorithm
184+
)doc")
185+
.def_readwrite("maxSearchDist", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::maxSearchDist, R"doc(
186+
Max search distance (acceleration)
187+
188+
Default value: 0. If greater than 0, then the algorithm won't compute distances over this value
189+
)doc")
190+
.def_readwrite("useDistanceMap", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::useDistanceMap, R"doc(
191+
Use distance map (acceleration)
192+
193+
If true the distances will be approximated by a Distance Transform.
194+
195+
Incompatible with signed distances or Closest Point Set.
196+
)doc")
197+
.def_readwrite("signedDistances", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::signedDistances, R"doc(
198+
Whether to compute signed distances or not
199+
200+
If true, the computed distances will be signed (in this case, the Distance Transform can't be used
201+
and therefore useDistanceMap will be ignored)
202+
)doc")
203+
.def_readwrite("flipNormals", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::flipNormals, R"doc(
204+
Whether triangle normals should be computed in the 'direct' order (true) or 'indirect' (false)
205+
)doc")
206+
.def_readwrite("multiThread", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::multiThread, R"doc(
207+
Whether to use multi-thread or single thread mode (if maxSearchDist > 0, single thread mode is forced)
208+
)doc")
209+
.def_readwrite("maxThreadCount", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::maxThreadCount, R"doc(
210+
Maximum number of threads to use (0 = max)
211+
)doc")
212+
.def_readwrite("CPSet", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::CPSet, R"doc(
213+
Cloud to store the Closest Point Set
214+
215+
The cloud should be initialized but empty on input. It will have the same size as the compared cloud on output.
216+
217+
Not compatible with maxSearchDist > 0.
218+
)doc")
219+
.def_readwrite("robust", &CCCoreLib::DistanceComputationTools::Cloud2MeshDistancesComputationParams::robust, R"doc(
220+
Whether to compute distances in a robust way (trying to detect edge cases)
221+
222+
Computation will be slightly slower, and a little bit more memory will be required
223+
)doc")
224+
.def(py::init<>());
225+
226+
DistanceComputationTools.def_static("computeCloud2MeshDistances",
227+
&CCCoreLib::DistanceComputationTools::computeCloud2MeshDistances,
228+
"pointCloud"_a,
229+
"mesh"_a,
230+
"params"_a,
231+
"progressCb"_a = nullptr,
232+
"cloudOctree"_a = nullptr,
233+
R"doc(
234+
Computes the distances between a point cloud and a mesh
235+
236+
The algorithm, inspired from METRO by Cignoni et al., is described
237+
in Daniel Girardeau-Montaut's PhD manuscript (Chapter 2, section 2.2).
238+
It is the general way to compare a point cloud with a triangular mesh.
239+
240+
Parameters
241+
----------
242+
pointCloud: the compared cloud (the distances will be computed on these points)
243+
mesh: the reference mesh (the distances will be computed relatively to its triangles)
244+
params: distance computation parameters
245+
progressCb:the client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback)
246+
cloudOctree: the pre-computed octree of the compared cloud
247+
(warning: its bounding box should be equal to the union of both point cloud and mesh bbs
248+
and it should be cubical - it is automatically computed if 0)
249+
250+
Returns
251+
-------
252+
0 if ok, a negative value otherwise
253+
)doc");
254+
30255
py::enum_<CCCoreLib::DistanceComputationTools::ERROR_MEASURES>(DistanceComputationTools,
31256
"ERRPOR_MEASURES")
32257
.value("RMS", CCCoreLib::DistanceComputationTools::ERROR_MEASURES::RMS)

0 commit comments

Comments
 (0)