3
3
#include " geometrycentral/pointcloud/point_cloud_heat_solver.h"
4
4
#include " geometrycentral/pointcloud/point_cloud_io.h"
5
5
#include " geometrycentral/pointcloud/point_position_geometry.h"
6
+ #include " geometrycentral/pointcloud/local_triangulation.h"
6
7
#include " geometrycentral/utilities/eigen_interop_helpers.h"
7
8
8
9
#include < pybind11/eigen.h>
11
12
12
13
#include " Eigen/Dense"
13
14
15
+
14
16
namespace py = pybind11;
15
17
16
18
using namespace geometrycentral ;
@@ -120,6 +122,59 @@ class PointCloudHeatSolverEigen {
120
122
std::unique_ptr<PointCloudHeatSolver> solver;
121
123
};
122
124
125
+ // A class that exposes the local pointcloud trinagulation to python
126
+ class PointCloudLocalTriangulation {
127
+ public:
128
+ PointCloudLocalTriangulation (DenseMatrix<double > points, bool withDegeneracyHeuristic) : withDegeneracyHeuristic(withDegeneracyHeuristic) {
129
+
130
+ // Construct the internal cloud and geometry
131
+ cloud.reset (new PointCloud (points.rows ()));
132
+ geom.reset (new PointPositionGeometry (*cloud));
133
+ for (size_t i = 0 ; i < cloud->nPoints (); i++) {
134
+ for (size_t j = 0 ; j < 3 ; j++) {
135
+ geom->positions [i][j] = points (i, j);
136
+ }
137
+ }
138
+ }
139
+
140
+
141
+ Eigen::Matrix<int , Eigen::Dynamic, Eigen::Dynamic> get_local_triangulation () {
142
+ PointData<std::vector<std::array<Point, 3 >>> local_triangulation = buildLocalTriangulations (*cloud, *geom, withDegeneracyHeuristic);
143
+
144
+ int max_neigh = 0 ;
145
+
146
+ size_t idx = 0 ;
147
+ for (Point v : cloud->points ()) {
148
+ max_neigh = std::max (max_neigh, static_cast <int >(local_triangulation[v].size ()));
149
+ if (idx != v.getIndex ()) {
150
+ py::print (" Error. Index of points not consistent. (Idx, v.getIndex) = " , idx, v.getIndex ());
151
+ }
152
+ idx++;
153
+ }
154
+
155
+ Eigen::Matrix<int , Eigen::Dynamic, Eigen::Dynamic> out (cloud->nPoints (), 3 * max_neigh);
156
+ out.setConstant (-1 );
157
+
158
+ for (Point v : cloud->points ()) {
159
+ int i = 0 ;
160
+ for (auto const &neighs : local_triangulation[v]) {
161
+ out (v.getIndex (), i + 0 ) = (int ) neighs[0 ].getIndex ();
162
+ out (v.getIndex (), i + 1 ) = (int ) neighs[1 ].getIndex ();
163
+ out (v.getIndex (), i + 2 ) = (int ) neighs[2 ].getIndex ();
164
+ i += 3 ;
165
+ }
166
+ }
167
+
168
+ return out;
169
+ }
170
+
171
+ private:
172
+ const bool withDegeneracyHeuristic;
173
+ std::unique_ptr<PointCloud> cloud;
174
+ std::unique_ptr<PointPositionGeometry> geom;
175
+ std::unique_ptr<PointCloudHeatSolver> solver;
176
+ };
177
+
123
178
124
179
// Actual binding code
125
180
// clang-format off
@@ -134,4 +189,8 @@ void bind_point_cloud(py::module& m) {
134
189
.def (" transport_tangent_vector" , &PointCloudHeatSolverEigen::transport_tangent_vector, py::arg (" source_point" ), py::arg (" vector" ))
135
190
.def (" transport_tangent_vectors" , &PointCloudHeatSolverEigen::transport_tangent_vectors, py::arg (" source_points" ), py::arg (" vectors" ))
136
191
.def (" compute_log_map" , &PointCloudHeatSolverEigen::compute_log_map, py::arg (" source_point" ));
192
+
193
+ py::class_<PointCloudLocalTriangulation>(m, " PointCloudLocalTriangulation" )
194
+ .def (py::init<DenseMatrix<double >, bool >())
195
+ .def (" get_local_triangulation" , &PointCloudLocalTriangulation::get_local_triangulation);
137
196
}
0 commit comments