Compare commits

...

555 Commits

Author SHA1 Message Date
Vladimír Vondruš 46a7659136 package: enable _LIBCPP_REMOVE_TRANSITIVE_INCLUDES for all libc++ builds. 3 months ago
Vladimír Vondruš 13f82984cc package/homebrew: bump stable version to latest master. 4 months ago
Vladimír Vondruš 67cad39cb8 package/homebrew: extract the SHA1 from the version instead of duplicating. 4 months ago
Vladimír Vondruš ca5328a1b8 package/ci: verify that relative DLL paths work as expected too. 4 months ago
Vladimír Vondruš f8a3130d73 package/ci: explicitly add SDL DLL path for static Windows builds. 4 months ago
Vladimír Vondruš 483ef745e4 python: add an option to provide DLL path on Windows. 4 months ago
Vladimír Vondruš 031ead4d99 CMake: show a Python-bindings-specific option only if they're enabled. 4 months ago
Vladimír Vondruš 17023550a6 Update copyright year. 4 months ago
Vladimír Vondruš 8d58df3ab1 modules: updated Corrade and Magnum Find modules. 4 months ago
Vladimír Vondruš 1cc3ea8555 python: do more fuzzy comparisons for floats. 4 months ago
Vladimír Vondruš 65f7f24dd4 package/ci: use Python 3.8 instead of 3.7 on MSVC 2019 and 2022. 4 months ago
Vladimír Vondruš e5d3a6e5b0 package/ci: work around too new CMake used with old pybind11 on Windows. 4 months ago
Vladimír Vondruš c1a0c534ca package/ci: a comment copypasted from magnum-plugins, what?! 4 months ago
Vladimír Vondruš 0fd2ceac52 package/ci: use a meshoptimizer download that isn't 404ing. 4 months ago
Vladimír Vondruš 946e9da65c package/ci: new macOS image, new lcov, new trash errors. 4 months ago
Vladimír Vondruš d631ed9781 package/ci: pass lcov options as a param instead of an env var. 4 months ago
Vladimír Vondruš 9fcc660494 modules: update FindCorrade.cmake for reworked Corrade::Main on MinGW. 4 months ago
Vladimír Vondruš ad3dda094e python: add TODOs for converting more asserts to Python exceptions. 4 months ago
Vladimír Vondruš 3b5df0d8ae python: fix deprecation warnings with pybing11 3.0. 4 months ago
Vladimír Vondruš 8893c1c057 python: skip a test for operation that can't be made legal at the moment. 4 months ago
Vladimír Vondruš a4e35fdfb4 package/ci: switch to a macOS image that isn't removed. 4 months ago
Vladimír Vondruš 96d6019c5b modules: updated FindMagnum.cmake. 6 months ago
Vladimír Vondruš e7a382c577 Use https for links. 7 months ago
Vladimír Vondruš 7e60232ea9 python: expose new Unicode 17 text.Script values. 8 months ago
Vladimír Vondruš 72919da715 package/homebrew: C++14 is nothing to boast with in 2025. 8 months ago
Vladimír Vondruš 27a5c99a1c package/homebrew: use current master for the stable version. 8 months ago
Vladimír Vondruš 439945ce1f python: expose new cube primitive flags. 12 months ago
Vladimír Vondruš efb296029e python: gracefully handle argument errors in the primitives module. 12 months ago
Vladimír Vondruš 45811bb52e python: expose application is_key_pressed() queries. 1 year ago
Vladimír Vondruš 6dc0946ce4 python: make it possible to specify application Configuration as kwargs. 1 year ago
Vladimír Vondruš 55b899d151 python: expose all application Configuration.WindowFlags. 1 year ago
Vladimír Vondruš f0505b4bec python: application Configuration WindowFlags were not plural-named. 1 year ago
Vladimír Vondruš 9b150d60f8 python: there's also a bunch more text.Alignment values. 1 year ago
Vladimír Vondruš 6649b6c3f3 python: expose the new text renderer APIs. 1 year ago
Vladimír Vondruš a2bc076ef0 package/archlinux: blargh lcov suppressions ffs. 1 year ago
Vladimír Vondruš 4ae645c54b python: properly test text.AbstractFont.fill_glyph_cache(). 1 year ago
Vladimír Vondruš 4a0891ad25 python: avoid using outdated names w/o GL suffix in Text bindings. 1 year ago
Vladimír Vondruš 9daa41724a python: this should be deleted, not defaulted. 1 year ago
Vladimír Vondruš 78af75ad5a python: need also unsigned Range types for the new Text APIs. 1 year ago
Vladimír Vondruš 851219059f python: fix wrongly copypasted docs. 1 year ago
Vladimír Vondruš 4731ecd063 package/homebrew: make the 2020.06 version still work with CMake 4. 1 year ago
Vladimír Vondruš 960910e8cb python: hotfix to still compile with the now-deprecated text renderer. 1 year ago
Vladimír Vondruš 1794cd6027 python: add a test case showing typed StridedArrayView as an argument. 1 year ago
Vladimír Vondruš 7f581c6114 It's 2025, C++14 is nothing to boast with. 1 year ago
Vladimír Vondruš 86fcf4d85f Mention Bluesky in contacts. 1 year ago
Vladimír Vondruš bcf0117f97 Not sure why the build status badges are not in README here. 1 year ago
Vladimír Vondruš fcb49770eb package/ci: unify base linux install step on CircleCI. 1 year ago
Vladimír Vondruš d011297c13 Here we go again. 1 year ago
Vladimír Vondruš ee2f65e792 modules: updated FindCorrade and FindMagnum. 1 year ago
Vladimír Vondruš c8824470c9 python: provide a MagnumBindings::Python library for CMake superprojects. 1 year ago
Vladimír Vondruš 20700b7e3d python: expose new Quaternion.xyzw and wxyz properties. 1 year ago
Vladimír Vondruš 81a2683672 package: add an utility for syncing Find modules. 1 year ago
Vladimír Vondruš a7e6ae9493 modules: updated FindCorrade and FindMagnum. 1 year ago
Vladimír Vondruš 2bcc7b94d3 modules: create MagnumBindings targets only once they're actually found. 1 year ago
Vladimír Vondruš 3d49fdf91f modules: workaround to fix KDE's higlighter. 1 year ago
Vladimír Vondruš 585b4b7cf7 CMake: fix version deprecation warning on CMake 3.31. 1 year ago
Vladimír Vondruš 8ebe5e074f CMake: set policies before the project() call. 1 year ago
Vladimír Vondruš 37ddbf7598 CMake: try to clarify that Git version match failure is not an error. 1 year ago
Vladimír Vondruš 92d06e9e6b python: adapt to Magnum key and pointer event changes. 2 years ago
Vladimír Vondruš bed89fdd61 package/ci: add an ARM64 build. 2 years ago
Vladimír Vondruš d5ffa81fe2 package/ci: build w/ deprecated APIs enabled by default. 2 years ago
Vladimír Vondruš c45eb57d34 package/archlinux: report missed lines in coverage output. 2 years ago
Vladimír Vondruš 1c80a7a6f2 python: fix a MSVC build failure with BUILD_DEPRECATED not being ON. 2 years ago
Vladimír Vondruš a5af8ba355 CMake: don't use configure_file() with filenames containing genexprs. 2 years ago
Vladimír Vondruš 9b683b1441 CMake: mark variables that shouldn't need to be toggled as advanced. 2 years ago
Vladimír Vondruš 2ec062c48f doc: this unindent makes docutils throw up. 2 years ago
Vladimír Vondruš 9937209f49 python: adapt to Text library changes. 2 years ago
Vladimír Vondruš fbd8786777 Adapt to Vector getter signature changes. 2 years ago
Vladimír Vondruš 5f4da68f53 CMake: prepare for install and use of Find modules of dependencies. 2 years ago
Vladimír Vondruš 3d8066afec modules: skip all setup in FindMagnumBindings if the component isn't found. 2 years ago
Vladimír Vondruš b0d714344a It's October already?! 2 years ago
Vladimír Vondruš 1f5a8494d4 modules: update FindCorrade and FindMagnum*. 2 years ago
Vladimír Vondruš bce2c33a48 doc: adapt to more pybind11 type annotation changes. 2 years ago
Vladimír Vondruš e9c412c46e doc: adapt to type annotation changes in pybind11 / m.css. 2 years ago
Vladimír Vondruš 11b46bb5ca package/ci: there's no Travis CI anywhere anymore. 2 years ago
Vladimír Vondruš 6bb1ff775a package/ci: use a SwiftShader build that works on ARM Mac. 2 years ago
Vladimír Vondruš d14bb02cd1 package/archlinux: ignore another lcov error. 2 years ago
Vladimír Vondruš 57fc62f121 package/archlinux: force a concrete Python executable. 2 years ago
Vladimír Vondruš 23e5f80725 python: work around float printing differences in tests on ARM Mac. 2 years ago
Vladimír Vondruš a49d4e1748 package/ci: fuck all your containers and environments, FUCK THEM 2 years ago
Vladimír Vondruš 2202693dc1 package/homebrew: cmake is a build-only dependency. 2 years ago
Vladimír Vondruš ecfd7302dc package/homebrew: python-setuptools is a build dependency. 2 years ago
Vladimír Vondruš 3b545dc181 python: adapt to PluginManager changes. 2 years ago
Vladimír Vondruš 2be5398209 package/ci: use newer Mac VM. 2 years ago
Vladimír Vondruš 40827a621f package/ci: use a correctly prefixed Corrade CMake option. 2 years ago
Vladimír Vondruš 49d489382b python: missing include. 2 years ago
Vladimír Vondruš 41f488c7b2 modules: update FindCorrade.cmake. 2 years ago
Vladimír Vondruš 55102734ca python: lol @ MSVC. 2 years ago
Vladimír Vondruš 7e9acb06f2 python: don't leak local __init__.py variables to python introspection. 2 years ago
Vladimír Vondruš 3218db2e2e python: make it possible to skip gl.Context.current() blowing up. 2 years ago
Vladimír Vondruš b0df197b57 python: define trade.AbstractSceneConverter before trade.SceneContents. 2 years ago
Vladimír Vondruš 335bbfc191 python: make corrade.utility depend on corrade.containers. 2 years ago
Vladimír Vondruš ded83398ea python: supply docstrings for the most used pluginmanager APIs. 2 years ago
Vladimír Vondruš 58e16bfb3f package/archlinux: run doctest with proper PYTHONPATH. 2 years ago
Vladimír Vondruš 45af353340 modules: update FindGLFW.cmake. 2 years ago
Vladimír Vondruš a775640b02 modules: use a unique name to find MAGNUMBINDINGS_INCLUDE_DIR. 2 years ago
Vladimír Vondruš 16cd0ebead package/ci: use prebuilt meshoptimizer 0.20 on AppVeyor. 2 years ago
Vladimír Vondruš 40150b7955 python: adapt to Math::sign() changes for units. 2 years ago
Vladimír Vondruš c5eb940ccf python: suppress a useless MSVC warning. 2 years ago
Vladimír Vondruš c46d21249b Use Debug::hex instead of reinterpret_cast<void*>(). 2 years ago
Vladimír Vondruš 806a0e46a0 python: remove py::implicitly_convertible<py::array> for array views. 2 years ago
Vladimír Vondruš 40f9048adf python: expose the attribute-less MeshData constructor. 2 years ago
Vladimír Vondruš c2284590e2 python: expose scenetools.combine_fields(). 2 years ago
Vladimír Vondruš dcbfb28c05 python: expose trade.SceneFieldData. 2 years ago
Vladimír Vondruš d38210add7 python: make BitArray implicitly convertible to StridedBitArrayView. 2 years ago
Vladimír Vondruš eb32900b4b python: there's StridedBitArrayView, just not passed all the way here. 2 years ago
Vladimír Vondruš af00836cf3 python: expose forgotten SceneFieldFlag::MultiEntry. 2 years ago
Vladimír Vondruš cade85c94f python: ability to pass extra attributes to meshtools.interleave(). 2 years ago
Vladimír Vondruš c968b91a41 python: expose trade.MeshAttributeData. 2 years ago
Vladimír Vondruš 37b58362a1 python: minor cleanup. 2 years ago
Vladimír Vondruš 3f7371013d python: doc++ 2 years ago
Vladimír Vondruš 63cea4187e python: make the MeshData / SceneData view helpers a bit more generic. 2 years ago
Vladimír Vondruš 6381b86fac python: reshuffle common code together. 2 years ago
Vladimír Vondruš 78897dddf7 python: preserve type in StridedArrayViews created from buffers. 2 years ago
Vladimír Vondruš 49ac964c49 python: make ArrayView element access behavior match bytes/bytearray. 2 years ago
Vladimír Vondruš 67d78789cd python: properly initialize all members even if unused. 2 years ago
Vladimír Vondruš d719871b33 python: remove dead code. 2 years ago
Vladimír Vondruš 1f830e6bad python: expose the new Quaternion rotation overload. 2 years ago
Vladimír Vondruš 51b65af126 python: compare a correct variable in the test. 2 years ago
Vladimír Vondruš e5e7824b96 python: don't generate corrade/__init__.py to two different locations. 2 years ago
Vladimír Vondruš b4d437bb3f python: introduce MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL. 2 years ago
Vladimír Vondruš 37b0229680 python: doc++ 2 years ago
Vladimír Vondruš 3d9d210f5f python: fix gl.Context.reset_state() to actually reset something. 2 years ago
Vladimír Vondruš d679bfdb2d python: expose the whole MaterialTools library. 2 years ago
Vladimír Vondruš 61d18ec10e python: expose trade.MaterialData and related importer & converter APIs. 2 years ago
Vladimír Vondruš 6a1f1b772a python: properly test all trade.AbstractImporter texture APIs. 2 years ago
Vladimír Vondruš 21b643e87f python: use const self where possible in Trade binding lambdas. 2 years ago
Vladimír Vondruš 7f161b3cf4 package/ci: Python 3.6 is not on AppVeyor MSVC 2019+ images anymore. 2 years ago
Vladimír Vondruš 8b0dc8ca67 python: expose new Quaternion reflection APIs. 2 years ago
Vladimír Vondruš 7a35f405b4 python: raise exceptions for Math API usage errors. 2 years ago
Vladimír Vondruš daa78626fe python: don't be lazy and name arguments in math APIs. 2 years ago
Vladimír Vondruš 6330b6cc19 python: significantly improve matrix and quaternion test coverage. 2 years ago
Vladimír Vondruš 1303032829 python: add actual exception messages to all Trade and *Tools APIs. 3 years ago
Vladimír Vondruš 619b8a51bf python: fix normalized signed VertexFormat enum values. 3 years ago
Vladimír Vondruš f561337caa python: implement pickling for all math types. 3 years ago
Vladimír Vondruš 08ff96da0b python: adapt test to Magnum Text library changes. 3 years ago
Vladimír Vondruš 6212e36fda python: expose new Range scaled() and scaledFromCenter() overloads. 3 years ago
Vladimír Vondruš 11060aa30f python: properly test all Range APIs. 3 years ago
Vladimír Vondruš 25849d3e27 python: actually adapt to Text::AbstractGlyphCache changes, ugh. 3 years ago
Vladimír Vondruš eee7bf002b python: adapt to Text::AbstractGlyphCache changes. 3 years ago
Vladimír Vondruš a9174def9b modules: update Magnum Find modules. 3 years ago
Vladimír Vondruš 8ca1c30187 python: expose new text.AbstractFont APIs. 3 years ago
Vladimír Vondruš 1e0559bc0b python: oops, forgot to adapt Vector::minmax(). 3 years ago
Vladimír Vondruš ecb6351497 python: adapt to std::pair cleanup in Magnum. 3 years ago
Vladimír Vondruš 561b8ca901 python: consistently use "out of range" instead of "out of bounds". 3 years ago
Vladimír Vondruš f26cfcde2e package/ci: use Xcode 12. 3 years ago
Vladimír Vondruš 26749e56dc modules: updated Magnum find modules. 3 years ago
Vladimír Vondruš ff32ae2824 package/archlinux: enable colored output in dev PKGBUILDs. 3 years ago
Vladimír Vondruš 93f9eb814b python: adapt to deprecated Math::angle() for quaternions. 3 years ago
Vladimír Vondruš a81071eae4 CMake: allow both <PackageName>_ROOT and <PACKAGENAME>_ROOT variables. 3 years ago
Vladimír Vondruš 74767f4db4 Bump minimal CMake version to 3.5 to silence a CMake 3.27 warning. 3 years ago
Vladimír Vondruš cec30658ed modules: updated FindCorrade and FindMagnum. 3 years ago
Vladimír Vondruš 2b09a43f99 python: ugh, once again hit the "let's interpret an int as enum" bug. 3 years ago
Vladimír Vondruš 46d6777315 doc: update copyright year in site footer as well. 3 years ago
Vladimír Vondruš 9950b9fca4 python: adapt to Magnum changes re MeshData morph target support. 3 years ago
Vladimír Vondruš 305fdf81ee It's 2023 already! 3 years ago
Vladimír Vondruš 0a2488d474 modules: updated Find modules from Corrade and Magnum. 3 years ago
Vladimír Vondruš 12230c93b8 python: update some test TODOs. 3 years ago
Vladimír Vondruš 85e8fae9b8 python: expose compressed image APIs in AbstractImageConverter. 3 years ago
Vladimír Vondruš c9515bbd1d python: exposed CompressedImage and ImageView classes. 3 years ago
Vladimír Vondruš f9473638fc python: turns out documenting function overloads *is* possible. 3 years ago
Vladimír Vondruš f9d1fdecf3 package/archlinux: adapt to lcov 2.0 changes. 3 years ago
Vladimír Vondruš 6d473cf2aa python: expose various pixel format helpers. 3 years ago
Vladimír Vondruš 7c78ee34a0 python: expose the CompressedPixelFormat enum. 3 years ago
Vladimír Vondruš 6d8ab441e8 python: expose the new expanded() API on strided (bit) array views. 3 years ago
Vladimír Vondruš 5747d58049 python: expose 2D image APIs in AbstractSceneConverter. 3 years ago
Vladimír Vondruš f7c026fbd3 python: expose image-to-image ImageConverter APIs as well. 3 years ago
Vladimír Vondruš d1a7a7c6c8 python: convert more Trade assertions to Python exceptions. 3 years ago
Vladimír Vondruš 0858c844e8 python: minor, doc++ 3 years ago
Vladimír Vondruš 229ec2cb18 python: the WHAT was done in the test here and then copied 100 times? 3 years ago
Vladimír Vondruš cfaa484147 python: test SceneData mutable access failures now that it's possible. 3 years ago
Vladimír Vondruš 738c3f8d38 python: improve test coverage for new SceneConverter APIs. 3 years ago
Vladimír Vondruš 05fad9ccdd python: expose scene-related APIs in AbstractSceneConverter. 3 years ago
Vladimír Vondruš 8d9d7d3230 python: expose scenetools.{parents_breadth,children_depth}_first(). 3 years ago
Vladimír Vondruš 561ba51805 python: test the remaining scenetools assertion now that we can. 3 years ago
Vladimír Vondruš 3b799fcad9 python: expose scenetools.filter_objects(). 3 years ago
Vladimír Vondruš f83c2cb1aa python: expose scenetools.filter_field_entries(). 3 years ago
Vladimír Vondruš b3517b0411 python: doc++ 3 years ago
Vladimír Vondruš 4be2d4d9c0 python: expose scenetools.filter_fields(), filter_{only,except}_fields(). 3 years ago
Vladimír Vondruš d8b98c2057 python: expose the new meshtools.filter_attributes() as well. 3 years ago
Vladimír Vondruš 8dec36ff3d python: adapt MeshTools filter test comments to Magnum updates. 3 years ago
Vladimír Vondruš 2373d2dc9e python: BitArray is implicitly convertible to [Mutable]BitArrayView. 3 years ago
Vladimír Vondruš 104c337f10 python: drop containers binding helpers that are only for a single type. 3 years ago
Vladimír Vondruš d6fec89dc5 python: workaround gl.Context.current blowing up during doc generation. 3 years ago
Vladimír Vondruš b5557a94cd package/archlinux: use Ninja Multi-Config for the dev PKGBUILD. 3 years ago
Vladimír Vondruš b78d809d10 python: put PyPluginHolder into a public header as well. 3 years ago
Vladimír Vondruš 949820b01a python: adapt to SceneTools and MeshTools changes. 3 years ago
Vladimír Vondruš ee284aa4aa python: expose Application cursor setup and warping. 3 years ago
Vladimír Vondruš 8ee4ed882c CMake: enter the Corrade/Containers directory unconditionally. 3 years ago
Vladimír Vondruš 007fe23731 python: support bit field access in SceneData. 3 years ago
Vladimír Vondruš 0091fc97d4 python: haha whoops? 3 years ago
Vladimír Vondruš 94d26a25e5 python: expose all [Mutable][Strided]BitArray[View] APIs. 3 years ago
Vladimír Vondruš fc716799b8 python: clarify a test comment. 3 years ago
Vladimír Vondruš 4fe21deaaf python: document and test error cases in "fancy" strided view APIs. 3 years ago
Vladimír Vondruš 16cb94a338 python: use flipped() instead of every() with a negative number. 3 years ago
Vladimír Vondruš 69f859a579 python: no need to prefix a test class with Test. 3 years ago
Vladimír Vondruš b70001f6c0 python: don't be lazy and name container API arguments. 3 years ago
Vladimír Vondruš ba1c92d7f0 python: reduce code duplication for StridedArrayView bindings. 3 years ago
Vladimír Vondruš 6298ca29fd python: add implicit DLL search paths on Windows, if they exist. 3 years ago
Vladimír Vondruš 8b30876304 python: expose Corrade's utility.copy(). 3 years ago
Vladimír Vondruš 1726086a80 python: add new trade.*Flag.QUIET. 3 years ago
Vladimír Vondruš 6a2fe6e677 package/ci: adapt to new Codecov dumpster fires. 3 years ago
Vladimír Vondruš 57ebae97c5 python: fix meshtools.filter_*_attributes() to reference the owner. 3 years ago
Vladimír Vondruš 557277e995 python: add an ability for referencing owner of trade.*Data memory. 3 years ago
Vladimír Vondruš bc6b67e2f9 python: adapt to Trade::DataFlags changes. 3 years ago
Vladimír Vondruš f30c1c503f python: expose meshtools.concatenate() as well. 3 years ago
Vladimír Vondruš 13c5ad1ea6 python: huh, not sure why this generated file changed. 3 years ago
Vladimír Vondruš 0eabbebbae python: expose almost all remaining mesh tools operating on a MeshData. 3 years ago
Vladimír Vondruš 54828bebca python: fix naming of meshtools.CompileFlags. 3 years ago
Vladimír Vondruš c1f970139b python: simplify argument naming in meshtools. 3 years ago
Vladimír Vondruš bb77c2f25f python: skip tests that use PrimitiveImporter scenes on static builds. 3 years ago
Vladimír Vondruš 8aa953c5f0 python: expose barebones scenetools library. 3 years ago
Vladimír Vondruš 938b551f07 python: further improve developer guide for adding new libraries. 3 years ago
Vladimír Vondruš 38896feb66 modules: update Find modules from Magnum repositories. 3 years ago
Vladimír Vondruš 513fbc547d python: expose trade.TextureData and related importer APIs. 3 years ago
Vladimír Vondruš 55d5445ebf python: typed access to Image*.pixels. 3 years ago
Vladimír Vondruš badc94c122 python: resolve a test TODO now that we have plugin metadata access. 3 years ago
Vladimír Vondruš 6b94109f9f python: resolve a test TODO now that we can change plugin configuration. 3 years ago
Vladimír Vondruš 52fe802932 python: handle Windows paths in trade.AbstractSceneConverter.begin_file(). 3 years ago
Vladimír Vondruš e2642033b3 python: expose pluginmanager.AbstractManager.register_external_manager(). 3 years ago
Vladimír Vondruš d508fd9c04 python: ability to set ConfigurationGroup values in all primitive types. 3 years ago
Vladimír Vondruš e319f098eb python: expose trade.AbstractConverter.add*_importer_contents(). 3 years ago
Vladimír Vondruš d29c5554d8 python: expose trade.AbstractSceneConverter batch mode for files. 3 years ago
Vladimír Vondruš cdfd79571f python: expose mesh-to-mesh and in-place mesh conversion. 3 years ago
Vladimír Vondruš f12aabf788 python: expose trade.Abstract{Importer,Converter}.features and .flags. 3 years ago
Vladimír Vondruš 2a2fa675b7 python: fix inconsistent naming of Trade enum sets. 3 years ago
Vladimír Vondruš 7de13ef7cb python: drop a SceneConverter helper that's used exactly once. 3 years ago
Vladimír Vondruš cf44cba1fb python: stupid typo in a test name. 3 years ago
Vladimír Vondruš 58a163adf7 python: expose plugin configuration as well. 3 years ago
Vladimír Vondruš 1f75e4ea71 python: expose pluginmanager.PluginMetadata. 3 years ago
Vladimír Vondruš 2fb45a91f9 python: expose static AbstractPlugin properties as well. 3 years ago
Vladimír Vondruš e78092a18e python: explicitly test all pluginmanager.AbstractManager interfaces. 3 years ago
Vladimír Vondruš 45a48f6c0b python: add a dummy test file for the PluginManager library. 3 years ago
Vladimír Vondruš 7ad200c03a python: expose pluginmanager.AbstractPlugin. 3 years ago
Vladimír Vondruš d660155a0a python: don't be lazy and document argument names. 3 years ago
Vladimír Vondruš aadd07dad6 python: expose pluginmanager.AbstractManager.set_preferred_plugins(). 3 years ago
Vladimír Vondruš 157c883be4 python: fix wrongly copypasted comment. 3 years ago
Vladimír Vondruš 12dbfc56c8 python: expose essentials of utility.ConfigurationGroup. 3 years ago
Vladimír Vondruš c83c1fcc4f CMake: make it possible to use <PackageName>_ROOT to locate dependencies. 3 years ago
Vladimír Vondruš 52d290a491 python: recognize the new Trade::SceneFieldType::Bit. 3 years ago
Vladimír Vondruš 2696ac6ba7 python: update docs about working around a pybind11 misbehavior. 3 years ago
Vladimír Vondruš 1752e61f9b package/archlinux: python-coverage is a dependency as well. 3 years ago
Vladimír Vondruš c0b155763e doc: bad copypaste, bad. 3 years ago
Vladimír Vondruš d51b45e2bb python: accidentally didn't test trade.SceneData.field_type() w/ an enum. 3 years ago
Vladimír Vondruš e59f8445f8 doc: updated changelog. 3 years ago
Vladimír Vondruš 89fa0d3f93 python: data access in trade.SceneData. 3 years ago
Vladimír Vondruš d62b44e3cd python: support also normalized VertexFormat values. 3 years ago
Vladimír Vondruš c07952fc18 python: have a common header with Python format string definitions. 3 years ago
Vladimír Vondruš 173a01f1b6 python: rename Python struct format helper to avoid clashes. 3 years ago
Vladimír Vondruš 5820b9da60 python: doc++ 3 years ago
Vladimír Vondruš 21fb02ff65 python: fix & test handling of cast/packed VertexFormats. 3 years ago
Vladimír Vondruš 15a06c82c1 python: no need to cast sub-32bit scalar VertexFormats apparently. 3 years ago
Vladimír Vondruš bbd7ccedb1 python: expose trade.SceneData basics together with importer APIs. 3 years ago
Vladimír Vondruš 744bffada6 python: compact trade.AbstractImporter image tests a bit. 3 years ago
Vladimír Vondruš 9c1e4c7add python: use PyErr_SetNone() if the string is empty. 3 years ago
Vladimír Vondruš 551fd567f9 python: distinguish OOB ID and OOB level in trade.AbstractImporter. 3 years ago
Vladimír Vondruš 165416f73b python: add code coverage markers for trade bindings. 3 years ago
Vladimír Vondruš 526def5f45 python: parametrize AbstractImporter name helpers by return type. 3 years ago
Vladimír Vondruš d20727c995 python: move MeshData.attribute_id() info to the relevant function. 3 years ago
Vladimír Vondruš 47f4353f69 Indent glTF files with two spaces. 3 years ago
Vladimír Vondruš f59d8bb9b6 python: test trade.AbstractImporter.image2d() by name. 3 years ago
Vladimír Vondruš 8ccd378870 python: test trade.AbstractImporter.mesh() failure. 3 years ago
Vladimír Vondruš 47226d22f6 python: test also named AbstractImporter APIs with no file opened. 3 years ago
Vladimír Vondruš ee56f6f114 python: improve docs of trade.AbstractImporter APIs. 3 years ago
Vladimír Vondruš c0c78d83f5 python: ... and compatibility with pybind11 < 2.6.2 as well. 3 years ago
Vladimír Vondruš b811592407 python: fix compatibility with pybind11 < 2.6. 3 years ago
Vladimír Vondruš d95c60942b python: implement handling for custom trade.MeshAttribute values. 3 years ago
Vladimír Vondruš d75f31e854 python: expose new linear RGB(A) conversion APIs from Color. 3 years ago
Vladimír Vondruš dddef56c87 python: adapt to Magnum changes. 3 years ago
Vladimír Vondruš a45fbb84da python: handle Windows path insanities in the bindings directly. 3 years ago
Vladimír Vondruš b3e24a11b4 python: reorder trade.MeshData APIs to have enum overloads first. 3 years ago
Vladimír Vondruš 5edd1a49f6 python: adapt the MeshData test to behavior on non-deprecated builds. 3 years ago
Vladimír Vondruš c78cc3fd13 python: expose the BUILD_DEPRECATED constants as well. 3 years ago
Vladimír Vondruš 28497ec2ca python: no, using backward slashes IS NOT A GOOD IDEA, python! 3 years ago
Vladimír Vondruš 56dd4b4a36 python: updated changelog. 3 years ago
Vladimír Vondruš d106fc09d7 python: direct access to trade.MeshData indices and attributes. 3 years ago
Vladimír Vondruš 211bd5f0a8 python: mutable access to trade.MeshData raw index/vertex data. 3 years ago
Vladimír Vondruš cca2eaf659 python: expose all index/attribute property queries in trade.MeshData. 3 years ago
Vladimír Vondruš ae5741e4d0 python: fix to build with pybind11 2.3. 3 years ago
Vladimír Vondruš 27983b66ba python: add a dedicated test for StridedArrayView of a dynamic type. 3 years ago
Vladimír Vondruš a3f88d4db4 python: adapt to std::string removal in the GL library. 3 years ago
Vladimír Vondruš eb334e1d7f python: use the new, shorter, Size and Stride typedefs. 3 years ago
Vladimír Vondruš 7ee0c7d949 python: fix build against latest Corrade. 3 years ago
Vladimír Vondruš a1e49aa8f2 package/ci: add a CTest timeout on AppVeyor. 3 years ago
Vladimír Vondruš 2bc0748c05 doc: updated changelog. 3 years ago
Aaron Gokaslan 695c40b2d1 python: more missing moves, unnecessary inc_ref. 3 years ago
Vladimír Vondruš 71880c743d python: adapt to Magnum changes. 3 years ago
Vladimír Vondruš f6d4385a44 python: add an API-breaking TODO for Application wrappers. 3 years ago
Vladimír Vondruš 99a22dfcd5 python: adapt to Magnum changes. 4 years ago
Vladimír Vondruš 2e2cea6a68 CMake: exclude test dirs from ALL with CORRADE_TESTSUITE_TEST_TARGET. 4 years ago
Vladimír Vondruš 6d02603090 package/ci: don't build MaterialTools, we don't need it for anything. 4 years ago
Vladimír Vondruš 7009d66d18 package/archlinux: use a wildcard .kateconfig for PKGBUILD highlighting. 4 years ago
Vladimír Vondruš 9bce5cfea7 doc: mention how to upgrade HEAD Homebrew packages. 4 years ago
Vladimír Vondruš 50c7f1294a doc: there already *is* a stable version. 4 years ago
Stanislaw Halik 585d136777 CMake: fix test build when Magnum is not in a shared include path. 4 years ago
Vladimír Vondruš 0f1b6e11ab package/ci: add CircleCI job dependencies to reduce credit usage. 4 years ago
Vladimír Vondruš 7a47c41eb7 doc: updated changelog. 4 years ago
Aaron Gokaslan 75be40300b python: remove extra copy in gl.cpp 4 years ago
Vladimír Vondruš 734072bee3 python: doc++ 4 years ago
Vladimír Vondruš b983d29acf python: avoid an assertion in trade.MeshData.index_count. 4 years ago
Vladimír Vondruš 7bd8bd965b python: expose trade.MeshData.index_data and .vertex_data. 4 years ago
Vladimír Vondruš 12950365e3 python: properly test trade.ImageData.data refcounting. 4 years ago
Vladimír Vondruš 58cb836bb7 modules: updated FindMagnum.cmake. 4 years ago
Vladimír Vondruš 661f9fa451 package/archlinux: don't use buildflags in the dev PKGBUILD. 4 years ago
Vladimír Vondruš bce7509e87 python: expose also platform.*.Application.dpi_scaling. 4 years ago
Vladimír Vondruš c4105cb052 doc: update changelog. 4 years ago
Aaron Gokaslan ddaf12757f python: missing move in Corrade container bindings. 4 years ago
Vladimír Vondruš 9e8b846418 doc: updated changelog. 4 years ago
Vladimír Vondruš c72d7146b5 doc: forgot to list the Developers Guide among pages. 4 years ago
Vladimír Vondruš 41e3da6fb2 python: default the destructor also in the SDL2 application. 4 years ago
Aaron Gokaslan f22d3777d5 Minor clang-tidy fixups in some of the newer magnum-bindings 4 years ago
Vladimír Vondruš 732a0b795a doc: add a checklist for adding a new Python module. 4 years ago
Vladimír Vondruš 48b0015782 python: don't look for WindowlessGlxApplication on Apple platforms. 4 years ago
Vladimír Vondruš 83a4ba0390 Doc++ 4 years ago
Vladimír Vondruš 1d662bcd48 CMake: add a MAGNUM_PYTHON_BINDINGS_STATIC_PLUGINS CMake option. 4 years ago
Vladimír Vondruš 3ce8b6d96e python: add also windowless CGL application. 4 years ago
Vladimír Vondruš e4457383c6 python: properly expose the platform.wgl module. 4 years ago
Vladimír Vondruš 7362ff92dc Adapt to Magnum changes. 4 years ago
Vladimír Vondruš 66bb4451df modules: updated FindMagnum.cmake. 4 years ago
Vladimír Vondruš 403689f3bf python: skip GL text rendering test case on ES2. 4 years ago
Vladimír Vondruš f4b5d915d9 python: bind also the vector shaders. 4 years ago
Vladimír Vondruš 9b60dd30b0 python: fix inconsistencies in bound Flat and Phong feature sets. 4 years ago
Vladimír Vondruš c2499fea34 python: no need to bind draw() again for shader subclasses. 4 years ago
Vladimír Vondruš 137211b2b2 doc: a very hacky way to make python shader docs a bit more readable. 4 years ago
Vladimír Vondruš 1ce696203e python: TODOs. 4 years ago
Vladimír Vondruš ecd1e9544f package/ci: build & test also the Text library bindings. 4 years ago
Vladimír Vondruš e6fdfd7d8e python: expose the essentials from the Text library. 4 years ago
Vladimír Vondruš 6a161d5044 doc: it's almost 2023, update the copyright year already. 4 years ago
Vladimír Vondruš 020e1966ab package/archlinux: update AUR PKGBUILD version. 4 years ago
Vladimír Vondruš 716869599b python: fix platform.Application.Configuration.title property getter. 4 years ago
Vladimír Vondruš 04c1f712ed python: adapt to Magnum changes in a less lazy way. 4 years ago
Vladimír Vondruš 62a07c38bc python: adapt to Magnum changes. 4 years ago
Vladimír Vondruš 36b6c4465b package/ci: use Xcode 11.7 on CircleCI. 4 years ago
Vladimír Vondruš 704c904d6a package: use MAGNUM_-prefixed CMake options. 4 years ago
Vladimír Vondruš 5fd2033103 package/ci: adapt to Corrade and Magnum changes. 4 years ago
Vladimír Vondruš 737ec6c415 Prefix all CMake options with MAGNUM_*. 4 years ago
Vladimír Vondruš d476d63bca modules: update FindCorrade.cmake and FindMagnum.cmake. 4 years ago
Vladimír Vondruš c859405c6a package/ci: can't test on Xcode 10 anymore. 4 years ago
Vladimír Vondruš 0a32aa0ed7 package/ci: sync Linux and macOS images with other magnum repos. 4 years ago
Vladimír Vondruš 09e5e90426 python: CgltfImporter is deprecated, test with GltfImporter instead. 4 years ago
Vladimír Vondruš ddfc5ccc36 python: adapt to STL string removal in Application classes. 4 years ago
Vladimír Vondruš 24f2242842 doc: updated changelog. 4 years ago
Aaron Gokaslan ca5e16f658 python: avoid some unnecessary object copies. 4 years ago
Vladimír Vondruš 0510bdf353 CMake: fix and harden Git version detection on Windows. 4 years ago
Vladimír Vondruš 9d916eeae6 Don't use git://. 4 years ago
Vladimír Vondruš a79bc39f3e python: ability to import images and meshes by name. 4 years ago
Vladimír Vondruš 831631e10e python: properly test also image import level OOB checks. 4 years ago
Vladimír Vondruš ea4e353231 python: work around GCC 4.8 being utterly confused. 4 years ago
Vladimír Vondruš c2e2a8e520 python: expose basics of trade.AbstractSceneConverter. 4 years ago
Vladimír Vondruš da21863ac7 python: exposed basics of trade.AbstractImageConverter. 4 years ago
Vladimír Vondruš fda9e34b9d python: use CgltfImporter instead of TinyGltfImporter in tests. 4 years ago
Vladimír Vondruš a325f3d0c1 python: minor, doc++, add TODOs. 4 years ago
Vladimír Vondruš 8e8a03e175 python: use AssertionError for trade.AbstractImporter usage errors. 4 years ago
Vladimír Vondruš b58b53bfda python: lazily adapt to Corrade & Magnum std::string removal. 4 years ago
Vladimír Vondruš d2f5ea43d5 CMake: use the CMAKE_FOLDER variable instead of FOLDER property. 4 years ago
Vladimír Vondruš 5ea50ee86e CMake: drop last remaining mention of Utility::Directory. 4 years ago
Vladimír Vondruš 4fe9d385dc modules: updated FindCorrade.cmake. 4 years ago
Vladimír Vondruš ca4a35e78c doc: updated changelog. 4 years ago
Vladimír Vondruš 2295f43873 Updated copyright year. 4 years ago
Vladimír Vondruš ae23365869 Bye, Travis! You won't be missed. 4 years ago
Vladimír Vondruš f18acb6af6 modules: updated Find modules from Magnum repositories. 4 years ago
Vladimír Vondruš 0eade80567 python: expose RGB<->XYZ conversion utilities. 4 years ago
Vladimír Vondruš 43d7e10f2d modules: updated Find modules from the Magnum repository. 4 years ago
Vladimír Vondruš 2b8b67addc package/ci: add a macOS GLES3 build. 4 years ago
Vladimír Vondruš 281c18fdeb package/ci: add MSVC 2022 and /permissive- builds. 4 years ago
Vladimír Vondruš e35de34fee package/ci: Chocolatey, go away. 4 years ago
Vladimír Vondruš 8938a29f67 python: expose depth/stencil PixelFormat values. 4 years ago
Vladimír Vondruš 9bc5840926 python: gl.Framebuffer has to be defined after gl.Texture2D which it uses. 4 years ago
Vladimír Vondruš 79009b7d21 python: gl.TextureFormat.SRG8 is available on desktop now as well. 4 years ago
Vladimír Vondruš 7dc03d59aa doc: updated changelog and credits. 4 years ago
James Murphy 0e84055b49 python: expose depth/stencil gl.TextureFormat values. 4 years ago
James Murphy 6f260b05cd python: expose gl.Framebuffer.attach_texture(). 4 years ago
Vladimír Vondruš 1dd625a420 python: test gl.Framebuffer renderbuffer refcounting properly. 4 years ago
Vladimír Vondruš 60c48b63f7 python: document gl.Framebuffer.attach_renderbuffer() args. 4 years ago
Vladimír Vondruš 75a0564cc3 python: make it possible to set mesh index buffer. 4 years ago
Vladimír Vondruš 71d2cf0d95 python: unify parameter naming of all math.angle() functions. 4 years ago
Vladimír Vondruš 0120b3f768 python: add remaining vector/scalar, exp and other math functions. 4 years ago
Vladimír Vondruš 831ab24e49 package/ci: I wonder how this RPATH mess ever worked. 4 years ago
Vladimír Vondruš fa55f1df54 package/ci: we don't need SceneTools for anything here, yet. 4 years ago
Vladimír Vondruš a2bbcf54aa package/ci: use Ubuntu 18.04 to restore access to the deadsnakes PPA. 4 years ago
Vladimír Vondruš 03cbaf5f19 package/ci: GitHub says I can't use git:// anymore. 4 years ago
Vladimír Vondruš 24921c7409 Doc++ 4 years ago
Vladimír Vondruš 32fe5ead80 package/ci: drop Gitter webhook notifications. 4 years ago
Vladimír Vondruš 5994150a68 python: expose glfw.Application.{swap_interval,main_loop_iteration}. 5 years ago
Vladimír Vondruš 2a528e23bf python: doc++, updated credits & changelog. 5 years ago
Vladimír Vondruš 6be3566e9b package/homebrew: make this work on ARM Macs as well. 5 years ago
James Murphy 40ba765fad Don't error if path is already fullpath 5 years ago
Vladimír Vondruš dda78038be doc: updated changelog. 5 years ago
Aaron Gokaslan c50a2f6851 python: add bindings for convenience color functions. 5 years ago
Vladimír Vondruš 4d5a9ed456 python: expose viewport and exit event. 5 years ago
Vladimír Vondruš 18ea028c8a python: fix InputEvent.Modifier to behave like proper flags. 5 years ago
Vladimír Vondruš 8f733ca8db python: properly expose gl.Context.flags. 5 years ago
Vladimír Vondruš 48b94ffd19 python: doc++ 5 years ago
Vladimír Vondruš d66b581e73 python: add off-center variants of 2D/3D orthographic projection. 5 years ago
Vladimír Vondruš 1417d59b6c doc: updated changelog with latest fixes. 5 years ago
Vladimír Vondruš 9f08717e77 python: fixed a copypaste error in MouseMoveEvent.relative_position. 5 years ago
Aaron Gokaslan c7897429af python: don't pass potentially huge types by value. 5 years ago
Vladimír Vondruš 7ede64e7d4 python: whoopsie. 5 years ago
Vladimír Vondruš 5c2cad1461 package/ci: curses, lots of curses. 5 years ago
Vladimír Vondruš dfb44e98ca doc: updated credits and changelog. 5 years ago
Aaron Gokaslan 31785426d8 Typo fixing 5 years ago
Aaron Gokaslan a42018d075 python: don't carelessly copy py::args and py::kwargs. 5 years ago
Vladimír Vondruš 7f86477c3e Adapt to Magnum changes. 5 years ago
Vladimír Vondruš 2fec9c1e5e Enable a bunch of useful CMake policies. 5 years ago
Vladimír Vondruš aadc437b25 python: added Vector4 from Vector3 and Vector3 from Vector2 constructors. 5 years ago
Vladimír Vondruš 431074a776 python: adapt to GL shader renaming. 5 years ago
Vladimír Vondruš 0bf27c07f2 python: I don't understand this comment. Remove. 5 years ago
Vladimír Vondruš 8e00226da3 python: add a caster for Containers::Optional. 5 years ago
Vladimír Vondruš ba4e20006a python: adapt to GL::TextureFormat updates. 5 years ago
Vladimír Vondruš 98a3dcf59c python: basic support for arbitrary types in strided array views. 5 years ago
Vladimír Vondruš 805a781f0a python: adapt to GL::Context changes. 5 years ago
Vladimír Vondruš cbb5358efd python: apparently I can't name functions from(), hah. 5 years ago
Vladimír Vondruš a2d16c15f8 python: expose Platform::GLContext as platform.{egl,wgl,glx}.Context. 5 years ago
Vladimír Vondruš c51928c07e python: expose gl.Context. 5 years ago
Vladimír Vondruš 84f9bb2a9d Updated copyright year. 5 years ago
Vladimír Vondruš ac8491a619 modules: updated dependency modules. 5 years ago
Vladimír Vondruš b63ae43f1e modules: provide additional info about not found components on CMake 3.16. 5 years ago
Vladimír Vondruš 3a82b18566 modules: use if(IN_LIST) from CMake 3.4. 5 years ago
Vladimír Vondruš 32b4c3dcff doc: updated credits and changelog. 5 years ago
Vladimír Vondruš 177ea859d8 package/homebrew: a patch to make 2020.06 compile with latest pybind. 5 years ago
John Laxson e64a27e156 package/homebrew: use std_cmake_args. 5 years ago
Vladimír Vondruš 2b7a1af397 python: make it possible to get py::object from a raw void*/type pair. 5 years ago
Vladimír Vondruš 05e0bb764a Test: prefix VersionTest with repo name to avoid conflicts. 5 years ago
Vladimír Vondruš 52f2073ff9 package/ci: we don't need ShaderTools here. 5 years ago
Vladimír Vondruš 5dad3bb8af package/ci: note to self: don't use CIRCLE_WORKING_DIRECTORY ever again. 5 years ago
Vladimír Vondruš c6699187cb package/ci: apparently 4 GB RAM is not enough FOR MODERN C++ FFS. 5 years ago
Vladimír Vondruš fa81020de7 package/ci: migrate to CircleCI. 5 years ago
Vladimír Vondruš 372c5e0065 doc: updated credits and changelog. 6 years ago
Vladimír Vondruš 15bee01a04 Update README and docs for travis-ci.com migration. 6 years ago
Aaron Gokaslan 41b720e44c Apply clang-tidy performance fixes 6 years ago
Vladimír Vondruš 4bb19e0b3f python: re-add an inverse of pybind11 2.2.4 workarounds for 2.6. 6 years ago
Vladimír Vondruš 57db13422f python: make this compatible with pybind11 2.6. 6 years ago
Vladimír Vondruš b83e12a8fd package/homebrew: update to what's actually latest. 6 years ago
Vladimír Vondruš 0f98d2f172 python: expose new shaders.Phong features. 6 years ago
Vladimír Vondruš bbb2d0a395 python: document args of gl.Renderer.enable() and friends. 6 years ago
Vladimír Vondruš 5594a64c2a python: add new clip distance features to gl.Renderer. 6 years ago
Vladimír Vondruš 4cb109f592 python: add remaining gl.Renderer.set_blend*() overloads and a test. 6 years ago
Vladimír Vondruš 615551a390 doc: updated changelog and credits. 6 years ago
Vladimír Vondruš be5ffdd916 doc: switch to explicit :ref: as default roles don't work well. 6 years ago
Vladimir Gamalyan fe559e69bd python: expose GL::Renderer::setBlendEquation(), GL::Renderer::setBlendFunction() and related enums. 6 years ago
Vladimír Vondruš 11075a4adf package/ci: rename Windows builds to not include GL anymore. 6 years ago
Vladimír Vondruš 799629e410 python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš ea4c792d26 doc: ArchLinux uses zst now. 6 years ago
Vladimír Vondruš 66681d4dee Fix generation of versionBindings.h when inside a Git submodule. 6 years ago
Vladimír Vondruš 579107365d modules: adapt FindMagnumBindings.cmake to recent header renames. 6 years ago
Vladimír Vondruš dffa0fa7f8 python: oh, forgot to install Containers/PythonBindings.h. 6 years ago
Vladimír Vondruš 1d278d1112 python: rename all Python.h headers to PythonBindings.h. 6 years ago
Vladimír Vondruš 24b18aff93 Update project version. 6 years ago
Vladimír Vondruš 661e8243cd Of course I messed up generating the version header. 6 years ago
Vladimír Vondruš 2df41d3afe doc: updated changelog for 2020.06. 6 years ago
Vladimír Vondruš 9b0e7bcf3e package/archlinux: actually, those are transitive deps. 6 years ago
Vladimír Vondruš 01d0abb9fc modules: updated FindMagnum and FindGLFW. 6 years ago
Vladimír Vondruš 267f7c36d9 package/archlinux: switch to Ninja. 6 years ago
Vladimír Vondruš f5d78009a2 package/archlinux: interestingly enough, this got never commited. 6 years ago
Vladimír Vondruš f2cba9cb57 python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš e7b5708ca9 Add a TODO for CMake 3.15. 6 years ago
Vladimír Vondruš 3d519d6c19 Add a version header containing full Git version information. 6 years ago
Vladimír Vondruš fe7e6eb545 Bootstrap for C++-side unit tests. 6 years ago
Vladimír Vondruš b1d45fc85a Updated copyright year. 6 years ago
Vladimír Vondruš 1a7efcac4c modules: updated Corrade and Magnum modules. 6 years ago
Vladimír Vondruš 5950f00f01 modules: updated FindMagnum.cmake. 6 years ago
Vladimír Vondruš 8de3e91ce3 python: fix build against latest Magnum. 6 years ago
Vladimír Vondruš a611455034 package/ci: make tests using static plugins work again. 6 years ago
Vladimír Vondruš 86bac39471 Adapt to Corrade changes. 6 years ago
Vladimír Vondruš e222ba7a32 python: provide a better error if draw_event() is not overriden. 6 years ago
Vladimír Vondruš a3f6b2cce0 python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš 7aef7bd4c8 python: this was a bug in my test. 6 years ago
Vladimír Vondruš 500311fa7c python: add APIs for Color from/to sRGB int. 6 years ago
Vladimír Vondruš de204f778b python: define Mesh early enough so AbstractShaderProgram::draw() works. 6 years ago
Vladimír Vondruš 38d56059e2 python: adapt to changes in the Primitives library. 6 years ago
Vladimír Vondruš 70e7ab94c8 oackage/archlinux: expect zstd-compressed packages. 6 years ago
Vladimír Vondruš 2045e22463 python: properly check also level bounds in importers. 6 years ago
Vladimír Vondruš d2dc71369c python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš d3ecefcfac modules: updated FindMagnum.cmake. 6 years ago
Vladimír Vondruš a470eae5f1 python: adapt to Trade::MeshDataXD deprecation. 6 years ago
Vladimír Vondruš 45eb76446b python: expose trade.abstractImporter.imageXd_level_count(). 6 years ago
Vladimír Vondruš b2f92b9d6e python: avoid using deprecated functionality. 6 years ago
Vladimír Vondruš 5d7e5c5b1c python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš 15d0714d90 python: adapt to Magnum changes. 6 years ago
Vladimír Vondruš 2cbe09c1f7 package/ci: THINGS ARE BAD. 6 years ago
Vladimír Vondruš c560b8085a python: added gl.AbstractTexture.unbind(). 6 years ago
Vladimír Vondruš 3a0c478834 python: a bunch of new keys in SDL and GLFW. 6 years ago
Vladimír Vondruš 1aefd45f2c doc: enable latex caching so docs can finish building in this decade. 6 years ago
Vladimír Vondruš 0d9c5687dd modules: update just about all the modules, apparently. 6 years ago
Vladimír Vondruš 97062bcc04 python: expose new Matrix4.normal_matrix() and related APIs. 7 years ago
Vladimír Vondruš 9131edff97 python: doc++ 7 years ago
Vladimír Vondruš 016f5954e3 python: exposed framebuffer blit. 7 years ago
Vladimír Vondruš 3b72f10211 package/homebrew: updated for 2019.10. 7 years ago
Vladimír Vondruš 396e48bf4d package/ci: TRAVIS! WHAT DO YOU WANT TODAY 7 years ago
Vladimír Vondruš 19cb8f41b3 doc: added changelog for Python bindings. 7 years ago
Vladimír Vondruš 7f6a1f1529 CMake: override binary output location only if none of these is set. 7 years ago
Vladimír Vondruš 875a81803b python: avoid clash with the builtin platform module when running tests. 7 years ago
Vladimír Vondruš 7068412b7c platform: expose Sdl2Application::mainLoopIteration(). 7 years ago
Vladimír Vondruš 41609aceef python: don't try to find applications that aren't on target platform. 7 years ago
Vladimír Vondruš e334cc17b2 python: expose remaining primitives. 7 years ago
Vladimír Vondruš 70fe4e8a25 python: add more getters to trade.MeshDataXD. 7 years ago
Vladimír Vondruš d67a1d27ed python: primitives.square_solid() didn't have a default argument. 7 years ago
Vladimír Vondruš 65d8e47cbe CMake: put all binaries into a single location. 7 years ago
Vladimír Vondruš d2bec5eba7 python: fix build in a CMake subproject. 7 years ago
Vladimír Vondruš 8700217943 Require CMake 3.4 at least. 7 years ago
Vladimír Vondruš 106ca8f314 python: adapted to Magnum changes. 7 years ago
Vladimír Vondruš 027492966d doc: shorten the experimental notice. 7 years ago
Vladimír Vondruš a6dd10ae69 python: we don't use pybind11 exceptions anymore, so this is not needed. 7 years ago
Vladimír Vondruš 34ca50dca8 python: expose application properties as actual properties. 7 years ago
Vladimír Vondruš d5bbd193f3 python: minor cleanup. 7 years ago
Vladimír Vondruš 6bce9fbeb2 python: remove the black magic from magnum.platform. 7 years ago
Vladimír Vondruš 2cbb083f0a package/ci: minor cleanup. 7 years ago
Vladimír Vondruš 6ca302befc package/ci: enable TinyGltfImporter for mesh import testing. 7 years ago
Vladimír Vondruš 59a2773808 python: expose mesh import. 7 years ago
Vladimír Vondruš 9afe7ebe50 python: expose key and scroll events. 7 years ago
Vladimír Vondruš f20c5beb76 python: move away from concrete pybind exceptions. 7 years ago
Vladimír Vondruš ee54dc6cdc package/ci: build Magnum Plugins on the CI. 7 years ago
Vladimír Vondruš 7da09f9080 python: expose basic image import in trade. 7 years ago
Vladimír Vondruš f8f0f3f1b7 python: expose framebuffer reading to an image (not a view). 7 years ago
Vladimír Vondruš e07e61c1ef python: expose Image. 7 years ago
Vladimír Vondruš c21972efb6 python: document the behavior of ImageView refcounting as well. 7 years ago
Vladimír Vondruš 432d424a77 python: make conversion from a mutable image view implicit. 7 years ago
Vladimír Vondruš 2eebb45557 python: don't keep a reference to owner for empty array views. 7 years ago
Vladimír Vondruš e18fbdbb16 python: raise an exception on plugin load/unload failure. 7 years ago
Vladimír Vondruš 6dd3e2fd6d python: those pluginmanager APIs should have been properties. 7 years ago
Vladimír Vondruš 859309b07c python: actually install the corrade.pluginmanager module. 7 years ago
Vladimír Vondruš 483ffb4453 python: document gl.default_framebuffer 7 years ago
Vladimír Vondruš 843160f58a python: throw instead of returning a falsy value in shader APIs. 7 years ago
Vladimír Vondruš 3f0aa76c28 python: expose Shaders::Flat. 7 years ago
Vladimír Vondruš 313e74142c python: expose texturing in Phong. 7 years ago
Vladimír Vondruš 02fc8900b9 python: expose Phong tangents and vertex colors. 7 years ago
Vladimír Vondruš 40891858d6 python: raise Python exceptions for shader API usage failures. 7 years ago
Vladimír Vondruš 006987fa45 python: update shader attribute docs, add Phong there too. 7 years ago
Vladimír Vondruš 563f5222b5 python: better way to expose shader attributes. 7 years ago
Vladimír Vondruš 7f82f76eba python: test gl.AbstractShaderProgram.set_uniform() as well. 7 years ago
Vladimír Vondruš 033e0c17bc python: minor code cleanup. 7 years ago
Vladimír Vondruš 3c9643ce74 python: expose textures and related APIs. 7 years ago
Vladimír Vondruš 1083e2d6aa python: improve docs of gl.Mesh primitive setting. 7 years ago
Vladimír Vondruš fdf5671c4c python: implicitly test for GL errors in all tests. 7 years ago
Vladimír Vondruš 79ac50e11a python: expose gl.Renderer.error. 7 years ago
Vladimír Vondruš bbbda61f6e magnum: no_create() constructors are useless, don't add them. 7 years ago
Vladimír Vondruš d818e40698 python: implemented vector swizzles. 7 years ago
Vladimír Vondruš d6f1c50c34 python: I'm happy to see MSVC continuing to be consistenly underdelivering. 7 years ago
Vladimír Vondruš 30d7b0796c package/ci: make code coverage actually work on macOS. 7 years ago
Vladimír Vondruš 9b652f6213 package/ci: nope, this was not a good idea. 7 years ago
Vladimír Vondruš 5947b76df9 python: cross() should be in math, not a member function. 7 years ago
Vladimír Vondruš 0c9cd88fd3 python: doc++ 7 years ago
Vladimír Vondruš 9faed0651e python: expose basics of plugin manager. 7 years ago
Vladimír Vondruš 857062e152 python: TODOs so I don't forget. 7 years ago
Vladimír Vondruš f9851bdb1e python: expose shader interface APIs. 7 years ago
Vladimír Vondruš c8e99ca086 python: expose corrade and magnum compilation defines. 7 years ago
Vladimír Vondruš 14f7810870 python: finish the magic and docs for Matrix[34].scaling() and friends. 7 years ago
Vladimír Vondruš d50b79d698 python: expose gl.Version and related utilities. 7 years ago
Vladimír Vondruš 128c2aa0af python: use an underscore for the less readable PixelFormat values. 7 years ago
Vladimír Vondruš 3ae0c3fbf2 doc: we have an AppVeyor build now. 7 years ago
Vladimír Vondruš e105109981 doc: document differences in platform and scenegraph. 7 years ago
Vladimír Vondruš 73087f3b3f doc: we can disable GL tests now. 7 years ago
Vladimír Vondruš b84f88e189 doc: add 3rd party license info and contributor list. 7 years ago
Vladimír Vondruš 9a7c167e73 doc: switch to a nicer URL scheme. 7 years ago
Vladimír Vondruš 3ceb292c15 python: update docs with crosslinking and all the fancy stuff. 7 years ago
  1. 1
      .circleci/config.yml
  2. 2
      .editorconfig
  3. 1
      .travis.yml
  4. 212
      CMakeLists.txt
  5. 5
      COPYING
  6. 10
      README.md
  7. 15
      doc/python/conf-public.py
  8. 211
      doc/python/conf.py
  9. 425
      doc/python/corrade.containers.rst
  10. 40
      doc/python/corrade.pluginmanager.rst
  11. 50
      doc/python/corrade.rst
  12. 37
      doc/python/corrade.utility.rst
  13. 71
      doc/python/magnum.gl.rst
  14. 43
      doc/python/magnum.materialtools.rst
  15. 613
      doc/python/magnum.math.rst
  16. 97
      doc/python/magnum.meshtools.rst
  17. 28
      doc/python/magnum.platform.rst
  18. 70
      doc/python/magnum.primitives.rst
  19. 280
      doc/python/magnum.rst
  20. 3
      doc/python/magnum.scenegraph.rst
  21. 75
      doc/python/magnum.scenetools.rst
  22. 132
      doc/python/magnum.shaders.rst
  23. 169
      doc/python/magnum.text.rst
  24. 1479
      doc/python/magnum.trade.rst
  25. BIN
      doc/python/numpy.inv
  26. 120
      doc/python/pages/api-conventions.rst
  27. 95
      doc/python/pages/building.rst
  28. 238
      doc/python/pages/changelog.rst
  29. 81
      doc/python/pages/credits.rst
  30. 80
      doc/python/pages/developers.rst
  31. 21
      doc/python/pages/index.rst
  32. BIN
      doc/python/python.inv
  33. 16
      modules/CMakeLists.txt
  34. 506
      modules/FindCorrade.cmake
  35. 86
      modules/FindEGL.cmake
  36. 94
      modules/FindGLFW.cmake
  37. 784
      modules/FindMagnum.cmake
  38. 158
      modules/FindMagnumBindings.cmake
  39. 78
      modules/FindOpenGLES2.cmake
  40. 92
      modules/FindOpenGLES3.cmake
  41. 173
      modules/FindSDL2.cmake
  42. 3
      modules/MagnumBindingsConfig.cmake
  43. 2
      package/archlinux/.gitignore
  44. 1
      package/archlinux/.kateconfig
  45. 37
      package/archlinux/PKGBUILD
  46. 23
      package/archlinux/PKGBUILD-coverage
  47. 41
      package/archlinux/magnum-bindings-git/PKGBUILD
  48. 123
      package/ci/appveyor-desktop-gles.bat
  49. 133
      package/ci/appveyor-desktop.bat
  50. 143
      package/ci/appveyor.yml
  51. 499
      package/ci/circleci.yml
  52. 8
      package/ci/codecov.yml
  53. 13
      package/ci/setup-pybind11.sh
  54. 80
      package/ci/travis-desktop-gles.sh
  55. 74
      package/ci/travis-desktop.sh
  56. 146
      package/ci/travis.yml
  57. 117
      package/ci/unix-desktop-gles.sh
  58. 122
      package/ci/unix-desktop.sh
  59. 12
      package/git/README.md
  60. 24
      package/homebrew/magnum-bindings.rb
  61. 7
      package/sync-modules.sh
  62. 8
      src/CMakeLists.txt
  63. 20
      src/Corrade/CMakeLists.txt
  64. 15
      src/Corrade/Containers/CMakeLists.txt
  65. 63
      src/Corrade/Containers/OptionalPythonBindings.h
  66. 10
      src/Corrade/Containers/PythonBindings.h
  67. 203
      src/Corrade/Containers/StridedArrayViewPythonBindings.h
  68. 29
      src/Corrade/PluginManager/CMakeLists.txt
  69. 72
      src/Corrade/PluginManager/PythonBindings.h
  70. 34
      src/Corrade/PythonBindings.h
  71. 67
      src/Magnum/CMakeLists.txt
  72. 10
      src/Magnum/GL/CMakeLists.txt
  73. 9
      src/Magnum/GL/PythonBindings.h
  74. 20
      src/Magnum/PythonBindings.h
  75. 10
      src/Magnum/SceneGraph/CMakeLists.txt
  76. 29
      src/Magnum/SceneGraph/PythonBindings.h
  77. 119
      src/Magnum/StridedArrayViewPythonBindings.h
  78. 30
      src/Magnum/Test/CMakeLists.txt
  79. 67
      src/Magnum/Test/VersionTest.cpp
  80. 30
      src/Magnum/Trade/CMakeLists.txt
  81. 103
      src/Magnum/Trade/PythonBindings.h
  82. 39
      src/Magnum/versionBindings.h.cmake
  83. 33
      src/python/CMakeLists.txt
  84. 100
      src/python/corrade/CMakeLists.txt
  85. 3
      src/python/corrade/EnumOperators.h
  86. 13
      src/python/corrade/PyBuffer.h
  87. 82
      src/python/corrade/__init__.py.in
  88. 22
      src/python/corrade/bootstrap.h
  89. 1025
      src/python/corrade/containers.cpp
  90. 107
      src/python/corrade/corrade.cpp
  91. 190
      src/python/corrade/pluginmanager.cpp
  92. 102
      src/python/corrade/pluginmanager.h
  93. 30
      src/python/corrade/staticconfigure.h.cmake
  94. 36
      src/python/corrade/test/CMakeLists.txt
  95. 8
      src/python/corrade/test/__init__.py
  96. 1
      src/python/corrade/test/broken.conf
  97. 6
      src/python/corrade/test/file.conf
  98. 1718
      src/python/corrade/test/test_containers.py
  99. 186
      src/python/corrade/test/test_containers_numpy.py
  100. 76
      src/python/corrade/test/test_optional.cpp
  101. Some files were not shown because too many files have changed in this diff Show More

1
.circleci/config.yml

@ -0,0 +1 @@
../package/ci/circleci.yml

2
.editorconfig

@ -5,6 +5,6 @@ indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[*.{css,html,yml,rb}]
[*.{css,html,yml,rb,gltf}]
indent_style = space
indent_size = 2

1
.travis.yml

@ -1 +0,0 @@
package/ci/travis.yml

212
CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,14 +24,41 @@
# DEALINGS IN THE SOFTWARE.
#
cmake_minimum_required(VERSION 3.1)
# Matches Corrade requirement, see its root CMakeLists for more information.
cmake_minimum_required(VERSION 3.5...3.10)
# Configuration fails on < 3.4 if only C++ is enabled (CheckFunctionExists
# macro called from FindX11)
if(NOT CMAKE_VERSION VERSION_LESS 3.4.0)
set(LANG CXX)
# CMake 3.12+ uses the policy max version specified in
# cmake_minimum_required(), meaning that with ...3.10, everything until CMP0071
# gets set to NEW implicitly. We however want to keep compatibility with
# versions before 3.12, so the NEW policies are still being hand-picked. Also
# don't want to do a blanket cmake_policy(VERSION) because that may break
# behavior for existing projects that rely on the OLD behavior.
# Don't restrict INTERPROCEDURAL_OPTIMIZATION only for icc on Linux
if(POLICY CMP0069)
cmake_policy(SET CMP0069 NEW)
endif()
# If CMAKE_AUTOMOC is set, all uses of corrade_add_resource() would otherwise
# complain on 3.10 that AUTOMOC is not processing GENERATED files
if(POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif()
# Allow <PackageName>_ROOT to be used on 3.12+ to point to per-package install
# locations that find_package(PackageName) subsequently picks up
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
# Allow also <PACKAGENAME>_ROOT (i.e., uppercase), on 3.27+
if(POLICY CMP0144)
cmake_policy(SET CMP0144 NEW)
endif()
# Superprojects can use just set(MAGNUM_WITH_BLAH ON) without FORCE CACHE on
# 3.13+
if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
project(MagnumBindings ${LANG})
project(MagnumBindings CXX)
# Use folders for nice tree in Visual Studio and XCode
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@ -40,10 +68,178 @@ find_package(Magnum REQUIRED)
include(CMakeDependentOption)
# Options that used to be unprefixed. New options shouldn't be added to this
# list.
set(_MAGNUMBINDINGS_DEPRECATED_UNPREFIXED_OPTIONS
WITH_PYTHON
BUILD_TESTS)
# If during the first run (i.e., when the variable isn't in cache yet), check
# if any of the prefixed options are already set. If so, we assume the user is
# already switched to the prefixed options and won't accept the deprecated
# unprefixed options for backwards compatibility. This way it's possible for
# projects to reuse these variables for other purposes without affecting
# Corrade in any way.
if(NOT DEFINED _MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS)
set(_MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS ON CACHE INTERNAL "")
foreach(option ${_MAGNUMBINDINGS_DEPRECATED_UNPREFIXED_OPTIONS})
if(DEFINED MAGNUM_${option})
set(_MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS OFF CACHE INTERNAL "")
break()
endif()
endforeach()
endif()
# Libraries to build
option(WITH_PYTHON "Build Python bindings" OFF)
option(MAGNUM_WITH_PYTHON "Build Python bindings" OFF)
# There's no global MAGNUM_BUILD_PLUGINS_STATIC option (only exposed as
# per-plugin define), so not checking it.
if(MAGNUM_WITH_PYTHON AND MAGNUM_BUILD_STATIC)
set(MAGNUM_PYTHON_BINDINGS_STATIC_PLUGINS "" CACHE STRING "Static plugins to link to Magnum Python bindings")
endif()
option(MAGNUM_BUILD_TESTS "Build unit tests" OFF)
if(MAGNUM_WITH_PYTHON AND MAGNUM_BUILD_STATIC AND UNIX)
# See src/python/corrade/__init__.py.in and the corresponding CMakeLists
# for details
option(MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL "Build Python bindings linking to static libraries with RTLD_GLOBAL enabled for loading" ON)
endif()
# Python since version 3.8 doesn't take dependency DLLs implicitly from PATH
# anymore, and one has to either place them right next to the Python modules,
# into system locations, or add extra paths via os.add_dll_directory().
#
# Be nice to the user and implicitly populate that with Corrade and Magnum DLL
# directories, if found, on the first run. Anything else (such as SDL or GLFW
# DLL path) has to be specified by the user.
if(MAGNUM_WITH_PYTHON AND WIN32)
# Do this lookup only on the first ever run. But add the option always, so
# in case it's passed via command line in the initial CMake run, it
# actually becomes a cached option with a help text and not just a loose
# variable.
if(NOT MAGNUM_PYTHON_BINDINGS_DLL_PATH)
set(dll_path )
foreach(dll_variable CORRADE_UTILITY_DLL_DEBUG CORRADE_UTILITY_DLL_RELEASE MAGNUM_DLL_DEBUG MAGNUM_DLL_RELEASE)
if(${dll_variable})
get_filename_component(dll_directory ${${dll_variable}} DIRECTORY)
list(APPEND dll_path ${dll_directory})
endif()
endforeach()
list(REMOVE_DUPLICATES dll_path)
# If no DLLs were found, it means Corrade and Magnum is static and thus no
# DLL directories may need to be passed
if(dll_path)
message(STATUS "Autodetected ${dll_path} as directories to pass to Python for finding Corrade, Magnum and other dependency DLLs. Update the MAGNUM_PYTHON_BINDINGS_DLL_PATH variable if needed.")
endif()
endif()
# This variable is then used in src/python/corrade/__init__.py.in
set(MAGNUM_PYTHON_BINDINGS_DLL_PATH "${dll_path}" CACHE STRING "Semicolon-separated directories where to look for Corrade, Magnum and other dependency DLLs")
endif()
# Backwards compatibility for unprefixed CMake options. If the user isn't
# explicitly using prefixed options in the first run already, accept the
# unprefixed options, and remember this decision for subsequent runs
if(NOT DEFINED _MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS)
set(_MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS ON CACHE INTERNAL "")
endif()
# If the user wasn't explicitly using prefixed options in the first run and the
# MAGNUM_BUILD_DEPRECATED option is not currently disabled (which can get
# changed subsequently), accept the unprefixed options and print a warning if
# they're different from the prefixed ones.
if(_MAGNUMBINDINGS_ACCEPT_DEPRECATED_UNPREFIXED_OPTIONS AND MAGNUM_BUILD_DEPRECATED)
set(_MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION )
foreach(option ${_MAGNUMBINDINGS_DEPRECATED_UNPREFIXED_OPTIONS})
if(DEFINED ${option})
# CMake has no comparison of boolean values (EQUAL returns false if
# comparing ON and 1 or OFF and FALSE, STREQUAL also), so we have
# to do it this way. Also warn only on the first encountered
# variable so people can fix it, reconfigure and go to the next one
# that warns.
if((${option} AND NOT MAGNUM_${option}) OR
(NOT ${option} AND MAGNUM_${option}) AND NOT _MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION)
set(_MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION ${option})
endif()
set(MAGNUM_${option} ${${option}})
# If variables specified on the command line don't match any
# options, they're kept in cache but set as UNINITIALIZED, meaning
# they don't appear in cmake-gui or ccmake, so there's no way to
# fix the warning apart from hand-enditing the CMakeCache.txt or
# recreating the build dir. Update their cached type to be BOOL to
# make them appear.
set(${option} ${${option}} CACHE BOOL "Deprecated, use MAGNUM_${option} instead" FORCE)
endif()
endforeach()
if(_MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION)
message(DEPRECATION "Unprefixed options such as ${_MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION} are deprecated, use MAGNUM_${_MAGNUMBINDINGS_WARN_DEPRECATED_UNPREFIXED_OPTION} instead. Delete the unprefixed variable from CMake cache or set both to the same value to silence this warning.")
endif()
endif()
if(MAGNUM_BUILD_TESTS)
find_package(Corrade REQUIRED TestSuite)
if(CORRADE_TARGET_IOS)
set(CORRADE_TESTSUITE_BUNDLE_IDENTIFIER_PREFIX "cz.mosra.magnum-bindings")
endif()
enable_testing()
# If CORRADE_TESTSUITE_TEST_TARGET is set, tests aren't built by default
# (in the ALL target) but instead set as dependencies of a target named
# after the value of CORRADE_TESTSUITE_TEST_TARGET. This is a copy of
# what's done in corrade_add_test(), because we also build various test
# libraries and plugins in addition to the test executables.
if(CORRADE_TESTSUITE_TEST_TARGET)
if(NOT TARGET ${CORRADE_TESTSUITE_TEST_TARGET})
add_custom_target(${CORRADE_TESTSUITE_TEST_TARGET})
endif()
set(EXCLUDE_FROM_ALL_IF_TEST_TARGET EXCLUDE_FROM_ALL)
endif()
endif()
set(MAGNUMBINDINGS_CMAKE_MODULE_INSTALL_DIR share/cmake/MagnumBindings)
# Library version. MAGNUMBINDINGS_VERSION_YEAR/MONTH is used in
# src/Magnum/CMakeLists.txt to generate the versionBindings.h header.
set(MAGNUMBINDINGS_VERSION_YEAR 2020)
set(MAGNUMBINDINGS_VERSION_MONTH 6)
# A single output location. After a decade of saying NO THIS IS A NON-SOLUTION
# TO A NON-PROBLEM I reconsidered my views and enabled this, because:
#
# - On Windows (which don't have RPATH), this makes test execution finally
# possible without having to install all the stuff first (including the
# test-only libs, which is ugh).
# - With CMake subprojects, this makes it finally possible to use dynamic
# plugins directly from the build dir (again without installing anything) ---
# all plugins are put into the same place, so PluginManager has a single
# place to look into; and thanks to the dynamic libraries being there as
# well, this location can be automagically detected as relative to
# Utility::Path::libraryLocation().
# - Thanks to the $<CONFIG> being part of the output path, you are always sure
# you never accidentally mix up debug/release libraries when switching
# CMAKE_BUILD_TYPE in an existing build dir.
#
# The runtime location is set to CMAKE_BINARY_DIR and not PROJECT_BINARY_DIR
# because have one runtime location per CMake subproject would not solve much
# either. If the user already provides CMAKE_RUNTIME_OUTPUT_DIRECTORY (even
# empty), it's respected and nothing is being done.
#
# Explicitly using a generator expression to ensure plugins are added to e.g.
# <CONFIG>/lib/magnum/importers/ instead of lib/magnum/importers/<CONFIG>. Also
# adding this to cache, making superprojects pick that up implicitly as well,
# without forcing them to explicitly mirror this setting.
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY AND NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY AND NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/bin CACHE PATH "" FORCE)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/lib CACHE PATH "" FORCE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/lib CACHE PATH "" FORCE)
# There should be no need for the "90% use case" user to adjust these, so
# don't show them in the default view
mark_as_advanced(
CMAKE_RUNTIME_OUTPUT_DIRECTORY
CMAKE_LIBRARY_OUTPUT_DIRECTORY
CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
endif()
add_subdirectory(modules)
add_subdirectory(src)

5
COPYING

@ -1,5 +1,6 @@
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz> and contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

10
README.md

@ -1,8 +1,9 @@
This repository contains bindings of the Magnum C++11/C++14 graphics engine
into other languages such as Python.
This repository contains bindings of the Magnum C++11 graphics engine into
other languages such as Python.
[![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)
[![Build Status](https://travis-ci.org/mosra/magnum-bindings.svg?branch=master)](https://travis-ci.org/mosra/magnum-bindings)
[![Build Status](https://circleci.com/gh/mosra/magnum-bindings.svg?style=shield)](https://circleci.com/gh/mosra/magnum-bindings)
[![Build status](https://ci.appveyor.com/api/projects/status/utnexv0i8jbwfhff/branch/master?svg=true)](https://ci.appveyor.com/project/mosra/magnum-bindings/branch/master)
[![Coverage Status](https://codecov.io/gh/mosra/magnum-bindings/branch/master/graph/badge.svg)](https://codecov.io/gh/mosra/magnum-bindings)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
@ -33,8 +34,7 @@ right away!
- E-mail — info@magnum.graphics
- Google Groups mailing list — magnum-engine@googlegroups.com
([archive](https://groups.google.com/forum/#!forum/magnum-engine))
- Twitter — https://twitter.com/czmosra and the
[#MagnumEngine](https://twitter.com/hashtag/MagnumEngine) hashtag
- Bluesky — https://bsky.app/profile/mosra.cz
See also the Magnum Project [Contact & Support page](https://magnum.graphics/contact/)
for further information.

15
doc/python/conf-public.py

@ -22,6 +22,19 @@ STYLESHEETS = [
FAVICON = 'https://doc.magnum.graphics/favicon.ico'
SEARCH_DOWNLOAD_BINARY = True
SEARCH_DOWNLOAD_BINARY = 'searchdata-v1.bin'
SEARCH_BASE_URL = 'https://doc.magnum.graphics/python/'
SEARCH_EXTERNAL_URL = 'https://google.com/search?q=site:doc.magnum.graphics+Magnum+Python+{query}'
def URL_FORMATTER(type, path):
# Put static files into the root, everything else into subdirs
if type.name == 'STATIC':
prefix = os.path.basename(path[0])
return prefix, '/python/' + prefix
# And special casing for index, of course
if type.name == 'PAGE' and len(path) == 1 and path[0] == 'index':
return 'index.html', '/python/'
prefix = '/'.join(path) + '/'
return prefix + 'index.html', '/python/' + prefix

211
doc/python/conf.py

@ -1,14 +1,21 @@
import os
import sys
from typing import List
# TODO make this less brittle
sys.path = [os.path.join(os.path.dirname(__file__), '../../build/src/python/')] + sys.path
sys.path = [
os.path.join(os.path.dirname(__file__), '../../build/src/python/'),
os.path.join(os.path.dirname(__file__), '../../build/src/python/Release')
] + sys.path
import corrade
import corrade.containers
import corrade.pluginmanager
import corrade.utility
import magnum
import magnum.gl
import magnum.materialtools
import magnum.meshtools
import magnum.platform
import magnum.platform.egl
@ -18,28 +25,164 @@ import magnum.platform.sdl2
import magnum.primitives
import magnum.shaders
import magnum.scenegraph
import magnum.scenetools
import magnum.text
import magnum.trade
# So the doc see everything
# TODO: use just +=, m.css should reorder this on its own
corrade.__all__ = ['containers']
magnum.__all__ = ['math', 'gl', 'meshtools', 'platform', 'primitives', 'shaders', 'scenegraph', 'trade'] + magnum.__all__
corrade.__all__ = ['containers', 'pluginmanager', 'utility', 'BUILD_DEPRECATED', 'BUILD_STATIC', 'BUILD_MULTITHREADED', 'TARGET_UNIX', 'TARGET_APPLE', 'TARGET_IOS', 'TARGET_IOS_SIMULATOR', 'TARGET_WINDOWS', 'TARGET_WINDOWS_RT', 'TARGET_EMSCRIPTEN', 'TARGET_ANDROID']
magnum.__all__ = ['math', 'gl', 'materialtools', 'meshtools', 'platform', 'primitives', 'shaders', 'scenegraph', 'scenetools', 'text', 'trade', 'BUILD_DEPRECATED', 'BUILD_STATIC', 'TARGET_GL', 'TARGET_GLES', 'TARGET_GLES2', 'TARGET_WEBGL', 'TARGET_EGL', 'TARGET_VK'] + magnum.__all__
# hide values of the preprocessor defines to avoid confusion by assigning a
# class without __repr__ to them
# TODO: more systematic solution directly in m.css
class DoNotPrintValue: pass
corrade.BUILD_DEPRECATED = DoNotPrintValue()
corrade.BUILD_STATIC = DoNotPrintValue()
corrade.BUILD_MULTITHREADED = DoNotPrintValue()
corrade.TARGET_UNIX = DoNotPrintValue()
corrade.TARGET_APPLE = DoNotPrintValue()
corrade.TARGET_IOS = DoNotPrintValue()
corrade.TARGET_IOS_SIMULATOR = DoNotPrintValue()
corrade.TARGET_WINDOWS = DoNotPrintValue()
corrade.TARGET_WINDOWS_RT = DoNotPrintValue()
corrade.TARGET_EMSCRIPTEN = DoNotPrintValue()
corrade.TARGET_ANDROID = DoNotPrintValue()
magnum.BUILD_DEPRECATED = DoNotPrintValue()
magnum.BUILD_STATIC = DoNotPrintValue()
magnum.TARGET_GL = DoNotPrintValue()
magnum.TARGET_GLES = DoNotPrintValue()
magnum.TARGET_GLES2 = DoNotPrintValue()
magnum.TARGET_WEBGL = DoNotPrintValue()
magnum.TARGET_EGL = DoNotPrintValue()
magnum.TARGET_VK = DoNotPrintValue()
# TODO ugh... can this be expressed directly in pybind? and the docs parsed
# from it so i don't need to repeat them in docs/*.rst files?
for i in [magnum.text.AbstractFont,
magnum.trade.AbstractImporter,
magnum.trade.AbstractImageConverter,
magnum.trade.AbstractSceneConverter]:
i.__annotations__ = {
'plugin_interface': str,
'plugin_search_paths': List[str],
'plugin_suffix': str,
'plugin_metadata_suffix': str
}
# Don't show the values. Without delattr() first it complains that the
# attribute can't be set
for key in i.__annotations__:
delattr(i, key)
setattr(i, key, DoNotPrintValue())
# TODO ugh... can this be expressed directly in pybind?
magnum.gl.__annotations__ = {}
magnum.gl.__annotations__['default_framebuffer'] = magnum.gl.DefaultFramebuffer
magnum.shaders.VertexColor2D.__annotations__ = {}
magnum.shaders.VertexColor2D.__annotations__['POSITION'] = magnum.gl.Attribute
magnum.shaders.VertexColor2D.__annotations__['COLOR3'] = magnum.gl.Attribute
magnum.shaders.VertexColor2D.__annotations__['COLOR4'] = magnum.gl.Attribute
magnum.shaders.VertexColor3D.__annotations__ = {}
magnum.shaders.VertexColor3D.__annotations__['POSITION'] = magnum.gl.Attribute
magnum.shaders.VertexColor3D.__annotations__['COLOR3'] = magnum.gl.Attribute
magnum.shaders.VertexColor3D.__annotations__['COLOR4'] = magnum.gl.Attribute
magnum.shaders.Phong.__annotations__ = {}
magnum.shaders.Phong.__annotations__['POSITION'] = magnum.gl.Attribute
magnum.shaders.Phong.__annotations__['TEXTURE_COORDINATES'] = magnum.gl.Attribute
magnum.shaders.Phong.__annotations__['NORMAL'] = magnum.gl.Attribute
corrade.__annotations__ = {
'BUILD_DEPRECATED': bool,
'BUILD_STATIC': bool,
'BUILD_MULTITHREADED': bool,
'TARGET_UNIX': bool,
'TARGET_APPLE': bool,
'TARGET_IOS': bool,
'TARGET_IOS_SIMULATOR': bool,
'TARGET_WINDOWS': bool,
'TARGET_WINDOWS_RT': bool,
'TARGET_EMSCRIPTEN': bool,
'TARGET_ANDROID': bool
}
magnum.__annotations__ = {
'BUILD_DEPRECATED': bool,
'BUILD_STATIC': bool,
'TARGET_GL': bool,
'TARGET_GLES': bool,
'TARGET_GLES2': bool,
'TARGET_WEBGL': bool,
'TARGET_VK': bool
}
magnum.gl.__annotations__ = {
'default_framebuffer': magnum.gl.DefaultFramebuffer
}
magnum.shaders.DistanceFieldVectorGL2D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute
}
magnum.shaders.DistanceFieldVectorGL3D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute
}
magnum.shaders.FlatGL2D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute,
'COLOR3': magnum.gl.Attribute,
'COLOR4': magnum.gl.Attribute,
'TRANSFORMATION_MATRIX': magnum.gl.Attribute,
'TEXTURE_OFFSET': magnum.gl.Attribute,
}
magnum.shaders.FlatGL3D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute,
'COLOR3': magnum.gl.Attribute,
'COLOR4': magnum.gl.Attribute,
'TRANSFORMATION_MATRIX': magnum.gl.Attribute,
'TEXTURE_OFFSET': magnum.gl.Attribute,
}
magnum.shaders.VertexColorGL2D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'COLOR3': magnum.gl.Attribute,
'COLOR4': magnum.gl.Attribute
}
magnum.shaders.VertexColorGL3D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'COLOR3': magnum.gl.Attribute,
'COLOR4': magnum.gl.Attribute
}
magnum.shaders.PhongGL.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'NORMAL': magnum.gl.Attribute,
'TANGENT': magnum.gl.Attribute,
'TANGENT4': magnum.gl.Attribute,
'BITANGENT': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute,
'COLOR3': magnum.gl.Attribute,
'COLOR4': magnum.gl.Attribute,
'TRANSFORMATION_MATRIX': magnum.gl.Attribute,
'TEXTURE_OFFSET': magnum.gl.Attribute,
}
magnum.shaders.VectorGL2D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute
}
magnum.shaders.VectorGL3D.__annotations__ = {
'POSITION': magnum.gl.Attribute,
'TEXTURE_COORDINATES': magnum.gl.Attribute
}
# An extremely hacky way to remove noise for shader docs. It doesn't hide
# those, but at least puts them way down in the page, removing all docs.
# TODO needs a better solution directly in m.css
for shader in [magnum.shaders.DistanceFieldVectorGL2D,
magnum.shaders.DistanceFieldVectorGL3D,
magnum.shaders.FlatGL2D,
magnum.shaders.FlatGL3D,
magnum.shaders.VertexColorGL2D,
magnum.shaders.VertexColorGL3D,
magnum.shaders.PhongGL,
magnum.shaders.VectorGL2D,
magnum.shaders.VectorGL3D]:
shader.attach_shader = DoNotPrintValue()
shader.bind_attribute_location = DoNotPrintValue()
shader.bind_fragment_data_location = DoNotPrintValue()
shader.bind_fragment_data_location_indexed = DoNotPrintValue()
shader.dispatch_compute = DoNotPrintValue()
shader.link = DoNotPrintValue()
shader.retrievable_binary = DoNotPrintValue()
shader.separable = DoNotPrintValue()
shader.set_uniform_block_binding = DoNotPrintValue()
shader.set_uniform = DoNotPrintValue()
shader.uniform_block_index = DoNotPrintValue()
shader.uniform_location = DoNotPrintValue()
shader.TransformFeedbackBufferMode = DoNotPrintValue()
PROJECT_TITLE = 'Magnum'
PROJECT_SUBTITLE = 'Python docs'
@ -49,18 +192,30 @@ INPUT_PAGES = [
'pages/index.rst',
'pages/building.rst',
'pages/api-conventions.rst',
'pages/changelog.rst',
'pages/credits.rst',
'pages/developers.rst',
'../../../magnum-examples/doc/python/examples.rst'
]
INPUT_DOCS = [
'corrade.rst',
'corrade.containers.rst',
'corrade.pluginmanager.rst',
'corrade.utility.rst',
'magnum.rst',
'magnum.gl.rst',
'magnum.math.rst',
'magnum.materialtools.rst',
'magnum.meshtools.rst',
'magnum.platform.rst',
'magnum.primitives.rst',
'magnum.scenegraph.rst',
'magnum.shaders.rst'
'magnum.scenetools.rst',
'magnum.shaders.rst',
'magnum.text.rst',
'magnum.trade.rst',
]
LINKS_NAVBAR2 = [
@ -87,11 +242,16 @@ STYLESHEETS = [
FAVICON = '../favicon.ico'
M_DOX_TAGFILES = [
# TODO: the path should be relative to this file
(os.path.join(os.path.dirname(__file__), '../../../corrade/build/doc-mcss/corrade.tag'), '../../../../corrade/build/doc-mcss/html/', ['Corrade::'], ['m-doc-external']),
(os.path.join(os.path.dirname(__file__), '../../../magnum/build/doc-mcss/magnum.tag'), '../../../../magnum/build/doc-mcss/html/', ['Magnum::'], ['m-doc-external'])
('../../../corrade/build/doc-mcss/corrade.tag', '../../../../corrade/build/doc-mcss/html/', ['Corrade::'], ['m-doc-external']),
('../../../magnum/build/doc-mcss/magnum.tag', '../../../../magnum/build/doc-mcss/html/', ['Magnum::'], ['m-doc-external'])
]
M_SPHINX_INVENTORY_OUTPUT = 'objects.inv'
M_SPHINX_INVENTORIES = [
('python.inv', 'https://docs.python.org/3/', [], ['m-doc-external']),
('numpy.inv', 'https://docs.scipy.org/doc/numpy/', [], ["m-doc-external"])
]
M_HTMLSANITY_SMART_QUOTES = True
M_MATH_CACHE = 'm.math.cache'
PYBIND11_COMPATIBILITY = True
@ -100,15 +260,14 @@ OUTPUT = '../../build/doc/python/'
PAGE_HEADER = """
.. container:: m-note m-success
Welcome to the exciting new Python-flavored future of Magnum! Have fun, but
please note this functionality is *heavily experimental* at the moment.
Most APIs are missing, documentation is very sparse and everything is still
evolving. **Use at your own risk.**
Welcome to Python-flavored Magnum! Please note that, while already being
rather stable, this functionality is still considered *experimental* and
some APIs might get changed without preserving full backwards compatibility.
"""
FINE_PRINT = """
| Magnum Python docs. Part of the `Magnum project <https://magnum.graphics/>`_,
copyright © `Vladimír Vondruš <http://mosra.cz/>`_ and contributors, 20102019.
copyright © `Vladimír Vondruš <https://mosra.cz/>`_ and contributors, 2010--2026.
| Generated by `m.css Python doc generator <https://mcss.mosra.cz/documentation/python/>`_.
Contact the team via `GitHub <https://github.com/mosra/magnum>`_,
`Gitter <https://gitter.im/mosra/magnum>`_,

425
doc/python/corrade.containers.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -25,34 +26,39 @@
.. doctest setup
>>> from corrade import containers
>>> import array
.. py:class:: corrade.containers.ArrayView
Provides one-dimensional tightly packed view on a memory range. Convertible
both from and to Python objects supporting the Buffer Protocol, with one
dimension and stride of :py:`1`. See `StridedArrayView1D` and others for
more generic views. `ArrayView` is immutable, see `MutableArrayView` for
the mutable alterantive. All slicing operations are supported, specifying a
non-trivial stride will return `StridedArrayView1D` instead of `ArrayView`.
Example usage:
Provides an untyped one-dimensional read-only view on a contiguous memory
range. Convertible both to and from Python objects supporting the Buffer
Protocol. The buffer type is lost in the conversion process and the memory
is always treated as plain bytes:
.. code:: pycon
>>> a = b'hello'
>>> b = containers.ArrayView(a)
>>> b[2]
>>> chr(b[2])
'l'
>>> bytes(b[1:4])
b'ell'
See the :ref:`StridedArrayView1D` and its multi-dimensional variants for an
alternative that can provide typed access. The :ref:`ArrayView` is
immutable, see :ref:`MutableArrayView` for the mutable alternative. All
slicing operations are supported, specifying a non-trivial stride will
return :ref:`StridedArrayView1D` instead of :ref:`ArrayView`.
`Memory ownership and reference counting`_
==========================================
Unlike in C++, the view keeps a reference to the original memory owner
object, meaning that calling :py:`del` on the original object will *not*
invalidate the view. Slicing a view creates a new view referencing the same
original object, without any dependency on the previous view. That means a
long chained slicing operation will not cause increased memory usage.
object in the :ref:`owner` field, meaning that calling :py:`del` on the
original object will *not* invalidate the view. Slicing a view creates a
new view referencing the same original object, without any dependency on
the previous view. That means a long chained slicing operation will not
cause increased memory usage.
.. code:: pycon
@ -61,51 +67,408 @@
>>> b[1:4][:-1].owner is a
True
The :py:`owner` is :py:`None` if the view is empty.
`Comparison to Python's memoryview`_
====================================
The `ArrayView` class is equivalent to one-dimensional `memoryview` with a
stride of :py:`1`. For multiple dimensions and non-trivial strides,
`StridedArrayView1D` and friends provide a superset of `memoryview`
features.
The :ref:`ArrayView` class is equivalent to one-dimensional
:ref:`memoryview` with a stride of :py:`1`. For multiple dimensions and
non-trivial strides, :ref:`StridedArrayView1D` and friends provide a
superset of :ref:`memoryview` features.
.. py:class:: corrade.containers.MutableArrayView
Equivalent to `ArrayView`, but implementing `__setitem__()` as well.
Equivalent to :ref:`ArrayView`, but implementing :ref:`__setitem__()` as
well.
.. py:class:: corrade.containers.StridedArrayView1D
Provides one-dimensional read-only view on a memory range with custom
stride values. See `StridedArrayView2D`, `StridedArrayView3D`,
`MutableStridedArrayView1D` and others for multi-dimensional and mutable
equivalents.
Provides a typed one-dimensional read-only view on a memory range with
custom stride values. Convertible both to and from Python objects
supporting the Buffer Protocol, preserving the dimensionality, type and
stride information:
.. code:: pycon
>>> a = array.array('f', [2.5, 3.14, -1.75, 53.2])
>>> b = containers.StridedArrayView1D(memoryview(a)[::2])
>>> b[0]
2.5
>>> b[1]
-1.75
See :ref:`StridedArrayView2D`, :ref:`StridedArrayView3D`,
:ref:`StridedArrayView4D`, :ref:`MutableStridedArrayView1D` and others for
multi-dimensional and mutable equivalents.
`Memory ownership and reference counting`_
==========================================
Similarly to :ref:`ArrayView`, the view keeps a reference to the original
memory owner object in the :ref:`owner` field. Slicing a view creates a
new view referencing the same original object, without any dependency on
the previous view. The :py:`owner` is :py:`None` if the view is empty.
`Comparison to Python's memoryview`_
====================================
The `StridedArrayView1D` and its multi-dimensional variants are equivalent
to any `memoryview`, but additionally supporting multi-dimensional slicing
as well (which raises `NotImplementedError` in Py3.7 `memoryview`).
The :ref:`StridedArrayView1D` and its multi-dimensional variants are
equivalent to any :ref:`memoryview`, but additionally supporting
multi-dimensional slicing as well (which raises :ref:`NotImplementedError`
in Py3.7 :ref:`memoryview`).
.. py:function:: corrade.containers.StridedArrayView1D.__getitem__(self, i: int)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <StridedArrayView1D.format>` is not one of :py:`'b'`,
:py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`, :py:`'q'`,
:py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.StridedArrayView1D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.StridedArrayView1D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.StridedArrayView1D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedArrayView1D
Equivalent to `StridedArrayView1D`, but implementing `__setitem__()` as
well.
Equivalent to :ref:`StridedArrayView1D`, but implementing
:ref:`__setitem__()` as well.
.. py:function:: corrade.containers.MutableStridedArrayView1D.__getitem__(self, i: int)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView1D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView1D.__setitem__(self, i: int, value: object)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView1D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView1D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.MutableStridedArrayView1D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.MutableStridedArrayView1D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedArrayView2D
See `StridedArrayView1D` for more information.
See :ref:`StridedArrayView1D` for more information.
.. py:function:: corrade.containers.StridedArrayView2D.__getitem__(self, i: tuple[int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <StridedArrayView2D.format>` is not one of :py:`'b'`,
:py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`, :py:`'q'`,
:py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.StridedArrayView2D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.StridedArrayView2D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.StridedArrayView2D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0` or :py:`1` or if
they're the same
.. py:function:: corrade.containers.StridedArrayView2D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedArrayView2D
See `StridedArrayView1D` and `MutableStridedArrayView1D` for more
See :ref:`StridedArrayView1D` and :ref:`MutableStridedArrayView1D` for more
information.
.. py:function:: corrade.containers.MutableStridedArrayView2D.__getitem__(self, i: tuple[int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView2D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView2D.__setitem__(self, i: tuple[int, int], value: object)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView2D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView2D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.MutableStridedArrayView2D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.MutableStridedArrayView2D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0` or :py:`1` or if
they're the same
.. py:function:: corrade.containers.MutableStridedArrayView2D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedArrayView3D
See `StridedArrayView1D` for more information.
See :ref:`StridedArrayView1D` for more information.
.. py:function:: corrade.containers.StridedArrayView3D.__getitem__(self, i: tuple[int, int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <StridedArrayView3D.format>` is not one of :py:`'b'`,
:py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`, :py:`'q'`,
:py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.StridedArrayView3D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.StridedArrayView3D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.StridedArrayView3D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` or :py:`2`
or if they're the same
.. py:function:: corrade.containers.StridedArrayView3D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedArrayView3D
See `StridedArrayView1D` and `MutableStridedArrayView1D` for more
See :ref:`StridedArrayView1D` and :ref:`MutableStridedArrayView1D` for more
information.
.. py:function:: corrade.containers.MutableStridedArrayView3D.__getitem__(self, i: tuple[int, int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView3D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView3D.__setitem__(self, i: tuple[int, int, int], value: object)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView3D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView3D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.MutableStridedArrayView3D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.MutableStridedArrayView3D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` or :py:`2`
or if they're the same
.. py:function:: corrade.containers.MutableStridedArrayView3D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedArrayView4D
See :ref:`StridedArrayView1D` for more information.
.. py:function:: corrade.containers.StridedArrayView4D.__getitem__(self, i: tuple[int, int, int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <StridedArrayView4D.format>` is not one of :py:`'b'`,
:py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`, :py:`'q'`,
:py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.StridedArrayView4D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.StridedArrayView4D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.StridedArrayView4D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` :py:`2` or
:py:`3` or if they're the same
.. py:class:: corrade.containers.MutableStridedArrayView4D
See :ref:`StridedArrayView1D` and :ref:`MutableStridedArrayView1D` for more
information.
.. py:function:: corrade.containers.MutableStridedArrayView4D.__getitem__(self, i: tuple[int, int, int, int])
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView4D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView4D.__setitem__(self, i: tuple[int, int, int, int], value: object)
:raise IndexError: If :p:`i` is out of range
:raise NotImplementedError: If the view was created from a buffer and
:ref:`format <MutableStridedArrayView4D.format>` is not one of
:py:`'b'`, :py:`'B'`, :py:`'h'`, :py:`'H'`, :py:`'i'`, :py:`'I'`,
:py:`'q'`, :py:`'Q'`, :py:`'f'` or :py:`'d'`
.. py:function:: corrade.containers.MutableStridedArrayView4D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.MutableStridedArrayView4D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.MutableStridedArrayView4D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` :py:`2` or
:py:`3` or if they're the same
.. py:class:: corrade.containers.BitArray
An owning counterpart to :ref:`BitArrayView` / :ref:`MutableBitArrayView`.
Holds its own data buffer, thus doesn't have an equivalent to
:ref:`BitArrayView.owner`. Implicitly convertible to :ref:`BitArrayView`,
:ref:`MutableBitArrayView`, :ref:`StridedBitArrayView1D` and
:ref:`MutableStridedBitArrayView1D`, so all APIs consuming (strided) bit
array views work with this type as well.
.. py:class:: corrade.containers.BitArrayView
Comparex to an :ref:`ArrayView`, which operates with byte-sized types,
provides a view on individual bits. Convertible from a :ref:`BitArrayView`.
See :ref:`StridedBitArrayView1D` and others for more generic bit views. :ref:`BitArrayView` is immutable, see :ref:`MutableBitArrayView` for the
mutable alternative. All slicing operations are supported, specifying a
non-trivial stride will return a :ref:`StridedBitArrayView1D` instead of a :ref:`BitArrayView`.
`Memory ownership and reference counting`_
==========================================
Similarly to :ref:`ArrayView`, the view keeps a reference to the original
memory owner object in the :ref:`owner` field. Slicing a view creates a
new view referencing the same original object, without any dependency on
the previous view. The :py:`owner` is :py:`None` if the view is empty.
.. py:class:: corrade.containers.MutableBitArrayView
Equivalent to :ref:`BitArrayView`, but implementing :ref:`__setitem__()` as
well.
.. py:class:: corrade.containers.StridedBitArrayView1D
Provides one-dimensional read-only view on a memory range with custom
stride values. See :ref:`StridedBitArrayView2D`,
:ref:`StridedBitArrayView3D`, :ref:`StridedBitArrayView4D`,
:ref:`MutableStridedBitArrayView1D` and others for multi-dimensional and
mutable equivalents.
`Memory ownership and reference counting`_
==========================================
Similarly to :ref:`BitArrayView`, the view keeps a reference to the
original memory owner object in the :ref:`owner` field. Slicing a view
creates a new view referencing the same original object, without any
dependency on the previous view. The :py:`owner` is :py:`None` if the view
is empty.
.. py:function:: corrade.containers.StridedBitArrayView1D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.StridedBitArrayView1D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.StridedBitArrayView1D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedBitArrayView1D
Equivalent to :ref:`StridedBitArrayView1D`, but implementing
:ref:`__setitem__()` as well.
.. py:function:: corrade.containers.MutableStridedBitArrayView1D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.MutableStridedBitArrayView1D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`
.. py:function:: corrade.containers.MutableStridedBitArrayView1D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedBitArrayView2D
See :ref:`StridedBitArrayView1D` for more information.
.. py:function:: corrade.containers.StridedBitArrayView2D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.StridedBitArrayView2D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.StridedBitArrayView2D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0` or :py:`1` or if
they're the same
.. py:function:: corrade.containers.StridedBitArrayView2D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedBitArrayView2D
See :ref:`StridedBitArrayView1D` and :ref:`MutableStridedBitArrayView1D`
for more information.
.. py:function:: corrade.containers.MutableStridedBitArrayView2D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.MutableStridedBitArrayView2D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
.. py:function:: corrade.containers.MutableStridedBitArrayView2D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0` or :py:`1` or if
they're the same
.. py:function:: corrade.containers.MutableStridedBitArrayView2D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0` or :py:`1`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedBitArrayView3D
See :ref:`StridedBitArrayView1D` for more information.
.. py:function:: corrade.containers.StridedBitArrayView3D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.StridedBitArrayView3D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.StridedBitArrayView3D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` or :py:`2`
or if they're the same
.. py:function:: corrade.containers.StridedBitArrayView3D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.MutableStridedBitArrayView3D
See :ref:`StridedBitArrayView1D` and :ref:`MutableStridedBitArrayView1D`
for more information.
.. py:function:: corrade.containers.MutableStridedBitArrayView3D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.MutableStridedBitArrayView3D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
.. py:function:: corrade.containers.MutableStridedBitArrayView3D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` or :py:`2`
or if they're the same
.. py:function:: corrade.containers.MutableStridedBitArrayView3D.expanded
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` or :py:`2`
:raise ValueError: If product of :p:`size` is not equal to size in
:p:`dimension`
.. py:class:: corrade.containers.StridedBitArrayView4D
See :ref:`StridedBitArrayView1D` for more information.
.. py:function:: corrade.containers.StridedBitArrayView4D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.StridedBitArrayView4D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.StridedBitArrayView4D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` :py:`2` or
:py:`3` or if they're the same
.. py:class:: corrade.containers.MutableStridedBitArrayView4D
See :ref:`StridedBitArrayView1D` and :ref:`MutableStridedBitArrayView1D`
for more information.
.. py:function:: corrade.containers.MutableStridedBitArrayView4D.flipped
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.MutableStridedBitArrayView4D.broadcasted
:raise IndexError: If :p:`dimension` is not :py:`0`, :py:`1` :py:`2` or
:py:`3`
.. py:function:: corrade.containers.MutableStridedBitArrayView4D.transposed
:raise IndexError: If :p:`a` or :p:`b` is not :py:`0`, :py:`1` :py:`2` or
:py:`3` or if they're the same

40
doc/python/corrade.pluginmanager.rst

@ -0,0 +1,40 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:class:: corrade.pluginmanager.AbstractManager
:data VERSION: Plugin ABI version
.. py:function:: corrade.pluginmanager.AbstractManager.load
:raise RuntimeError: When loading fails
:return: :ref:`LoadState.LOADED`, possibly combined with other flags such
as :ref:`LoadState.STATIC`
.. py:function:: corrade.pluginmanager.AbstractManager.unload
:raise RuntimeError: When unloading fails
:return: Either :ref:`LoadState.NOT_LOADED` or :ref:`LoadState.STATIC`
.. py:function:: corrade.pluginmanager.AbstractManager.set_preferred_plugins
:raise KeyError: If the alias doesn't exist

50
doc/python/corrade.rst

@ -0,0 +1,50 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. roles used for all other docs
.. role:: cpp(code)
:language: c++
.. role:: py(code)
:language: py
.. role:: sh(code)
:language: sh
.. doctest setup
>>> from corrade import *
.. py:module:: corrade
:data BUILD_DEPRECATED: Build with deprecated features enabled
:data BUILD_STATIC: Static library build
:data BUILD_MULTITHREADED: Multi-threaded build
:data TARGET_UNIX: Unix target
:data TARGET_APPLE: Apple target
:data TARGET_IOS: iOS target
:data TARGET_IOS_SIMULATOR: iOS simulator target
:data TARGET_WINDOWS: Windows target
:data TARGET_WINDOWS_RT: Windows RT target
:data TARGET_EMSCRIPTEN: Emscripten target
:data TARGET_ANDROID: Android target

37
doc/python/corrade.utility.rst

@ -0,0 +1,37 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:function:: corrade.utility.copy
:raise AssertionError: If :p:`src` and :p:`dst` sizes, type sizes or types are different
.. py:function:: corrade.utility.ConfigurationGroup.group
:raise KeyError: If group :p:`name` doesn't exist
.. py:function:: corrade.utility.Configuration.__init__(self, filename: str)
:raise IOError: If :p:`filename` contains a parse error
.. py:function:: corrade.utility.Configuration.save
:raise IOError: If the file can't be saved

71
doc/python/magnum.gl.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -23,12 +24,76 @@
DEALINGS IN THE SOFTWARE.
..
.. py:module:: magnum.gl
:data default_framebuffer: Default framebuffer instance
:TODO: remove this line once m.css stops ignoring first caption on a page
`NoCreate constructors`_
========================
.. TODO: link to NoCreate once m.dox handles variables properly
Compared to C++, the Python APIs don't have an alternative to the
:dox:`NoCreate <NoCreateT>` constructor tag. In C++ these make it possible
to have class members initialized before a GL context is present, but in
Python there's no such limitation so these don't make sense.
.. py:function:: magnum.gl.AbstractShaderProgram.link
:raise RuntimeError: If linking fails
.. py:function:: magnum.gl.AbstractShaderProgram.uniform_location
:raise ValueError: If there's no uniform of that name
.. py:function:: magnum.gl.AbstractShaderProgram.uniform_block_index
:raise ValueError: If there's no uniform block of that name
.. py:function:: magnum.gl.Shader.compile
:raise RuntimeError: If compilation fails
.. py:class:: magnum.gl.Mesh
:TODO: remove this line once m.css stops ignoring first caption on a page
`Buffer ownership and reference counting`_
==========================================
Unlike in C++, where a :dox:`GL::Buffer` is either :dox:`std::move()`\ d
into the mesh or referenced externally (with the user being responsible for
its lifetime), the `gl.Mesh` object keeps references to all buffers added
to it.
its lifetime), the :ref:`gl.Mesh` object keeps references to all buffers
added to it.
.. py:property:: magnum.gl.Mesh.primitive
While querying this property will always give back a :ref:`gl.MeshPrimitive`,
this property can be set using either :ref:`magnum.MeshPrimitive` or
:ref:`gl.MeshPrimitive`, similarly to how the overloaded
:dox:`GL::Mesh::setPrimitive()` works.
.. py:property:: magnum.gl.Texture1D.minification_filter
See :ref:`Texture2D.minification_filter` for more information.
.. py:property:: magnum.gl.Texture2D.minification_filter
This property accepts either a tuple of :ref:`magnum.SamplerFilter` /
:ref:`gl.SamplerFilter` and :ref:`magnum.SamplerMipmap` /
:ref:`gl.SamplerMipmap` values or just :ref:`magnum.SamplerFilter` / :ref:`gl.SamplerFilter` alone in which case :ref:`gl.SamplerMipmap.BASE`
will be used implicitly; similarly to how the overloaded
:dox:`GL::Texture::setMinificationFilter()` works.
.. py:property:: magnum.gl.Texture3D.minification_filter
See :ref:`Texture2D.minification_filter` for more information.
.. py:property:: magnum.gl.Texture1D.magnification_filter
See :ref:`Texture2D.magnification_filter` for more information.
.. py:property:: magnum.gl.Texture2D.magnification_filter
This property accepts either :ref:`magnum.SamplerFilter` or
:ref:`gl.SamplerFilter`, similarly to how the overloaded
:dox:`GL::Texture::setMagnificationFilter()`
works.
.. py:property:: magnum.gl.Texture3D.magnification_filter
See :ref:`Texture2D.magnification_filter` for more information.

43
doc/python/magnum.materialtools.rst

@ -0,0 +1,43 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:function:: magnum.materialtools.filter_attributes
:raise AssertionError: If size of :p:`attributes_to_keep` is different than
:ref:`trade.MaterialData.attribute_data_offset()` for
:ref:`trade.MaterialData.layer_count`
.. py:function:: magnum.materialtools.filter_layers
:raise AssertionError: If size of :p:`layers_to_keep` is different than
:ref:`trade.MaterialData.layer_count`
.. py:function:: magnum.materialtools.filter_attributes_layers
:raise AssertionError: If size of :p:`attributes_to_keep` is different than
:ref:`trade.MaterialData.attribute_data_offset()` for
:ref:`trade.MaterialData.layer_count`
:raise AssertionError: If size of :p:`layers_to_keep` is different than
:ref:`trade.MaterialData.layer_count`
.. py:function:: magnum.materialtools.merge
:raise RuntimeError: If merge failed due to a conflict
.. py:function:: magnum.materialtools.phong_to_pbr_metallic_roughness
:raise RuntimeError: If conversion failed

613
doc/python/magnum.math.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -24,11 +25,21 @@
..
.. py:module:: magnum.math
:data pi: :math:`\pi`
:data pi_half: Half of a :math:`\pi`
:data pi_quarter: Quarter of a :math:`\pi`
:data tau: :math:`\tau`, or :math:`2 \pi`
:data e: Euler's number
:data sqrt2: Square root of 2
:data sqrt3: Square root of 3
:data sqrt_half: Square root of :math:`\frac{1}{2}`
:data nan: Quiet NaN
:data inf: Positive :math:`\infty`
In the C++ API, math types are commonly used via :cpp:`typedef`\ s in the
root namespace, only library-level generic code uses things like
:dox:`Math::Vector<size, T> <Math::Vector>`. Since Python doesn't have
templates or generics, there are no generic variants in the `magnum.math`
templates or generics, there are no generic variants in the :ref:`magnum.math`
module, all the concrete types are in the root module with the same names
as in the C++ variant.
@ -72,7 +83,7 @@
As shown above, all math types are constructible from a (nested) tuple of
matching type, matching the convenience of C++11 uniform initializers. As
another example, a function accepting a `Quaternion` will accept a
another example, a function accepting a :ref:`Quaternion` will accept a
:py:`((x, y, z), w)` tuple as well, but not :py:`(x, y, z, w)`, as that is
not convertible to a pair of a three-component vector and a scalar.
@ -83,12 +94,12 @@
Currently, doing :py:`from magnum import math` will bring in the
Magnum's math module which at the moment *does not* contain the
well-known Python APIs and constants. In particular, calling `math.sin()`
expects an explicit `Deg` / `Rad` type, while Python's :py:`math.sin()`
doesn't. This will get resolved either by making all Python overloads
present in the same module or giving the user an option whether to use
Magnum math or Python math. For now, to avoid confusion, do for example
this:
well-known Python APIs and constants. In particular, calling
:ref:`magnum.math.sin()` expects an explicit :ref:`Deg` / :ref:`Rad`
type, while Python's :ref:`math.sin()` doesn't. This will get resolved
either by making all Python overloads present in the same module or
giving the user an option whether to use Magnum math or Python math.
For now, to avoid confusion, do for example this:
.. code:: pycon
@ -104,9 +115,10 @@
Since Python doesn't really differentiate between 32bit and 64bit doubles,
all *scalar* functions taking or returning a floating-point type (such as
the `Deg` / `Rad` types, `math.pi` or `math.sin()`) use the :cpp:`double`
variant of the underlying C++ API --- the extra arithmetic cost is
negligible to the Python-to-C++ function call overhead.
the :ref:`Deg` / :ref:`Rad` types, :ref:`math.pi <magnum.math.pi>` or
:ref:`math.sin <magnum.math.sin()>`) use the :cpp:`double` variant of the
underlying C++ API --- the extra arithmetic cost is negligible to the
Python-to-C++ function call overhead.
On the other hand, matrix and vector types are exposed in both the float
and double variants.
@ -117,7 +129,7 @@
All vector classes are implicitly convertible from a tuple of correct size
and type as well as from/to type implementing the buffer protocol, and
these can be also converted back to lists using list comprehensions. This
makes them fully compatible with `numpy.array`, so the following
makes them fully compatible with :ref:`numpy.ndarray`, so the following
expressions are completely valid:
..
@ -147,7 +159,7 @@
To simplify the implementation, Magnum matrices are convertible only from
32-bit and 64-bit floating-point types (:py:`'f'` and :py:`'d'` numpy
``dtype``). In the other direction, unless overriden using ``dtype`` or
``dtype``). In the other direction, unless overridden using ``dtype`` or
``order``, the created numpy array matches Magnum data type and layout:
.. code:: pycon
@ -159,21 +171,34 @@
>>> a[0] # first column
Vector(1, 4, 7)
..
In order to minimize floating-point printing differences across
architectures (ARM Mac has a different output below otherwise)
>>> np.set_printoptions(precision=5)
.. code:: pycon
>>> b = np.array(Matrix3.rotation(Deg(45.0)))
>>> b.strides[0] # column-major storage
4
>>> b[0] # first column, 32-bit floats
array([ 0.70710677, -0.70710677, 0. ], dtype=float32)
array([ 0.70711, -0.70711, 0. ], dtype=float32)
..
A bit longer for doubles
>>> np.set_printoptions(precision=7)
.. code:: pycon
>>> c = np.array(Matrix3.rotation(Deg(45.0)), order='C', dtype='d')
>>> c.strides[0] # row-major storage (overriden)
>>> c.strides[0] # row-major storage (overridden)
24
>>> c[0] # first column, 64-bit floats (overriden)
array([ 0.70710677, -0.70710677, 0. ])
>>> c[0] # first column, 64-bit floats (overridden)
array([ 0.7071068, -0.7071068, 0. ])
..
Reset back
>>> np.set_printoptions()
`Major differences to the C++ API`_
===================================
@ -181,62 +206,508 @@
- All vector and matrix classes implement :py:`len()`, which is used
instead of e.g. :dox:`Math::Vector::Size`. Works on both classes
and instances.
- :dox:`Math::Matrix3::from()` / :dox:`Math::Matrix4::from()` are named
:ref:`Matrix3.from_()` / :ref:`Matrix4.from_()` because :py:`from` is
a Python keyword and thus can't be used as a name.
- :dox:`Math::isInf()` and :dox:`Math::isNan()` are named
:ref:`math.isinf() <magnum.math.isinf()>` and
:ref:`math.isnan() <magnum.math.isnan()>` for consistency with the
Python :ref:`math` module
- :cpp:`Math::gather()` and :cpp:`Math::scatter()` operations are
implemented as real swizzles:
.. code:: pycon
>>> a = Vector4(1.5, 0.3, -1.0, 1.0)
>>> b = Vector4(7.2, 2.3, 1.1, 0.0)
>>> a.wxy = b.xwz
>>> a
Vector(0, 1.1, -1, 7.2)
- :py:`mat[a][b] = c` on matrices doesn't do the expected thing, use
:py:`mat[a, b] = c` instead
- :cpp:`Math::BoolVector::set()` doesn't exist, use ``[]`` instead
- While both boolean and bitwise operations on :cpp:`Math::BoolVector`
- :cpp:`Math::BitVector::set()` doesn't exist, use ``[]`` instead
- While both boolean and bitwise operations on :cpp:`Math::BitVector`
behave the same to ensure consistency in generic code, this is not
possible to do in Python. Here the boolean operations behave like
if :py:`any()` was applied before doing the operation.
.. block-warning:: Subject to change
The :dox:`Math::swizzle()` operation is not yet available in the Python
API. Thanks to better flexibility of the Python language this will get
implemented as a *real* swizzle, allowing for convenient expressions
like :py:`vec.xz = (3.5, 0.1)`.
`Static constructors and instance method overloads`_
----------------------------------------------------
While not common in Python, the `Matrix4.scaling()` / `Matrix4.rotation()`
methods mimic the C++ equivalent --- calling `Matrix4.scaling()` will
return a scaling matrix, while :py:`mat.scaling()` returns the 3x3 scaling
part of the matrix. Similarly for the `Matrix3` class.
.. block-warning:: Subject to change
On the other hand, there's currently just `Matrix3.translation()` and
the corresponding :py:`mat.translation` property is temporarily
available as an underscored `Matrix3._translation`. This will change
later.
.. py:data:: magnum.math.pi
:summary: :math:`\pi`
.. py:data:: magnum.math.pi_half
:summary: Half of a :math:`\pi`
.. py:data:: magnum.math.pi_quarter
:summary: Quarter of a :math:`\pi`
.. py:data:: magnum.math.tau
:summary: :math:`\tau`
.. py:data:: magnum.math.e
:summary: Euler's number
.. py:data:: magnum.math.sqrt2
:summary: Square root of 2
.. py:data:: magnum.math.sqrt3
:summary: Square root of 3
.. py:data:: magnum.math.sqrt_half
:summary: Square root of :math:`\frac{1}{2}`
.. py:data:: magnum.math.nan
:summary: Quiet NaN
.. py:data:: magnum.math.inf
:summary: Positive :math:`\infty`
`Static constructors and instance method / property overloads`_
---------------------------------------------------------------
While not common in Python, the :ref:`Matrix4.scaling()` /
:ref:`Matrix4.rotation()` methods mimic the C++ equivalent --- calling
:py:`Matrix4.scaling(vec)` will return a scaling matrix, while
:py:`mat.scaling()` returns the 3x3 scaling part of the matrix. With
:ref:`Matrix4.translation`, it's a bit more involved --- calling
:py:`Matrix4.translation(vec)` will return a translation matrix, while
:py:`mat.translation` is a read-write property accessing the fourth column
of the matrix. Similarly for the :ref:`Matrix3` class.
.. py:function:: magnum.Matrix2x2.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix2x2d.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix3x3.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix3x3d.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix4x4.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix4x4d.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix3.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix3d.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix4.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix4d.inverted_orthogonal
:raise ValueError: If the matrix is not orthogonal
.. py:function:: magnum.Matrix3.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Matrix3d.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Matrix4.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Matrix4d.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Matrix3.rotation(self)
:raise ValueError: If the normalized rotation part is not orthogonal
.. py:function:: magnum.Matrix3d.rotation(self)
:raise ValueError: If the normalized rotation part is not orthogonal
.. py:function:: magnum.Matrix4.rotation(self)
:raise ValueError: If the normalized rotation part is not orthogonal
.. py:function:: magnum.Matrix4d.rotation(self)
:raise ValueError: If the normalized rotation part is not orthogonal
.. py:function:: magnum.Matrix3.rotation_normalized
:raise ValueError: If the rotation part is not orthogonal
.. py:function:: magnum.Matrix3d.rotation_normalized
:raise ValueError: If the rotation part is not orthogonal
.. py:function:: magnum.Matrix4.rotation_normalized
:raise ValueError: If the rotation part is not orthogonal
.. py:function:: magnum.Matrix4d.rotation_normalized
:raise ValueError: If the rotation part is not orthogonal
.. py:function:: magnum.Matrix3.uniform_scaling_squared
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix3d.uniform_scaling_squared
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix4.uniform_scaling_squared
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix4d.uniform_scaling_squared
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix3.uniform_scaling
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix3d.uniform_scaling
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix4.uniform_scaling
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix4d.uniform_scaling
:raise ValueError: If the matrix doesn't have uniform scaling
.. py:function:: magnum.Matrix3.inverted_rigid
:raise ValueError: If the matrix doesn't represent a rigid transformation
.. py:function:: magnum.Matrix3d.inverted_rigid
:raise ValueError: If the matrix doesn't represent a rigid transformation
.. py:function:: magnum.Matrix4.inverted_rigid
:raise ValueError: If the matrix doesn't represent a rigid transformation
.. py:function:: magnum.Matrix4d.inverted_rigid
:raise ValueError: If the matrix doesn't represent a rigid transformation
.. py:function:: magnum.math.half_angle(normalized_a: magnum.Quaternion, normalized_b: magnum.Quaternion)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.half_angle(normalized_a: magnum.Quaterniond, normalized_b: magnum.Quaterniond)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.lerp(normalized_a: magnum.Quaternion, normalized_b: magnum.Quaternion, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.lerp(normalized_a: magnum.Quaterniond, normalized_b: magnum.Quaterniond, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.lerp_shortest_path(normalized_a: magnum.Quaternion, normalized_b: magnum.Quaternion, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.lerp_shortest_path(normalized_a: magnum.Quaterniond, normalized_b: magnum.Quaterniond, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.slerp(normalized_a: magnum.Quaternion, normalized_b: magnum.Quaternion, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.slerp(normalized_a: magnum.Quaterniond, normalized_b: magnum.Quaterniond, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.slerp_shortest_path(normalized_a: magnum.Quaternion, normalized_b: magnum.Quaternion, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.math.slerp_shortest_path(normalized_a: magnum.Quaterniond, normalized_b: magnum.Quaterniond, t: float)
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.Quaternion.rotation(angle: magnum.Rad, normalized_axis: magnum.Vector3)
:raise ValueError: If :p:`normalized_axis` is not normalized
.. py:function:: magnum.Quaternion.rotation(normalized_from: magnum.Vector3, normalized_to: magnum.Vector3)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.Quaterniond.rotation(angle: magnum.Rad, normalized_axis: magnum.Vector3d)
:raise ValueError: If :p:`normalized_axis` is not normalized
.. py:function:: magnum.Quaternion.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Quaterniond.reflection
:raise ValueError: If :p:`normal` is not normalized
.. py:function:: magnum.Quaternion.from_matrix
:raise ValueError: If :p:`matrix` is not a rotation
.. py:function:: magnum.Quaterniond.from_matrix
:raise ValueError: If :p:`matrix` is not a rotation
.. py:function:: magnum.Quaternion.angle
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaterniond.angle
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaternion.axis
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaterniond.axis
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaternion.inverted_normalized
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaterniond.inverted_normalized
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaternion.transform_vector_normalized
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.Quaterniond.transform_vector_normalized
:raise ValueError: If the quaternion is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector2, normalized_b: magnum.Vector2)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector2d, normalized_b: magnum.Vector2d)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector3, normalized_b: magnum.Vector3)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector3d, normalized_b: magnum.Vector3d)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector4, normalized_b: magnum.Vector4)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.math.angle(normalized_a: magnum.Vector4d, normalized_b: magnum.Vector4d)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.Vector2.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. py:function:: magnum.Vector2d.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. py:function:: magnum.Vector3.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. py:function:: magnum.Vector3d.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. py:function:: magnum.Vector4.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. py:function:: magnum.Vector4d.projected_onto_normalized
:raise ValueError: If :p:`line` is not normalized
.. For pickling, because py::pickle() doesn't seem to have a way to set the
__setstate__ / __getstate__ docs directly FFS
.. py:function:: magnum.Deg.__getstate__
:summary: Dumps the in-memory representation as a float
.. py:function:: magnum.Rad.__getstate__
:summary: Dumps the in-memory representation as a float
.. py:function:: magnum.BitVector2.__getstate__
:summary: Dumps the in-memory representation of vector bits
.. py:function:: magnum.BitVector3.__getstate__
:summary: Dumps the in-memory representation of vector bits
.. py:function:: magnum.BitVector4.__getstate__
:summary: Dumps the in-memory representation of vector bits
.. py:function:: magnum.Vector2.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector3.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector4.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector2d.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector3d.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector4d.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector2i.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector3i.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector4i.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector2ui.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector3ui.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Vector4ui.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Color3.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Color4.__getstate__
:summary: Dumps the in-memory representation of vector components
.. py:function:: magnum.Matrix2x2.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix2x3.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix2x4.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x2.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x3.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x4.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x2.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x3.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x4.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix2x2d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix2x3d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix2x4d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x2d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x3d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3x4d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x2d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x3d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4x4d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix3d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Matrix4d.__getstate__
:summary: Dumps the in-memory representation of matrix components
.. py:function:: magnum.Quaternion.__getstate__
:summary: Dumps the in-memory representation of quaternion components
.. py:function:: magnum.Quaterniond.__getstate__
:summary: Dumps the in-memory representation of quaternion components
.. py:function:: magnum.Range1D.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range2D.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range3D.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range1Dd.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range2Dd.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range3Dd.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range1Di.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range2Di.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Range3Di.__getstate__
:summary: Dumps the in-memory representation of range min/max components
.. py:function:: magnum.Deg.__setstate__
:summary: Uses the float as the in-memory representation
.. py:function:: magnum.Rad.__setstate__
:summary: Uses the float as the in-memory representation
.. py:function:: magnum.BitVector2.__setstate__
:summary: Treats the data as the in-memory representation of vector bits
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.BitVector3.__setstate__
:summary: Treats the data as the in-memory representation of vector bits
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.BitVector4.__setstate__
:summary: Treats the data as the in-memory representation of vector bits
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector2.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector3.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector4.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector2d.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector3d.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector4d.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector2i.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector3i.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector4i.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector2ui.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector3ui.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Vector4ui.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Color3.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Color4.__setstate__
:summary: Treats the data as the in-memory representation of vector
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x2.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x3.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x4.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x2.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x3.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x4.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x2.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x3.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x4.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x2d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x3d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix2x4d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x2d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x3d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3x4d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x2d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x3d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4x4d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix3d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Matrix4d.__setstate__
:summary: Treats the data as the in-memory representation of matrix
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Quaternion.__setstate__
:summary: Treats the data as the in-memory representation of quaternion
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Quaterniond.__setstate__
:summary: Treats the data as the in-memory representation of quaternion
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range1D.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range2D.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range3D.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range1Dd.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range2Dd.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range3Dd.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range1Di.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range2Di.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size
.. py:function:: magnum.Range3Di.__setstate__
:summary: Treats the data as the in-memory representation of range min/max
components
:raise ValueError: If the data size doesn't match type size

97
doc/python/magnum.meshtools.rst

@ -0,0 +1,97 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:function:: magnum.meshtools.compress_indices
:raise AssertionError: If :p:`mesh` is not indexed
.. py:function:: magnum.meshtools.concatenate
:raise AssertionError: If :p:`meshes` is empty
:raise AssertionError: If any of the :p:`meshes` is
:ref:`MeshPrimitive.LINE_STRIP`, :ref:`MeshPrimitive.LINE_LOOP`,
:ref:`MeshPrimitive.TRIANGLE_STRIP` or
:ref:`MeshPrimitive.TRIANGLE_FAN`
:raise AssertionError: If all :p:`meshes` don't have the same
:ref:`MeshPrimitive`
.. py:function:: magnum.meshtools.duplicate
:raise AssertionError: If :p:`mesh` is not indexed
.. py:function:: magnum.meshtools.filter_attributes
:raise AssertionError: If size of :p:`attributes_to_keep` is different than
:p:`mesh` attribute count
.. py:function:: magnum.meshtools.generate_indices
:raise AssertionError: If :p:`mesh` is not :ref:`MeshPrimitive.LINE_STRIP`,
:ref:`MeshPrimitive.LINE_LOOP`, :ref:`MeshPrimitive.TRIANGLE_STRIP` or
:ref:`MeshPrimitive.TRIANGLE_FAN`
.. py:function:: magnum.meshtools.interleave
:raise AssertionError: If any attribute in :p:`extra` has the data size
different from :p:`mesh` vertex count
.. py:function:: magnum.meshtools.transform2d
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.POSITION` of index :p:`id` (and in morph
target :p:`morph_target_id` if not :py:`-1`)
:raise AssertionError: If :ref:`trade.MeshAttribute.POSITION` are not 2D
.. py:function:: magnum.meshtools.transform2d_in_place
:raise AssertionError: If :p:`mesh` vertex data aren't
:ref:`trade.DataFlags.MUTABLE`
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.POSITION` of index :p:`id` (and in morph
target :p:`morph_target_id` if not :py:`-1`)
:raise AssertionError: If :ref:`trade.MeshAttribute.POSITION` are not
:ref:`VertexFormat.VECTOR2`
.. py:function:: magnum.meshtools.transform3d
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.POSITION` of index :p:`id` (and in morph
target :p:`morph_target_id` if not :py:`-1`)
:raise AssertionError: If :ref:`trade.MeshAttribute.POSITION` are not 3D
.. py:function:: magnum.meshtools.transform3d_in_place
:raise AssertionError: If :p:`mesh` vertex data aren't
:ref:`trade.DataFlags.MUTABLE`
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.POSITION` of index :p:`id` (and in morph
target :p:`morph_target_id` if not :py:`-1`)
:raise AssertionError: If :ref:`trade.MeshAttribute.POSITION` are not
:ref:`VertexFormat.VECTOR3`
.. py:function:: magnum.meshtools.transform_texture_coordinates2d
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.TEXTURE_COORDINATES` of index :p:`id` (and in
morph target :p:`morph_target_id` if not :py:`-1`)
.. py:function:: magnum.meshtools.transform_texture_coordinates2d_in_place
:raise AssertionError: If :p:`mesh` vertex data aren't
:ref:`trade.DataFlags.MUTABLE`
:raise KeyError: If :p:`mesh` doesn't have
:ref:`trade.MeshAttribute.TEXTURE_COORDINATES` of index :p:`id` (and in
morph target :p:`morph_target_id` if not :py:`-1`)
:raise AssertionError: If :ref:`trade.MeshAttribute.TEXTURE_COORDINATES`
are not :ref:`VertexFormat.VECTOR2`

28
doc/python/magnum.platform.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -25,18 +26,16 @@
.. py:module:: magnum.platform
While concrete implementations of :py:`Application` and
:py:`WindowlessApplication` classes are available in the submodules,
there's a convenience logic importing the most fitting implementation
that's available directly into the :py:`platform` module, meaning you can
do just this without having to think about a particular implementation,
for example:
Concrete implementations of :py:`Application` and :py:`WindowlessApplication`
classes are available in submodules, and it's up to you which one you
choose. For example:
.. code:: py
from magnum import platform
import magnum.platform.sdl2
class MyApp(platform.Application): # platform.sdl2.Application
class MyApp(platform.sdl2.Application):
...
The same goes for :py:`WindowlessApplication` implementations, for example:
@ -44,11 +43,16 @@
.. code:: py
from magnum import platform
import magnum.platform.egl
class MyApp(platform.WindowlessApplication): # platform.egl.WindowlessApp
class MyApp(platform.egl.WindowlessApplication):
...
.. block-warning:: Subject to change
Alternatively, if you want to narrow down the mention of a particular
toolkit to just one line, you can also do:
At the moment, there's no way to specify a different priority order or
disable the auto-import altogether.
.. code:: py
from magnum.platform.sdl2 import Application
class MyApp(Application):

70
doc/python/magnum.primitives.rst

@ -0,0 +1,70 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:function:: magnum.primitives.capsule2d_wireframe
:raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1`
:raise AssertionError: If :p:`cylinder_rings` is less than :py:`1`
.. py:function:: magnum.primitives.capsule3d_solid
:raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1`
:raise AssertionError: If :p:`cylinder_rings` is less than :py:`1`
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.capsule3d_wireframe
:raise AssertionError: If :p:`hemisphere_rings` is less than :py:`1`
:raise AssertionError: If :p:`cylinder_rings` is less than :py:`1`
:raise AssertionError: If :p:`segments` is zero or not a multiple of
:py:`4`
.. py:function:: magnum.primitives.circle2d_solid
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.circle2d_wireframe
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.circle3d_solid
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.circle3d_wireframe
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.cone_solid
:raise AssertionError: If :p:`rings` is less than :py:`1`
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.cone_wireframe
:raise AssertionError: If :p:`segments` is zero or not a multiple of
:py:`4`
.. py:function:: magnum.primitives.cylinder_solid
:raise AssertionError: If :p:`rings` is less than :py:`1`
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.cylinder_wireframe
:raise AssertionError: If :p:`rings` is less than :py:`1`
:raise AssertionError: If :p:`segments` is zero or not a multiple of
:py:`4`
.. py:function:: magnum.primitives.uv_sphere_solid
:raise AssertionError: If :p:`rings` is less than :py:`2`
:raise AssertionError: If :p:`segments` is less than :py:`3`
.. py:function:: magnum.primitives.uv_sphere_wireframe
:raise AssertionError: If :p:`rings` is zero or not a multiple of :py:`2`
:raise AssertionError: If :p:`segments` is zero or not a multiple of
:py:`4`

280
doc/python/magnum.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -25,15 +26,274 @@
.. roles used for all other docs
.. role:: cpp(code)
:language: c++
.. role:: py(code)
:language: py
.. role:: link-ref(link)
:class: m-doc
.. doctest setup
>>> from magnum import *
.. TODO: change this to py:ref or something when we are able to reference names
.. default-role:: py
.. py:module:: magnum
:data BUILD_DEPRECATED: Build with deprecated features enabled
:data BUILD_STATIC: Static library build
:data TARGET_GL: OpenGL interoperability
:data TARGET_GLES: OpenGL ES target
:data TARGET_GLES2: OpenGL ES 2.0 target
:data TARGET_WEBGL: WebGL target
:data TARGET_EGL: EGL target
:data TARGET_VK: Vulkan interoperability
.. py:enum:: magnum.PixelFormat
The ``size``, ``channel_format``, ``channel_count``, ``is_normalized``,
``is_integral``, ``is_floating_point``, ``is_srgb``,
``is_depth_or_stencil`` and ``is_implementation_specific`` properties match
:dox:`pixelFormatSize()`, :dox:`pixelFormatChannelFormat()` and other
helpers.
.. code:: pycon
>>> PixelFormat.RGB8_SRGB.channel_count
3
>>> PixelFormat.RGB16F.is_floating_point
True
.. py:enum:: magnum.CompressedPixelFormat
The ``block_size``, ``block_data_size`` and ``is_implementation_specific``
properties match :dox:`compressedPixelFormatBlockSize()`,
:dox:`compressedPixelFormatBlockDataSize()` and other helpers.
.. code:: pycon
>>> CompressedPixelFormat.ASTC_6X5_RGBA_SRGB.block_size
Vector(6, 5, 1)
>>> CompressedPixelFormat.ASTC_6X5_RGBA_SRGB.block_data_size
16
.. py:class:: magnum.Image1D
See :ref:`Image2D` for more information.
.. py:class:: magnum.Image2D
An owning counterpart to :ref:`ImageView2D` / :ref:`MutableImageView2D`.
Holds its own data buffer, thus doesn't have an equivalent to
:ref:`ImageView2D.owner`. The :ref:`data` and :ref:`pixels` views allow
mutable access. Implicitly convertible to :ref:`ImageView2D` /
:ref:`MutableImageView2D`, so all APIs consuming image views work with this
type as well.
.. py:class:: magnum.Image3D
See :ref:`Image2D` for more information.
.. py:class:: magnum.CompressedImage1D
See :ref:`CompressedImage2D` for more information.
.. py:class:: magnum.CompressedImage2D
An owning counterpart to :ref:`CompressedImageView2D` /
:ref:`MutableCompressedImageView2D`. Holds its own data buffer, thus
doesn't have an equivalent to :ref:`CompressedImageView2D.owner`. The
:ref:`data` view allows mutable access. Implicitly convertible to
:ref:`CompressedImageView2D` / :ref:`MutableCompressedImageView2D`, so all
APIs consuming image views work with this type as well.
.. py:class:: magnum.CompressedImage3D
See :ref:`CompressedImage2D` for more information.
.. py:class:: magnum.ImageView1D
See :ref:`ImageView2D` for more information.
.. py:class:: magnum.ImageView2D
:TODO: remove this line once m.css stops ignoring first caption on a page
`Memory ownership and reference counting`_
==========================================
Similarly to :ref:`corrade.containers.ArrayView` (and unlike in C++), the
view keeps a reference to the original memory owner object in the
:ref:`owner` field, meaning that calling :py:`del` on the original object
will *not* invalidate the view. Slicing a view creates a new view
referencing the same original object, without any dependency on the
previous view. That means a long chained slicing operation will not cause
increased memory usage.
The :ref:`owner` is :py:`None` if the view is empty.
`Pixel data access`_
====================
The class makes use of Python's dynamic nature and provides direct access
to pixel data in their concrete types via :ref:`pixels`. The returned views
point to the underlying image data, element access coverts to a type
corresponding to a particular :ref:`PixelFormat` and for
performance-oriented access the view implements a buffer protocol with a
corresponding type annotation.
Normalized formats (such as :ref:`PixelFormat.RGB8_UNORM` but also
:ref:`PixelFormat.RGBA8_SRGB`) are unpacked to a corresponding
floating-point representation in element access and packed from a
floating-point representation in mutable acess. The type annotation is
however still matching the original type (such as :py:`'3B'` / :py:`'4B'`
in these cases), so code consuming these via the buffer protocol needs to
handle the normalization explicitly if needed.
..
>>> from magnum import *
>>> import numpy as np
>>> import array
.. code:: pycon
>>> data = array.array('B', [0xf3, 0x2a, 0x80, 0x23, 0x00, 0xff, 0x00, 0xff])
>>> image = ImageView2D(PixelFormat.RGBA8_SRGB, (2, 1), data)
>>> image.pixels[0, 0] # sRGB -> float conversion
Vector(0.896269, 0.0231534, 0.215861, 0.137255)
>>> np.array(image.pixels, copy=False)[0]
array([[243, 42, 128, 35],
[ 0, 255, 0, 255]], dtype=uint8)
.. py:class:: magnum.ImageView3D
See :ref:`ImageView2D` for more information.
.. py:class:: magnum.MutableImageView1D
See :ref:`ImageView2D` for more information. The only difference to the
non-mutable variant is that it's possible to modify the image through
:ref:`data` and :ref:`pixels`.
.. py:class:: magnum.MutableImageView2D
See :ref:`ImageView2D` for more information. The only difference to the
non-mutable variant is that it's possible to modify the image through
:ref:`data` and :ref:`pixels`.
.. py:class:: magnum.MutableImageView3D
See :ref:`ImageView2D` for more information. The only difference to the
non-mutable variant is that it's possible to modify the image through
:ref:`data` and :ref:`pixels`.
.. py:function:: magnum.ImageView1D.__init__(self, arg0: magnum.ImageView1D)
:raise RuntimeError: If :ref:`trade.ImageData1D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData1D` in the :ref:`trade` module.
.. py:function:: magnum.ImageView2D.__init__(self, arg0: magnum.ImageView2D)
:raise RuntimeError: If :ref:`trade.ImageData2D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData2D` in the :ref:`trade` module.
.. py:function:: magnum.ImageView3D.__init__(self, arg0: magnum.ImageView3D)
:raise RuntimeError: If :ref:`trade.ImageData3D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData3D` in the :ref:`trade` module.
.. py:function:: magnum.MutableImageView1D.__init__(self, arg0: magnum.MutableImageView1D)
:raise RuntimeError: If :ref:`trade.ImageData1D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData1D` in the :ref:`trade` module.
.. py:function:: magnum.MutableImageView2D.__init__(self, arg0: magnum.MutableImageView2D)
:raise RuntimeError: If :ref:`trade.ImageData2D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData2D` in the :ref:`trade` module.
.. py:function:: magnum.MutableImageView3D.__init__(self, arg0: magnum.MutableImageView3D)
:raise RuntimeError: If :ref:`trade.ImageData3D.is_compressed` is :py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData3D` in the :ref:`trade` module.
.. py:class:: magnum.CompressedImageView1D
See :ref:`CompressedImageView2D` for more information.
.. py:class:: magnum.CompressedImageView2D
:TODO: remove this line once m.css stops ignoring first caption on a page
`Memory ownership and reference counting`_
==========================================
Similarly to :ref:`corrade.containers.ArrayView` (and unlike in C++), the
view keeps a reference to the original memory owner object in the
:ref:`owner` field, meaning that calling :py:`del` on the original object
will *not* invalidate the view. Slicing a view creates a new view
referencing the same original object, without any dependency on the
previous view. That means a long chained slicing operation will not cause
increased memory usage.
The :ref:`owner` is :py:`None` if the view is empty.
.. py:class:: magnum.CompressedImageView3D
See :ref:`CompressedImageView2D` for more information.
.. py:class:: magnum.MutableCompressedImageView1D
See :ref:`CompressedImageView2D` for more information. The only difference
to the non-mutable variant is that it's possible to modify the image
through :ref:`data`.
.. py:class:: magnum.MutableCompressedImageView2D
See :ref:`CompressedImageView2D` for more information. The only difference
to the non-mutable variant is that it's possible to modify the image
through :ref:`data`.
.. py:class:: magnum.MutableImageView3D
See :ref:`CompressedImageView2D` for more information. The only difference
to the non-mutable variant is that it's possible to modify the image
through :ref:`data`.
.. py:function:: magnum.CompressedImageView1D.__init__(self, arg0: magnum.CompressedImageView1D)
:raise RuntimeError: If :ref:`trade.ImageData1D.is_compressed` is
:py:`False`
This function is used to implement implicit conversion from
:ref:`trade.ImageData1D` in the :ref:`trade` module.
.. py:function:: magnum.CompressedImageView2D.__init__(self, arg0: magnum.CompressedImageView2D)
:raise RuntimeError: If :ref:`trade.ImageData2D.is_compressed` is
:py:`False`
This function is used to implement implicit conversion from
:ref:`trade.ImageData2D` in the :ref:`trade` module.
.. py:function:: magnum.CompressedImageView3D.__init__(self, arg0: magnum.CompressedImageView3D)
:raise RuntimeError: If :ref:`trade.ImageData3D.is_compressed` is
:py:`False`
This function is used to implement implicit conversion from
:ref:`trade.ImageData3D` in the :ref:`trade` module.
.. py:function:: magnum.MutableCompressedImageView1D.__init__(self, arg0: magnum.MutableCompressedImageView1D)
:raise RuntimeError: If :ref:`trade.ImageData1D.is_compressed` is
:py:`False`
This function is used to implement implicit conversion from
:ref:`trade.ImageData1D` in the :ref:`trade` module.
.. py:function:: magnum.MutableCompressedImageView2D.__init__(self, arg0: magnum.MutableCompressedImageView2D)
:raise RuntimeError: If :ref:`trade.ImageData2D.is_compressed` is
:py:`True`
This function is used to implement implicit conversion from
:ref:`trade.ImageData2D` in the :ref:`trade` module.
.. py:function:: magnum.MutableCompressedImageView3D.__init__(self, arg0: magnum.MutableCompressedImageView3D)
:raise RuntimeError: If :ref:`trade.ImageData3D.is_compressed` is
:py:`False`
This function is used to implement implicit conversion from
:ref:`trade.ImageData3D` in the :ref:`trade` module.

3
doc/python/magnum.scenegraph.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a

75
doc/python/magnum.scenetools.rst

@ -0,0 +1,75 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:function:: magnum.scenetools.filter_fields
:raise AssertionError: If size of :p:`fields_to_keep` is different than
:ref:`trade.SceneData.field_count`
.. py:function:: magnum.scenetools.filter_field_entries
:raise AssertionError: If any field in :p:`entries_to_keep` does not exist
in :p:`scene`
:raise AssertionError: If any field in :p:`entries_to_keep` is listed more
than once
:raise AssertionError: If size of any array in :p:`entries_to_keep` does
not match :ref:`trade.SceneData.field_size()` for given field
.. py:function:: magnum.scenetools.filter_objects
:raise AssertionError: If size of :p:`objects_to_keep` is different than
:ref:`trade.SceneData.mapping_bound`
.. py:function:: magnum.scenetools.parents_breadth_first
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`
.. py:function:: magnum.scenetools.children_depth_first
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`
.. py:function:: magnum.scenetools.absolute_field_transformations2d(scene: magnum.trade.SceneData, field: magnum.trade.SceneField, global_transformation: magnum.Matrix3)
:raise KeyError: If :p:`field` does not exist in :p:`scene`
:raise AssertionError: If :p:`scene` is not 2D
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`
.. py:function:: magnum.scenetools.absolute_field_transformations2d(scene: magnum.trade.SceneData, field_id: int, global_transformation: magnum.Matrix3)
:raise IndexError: If :p:`field_id` negative or not less than
:ref:`trade.SceneData.field_count`
:raise AssertionError: If :p:`scene` is not 2D
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`
.. py:function:: magnum.scenetools.absolute_field_transformations3d(scene: magnum.trade.SceneData, field: magnum.trade.SceneField, global_transformation: magnum.Matrix4)
:raise KeyError: If :p:`field` does not exist in :p:`scene`
:raise AssertionError: If :p:`scene` is not 2D
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`
.. py:function:: magnum.scenetools.absolute_field_transformations3d(scene: magnum.trade.SceneData, field_id: int, global_transformation: magnum.Matrix4)
:raise IndexError: If :p:`field_id` negative or not less than
:ref:`trade.SceneData.field_count`
:raise AssertionError: If :p:`scene` is not 2D
:raise AssertionError: If :p:`scene` does not have
:ref:`trade.SceneField.PARENT`

132
doc/python/magnum.shaders.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -23,20 +24,125 @@
DEALINGS IN THE SOFTWARE.
..
.. py:data:: magnum.shaders.VertexColor2D.POSITION
:summary: Two-component vertex position
.. py:class:: magnum.shaders.DistanceFieldVectorGL2D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
.. py:data:: magnum.shaders.VertexColor3D.POSITION
:summary: Three-component vertex position
.. py:class:: magnum.shaders.DistanceFieldVectorGL3D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
.. py:data:: magnum.shaders.VertexColor2D.COLOR3
:summary: Three-component vertex color
.. py:property:: magnum.shaders.DistanceFieldVectorGL2D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:property:: magnum.shaders.DistanceFieldVectorGL3D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:data:: magnum.shaders.VertexColor3D.COLOR3
:summary: Three-component vertex color
.. py:class:: magnum.shaders.FlatGL2D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
:data COLOR3: Three-component vertex color
:data COLOR4: Four-component vertex color
:data TRANSFORMATION_MATRIX: (Instanced) transformation matrix
:data TEXTURE_OFFSET: (Instanced) texture offset
.. py:data:: magnum.shaders.VertexColor2D.COLOR4
:summary: Four-component vertex color
.. py:class:: magnum.shaders.FlatGL3D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
:data COLOR3: Three-component vertex color
:data COLOR4: Four-component vertex color
:data TRANSFORMATION_MATRIX: (Instanced) transformation matrix
:data TEXTURE_OFFSET: (Instanced) texture offset
.. py:data:: magnum.shaders.VertexColor3D.COLOR4
:summary: Four-component vertex color
.. py:property:: magnum.shaders.FlatGL2D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:property:: magnum.shaders.FlatGL3D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:property:: magnum.shaders.FlatGL2D.alpha_mask
:raise AttributeError: If the shader was not created with
:ref:`Flags.ALPHA_MASK`
.. py:property:: magnum.shaders.FlatGL3D.alpha_mask
:raise AttributeError: If the shader was not created with
:ref:`Flags.ALPHA_MASK`
.. py:function:: magnum.shaders.FlatGL2D.bind_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURED`
.. py:function:: magnum.shaders.FlatGL3D.bind_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURED`
.. py:class:: magnum.shaders.VertexColorGL2D
:data POSITION: Vertex position
:data COLOR3: Three-component vertex color
:data COLOR4: Four-component vertex color
.. py:class:: magnum.shaders.VertexColorGL3D
:data POSITION: Vertex position
:data COLOR3: Three-component vertex color
:data COLOR4: Four-component vertex color
.. py:class:: magnum.shaders.PhongGL
:data POSITION: Vertex position
:data NORMAL: Normal direction
:data TANGENT: Tangent direction
:data TANGENT4: Tangent direction with a bitangent sign
:data BITANGENT: Bitangent direction
:data TEXTURE_COORDINATES: 2D texture coordinates
:data COLOR3: Three-component vertex color
:data COLOR4: Four-component vertex color
:data TRANSFORMATION_MATRIX: (Instanced) transformation matrix
:data NORMAL_MATRIX: (Instanced) normal matrix
:data TEXTURE_OFFSET: (Instanced) texture offset
.. py:property:: magnum.shaders.PhongGL.normal_texture_scale
:raise AttributeError: If the shader was not created with
:ref:`Flags.NORMAL_TEXTURE`
.. py:property:: magnum.shaders.PhongGL.alpha_mask
:raise AttributeError: If the shader was not created with
:ref:`Flags.ALPHA_MASK`
.. py:property:: magnum.shaders.PhongGL.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:property:: magnum.shaders.PhongGL.light_positions
:raise ValueError: If list length is different from :ref:`light_count`
.. py:property:: magnum.shaders.PhongGL.light_colors
:raise ValueError: If list length is different from :ref:`light_count`
.. py:property:: magnum.shaders.PhongGL.light_ranges
:raise ValueError: If list length is different from :ref:`light_count`
.. py:function:: magnum.shaders.PhongGL.bind_ambient_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.AMBIENT_TEXTURE`
.. py:function:: magnum.shaders.PhongGL.bind_diffuse_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.DIFFUSE_TEXTURE`
.. py:function:: magnum.shaders.PhongGL.bind_specular_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.SPECULAR_TEXTURE`
.. py:function:: magnum.shaders.PhongGL.bind_normal_texture
:raise AttributeError: If the shader was not created with
:ref:`Flags.NORMAL_TEXTURE`
.. py:function:: magnum.shaders.PhongGL.bind_textures
:raise AttributeError: If the shader was not created with any of
:ref:`Flags.AMBIENT_TEXTURE`, :ref:`Flags.DIFFUSE_TEXTURE`,
:ref:`Flags.SPECULAR_TEXTURE` or :ref:`Flags.NORMAL_TEXTURE`
.. py:class:: magnum.shaders.VectorGL2D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
.. py:class:: magnum.shaders.VectorGL3D
:data POSITION: Vertex position
:data TEXTURE_COORDINATES: 2D texture coordinates
.. py:property:: magnum.shaders.VectorGL2D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`
.. py:property:: magnum.shaders.VectorGL3D.texture_matrix
:raise AttributeError: If the shader was not created with
:ref:`Flags.TEXTURE_TRANSFORMATION`

169
doc/python/magnum.text.rst

@ -0,0 +1,169 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
.. py:class:: magnum.text.FontManager
:summary: Manager for :ref:`AbstractFont` plugin instances
Each plugin returned by :ref:`instantiate()` or :ref:`load_and_instantiate()`
references its owning :ref:`FontManager` through
:ref:`AbstractFont.manager`, ensuring the manager is not deleted before the
plugin instances are.
.. TODO couldn't the plugin_interface etc. docs be parsed from pybind's docs?
repeating them for every plugin is annoying
.. py:class:: magnum.text.AbstractFont
:data plugin_interface: Plugin interface string
:data plugin_search_paths: Plugin search paths
:data plugin_suffix: Plugin suffix
:data plugin_metadata_suffix: Plugin metadata suffix
Similarly to C++, font plugins are loaded through :ref:`FontManager`:
..
>>> from magnum import text
.. code:: py
>>> manager = text.FontManager()
>>> font = manager.load_and_instantiate('StbTrueTypeFont')
Unlike C++, errors in both API usage and file parsing are reported by
raising an exception. See particular function documentation for detailed
behavior.
.. py:function:: magnum.text.AbstractFont.open_data
:raise RuntimeError: If file opening fails
.. py:function:: magnum.text.AbstractFont.open_file
:raise RuntimeError: If file opening fails
For compatibility with :ref:`os.path`, on Windows this function converts
all backslashes in :p:`filename` to forward slashes before passing it to
:dox:`Text::AbstractFont::openFile()`, which expects forward slashes as
directory separators on all platforms.
.. py:property:: magnum.text.AbstractFont.size
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.ascent
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.descent
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.line_height
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.glyph_count
:raise AssertionError: If no file is opened
.. py:function:: magnum.text.AbstractFont.glyph_id
:raise AssertionError: If no file is opened
.. py:function:: magnum.text.AbstractFont.glyph_size
:raise AssertionError: If no file is opened
:raise IndexError: If :p:`glyph` is negative or not less than
:ref:`glyph_count`
.. py:function:: magnum.text.AbstractFont.glyph_advance
:raise AssertionError: If no file is opened
:raise IndexError: If :p:`glyph` is negative or not less than
:ref:`glyph_count`
.. py:function:: magnum.text.AbstractFont.fill_glyph_cache
:raise AssertionError: If no file is opened
.. py:function:: magnum.text.AbstractFont.create_shaper
:raise AssertionError: If no file is opened
.. TODO remove the copies once the base class methods don't leak to subclasses
.. py:property:: magnum.text.RendererCore.cursor
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.Renderer.cursor
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererGL.cursor
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererCore.alignment
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.Renderer.alignment
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererGL.alignment
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererCore.line_advance
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.Renderer.line_advance
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererGL.line_advance
:raise AssertionError: If setting this property while rendering is in
progress
.. py:property:: magnum.text.RendererGL.index_type
:raise AssertionError: If setting this property while rendering is in
progress
.. py:function:: magnum.text.RendererCore.add
:raise AssertionError: If :p:`shaper` font isn't present in
:ref:`glyph_cache`
.. py:function:: magnum.text.Renderer.add
:raise AssertionError: If :p:`shaper` font isn't present in
:ref:`glyph_cache`
.. py:function:: magnum.text.RendererGL.add
:raise AssertionError: If :p:`shaper` font isn't present in
:ref:`glyph_cache`
.. py:function:: magnum.text.RendererGL.render(self, shaper: magnum.text.AbstractShaper, size: float, text: str, features: list[magnum.text.FeatureRange])
:raise AssertionError: If :p:`shaper` font isn't present in
:ref:`glyph_cache`
.. py:enum:: magnum.text.Feature
The equivalent to C++ :dox:`Text::feature()` is passing the four-character
code to the constructor:
..
>>> from magnum import text
.. code:: pycon
>>> feature = text.Feature('kern')
>>> feature.name
'KERNING'
.. py:enum:: magnum.text.Script
The equivalent to C++ :dox:`Text::script()` is passing the four-character
code to the constructor:
..
>>> from magnum import text
.. code:: pycon
>>> script = text.Script('Latn')
>>> script.name
'LATIN'

1479
doc/python/magnum.trade.rst

File diff suppressed because it is too large Load Diff

BIN
doc/python/numpy.inv

Binary file not shown.

120
doc/python/pages/api-conventions.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -26,8 +27,11 @@
Python API conventions
######################
:summary: Basic rules and good practices for both Python binding develpoers and
:summary: Basic rules and good practices for both Python binding developers and
users.
:ref-prefix:
corrade
magnum
`API naming`_
=============
@ -41,16 +45,31 @@ Python API conventions
- constants and enums ``UPPERCASE``, again underscores omitted if it doesn't
hurt readability
`Namespaces`_
-------------
`Preprocessor definitions`_
---------------------------
Exposed to Python as plain boolean constants, and only those that actually are
useful in a Python setting.
.. class:: m-table
=================================== ==================================
C++ Python
=================================== ==================================
:dox:`CORRADE_BUILD_MULTITHREADED` :ref:`corrade.BUILD_MULTITHREADED`
:dox:`MAGNUM_TARGET_GLES` :ref:`magnum.TARGET_GLES`
=================================== ==================================
`Namespaces / modules`_
-----------------------
.. class:: m-table
=================================== ============================
C++ Python
=================================== ============================
:dox:`Magnum::Math` `magnum.math`
:dox:`Magnum::SceneGraph` `magnum.scenegraph`
:dox:`Magnum::Math` :ref:`magnum.math`
:dox:`Magnum::SceneGraph` :ref:`magnum.scenegraph`
=================================== ============================
`Classes`_
@ -61,8 +80,8 @@ C++ Python
=================================== ============================
C++ Python
=================================== ============================
:dox:`Vector2i` `Vector2i`
:dox:`GL::Buffer` `gl.Buffer`
:dox:`Vector2i` :ref:`Vector2i`
:dox:`GL::Buffer` :ref:`gl.Buffer`
=================================== ============================
`Functions`_
@ -73,38 +92,59 @@ C++ Python
=============================================================== ===========
C++ Python
=============================================================== ===========
:dox:`Math::angle()` `math.angle()`
:dox:`Vector2::xAxis() <Math::Vector2::xAxis()>` `Vector2.x_axis()`
:cpp:`v.isZero()` :py:`v.is_zero()`
:cpp:`m.transformVector(a)` :py:`m.transform_vector(a)`
:dox:`Math::angle()` :ref:`math.angle()`
:dox:`Vector2::xAxis() <Math::Vector2::xAxis()>` :ref:`Vector2.x_axis()`
:dox:`v.isZero() <Math::Vector::isZero()>` :ref:`v.is_zero() <Vector3.is_zero()>`
:dox:`m.transformVector(a) <Math::Matrix4::transformVector()>` :ref:`m.transform_vector(a) <Matrix4.transform_vector()>`
=============================================================== ===========
`Enums`_
--------
Custom construction helpers for enums are converted to functions directly on
the Python enum class.
.. class:: m-table
============================================== ============================
C++ Python
============================================== ============================
:dox:`PixelFormat::RGB8Unorm` :ref:`PixelFormat.RGB8_UNORM`
:dox:`MeshPrimitive::TriangleStrip` :ref:`MeshPrimitive.TRIANGLE_STRIP`
:dox:`Trade::meshAttributeCustom()` :ref:`trade.MeshAttribute.CUSTOM() <trade.MeshAttribute>`
:dox:`Trade::isMeshAttributeCustom()` :ref:`trade.MeshAttribute.is_custom <trade.MeshAttribute>`
============================================== ============================
`Enum sets`_
------------
Compared to C++, there's just one enum type with a plural name, and it contains
both the values and binary operators. Additionally, there's an explicit
``NONE`` value for an empty set.
.. class:: m-table
============================================== ============================
C++ Python
============================================== ============================
:dox:`PixelFormat::RGB8Unorm` `PixelFormat.RGB8UNORM`
:dox:`MeshPrimitive::TriangleStrip` :py:`MeshPrimitive.TRIANGLE_STRIP`
:dox:`Trade::DataFlag::Mutable` :ref:`trade.DataFlags.MUTABLE`
:dox:`Trade::DataFlags{} <Trade::DataFlags>` :ref:`trade.DataFlags.NONE`
============================================== ============================
`Constants`_
------------
Apart from :dox:`Math::Constants`, which are exposed directly as members of the
`math` submodule to mimic Python's :py:`math`, most of the constants used
throughout the C++ API are related to templates. Those are, where applicable,
converted to Python builtins such as :py:`len()`.
:ref:`magnum.math` submodule to mimic Python's :ref:`math`, most of the
constants used throughout the C++ API are related to templates. Those are,
where applicable, converted to Python builtins such as :py:`len()`.
.. class:: m-table
============================================== ============================
C++ Python
============================================== ============================
:dox:`Constants::pi() <Math::Constants::pi()>` `math.pi`
:dox:`Constants::pi() <Math::Constants::pi()>` :ref:`math.pi <magnum.math.pi>`
:dox:`Math::Vector::Size` :py:`len(vec)`
============================================== ============================
@ -171,10 +211,52 @@ In particular, both the C++ and the Python API is designed in a way to prevent
too generic or confusing names in the root namespace / module and also keeping
it relatively clean and small, without too many symbols. On the other hand, the
subnamespaces *do* have generic names. The :dox:`GL::version()` /
`gl.version()` API is one example --- it's tucked in a subnamespace so the
:ref:`gl.version()` API is one example --- it's tucked in a subnamespace so the
generic name isn't a problem, but you wouldn't find anything of similar
genericity in the root namespace / module.
An exception to this rule is exposed preprocessor definitions --- these are
*not* pulled in when doing :py:`from magnum import *` as this would likely
cause conflicts (in particular, :ref:`BUILD_STATIC` is defined by Corrade as
well). Instead, you have to access them like this:
.. code:: py
import magnum
if magnum.TARGET_GLES2:
format = gl.TextureFormat.RGBA8
else:
format = gl.TextureFormat.R8
`Handling of alternate implementations`_
----------------------------------------
C++ APIs that have alternative implementations (such as
:dox:`Platform::Sdl2Application` vs. :dox:`Platform::GlfwApplication`, or
:dox:`SceneGraph::MatrixTransformation3D` vs.
:dox:`SceneGraph::TranslationRotationScalingTransformation3D`) either provide
:cpp:`typedef`\ s based on what header you include or require you to
:cpp:`typedef` them yourselves:
.. code:: c++
class MyApplication: Platform::Application {}; // depends on what you include
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
In Python, the alternate implementations are tucked in submodules (such as
:ref:`platform.sdl2` vs. :ref:`platform.glfw`, or :ref:`scenegraph.matrix` vs.
:ref:`scenegraph.trs`), each submodule providing the same names (such as
:ref:`Application <platform.sdl2.Application>` or
:ref:`Object3D <scenegraph.matrix.Object3D>`)
and the designed way to use them is via :py:`from ... import`:
.. code:: py
from magnum.platform.sdl2 import Application
from magnum.scenegraph.trs import Scene3D, Object3D
`Basic guarantees`_
===================

95
doc/python/pages/building.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -28,8 +29,13 @@ Downloading and building
.. role:: sh(code)
:language: sh
.. role:: bat(code)
:language: bat
:summary: Installation guide for the Python bindings.
:ref-prefix:
corrade
magnum
Building of Python bindings is a similar process to
:dox:`building Magnum itself <building>` with an additional step involving
@ -55,7 +61,7 @@ the source tree.
.. code:: sh
git clone git://github.com/mosra/magnum-bindings && cd magnum-bindings
git clone https://github.com/mosra/magnum-bindings && cd magnum-bindings
cd package/archlinux
makepkg -fp PKGBUILD
@ -67,16 +73,22 @@ Once built, install the package using ``pacman``:
.. code:: sh
sudo pacman -U magnum-bindings-*.pkg.tar.xz
sudo pacman -U magnum-bindings-*.pkg.tar.zst
`Homebrew formulas for macOS`_
------------------------------
macOS `Homebrew <https://brew.sh>`_ formulas building the latest Git revision
are in the `package/homebrew` directory. Either use the `*.rb` files directly
or use the tap at https://github.com/mosra/homebrew-magnum. Right now, there's
no stable release of Python bindings yet, so you need to install the latest Git
revision of all Magnum projects instead:
are in the ``package/homebrew`` directory. Either use the ``*.rb`` files
directly or use the tap at https://github.com/mosra/homebrew-magnum. This will
install the latest stable version of Magnum Bindings with all its dependencies:
.. code:: sh
brew install mosra/magnum/magnum-bindings
But often you may want to install the latest Git revision of all Magnum
projects instead:
.. code:: sh
@ -84,14 +96,19 @@ revision of all Magnum projects instead:
brew install --HEAD mosra/magnum/magnum
brew install --HEAD mosra/magnum/magnum-bindings
When installing from the `*.rb` files you need to install the
# If already installed, use the following to upgrade, in the same order
brew upgrade --fetch-HEAD mosra/magnum/corrade
brew upgrade --fetch-HEAD mosra/magnum/magnum
brew upgrade --fetch-HEAD mosra/magnum/magnum-bindings
When installing from the ``*.rb`` files you need to install the
:dox:`Corrade <building-corrade-packages-brew>` and
:dox:`Magnum <building-packages-brew>` Homebrew packages first. If you want to
pass additional flags to CMake or ``setup.py`` or enable / disable additional
features, edit the ``*.rb`` file.
There are also Homebrew packages for
:dox:`Magnum Plugins <building-plugins-packages-brew>`
:dox:`Magnum Plugins <building-plugins-packages-brew>`,
:dox:`Magnum Integration <building-integration-packages-brew>`,
:dox:`Magnum Extras <building-extras-packages-brew>` and
:dox:`Magnum Examples <building-examples-packages-brew>`.
@ -105,7 +122,7 @@ snapshot as a compressed archive or use the command line:
.. code:: sh
git clone git://github.com/mosra/magnum-bindings.git
git clone https://github.com/mosra/magnum-bindings.git
Assuming a Unix-based OS, the first step is to build the native libraries. The
bindings will be generated for all Corrade and Magnum libraries that are found,
@ -116,7 +133,7 @@ default location known to CMake, add their path to ``CMAKE_PREFIX_PATH``.
mkdir build && cd build
cmake .. \
-DWITH_PYTHON=ON
-DMAGNUM_WITH_PYTHON=ON
make
Note that pybind11 compilation is quite time- and memory-hungry, so you might
@ -138,6 +155,39 @@ In case Corrade or Magnum is built with :dox:`CORRADE_BUILD_STATIC` /
:dox:`MAGNUM_BUILD_STATIC`, the corresponding bindings are compiled into a
single dynamic module instead of one module per Corrade/Magnum library.
In this case, similarly to linking static plugins to Magnum's own command-line
utilities, you can use the ``MAGNUM_PYTHON_BINDINGS_STATIC_PLUGINS`` CMake
variable to link static plugins to the Python module, assuming Magnum, Magnum
Plugins and Magnum Bindings are all CMake subprojects. It's a
semicolon-separated list of existing CMake targets, for example
``Magnum::AnyImageImporter;MagnumPlugins::StbImageImporter``.
On Unix platforms, Python by default loads the modules in isolated namespaces.
That's a good thing to do from a security point of view, nevertheless with
static builds of Corrade and Magnum it will result in globals duplicated across
the Corrade and Magnum modules (and also any other Python modules that
use Magnum natively inside) unable to see each other in order to deduplicate
themselves, causing strange issues. To solve that, the
``MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL`` CMake option, which is enabled by
default on static builds on Unix platforms, overrides Python's module loading
code to not load them in isolated namespaces using :ref:`sys.setdlopenflags()`.
The override then happens inside :py:`import corrade` and is in effect for the
rest of the interpreter lifetime, to affect also any potential other modules
depending on Magnum loaded later. See also
:dox:`CORRADE_BUILD_STATIC_UNIQUE_GLOBALS` and
:dox:`MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS` in Corrade and Magnum for more
information.
On Windows, Python since version 3.8 no longer loads dependency DLLs from
:bat:`%PATH%`. Instead, it requires relevant DLL directories to be explicitly
passed to :ref:`os.add_dll_directory()`. CMake by default adds the (absolute)
path to Corrade and Magnum DLLs there, you can edit the path or add additional
directories for other dependencies (such as SDL or GLFW) using the
``MAGNUM_PYTHON_BINDINGS_DLL_PATH`` CMake option. Non-absolute paths are
interpreted as relative to the package root --- for example, if the Corrade
module is in ``tools/python/corrade/``, specifying ``bin/`` as the DLL path
will resolve to ``tools/bin/``.
`Running unit tests`_
---------------------
@ -151,16 +201,17 @@ running them is then a matter of:
cd src/python/magnum
python -m unittest
.. block-warning:: Subject to change
.. block-default:: Disabling GL tests
If the tests detect that one of `platform.WindowlessApplication`\ s is
present, GL tests (suffixed with ``_gl``) will be run as well. Currently
there's no way to blacklist them if windowless application implementations
are compiled, you can only whitelist-run the remaining tests:
If the tests detect that one of
:ref:`platform.WindowlessApplication <platform.egl.WindowlessApplication>`\ s
is present, GL tests (suffixed with ``_gl``) will be run as well. In order
to disable them (for example when running on a headless CI), set the
:sh:`$MAGNUM_SKIP_GL_TESTS` environment variable to ``ON``:
.. code:: sh
python -m unittest test.test_gl test.test_math # test.test_gl_gl is a GL test
MAGNUM_SKIP_GL_TESTS=ON python -m unittest
For code coverage, `coverage.py <https://coverage.readthedocs.io/>`_ is used.
Get it via ``pip`` or as a system package.
@ -182,8 +233,10 @@ following commands, the resulting HTML overview is located in
`Continuous Integration`_
=========================
In ``package/ci/`` there is a ``travis.yml`` file that compiles and tests the
bindings on Linux GCC 4.8 + CMake 3.1 and on macOS. Online at
https://travis-ci.org/mosra/magnum-bindings. Code coverage for both the C++
bindings code and Python side is reported to
In ``package/ci/`` there is a ``circleci.yml`` file that compiles and tests the
bindings on Linux GCC 4.8 + CMake 3.5 and on macOS, online at
https://circleci.com/gh/mosra/magnum-bindings. For Windows there is an
``appveyor.yml`` testing on Windows with MSVC, online at
https://ci.appveyor.com/project/mosra/magnum-bindings. Code coverage for both
the C++ bindings code and Python side is reported to
https://codecov.io/gh/mosra/magnum-bindings.

238
doc/python/pages/changelog.rst

@ -0,0 +1,238 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
Changelog
#########
:ref-prefix:
corrade
magnum
:some_directive: TODO: why can't the title below "just work" and I have to
add some bogus content before?
`Changes since 2020.06`_
========================
- Minimal supported CMake version is now 3.5, changed from 3.4, since CMake
3.27+ warns if a compatibility with CMake below 3.5 is requested. Older
versions are not supported anymore and all workarounds for them were
removed. This is a conservative change, as there are no known supported
distributions which would have anything older than 3.5.
- Exposed the :ref:`corrade.BUILD_DEPRECATED` and
:ref:`magnum.BUILD_DEPRECATED` constants, as some features may work
differently depending on these being enabled or not and it's useful to be
able to query this
- Exposed the new :ref:`containers.BitArray`, :ref:`containers.BitArrayView`,
:ref:`containers.StridedBitArrayView1D` containers, their mutable and
multi-dimensional counterparts as well as the
:ref:`containers.StridedArrayView*D.slice_bit() <containers.StridedArrayView1D.slice_bit()>`
utility
- Exposed missing :ref:`Vector4` constructor from a :ref:`Vector3` and a
W component and :ref:`Vector3` from :ref:`Vector2` and a Z component
- Renamed :py:`Matrix3.from()` / :py:`Matrix4.from()` to :ref:`Matrix3.from_()`
/ :ref:`Matrix4.from_()` because :py:`from` is a Python keyword and it
would be silly to have to write :py:`getattr(Matrix4, 'from')` just to use
these APIs
- Exposed newly added off-center variants of
:ref:`Matrix4.orthographic_projection()` and
:ref:`Matrix3.projection()`
- Exposed remaining vector/scalar, exponential and other functions in the
:ref:`math <magnum.math>` library
- Exposed the :ref:`CompressedPixelFormat` enum, various pixel-format-related
helper APIs are now properties on :ref:`PixelFormat` and
:ref:`CompressedPixelFormat`
- Exposed :ref:`CompressedImage2D`, :ref:`CompressedImageView2D`,
:ref:`MutableCompressedImageView2D` and their 1D and 3D counterparts
- Exposed :ref:`Color3.from_xyz()`, :ref:`Color3.from_linear_rgb_int()`,
:ref:`Color3.to_xyz()`, :ref:`Color3.to_linear_rgb_int()` and equivalent
APIs on :ref:`Color4`
- Exposed unsigned :ref:`Range1Dui`, :ref:`Range2Dui` and :ref:`Range3Dui`
types in addition to the signed variants
- Exposed new :ref:`Quaternion.rotation()`, :ref:`Quaternion.reflection()`,
:ref:`Quaternion.reflect_vector()`, :ref:`Quaternion.xyzw` and
:ref:`Quaternion.wxyz` APIs
- Exposed :ref:`gl.Context` and its platform-specific subclasses for EGL, WGL
and GLX
- Exposed :ref:`gl.Framebuffer.attach_texture()` and missing sRGB, depth
and stencil :ref:`gl.TextureFormat` values (see :gh:`mosra/magnum-bindings#14`)
- Exposed :ref:`gl.Renderer.set_blend_function()`,
:ref:`gl.Renderer.set_blend_equation()` and related enums (see :gh:`mosra/magnum-bindings#9`)
- Exposed :ref:`gl.Renderer.Feature.CLIP_DISTANCEn <gl.Renderer.Feature.CLIP_DISTANCE0>`
values that are new since 2020.06
- Exposed new instancing, texture transformation, normal-mapping-related and
lighting features in :ref:`shaders.PhongGL`
- Exposed new instancing and texture transformation features in
:ref:`shaders.FlatGL2D` and :ref:`shaders.FlatGL3D`
- Exposed :ref:`shaders.DistanceFieldVectorGL2D`,
:ref:`shaders.DistanceFieldVectorGL3D`, :ref:`shaders.VectorGL2D` and
:ref:`shaders.VectorGL3D` shaders
- Renamed all helper ``Python.h`` headers to ``PythonBindings.h`` to avoid
issues with shitty IDE indexers such as Eclipse, confusing these with
Python's ``<Python.h>``
- Minor performance fixes (see :gh:`mosra/magnum-bindings#10`,
:gh:`mosra/magnum-bindings#15`,
:gh:`mosra/magnum-bindings#16`,
:gh:`mosra/magnum-bindings#17`,
:gh:`mosra/magnum-bindings#19`,
:gh:`mosra/magnum-bindings#20`)
Travis banned everyone from using their CI and so all Linux and macOS
builds were migrated from Travis to Circle CI. See also
:gh:`mosra/magnum#350` and :gh:`mosra/magnum#523`.
- It's now possible to use ``<PackageName>_ROOT`` to point to install
locations of dependencies such as Corrade on CMake 3.12+, in addition to
putting them all together inside ``CMAKE_PREFIX_PATH``. See also
:gh:`mosra/magnum#614`.
- On CMake 3.16 and newer, ``FindMagnumBindings.cmake`` can provide
additional details if some component is not found
- The Homebrew package now uses ``std_cmake_args`` instead of hardcoded build
type and install prefix, which resolves certain build issues (see
:gh:`mosra/homebrew-magnum#6`)
- Added a caster for :dox:`Containers::Optional`, allowing it to be used
directly in function signatures and showing up on the Python side as either
:py:`None` or the actual value
- Various documentation fixes (see :gh:`mosra/magnum-bindings#11`)
- Fixed copypaste errors in bindings for :ref:`Range2D.center_x()` /
:ref:`Range2D.center_y()`, :ref:`Range3D.z()`, :ref:`Range3D.center_x()` /
:ref:`Range3D.center_y()` / :ref:`Range3D.center_z()`
- Fixed a copypaste error in
:ref:`platform.sdl2.Application.PointerMoveEvent.relative_position` and
:ref:`platform.glfw.Application.PointerMoveEvent.relative_position`
- Fixed :ref:`platform.sdl2.Application.Modifier` and
:ref:`platform.glfw.Application.Modifier` to behave properly
as flags and not just as an enum
- Exposed :ref:`meshtools.compress_indices()`, :ref:`meshtools.concatenate()`,
:ref:`meshtools.copy()`, :ref:`meshtools.duplicate()`,
:ref:`meshtools.filter_attributes()`,
:ref:`meshtools.filter_except_attributes()`,
:ref:`meshtools.filter_only_attributes()`,
:ref:`meshtools.generate_indices()`, :ref:`meshtools.interleave()`,
:ref:`meshtools.remove_duplicates()`,
:ref:`meshtools.remove_duplicates_fuzzy()`, :ref:`meshtools.transform2d()`,
:ref:`meshtools.transform2d_in_place()`, :ref:`meshtools.transform3d()`,
:ref:`meshtools.transform3d_in_place()`,
:ref:`meshtools.transform_texture_coordinates2d()` and
:ref:`meshtools.transform_texture_coordinates2d_in_place()`
- Exposed :ref:`platform.sdl2.Application.viewport_event` and
:ref:`platform.glfw.Application.viewport_event` and a possibility
to make the window resizable on startup
- Exposed :ref:`platform.sdl2.Application.exit_event` and
:ref:`platform.glfw.Application.exit_event`
- Exposed :ref:`platform.sdl2.Application.dpi_scaling` and
:ref:`platform.glfw.Application.dpi_scaling`
- Exposed :ref:`platform.glfw.Application.swap_interval` and
:ref:`platform.glfw.Application.main_loop_iteration`
- Exposed :ref:`platform.sdl2.Application.cursor` and
:ref:`platform.sdl2.Application.warp_cursor`, same for GLFW
- Exposed :ref:`platform.sdl2.Application.is_key_pressed()` and
:ref:`platform.glfw.Application.is_key_pressed()`
- Exposed all :ref:`platform.sdl2.Application.Configuration.WindowFlags` and
:ref:`platform.glfw.Application.Configuration.WindowFlags`
- Exposed the new :ref:`primitives.CubeFlags`
- Exposed the new :ref:`text.AbstractShaper`, :ref:`text.RendererCore`,
:ref:`text.Renderer`, :ref:`text.RendererGL` classes as well as the new
:ref:`text.Feature`, :ref:`text.Script` enums and the
:ref:`text.FeatureRange` helper, plus more :ref:`text.Alignment` options
- Exposed :ref:`trade.AbstractImporter.features` and
:ref:`trade.AbstractImporter.flags` and corresponding enums
- Exposed a basic interface of :ref:`trade.AbstractImageConverter` and
:ref:`trade.AbstractSceneConverter`
- Exposed the whole interface of :ref:`trade.MeshData` and
:ref:`trade.MeshAttributeData` including typed access to index and
attribute data, together with :ref:`VertexFormat`, :ref:`trade.DataFlags`,
:ref:`trade.AbstractImporter.mesh_attribute_name()` and
:ref:`trade.AbstractImporter.mesh_attribute_for_name()`
- Exposed the whole interface of :ref:`trade.MaterialData` including typed
access to attribute data, together with
:ref:`trade.AbstractImporter.material()` and related importer APIs
- Exposed the whole interface of :ref:`trade.SceneData` and
:ref:`trade.SceneFieldData` including typed access to mapping and field
data, together with :ref:`trade.AbstractImporter.scene()` and related
importer APIs
- Exposed :ref:`Color3.red()` and other convenience constructors (see
:gh:`mosra/magnum-bindings#12`)
- Exposed the :ref:`materialtools`, :ref:`scenetools` and :ref:`text`
libraries
- Exposed :ref:`utility.copy()` for convenient, fast and safe copying of
multi-dimensional strided arrays
- Exposed the minimal interface of :ref:`utility.ConfigurationGroup` and
:ref:`utility.Configuration`
- Exposed :ref:`pluginmanager.AbstractManager.set_preferred_plugins()`,
:ref:`pluginmanager.AbstractManager.register_external_manager()`, the base
:ref:`pluginmanager.AbstractPlugin` class and
:ref:`pluginmanager.PluginMetadata`
- Fixed issues with an in-source build (see :gh:`mosra/magnum-bindings#13`)
- All CMake build options are now prefixed with ``MAGNUM_``. For backwards
compatibility, unless ``MAGNUM_BUILD_DEPRECATED`` is disabled and unless a
prefixed option is already set during the initial run, the unprefixed
options are still recognized with a warning. See also :gh:`mosra/corrade#139`.
- Added a ``MAGNUM_PYTHON_BINDINGS_STATIC_PLUGINS`` CMake option for linking
static plugins to the Python bindings module. See the
:ref:`building documentation <std:doc:building>` for more information.
- Added a ``MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL`` CMake option to make
the Python bindings module loaded into the global namespace instead of
isolated in order to attempt to solve problems with duplicated globals when
static builds of Corrade and Magnum are linked into multiple dynamic
modules. See the :ref:`building documentation <std:doc:building>` for more
information.
`2020.06`_
==========
Released 2020-06-27, tagged as
:gh:`v2020.06 <mosra/magnum-bindings/releases/tag/v2020.06>`.
- Exposed :ref:`Matrix4.cofactor()`, :ref:`Matrix4.comatrix()`,
:ref:`Matrix4.adjugate()` (and equivalents in other matrix sizes), and
:ref:`Matrix4.normal_matrix()`
- Exposed :ref:`gl.AbstractFramebuffer.blit()` functions and related enums
- Exposed more keys in :ref:`platform.sdl2.Application` and
:ref:`platform.glfw.Application`
- Exposed :ref:`gl.AbstractTexture.unbind()`
- Exposed :ref:`trade.AbstractImporter.image2d_level_count()` and related
APIs for 1D and 3D
- Exposed :ref:`trade.MeshData` and related APIs, the previous
``trade.MeshData3D`` APIs are removed
- Exposed new APIs and tangent support in the :ref:`primitives` library
- :ref:`platform.sdl2.Application` and :ref:`platform.glfw.Application` now
provide a clear error instead of "pure virtual method call" in case
``draw_event()`` is not implemented
- Library version is now exposed through ``MAGNUMBINDINGS_VERSION_YEAR``,
``MAGNUMBINDINGS_VERSION_MONTH``, ``MAGNUMBINDINGS_VERSION_COMMIT``,
``MAGNUMBINDINGS_VERSION_HASH`` and ``MAGNUMBINDINGS_VERSION_STRING``
preprocessor defines in a new ``Magnum/versionBindings.h`` header. This
header is not included by any other header to avoid trigerring a full
rebuild when Git commit changes. If Git is not found, only the first two
defines are present.
`2019.10`_
==========
Released 2019-10-24, tagged as
:gh:`v2019.10 <mosra/magnum-bindings/releases/tag/v2019.10>`.
Initial version. See :gh:`mosra/magnum#228`, :gh:`mosra/magnum-bindings#1`,
:gh:`mosra/magnum-bindings#2` and :gh:`mosra/magnum-bindings#6` for more
information.

81
doc/python/pages/credits.rst

@ -0,0 +1,81 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
Credits
#######
:ref-prefix:
corrade
magnum
:summary: Third-party dependencies and their corresponding license information;
people and organizations that contributed to Magnum Python Bindings.
`Third-party components`_
=========================
.. TODO: ffs doxygen SORT YOUR SHIT OUT, why can't I link to
credits-third-party?!
.. role:: doxygen-you-fool(link)
:class: m-doc-external
While Magnum Python Bindings themselves don't depend on much, a lot of
third-party components is used transitively from the Magnum C++ implementation.
Please see the :ref:`main page <std:doc:index#license>` for license of Magnum
Python Bindings themselves and the
:doxygen-you-fool:`Third-party components <https://doc.magnum.graphics/magnum/credits-third-party.html>`
page of C++ docs for a detailed overview of all used components. The list below
uses the same color-coding scheme for easier overview:
:ref:`Magnum Python Bindings <std:doc:index>`
Bindings generated with :gh:`pybind11 <pybind/pybind11>`, released under a
:label-success:`BSD-style license`
(`license text <https://github.com/pybind/pybind11/blob/master/LICENSE>`_,
`choosealicense.com <https://choosealicense.com/licenses/bsd-3-clause/>`_).
It requires attribution for public use.
`Contributors`_
===============
Listing only people with code contributions or other significant work, because
otherwise there's too many :) There's also a
:dox:`similar list for Corrade <corrade-credits-contributors>` and
:dox:`Magnum <credits-contributors>` themselves. Big thanks to everyone
involved!
.. class:: m-text-center m-text m-dim
Are the below lists missing your name or something's wrong?
`Let us know! <https://magnum.graphics/contact/>`_
- **Aaron Gokaslan** (:gh:`Skylion007`) --- minor performance and
documentation fixes, expanding :ref:`Color3` / :ref:`Color4` bindings
- **Cameron Egbert** (:gh:`cegbertOculus`) --- initial Windows port
- **James Murphy** (:gh:`mCodingLLC`) --- buildsystem fixes, expanding
:ref:`gl.Framebuffer` bindings
- **John Laxson** (:gh:`jlaxson`) --- Homebrew package improvements
- **Stanislaw Halik** (:gh:`sthalik`) --- build fixes
- **Vladimir Gamalyan** (:gh:`vladimirgamalyan`) --- expanding
:ref:`gl.Renderer` bindings

80
doc/python/pages/developers.rst

@ -0,0 +1,80 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
..
Developers Guide
################
:ref-prefix:
corrade
magnum
:summary: Checklists for developing new things in Magnum Python bindings
themselves.
.. role:: cmake(code)
:language: cmake
.. role:: cpp(code)
:language: c++
.. role:: py(code)
:language: py
`Checklist for adding / removing bindings for a library`_
=========================================================
1. Add a corresponding ``Foo`` Magnum dependency to the :cmake:`find_package()`
call in ``src/python/magnum/CMakeLists.txt``, create a ``magnum_foo_SRCS``
variable with its source file(s).
2. Add a :cmake:`if(Magnum_Foo_FOUND)` branch to the
:cmake:`if(NOT MAGNUM_BUILD_STATIC)` condition, adding a new ``magnum_foo``
module from ``magnum_foo_SRCS``, linking to ``Magnum::Foo`` and setting
``OUTPUT_NAME`` to ``foo``.
3. Add a :cmake:`if(Magnum_Foo_FOUND)` branch to the :cmake:`else()`
condition, ``APPEND``\ ing ``magnum_foo_SRCS`` to ``magnum_SRCS`` and
``Magnum::Foo`` to ``magnum_LIBS``.
4. Add :cpp:`void foo(py::module_& m);` forward declaration to
``magnum/bootstrap.h``, and :cpp:`#cmakdefeine Magnum_Foo_FOUND` to
``magnum/staticconfigure.h.cmake``.
5. Implement ``void foo(py::module_& m)`` in ``src/python/magnum/foo.cpp``,
add a :cpp:`PYBIND11_MODULE()` calling it.
6. Add :cpp:`m.def_submodule("foo");` and a call to :cpp:`magnum:foo()`
wrapped in :cpp:`#ifdef Magnum_Foo_FOUND` to the
:cpp:`#ifdef MAGNUM_BUILD_STATIC` section of :cpp:`PYBIND11_MODULE()` in
``magnum/magnum.cpp``.
7. Add the new module name to the list in ``magnum/__init__.py``.
8. Add a line with ``magnum_foo`` to the :cmake:`foreach()` in
``src/python/CMakeLists.txt``, and then a corresponding :py:`'magnum.foo'`
entry in ``src/python/setup.py.cmake``
9. Add a ``magnum/test/test_foo.py`` test file, and potentially also
``magnum/test/test_foo_gl.py`` where is
:py:`from . import GLTestCase, setUpModule` to skip the test if GL context
doesn't exist, and the test cases derive from :py:`GLTestCase` instead of
:py:`unittest.TestCase`.
10. Add the new module into the :py:`magnum.__all__` list in
``doc/python/conf.py``.
11. Add a ``doc/python/magnum.foo.rst`` documentation file for more detailed
docs, if needed, and reference it from ``INPUT_DOCS``.
12. Add a ``doc/python/pages/changelog.rst`` entry.
For Corrade bindings it's similar.

21
doc/python/pages/index.rst

@ -1,7 +1,8 @@
..
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -42,11 +43,11 @@ the C++ docs --- highlighting important differences and describing general
conventions, but referring to documentation of underlying C++ APIs for all
details.
See the :link-ref:`building docs <building.html>` for an installation guide,
:link-ref:`API convention documentation <api-conventions.html>` and
:link-ref:`documentation of each module <modules.html>` for more information
about the actual usage. There are also :link-ref:`examples <examples.html>` to
give you an idea about how the API feels.
See the :ref:`building docs <std:doc:building>` for an installation guide,
:ref:`API convention documentation <std:doc:api-conventions>` and
:ref:`documentation of each module <std:special:modules>` for more information about
the actual usage. There are also :ref:`examples <std:doc:examples>` to give you
an idea about how the API feels.
`Contact & support`_
====================
@ -64,8 +65,7 @@ right away!
- E-mail --- info@magnum.graphics
- Google Groups mailing list --- magnum-engine@googlegroups.com
(`archive <https://groups.google.com/forum/#!forum/magnum-engine>`_)
- Twitter --- https://twitter.com/czmosra and the
`#MagnumEngine <https://twitter.com/hashtag/MagnumEngine>`_ hashtag
- Bluesky --- https://bsky.app/profile/mosra.cz
See also the `Contact & Support page <https://magnum.graphics/contact/>`_ on
the project website for further information.
@ -75,8 +75,9 @@ the project website for further information.
Magnum, including the Python bindings, is licensed under the MIT/Expat license:
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Vladimír Vondruš <mosra@centrum.cz> and contributors
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026 Vladimír Vondruš
<mosra@centrum.cz> and contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

BIN
doc/python/python.inv

Binary file not shown.

16
modules/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -27,4 +28,17 @@ set(MagnumBindings_MODULES
FindMagnumBindings.cmake
MagnumBindingsConfig.cmake)
# IMPORTANT: When adding a new module here, be sure to update the
# find_path(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR ...) list in
# FindMagnumBindings.cmake to avoid breakages when the directory contains only
# that new module.
set(MagnumBindings_DEPENDENCY_MODULES )
# No dependency Find modules so far
install(FILES ${MagnumBindings_MODULES} DESTINATION ${MAGNUMBINDINGS_CMAKE_MODULE_INSTALL_DIR})
if(MagnumBindings_DEPENDENCY_MODULES)
install(FILES ${MagnumBindings_DEPENDENCY_MODULES} DESTINATION ${MAGNUMBINDINGS_CMAKE_MODULE_INSTALL_DIR}/dependencies)
endif()
# Magnum Bindings dependency module dir for superprojects
set(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")

506
modules/FindCorrade.cmake

@ -11,14 +11,13 @@
#
# Corrade_FOUND - Whether the base library was found
# CORRADE_LIB_SUFFIX_MODULE - Path to CorradeLibSuffix.cmake module
# CORRADE_INCLUDE_INSTALL_PREFIX - Prefix where to put platform-independent
# include and other files, defaults to ``.``. If a relative path is used,
# it's relative to :variable:`CMAKE_INSTALL_PREFIX`.
#
# This command will try to find only the base library, not the optional
# components, which are:
#
# Containers - Containers library
# Interconnect - Interconnect library
# Main - Main library
# PluginManager - PluginManager library
# TestSuite - TestSuite library
# Utility - Utility library
@ -65,19 +64,25 @@
#
# Features of found Corrade library are exposed in these variables:
#
# CORRADE_MSVC2019_COMPATIBILITY - Defined if compiled with compatibility
# mode for MSVC 2019
# CORRADE_MSVC_COMPATIBILITY - Defined if compiled with compatibility
# mode for MSVC 2019+ without the /permissive- flag set
# CORRADE_MSVC2017_COMPATIBILITY - Defined if compiled with compatibility
# mode for MSVC 2017
# CORRADE_MSVC2015_COMPATIBILITY - Defined if compiled with compatibility
# mode for MSVC 2015
# CORRADE_BUILD_DEPRECATED - Defined if compiled with deprecated APIs
# CORRADE_BUILD_DEPRECATED - Defined if compiled with deprecated features
# included
# CORRADE_BUILD_STATIC - Defined if compiled as static libraries.
# Default are shared libraries.
# CORRADE_BUILD_STATIC_UNIQUE_GLOBALS - Defined if static libraries keep their
# globals unique even across different shared libraries. Enabled by default
# for static builds.
# CORRADE_BUILD_MULTITHREADED - Defined if compiled in a way that makes it
# possible to safely use certain Corrade features simultaenously in multiple
# possible to safely use certain Corrade features simultaneously in multiple
# threads
# CORRADE_BUILD_CPU_RUNTIME_DISPATCH - Defined if built with code paths
# optimized for multiple architectres with the best matching variant selected
# at runtime based on detected CPU features
# CORRADE_TARGET_UNIX - Defined if compiled for some Unix flavor
# (Linux, BSD, macOS)
# CORRADE_TARGET_APPLE - Defined if compiled for Apple platforms
@ -88,9 +93,21 @@
# CORRADE_TARGET_WINDOWS_RT - Defined if compiled for Windows RT
# CORRADE_TARGET_EMSCRIPTEN - Defined if compiled for Emscripten
# CORRADE_TARGET_ANDROID - Defined if compiled for Android
# CORRADE_TARGET_GCC - Defined if compiling with GCC or GCC-
# compatible Clang
# CORRADE_TARGET_CLANG - Defined if compiling with Clang or any of its
# variants
# CORRADE_TARGET_APPLE_CLANG - Defined if compiling with Apple's Clang
# CORRADE_TARGET_CLANG_CL - Defined if compiling with Clang-CL (Clang
# with a MSVC frontend)
# CORRADE_TARGET_MSVC - Defined if compiling with MSVC or Clang with
# a MSVC frontend
# CORRADE_TARGET_MINGW - Defined if compiling under MinGW
# CORRADE_CPU_USE_IFUNC - Defined if GNU IFUNC is allowed to be used
# for runtime dispatch in the Cpu library
# CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT - Defined if PluginManager
# doesn't support dynamic plugin loading due to platform limitations
# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targetting Xcode
# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targeting Xcode
# XCTest
# CORRADE_UTILITY_USE_ANSI_COLORS - Defined if ANSI escape sequences are used
# for colored output with Utility::Debug on Windows
@ -101,24 +118,25 @@
# CORRADE_*_LIBRARY_DEBUG - Debug version of given library, if found
# CORRADE_*_LIBRARY_RELEASE - Release version of given library, if found
# CORRADE_*_EXECUTABLE - Location of given executable, if found
# CORRADE_*_EXECUTABLE_EMULATOR - Emulator to run CORRADE_*_EXECUTABLE, if a
# non-native version was found when cross-compiling
# CORRADE_USE_MODULE - Path to UseCorrade.cmake module (included
# automatically)
# CORRADE_DEPENDENCY_MODULE_DIR - Path to Find modules for dependencies used
# internally by Corrade. Defined only if any such modules are expected to
# exist on given platform.
# CORRADE_TESTSUITE_XCTEST_RUNNER - Path to XCTestRunner.mm.in file
# CORRADE_TESTSUITE_ADB_RUNNER - Path to AdbRunner.sh file
# CORRADE_UTILITY_JS - Path to CorradeUtility.js file
# CORRADE_PEDANTIC_COMPILER_OPTIONS - List of pedantic compiler options used
# for targets with :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS` enabled
# CORRADE_PEDANTIC_COMPILER_DEFINITIONS - List of pedantic compiler
# definitions used for targets with :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS`
# enabled
#
# Workflows without :prop_tgt:`IMPORTED` targets are deprecated and the
# following variables are included just for backwards compatibility and only if
# :variable:`CORRADE_BUILD_DEPRECATED` is enabled:
#
# CORRADE_CXX_FLAGS - Pedantic compile flags. Use
# :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS` property or
# :variable:`CORRADE_PEDANTIC_COMPILER_DEFINITIONS` /
# :variable:`CORRADE_PEDANTIC_COMPILER_OPTIONS` list variables instead.
# CORRADE_CXX{11,14,17,20}_STANDARD_FLAG - Compiler flag to use for targeting
# C++11, 14, 17 or 20 in cases where it's not possible to use
# :prop_tgt:`CORRADE_CXX_STANDARD`. Not defined if a standard switch is
# already present in :variable:`CMAKE_CXX_FLAGS`.
#
# Corrade provides these macros and functions:
#
@ -183,13 +201,19 @@
# <metadata file>
# <sources>...)
#
# The macro adds preprocessor directive ``CORRADE_DYNAMIC_PLUGIN``. Additional
# libraries can be linked in via :command:`target_link_libraries(plugin_name ...) <target_link_libraries>`.
# The macro adds a preprocessor directive ``CORRADE_DYNAMIC_PLUGIN`` when
# compiling ``<sources>``. Additional libraries can be linked in via
# :command:`target_link_libraries(plugin_name ...) <target_link_libraries>`.
# On DLL platforms, the plugin DLLs and metadata files are put into
# ``<debug binary install dir>`` / ``<release binary install dir>`` and the
# ``*.lib`` files into ``<debug library install dir>``/``<release library install dir>``.
# On non-DLL platforms everything is put into ``<debug library install dir>``/
# ``<release library install dir>``.
# ``*.lib`` files into ``<debug library install dir>`` /
# ``<release library install dir>``. On non-DLL platforms everything is put
# into ``<debug library install dir>`` / ``<release library install dir>``.
#
# If the plugin interface disables plugin metadata files, the
# ``<metadata file>`` can be set to ``""``, in which case no metadata file is
# copied anywhere. Otherwise the metadata file is copied and renamed to
# ``<plugin name>``, retaining its original extension.
#
# corrade_add_plugin(<plugin name>
# <debug install dir>
@ -197,7 +221,7 @@
# <metadata file>
# <sources>...)
#
# Unline the above version this puts everything into ``<debug install dir>`` on
# Unlike the above version this puts everything into ``<debug install dir>`` on
# both DLL and non-DLL platforms. If ``<debug install dir>`` is set to
# :variable:`CMAKE_CURRENT_BINARY_DIR` (e.g. for testing purposes), the files
# are copied directly, without the need to perform install step. Note that the
@ -214,8 +238,9 @@
# <metadata file>
# <sources>...)
#
# The macro adds preprocessor directive ``CORRADE_STATIC_PLUGIN``. Additional
# libraries can be linked in via :command:`target_link_libraries(plugin_name ...) <target_link_libraries>`.
# The macro adds a preprocessor directive ``CORRADE_STATIC_PLUGIN`` when
# compiling ``<sources>``. Additional libraries can be linked in via
# :command:`target_link_libraries(plugin_name ...) <target_link_libraries>`.
# The ``<binary install dir>`` is ignored and included just for compatibility
# with the :command:`corrade_add_plugin` command, everything is installed into
# ``<library install dir>``. Note that plugins built in debug configuration
@ -223,6 +248,11 @@
# suffix to make it possible to have both debug and release plugins installed
# alongside each other.
#
# If the plugin interface disables plugin metadata files, the
# ``<metadata file>`` can be set to ``""``, in which case no metadata file is
# used. Otherwise the metadata file is bundled and renamed to
# ``<plugin name>``, retaining its original extension.
#
# corrade_add_static_plugin(<plugin name>
# <install dir>
# <metadata file>
@ -247,7 +277,8 @@
# This file is part of Corrade.
#
# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
# 2017, 2018, 2019 Vladimír Vondruš <mosra@centrum.cz>
# 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@ -289,16 +320,17 @@ endif()
# Read flags from configuration
file(READ ${_CORRADE_CONFIGURE_FILE} _corradeConfigure)
string(REGEX REPLACE ";" "\\\\;" _corradeConfigure "${_corradeConfigure}")
string(REGEX REPLACE "\n" ";" _corradeConfigure "${_corradeConfigure}")
set(_corradeFlags
# WARNING: CAREFUL HERE, the string(FIND) succeeds even if a subset is
# found -- so e.g. looking for TARGET_GL will match TARGET_GLES2 as well.
# So far that's not a problem, but might become an issue for new flags.
MSVC2015_COMPATIBILITY
MSVC2017_COMPATIBILITY
MSVC2019_COMPATIBILITY
MSVC_COMPATIBILITY
BUILD_DEPRECATED
BUILD_STATIC
BUILD_STATIC_UNIQUE_GLOBALS
BUILD_MULTITHREADED
BUILD_CPU_RUNTIME_DISPATCH
TARGET_UNIX
TARGET_APPLE
TARGET_IOS
@ -307,11 +339,17 @@ set(_corradeFlags
TARGET_WINDOWS_RT
TARGET_EMSCRIPTEN
TARGET_ANDROID
# TARGET_X86 etc, TARGET_32BIT, TARGET_BIG_ENDIAN and TARGET_LIBCXX etc.
# are not exposed to CMake as the meaning is unclear on platforms with
# multi-arch binaries or when mixing different STL implementations.
# TARGET_GCC etc are figured out via UseCorrade.cmake, as the compiler can
# be different when compiling the lib & when using it.
CPU_USE_IFUNC
PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT
TESTSUITE_TARGET_XCTEST
UTILITY_USE_ANSI_COLORS)
foreach(_corradeFlag ${_corradeFlags})
string(FIND "${_corradeConfigure}" "#define CORRADE_${_corradeFlag}" _corrade_${_corradeFlag})
list(FIND _corradeConfigure "#define CORRADE_${_corradeFlag}" _corrade_${_corradeFlag})
if(NOT _corrade_${_corradeFlag} EQUAL -1)
set(CORRADE_${_corradeFlag} 1)
endif()
@ -322,44 +360,60 @@ find_path(_CORRADE_MODULE_DIR
NAMES UseCorrade.cmake CorradeLibSuffix.cmake
PATH_SUFFIXES share/cmake/Corrade)
mark_as_advanced(_CORRADE_MODULE_DIR)
if(CORRADE_TARGET_EMSCRIPTEN)
find_path(CORRADE_DEPENDENCY_MODULE_DIR
NAMES FindNodeJs.cmake
PATH_SUFFIXES share/cmake/Corrade/dependencies)
mark_as_advanced(CORRADE_DEPENDENCY_MODULE_DIR)
endif()
set(CORRADE_USE_MODULE ${_CORRADE_MODULE_DIR}/UseCorrade.cmake)
set(CORRADE_LIB_SUFFIX_MODULE ${_CORRADE_MODULE_DIR}/CorradeLibSuffix.cmake)
# Ensure that all inter-component dependencies are specified as well
foreach(_component ${Corrade_FIND_COMPONENTS})
string(TOUPPER ${_component} _COMPONENT)
if(_component STREQUAL Containers)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility)
elseif(_component STREQUAL Interconnect)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility)
elseif(_component STREQUAL PluginManager)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Containers Utility rc)
elseif(_component STREQUAL TestSuite)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility Main) # see below
elseif(_component STREQUAL Utility)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Containers rc)
# Component distinction (listing them explicitly to avoid mistakes with finding
# unknown components)
set(_CORRADE_LIBRARY_COMPONENTS
Containers Interconnect Main PluginManager TestSuite Utility)
# These libraries are excluded from DLL detection if Corrade is built as shared
set(_CORRADE_LIBRARY_COMPONENTS_ALWAYS_STATIC
Main)
set(_CORRADE_HEADER_ONLY_COMPONENTS Containers)
if(NOT CORRADE_TARGET_WINDOWS)
# CorradeMain is a real library only on windows, a dummy target elsewhere
list(APPEND _CORRADE_HEADER_ONLY_COMPONENTS Main)
endif()
set(_CORRADE_EXECUTABLE_COMPONENTS rc)
# Currently everything is enabled implicitly. Keep in sync with Corrade's root
# CMakeLists.txt.
set(_CORRADE_IMPLICITLY_ENABLED_COMPONENTS
Containers Interconnect Main PluginManager TestSuite Utility rc)
# Inter-component dependencies
set(_CORRADE_Containers_DEPENDENCIES Utility)
set(_CORRADE_Interconnect_DEPENDENCIES Containers Utility)
set(_CORRADE_PluginManager_DEPENDENCIES Containers Utility rc)
set(_CORRADE_TestSuite_DEPENDENCIES Containers Utility Main) # see below
set(_CORRADE_Utility_DEPENDENCIES Containers rc)
# Ensure that all inter-component dependencies are specified as well
foreach(_component ${Corrade_FIND_COMPONENTS})
# Mark the dependencies as required if the component is also required
if(Corrade_FIND_REQUIRED_${_component})
foreach(_dependency ${_CORRADE_${_COMPONENT}_DEPENDENCIES})
foreach(_dependency ${_CORRADE_${_component}_DEPENDENCIES})
set(Corrade_FIND_REQUIRED_${_dependency} TRUE)
endforeach()
endif()
list(APPEND _CORRADE_ADDITIONAL_COMPONENTS ${_CORRADE_${_COMPONENT}_DEPENDENCIES})
list(APPEND _CORRADE_ADDITIONAL_COMPONENTS ${_CORRADE_${_component}_DEPENDENCIES})
endforeach()
# Main is linked only in corrade_add_test(), not to everything that depends
# on TestSuite, so remove it from the list again once we filled the above
# Main is linked only in corrade_add_test(), not to everything that depends on
# TestSuite, so remove it from the list again once we filled the above
# variables
if(_component STREQUAL TestSuite)
set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility)
endif()
endforeach()
set(_CORRADE_TestSuite_DEPENDENCIES Containers Utility)
# Join the lists, remove duplicate components
set(_CORRADE_ORIGINAL_FIND_COMPONENTS ${Corrade_FIND_COMPONENTS})
if(_CORRADE_ADDITIONAL_COMPONENTS)
list(INSERT Corrade_FIND_COMPONENTS 0 ${_CORRADE_ADDITIONAL_COMPONENTS})
endif()
@ -367,15 +421,10 @@ if(Corrade_FIND_COMPONENTS)
list(REMOVE_DUPLICATES Corrade_FIND_COMPONENTS)
endif()
# Component distinction
set(_CORRADE_LIBRARY_COMPONENTS "^(Containers|Interconnect|Main|PluginManager|TestSuite|Utility)$")
if(CORRADE_TARGET_WINDOWS)
# CorradeMain is a real library only on windows, a dummy target elsewhere
set(_CORRADE_HEADER_ONLY_COMPONENTS "^(Containers)$")
else()
set(_CORRADE_HEADER_ONLY_COMPONENTS "^(Containers|Main)$")
endif()
set(_CORRADE_EXECUTABLE_COMPONENTS "^(rc)$")
# Special cases of include paths. Libraries not listed here have a path suffix
# and include name derived from the library name in the loop below.
set(_CORRADE_MAIN_INCLUDE_PATH_SUFFIX Corrade)
set(_CORRADE_MAIN_INCLUDE_PATH_NAMES Corrade.h)
# Find all components
foreach(_component ${Corrade_FIND_COMPONENTS})
@ -384,66 +433,190 @@ foreach(_component ${Corrade_FIND_COMPONENTS})
# Create imported target in case the library is found. If the project is
# added as subproject to CMake, the target already exists and all the
# required setup is already done from the build tree.
if(TARGET Corrade::${_component})
if(TARGET "Corrade::${_component}") # Quotes to "fix" KDE's higlighter
set(Corrade_${_component}_FOUND TRUE)
else()
# Library (and not header-only) components
if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} AND NOT _component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS})
add_library(Corrade::${_component} UNKNOWN IMPORTED)
# Default include path names to look for for library / header-only
# components, unless set above already
if(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS)
if(NOT _CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX)
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX Corrade/${_component})
endif()
if(NOT _CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES)
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h)
endif()
endif()
# The Main library consists of two libraries on MinGW to be able to
# handle both console and windows apps, special-case it before any
# other libraries. The CORRADE_MAIN{CONSOLE,WINDOWS}_LIBRARY_<CONFIG>
# variables then get subsequently used below.
if(MINGW AND _component STREQUAL Main)
foreach(_mainComponent Console Windows)
string(TOUPPER ${_mainComponent} _MAIN_COMPONENT)
find_library(CORRADE_MAIN${_MAIN_COMPONENT}_LIBRARY_DEBUG CorradeMain${_mainComponent}-d)
find_library(CORRADE_MAIN${_MAIN_COMPONENT}_LIBRARY_RELEASE CorradeMain${_mainComponent})
mark_as_advanced(CORRADE_MAIN${_MAIN_COMPONENT}_LIBRARY_DEBUG
CORRADE_MAIN${_MAIN_COMPONENT}_LIBRARY_RELEASE)
endforeach()
# Library (and not header-only) components
elseif(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS AND NOT _component IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS)
# Try to find both debug and release version
find_library(CORRADE_${_COMPONENT}_LIBRARY_DEBUG Corrade${_component}-d)
find_library(CORRADE_${_COMPONENT}_LIBRARY_RELEASE Corrade${_component})
mark_as_advanced(CORRADE_${_COMPONENT}_LIBRARY_DEBUG
CORRADE_${_COMPONENT}_LIBRARY_RELEASE)
if(CORRADE_${_COMPONENT}_LIBRARY_RELEASE)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_property(TARGET Corrade::${_component} PROPERTY
IMPORTED_LOCATION_RELEASE ${CORRADE_${_COMPONENT}_LIBRARY_RELEASE})
# On Windows, if we have a dynamic build of given library, find the
# DLLs as well. Abuse find_program() since the DLLs should be
# alongside usual executables. On MinGW they however have a lib
# prefix.
if(CORRADE_TARGET_WINDOWS AND NOT CORRADE_BUILD_STATIC AND NOT _component IN_LIST _CORRADE_LIBRARY_COMPONENTS_ALWAYS_STATIC)
find_program(CORRADE_${_COMPONENT}_DLL_DEBUG ${CMAKE_SHARED_LIBRARY_PREFIX}Corrade${_component}-d.dll)
find_program(CORRADE_${_COMPONENT}_DLL_RELEASE ${CMAKE_SHARED_LIBRARY_PREFIX}Corrade${_component}.dll)
mark_as_advanced(CORRADE_${_COMPONENT}_DLL_DEBUG
CORRADE_${_COMPONENT}_DLL_RELEASE)
# If not on Windows or on a static build, unset the DLL variables
# to avoid leaks when switching shared and static builds
else()
unset(CORRADE_${_COMPONENT}_DLL_DEBUG CACHE)
unset(CORRADE_${_COMPONENT}_DLL_RELEASE CACHE)
endif()
if(CORRADE_${_COMPONENT}_LIBRARY_DEBUG)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_property(TARGET Corrade::${_component} PROPERTY
IMPORTED_LOCATION_DEBUG ${CORRADE_${_COMPONENT}_LIBRARY_DEBUG})
# Executable components
elseif(_component IN_LIST _CORRADE_EXECUTABLE_COMPONENTS)
find_program(CORRADE_${_COMPONENT}_EXECUTABLE corrade-${_component})
mark_as_advanced(CORRADE_${_COMPONENT}_EXECUTABLE)
# If the executable wasn't found, we're cross-compiling, an
# emulator is set and we're on CMake 3.6+ that actually uses
# CMAKE_CROSSCOMPILING_EMULATOR in add_custom_command((), try to
# find the cross-compiled version as a (slower) fallback. This
# assumes the toolchain sets CMAKE_FIND_ROOT_PATH_MODE_PROGRAM to
# NEVER, i.e. that the search is restricted to native executables
# by default.
if(NOT CORRADE_${_COMPONENT}_EXECUTABLE AND CMAKE_CROSSCOMPILING AND CMAKE_CROSSCOMPILING_EMULATOR AND NOT CMAKE_VERSION VERSION_LESS 3.6)
# Additionally, there are no CMAKE_FIND_PROGRAM_SUFFIXES akin
# to CMAKE_FIND_LIBRARY_SUFFIXES for libraries, so we have to
# try manually.
if(CORRADE_TARGET_EMSCRIPTEN)
set(_CORRADE_PROGRAM_EXTENSION .js)
endif()
find_program(CORRADE_${_COMPONENT}_EXECUTABLE
NAMES
corrade-${_component}
corrade-${_component}${_CORRADE_PROGRAM_EXTENSION}
ONLY_CMAKE_FIND_ROOT_PATH)
if(CORRADE_${_COMPONENT}_EXECUTABLE)
set(CORRADE_${_COMPONENT}_EXECUTABLE_EMULATOR ${CMAKE_CROSSCOMPILING_EMULATOR} CACHE PATH "Emulator for running a cross-compiled corrade-${_component} executable")
mark_as_advanced(CORRADE_${_COMPONENT}_EXECUTABLE_EMULATOR)
endif()
endif()
# If not a header-only component it's something unknown, skip. FPHSA
# will take care of handling this below.
elseif(NOT _component IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS)
continue()
endif()
# Find library includes
if(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS)
find_path(_CORRADE_${_COMPONENT}_INCLUDE_DIR
NAMES ${_CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES}
HINTS ${CORRADE_INCLUDE_DIR}/${_CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX})
mark_as_advanced(_CORRADE_${_COMPONENT}_INCLUDE_DIR)
endif()
# Header-only library components
if(_component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS})
# Decide if the component was found. If not, skip the rest, which
# creates and populates the target and finds additional dependencies.
# If found, the _FOUND variable may still get reset by something below.
#
# The Main library consists of two libraries on MinGW to be able to
# handle both console and windows apps. See
# src/Corrade/CMakeLists.txt for a lengthy explanation. On non-MinGW
# it's handled as a regular library or a header-only library.
if(MINGW AND _component STREQUAL Main)
if((CORRADE_MAINCONSOLE_LIBRARY_DEBUG AND CORRADE_MAINWINDOWS_LIBRARY_DEBUG) OR (CORRADE_MAINCONSOLE_LIBRARY_RELEASE AND CORRADE_MAINWINDOWS_LIBRARY_RELEASE))
set(Corrade_Main_FOUND TRUE)
else()
set(Corrade_Main_FOUND FALSE)
continue()
endif()
elseif(
# If the component is a library, it should have the include dir
(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS AND _CORRADE_${_COMPONENT}_INCLUDE_DIR AND (
# And it should be either header-only
_component IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS OR
# Or have a debug library, and a DLL found if expected
(CORRADE_${_COMPONENT}_LIBRARY_DEBUG AND (
NOT DEFINED CORRADE_${_COMPONENT}_DLL_DEBUG OR
CORRADE_${_COMPONENT}_DLL_DEBUG)) OR
# Or have a release library, and a DLL found if expected
(CORRADE_${_COMPONENT}_LIBRARY_RELEASE AND (
NOT DEFINED CORRADE_${_COMPONENT}_DLL_RELEASE OR
CORRADE_${_COMPONENT}_DLL_RELEASE)))) OR
# If the component is an executable, it should have just the
# location
(_component IN_LIST _CORRADE_EXECUTABLE_COMPONENTS AND CORRADE_${_COMPONENT}_EXECUTABLE)
)
set(Corrade_${_component}_FOUND TRUE)
else()
set(Corrade_${_component}_FOUND FALSE)
continue()
endif()
# Target for header-only library components. The Main library consists
# of two libraries on MinGW to be able to handle both console and
# windows apps, so there the target is INTERFACE as well, and is filled
# with INTERFACE_LINK_LIBRARIES later below.
if(_component IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS OR (MINGW AND _component STREQUAL Main))
add_library(Corrade::${_component} INTERFACE IMPORTED)
# Target and location for (non-header-only) libraries
elseif(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS)
if(CORRADE_BUILD_STATIC OR _component IN_LIST _CORRADE_LIBRARY_COMPONENTS_ALWAYS_STATIC)
add_library(Corrade::${_component} STATIC IMPORTED)
else()
add_library(Corrade::${_component} SHARED IMPORTED)
endif()
# Default include path names to look for for library / header-only
# components
if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS})
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX Corrade/${_component})
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h)
foreach(_CONFIG DEBUG RELEASE)
if(NOT CORRADE_${_COMPONENT}_LIBRARY_${_CONFIG})
continue()
endif()
# Executable components
if(_component MATCHES ${_CORRADE_EXECUTABLE_COMPONENTS})
add_executable(Corrade::${_component} IMPORTED)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
IMPORTED_CONFIGURATIONS ${_CONFIG})
# Unfortunately for a DLL the two properties are swapped out,
# *.lib goes to IMPLIB, so it's duplicated like this
if(DEFINED CORRADE_${_COMPONENT}_DLL_${_CONFIG})
# Quotes to "fix" KDE's higlighter
set_target_properties("Corrade::${_component}" PROPERTIES
IMPORTED_LOCATION_${_CONFIG} ${CORRADE_${_COMPONENT}_DLL_${_CONFIG}}
IMPORTED_IMPLIB_${_CONFIG} ${CORRADE_${_COMPONENT}_LIBRARY_${_CONFIG}})
else()
set_property(TARGET Corrade::${_component} PROPERTY
IMPORTED_LOCATION_${_CONFIG} ${CORRADE_${_COMPONENT}_LIBRARY_${_CONFIG}})
endif()
endforeach()
find_program(CORRADE_${_COMPONENT}_EXECUTABLE corrade-${_component})
mark_as_advanced(CORRADE_${_COMPONENT}_EXECUTABLE)
# Target and location for executable components
elseif(_component IN_LIST _CORRADE_EXECUTABLE_COMPONENTS)
add_executable(Corrade::${_component} IMPORTED)
if(CORRADE_${_COMPONENT}_EXECUTABLE)
set_property(TARGET Corrade::${_component} PROPERTY
IMPORTED_LOCATION ${CORRADE_${_COMPONENT}_EXECUTABLE})
endif()
endif()
# No special setup for Containers library
# Interconnect library
if(_component STREQUAL Interconnect)
# Disable /OPT:ICF on MSVC, which merges functions with identical
# contents and thus breaks signal comparison
if(CORRADE_TARGET_WINDOWS AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# contents and thus breaks signal comparison. Same case is for
# clang-cl which uses the MSVC linker by default.
if(CORRADE_TARGET_WINDOWS AND (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
if(CMAKE_VERSION VERSION_LESS 3.13)
set_property(TARGET Corrade::${_component} PROPERTY
INTERFACE_LINK_LIBRARIES "-OPT:NOICF,REF")
@ -455,11 +628,40 @@ foreach(_component ${Corrade_FIND_COMPONENTS})
# Main library
elseif(_component STREQUAL Main)
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX Corrade)
set(_CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES Corrade.h)
# On non-Windows platforms Main is a no-op interface target
if(CORRADE_TARGET_WINDOWS)
if(NOT MINGW)
# On MinGW the library consists of two libraries, for which we
# need to add two extra targets to delegate to. See
# src/Corrade/CMakeLists.txt for a lengthy explanation.
if(MINGW)
foreach(_mainComponent Console Windows)
string(TOUPPER ${_mainComponent} _MAINCOMPONENT)
# Similarly as with _CORRADE_LIBRARY_COMPONENTS above,
# just specialized for the Main library (and without
# DLL handling, as the library is always static)
add_library(Corrade::Main${_mainComponent} STATIC IMPORTED)
foreach(_CONFIG DEBUG RELEASE)
if(NOT CORRADE_MAIN${_MAINCOMPONENT}_LIBRARY_${_CONFIG})
continue()
endif()
set_property(TARGET Corrade::Main${_mainComponent} APPEND PROPERTY
IMPORTED_CONFIGURATIONS ${_CONFIG})
set_property(TARGET Corrade::Main${_mainComponent} PROPERTY
IMPORTED_LOCATION_${_CONFIG} ${CORRADE_MAIN${_MAINCOMPONENT}_LIBRARY_${_CONFIG}})
endforeach()
endforeach()
# See src/Corrade/CMakeLists.txt for why -lmingw32 has to
# be linked this way
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "-municode;$<$<NOT:$<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>>:Corrade::MainConsole>$<$<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>:-lmingw32;Corrade::MainWindows>")
# On MSVC and clang-cl it's simple, there's just a single
# library that was already added above. Add just the /ENTRY
# flag.
else()
# Abusing INTERFACE_LINK_LIBRARIES because
# INTERFACE_LINK_OPTIONS is only since 3.13. They treat
# things with `-` in front as linker flags and fortunately
@ -467,39 +669,40 @@ foreach(_component ${Corrade_FIND_COMPONENTS})
# https://gitlab.kitware.com/cmake/cmake/issues/16543
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "-ENTRY:$<$<NOT:$<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>>:wmainCRTStartup>$<$<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>:wWinMainCRTStartup>")
else()
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "-municode")
endif()
endif()
# PluginManager library
elseif(_component STREQUAL PluginManager)
# At least static build needs this
if(CORRADE_TARGET_UNIX)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS})
endif()
# -ldl is handled by Utility now
# TestSuite library has some additional files
# TestSuite library has some additional files. If those are not found,
# set the component _FOUND variable to false so it works properly both
# when the component is required and when it's optional.
elseif(_component STREQUAL TestSuite)
# XCTest runner file
if(CORRADE_TESTSUITE_TARGET_XCTEST)
find_file(CORRADE_TESTSUITE_XCTEST_RUNNER XCTestRunner.mm.in
PATH_SUFFIXES share/corrade/TestSuite)
set(CORRADE_TESTSUITE_XCTEST_RUNNER_NEEDED CORRADE_TESTSUITE_XCTEST_RUNNER)
if(NOT CORRADE_TESTSUITE_XCTEST_RUNNER)
set(Corrade_${_component}_FOUND FALSE)
endif()
# ADB runner file
elseif(CORRADE_TARGET_ANDROID)
find_file(CORRADE_TESTSUITE_ADB_RUNNER AdbRunner.sh
PATH_SUFFIXES share/corrade/TestSuite)
set(CORRADE_TESTSUITE_ADB_RUNNER_NEEDED CORRADE_TESTSUITE_ADB_RUNNER)
if(NOT CORRADE_TESTSUITE_ADB_RUNNER)
set(Corrade_${_component}_FOUND FALSE)
endif()
# Emscripten runner file
elseif(CORRADE_TARGET_EMSCRIPTEN)
find_file(CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER EmscriptenRunner.html.in
PATH_SUFFIXES share/corrade/TestSuite)
set(CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER_NEEDED CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER)
if(NOT CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER)
set(Corrade_${_component}_FOUND FALSE)
endif()
endif()
# Utility library (contains all setup that is used by others)
@ -514,55 +717,96 @@ foreach(_component ${Corrade_FIND_COMPONENTS})
set_property(TARGET Corrade::${_component} APPEND PROPERTY
COMPATIBLE_INTERFACE_NUMBER_MAX CORRADE_CXX_STANDARD)
# -fno-strict-aliasing is set in UseCorrade.cmake for everyone who
# enables CORRADE_USE_PEDANTIC_FLAGS. Not all projects linking to
# Corrade enable it (or can't enable it), but this flag is
# essential to prevent insane bugs and random breakages, so force
# it for anyone linking to Corrade::Utility. Similar code is in
# Corrade/Utility/CMakeLists.txt.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" AND NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") OR CORRADE_TARGET_EMSCRIPTEN)
set_property(TARGET Corrade::${_component} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS -fno-strict-aliasing)
endif()
# Path::libraryLocation() needs this
if(CORRADE_TARGET_UNIX)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS})
endif()
# AndroidLogStreamBuffer class needs to be linked to log library
if(CORRADE_TARGET_ANDROID)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "log")
endif()
# Emscripten has various stuff implemented in JS
if(CORRADE_TARGET_EMSCRIPTEN)
find_file(CORRADE_UTILITY_JS CorradeUtility.js
PATH_SUFFIXES lib)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
# TODO switch to INTERFACE_LINK_OPTIONS and SHELL: once we
# require CMake 3.13 unconditionally
INTERFACE_LINK_LIBRARIES "--js-library ${CORRADE_UTILITY_JS}")
endif()
# Find library includes
if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS})
find_path(_CORRADE_${_COMPONENT}_INCLUDE_DIR
NAMES ${_CORRADE_${_COMPONENT}_INCLUDE_PATH_NAMES}
HINTS ${CORRADE_INCLUDE_DIR}/${_CORRADE_${_COMPONENT}_INCLUDE_PATH_SUFFIX})
mark_as_advanced(_CORRADE_${_COMPONENT}_INCLUDE_DIR)
endif()
# Add inter-library dependencies
if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} OR _component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS})
foreach(_dependency ${_CORRADE_${_COMPONENT}_DEPENDENCIES})
if(_dependency MATCHES ${_CORRADE_LIBRARY_COMPONENTS} OR _dependency MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS})
if(_component IN_LIST _CORRADE_LIBRARY_COMPONENTS OR _component IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS)
foreach(_dependency ${_CORRADE_${_component}_DEPENDENCIES})
if(_dependency IN_LIST _CORRADE_LIBRARY_COMPONENTS OR _dependency IN_LIST _CORRADE_HEADER_ONLY_COMPONENTS)
set_property(TARGET Corrade::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES Corrade::${_dependency})
endif()
endforeach()
endif()
endif()
endforeach()
# Decide if the component was found
if((_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} AND _CORRADE_${_COMPONENT}_INCLUDE_DIR AND (_component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS} OR CORRADE_${_COMPONENT}_LIBRARY_RELEASE OR CORRADE_${_COMPONENT}_LIBRARY_DEBUG)) OR (_component MATCHES ${_CORRADE_EXECUTABLE_COMPONENTS} AND CORRADE_${_COMPONENT}_EXECUTABLE))
set(Corrade_${_component}_FOUND TRUE)
else()
set(Corrade_${_component}_FOUND FALSE)
# For CMake 3.16+ with REASON_FAILURE_MESSAGE, provide additional potentially
# useful info about the failed components.
if(NOT CMAKE_VERSION VERSION_LESS 3.16)
set(_CORRADE_REASON_FAILURE_MESSAGE )
# Go only through the originally specified find_package() components, not
# the dependencies added by us afterwards
foreach(_component ${_CORRADE_ORIGINAL_FIND_COMPONENTS})
if(Corrade_${_component}_FOUND)
continue()
endif()
# If it's not known at all, tell the user -- it might be a new library
# and an old Find module, or something platform-specific.
if(NOT _component IN_LIST _CORRADE_LIBRARY_COMPONENTS AND NOT _component IN_LIST _CORRADE_EXECUTABLE_COMPONENTS)
list(APPEND _CORRADE_REASON_FAILURE_MESSAGE "${_component} is not a known component on this platform.")
# Otherwise, if it's not among implicitly built components, hint that
# the user may need to enable it.
# TODO: currently, the _FOUND variable doesn't reflect if dependencies
# were found. When it will, this needs to be updated to avoid
# misleading messages.
elseif(NOT _component IN_LIST _CORRADE_IMPLICITLY_ENABLED_COMPONENTS)
string(TOUPPER ${_component} _COMPONENT)
list(APPEND _CORRADE_REASON_FAILURE_MESSAGE "${_component} is not built by default. Make sure you enabled CORRADE_WITH_${_COMPONENT} when building Corrade.")
# Otherwise we have no idea. Better be silent than to print something
# misleading.
else()
endif()
endforeach()
string(REPLACE ";" " " _CORRADE_REASON_FAILURE_MESSAGE "${_CORRADE_REASON_FAILURE_MESSAGE}")
set(_CORRADE_REASON_FAILURE_MESSAGE REASON_FAILURE_MESSAGE "${_CORRADE_REASON_FAILURE_MESSAGE}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Corrade REQUIRED_VARS
CORRADE_INCLUDE_DIR
_CORRADE_MODULE_DIR
_CORRADE_CONFIGURE_FILE
${CORRADE_TESTSUITE_XCTEST_RUNNER_NEEDED}
${CORRADE_TESTSUITE_ADB_RUNNER_NEEDED}
${CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER_NEEDED}
HANDLE_COMPONENTS)
HANDLE_COMPONENTS
${_CORRADE_REASON_FAILURE_MESSAGE})
# Finalize the finding process
include(${CORRADE_USE_MODULE})
# Installation dirs
set(CORRADE_INCLUDE_INSTALL_PREFIX "."
CACHE STRING "Prefix where to put platform-independent include and other files")
set(CORRADE_INCLUDE_INSTALL_DIR include/Corrade)
set(CORRADE_INCLUDE_INSTALL_DIR ${CORRADE_INCLUDE_INSTALL_PREFIX}/include/Corrade)
if(CORRADE_BUILD_DEPRECATED AND CORRADE_INCLUDE_INSTALL_PREFIX AND NOT CORRADE_INCLUDE_INSTALL_PREFIX STREQUAL ".")
message(DEPRECATION "CORRADE_INCLUDE_INSTALL_PREFIX is obsolete as its primary use was for old Android NDK versions. Please switch to the NDK r19+ layout instead of using this variable and recreate your build directory to get rid of this warning.")
set(CORRADE_INCLUDE_INSTALL_DIR ${CORRADE_INCLUDE_INSTALL_PREFIX}/${CORRADE_INCLUDE_INSTALL_DIR})
endif()

86
modules/FindEGL.cmake

@ -1,86 +0,0 @@
#.rst:
# Find EGL
# --------
#
# Finds the EGL library. This module defines:
#
# EGL_FOUND - True if EGL library is found
# EGL::EGL - EGL imported target
#
# Additionally these variables are defined for internal usage:
#
# EGL_LIBRARY - EGL library
# EGL_INCLUDE_DIR - Include dir
#
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Under Emscripten, GL is linked implicitly. With MINIMAL_RUNTIME you need to
# specify -lGL. Simply set the library name to that.
if(CORRADE_TARGET_EMSCRIPTEN)
set(EGL_LIBRARY GL CACHE STRING "Path to a library." FORCE)
else()
find_library(EGL_LIBRARY NAMES
EGL
# ANGLE (CMake doesn't search for lib prefix on Windows)
libEGL
# On iOS a part of OpenGLES
OpenGLES)
endif()
# Include dir
find_path(EGL_INCLUDE_DIR NAMES
EGL/egl.h
# iOS
EAGL.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(EGL DEFAULT_MSG
EGL_LIBRARY
EGL_INCLUDE_DIR)
if(NOT TARGET EGL::EGL)
# Work around BUGGY framework support on macOS. Do this also in case of
# Emscripten, since there we don't have a location either.
# http://public.kitware.com/pipermail/cmake/2016-April/063179.html
if((APPLE AND ${EGL_LIBRARY} MATCHES "\\.framework$") OR CORRADE_TARGET_EMSCRIPTEN)
add_library(EGL::EGL INTERFACE IMPORTED)
set_property(TARGET EGL::EGL APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${EGL_LIBRARY})
else()
add_library(EGL::EGL UNKNOWN IMPORTED)
set_property(TARGET EGL::EGL PROPERTY
IMPORTED_LOCATION ${EGL_LIBRARY})
endif()
set_target_properties(EGL::EGL PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${EGL_INCLUDE_DIR})
endif()
mark_as_advanced(EGL_LIBRARY EGL_INCLUDE_DIR)

94
modules/FindGLFW.cmake

@ -1,94 +0,0 @@
#.rst:
# Find GLFW
# ---------
#
# Finds the GLFW library using its cmake config if that exists, otherwise
# falls back to finding it manually. This module defines:
#
# GLFW_FOUND - True if GLFW library is found
# GLFW::GLFW - GLFW imported target
#
# Additionally, in case the config was not found, these variables are defined
# for internal usage:
#
# GLFW_LIBRARY - GLFW library
# GLFW_INCLUDE_DIR - Root include dir
#
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Vladimír Vondruš <mosra@centrum.cz>
# Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# GLFW installs cmake package config files to shared/ folder which handles
# dependencies in case GLFW is built statically. Try to find first, quietly, so
# it doesn't print loud messages when it's not found, since that's okay.
find_package(glfw3 CONFIG QUIET)
if(TARGET glfw)
if(NOT TARGET GLFW::GLFW)
# Aliases of (global) targets are only supported in CMake 3.11, so we
# work around it by this. This is easier than fetching all possible
# properties (which are impossible to track of) and then attempting to
# rebuild them into a new target.
add_library(GLFW::GLFW INTERFACE IMPORTED)
set_target_properties(GLFW::GLFW PROPERTIES INTERFACE_LINK_LIBRARIES glfw)
endif()
# Just to make FPHSA print some meaningful location, nothing else
get_target_property(_GLFW_INTERFACE_INCLUDE_DIRECTORIES glfw INTERFACE_INCLUDE_DIRECTORIES)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("GLFW" DEFAULT_MSG
_GLFW_INTERFACE_INCLUDE_DIRECTORIES)
return()
endif()
# In case no config file was found, try manually finding the library.
find_library(GLFW_LIBRARY NAMES glfw glfw3)
# Include dir
find_path(GLFW_INCLUDE_DIR
NAMES GLFW/glfw3.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("GLFW" DEFAULT_MSG
GLFW_LIBRARY
GLFW_INCLUDE_DIR)
if(NOT TARGET GLFW::GLFW)
add_library(GLFW::GLFW UNKNOWN IMPORTED)
# Work around BUGGY framework support on macOS
# https://cmake.org/Bug/view.php?id=14105
if(CORRADE_TARGET_APPLE AND ${GLFW_LIBRARY} MATCHES "\\.framework$")
set_property(TARGET GLFW::GLFW PROPERTY IMPORTED_LOCATION ${GLFW_LIBRARY}/GLFW)
else()
set_property(TARGET GLFW::GLFW PROPERTY IMPORTED_LOCATION ${GLFW_LIBRARY})
endif()
set_property(TARGET GLFW::GLFW PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${GLFW_INCLUDE_DIR})
endif()
mark_as_advanced(GLFW_LIBRARY GLFW_INCLUDE_DIR)

784
modules/FindMagnum.cmake

File diff suppressed because it is too large Load Diff

158
modules/FindMagnumBindings.cmake

@ -34,7 +34,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -58,22 +59,77 @@
find_package(Magnum REQUIRED)
# Global bindings include dir
find_path(MAGNUMBINDINGS_INCLUDE_DIR Magnum
HINTS ${MAGNUMBINDINGS_INCLUDE_DIR})
# Global include dir that's unique to Magnum Bindings. Often they will be
# installed alongside Magnum, which is why the hint, but if not, it shouldn't
# just pick MAGNUM_INCLUDE_DIR because then _MAGNUMBINDINGS_*_INCLUDE_DIR will
# fail to be found. In case of CMake subprojects the versionBindings.h is
# generated inside the build dir so this won't find it, instead
# src/CMakeLists.txt forcibly sets MAGNUMBINDINGS_INCLUDE_DIR as an internal
# cache value to make that work.
find_path(MAGNUMBINDINGS_INCLUDE_DIR Magnum/versionBindings.h
HINTS ${MAGNUM_INCLUDE_DIR})
mark_as_advanced(MAGNUMBINDINGS_INCLUDE_DIR)
# CMake module dir for dependencies. It might not be present at all if no
# feature that needs them is enabled, in which case it'll be left at NOTFOUND.
# But in that case it should also not be subsequently needed for any
# find_package(). If this is called from a superproject, the
# _MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR is already set by
# modules/CMakeLists.txt.
#
# There's no dependency Find modules so far. Once there are, uncomment this and
# list the modules in NAMES.
#find_path(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR
# NAMES
# PATH_SUFFIXES share/cmake/MagnumBindings/dependencies)
#mark_as_advanced(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR)
# If the module dir is found and is not present in CMAKE_MODULE_PATH already
# (such as when someone explicitly added it, or if it's the Magnum's modules/
# dir in case of a superproject), add it as the first before all other. Set a
# flag to remove it again at the end, so the modules don't clash with Find
# modules of the same name from other projects.
if(_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR AND NOT _MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR IN_LIST CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH ${_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR} ${CMAKE_MODULE_PATH})
set(_MAGNUMBINDINGS_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH ON)
else()
unset(_MAGNUMBINDINGS_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
endif()
# Component distinction (listing them explicitly to avoid mistakes with finding
# components from other repositories)
set(_MAGNUMBINDINGS_HEADER_ONLY_COMPONENT_LIST Python)
set(_MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS Python)
# Nothing is enabled by default right now
set(_MAGNUMBINDINGS_IMPLICITLY_ENABLED_COMPONENTS )
# No inter-component dependencies right now
# Ensure that all inter-component dependencies are specified as well
set(_MAGNUMBINDINGS_ADDITIONAL_COMPONENTS )
foreach(_component ${MagnumBindings_FIND_COMPONENTS})
# Mark the dependencies as required if the component is also required
if(MagnumBindings_FIND_REQUIRED_${_component})
foreach(_dependency ${_MAGNUMBINDINGS_${_component}_DEPENDENCIES})
set(MagnumBindings_FIND_REQUIRED_${_dependency} TRUE)
endforeach()
endif()
# Convert components lists to regular expressions so I can use if(MATCHES).
# TODO: Drop this once CMake 3.3 and if(IN_LIST) can be used
foreach(_WHAT HEADER_ONLY)
string(REPLACE ";" "|" _MAGNUMBINDINGS_${_WHAT}_COMPONENTS "${_MAGNUMBINDINGS_${_WHAT}_COMPONENT_LIST}")
set(_MAGNUMBINDINGS_${_WHAT}_COMPONENTS "^(${_MAGNUMBINDINGS_${_WHAT}_COMPONENTS})$")
list(APPEND _MAGNUMBINDINGS_ADDITIONAL_COMPONENTS ${_MAGNUMBINDINGS_${_component}_DEPENDENCIES})
endforeach()
# Join the lists, remove duplicate components
set(_MAGNUMBINDINGS_ORIGINAL_FIND_COMPONENTS ${MagnumBindings_FIND_COMPONENTS})
if(_MAGNUMBINDINGS_ADDITIONAL_COMPONENTS)
list(INSERT MagnumBindings_FIND_COMPONENTS 0 ${_MAGNUMBINDINGS_ADDITIONAL_COMPONENTS})
endif()
if(MagnumBindings_FIND_COMPONENTS)
list(REMOVE_DUPLICATES MagnumBindings_FIND_COMPONENTS)
endif()
# Special cases of include paths. Libraries not listed here have a path suffix
# and include name derived from the library name in the loop below. (So far no
# special cases.)
# Find all components
foreach(_component ${MagnumBindings_FIND_COMPONENTS})
string(TOUPPER ${_component} _COMPONENT)
@ -81,45 +137,95 @@ foreach(_component ${MagnumBindings_FIND_COMPONENTS})
# Create imported target in case the library is found. If the project is
# added as subproject to CMake, the target already exists and all the
# required setup is already done from the build tree.
if(TARGET MagnumBindings::${_component})
if(TARGET "MagnumBindings::${_component}") # Quotes to fix KDE's higlighter
set(MagnumBindings_${_component}_FOUND TRUE)
else()
# Header-only components
if(_component MATCHES ${_MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS})
add_library(MagnumBindings::${_component} INTERFACE IMPORTED)
if(_component IN_LIST _MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS)
# Include path names to find, unless specified above
if(NOT _MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_PATH_NAMES)
set(_MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}Bindings.h)
endif()
# Python bindings
if(_component STREQUAL Python)
set(_MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_PATH_NAMES Magnum/SceneGraph/Python.h)
endif()
if(_component MATCHES ${_MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS})
# Find includes
# Find library includes
if(_component IN_LIST _MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS)
find_path(_MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_DIR
NAMES ${_MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_PATH_NAMES}
HINTS ${MAGNUMBINDINGS_INCLUDE_DIR})
mark_as_advanced(_MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_DIR)
endif()
# Decide if the component was found. If not, skip the rest, which
# populates the target properties and finds additional dependencies.
if(_component IN_LIST _MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS AND _MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_DIR)
set(MagnumBindings_${_component}_FOUND TRUE)
else()
set(MagnumBindings_${_component}_FOUND FALSE)
continue()
endif()
# Target for header-only library components
if(_component IN_LIST _MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS)
add_library(MagnumBindings::${_component} INTERFACE IMPORTED)
endif()
# No special setup for Python bindings
if(_component IN_LIST _MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS)
# Link to core Magnum library
set_property(TARGET MagnumBindings::${_component} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES Magnum::Magnum)
# Add bindings incldue dir
# Add bindings include dir
set_property(TARGET MagnumBindings::${_component} APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${MAGNUMBINDINGS_INCLUDE_DIR})
endif()
endif()
endforeach()
# Decide if the component was found
if(_component MATCHES ${_MAGNUMBINDINGS_HEADER_ONLY_COMPONENTS} AND _MAGNUMBINDINGS_${_COMPONENT}_INCLUDE_DIR)
set(MagnumBindings_${_component}_FOUND TRUE)
else()
set(MagnumBindings_${_component}_FOUND FALSE)
# For CMake 3.16+ with REASON_FAILURE_MESSAGE, provide additional potentially
# useful info about the failed components.
if(NOT CMAKE_VERSION VERSION_LESS 3.16)
set(_MAGNUMBINDINGS_REASON_FAILURE_MESSAGE)
# Go only through the originally specified find_package() components, not
# the dependencies added by us afterwards
foreach(_component ${_MAGNUMBINDINGS_ORIGINAL_FIND_COMPONENTS})
if(MagnumBindings_${_component}_FOUND)
continue()
endif()
# If it's not known at all, tell the user -- it might be a new library
# and an old Find module, or something platform-specific.
if(NOT _component IN_LIST _MAGNUMBINDINGS_LIBRARY_COMPONENTS AND NOT _component IN_LIST _MAGNUMBINDINGS_PLUGIN_COMPONENTS)
list(APPEND _MAGNUMBINDINGS_REASON_FAILURE_MESSAGE "${_component} is not a known component on this platform.")
# Otherwise, if it's not among implicitly built components, hint that
# the user may need to enable it
# TODO: currently, the _FOUND variable doesn't reflect if dependencies
# were found. When it will, this needs to be updated to avoid
# misleading messages.
elseif(NOT _component IN_LIST _MAGNUMBINDINGS_IMPLICITLY_ENABLED_COMPONENTS)
string(TOUPPER ${_component} _COMPONENT)
list(APPEND _MAGNUMBINDINGS_REASON_FAILURE_MESSAGE "${_component} is not built by default. Make sure you enabled MAGNUM_WITH_${_COMPONENT} when building Magnum Bindings")
# Otherwise we have no idea. Better be silent than to print something
# misleading.
else()
endif()
endforeach()
string(REPLACE ";" " " _MAGNUMBINDINGS_REASON_FAILURE_MESSAGE "${_MAGNUMBINDINGS_REASON_FAILURE_MESSAGE}")
set(_MAGNUMBINDINGS_REASON_FAILURE_MESSAGE REASON_FAILURE_MESSAGE "${_MAGNUMBINDINGS_REASON_FAILURE_MESSAGE}")
endif()
# Remove Magnum Extras dependency module dir from CMAKE_MODULE_PATH again. Do
# it before the FPHSA call which may exit early in case of a failure.
if(_MAGNUMBINDINGS_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
list(REMOVE_ITEM CMAKE_MODULE_PATH ${_MAGNUMBINDINGS_DEPENDENCY_MODULE_DIR})
unset(_MAGNUMBINDINGS_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MagnumBindings
REQUIRED_VARS MAGNUMBINDINGS_INCLUDE_DIR
HANDLE_COMPONENTS)
HANDLE_COMPONENTS
${_MAGNUMBINDINGS_REASON_FAILURE_MESSAGE})

78
modules/FindOpenGLES2.cmake

@ -1,78 +0,0 @@
#.rst:
# Find OpenGL ES 2
# ----------------
#
# Finds the OpenGL ES 2 library. This module defines:
#
# OpenGLES2_FOUND - True if OpenGL ES 2 library is found
# OpenGLES2::OpenGLES2 - OpenGL ES 2 imported target
#
# Additionally these variables are defined for internal usage:
#
# OPENGLES2_LIBRARY - OpenGL ES 2 library
#
# Please note this find module is tailored especially for the needs of Magnum.
# In particular, it depends on its platform definitions and doesn't look for
# OpenGL ES includes as Magnum has its own, generated using flextGL.
#
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Under Emscripten, GL is linked implicitly. With MINIMAL_RUNTIME you need to
# specify -lGL. Simply set the library name to that.
if(CORRADE_TARGET_EMSCRIPTEN)
set(OPENGLES2_LIBRARY GL CACHE STRING "Path to a library." FORCE)
else()
find_library(OPENGLES2_LIBRARY NAMES
GLESv2
# ANGLE (CMake doesn't search for lib prefix on Windows)
libGLESv2
# iOS
OpenGLES)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG
OPENGLES2_LIBRARY)
if(NOT TARGET OpenGLES2::OpenGLES2)
# Work around BUGGY framework support on macOS. Do this also in case of
# Emscripten, since there we don't have a location either.
# http://public.kitware.com/pipermail/cmake/2016-April/063179.html
if((CORRADE_TARGET_APPLE AND ${OPENGLES2_LIBRARY} MATCHES "\\.framework$") OR CORRADE_TARGET_EMSCRIPTEN)
add_library(OpenGLES2::OpenGLES2 INTERFACE IMPORTED)
set_property(TARGET OpenGLES2::OpenGLES2 APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${OPENGLES2_LIBRARY})
else()
add_library(OpenGLES2::OpenGLES2 UNKNOWN IMPORTED)
set_property(TARGET OpenGLES2::OpenGLES2 PROPERTY
IMPORTED_LOCATION ${OPENGLES2_LIBRARY})
endif()
endif()
mark_as_advanced(OPENGLES2_LIBRARY)

92
modules/FindOpenGLES3.cmake

@ -1,92 +0,0 @@
#.rst:
# Find OpenGL ES 3
# ----------------
#
# Finds the OpenGL ES 3 library. This module defines:
#
# OpenGLES3_FOUND - True if OpenGL ES 3 library is found
# OpenGLES3::OpenGLES3 - OpenGL ES 3 imported target
#
# Additionally these variables are defined for internal usage:
#
# OPENGLES3_LIBRARY - OpenGL ES 3 library
#
# Please note this find module is tailored especially for the needs of Magnum.
# In particular, it depends on its platform definitions and doesn't look for
# OpenGL ES includes as Magnum has its own, generated using flextGL.
#
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Under Emscripten, GL is linked implicitly. With MINIMAL_RUNTIME you need to
# specify -lGL. Simply set the library name to that.
if(CORRADE_TARGET_EMSCRIPTEN)
set(OPENGLES3_LIBRARY GL CACHE STRING "Path to a library." FORCE)
else()
find_library(OPENGLES3_LIBRARY NAMES
GLESv3
# On some platforms (e.g. desktop emulation with Mesa or NVidia) ES3
# support is provided in ES2 lib
GLESv2
# ANGLE (CMake doesn't search for lib prefix on Windows)
libGLESv2
# iOS
OpenGLES)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("OpenGLES3" DEFAULT_MSG
OPENGLES3_LIBRARY)
if(NOT TARGET OpenGLES3::OpenGLES3)
# Work around BUGGY framework support on macOS. Do this also in case of
# Emscripten, since there we don't have a location either.
# http://public.kitware.com/pipermail/cmake/2016-April/063179.html
if((CORRADE_TARGET_APPLE AND ${OPENGLES3_LIBRARY} MATCHES "\\.framework$") OR CORRADE_TARGET_EMSCRIPTEN)
add_library(OpenGLES3::OpenGLES3 INTERFACE IMPORTED)
set_property(TARGET OpenGLES3::OpenGLES3 APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${OPENGLES3_LIBRARY})
else()
add_library(OpenGLES3::OpenGLES3 UNKNOWN IMPORTED)
set_property(TARGET OpenGLES3::OpenGLES3 PROPERTY
IMPORTED_LOCATION ${OPENGLES3_LIBRARY})
endif()
# Emscripten needs a special flag to use WebGL 2. CMake 3.13 allows to set
# this via INTERFACE_LINK_OPTIONS, for older versions we modify the global
# CMAKE_EXE_LINKER_FLAGS inside FindMagnum.cmake.
if(CORRADE_TARGET_EMSCRIPTEN AND NOT CMAKE_VERSION VERSION_LESS 3.13)
# I could probably use target_link_options() here, but let's be
# consistent with the rest
set_property(TARGET OpenGLES3::OpenGLES3 APPEND PROPERTY
INTERFACE_LINK_OPTIONS "SHELL:-s USE_WEBGL2=1")
endif()
endif()
mark_as_advanced(OPENGLES3_LIBRARY)

173
modules/FindSDL2.cmake

@ -1,173 +0,0 @@
#.rst:
# Find SDL2
# ---------
#
# Finds the SDL2 library. This module defines:
#
# SDL2_FOUND - True if SDL2 library is found
# SDL2::SDL2 - SDL2 imported target
#
# Additionally these variables are defined for internal usage:
#
# SDL2_LIBRARY_DEBUG - SDL2 debug library, if found
# SDL2_LIBRARY_RELEASE - SDL2 release library, if found
# SDL2_INCLUDE_DIR - Root include dir
#
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Vladimír Vondruš <mosra@centrum.cz>
# Copyright © 2018 Jonathan Hale <squareys@googlemail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# In Emscripten SDL is linked automatically, thus no need to find the library.
# Also the includes are in SDL subdirectory, not SDL2.
if(CORRADE_TARGET_EMSCRIPTEN)
set(_SDL2_PATH_SUFFIXES SDL)
else()
set(_SDL2_PATH_SUFFIXES SDL2)
if(WIN32)
# Precompiled libraries for MSVC are in x86/x64 subdirectories
if(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_SDL2_LIBRARY_PATH_SUFFIX lib/x64)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(_SDL2_LIBRARY_PATH_SUFFIX lib/x86)
endif()
# Both includes and libraries for MinGW are in some directory deep
# inside. There's also a CMake config file but it has HARDCODED path
# to /opt/local/i686-w64-mingw32, which doesn't make ANY SENSE,
# especially on Windows.
elseif(MINGW)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_SDL2_LIBRARY_PATH_SUFFIX x86_64-w64-mingw32/lib)
list(APPEND _SDL2_PATH_SUFFIXES x86_64-w64-mingw32/include/SDL2)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(_SDL2_LIBRARY_PATH_SUFFIX i686-w64-mingw32/lib)
list(APPEND _SDL2_PATH_SUFFIXES i686-w64-mingw32/include/SDL2)
endif()
endif()
endif()
find_library(SDL2_LIBRARY_RELEASE
# Compiling SDL2 from scratch on macOS creates dead libSDL2.so symlink
# which CMake somehow prefers before the SDL2-2.0.dylib file. Making
# the dylib first so it is preferred. Not sure how this maps to debug
# config though :/
NAMES SDL2-2.0 SDL2
PATH_SUFFIXES ${_SDL2_LIBRARY_PATH_SUFFIX})
find_library(SDL2_LIBRARY_DEBUG
NAMES SDL2d
PATH_SUFFIXES ${_SDL2_LIBRARY_PATH_SUFFIX})
# FPHSA needs one of the _DEBUG/_RELEASE variables to check that the
# library was found -- using SDL_LIBRARY, which will get populated by
# select_library_configurations() below.
set(SDL2_LIBRARY_NEEDED SDL2_LIBRARY)
endif()
include(SelectLibraryConfigurations)
select_library_configurations(SDL2)
# Include dir
find_path(SDL2_INCLUDE_DIR
# We must search file which is present only in SDL2 and not in SDL1.
# Apparently when both SDL.h and SDL_scancode.h are specified, CMake is
# happy enough that it found SDL.h and doesn't bother about the other.
#
# On macOS, where the includes are not in SDL2/SDL.h form (which would
# solve this issue), but rather SDL2.framework/Headers/SDL.h, CMake might
# find SDL.framework/Headers/SDL.h if SDL1 is installed, which is wrong.
NAMES SDL_scancode.h
PATH_SUFFIXES ${_SDL2_PATH_SUFFIXES})
# iOS dependencies
if(CORRADE_TARGET_IOS)
set(_SDL2_FRAMEWORKS
AudioToolbox
AVFoundation
CoreGraphics
CoreMotion
Foundation
GameController
QuartzCore
UIKit)
set(_SDL2_FRAMEWORK_LIBRARIES )
foreach(framework ${_SDL2_FRAMEWORKS})
find_library(_SDL2_${framework}_LIBRARY ${framework})
mark_as_advanced(_SDL2_${framework}_LIBRARY)
list(APPEND _SDL2_FRAMEWORK_LIBRARIES ${_SDL2_${framework}_LIBRARY})
list(APPEND _SDL2_FRAMEWORK_LIBRARY_NAMES _SDL2_${framework}_LIBRARY)
endforeach()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("SDL2" DEFAULT_MSG
${SDL2_LIBRARY_NEEDED}
${_SDL2_FRAMEWORK_LIBRARY_NAMES}
SDL2_INCLUDE_DIR)
if(NOT TARGET SDL2::SDL2)
if(SDL2_LIBRARY_NEEDED)
add_library(SDL2::SDL2 UNKNOWN IMPORTED)
# Work around BUGGY framework support on macOS
# https://cmake.org/Bug/view.php?id=14105
if(CORRADE_TARGET_APPLE AND SDL2_LIBRARY_RELEASE MATCHES "\\.framework$")
set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_RELEASE ${SDL2_LIBRARY_RELEASE}/SDL2)
else()
if(SDL2_LIBRARY_RELEASE)
set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_RELEASE ${SDL2_LIBRARY_RELEASE})
endif()
if(SDL2_LIBRARY_DEBUG)
set_property(TARGET SDL2::SDL2 APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_property(TARGET SDL2::SDL2 PROPERTY IMPORTED_LOCATION_DEBUG ${SDL2_LIBRARY_DEBUG})
endif()
endif()
# Link additional `dl` and `pthread` libraries required by a static
# build of SDL on Unixy platforms (except Apple, where it is most
# probably some frameworks instead)
if(CORRADE_TARGET_UNIX AND NOT CORRADE_TARGET_APPLE AND SDL2_LIBRARY MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")
find_package(Threads)
set_property(TARGET SDL2::SDL2 APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
endif()
# Link frameworks on iOS
if(CORRADE_TARGET_IOS)
set_property(TARGET SDL2::SDL2 APPEND PROPERTY
INTERFACE_LINK_LIBRARIES ${_SDL2_FRAMEWORK_LIBRARIES})
endif()
else()
add_library(SDL2::SDL2 INTERFACE IMPORTED)
endif()
set_property(TARGET SDL2::SDL2 PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR})
endif()
mark_as_advanced(SDL2_INCLUDE_DIR)

3
modules/MagnumBindingsConfig.cmake

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a

2
package/archlinux/.gitignore vendored

@ -1,3 +1,3 @@
pkg/
src/
*pkg.tar.xz
*pkg.tar.zst

1
package/archlinux/.kateconfig

@ -0,0 +1 @@
kate-wildcard(PKGBUILD*): hl bash;

37
package/archlinux/PKGBUILD

@ -8,27 +8,42 @@ url="https://magnum.graphics"
license=('MIT')
depends=('corrade' 'magnum' 'python')
makedepends=('cmake' 'ninja' 'pybind11')
options=(!buildflags)
provides=('magnum-bindings-git')
_rootdir=$startdir/../../
_buildtype=Release
# _buildtype=Debug
build() {
mkdir -p "$_rootdir/build"
cd "$_rootdir/build"
# Disable optimization (saves A LOT of compilation time)
newcxxflags=$(echo $CXXFLAGS | sed s/-O.//g | sed s/-D_FORTIFY_SOURCE=.//g)
export CXXFLAGS="$newcxxflags"
# Only one of these is built.
#
# Colored output is enabled implicitly. If Ninja detects it's outputting to
# a pipe, it strips it away from the output, alternatively you can set the
# GCC_COLORS= (empty) env variable to temporarily disable colors. The
# inverse, i.e. preserving colors when Ninja outputs to a pipe can be done
# with CLICOLOR_FORCE=1: https://github.com/ninja-build/ninja/issues/2196
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CONFIGURATION_TYPES="Release;Debug;RelWithDebInfo" \
-DCMAKE_CROSS_CONFIGS=all \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -g -DNDEBUG -fno-omit-frame-pointer" \
-DCMAKE_INSTALL_PREFIX=/usr \
-DWITH_PYTHON=ON \
-G Ninja
ninja
-DCMAKE_COLOR_DIAGNOSTICS=ON \
-DPYTHON_EXECUTABLE=$(which python) \
-DMAGNUM_WITH_PYTHON=ON \
-DMAGNUM_BUILD_TESTS=ON \
-G "Ninja Multi-Config"
ninja all:$_buildtype
}
check() {
cd "$_rootdir/build"
CORRADE_TEST_COLOR=ON ctest --output-on-failure -C $_buildtype
cd "$_rootdir/src/python/corrade"
python -m unittest -v
@ -36,15 +51,15 @@ check() {
python -m unittest -v
cd "$_rootdir/doc/python"
PYTHONPATH="$_rootdir/build/src/python" python -m doctest -v *.rst
PYTHONPATH="$_rootdir/build/src/python/$_buildtype" python -m doctest -v *.rst
}
package() {
# Helper headers
cd "$_rootdir/build"
DESTDIR="$pkgdir/" ninja install
DESTDIR="$pkgdir/" ninja install:$_buildtype
# Native and python packages
cd "$_rootdir/build/src/python"
cd "$_rootdir/build/src/python/$_buildtype"
python setup.py install --root="$pkgdir" --prefix=/usr
}

23
package/archlinux/PKGBUILD-coverage

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://magnum.graphics"
license=('MIT')
depends=('corrade' 'magnum' 'python')
makedepends=('cmake' 'ninja' 'pybind11' 'lcov')
makedepends=('cmake' 'ninja' 'pybind11' 'lcov' 'python-coverage')
provides=('magnum-bindings-git')
_rootdir=$startdir/../../
@ -20,11 +20,19 @@ build() {
newcxxflags=$(echo $CXXFLAGS | sed s/-O.//g | sed s/-D_FORTIFY_SOURCE=.//g)
export CXXFLAGS="$newcxxflags"
# Colored output is enabled implicitly. If Ninja detects it's outputting to
# a pipe, it strips it away from the output, alternatively you can set the
# GCC_COLORS= (empty) env variable to temporarily disable colors. The
# inverse, i.e. preserving colors when Ninja outputs to a pipe can be done
# with CLICOLOR_FORCE=1: https://github.com/ninja-build/ninja/issues/2196
cmake .. \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_INSTALL_PREFIX=/usr \
-DWITH_PYTHON=ON \
-DCMAKE_COLOR_DIAGNOSTICS=ON \
-DPYTHON_EXECUTABLE=$(which python) \
-DMAGNUM_WITH_PYTHON=ON \
-DMAGNUM_BUILD_TESTS=ON \
-G Ninja
ninja
}
@ -48,14 +56,13 @@ check() {
rm -rf coverage
mkdir coverage
# Keep in sync with package/ci/travis.yml, please
lcov --directory . --capture --output-file coverage.info
lcov --extract coverage.info "*/src/python/*" "*/src/Corrade/*" "*/src/Magnum/*" --output-file coverage.info
genhtml --output-directory ./coverage coverage.info
# Keep in sync with package/ci/circleci.yml, please
# TODO figure out a way to avoid adding --ignore-errors mismatch etc
lcov --ignore-errors mismatch,inconsistent --directory . --capture --output-file coverage.info
lcov --ignore-errors inconsistent --extract coverage.info "*/src/python/*" "*/src/Corrade/*" "*/src/Magnum/*" --output-file coverage.info
genhtml --no-function-coverage --missed --output-directory ./coverage coverage.info
}
package() {
echo -e "Open \n file://${_rootdir}build-coverage/coverage/index.html\n file://${_rootdir}src/python/htmlcov/index.html\nto see the results." && false
}
# kate: hl bash

41
package/archlinux/magnum-bindings-git/PKGBUILD

@ -0,0 +1,41 @@
# Author: mosra <mosra@centrum.cz>
pkgname=magnum-bindings-git
pkgver=2020.06.r116.g62a07c3
pkgrel=1
pkgdesc="Bindings for the Magnum C++11/C++14 graphics engine (Git version)"
arch=('i686' 'x86_64')
url="https://magnum.graphics"
license=('MIT')
depends=('magnum-git' 'python')
makedepends=('cmake' 'git' 'ninja' 'pybind11')
provides=('magnum-bindings')
conflicts=('magnum-bindings')
source=("git+https://github.com/mosra/magnum-bindings.git")
sha1sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
git describe --long | sed -r 's/([^-]*-g)/r\1/;s/-/./g;s/v//g'
}
build() {
mkdir -p "$srcdir/build"
cd "$srcdir/build"
cmake "$srcdir/${pkgname%-git}" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DMAGNUM_WITH_PYTHON=ON \
-G Ninja
ninja
}
package() {
# Helper headers
cd "$srcdir/build"
DESTDIR="$pkgdir/" ninja install
# Native and python packages
cd "$srcdir/build/src/python"
python setup.py install --root="$pkgdir" --prefix=/usr
}

123
package/ci/appveyor-desktop-gles.bat

@ -1,90 +1,139 @@
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2022" call "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2019" call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" call "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
set PATH=%APPVEYOR_BUILD_FOLDER%\deps\bin;%PATH%
rem Build pybind11. Downloaded in the appveyor.yml script.
cd pybind11-2.3.0 || exit /b
rem Build pybind11. Downloaded in the appveyor.yml script. Forcing
rem -DCMAKE_POLICY_VERSION_MINIMUM=3.5 because it's bumped from 3.4 to 3.5 only
rem in version 2.11, which got released in 2023, years after the MSVC versions
rem we test for.
cd pybind11-%PYBIND% || exit /b
mkdir -p build && cd build || exit /b
cmake .. ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DPYBIND11_PYTHON_VERSION=3.6 ^
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^
-DPYBIND11_PYTHON_VERSION=3.%PYTHON% ^
-DPYBIND11_TEST=OFF ^
-G Ninja || exit /b
ninja install || exit /b
cd .. && cd ..
rem Build Corrade
git clone --depth 1 git://github.com/mosra/corrade.git || exit /b
git clone --depth 1 https://github.com/mosra/corrade.git || exit /b
cd corrade || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DBUILD_DEPRECATED=OFF ^
-DBUILD_STATIC=%BUILD_STATIC% ^
-DWITH_INTERCONNECT=OFF ^
-DWITH_PLUGINMANAGER=ON ^
-DWITH_TESTSUITE=OFF ^
-DUTILITY_USE_ANSI_COLORS=ON ^
-DCORRADE_BUILD_STATIC=%BUILD_STATIC% ^
-DCORRADE_WITH_INTERCONNECT=OFF ^
-DCORRADE_WITH_PLUGINMANAGER=ON ^
-DCORRADE_WITH_TESTSUITE=ON ^
-DCORRADE_UTILITY_USE_ANSI_COLORS=ON ^
-G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build Magnum
git clone --depth 1 git://github.com/mosra/magnum.git || exit /b
git clone --depth 1 https://github.com/mosra/magnum.git || exit /b
cd magnum || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DBUILD_DEPRECATED=OFF ^
-DBUILD_STATIC=%BUILD_STATIC% ^
-DTARGET_GLES=ON ^
-DTARGET_GLES2=%TARGET_GLES2% ^
-DTARGET_DESKTOP_GLES=ON ^
-DWITH_AUDIO=OFF ^
-DWITH_DEBUGTOOLS=OFF ^
-DWITH_GL=ON ^
-DWITH_MESHTOOLS=ON ^
-DWITH_PRIMITIVES=ON ^
-DWITH_SCENEGRAPH=ON ^
-DWITH_SHADERS=ON ^
-DWITH_TEXT=OFF ^
-DWITH_TEXTURETOOLS=ON ^
-DWITH_TRADE=ON ^
-DWITH_VK=OFF ^
-DWITH_SDL2APPLICATION=OFF ^
-DWITH_GLFWAPPLICATION=OFF ^
-DWITH_WINDOWLESSWGLAPPLICATION=ON ^
-DMAGNUM_BUILD_STATIC=%BUILD_STATIC% ^
-DMAGNUM_TARGET_GLES=ON ^
-DMAGNUM_TARGET_GLES2=%TARGET_GLES2% ^
-DMAGNUM_TARGET_EGL=OFF ^
-DMAGNUM_WITH_AUDIO=OFF ^
-DMAGNUM_WITH_DEBUGTOOLS=OFF ^
-DMAGNUM_WITH_MATERIALTOOLS=ON ^
-DMAGNUM_WITH_GL=ON ^
-DMAGNUM_WITH_MESHTOOLS=ON ^
-DMAGNUM_WITH_PRIMITIVES=ON ^
-DMAGNUM_WITH_SCENEGRAPH=ON ^
-DMAGNUM_WITH_SCENETOOLS=ON ^
-DMAGNUM_WITH_SHADERS=ON ^
-DMAGNUM_WITH_SHADERTOOLS=OFF ^
-DMAGNUM_WITH_TEXT=ON ^
-DMAGNUM_WITH_TEXTURETOOLS=ON ^
-DMAGNUM_WITH_TRADE=ON ^
-DMAGNUM_WITH_VK=OFF ^
-DMAGNUM_WITH_SDL2APPLICATION=OFF ^
-DMAGNUM_WITH_GLFWAPPLICATION=OFF ^
-DMAGNUM_WITH_WINDOWLESSWGLAPPLICATION=ON ^
-DMAGNUM_WITH_ANYIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_ANYSCENECONVERTER=ON ^
-DMAGNUM_WITH_ANYSCENEIMPORTER=ON ^
-DMAGNUM_WITH_TGAIMPORTER=ON ^
-G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build. BUILD_GL_TESTS is enabled just to be sure, it should not be needed
rem by any plugin.
rem Build Magnum Plugins
git clone --depth 1 https://github.com/mosra/magnum-plugins.git || exit /b
cd magnum-plugins || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DPYBIND11_PYTHON_VERSION=3.6 ^
-DWITH_PYTHON=ON ^
-DMAGNUM_BUILD_STATIC=%BUILD_STATIC% ^
-DMAGNUM_WITH_BCDECIMAGECONVERTER=ON ^
-DMAGNUM_WITH_DDSIMPORTER=ON ^
-DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON ^
-DMAGNUM_WITH_GLTFIMPORTER=ON ^
-DMAGNUM_WITH_GLTFSCENECONVERTER=ON ^
-DMAGNUM_WITH_KTXIMAGECONVERTER=ON ^
-DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=ON ^
-DMAGNUM_WITH_PRIMITIVEIMPORTER=ON ^
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBTRUETYPEFONT=ON ^
-G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build. Again forcing -DCMAKE_POLICY_VERSION_MINIMUM=3.5 because the
rem pybind11 CMake config files also require just 3.4 now.
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^
-DPYBIND11_PYTHON_VERSION=3.%PYTHON% ^
-DMAGNUM_WITH_PYTHON=ON ^
-DMAGNUM_BUILD_TESTS=ON ^
-G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
rem Test
set CORRADE_TEST_COLOR=ON
rem On Windows, if an assertion or other issue happens, A DIALOG WINDOWS POPS
rem UP FROM THE CONSOLE. And then, for fucks sake, IT WAITS ENDLESSLY FOR YOU
rem TO CLOSE IT!! Such behavior is utterly stupid in a non-interactive setting
rem such as on this very CI, so I'm setting a timeout to 60 seconds to avoid
rem the CI job being stuck for an hour if an assertion happens. CTest's default rem timeouts is somehow 10M seconds, which is as useful as nothing at all.
ctest -V -E GLTest --timeout 60 || exit /b
rem Verify the setuptools install
cd src/python || exit /b
python setup.py install --root="%APPVEYOR_BUILD_FOLDER%/install" || exit /b
rem Run tests & gather coverage
rem Run python tests & gather coverage
cd ../../../src/python/corrade || exit /b
coverage run -m unittest -v && cp .coverage ../.coverage.corrade || exit /b
coverage run -m unittest -v || exit /b
cp .coverage ../.coverage.corrade || exit /b
cd ../magnum || exit /b
set MAGNUM_SKIP_GL_TESTS=ON
coverage run -m unittest -v && cp .coverage ../.coverage.magnum || exit /b
coverage run -m unittest -v || exit /b
cp .coverage ../.coverage.magnum || exit /b
rem Test docstring validity
cd ../../../doc/python || exit /b

133
package/ci/appveyor-desktop.bat

@ -1,91 +1,150 @@
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2022" call "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2019" call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" call "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" x64 || exit /b
rem SDL2 has the DLL in lib/x64, and in the static build it's imported so the
rem DLL has to be found.
set PATH=%APPVEYOR_BUILD_FOLDER%\deps\bin;%APPVEYOR_BUILD_FOLDER%\SDL\lib\x64;%PATH%
rem Build pybind11. Downloaded in the appveyor.yml script.
cd pybind11-2.3.0 || exit /b
rem need to explicitly specify a 64-bit target, otherwise CMake+Ninja can't
rem figure that out -- https://gitlab.kitware.com/cmake/cmake/issues/16259
rem for TestSuite we need to enable exceptions explicitly with /EH as these are
rem currently disabled -- https://github.com/catchorg/Catch2/issues/1113
if "%COMPILER%" == "msvc-clang" if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2022" set COMPILER_EXTRA=-DCMAKE_CXX_COMPILER="C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/Llvm/bin/clang-cl.exe" -DCMAKE_LINKER="C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/Llvm/bin/lld-link.exe" -DCMAKE_CXX_FLAGS="-m64 /EHsc"
if "%COMPILER%" == "msvc-clang" if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2019" set COMPILER_EXTRA=-DCMAKE_CXX_COMPILER="C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/bin/clang-cl.exe" -DCMAKE_LINKER="C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/bin/lld-link.exe" -DCMAKE_CXX_FLAGS="-m64 /EHsc"
set EXCEPT_MSVC2017=ON
IF "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" set EXCEPT_MSVC2017=OFF
rem Build pybind11. Downloaded in the appveyor.yml script. Forcing
rem -DCMAKE_POLICY_VERSION_MINIMUM=3.5 because it's bumped from 3.4 to 3.5 only
rem in version 2.11, which got released in 2023, years after the MSVC versions
rem we test for.
cd pybind11-%PYBIND% || exit /b
mkdir -p build && cd build || exit /b
cmake .. ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DPYBIND11_PYTHON_VERSION=3.6 ^
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^
-DPYBIND11_PYTHON_VERSION=3.%PYTHON% ^
-DPYBIND11_TEST=OFF ^
-G Ninja || exit /b
ninja install || exit /b
cd .. && cd ..
rem Build Corrade
git clone --depth 1 git://github.com/mosra/corrade.git || exit /b
git clone --depth 1 https://github.com/mosra/corrade.git || exit /b
cd corrade || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DBUILD_DEPRECATED=OFF ^
-DBUILD_STATIC=%BUILD_STATIC% ^
-DWITH_INTERCONNECT=OFF ^
-DWITH_PLUGINMANAGER=ON ^
-DWITH_TESTSUITE=OFF ^
-DUTILITY_USE_ANSI_COLORS=ON ^
-G Ninja || exit /b
-DCORRADE_BUILD_STATIC=%BUILD_STATIC% ^
-DCORRADE_WITH_INTERCONNECT=OFF ^
-DCORRADE_WITH_PLUGINMANAGER=ON ^
-DCORRADE_WITH_TESTSUITE=ON ^
-DCORRADE_UTILITY_USE_ANSI_COLORS=ON ^
%COMPILER_EXTRA% -G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build Magnum
git clone --depth 1 git://github.com/mosra/magnum.git || exit /b
git clone --depth 1 https://github.com/mosra/magnum.git || exit /b
cd magnum || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DCMAKE_PREFIX_PATH=%APPVEYOR_BUILD_FOLDER%/SDL ^
-DBUILD_DEPRECATED=OFF ^
-DBUILD_STATIC=%BUILD_STATIC% ^
-DWITH_AUDIO=OFF ^
-DWITH_DEBUGTOOLS=OFF ^
-DWITH_GL=ON ^
-DWITH_MESHTOOLS=ON ^
-DWITH_PRIMITIVES=ON ^
-DWITH_SCENEGRAPH=ON ^
-DWITH_SHADERS=ON ^
-DWITH_TEXT=OFF ^
-DWITH_TEXTURETOOLS=ON ^
-DWITH_TRADE=ON ^
-DWITH_VK=OFF ^
-DWITH_SDL2APPLICATION=ON ^
-DWITH_GLFWAPPLICATION=ON ^
-DWITH_WINDOWLESSWGLAPPLICATION=ON ^
-G Ninja || exit /b
-DMAGNUM_BUILD_STATIC=%BUILD_STATIC% %STATIC_PLUGIN_PATH% ^
-DMAGNUM_WITH_AUDIO=OFF ^
-DMAGNUM_WITH_DEBUGTOOLS=OFF ^
-DMAGNUM_WITH_GL=ON ^
-DMAGNUM_WITH_MATERIALTOOLS=ON ^
-DMAGNUM_WITH_MESHTOOLS=ON ^
-DMAGNUM_WITH_PRIMITIVES=ON ^
-DMAGNUM_WITH_SCENEGRAPH=ON ^
-DMAGNUM_WITH_SCENETOOLS=ON ^
-DMAGNUM_WITH_SHADERS=ON ^
-DMAGNUM_WITH_SHADERTOOLS=OFF ^
-DMAGNUM_WITH_TEXT=ON ^
-DMAGNUM_WITH_TEXTURETOOLS=ON ^
-DMAGNUM_WITH_TRADE=ON ^
-DMAGNUM_WITH_VK=OFF ^
-DMAGNUM_WITH_SDL2APPLICATION=ON ^
-DMAGNUM_WITH_GLFWAPPLICATION=ON ^
-DMAGNUM_WITH_WINDOWLESSWGLAPPLICATION=ON ^
-DMAGNUM_WITH_ANYIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_ANYSCENECONVERTER=ON ^
-DMAGNUM_WITH_ANYSCENEIMPORTER=ON ^
-DMAGNUM_WITH_TGAIMPORTER=ON ^
%COMPILER_EXTRA% -G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build Magnum Plugins
git clone --depth 1 https://github.com/mosra/magnum-plugins.git || exit /b
cd magnum-plugins || exit /b
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DMAGNUM_BUILD_STATIC=%BUILD_STATIC% ^
-DMAGNUM_WITH_BCDECIMAGECONVERTER=ON ^
-DMAGNUM_WITH_DDSIMPORTER=ON ^
-DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON ^
-DMAGNUM_WITH_GLTFIMPORTER=ON ^
-DMAGNUM_WITH_GLTFSCENECONVERTER=ON ^
-DMAGNUM_WITH_KTXIMAGECONVERTER=ON ^
-DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=%EXCEPT_MSVC2017% ^
-DMAGNUM_WITH_PRIMITIVEIMPORTER=ON ^
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBTRUETYPEFONT=ON ^
%COMPILER_EXTRA% -G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
cd .. && cd ..
rem Build. BUILD_GL_TESTS is enabled just to be sure, it should not be needed
rem by any plugin.
rem Build. Again forcing -DCMAKE_POLICY_VERSION_MINIMUM=3.5 because the
rem pybind11 CMake config files also require just 3.4 now.
mkdir build && cd build || exit /b
cmake .. ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DCMAKE_PREFIX_PATH=%APPVEYOR_BUILD_FOLDER%/SDL ^
-DPYBIND11_PYTHON_VERSION=3.6 ^
-DWITH_PYTHON=ON ^
-G Ninja || exit /b
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^
-DPYBIND11_PYTHON_VERSION=3.%PYTHON% ^
-DMAGNUM_WITH_PYTHON=ON ^
-DMAGNUM_BUILD_TESTS=ON ^
%COMPILER_EXTRA% %BINDINGS_EXTRA% -G Ninja || exit /b
cmake --build . || exit /b
cmake --build . --target install || exit /b
rem Test
set CORRADE_TEST_COLOR=ON
rem On Windows, if an assertion or other issue happens, A DIALOG WINDOWS POPS
rem UP FROM THE CONSOLE. And then, for fucks sake, IT WAITS ENDLESSLY FOR YOU
rem TO CLOSE IT!! Such behavior is utterly stupid in a non-interactive setting
rem such as on this very CI, so I'm setting a timeout to 60 seconds to avoid
rem the CI job being stuck for an hour if an assertion happens. CTest's default rem timeouts is somehow 10M seconds, which is as useful as nothing at all.
ctest -V -E GLTest --timeout 60 || exit /b
rem Verify the setuptools install
cd src/python || exit /b
python setup.py install --root="%APPVEYOR_BUILD_FOLDER%/install" || exit /b
rem Run tests & gather coverage
rem Run python tests & gather coverage
cd ../../../src/python/corrade || exit /b
coverage run -m unittest -v && cp .coverage ../.coverage.corrade || exit /b
coverage run -m unittest -v || exit /b
cp .coverage ../.coverage.corrade || exit /b
cd ../magnum || exit /b
set MAGNUM_SKIP_GL_TESTS=ON
coverage run -m unittest -v && cp .coverage ../.coverage.magnum || exit /b
coverage run -m unittest -v || exit /b
cp .coverage ../.coverage.magnum || exit /b
rem Test docstring validity
cd ../../../doc/python || exit /b

143
package/ci/appveyor.yml

@ -5,70 +5,149 @@ environment:
- TARGET: desktop
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
APPVEYOR_JOB_NAME: windows-gl-msvc2017
PYTHON: 36
APPVEYOR_JOB_NAME: windows-msvc2017
PYTHON: 6
PYBIND: 2.3.0
- TARGET: desktop
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
APPVEYOR_JOB_NAME: windows-gl-msvc2019
PYTHON: 36
APPVEYOR_JOB_NAME: windows-msvc2019
# Python 3.7 was removed from 2019 and 2022 images sometimes in 2025
PYTHON: 8
PYBIND: 2.3.0
- TARGET: desktop
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: windows-msvc2022
PYTHON: 8
PYBIND: 2.9.0 # first supporting MSVC 2022
- TARGET: desktop
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
APPVEYOR_JOB_NAME: windows-static-msvc2019
BUILD_STATIC: ON
PYTHON: 36
- TARGET: desktop-gles
TARGET_GLES2: ON
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
APPVEYOR_JOB_NAME: windows-gles2-msvc2017
PYTHON: 36
PYTHON: 8
PYBIND: 2.3.0
# The static build puts everything including Sdl2Application together so it
# needs the SDL DLL directory as well. Here also making one relative to
# verify it gets correctly turned into absolute -- the built modules are in
# C:/projects/magnum-bindings/build/src/python, and the DLLs in
# C:/projects/magnum-bindings/SDL/lib/x64
BINDINGS_EXTRA: "-DMAGNUM_PYTHON_BINDINGS_DLL_PATH=C:/projects/magnum-bindings/deps/bin;../../../SDL/lib/x64"
- TARGET: desktop
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: windows-static-msvc2022
BUILD_STATIC: ON
PYTHON: 8
PYBIND: 2.9.0 # first supporting MSVC 2022
# The static build puts everything including Sdl2Application together so it
# needs the SDL DLL directory as well. Here making the other one relative
# to verify both get correctly turned into absolute -- the built modules
# are in C:/projects/magnum-bindings/build/src/python, and the DLLs in
# C:/projects/magnum-bindings/deps/bin
BINDINGS_EXTRA: "-DMAGNUM_PYTHON_BINDINGS_DLL_PATH=../../../deps/bin;C:/projects/magnum-bindings/SDL/lib/x64"
# clang-cl crashes with pybind11, "Illegal instruction" and
# lld-link: warning: ignoring unknown argument '-flto'
# LLVM ERROR: Associative COMDAT symbol '??0type_error@pybind11@@QEAA@PEBD@Z' does not exist.
# TODO: retry once their changelog says something about clang-cl being fixed
#- TARGET: desktop
#COMPILER: msvc-clang
#APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
#APPVEYOR_JOB_NAME: windows-msvc2019-clang
#PYTHON: 8
#PYBIND: 2.7.0
#- TARGET: desktop
#COMPILER: msvc-clang
#APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
#APPVEYOR_JOB_NAME: windows-msvc2022-clang
#PYTHON: 8
#PYBIND: 2.9.0 # first supporting MSVC 2022
- TARGET: desktop
COMPILER: msvc
# Same reasoning as in Corrade for /EHsc
COMPILER_EXTRA: -DCMAKE_CXX_FLAGS="/permissive- /EHsc" -DCORRADE_MSVC_COMPATIBILITY=OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
APPVEYOR_JOB_NAME: windows-conforming-msvc2019
PYTHON: 8
PYBIND: 2.3.0
- TARGET: desktop
COMPILER: msvc
# Not playing with fire and using /EHsc on 2022 as well
COMPILER_EXTRA: -DCMAKE_CXX_FLAGS="/permissive- /EHsc" -DCORRADE_MSVC_COMPATIBILITY=OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: windows-conforming-msvc2022
PYTHON: 8
PYBIND: 2.9.0 # first supporting MSVC 2022
- TARGET: desktop-gles
TARGET_GLES2: ON
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
APPVEYOR_JOB_NAME: windows-gles2-msvc2019
PYTHON: 36
PYTHON: 8
PYBIND: 2.3.0
- TARGET: desktop-gles
TARGET_GLES2: OFF
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
APPVEYOR_JOB_NAME: windows-gles3-msvc2017
PYTHON: 36
TARGET_GLES2: ON
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: windows-gles2-msvc2022
PYTHON: 8
PYBIND: 2.9.0 # first supporting MSVC 2022
- TARGET: desktop-gles
TARGET_GLES2: OFF
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
APPVEYOR_JOB_NAME: windows-gles3-msvc2019
PYTHON: 36
notifications:
- provider: Webhook
url: https://webhooks.gitter.im/e/415ae90928ba0dbd3df4
on_build_success: false
on_build_failure: true
on_build_status_changed: true
PYTHON: 8
PYBIND: 2.3.0
- TARGET: desktop-gles
TARGET_GLES2: OFF
COMPILER: msvc
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: windows-gles3-msvc2022
PYTHON: 8
PYBIND: 2.9.0 # first supporting MSVC 2022
install:
- cinst ninja
# Ninja. `cinst ninja` started 503ing in late November 2019 and wasn't really
# reliable before either. So install by hand, as that's reliable always.
- IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\ninja-win.zip appveyor DownloadFile https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip
- 7z x ninja-win.zip -oC:/tools
- set PATH=C:/tools;%PATH%
# Codecov uploader
- appveyor DownloadFile https://uploader.codecov.io/latest/windows/codecov.exe -FileName C:/tools/codecov.exe
# pip is in Scripts
- set PATH=C:/tools/ninja;C:/Python%PYTHON%-x64;C:/Python%PYTHON%-x64/Scripts;%PATH%
- pip3 install coverage codecov
- set PATH=C:/tools/ninja;C:/Python3%PYTHON%-x64;C:/Python3%PYTHON%-x64/Scripts;%PATH%
- pip3 install coverage
- IF NOT "%BUILD_STATIC%" == "ON" set BUILD_STATIC=OFF
# The fugly \=/ magic is to replace backward slashes with forward so CMake
# doesn't treat those as escape characters
- IF "%BUILD_STATIC%" == "ON" set "STATIC_PLUGIN_PATH=-DMAGNUM_PLUGINS_DIR=%APPVEYOR_BUILD_FOLDER:\=/%/deps/bin/magnum"
# pybind11. Built in the CI script.
- IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\v2.3.0.zip appveyor DownloadFile https://github.com/pybind/pybind11/archive/v2.3.0.zip
- 7z x v2.3.0.zip
- IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\v%PYBIND%.zip appveyor DownloadFile https://github.com/pybind/pybind11/archive/v%PYBIND%.zip
- 7z x v%PYBIND%.zip
# SDL2
- IF "%TARGET%" == "desktop" IF "%COMPILER%" == "msvc" IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\SDL2-devel-2.0.9-VC.zip appveyor DownloadFile http://www.libsdl.org/release/SDL2-devel-2.0.9-VC.zip
- IF "%TARGET%" == "desktop" IF "%COMPILER%" == "msvc" 7z x SDL2-devel-2.0.9-VC.zip && ren SDL2-2.0.9 SDL
- IF "%TARGET%" == "desktop" IF "%COMPILER:~0,4%" == "msvc" IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\SDL2-devel-2.0.9-VC.zip appveyor DownloadFile https://www.libsdl.org/release/SDL2-devel-2.0.9-VC.zip
- IF "%TARGET%" == "desktop" IF "%COMPILER:~0,4%" == "msvc" 7z x SDL2-devel-2.0.9-VC.zip && ren SDL2-2.0.9 SDL
# GLFW
- IF "%TARGET%" == "desktop" IF NOT EXIST %APPVEYOR_BUILD_FOLDER%\glfw-3.2.1.bin.WIN64.zip appveyor DownloadFile https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.bin.WIN64.zip
- IF "%TARGET%" == "desktop" 7z x glfw-3.2.1.bin.WIN64.zip && ren glfw-3.2.1.bin.WIN64 glfw && mkdir deps && mkdir deps\lib && mkdir deps\bin && mkdir deps\include && xcopy /e glfw\include\* deps\include\
- IF "%TARGET%" == "desktop" IF "%COMPILER%" == "msvc" copy glfw\lib-vc2015\glfw3.dll deps\bin\ && copy glfw\lib-vc2015\glfw3dll.lib deps\lib\glfw3.lib
- IF "%TARGET%" == "desktop" IF "%COMPILER:~0,4%" == "msvc" copy glfw\lib-vc2015\glfw3.dll deps\bin\ && copy glfw\lib-vc2015\glfw3dll.lib deps\lib\glfw3.lib
# meshoptimizer for MSVC 2022, 2019 and clang-cl; MinGW. MSVC 2017 doesn't work
# with the 2019 build unfortunately, and can't build it because of
# https://github.com/actions/runner-images/issues/3294
- IF "%COMPILER:~0,4%" == "msvc" appveyor DownloadFile https://ci.magnum.graphics/meshoptimizer-0.21-windows-2019-debug.zip && 7z x meshoptimizer-0.21-windows-2019-debug.zip -o%APPVEYOR_BUILD_FOLDER%\deps
- IF "%COMPILER%" == "mingw" appveyor DownloadFile https://ci.magnum.graphics/meshoptimizer-0.21-windows-mingw.zip && 7z x meshoptimizer-0.21-windows-mingw.zip -o%APPVEYOR_BUILD_FOLDER%\deps
build_script:
- IF "%TARGET%" == "desktop" IF "%COMPILER%" == "msvc" call package\ci\appveyor-desktop.bat
- IF "%TARGET%" == "desktop" IF "%COMPILER:~0,4%" == "msvc" call package\ci\appveyor-desktop.bat
- IF "%TARGET%" == "desktop-gles" call package\ci\appveyor-desktop-gles.bat
cache:

499
package/ci/circleci.yml

@ -0,0 +1,499 @@
version: 2.1
orbs:
# Version 3.2.4 is the "new" uploader, but it's a 50 MB Node.js *binary* and
# doesn't work on ARM64 Linux (or ARM Macs, or FreeBSD for that matter) and
# nobody seems to care. Issues opened since Septembe 2021:
# https://github.com/codecov/uploader/issues/347
# https://github.com/codecov/uploader/issues/523
# https://github.com/codecov/uploader/issues/849
# The old 1.1.1 still seems to work even though codecov got removed from pip
# on 2023-04-14.
codecov: codecov/codecov@1.1.1
executors:
ubuntu-18_04:
docker:
- image: ubuntu:bionic-20220427
# As of November 7, 2025, M4 is the default, and the oldest version there is
# 14.3.1.
xcode-14_3:
macos:
xcode: 14.3.1
arm64:
machine:
image: ubuntu-2004:2023.07.1
resource_class: arm.medium
commands:
install-base-linux:
parameters:
extra:
type: string
default: ""
sudo:
type: string
default: ""
steps:
- run:
name: Update apt and install base packages
# Git is needed always for cloning Corrade etc
command: |
<< parameters.sudo >> apt update
if [[ "$CMAKE_CXX_FLAGS" == *"--coverage"* ]]; then export LCOV_PACKAGES="lcov curl"; fi
<< parameters.sudo >> apt install -y git ninja-build $LCOV_PACKAGES << parameters.extra >>
install-base-macos:
parameters:
extra:
type: string
default: ""
steps:
- run:
name: Install base packages
# As usual, homebrew takes five minutes to update and then explodes in
# a spectacular way. How is this acceptable?!
command: |
if [[ "$CMAKE_CXX_FLAGS" == *"--coverage"* ]]; then export LCOV_PACKAGES="lcov"; fi
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja $LCOV_PACKAGES << parameters.extra >>
- run:
name: Uninstall the pyenv crap and install plain python instead
# Otherwise the numpy installed by homebrew is unreachable by actual
# user-side python. THIS ALL USED TO WORK BUT NOT ANYMORE. They
# subsequently added `brew pyenv-sync` in an attempt to fix this trash
# fire, but that damn thing doesn't work at all either. Fuck it, then.
# https://github.com/orgs/Homebrew/discussions/4664
# https://github.com/Homebrew/brew/issues/17563
command: |
HOMEBREW_NO_AUTO_UPDATE=1 brew remove pyenv
HOMEBREW_NO_AUTO_UPDATE=1 brew install python
rm -r ~/.pyenv
install-gcc-4_8:
steps:
- run:
name: Install GCC 4.8
# For some reason, CMake needs a working C compiler, so provice CC as
# well for the case when default gcc isn't installed.
command: |
apt install -y g++-4.8
echo 'export CC=gcc-4.8' >> $BASH_ENV
echo 'export CXX=g++-4.8' >> $BASH_ENV
install-cmake:
parameters:
version:
type: string
sudo:
type: string
default: ""
steps:
- run:
name: Install CMake << parameters.version >>
command: |
version_short=<< parameters.version >>
version_short="${version_short%.*}"
<< parameters.sudo >> apt install -y wget
mkdir -p $HOME/cmake && cd $HOME/cmake
wget -nc --no-check-certificate https://cmake.org/files/v$version_short/cmake-<< parameters.version >>-Linux-x86_64.tar.gz
tar --strip-components=1 -xzf cmake-<< parameters.version >>-Linux-x86_64.tar.gz
echo 'export PATH=$HOME/cmake/bin:$PATH' >> $BASH_ENV
source $BASH_ENV
cmake --version | grep << parameters.version >>
ctest --version | grep << parameters.version >>
install-python-3_6:
# Can't use the python3.6 docker image because there I can't install GCC
# 4.8. Loosely based on https://gist.github.com/monkut/c4c07059444fd06f3f8661e13ccac619
# The deadsnakes PPA no longer supports 16.04, so this repo builds against
# 18.04.
steps:
- run:
name: Install Python 3.6 and numpy
# The software-properties-common need to be installed in order to have
# apt-add-repository. Sigh, adding a repository should be a core
# feature ffs!
#
# Also, "Press ENTER to continue." Are we still in the DOS days?!
#
# Setting up 3.6 as the default is OF COURSE one command more than
# would be acceptable, but am I surprised on this distro?!
command: |
apt install -y software-properties-common
echo -e "\n" | add-apt-repository ppa:deadsnakes/ppa
apt update
apt install -y python3.6 python3.6-dev python3-pip
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 10
python3 --version | grep 3.6
python3 -m pip install pip --upgrade
python3 -m pip install wheel
pip3 install numpy
install-pybind11:
parameters:
version:
type: string
default: "2.3.0"
steps:
- run:
name: Install Pybind11 << parameters.version >>
command: |
cd $HOME
wget --no-clobber https://github.com/pybind/pybind11/archive/v<< parameters.version >>.tar.gz
tar -xzf v<< parameters.version >>.tar.gz
cd pybind11-<< parameters.version >>
mkdir -p build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/pybind11 \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DPYBIND11_TEST=OFF \
-G Ninja
ninja install
install-swiftshader-gles:
parameters:
build:
type: string
steps:
- run:
name: Install SwiftShader GLES
# Zip from https://github.com/mosra/magnum-ci/tree/swiftshader and
# self-hosted because GH Actions would make it too simple for people if
# you could just download the artifacts directly, right? RIGHT?
command: |
mkdir -p $HOME/swiftshader && cd $HOME/swiftshader
wget https://ci.magnum.graphics/swiftshader-gles-r5904.14dcbed947-<< parameters.build >>.zip
unzip swiftshader-gles-r5904.14dcbed947-<< parameters.build >>.zip
install-meshoptimizer:
steps:
- run:
name: Install meshoptimizer
# few commits after 0.14 with a fix for old Apple Clang
command: |
export MESHOPTIMIZER_VERSION=97c52415c6d29f297a76482ddde22f739292446d
mkdir -p $HOME/meshoptimizer && cd $HOME/meshoptimizer
wget -nc --no-check-certificate https://github.com/zeux/meshoptimizer/archive/$MESHOPTIMIZER_VERSION.tar.gz
tar --strip-components=1 -xzf $MESHOPTIMIZER_VERSION.tar.gz
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-G Ninja
ninja install
build:
parameters:
script:
type: string
steps:
- run:
name: Install coverage
command: pip3 install coverage
- checkout
- run:
name: Build & test
command: |
if [ "$BUILD_STATIC" != "ON" ]; then export BUILD_STATIC=OFF; fi
if [ "$BUILD_DEPRECATED" != "OFF" ]; then export BUILD_DEPRECATED=ON; fi
./package/ci/<< parameters.script >>
# Official docs say "token not needed for public repos", in reality not using
# the token is "extremely flakey". What's best is that if the upload fails,
# the damn thing exits with a success error code, and nobody cares:
# https://github.com/codecov/codecov-circleci-orb/issues/139
upload-codecov:
parameters:
file:
type: string
steps:
# Second best thing is that the codecov/upload helper takes a `token`
# parameter. But the token parameter is an ENVIRONMENT VARIABLE NAME!! So
# one just *can't* pass the token there. It got changed arbitrarily in
# https://github.com/codecov/codecov-circleci-orb/pull/93 "because
# CircleCI docs suggested so", yet all codecov docs suggest just
# commiting that token directly to the YML files because "it's fine". So
# if it's fine, why do I have to suffer like this?!
- run:
name: Set codecov upload token because everything is a dumpster fire
# An icing on the cake is that CircleCI commands don't allow setting
# `environment` for `commands`, only for `jobs`, so I have to do that
# via bash, and because the environment isn't passsed from a run to
# run, use the BASH_ENV hack. Mmm. Technology.
command: |
echo 'export CODECOV_TOKEN=ade9e2f1-d6d7-45cb-a292-c5bb1ad45be9' >> "$BASH_ENV"
- codecov/upload:
file: << parameters.file >>
lcov:
parameters:
extra:
type: string
default: ""
steps:
- run:
name: Collect code coverage
# Keep in sync with PKBUILD-coverage, please
command: |
lcov << parameters.extra >> --directory . --capture --output-file coverage.info > /dev/null
lcov << parameters.extra >> --extract coverage.info "*/src/python/*" "*/src/Corrade/*" "*/src/Magnum/*" --output-file coverage.info > /dev/null
cd src/python && coverage combine
- upload-codecov:
file: coverage.info
jobs:
linux-gl:
executor: ubuntu-18_04
environment:
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: GLX
# It crashes (OOM, probably) with the default setting
NINJA_JOBS: -j2
steps:
# libidn11 needed by CMake
- install-base-linux:
extra: libidn11 libgl1-mesa-dev libsdl2-dev libglfw3-dev
- install-gcc-4_8
- install-cmake:
version: "3.5.2"
- install-python-3_6
- install-pybind11
- install-meshoptimizer
- build:
script: unix-desktop.sh
- lcov:
extra: --gcov-tool /usr/bin/gcov-4.8
linux-arm64:
executor: arm64
environment:
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: GLX
steps:
# Not installing the old GCC 4.8 and CMake 3.5 to speed up. These are
# tested more than enough on other jobs. Machine executors need sudo.
- install-base-linux:
extra: gcc cmake libgl1-mesa-dev libsdl2-dev libglfw3-dev libpython3-dev
sudo: sudo
# 2.3.0 doesn't work with Python 3.11, this one should
- install-pybind11:
version: "2.11.1"
- run:
name: Install numpy
command: pip3 install numpy
- install-meshoptimizer
- build:
script: unix-desktop.sh
- lcov
linux-gles2:
executor: ubuntu-18_04
environment:
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: EGL
# STUPID yml interprets unquoted ON as a boolean
TARGET_GLES2: "ON"
# It crashes (OOM, probably) with the default setting
NINJA_JOBS: -j2
steps:
# libidn11 needed by CMake
- install-base-linux:
extra: libidn11 libsdl2-dev libglfw3-dev wget unzip
- install-gcc-4_8
- install-cmake:
version: "3.5.2"
- install-python-3_6
- install-pybind11
- install-meshoptimizer
- install-swiftshader-gles:
build: ubuntu-18.04
- build:
script: unix-desktop-gles.sh
- lcov:
extra: --gcov-tool /usr/bin/gcov-4.8
linux-gles3:
executor: ubuntu-18_04
environment:
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: EGL
# STUPID yml interprets unquoted OFF as a boolean
TARGET_GLES2: "OFF"
# It crashes (OOM, probably) with the default setting
NINJA_JOBS: -j2
steps:
# libidn11 needed by CMake
- install-base-linux:
extra: libidn11 libsdl2-dev libglfw3-dev wget unzip
- install-gcc-4_8
- install-cmake:
version: "3.5.2"
- install-python-3_6
- install-pybind11
- install-meshoptimizer
- install-swiftshader-gles:
build: ubuntu-18.04
- build:
script: unix-desktop-gles.sh
- lcov:
extra: --gcov-tool /usr/bin/gcov-4.8
linux-static:
executor: ubuntu-18_04
environment:
# STUPID yml interprets unquoted ON as a boolean
# https://stackoverflow.com/questions/53648244/specifying-the-string-value-yes-in-a-yaml-property
BUILD_STATIC: "ON"
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: GLX
# It crashes (OOM, probably) with the default setting
NINJA_JOBS: -j2
steps:
# libidn11 needed by CMake
- install-base-linux:
extra: libidn11 libsdl2-dev libglfw3-dev
- install-gcc-4_8
- install-cmake:
version: "3.5.2"
- install-python-3_6
- install-pybind11
- install-meshoptimizer
- build:
script: unix-desktop.sh
- lcov:
extra: --gcov-tool /usr/bin/gcov-4.8
linux-nondeprecated:
executor: ubuntu-18_04
environment:
# STUPID yml interprets unquoted OFF as a boolean
BUILD_DEPRECATED: "OFF"
CMAKE_CXX_FLAGS: --coverage
PLATFORM_GL_API: GLX
# It crashes (OOM, probably) with the default setting
NINJA_JOBS: -j2
steps:
# libidn11 needed by CMake
- install-base-linux:
extra: libidn11 libgl1-mesa-dev libsdl2-dev libglfw3-dev
- install-gcc-4_8
- install-cmake:
version: "3.5.2"
- install-python-3_6
- install-pybind11
- install-meshoptimizer
- build:
script: unix-desktop.sh
- lcov:
extra: --gcov-tool /usr/bin/gcov-4.8
macos-gl:
executor: xcode-14_3
environment:
# Make libc++ remove transitive includes, both for faster build times and
# to detect if we're missing a transitive include. Works with libc++ 16+,
# which is used by Xcode 15 (i.e., will get used on the next CircleCI
# executor update).
CMAKE_CXX_FLAGS: --coverage -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES
PLATFORM_GL_API: CGL
steps:
- install-base-macos:
extra: sdl2 glfw wget numpy pybind11
- install-meshoptimizer
- build:
script: unix-desktop.sh
# The 14.3 image seems to have the new lcov, which is very picky and throws
# errors about a ton of little things, 14.0.1 and older didn't
- lcov:
extra: --ignore-errors inconsistent
macos-gles3:
executor: xcode-14_3
environment:
# Make libc++ remove transitive includes, both for faster build times and
# to detect if we're missing a transitive include. Works with libc++ 16+,
# which is used by Xcode 15 (i.e., will get used on the next CircleCI
# executor update).
CMAKE_CXX_FLAGS: --coverage -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES
PLATFORM_GL_API: EGL
# STUPID yml interprets unquoted OFF as a boolean
TARGET_GLES2: "OFF"
steps:
- install-base-macos:
extra: sdl2 glfw wget numpy pybind11
- install-swiftshader-gles:
build: macos12-arm64
- install-meshoptimizer
- build:
script: unix-desktop-gles.sh
# The 14.3 image seems to have the new lcov, which is very picky and throws
# errors about a ton of little things, 14.0.1 and older didn't
- lcov:
extra: --ignore-errors inconsistent
macos-static:
executor: xcode-14_3
environment:
# STUPID yml interprets unquoted ON as a boolean
BUILD_STATIC: "ON"
# Make libc++ remove transitive includes, both for faster build times and
# to detect if we're missing a transitive include. Works with libc++ 16+,
# which is used by Xcode 15 (i.e., will get used on the next CircleCI
# executor update).
CMAKE_CXX_FLAGS: --coverage -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES
PLATFORM_GL_API: CGL
steps:
- install-base-macos:
extra: sdl2 glfw wget numpy pybind11
- install-meshoptimizer
- build:
script: unix-desktop.sh
# The 14.3 image seems to have the new lcov, which is very picky and throws
# errors about a ton of little things, 14.0.1 and older didn't
- lcov:
extra: --ignore-errors inconsistent
workflows:
version: 2
build:
# While there's no actual execution or data dependency between the jobs,
# this is done in order to reduce unnecessary credit usage. The GL and
# non-deprecated Linux builds are taken as the main sanity checks. Only if
# they pass, the rest of the jobs gets gradually executed, with further
# dependencies especially for the macOS jobs that take the most credits.
jobs:
- linux-gl
- linux-nondeprecated
- linux-arm64:
requires:
- linux-gl
- linux-nondeprecated
- linux-gles2:
requires:
- linux-gl
- linux-nondeprecated
- linux-gles3:
requires:
- linux-gl
- linux-nondeprecated
- linux-static:
requires:
- linux-gl
- linux-nondeprecated
- macos-gl:
requires:
- linux-arm64
- linux-gl
- linux-nondeprecated
- macos-gles3:
requires:
- linux-gles3
- macos-gl
- macos-static:
requires:
- linux-static
- macos-gl

8
package/ci/codecov.yml

@ -1,9 +1,9 @@
fixes:
# The src/python/magnum/__init__.py is copied to cmake's build dir together
# with # setup.py next to the C++ binaries and the test is done from here.
# with setup.py next to the C++ binaries and the test is done from here.
# Python's coverage.py reports an absolute path to it, which means a simple
# "build/src/python/::src/python/" won't suffice. This is hardcoded to Travis
# "build/src/python/::src/python/" won't suffice. This is hardcoded to CircleCI
# Linux / macOS and AppVeyor build paths so let's hope these won't change.
- "/home/travis/build/mosra/magnum-bindings/build/src/python/::src/python/"
- "/Users/travis/build/mosra/magnum-bindings/build/src/python/::src/python/"
- "/root/project/build/src/python/::src/python/"
- "/Users/distiller/project/build/src/python/::src/python/"
- "C:/projects/magnum-bindings/build/src/python/::src/python/"

13
package/ci/setup-pybind11.sh

@ -1,13 +0,0 @@
set -e
wget --no-clobber https://github.com/pybind/pybind11/archive/v2.3.0.tar.gz && tar -xzf v2.3.0.tar.gz
cd pybind11-2.3.0
mkdir -p build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/pybind11 \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DPYBIND11_TEST=OFF \
-G Ninja
ninja install

80
package/ci/travis-desktop-gles.sh

@ -1,80 +0,0 @@
#!/bin/bash
set -ev
# Corrade
git clone --depth 1 git://github.com/mosra/corrade.git
cd corrade
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_DEPRECATED=$BUILD_DEPRECATED \
-DWITH_INTERCONNECT=OFF \
-DWITH_PLUGINMANAGER=ON \
-DWITH_TESTSUITE=OFF \
-G Ninja
ninja install
cd ../..
# Magnum
git clone --depth 1 git://github.com/mosra/magnum.git
cd magnum
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DEGL_LIBRARY=$HOME/swiftshader/libEGL.so \
-DOPENGLES2_LIBRARY=$HOME/swiftshader/libGLESv2.so \
-DOPENGLES3_LIBRARY=$HOME/swiftshader/libGLESv2.so \
-DCMAKE_INSTALL_RPATH=$HOME/swiftshader \
-DTARGET_GLES=ON \
-DTARGET_GLES2=$TARGET_GLES2 \
-DWITH_AUDIO=OFF \
-DWITH_DEBUGTOOLS=OFF \
-DWITH_GL=ON \
-DWITH_MESHTOOLS=ON \
-DWITH_PRIMITIVES=ON \
-DWITH_SCENEGRAPH=ON \
-DWITH_SHADERS=ON \
-DWITH_TEXT=OFF \
-DWITH_TEXTURETOOLS=OFF \
-DWITH_TRADE=ON \
-DWITH_VK=OFF \
-DWITH_WINDOWLESSEGLAPPLICATION=ON \
-DBUILD_DEPRECATED=OFF \
-G Ninja
ninja install
cd ../..
# Build the thing
mkdir build && cd build
cmake .. \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=$HOME/pybind11 \
-DEGL_LIBRARY=$HOME/swiftshader/libEGL.so \
-DOPENGLES2_LIBRARY=$HOME/swiftshader/libGLESv2.so \
-DOPENGLES3_LIBRARY=$HOME/swiftshader/libGLESv2.so \
-DCMAKE_INSTALL_RPATH=$HOME/swiftshader \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DWITH_PYTHON=ON \
-G Ninja
ninja
# Verify the setuptools install
cd src/python
python3 setup.py install --root="$TRAVIS_BUILD_DIR/install" --prefix=/usr
# Run tests & gather coverage
cd ../../../src/python/corrade
coverage run -m unittest -v && cp .coverage ../.coverage.corrade
cd ../magnum
coverage run -m unittest -v && cp .coverage ../.coverage.magnum
# Test docstring validity
cd ../../../doc/python
PYTHONPATH="$TRAVIS_BUILD_DIR/build/src/python" python3 -m doctest -v *.rst

74
package/ci/travis-desktop.sh

@ -1,74 +0,0 @@
#!/bin/bash
set -ev
# Corrade
git clone --depth 1 git://github.com/mosra/corrade.git
cd corrade
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_DEPRECATED=OFF \
-DBUILD_STATIC=$BUILD_STATIC \
-DWITH_INTERCONNECT=OFF \
-DWITH_PLUGINMANAGER=ON \
-DWITH_TESTSUITE=OFF \
-G Ninja
ninja install
cd ../..
# Magnum
git clone --depth 1 git://github.com/mosra/magnum.git
cd magnum
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_DEPRECATED=OFF \
-DBUILD_STATIC=$BUILD_STATIC \
-DWITH_AUDIO=OFF \
-DWITH_DEBUGTOOLS=OFF \
-DWITH_GL=ON \
-DWITH_MESHTOOLS=ON \
-DWITH_PRIMITIVES=ON \
-DWITH_SCENEGRAPH=ON \
-DWITH_SHADERS=ON \
-DWITH_TEXT=OFF \
-DWITH_TEXTURETOOLS=OFF \
-DWITH_TRADE=ON \
-DWITH_VK=OFF \
-DWITH_GLFWAPPLICATION=ON \
-DWITH_SDL2APPLICATION=ON \
-DWITH_WINDOWLESS${PLATFORM_GL_API}APPLICATION=ON \
-G Ninja
ninja install
cd ../..
# Build the thing
mkdir build && cd build
cmake .. \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=$HOME/pybind11 \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DWITH_PYTHON=ON \
-G Ninja
ninja
# Verify the setuptools install
cd src/python
python3 setup.py install --root="$TRAVIS_BUILD_DIR/install" --prefix=/usr
# Run tests & gather coverage
cd ../../../src/python/corrade
coverage run -m unittest -v && cp .coverage ../.coverage.corrade
cd ../magnum
MAGNUM_SKIP_GL_TESTS=ON coverage run -m unittest -v && cp .coverage ../.coverage.magnum
# Test docstring validity
cd ../../../doc/python
PYTHONPATH="$TRAVIS_BUILD_DIR/build/src/python" python3 -m doctest -v *.rst

146
package/ci/travis.yml

@ -1,146 +0,0 @@
addons:
apt:
packages:
- g++-4.8
- libgl1-mesa-dev
- ninja-build
- lcov
- libsdl2-dev
- libglfw3-dev
matrix:
include:
- language: python
python: 3.6
os: linux
dist: xenial
compiler: gcc
env:
- JOBID=linux-gl
- TARGET=desktop
- LCOV_EXTRA_OPTS="--gcov-tool /usr/bin/gcov-4.8"
- language: python
python: 3.6
os: linux
dist: xenial
compiler: gcc
env:
- JOBID=linux-gles2
- TARGET=desktop-gles
- TARGET_GLES2=ON
- CMAKE_CXX_FLAGS="--coverage"
- LCOV_EXTRA_OPTS="--gcov-tool /usr/bin/gcov-4.8"
addons:
apt:
packages:
- g++-4.8
- ninja-build
- lcov
- libsdl2-dev
- libglfw3-dev
- language: python
python: 3.6
os: linux
dist: xenial
compiler: gcc
env:
- JOBID=linux-gles3
- TARGET=desktop-gles
- TARGET_GLES2=OFF
- CMAKE_CXX_FLAGS="--coverage"
- LCOV_EXTRA_OPTS="--gcov-tool /usr/bin/gcov-4.8"
addons:
apt:
packages:
- g++-4.8
- ninja-build
- lcov
- libsdl2-dev
- libglfw3-dev
- language: python
python: 3.6
os: linux
dist: xenial
compiler: gcc
env:
- JOBID=linux-static
- TARGET=desktop
- BUILD_STATIC=ON
- LCOV_EXTRA_OPTS="--gcov-tool /usr/bin/gcov-4.8"
- language: cpp
os: osx
compiler: clang
env:
- JOBID=macos-gl
- TARGET=desktop
- language: cpp
os: osx
compiler: clang
env:
- JOBID=macos-static
- TARGET=desktop
- BUILD_STATIC=ON
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/00ec7a9066bb0fec98f3
on_success: change
on_failure: always
on_start: never
cache:
directories:
- $HOME/swiftshader
- $HOME/cmake
- $HOME/pybind11
install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then export CXX=g++-4.8; fi
- if [ "$BUILD_STATIC" != "ON" ]; then export BUILD_STATIC=OFF; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && ( [ "$TARGET" == "desktop" ] || [ "$TARGET" == "desktop-sanitizers" ] ); then export PLATFORM_GL_API=GLX; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TARGET" == "desktop-gles" ]; then export PLATFORM_GL_API=EGL; fi
# Download CMake 3.1.3 to ensure we're still compatible with it (Travis has
# 3.9 since December 2017). Also, the PATH setting can't be cached, so it's
# separate (bit me two times already). Android needs CMake 3.7, but
# https://gitlab.kitware.com/cmake/cmake/issues/17253 is fixed in 3.9.2, so
# grab that. FindVulkan is since 3.7, in that case just use the system package.
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ ! -e "$HOME/cmake/bin" ]; then cd $HOME ; wget -nc --no-check-certificate https://cmake.org/files/v3.1/cmake-3.1.3-Linux-x86_64.tar.gz && mkdir -p cmake && cd cmake && tar --strip-components=1 -xzf ../cmake-3.1.3-Linux-x86_64.tar.gz && cd $TRAVIS_BUILD_DIR ; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then export PATH=$HOME/cmake/bin:$PATH && cmake --version; fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja; fi
# Code coverage of python bindings
- if [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ]; then pip3 install coverage codecov; fi
# pybind11 (cached). On macOS the version 2.3.0 needs a brew update, the stale
# Travis image has just 2.2.4.
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ ! -e "$HOME/pybind11/bin" ]; then $TRAVIS_BUILD_DIR/package/ci/setup-pybind11.sh; fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install pybind11; fi
# SDL and GLFW on macOS
- if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$TARGET" == "desktop" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install sdl2 glfw; fi
# numpy on macOS -- probably because we updated Homebrew to install new pybind
# (and thus python as well, apparently), the preinstalled numpy is no longer
# visible.
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew upgrade numpy; fi
# SwiftShader on Linux (cached). Taken from Chromium snapshot 587878
# (swiftshader-bin Arch package).
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TARGET" == "desktop-gles" ] && [ ! -e "$HOME/swiftshader/libEGL.so" ]; then cd $HOME ; wget https://ci.magnum.graphics/swiftshader-chromium-587878.tar.gz && mkdir -p swiftshader && cd swiftshader && tar -xzf ../swiftshader-chromium-587878.tar.gz && cd $TRAVIS_BUILD_DIR ; fi
# lcov on macOS
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install lcov; fi
script:
- if [ "$TARGET" == "desktop" ] && ( [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ] ); then ./package/ci/travis-desktop.sh; fi
- if [ "$TARGET" == "desktop-gles" ] && ( [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ] ); then ./package/ci/travis-desktop-gles.sh; fi
# Travis somehow is not able to gather all output, try to force it using this
- sync
after_success:
# Keep in sync with package/archlinux/PKGBUILD-coverage, please
- if [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ]; then lcov $LCOV_EXTRA_OPTS --directory . --capture --output-file coverage.info > /dev/null; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ]; then lcov $LCOV_EXTRA_OPTS --extract coverage.info "*/src/python/*" "*/src/Corrade/*" "*/src/Magnum/*" --output-file coverage.info; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ]; then cd src/python && coverage combine && codecov -X gcov; fi

117
package/ci/unix-desktop-gles.sh

@ -0,0 +1,117 @@
#!/bin/bash
set -ev
# Corrade
git clone --depth 1 https://github.com/mosra/corrade.git
cd corrade
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DCORRADE_WITH_INTERCONNECT=OFF \
-DCORRADE_WITH_PLUGINMANAGER=ON \
-DCORRADE_WITH_TESTSUITE=ON \
-G Ninja
ninja install
cd ../..
# Magnum
git clone --depth 1 https://github.com/mosra/magnum.git
cd magnum
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$HOME/swiftshader;$HOME/pybind11" \
-DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \
-DMAGNUM_TARGET_GLES=ON \
-DMAGNUM_TARGET_GLES2=$TARGET_GLES2 \
-DMAGNUM_WITH_AUDIO=OFF \
-DMAGNUM_WITH_DEBUGTOOLS=OFF \
-DMAGNUM_WITH_GL=ON \
-DMAGNUM_WITH_MATERIALTOOLS=ON \
-DMAGNUM_WITH_MESHTOOLS=ON \
-DMAGNUM_WITH_PRIMITIVES=ON \
-DMAGNUM_WITH_SCENEGRAPH=ON \
-DMAGNUM_WITH_SCENETOOLS=ON \
-DMAGNUM_WITH_SHADERS=ON \
-DMAGNUM_WITH_SHADERTOOLS=OFF \
-DMAGNUM_WITH_TEXT=ON \
-DMAGNUM_WITH_TEXTURETOOLS=OFF \
-DMAGNUM_WITH_TRADE=ON \
-DMAGNUM_WITH_VK=OFF \
-DMAGNUM_WITH_WINDOWLESSEGLAPPLICATION=ON \
-DMAGNUM_WITH_ANYIMAGEIMPORTER=ON \
-DMAGNUM_WITH_ANYSCENECONVERTER=ON \
-DMAGNUM_WITH_ANYSCENEIMPORTER=ON \
-DMAGNUM_WITH_TGAIMPORTER=ON \
-G Ninja
ninja install
cd ../..
# Magnum Plugins
git clone --depth 1 https://github.com/mosra/magnum-plugins.git
cd magnum-plugins
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Release \
`# StanfordSceneConverter uses MeshTools which rely on GL which looks` \
`# for OpenGLES. And the RPATH entry needs to be there as well,` \
`# otherwise it won't load.` \
-DCMAKE_PREFIX_PATH=$HOME/swiftshader \
-DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \
-DMAGNUM_BUILD_STATIC=$BUILD_STATIC \
-DMAGNUM_WITH_BCDECIMAGECONVERTER=ON \
-DMAGNUM_WITH_DDSIMPORTER=ON \
-DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON \
-DMAGNUM_WITH_GLTFIMPORTER=ON \
-DMAGNUM_WITH_GLTFSCENECONVERTER=ON \
-DMAGNUM_WITH_KTXIMAGECONVERTER=ON \
-DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=ON \
-DMAGNUM_WITH_PRIMITIVEIMPORTER=ON \
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON \
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBTRUETYPEFONT=ON \
-G Ninja
ninja install
cd ../..
# Build the thing
mkdir build && cd build
cmake .. \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH="$HOME/swiftshader;$HOME/pybind11" \
-DCMAKE_INSTALL_RPATH="$HOME/deps/lib;$HOME/swiftshader/lib" \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DMAGNUM_WITH_PYTHON=ON \
-DMAGNUM_BUILD_TESTS=ON \
-G Ninja
ninja $NINJA_JOBS
CORRADE_TEST_COLOR=ON ctest -V
# Verify the setuptools install. Not using $CIRCLE_WORKING_DIRECTORY because
# it's ~ and that's not correctly expanded always.
cd src/python
python3 setup.py install --root="$(pwd)/../../install" --prefix=/usr
# Run tests & gather coverage
cd ../../../src/python/corrade
coverage run -m unittest -v
cp .coverage ../.coverage.corrade
cd ../magnum
coverage run -m unittest -v
cp .coverage ../.coverage.magnum
# Test docstring validity
cd ../../../doc/python
# I would use $CIRCLE_WORKING_DIRECTORY, but that's ~ and that's not expanded
# here for some reason
PYTHONPATH="$(pwd)/../../build/src/python" python3 -m doctest -v *.rst

122
package/ci/unix-desktop.sh

@ -0,0 +1,122 @@
#!/bin/bash
set -ev
# Corrade
git clone --depth 1 https://github.com/mosra/corrade.git
cd corrade
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DMAGNUM_BUILD_DEPRECATED=$BUILD_DEPRECATED \
-DCORRADE_BUILD_STATIC=$BUILD_STATIC \
-DCORRADE_WITH_INTERCONNECT=OFF \
-DCORRADE_WITH_PLUGINMANAGER=ON \
-DCORRADE_WITH_TESTSUITE=ON \
-G Ninja
ninja install
cd ../..
# Magnum
git clone --depth 1 https://github.com/mosra/magnum.git
cd magnum
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DMAGNUM_BUILD_DEPRECATED=$BUILD_DEPRECATED \
-DMAGNUM_BUILD_STATIC=$BUILD_STATIC \
-DMAGNUM_WITH_AUDIO=OFF \
-DMAGNUM_WITH_DEBUGTOOLS=OFF \
-DMAGNUM_WITH_GL=ON \
-DMAGNUM_WITH_MATERIALTOOLS=ON \
-DMAGNUM_WITH_MESHTOOLS=ON \
-DMAGNUM_WITH_PRIMITIVES=ON \
-DMAGNUM_WITH_SCENEGRAPH=ON \
-DMAGNUM_WITH_SCENETOOLS=ON \
-DMAGNUM_WITH_SHADERS=ON \
-DMAGNUM_WITH_SHADERTOOLS=OFF \
-DMAGNUM_WITH_TEXT=ON \
-DMAGNUM_WITH_TEXTURETOOLS=OFF \
-DMAGNUM_WITH_TRADE=ON \
-DMAGNUM_WITH_VK=OFF \
-DMAGNUM_WITH_GLFWAPPLICATION=ON \
-DMAGNUM_WITH_SDL2APPLICATION=ON \
-DMAGNUM_WITH_WINDOWLESS${PLATFORM_GL_API}APPLICATION=ON \
-DMAGNUM_WITH_ANYIMAGEIMPORTER=ON \
-DMAGNUM_WITH_ANYSCENECONVERTER=ON \
-DMAGNUM_WITH_ANYSCENEIMPORTER=ON \
-DMAGNUM_WITH_TGAIMPORTER=ON \
-G Ninja
# In case of a static build there's no way for the test to know the plugin
# install directory so we have to hardcode it
if [ "$BUILD_STATIC" == "ON" ]; then
cmake . -DMAGNUM_PLUGINS_DIR=$HOME/deps/lib/magnum
fi
ninja install
cd ../..
# Magnum Plugins
git clone --depth 1 https://github.com/mosra/magnum-plugins.git
cd magnum-plugins
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_INSTALL_RPATH=$HOME/deps/lib \
-DCMAKE_BUILD_TYPE=Release \
-DMAGNUM_BUILD_STATIC=$BUILD_STATIC \
-DMAGNUM_WITH_BCDECIMAGECONVERTER=ON \
-DMAGNUM_WITH_DDSIMPORTER=ON \
-DMAGNUM_WITH_ETCDECIMAGECONVERTER=ON \
-DMAGNUM_WITH_GLTFIMPORTER=ON \
-DMAGNUM_WITH_GLTFSCENECONVERTER=ON \
-DMAGNUM_WITH_KTXIMAGECONVERTER=ON \
-DMAGNUM_WITH_MESHOPTIMIZERSCENECONVERTER=ON \
-DMAGNUM_WITH_PRIMITIVEIMPORTER=ON \
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON \
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBTRUETYPEFONT=ON \
-G Ninja
ninja install
cd ../..
# Build the thing
mkdir build && cd build
cmake .. \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_INSTALL_PREFIX=$HOME/deps \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=$HOME/pybind11 \
-DPYBIND11_PYTHON_VERSION=3.6 \
-DMAGNUM_WITH_PYTHON=ON \
-DMAGNUM_BUILD_TESTS=ON \
-G Ninja
ninja $NINJA_JOBS
CORRADE_TEST_COLOR=ON ctest -V
# Verify the setuptools install. Not using $CIRCLE_WORKING_DIRECTORY because
# it's ~ and that's not correctly expanded always.
cd src/python
python3 setup.py install --root="$(pwd)/../../install" --prefix=/usr
# Run tests & gather coverage
cd ../../../src/python/corrade
coverage run -m unittest -v
cp .coverage ../.coverage.corrade
cd ../magnum
MAGNUM_SKIP_GL_TESTS=ON coverage run -m unittest -v
cp .coverage ../.coverage.magnum
# Test docstring validity
cd ../../../doc/python
# I would use $CIRCLE_WORKING_DIRECTORY, but that's ~ and that's not expanded
# here for some reason
PYTHONPATH="$(pwd)/../../build/src/python" python3 -m doctest -v *.rst

12
package/git/README.md

@ -0,0 +1,12 @@
This dir is used by `src/*/CMakeLists.txt` to run `git describe --match "v*"`.
Because, if it would be run in that directory, on Windows the `--match "v*"`
would get expanded to the `version.h.cmake` file there, causing Git to
obviously not find any such tag. The reason is probably that on Windows the
wildcard expansion is done on the application side and not by the shell, thus
being performed even though CMake docs say `execute_process()` doesn't involve
a shell. This directory is thus dedicated for that operation, *guaranteed* to
never contain any file starting with `v` (or `V` for that matter because,
again, HELLO WINDOWS).
No matter what you do, DON'T put any files starting with `v` or `V` here, or
hell breaks loose again.

24
package/homebrew/magnum-bindings.rb

@ -1,20 +1,30 @@
class MagnumBindings < Formula
desc "`Bindings for the Magnum C++11/C++14 graphics engine"
desc "`Bindings for the Magnum C++11 graphics engine"
homepage "https://magnum.graphics"
# url "https://github.com/mosra/magnum-plugins/archive/v2019.01.tar.gz"
# wget https://github.com/mosra/magnum-plugins/archive/v2019.01.tar.gz -O - | sha256sum
# sha256 "d3adadc5b6d4f2e5061608d67f0c7fa07f0dd078bab4672dc5604ddbcd11ca80"
head "git://github.com/mosra/magnum-bindings.git"
# git describe origin/master, except the `v` prefix
version "2020.06-444-gca5328a"
# Clone instead of getting an archive to have tags for version.h generation
url "https://github.com/mosra/magnum-bindings.git", revision: version.to_str().rpartition('g')[2]
head "https://github.com/mosra/magnum-bindings.git"
depends_on "cmake"
depends_on "cmake" => :build
depends_on "python"
depends_on "python-setuptools" => :build
depends_on "magnum"
depends_on "pybind11" => :build
def install
system "mkdir build"
cd "build" do
system "cmake", "-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_INSTALL_PREFIX=#{prefix}", "-DWITH_PYTHON=ON", ".."
system "cmake",
*std_cmake_args,
# Without this, ARM builds will try to look for dependencies in
# /usr/local/lib and /usr/lib (which are the default locations) instead
# of /opt/homebrew/lib which is dedicated for ARM binaries. Please
# complain to Homebrew about this insane non-obvious filesystem layout.
"-DCMAKE_INSTALL_NAME_DIR:STRING=#{lib}",
"-DMAGNUM_WITH_PYTHON=ON",
".."
system "cmake", "--build", "."
system "cmake", "--build", ".", "--target", "install"
cd "src/python" do

7
package/sync-modules.sh

@ -0,0 +1,7 @@
#!/bin/bash
set -e
dir=$(dirname "$0")
cp $dir/../../corrade/modules/FindCorrade.cmake $dir/../modules/
cp $dir/../../magnum/modules/FindMagnum.cmake $dir/../modules/

8
src/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,7 +24,8 @@
# DEALINGS IN THE SOFTWARE.
#
# On MSVC remove /W3, as we are replacing it with /W4
# On MSVC remove /W3, as we are replacing it with /W4. Could be removed as of
# 3.15 with this: https://cmake.org/cmake/help/latest/policy/CMP0092.html
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
@ -41,7 +43,7 @@ set_directory_properties(PROPERTIES
add_subdirectory(Corrade)
add_subdirectory(Magnum)
if(WITH_PYTHON)
if(MAGNUM_WITH_PYTHON)
add_subdirectory(python)
endif()

20
src/Corrade/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,8 +24,17 @@
# DEALINGS IN THE SOFTWARE.
#
if(WITH_PYTHON)
add_custom_target(CorradePython SOURCES Python.h)
set_target_properties(CorradePython PROPERTIES FOLDER "Corrade/Python")
install(FILES Python.h DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR})
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Corrade/Python")
if(MAGNUM_WITH_PYTHON)
add_custom_target(CorradePython SOURCES PythonBindings.h)
install(FILES PythonBindings.h DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR})
endif()
add_subdirectory(Containers)
if(Corrade_PluginManager_FOUND)
add_subdirectory(PluginManager)
endif()

15
src/Corrade/Containers/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,8 +24,12 @@
# DEALINGS IN THE SOFTWARE.
#
if(WITH_PYTHON)
add_custom_target(CorradeContainersPython SOURCES Python.h)
set_target_properties(CorradeContainersPython PROPERTIES FOLDER "Corrade/Python")
install(FILES Python.h DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}/Containers)
if(MAGNUM_WITH_PYTHON)
set(CorradeContainersPython_HEADERS
OptionalPythonBindings.h
PythonBindings.h
StridedArrayViewPythonBindings.h)
add_custom_target(CorradeContainersPython SOURCES ${CorradeContainersPython_HEADERS})
install(FILES ${CorradeContainersPython_HEADERS} DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}/Containers)
endif()

63
src/Corrade/Containers/OptionalPythonBindings.h

@ -0,0 +1,63 @@
#ifndef Corrade_Containers_OptionalPythonBindings_h
#define Corrade_Containers_OptionalPythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <pybind11/pybind11.h>
#include <Corrade/Containers/Optional.h>
namespace pybind11 { namespace detail {
/* pybind11/stl.h has optional_caster for this, but that relies on a value_type
typedef that Optional doesn't have, so adapting a copy of it, also without
std::is_lvalue_reference<T>::value, which is not a thing here */
template<class T> struct type_caster<Corrade::Containers::Optional<T>> {
using value_conv = make_caster<T>;
template<class T_> static handle cast(T_&& src, const return_value_policy policy, const handle parent) {
if(!src) return none{}.release();
return value_conv::cast(*std::forward<T_>(src), return_value_policy_override<T>::policy(policy), parent);
}
bool load(const handle src, bool convert) {
if(!src) return false;
/* default-constructed value is already empty */
if(src.is_none()) return true;
value_conv inner_caster;
if(!inner_caster.load(src, convert)) return false;
value.emplace(cast_op<T&&>(std::move(inner_caster)));
return true;
}
PYBIND11_TYPE_CASTER(Corrade::Containers::Optional<T>, _("Optional[") + value_conv::name + _("]"));
};
}}
#endif

10
src/Corrade/Containers/Python.h → src/Corrade/Containers/PythonBindings.h

@ -1,9 +1,10 @@
#ifndef Corrade_Containers_Python_h
#define Corrade_Containers_Python_h
#ifndef Corrade_Containers_PythonBindings_h
#define Corrade_Containers_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -45,7 +46,7 @@ template<class T> struct PyArrayViewHolder: std::unique_ptr<T> {
};
template<class T> PyArrayViewHolder<T> pyArrayViewHolder(const T& view, pybind11::object owner) {
return PyArrayViewHolder<T>{new T{view}, owner};
return PyArrayViewHolder<T>{new T{view}, std::move(owner)};
}
}}
@ -53,4 +54,3 @@ template<class T> PyArrayViewHolder<T> pyArrayViewHolder(const T& view, pybind11
PYBIND11_DECLARE_HOLDER_TYPE(T, Corrade::Containers::PyArrayViewHolder<T>)
#endif

203
src/Corrade/Containers/StridedArrayViewPythonBindings.h

@ -0,0 +1,203 @@
#ifndef Corrade_Containers_StridedArrayViewPythonBindings_h
#define Corrade_Containers_StridedArrayViewPythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <pybind11/pybind11.h>
#include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/Containers/String.h>
namespace Corrade { namespace Containers {
namespace Implementation {
/* For maintainability please keep in the same order as
https://docs.python.org/3/library/struct.html#format-characters. Each of
these has also a corresponding entry in accessorsForFormat() in
containers.cpp in the same order. */
template<class T> constexpr const char* pythonFormatString() {
static_assert(sizeof(T) == 0, "format string unknown for this type, supply it explicitly");
return {};
}
/* Treating bytes as unsigned 8-bit integers and not as chars for consistency
with bytes/bytearray, where you have to use ord(a[0]) to get a character
value. Same done for PyStridedArrayViewItem and PyStridedArrayViewSetItem
below. To further emphasize that this is "general data", a null format
string is returned, which should be treated the same as B:
https://docs.python.org/3/c-api/buffer.html#c.Py_buffer.format */
template<> constexpr const char* pythonFormatString<char>() { return nullptr; }
template<> constexpr const char* pythonFormatString<std::int8_t>() { return "b"; }
template<> constexpr const char* pythonFormatString<std::uint8_t>() { return "B"; }
template<> constexpr const char* pythonFormatString<std::int16_t>() { return "h"; }
template<> constexpr const char* pythonFormatString<std::uint16_t>() { return "H"; }
template<> constexpr const char* pythonFormatString<std::int32_t>() { return "i"; }
template<> constexpr const char* pythonFormatString<std::uint32_t>() { return "I"; }
/* *not* l / L, that's 4 bytes in Python */
template<> constexpr const char* pythonFormatString<std::int64_t>() { return "q"; }
template<> constexpr const char* pythonFormatString<std::uint64_t>() { return "Q"; }
/** @todo how to represent std::size_t? conflicts with uint32_t/uint64_t above */
template<> constexpr const char* pythonFormatString<float>() { return "f"; }
template<> constexpr const char* pythonFormatString<double>() { return "d"; }
template<class U> struct PyStridedArrayViewItem {
static pybind11::object get(const char* item) {
return pybind11::cast(*reinterpret_cast<const U*>(item));
}
};
/* Treating bytes as unsigned 8-bit integers and not as chars for consistency
with bytes/bytearray, where you have to use ord(a[0]) to get a character
value. Same done for pythonFormatString<char>() above and
PyStridedArrayViewSetItem below. */
template<> struct PyStridedArrayViewItem<const char> {
static pybind11::object get(const char* item) {
return pybind11::cast(*reinterpret_cast<const std::uint8_t*>(item));
}
};
template<class T, class U> struct PyStridedArrayViewSetItem;
template<class U> struct PyStridedArrayViewSetItem<const char, U> {
/* __setitem__ is not even exposed for immutable views so this is fine */
constexpr static std::nullptr_t set = nullptr;
};
template<class U> struct PyStridedArrayViewSetItem<char, U> {
static void set(char* item, pybind11::handle object) {
*reinterpret_cast<U*>(item) = pybind11::cast<U>(object);
}
};
/* Treating bytes as unsigned 8-bit integers and not as chars for consistency
with bytes/bytearray, where you have to use a[0] = ord('A') to set a
character value. Same done for pythonFormatString<char>() and
PyStridedArrayViewItem above. */
template<> struct PyStridedArrayViewSetItem<char, char> {
static void set(char* item, pybind11::handle object) {
*reinterpret_cast<std::uint8_t*>(item) = pybind11::cast<std::uint8_t>(object);
}
};
template<unsigned, class> struct PyStridedElement;
}
template<unsigned dimensions, class T> class PyStridedArrayView: public StridedArrayView<dimensions, T> {
/* the type is dynamic; ArrayView has the same check */
static_assert(std::is_same<const T, const char>::value, "only the (const) char StridedArrayView is meant to be exposed");
public:
/* Null function pointers should be okay as it shouldn't ever get to
them -- IndexError gets fired first. The format string can be null
as well (which nicely implies "general data"), in which case B
should be assumed:
https://docs.python.org/3/c-api/buffer.html#c.Py_buffer.format */
/*implicit*/ PyStridedArrayView(): format{}, getitem{}, setitem{} {}
template<class U> explicit PyStridedArrayView(const StridedArrayView<dimensions, U>& view): PyStridedArrayView{view, Implementation::pythonFormatString<typename std::decay<U>::type>(), sizeof(U)} {}
template<class U> explicit PyStridedArrayView(const StridedArrayView<dimensions, U>& view, Containers::StringView format, std::size_t itemsize): PyStridedArrayView<dimensions, T>{
arrayCast<T>(view),
format,
itemsize,
Implementation::PyStridedArrayViewItem<const U>::get,
Implementation::PyStridedArrayViewSetItem<T, U>::set
} {}
explicit PyStridedArrayView(const StridedArrayView<dimensions, T>& view, Containers::StringView format, std::size_t itemsize, pybind11::object(*getitem)(const char*), void(*setitem)(char*, pybind11::handle)): StridedArrayView<dimensions, T>{view}, format{format}, itemsize{itemsize}, getitem{getitem}, setitem{setitem} {}
/* All APIs that are exposed by bindings and return a StridedArrayView
have to return the wrapper now */
typedef typename std::conditional<dimensions == 1, T&, PyStridedArrayView<dimensions - 1, T>>::type ElementType;
ElementType operator[](std::size_t i) const {
return Implementation::PyStridedElement<dimensions, T>::wrap(StridedArrayView<dimensions, T>::operator[](i), format, itemsize, getitem, setitem);
}
T& operator[](const Containers::Size<dimensions>& i) const {
return StridedArrayView<dimensions, T>::operator[](i);
}
PyStridedArrayView<dimensions, T> slice(std::size_t begin, std::size_t end) const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::slice(begin, end), format, itemsize, getitem, setitem};
}
PyStridedArrayView<dimensions, T> slice(const Containers::Size<dimensions>& begin, const Containers::Size<dimensions>& end) const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::slice(begin, end), format, itemsize, getitem, setitem};
}
/* slice() with templated dimensions not used */
/* slice(&T::member) not used */
/* prefix(), suffix(), except() not used */
PyStridedArrayView<dimensions, T> every(std::size_t skip) const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::every(skip), format, itemsize, getitem, setitem};
}
PyStridedArrayView<dimensions, T> every(const Containers::Stride<dimensions>& skip) const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::every(skip), format, itemsize, getitem, setitem};
}
template<unsigned dimensionA, unsigned dimensionB> PyStridedArrayView<dimensions, T> transposed() const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::template transposed<dimensionA, dimensionB>(), format, itemsize, getitem, setitem};
}
template<unsigned dimension> PyStridedArrayView<dimensions, T> flipped() const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::template flipped<dimension>(), format, itemsize, getitem, setitem};
}
template<unsigned dimension> PyStridedArrayView<dimensions, T> broadcasted(std::size_t size) const {
return PyStridedArrayView<dimensions, T>{StridedArrayView<dimensions, T>::template broadcasted<dimension>(size), format, itemsize, getitem, setitem};
}
template<unsigned dimension, unsigned count> PyStridedArrayView<dimensions + count - 1, T> expanded(const Containers::Size<count>& size) const {
return PyStridedArrayView<dimensions + count - 1, T>{StridedArrayView<dimensions, T>::template expanded<dimension>(size), format, itemsize, getitem, setitem};
}
/* has to be public as it's accessed by the bindings directly */
/* The assumption is that >99% of format strings should be just a few
characters, stored with a SSO. I.e., not even bothering with
String::nullTerminatedGlobalView() anywhere. */
Containers::String format;
std::size_t itemsize;
pybind11::object(*getitem)(const char*);
void(*setitem)(char*, pybind11::handle);
};
namespace Implementation {
template<unsigned dimensions, class T> struct PyStridedElement {
static PyStridedArrayView<dimensions - 1, T> wrap(const StridedArrayView<dimensions - 1, T>& element, Containers::StringView format, std::size_t itemsize, pybind11::object(*getitem)(const char*), void(*setitem)(char*, pybind11::handle)) {
return PyStridedArrayView<dimensions - 1, T>{element, format, itemsize, getitem, setitem};
}
};
template<class T> struct PyStridedElement<1, T> {
static T& wrap(T& element, Containers::StringView, std::size_t, pybind11::object(*)(const char*), void(*)(char*, pybind11::handle)) {
return element;
}
};
}
}}
#endif

29
src/python/corrade/__init__.py → src/Corrade/PluginManager/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,24 +24,10 @@
# DEALINGS IN THE SOFTWARE.
#
"""Root Corrade module"""
if(MAGNUM_WITH_PYTHON)
set(CorradePluginManagerPython_HEADERS
PythonBindings.h)
import sys
# In case Corrade is built statically, the whole core project is put into
# _corrade. If corrade is built dynamically, there's no core library at the
# moment.
try:
from _corrade import *
# The following feels extremely hackish, but without that it wouldn't be
# possible to do `import corrade.containers`, which is weird
# (`from corrade import containers` works, tho, for whatever reason)
for i in ['containers']:
if i in globals(): sys.modules['corrade.' + i] = globals()[i]
except ImportError:
pass
# Prevent all submodules being pulled in when saying `from corrade import *` --
# this is consistent with behavior in magnum
__all__ = []
add_custom_target(CorradePluginManagerPython SOURCES ${CorradePluginManagerPython_HEADERS})
install(FILES ${CorradePluginManagerPython_HEADERS} DESTINATION ${CORRADE_INCLUDE_INSTALL_DIR}/PluginManager)
endif()

72
src/Corrade/PluginManager/PythonBindings.h

@ -0,0 +1,72 @@
#ifndef Corrade_PluginManager_PythonBindings_h
#define Corrade_PluginManager_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <memory> /* :( */
#include <pybind11/pybind11.h>
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Utility/Assert.h>
namespace Corrade { namespace PluginManager {
/* Stores additional stuff needed for proper refcounting of plugin instances.
Due to obvious reasons we can't subclass plugins so this is the only
possible way. */
template<class T> struct PyPluginHolder: std::unique_ptr<T> {
explicit PyPluginHolder(T* object) noexcept: std::unique_ptr<T>{object} {
/* Plugin instance without an owner can only be without a manager and
thus without any metadata */
CORRADE_INTERNAL_ASSERT(!object->metadata());
}
explicit PyPluginHolder(T* object, pybind11::object manager) noexcept: std::unique_ptr<T>{object}, manager{std::move(manager)} {}
PyPluginHolder(PyPluginHolder<T>&&) noexcept = default;
PyPluginHolder(const PyPluginHolder<T>&) = delete;
PyPluginHolder<T>& operator=(PyPluginHolder<T>&&) noexcept = default;
PyPluginHolder<T>& operator=(const PyPluginHolder<T>&) = delete;
~PyPluginHolder() {
/* On destruction, first `manager` and then the plugin would be
destroyed, which would mean it asserts due to the manager being
destructed while plugins are still around. To flip the order, we
need to reset the pointer first */
std::unique_ptr<T>::reset();
}
pybind11::object manager;
};
template<class T> PyPluginHolder<T> pyPluginHolder(Containers::Pointer<T>&& plugin, pybind11::object owner) {
return PyPluginHolder<T>{plugin.release(), std::move(owner)};
}
}}
PYBIND11_DECLARE_HOLDER_TYPE(T, Corrade::PluginManager::PyPluginHolder<T>)
#endif

34
src/Corrade/Python.h → src/Corrade/PythonBindings.h

@ -1,9 +1,10 @@
#ifndef Corrade_Python_h
#define Corrade_Python_h
#ifndef Corrade_PythonBindings_h
#define Corrade_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -30,14 +31,22 @@
namespace Corrade {
template<class T> inline pybind11::handle pyHandleFromInstance(T& obj) {
inline pybind11::handle pyHandleFromInstance(const void* obj, const std::type_info& type) {
/** @todo don't tell me there's no API for this either, ugh */
return pybind11::detail::get_object_handle(&obj, pybind11::detail::get_type_info(typeid(T)));
return pybind11::detail::get_object_handle(obj, pybind11::detail::get_type_info(type));
}
template<class T> inline pybind11::object pyObjectFromInstance(T& obj) {
template<class T> inline pybind11::handle pyHandleFromInstance(T& obj) {
return pyHandleFromInstance(&obj, typeid(T));
}
inline pybind11::object pyObjectFromInstance(const void* obj, const std::type_info& type) {
/* reinterpret_borrow?! seriously?! */
return pybind11::reinterpret_borrow<pybind11::object>(pyHandleFromInstance(obj));
return pybind11::reinterpret_borrow<pybind11::object>(pyHandleFromInstance(obj, type));
}
template<class T> inline pybind11::object pyObjectFromInstance(T& obj) {
return pyObjectFromInstance(&obj, typeid(T));
}
template<class T> inline T& pyInstanceFromHandle(pybind11::handle handle) {
@ -88,6 +97,17 @@ template<template<class> class T, class U> T<U>& pyObjectHolderFor(U& obj) {
return pyObjectHolderFor<T<U>>(pybind11::detail::get_object_handle(&obj, typeinfo), typeinfo);
}
/* This is a variant of https://github.com/pybind/pybind11/issues/1178,
implemented on the client side instead of patching pybind itself */
template<class, bool> struct PyNonDestructibleBaseDeleter;
template<class T> struct PyNonDestructibleBaseDeleter<T, false> {
void operator()(T*) { CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ }
};
template<class T> struct PyNonDestructibleBaseDeleter<T, true> {
void operator()(T* ptr) { delete ptr; }
};
template<class T, class... Args> using PyNonDestructibleClass = pybind11::class_<T, Args..., std::unique_ptr<T, PyNonDestructibleBaseDeleter<T, std::is_destructible<T>::value>>>;
}
#endif

67
src/Magnum/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,10 +24,58 @@
# DEALINGS IN THE SOFTWARE.
#
if(WITH_PYTHON)
add_custom_target(MagnumPython SOURCES Python.h)
set_target_properties(MagnumPython PROPERTIES FOLDER "Magnum/Python")
install(FILES Python.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR})
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Magnum/Python")
# Generate version header. If Git is found and this is a Git working copy,
# extract values from there, otherwise use just MAGNUMBINDINGS_VERSION_YEAR /
# MONTH that are set in project root CMakeLists.
find_package(Git)
if(Git_FOUND)
# Match only tags starting with `v`, always use the long format so we have
# a commit hash also on a tagged version
execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v*" --long
OUTPUT_VARIABLE MAGNUMBINDINGS_VERSION_STRING
RESULT_VARIABLE _MAGNUMBINDINGS_VERSION_RESULT
ERROR_VARIABLE _MAGNUMBINDINGS_VERSION_ERROR
# Otherwise this gets executed in the build dir, which might be inside
# a totally different Git working copy. But that's not enough, if it
# would be run in ${CMAKE_CURRENT_SOURCE_DIR}, on Windows the
# `--match "v*"` would get expanded to the `versionBindings.h.cmake`
# file, causing Git to obviously not find any such tag. The reason is
# probably that on Windows the wildcard expansion is done on the
# application side and not by the shell, thus being performed even
# though CMake docs say `execute_process()` doesn't involve a shell.
# The package/git directory is thus dedicated for that operation,
# *guaranteed* to never contain any file starting with `v` (or `V` for
# that matter because, again, HELLO WINDOWS).
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/package/git
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(MAGNUMBINDINGS_VERSION_STRING MATCHES "^v([0-9][0-9][0-9][0-9])\\.0?([0-9][0-9]?)-([0-9]+)-g([a-f0-9]+)$")
set(MAGNUMBINDINGS_VERSION_YEAR ${CMAKE_MATCH_1})
set(MAGNUMBINDINGS_VERSION_MONTH ${CMAKE_MATCH_2})
set(MAGNUMBINDINGS_VERSION_COMMIT ${CMAKE_MATCH_3})
# Otherwise if commit is 0, it would #undef the variable
set(MAGNUMBINDINGS_VERSION_COMMIT " ${MAGNUMBINDINGS_VERSION_COMMIT}")
set(MAGNUMBINDINGS_VERSION_HASH ${CMAKE_MATCH_4})
elseif(_MAGNUMBINDINGS_VERSION_RESULT EQUAL 0)
message(WARNING "Can't match Git version from ${MAGNUMBINDINGS_VERSION_STRING}, generating a fallback versionBindings.h instead")
else()
message(WARNING "Can't match Git version, generating a fallback versionBindings.h instead: ${_MAGNUMBINDINGS_VERSION_ERROR}")
endif()
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/versionBindings.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/versionBindings.h)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/versionBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR})
if(MAGNUM_WITH_PYTHON)
set(MagnumPython_SRCS
PythonBindings.h
StridedArrayViewPythonBindings.h)
add_custom_target(MagnumPython SOURCES ${MagnumPython_SRCS})
install(FILES ${MagnumPython_SRCS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR})
endif()
find_package(Magnum COMPONENTS GL SceneGraph)
@ -38,3 +87,11 @@ endif()
if(Magnum_SceneGraph_FOUND)
add_subdirectory(SceneGraph)
endif()
if(Magnum_Trade_FOUND)
add_subdirectory(Trade)
endif()
if(MAGNUM_BUILD_TESTS)
add_subdirectory(Test ${EXCLUDE_FROM_ALL_IF_TEST_TARGET})
endif()

10
src/Magnum/GL/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,8 +24,7 @@
# DEALINGS IN THE SOFTWARE.
#
if(WITH_PYTHON)
add_custom_target(MagnumGLPython SOURCES Python.h)
set_target_properties(MagnumGLPython PROPERTIES FOLDER "Magnum/Python")
install(FILES Python.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/GL)
if(MAGNUM_WITH_PYTHON)
add_custom_target(MagnumGLPython SOURCES PythonBindings.h)
install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/GL)
endif()

9
src/Magnum/GL/Python.h → src/Magnum/GL/PythonBindings.h

@ -1,9 +1,10 @@
#ifndef Magnum_GL_Python_h
#define Magnum_GL_Python_h
#ifndef Magnum_GL_PythonBindings_h
#define Magnum_GL_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -30,7 +31,7 @@
#include <pybind11/pybind11.h>
#include <Magnum/GL/GL.h>
#include "Magnum/Python.h"
#include "Magnum/PythonBindings.h"
namespace Magnum { namespace GL {

20
src/Magnum/Python.h → src/Magnum/PythonBindings.h

@ -1,9 +1,10 @@
#ifndef Magnum_Python_h
#define Magnum_Python_h
#ifndef Magnum_PythonBindings_h
#define Magnum_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -45,20 +46,9 @@ template<class T> struct PyImageViewHolder: std::unique_ptr<T> {
};
template<class T> PyImageViewHolder<T> pyImageViewHolder(const T& view, pybind11::object owner) {
return PyImageViewHolder<T>{new T{view}, owner};
return PyImageViewHolder<T>{new T{view}, std::move(owner)};
}
/* This is a variant of https://github.com/pybind/pybind11/issues/1178,
implemented on the client side instead of patching pybind itself */
template<class, bool> struct PyNonDestructibleBaseDeleter;
template<class T> struct PyNonDestructibleBaseDeleter<T, false> {
void operator()(T*) { CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ }
};
template<class T> struct PyNonDestructibleBaseDeleter<T, true> {
void operator()(T* ptr) { delete ptr; }
};
template<class T, class... Args> using PyNonDestructibleClass = pybind11::class_<T, Args..., std::unique_ptr<T, PyNonDestructibleBaseDeleter<T, std::is_destructible<T>::value>>>;
}
PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::PyImageViewHolder<T>)

10
src/Magnum/SceneGraph/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,8 +24,7 @@
# DEALINGS IN THE SOFTWARE.
#
if(WITH_PYTHON)
add_custom_target(MagnumSceneGraphPython SOURCES Python.h)
set_target_properties(MagnumSceneGraphPython PROPERTIES FOLDER "Magnum/Python")
install(FILES Python.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/SceneGraph)
if(MAGNUM_WITH_PYTHON)
add_custom_target(MagnumSceneGraphPython SOURCES PythonBindings.h)
install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/SceneGraph)
endif()

29
src/Magnum/SceneGraph/Python.h → src/Magnum/SceneGraph/PythonBindings.h

@ -1,9 +1,10 @@
#ifndef Magnum_SceneGraph_Python_h
#define Magnum_SceneGraph_Python_h
#ifndef Magnum_SceneGraph_PythonBindings_h
#define Magnum_SceneGraph_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -28,6 +29,7 @@
#include <memory> /* :( */
#include <pybind11/pybind11.h>
#include <Corrade/Utility/Assert.h>
#include <Magnum/SceneGraph/AbstractFeature.h>
namespace Magnum { namespace SceneGraph {
@ -62,22 +64,27 @@ template<class T> struct PyFeatureHolder: std::unique_ptr<T> {
/* Hey this needs docs. */
template<class Object> class PyObject: public Object {
/* This template parameter can't be just Object, as that makes MSVC confused
when CRTP'ing something else than a class named Object -- it fails inside
the Object{} call in the constructor, saying `error C2614:
'Magnum::SceneGraph::PyObject<SomeOtherName>': illegal member initialization:
'Object' is not a base or member`. */
template<class Object_> class PyObject: public Object_ {
public:
template<class ...Args> explicit PyObject(Args&&... args): Object{std::forward<Args>(args)...} {}
template<class ...Args> explicit PyObject(Args&&... args): Object_{std::forward<Args>(args)...} {}
PyObject(const PyObject<Object>&) = delete;
PyObject(PyObject<Object>&&) = delete;
PyObject(const PyObject<Object_>&) = delete;
PyObject(PyObject<Object_>&&) = delete;
PyObject<Object>& operator=(const PyObject<Object>&) = delete;
PyObject<Object>& operator=(PyObject<Object>&&) = delete;
PyObject<Object_>& operator=(const PyObject<Object_>&) = delete;
PyObject<Object_>& operator=(PyObject<Object_>&&) = delete;
private:
void doErase() override {
/* When deleting a parent, disconnect this from the parent instead
of deleting it. Deletion is then handled by Python itself. */
CORRADE_INTERNAL_ASSERT(Object::parent());
Object::setParent(nullptr);
CORRADE_INTERNAL_ASSERT(Object_::parent());
Object_::setParent(nullptr);
pybind11::cast(this).dec_ref();
}
};

119
src/Magnum/StridedArrayViewPythonBindings.h

@ -0,0 +1,119 @@
#ifndef Magnum_StridedArrayViewPythonBindings_h
#define Magnum_StridedArrayViewPythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Magnum/Magnum.h>
#include "Corrade/Containers/StridedArrayViewPythonBindings.h"
namespace Corrade { namespace Containers { namespace Implementation {
/* This expands Containers::Implementation::pythonFormatString() with Magnum
types. Using e.g. "3f" instead of "fff" as that makes Numpy understand even
the slices as arrays in a concrete type (or it at least repr()s them as
such), with "fff" it gives back an untyped tuple. */
#define _c(type, string) \
template<> constexpr const char* pythonFormatString<Magnum::type>() { return string; }
_c(Half, "e")
_c(Vector2, "2f")
_c(Vector2h, "2e")
_c(Vector2d, "2d")
_c(Vector2ub, "2B")
_c(Vector2b, "2b")
_c(Vector2us, "2H")
_c(Vector2s, "2h")
_c(Vector2ui, "2I")
_c(Vector2i, "2i")
_c(Vector3, "3f")
_c(Vector3h, "3e")
_c(Vector3d, "3d")
_c(Vector3ub, "3B")
_c(Vector3b, "3b")
_c(Vector3us, "3H")
_c(Vector3s, "3h")
_c(Vector3ui, "3I")
_c(Vector3i, "3i")
_c(Vector4, "4f")
_c(Vector4h, "4e")
_c(Vector4d, "4d")
_c(Vector4ub, "4B")
_c(Vector4b, "4b")
_c(Vector4us, "4H")
_c(Vector4s, "4h")
_c(Vector4ui, "4I")
_c(Vector4i, "4i")
_c(Matrix2x2, "4f")
_c(Matrix2x2d, "4d")
_c(Matrix2x3, "6f")
_c(Matrix2x3d, "6d")
_c(Matrix2x4, "8f")
_c(Matrix2x4d, "8d")
_c(Matrix3x2, "6f")
_c(Matrix3x2d, "6d")
_c(Matrix3x3, "9f")
_c(Matrix3x3d, "9d")
_c(Matrix3x4, "12f")
_c(Matrix3x4d, "12d")
_c(Matrix4x2, "8f")
_c(Matrix4x2d, "8d")
_c(Matrix4x3, "12f")
_c(Matrix4x3d, "12d")
_c(Matrix4x4, "16f")
_c(Matrix4x4d, "16d")
_c(Range1D, "2f")
_c(Range1Dd, "2d")
_c(Range1Di, "2i")
_c(Range2D, "4f")
_c(Range2Dd, "4d")
_c(Range2Di, "4i")
_c(Range3D, "6f")
_c(Range3Dd, "6d")
_c(Range3Di, "6i")
_c(Complex, "2f")
_c(Complexd, "2d")
_c(DualComplex, "4f")
_c(DualComplexd, "4f")
_c(Quaternion, "4f")
_c(Quaterniond, "4d")
_c(DualQuaternion, "8f")
_c(DualQuaterniond, "8d")
_c(Deg, "f")
_c(Degd, "d")
_c(Rad, "f")
_c(Radd, "d")
#undef _c
}
}}
#endif

30
src/Magnum/Test/CMakeLists.txt

@ -0,0 +1,30 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Prefixed with project name to avoid conflicts with VersionTest in Magnum and
# related repos
corrade_add_test(MagnumBindingsVersionTest VersionTest.cpp LIBRARIES Magnum::Magnum)
target_include_directories(MagnumBindingsVersionTest PRIVATE ${PROJECT_BINARY_DIR}/src)

67
src/Magnum/Test/VersionTest.cpp

@ -0,0 +1,67 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/TestSuite/Compare/Numeric.h>
#include "Magnum/Magnum.h"
#include "Magnum/versionBindings.h"
namespace Magnum { namespace Test { namespace {
struct VersionTest: TestSuite::Tester {
explicit VersionTest();
void test();
};
VersionTest::VersionTest() {
addTests({&VersionTest::test});
}
void VersionTest::test() {
Debug{} << "MAGNUMBINDINGS_VERSION_YEAR:" << MAGNUMBINDINGS_VERSION_YEAR;
Debug{} << "MAGNUMBINDINGS_VERSION_MONTH:" << MAGNUMBINDINGS_VERSION_MONTH;
#ifdef MAGNUMBINDINGS_VERSION_COMMIT
Debug{} << "MAGNUMBINDINGS_VERSION_COMMIT:" << MAGNUMBINDINGS_VERSION_COMMIT;
Debug{} << "MAGNUMBINDINGS_VERSION_HASH:" << Debug::hex << MAGNUMBINDINGS_VERSION_HASH;
Debug{} << "MAGNUMBINDINGS_VERSION_STRING:" << MAGNUMBINDINGS_VERSION_STRING;
#else
Debug{} << "No Git version information available.";
#endif
CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_YEAR, 2019, TestSuite::Compare::GreaterOrEqual);
CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_YEAR, 2100, TestSuite::Compare::LessOrEqual);
CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_MONTH, 0, TestSuite::Compare::Greater);
CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_MONTH, 12, TestSuite::Compare::LessOrEqual);
#ifdef MAGNUMBINDINGS_VERSION_COMMIT
CORRADE_COMPARE_AS(MAGNUMBINDINGS_VERSION_COMMIT, 0, TestSuite::Compare::GreaterOrEqual);
#endif
}
}}}
CORRADE_TEST_MAIN(Magnum::Test::VersionTest)

30
src/Magnum/Trade/CMakeLists.txt

@ -0,0 +1,30 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
if(MAGNUM_WITH_PYTHON)
add_custom_target(MagnumTradePython SOURCES PythonBindings.h)
install(FILES PythonBindings.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Trade)
endif()

103
src/Magnum/Trade/PythonBindings.h

@ -0,0 +1,103 @@
#ifndef Magnum_Trade_PythonBindings_h
#define Magnum_Trade_PythonBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <memory> /* :( */
#include <pybind11/pybind11.h>
#include "Magnum/Trade/Data.h"
#include "Magnum/Trade/MaterialData.h" /* :( */
#include "Magnum/Trade/MeshData.h" /* :( */
#include "Magnum/Trade/SceneData.h"
namespace Magnum { namespace Trade {
namespace Implementation {
/* For assertions only */
template<class T> inline bool pyDataFlagsNeedOwner(const T& data) {
return !(data.dataFlags() & (DataFlag::Owned|DataFlag::Global));
}
inline bool pyDataFlagsNeedOwner(const MaterialData& data) {
return
!(data.attributeDataFlags() & (DataFlag::Owned|DataFlag::Global)) ||
!(data.layerDataFlags() & (DataFlag::Owned|DataFlag::Global));
}
inline bool pyDataFlagsNeedOwner(const MeshData& data) {
return
!(data.indexDataFlags() & (DataFlag::Owned|DataFlag::Global)) ||
!(data.vertexDataFlags() & (DataFlag::Owned|DataFlag::Global));
}
inline bool pyDataFlagsNeedOwner(const MeshAttributeData& data) {
return data.data().data();
}
}
/* Stores additional stuff needed for proper refcounting of non-owning FooData.
Better than subclassing each FooData class because then we would need to
wrap it every time it's exposed to Python, making 3rd party bindings
unnecessarily complex */
template<class T> struct PyDataHolder: std::unique_ptr<T> {
explicit PyDataHolder(T* object): PyDataHolder{object, pybind11::none{}} {
/* Data without an owner can only be self-owned, global or empty */
CORRADE_INTERNAL_ASSERT(!Implementation::pyDataFlagsNeedOwner(*object));
}
explicit PyDataHolder(T* object, pybind11::object owner): std::unique_ptr<T>{object}, owner{std::move(owner)} {}
pybind11::object owner;
};
template<class T> PyDataHolder<T> pyDataHolder(T&& data, pybind11::object owner) {
return PyDataHolder<T>{new T{std::move(data)}, std::move(owner)};
}
/* Compared to PyDataHolder this stores two owner objects. Has to be a template
even though it's only ever used for a single type because
PYBIND11_DECLARE_HOLDER_TYPE() wants it to be so. */
template<class T> struct PySceneFieldDataHolder: std::unique_ptr<SceneFieldData> {
explicit PySceneFieldDataHolder(SceneFieldData* object): PySceneFieldDataHolder{object, pybind11::none{}, pybind11::none{}} {
/* Data without owners can only be empty */
CORRADE_INTERNAL_ASSERT(!object->mappingData().data() && !object->fieldData().data());
}
explicit PySceneFieldDataHolder(SceneFieldData* object, pybind11::object mappingOwner, pybind11::object fieldOwner): std::unique_ptr<T>{object}, mappingOwner{std::move(mappingOwner)}, fieldOwner{std::move(fieldOwner)} {}
pybind11::object mappingOwner, fieldOwner;
};
inline PySceneFieldDataHolder<SceneFieldData> pySceneFieldDataHolder(SceneFieldData&& data, pybind11::object mappingOwner, pybind11::object fieldOwner) {
return PySceneFieldDataHolder<SceneFieldData>{new SceneFieldData{std::move(data)}, std::move(mappingOwner), std::move(fieldOwner)};
}
}}
PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::Trade::PyDataHolder<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, Magnum::Trade::PySceneFieldDataHolder<T>)
#endif

39
src/Magnum/versionBindings.h.cmake

@ -0,0 +1,39 @@
#ifndef Magnum_versionBindings_h
#define Magnum_versionBindings_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/* Note: this header is deliberately not included from anywhere except
VersionTest to avoid triggering a full rebuild every time the Git commit
hash changes. */
#define MAGNUMBINDINGS_VERSION_YEAR ${MAGNUMBINDINGS_VERSION_YEAR}
#define MAGNUMBINDINGS_VERSION_MONTH ${MAGNUMBINDINGS_VERSION_MONTH}
#cmakedefine MAGNUMBINDINGS_VERSION_COMMIT${MAGNUMBINDINGS_VERSION_COMMIT}
#cmakedefine MAGNUMBINDINGS_VERSION_HASH 0x${MAGNUMBINDINGS_VERSION_HASH}
#cmakedefine MAGNUMBINDINGS_VERSION_STRING "${MAGNUMBINDINGS_VERSION_STRING}"
#endif

33
src/python/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -26,9 +27,23 @@
# Thanks, CMake, for making the recommended way of installing pacakges so
# useless that it's impossible to call find_package() consistently independent
# of whether it's installed system-wide or added through add_subdirectory().
# This is absolutely awful.
# This also means we can't use pybind11_VERSION below but have to extract it
# from some private cache variables instead. THIS IS ABSOLUTELY AWFUL, FFS.
if(NOT COMMAND pybind11_add_module)
find_package(pybind11 CONFIG REQUIRED)
elseif(NOT pybind11_VERSION)
set(pybind11_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH})
endif()
# In pybind11 2.2.4 and below, pybind11_add_module() added the include
# directories as non-system. That, combined with Corrade's warning level, added
# an insane amount of warnings to the build. Since 2.3 it was possible to
# override that by passing SYSTEM to pybind11_add_module(), HOWEVER since 2.6
# doing so causes an ANNOYING warning because they made that a default. That
# all in a span of barely two years. Can't things just stay stable for a little
# moment?!
if(pybind11_VERSION VERSION_LESS 2.6)
set(pybind11_add_module_SYSTEM SYSTEM)
endif()
# UGH FFS
@ -46,17 +61,22 @@ add_subdirectory(magnum)
# CMake 3.12, so I need to do two passes, first replacing variables using
# configure_file() and then replacing generator expressions with file(GENERATE)
foreach(target
corrade
corrade_containers
corrade_pluginmanager
corrade_utility
magnum_gl
magnum_materialtools
magnum_meshtools
magnum_primitives
magnum_scenegraph
magnum_scenetools
magnum_shaders
magnum_platform_cgl
magnum_platform_egl
magnum_platform_glx
magnum_platform_glfw
magnum_platform_sdl2
magnum_text
magnum_trade)
if(TARGET ${target})
set(${target}_file $<TARGET_FILE:${target}>)
@ -66,3 +86,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmake
${CMAKE_CURRENT_BINARY_DIR}/setup.py.in)
file(GENERATE OUTPUT ${output_dir}/setup.py
INPUT ${CMAKE_CURRENT_BINARY_DIR}/setup.py.in)
# MagnumPythonBindings library and alias, just for superprojects to have
# something to link to get to the headers
add_library(MagnumPythonBindings INTERFACE)
set_target_properties(MagnumPythonBindings PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/src)
add_library(MagnumBindings::Python ALIAS MagnumPythonBindings)

100
src/python/corrade/CMakeLists.txt

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -23,13 +24,33 @@
# DEALINGS IN THE SOFTWARE.
#
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Corrade/Python")
# *Not* REQUIRED
find_package(Corrade COMPONENTS
PluginManager)
set(corrade_SRCS
corrade.cpp)
# Extra libraries to link to. Populated only in case of CORRADE_BUILD_STATIC.
set(corrade_LIBS )
set(corrade_containers_SRCS
containers.cpp)
set(corrade_pluginmanager_SRCS
pluginmanager.cpp)
set(corrade_utility_SRCS
utility.cpp)
# If Corrade is not built as static, compile the sub-libraries as separate
# modules
if(NOT CORRADE_BUILD_STATIC)
pybind11_add_module(corrade_containers SYSTEM ${corrade_containers_SRCS})
pybind11_add_module(corrade_containers ${pybind11_add_module_SYSTEM} ${corrade_containers_SRCS})
target_include_directories(corrade_containers PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/python)
@ -37,28 +58,81 @@ if(NOT CORRADE_BUILD_STATIC)
Corrade::Containers
Corrade::Utility)
set_target_properties(corrade_containers PROPERTIES
FOLDER "python/corrade"
OUTPUT_NAME "containers"
LIBRARY_OUTPUT_DIRECTORY ${output_dir}/corrade)
pybind11_add_module(corrade_utility ${pybind11_add_module_SYSTEM} ${corrade_utility_SRCS})
target_include_directories(corrade_utility PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/python)
target_link_libraries(corrade_utility PRIVATE
Corrade::Utility)
set_target_properties(corrade_utility PROPERTIES
OUTPUT_NAME "utility"
LIBRARY_OUTPUT_DIRECTORY ${output_dir}/corrade)
if(Corrade_PluginManager_FOUND)
pybind11_add_module(corrade_pluginmanager ${pybind11_add_module_SYSTEM} ${corrade_pluginmanager_SRCS})
target_include_directories(corrade_pluginmanager PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/python)
target_link_libraries(corrade_pluginmanager PRIVATE
Corrade::PluginManager)
set_target_properties(corrade_pluginmanager PROPERTIES
OUTPUT_NAME "pluginmanager"
LIBRARY_OUTPUT_DIRECTORY ${output_dir}/corrade)
endif()
# Otherwise put it all into one library so it's easier to install (which is the
# point of static builds). It also nicely avoids problems with multiply-defined
# global data.
# global data. Unless the static libraries are linked into multiple Python
# modules, that is, which is (on Unix at least) attempted to be solved by the
# MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL option below.
else()
set(corrade_SRCS
corrade.cpp
${corrade_containers_SRCS})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/staticconfigure.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/staticconfigure.h)
list(APPEND corrade_SRCS
${corrade_containers_SRCS}
${corrade_utility_SRCS})
list(APPEND corrade_LIBS
Corrade::Containers
Corrade::Utility)
if(Corrade_PluginManager_FOUND)
list(APPEND corrade_SRCS ${corrade_pluginmanager_SRCS})
list(APPEND corrade_LIBS Corrade::PluginManager)
endif()
endif()
pybind11_add_module(corrade SYSTEM ${corrade_SRCS})
# If the option is enabled, the setdlopenflags() code in __init__.py is used,
# otherwise it's commented out
if(MAGNUM_BUILD_STATIC AND UNIX AND MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL)
set(_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL "")
else()
set(_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL "## ")
endif()
# ${output_dir} contains $<CONFIG> on multi-config builds, and configure_file()
# cannot expand that during the configure step so it has to put the result into
# a temporary location and then file(GENERATE) does the rest. It's important to
# ensure that the file put in ${CMAKE_CURRENT_BINARY_DIR} isn't named
# __init__.py as that may cause Python to wrongly treat the directory as a
# package, which it isn't.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in
${CMAKE_CURRENT_BINARY_DIR}/__init__.py.in)
file(GENERATE OUTPUT ${output_dir}/corrade/__init__.py
INPUT ${CMAKE_CURRENT_BINARY_DIR}/__init__.py.in)
pybind11_add_module(corrade ${pybind11_add_module_SYSTEM} ${corrade_SRCS})
target_include_directories(corrade PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/python)
${PROJECT_SOURCE_DIR}/src/python
${PROJECT_BINARY_DIR}/src/python) # for static build
target_link_libraries(corrade PRIVATE Corrade::Utility ${corrade_LIBS})
set_target_properties(corrade PROPERTIES
FOLDER "python"
OUTPUT_NAME "_corrade"
LIBRARY_OUTPUT_DIRECTORY ${output_dir})
endif()
file(GENERATE OUTPUT ${output_dir}/corrade/__init__.py
INPUT ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py)
if(MAGNUM_BUILD_TESTS)
add_subdirectory(test)
endif()

3
src/python/corrade/EnumOperators.h

@ -3,7 +3,8 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a

13
src/python/corrade/PyBuffer.h

@ -3,7 +3,8 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -29,7 +30,7 @@
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StridedArrayView.h>
#include "Corrade/Python.h"
#include "Corrade/PythonBindings.h"
#include "bootstrap.h"
@ -61,7 +62,7 @@ template<class Class, bool(*getter)(Class&, Py_buffer&, int)> void enableBetterB
/* Set the memory owner to the object and increase its reference count.
We need to keep the object around because buffer->shapes /
buffer->strides might be refering to it, moreover setting it to
buffer->strides might be referring to it, moreover setting it to
something else (like ArrayView's memory owner object) would mean
Python calls the releasebuffer on that object instead of on us,
leading to reference count getting negative in many cases. */
@ -77,10 +78,4 @@ template<class Class, bool(*getter)(Class&, Py_buffer&, int)> void enableBetterB
}
/** @todo remove when https://github.com/pybind/pybind11/pull/1852 is merged
and released */
namespace pybind11 {
PYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError)
}
#endif

82
src/python/corrade/__init__.py.in

@ -0,0 +1,82 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
"""Root Corrade module"""
# If MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL is enabled in CMake, the lines
# below are included, otherwise they are commented out. What it does is a
# futile attempt to make Corrade (and Magnum) built as static libraries work
# together when built into multiple dynamic Python modules.
${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}import sys
${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}import ctypes
${_MAGNUM_BUILD_PYTHON_BINDINGS_RTLD_GLOBAL}sys.setdlopenflags(sys.getdlopenflags()|ctypes.RTLD_GLOBAL)
# On Windows, if a known directory layout is detected, add paths containing
# binaries to the DLL search path
import platform
if platform.system() == 'Windows':
import os
# os.add_dll_directory() is only since Python 3.8, in earlier versions
# PATH is used and that alone may be sufficient
if hasattr(os, 'add_dll_directory'):
# The variable might be empty, or might contain empty parts, so skip
# all empty items. There's no splitWithoutEmptyParts() like in Corrade,
# sigh. Using """ to prevent accidental syntax errors if the path
# itself would contain quotes.
for directory in """${MAGNUM_PYTHON_BINDINGS_DLL_PATH}""".split(';'):
if not directory:
continue
# If the directory is relative, interpret is as relative to parent
# dir. Also add it only if it exists.
bin_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), directory)
if os.path.exists(bin_path):
os.add_dll_directory(bin_path)
from _corrade import *
import sys
# In case Corrade is built statically, the whole core project is put into
# _corrade. The following feels extremely hackish, but without that it wouldn't
# be possible to do `import corrade.containers`, which is weird
# (`from corrade import containers` works, tho, for whatever reason)
for i in ['containers', 'pluginmanager', 'utility']:
if i in globals(): sys.modules['corrade.' + i] = globals()[i]
# Just to not have the variable leak into stubs generated by pybind11-stubgen
# TODO any way to exclude it?
del i
# Prevent all submodules being pulled in when saying `from corrade import *` --
# this is consistent with behavior in magnum
__all__ = [
# TARGET_*, BUILD_* are omitted as `from corrade import *` would pull them
# to globals and this would likely cause conflicts (magnum also defines
# BUILD_*)
]
# kate: hl python

22
src/python/corrade/bootstrap.h

@ -3,7 +3,8 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -25,7 +26,20 @@
DEALINGS IN THE SOFTWARE.
*/
namespace pybind11 { class module; }
#include <pybind11/detail/common.h> /* for PYBIND11_VERSION_* */
namespace pybind11 {
/* pybind11 2.6 changes py::module to py::module_ to be compatible with C++
modules. In order to be forward-compatible, we use module_ everywhere
and define it as an alias to module on < 2.6 */
#if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
class module_;
#else
class module;
typedef module module_;
#endif
}
namespace Corrade {}
namespace corrade {
@ -33,7 +47,9 @@ namespace corrade {
using namespace Corrade;
namespace py = pybind11;
void containers(py::module& m);
void containers(py::module_& m);
void pluginmanager(py::module_& m);
void utility(py::module_& m);
}

1025
src/python/corrade/containers.cpp

File diff suppressed because it is too large Load Diff

107
src/python/corrade/corrade.cpp

@ -1,7 +1,8 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
@ -28,8 +29,8 @@
#include "corrade/bootstrap.h"
#ifndef CORRADE_BUILD_STATIC
#error this file should be compiled only in the static build
#ifdef CORRADE_BUILD_STATIC
#include "corrade/staticconfigure.h"
#endif
namespace py = pybind11;
@ -38,6 +39,104 @@ namespace py = pybind11;
is released */
extern "C" PYBIND11_EXPORT PyObject* PyInit__corrade();
PYBIND11_MODULE(_corrade, m) {
py::module containers = m.def_submodule("containers");
m.doc() = "Root Corrade module";
m.attr("BUILD_DEPRECATED") =
#ifdef CORRADE_BUILD_DEPRECATED
true
#else
false
#endif
;
m.attr("BUILD_STATIC") =
#ifdef CORRADE_BUILD_STATIC
true
#else
false
#endif
;
m.attr("BUILD_MULTITHREADED") =
#ifdef CORRADE_BUILD_MULTITHREADED
true
#else
false
#endif
;
m.attr("TARGET_APPLE") =
#ifdef CORRADE_TARGET_APPLE
true
#else
false
#endif
;
m.attr("TARGET_IOS") =
#ifdef CORRADE_TARGET_IOS
true
#else
false
#endif
;
m.attr("TARGET_IOS_SIMULATOR") =
#ifdef CORRADE_TARGET_IOS_SIMULATOR
true
#else
false
#endif
;
m.attr("TARGET_UNIX") =
#ifdef CORRADE_TARGET_UNIX
true
#else
false
#endif
;
m.attr("TARGET_WINDOWS") =
#ifdef CORRADE_TARGET_WINDOWS
true
#else
false
#endif
;
m.attr("TARGET_WINDOWS_RT") =
#ifdef CORRADE_TARGET_WINDOWS_RT
true
#else
false
#endif
;
m.attr("TARGET_EMSCRIPTEN") =
#ifdef CORRADE_TARGET_EMSCRIPTEN
true
#else
false
#endif
;
m.attr("TARGET_ANDROID") =
#ifdef CORRADE_TARGET_ANDROID
true
#else
false
#endif
;
/* Not exposing CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT as this
is a plugin itself and so if this works, plugin manager should too */
/* In case Corrade is a bunch of static libraries, put everything into a
single shared lib to make it easier to install (which is the point of
static builds) and avoid issues with multiply-defined global symbols.
These need to be defined in the order they depend on. */
#ifdef CORRADE_BUILD_STATIC
py::module_ containers = m.def_submodule("containers");
corrade::containers(containers);
py::module_ utility = m.def_submodule("utility");
corrade::utility(utility);
/* PluginManager needs Utility::ConfigurationGroup, needs to be defined
after */
#ifdef Corrade_PluginManager_FOUND
py::module_ pluginmanager = m.def_submodule("pluginmanager");
corrade::pluginmanager(pluginmanager);
#endif
#endif
}

190
src/python/corrade/pluginmanager.cpp

@ -0,0 +1,190 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "pluginmanager.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> /* for pluginList() and aliasList() */
#include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/PluginManager/AbstractManager.h>
#include <Corrade/PluginManager/AbstractPlugin.h>
#include <Corrade/PluginManager/PluginMetadata.h>
#include <Corrade/Utility/ConfigurationGroup.h>
#include "Corrade/PythonBindings.h"
#include "corrade/bootstrap.h"
#include "corrade/EnumOperators.h"
namespace corrade {
void pluginmanager(py::module_& m) {
m.doc() = "Plugin management";
#ifndef CORRADE_BUILD_STATIC
/* Need ConfigurationGroup from there. These are a part of the same module
in the static build, no need to import (also can't import because there
it's _corrade.*) */
py::module_::import("corrade.utility");
#endif
py::enum_<PluginManager::LoadState> loadState{m, "LoadState", "Plugin load state"};
loadState
.value("NOT_FOUND", PluginManager::LoadState::NotFound)
.value("WRONG_PLUGIN_VERSION", PluginManager::LoadState::WrongPluginVersion)
.value("WRONG_INTERFACE_VERSION", PluginManager::LoadState::WrongInterfaceVersion)
.value("WRONG_METADATA_FILE", PluginManager::LoadState::WrongMetadataFile)
.value("UNRESOLVED_DEPENDENCY", PluginManager::LoadState::UnresolvedDependency)
.value("STATIC", PluginManager::LoadState::Static)
.value("LOADED", PluginManager::LoadState::Loaded)
.value("NOT_LOADED", PluginManager::LoadState::NotLoaded)
.value("UNLOAD_FAILED", PluginManager::LoadState::UnloadFailed)
.value("REQUIRED", PluginManager::LoadState::Required)
.value("USED", PluginManager::LoadState::Used);
corrade::enumOperators(loadState);
py::class_<PluginManager::PluginMetadata>{m, "PluginMetadata", "Plugin metadata"}
.def_property_readonly("name", [](PluginManager::PluginMetadata& self) {
/** @todo drop std::string in favor of our own string caster */
return std::string{self.name()};
}, "Plugin name")
.def_property_readonly("depends", [](PluginManager::PluginMetadata& self) {
/** @todo make a generic caster for arbitrary arrays and strings */
std::vector<std::string> out;
for(Containers::StringView i: self.depends())
out.push_back(i);
return out;
}, "Plugins on which this plugin depends")
.def_property_readonly("used_by", [](PluginManager::PluginMetadata& self) {
/** @todo make a generic caster for arbitrary arrays and strings */
std::vector<std::string> out;
for(Containers::StringView i: self.usedBy())
out.push_back(i);
return out;
}, "Plugins which depend on this plugin")
.def_property_readonly("provides", [](PluginManager::PluginMetadata& self) {
/** @todo make a generic caster for arbitrary arrays and strings */
std::vector<std::string> out;
for(Containers::StringView i: self.provides())
out.push_back(i);
return out;
}, "Plugins which are provided by this plugin")
/** @todo data? no plugin uses this at the moment */
.def_property_readonly("configuration", static_cast<Utility::ConfigurationGroup&(PluginManager::PluginMetadata::*)()>(&PluginManager::PluginMetadata::configuration), "Initial plugin-specific configuration", py::return_value_policy::reference_internal);
PyNonDestructibleClass<PluginManager::AbstractManager> manager{m, "AbstractManager", "Base for plugin managers"};
manager.attr("VERSION") = PluginManager::AbstractManager::Version;
manager
.def_property_readonly("plugin_interface", [](PluginManager::AbstractManager& self) {
/** @todo drop std::string in favor of our own string caster */
return std::string{self.pluginInterface()};
}, "Plugin interface string")
.def_property("plugin_directory",
/** @todo drop std::string in favor of our own string caster */
[](PluginManager::AbstractManager& self) {
return std::string{self.pluginDirectory()};
}, [](PluginManager::AbstractManager& self, const std::string& directory) {
self.setPluginDirectory(directory);
}, "Plugin directory")
.def("reload_plugin_directory", &PluginManager::AbstractManager::reloadPluginDirectory, "Reload plugin directory")
.def("set_preferred_plugins", [](PluginManager::AbstractManager& self, const std::string& alias, const std::vector<std::string>& plugins) {
if(self.loadState(alias) == PluginManager::LoadState::NotFound) {
PyErr_SetNone(PyExc_KeyError);
throw py::error_already_set{};
}
/** @todo drop all this once StringIterable can be a view on
std::strings */
Containers::Array<Containers::StringView> pluginViews{NoInit, plugins.size()};
for(std::size_t i = 0; i != plugins.size(); ++i)
pluginViews[i] = plugins[i];
self.setPreferredPlugins(alias, pluginViews);
}, "Set preferred plugins for given alias", py::arg("alias"), py::arg("plugins"))
.def_property_readonly("plugin_list", [](PluginManager::AbstractManager& self) {
/** @todo make a generic caster for arbitrary arrays and strings */
std::vector<std::string> out;
for(Containers::StringView i: self.pluginList())
out.push_back(i);
return out;
}, "List of all available plugin names")
.def_property_readonly("alias_list", [](PluginManager::AbstractManager& self) {
/** @todo make a generic caster for arbitrary arrays and strings */
std::vector<std::string> out;
for(Containers::StringView i: self.aliasList())
out.push_back(i);
return out;
}, "List of all available alias names")
.def("metadata", [](PluginManager::AbstractManager& self, const std::string& plugin) {
return self.metadata(plugin);
}, "Plugin metadata", py::arg("plugin"), py::return_value_policy::reference_internal)
/** @todo drop std::string in favor of our own string caster */
.def("load_state", [](PluginManager::AbstractManager& self, const std::string& plugin) {
return self.loadState(plugin);
}, "Load state of a plugin", py::arg("plugin"))
.def("load", [](PluginManager::AbstractManager& self, const std::string& plugin) {
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies, the user can still see why */
const PluginManager::LoadState state = self.load(plugin);
if(!(state & PluginManager::LoadState::Loaded)) {
PyErr_Format(PyExc_RuntimeError, "can't load plugin %s", plugin.data());
throw py::error_already_set{};
}
return state;
}, "Load a plugin", py::arg("plugin"))
.def("unload", [](PluginManager::AbstractManager& self, const std::string& plugin) {
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies, the user can still see why */
const PluginManager::LoadState state = self.unload(plugin);
if(state != PluginManager::LoadState::NotLoaded && state != PluginManager::LoadState::Static) {
PyErr_Format(PyExc_RuntimeError, "can't unload plugin %s", plugin.data());
throw py::error_already_set{};
}
return state;
}, "Unload a plugin", py::arg("plugin"))
.def("register_external_manager", &PluginManager::AbstractManager::registerExternalManager, "Register an external manager for resolving inter-manager dependencies", py::arg("manager"), py::keep_alive<1, 2>());
py::class_<PluginManager::AbstractPlugin, PluginManager::PyPluginHolder<PluginManager::AbstractPlugin>>{m, "AbstractPlugin", "Base class for plugin interfaces"}
/* Plugin interface string, search paths, suffix, metadata file suffix
are meant to be overriden in subclasses */
.def_property_readonly("plugin", [](PluginManager::AbstractPlugin& self) {
/** @todo drop std::string in favor of our own string caster */
return std::string{self.plugin()};
}, "Plugin identifier string")
.def_property_readonly("metadata", &PluginManager::AbstractPlugin::metadata, "Plugin metadata", py::return_value_policy::reference_internal)
.def_property_readonly("configuration", static_cast<Utility::ConfigurationGroup&(PluginManager::AbstractPlugin::*)()>(&PluginManager::AbstractPlugin::configuration), "Plugin-specific configuration", py::return_value_policy::reference_internal);
}
}
#ifndef CORRADE_BUILD_STATIC
extern "C" PYBIND11_EXPORT PyObject* PyInit_pluginmanager();
PYBIND11_MODULE(pluginmanager, m) {
corrade::pluginmanager(m);
}
#endif

102
src/python/corrade/pluginmanager.h

@ -0,0 +1,102 @@
#ifndef corrade_pluginmanager_h
#define corrade_pluginmanager_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <memory> /* :( */
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> /** @todo remove once I can return Array<String> directly */
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
#include <Corrade/PluginManager/Manager.h>
#include "Corrade/PythonBindings.h"
#include "Corrade/PluginManager/PythonBindings.h"
#include "corrade/bootstrap.h"
namespace corrade {
template<class T> void plugin(py::class_<T, PluginManager::PyPluginHolder<T>, PluginManager::AbstractPlugin>& c) {
c
.def_property_readonly_static("plugin_interface", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginInterface()};
}, "Plugin interface string")
.def_property_readonly_static("plugin_search_paths", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
std::vector<std::string> out;
for(auto&& i: T::pluginSearchPaths())
out.push_back(i);
return out;
}, "Plugin search paths")
.def_property_readonly_static("plugin_suffix", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginSuffix()};
}, "Plugin binary suffix")
.def_property_readonly_static("plugin_metadata_suffix", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginMetadataSuffix()};
}, "Plugin metadata file suffix")
/** @todo plugin interface string, search paths, suffix, metadata file
suffix (all are static properties) */
.def_property_readonly("manager", [](const T& self) {
return pyObjectHolderFor<PluginManager::PyPluginHolder>(self).manager;
}, "Manager owning this plugin instance");
}
template<class T> void manager(py::class_<PluginManager::Manager<T>, PluginManager::AbstractManager>& c) {
c
.def(py::init<const std::string&>(), py::arg("plugin_directory") = std::string{}, "Constructor")
.def("instantiate", [](PluginManager::Manager<T>& self, const std::string& plugin) {
/* This causes a double lookup, but well... better than dying */
if(!(self.loadState(plugin) & PluginManager::LoadState::Loaded)) {
PyErr_Format(PyExc_RuntimeError, "plugin %s is not loaded", plugin.data());
throw py::error_already_set{};
}
auto loaded = self.instantiate(plugin);
if(!loaded) {
PyErr_Format(PyExc_RuntimeError, "can't instantiate plugin %s", plugin.data());
throw py::error_already_set{};
}
return PluginManager::pyPluginHolder(std::move(loaded), py::cast(self));
}, "Instantiate a plugin")
.def("load_and_instantiate", [](PluginManager::Manager<T>& self, const std::string& plugin) {
auto loaded = self.loadAndInstantiate(plugin);
if(!loaded) {
PyErr_Format(PyExc_RuntimeError, "can't load and instantiate plugin %s", plugin.data());
throw py::error_already_set{};
}
return PluginManager::pyPluginHolder(std::move(loaded), py::cast(self));
}, "Load and instantiate plugin");
}
}
#endif

30
src/python/corrade/staticconfigure.h.cmake

@ -0,0 +1,30 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
/* Named corrade/staticconfigure.h to avoid it colliding with Corrade/configure.h
on case-insensitive filesystems */
#cmakedefine Corrade_PluginManager_FOUND

36
src/python/corrade/test/CMakeLists.txt

@ -0,0 +1,36 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# IDE folder in VS, Xcode etc. CMake 3.12+, older versions have only the FOLDER
# property that would have to be set on each target separately.
set(CMAKE_FOLDER "Corrade/Python/Test")
foreach(_test optional stridedarrayview)
pybind11_add_module(test_${_test} ${pybind11_add_module_SYSTEM} test_${_test}.cpp)
target_include_directories(test_${_test} PRIVATE ${PROJECT_SOURCE_DIR}/src)
target_link_libraries(test_${_test} PRIVATE Corrade::Containers)
set_target_properties(test_${_test} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${output_dir})
endforeach()

8
src/python/corrade/test/__init__.py

@ -1,7 +1,8 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
@ -27,4 +28,7 @@ import os
import sys
# TODO: do this differently / more robustly
sys.path = [os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python')] + sys.path
sys.path = [
os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python'),
os.path.join(os.path.dirname(__file__), os.environ.get('CMAKE_BINARY_DIR', '../../../../build'), 'src/python/Release')
] + sys.path

1
src/python/corrade/test/broken.conf

@ -0,0 +1 @@
]]] yes this is invalid!!!

6
src/python/corrade/test/file.conf

@ -0,0 +1,6 @@
someKey=42
[someGroup]
value=hello
[someGroup/subgroup]
anotherValue=another
[emptyGroup]

1718
src/python/corrade/test/test_containers.py

File diff suppressed because it is too large Load Diff

186
src/python/corrade/test/test_containers_numpy.py

@ -0,0 +1,186 @@
#
# This file is part of Magnum.
#
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
# 2020, 2021, 2022, 2023, 2024, 2025, 2026
# Vladimír Vondruš <mosra@centrum.cz>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
import unittest
from corrade import containers
import test_stridedarrayview
try:
import numpy as np
except ModuleNotFoundError:
raise unittest.SkipTest("numpy not installed")
class StridedArrayViewCustomType(unittest.TestCase):
# This tests exposing statically typed StridedArrayView instances from C++,
# see StridedArrayViewCustomDynamicType below for types specified
# dynamically and types inherited from the buffer protocol. The short and
# mutable_int variants tested in test_containers, as for those memoryview
# works well... well, for one dimension it does.
def test_mutable_vector3d(self):
a = test_stridedarrayview.MutableContainer3d()
self.assertEqual(type(a.view), containers.MutableStridedArrayView2D)
self.assertEqual(a.view.format, 'ddd')
self.assertEqual(a.list, [
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0]
])
a.view[0][1] = [-765.6581, 3.5, 1.125]
a.view[1][2] = [4.666, 0.25, -7.5]
self.assertEqual(a.list, [
[0.0, 0.0, 0.0],
[-765.6581, 3.5, 1.125],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[4.666, 0.25, -7.5]
])
# memoryview ... doesn't understand the type. HAH
mav = memoryview(a.view[0])
with self.assertRaisesRegex(NotImplementedError, "unsupported format ddd"):
self.assertEqual(mav[1], [-765.6581, 3.5, 1.125])
# Test that numpy understands the type and has changes reflected
av = np.array(a.view, copy=False)
a.view[1][0] = [-3.33, 1.0, 0.0]
# Converting to a tuple, otherwise numpy always compares to False
self.assertEqual(tuple(av[1][0]), (-3.33, 1.0, 0.0))
self.assertEqual(tuple(av[1][1]), (0.0, 0.0, 0.0))
self.assertEqual(tuple(av[1][2]), (4.666, 0.25, -7.5))
# And the other way around as well
av[1][1] = (1.0, 0.125, 1.125)
self.assertEqual(a.list, [
[0.0, 0.0, 0.0],
[-765.6581, 3.5, 1.125],
[0.0, 0.0, 0.0],
[-3.33, 1.0, 0.0],
[1.0, 0.125, 1.125],
[4.666, 0.25, -7.5]
])
def test_mutable_long_float(self):
a = test_stridedarrayview.MutableContainerlf()
self.assertEqual(type(a.view), containers.MutableStridedArrayView2D)
self.assertEqual(a.view.format, 'Qf')
self.assertEqual(a.list, [
(0, 0.0),
(0, 0.0),
(0, 0.0),
(0, 0.0),
(0, 0.0),
(0, 0.0)
])
a.view[0][1] = (7656581356781257, 1.125)
a.view[1][2] = (4666025, -7.5)
self.assertEqual(a.list, [
(0, 0.0),
(7656581356781257, 1.125),
(0, 0.0),
(0, 0.0),
(0, 0.0),
(4666025, -7.5)
])
# memoryview ... doesn't understand the type. HAH
mav = memoryview(a.view[0])
with self.assertRaisesRegex(NotImplementedError, "unsupported format Qf"):
self.assertEqual(mav[1], (7656581356781257, 1.125))
# Test that numpy understands the type and has changes reflected
av = np.array(a.view, copy=False)
a.view[1][0] = (333106832, 0.0)
# Converting to a tuple, otherwise numpy always compares to False
self.assertEqual(tuple(av[1][0]), (333106832, 0.0))
self.assertEqual(tuple(av[1][1]), (0, 0.0))
self.assertEqual(tuple(av[1][2]), (4666025, -7.5))
# And the other way around as well
av[1][1] = (1001, 1.125)
self.assertEqual(a.list, [
(0, 0.0),
(7656581356781257, 1.125),
(0, 0.0),
(333106832, 0.0),
(1001, 1.125),
(4666025, -7.5)
])
class StridedArrayViewCustomDynamicType(unittest.TestCase):
def test_binding_short_short(self):
a = test_stridedarrayview.MutableContainerDynamicType('hh')
self.assertEqual(a.view.size, (2, 3))
self.assertEqual(a.view.stride, (12, 4))
self.assertEqual(a.view.format, 'hh')
# Test that numpy understands the type and has changes reflected
av = np.array(a.view, copy=False)
av[1][0] = (22563, -17665)
a.view[0][1] = (15, 34)
a.view[1][1] = (-22, 18)
# Converting to a tuple, otherwise numpy always compares to False
self.assertEqual(tuple(av[0][1]), (15, 34))
self.assertEqual(tuple(av[1][0]), (22563, -17665))
self.assertEqual(tuple(av[1][1]), (-22, 18))
# And the other way around as well
self.assertEqual(a.view[0][0], (0, 0))
self.assertEqual(a.view[0][1], (15, 34))
self.assertEqual(a.view[0][2], (0, 0))
self.assertEqual(a.view[1][0], (22563, -17665))
self.assertEqual(a.view[1][1], (-22, 18))
self.assertEqual(a.view[1][2], (0, 0))
def test_init_long(self):
a = np.array([[1, 2, 3], [-4, 5000000000, 6]], np.dtype('q'))
self.assertEqual(a.dtype, 'int64')
b = containers.MutableStridedArrayView2D(a)
self.assertEqual(b.size, (2, 3))
self.assertEqual(b.stride, (24, 8))
self.assertEqual(b.format, 'q')
b[1, 1] *= 2
self.assertEqual(b[0, 2], 3)
self.assertEqual(b[1, 0], -4)
self.assertEqual(b[1, 1], 10000000000)
def test_init_double(self):
a = np.array([[[1.0], [2.0]], [[-4.0], [5.0]]], np.dtype('d'))
self.assertEqual(a.dtype, 'float64')
b = containers.MutableStridedArrayView3D(a)
self.assertEqual(b.size, (2, 2, 1))
self.assertEqual(b.stride, (16, 8, 8))
self.assertEqual(b.format, 'd')
b[1, 1, 0] *= -2.0
self.assertEqual(b[0, 1, 0], 2.0)
self.assertEqual(b[1, 1, 0], -10.0)

76
src/python/corrade/test/test_optional.cpp

@ -0,0 +1,76 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021, 2022, 2023, 2024, 2025, 2026
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <pybind11/pybind11.h>
#include "../bootstrap.h" /* for module / _module alias */
#include "Corrade/Containers/OptionalPythonBindings.h"
using namespace Corrade;
namespace py = pybind11;
namespace {
struct Foo {
Foo(int a): a{a} {}
int a;
};
Containers::Optional<int> simpleType(bool set) {
return set ? Containers::optional(5) : Containers::NullOpt;
}
Containers::Optional<Foo> nestedType(bool set) {
return set ? Containers::optional(Foo{15}) : Containers::NullOpt;
}
int acquireSimpleType(Containers::Optional<int> value) {
return value ? *value : -1;
}
int acquireNestedType(Containers::Optional<Foo> value) {
return value ? value->a : -1;
}
}
/* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863
is released */
extern "C" PYBIND11_EXPORT PyObject* PyInit_test_optional();
PYBIND11_MODULE(test_optional, m) {
py::module_::import("corrade.containers");
py::class_<Foo>{m, "Foo"}
.def(py::init<int>())
.def_readwrite("a", &Foo::a);
m.def("simple_type", simpleType);
m.def("nested_type", nestedType);
m.def("acquire_simple_type", acquireSimpleType);
m.def("acquire_nested_type", acquireNestedType);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save