diff --git a/doc/python/magnum.trade.rst b/doc/python/magnum.trade.rst index fbe7b30..5be9476 100644 --- a/doc/python/magnum.trade.rst +++ b/doc/python/magnum.trade.rst @@ -112,7 +112,7 @@ >>> list(mesh.attribute(trade.MeshAttribute.POSITION))[:3] [Vector(-1, -1, 1), Vector(1, -1, 1), Vector(1, 1, 1)] >>> np.array(mesh.attribute(trade.MeshAttribute.NORMAL), copy=False)[2] - (0., 0., 1.) + array([0., 0., 1.], dtype=float32) Depending on the value of :ref:`index_data_flags` / :ref:`vertex_data_flags` it's also possible to access the data in a mutable way via diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index 7c2bec8..e5d40a4 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -70,8 +70,11 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/versionBindings.h.cmake install(FILES ${CMAKE_CURRENT_BINARY_DIR}/versionBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}) if(MAGNUM_WITH_PYTHON) - add_custom_target(MagnumPython SOURCES PythonBindings.h) - install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}) + set(MagnumPython_SRCS + PythonBindings.h + StridedArrayViewPythonBindings.h) + add_custom_target(MagnumPython SOURCES ${MagnumPython_SRCS}) + install(FILES ${MagnumPython_SRCS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}) endif() find_package(Magnum COMPONENTS GL SceneGraph) diff --git a/src/Magnum/StridedArrayViewPythonBindings.h b/src/Magnum/StridedArrayViewPythonBindings.h new file mode 100644 index 0000000..c5925e2 --- /dev/null +++ b/src/Magnum/StridedArrayViewPythonBindings.h @@ -0,0 +1,70 @@ +#ifndef Magnum_StridedArrayViewPythonBindings_h +#define Magnum_StridedArrayViewPythonBindings_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +namespace Corrade { namespace Containers { namespace Implementation { + +/* This expands Containers::Implementation::pythonFormatString() with Magnum + types. Using e.g. "3f" instead of "fff" as that makes Numpy understand even + the slices as arrays in a concrete type (or it at least repr()s them as + such), with "fff" it gives back an untyped tuple. */ + +#define _c(type, string) \ + template<> constexpr const char* pythonFormatString() { return string; } +_c(Vector2, "2f") +_c(Vector2d, "2d") +_c(Vector2ub, "2B") +_c(Vector2b, "2b") +_c(Vector2us, "2H") +_c(Vector2s, "2h") +_c(Vector2ui, "2I") +_c(Vector2i, "2i") +_c(Vector3, "3f") +_c(Vector3d, "3d") +_c(Vector3ub, "3B") +_c(Vector3b, "3b") +_c(Vector3us, "3H") +_c(Vector3s, "3h") +_c(Vector3ui, "3I") +_c(Vector3i, "3i") +_c(Vector4, "4f") +_c(Vector4d, "4d") +_c(Vector4ub, "4B") +_c(Vector4b, "4b") +_c(Vector4us, "4H") +_c(Vector4s, "4h") +_c(Vector4ui, "4I") +_c(Vector4i, "4i") +#undef _c + +} + +}} + +#endif diff --git a/src/python/magnum/test/test_trade.py b/src/python/magnum/test/test_trade.py index aab163a..21450eb 100644 --- a/src/python/magnum/test/test_trade.py +++ b/src/python/magnum/test/test_trade.py @@ -322,7 +322,7 @@ class MeshData(unittest.TestCase): positions = mesh.attribute(position_id) self.assertEqual(positions.size, (3, )) self.assertEqual(positions.stride, (28, )) - self.assertEqual(positions.format, 'fff') + self.assertEqual(positions.format, '3f') self.assertEqual(list(positions), [ Vector3(-1, -1, 0.25), Vector3(0, 1, 0.5), @@ -348,7 +348,7 @@ class MeshData(unittest.TestCase): mutable_positions = mesh.mutable_attribute(position_id) self.assertEqual(mutable_positions.size, (3, )) self.assertEqual(mutable_positions.stride, (28, )) - self.assertEqual(mutable_positions.format, 'fff') + self.assertEqual(mutable_positions.format, '3f') self.assertEqual(list(mutable_positions), [ Vector3(-1, -1, 0.25), Vector3(0, 1, 0.5), diff --git a/src/python/magnum/trade.cpp b/src/python/magnum/trade.cpp index 249f7b6..6bbffad 100644 --- a/src/python/magnum/trade.cpp +++ b/src/python/magnum/trade.cpp @@ -40,8 +40,8 @@ #include "Corrade/Containers/PythonBindings.h" #include "Corrade/Containers/OptionalPythonBindings.h" -#include "Corrade/Containers/StridedArrayViewPythonBindings.h" #include "Magnum/PythonBindings.h" +#include "Magnum/StridedArrayViewPythonBindings.h" #include "corrade/EnumOperators.h" #include "corrade/pluginmanager.h" @@ -447,9 +447,9 @@ template accessorsForMeshIndexType(const MeshIndexType type) { switch(type) { - #define _c(type, string) \ + #define _c(type) \ case MeshIndexType::type: return { \ - string, \ + Containers::Implementation::pythonFormatString(), \ [](const char* item) { \ return py::cast(*reinterpret_cast(item)); \ }, \ @@ -457,9 +457,9 @@ Containers::Triple(item) = py::cast(object); \ }}; /* LCOV_EXCL_START */ - _c(UnsignedByte, "B") - _c(UnsignedShort, "H") - _c(UnsignedInt, "I") + _c(UnsignedByte) + _c(UnsignedShort) + _c(UnsignedInt) /* LCOV_EXCL_STOP */ #undef _c } @@ -469,9 +469,9 @@ Containers::Triple accessorsForVertexFormat(const VertexFormat format) { switch(format) { - #define _c(format, string) \ + #define _c(format) \ case VertexFormat::format: return { \ - string, \ + Containers::Implementation::pythonFormatString(), \ [](const char* item) { \ return py::cast(*reinterpret_cast(item)); \ }, \ @@ -480,9 +480,9 @@ Containers::Triple(), \ [](const char* item) { \ return py::cast(castType(*reinterpret_cast(item))); \ }, \ @@ -490,41 +490,41 @@ Containers::Triple(item) = format(py::cast(object)); \ }}; /* LCOV_EXCL_START */ - _c(Float, "f") - _c(Double, "d") - _c(UnsignedByte, "B") - _c(Byte, "b") - _c(UnsignedShort, "H") - _c(Short, "h") - _c(UnsignedInt, "I") - _c(Int, "i") - - _c(Vector2, "ff") - _c(Vector2d, "dd") - _cc(Vector2ub, Vector2ui, "BB") - _cc(Vector2b, Vector2i, "bb") - _cc(Vector2us, Vector2ui, "HH") - _cc(Vector2s, Vector2i, "hh") - _c(Vector2ui, "II") - _c(Vector2i, "ii") - - _c(Vector3, "fff") - _c(Vector3d, "ddd") - _cc(Vector3ub, Vector3ui, "BBB") - _cc(Vector3b, Vector3i, "bbb") - _cc(Vector3us, Vector3ui, "HHH") - _cc(Vector3s, Vector3i, "hhh") - _c(Vector3ui, "III") - _c(Vector3i, "iii") - - _c(Vector4, "ffff") - _c(Vector4d, "dddd") - _cc(Vector4ub, Vector4ui, "BBBB") - _cc(Vector4b, Vector4i, "bbbb") - _cc(Vector4us, Vector4ui, "HHHH") - _cc(Vector4s, Vector4i, "hhhh") - _c(Vector4ui, "IIII") - _c(Vector4i, "iiii") + _c(Float) + _c(Double) + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + + _c(Vector2) + _c(Vector2d) + _cc(Vector2ub, Vector2ui) + _cc(Vector2b, Vector2i) + _cc(Vector2us, Vector2ui) + _cc(Vector2s, Vector2i) + _c(Vector2ui) + _c(Vector2i) + + _c(Vector3) + _c(Vector3d) + _cc(Vector3ub, Vector3ui) + _cc(Vector3b, Vector3i) + _cc(Vector3us, Vector3ui) + _cc(Vector3s, Vector3i) + _c(Vector3ui) + _c(Vector3i) + + _c(Vector4) + _c(Vector4d) + _cc(Vector4ub, Vector4ui) + _cc(Vector4b, Vector4i) + _cc(Vector4us, Vector4ui) + _cc(Vector4s, Vector4i) + _c(Vector4ui) + _c(Vector4i) /* LCOV_EXCL_STOP */ #undef _c #undef _cc