From de625b118b8cbca40f0042bbfaaa162093517a81 Mon Sep 17 00:00:00 2001
From: Guillaume Cerutti <guillaume.cerutti@inria.fr>
Date: Mon, 25 Mar 2024 16:25:10 +0100
Subject: [PATCH] use eigen for native numpy output

---
 CMakeLists.txt                         |  1 +
 cpp/CMakeLists.txt                     |  1 +
 cpp/LabelledTetrahedralMesh.cpp        | 15 +++++++++++----
 cpp/LabelledTetrahedralMesh.h          |  5 +++--
 tests/test_tetrahedral_mesh.py         |  2 +-
 wrp/LabelledTetrahedralMeshWrapper.cpp |  1 +
 6 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bb824d5..4148520 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
 find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
 find_package(pybind11 CONFIG REQUIRED)
 find_package(CGAL REQUIRED COMPONENTS ImageIO)
+find_package(Eigen3 3.3 REQUIRED NO_MODULE)
 
 # make cache variables for install destinations
 include(GNUInstallDirs)
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index d560f02..2aed2d1 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -12,5 +12,6 @@ add_library(${PROJECT_NAME} SHARED
     ${${PROJECT_NAME}_HEADERS}
     ${${PROJECT_NAME}_SOURCES}
 )
+target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen)
 
 install(TARGETS ${PROJECT_NAME} DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
\ No newline at end of file
diff --git a/cpp/LabelledTetrahedralMesh.cpp b/cpp/LabelledTetrahedralMesh.cpp
index 0e4d977..e7ab4d2 100644
--- a/cpp/LabelledTetrahedralMesh.cpp
+++ b/cpp/LabelledTetrahedralMesh.cpp
@@ -1,12 +1,19 @@
 #include "LabelledTetrahedralMesh.h"
 
 
-std::vector< std::vector<double> > LabelledTetrahedralMesh::vertexPoints(void) const
+Eigen::ArrayX3d LabelledTetrahedralMesh::vertexPoints(void) const
 {
-    return this->_vertex_points;
+    Eigen::ArrayX3d vertex_points(this->_vertex_points.size(), 3);
+    for (int i=0; i<this->_vertex_points.size(); i++) {
+        for (int dim=0; dim<3; dim++) {
+            vertex_points(i, dim) = this->_vertex_points[i][dim];
+        }
+    }
+    return vertex_points;
 }
 
-void LabelledTetrahedralMesh::addPoint(const std::vector<double>& point)
+void LabelledTetrahedralMesh::addPoint(Eigen::Array3d point)
 {
-    this->_vertex_points.push_back(point);
+    std::vector<double> _point = std::vector<double> {point(0, 0), point(0, 1), point(0, 2)};
+    this->_vertex_points.push_back(_point);
 }
diff --git a/cpp/LabelledTetrahedralMesh.h b/cpp/LabelledTetrahedralMesh.h
index 16bf3cf..c6be404 100644
--- a/cpp/LabelledTetrahedralMesh.h
+++ b/cpp/LabelledTetrahedralMesh.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <vector>
+#include <Eigen/Dense>
 
 class LabelledTetrahedralMesh
 {
@@ -9,8 +10,8 @@ public:
     ~LabelledTetrahedralMesh(void) = default;
 
 public:
-    std::vector< std::vector<double> > vertexPoints(void) const;
-    void addPoint(const std::vector<double>& point);
+    Eigen::ArrayX3d vertexPoints(void) const;
+    void addPoint(Eigen::Array3d point);
 
 private:
     std::vector< std::vector<double> > _vertex_points;
diff --git a/tests/test_tetrahedral_mesh.py b/tests/test_tetrahedral_mesh.py
index 1ef3268..3ae1ffd 100644
--- a/tests/test_tetrahedral_mesh.py
+++ b/tests/test_tetrahedral_mesh.py
@@ -13,4 +13,4 @@ class TestTetrahedralMesh(unittest.TestCase):
         mesh = LabelledTetrahedralMesh()
         mesh.add_point([0, 0, 0])
         points = mesh.vertex_points()
-        assert len(points) == 1
+        assert points.shape == (1, 3)
diff --git a/wrp/LabelledTetrahedralMeshWrapper.cpp b/wrp/LabelledTetrahedralMeshWrapper.cpp
index 79ce03d..e07adf8 100644
--- a/wrp/LabelledTetrahedralMeshWrapper.cpp
+++ b/wrp/LabelledTetrahedralMeshWrapper.cpp
@@ -1,5 +1,6 @@
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h> // This header is needed to work with STL containers like std::vector
+#include <pybind11/eigen.h>
 
 #include "LabelledTetrahedralMesh.h"
 
-- 
GitLab