Skip to content

Commit 977844f

Browse files
authored
Merge pull request #16 from jcarpent/devel
Make EigenPy a library for Python
2 parents 780ce8f + a02f5cd commit 977844f

19 files changed

+940
-35
lines changed

CMakeLists.txt

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2015-2016 LAAS-CNRS
2+
# Copyright (c) 2015-2017 LAAS-CNRS
33
#
44
# This file is part of eigenpy.
55
# eigenpy is free software: you can redistribute it and/or
@@ -19,6 +19,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
1919
INCLUDE(cmake/base.cmake)
2020
INCLUDE(cmake/boost.cmake)
2121
INCLUDE(cmake/python.cmake)
22+
INCLUDE(cmake/ide.cmake)
2223

2324
SET(PROJECT_NAME eigenpy)
2425
SET(PROJECT_DESCRIPTION "Wrapping Eigen3 -- numpy")
@@ -45,6 +46,12 @@ IF(APPLE)
4546
ENDIF("${isSystemDir}" STREQUAL "-1")
4647
ENDIF(APPLE)
4748

49+
IF(WIN32)
50+
SET(LINK copy_if_different)
51+
ELSE(WIN32)
52+
SET(LINK create_symlink)
53+
ENDIF(WIN32)
54+
4855
# ----------------------------------------------------
4956
# --- OPTIONS ---------------------------------------
5057
# ----------------------------------------------------
@@ -73,61 +80,97 @@ INCLUDE_DIRECTORIES(${NUMPY_INCLUDE_DIRS})
7380
# ----------------------------------------------------
7481
# --- INCLUDE ----------------------------------------
7582
# ----------------------------------------------------
83+
SET(${PROJECT_NAME}_SOLVERS_HEADERS
84+
solvers/solvers.hpp
85+
solvers/preconditioners.hpp
86+
solvers/IterativeSolverBase.hpp
87+
solvers/LeastSquaresConjugateGradient.hpp
88+
solvers/ConjugateGradient.hpp
89+
solvers/SparseSolverBase.hpp
90+
solvers/BasicPreconditioners.hpp
91+
solvers/BFGSPreconditioners.hpp
92+
)
93+
7694
SET(HEADERS
77-
src/eigenpy.hpp
78-
src/exception.hpp
79-
src/details.hpp
80-
src/fwd.hpp
81-
src/map.hpp
82-
src/geometry.hpp
83-
src/memory.hpp
84-
src/registration.hpp
85-
src/angle-axis.hpp
86-
src/quaternion.hpp
95+
${${PROJECT_NAME}_SOLVERS_HEADERS}
96+
eigenpy.hpp
97+
exception.hpp
98+
details.hpp
99+
fwd.hpp
100+
map.hpp
101+
geometry.hpp
102+
memory.hpp
103+
registration.hpp
104+
angle-axis.hpp
105+
quaternion.hpp
87106
)
107+
88108
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy")
109+
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy/solvers")
89110
INCLUDE_DIRECTORIES(${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy)
90111

112+
#FOREACH(header ${HEADERS})
113+
# GET_FILENAME_COMPONENT(headerName ${header} NAME)
114+
# IF(WIN32)
115+
# execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
116+
# ${${PROJECT_NAME}_SOURCE_DIR}/${header}
117+
# ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/)
118+
# ELSE(WIN32)
119+
# execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
120+
# ${${PROJECT_NAME}_SOURCE_DIR}/${header}
121+
# ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${headerName})
122+
# ENDIF(WIN32)
123+
# INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/${header}
124+
# DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}
125+
# PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
126+
#ENDFOREACH(header)
127+
128+
SET(${PROJECT_NAME}_HEADERS)
91129
FOREACH(header ${HEADERS})
92130
GET_FILENAME_COMPONENT(headerName ${header} NAME)
93-
IF(WIN32)
94-
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
95-
${${PROJECT_NAME}_SOURCE_DIR}/${header}
96-
${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/)
97-
ELSE(WIN32)
98-
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
99-
${${PROJECT_NAME}_SOURCE_DIR}/${header}
100-
${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${headerName})
101-
ENDIF(WIN32)
102-
INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/${header}
103-
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}
104-
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
131+
GET_FILENAME_COMPONENT(headerPath ${header} PATH)
132+
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
133+
${${PROJECT_NAME}_SOURCE_DIR}/src/${header}
134+
${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${header})
135+
INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/src/${header}
136+
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/${headerPath}
137+
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
138+
LIST(APPEND ${PROJECT_NAME}_HEADERS src/${header})
105139
ENDFOREACH(header)
106140

107141
# ----------------------------------------------------
108142
# --- TARGETS ----------------------------------------
109143
# ----------------------------------------------------
144+
SET(${PROJECT_NAME}_SOLVERS_SOURCES
145+
src/solvers/preconditioners.cpp
146+
src/solvers/solvers.cpp
147+
)
110148
SET(${PROJECT_NAME}_SOURCES
149+
${${PROJECT_NAME}_SOLVERS_SOURCES}
111150
src/exception.cpp
112151
src/eigenpy.cpp
113152
src/angle-axis.cpp
114153
src/quaternion.cpp
115154
)
116155

117-
ADD_LIBRARY(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${HEADERS})
156+
ADD_LIBRARY(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS})
118157

119158
TARGET_LINK_BOOST_PYTHON(${PROJECT_NAME})
120159
PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME} eigen3)
121160
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
122161

162+
ADD_HEADER_GROUP(${PROJECT_NAME}_HEADERS)
163+
ADD_SOURCE_GROUP(${PROJECT_NAME}_SOURCES)
164+
123165
# ----------------------------------------------------
124-
# --- UNIT TEST --------------------------------------
166+
# --- PYTHON LIBRARY ---------------------------------
125167
# ----------------------------------------------------
126-
ADD_SUBDIRECTORY(unittest)
168+
ADD_SUBDIRECTORY(python)
127169

128170
# ----------------------------------------------------
129-
# --- EXECUTABLES ------------------------------------
171+
# --- UNIT TEST --------------------------------------
130172
# ----------------------------------------------------
173+
ADD_SUBDIRECTORY(unittest)
131174

132175
IF(EIGEN_NUMPY_ALIGNED)
133176
PKG_CONFIG_APPEND_CFLAGS("-DEIGENPY_ALIGNED")

python/CMakeLists.txt

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#
2+
# Copyright (c) 2017 CNRS
3+
#
4+
# This file is part of eigenpy
5+
# eigenpy is free software: you can redistribute it
6+
# and/or modify it under the terms of the GNU Lesser General Public
7+
# License as published by the Free Software Foundation, either version
8+
# 3 of the License, or (at your option) any later version.
9+
# eigenpy is distributed in the hope that it will be
10+
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
# General Lesser Public License for more details. You should have
13+
# received a copy of the GNU Lesser General Public License along with
14+
# eigenpy If not, see
15+
# <http://www.gnu.org/licenses/>.
16+
17+
MACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH)
18+
FOREACH(header ${HEADERS})
19+
GET_FILENAME_COMPONENT(headerName ${header} NAME)
20+
GET_FILENAME_COMPONENT(headerPath ${header} PATH)
21+
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
22+
${CMAKE_CURRENT_SOURCE_DIR}/${header}
23+
${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${SUBPATH}/${header})
24+
25+
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${header}
26+
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/${SUBPATH}/${headerPath}
27+
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
28+
ENDFOREACH(header)
29+
ENDMACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH)
30+
31+
# --- LIBRARY --- #
32+
SET(PYWRAP ${PROJECT_NAME}_pywrap)
33+
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}")
34+
35+
ADD_LIBRARY(${PYWRAP} SHARED main.cpp)
36+
TARGET_LINK_LIBRARIES(${PYWRAP} ${PROJECT_NAME})
37+
TARGET_LINK_BOOST_PYTHON(${PYWRAP})
38+
#IF(BUILD_WITH_COMMIT_VERSION)
39+
# TAG_LIBRARY_VERSION(${PYWRAP})
40+
#ENDIF(BUILD_WITH_COMMIT_VERSION)
41+
SET(${PYWRAP}_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB})
42+
43+
SET_PROPERTY(TARGET ${PYWRAP} PROPERTY LINKER_LANGUAGE CXX)
44+
IF(APPLE)
45+
# We need to change the extension for python bindings
46+
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES SUFFIX ".so")
47+
ENDIF(APPLE)
48+
49+
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES
50+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}")
51+
52+
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES PREFIX "")
53+
SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
54+
55+
INSTALL(TARGETS ${PYWRAP} DESTINATION ${${PYWRAP}_INSTALL_DIR})
56+
57+
## --- INSTALL SCRIPTS
58+
#SET(PYTHON_FILES
59+
# __init__.py
60+
# )
61+
#
62+
#FOREACH(python ${PYTHON_FILES})
63+
# GET_FILENAME_COMPONENT(pythonFile ${python} NAME)
64+
# EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
65+
# ${${PROJECT_NAME}_SOURCE_DIR}/python/scripts/${python}
66+
# ${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile})
67+
#
68+
# # Generate pyc file
69+
# EXECUTE_PROCESS(COMMAND
70+
# ${PYTHON_EXECUTABLE} -m py_compile
71+
# ${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile})
72+
# # Tag pyc file as generated.
73+
# SET_SOURCE_FILES_PROPERTIES(
74+
# "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c"
75+
# PROPERTIES GENERATED TRUE)
76+
#
77+
# # Clean generated files.
78+
# SET_PROPERTY(
79+
# DIRECTORY APPEND PROPERTY
80+
# ADDITIONAL_MAKE_CLEAN_FILES
81+
# "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c")
82+
#
83+
# INSTALL(FILES
84+
# "${${PROJECT_NAME}_SOURCE_DIR}/python/scripts/${python}"
85+
# "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c"
86+
# DESTINATION ${${PYWRAP}_INSTALL_DIR})
87+
#ENDFOREACH(python)
88+

python/main.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Copyright (c) 2017, Justin Carpentier, CNRS
3+
//
4+
// This file is part of eigenpy
5+
// eigenpy is free software: you can redistribute it
6+
// and/or modify it under the terms of the GNU Lesser General Public
7+
// License as published by the Free Software Foundation, either version
8+
// 3 of the License, or (at your option) any later version.
9+
//
10+
// eigenpy is distributed in the hope that it will be
11+
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12+
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
// General Lesser Public License for more details. You should have
14+
// received a copy of the GNU Lesser General Public License along with
15+
// eigenpy If not, see
16+
// <http://www.gnu.org/licenses/>.
17+
18+
#include "eigenpy/eigenpy.hpp"
19+
#include "eigenpy/geometry.hpp"
20+
#include "eigenpy/solvers/solvers.hpp"
21+
#include "eigenpy/solvers/preconditioners.hpp"
22+
23+
#include <iostream>
24+
#include <boost/python/scope.hpp>
25+
26+
using namespace eigenpy;
27+
28+
BOOST_PYTHON_MODULE(eigenpy)
29+
{
30+
enableEigenPy();
31+
exposeAngleAxis();
32+
exposeQuaternion();
33+
34+
{
35+
boost::python::scope solvers = boost::python::class_<SolversScope>("solvers");
36+
exposeSolvers();
37+
exposePreconditioners();
38+
}
39+
40+
}

python/scripts/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright (c) 2017 CNRS
3+
#
4+
# This file is part of eigenpy
5+
# eigenpy is free software: you can redistribute it
6+
# and/or modify it under the terms of the GNU Lesser General Public
7+
# License as published by the Free Software Foundation, either version
8+
# 3 of the License, or (at your option) any later version.
9+
# Pinocchio is distributed in the hope that it will be
10+
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
# General Lesser Public License for more details. You should have
13+
# received a copy of the GNU Lesser General Public License along with
14+
# eigenpy If not, see
15+
# <http://www.gnu.org/licenses/>.
16+
17+
import numpy as np
18+
from eigenpy import *

src/quaternion.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ namespace eigenpy
7171
"The [] operator numbers them differently, 0...4 for *x* *y* *z* *w*!"))
7272

7373
.add_property("x",
74-
(Scalar (Quaternion::*)()const)&Quaternion::x,
74+
&QuaternionVisitor::getCoeff<0>,
7575
&QuaternionVisitor::setCoeff<0>,"The x coefficient.")
7676
.add_property("y",
77-
(Scalar (Quaternion::*)()const)&Quaternion::y,
77+
&QuaternionVisitor::getCoeff<1>,
7878
&QuaternionVisitor::setCoeff<1>,"The y coefficient.")
7979
.add_property("z",
80-
(Scalar (Quaternion::*)()const)&Quaternion::z,
80+
&QuaternionVisitor::getCoeff<2>,
8181
&QuaternionVisitor::setCoeff<2>,"The z coefficient.")
8282
.add_property("w",
83-
(Scalar (Quaternion::*)()const)&Quaternion::w,
83+
&QuaternionVisitor::getCoeff<3>,
8484
&QuaternionVisitor::setCoeff<3>,"The w coefficient.")
8585

8686
// .def("isApprox",(bool (Quaternion::*)(const Quaternion &))&Quaternion::template isApprox<Quaternion>,
@@ -151,6 +151,9 @@ namespace eigenpy
151151
template<int i>
152152
static void setCoeff(Quaternion & self, Scalar value) { self.coeffs()[i] = value; }
153153

154+
template<int i>
155+
static Scalar getCoeff(Quaternion & self) { return self.coeffs()[i]; }
156+
154157
static Quaternion & setFromTwoVectors(Quaternion & self, const Vector3 & a, const Vector3 & b)
155158
{ return self.setFromTwoVectors(a,b); }
156159

0 commit comments

Comments
 (0)