ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
cccorelib.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include <limits>
9 #include <pybind11/functional.h>
10 #include <pybind11/numpy.h>
11 #include <pybind11/pybind11.h>
12 #include <pybind11/stl.h>
13 #include <pybind11/stl_bind.h>
14 
15 #include <AutoSegmentationTools.h>
16 #include <BoundingBox.h>
17 #include <CVGeom.h>
18 #include <CVPointCloud.h>
22 #include <Grid3D.h>
23 #include <ReferenceCloud.h>
24 #include <TrueKdTree.h>
25 
26 namespace py = pybind11;
27 using namespace pybind11::literals;
28 
29 #include "cccorelib.h"
30 
31 void define_AutoSegmentationTools(py::module &);
32 
33 void define_BoundingBox(py::module &);
34 
35 void define_CCGeom(py::module &);
36 
37 void define_CCMath(py::module &);
38 
39 void define_CCConst(py::module &);
40 
41 void define_CCShareable(py::module &);
42 
43 void define_ChamferDistanceTransform(py::module &);
44 
45 void define_CloudSamplingTools(py::module &);
46 
47 void define_DgmOctree(py::module &);
48 
49 void define_DgmOctreeReferenceCloud(py::module &);
50 
51 void define_GenericCloud(py::module &);
52 
53 void define_TrueKdTree(py::module &);
54 
55 void define_GenericDistribution(py::module &);
56 
57 void define_StatisticalTestingTools(py::module &);
58 
59 void define_GenericTriangle(py::module &);
60 
61 void define_SimpleTriangle(py::module &);
62 
63 void define_GenericIndexedCloud(py::module &);
64 
65 void define_GenericProgressCallback(py::module &);
66 
67 void define_GeometricalAnalysisTools(py::module &);
68 
69 void define_GenericMesh(py::module &);
70 
71 void define_SimpleMesh(py::module &cccorelib);
72 
73 void define_GenericIndexedMesh(py::module &);
74 
75 void define_WeibullDistribution(py::module &);
76 
77 void define_ScalarField(py::module &cccorelib);
78 
79 void define_ScalarFieldTools(py::module &cccorelib);
80 
81 void define_RegistrationTools(py::module &cccorelib);
82 
83 void define_ReferenceCloud(py::module &cccorelib);
84 
85 void define_Polyline(py::module &cccorelib);
86 
87 void define_PointProjectionTools(py::module &cccorelib);
88 
89 void define_GenericIndexedCloudPersist(py::module &cccorelib);
90 
91 void define_PointCloud(py::module &cccorelib);
92 
93 void define_GenericOctree(py::module &cccorelib);
94 
95 void define_KdTree(py::module &cccorelib);
96 
97 void define_LocalModel(py::module &cccorelib);
98 
99 void define_ManualSegmentationTools(py::module &);
100 
101 void define_CCMiscTools(py::module &);
102 
103 void define_NormalDistribution(py::module &);
104 
105 void define_Delaunay2dMesh(py::module &);
106 
107 void define_ErrorFunction(py::module &);
108 
109 void define_FastMarching(py::module &);
110 
111 void define_DistanceComputationTools(py::module &);
112 
113 /* example of return a numpy float, in case we ever need this
114 py::object return_npy_float()
115 {
116 
117  // #include <numpy/ndarrayobject.h> get path from numpy.get_include()
118  if (![]() { import_array() }()) // should be done in module init
119  {
120  throw std::runtime_error("init failed");
121  }
122 
123  float a{1.1};
124  PyArray_Descr *descr = PyArray_DescrFromType(NPY_FLOAT32);
125 
126  PyObject *ret1 = PyArray_Scalar(&a, descr, nullptr);
127  return py::object(py::handle(ret1), false);
128 }
129 */
130 
132 {
133  public:
134  explicit NumpyCloud(const py::array &array)
135  {
136 
137  py::list names;
138 #if ((PYBIND11_VERSION_MAJOR > 2) || (PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR > 11))
139  // The "names" field is no longer available in Descr_Proxy struct,
140  // but it is available on both Descr1_Proxy and Descr2_Proxy structs
141 
142  // Get the currrent numpy version
143  // Maybe it would be worth having a dedicated function in the long run.
144  py::module_ numpy = py::module_::import("numpy");
145  py::str version_string = numpy.attr("__version__");
146 
147  py::module_ numpy_lib = py::module_::import("numpy.lib");
148  py::object numpy_version = numpy_lib.attr("NumpyVersion")(version_string);
149  int major_version = numpy_version.attr("major").cast<int>();
150 
151  if (major_version < 2)
152  {
153  const py::detail::PyArrayDescr1_Proxy *descr =
154  py::detail::array_descriptor1_proxy(py::detail::array_proxy(array.ptr())->descr);
155  names = py::cast<py::list>(descr->names);
156  }
157  else
158  {
159  const py::detail::PyArrayDescr2_Proxy *descr =
160  py::detail::array_descriptor2_proxy(py::detail::array_proxy(array.ptr())->descr);
161  names = py::cast<py::list>(descr->names);
162  }
163 #else
164  const py::detail::PyArrayDescr_Proxy *descr =
165  py::detail::array_descriptor_proxy(py::detail::array_proxy(array.ptr())->descr);
166  names = py::cast<py::list>(descr->names);
167 #endif
168  if (names.size() >= 3)
169  {
170  m_xs = array[names[0]].cast<py::array_t<PointCoordinateType>>();
171  m_ys = array[names[1]].cast<py::array_t<PointCoordinateType>>();
172  m_zs = array[names[2]].cast<py::array_t<PointCoordinateType>>();
173  }
174  else
175  {
176  m_xs = array[py::make_tuple(py::ellipsis(), 0)].cast<py::array_t<PointCoordinateType>>();
177  m_ys = array[py::make_tuple(py::ellipsis(), 1)].cast<py::array_t<PointCoordinateType>>();
178  m_zs = array[py::make_tuple(py::ellipsis(), 2)].cast<py::array_t<PointCoordinateType>>();
179  }
180  // py::dict fields = py::cast<py::dict>(descr->fields);
181  // py::print(fields);
182  }
183 
184  const CCVector3 *getPoint(unsigned int index) const override
185  {
186  m_pts.x = m_xs.at(index);
187  m_pts.y = m_ys.at(index);
188  m_pts.z = m_zs.at(index);
189  return &m_pts;
190  }
191  void getPoint(unsigned int index, CCVector3 &P) const override
192  {
193  P.x = m_xs.at(index);
194  P.y = m_ys.at(index);
195  P.z = m_zs.at(index);
196  }
197  unsigned int size() const override
198  {
199  assert(m_xs.size() <= std::numeric_limits<unsigned int>::max());
200  assert(m_xs.size() >= std::numeric_limits<unsigned int>::min());
201  return static_cast<unsigned int>(m_xs.size());
202  }
203 
204  void forEach(genericPointAction action) override
205  {
206  auto xs = m_xs.mutable_unchecked<1>();
207  auto ys = m_xs.mutable_unchecked<1>();
208  auto zs = m_xs.mutable_unchecked<1>();
209 
210  CCVector3 p;
211  for (size_t i{0}; i < size(); ++i)
212  {
213  p.x = xs(i);
214  p.y = ys(i);
215  p.z = zs(i);
216 
217  ScalarType todoScalar = 0;
218  action(p, todoScalar);
219  };
220  }
221  void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
222  {
223  const auto updateMinMax = [&bbMin, &bbMax](const CCVector3 &point, ScalarType _s)
224  {
225  bbMin.x = std::min(point.x, bbMin.x);
226  bbMin.y = std::min(point.y, bbMin.y);
227  bbMin.z = std::min(point.z, bbMin.z);
228  bbMax.x = std::max(point.x, bbMax.x);
229  bbMax.y = std::max(point.y, bbMax.y);
230  bbMax.z = std::max(point.z, bbMax.z);
231  };
232 
233  forEach(updateMinMax);
234  }
235  void placeIteratorAtBeginning() override {}
236  const CCVector3 *getNextPoint() override
237  {
238  return &m_pts;
239  }
240  bool enableScalarField() override
241  {
242  return false;
243  }
244  bool isScalarFieldEnabled() const override
245  {
246  return false;
247  }
248  void setPointScalarValue(unsigned int pointIndex, ScalarType value) override {}
249  ScalarType getPointScalarValue(unsigned int pointIndex) const override
250  {
251  return 0;
252  }
253 
254  private:
255  mutable CCVector3 m_pts{};
256  py::array_t<PointCoordinateType> m_xs;
257  py::array_t<PointCoordinateType> m_ys;
258  py::array_t<PointCoordinateType> m_zs;
259 };
260 
261 void define_cccorelib(py::module &m)
262 {
264 
265  define_CCGeom(m);
266  define_CCMath(m);
267  define_CCConst(m);
269  py::bind_vector<std::vector<CCVector2>>(m, "CCVector2List");
270 
272 
277 
283  define_Polyline(m);
284  py::bind_vector<cloudViewer::ReferenceCloudContainer>(m, "ReferenceCloudContainer");
285 
289 
291 
293  define_DgmOctree(m);
295 
298 
301 
313 
314  define_KdTree(m);
316 
318 
319  py::class_<NumpyCloud, cloudViewer::GenericIndexedCloud, cloudViewer::GenericCloud>(m, "NumpyCloud")
320  .def(py::init<py::array>());
321  // .def("forEach", &NumpyCloud::forEach)
322  // .def("getBoundingBox", &NumpyCloud::getBoundingBox);
323 
324  // Conjugate Gradient
325  // Delaunay2dMesh
326  // DistanceComputationTools
327  // Error function
328  // FastMarching
329  // FastMarchingFor...
330  // RayAndBox
331  // SaitoSquared...
332  // SquareMatrix
333 }
334 
335 #ifdef USE_EMBEDDED_MODULES
336 #include <pybind11/embed.h>
337 PYBIND11_EMBEDDED_MODULE(cccorelib, m)
338 {
339  define_cccorelib(m);
340 }
341 #else
342 PYBIND11_MODULE(cccorelib, m)
343 {
344  define_cccorelib(m);
345 }
346 #endif
int size
PYBIND11_EMBEDDED_MODULE(ccinternals, m)
Definition: Runtime.cpp:117
void define_WeibullDistribution(py::module &)
void define_ReferenceCloud(py::module &cccorelib)
void define_CCMiscTools(py::module &)
Definition: CCMiscTools.cpp:15
void define_GenericTriangle(py::module &)
void define_cccorelib(py::module &m)
Definition: cccorelib.cpp:261
void define_DgmOctreeReferenceCloud(py::module &)
void define_KdTree(py::module &cccorelib)
Definition: KdTree.cpp:20
void define_GenericCloud(py::module &)
void define_SimpleTriangle(py::module &)
void define_ManualSegmentationTools(py::module &)
void define_DistanceComputationTools(py::module &)
void define_NormalDistribution(py::module &)
void define_GenericIndexedMesh(py::module &)
void define_GenericDistribution(py::module &)
void define_PointProjectionTools(py::module &cccorelib)
void define_GenericIndexedCloud(py::module &)
void define_ChamferDistanceTransform(py::module &)
void define_GeometricalAnalysisTools(py::module &)
void define_Polyline(py::module &cccorelib)
Definition: Polyline.cpp:15
void define_FastMarching(py::module &)
void define_AutoSegmentationTools(py::module &)
PYBIND11_MODULE(cccorelib, m)
Definition: cccorelib.cpp:342
void define_CCGeom(py::module &)
Definition: CCGeom.cpp:138
void define_StatisticalTestingTools(py::module &)
void define_ScalarFieldTools(py::module &cccorelib)
void define_TrueKdTree(py::module &)
Definition: TrueKdTree.cpp:22
void define_PointCloud(py::module &cccorelib)
Definition: PointCloud.cpp:14
void define_SimpleMesh(py::module &cccorelib)
Definition: SimpleMesh.cpp:18
void define_LocalModel(py::module &cccorelib)
Definition: LocalModel.cpp:15
void define_RegistrationTools(py::module &cccorelib)
void define_GenericProgressCallback(py::module &)
void define_BoundingBox(py::module &)
Definition: BoundingBox.cpp:16
void define_CloudSamplingTools(py::module &)
void define_ErrorFunction(py::module &)
void define_DgmOctree(py::module &)
Definition: DgmOctree.cpp:21
void define_CCMath(py::module &)
Definition: CCMath.cpp:15
void define_GenericMesh(py::module &)
Definition: GenericMesh.cpp:16
void define_CCShareable(py::module &)
Definition: CCShareable.cpp:17
void define_CCConst(py::module &)
Definition: CCConst.cpp:15
void define_GenericOctree(py::module &cccorelib)
void define_ScalarField(py::module &cccorelib)
void define_Delaunay2dMesh(py::module &)
void define_GenericIndexedCloudPersist(py::module &cccorelib)
unsigned int size() const override
Returns the number of points.
Definition: cccorelib.cpp:197
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
Returns the cloud bounding box.
Definition: cccorelib.cpp:221
void placeIteratorAtBeginning() override
Sets the cloud iterator at the beginning.
Definition: cccorelib.cpp:235
const CCVector3 * getPoint(unsigned int index) const override
Definition: cccorelib.cpp:184
const CCVector3 * getNextPoint() override
Returns the next point (relatively to the global iterator position)
Definition: cccorelib.cpp:236
bool enableScalarField() override
Enables the scalar field associated to the cloud.
Definition: cccorelib.cpp:240
void forEach(genericPointAction action) override
Fast iteration mechanism.
Definition: cccorelib.cpp:204
void setPointScalarValue(unsigned int pointIndex, ScalarType value) override
Definition: cccorelib.cpp:248
NumpyCloud(const py::array &array)
Definition: cccorelib.cpp:134
ScalarType getPointScalarValue(unsigned int pointIndex) const override
Definition: cccorelib.cpp:249
bool isScalarFieldEnabled() const override
Returns true if the scalar field is enabled, false otherwise.
Definition: cccorelib.cpp:244
void getPoint(unsigned int index, CCVector3 &P) const override
Definition: cccorelib.cpp:191
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
std::function< void(const CCVector3 &, ScalarType &)> genericPointAction
Generic function applied to a point (used by foreach)
Definition: GenericCloud.h:30
A generic 3D point cloud with index-based point access.
int min(int a, int b)
Definition: cutil_math.h:53
int max(int a, int b)
Definition: cutil_math.h:48
Definition: lsd.c:149
int y
Definition: lsd.c:149
int x
Definition: lsd.c:149