├── .gitignore ├── .circleci └── config.yml ├── doc ├── python │ ├── .gitignore │ ├── numpy.inv │ ├── python.inv │ ├── conf-public.py │ ├── corrade.utility.rst │ ├── corrade.pluginmanager.rst │ ├── corrade.rst │ ├── magnum.platform.rst │ ├── magnum.materialtools.rst │ ├── magnum.primitives.rst │ ├── pages │ │ ├── credits.rst │ │ └── developers.rst │ ├── magnum.scenegraph.rst │ ├── magnum.scenetools.rst │ └── magnum.gl.rst └── favicon.ico ├── src ├── python │ ├── magnum │ │ ├── test │ │ │ ├── .gitignore │ │ │ ├── rgb.png │ │ │ ├── Oxygen.ttf │ │ │ ├── mesh.bin │ │ │ ├── mesh-packed.bin │ │ │ ├── rgba_dxt1.dds │ │ │ ├── dxt10-depth32f-stencil8ui.dds │ │ │ ├── convert.sh │ │ │ ├── .gitattributes │ │ │ ├── mesh-packed.bin.in │ │ │ ├── texture.gltf │ │ │ ├── mesh.bin.in │ │ │ ├── scene.gltf │ │ │ ├── material.gltf │ │ │ ├── two-meshes.gltf │ │ │ ├── test_meshtools_gl.py │ │ │ ├── mesh-packed.gltf │ │ │ ├── test_scenegraph_trs.py │ │ │ ├── test_scenegraph_matrix.py │ │ │ ├── test_scenegraph_numpy.py │ │ │ ├── test_gl.py │ │ │ ├── __init__.py │ │ │ ├── mesh.gltf │ │ │ └── benchmark_math.py │ │ ├── .coveragerc │ │ ├── platform │ │ │ ├── _init.py │ │ │ ├── windowlessapplication.h │ │ │ ├── holder.h │ │ │ ├── cgl.cpp │ │ │ ├── egl.cpp │ │ │ ├── glx.cpp │ │ │ └── wgl.cpp │ │ ├── staticconfigure.h.cmake │ │ ├── scenegraph.matrix.cpp │ │ ├── bootstrap.h │ │ ├── math.h │ │ ├── scenegraph.trs.cpp │ │ └── __init__.py │ ├── .gitignore │ ├── corrade │ │ ├── .coveragerc │ │ ├── test │ │ │ ├── broken.conf │ │ │ ├── file.conf │ │ │ ├── test_pluginmanager.py │ │ │ ├── __init__.py │ │ │ ├── CMakeLists.txt │ │ │ └── test_optional.cpp │ │ ├── staticconfigure.h.cmake │ │ ├── bootstrap.h │ │ ├── EnumOperators.h │ │ ├── __init__.py.in │ │ ├── PyBuffer.h │ │ └── corrade.cpp │ ├── CMakeLists.txt │ └── setup.py.cmake ├── Magnum │ ├── GL │ │ ├── CMakeLists.txt │ │ └── PythonBindings.h │ ├── Trade │ │ └── CMakeLists.txt │ ├── SceneGraph │ │ └── CMakeLists.txt │ ├── Test │ │ ├── CMakeLists.txt │ │ └── VersionTest.cpp │ ├── versionBindings.h.cmake │ ├── PythonBindings.h │ └── StridedArrayViewPythonBindings.h ├── Corrade │ ├── PluginManager │ │ ├── CMakeLists.txt │ │ └── PythonBindings.h │ ├── Containers │ │ ├── CMakeLists.txt │ │ ├── PythonBindings.h │ │ └── OptionalPythonBindings.h │ └── CMakeLists.txt └── CMakeLists.txt ├── package ├── archlinux │ ├── .gitignore │ ├── .kateconfig │ ├── magnum-bindings-git │ │ └── PKGBUILD │ ├── PKGBUILD │ └── PKGBUILD-coverage ├── sync-modules.sh ├── ci │ ├── codecov.yml │ ├── unix-desktop-gles.sh │ └── unix-desktop.sh ├── git │ └── README.md └── homebrew │ └── magnum-bindings.rb ├── .editorconfig ├── CREDITS.md ├── COPYING ├── CONTRIBUTING.md ├── modules ├── MagnumBindingsConfig.cmake └── CMakeLists.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | ../package/ci/circleci.yml -------------------------------------------------------------------------------- /doc/python/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | m.math.cache -------------------------------------------------------------------------------- /src/python/magnum/test/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | -------------------------------------------------------------------------------- /package/archlinux/.gitignore: -------------------------------------------------------------------------------- 1 | pkg/ 2 | src/ 3 | *pkg.tar.zst 4 | -------------------------------------------------------------------------------- /package/archlinux/.kateconfig: -------------------------------------------------------------------------------- 1 | kate-wildcard(PKGBUILD*): hl bash; 2 | -------------------------------------------------------------------------------- /src/python/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | htmlcov/ 3 | .coverage 4 | -------------------------------------------------------------------------------- /src/python/corrade/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | */test/* 4 | -------------------------------------------------------------------------------- /src/python/corrade/test/broken.conf: -------------------------------------------------------------------------------- 1 | ]]] yes this is invalid!!! 2 | -------------------------------------------------------------------------------- /src/python/magnum/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | */test/* 4 | -------------------------------------------------------------------------------- /doc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/doc/favicon.ico -------------------------------------------------------------------------------- /doc/python/numpy.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/doc/python/numpy.inv -------------------------------------------------------------------------------- /doc/python/python.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/doc/python/python.inv -------------------------------------------------------------------------------- /src/python/magnum/test/rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/rgb.png -------------------------------------------------------------------------------- /src/python/magnum/test/Oxygen.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/Oxygen.ttf -------------------------------------------------------------------------------- /src/python/magnum/test/mesh.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/mesh.bin -------------------------------------------------------------------------------- /src/python/magnum/test/mesh-packed.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/mesh-packed.bin -------------------------------------------------------------------------------- /src/python/magnum/test/rgba_dxt1.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/rgba_dxt1.dds -------------------------------------------------------------------------------- /src/python/corrade/test/file.conf: -------------------------------------------------------------------------------- 1 | someKey=42 2 | [someGroup] 3 | value=hello 4 | [someGroup/subgroup] 5 | anotherValue=another 6 | [emptyGroup] 7 | -------------------------------------------------------------------------------- /src/python/magnum/test/dxt10-depth32f-stencil8ui.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mosra/magnum-bindings/HEAD/src/python/magnum/test/dxt10-depth32f-stencil8ui.dds -------------------------------------------------------------------------------- /src/python/magnum/test/convert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # in -> bin 6 | for i in *.bin.in; do 7 | ../../../../../magnum-plugins/src/MagnumPlugins/GltfImporter/Test/in2bin.py $i 8 | done 9 | -------------------------------------------------------------------------------- /package/sync-modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | dir=$(dirname "$0") 6 | cp $dir/../../corrade/modules/FindCorrade.cmake $dir/../modules/ 7 | cp $dir/../../magnum/modules/FindMagnum.cmake $dir/../modules/ 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | 8 | [*.{css,html,yml,rb,gltf}] 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | Third-party components 2 | ---------------------- 3 | 4 | The following third-party components are used internally: 5 | 6 | - The Python bindings make use of the pybind11 library -- 7 | https://pybind11.readthedocs.io/, available under a 8 | [BSD-style license](https://github.com/pybind/pybind11/blob/master/LICENSE) 9 | -------------------------------------------------------------------------------- /src/python/magnum/test/.gitattributes: -------------------------------------------------------------------------------- 1 | # You have to add the following to your .git/config or global 2 | # ~/.gitconfig to make the binary diffs work (without the comment 3 | # character, of course): 4 | # 5 | # [diff "hex"] 6 | # textconv = hexdump -v -C 7 | # binary = true 8 | # 9 | 10 | *.glb binary diff=hex 11 | *.bin binary diff=hex 12 | -------------------------------------------------------------------------------- /src/python/magnum/test/mesh-packed.bin.in: -------------------------------------------------------------------------------- 1 | type = '<3f3H4h 3f3H4h 3f3H4h' 2 | input = [ 3 | # float positions, 16-bit positions, 16-bit normals/tangents/texcoords 4 | 1.0, 2.0, 3.0, 1, 2, 3, 32767, 0, 0, 0, 5 | 4.0, 5.0, 6.0, 4, 5, 6, 0, 32767, 0, 0, 6 | 7.0, 8.0, 9.0, 7, 8, 9, 0, 0, -32768, 0 7 | ] 8 | 9 | # kate: hl python 10 | -------------------------------------------------------------------------------- /package/ci/codecov.yml: -------------------------------------------------------------------------------- 1 | fixes: 2 | # The src/python/magnum/__init__.py is copied to cmake's build dir together 3 | # with setup.py next to the C++ binaries and the test is done from here. 4 | # Python's coverage.py reports an absolute path to it, which means a simple 5 | # "build/src/python/::src/python/" won't suffice. This is hardcoded to CircleCI 6 | # Linux / macOS and AppVeyor build paths so let's hope these won't change. 7 | - "/root/project/build/src/python/::src/python/" 8 | - "/Users/distiller/project/build/src/python/::src/python/" 9 | - "C:/projects/magnum-bindings/build/src/python/::src/python/" 10 | -------------------------------------------------------------------------------- /src/python/magnum/test/texture.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0" 4 | }, 5 | "images": [ 6 | { 7 | "uri": "nonexistent.foo", 8 | "name": "A broken image" 9 | }, 10 | { 11 | "uri": "rgb.png", 12 | "name": "A named image" 13 | } 14 | ], 15 | "samplers": [ 16 | { 17 | "wrapS": 33648, 18 | "wrapT": 33071, 19 | "minFilter": 9984, 20 | "magFilter": 9729 21 | } 22 | ], 23 | "textures": [ 24 | { 25 | "source": 0 26 | }, 27 | { 28 | "name": "A broken texture" 29 | }, 30 | { 31 | "name": "A texture", 32 | "sampler": 0, 33 | "source": 1 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /src/python/magnum/test/mesh.bin.in: -------------------------------------------------------------------------------- 1 | type = ' 2 | pkgname=magnum-bindings-git 3 | pkgver=2020.06.r116.g62a07c3 4 | pkgrel=1 5 | pkgdesc="Bindings for the Magnum C++11/C++14 graphics engine (Git version)" 6 | arch=('i686' 'x86_64') 7 | url="https://magnum.graphics" 8 | license=('MIT') 9 | depends=('magnum-git' 'python') 10 | makedepends=('cmake' 'git' 'ninja' 'pybind11') 11 | provides=('magnum-bindings') 12 | conflicts=('magnum-bindings') 13 | source=("git+https://github.com/mosra/magnum-bindings.git") 14 | sha1sums=('SKIP') 15 | 16 | pkgver() { 17 | cd "$srcdir/${pkgname%-git}" 18 | git describe --long | sed -r 's/([^-]*-g)/r\1/;s/-/./g;s/v//g' 19 | } 20 | 21 | build() { 22 | mkdir -p "$srcdir/build" 23 | cd "$srcdir/build" 24 | 25 | cmake "$srcdir/${pkgname%-git}" \ 26 | -DCMAKE_BUILD_TYPE=Release \ 27 | -DCMAKE_INSTALL_PREFIX=/usr \ 28 | -DMAGNUM_WITH_PYTHON=ON \ 29 | -G Ninja 30 | ninja 31 | } 32 | 33 | package() { 34 | # Helper headers 35 | cd "$srcdir/build" 36 | DESTDIR="$pkgdir/" ninja install 37 | 38 | # Native and python packages 39 | cd "$srcdir/build/src/python" 40 | python setup.py install --root="$pkgdir" --prefix=/usr 41 | } 42 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2 | 2020, 2021, 2022, 2023, 2024, 2025 3 | Vladimír Vondruš and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Bug reports, feature requests or code contributions are always very welcome. 2 | To make things easier, here are a few tips: 3 | 4 | Reporting bugs, requesting features 5 | ----------------------------------- 6 | 7 | - Best way to report bugs and request new features is to use GitHub 8 | [Issues](https://github.com/mosra/magnum-bindings/issues), but you can 9 | contact the team also any other way — see the [README](README.md) for 10 | details. 11 | 12 | Code contribution 13 | ----------------- 14 | 15 | - Best way to contribute is using GitHub [Pull Requests](https://github.com/mosra/magnum-bindings/pulls) 16 | — fork the repository and make a pull request from a feature branch. You 17 | can also send patches via e-mail or contact the team in any other way — see 18 | the [README](README.md) for details. 19 | - Follow the project coding guidelines. In short — try to match style of the 20 | surrounding code and avoid any trailing whitespace. For C++, there's the 21 | [C++ Coding Style](https://doc.magnum.graphics/magnum/coding-style.html). 22 | - All your code will be released under the project license (see the 23 | [COPYING](COPYING) file for details), so make sure you and your 24 | collaborators (or employers) have no problems with it. 25 | -------------------------------------------------------------------------------- /src/python/magnum/platform/_init.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | """Platform-specific application and context creation""" 28 | -------------------------------------------------------------------------------- /modules/MagnumBindingsConfig.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | include(${CMAKE_CURRENT_LIST_DIR}/FindMagnumBindings.cmake) 28 | -------------------------------------------------------------------------------- /src/python/magnum/test/scene.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0" 4 | }, 5 | "cameras": [ 6 | { 7 | "type": "orthographic", 8 | "orthographic": { 9 | "xmag": 1.0, 10 | "ymag": 1.0, 11 | "znear": 0.1, 12 | "zfar": 100.0 13 | } 14 | }, 15 | { 16 | "type": "perspective", 17 | "perspective": { 18 | "yfov": 0.6108652, 19 | "znear": 0.1, 20 | "zfar": 100.0 21 | } 22 | } 23 | ], 24 | "nodes": [ 25 | { 26 | "translation": [7, 8, 9] 27 | }, 28 | { 29 | "name": "Translated node", 30 | "translation": [1, 2, 3] 31 | }, 32 | { 33 | "name": "Camera node", 34 | "matrix": [ 35 | 1, 0, 0, 0, 36 | 0, 3, 0, 0, 37 | 0, 0, 2, 0, 38 | 0, 0, 0, 1 39 | ], 40 | "camera": 1, 41 | "extras": { 42 | "aNumber": 5, 43 | "aString": "hello!", 44 | "yes": true 45 | }, 46 | "children": [3] 47 | }, 48 | { 49 | "camera": 0, 50 | "translation": [4, 5, 6], 51 | "children": [0], 52 | "extras": { 53 | "yes": false 54 | } 55 | }, 56 | { 57 | "name": "A broken node", 58 | "mesh": 666 59 | } 60 | ], 61 | "scenes": [ 62 | { 63 | "name": "A scene", 64 | "nodes": [1, 2] 65 | }, 66 | { 67 | "name": "A default scene that's empty" 68 | }, 69 | { 70 | "name": "A broken scene", 71 | "nodes": [4] 72 | } 73 | ], 74 | "scene": 1 75 | } 76 | -------------------------------------------------------------------------------- /src/Magnum/GL/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | if(MAGNUM_WITH_PYTHON) 28 | add_custom_target(MagnumGLPython SOURCES PythonBindings.h) 29 | install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/GL) 30 | endif() 31 | -------------------------------------------------------------------------------- /src/python/corrade/staticconfigure.h.cmake: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* Named corrade/staticconfigure.h to avoid it colliding with Corrade/configure.h 28 | on case-insensitive filesystems */ 29 | 30 | #cmakedefine Corrade_PluginManager_FOUND 31 | -------------------------------------------------------------------------------- /src/Magnum/Trade/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | if(MAGNUM_WITH_PYTHON) 28 | add_custom_target(MagnumTradePython SOURCES PythonBindings.h) 29 | install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Trade) 30 | endif() 31 | -------------------------------------------------------------------------------- /src/Magnum/SceneGraph/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | if(MAGNUM_WITH_PYTHON) 28 | add_custom_target(MagnumSceneGraphPython SOURCES PythonBindings.h) 29 | install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/SceneGraph) 30 | endif() 31 | -------------------------------------------------------------------------------- /src/python/corrade/test/test_pluginmanager.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # Right now, Corrade itself doesn't define any plugin interfaces and thus it's 28 | # impossible to test the plugin APIs here. Those are instead tested in Magnum's 29 | # test.test_trade.Importer. 30 | -------------------------------------------------------------------------------- /src/Magnum/Test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # Prefixed with project name to avoid conflicts with VersionTest in Magnum and 28 | # related repos 29 | corrade_add_test(MagnumBindingsVersionTest VersionTest.cpp LIBRARIES Magnum::Magnum) 30 | target_include_directories(MagnumBindingsVersionTest PRIVATE ${PROJECT_BINARY_DIR}/src) 31 | -------------------------------------------------------------------------------- /src/Corrade/PluginManager/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | if(MAGNUM_WITH_PYTHON) 28 | set(CorradePluginManagerPython_HEADERS 29 | PythonBindings.h) 30 | 31 | add_custom_target(CorradePluginManagerPython SOURCES ${CorradePluginManagerPython_HEADERS}) 32 | install(FILES ${CorradePluginManagerPython_HEADERS} DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}/PluginManager) 33 | endif() 34 | -------------------------------------------------------------------------------- /src/python/corrade/test/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import os 28 | import sys 29 | 30 | # TODO: do this differently / more robustly 31 | sys.path = [ 32 | os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python'), 33 | os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python/Release') 34 | ] + sys.path 35 | -------------------------------------------------------------------------------- /src/python/magnum/test/material.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0" 4 | }, 5 | "images": [ 6 | { 7 | "uri": "rgb.png" 8 | } 9 | ], 10 | "materials": [ 11 | { 12 | "name": "A material with a layer", 13 | "alphaCutoff": 0.369, 14 | "alphaMode": "MASK", 15 | "doubleSided": true, 16 | "pbrMetallicRoughness": { 17 | "baseColorFactor": [0.3, 0.4, 0.5, 0.8] 18 | }, 19 | "extensions": { 20 | "KHR_materials_clearcoat": { 21 | "clearcoatFactor": 0.7, 22 | "clearcoatTexture": { 23 | "index": 2, 24 | "texCoord": 13, 25 | "extensions": { 26 | "KHR_texture_transform": { 27 | "offset": [0.25, 0.5] 28 | } 29 | } 30 | }, 31 | "clearcoatRoughnessTexture": { 32 | "index": 1 33 | } 34 | } 35 | } 36 | }, 37 | { 38 | "name": "Empty material" 39 | }, 40 | { 41 | "name": "Material with an empty layer", 42 | "emissiveFactor": [0.5, 0.4, 0.3], 43 | "extensions": { 44 | "KHR_materials_clearcoat": {} 45 | } 46 | }, 47 | { 48 | "name": "A broken material", 49 | "alphaMode": false 50 | }, 51 | { 52 | "name": "Specular/glossiness", 53 | "extensions": { 54 | "KHR_materials_pbrSpecularGlossiness": { 55 | "specularFactor": [0.1, 0.2, 0.6] 56 | } 57 | } 58 | } 59 | ], 60 | "samplers": [ 61 | {} 62 | ], 63 | "textures": [ 64 | { 65 | "sampler": 0, 66 | "source": 0 67 | }, 68 | { 69 | "sampler": 0, 70 | "source": 0 71 | }, 72 | { 73 | "sampler": 0, 74 | "source": 0 75 | } 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /src/Corrade/Containers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | if(MAGNUM_WITH_PYTHON) 28 | set(CorradeContainersPython_HEADERS 29 | OptionalPythonBindings.h 30 | PythonBindings.h 31 | StridedArrayViewPythonBindings.h) 32 | 33 | add_custom_target(CorradeContainersPython SOURCES ${CorradeContainersPython_HEADERS}) 34 | install(FILES ${CorradeContainersPython_HEADERS} DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}/Containers) 35 | endif() 36 | -------------------------------------------------------------------------------- /doc/python/conf-public.py: -------------------------------------------------------------------------------- 1 | # Inherit everything from the local config 2 | import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__))) 3 | from conf import * 4 | 5 | assert LINKS_NAVBAR2[0][0] == 'C++ API' 6 | LINKS_NAVBAR2[0] = (LINKS_NAVBAR2[0][0], 'https://magnum.graphics/doc/magnum/', []) 7 | 8 | OUTPUT = '../../build/doc-public/python/' 9 | 10 | assert len(M_DOX_TAGFILES) == 2 11 | M_DOX_TAGFILES = [ 12 | # TODO: the path should be relative to this file 13 | (os.path.join(os.path.dirname(__file__), '../../../corrade/build/doc-mcss/corrade.tag'), 'https://doc.magnum.graphics/corrade/', ['Corrade::'], ['m-doc-external']), 14 | (os.path.join(os.path.dirname(__file__), '../../../magnum/build/doc-mcss/magnum.tag'), 'https://doc.magnum.graphics/magnum/', ['Magnum::'], ['m-doc-external']) 15 | ] 16 | 17 | STYLESHEETS = [ 18 | 'https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600&subset=latin-ext', 19 | 'https://static.magnum.graphics/m-dark.compiled.css', 20 | 'https://static.magnum.graphics/m-dark.documentation.compiled.css' 21 | ] 22 | 23 | FAVICON = 'https://doc.magnum.graphics/favicon.ico' 24 | 25 | SEARCH_DOWNLOAD_BINARY = 'searchdata-v1.bin' 26 | SEARCH_BASE_URL = 'https://doc.magnum.graphics/python/' 27 | SEARCH_EXTERNAL_URL = 'https://google.com/search?q=site:doc.magnum.graphics+Magnum+Python+{query}' 28 | 29 | def URL_FORMATTER(type, path): 30 | # Put static files into the root, everything else into subdirs 31 | if type.name == 'STATIC': 32 | prefix = os.path.basename(path[0]) 33 | return prefix, '/python/' + prefix 34 | 35 | # And special casing for index, of course 36 | if type.name == 'PAGE' and len(path) == 1 and path[0] == 'index': 37 | return 'index.html', '/python/' 38 | 39 | prefix = '/'.join(path) + '/' 40 | return prefix + 'index.html', '/python/' + prefix 41 | -------------------------------------------------------------------------------- /src/Corrade/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER 28 | # property that would have to be set on each target separately. 29 | set(CMAKE_FOLDER "Corrade/Python") 30 | 31 | if(MAGNUM_WITH_PYTHON) 32 | add_custom_target(CorradePython SOURCES PythonBindings.h) 33 | install(FILES PythonBindings.h DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}) 34 | endif() 35 | 36 | add_subdirectory(Containers) 37 | 38 | if(Corrade_PluginManager_FOUND) 39 | add_subdirectory(PluginManager) 40 | endif() 41 | -------------------------------------------------------------------------------- /doc/python/corrade.utility.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:function:: corrade.utility.copy 28 | :raise AssertionError: If :p:`src` and :p:`dst` sizes, type sizes or types are different 29 | 30 | .. py:function:: corrade.utility.ConfigurationGroup.group 31 | :raise KeyError: If group :p:`name` doesn't exist 32 | 33 | .. py:function:: corrade.utility.Configuration.__init__(self, filename: str) 34 | :raise IOError: If :p:`filename` contains a parse error 35 | 36 | .. py:function:: corrade.utility.Configuration.save 37 | :raise IOError: If the file can't be saved 38 | -------------------------------------------------------------------------------- /src/python/magnum/test/two-meshes.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0", 4 | "note": "same as meshes.gltf, just with no errors, no custom attribs, no attribs that aren't valid glTF and no skinning attribs either" 5 | }, 6 | "meshes": [ 7 | { 8 | "name": "Indexed mesh", 9 | "primitives": [ 10 | { 11 | "attributes": { 12 | "POSITION": 1, 13 | "TEXCOORD_0": 2, 14 | "COLOR": 3, 15 | "TEXCOORD_1": 2 16 | }, 17 | "indices": 0 18 | } 19 | ] 20 | }, 21 | { 22 | "name": "Non-indexed mesh", 23 | "primitives": [ 24 | { 25 | "attributes": { 26 | "POSITION": 1 27 | } 28 | } 29 | ] 30 | } 31 | ], 32 | "accessors": [ 33 | { 34 | "bufferView": 0, 35 | "byteOffset": 2, 36 | "componentType": 5123, 37 | "count": 3, 38 | "type": "SCALAR" 39 | }, 40 | { 41 | "bufferView": 1, 42 | "componentType": 5126, 43 | "count": 3, 44 | "type": "VEC3" 45 | }, 46 | { 47 | "bufferView": 1, 48 | "byteOffset": 12, 49 | "componentType": 5126, 50 | "count": 3, 51 | "type": "VEC2" 52 | }, 53 | { 54 | "bufferView": 1, 55 | "byteOffset": 20, 56 | "componentType": 5121, 57 | "normalized": true, 58 | "count": 3, 59 | "type": "VEC3" 60 | }, 61 | { 62 | "bufferView": 1, 63 | "byteOffset": 24, 64 | "componentType": 5125, 65 | "count": 3, 66 | "type": "SCALAR" 67 | } 68 | ], 69 | "bufferViews": [ 70 | { 71 | "buffer": 0, 72 | "byteOffset": 0, 73 | "byteLength": 8 74 | }, 75 | { 76 | "buffer": 0, 77 | "byteOffset": 8, 78 | "byteLength": 84, 79 | "byteStride": 28 80 | } 81 | ], 82 | "buffers": [ 83 | { 84 | "byteLength": 92, 85 | "uri": "mesh.bin" 86 | } 87 | ] 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/python/corrade/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER 28 | # property that would have to be set on each target separately. 29 | set(CMAKE_FOLDER "Corrade/Python/Test") 30 | 31 | foreach(_test optional stridedarrayview) 32 | pybind11_add_module(test_${_test} ${pybind11_add_module_SYSTEM} test_${_test}.cpp) 33 | target_include_directories(test_${_test} PRIVATE ${PROJECT_SOURCE_DIR}/src) 34 | target_link_libraries(test_${_test} PRIVATE Corrade::Containers) 35 | set_target_properties(test_${_test} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${output_dir}) 36 | endforeach() 37 | -------------------------------------------------------------------------------- /src/Magnum/versionBindings.h.cmake: -------------------------------------------------------------------------------- 1 | #ifndef Magnum_versionBindings_h 2 | #define Magnum_versionBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | /* Note: this header is deliberately not included from anywhere except 30 | VersionTest to avoid triggering a full rebuild every time the Git commit 31 | hash changes. */ 32 | 33 | #define MAGNUMBINDINGS_VERSION_YEAR ${MAGNUMBINDINGS_VERSION_YEAR} 34 | #define MAGNUMBINDINGS_VERSION_MONTH ${MAGNUMBINDINGS_VERSION_MONTH} 35 | #cmakedefine MAGNUMBINDINGS_VERSION_COMMIT${MAGNUMBINDINGS_VERSION_COMMIT} 36 | #cmakedefine MAGNUMBINDINGS_VERSION_HASH 0x${MAGNUMBINDINGS_VERSION_HASH} 37 | #cmakedefine MAGNUMBINDINGS_VERSION_STRING "${MAGNUMBINDINGS_VERSION_STRING}" 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /doc/python/corrade.pluginmanager.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:class:: corrade.pluginmanager.AbstractManager 28 | :data VERSION: Plugin ABI version 29 | 30 | .. py:function:: corrade.pluginmanager.AbstractManager.load 31 | :raise RuntimeError: When loading fails 32 | :return: :ref:`LoadState.LOADED`, possibly combined with other flags such 33 | as :ref:`LoadState.STATIC` 34 | 35 | .. py:function:: corrade.pluginmanager.AbstractManager.unload 36 | :raise RuntimeError: When unloading fails 37 | :return: Either :ref:`LoadState.NOT_LOADED` or :ref:`LoadState.STATIC` 38 | 39 | .. py:function:: corrade.pluginmanager.AbstractManager.set_preferred_plugins 40 | :raise KeyError: If the alias doesn't exist 41 | -------------------------------------------------------------------------------- /src/python/magnum/test/test_meshtools_gl.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import unittest 28 | 29 | # setUpModule gets called before everything else, skipping if GL tests can't 30 | # be run 31 | from . import GLTestCase, setUpModule 32 | 33 | from magnum import * 34 | from magnum import gl, meshtools, primitives 35 | 36 | class Compile(GLTestCase): 37 | def test_2d(self): 38 | a = meshtools.compile(primitives.square_wireframe()) 39 | self.assertEqual(a.primitive, gl.MeshPrimitive.LINE_LOOP) 40 | self.assertEqual(a.count, 4) 41 | 42 | def test_3d(self): 43 | a = meshtools.compile(primitives.cube_solid()) 44 | self.assertEqual(a.primitive, gl.MeshPrimitive.TRIANGLES) 45 | self.assertEqual(a.count, 36) 46 | -------------------------------------------------------------------------------- /doc/python/corrade.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. roles used for all other docs 28 | 29 | .. role:: cpp(code) 30 | :language: c++ 31 | .. role:: py(code) 32 | :language: py 33 | .. role:: sh(code) 34 | :language: sh 35 | 36 | .. doctest setup 37 | >>> from corrade import * 38 | 39 | .. py:module:: corrade 40 | :data BUILD_DEPRECATED: Build with deprecated features enabled 41 | :data BUILD_STATIC: Static library build 42 | :data BUILD_MULTITHREADED: Multi-threaded build 43 | :data TARGET_UNIX: Unix target 44 | :data TARGET_APPLE: Apple target 45 | :data TARGET_IOS: iOS target 46 | :data TARGET_IOS_SIMULATOR: iOS simulator target 47 | :data TARGET_WINDOWS: Windows target 48 | :data TARGET_WINDOWS_RT: Windows RT target 49 | :data TARGET_EMSCRIPTEN: Emscripten target 50 | :data TARGET_ANDROID: Android target 51 | -------------------------------------------------------------------------------- /src/python/magnum/staticconfigure.h.cmake: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | /* Named magnum/staticconfigure.h to avoid it colliding with Magnum/configure.h 28 | on case-insensitive filesystems */ 29 | 30 | #cmakedefine Magnum_GL_FOUND 31 | #cmakedefine Magnum_MaterialTools_FOUND 32 | #cmakedefine Magnum_MeshTools_FOUND 33 | #cmakedefine Magnum_Primitives_FOUND 34 | #cmakedefine Magnum_SceneGraph_FOUND 35 | #cmakedefine Magnum_SceneTools_FOUND 36 | #cmakedefine Magnum_Shaders_FOUND 37 | #cmakedefine Magnum_Text_FOUND 38 | #cmakedefine Magnum_Trade_FOUND 39 | 40 | #cmakedefine Magnum_GlfwApplication_FOUND 41 | #cmakedefine Magnum_Sdl2Application_FOUND 42 | #cmakedefine Magnum_WindowlessCglApplication_FOUND 43 | #cmakedefine Magnum_WindowlessEglApplication_FOUND 44 | #cmakedefine Magnum_WindowlessGlxApplication_FOUND 45 | #cmakedefine Magnum_WindowlessWglApplication_FOUND 46 | -------------------------------------------------------------------------------- /src/python/corrade/bootstrap.h: -------------------------------------------------------------------------------- 1 | #ifndef corrade_h 2 | #define corrade_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include /* for PYBIND11_VERSION_* */ 30 | 31 | namespace pybind11 { 32 | /* pybind11 2.6 changes py::module to py::module_ to be compatible with C++ 33 | modules. In order to be forward-compatible, we use module_ everywhere 34 | and define it as an alias to module on < 2.6 */ 35 | #if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206 36 | class module_; 37 | #else 38 | class module; 39 | typedef module module_; 40 | #endif 41 | } 42 | 43 | namespace Corrade {} 44 | 45 | namespace corrade { 46 | 47 | using namespace Corrade; 48 | namespace py = pybind11; 49 | 50 | void containers(py::module_& m); 51 | void pluginmanager(py::module_& m); 52 | void utility(py::module_& m); 53 | 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /package/archlinux/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Author: mosra 2 | pkgname=magnum-bindings 3 | pkgver=dev 4 | pkgrel=1 5 | pkgdesc="C++11/C++14 graphics middleware for games and data visualization — bindings" 6 | arch=('i686' 'x86_64') 7 | url="https://magnum.graphics" 8 | license=('MIT') 9 | depends=('corrade' 'magnum' 'python') 10 | makedepends=('cmake' 'ninja' 'pybind11') 11 | options=(!buildflags) 12 | provides=('magnum-bindings-git') 13 | 14 | _rootdir=$startdir/../../ 15 | 16 | _buildtype=Release 17 | # _buildtype=Debug 18 | 19 | build() { 20 | mkdir -p "$_rootdir/build" 21 | cd "$_rootdir/build" 22 | 23 | # Only one of these is built. 24 | # 25 | # Colored output is enabled implicitly. If Ninja detects it's outputting to 26 | # a pipe, it strips it away from the output, alternatively you can set the 27 | # GCC_COLORS= (empty) env variable to temporarily disable colors. The 28 | # inverse, i.e. preserving colors when Ninja outputs to a pipe can be done 29 | # with CLICOLOR_FORCE=1: https://github.com/ninja-build/ninja/issues/2196 30 | cmake .. \ 31 | -DCMAKE_CONFIGURATION_TYPES="Release;Debug;RelWithDebInfo" \ 32 | -DCMAKE_CROSS_CONFIGS=all \ 33 | -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -g -DNDEBUG -fno-omit-frame-pointer" \ 34 | -DCMAKE_INSTALL_PREFIX=/usr \ 35 | -DCMAKE_COLOR_DIAGNOSTICS=ON \ 36 | -DPYTHON_EXECUTABLE=$(which python) \ 37 | -DMAGNUM_WITH_PYTHON=ON \ 38 | -DMAGNUM_BUILD_TESTS=ON \ 39 | -G "Ninja Multi-Config" 40 | ninja all:$_buildtype 41 | } 42 | 43 | check() { 44 | cd "$_rootdir/build" 45 | CORRADE_TEST_COLOR=ON ctest --output-on-failure -C $_buildtype 46 | 47 | cd "$_rootdir/src/python/corrade" 48 | python -m unittest -v 49 | 50 | cd "$_rootdir/src/python/magnum" 51 | python -m unittest -v 52 | 53 | cd "$_rootdir/doc/python" 54 | PYTHONPATH="$_rootdir/build/src/python/$_buildtype" python -m doctest -v *.rst 55 | } 56 | 57 | package() { 58 | # Helper headers 59 | cd "$_rootdir/build" 60 | DESTDIR="$pkgdir/" ninja install:$_buildtype 61 | 62 | # Native and python packages 63 | cd "$_rootdir/build/src/python/$_buildtype" 64 | python setup.py install --root="$pkgdir" --prefix=/usr 65 | } 66 | -------------------------------------------------------------------------------- /modules/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | set(MagnumBindings_MODULES 28 | FindMagnumBindings.cmake 29 | MagnumBindingsConfig.cmake) 30 | 31 | # IMPORTANT: When adding a new module here, be sure to update the 32 | # find_path(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR ...) list in 33 | # FindMagnumBindings.cmake to avoid breakages when the directory contains only 34 | # that new module. 35 | set(MagnumBindings_DEPENDENCY_MODULES ) 36 | # No dependency Find modules so far 37 | 38 | install(FILES ${MagnumBindings_MODULES} DESTINATION ${MAGNUMBINDINGS_CMAKE_MODULE_INSTALL_DIR}) 39 | if(MagnumBindings_DEPENDENCY_MODULES) 40 | install(FILES ${MagnumBindings_DEPENDENCY_MODULES} DESTINATION ${MAGNUMBINDINGS_CMAKE_MODULE_INSTALL_DIR}/dependencies) 41 | endif() 42 | 43 | # Magnum Bindings dependency module dir for superprojects 44 | set(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") 45 | -------------------------------------------------------------------------------- /src/python/magnum/test/mesh-packed.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0" 4 | }, 5 | "meshes": [ 6 | { 7 | "name": "packed positions", 8 | "primitives": [ 9 | { 10 | "attributes": { 11 | "POSITION": 1 12 | } 13 | } 14 | ] 15 | }, 16 | { 17 | "name": "packed normals", 18 | "primitives": [ 19 | { 20 | "attributes": { 21 | "POSITION": 0, 22 | "NORMAL": 2 23 | } 24 | } 25 | ] 26 | }, 27 | { 28 | "name": "packed tangents", 29 | "primitives": [ 30 | { 31 | "attributes": { 32 | "POSITION": 0, 33 | "TANGENT": 3 34 | } 35 | } 36 | ] 37 | }, 38 | { 39 | "name": "packed texcoords", 40 | "primitives": [ 41 | { 42 | "attributes": { 43 | "POSITION": 0, 44 | "TEXCOORD_0": 4 45 | } 46 | } 47 | ] 48 | } 49 | ], 50 | "accessors": [ 51 | { 52 | "bufferView": 0, 53 | "componentType": 5126, 54 | "count": 3, 55 | "type": "VEC3" 56 | }, 57 | { 58 | "bufferView": 0, 59 | "byteOffset": 12, 60 | "componentType": 5123, 61 | "count": 3, 62 | "type": "VEC3" 63 | }, 64 | { 65 | "bufferView": 0, 66 | "byteOffset": 18, 67 | "componentType": 5122, 68 | "normalized": true, 69 | "count": 3, 70 | "type": "VEC3" 71 | }, 72 | { 73 | "bufferView": 0, 74 | "byteOffset": 18, 75 | "componentType": 5122, 76 | "normalized": true, 77 | "count": 3, 78 | "type": "VEC4" 79 | }, 80 | { 81 | "bufferView": 0, 82 | "byteOffset": 18, 83 | "componentType": 5123, 84 | "normalized": true, 85 | "count": 3, 86 | "type": "VEC2" 87 | } 88 | ], 89 | "bufferViews": [ 90 | { 91 | "buffer": 0, 92 | "byteOffset": 0, 93 | "byteLength": 78, 94 | "byteStride": 26 95 | } 96 | ], 97 | "buffers": [ 98 | { 99 | "byteLength": 78, 100 | "uri": "mesh-packed.bin" 101 | } 102 | ] 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # On MSVC remove /W3, as we are replacing it with /W4. Could be removed as of 28 | # 3.15 with this: https://cmake.org/cmake/help/latest/policy/CMP0092.html 29 | if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") 30 | string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 31 | endif() 32 | 33 | # On Windows enable UNICODE/_UNICODE macros to avoid accidentally passing UTF-8 34 | # values to ANSI functions 35 | if(CORRADE_TARGET_WINDOWS) 36 | add_definitions("-DUNICODE" "-D_UNICODE") 37 | endif() 38 | 39 | set_directory_properties(PROPERTIES 40 | CORRADE_CXX_STANDARD 11 41 | CORRADE_USE_PEDANTIC_FLAGS ON) 42 | 43 | add_subdirectory(Corrade) 44 | add_subdirectory(Magnum) 45 | 46 | if(MAGNUM_WITH_PYTHON) 47 | add_subdirectory(python) 48 | endif() 49 | 50 | # Magnum Bindings include dir for superprojects 51 | set(MAGNUMBINDINGS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "" FORCE) 52 | -------------------------------------------------------------------------------- /src/python/corrade/EnumOperators.h: -------------------------------------------------------------------------------- 1 | #ifndef corrade_EnumOperators_h 2 | #define corrade_EnumOperators_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | 31 | /* Pybind's py::arithmetic() is useless because it doesn't work on 32 | strongly-typed enums with custom operators */ 33 | namespace corrade { 34 | 35 | template void enumOperators(pybind11::enum_& e) { 36 | e 37 | .def("__or__", [](const T& a, const T& b) { return T(typename std::underlying_type::type(a | b)); }) 38 | .def("__and__", [](const T& a, const T& b) { return T(typename std::underlying_type::type(a & b)); }) 39 | .def("__xor__", [](const T& a, const T& b) { return T(typename std::underlying_type::type(a ^ b)); }) 40 | .def("__invert__", [](const T& a) { return T(typename std::underlying_type::type(~a)); }) 41 | .def("__bool__", [](const T& a) { return bool(typename std::underlying_type::type(a)); }); 42 | } 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/python/magnum/platform/windowlessapplication.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | 29 | #include "magnum/bootstrap.h" 30 | 31 | namespace magnum { namespace platform { 32 | 33 | template void windowlessapplication(py::class_& c) { 34 | py::class_ configuration{c, "Configuration", "Configuration"}; 35 | configuration 36 | .def(py::init()); 37 | /** @todo others */ 38 | 39 | c 40 | /* Constructor */ 41 | .def(py::init(), py::arg("configuration") = typename T::Configuration{}, 42 | "Constructor") 43 | /** @todo the nocreate ones */ 44 | 45 | .def("exec", &T::exec, "Execute application") 46 | /** @todo more */ 47 | ; 48 | } 49 | 50 | template void context(py::class_& c) { 51 | c 52 | .def(py::init()) 53 | /** @todo delayed creation */ 54 | ; 55 | } 56 | 57 | }} 58 | -------------------------------------------------------------------------------- /doc/python/magnum.platform.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:module:: magnum.platform 28 | 29 | Concrete implementations of :py:`Application` and :py:`WindowlessApplication` 30 | classes are available in submodules, and it's up to you which one you 31 | choose. For example: 32 | 33 | .. code:: py 34 | 35 | from magnum import platform 36 | import magnum.platform.sdl2 37 | 38 | class MyApp(platform.sdl2.Application): 39 | ... 40 | 41 | The same goes for :py:`WindowlessApplication` implementations, for example: 42 | 43 | .. code:: py 44 | 45 | from magnum import platform 46 | import magnum.platform.egl 47 | 48 | class MyApp(platform.egl.WindowlessApplication): 49 | ... 50 | 51 | Alternatively, if you want to narrow down the mention of a particular 52 | toolkit to just one line, you can also do: 53 | 54 | .. code:: py 55 | 56 | from magnum.platform.sdl2 import Application 57 | 58 | class MyApp(Application): 59 | -------------------------------------------------------------------------------- /package/homebrew/magnum-bindings.rb: -------------------------------------------------------------------------------- 1 | class MagnumBindings < Formula 2 | desc "`Bindings for the Magnum C++11/C++14 graphics engine" 3 | homepage "https://magnum.graphics" 4 | url "https://github.com/mosra/magnum-bindings/archive/v2020.06.tar.gz" 5 | # wget https://github.com/mosra/magnum-bindings/archive/v2020.06.tar.gz -O - | sha256sum 6 | sha256 "959c703e6409ba0c2cd6c0da3a2b6190f6fac837ff69f64cbdc372e11359e7d8" 7 | head "https://github.com/mosra/magnum-bindings.git" 8 | 9 | depends_on "cmake" => :build 10 | depends_on "python" 11 | depends_on "python-setuptools" => :build 12 | depends_on "magnum" 13 | depends_on "pybind11" => :build 14 | 15 | # Apply a patch to make 2020.06 working with latest pybind11, which changes 16 | # py::module to py::module_ 17 | stable do 18 | patch do 19 | url "https://github.com/mosra/magnum-bindings/commit/57db13422fe36d1bcfc7bee9b138c79901062dae.diff?full_index=1" 20 | sha256 "c13536e1bac8721f0c766768159e2b91babc4674fcbf46edfc0c43c72c77df3b" 21 | end 22 | end 23 | 24 | def install 25 | # 2020.06 has the options unprefixed, current master has them prefixed. 26 | # Options not present in 2020.06 are prefixed always. 27 | option_prefix = build.head? ? 'MAGNUM_' : '' 28 | # 2020.06 has CMake 3.5 as minimum required for backwards compatibility 29 | # purposes, but it works with any newer. CMake 4.0 removed compatibility 30 | # with it and suggests this as an override. 31 | # TODO remove once a new release is finally made 32 | extra_cmake_args = build.head? ? [] : ['-DCMAKE_POLICY_VERSION_MINIMUM=3.5'] 33 | 34 | system "mkdir build" 35 | cd "build" do 36 | system "cmake", 37 | *(std_cmake_args + extra_cmake_args), 38 | # Without this, ARM builds will try to look for dependencies in 39 | # /usr/local/lib and /usr/lib (which are the default locations) instead 40 | # of /opt/homebrew/lib which is dedicated for ARM binaries. Please 41 | # complain to Homebrew about this insane non-obvious filesystem layout. 42 | "-DCMAKE_INSTALL_NAME_DIR:STRING=#{lib}", 43 | "-D#{option_prefix}WITH_PYTHON=ON", 44 | ".." 45 | system "cmake", "--build", "." 46 | system "cmake", "--build", ".", "--target", "install" 47 | cd "src/python" do 48 | system "python3", *Language::Python.setup_install_args(prefix) 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /src/python/magnum/test/test_scenegraph_trs.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import sys 28 | import unittest 29 | 30 | from magnum import * 31 | from magnum import scenegraph 32 | from magnum.scenegraph.trs import Object3D, Scene3D 33 | 34 | class Object(unittest.TestCase): 35 | def test(self): 36 | scene = Scene3D() 37 | 38 | a = Object3D(scene) 39 | a.rotate_local(Deg(35.0), Vector3.x_axis()) 40 | self.assertEqual(a.transformation, Matrix4.rotation_x(Deg(35.0))) 41 | self.assertEqual(a.absolute_transformation(), Matrix4.rotation_x(Deg(35.0))) 42 | 43 | b = Object3D(a) 44 | b.translate((3.0, 4.0, 5.0)) 45 | self.assertEqual(b.transformation, Matrix4.translation((3.0, 4.0, 5.0))) 46 | self.assertEqual(b.absolute_transformation(), 47 | Matrix4.rotation_x(Deg(35.0))@ 48 | Matrix4.translation((3.0, 4.0, 5.0))) 49 | 50 | c = Object3D(scene) 51 | self.assertEqual(c.transformation, Matrix4.identity_init()) 52 | self.assertEqual(c.absolute_transformation(), Matrix4.identity_init()) 53 | -------------------------------------------------------------------------------- /src/python/magnum/test/test_scenegraph_matrix.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import sys 28 | import unittest 29 | 30 | from magnum import * 31 | from magnum import scenegraph 32 | from magnum.scenegraph.matrix import Object3D, Scene3D 33 | 34 | class Object(unittest.TestCase): 35 | def test_transformation(self): 36 | scene = Scene3D() 37 | 38 | a = Object3D(scene) 39 | a.rotate_local(Deg(35.0), Vector3.x_axis()) 40 | self.assertEqual(a.transformation, Matrix4.rotation_x(Deg(35.0))) 41 | self.assertEqual(a.absolute_transformation(), Matrix4.rotation_x(Deg(35.0))) 42 | 43 | b = Object3D(a) 44 | b.translate((3.0, 4.0, 5.0)) 45 | self.assertEqual(b.transformation, Matrix4.translation((3.0, 4.0, 5.0))) 46 | self.assertEqual(b.absolute_transformation(), 47 | Matrix4.rotation_x(Deg(35.0))@ 48 | Matrix4.translation((3.0, 4.0, 5.0))) 49 | 50 | c = Object3D(scene) 51 | self.assertEqual(c.transformation, Matrix4.identity_init()) 52 | self.assertEqual(c.absolute_transformation(), Matrix4.identity_init()) 53 | -------------------------------------------------------------------------------- /doc/python/magnum.materialtools.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:function:: magnum.materialtools.filter_attributes 28 | :raise AssertionError: If size of :p:`attributes_to_keep` is different than 29 | :ref:`trade.MaterialData.attribute_data_offset()` for 30 | :ref:`trade.MaterialData.layer_count` 31 | .. py:function:: magnum.materialtools.filter_layers 32 | :raise AssertionError: If size of :p:`layers_to_keep` is different than 33 | :ref:`trade.MaterialData.layer_count` 34 | .. py:function:: magnum.materialtools.filter_attributes_layers 35 | :raise AssertionError: If size of :p:`attributes_to_keep` is different than 36 | :ref:`trade.MaterialData.attribute_data_offset()` for 37 | :ref:`trade.MaterialData.layer_count` 38 | :raise AssertionError: If size of :p:`layers_to_keep` is different than 39 | :ref:`trade.MaterialData.layer_count` 40 | .. py:function:: magnum.materialtools.merge 41 | :raise RuntimeError: If merge failed due to a conflict 42 | .. py:function:: magnum.materialtools.phong_to_pbr_metallic_roughness 43 | :raise RuntimeError: If conversion failed 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains bindings of the Magnum C++11 graphics engine into 2 | other languages such as Python. 3 | 4 | [![Join the chat at https://gitter.im/mosra/magnum](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mosra/magnum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | [![Build Status](https://circleci.com/gh/mosra/magnum-bindings.svg?style=shield)](https://circleci.com/gh/mosra/magnum-bindings) 6 | [![Build status](https://ci.appveyor.com/api/projects/status/utnexv0i8jbwfhff/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum-bindings/branch/master) 7 | [![Coverage Status](https://codecov.io/gh/mosra/magnum-bindings/branch/master/graph/badge.svg)](https://codecov.io/gh/mosra/magnum-bindings) 8 | [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT) 9 | 10 | - Project homepage — https://magnum.graphics/ 11 | - Documentation — https://doc.magnum.graphics/ 12 | - GitHub project page — https://github.com/mosra/magnum-bindings 13 | 14 | UNDER CONSTRUCTION 15 | ================== 16 | 17 | Contents of this repository and documentation is under construction. You can 18 | find work-in-progress docs at https://doc.magnum.graphics/python/ but there 19 | isn't much to look at yet. 20 | 21 | CONTACT & SUPPORT 22 | ================= 23 | 24 | If you want to contribute to Magnum, if you spotted a bug, need a feature or 25 | have an awesome idea, you can get a copy of the sources from GitHub and start 26 | right away! 27 | 28 | - Project homepage — https://magnum.graphics/ 29 | - Documentation — https://doc.magnum.graphics/ 30 | - GitHub — https://github.com/mosra/magnum-bindings and the 31 | [#magnum](https://github.com/topics/magnum) topic 32 | - GitLab — https://gitlab.com/mosra/magnum-bindings 33 | - Gitter community chat — https://gitter.im/mosra/magnum 34 | - E-mail — info@magnum.graphics 35 | - Google Groups mailing list — magnum-engine@googlegroups.com 36 | ([archive](https://groups.google.com/forum/#!forum/magnum-engine)) 37 | - Bluesky — https://bsky.app/profile/mosra.cz 38 | 39 | See also the Magnum Project [Contact & Support page](https://magnum.graphics/contact/) 40 | for further information. 41 | 42 | CREDITS 43 | ======= 44 | 45 | See the [CREDITS.md](CREDITS.md) file for details. Big thanks to everyone 46 | involved! 47 | 48 | LICENSE 49 | ======= 50 | 51 | Magnum is licensed under the MIT/Expat license, see the [COPYING](COPYING) file 52 | for details. 53 | -------------------------------------------------------------------------------- /src/Magnum/PythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Magnum_PythonBindings_h 2 | #define Magnum_PythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include /* :( */ 30 | #include 31 | 32 | namespace Magnum { 33 | 34 | /* Stores additional stuff needed for proper refcounting of image views. Better 35 | than subclassing ImageView because then we would need to wrap it every time 36 | it's exposed to Python, making 3rd party bindings unnecessarily complex */ 37 | template struct PyImageViewHolder: std::unique_ptr { 38 | explicit PyImageViewHolder(T* object): PyImageViewHolder{object, pybind11::none{}} { 39 | /* Image view without an owner can only be empty */ 40 | CORRADE_INTERNAL_ASSERT(!object->data()); 41 | } 42 | 43 | explicit PyImageViewHolder(T* object, pybind11::object owner): std::unique_ptr{object}, owner{std::move(owner)} {} 44 | 45 | pybind11::object owner; 46 | }; 47 | 48 | template PyImageViewHolder pyImageViewHolder(const T& view, pybind11::object owner) { 49 | return PyImageViewHolder{new T{view}, std::move(owner)}; 50 | } 51 | 52 | } 53 | 54 | PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::PyImageViewHolder) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/Corrade/Containers/PythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Corrade_Containers_PythonBindings_h 2 | #define Corrade_Containers_PythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include /* :( */ 30 | #include 31 | 32 | namespace Corrade { namespace Containers { 33 | 34 | /* Stores additional stuff needed for proper refcounting of array views. Better 35 | than subclassing ArrayView because then we would need to wrap it every time 36 | it's exposed to Python, making 3rd party bindings unnecessarily complex. */ 37 | template struct PyArrayViewHolder: std::unique_ptr { 38 | explicit PyArrayViewHolder(T* object): PyArrayViewHolder{object, pybind11::none{}} { 39 | /* Array view without an owner can only be empty */ 40 | CORRADE_INTERNAL_ASSERT(!object->data()); 41 | } 42 | 43 | explicit PyArrayViewHolder(T* object, pybind11::object owner): std::unique_ptr{object}, owner{std::move(owner)} {} 44 | 45 | pybind11::object owner; 46 | }; 47 | 48 | template PyArrayViewHolder pyArrayViewHolder(const T& view, pybind11::object owner) { 49 | return PyArrayViewHolder{new T{view}, std::move(owner)}; 50 | } 51 | 52 | }} 53 | 54 | PYBIND11_DECLARE_HOLDER_TYPE(T, Corrade::Containers::PyArrayViewHolder) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /package/archlinux/PKGBUILD-coverage: -------------------------------------------------------------------------------- 1 | # Author: mosra 2 | pkgname=magnum-bindings 3 | pkgver=dev 4 | pkgrel=1 5 | pkgdesc="C++11/C++14 graphics middleware for games and data visualization — bindings" 6 | arch=('i686' 'x86_64') 7 | url="https://magnum.graphics" 8 | license=('MIT') 9 | depends=('corrade' 'magnum' 'python') 10 | makedepends=('cmake' 'ninja' 'pybind11' 'lcov' 'python-coverage') 11 | provides=('magnum-bindings-git') 12 | 13 | _rootdir=$startdir/../../ 14 | 15 | build() { 16 | mkdir -p "$_rootdir/build-coverage" 17 | cd "$_rootdir/build-coverage" 18 | 19 | # Disable optimization (saves A LOT of compilation time) 20 | newcxxflags=$(echo $CXXFLAGS | sed s/-O.//g | sed s/-D_FORTIFY_SOURCE=.//g) 21 | export CXXFLAGS="$newcxxflags" 22 | 23 | # Colored output is enabled implicitly. If Ninja detects it's outputting to 24 | # a pipe, it strips it away from the output, alternatively you can set the 25 | # GCC_COLORS= (empty) env variable to temporarily disable colors. The 26 | # inverse, i.e. preserving colors when Ninja outputs to a pipe can be done 27 | # with CLICOLOR_FORCE=1: https://github.com/ninja-build/ninja/issues/2196 28 | cmake .. \ 29 | -DCMAKE_CXX_FLAGS="--coverage" \ 30 | -DCMAKE_BUILD_TYPE=Debug \ 31 | -DCMAKE_INSTALL_PREFIX=/usr \ 32 | -DCMAKE_COLOR_DIAGNOSTICS=ON \ 33 | -DPYTHON_EXECUTABLE=$(which python) \ 34 | -DMAGNUM_WITH_PYTHON=ON \ 35 | -DMAGNUM_BUILD_TESTS=ON \ 36 | -G Ninja 37 | ninja 38 | } 39 | 40 | check() { 41 | # Python coverage 42 | cd "$_rootdir/src/python/corrade" 43 | CMAKE_BINARY_DIR="$_rootdir/build-coverage" coverage run -m unittest -v || true 44 | cp .coverage ../.coverage.corrade 45 | 46 | cd "$_rootdir/src/python/magnum" 47 | CMAKE_BINARY_DIR="$_rootdir/build-coverage" coverage run -m unittest -v || true 48 | cp .coverage ../.coverage.magnum 49 | 50 | cd .. 51 | coverage combine 52 | coverage html 53 | 54 | # C++ coverage 55 | cd "$_rootdir/build-coverage" 56 | 57 | rm -rf coverage 58 | mkdir coverage 59 | # Keep in sync with package/ci/circleci.yml, please 60 | # TODO figure out a way to avoid adding --ignore-errors mismatch etc 61 | lcov --ignore-errors mismatch,inconsistent --directory . --capture --output-file coverage.info 62 | lcov --ignore-errors inconsistent --extract coverage.info "*/src/python/*" "*/src/Corrade/*" "*/src/Magnum/*" --output-file coverage.info 63 | genhtml --no-function-coverage --missed --output-directory ./coverage coverage.info 64 | } 65 | 66 | package() { 67 | echo -e "Open \n file://${_rootdir}build-coverage/coverage/index.html\n file://${_rootdir}src/python/htmlcov/index.html\nto see the results." && false 68 | } 69 | -------------------------------------------------------------------------------- /src/Magnum/GL/PythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Magnum_GL_PythonBindings_h 2 | #define Magnum_GL_PythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include /* :( */ 30 | #include 31 | #include 32 | #include 33 | 34 | #include "Magnum/PythonBindings.h" 35 | 36 | namespace Magnum { namespace GL { 37 | 38 | /* Stores additional stuff needed for proper refcounting of buffers owned by 39 | a mesh. For some reason it *has to be* templated, otherwise 40 | PYBIND11_DECLARE_HOLDER_TYPE doesn't work. Ugh. */ 41 | template struct PyMeshHolder: std::unique_ptr { 42 | static_assert(std::is_same::value, "mesh holder has to hold a mesh"); 43 | 44 | explicit PyMeshHolder(T* object): std::unique_ptr{object} {} 45 | 46 | std::vector buffers; 47 | }; 48 | 49 | template struct PyFramebufferHolder: std::unique_ptr::value>> { 50 | static_assert(std::is_same::value, "framebuffer holder has to hold a framebuffer"); 51 | 52 | explicit PyFramebufferHolder(T* object): std::unique_ptr::value>>{object} {} 53 | 54 | std::vector attachments; 55 | }; 56 | 57 | }} 58 | 59 | PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::GL::PyMeshHolder) 60 | PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::GL::PyFramebufferHolder) 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/python/corrade/test/test_optional.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | 29 | #include "../bootstrap.h" /* for module / _module alias */ 30 | 31 | #include "Corrade/Containers/OptionalPythonBindings.h" 32 | 33 | using namespace Corrade; 34 | namespace py = pybind11; 35 | 36 | namespace { 37 | 38 | struct Foo { 39 | Foo(int a): a{a} {} 40 | int a; 41 | }; 42 | 43 | Containers::Optional simpleType(bool set) { 44 | return set ? Containers::optional(5) : Containers::NullOpt; 45 | } 46 | 47 | Containers::Optional nestedType(bool set) { 48 | return set ? Containers::optional(Foo{15}) : Containers::NullOpt; 49 | } 50 | 51 | int acquireSimpleType(Containers::Optional value) { 52 | return value ? *value : -1; 53 | } 54 | 55 | int acquireNestedType(Containers::Optional value) { 56 | return value ? value->a : -1; 57 | } 58 | 59 | } 60 | 61 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 62 | is released */ 63 | extern "C" PYBIND11_EXPORT PyObject* PyInit_test_optional(); 64 | PYBIND11_MODULE(test_optional, m) { 65 | py::module_::import("corrade.containers"); 66 | 67 | py::class_{m, "Foo"} 68 | .def(py::init()) 69 | .def_readwrite("a", &Foo::a); 70 | 71 | m.def("simple_type", simpleType); 72 | m.def("nested_type", nestedType); 73 | 74 | m.def("acquire_simple_type", acquireSimpleType); 75 | m.def("acquire_nested_type", acquireNestedType); 76 | } 77 | -------------------------------------------------------------------------------- /src/Corrade/Containers/OptionalPythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Corrade_Containers_OptionalPythonBindings_h 2 | #define Corrade_Containers_OptionalPythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | namespace pybind11 { namespace detail { 33 | 34 | /* pybind11/stl.h has optional_caster for this, but that relies on a value_type 35 | typedef that Optional doesn't have, so adapting a copy of it, also without 36 | std::is_lvalue_reference::value, which is not a thing here */ 37 | template struct type_caster> { 38 | using value_conv = make_caster; 39 | 40 | template static handle cast(T_&& src, const return_value_policy policy, const handle parent) { 41 | if(!src) return none{}.release(); 42 | return value_conv::cast(*std::forward(src), return_value_policy_override::policy(policy), parent); 43 | } 44 | 45 | bool load(const handle src, bool convert) { 46 | if(!src) return false; 47 | 48 | /* default-constructed value is already empty */ 49 | if(src.is_none()) return true; 50 | 51 | value_conv inner_caster; 52 | if(!inner_caster.load(src, convert)) return false; 53 | 54 | value.emplace(cast_op(std::move(inner_caster))); 55 | return true; 56 | } 57 | 58 | PYBIND11_TYPE_CASTER(Corrade::Containers::Optional, _("Optional[") + value_conv::name + _("]")); 59 | }; 60 | 61 | }} 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/python/magnum/test/test_scenegraph_numpy.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import unittest 28 | 29 | from magnum import * 30 | from magnum import scenegraph 31 | from magnum.scenegraph.matrix import Object3D, Scene3D 32 | 33 | try: 34 | import numpy as np 35 | except ModuleNotFoundError: 36 | raise unittest.SkipTest("numpy not installed") 37 | 38 | class Object(unittest.TestCase): 39 | def test_transformation(self): 40 | scene = Scene3D() 41 | 42 | a = Object3D(scene) 43 | 44 | # like a.rotate_local(Deg(35.0), Vector3.x_axis()), but way uglier, 45 | # another could be scipy.spatial.transform.Rotation but that's meh as 46 | # well 47 | a.transform_local(np.array( 48 | [[1.0, 0.0, 0.0, 0.0], 49 | [0.0, 0.819152, -0.573576, 0.0], 50 | [0.0, 0.573576, 0.819152, 0.0], 51 | [0.0, 0.0, 0.0, 1.0]])) 52 | self.assertEqual(a.transformation, Matrix4.rotation_x(Deg(35.0))) 53 | self.assertEqual(a.absolute_transformation(), Matrix4.rotation_x(Deg(35.0))) 54 | 55 | b = Object3D(a) 56 | b.translate(np.array([3.0, 4.0, 5.0], dtype='float32')) 57 | self.assertEqual(b.transformation, Matrix4.translation((3.0, 4.0, 5.0))) 58 | self.assertEqual(b.absolute_transformation(), 59 | Matrix4.rotation_x(Deg(35.0))@ 60 | Matrix4.translation((3.0, 4.0, 5.0))) 61 | 62 | c = Object3D(scene) 63 | self.assertEqual(c.transformation, Matrix4.identity_init()) 64 | self.assertEqual(c.absolute_transformation(), Matrix4.identity_init()) 65 | -------------------------------------------------------------------------------- /src/python/magnum/test/test_gl.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import unittest 28 | 29 | import magnum 30 | from magnum import gl 31 | 32 | class Attribute(unittest.TestCase): 33 | def test_init(self): 34 | a = gl.Attribute(gl.Attribute.Kind.GENERIC, 2, gl.Attribute.Components.TWO, gl.Attribute.DataType.FLOAT) 35 | self.assertEqual(a.kind, gl.Attribute.Kind.GENERIC) 36 | self.assertEqual(a.location, 2) 37 | self.assertEqual(a.components, gl.Attribute.Components.TWO) 38 | self.assertEqual(a.data_type, gl.Attribute.DataType.FLOAT) 39 | 40 | class Context(unittest.TestCase): 41 | def test_no_current(self): 42 | self.assertFalse(gl.Context.has_current) 43 | 44 | with self.assertRaisesRegex(RuntimeError, "no current context"): 45 | gl.Context.current 46 | 47 | class FramebufferClear(unittest.TestCase): 48 | def test_ops(self): 49 | self.assertEqual(gl.FramebufferClear.COLOR|gl.FramebufferClear.COLOR, gl.FramebufferClear.COLOR) 50 | self.assertFalse(gl.FramebufferClear.COLOR & ~gl.FramebufferClear.COLOR) 51 | 52 | class Version(unittest.TestCase): 53 | def test_enum_to_major_minor(self): 54 | if magnum.TARGET_GLES: 55 | self.assertEqual(gl.version(gl.Version.GLES200), (2, 0)) 56 | else: 57 | self.assertEqual(gl.version(gl.Version.GL430), (4, 3)) 58 | 59 | def test_major_minor_to_enum(self): 60 | if magnum.TARGET_GLES: 61 | self.assertEqual(gl.version(3, 0), gl.Version.GLES300) 62 | else: 63 | self.assertEqual(gl.version(4, 3), gl.Version.GL430) 64 | -------------------------------------------------------------------------------- /src/Magnum/Test/VersionTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "Magnum/Magnum.h" 31 | #include "Magnum/versionBindings.h" 32 | 33 | namespace Magnum { namespace Test { namespace { 34 | 35 | struct VersionTest: TestSuite::Tester { 36 | explicit VersionTest(); 37 | 38 | void test(); 39 | }; 40 | 41 | VersionTest::VersionTest() { 42 | addTests({&VersionTest::test}); 43 | } 44 | 45 | void VersionTest::test() { 46 | Debug{} << "MAGNUMBINDINGS_VERSION_YEAR:" << MAGNUMBINDINGS_VERSION_YEAR; 47 | Debug{} << "MAGNUMBINDINGS_VERSION_MONTH:" << MAGNUMBINDINGS_VERSION_MONTH; 48 | #ifdef MAGNUMBINDINGS_VERSION_COMMIT 49 | Debug{} << "MAGNUMBINDINGS_VERSION_COMMIT:" << MAGNUMBINDINGS_VERSION_COMMIT; 50 | Debug{} << "MAGNUMBINDINGS_VERSION_HASH:" << Debug::hex << MAGNUMBINDINGS_VERSION_HASH; 51 | Debug{} << "MAGNUMBINDINGS_VERSION_STRING:" << MAGNUMBINDINGS_VERSION_STRING; 52 | #else 53 | Debug{} << "No Git version information available."; 54 | #endif 55 | 56 | CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_YEAR, 2019, TestSuite::Compare::GreaterOrEqual); 57 | CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_YEAR, 2100, TestSuite::Compare::LessOrEqual); 58 | CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_MONTH, 0, TestSuite::Compare::Greater); 59 | CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_MONTH, 12, TestSuite::Compare::LessOrEqual); 60 | #ifdef MAGNUMBINDINGS_VERSION_COMMIT 61 | CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_COMMIT, 0, TestSuite::Compare::GreaterOrEqual); 62 | #endif 63 | } 64 | 65 | }}} 66 | 67 | CORRADE_TEST_MAIN(Magnum::Test::VersionTest) 68 | -------------------------------------------------------------------------------- /src/python/magnum/test/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import os 28 | import sys 29 | import unittest 30 | 31 | # TODO: do this differently / more robustly 32 | sys.path = [ 33 | os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python'), 34 | os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python/Release'), 35 | ] + sys.path 36 | 37 | from magnum import * 38 | from magnum import gl, platform 39 | 40 | try: 41 | from magnum.platform.glx import WindowlessApplication 42 | except ImportError: 43 | try: 44 | from magnum.platform.cgl import WindowlessApplication 45 | except ImportError: 46 | try: 47 | from magnum.platform.wgl import WindowlessApplication 48 | except ImportError: 49 | try: 50 | from magnum.platform.egl import WindowlessApplication 51 | except ImportError: 52 | WindowlessApplication = None 53 | 54 | def setUpModule(): 55 | if os.environ.get('MAGNUM_SKIP_GL_TESTS') == 'ON': 56 | raise unittest.SkipTest('GL tests skipped') 57 | 58 | if not WindowlessApplication: 59 | raise unittest.SkipTest('no WindowlessApplication found') 60 | 61 | class GLTestCase(unittest.TestCase): 62 | app = None 63 | 64 | @classmethod 65 | def setUpClass(cls): 66 | if not GLTestCase.app: 67 | GLTestCase.app = WindowlessApplication() 68 | 69 | def assertNoGLError(self): 70 | self.assertEqual(gl.Renderer.error, gl.Renderer.Error.NO_ERROR) 71 | 72 | def setUp(self): 73 | self.assertNoGLError() 74 | 75 | def tearDown(self): 76 | self.assertNoGLError() 77 | -------------------------------------------------------------------------------- /src/python/magnum/scenegraph.matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "scenegraph.h" 31 | 32 | namespace magnum { 33 | 34 | void scenegraphMatrix(py::module_& m) { 35 | py::module_ matrix = m.def_submodule("matrix"); 36 | matrix.doc() = "General matrix-based scene graph implementation"; 37 | 38 | py::class_> scene2D_{matrix, "Scene2D", "Two-dimensional scene with matrix-based transformation implementation"}; 39 | scene(scene2D_); 40 | 41 | py::class_> scene3D_{matrix, "Scene3D", "Three-dimensional scene with matrix-based transformation implementation"}; 42 | scene(scene3D_); 43 | 44 | py::class_, SceneGraph::PyObject>, SceneGraph::AbstractObject2D, SceneGraph::PyObjectHolder>> object2D_{matrix, "Object2D", "Two-dimensional object with matrix-based transformation implementation"}; 45 | object(object2D_); 46 | objectTransform(object2D_); 47 | object2D(object2D_); 48 | objectScale(object2D_); 49 | objectReflect(object2D_); 50 | 51 | py::class_, SceneGraph::PyObject>, SceneGraph::AbstractObject3D, SceneGraph::PyObjectHolder>> object3D_{matrix, "Object3D", "Three-dimensional object with matrix-based transformation implementation"}; 52 | object(object3D_); 53 | objectTransform(object3D_); 54 | object3D(object3D_); 55 | objectScale(object3D_); 56 | objectReflect(object3D_); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/Corrade/PluginManager/PythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Corrade_PluginManager_PythonBindings_h 2 | #define Corrade_PluginManager_PythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include /* :( */ 30 | #include 31 | #include 32 | #include 33 | 34 | namespace Corrade { namespace PluginManager { 35 | 36 | /* Stores additional stuff needed for proper refcounting of plugin instances. 37 | Due to obvious reasons we can't subclass plugins so this is the only 38 | possible way. */ 39 | template struct PyPluginHolder: std::unique_ptr { 40 | explicit PyPluginHolder(T* object) noexcept: std::unique_ptr{object} { 41 | /* Plugin instance without an owner can only be without a manager and 42 | thus without any metadata */ 43 | CORRADE_INTERNAL_ASSERT(!object->metadata()); 44 | } 45 | 46 | explicit PyPluginHolder(T* object, pybind11::object manager) noexcept: std::unique_ptr{object}, manager{std::move(manager)} {} 47 | 48 | PyPluginHolder(PyPluginHolder&&) noexcept = default; 49 | PyPluginHolder(const PyPluginHolder&) = delete; 50 | PyPluginHolder& operator=(PyPluginHolder&&) noexcept = default; 51 | PyPluginHolder& operator=(const PyPluginHolder&) = delete; 52 | 53 | ~PyPluginHolder() { 54 | /* On destruction, first `manager` and then the plugin would be 55 | destroyed, which would mean it asserts due to the manager being 56 | destructed while plugins are still around. To flip the order, we 57 | need to reset the pointer first */ 58 | std::unique_ptr::reset(); 59 | } 60 | 61 | pybind11::object manager; 62 | }; 63 | 64 | template PyPluginHolder pyPluginHolder(Containers::Pointer&& plugin, pybind11::object owner) { 65 | return PyPluginHolder{plugin.release(), std::move(owner)}; 66 | } 67 | 68 | }} 69 | 70 | PYBIND11_DECLARE_HOLDER_TYPE(T, Corrade::PluginManager::PyPluginHolder) 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/python/magnum/test/mesh.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "version": "2.0" 4 | }, 5 | "meshes": [ 6 | { 7 | "name": "Indexed mesh", 8 | "primitives": [ 9 | { 10 | "attributes": { 11 | "POSITION": 1, 12 | "TEXCOORD_0": 2, 13 | "COLOR": 3, 14 | "_OBJECT_ID": 4, 15 | "TEXCOORD_1": 2, 16 | "JOINTS_0": 5, 17 | "WEIGHTS_0": 6, 18 | "_CUSTOM_PACKED_ATTRIBUTE": 7, 19 | "_CUSTOM_MATRIX_ATTRIBUTE": 8 20 | }, 21 | "indices": 0 22 | } 23 | ] 24 | }, 25 | { 26 | "name": "Non-indexed mesh", 27 | "primitives": [ 28 | { 29 | "attributes": { 30 | "POSITION": 1 31 | } 32 | } 33 | ] 34 | }, 35 | { 36 | "name": "A broken mesh", 37 | "primitives": [ 38 | { 39 | "mode": 666 40 | } 41 | ] 42 | }, 43 | { 44 | "name": "Point mesh", 45 | "primitives": [ 46 | { 47 | "attributes": { 48 | "POSITION": 1 49 | }, 50 | "mode": 0 51 | } 52 | ] 53 | }, 54 | { 55 | "name": "Custom mesh attribute", 56 | "primitives": [ 57 | { 58 | "attributes": { 59 | "_FOOBARTHINGY": 1 60 | } 61 | } 62 | ] 63 | } 64 | ], 65 | "accessors": [ 66 | { 67 | "bufferView": 0, 68 | "byteOffset": 2, 69 | "componentType": 5123, 70 | "count": 3, 71 | "type": "SCALAR" 72 | }, 73 | { 74 | "bufferView": 1, 75 | "componentType": 5126, 76 | "count": 3, 77 | "type": "VEC3" 78 | }, 79 | { 80 | "bufferView": 1, 81 | "byteOffset": 12, 82 | "componentType": 5126, 83 | "count": 3, 84 | "type": "VEC2" 85 | }, 86 | { 87 | "bufferView": 1, 88 | "byteOffset": 20, 89 | "componentType": 5121, 90 | "normalized": true, 91 | "count": 3, 92 | "type": "VEC3" 93 | }, 94 | { 95 | "bufferView": 1, 96 | "byteOffset": 24, 97 | "componentType": 5125, 98 | "count": 3, 99 | "type": "SCALAR" 100 | }, 101 | { 102 | "bufferView": 1, 103 | "byteOffset": 20, 104 | "componentType": 5121, 105 | "count": 3, 106 | "type": "VEC4" 107 | }, 108 | { 109 | "bufferView": 1, 110 | "byteOffset": 0, 111 | "componentType": 5126, 112 | "count": 3, 113 | "type": "VEC4" 114 | }, 115 | { 116 | "bufferView": 1, 117 | "byteOffset": 20, 118 | "componentType": 5121, 119 | "count": 3, 120 | "type": "VEC3" 121 | }, 122 | { 123 | "bufferView": 1, 124 | "byteOffset": 0, 125 | "componentType": 5126, 126 | "count": 3, 127 | "type": "MAT2" 128 | } 129 | ], 130 | "bufferViews": [ 131 | { 132 | "buffer": 0, 133 | "byteOffset": 0, 134 | "byteLength": 8 135 | }, 136 | { 137 | "buffer": 0, 138 | "byteOffset": 8, 139 | "byteLength": 84, 140 | "byteStride": 28 141 | } 142 | ], 143 | "buffers": [ 144 | { 145 | "byteLength": 92, 146 | "uri": "mesh.bin" 147 | } 148 | ] 149 | } 150 | 151 | -------------------------------------------------------------------------------- /src/python/corrade/__init__.py.in: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | """Root Corrade module""" 28 | 29 | # If MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL is enabled in CMake, the lines 30 | # below are included, otherwise they are commented out. What it does is a 31 | # futile attempt to make Corrade (and Magnum) built as static libraries work 32 | # together when built into multiple dynamic Python modules. 33 | ${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}import sys 34 | ${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}import ctypes 35 | ${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}sys.setdlopenflags(sys.getdlopenflags()|ctypes.RTLD_GLOBAL) 36 | 37 | # On Windows, if a known directory layout is detected, add paths containing 38 | # binaries to the DLL search path 39 | import platform 40 | if platform.system() == 'Windows': 41 | import os 42 | 43 | for directory in [ 44 | # Prebuilt binaries from the magnum-ci repo have this file in 45 | # python/corrade/ and DLLs in bin/ 46 | '../../bin' 47 | ]: 48 | bin_path = os.path.join(os.path.dirname(__file__), directory) 49 | if os.path.exists(bin_path): 50 | os.add_dll_directory(bin_path) 51 | break 52 | 53 | from _corrade import * 54 | 55 | import sys 56 | 57 | # In case Corrade is built statically, the whole core project is put into 58 | # _corrade. The following feels extremely hackish, but without that it wouldn't 59 | # be possible to do `import corrade.containers`, which is weird 60 | # (`from corrade import containers` works, tho, for whatever reason) 61 | for i in ['containers', 'pluginmanager', 'utility']: 62 | if i in globals(): sys.modules['corrade.' + i] = globals()[i] 63 | 64 | # Just to not have the variable leak into stubs generated by pybind11-stubgen 65 | # TODO any way to exclude it? 66 | del i 67 | 68 | # Prevent all submodules being pulled in when saying `from corrade import *` -- 69 | # this is consistent with behavior in magnum 70 | __all__ = [ 71 | # TARGET_*, BUILD_* are omitted as `from corrade import *` would pull them 72 | # to globals and this would likely cause conflicts (magnum also defines 73 | # BUILD_*) 74 | ] 75 | 76 | # kate: hl python 77 | -------------------------------------------------------------------------------- /src/python/magnum/bootstrap.h: -------------------------------------------------------------------------------- 1 | #ifndef magnum_bootstrap_h 2 | #define magnum_bootstrap_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | #include /* for PYBIND11_VERSION_* */ 31 | #include 32 | 33 | namespace pybind11 { 34 | /* pybind11 2.6 changes py::module to py::module_ to be compatible with C++ 35 | modules. In order to be forward-compatible, we use module_ everywhere 36 | and define it as an alias to module on < 2.6 */ 37 | #if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206 38 | class module_; 39 | #else 40 | class module; 41 | typedef module module_; 42 | #endif 43 | } 44 | 45 | namespace Magnum {} 46 | 47 | namespace magnum { 48 | 49 | using namespace Magnum; 50 | namespace py = pybind11; 51 | 52 | template struct PyDimensionTraits; 53 | template struct PyDimensionTraits<1, T> { 54 | typedef T VectorType; 55 | static VectorType from(const Math::Vector<1, T>& vec) { return vec[0]; } 56 | }; 57 | template struct PyDimensionTraits<2, T> { 58 | typedef Math::Vector2 VectorType; 59 | static VectorType from(const Math::Vector<2, T>& vec) { return vec; } 60 | }; 61 | template struct PyDimensionTraits<3, T> { 62 | typedef Math::Vector3 VectorType; 63 | static VectorType from(const Math::Vector<3, T>& vec) { return vec; } 64 | }; 65 | 66 | void math(py::module_& root, py::module_& m); 67 | void mathVectorFloat(py::module_& root, py::module_& m); 68 | void mathVectorIntegral(py::module_& root, py::module_& m); 69 | void mathMatrixFloat(py::module_& root, PyTypeObject* metaclass); 70 | void mathMatrixDouble(py::module_& root, PyTypeObject* metaclass); 71 | void mathRange(py::module_& root, py::module_& m); 72 | 73 | void gl(py::module_& m); 74 | void materialtools(py::module_& m); 75 | void meshtools(py::module_& m); 76 | void primitives(py::module_& m); 77 | void scenegraph(py::module_& m); 78 | void scenetools(py::module_& m); 79 | void shaders(py::module_& m); 80 | void text(py::module_& m); 81 | void trade(py::module_& m); 82 | 83 | namespace platform { 84 | void glfw(py::module_& m); 85 | void sdl2(py::module_& m); 86 | 87 | void cgl(py::module_& m); 88 | void egl(py::module_& m); 89 | void glx(py::module_& m); 90 | void wgl(py::module_& m); 91 | } 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/python/magnum/math.h: -------------------------------------------------------------------------------- 1 | #ifndef magnum_math_h 2 | #define magnum_math_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "magnum/bootstrap.h" 35 | 36 | namespace magnum { 37 | 38 | /* Keep in sync with math.cpp */ 39 | 40 | extern const char* const FormatStrings[]; 41 | template constexpr std::size_t formatIndex(); 42 | template<> constexpr std::size_t formatIndex() { return 0; } 43 | template<> constexpr std::size_t formatIndex() { return 1; } 44 | template<> constexpr std::size_t formatIndex() { return 2; } 45 | template<> constexpr std::size_t formatIndex() { return 3; } 46 | template<> constexpr std::size_t formatIndex() { return 4; } 47 | template<> constexpr std::size_t formatIndex() { return 5; } 48 | template<> constexpr std::size_t formatIndex() { return 6; } 49 | 50 | extern const Py_ssize_t MatrixShapes[][2]; 51 | template constexpr std::size_t matrixShapeStrideIndex(); 52 | template<> constexpr std::size_t matrixShapeStrideIndex<2, 2>() { return 0; } 53 | template<> constexpr std::size_t matrixShapeStrideIndex<2, 3>() { return 1; } 54 | template<> constexpr std::size_t matrixShapeStrideIndex<2, 4>() { return 2; } 55 | template<> constexpr std::size_t matrixShapeStrideIndex<3, 2>() { return 3; } 56 | template<> constexpr std::size_t matrixShapeStrideIndex<3, 3>() { return 4; } 57 | template<> constexpr std::size_t matrixShapeStrideIndex<3, 4>() { return 5; } 58 | template<> constexpr std::size_t matrixShapeStrideIndex<4, 2>() { return 6; } 59 | template<> constexpr std::size_t matrixShapeStrideIndex<4, 3>() { return 7; } 60 | template<> constexpr std::size_t matrixShapeStrideIndex<4, 4>() { return 8; } 61 | 62 | extern const Py_ssize_t MatrixStridesFloat[][2]; 63 | extern const Py_ssize_t MatrixStridesDouble[][2]; 64 | template constexpr const Py_ssize_t* matrixStridesFor(std::size_t i); 65 | template<> constexpr const Py_ssize_t* matrixStridesFor(std::size_t i) { 66 | return MatrixStridesFloat[i]; 67 | } 68 | template<> constexpr const Py_ssize_t* matrixStridesFor(std::size_t i) { 69 | return MatrixStridesDouble[i]; 70 | } 71 | 72 | template std::string repr(const T& value) { 73 | std::ostringstream out; 74 | Debug{&out, Debug::Flag::NoNewlineAtTheEnd} << value; 75 | return out.str(); 76 | } 77 | 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /doc/python/magnum.primitives.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:function:: magnum.primitives.capsule2d_wireframe 28 | :raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1` 29 | :raise AssertionError: If :p:`cylinder_rings` is less than :py:`1` 30 | .. py:function:: magnum.primitives.capsule3d_solid 31 | :raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1` 32 | :raise AssertionError: If :p:`cylinder_rings` is less than :py:`1` 33 | :raise AssertionError: If :p:`segments` is less than :py:`3` 34 | .. py:function:: magnum.primitives.capsule3d_wireframe 35 | :raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1` 36 | :raise AssertionError: If :p:`cylinder_rings` is less than :py:`1` 37 | :raise AssertionError: If :p:`segments` is zero or not a multiple of 38 | :py:`4` 39 | 40 | .. py:function:: magnum.primitives.circle2d_solid 41 | :raise AssertionError: If :p:`segments` is less than :py:`3` 42 | .. py:function:: magnum.primitives.circle2d_wireframe 43 | :raise AssertionError: If :p:`segments` is less than :py:`3` 44 | .. py:function:: magnum.primitives.circle3d_solid 45 | :raise AssertionError: If :p:`segments` is less than :py:`3` 46 | .. py:function:: magnum.primitives.circle3d_wireframe 47 | :raise AssertionError: If :p:`segments` is less than :py:`3` 48 | 49 | .. py:function:: magnum.primitives.cone_solid 50 | :raise AssertionError: If :p:`rings` is less than :py:`1` 51 | :raise AssertionError: If :p:`segments` is less than :py:`3` 52 | .. py:function:: magnum.primitives.cone_wireframe 53 | :raise AssertionError: If :p:`segments` is zero or not a multiple of 54 | :py:`4` 55 | 56 | .. py:function:: magnum.primitives.cylinder_solid 57 | :raise AssertionError: If :p:`rings` is less than :py:`1` 58 | :raise AssertionError: If :p:`segments` is less than :py:`3` 59 | .. py:function:: magnum.primitives.cylinder_wireframe 60 | :raise AssertionError: If :p:`rings` is less than :py:`1` 61 | :raise AssertionError: If :p:`segments` is zero or not a multiple of 62 | :py:`4` 63 | 64 | .. py:function:: magnum.primitives.uv_sphere_solid 65 | :raise AssertionError: If :p:`rings` is less than :py:`2` 66 | :raise AssertionError: If :p:`segments` is less than :py:`3` 67 | .. py:function:: magnum.primitives.uv_sphere_wireframe 68 | :raise AssertionError: If :p:`rings` is zero or not a multiple of :py:`2` 69 | :raise AssertionError: If :p:`segments` is zero or not a multiple of 70 | :py:`4` 71 | -------------------------------------------------------------------------------- /src/python/magnum/platform/holder.h: -------------------------------------------------------------------------------- 1 | #ifndef magnum_platform_holder_h 2 | #define magnum_platform_holder_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | 31 | namespace magnum { namespace platform { namespace { 32 | 33 | /* Takes care of updating magnum::glContextOwner so it doesn't need to be 34 | duplicated in every application implementation */ 35 | template struct ApplicationHolder: std::unique_ptr { 36 | explicit ApplicationHolder(T* object): std::unique_ptr{object} { 37 | /* There's no real possibility to export a symbol from magnum.gl and 38 | access it from here (because there's no real possibility for a 39 | module to ensure another module is loaded before it in order to make 40 | the symbols resolve correctly; Corrade's PluginManager does that by 41 | having dependency info *external* to the module, that's the only 42 | way), so we're sharing the data using a bunch of very ugly 43 | allocations instead. Fortunately construction/destruction of an 44 | application happens *very seldom*, and gl.Context.current() 45 | hopefully also not that often. Yes, the parameter is a std::string. 46 | JOY. */ 47 | auto* glContextOwner = static_cast*>(py::get_shared_data("magnumGLContextOwner")); 48 | if(!glContextOwner) 49 | py::set_shared_data("magnumGLContextOwner", glContextOwner = new std::pair{}); 50 | 51 | CORRADE_ASSERT(!glContextOwner->first, "Sorry, just one magnum.*.Application instance can exist at a time", ); 52 | *glContextOwner = {object, &typeid(T)}; 53 | } 54 | 55 | ApplicationHolder(ApplicationHolder&&) noexcept = default; 56 | ApplicationHolder(const ApplicationHolder&) = delete; 57 | 58 | ~ApplicationHolder() { 59 | auto* glContextOwner = static_cast*>(py::get_shared_data("magnumGLContextOwner")); 60 | CORRADE_INTERNAL_ASSERT(glContextOwner && glContextOwner->first == this->get()); 61 | delete glContextOwner; 62 | py::set_shared_data("magnumGLContextOwner", nullptr); 63 | } 64 | 65 | ApplicationHolder& operator=(ApplicationHolder&&) noexcept = default; 66 | ApplicationHolder& operator=(const ApplicationHolder&) = default; 67 | }; 68 | 69 | }}} 70 | 71 | PYBIND11_DECLARE_HOLDER_TYPE(T, magnum::platform::ApplicationHolder) 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /doc/python/pages/credits.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | Credits 28 | ####### 29 | 30 | :ref-prefix: 31 | corrade 32 | magnum 33 | :summary: Third-party dependencies and their corresponding license information; 34 | people and organizations that contributed to Magnum Python Bindings. 35 | 36 | `Third-party components`_ 37 | ========================= 38 | 39 | .. TODO: ffs doxygen SORT YOUR SHIT OUT, why can't I link to 40 | credits-third-party?! 41 | .. role:: doxygen-you-fool(link) 42 | :class: m-doc-external 43 | 44 | While Magnum Python Bindings themselves don't depend on much, a lot of 45 | third-party components is used transitively from the Magnum C++ implementation. 46 | Please see the :ref:`main page ` for license of Magnum 47 | Python Bindings themselves and the 48 | :doxygen-you-fool:`Third-party components ` 49 | page of C++ docs for a detailed overview of all used components. The list below 50 | uses the same color-coding scheme for easier overview: 51 | 52 | :ref:`Magnum Python Bindings ` 53 | Bindings generated with :gh:`pybind11 `, released under a 54 | :label-success:`BSD-style license` 55 | (`license text `_, 56 | `choosealicense.com `_). 57 | It requires attribution for public use. 58 | 59 | `Contributors`_ 60 | =============== 61 | 62 | Listing only people with code contributions or other significant work, because 63 | otherwise there's too many :) There's also a 64 | :dox:`similar list for Corrade ` and 65 | :dox:`Magnum ` themselves. Big thanks to everyone 66 | involved! 67 | 68 | .. class:: m-text-center m-text m-dim 69 | 70 | Are the below lists missing your name or something's wrong? 71 | `Let us know! `_ 72 | 73 | - **Aaron Gokaslan** (:gh:`Skylion007`) --- minor performance and 74 | documentation fixes, expanding :ref:`Color3` / :ref:`Color4` bindings 75 | - **Cameron Egbert** (:gh:`cegbertOculus`) --- initial Windows port 76 | - **James Murphy** (:gh:`mCodingLLC`) --- buildsystem fixes, expanding 77 | :ref:`gl.Framebuffer` bindings 78 | - **John Laxson** (:gh:`jlaxson`) --- Homebrew package improvements 79 | - **Stanislaw Halik** (:gh:`sthalik`) --- build fixes 80 | - **Vladimir Gamalyan** (:gh:`vladimirgamalyan`) --- expanding 81 | :ref:`gl.Renderer` bindings 82 | -------------------------------------------------------------------------------- /src/python/magnum/platform/cgl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "magnum/bootstrap.h" 32 | #include "magnum/platform/windowlessapplication.h" 33 | #include "magnum/platform/holder.h" 34 | 35 | namespace magnum { namespace platform { 36 | 37 | namespace { 38 | int argc = 0; 39 | } 40 | 41 | void cgl(py::module_& m) { 42 | m.doc() = "CGL-based platform integration"; 43 | 44 | struct PyWindowlessApplication: Platform::WindowlessApplication { 45 | explicit PyWindowlessApplication(const Configuration& configuration = Configuration{}): Platform::WindowlessApplication{Arguments{argc, nullptr}, configuration} {} 46 | 47 | int exec() override { 48 | #ifdef __clang__ 49 | /* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a 50 | warning here. Why there's no PYBIND11_OVERLOAD_PURE_NAME_ARG() 51 | variant *with* arguments and one without? */ 52 | #pragma GCC diagnostic push 53 | #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 54 | #endif 55 | PYBIND11_OVERLOAD_PURE_NAME( 56 | int, 57 | PyWindowlessApplication, 58 | "exec", 59 | ); 60 | #ifdef __clang__ 61 | #pragma GCC diagnostic pop 62 | #endif 63 | } 64 | 65 | /* The base doesn't have a virtual destructor because in C++ it's never 66 | deleted through a pointer to the base. Here we need it, though. */ 67 | virtual ~PyWindowlessApplication() = default; 68 | }; 69 | 70 | py::class_> windowlessGlxApplication{m, "WindowlessApplication", "Windowless CGL application"}; 71 | 72 | windowlessapplication(windowlessGlxApplication); 73 | 74 | /* Exposing a subclass to avoid the same type being exposed in multiple 75 | (glx, egl...) modules. */ 76 | struct PyContext: Platform::GLContext {}; 77 | py::class_ glContext{m, "Context", "CGL-specific Magnum OpenGL context"}; 78 | 79 | context(glContext); 80 | } 81 | 82 | }} 83 | 84 | #ifndef MAGNUM_BUILD_STATIC 85 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 86 | is released */ 87 | extern "C" PYBIND11_EXPORT PyObject* PyInit_cgl(); 88 | PYBIND11_MODULE(cgl, m) { 89 | magnum::platform::cgl(m); 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /src/python/magnum/platform/egl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "magnum/bootstrap.h" 32 | #include "magnum/platform/windowlessapplication.h" 33 | #include "magnum/platform/holder.h" 34 | 35 | namespace magnum { namespace platform { 36 | 37 | namespace { 38 | int argc = 0; 39 | } 40 | 41 | void egl(py::module_& m) { 42 | m.doc() = "EGL-based platform integration"; 43 | 44 | struct PyWindowlessApplication: Platform::WindowlessApplication { 45 | explicit PyWindowlessApplication(const Configuration& configuration = Configuration{}): Platform::WindowlessApplication{Arguments{argc, nullptr}, configuration} {} 46 | 47 | int exec() override { 48 | #ifdef __clang__ 49 | /* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a 50 | warning here. Why there's no PYBIND11_OVERLOAD_PURE_NAME_ARG() 51 | variant *with* arguments and one without? */ 52 | #pragma GCC diagnostic push 53 | #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 54 | #endif 55 | PYBIND11_OVERLOAD_PURE_NAME( 56 | int, 57 | PyWindowlessApplication, 58 | "exec", 59 | ); 60 | #ifdef __clang__ 61 | #pragma GCC diagnostic pop 62 | #endif 63 | } 64 | 65 | /* The base doesn't have a virtual destructor because in C++ it's never 66 | deleted through a pointer to the base. Here we need it, though. */ 67 | virtual ~PyWindowlessApplication() = default; 68 | }; 69 | 70 | py::class_> windowlessEglApplication{m, "WindowlessApplication", "Windowless EGL application"}; 71 | 72 | windowlessapplication(windowlessEglApplication); 73 | 74 | /* Exposing a subclass to avoid the same type being exposed in multiple 75 | (glx, egl...) modules. */ 76 | struct PyContext: Platform::GLContext {}; 77 | py::class_ glContext{m, "Context", "EGL-specific Magnum OpenGL context"}; 78 | 79 | context(glContext); 80 | } 81 | 82 | }} 83 | 84 | #ifndef MAGNUM_BUILD_STATIC 85 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 86 | is released */ 87 | extern "C" PYBIND11_EXPORT PyObject* PyInit_egl(); 88 | PYBIND11_MODULE(egl, m) { 89 | magnum::platform::egl(m); 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /src/python/magnum/platform/glx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "magnum/bootstrap.h" 32 | #include "magnum/platform/windowlessapplication.h" 33 | #include "magnum/platform/holder.h" 34 | 35 | namespace magnum { namespace platform { 36 | 37 | namespace { 38 | int argc = 0; 39 | } 40 | 41 | void glx(py::module_& m) { 42 | m.doc() = "GLX-based platform integration"; 43 | 44 | struct PyWindowlessApplication: Platform::WindowlessApplication { 45 | explicit PyWindowlessApplication(const Configuration& configuration = Configuration{}): Platform::WindowlessApplication{Arguments{argc, nullptr}, configuration} {} 46 | 47 | int exec() override { 48 | #ifdef __clang__ 49 | /* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a 50 | warning here. Why there's no PYBIND11_OVERLOAD_PURE_NAME_ARG() 51 | variant *with* arguments and one without? */ 52 | #pragma GCC diagnostic push 53 | #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 54 | #endif 55 | PYBIND11_OVERLOAD_PURE_NAME( 56 | int, 57 | PyWindowlessApplication, 58 | "exec", 59 | ); 60 | #ifdef __clang__ 61 | #pragma GCC diagnostic pop 62 | #endif 63 | } 64 | 65 | /* The base doesn't have a virtual destructor because in C++ it's never 66 | deleted through a pointer to the base. Here we need it, though. */ 67 | virtual ~PyWindowlessApplication() = default; 68 | }; 69 | 70 | py::class_> windowlessGlxApplication{m, "WindowlessApplication", "Windowless GLX application"}; 71 | 72 | windowlessapplication(windowlessGlxApplication); 73 | 74 | /* Exposing a subclass to avoid the same type being exposed in multiple 75 | (glx, egl...) modules. */ 76 | struct PyContext: Platform::GLContext {}; 77 | py::class_ glContext{m, "Context", "GLX-specific Magnum OpenGL context"}; 78 | 79 | context(glContext); 80 | } 81 | 82 | }} 83 | 84 | #ifndef MAGNUM_BUILD_STATIC 85 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 86 | is released */ 87 | extern "C" PYBIND11_EXPORT PyObject* PyInit_glx(); 88 | PYBIND11_MODULE(glx, m) { 89 | magnum::platform::glx(m); 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /src/python/magnum/platform/wgl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "magnum/bootstrap.h" 32 | #include "magnum/platform/windowlessapplication.h" 33 | #include "magnum/platform/holder.h" 34 | 35 | namespace magnum { namespace platform { 36 | 37 | namespace { 38 | int argc = 0; 39 | } 40 | 41 | void wgl(py::module_& m) { 42 | m.doc() = "WGL-based platform integration"; 43 | 44 | struct PyWindowlessApplication: Platform::WindowlessApplication { 45 | explicit PyWindowlessApplication(const Configuration& configuration = Configuration{}): Platform::WindowlessApplication{Arguments{argc, nullptr}, configuration} {} 46 | 47 | int exec() override { 48 | #ifdef __clang__ 49 | /* ugh pybind don't tell me I AM THE FIRST ON EARTH to get a 50 | warning here. Why there's no PYBIND11_OVERLOAD_PURE_NAME_ARG() 51 | variant *with* arguments and one without? */ 52 | #pragma GCC diagnostic push 53 | #pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 54 | #endif 55 | PYBIND11_OVERLOAD_PURE_NAME( 56 | int, 57 | PyWindowlessApplication, 58 | "exec", 59 | ); 60 | #ifdef __clang__ 61 | #pragma GCC diagnostic pop 62 | #endif 63 | } 64 | 65 | /* The base doesn't have a virtual destructor because in C++ it's never 66 | deleted through a pointer to the base. Here we need it, though. */ 67 | virtual ~PyWindowlessApplication() = default; 68 | }; 69 | 70 | py::class_> windowlessWglApplication{m, "WindowlessApplication", "Windowless WGL application"}; 71 | 72 | windowlessapplication(windowlessWglApplication); 73 | 74 | /* Exposing a subclass to avoid the same type being exposed in multiple 75 | (glx, egl...) modules. */ 76 | struct PyContext: Platform::GLContext {}; 77 | py::class_ glContext{m, "Context", "WGL-specific Magnum OpenGL context"}; 78 | 79 | context(glContext); 80 | } 81 | 82 | }} 83 | 84 | #ifndef MAGNUM_BUILD_STATIC 85 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 86 | is released */ 87 | extern "C" PYBIND11_EXPORT PyObject* PyInit_wgl(); 88 | PYBIND11_MODULE(wgl, m) { 89 | magnum::platform::wgl(m); 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /src/python/corrade/PyBuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef corrade_PyBuffer_h 2 | #define corrade_PyBuffer_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "Corrade/PythonBindings.h" 34 | 35 | #include "bootstrap.h" 36 | 37 | namespace corrade { 38 | 39 | /* pybind's py::buffer_info is EXTREMELY USELESS IT HURTS (and also allocates 40 | like hell), doing my own thing here instead. IMAGINE, I can pass flags to 41 | say what features I'm able to USE! WOW! */ 42 | 43 | template void enableBetterBufferProtocol(py::object& object) { 44 | auto& typeObject = reinterpret_cast(*object.ptr()); 45 | /* Sanity check -- we expect pybind set up its own buffer functions before 46 | us */ 47 | CORRADE_INTERNAL_ASSERT(typeObject.as_buffer.bf_getbuffer == pybind11::detail::pybind11_getbuffer); 48 | CORRADE_INTERNAL_ASSERT(typeObject.as_buffer.bf_releasebuffer == pybind11::detail::pybind11_releasebuffer); 49 | 50 | typeObject.as_buffer.bf_getbuffer = [](PyObject *obj, Py_buffer *buffer, int flags) { 51 | CORRADE_INTERNAL_ASSERT(!PyErr_Occurred() && buffer); 52 | 53 | /* Zero-initialize the output and ask the class to fill it. If that 54 | fails for some reason, give up. Need to list all members otherwise 55 | GCC 4.8 loudly complains about missing initializers. */ 56 | *buffer = Py_buffer{nullptr, nullptr, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr}; 57 | if(!getter(pyInstanceFromHandle(obj), *buffer, flags)) { 58 | CORRADE_INTERNAL_ASSERT(!buffer->obj); 59 | CORRADE_INTERNAL_ASSERT(PyErr_Occurred()); 60 | return -1; 61 | } 62 | 63 | /* Set the memory owner to the object and increase its reference count. 64 | We need to keep the object around because buffer->shapes / 65 | buffer->strides might be referring to it, moreover setting it to 66 | something else (like ArrayView's memory owner object) would mean 67 | Python calls the releasebuffer on that object instead of on us, 68 | leading to reference count getting negative in many cases. */ 69 | CORRADE_INTERNAL_ASSERT(!buffer->obj); 70 | buffer->obj = obj; 71 | Py_INCREF(buffer->obj); 72 | return 0; 73 | }; 74 | /* No need to release anything, we haven't made any garbage in the first 75 | place */ 76 | typeObject.as_buffer.bf_releasebuffer = nullptr; 77 | } 78 | 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /doc/python/pages/developers.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | Developers Guide 28 | ################ 29 | 30 | :ref-prefix: 31 | corrade 32 | magnum 33 | :summary: Checklists for developing new things in Magnum Python bindings 34 | themselves. 35 | 36 | .. role:: cmake(code) 37 | :language: cmake 38 | .. role:: cpp(code) 39 | :language: c++ 40 | .. role:: py(code) 41 | :language: py 42 | 43 | `Checklist for adding / removing bindings for a library`_ 44 | ========================================================= 45 | 46 | 1. Add a corresponding ``Foo`` Magnum dependency to the :cmake:`find_package()` 47 | call in ``src/python/magnum/CMakeLists.txt``, create a ``magnum_foo_SRCS`` 48 | variable with its source file(s). 49 | 2. Add a :cmake:`if(Magnum_Foo_FOUND)` branch to the 50 | :cmake:`if(NOT MAGNUM_BUILD_STATIC)` condition, adding a new ``magnum_foo`` 51 | module from ``magnum_foo_SRCS``, linking to ``Magnum::Foo`` and setting 52 | ``OUTPUT_NAME`` to ``foo``. 53 | 3. Add a :cmake:`if(Magnum_Foo_FOUND)` branch to the :cmake:`else()` 54 | condition, ``APPEND``\ ing ``magnum_foo_SRCS`` to ``magnum_SRCS`` and 55 | ``Magnum::Foo`` to ``magnum_LIBS``. 56 | 4. Add :cpp:`void foo(py::module_& m);` forward declaration to 57 | ``magnum/bootstrap.h``, and :cpp:`#cmakdefeine Magnum_Foo_FOUND` to 58 | ``magnum/staticconfigure.h.cmake``. 59 | 5. Implement ``void foo(py::module_& m)`` in ``src/python/magnum/foo.cpp``, 60 | add a :cpp:`PYBIND11_MODULE()` calling it. 61 | 6. Add :cpp:`m.def_submodule("foo");` and a call to :cpp:`magnum:foo()` 62 | wrapped in :cpp:`#ifdef Magnum_Foo_FOUND` to the 63 | :cpp:`#ifdef MAGNUM_BUILD_STATIC` section of :cpp:`PYBIND11_MODULE()` in 64 | ``magnum/magnum.cpp``. 65 | 7. Add the new module name to the list in ``magnum/__init__.py``. 66 | 8. Add a line with ``magnum_foo`` to the :cmake:`foreach()` in 67 | ``src/python/CMakeLists.txt``, and then a corresponding :py:`'magnum.foo'` 68 | entry in ``src/python/setup.py.cmake`` 69 | 9. Add a ``magnum/test/test_foo.py`` test file, and potentially also 70 | ``magnum/test/test_foo_gl.py`` where is 71 | :py:`from . import GLTestCase, setUpModule` to skip the test if GL context 72 | doesn't exist, and the test cases derive from :py:`GLTestCase` instead of 73 | :py:`unittest.TestCase`. 74 | 10. Add the new module into the :py:`magnum.__all__` list in 75 | ``doc/python/conf.py``. 76 | 11. Add a ``doc/python/magnum.foo.rst`` documentation file for more detailed 77 | docs, if needed, and reference it from ``INPUT_DOCS``. 78 | 12. Add a ``doc/python/pages/changelog.rst`` entry. 79 | 80 | For Corrade bindings it's similar. 81 | -------------------------------------------------------------------------------- /src/Magnum/StridedArrayViewPythonBindings.h: -------------------------------------------------------------------------------- 1 | #ifndef Magnum_StridedArrayViewPythonBindings_h 2 | #define Magnum_StridedArrayViewPythonBindings_h 3 | /* 4 | This file is part of Magnum. 5 | 6 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | 2020, 2021, 2022, 2023, 2024, 2025 8 | Vladimír Vondruš 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | and/or sell copies of the Software, and to permit persons to whom the 15 | Software is furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include 30 | 31 | #include "Corrade/Containers/StridedArrayViewPythonBindings.h" 32 | 33 | namespace Corrade { namespace Containers { namespace Implementation { 34 | 35 | /* This expands Containers::Implementation::pythonFormatString() with Magnum 36 | types. Using e.g. "3f" instead of "fff" as that makes Numpy understand even 37 | the slices as arrays in a concrete type (or it at least repr()s them as 38 | such), with "fff" it gives back an untyped tuple. */ 39 | 40 | #define _c(type, string) \ 41 | template<> constexpr const char* pythonFormatString() { return string; } 42 | _c(Half, "e") 43 | _c(Vector2, "2f") 44 | _c(Vector2h, "2e") 45 | _c(Vector2d, "2d") 46 | _c(Vector2ub, "2B") 47 | _c(Vector2b, "2b") 48 | _c(Vector2us, "2H") 49 | _c(Vector2s, "2h") 50 | _c(Vector2ui, "2I") 51 | _c(Vector2i, "2i") 52 | _c(Vector3, "3f") 53 | _c(Vector3h, "3e") 54 | _c(Vector3d, "3d") 55 | _c(Vector3ub, "3B") 56 | _c(Vector3b, "3b") 57 | _c(Vector3us, "3H") 58 | _c(Vector3s, "3h") 59 | _c(Vector3ui, "3I") 60 | _c(Vector3i, "3i") 61 | _c(Vector4, "4f") 62 | _c(Vector4h, "4e") 63 | _c(Vector4d, "4d") 64 | _c(Vector4ub, "4B") 65 | _c(Vector4b, "4b") 66 | _c(Vector4us, "4H") 67 | _c(Vector4s, "4h") 68 | _c(Vector4ui, "4I") 69 | _c(Vector4i, "4i") 70 | 71 | _c(Matrix2x2, "4f") 72 | _c(Matrix2x2d, "4d") 73 | _c(Matrix2x3, "6f") 74 | _c(Matrix2x3d, "6d") 75 | _c(Matrix2x4, "8f") 76 | _c(Matrix2x4d, "8d") 77 | _c(Matrix3x2, "6f") 78 | _c(Matrix3x2d, "6d") 79 | _c(Matrix3x3, "9f") 80 | _c(Matrix3x3d, "9d") 81 | _c(Matrix3x4, "12f") 82 | _c(Matrix3x4d, "12d") 83 | _c(Matrix4x2, "8f") 84 | _c(Matrix4x2d, "8d") 85 | _c(Matrix4x3, "12f") 86 | _c(Matrix4x3d, "12d") 87 | _c(Matrix4x4, "16f") 88 | _c(Matrix4x4d, "16d") 89 | 90 | _c(Range1D, "2f") 91 | _c(Range1Dd, "2d") 92 | _c(Range1Di, "2i") 93 | _c(Range2D, "4f") 94 | _c(Range2Dd, "4d") 95 | _c(Range2Di, "4i") 96 | _c(Range3D, "6f") 97 | _c(Range3Dd, "6d") 98 | _c(Range3Di, "6i") 99 | 100 | _c(Complex, "2f") 101 | _c(Complexd, "2d") 102 | _c(DualComplex, "4f") 103 | _c(DualComplexd, "4f") 104 | _c(Quaternion, "4f") 105 | _c(Quaterniond, "4d") 106 | _c(DualQuaternion, "8f") 107 | _c(DualQuaterniond, "8d") 108 | 109 | _c(Deg, "f") 110 | _c(Degd, "d") 111 | _c(Rad, "f") 112 | _c(Radd, "d") 113 | #undef _c 114 | 115 | } 116 | 117 | }} 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /doc/python/magnum.scenegraph.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:module:: magnum.scenegraph 28 | 29 | The Python API for :dox:`SceneGraph` provides, similarly to C++, multiple 30 | different transformation implementations. Recommended usage is importing 31 | desired implementation akin to :cpp:`typedef`\ ing the types in C++: 32 | 33 | .. code-figure:: 34 | 35 | .. code:: c++ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | typedef SceneGraph::Scene Scene3D; 42 | typedef SceneGraph::Object Object3D; 43 | 44 | C++ 45 | 46 | .. code-figure:: 47 | 48 | .. code:: py 49 | 50 | from magnum import scenegraph 51 | from magnum.scenegraph.matrix import Scene3D, Object3D 52 | 53 | Python 54 | 55 | `Scene vs Object`_ 56 | ================== 57 | 58 | In C++, the Scene is a subclass of Object. However, because the Scene 59 | object is not transformable nor it's possible to attach features to it, 60 | most of the inherited API is unusable. This could be considered a wart of 61 | the C++ API, so the Python bindings expose Scene and Object as two 62 | unrelated types and all APIs that can take either a Scene or an Object 63 | have corresponding overloads. 64 | 65 | `Reference counting`_ 66 | ===================== 67 | 68 | Compared to C++, the following is done with all Object instances created 69 | on Python side: 70 | 71 | - the object is additionally referenced by its parent (if there's any) 72 | so objects created in local scope stay alive even after exiting the 73 | scope 74 | - deleting its parent (either due to it going out of scope or using 75 | :py:`del` in Python) will cause it to have no parent instead of being 76 | cascade deleted (unless it's not referenced anymore, in which case it's deleted as well) 77 | - in order to actually destroy an object, it has to have no parent 78 | 79 | For features it's slightly different: 80 | 81 | - the feature is additionally referenced by the holder object so features 82 | created in local scope stay alive even after exiting the scope 83 | - deleting the holder object (either due to it going out of scope 84 | or using :py:`del` in Python) will cause it to be without a holder 85 | object (unless it's not referenced anymore, in which case it's deleted 86 | as well) --- this makes any further operations on it impossible and 87 | likely dangerous 88 | - in order to actually destroy a feature, it has to have no holder object 89 | -------------------------------------------------------------------------------- /doc/python/magnum.scenetools.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:function:: magnum.scenetools.filter_fields 28 | :raise AssertionError: If size of :p:`fields_to_keep` is different than 29 | :ref:`trade.SceneData.field_count` 30 | 31 | .. py:function:: magnum.scenetools.filter_field_entries 32 | :raise AssertionError: If any field in :p:`entries_to_keep` does not exist 33 | in :p:`scene` 34 | :raise AssertionError: If any field in :p:`entries_to_keep` is listed more 35 | than once 36 | :raise AssertionError: If size of any array in :p:`entries_to_keep` does 37 | not match :ref:`trade.SceneData.field_size()` for given field 38 | 39 | .. py:function:: magnum.scenetools.filter_objects 40 | :raise AssertionError: If size of :p:`objects_to_keep` is different than 41 | :ref:`trade.SceneData.mapping_bound` 42 | 43 | .. py:function:: magnum.scenetools.parents_breadth_first 44 | :raise AssertionError: If :p:`scene` does not have 45 | :ref:`trade.SceneField.PARENT` 46 | 47 | .. py:function:: magnum.scenetools.children_depth_first 48 | :raise AssertionError: If :p:`scene` does not have 49 | :ref:`trade.SceneField.PARENT` 50 | 51 | .. py:function:: magnum.scenetools.absolute_field_transformations2d(scene: magnum.trade.SceneData, field: magnum.trade.SceneField, global_transformation: magnum.Matrix3) 52 | :raise KeyError: If :p:`field` does not exist in :p:`scene` 53 | :raise AssertionError: If :p:`scene` is not 2D 54 | :raise AssertionError: If :p:`scene` does not have 55 | :ref:`trade.SceneField.PARENT` 56 | 57 | .. py:function:: magnum.scenetools.absolute_field_transformations2d(scene: magnum.trade.SceneData, field_id: int, global_transformation: magnum.Matrix3) 58 | :raise IndexError: If :p:`field_id` negative or not less than 59 | :ref:`trade.SceneData.field_count` 60 | :raise AssertionError: If :p:`scene` is not 2D 61 | :raise AssertionError: If :p:`scene` does not have 62 | :ref:`trade.SceneField.PARENT` 63 | 64 | .. py:function:: magnum.scenetools.absolute_field_transformations3d(scene: magnum.trade.SceneData, field: magnum.trade.SceneField, global_transformation: magnum.Matrix4) 65 | :raise KeyError: If :p:`field` does not exist in :p:`scene` 66 | :raise AssertionError: If :p:`scene` is not 2D 67 | :raise AssertionError: If :p:`scene` does not have 68 | :ref:`trade.SceneField.PARENT` 69 | 70 | .. py:function:: magnum.scenetools.absolute_field_transformations3d(scene: magnum.trade.SceneData, field_id: int, global_transformation: magnum.Matrix4) 71 | :raise IndexError: If :p:`field_id` negative or not less than 72 | :ref:`trade.SceneData.field_count` 73 | :raise AssertionError: If :p:`scene` is not 2D 74 | :raise AssertionError: If :p:`scene` does not have 75 | :ref:`trade.SceneField.PARENT` 76 | -------------------------------------------------------------------------------- /package/ci/unix-desktop-gles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ev 3 | 4 | # Corrade 5 | git clone --depth 1 https://github.com/mosra/corrade.git 6 | cd corrade 7 | mkdir build && cd build 8 | cmake .. \ 9 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 10 | -DCMAKE_INSTALL_RPATH=$HOME/deps/lib \ 11 | -DCMAKE_BUILD_TYPE=Release \ 12 | -DCORRADE_WITH_INTERCONNECT=OFF \ 13 | -DCORRADE_WITH_PLUGINMANAGER=ON \ 14 | -DCORRADE_WITH_TESTSUITE=ON \ 15 | -G Ninja 16 | ninja install 17 | cd ../.. 18 | 19 | # Magnum 20 | git clone --depth 1 https://github.com/mosra/magnum.git 21 | cd magnum 22 | mkdir build && cd build 23 | cmake .. \ 24 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 25 | -DCMAKE_BUILD_TYPE=Release \ 26 | -DCMAKE_PREFIX_PATH="$HOME/swiftshader;$HOME/pybind11" \ 27 | -DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \ 28 | -DMAGNUM_TARGET_GLES=ON \ 29 | -DMAGNUM_TARGET_GLES2=$TARGET_GLES2 \ 30 | -DMAGNUM_WITH_AUDIO=OFF \ 31 | -DMAGNUM_WITH_DEBUGTOOLS=OFF \ 32 | -DMAGNUM_WITH_GL=ON \ 33 | -DMAGNUM_WITH_MATERIALTOOLS=ON \ 34 | -DMAGNUM_WITH_MESHTOOLS=ON \ 35 | -DMAGNUM_WITH_PRIMITIVES=ON \ 36 | -DMAGNUM_WITH_SCENEGRAPH=ON \ 37 | -DMAGNUM_WITH_SCENETOOLS=ON \ 38 | -DMAGNUM_WITH_SHADERS=ON \ 39 | -DMAGNUM_WITH_SHADERTOOLS=OFF \ 40 | -DMAGNUM_WITH_TEXT=ON \ 41 | -DMAGNUM_WITH_TEXTURETOOLS=OFF \ 42 | -DMAGNUM_WITH_TRADE=ON \ 43 | -DMAGNUM_WITH_VK=OFF \ 44 | -DMAGNUM_WITH_WINDOWLESSEGLAPPLICATION=ON \ 45 | -DMAGNUM_WITH_ANYIMAGEIMPORTER=ON \ 46 | -DMAGNUM_WITH_ANYSCENECONVERTER=ON \ 47 | -DMAGNUM_WITH_ANYSCENEIMPORTER=ON \ 48 | -DMAGNUM_WITH_TGAIMPORTER=ON \ 49 | -G Ninja 50 | ninja install 51 | cd ../.. 52 | 53 | # Magnum Plugins 54 | git clone --depth 1 https://github.com/mosra/magnum-plugins.git 55 | cd magnum-plugins 56 | mkdir build && cd build 57 | cmake .. \ 58 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 59 | -DCMAKE_BUILD_TYPE=Release \ 60 | `# StanfordSceneConverter uses MeshTools which rely on GL which looks` \ 61 | `# for OpenGLES. And the RPATH entry needs to be there as well,` \ 62 | `# otherwise it won't load.` \ 63 | -DCMAKE_PREFIX_PATH=$HOME/swiftshader \ 64 | -DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \ 65 | -DMAGNUM_BUILD_STATIC=$BUILD_STATIC \ 66 | -DMAGNUM_WITH_BCDECIMAGECONVERTER=ON \ 67 | -DMAGNUM_WITH_DDSIMPORTER=ON \ 68 | -DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON \ 69 | -DMAGNUM_WITH_GLTFIMPORTER=ON \ 70 | -DMAGNUM_WITH_GLTFSCENECONVERTER=ON \ 71 | -DMAGNUM_WITH_KTXIMAGECONVERTER=ON \ 72 | -DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=ON \ 73 | -DMAGNUM_WITH_PRIMITIVEIMPORTER=ON \ 74 | -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ 75 | -DMAGNUM_WITH_STBIMAGECONVERTER=ON \ 76 | -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ 77 | -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \ 78 | -DMAGNUM_WITH_STBTRUETYPEFONT=ON \ 79 | -G Ninja 80 | ninja install 81 | cd ../.. 82 | 83 | # Build the thing 84 | mkdir build && cd build 85 | cmake .. \ 86 | -DCMAKE_CXX_FLAGS="--coverage" \ 87 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 88 | -DCMAKE_BUILD_TYPE=Debug \ 89 | -DCMAKE_PREFIX_PATH="$HOME/swiftshader;$HOME/pybind11" \ 90 | -DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \ 91 | -DPYBIND11_PYTHON_VERSION=3.6 \ 92 | -DMAGNUM_WITH_PYTHON=ON \ 93 | -DMAGNUM_BUILD_TESTS=ON \ 94 | -G Ninja 95 | ninja $NINJA_JOBS 96 | 97 | CORRADE_TEST_COLOR=ON ctest -V 98 | 99 | # Verify the setuptools install. Not using $CIRCLE_WORKING_DIRECTORY because 100 | # it's ~ and that's not correctly expanded always. 101 | cd src/python 102 | python3 setup.py install --root="$(pwd)/../../install" --prefix=/usr 103 | 104 | # Run tests & gather coverage 105 | cd ../../../src/python/corrade 106 | coverage run -m unittest -v 107 | cp .coverage ../.coverage.corrade 108 | 109 | cd ../magnum 110 | coverage run -m unittest -v 111 | cp .coverage ../.coverage.magnum 112 | 113 | # Test docstring validity 114 | cd ../../../doc/python 115 | # I would use $CIRCLE_WORKING_DIRECTORY, but that's ~ and that's not expanded 116 | # here for some reason 117 | PYTHONPATH="$(pwd)/../../build/src/python" python3 -m doctest -v *.rst 118 | -------------------------------------------------------------------------------- /package/ci/unix-desktop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ev 3 | 4 | # Corrade 5 | git clone --depth 1 https://github.com/mosra/corrade.git 6 | cd corrade 7 | mkdir build && cd build 8 | cmake .. \ 9 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 10 | -DCMAKE_INSTALL_RPATH=$HOME/deps/lib \ 11 | -DCMAKE_BUILD_TYPE=Release \ 12 | -DMAGNUM_BUILD_DEPRECATED=$BUILD_DEPRECATED \ 13 | -DCORRADE_BUILD_STATIC=$BUILD_STATIC \ 14 | -DCORRADE_WITH_INTERCONNECT=OFF \ 15 | -DCORRADE_WITH_PLUGINMANAGER=ON \ 16 | -DCORRADE_WITH_TESTSUITE=ON \ 17 | -G Ninja 18 | ninja install 19 | cd ../.. 20 | 21 | # Magnum 22 | git clone --depth 1 https://github.com/mosra/magnum.git 23 | cd magnum 24 | mkdir build && cd build 25 | cmake .. \ 26 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 27 | -DCMAKE_INSTALL_RPATH=$HOME/deps/lib \ 28 | -DCMAKE_BUILD_TYPE=Release \ 29 | -DMAGNUM_BUILD_DEPRECATED=$BUILD_DEPRECATED \ 30 | -DMAGNUM_BUILD_STATIC=$BUILD_STATIC \ 31 | -DMAGNUM_WITH_AUDIO=OFF \ 32 | -DMAGNUM_WITH_DEBUGTOOLS=OFF \ 33 | -DMAGNUM_WITH_GL=ON \ 34 | -DMAGNUM_WITH_MATERIALTOOLS=ON \ 35 | -DMAGNUM_WITH_MESHTOOLS=ON \ 36 | -DMAGNUM_WITH_PRIMITIVES=ON \ 37 | -DMAGNUM_WITH_SCENEGRAPH=ON \ 38 | -DMAGNUM_WITH_SCENETOOLS=ON \ 39 | -DMAGNUM_WITH_SHADERS=ON \ 40 | -DMAGNUM_WITH_SHADERTOOLS=OFF \ 41 | -DMAGNUM_WITH_TEXT=ON \ 42 | -DMAGNUM_WITH_TEXTURETOOLS=OFF \ 43 | -DMAGNUM_WITH_TRADE=ON \ 44 | -DMAGNUM_WITH_VK=OFF \ 45 | -DMAGNUM_WITH_GLFWAPPLICATION=ON \ 46 | -DMAGNUM_WITH_SDL2APPLICATION=ON \ 47 | -DMAGNUM_WITH_WINDOWLESS${PLATFORM_GL_API}APPLICATION=ON \ 48 | -DMAGNUM_WITH_ANYIMAGEIMPORTER=ON \ 49 | -DMAGNUM_WITH_ANYSCENECONVERTER=ON \ 50 | -DMAGNUM_WITH_ANYSCENEIMPORTER=ON \ 51 | -DMAGNUM_WITH_TGAIMPORTER=ON \ 52 | -G Ninja 53 | 54 | # In case of a static build there's no way for the test to know the plugin 55 | # install directory so we have to hardcode it 56 | if [ "$BUILD_STATIC" == "ON" ]; then 57 | cmake . -DMAGNUM_PLUGINS_DIR=$HOME/deps/lib/magnum 58 | fi 59 | 60 | ninja install 61 | cd ../.. 62 | 63 | # Magnum Plugins 64 | git clone --depth 1 https://github.com/mosra/magnum-plugins.git 65 | cd magnum-plugins 66 | mkdir build && cd build 67 | cmake .. \ 68 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 69 | -DCMAKE_INSTALL_RPATH=$HOME/deps/lib \ 70 | -DCMAKE_BUILD_TYPE=Release \ 71 | -DMAGNUM_BUILD_STATIC=$BUILD_STATIC \ 72 | -DMAGNUM_WITH_BCDECIMAGECONVERTER=ON \ 73 | -DMAGNUM_WITH_DDSIMPORTER=ON \ 74 | -DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON \ 75 | -DMAGNUM_WITH_GLTFIMPORTER=ON \ 76 | -DMAGNUM_WITH_GLTFSCENECONVERTER=ON \ 77 | -DMAGNUM_WITH_KTXIMAGECONVERTER=ON \ 78 | -DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=ON \ 79 | -DMAGNUM_WITH_PRIMITIVEIMPORTER=ON \ 80 | -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ 81 | -DMAGNUM_WITH_STBIMAGECONVERTER=ON \ 82 | -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ 83 | -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \ 84 | -DMAGNUM_WITH_STBTRUETYPEFONT=ON \ 85 | -G Ninja 86 | ninja install 87 | cd ../.. 88 | 89 | # Build the thing 90 | mkdir build && cd build 91 | cmake .. \ 92 | -DCMAKE_CXX_FLAGS="--coverage" \ 93 | -DCMAKE_INSTALL_PREFIX=$HOME/deps \ 94 | -DCMAKE_BUILD_TYPE=Debug \ 95 | -DCMAKE_PREFIX_PATH=$HOME/pybind11 \ 96 | -DPYBIND11_PYTHON_VERSION=3.6 \ 97 | -DMAGNUM_WITH_PYTHON=ON \ 98 | -DMAGNUM_BUILD_TESTS=ON \ 99 | -G Ninja 100 | ninja $NINJA_JOBS 101 | 102 | CORRADE_TEST_COLOR=ON ctest -V 103 | 104 | # Verify the setuptools install. Not using $CIRCLE_WORKING_DIRECTORY because 105 | # it's ~ and that's not correctly expanded always. 106 | cd src/python 107 | python3 setup.py install --root="$(pwd)/../../install" --prefix=/usr 108 | 109 | # Run tests & gather coverage 110 | cd ../../../src/python/corrade 111 | coverage run -m unittest -v 112 | cp .coverage ../.coverage.corrade 113 | 114 | cd ../magnum 115 | MAGNUM_SKIP_GL_TESTS=ON coverage run -m unittest -v 116 | cp .coverage ../.coverage.magnum 117 | 118 | # Test docstring validity 119 | cd ../../../doc/python 120 | # I would use $CIRCLE_WORKING_DIRECTORY, but that's ~ and that's not expanded 121 | # here for some reason 122 | PYTHONPATH="$(pwd)/../../build/src/python" python3 -m doctest -v *.rst 123 | -------------------------------------------------------------------------------- /src/python/magnum/scenegraph.trs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "scenegraph.h" 31 | 32 | namespace magnum { 33 | 34 | namespace { 35 | 36 | template void objectTrs(py::class_, SceneGraph::PyObject>, SceneGraph::AbstractObject, SceneGraph::PyObjectHolder>>& c) { 37 | c 38 | .def_property("translation", 39 | &SceneGraph::Object::translation, 40 | &SceneGraph::Object::setTranslation, 41 | "Object translation") 42 | .def_property("rotation", 43 | &SceneGraph::Object::rotation, 44 | &SceneGraph::Object::setRotation, 45 | "Object rotation") 46 | .def_property("scaling", 47 | &SceneGraph::Object::scaling, 48 | &SceneGraph::Object::setScaling, 49 | "Object scaling"); 50 | } 51 | 52 | } 53 | 54 | void scenegraphTrs(py::module_& m) { 55 | py::module_ matrix = m.def_submodule("trs"); 56 | matrix.doc() = "Translation/rotation/scaling-based scene graph implementation"; 57 | 58 | py::class_> scene2D_{matrix, "Scene2D", "Two-dimensional scene with TRS-based transformation implementation"}; 59 | scene(scene2D_); 60 | 61 | py::class_> scene3D_{matrix, "Scene3D", "Three-dimensional scene with TRS-based transformation implementation"}; 62 | scene(scene3D_); 63 | 64 | py::class_, SceneGraph::PyObject>, SceneGraph::AbstractObject2D, SceneGraph::PyObjectHolder>> object2D_{matrix, "Object2D", "Two-dimensional object with TRS-based transformation implementation"}; 65 | object(object2D_); 66 | object2D(object2D_); 67 | objectScale(object2D_); 68 | objectTrs(object2D_); 69 | 70 | py::class_, SceneGraph::PyObject>, SceneGraph::AbstractObject3D, SceneGraph::PyObjectHolder>> object3D_{matrix, "Object3D", "Three-dimensional object with TRS-based transformation implementation"}; 71 | object(object3D_); 72 | object3D(object3D_); 73 | objectScale(object3D_); 74 | objectTrs(object3D_); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | # Thanks, CMake, for making the recommended way of installing pacakges so 28 | # useless that it's impossible to call find_package() consistently independent 29 | # of whether it's installed system-wide or added through add_subdirectory(). 30 | # This also means we can't use pybind11_VERSION below but have to extract it 31 | # from some private cache variables instead. THIS IS ABSOLUTELY AWFUL, FFS. 32 | if(NOT COMMAND pybind11_add_module) 33 | find_package(pybind11 CONFIG REQUIRED) 34 | elseif(NOT pybind11_VERSION) 35 | set(pybind11_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}) 36 | endif() 37 | 38 | # In pybind11 2.2.4 and below, pybind11_add_module() added the include 39 | # directories as non-system. That, combined with Corrade's warning level, added 40 | # an insane amount of warnings to the build. Since 2.3 it was possible to 41 | # override that by passing SYSTEM to pybind11_add_module(), HOWEVER since 2.6 42 | # doing so causes an ANNOYING warning because they made that a default. That 43 | # all in a span of barely two years. Can't things just stay stable for a little 44 | # moment?! 45 | if(pybind11_VERSION VERSION_LESS 2.6) 46 | set(pybind11_add_module_SYSTEM SYSTEM) 47 | endif() 48 | 49 | # UGH FFS 50 | get_property(CMAKE_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 51 | if(CMAKE_GENERATOR_IS_MULTI_CONFIG) 52 | set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/$) 53 | else() 54 | set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) 55 | endif() 56 | 57 | add_subdirectory(corrade) 58 | add_subdirectory(magnum) 59 | 60 | # This would be bad enough already, but $ doesn't exist until 61 | # CMake 3.12, so I need to do two passes, first replacing variables using 62 | # configure_file() and then replacing generator expressions with file(GENERATE) 63 | foreach(target 64 | corrade_containers 65 | corrade_pluginmanager 66 | corrade_utility 67 | magnum_gl 68 | magnum_materialtools 69 | magnum_meshtools 70 | magnum_primitives 71 | magnum_scenegraph 72 | magnum_scenetools 73 | magnum_shaders 74 | magnum_platform_cgl 75 | magnum_platform_egl 76 | magnum_platform_glx 77 | magnum_platform_glfw 78 | magnum_platform_sdl2 79 | magnum_text 80 | magnum_trade) 81 | if(TARGET ${target}) 82 | set(${target}_file $) 83 | endif() 84 | endforeach() 85 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmake 86 | ${CMAKE_CURRENT_BINARY_DIR}/setup.py.in) 87 | file(GENERATE OUTPUT ${output_dir}/setup.py 88 | INPUT ${CMAKE_CURRENT_BINARY_DIR}/setup.py.in) 89 | 90 | # MagnumPythonBindings library and alias, just for superprojects to have 91 | # something to link to get to the headers 92 | add_library(MagnumPythonBindings INTERFACE) 93 | set_target_properties(MagnumPythonBindings PROPERTIES 94 | INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/src) 95 | add_library(MagnumBindings::Python ALIAS MagnumPythonBindings) 96 | -------------------------------------------------------------------------------- /src/python/magnum/test/benchmark_math.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # 4 | # This file is part of Magnum. 5 | # 6 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 7 | # 2020, 2021, 2022, 2023, 2024, 2025 8 | # Vladimír Vondruš 9 | # 10 | # Permission is hereby granted, free of charge, to any person obtaining a 11 | # copy of this software and associated documentation files (the "Software"), 12 | # to deal in the Software without restriction, including without limitation 13 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | # and/or sell copies of the Software, and to permit persons to whom the 15 | # Software is furnished to do so, subject to the following conditions: 16 | # 17 | # The above copyright notice and this permission notice shall be included 18 | # in all copies or substantial portions of the Software. 19 | # 20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | # DEALINGS IN THE SOFTWARE. 27 | # 28 | 29 | # Avoid this being run implicitly during unit tests 30 | if __name__ != '__main__': exit() 31 | 32 | import timeit 33 | 34 | import array 35 | from magnum import * 36 | import numpy as np 37 | 38 | repeats = 100000 39 | 40 | def timethat(expr: str, *, setup:str = 'pass', title=None): 41 | if not title: 42 | if setup != 'pass': title = f'{setup}; {expr}' 43 | else: title = expr 44 | 45 | print('{:67} {:8.5f} µs'.format(title, timeit.timeit(expr, number=repeats, globals=globals(), setup=setup)*1000000.0/repeats)) 46 | 47 | def timethat_exception(expr: str): 48 | return timethat(f""" 49 | try: 50 | {expr} 51 | except: 52 | pass 53 | """, title=f'{expr} # throws') 54 | 55 | print(" plain list expressions:\n") 56 | 57 | timethat('[]') 58 | timethat('list([])') 59 | timethat('[1.0, 2.0, 3.0]') 60 | timethat('list([1.0, 2.0, 3.0])') 61 | 62 | print("\n Vector3 from/to list:\n") 63 | 64 | timethat('Vector3()') 65 | timethat('Vector3(1.0, 2.0, 3.0)') 66 | timethat('Vector3([1.0, 2.0, 3.0])') 67 | timethat('list(a)', setup='a = Vector3(1.0, 2.0, 3.0)') 68 | timethat('[a.x, a.y, a.z]', setup='a = Vector3(1.0, 2.0, 3.0)') 69 | 70 | print("\n Vector3 from/to builtin array:\n") 71 | 72 | timethat('array.array("f", [])') 73 | timethat('array.array("f", [1.0, 2.0, 3.0])') 74 | timethat('memoryview(a)', setup='a = array.array("f", [1.0, 2.0, 3.0])') 75 | timethat('memoryview(a)', setup='a = Vector3(1.0, 2.0, 3.0)') 76 | timethat('Vector3(a)', setup='a = array.array("f", [1.0, 2.0, 3.0])') 77 | 78 | print("\n Vector3 from/to np.array:\n") 79 | 80 | timethat('np.array([])') 81 | timethat('np.array([1.0, 2.0, 3.0])') 82 | timethat('np.array(a)', setup='a = array.array("f", [1.0, 2.0, 3.0])') 83 | timethat('np.array(a)', setup='a = Vector3(1.0, 2.0, 3.0)') 84 | timethat('Vector3(a)', setup='a = np.array([1.0, 2.0, 3.0])') 85 | 86 | print("\n Matrix3 from/to list, equivalent np.array operations:\n") 87 | 88 | timethat('Matrix3()') 89 | timethat('Matrix3.from_diagonal(Vector3(1.0, 2.0, 3.0))') 90 | timethat('Matrix3.from_diagonal([1.0, 2.0, 3.0])') 91 | timethat('list(Matrix3.from_diagonal(Vector3(1.0, 2.0, 3.0)))') 92 | timethat('np.diagflat([1.0, 2.0, 3.0])') 93 | timethat('np.array(Matrix3.from_diagonal(Vector3(1.0, 2.0, 3.0)))') 94 | 95 | print("\n exception throwing:\n") 96 | 97 | timethat('Vector3()[0] # doesn\'t throw') 98 | timethat_exception('Vector3()[3]') 99 | timethat_exception('raise IndexError()') 100 | 101 | print("\n basic operations:\n") 102 | 103 | timethat('a + a', setup='a = Vector4d(1.0, 2.0, 3.0, 4.0)') 104 | timethat('a + a', setup='a = np.array([1.0, 2.0, 3.0, 4.0])') 105 | timethat('a.dot()', setup='a = Vector4d(1.0, 2.0, 3.0, 4.0)') 106 | timethat('np.dot(a, a)', setup='a = np.array([1.0, 2.0, 3.0, 4.0])') 107 | timethat('a@a', setup='a = Matrix4d.from_diagonal([1.0, 2.0, 3.0, 4.0])') 108 | timethat('a@a', setup='a = np.diagflat([1.0, 2.0, 3.0, 4.0])') 109 | -------------------------------------------------------------------------------- /src/python/setup.py.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | import os 28 | import shutil 29 | 30 | from setuptools import setup, Extension, find_packages 31 | from setuptools.command.build_ext import build_ext 32 | 33 | extension_paths = { 34 | # Filled in by cmake. This works for both static and dynamic builds -- in 35 | # case a library is built statically, only the underscored name will be 36 | # present. 37 | '_corrade': '$', 38 | 'corrade.containers': '${corrade_containers_file}', 39 | 'corrade.pluginmanager': '${corrade_pluginmanager_file}', 40 | 'corrade.utility': '${corrade_utility_file}', 41 | '_magnum': '$', 42 | 'magnum.gl': '${magnum_gl_file}', 43 | 'magnum.materialtools': '${magnum_materialtools_file}', 44 | 'magnum.meshtools': '${magnum_meshtools_file}', 45 | 'magnum.primitives': '${magnum_primitives_file}', 46 | 'magnum.scenegraph': '${magnum_scenegraph_file}', 47 | 'magnum.scenetools': '${magnum_scenetools_file}', 48 | 'magnum.shaders': '${magnum_shaders_file}', 49 | 'magnum.platform.cgl': '${magnum_platform_cgl_file}', 50 | 'magnum.platform.egl': '${magnum_platform_egl_file}', 51 | 'magnum.platform.glx': '${magnum_platform_glx_file}', 52 | 'magnum.platform.wgl': '${magnum_platform_wgl_file}', 53 | 'magnum.platform.glfw': '${magnum_platform_glfw_file}', 54 | 'magnum.platform.sdl2': '${magnum_platform_sdl2_file}', 55 | 'magnum.text': '${magnum_text_file}', 56 | 'magnum.trade': '${magnum_trade_file}', 57 | } 58 | 59 | packages = ['corrade', 'magnum'] 60 | 61 | # On dynamic builds, platform is a package with an __init__.py and submodules. 62 | # On static builds, it's a submodule of magnum with everything present 63 | # statically. 64 | if '${MAGNUM_BUILD_STATIC}' != 'ON': 65 | packages += ['magnum.platform'] 66 | 67 | class TheExtensionIsAlreadyBuiltWhyThisHasToBeSoDamnComplicated(build_ext): 68 | def run(self): 69 | for ext in self.extensions: 70 | # SameFileError can happen in case of an in-source CMake build 71 | try: 72 | shutil.copyfile(extension_paths[ext.name], self.get_ext_fullpath(ext.name)) 73 | except shutil.SameFileError: 74 | pass 75 | 76 | setup( 77 | name='magnum', 78 | packages=packages, 79 | ext_modules=[Extension(name, sources=[]) for name, path in extension_paths.items() if path], 80 | package_dir={ 81 | # Explicitly supply package_dir so importing this file from another 82 | # setup.py (i.e., when this is a bundled dependency of another project) 83 | # does the right thing. Can't use '': because that doesn't work when 84 | # executing setup.py directly, can't use '.': because that doesn't work 85 | # when executing setup.py from another setup, so need to list all 86 | # packages explicitly. 87 | i: os.path.join(os.path.dirname(__file__), i.replace('.', '/')) for i in packages 88 | }, 89 | cmdclass={ 90 | 'build_ext': TheExtensionIsAlreadyBuiltWhyThisHasToBeSoDamnComplicated 91 | }, 92 | zip_safe=True 93 | ) 94 | 95 | # kate: hl python 96 | -------------------------------------------------------------------------------- /src/python/magnum/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Magnum. 3 | # 4 | # Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | # 2020, 2021, 2022, 2023, 2024, 2025 6 | # Vladimír Vondruš 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a 9 | # copy of this software and associated documentation files (the "Software"), 10 | # to deal in the Software without restriction, including without limitation 11 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | # and/or sell copies of the Software, and to permit persons to whom the 13 | # Software is furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included 16 | # in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | # DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | """Root Magnum module""" 28 | 29 | # Important -- performs various platform-specific setup like adding DLL paths 30 | # on Windows 31 | import corrade 32 | 33 | from _magnum import * 34 | 35 | # This feels extremely hackish, but without that it wouldn't be possible to 36 | # do `import magnum.math`, which is weird (`from magnum import math` works, 37 | # tho, for whatever reason) 38 | import sys 39 | sys.modules['magnum.math'] = math 40 | 41 | # In case Magnum is built statically, the whole core project is put into 42 | # _magnum. Then we need to do the same as above but for all modules. 43 | for i in ['gl', 'materialtools', 'meshtools', 'platform', 'primitives', 'scenegraph', 'scenetools', 'shaders', 'text', 'trade']: 44 | if i in globals(): sys.modules['magnum.' + i] = globals()[i] 45 | 46 | # Platform has subpackages 47 | if 'platform' in globals(): 48 | for i in ['glfw', 'sdl2', 'cgl', 'glx', 'wgl', 'egl']: 49 | if hasattr(platform, i): sys.modules['magnum.platform.' + i] = getattr(platform, i) 50 | 51 | # Scenegraph has subpackages 52 | if 'scenegraph' in globals(): 53 | for i in ['matrix', 'trs']: 54 | sys.modules['magnum.scenegraph.' + i] = getattr(scenegraph, i) 55 | 56 | # Just to not have the variable leak into stubs generated by pybind11-stubgen 57 | # TODO any way to exclude it? 58 | del i 59 | 60 | __all__ = [ 61 | 'Deg', 'Rad', 62 | 63 | 'BitVector2', 'BitVector3', 'BitVector4', 64 | 'Vector2', 'Vector3', 'Vector4', 65 | 'Vector2d', 'Vector3d', 'Vector4d', 66 | 'Vector2i', 'Vector3i', 'Vector4i', 67 | 'Vector2ui', 'Vector3ui', 'Vector4ui', 68 | 'Color3', 'Color4', 69 | 70 | 'Matrix2x2', 'Matrix2x3', 'Matrix2x4', 71 | 'Matrix3x2', 'Matrix3x3', 'Matrix3x4', 72 | 'Matrix4x2', 'Matrix4x3', 'Matrix4x4', 73 | 'Matrix2x2d', 'Matrix2x3d', 'Matrix2x4d', 74 | 'Matrix3x2d', 'Matrix3x3d', 'Matrix3x4d', 75 | 'Matrix4x2d', 'Matrix4x3d', 'Matrix4x4d', 76 | 'Matrix3', 'Matrix4', 'Matrix3d', 'Matrix4d', 77 | 78 | 'Quaternion', 'Quaterniond', 79 | 'Range1D', 'Range1Di', 'Range1Dui', 'Range1Dd', 80 | 'Range2D', 'Range2Di', 'Range2Dui', 'Range2Dd', 81 | 'Range3D', 'Range3Di', 'Range3Dui', 'Range3Dd', 82 | 83 | 'MeshPrimitive', 'MeshIndexType', 84 | 85 | 'PixelFormat', 'PixelStorage', 86 | 'CompressedPixelFormat', 87 | 'Image1D', 'Image2D', 'Image3D', 88 | 'CompressedImage1D', 'CompressedImage2D', 'CompressedImage3D', 89 | 'ImageView1D', 'ImageView2D', 'ImageView3D', 90 | 'MutableImageView1D', 'MutableImageView2D', 'MutableImageView3D', 91 | 'CompressedImageView1D', 'CompressedImageView2D', 'CompressedImageView3D', 92 | 'MutableCompressedImageView1D', 'MutableCompressedImageView2D', 'MutableCompressedImageView3D', 93 | 94 | 'SamplerFilter', 'SamplerMipmap', 'SamplerWrapping', 95 | 96 | 'VertexFormat' 97 | 98 | # TARGET_*, BUILD_* are omitted as `from magnum import *` would pull them 99 | # to globals and this would likely cause conflicts (corrade also defines 100 | # BUILD_*) 101 | ] 102 | -------------------------------------------------------------------------------- /doc/python/magnum.gl.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | .. 26 | 27 | .. py:module:: magnum.gl 28 | :data default_framebuffer: Default framebuffer instance 29 | 30 | :TODO: remove this line once m.css stops ignoring first caption on a page 31 | 32 | `NoCreate constructors`_ 33 | ======================== 34 | 35 | .. TODO: link to NoCreate once m.dox handles variables properly 36 | 37 | Compared to C++, the Python APIs don't have an alternative to the 38 | :dox:`NoCreate ` constructor tag. In C++ these make it possible 39 | to have class members initialized before a GL context is present, but in 40 | Python there's no such limitation so these don't make sense. 41 | 42 | .. py:function:: magnum.gl.AbstractShaderProgram.link 43 | :raise RuntimeError: If linking fails 44 | .. py:function:: magnum.gl.AbstractShaderProgram.uniform_location 45 | :raise ValueError: If there's no uniform of that name 46 | .. py:function:: magnum.gl.AbstractShaderProgram.uniform_block_index 47 | :raise ValueError: If there's no uniform block of that name 48 | .. py:function:: magnum.gl.Shader.compile 49 | :raise RuntimeError: If compilation fails 50 | 51 | .. py:class:: magnum.gl.Mesh 52 | 53 | :TODO: remove this line once m.css stops ignoring first caption on a page 54 | 55 | `Buffer ownership and reference counting`_ 56 | ========================================== 57 | 58 | Unlike in C++, where a :dox:`GL::Buffer` is either :dox:`std::move()`\ d 59 | into the mesh or referenced externally (with the user being responsible for 60 | its lifetime), the :ref:`gl.Mesh` object keeps references to all buffers 61 | added to it. 62 | 63 | .. py:property:: magnum.gl.Mesh.primitive 64 | 65 | While querying this property will always give back a :ref:`gl.MeshPrimitive`, 66 | this property can be set using either :ref:`magnum.MeshPrimitive` or 67 | :ref:`gl.MeshPrimitive`, similarly to how the overloaded 68 | :dox:`GL::Mesh::setPrimitive()` works. 69 | 70 | .. py:property:: magnum.gl.Texture1D.minification_filter 71 | 72 | See :ref:`Texture2D.minification_filter` for more information. 73 | 74 | .. py:property:: magnum.gl.Texture2D.minification_filter 75 | 76 | This property accepts either a tuple of :ref:`magnum.SamplerFilter` / 77 | :ref:`gl.SamplerFilter` and :ref:`magnum.SamplerMipmap` / 78 | :ref:`gl.SamplerMipmap` values or just :ref:`magnum.SamplerFilter` / :ref:`gl.SamplerFilter` alone in which case :ref:`gl.SamplerMipmap.BASE` 79 | will be used implicitly; similarly to how the overloaded 80 | :dox:`GL::Texture::setMinificationFilter()` works. 81 | 82 | .. py:property:: magnum.gl.Texture3D.minification_filter 83 | 84 | See :ref:`Texture2D.minification_filter` for more information. 85 | 86 | .. py:property:: magnum.gl.Texture1D.magnification_filter 87 | 88 | See :ref:`Texture2D.magnification_filter` for more information. 89 | 90 | .. py:property:: magnum.gl.Texture2D.magnification_filter 91 | 92 | This property accepts either :ref:`magnum.SamplerFilter` or 93 | :ref:`gl.SamplerFilter`, similarly to how the overloaded 94 | :dox:`GL::Texture::setMagnificationFilter()` 95 | works. 96 | 97 | .. py:property:: magnum.gl.Texture3D.magnification_filter 98 | 99 | See :ref:`Texture2D.magnification_filter` for more information. 100 | -------------------------------------------------------------------------------- /src/python/corrade/corrade.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Magnum. 3 | 4 | Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 5 | 2020, 2021, 2022, 2023, 2024, 2025 6 | Vladimír Vondruš 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "corrade/bootstrap.h" 31 | 32 | #ifdef CORRADE_BUILD_STATIC 33 | #include "corrade/staticconfigure.h" 34 | #endif 35 | 36 | namespace py = pybind11; 37 | 38 | /* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863 39 | is released */ 40 | extern "C" PYBIND11_EXPORT PyObject* PyInit__corrade(); 41 | PYBIND11_MODULE(_corrade, m) { 42 | m.doc() = "Root Corrade module"; 43 | m.attr("BUILD_DEPRECATED") = 44 | #ifdef CORRADE_BUILD_DEPRECATED 45 | true 46 | #else 47 | false 48 | #endif 49 | ; 50 | m.attr("BUILD_STATIC") = 51 | #ifdef CORRADE_BUILD_STATIC 52 | true 53 | #else 54 | false 55 | #endif 56 | ; 57 | m.attr("BUILD_MULTITHREADED") = 58 | #ifdef CORRADE_BUILD_MULTITHREADED 59 | true 60 | #else 61 | false 62 | #endif 63 | ; 64 | m.attr("TARGET_APPLE") = 65 | #ifdef CORRADE_TARGET_APPLE 66 | true 67 | #else 68 | false 69 | #endif 70 | ; 71 | m.attr("TARGET_IOS") = 72 | #ifdef CORRADE_TARGET_IOS 73 | true 74 | #else 75 | false 76 | #endif 77 | ; 78 | m.attr("TARGET_IOS_SIMULATOR") = 79 | #ifdef CORRADE_TARGET_IOS_SIMULATOR 80 | true 81 | #else 82 | false 83 | #endif 84 | ; 85 | m.attr("TARGET_UNIX") = 86 | #ifdef CORRADE_TARGET_UNIX 87 | true 88 | #else 89 | false 90 | #endif 91 | ; 92 | m.attr("TARGET_WINDOWS") = 93 | #ifdef CORRADE_TARGET_WINDOWS 94 | true 95 | #else 96 | false 97 | #endif 98 | ; 99 | m.attr("TARGET_WINDOWS_RT") = 100 | #ifdef CORRADE_TARGET_WINDOWS_RT 101 | true 102 | #else 103 | false 104 | #endif 105 | ; 106 | m.attr("TARGET_EMSCRIPTEN") = 107 | #ifdef CORRADE_TARGET_EMSCRIPTEN 108 | true 109 | #else 110 | false 111 | #endif 112 | ; 113 | m.attr("TARGET_ANDROID") = 114 | #ifdef CORRADE_TARGET_ANDROID 115 | true 116 | #else 117 | false 118 | #endif 119 | ; 120 | /* Not exposing CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT as this 121 | is a plugin itself and so if this works, plugin manager should too */ 122 | 123 | /* In case Corrade is a bunch of static libraries, put everything into a 124 | single shared lib to make it easier to install (which is the point of 125 | static builds) and avoid issues with multiply-defined global symbols. 126 | 127 | These need to be defined in the order they depend on. */ 128 | #ifdef CORRADE_BUILD_STATIC 129 | py::module_ containers = m.def_submodule("containers"); 130 | corrade::containers(containers); 131 | 132 | py::module_ utility = m.def_submodule("utility"); 133 | corrade::utility(utility); 134 | 135 | /* PluginManager needs Utility::ConfigurationGroup, needs to be defined 136 | after */ 137 | #ifdef Corrade_PluginManager_FOUND 138 | py::module_ pluginmanager = m.def_submodule("pluginmanager"); 139 | corrade::pluginmanager(pluginmanager); 140 | #endif 141 | #endif 142 | } 143 | --------------------------------------------------------------------------------