Browse Source
Just stuff I consider important at the moment scattered across numerous files.pull/1/head
13 changed files with 1042 additions and 0 deletions
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,23 @@
|
||||
# Inherit everything from the local config |
||||
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__))) |
||||
from conf import * |
||||
|
||||
assert LINKS_NAVBAR2[0][0] == 'C++ API' |
||||
LINKS_NAVBAR2[0] = (LINKS_NAVBAR2[0][0], 'https://magnum.graphics/doc/magnum/', []) |
||||
|
||||
OUTPUT = '../../build/doc-public/python/' |
||||
|
||||
assert len(M_DOX_TAGFILES) == 2 |
||||
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'), 'https://doc.magnum.graphics/corrade/', ['Corrade::'], ['m-doc-external']), |
||||
(os.path.join(os.path.dirname(__file__), '../../../magnum/build/doc-mcss/magnum.tag'), 'https://doc.magnum.graphics/magnum/', ['Magnum::'], ['m-doc-external']) |
||||
] |
||||
|
||||
STYLESHEETS = [ |
||||
'https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600&subset=latin-ext', |
||||
'https://static.magnum.graphics/m-dark.compiled.css', |
||||
'https://static.magnum.graphics/m-dark.documentation.compiled.css' |
||||
] |
||||
|
||||
FAVICON = 'https://doc.magnum.graphics/favicon.ico' |
||||
@ -0,0 +1,105 @@
|
||||
import os |
||||
import sys |
||||
|
||||
# TODO make this less brittle |
||||
sys.path = [os.path.join(os.path.dirname(__file__), '../../build/src/python/')] + sys.path |
||||
|
||||
import corrade |
||||
import corrade.containers |
||||
|
||||
import magnum |
||||
import magnum.gl |
||||
import magnum.platform |
||||
import magnum.platform.egl |
||||
import magnum.platform.glx |
||||
import magnum.platform.glfw |
||||
import magnum.platform.sdl2 |
||||
import magnum.shaders |
||||
|
||||
# So the doc see everything |
||||
# TODO: use just +=, m.css should reorder this on its own |
||||
magnum.__all__ = ['math', 'gl', 'platform', 'shaders'] + magnum.__all__ |
||||
|
||||
# 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 |
||||
|
||||
PROJECT_TITLE = 'Magnum' |
||||
PROJECT_SUBTITLE = 'Python docs' |
||||
MAIN_PROJECT_URL = 'https://magnum.graphics' |
||||
INPUT_MODULES = [corrade, magnum] |
||||
INPUT_PAGES = [ |
||||
'pages/index.rst', |
||||
'pages/building.rst', |
||||
'pages/api-conventions.rst' |
||||
] |
||||
INPUT_DOCS = [ |
||||
'corrade.containers.rst', |
||||
|
||||
'magnum.rst', |
||||
'magnum.gl.rst', |
||||
'magnum.math.rst', |
||||
'magnum.platform.rst', |
||||
'magnum.shaders.rst' |
||||
] |
||||
|
||||
LINKS_NAVBAR2 = [ |
||||
('C++ API', '../../../../magnum/build/doc-mcss/html/index', []) |
||||
] |
||||
|
||||
PLUGINS = [ |
||||
'm.code', |
||||
'm.components', |
||||
'm.dox', |
||||
'm.gh', |
||||
'm.htmlsanity', |
||||
'm.link', |
||||
'm.math', |
||||
'm.sphinx' |
||||
] |
||||
|
||||
STYLESHEETS = [ |
||||
'https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600&subset=latin-ext', |
||||
'../css/m-dark+documentation.compiled.css' |
||||
] |
||||
|
||||
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']) |
||||
] |
||||
M_HTMLSANITY_SMART_QUOTES = True |
||||
|
||||
PYBIND11_COMPATIBILITY = True |
||||
|
||||
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 |
||||
:gh:`everything is still evolving <mosra/magnum-bindings#1>`. |
||||
**Use at your own risk.** Search and name cross-linking is not working yet, |
||||
sorry about that. |
||||
""" |
||||
|
||||
FINE_PRINT = """ |
||||
| Magnum Python docs. Part of the `Magnum project <https://magnum.graphics/>`_, |
||||
copyright © `Vladimír Vondruš <http://mosra.cz/>`_ and contributors, 2010–2019. |
||||
| 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>`_, |
||||
`e-mail <mailto:info@magnum.graphics>`_ or |
||||
`Twitter <https://twitter.com/czmosra>`_""" |
||||
@ -0,0 +1,121 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. doctest setup |
||||
>>> from corrade import containers |
||||
|
||||
.. 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: |
||||
|
||||
.. code:: pycon |
||||
|
||||
>>> a = b'hello' |
||||
>>> b = containers.ArrayView(a) |
||||
>>> b[2] |
||||
'l' |
||||
>>> bytes(b[1:4]) |
||||
b'ell' |
||||
|
||||
`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. |
||||
|
||||
.. code:: pycon |
||||
|
||||
>>> b.obj is a |
||||
True |
||||
>>> b[1:4].obj is a |
||||
True |
||||
|
||||
.. block-danger:: Pybind11 Buffer Protocol issues |
||||
|
||||
Currently, due to how buffer protocol is exposed in pybind11, there are |
||||
several issues with converting array views from and to buffer objects: |
||||
|
||||
- readonly property is not preserved when converting an ArrayView |
||||
to Python `memoryview` |
||||
- subsequent slicing and view conversion keeps reference to the |
||||
previous view instance instead of just to the original object, |
||||
creating unnecesarily long GC chains |
||||
|
||||
`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. |
||||
|
||||
.. py:class:: corrade.containers.MutableArrayView |
||||
|
||||
Equivalent to `ArrayView`, but implementing `__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. |
||||
|
||||
`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`). |
||||
|
||||
.. py:class:: corrade.containers.MutableStridedArrayView1D |
||||
|
||||
Equivalent to `StridedArrayView1D`, but implementing `__setitem__()` as |
||||
well. |
||||
|
||||
.. py:class:: corrade.containers.StridedArrayView2D |
||||
|
||||
See `StridedArrayView1D` for more information. |
||||
|
||||
.. py:class:: corrade.containers.MutableStridedArrayView2D |
||||
|
||||
See `StridedArrayView1D` and `MutableStridedArrayView1D` for more |
||||
information. |
||||
|
||||
.. py:class:: corrade.containers.StridedArrayView3D |
||||
|
||||
See `StridedArrayView1D` for more information. |
||||
|
||||
.. py:class:: corrade.containers.MutableStridedArrayView3D |
||||
|
||||
See `StridedArrayView1D` and `MutableStridedArrayView1D` for more |
||||
information. |
||||
@ -0,0 +1,34 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. py:class:: magnum.gl.Mesh |
||||
|
||||
`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. |
||||
@ -0,0 +1,178 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. py:module:: magnum.math |
||||
|
||||
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` |
||||
module, all the concrete types are in the root module with the same names |
||||
as in the C++ variant. |
||||
|
||||
All math structures are instantiated for the most common sizes and types |
||||
and so they all share a very similar API. As in C++, main differences are |
||||
between floating-point types and integral types (one having normalization |
||||
and projection while the other having bitwise operations) and extra |
||||
convenience methods added for vectors of particular size. |
||||
|
||||
.. container:: m-row |
||||
|
||||
.. container:: m-col-m-6 |
||||
|
||||
.. code-figure:: |
||||
|
||||
.. code:: c++ |
||||
|
||||
using namespace Magnum; |
||||
Vector4i b{3, 4, 5, 6}; |
||||
b.b() *= 3; |
||||
b.xy() += {1, -1}; |
||||
Debug{} << b; |
||||
// Vector(4, 3, 15, 6) |
||||
|
||||
C++ |
||||
|
||||
.. container:: m-col-m-6 |
||||
|
||||
.. code-figure:: |
||||
|
||||
.. code:: pycon |
||||
|
||||
>>> from magnum import * |
||||
>>> b = Vector4i(3, 4, 5, 6) |
||||
>>> b.b *= 3 |
||||
>>> b.xy += (1, -1) |
||||
>>> b |
||||
Vector(4, 3, 15, 6) |
||||
|
||||
Python |
||||
|
||||
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 |
||||
: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. |
||||
|
||||
`Magnum math vs Python math`_ |
||||
============================= |
||||
|
||||
.. block-warning:: Subject to change |
||||
|
||||
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: |
||||
|
||||
.. code:: pycon |
||||
|
||||
>>> import math |
||||
>>> import magnum.math as mmath |
||||
>>> mmath.sin(Deg(45.0)) |
||||
0.7071067811865475 |
||||
>>> math.sin(45.0*math.pi/180) |
||||
0.7071067811865475 |
||||
|
||||
`Float vs double overloads`_ |
||||
============================ |
||||
|
||||
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. |
||||
|
||||
On the other hand, matrix and vector types are exposed in both the float |
||||
and double variants. |
||||
|
||||
`Major differences to the C++ API`_ |
||||
=================================== |
||||
|
||||
- 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. |
||||
- :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` |
||||
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` |
||||
@ -0,0 +1,54 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. 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: |
||||
|
||||
.. code:: py |
||||
|
||||
from magnum import platform |
||||
|
||||
class MyApp(platform.Application): # platform.sdl2.Application |
||||
... |
||||
|
||||
The same goes for :py:`WindowlessApplication` implementations, for example: |
||||
|
||||
.. code:: py |
||||
|
||||
from magnum import platform |
||||
|
||||
class MyApp(platform.WindowlessApplication): # platform.egl.WindowlessApp |
||||
... |
||||
|
||||
.. block-warning:: Subject to change |
||||
|
||||
At the moment, there's no way to specify a different priority order or |
||||
disable the auto-import altogether. |
||||
@ -0,0 +1,39 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. 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 |
||||
@ -0,0 +1,42 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor2D.POSITION |
||||
:summary: Two-component vertex position |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor3D.POSITION |
||||
:summary: Three-component vertex position |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor2D.COLOR3 |
||||
:summary: Three-component vertex color |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor3D.COLOR3 |
||||
:summary: Three-component vertex color |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor2D.COLOR4 |
||||
:summary: Four-component vertex color |
||||
|
||||
.. py:data:: magnum.shaders.VertexColor3D.COLOR4 |
||||
:summary: Four-component vertex color |
||||
@ -0,0 +1,182 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
Python API conventions |
||||
###################### |
||||
|
||||
:summary: Basic rules and good practices for both Python binding develpoers and |
||||
users. |
||||
|
||||
`API naming`_ |
||||
============= |
||||
|
||||
- mapping is made as clear as possible, the user should not need assistance |
||||
to know what's the corresponding name in Python |
||||
- modules ``lowercase``, words *not* separated with underscores (which means |
||||
C++ namespaces have to be named clearly and tersely to make this possible) |
||||
- class names ``CamelCase`` |
||||
- function names ``snake_case`` |
||||
- constants and enums ``UPPERCASE``, again underscores omitted if it doesn't |
||||
hurt readability |
||||
|
||||
`Namespaces`_ |
||||
------------- |
||||
|
||||
.. class:: m-table |
||||
|
||||
=================================== ============================ |
||||
C++ Python |
||||
=================================== ============================ |
||||
:dox:`Magnum::Math` `magnum.math` |
||||
:dox:`Magnum::SceneGraph` `magnum.scenegraph` |
||||
=================================== ============================ |
||||
|
||||
`Classes`_ |
||||
---------- |
||||
|
||||
.. class:: m-table |
||||
|
||||
=================================== ============================ |
||||
C++ Python |
||||
=================================== ============================ |
||||
:dox:`Vector2i` `Vector2i` |
||||
:dox:`GL::Buffer` `gl.Buffer` |
||||
=================================== ============================ |
||||
|
||||
`Functions`_ |
||||
------------ |
||||
|
||||
.. class:: m-table |
||||
|
||||
================================================ ========================== |
||||
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)` |
||||
================================================ ========================== |
||||
|
||||
`Enums`_ |
||||
-------- |
||||
|
||||
.. class:: m-table |
||||
|
||||
============================================== ============================ |
||||
C++ Python |
||||
============================================== ============================ |
||||
:dox:`PixelFormat::RGB8Unorm` `PixelFormat.RGB8UNORM` |
||||
:dox:`MeshPrimitive::TriangleStrip` :py:`MeshPrimitive.TRIANGLE_STRIP` |
||||
============================================== ============================ |
||||
|
||||
`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()`. |
||||
|
||||
.. class:: m-table |
||||
|
||||
============================================== ============================ |
||||
C++ Python |
||||
============================================== ============================ |
||||
:dox:`Constants::pi() <Math::Constants::pi()>` `math.pi` |
||||
:dox:`Math::Vector::Size` :py:`len(vec)` |
||||
============================================== ============================ |
||||
|
||||
`Initialization tags`_ |
||||
---------------------- |
||||
|
||||
Since overloading based on argument types is not a common thing to do in Python |
||||
(and it adds extra overhead in pybind11), all initialization tags are converted |
||||
to static constructors instead: |
||||
|
||||
.. container:: m-row |
||||
|
||||
.. container:: m-col-m-6 |
||||
|
||||
.. code-figure:: |
||||
|
||||
.. code:: c++ |
||||
|
||||
Matrix4 a{Math::IdentityInit, 5.0f}; |
||||
GL::Buffer b{NoCreate}; |
||||
|
||||
C++ |
||||
|
||||
.. container:: m-col-m-6 |
||||
|
||||
.. code-figure:: |
||||
|
||||
.. code:: py |
||||
|
||||
a = Matrix4.identity_init(5.0) |
||||
b = gl.Buffer.no_create() |
||||
|
||||
Python |
||||
|
||||
There's no equivalent for the :dox:`Math::NoInit <Math::NoInitT>` tag, as |
||||
such optimization doesn't make much sense when instances are copied back |
||||
and forth between C++ and Python. Similarly, the :dox:`NoCreate <NoCreateT>` |
||||
tag makes sense only in C++ which differentiates between stack-allocated and |
||||
heap-allocated instances. In Python it's enough to simply set an instance to |
||||
:py:`None` to achieve the same effect. |
||||
|
||||
`Name import conventions`_ |
||||
========================== |
||||
|
||||
Similarly to C++, where it's encouraged to do something like |
||||
|
||||
.. code:: c++ |
||||
|
||||
namespace YourProject { |
||||
using namespace Magnum; |
||||
} |
||||
|
||||
and then use Magnum C++ APIs unprefixed from inside that namespace, the |
||||
recommended Python workflow is similar. Note that importing the root module |
||||
*does not* import submodules, so you are expected to import those on an |
||||
as-needed basis as well. |
||||
|
||||
.. code:: py |
||||
|
||||
from magnum import * |
||||
from magnum import gl, platform |
||||
|
||||
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 |
||||
generic name isn't a problem, but you wouldn't find anything of similar |
||||
genericity in the root namespace / module. |
||||
|
||||
`Basic guarantees`_ |
||||
=================== |
||||
|
||||
- All types printable using :dox:`Utility::Debug` implement :py:`__repr__()` |
||||
on the Python side, producing the exact same output. |
||||
@ -0,0 +1,166 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
Downloading and building |
||||
######################## |
||||
|
||||
.. role:: sh(code) |
||||
:language: sh |
||||
|
||||
:summary: Installation guide for the Python bindings. |
||||
|
||||
Building of Python bindings is a similar process to |
||||
:dox:`building Magnum itself <building>` with an additional step involving |
||||
Python setuptools. Minimal set of tools and libraries required for building is: |
||||
|
||||
- C++ compiler with good C++11 support. Compilers which are tested to have |
||||
everything needed are **GCC** >= 4.8.1, **Clang** >= 3.3 and **MSVC** |
||||
>= 2015. On Windows you can also use **MinGW-w64**. |
||||
- **CMake** >= 3.1 |
||||
- **Corrade** and **Magnum** installed |
||||
:dox:`as described in their docs <building>` |
||||
- **Python** >= 3.5 and :gh:`pybind11 <pybind/pybind11>` |
||||
|
||||
`Prepared packages`_ |
||||
==================== |
||||
|
||||
`ArchLinux packages`_ |
||||
--------------------- |
||||
|
||||
In ``package/archlinux`` there is a development package, similar to the ones |
||||
in Magnum itself. They allow you to build and install the package directly from |
||||
the source tree. |
||||
|
||||
.. code:: sh |
||||
|
||||
git clone git://github.com/mosra/magnum-bindings && cd magnum-bindings |
||||
cd package/archlinux |
||||
makepkg -fp PKGBUILD |
||||
|
||||
.. block-warning:: Subject to change |
||||
|
||||
The bindings are not in ``master`` yet (:gh:`mosra/magnum-bindings#1`), use |
||||
:sh:`git checkout python` or pass ``--branch python`` to :sh:`git clone` at |
||||
the moment. |
||||
|
||||
The PKGBUILD also contains a :sh:`check()` function which will run all unit |
||||
tests before packaging. That might sometimes fail or take too long, pass |
||||
``--nocheck`` to ``makepkg`` to skip that. |
||||
|
||||
Once built, install the package using ``pacman``: |
||||
|
||||
.. code:: sh |
||||
|
||||
sudo pacman -U magnum-bindings-*.pkg.tar.xz |
||||
|
||||
`Manual build`_ |
||||
=============== |
||||
|
||||
The source is available on GitHub at https://github.com/mosra/magnum-bindings. |
||||
Clone the repository with your favorite IDE or Git GUI, download currrent |
||||
snapshot as a compressed archive or use the command line: |
||||
|
||||
.. code:: sh |
||||
|
||||
git clone git://github.com/mosra/magnum-bindings.git |
||||
|
||||
.. block-warning:: Subject to change |
||||
|
||||
The bindings are not in ``master`` yet (:gh:`mosra/magnum-bindings#1`), use |
||||
:sh:`git checkout python` or pass ``--branch python`` to :sh:`git clone` at |
||||
the moment. |
||||
|
||||
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, |
||||
ignoring the ones which aren't. If Corrade, Magnum and pybind11 are not in a |
||||
default location known to CMake, add their path to ``CMAKE_PREFIX_PATH``. |
||||
|
||||
.. code:: sh |
||||
|
||||
mkdir build && cd build |
||||
cmake .. \ |
||||
-DWITH_PYTHON=ON |
||||
make |
||||
|
||||
Note that pybind11 compilation is quite time- and memory-hungry, so you might |
||||
not want to run the build on all cores on memory-constrained systems. In the |
||||
build directory, CMake will create the desired Python package layout, meaning |
||||
the bindings can be used directly if you ``cd`` into ``build/src/python/magnum``. |
||||
For installing into a system-wide location, CMake generates a ``setup.py`` |
||||
containing location of all built libraries for use with Python setuptools: |
||||
|
||||
.. code:: sh |
||||
|
||||
cd build/src/python/magnum |
||||
python setup.py install # or python3, sudo might be needed |
||||
|
||||
`Running unit tests`_ |
||||
--------------------- |
||||
|
||||
Essential functionality of the bindings is tested using Python's builtin |
||||
``unittest`` module. The tests currently assume a CMake build directory with |
||||
all binaries already built located in a ``build/`` directory in project root, |
||||
running them is then a matter of: |
||||
|
||||
.. code:: sh |
||||
|
||||
cd src/python/magnum |
||||
python -m unittest |
||||
|
||||
.. block-warning:: Subject to change |
||||
|
||||
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: |
||||
|
||||
.. code:: sh |
||||
|
||||
python -m unittest test.test_gl test.test_math # test.test_gl_gl is a GL test |
||||
|
||||
For code coverage, `coverage.py <https://coverage.readthedocs.io/>`_ is used. |
||||
Get it via ``pip`` or as a system package. |
||||
|
||||
.. code:: sh |
||||
|
||||
pip install coverage # sudo might be needed |
||||
|
||||
Running the unit tests with coverage enabled is then a matter of executing the |
||||
following commands, the resulting HTML overview is located in |
||||
``htmlcov/index.html``: |
||||
|
||||
.. code:: sh |
||||
|
||||
cd src/python/magnum |
||||
coverage run -m unittest |
||||
coverage html |
||||
|
||||
`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 is reported to |
||||
https://codecov.io/gh/mosra/magnum-bindings. |
||||
@ -0,0 +1,96 @@
|
||||
.. |
||||
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. |
||||
.. |
||||
|
||||
Magnum Python bindings |
||||
###################### |
||||
|
||||
*Lightweight and modular graphics middleware for games and data visualization.* |
||||
|
||||
This site documents the Python bindings for the Magnum project. To see |
||||
high-level feature overview, project goals or read the developer blog, head |
||||
over to the `project homepage <https://magnum.graphics>`_. |
||||
|
||||
`Getting started`_ |
||||
================== |
||||
|
||||
Because it's out of human capabilities to maintain the Python documentation at |
||||
the same scale as the C++ documentation including all math equations, best |
||||
practices and such, most of the Python documentation is written as a delta to |
||||
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. |
||||
|
||||
`Contact & support`_ |
||||
==================== |
||||
|
||||
If you want to contribute to Magnum, if you spotted a bug, need a feature or |
||||
have an awesome idea, you can get a copy of the sources from GitHub and start |
||||
right away! |
||||
|
||||
- Project homepage --- https://magnum.graphics/ |
||||
- Documentation --- https://doc.magnum.graphics/ |
||||
- GitHub --- https://github.com/mosra/magnum and the |
||||
`\#magnum <https://github.com/topics/magnum>`_ topic |
||||
- GitLab --- https://gitlab.com/mosra/magnum |
||||
- Gitter community chat --- https://gitter.im/mosra/magnum |
||||
- 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 |
||||
|
||||
See also the `Contact & Support page <https://magnum.graphics/contact/>`_ on |
||||
the project website for further information. |
||||
|
||||
`License`_ |
||||
========== |
||||
|
||||
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 |
||||
|
||||
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. |
||||
Loading…
Reference in new issue