From 4e1f9c012a76e7f89bae8db3930db78e66d35536 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 3 May 2017 12:02:13 +0200 Subject: [PATCH 1/2] makepanda: set LANGUAGE=en to fix lib detection on German systems [skip ci] --- makepanda/makepandacore.py | 1 + 1 file changed, 1 insertion(+) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index ab1ec01feb..feab23e98a 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2533,6 +2533,7 @@ def SetupBuildEnvironment(compiler): # Setting it to UTF-8 is necessary for Python 3 modules to import # correctly. os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LANGUAGE"] = "en" if compiler == "MSVC": # Add the visual studio tools to PATH et al. From a1a99c49c02b6e46c676b4e72265403e0405d86d Mon Sep 17 00:00:00 2001 From: wolfgangp Date: Sat, 6 May 2017 02:16:07 +0200 Subject: [PATCH 2/2] =?UTF-8?q?Buffer=20protocol=20support=20for=20(Const)?= =?UTF-8?q?PointerToArray=20of=20vectors=20and=20matr=E2=80=A6=20(#148)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panda/src/express/pointerToArray_ext.I | 270 +++++++++++++++++++++++++ panda/src/express/pointerToArray_ext.h | 33 +++ 2 files changed, 303 insertions(+) diff --git a/panda/src/express/pointerToArray_ext.I b/panda/src/express/pointerToArray_ext.I index 7502334e6e..b7126e8363 100644 --- a/panda/src/express/pointerToArray_ext.I +++ b/panda/src/express/pointerToArray_ext.I @@ -11,6 +11,64 @@ * @date 2015-02-08 */ +/** + * This is a helper function to set most attributes of a Py_buffer in a manner + * that accommodates square matrices (in accordance with PEP 3118). It is tested + * for use with NumPy. The resulting array will be of shape + * (num_matrices, size, size) where size is the number of matrix rows (=columns) + */ +INLINE void set_matrix_view(Py_buffer &view, int flags, int length, int size, bool double_prec, bool read_only) { + int item_size, mat_size; + const char *format; + + if (double_prec) { + item_size = sizeof(double); + format = get_format_code(double); + } else { + item_size = sizeof(float); + format = get_format_code(float); + } + + if (size == 3 && !double_prec) { + mat_size = sizeof(LMatrix3f); + } else if (size == 3 && double_prec) { + mat_size = sizeof(LMatrix3d); + } else if (size == 4 && !double_prec) { + mat_size = sizeof(UnalignedLMatrix4f); + } else if (size == 4 && double_prec) { + mat_size = sizeof(UnalignedLMatrix4d); + } + + view.len = length * mat_size; + view.readonly = (read_only ? 1 : 0); + view.itemsize = item_size; + view.format = NULL; + if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { + view.format = (char*) format; + } + view.ndim = 3; + view.shape = NULL; + if ((flags & PyBUF_ND) == PyBUF_ND) { + // This leaks, which sucks, but __releasebuffer__ doesn't give us the same + // pointer, so we would need to store it elsewhere if we wanted to delete + // it there. Eh, it's just an int, who cares. + Py_ssize_t* shape = new Py_ssize_t[3]; + shape[0] = length; + shape[1] = size; + shape[2] = size; + view.shape = shape; + } + view.strides = NULL; + if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { + Py_ssize_t* strides = new Py_ssize_t[3]; + strides[0] = mat_size; + strides[1] = item_size * size; + strides[2] = item_size; + view.strides = strides; + } + view.suboffsets = NULL; +} + /** * This special constructor accepts a Python list of elements, or a Python * string (or a bytes object, in Python 3), or any object that supports the @@ -226,6 +284,110 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) { #endif } +/** + * This is used to implement the buffer protocol, in order to allow efficient + * access to the array data through a Python memoryview object. + */ +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) { +#if PY_VERSION_HEX >= 0x02060000 + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 3, false, false); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +/** + * This is used to implement the buffer protocol, in order to allow efficient + * access to the array data through a Python memoryview object. + */ +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) { +#if PY_VERSION_HEX >= 0x02060000 + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 3, true, false); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +/** + * This is used to implement the buffer protocol, in order to allow efficient + * access to the array data through a Python memoryview object. + */ +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) { +#if PY_VERSION_HEX >= 0x02060000 + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 4, false, false); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +/** + * This is used to implement the buffer protocol, in order to allow efficient + * access to the array data through a Python memoryview object. + */ +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) { +#if PY_VERSION_HEX >= 0x02060000 + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 4, true, false); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + /** * Releases the buffer allocated by __getbuffer__. */ @@ -299,6 +461,114 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const { #endif } +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) const { +#if PY_VERSION_HEX >= 0x02060000 + if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 3, false, true); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) const { +#if PY_VERSION_HEX >= 0x02060000 + if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 3, true, true); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) const { +#if PY_VERSION_HEX >= 0x02060000 + if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 4, false, true); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + +template<> +INLINE int Extension >:: +__getbuffer__(PyObject *self, Py_buffer *view, int flags) const { +#if PY_VERSION_HEX >= 0x02060000 + if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + if (self != NULL) { + Py_INCREF(self); + } + view->obj = self; + view->buf = (void*) this->_this->p(); + set_matrix_view(*view, flags, this->_this->size(), 4, true, true); + + // Store a reference to ourselves on the Py_buffer object as a reminder that + // we have increased our refcount. + this->_this->ref(); + view->internal = (void*) this->_this; + + return 0; +#else + return -1; +#endif +} + /** * Releases the buffer allocated by __getbuffer__. */ diff --git a/panda/src/express/pointerToArray_ext.h b/panda/src/express/pointerToArray_ext.h index 73ec780675..9fea54cbc4 100644 --- a/panda/src/express/pointerToArray_ext.h +++ b/panda/src/express/pointerToArray_ext.h @@ -19,6 +19,7 @@ #include "extension.h" #include "py_panda.h" #include "pointerToArray.h" +#include "luse.h" /** * This class defines the extension methods for PointerToArray, which are @@ -39,6 +40,15 @@ public: INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const; }; +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags); +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags); +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags); +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags); + /** * This class defines the extension methods for ConstPointerToArray, which are * called instead of any C++ methods with the same prototype. @@ -57,6 +67,15 @@ public: INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const; }; +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags) const; +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags) const; +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags) const; +template<> + INLINE int Extension >::__getbuffer__(PyObject *self, Py_buffer *view, int flags) const; + #ifdef _MSC_VER // Ugh... MSVC needs this because they still don't have a decent linker. #include "PTA_uchar.h" @@ -104,6 +123,20 @@ define_format_code("Q", unsigned long long); define_format_code("f", float); define_format_code("d", double); +define_format_code("2f", LVecBase2f); +define_format_code("2d", LVecBase2d); +define_format_code("2i", LVecBase2i); +define_format_code("3f", LVecBase3f); +define_format_code("3d", LVecBase3d); +define_format_code("3i", LVecBase3i); +define_format_code("4f", UnalignedLVecBase4f); +define_format_code("4d", UnalignedLVecBase4d); +define_format_code("4i", UnalignedLVecBase4i); +// define_format_code("9f", LMatrix3f); +// define_format_code("9d", LMatrix3d); +// define_format_code("16f", UnalignedLMatrix4f); +// define_format_code("16d", UnalignedLMatrix4d); + #include "pointerToArray_ext.I" #endif // CPPPARSER