Skip to content

Commit dffd691

Browse files
authored
Merge pull request #153 from jcarpent/devel
Fix potential bug introduced in 2.0.0
2 parents 27e7995 + 3e93257 commit dffd691

File tree

6 files changed

+147
-119
lines changed

6 files changed

+147
-119
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ SET(${PROJECT_NAME}_HEADERS
109109
include/eigenpy/geometry.hpp
110110
include/eigenpy/geometry-conversion.hpp
111111
include/eigenpy/memory.hpp
112+
include/eigenpy/numpy-type.hpp
112113
include/eigenpy/registration.hpp
113114
include/eigenpy/angle-axis.hpp
114115
include/eigenpy/quaternion.hpp

cmake

Submodule cmake updated 1 file

include/eigenpy/details.hpp

Lines changed: 1 addition & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <iostream>
1414

1515
#include "eigenpy/eigenpy.hpp"
16+
#include "eigenpy/numpy-type.hpp"
1617
#include "eigenpy/registration.hpp"
1718
#include "eigenpy/map.hpp"
1819
#include "eigenpy/exception.hpp"
@@ -64,124 +65,6 @@ namespace eigenpy
6465

6566
namespace bp = boost::python;
6667

67-
enum NP_TYPE
68-
{
69-
MATRIX_TYPE,
70-
ARRAY_TYPE
71-
};
72-
73-
struct NumpyType
74-
{
75-
76-
static NumpyType & getInstance()
77-
{
78-
static NumpyType instance;
79-
return instance;
80-
}
81-
82-
operator bp::object () { return CurrentNumpyType; }
83-
84-
bp::object make(PyArrayObject* pyArray, bool copy = false)
85-
{ return make((PyObject*)pyArray,copy); }
86-
87-
bp::object make(PyObject* pyObj, bool copy = false)
88-
{
89-
bp::object m;
90-
if(PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(CurrentNumpyType.ptr()),NumpyMatrixType))
91-
m = NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy);
92-
// m = NumpyAsMatrixObject(bp::object(bp::handle<>(pyObj)));
93-
else if(PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(CurrentNumpyType.ptr()),NumpyArrayType))
94-
m = bp::object(bp::handle<>(pyObj)); // nothing to do here
95-
96-
Py_INCREF(m.ptr());
97-
return m;
98-
}
99-
100-
static void setNumpyType(bp::object & obj)
101-
{
102-
PyTypeObject * obj_type = PyType_Check(obj.ptr()) ? reinterpret_cast<PyTypeObject*>(obj.ptr()) : obj.ptr()->ob_type;
103-
if(PyType_IsSubtype(obj_type,getInstance().NumpyMatrixType))
104-
switchToNumpyMatrix();
105-
else if(PyType_IsSubtype(obj_type,getInstance().NumpyArrayType))
106-
switchToNumpyArray();
107-
}
108-
109-
static void switchToNumpyArray()
110-
{
111-
getInstance().CurrentNumpyType = getInstance().NumpyArrayObject;
112-
getType() = ARRAY_TYPE;
113-
}
114-
115-
static void switchToNumpyMatrix()
116-
{
117-
getInstance().CurrentNumpyType = getInstance().NumpyMatrixObject;
118-
getType() = MATRIX_TYPE;
119-
}
120-
121-
static NP_TYPE & getType()
122-
{
123-
static NP_TYPE np_type;
124-
return np_type;
125-
}
126-
127-
static bp::object getNumpyType()
128-
{
129-
return getInstance().CurrentNumpyType;
130-
}
131-
132-
static const PyTypeObject * getNumpyMatrixType()
133-
{
134-
return getInstance().NumpyMatrixType;
135-
}
136-
137-
static const PyTypeObject * getNumpyArrayType()
138-
{
139-
return getInstance().NumpyArrayType;
140-
}
141-
142-
static bool isMatrix()
143-
{
144-
return PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(getInstance().CurrentNumpyType.ptr()),
145-
getInstance().NumpyMatrixType);
146-
}
147-
148-
static bool isArray()
149-
{
150-
return PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(getInstance().CurrentNumpyType.ptr()),
151-
getInstance().NumpyArrayType);
152-
}
153-
154-
protected:
155-
NumpyType()
156-
{
157-
pyModule = bp::import("numpy");
158-
#if PY_MAJOR_VERSION >= 3
159-
// TODO I don't know why this Py_INCREF is necessary.
160-
// Without it, the destructor of NumpyType SEGV sometimes.
161-
Py_INCREF(pyModule.ptr());
162-
#endif
163-
164-
NumpyMatrixObject = pyModule.attr("matrix");
165-
NumpyMatrixType = reinterpret_cast<PyTypeObject*>(NumpyMatrixObject.ptr());
166-
NumpyArrayObject = pyModule.attr("ndarray");
167-
NumpyArrayType = reinterpret_cast<PyTypeObject*>(NumpyArrayObject.ptr());
168-
//NumpyAsMatrixObject = pyModule.attr("asmatrix");
169-
//NumpyAsMatrixType = reinterpret_cast<PyTypeObject*>(NumpyAsMatrixObject.ptr());
170-
171-
CurrentNumpyType = NumpyArrayObject; // default conversion
172-
getType() = ARRAY_TYPE;
173-
}
174-
175-
bp::object CurrentNumpyType;
176-
bp::object pyModule;
177-
178-
// Numpy types
179-
bp::object NumpyMatrixObject; PyTypeObject * NumpyMatrixType;
180-
//bp::object NumpyAsMatrixObject; PyTypeObject * NumpyAsMatrixType;
181-
bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType;
182-
183-
};
184-
18568
template<typename MatType, bool IsVectorAtCompileTime = MatType::IsVectorAtCompileTime>
18669
struct initEigenObject
18770
{

include/eigenpy/map.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* Copyright 2018-2020, INRIA
44
*/
55

6+
#ifndef __eigenpy_map_hpp__
7+
#define __eigenpy_map_hpp__
8+
69
#include "eigenpy/fwd.hpp"
710
#include <numpy/arrayobject.h>
811
#include "eigenpy/exception.hpp"
@@ -126,3 +129,5 @@ namespace eigenpy
126129
}
127130

128131
} // namespace eigenpy
132+
133+
#endif // define __eigenpy_map_hpp__

include/eigenpy/numpy-type.hpp

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright 2018-2020, INRIA
3+
*/
4+
5+
#ifndef __eigenpy_numpy_type_hpp__
6+
#define __eigenpy_numpy_type_hpp__
7+
8+
#include "eigenpy/fwd.hpp"
9+
10+
#include <iostream>
11+
#include <patchlevel.h> // For PY_MAJOR_VERSION
12+
13+
namespace eigenpy
14+
{
15+
namespace bp = boost::python;
16+
17+
enum NP_TYPE
18+
{
19+
MATRIX_TYPE,
20+
ARRAY_TYPE
21+
};
22+
23+
struct NumpyType
24+
{
25+
26+
static NumpyType & getInstance()
27+
{
28+
static NumpyType instance;
29+
return instance;
30+
}
31+
32+
operator bp::object () { return getInstance().CurrentNumpyType; }
33+
34+
static bp::object make(PyArrayObject* pyArray, bool copy = false)
35+
{ return make((PyObject*)pyArray,copy); }
36+
37+
static bp::object make(PyObject* pyObj, bool copy = false)
38+
{
39+
bp::object m;
40+
if(isMatrix())
41+
m = getInstance().NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy);
42+
// m = NumpyAsMatrixObject(bp::object(bp::handle<>(pyObj)));
43+
else if(isArray())
44+
m = bp::object(bp::handle<>(pyObj)); // nothing to do here
45+
46+
Py_INCREF(m.ptr());
47+
return m;
48+
}
49+
50+
static void setNumpyType(bp::object & obj)
51+
{
52+
PyTypeObject * obj_type = PyType_Check(obj.ptr()) ? reinterpret_cast<PyTypeObject*>(obj.ptr()) : obj.ptr()->ob_type;
53+
if(PyType_IsSubtype(obj_type,getInstance().NumpyMatrixType))
54+
switchToNumpyMatrix();
55+
else if(PyType_IsSubtype(obj_type,getInstance().NumpyArrayType))
56+
switchToNumpyArray();
57+
}
58+
59+
static void switchToNumpyArray()
60+
{
61+
getInstance().CurrentNumpyType = getInstance().NumpyArrayObject;
62+
getInstance().getType() = ARRAY_TYPE;
63+
}
64+
65+
static void switchToNumpyMatrix()
66+
{
67+
getInstance().CurrentNumpyType = getInstance().NumpyMatrixObject;
68+
getInstance().getType() = MATRIX_TYPE;
69+
}
70+
71+
static NP_TYPE & getType()
72+
{
73+
return getInstance().np_type;
74+
}
75+
76+
static bp::object getNumpyType()
77+
{
78+
return getInstance().CurrentNumpyType;
79+
}
80+
81+
static const PyTypeObject * getNumpyMatrixType()
82+
{
83+
return getInstance().NumpyMatrixType;
84+
}
85+
86+
static const PyTypeObject * getNumpyArrayType()
87+
{
88+
return getInstance().NumpyArrayType;
89+
}
90+
91+
static bool isMatrix()
92+
{
93+
return PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(getInstance().CurrentNumpyType.ptr()),
94+
getInstance().NumpyMatrixType);
95+
}
96+
97+
static bool isArray()
98+
{
99+
if(getInstance().isMatrix()) return false;
100+
return PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(getInstance().CurrentNumpyType.ptr()),
101+
getInstance().NumpyArrayType);
102+
}
103+
104+
protected:
105+
NumpyType()
106+
{
107+
pyModule = bp::import("numpy");
108+
#if PY_MAJOR_VERSION >= 3
109+
// TODO I don't know why this Py_INCREF is necessary.
110+
// Without it, the destructor of NumpyType SEGV sometimes.
111+
Py_INCREF(pyModule.ptr());
112+
#endif
113+
114+
NumpyMatrixObject = pyModule.attr("matrix");
115+
NumpyMatrixType = reinterpret_cast<PyTypeObject*>(NumpyMatrixObject.ptr());
116+
NumpyArrayObject = pyModule.attr("ndarray");
117+
NumpyArrayType = reinterpret_cast<PyTypeObject*>(NumpyArrayObject.ptr());
118+
//NumpyAsMatrixObject = pyModule.attr("asmatrix");
119+
//NumpyAsMatrixType = reinterpret_cast<PyTypeObject*>(NumpyAsMatrixObject.ptr());
120+
121+
CurrentNumpyType = NumpyArrayObject; // default conversion
122+
np_type = ARRAY_TYPE;
123+
}
124+
125+
bp::object CurrentNumpyType;
126+
bp::object pyModule;
127+
128+
// Numpy types
129+
bp::object NumpyMatrixObject; PyTypeObject * NumpyMatrixType;
130+
//bp::object NumpyAsMatrixObject; PyTypeObject * NumpyAsMatrixType;
131+
bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType;
132+
133+
NP_TYPE np_type;
134+
};
135+
136+
}
137+
138+
#endif // ifndef __eigenpy_numpy_type_hpp__

unittest/python/test_dimensions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
quat = eigenpy.Quaternion()
77
# By default, we convert as numpy.matrix
8+
eigenpy.switchToNumpyMatrix()
89
coeffs_vector = quat.coeffs()
910
assert len(coeffs_vector.shape) == 2
1011

0 commit comments

Comments
 (0)