/*
This file is part of Magnum .
Copyright © 2010 , 2011 , 2012 , 2013 , 2014 , 2015 , 2016 , 2017 , 2018 , 2019 ,
2020 , 2021 , 2022 , 2023 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>
# include <Corrade/Containers/StridedArrayView.h>
# include <Corrade/Containers/StridedBitArrayView.h>
# include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
# include <Corrade/Containers/Triple.h>
# include <Magnum/ImageView.h>
# include <Magnum/Math/Complex.h>
# include <Magnum/Math/DualComplex.h>
# include <Magnum/Math/Matrix4.h>
# include <Magnum/Math/Packing.h>
# include <Magnum/Math/Quaternion.h>
# include <Magnum/Math/DualQuaternion.h>
# include <Magnum/Math/Range.h>
# include <Magnum/Trade/AbstractImporter.h>
# include <Magnum/Trade/AbstractImageConverter.h>
# include <Magnum/Trade/AbstractSceneConverter.h>
# include <Magnum/Trade/ImageData.h>
# include <Magnum/Trade/MaterialData.h>
# include <Magnum/Trade/MeshData.h>
# include <Magnum/Trade/SceneData.h>
# include <Magnum/Trade/TextureData.h>
# include "Corrade/Containers/PythonBindings.h"
# include "Corrade/Containers/OptionalPythonBindings.h"
# include "Magnum/PythonBindings.h"
# include "Magnum/StridedArrayViewPythonBindings.h"
# include "Magnum/Trade/PythonBindings.h"
# include "corrade/EnumOperators.h"
# include "corrade/pluginmanager.h"
# include "magnum/acessorsForPixelFormat.h"
# include "magnum/bootstrap.h"
# ifdef CORRADE_TARGET_WINDOWS
/* To allow people to conveniently use Python's os.path, we need to convert
backslashes to forward slashes as all Corrade and Magnum APIs expect
forward */
# include <Corrade/Utility/Path.h>
# endif
namespace magnum {
namespace {
/* Adapted from pybind11's base_enum internals -- if enum_name returns ???,
replace it with CUSTOM ( id ) */
template < class T , typename std : : underlying_type < T > : : type baseCustomValue > inline py : : str enumWithCustomValuesName ( const py : : object & arg ) {
/* The enum_name helper is only since pybind11 2.6, before it's inline:
https : //github.com/pybind/pybind11/commit/5e6ec496522b313e34af3de91f6c0565f68e3552 */
/** @todo remove once support for < 2.6 is dropped */
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : str name = py : : detail : : enum_name ( arg ) ;
# else
py : : str name = " ??? " ;
py : : dict entries = arg . get_type ( ) . attr ( " __entries " ) ;
for ( auto kv : entries ) {
if ( py : : handle ( kv . second [ py : : int_ ( 0 ) ] ) . equal ( arg ) ) {
name = py : : str ( kv . first ) ;
break ;
}
}
# endif
/* Haha what the hell is this comparison */
if ( std : : string { name } = = " ??? " )
return py : : str ( " CUSTOM({}) " ) . format ( typename std : : underlying_type < T > : : type ( py : : int_ ( arg ) ) - baseCustomValue ) ;
return name ;
}
/* Not using the meshAttributeCustom() etc helpers as it would be too painful
to pass them all , and I ' d need to make my own handling of the OOB cases
anyway */
template < class T , typename std : : underlying_type < T > : : type baseCustomValue > void enumWithCustomValues ( py : : enum_ < T > & enum_ ) {
static_assert ( ! typename std : : underlying_type < T > : : type ( baseCustomValue < < 1 ) ,
" base custom value expected to be a single highest bit " ) ;
enum_
. def ( " CUSTOM " , [ ] ( typename std : : underlying_type < T > : : type value ) {
/* Assuming the base custom value is a single highest bit, the
custom value should not have the same bit set ( or , in other
words , should be smaller ) */
if ( baseCustomValue & value ) {
PyErr_SetString ( PyExc_ValueError , " custom value too large " ) ;
throw py : : error_already_set { } ;
}
return T ( baseCustomValue + value ) ;
} )
. def_property_readonly ( " is_custom " , [ ] ( T value ) {
return typename std : : underlying_type < T > : : type ( value ) > = baseCustomValue ;
} )
. def_property_readonly ( " custom_value " , [ ] ( T value ) {
if ( typename std : : underlying_type < T > : : type ( value ) < baseCustomValue ) {
PyErr_SetString ( PyExc_AttributeError , " not a custom value " ) ;
throw py : : error_already_set { } ;
}
return typename std : : underlying_type < T > : : type ( value ) - baseCustomValue ;
} ) ;
/* Adapted from pybind11's base_enum internals, just calling our
customEnumName instead of py : : detail : : enum_name */
enum_ . attr ( " __repr__ " ) = py : : cpp_function (
[ ] ( const py : : object & arg ) - > py : : str {
py : : handle type =
/* handle_of(arg) is only since pybind11 2.6, before it's
arg . get_type ( ) :
https : //github.com/pybind/pybind11/commit/41aa92601ebce548290f6a9efcd66e64216bf972 */
/** @todo remove once support for < 2.6 is dropped */
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : type : : handle_of ( arg )
# else
arg . get_type ( )
# endif
;
py : : object type_name = type . attr ( " __name__ " ) ;
return py : : str ( " <{}.{}: {}> " )
. format ( std : : move ( type_name ) , enumWithCustomValuesName < T , baseCustomValue > ( arg ) , py : : int_ ( arg ) ) ;
} ,
py : : name ( " __repr__ " ) ,
py : : is_method ( enum_ ) ) ;
enum_ . attr ( " name " ) = py : : handle ( reinterpret_cast < PyObject * > ( & PyProperty_Type ) ) ( py : : cpp_function ( & enumWithCustomValuesName < T , baseCustomValue > , py : : name ( " name " ) , py : : is_method ( enum_ ) ) ) ;
enum_ . attr ( " __str__ " ) = py : : cpp_function (
[ ] ( const py : : object & arg ) - > py : : str {
py : : object type_name =
/* handle_of(arg) is only since pybind11 2.6, before it's
arg . get_type ( ) :
https : //github.com/pybind/pybind11/commit/41aa92601ebce548290f6a9efcd66e64216bf972 */
/** @todo remove once support for < 2.6 is dropped */
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : type : : handle_of ( arg )
# else
arg . get_type ( )
# endif
. attr ( " __name__ " ) ;
return pybind11 : : str ( " {}.{} " ) . format ( std : : move ( type_name ) , enumWithCustomValuesName < T , baseCustomValue > ( arg ) ) ;
} ,
py : : name ( " name " ) ,
py : : is_method ( enum_ ) ) ;
}
template < UnsignedInt dimensions , class T > PyObject * implicitlyConvertibleToImageView ( PyObject * obj , PyTypeObject * ) {
py : : detail : : make_caster < Trade : : ImageData < dimensions > > caster ;
if ( ! caster . load ( obj , false ) ) {
return nullptr ;
}
Trade : : ImageData < dimensions > & data = caster ;
if ( data . isCompressed ( ) ) {
PyErr_SetString ( PyExc_RuntimeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
auto r = pyCastButNotShitty ( pyImageViewHolder ( ImageView < dimensions , T > ( data ) , py : : reinterpret_borrow < py : : object > ( obj ) ) ) . release ( ) . ptr ( ) ;
return r ;
}
template < UnsignedInt dimensions , class T > PyObject * implicitlyConvertibleToCompressedImageView ( PyObject * obj , PyTypeObject * ) {
py : : detail : : make_caster < Trade : : ImageData < dimensions > > caster ;
if ( ! caster . load ( obj , false ) ) {
return nullptr ;
}
Trade : : ImageData < dimensions > & data = caster ;
if ( ! data . isCompressed ( ) ) {
PyErr_SetString ( PyExc_RuntimeError , " image is not compressed " ) ;
throw py : : error_already_set { } ;
}
auto r = pyCastButNotShitty ( pyImageViewHolder ( CompressedImageView < dimensions , T > ( data ) , py : : reinterpret_borrow < py : : object > ( obj ) ) ) . release ( ) . ptr ( ) ;
return r ;
}
template < UnsignedInt dimensions , class T > Containers : : PyArrayViewHolder < Containers : : PyStridedArrayView < dimensions , T > > imagePixelsView ( Trade : : ImageData < dimensions > & image , const Containers : : ArrayView < T > data , const Containers : : StridedArrayView < dimensions + 1 , T > & pixels ) {
const PixelFormat format = image . format ( ) ;
const std : : size_t itemsize = pixelFormatSize ( format ) ;
const Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > formatStringGetitemSetitem = accessorsForPixelFormat ( format ) ;
if ( ! formatStringGetitemSetitem . first ( ) ) {
PyErr_Format ( PyExc_NotImplementedError , " access to %S is not implemented yet, sorry " , py : : cast ( format ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( Containers : : PyStridedArrayView < dimensions , T > { flattenPixelView ( data , pixels ) , formatStringGetitemSetitem . first ( ) , itemsize , formatStringGetitemSetitem . second ( ) , formatStringGetitemSetitem . third ( ) } , py : : cast ( image ) ) ;
}
template < UnsignedInt dimensions > void imageData ( py : : class_ < Trade : : ImageData < dimensions > , Trade : : PyDataHolder < Trade : : ImageData < dimensions > > > & c ) {
/*
Missing APIs :
Dimensions
*/
/* These two are quite hacky attempts to bring the ImageData -> ImageView
conversion operator functionality here . Using py : : implicitly_convertible
alone doesn ' t work as it only calls conversion constructors exposed to
Python , and we can ' t expose such a thing to Python because ImageView is
defined in the ` magnum ` module while this is ` magnum . trade ` , and that
would mean a cyclic dependency .
Instead , I took the guts of py : : implicitly_convertible and instead of
calling into Python I ' m calling the C + + conversion operator directly
myself . That alone is not enough , as this implicit conversion is only
chosen if the target type has a Python - exposed constructor that takes a
type that ' s implicitly convertible from the source type . Ugh .
If this ever breaks with a pybind update , I ' m probably going to
reimplement this in a pure duck - typed fashion . I hope not tho . */
{
auto tinfo = py : : detail : : get_type_info ( typeid ( ImageView < dimensions , char > ) ) ;
CORRADE_INTERNAL_ASSERT ( tinfo ) ;
tinfo - > implicit_conversions . push_back ( implicitlyConvertibleToImageView < dimensions , char > ) ;
} {
auto tinfo = py : : detail : : get_type_info ( typeid ( ImageView < dimensions , const char > ) ) ;
CORRADE_INTERNAL_ASSERT ( tinfo ) ;
tinfo - > implicit_conversions . push_back ( implicitlyConvertibleToImageView < dimensions , const char > ) ;
} {
auto tinfo = py : : detail : : get_type_info ( typeid ( CompressedImageView < dimensions , char > ) ) ;
CORRADE_INTERNAL_ASSERT ( tinfo ) ;
tinfo - > implicit_conversions . push_back ( implicitlyConvertibleToCompressedImageView < dimensions , char > ) ;
} {
auto tinfo = py : : detail : : get_type_info ( typeid ( CompressedImageView < dimensions , const char > ) ) ;
CORRADE_INTERNAL_ASSERT ( tinfo ) ;
tinfo - > implicit_conversions . push_back ( implicitlyConvertibleToCompressedImageView < dimensions , const char > ) ;
}
c
/* There are no constructors at the moment --- expecting those types
get only created by importers . ( It would also need the Array type
and movability figured out , postponing that to later . ) */
. def_property_readonly ( " data_flags " , [ ] ( Trade : : ImageData < dimensions > & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . dataFlags ( ) ) ) ;
} , " Data flags " )
/* Properties */
. def_property_readonly ( " is_compressed " , & Trade : : ImageData < dimensions > : : isCompressed , " Whether the image is compressed " )
. def_property_readonly ( " storage " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
return self . storage ( ) ;
} , " Storage of pixel data " )
. def_property_readonly ( " format " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
return self . format ( ) ;
} , " Format of pixel data " )
. def_property_readonly ( " compressed_format " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( ! self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is not compressed " ) ;
throw py : : error_already_set { } ;
}
return self . compressedFormat ( ) ;
} , " Format of compressed pixel data " )
. def_property_readonly ( " pixel_size " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
return self . pixelSize ( ) ;
} , " Pixel size (in bytes) " )
. def_property_readonly ( " size " , [ ] ( Trade : : ImageData < dimensions > & self ) {
return PyDimensionTraits < dimensions , Int > : : from ( self . size ( ) ) ;
} , " Image size " )
. def_property_readonly ( " data " , [ ] ( Trade : : ImageData < dimensions > & self ) {
return Containers : : pyArrayViewHolder ( self . data ( ) , py : : cast ( self ) ) ;
} , " Raw image data " )
. def_property_readonly ( " mutable_data " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " image data is not mutable " ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( self . mutableData ( ) , py : : cast ( self ) ) ;
} , " Mutable raw image data " )
. def_property_readonly ( " pixels " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
return imagePixelsView ( self , self . data ( ) , self . pixels ( ) ) ;
} , " Pixel data " )
. def_property_readonly ( " mutable_pixels " , [ ] ( Trade : : ImageData < dimensions > & self ) {
if ( self . isCompressed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " image is compressed " ) ;
throw py : : error_already_set { } ;
}
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " image data is not mutable " ) ;
throw py : : error_already_set { } ;
}
return imagePixelsView ( self , self . mutableData ( ) , self . mutablePixels ( ) ) ;
} , " Mutable pixel data " )
. def_property_readonly ( " owner " , [ ] ( Trade : : ImageData < dimensions > & self ) {
return pyObjectHolderFor < Trade : : PyDataHolder > ( self ) . owner ;
} , " Memory owner " ) ;
}
/* For some reason having ...Args as the second (and not last) template
argument does not work . So I ' m listing all variants here . . . which are
exactly two , in fact . */
template < class R , R ( Trade : : AbstractImporter : : * f ) ( ) const > R checkOpened ( Trade : : AbstractImporter & self ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
return ( self . * f ) ( ) ;
}
template < class R , class Arg1 , R ( Trade : : AbstractImporter : : * f ) ( Arg1 ) > R checkOpened ( Trade : : AbstractImporter & self , Arg1 arg1 ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
return ( self . * f ) ( arg1 ) ;
}
/** @todo drop this in favor of our own string caster */
template < class R , R ( Trade : : AbstractImporter : : * f ) ( Containers : : StringView ) > R checkOpenedString ( Trade : : AbstractImporter & self , const std : : string & arg1 ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
return ( self . * f ) ( arg1 ) ;
}
template < class R , R ( Trade : : AbstractImporter : : * f ) ( UnsignedInt ) , UnsignedInt ( Trade : : AbstractImporter : : * bounds ) ( ) const > R checkOpenedBounds ( Trade : : AbstractImporter & self , UnsignedInt id ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
if ( id > = ( self . * bounds ) ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u entries " , id , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
return ( self . * f ) ( id ) ;
}
/** @todo drop this in favor of our own string caster */
template < class R , Containers : : String ( Trade : : AbstractImporter : : * f ) ( R ) , R ( Trade : : AbstractImporter : : * bounds ) ( ) const > std : : string checkOpenedBoundsReturnsString ( Trade : : AbstractImporter & self , R id ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
if ( id > = ( self . * bounds ) ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u entries " , id , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
return ( self . * f ) ( id ) ;
}
template < class R , Containers : : Optional < R > ( Trade : : AbstractImporter : : * f ) ( UnsignedInt ) , UnsignedInt ( Trade : : AbstractImporter : : * bounds ) ( ) const > R checkOpenedBoundsResult ( Trade : : AbstractImporter & self , UnsignedInt id ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
if ( id > = ( self . * bounds ) ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u entries " , id , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
Containers : : Optional < R > out = ( self . * f ) ( id ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
}
/** @todo drop std::string in favor of our own string caster */
template < class R , Containers : : Optional < R > ( Trade : : AbstractImporter : : * f ) ( UnsignedInt ) , Int ( Trade : : AbstractImporter : : * indexForName ) ( Containers : : StringView ) , UnsignedInt ( Trade : : AbstractImporter : : * bounds ) ( ) const > R checkOpenedBoundsResultString ( Trade : : AbstractImporter & self , const std : : string & name ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
const Int id = ( self . * indexForName ) ( name ) ;
if ( id = = - 1 ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u entries " , name . data ( ) , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
Containers : : Optional < R > out = ( self . * f ) ( id ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
}
template < class R , Containers : : Optional < R > ( Trade : : AbstractImporter : : * f ) ( UnsignedInt , UnsignedInt ) , UnsignedInt ( Trade : : AbstractImporter : : * bounds ) ( ) const , UnsignedInt ( Trade : : AbstractImporter : : * levelBounds ) ( UnsignedInt ) > R checkOpenedBoundsResult ( Trade : : AbstractImporter & self , UnsignedInt id , UnsignedInt level ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
if ( id > = ( self . * bounds ) ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u entries " , id , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
const UnsignedInt levelCount = ( self . * levelBounds ) ( id ) ;
if ( level > = levelCount ) {
PyErr_Format ( PyExc_IndexError , " level %u out of range for %u entries " , level , levelCount ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
Containers : : Optional < R > out = ( self . * f ) ( id , level ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
}
/** @todo drop std::string in favor of our own string caster */
template < class R , Containers : : Optional < R > ( Trade : : AbstractImporter : : * f ) ( UnsignedInt , UnsignedInt ) , Int ( Trade : : AbstractImporter : : * indexForName ) ( Containers : : StringView ) , UnsignedInt ( Trade : : AbstractImporter : : * bounds ) ( ) const , UnsignedInt ( Trade : : AbstractImporter : : * levelBounds ) ( UnsignedInt ) > R checkOpenedBoundsResultString ( Trade : : AbstractImporter & self , const std : : string & name , UnsignedInt level ) {
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
const Int id = ( self . * indexForName ) ( name ) ;
if ( id = = - 1 ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u entries " , name . data ( ) , ( self . * bounds ) ( ) ) ;
throw py : : error_already_set { } ;
}
const UnsignedInt levelCount = ( self . * levelBounds ) ( id ) ;
if ( level > = levelCount ) {
PyErr_Format ( PyExc_IndexError , " level %u out of range for %u entries " , level , levelCount ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
Containers : : Optional < R > out = ( self . * f ) ( id , level ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
}
/* Can't be named just checkResult() because the AbstractSceneConverter
overload would confuse GCC 4.8 */
template < class R , class T , Containers : : Optional < R > ( Trade : : AbstractImageConverter : : * f ) ( const T & ) > R checkImageConverterResult ( Trade : : AbstractImageConverter & self , const T & image ) {
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
Containers : : Optional < R > out = ( self . * f ) ( image ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " conversion failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
}
/** @todo drop std::string in favor of our own string caster */
template < class T , bool ( Trade : : AbstractImageConverter : : * f ) ( const T & , Containers : : StringView ) > void checkImageConverterResult ( Trade : : AbstractImageConverter & self , const T & image , const std : : string & filename ) {
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies , the user can still see why */
bool out = ( self . * f ) ( image ,
# ifdef CORRADE_TARGET_WINDOWS
/* To allow people to conveniently use Python's os.path, we need to
convert backslashes to forward slashes as all Corrade and Magnum
APIs expect forward */
Utility : : Path : : fromNativeSeparators ( filename )
# else
filename
# endif
) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " conversion failed " ) ;
throw py : : error_already_set { } ;
}
}
py : : object materialAttribute ( const Trade : : MaterialData & material , const UnsignedInt layer , const UnsignedInt id ) {
const Trade : : MaterialAttributeType type = material . attributeType ( layer , id ) ;
switch ( type ) {
# define _ct(enum_, type) \
case Trade : : MaterialAttributeType : : enum_ : \
return py : : cast ( material . attribute < type > ( layer , id ) ) ;
# define _c(type) _ct(type, type)
/* LCOV_EXCL_START */
_ct ( Bool , bool )
_c ( Float )
_c ( Deg )
_c ( Rad )
_c ( UnsignedInt )
_c ( Int )
_c ( UnsignedLong )
_c ( Long )
_c ( Vector2 )
_c ( Vector2ui )
_c ( Vector2i )
_c ( Vector3 )
_c ( Vector3ui )
_c ( Vector3i )
_c ( Vector4 )
_c ( Vector4ui )
_c ( Vector4i )
_c ( Matrix2x2 )
_c ( Matrix2x3 )
_c ( Matrix2x4 )
_c ( Matrix3x2 )
_c ( Matrix3x3 )
_c ( Matrix3x4 )
_c ( Matrix4x2 )
_c ( Matrix4x3 )
/* LCOV_EXCL_STOP */
_ct ( TextureSwizzle , Trade : : MaterialTextureSwizzle )
# undef _c
# undef _ct
/** @todo drop std::string in favor of our own string caster */
case Trade : : MaterialAttributeType : : String :
return py : : cast ( std : : string { material . attribute < Containers : : StringView > ( layer , id ) } ) ;
case Trade : : MaterialAttributeType : : Pointer :
case Trade : : MaterialAttributeType : : MutablePointer :
case Trade : : MaterialAttributeType : : Buffer :
PyErr_Format ( PyExc_NotImplementedError , " access to %S is not implemented yet, sorry " , py : : cast ( type ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
CORRADE_INTERNAL_ASSERT_UNREACHABLE ( ) ; /* LCOV_EXCL_LINE */
}
Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > accessorsForMeshIndexType ( const MeshIndexType type ) {
switch ( type ) {
# define _c(type) \
case MeshIndexType : : type : return { \
Containers : : Implementation : : pythonFormatString < type > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( * reinterpret_cast < const type * > ( item ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < type * > ( item ) = py : : cast < type > ( object ) ; \
} } ;
/* LCOV_EXCL_START */
_c ( UnsignedByte )
_c ( UnsignedShort )
_c ( UnsignedInt )
/* LCOV_EXCL_STOP */
# undef _c
}
CORRADE_INTERNAL_ASSERT_UNREACHABLE ( ) ; /* LCOV_EXCL_LINE */
}
Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > accessorsForVertexFormat ( const VertexFormat format ) {
switch ( format ) {
# define _c(format) \
case VertexFormat : : format : return { \
Containers : : Implementation : : pythonFormatString < format > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( * reinterpret_cast < const format * > ( item ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < format * > ( item ) = py : : cast < format > ( object ) ; \
} } ;
/* Types (such as half-floats) that need to be cast before passed
from / to pybind that doesn ' t understand the type directly */
# define _cc(format, castType) \
case VertexFormat : : format : return { \
Containers : : Implementation : : pythonFormatString < format > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( castType ( * reinterpret_cast < const format * > ( item ) ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < format * > ( item ) = format ( py : : cast < castType > ( object ) ) ; \
} } ;
/* Normalized types that need to be packed/unpacked before passed
from / to pybind */
# define _cNormalized(format, unpackType) \
case VertexFormat : : format # # Normalized : return { \
Containers : : Implementation : : pythonFormatString < format > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( Math : : unpack < unpackType > ( * reinterpret_cast < const format * > ( item ) ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < format * > ( item ) = Math : : pack < format > ( py : : cast < unpackType > ( object ) ) ; \
} } ;
/* LCOV_EXCL_START */
_c ( Float )
_c ( Double )
_c ( UnsignedByte )
_cNormalized ( UnsignedByte , Float )
_c ( Byte )
_cNormalized ( Byte , Float )
_c ( UnsignedShort )
_cNormalized ( UnsignedShort , Float )
_c ( Short )
_cNormalized ( Short , Float )
_c ( UnsignedInt )
_c ( Int )
_c ( Vector2 )
_c ( Vector2d )
_cc ( Vector2ub , Vector2ui )
_cNormalized ( Vector2ub , Vector2 )
_cc ( Vector2b , Vector2i )
_cNormalized ( Vector2b , Vector2 )
_cc ( Vector2us , Vector2ui )
_cNormalized ( Vector2us , Vector2 )
_cc ( Vector2s , Vector2i )
_cNormalized ( Vector2s , Vector2 )
_c ( Vector2ui )
_c ( Vector2i )
_c ( Vector3 )
_c ( Vector3d )
_cc ( Vector3ub , Vector3ui )
_cNormalized ( Vector3ub , Vector3 )
_cc ( Vector3b , Vector3i )
_cNormalized ( Vector3b , Vector3 )
_cc ( Vector3us , Vector3ui )
_cNormalized ( Vector3us , Vector3 )
_cc ( Vector3s , Vector3i )
_cNormalized ( Vector3s , Vector3 )
_c ( Vector3ui )
_c ( Vector3i )
_c ( Vector4 )
_c ( Vector4d )
_cc ( Vector4ub , Vector4ui )
_cNormalized ( Vector4ub , Vector4 )
_cc ( Vector4b , Vector4i )
_cNormalized ( Vector4b , Vector4 )
_cc ( Vector4us , Vector4ui )
_cNormalized ( Vector4us , Vector4 )
_cc ( Vector4s , Vector4i )
_cNormalized ( Vector4s , Vector4 )
_c ( Vector4ui )
_c ( Vector4i )
/* LCOV_EXCL_STOP */
# undef _c
# undef _cc
# undef _cNormalized
/** @todo handle half and matrix types */
default :
return { } ;
}
}
template < class T > Containers : : PyArrayViewHolder < Containers : : PyStridedArrayView < 1 , T > > meshIndicesView ( const MeshIndexType type , const Containers : : StridedArrayView2D < T > & data , py : : object owner ) {
const std : : size_t itemsize = meshIndexTypeSize ( type ) ;
const Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > formatStringGetitemSetitem = accessorsForMeshIndexType ( type ) ;
/** @todo update this once there are plugins that can give back custom
index types */
CORRADE_INTERNAL_ASSERT ( formatStringGetitemSetitem . first ( ) ) ;
return Containers : : pyArrayViewHolder ( Containers : : PyStridedArrayView < 1 , T > { data . template transposed < 0 , 1 > ( ) [ 0 ] , formatStringGetitemSetitem . first ( ) , itemsize , formatStringGetitemSetitem . second ( ) , formatStringGetitemSetitem . third ( ) } , std : : move ( owner ) ) ;
}
template < class T > Containers : : PyArrayViewHolder < Containers : : PyStridedArrayView < 1 , T > > meshAttributeView ( const VertexFormat format , const Containers : : StridedArrayView2D < T > & data , py : : object owner ) {
const std : : size_t itemsize = vertexFormatSize ( format ) ;
const Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > formatStringGetitemSetitem = accessorsForVertexFormat ( format ) ;
if ( ! formatStringGetitemSetitem . first ( ) ) {
PyErr_Format ( PyExc_NotImplementedError , " access to %S is not implemented yet, sorry " , py : : cast ( format ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( Containers : : PyStridedArrayView < 1 , T > { data . template transposed < 0 , 1 > ( ) [ 0 ] , formatStringGetitemSetitem . first ( ) , itemsize , formatStringGetitemSetitem . second ( ) , formatStringGetitemSetitem . third ( ) } , std : : move ( owner ) ) ;
}
Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > accessorsForSceneMappingType ( const Trade : : SceneMappingType type ) {
switch ( type ) {
# define _c(type) \
case Trade : : SceneMappingType : : type : return { \
Containers : : Implementation : : pythonFormatString < type > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( * reinterpret_cast < const type * > ( item ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < type * > ( item ) = py : : cast < type > ( object ) ; \
} } ;
/* LCOV_EXCL_START */
_c ( UnsignedByte )
_c ( UnsignedShort )
_c ( UnsignedInt )
_c ( UnsignedLong )
/* LCOV_EXCL_STOP */
# undef _c
}
CORRADE_INTERNAL_ASSERT_UNREACHABLE ( ) ; /* LCOV_EXCL_LINE */
}
Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > accessorsForSceneFieldType ( const Trade : : SceneFieldType type ) {
switch ( type ) {
# define _ctf(typeEnum, type, format) \
case Trade : : SceneFieldType : : typeEnum : return { \
format , \
[ ] ( const char * item ) { \
return py : : cast ( * reinterpret_cast < type const * > ( item ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < type * > ( item ) = py : : cast < type > ( object ) ; \
} } ;
# define _c(type) _ctf(type, type, Containers::Implementation::pythonFormatString<type>())
/* Types (such as half-floats) that need to be cast before passed
from / to pybind that doesn ' t understand the type directly */
# define _cc(type, castType) \
case Trade : : SceneFieldType : : type : return { \
Containers : : Implementation : : pythonFormatString < type > ( ) , \
[ ] ( const char * item ) { \
return py : : cast ( castType ( * reinterpret_cast < const type * > ( item ) ) ) ; \
} , \
[ ] ( char * item , py : : handle object ) { \
* reinterpret_cast < type * > ( item ) = type ( py : : cast < castType > ( object ) ) ; \
} } ;
/* LCOV_EXCL_START */
_c ( Float )
_c ( Double )
_c ( UnsignedByte )
_c ( Byte )
_c ( UnsignedShort )
_c ( Short )
_c ( UnsignedInt )
_c ( Int )
_c ( UnsignedLong )
_c ( Long )
_c ( Vector2 )
_c ( Vector2d )
_cc ( Vector2ub , Vector2ui )
_cc ( Vector2b , Vector2i )
_cc ( Vector2us , Vector2ui )
_cc ( Vector2s , Vector2i )
_c ( Vector2ui )
_c ( Vector2i )
_c ( Vector3 )
_c ( Vector3d )
_cc ( Vector3ub , Vector3ui )
_cc ( Vector3b , Vector3i )
_cc ( Vector3us , Vector3ui )
_cc ( Vector3s , Vector3i )
_c ( Vector3ui )
_c ( Vector3i )
_c ( Vector4 )
_c ( Vector4d )
_cc ( Vector4ub , Vector4ui )
_cc ( Vector4b , Vector4i )
_cc ( Vector4us , Vector4ui )
_cc ( Vector4s , Vector4i )
_c ( Vector4ui )
_c ( Vector4i )
_c ( Matrix2x2 )
_c ( Matrix2x2d )
_c ( Matrix2x3 )
_c ( Matrix2x3d )
_c ( Matrix2x4 )
_c ( Matrix2x4d )
_c ( Matrix3x2 )
_c ( Matrix3x2d )
_c ( Matrix3x3 )
_c ( Matrix3x3d )
_c ( Matrix3x4 )
_c ( Matrix3x4d )
_c ( Matrix4x2 )
_c ( Matrix4x2d )
_c ( Matrix4x3 )
_c ( Matrix4x3d )
_c ( Matrix4x4 )
_c ( Matrix4x4d )
_c ( Range1D )
_c ( Range1Dd )
_c ( Range1Di )
_c ( Range2D )
_c ( Range2Dd )
_c ( Range2Di )
_c ( Range3D )
_c ( Range3Dd )
_c ( Range3Di )
_c ( Complex )
_c ( Complexd )
_c ( DualComplex )
_c ( DualComplexd )
_c ( Quaternion )
_c ( Quaterniond )
_c ( DualQuaternion )
_c ( DualQuaterniond )
_c ( Deg )
_c ( Degd )
_c ( Rad )
_c ( Radd )
/* I see very little reason for accessing these from Python but
nevertheless , one never knows when it will be useful */
/** @todo passing them through as void* makes them a capsule object in
Python , is that useful for anything ? and the P type is useless for
numpy ( " 'P' is not a valid PEP 3118 buffer format string " ) */
_ctf ( Pointer , std : : size_t , " P " )
_ctf ( MutablePointer , std : : size_t , " P " )
/* LCOV_EXCL_STOP */
# undef _c
# undef _cc
/** @todo handle this once StridedBitArrayView is exposed */
case Trade : : SceneFieldType : : Bit :
/** @todo handle these once there's something to test with */
case Trade : : SceneFieldType : : Half :
case Trade : : SceneFieldType : : Vector2h :
case Trade : : SceneFieldType : : Vector3h :
case Trade : : SceneFieldType : : Vector4h :
case Trade : : SceneFieldType : : Matrix2x2h :
case Trade : : SceneFieldType : : Matrix2x3h :
case Trade : : SceneFieldType : : Matrix2x4h :
case Trade : : SceneFieldType : : Matrix3x2h :
case Trade : : SceneFieldType : : Matrix3x3h :
case Trade : : SceneFieldType : : Matrix3x4h :
case Trade : : SceneFieldType : : Matrix4x2h :
case Trade : : SceneFieldType : : Matrix4x3h :
case Trade : : SceneFieldType : : Matrix4x4h :
case Trade : : SceneFieldType : : Range1Dh :
case Trade : : SceneFieldType : : Range2Dh :
case Trade : : SceneFieldType : : Range3Dh :
case Trade : : SceneFieldType : : Degh :
case Trade : : SceneFieldType : : Radh :
/** @todo handle these once StringIterable is exposed */
case Trade : : SceneFieldType : : StringOffset8 :
case Trade : : SceneFieldType : : StringOffset16 :
case Trade : : SceneFieldType : : StringOffset32 :
case Trade : : SceneFieldType : : StringOffset64 :
case Trade : : SceneFieldType : : StringRange8 :
case Trade : : SceneFieldType : : StringRange16 :
case Trade : : SceneFieldType : : StringRange32 :
case Trade : : SceneFieldType : : StringRange64 :
case Trade : : SceneFieldType : : StringRangeNullTerminated8 :
case Trade : : SceneFieldType : : StringRangeNullTerminated16 :
case Trade : : SceneFieldType : : StringRangeNullTerminated32 :
case Trade : : SceneFieldType : : StringRangeNullTerminated64 :
return { } ;
}
CORRADE_INTERNAL_ASSERT_UNREACHABLE ( ) ; /* LCOV_EXCL_LINE */
}
template < class T > Containers : : PyArrayViewHolder < Containers : : PyStridedArrayView < 1 , T > > sceneMappingView ( const Trade : : SceneMappingType type , const Containers : : StridedArrayView2D < T > & data , py : : object owner ) {
const std : : size_t itemsize = Trade : : sceneMappingTypeSize ( type ) ;
const Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > formatStringGetitemSetitem = accessorsForSceneMappingType ( type ) ;
/* We support all mapping types */
CORRADE_INTERNAL_ASSERT ( formatStringGetitemSetitem . first ( ) ) ;
return Containers : : pyArrayViewHolder ( Containers : : PyStridedArrayView < 1 , T > { data . template transposed < 0 , 1 > ( ) [ 0 ] , formatStringGetitemSetitem . first ( ) , itemsize , formatStringGetitemSetitem . second ( ) , formatStringGetitemSetitem . third ( ) } , std : : move ( owner ) ) ;
}
template < class T > Containers : : PyArrayViewHolder < Containers : : PyStridedArrayView < 1 , T > > sceneFieldView ( const Trade : : SceneFieldType type , const Containers : : StridedArrayView2D < T > & data , py : : object owner ) {
const std : : size_t itemsize = Trade : : sceneFieldTypeSize ( type ) ;
const Containers : : Triple < const char * , py : : object ( * ) ( const char * ) , void ( * ) ( char * , py : : handle ) > formatStringGetitemSetitem = accessorsForSceneFieldType ( type ) ;
if ( ! formatStringGetitemSetitem . first ( ) ) {
PyErr_Format ( PyExc_NotImplementedError , " access to %S is not implemented yet, sorry " , py : : cast ( type ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( Containers : : PyStridedArrayView < 1 , T > { data . template transposed < 0 , 1 > ( ) [ 0 ] , formatStringGetitemSetitem . first ( ) , itemsize , formatStringGetitemSetitem . second ( ) , formatStringGetitemSetitem . third ( ) } , std : : move ( owner ) ) ;
}
}
void trade ( py : : module_ & m ) {
m . doc ( ) = " Data format exchange " ;
/* AbstractImporter depends on this */
py : : module_ : : import ( " corrade.pluginmanager " ) ;
py : : enum_ < Trade : : DataFlag > dataFlag { m , " DataFlags " , " Data flags " } ;
dataFlag
. value ( " OWNED " , Trade : : DataFlag : : Owned )
. value ( " EXTERNALLY_OWNED " , Trade : : DataFlag : : ExternallyOwned )
. value ( " GLOBAL " , Trade : : DataFlag : : Global )
. value ( " MUTABLE " , Trade : : DataFlag : : Mutable )
. value ( " NONE " , Trade : : DataFlag { } ) ;
corrade : : enumOperators ( dataFlag ) ;
py : : enum_ < Trade : : MeshAttribute > meshAttribute { m , " MeshAttribute " , " Mesh attribute name " } ;
meshAttribute
. value ( " POSITION " , Trade : : MeshAttribute : : Position )
. value ( " TANGENT " , Trade : : MeshAttribute : : Tangent )
. value ( " BITANGENT " , Trade : : MeshAttribute : : Bitangent )
. value ( " NORMAL " , Trade : : MeshAttribute : : Normal )
. value ( " TEXTURE_COORDINATES " , Trade : : MeshAttribute : : TextureCoordinates )
. value ( " COLOR " , Trade : : MeshAttribute : : Color )
. value ( " JOINT_IDS " , Trade : : MeshAttribute : : JointIds )
. value ( " WEIGHTS " , Trade : : MeshAttribute : : Weights )
. value ( " OBJECT_ID " , Trade : : MeshAttribute : : ObjectId ) ;
enumWithCustomValues < Trade : : MeshAttribute , Trade : : Implementation : : MeshAttributeCustom > ( meshAttribute ) ;
py : : class_ < Trade : : MeshData , Trade : : PyDataHolder < Trade : : MeshData > > { m , " MeshData " , " Mesh data " }
. def_property_readonly ( " primitive " , & Trade : : MeshData : : primitive , " Primitive " )
. def_property_readonly ( " index_data_flags " , [ ] ( const Trade : : MeshData & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . indexDataFlags ( ) ) ) ;
} , " Index data flags " )
. def_property_readonly ( " vertex_data_flags " , [ ] ( const Trade : : MeshData & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . vertexDataFlags ( ) ) ) ;
} , " Vertex data flags " )
. def_property_readonly ( " index_data " , [ ] ( const Trade : : MeshData & self ) {
return Containers : : pyArrayViewHolder ( self . indexData ( ) , py : : cast ( self ) ) ;
} , " Raw index data " )
. def_property_readonly ( " mutable_index_data " , [ ] ( Trade : : MeshData & self ) {
if ( ! ( self . indexDataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh index data is not mutable " ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( self . mutableIndexData ( ) , py : : cast ( self ) ) ;
} , " Mutable raw index data " )
/** @todo direct access to MeshAttributeData, once making custom
MeshData is desired */
. def_property_readonly ( " vertex_data " , [ ] ( const Trade : : MeshData & self ) {
return Containers : : pyArrayViewHolder ( self . vertexData ( ) , py : : cast ( self ) ) ;
} , " Raw vertex data " )
. def_property_readonly ( " mutable_vertex_data " , [ ] ( Trade : : MeshData & self ) {
if ( ! ( self . vertexDataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh vertex data is not mutable " ) ;
throw py : : error_already_set { } ;
}
return Containers : : pyArrayViewHolder ( self . mutableVertexData ( ) , py : : cast ( self ) ) ;
} , " Mutable raw vertex data " )
. def_property_readonly ( " is_indexed " , & Trade : : MeshData : : isIndexed , " Whether the mesh is indexed " )
. def_property_readonly ( " index_count " , [ ] ( const Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
return self . indexCount ( ) ;
} , " Index count " )
. def_property_readonly ( " index_type " , [ ] ( const Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
return self . indexType ( ) ;
} , " Index type " )
. def_property_readonly ( " index_offset " , [ ] ( const Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
return self . indexOffset ( ) ;
} , " Index offset " )
. def_property_readonly ( " index_stride " , [ ] ( const Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
return self . indexStride ( ) ;
} , " Index stride " )
. def_property_readonly ( " indices " , [ ] ( /*const*/ Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
return meshIndicesView ( self . indexType ( ) , self . indices ( ) , py : : cast ( self ) ) ;
} , " Indices " )
. def_property_readonly ( " mutable_indices " , [ ] ( Trade : : MeshData & self ) {
if ( ! self . isIndexed ( ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh is not indexed " ) ;
throw py : : error_already_set { } ;
}
if ( ! ( self . indexDataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh index data is not mutable " ) ;
throw py : : error_already_set { } ;
}
return meshIndicesView ( self . indexType ( ) , self . mutableIndices ( ) , py : : cast ( self ) ) ;
} , " Mutable indices " )
. def_property_readonly ( " vertex_count " , & Trade : : MeshData : : vertexCount , " Vertex count " )
/* Has to be a function instead of a property because there's an
overload taking a morph target ID and an overload taking a name */
. def ( " attribute_count " , static_cast < UnsignedInt ( Trade : : MeshData : : * ) ( ) const > ( & Trade : : MeshData : : attributeCount ) , " Attribute array count " )
/** @todo direct access to MeshAttributeData, once making custom
MeshData is desired */
. def ( " has_attribute " , & Trade : : MeshData : : hasAttribute , " Whether the mesh has given attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " morph_target_id " ) = - 1 )
/* IMPORTANT: due to pybind11 behavioral differences on (already EOL'd)
Python 3.7 the following overloads need to have the MeshAttribute
overload * before * the UnsignedInt overload , otherwise the integer
overload gets picked even if an enum is passed from Python , causing
massive suffering */
. def ( " attribute_count " , static_cast < UnsignedInt ( Trade : : MeshData : : * ) ( Trade : : MeshAttribute , Int ) const > ( & Trade : : MeshData : : attributeCount ) , " Count of given named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_count " , static_cast < UnsignedInt ( Trade : : MeshData : : * ) ( Int ) const > ( & Trade : : MeshData : : attributeCount ) , " Attribute array count for given morph target " ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " morph_target_id " ) )
. def ( " attribute_name " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeName ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute name " , py : : arg ( " id " ) )
. def ( " attribute_id " , [ ] ( const Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) )
return * found ;
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Absolute ID of a named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_id " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeId ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute ID in a set of attributes of the same name " , py : : arg ( " id " ) )
. def ( " attribute_format " , [ ] ( const Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) )
return self . attributeFormat ( * found ) ;
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Format of a named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_format " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeFormat ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute format " , py : : arg ( " id " ) )
. def ( " attribute_offset " , [ ] ( const Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) )
return self . attributeOffset ( * found ) ;
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Offset of a named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_offset " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeOffset ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute offset " , py : : arg ( " id " ) )
. def ( " attribute_stride " , [ ] ( const Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) )
return self . attributeStride ( * found ) ;
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Stride of a named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_stride " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeStride ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute stride " , py : : arg ( " id " ) )
. def ( " attribute_array_size " , [ ] ( const Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) )
return self . attributeArraySize ( * found ) ;
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Array size of a named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute_array_size " , [ ] ( const Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) )
return self . attributeArraySize ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute array size " , py : : arg ( " id " ) )
. def ( " attribute " , [ ] ( /*const*/ Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) ) {
/** @todo handle arrays (return a 2D view, and especially
annotate the return type properly in the docs ) */
if ( self . attributeArraySize ( * found ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array attributes not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
return meshAttributeView ( self . attributeFormat ( * found ) , self . attribute ( * found ) , py : : cast ( self ) ) ;
}
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Data for given named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " attribute " , [ ] ( /*const*/ Trade : : MeshData & self , UnsignedInt id ) {
if ( id < self . attributeCount ( ) ) {
/** @todo handle arrays (return a 2D view, and especially
annotate the return type properly in the docs ) */
if ( self . attributeArraySize ( id ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array attributes not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
return meshAttributeView ( self . attributeFormat ( id ) , self . attribute ( id ) , py : : cast ( self ) ) ;
}
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Data for given attribute " , py : : arg ( " id " ) )
. def ( " mutable_attribute " , [ ] ( Trade : : MeshData & self , Trade : : MeshAttribute name , UnsignedInt id , Int morphTargetId ) {
if ( ! ( self . vertexDataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh vertex data is not mutable " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name , id , morphTargetId ) ) {
/** @todo handle arrays (return a 2D view, and especially
annotate the return type properly in the docs ) */
if ( self . attributeArraySize ( * found ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array attributes not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
return meshAttributeView ( self . attributeFormat ( * found ) , self . mutableAttribute ( * found ) , py : : cast ( self ) ) ;
}
const UnsignedInt attributeCount = self . attributeCount ( name , morphTargetId ) ;
if ( morphTargetId = = - 1 )
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes " , id , attributeCount , py : : cast ( name ) . ptr ( ) ) ;
else
PyErr_Format ( PyExc_KeyError , " index %u out of range for %u %S attributes in morph target %i " , id , attributeCount , py : : cast ( name ) . ptr ( ) , morphTargetId ) ;
throw py : : error_already_set { } ;
} , " Mutable data for given named attribute " , py : : arg ( " name " ) ,
# if PYBIND11_VERSION_MAJOR*100 + PYBIND11_VERSION_MINOR >= 206
py : : kw_only { } , /* new in pybind11 2.6 */
# endif
py : : arg ( " id " ) = 0 , py : : arg ( " morph_target_id " ) = - 1 )
. def ( " mutable_attribute " , [ ] ( Trade : : MeshData & self , UnsignedInt id ) {
if ( ! ( self . vertexDataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " mesh vertex data is not mutable " ) ;
throw py : : error_already_set { } ;
}
if ( id < self . attributeCount ( ) ) {
/** @todo handle arrays (return a 2D view, and especially
annotate the return type properly in the docs ) */
if ( self . attributeArraySize ( id ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array attributes not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
return meshAttributeView ( self . attributeFormat ( id ) , self . mutableAttribute ( id ) , py : : cast ( self ) ) ;
}
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Mutable data for given attribute " , py : : arg ( " id " ) )
. def_property_readonly ( " owner " , [ ] ( Trade : : MeshData & self ) {
return pyObjectHolderFor < Trade : : PyDataHolder > ( self ) . owner ;
} , " Memory owner " ) ;
py : : enum_ < Trade : : MaterialLayer > { m , " MaterialLayer " , " Material layer name " }
. value ( " CLEAR_COAT " , Trade : : MaterialLayer : : ClearCoat )
. def_property_readonly ( " string " , [ ] ( Trade : : MaterialLayer value ) {
/** @todo drop std::string in favor of our own string caster */
return std : : string { Trade : : materialLayerName ( value ) } ;
} ) ;
py : : enum_ < Trade : : MaterialAttribute > { m , " MaterialAttribute " , " Material attribute name " }
. value ( " LAYER_NAME " , Trade : : MaterialAttribute : : LayerName )
. value ( " ALPHA_MASK " , Trade : : MaterialAttribute : : AlphaMask )
. value ( " ALPHA_BLEND " , Trade : : MaterialAttribute : : AlphaBlend )
. value ( " DOUBLE_SIDED " , Trade : : MaterialAttribute : : DoubleSided )
. value ( " AMBIENT_COLOR " , Trade : : MaterialAttribute : : AmbientColor )
. value ( " AMBIENT_TEXTURE " , Trade : : MaterialAttribute : : AmbientTexture )
. value ( " AMBIENT_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : AmbientTextureMatrix )
. value ( " AMBIENT_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : AmbientTextureCoordinates )
. value ( " AMBIENT_TEXTURE_LAYER " , Trade : : MaterialAttribute : : AmbientTextureLayer )
. value ( " DIFFUSE_COLOR " , Trade : : MaterialAttribute : : DiffuseColor )
. value ( " DIFFUSE_TEXTURE " , Trade : : MaterialAttribute : : DiffuseTexture )
. value ( " DIFFUSE_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : DiffuseTextureMatrix )
. value ( " DIFFUSE_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : DiffuseTextureCoordinates )
. value ( " DIFFUSE_TEXTURE_LAYER " , Trade : : MaterialAttribute : : DiffuseTextureLayer )
. value ( " SPECULAR_COLOR " , Trade : : MaterialAttribute : : SpecularColor )
. value ( " SPECULAR_TEXTURE " , Trade : : MaterialAttribute : : SpecularTexture )
. value ( " SPECULAR_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : SpecularTextureSwizzle )
. value ( " SPECULAR_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : SpecularTextureMatrix )
. value ( " SPECULAR_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : SpecularTextureCoordinates )
. value ( " SPECULAR_TEXTURE_LAYER " , Trade : : MaterialAttribute : : SpecularTextureLayer )
. value ( " SHININESS " , Trade : : MaterialAttribute : : Shininess )
. value ( " BASE_COLOR " , Trade : : MaterialAttribute : : BaseColor )
. value ( " BASE_COLOR_TEXTURE " , Trade : : MaterialAttribute : : BaseColorTexture )
. value ( " BASE_COLOR_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : BaseColorTextureMatrix )
. value ( " BASE_COLOR_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : BaseColorTextureCoordinates )
. value ( " BASE_COLOR_TEXTURE_LAYER " , Trade : : MaterialAttribute : : BaseColorTextureLayer )
. value ( " METALNESS " , Trade : : MaterialAttribute : : Metalness )
. value ( " METALNESS_TEXTURE " , Trade : : MaterialAttribute : : MetalnessTexture )
. value ( " METALNESS_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : MetalnessTextureSwizzle )
. value ( " METALNESS_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : MetalnessTextureMatrix )
. value ( " METALNESS_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : MetalnessTextureCoordinates )
. value ( " METALNESS_TEXTURE_LAYER " , Trade : : MaterialAttribute : : MetalnessTextureLayer )
. value ( " ROUGHNESS " , Trade : : MaterialAttribute : : Roughness )
. value ( " ROUGHNESS_TEXTURE " , Trade : : MaterialAttribute : : RoughnessTexture )
. value ( " ROUGHNESS_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : RoughnessTextureSwizzle )
. value ( " ROUGHNESS_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : RoughnessTextureMatrix )
. value ( " ROUGHNESS_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : RoughnessTextureCoordinates )
. value ( " ROUGHNESS_TEXTURE_LAYER " , Trade : : MaterialAttribute : : RoughnessTextureLayer )
. value ( " NONE_ROUGHNESS_METALLIC_TEXTURE " , Trade : : MaterialAttribute : : NoneRoughnessMetallicTexture )
. value ( " GLOSSINESS " , Trade : : MaterialAttribute : : Glossiness )
. value ( " GLOSSINESS_TEXTURE " , Trade : : MaterialAttribute : : GlossinessTexture )
. value ( " GLOSSINESS_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : GlossinessTextureSwizzle )
. value ( " GLOSSINESS_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : GlossinessTextureMatrix )
. value ( " GLOSSINESS_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : GlossinessTextureCoordinates )
. value ( " GLOSSINESS_TEXTURE_LAYER " , Trade : : MaterialAttribute : : GlossinessTextureLayer )
. value ( " SPECULAR_GLOSSINESS_TEXTURE " , Trade : : MaterialAttribute : : SpecularGlossinessTexture )
. value ( " NORMAL_TEXTURE " , Trade : : MaterialAttribute : : NormalTexture )
. value ( " NORMAL_TEXTURE_SCALE " , Trade : : MaterialAttribute : : NormalTextureScale )
. value ( " NORMAL_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : NormalTextureSwizzle )
. value ( " NORMAL_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : NormalTextureMatrix )
. value ( " NORMAL_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : NormalTextureCoordinates )
. value ( " NORMAL_TEXTURE_LAYER " , Trade : : MaterialAttribute : : NormalTextureLayer )
. value ( " OCCLUSION_TEXTURE " , Trade : : MaterialAttribute : : OcclusionTexture )
. value ( " OCCLUSION_TEXTURE_STRENGTH " , Trade : : MaterialAttribute : : OcclusionTextureStrength )
. value ( " OCCLUSION_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : OcclusionTextureSwizzle )
. value ( " OCCLUSION_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : OcclusionTextureMatrix )
. value ( " OCCLUSION_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : OcclusionTextureCoordinates )
. value ( " OCCLUSION_TEXTURE_LAYER " , Trade : : MaterialAttribute : : OcclusionTextureLayer )
. value ( " EMISSIVE_COLOR " , Trade : : MaterialAttribute : : EmissiveColor )
. value ( " EMISSIVE_TEXTURE " , Trade : : MaterialAttribute : : EmissiveTexture )
. value ( " EMISSIVE_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : EmissiveTextureMatrix )
. value ( " EMISSIVE_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : EmissiveTextureCoordinates )
. value ( " EMISSIVE_TEXTURE_LAYER " , Trade : : MaterialAttribute : : EmissiveTextureLayer )
. value ( " LAYER_FACTOR " , Trade : : MaterialAttribute : : LayerFactor )
. value ( " LAYER_FACTOR_TEXTURE " , Trade : : MaterialAttribute : : LayerFactorTexture )
. value ( " LAYER_FACTOR_TEXTURE_SWIZZLE " , Trade : : MaterialAttribute : : LayerFactorTextureSwizzle )
. value ( " LAYER_FACTOR_TEXTURE_MATRIX " , Trade : : MaterialAttribute : : LayerFactorTextureMatrix )
. value ( " LAYER_FACTOR_TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : LayerFactorTextureCoordinates )
. value ( " LAYER_FACTOR_TEXTURE_LAYER " , Trade : : MaterialAttribute : : LayerFactorTextureLayer )
. value ( " TEXTURE_MATRIX " , Trade : : MaterialAttribute : : TextureMatrix )
. value ( " TEXTURE_COORDINATES " , Trade : : MaterialAttribute : : TextureCoordinates )
. value ( " TEXTURE_LAYER " , Trade : : MaterialAttribute : : TextureLayer )
. def_property_readonly ( " string " , [ ] ( Trade : : MaterialAttribute value ) {
/** @todo drop std::string in favor of our own string caster */
return std : : string { Trade : : materialAttributeName ( value ) } ;
} ) ;
py : : enum_ < Trade : : MaterialTextureSwizzle > { m , " MaterialTextureSwizzle " , " Material texture swizzle " }
. value ( " R " , Trade : : MaterialTextureSwizzle : : R )
. value ( " G " , Trade : : MaterialTextureSwizzle : : G )
. value ( " B " , Trade : : MaterialTextureSwizzle : : B )
. value ( " A " , Trade : : MaterialTextureSwizzle : : A )
. value ( " RG " , Trade : : MaterialTextureSwizzle : : RG )
. value ( " GB " , Trade : : MaterialTextureSwizzle : : GB )
. value ( " GA " , Trade : : MaterialTextureSwizzle : : GA )
. value ( " BA " , Trade : : MaterialTextureSwizzle : : BA )
. value ( " RGB " , Trade : : MaterialTextureSwizzle : : RGB )
. value ( " GBA " , Trade : : MaterialTextureSwizzle : : GBA )
. value ( " RGBA " , Trade : : MaterialTextureSwizzle : : RGBA )
. def_property_readonly ( " component_count " , [ ] ( Trade : : MaterialTextureSwizzle value ) {
return Trade : : materialTextureSwizzleComponentCount ( value ) ;
} ) ;
py : : enum_ < Trade : : MaterialAttributeType > { m , " MaterialAttributeType " , " Material attribute type " }
. value ( " BOOL " , Trade : : MaterialAttributeType : : Bool )
. value ( " FLOAT " , Trade : : MaterialAttributeType : : Float )
. value ( " DEG " , Trade : : MaterialAttributeType : : Deg )
. value ( " RAD " , Trade : : MaterialAttributeType : : Rad )
. value ( " UNSIGNED_INT " , Trade : : MaterialAttributeType : : UnsignedInt )
. value ( " INT " , Trade : : MaterialAttributeType : : Int )
. value ( " UNSIGNED_LONG " , Trade : : MaterialAttributeType : : UnsignedLong )
. value ( " LONG " , Trade : : MaterialAttributeType : : Long )
. value ( " VECTOR2 " , Trade : : MaterialAttributeType : : Vector2 )
. value ( " VECTOR2UI " , Trade : : MaterialAttributeType : : Vector2ui )
. value ( " VECTOR2I " , Trade : : MaterialAttributeType : : Vector2i )
. value ( " VECTOR3 " , Trade : : MaterialAttributeType : : Vector3 )
. value ( " VECTOR3UI " , Trade : : MaterialAttributeType : : Vector3ui )
. value ( " VECTOR3I " , Trade : : MaterialAttributeType : : Vector3i )
. value ( " VECTOR4 " , Trade : : MaterialAttributeType : : Vector4 )
. value ( " VECTOR4UI " , Trade : : MaterialAttributeType : : Vector4ui )
. value ( " VECTOR4I " , Trade : : MaterialAttributeType : : Vector4i )
. value ( " MATRIX2X2 " , Trade : : MaterialAttributeType : : Matrix2x2 )
. value ( " MATRIX2X3 " , Trade : : MaterialAttributeType : : Matrix2x3 )
. value ( " MATRIX2X4 " , Trade : : MaterialAttributeType : : Matrix2x4 )
. value ( " MATRIX3X2 " , Trade : : MaterialAttributeType : : Matrix3x2 )
. value ( " MATRIX3X3 " , Trade : : MaterialAttributeType : : Matrix3x3 )
. value ( " MATRIX3X4 " , Trade : : MaterialAttributeType : : Matrix3x4 )
. value ( " MATRIX4X2 " , Trade : : MaterialAttributeType : : Matrix4x2 )
. value ( " MATRIX4X3 " , Trade : : MaterialAttributeType : : Matrix4x3 )
. value ( " POINTER " , Trade : : MaterialAttributeType : : Pointer )
. value ( " MUTABLE_POINTER " , Trade : : MaterialAttributeType : : MutablePointer )
. value ( " STRING " , Trade : : MaterialAttributeType : : String )
. value ( " BUFFER " , Trade : : MaterialAttributeType : : Buffer )
. value ( " TEXTURE_SWIZZLE " , Trade : : MaterialAttributeType : : TextureSwizzle ) ;
py : : enum_ < Trade : : MaterialType > materialType { m , " MaterialTypes " , " Material types " } ;
materialType
. value ( " FLAT " , Trade : : MaterialType : : Flat )
. value ( " PHONG " , Trade : : MaterialType : : Phong )
. value ( " PBR_METALLIC_ROUGHNESS " , Trade : : MaterialType : : PbrMetallicRoughness )
. value ( " PBR_SPECULAR_GLOSSINESS " , Trade : : MaterialType : : PbrSpecularGlossiness )
. value ( " PBR_CLEAR_COAT " , Trade : : MaterialType : : PbrClearCoat )
. value ( " NONE " , Trade : : MaterialType { } )
. value ( " ALL " , Trade : : MaterialType ( Containers : : enumCastUnderlyingType ( ~ Trade : : MaterialType { } ) ) ) ;
corrade : : enumOperators ( materialType ) ;
py : : enum_ < Trade : : MaterialAlphaMode > { m , " MaterialAlphaMode " , " Material alpha mode " }
. value ( " OPAQUE " , Trade : : MaterialAlphaMode : : Opaque )
. value ( " MASK " , Trade : : MaterialAlphaMode : : Mask )
. value ( " BLEND " , Trade : : MaterialAlphaMode : : Blend ) ;
py : : class_ < Trade : : MaterialData , Trade : : PyDataHolder < Trade : : MaterialData > > { m , " MaterialData " , " Material data " }
. def_property_readonly ( " attribute_data_flags " , [ ] ( const Trade : : MaterialData & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . attributeDataFlags ( ) ) ) ;
} , " Attribute data flags " )
. def_property_readonly ( " layer_data_flags " , [ ] ( const Trade : : MaterialData & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . layerDataFlags ( ) ) ) ;
} , " Layer data flags " )
. def_property_readonly ( " types " , [ ] ( const Trade : : MaterialData & self ) {
return Trade : : MaterialType ( Containers : : enumCastUnderlyingType ( self . types ( ) ) ) ;
} , " Material types " )
/** @todo as(), how to even implement that? */
/** @todo direct access to MaterialAttributeData and layer data, once
making custom MaterialData is desirable */
. def_property_readonly ( " layer_count " , & Trade : : MaterialData : : layerCount , " Layer count " )
. def ( " attribute_data_offset " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeDataOffset ( layer ) ;
} , " Offset of a layer inside attribute data " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_layer " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
return self . hasLayer ( layer ) ;
} , " Whether a material has given named layer " , py : : arg ( " layer " ) )
. def ( " has_layer " , static_cast < bool ( Trade : : MaterialData : : * ) ( Trade : : MaterialLayer ) const > ( & Trade : : MaterialData : : hasLayer ) , " Whether a material has given named layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_id " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return * found ;
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " ID of a named layer " , py : : arg ( " layer " ) )
. def ( " layer_id " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return * found ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " ID of a named layer " , py : : arg ( " layer " ) )
. def ( " layer_name " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo drop std::string in favor of our own string caster */
return std : : string { self . layerName ( layer ) } ;
} , " Layer name " , py : : arg ( " layer " ) )
/* IMPORTANT: due to pybind11 behavioral differences on (already EOL'd)
Python 3.7 the following overloads need to have the MaterialLayer
and MaterialAttribute overloads * before * the UnsignedInt overloads ,
otherwise the integer overload gets picked even if an enum is passed
from Python , causing massive suffering */
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . layerFactor ( * found ) ;
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Factor of a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . layerFactor ( * found ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Factor of a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactor ( layer ) ;
} , " Factor of given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor_texture " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTexture ( * found ) ;
} , " Factor texture ID for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTexture ( * found ) ;
} , " Factor texture ID for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( layer , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTexture ( layer ) ;
} , " Factor texture ID for given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor_texture_swizzle " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureSwizzle ( * found ) ;
} , " Factor texture swizzle for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_swizzle " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " name %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureSwizzle ( * found ) ;
} , " Factor texture swizzle for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_swizzle " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( layer , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureSwizzle ( layer ) ;
} , " Factor texture swizzle for given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor_texture_matrix " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureMatrix ( * found ) ;
} , " Factor texture coordinate transformation matrix for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_matrix " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureMatrix ( * found ) ;
} , " Factor texture coordinate transformation matrix for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_matrix " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( layer , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureMatrix ( layer ) ;
} , " Factor texture coordinate transformation matrix for given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor_texture_coordinates " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureCoordinates ( * found ) ;
} , " Factor texture coordinate set for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_coordinates " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureCoordinates ( * found ) ;
} , " Factor texture coordinate set for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_coordinates " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( layer , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureCoordinates ( layer ) ;
} , " Factor texture coordinate set for given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " layer_factor_texture_layer " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureLayer ( * found ) ;
} , " Factor array texture layer for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_layer " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( * found , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureLayer ( * found ) ;
} , " Factor array texture layer for a named layer " , py : : arg ( " layer " ) )
. def ( " layer_factor_texture_layer " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! self . hasAttribute ( layer , Trade : : MaterialAttribute : : LayerFactorTexture ) ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( Trade : : MaterialAttribute : : LayerFactorTexture ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . layerFactorTextureLayer ( layer ) ;
} , " Factor array texture layer for given layer " , py : : arg ( " layer " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_count " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . attributeCount ( * found ) ;
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute count in a named layer " , py : : arg ( " layer " ) )
. def ( " attribute_count " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . attributeCount ( * found ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Attribute count in a named layer " , py : : arg ( " layer " ) )
. def ( " attribute_count " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeCount ( layer ) ;
} , " Attribute count in given layer " , py : : arg ( " layer " ) )
. def ( " attribute_count " , static_cast < UnsignedInt ( Trade : : MaterialData : : * ) ( ) const > ( & Trade : : MaterialData : : attributeCount ) ,
" Attribute count in the base material " )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const std : : string & name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . hasAttribute ( * found , name ) ;
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Whether a named material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const Trade : : MaterialAttribute name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . hasAttribute ( * found , name ) ;
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Whether a named material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const std : : string & name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . hasAttribute ( * found , name ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Whether a named material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const Trade : : MaterialAttribute name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findLayerId ( layer ) )
return self . hasAttribute ( * found , name ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Whether a named material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const std : : string & name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . hasAttribute ( layer , name ) ;
} , " Whether a material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const Trade : : MaterialAttribute name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . hasAttribute ( layer , name ) ;
} , " Whether a material layer has given attribute " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " has_attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & name ) {
return self . hasAttribute ( name ) ;
} , " Whether the base material has given attribute " , py : : arg ( " name " ) )
. def ( " has_attribute " , static_cast < bool ( Trade : : MaterialData : : * ) ( Trade : : MaterialAttribute ) const > ( & Trade : : MaterialData : : hasAttribute ) ,
" Whether the base material has given attribute " , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( * foundLayer , name ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %s " , name . data ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( * foundLayer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( name ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( * foundLayer , name ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " attribute %s not found in %S " , name . data ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( * foundLayer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( name ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const std : : string & name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %d " , name . data ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const Trade : : MaterialAttribute name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %d " , py : : cast ( name ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " attribute %s not found in the base material " , name . data ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in the base material " , py : : arg ( " name " ) )
. def ( " attribute_id " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in the base material " , py : : cast ( name ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return * found ;
} , " ID of a named attribute in the base material " , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_name " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %s " , id , self . attributeCount ( * foundLayer ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo drop std::string in favor of our own string caster */
return std : : string { self . attributeName ( * foundLayer , id ) } ;
} , " Name of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
. def ( " attribute_name " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in %S " , id , self . attributeCount ( * foundLayer ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo drop std::string in favor of our own string caster */
return std : : string { self . attributeName ( * foundLayer , id ) } ;
} , " Name of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
. def ( " attribute_name " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const UnsignedInt id ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( layer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %u " , id , self . attributeCount ( layer ) , layer ) ;
throw py : : error_already_set { } ;
}
return std : : string { self . attributeName ( layer , id ) } ;
} , " Name of an attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
. def ( " attribute_name " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt id ) {
if ( id > = self . attributeCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in the base material " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo drop std::string in favor of our own string caster */
return std : : string { self . attributeName ( id ) } ;
} , " Name of an attribute in the base material " , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %s " , name . data ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , * found ) ;
} , " Type of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( name ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , * found ) ;
} , " Type of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %s " , id , self . attributeCount ( * foundLayer ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , id ) ;
} , " Type of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in %S " , name . data ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , * found ) ;
} , " Type of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( name ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , * found ) ;
} , " Type of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in %S " , id , self . attributeCount ( * foundLayer ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * foundLayer , id ) ;
} , " Type of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const std : : string & name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %u " , name . data ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( layer , * found ) ;
} , " Type of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const Trade : : MaterialAttribute name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( name ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( layer , * found ) ;
} , " Type of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const UnsignedInt id ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( layer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %u " , id , self . attributeCount ( layer ) , layer ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( layer , id ) ;
} , " Type of an attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in the base material " , name . data ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * found ) ;
} , " Type of a named attribute in the base material " , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in the base material " , py : : cast ( name ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( * found ) ;
} , " Type of a named attribute in the base material " , py : : arg ( " name " ) )
. def ( " attribute_type " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt id ) {
if ( id > = self . attributeCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in the base material " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
}
return self . attributeType ( id ) ;
} , " Type of an attribute in the base material " , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %s " , name . data ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , * found ) ;
} , " Value of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %s " , py : : cast ( name ) . ptr ( ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , * found ) ;
} , " Value of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u layers " , layer . data ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %s " , id , self . attributeCount ( * foundLayer ) , layer . data ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , id ) ;
} , " Value of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in %S " , name . data ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , * found ) ;
} , " Value of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in %S " , py : : cast ( name ) . ptr ( ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , * found ) ;
} , " Value of a named attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialLayer layer , const UnsignedInt id ) {
const Containers : : Optional < UnsignedInt > foundLayer = self . findLayerId ( layer ) ;
if ( ! foundLayer ) {
PyErr_Format ( PyExc_KeyError , " %S not found among %u layers " , py : : cast ( layer ) . ptr ( ) , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( * foundLayer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in %S " , id , self . attributeCount ( * foundLayer ) , py : : cast ( layer ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , * foundLayer , id ) ;
} , " Value of an attribute in a named material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const std : : string & name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in layer %u " , name . data ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , layer , * found ) ;
} , " Value of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const Trade : : MaterialAttribute name ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( layer , name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in layer %u " , py : : cast ( name ) . ptr ( ) , layer ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , layer , * found ) ;
} , " Value of a named attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt layer , const UnsignedInt id ) {
if ( layer > = self . layerCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u layers " , layer , self . layerCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . attributeCount ( layer ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in layer %u " , id , self . attributeCount ( layer ) , layer ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , layer , id ) ;
} , " Value of an attribute in given material layer " , py : : arg ( " layer " ) , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const std : : string & name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " attribute %s not found in the base material " , name . data ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , 0 , * found ) ;
} , " Value of a named attribute in the base material " , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const Trade : : MaterialAttribute name ) {
const Containers : : Optional < UnsignedInt > found = self . findAttributeId ( name ) ;
if ( ! found ) {
PyErr_Format ( PyExc_KeyError , " %S not found in the base material " , py : : cast ( name ) . ptr ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , 0 , * found ) ;
} , " Value of a named attribute in the base material " , py : : arg ( " name " ) )
. def ( " attribute " , [ ] ( const Trade : : MaterialData & self , const UnsignedInt id ) {
if ( id > = self . attributeCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u attributes in the base material " , id , self . attributeCount ( ) ) ;
throw py : : error_already_set { } ;
}
return materialAttribute ( self , 0 , id ) ;
} , " Value of an attribute in the base material " , py : : arg ( " id " ) )
. def_property_readonly ( " is_double_sided " , & Trade : : MaterialData : : isDoubleSided ,
" Whether a material is double-sided " )
. def_property_readonly ( " alpha_mode " , & Trade : : MaterialData : : alphaMode ,
" Alpha mode " )
. def_property_readonly ( " alpha_mask " , & Trade : : MaterialData : : alphaMask ,
" Alpha mask " ) ;
py : : class_ < Trade : : ImageData1D , Trade : : PyDataHolder < Trade : : ImageData1D > > imageData1D { m , " ImageData1D " , " One-dimensional image data " } ;
py : : class_ < Trade : : ImageData2D , Trade : : PyDataHolder < Trade : : ImageData2D > > imageData2D { m , " ImageData2D " , " Two-dimensional image data " } ;
py : : class_ < Trade : : ImageData3D , Trade : : PyDataHolder < Trade : : ImageData3D > > imageData3D { m , " ImageData3D " , " Three-dimensional image data " } ;
imageData ( imageData1D ) ;
imageData ( imageData2D ) ;
imageData ( imageData3D ) ;
py : : enum_ < Trade : : SceneMappingType > { m , " SceneMappingType " , " Scene object mapping type " }
. value ( " UNSIGNED_BYTE " , Trade : : SceneMappingType : : UnsignedByte )
. value ( " UNSIGNED_SHORT " , Trade : : SceneMappingType : : UnsignedShort )
. value ( " UNSIGNED_INT " , Trade : : SceneMappingType : : UnsignedInt )
. value ( " UNSIGNED_LONG " , Trade : : SceneMappingType : : UnsignedLong ) ;
py : : enum_ < Trade : : SceneField > sceneField { m , " SceneField " , " Scene field name " } ;
sceneField
. value ( " PARENT " , Trade : : SceneField : : Parent )
. value ( " TRANSFORMATION " , Trade : : SceneField : : Transformation )
. value ( " TRANSLATION " , Trade : : SceneField : : Translation )
. value ( " ROTATION " , Trade : : SceneField : : Rotation )
. value ( " SCALING " , Trade : : SceneField : : Scaling )
. value ( " MESH " , Trade : : SceneField : : Mesh )
. value ( " MESH_MATERIAL " , Trade : : SceneField : : MeshMaterial )
. value ( " LIGHT " , Trade : : SceneField : : Light )
. value ( " CAMERA " , Trade : : SceneField : : Camera )
. value ( " SKIN " , Trade : : SceneField : : Skin )
. value ( " IMPORTER_STATE " , Trade : : SceneField : : ImporterState ) ;
enumWithCustomValues < Trade : : SceneField , Trade : : Implementation : : SceneFieldCustom > ( sceneField ) ;
py : : enum_ < Trade : : SceneFieldType > { m , " SceneFieldType " , " Scene field type " }
. value ( " BIT " , Trade : : SceneFieldType : : Bit )
. value ( " FLOAT " , Trade : : SceneFieldType : : Float )
. value ( " HALF " , Trade : : SceneFieldType : : Half )
. value ( " DOUBLE " , Trade : : SceneFieldType : : Double )
. value ( " UNSIGNED_BYTE " , Trade : : SceneFieldType : : UnsignedByte )
. value ( " BYTE " , Trade : : SceneFieldType : : Byte )
. value ( " UNSIGNED_SHORT " , Trade : : SceneFieldType : : UnsignedShort )
. value ( " SHORT " , Trade : : SceneFieldType : : Short )
. value ( " UNSIGNED_INT " , Trade : : SceneFieldType : : UnsignedInt )
. value ( " INT " , Trade : : SceneFieldType : : Int )
. value ( " UNSIGNED_LONG " , Trade : : SceneFieldType : : UnsignedLong )
. value ( " LONG " , Trade : : SceneFieldType : : Long )
. value ( " VECTOR2 " , Trade : : SceneFieldType : : Vector2 )
. value ( " VECTOR2H " , Trade : : SceneFieldType : : Vector2h )
. value ( " VECTOR2D " , Trade : : SceneFieldType : : Vector2d )
. value ( " VECTOR2UB " , Trade : : SceneFieldType : : Vector2ub )
. value ( " VECTOR2B " , Trade : : SceneFieldType : : Vector2b )
. value ( " VECTOR2US " , Trade : : SceneFieldType : : Vector2us )
. value ( " VECTOR2S " , Trade : : SceneFieldType : : Vector2s )
. value ( " VECTOR2UI " , Trade : : SceneFieldType : : Vector2ui )
. value ( " VECTOR2I " , Trade : : SceneFieldType : : Vector2i )
. value ( " VECTOR3 " , Trade : : SceneFieldType : : Vector3 )
. value ( " VECTOR3H " , Trade : : SceneFieldType : : Vector3h )
. value ( " VECTOR3D " , Trade : : SceneFieldType : : Vector3d )
. value ( " VECTOR3UB " , Trade : : SceneFieldType : : Vector3ub )
. value ( " VECTOR3B " , Trade : : SceneFieldType : : Vector3b )
. value ( " VECTOR3US " , Trade : : SceneFieldType : : Vector3us )
. value ( " VECTOR3S " , Trade : : SceneFieldType : : Vector3s )
. value ( " VECTOR3UI " , Trade : : SceneFieldType : : Vector3ui )
. value ( " VECTOR3I " , Trade : : SceneFieldType : : Vector3i )
. value ( " VECTOR4 " , Trade : : SceneFieldType : : Vector4 )
. value ( " VECTOR4H " , Trade : : SceneFieldType : : Vector4h )
. value ( " VECTOR4D " , Trade : : SceneFieldType : : Vector4d )
. value ( " VECTOR4UB " , Trade : : SceneFieldType : : Vector4ub )
. value ( " VECTOR4B " , Trade : : SceneFieldType : : Vector4b )
. value ( " VECTOR4US " , Trade : : SceneFieldType : : Vector4us )
. value ( " VECTOR4S " , Trade : : SceneFieldType : : Vector4s )
. value ( " VECTOR4UI " , Trade : : SceneFieldType : : Vector4ui )
. value ( " VECTOR4I " , Trade : : SceneFieldType : : Vector4i )
. value ( " MATRIX2X2 " , Trade : : SceneFieldType : : Matrix2x2 )
. value ( " MATRIX2X2H " , Trade : : SceneFieldType : : Matrix2x2h )
. value ( " MATRIX2X2D " , Trade : : SceneFieldType : : Matrix2x2d )
. value ( " MATRIX2X3 " , Trade : : SceneFieldType : : Matrix2x3 )
. value ( " MATRIX2X3H " , Trade : : SceneFieldType : : Matrix2x3h )
. value ( " MATRIX2X3D " , Trade : : SceneFieldType : : Matrix2x3d )
. value ( " MATRIX2X4 " , Trade : : SceneFieldType : : Matrix2x4 )
. value ( " MATRIX2X4H " , Trade : : SceneFieldType : : Matrix2x4h )
. value ( " MATRIX2X4D " , Trade : : SceneFieldType : : Matrix2x4d )
. value ( " MATRIX3X2 " , Trade : : SceneFieldType : : Matrix3x2 )
. value ( " MATRIX3X2H " , Trade : : SceneFieldType : : Matrix3x2h )
. value ( " MATRIX3X2D " , Trade : : SceneFieldType : : Matrix3x2d )
. value ( " MATRIX3X3 " , Trade : : SceneFieldType : : Matrix3x3 )
. value ( " MATRIX3X3H " , Trade : : SceneFieldType : : Matrix3x3h )
. value ( " MATRIX3X3D " , Trade : : SceneFieldType : : Matrix3x3d )
. value ( " MATRIX3X4 " , Trade : : SceneFieldType : : Matrix3x4 )
. value ( " MATRIX3X4H " , Trade : : SceneFieldType : : Matrix3x4h )
. value ( " MATRIX3X4D " , Trade : : SceneFieldType : : Matrix3x4d )
. value ( " MATRIX4X2 " , Trade : : SceneFieldType : : Matrix4x2 )
. value ( " MATRIX4X2H " , Trade : : SceneFieldType : : Matrix4x2h )
. value ( " MATRIX4X2D " , Trade : : SceneFieldType : : Matrix4x2d )
. value ( " MATRIX4X3 " , Trade : : SceneFieldType : : Matrix4x3 )
. value ( " MATRIX4X3H " , Trade : : SceneFieldType : : Matrix4x3h )
. value ( " MATRIX4X3D " , Trade : : SceneFieldType : : Matrix4x3d )
. value ( " MATRIX4X4 " , Trade : : SceneFieldType : : Matrix4x4 )
. value ( " MATRIX4X4H " , Trade : : SceneFieldType : : Matrix4x4h )
. value ( " MATRIX4X4D " , Trade : : SceneFieldType : : Matrix4x4d )
. value ( " RANGE1D " , Trade : : SceneFieldType : : Range1D )
. value ( " RANGE1DH " , Trade : : SceneFieldType : : Range1Dh )
. value ( " RANGE1DD " , Trade : : SceneFieldType : : Range1Dd )
. value ( " RANGE1DI " , Trade : : SceneFieldType : : Range1Di )
. value ( " RANGE2D " , Trade : : SceneFieldType : : Range2D )
. value ( " RANGE2DH " , Trade : : SceneFieldType : : Range2Dh )
. value ( " RANGE2DD " , Trade : : SceneFieldType : : Range2Dd )
. value ( " RANGE2DI " , Trade : : SceneFieldType : : Range2Di )
. value ( " RANGE3D " , Trade : : SceneFieldType : : Range3D )
. value ( " RANGE3DH " , Trade : : SceneFieldType : : Range3Dh )
. value ( " RANGE3DD " , Trade : : SceneFieldType : : Range3Dd )
. value ( " RANGE3DI " , Trade : : SceneFieldType : : Range3Di )
. value ( " COMPLEX " , Trade : : SceneFieldType : : Complex )
. value ( " COMPLEXD " , Trade : : SceneFieldType : : Complexd )
. value ( " DUAL_COMPLEX " , Trade : : SceneFieldType : : DualComplex )
. value ( " DUAL_COMPLEXD " , Trade : : SceneFieldType : : DualComplexd )
. value ( " QUATERNION " , Trade : : SceneFieldType : : Quaternion )
. value ( " QUATERNIOND " , Trade : : SceneFieldType : : Quaterniond )
. value ( " DUAL_QUATERNION " , Trade : : SceneFieldType : : DualQuaternion )
. value ( " DUAL_QUATERNIOND " , Trade : : SceneFieldType : : DualQuaterniond )
. value ( " DEG " , Trade : : SceneFieldType : : Deg )
. value ( " DEGH " , Trade : : SceneFieldType : : Degh )
. value ( " DEGD " , Trade : : SceneFieldType : : Degd )
. value ( " RAD " , Trade : : SceneFieldType : : Rad )
. value ( " RADH " , Trade : : SceneFieldType : : Radh )
. value ( " RADD " , Trade : : SceneFieldType : : Radd )
. value ( " POINTER " , Trade : : SceneFieldType : : Pointer )
. value ( " MUTABLE_POINTER " , Trade : : SceneFieldType : : MutablePointer )
. value ( " STRING_OFFSET32 " , Trade : : SceneFieldType : : StringOffset32 )
. value ( " STRING_OFFSET8 " , Trade : : SceneFieldType : : StringOffset8 )
. value ( " STRING_OFFSET16 " , Trade : : SceneFieldType : : StringOffset16 )
. value ( " STRING_OFFSET64 " , Trade : : SceneFieldType : : StringOffset64 )
. value ( " STRING_RANGE32 " , Trade : : SceneFieldType : : StringRange32 )
. value ( " STRING_RANGE8 " , Trade : : SceneFieldType : : StringRange8 )
. value ( " STRING_RANGE16 " , Trade : : SceneFieldType : : StringRange16 )
. value ( " STRING_RANGE64 " , Trade : : SceneFieldType : : StringRange64 )
. value ( " STRING_RANGE_NULL_TERMINATED32 " , Trade : : SceneFieldType : : StringRangeNullTerminated32 )
. value ( " STRING_RANGE_NULL_TERMINATED8 " , Trade : : SceneFieldType : : StringRangeNullTerminated8 )
. value ( " STRING_RANGE_NULL_TERMINATED16 " , Trade : : SceneFieldType : : StringRangeNullTerminated16 )
. value ( " STRING_RANGE_NULL_TERMINATED64 " , Trade : : SceneFieldType : : StringRangeNullTerminated64 ) ;
py : : enum_ < Trade : : SceneFieldFlag > sceneFieldFlag { m , " SceneFieldFlags " , " Scene field flags " } ;
sceneFieldFlag
. value ( " OFFSET_ONLY " , Trade : : SceneFieldFlag : : OffsetOnly )
. value ( " ORDERED_MAPPING " , Trade : : SceneFieldFlag : : OrderedMapping )
. value ( " IMPLICIT_MAPPING " , Trade : : SceneFieldFlag : : ImplicitMapping )
. value ( " NULL_TERMINATED_STRING " , Trade : : SceneFieldFlag : : NullTerminatedString )
. value ( " NONE " , Trade : : SceneFieldFlag { } ) ;
corrade : : enumOperators ( sceneFieldFlag ) ;
py : : class_ < Trade : : SceneData , Trade : : PyDataHolder < Trade : : SceneData > > { m , " SceneData " , " Scene data " }
. def_property_readonly ( " data_flags " , [ ] ( const Trade : : SceneData & self ) {
return Trade : : DataFlag ( Containers : : enumCastUnderlyingType ( self . dataFlags ( ) ) ) ;
} , " Data flags " )
/** @todo expose raw data at all? compared to meshes there's no use
case like being able to pass raw memory to the GPU . . . yet */
. def_property_readonly ( " mapping_type " , & Trade : : SceneData : : mappingType , " Type used for object mapping " )
. def_property_readonly ( " mapping_bound " , & Trade : : SceneData : : mappingBound , " Object mapping bound " )
. def_property_readonly ( " field_count " , & Trade : : SceneData : : fieldCount , " Field count " )
. def_property_readonly ( " field_size_bound " , & Trade : : SceneData : : fieldSizeBound , " Field size bound " )
. def_property_readonly ( " is_2d " , & Trade : : SceneData : : is2D , " Whether the scene is two-dimensional " )
. def_property_readonly ( " is_3d " , & Trade : : SceneData : : is3D , " Whether the scene is three-dimensional " )
/* IMPORTANT: due to pybind11 behavioral differences on (already EOL'd)
Python 3.7 the following overloads need to have the SceneField
overload * before * the UnsignedInt overload , otherwise the integer
overload gets picked even if an enum is passed from Python , causing
massive suffering */
. def ( " field_name " , [ ] ( const Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return self . fieldName ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Field name " , py : : arg ( " id " ) )
. def ( " field_flags " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) )
return Trade : : SceneFieldFlag ( Containers : : enumCastUnderlyingType ( self . fieldFlags ( * foundField ) ) ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Flags of a named field " , py : : arg ( " name " ) )
. def ( " field_flags " , [ ] ( const Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return Trade : : SceneFieldFlag ( Containers : : enumCastUnderlyingType ( self . fieldFlags ( id ) ) ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Field flags " , py : : arg ( " id " ) )
. def ( " field_type " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) )
return self . fieldType ( * foundField ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Type of a named field " , py : : arg ( " name " ) )
. def ( " field_type " , [ ] ( const Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return self . fieldType ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Field type " , py : : arg ( " id " ) )
. def ( " field_size " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) )
return self . fieldSize ( * foundField ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Number of entries in a named field " , py : : arg ( " name " ) )
. def ( " field_size " , [ ] ( const Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return self . fieldSize ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Number of entries in a field " , py : : arg ( " id " ) )
. def ( " field_array_size " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) )
return self . fieldArraySize ( * foundField ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Array size of a named field " , py : : arg ( " name " ) )
. def ( " field_array_size " , [ ] ( const Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return self . fieldArraySize ( id ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Field array size " , py : : arg ( " id " ) )
. def ( " field_id " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findFieldId ( name ) )
return * found ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( name ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Absolute ID of a named field " , py : : arg ( " name " ) )
. def ( " has_field " , & Trade : : SceneData : : hasField , " Whether the scene has given field " )
. def ( " field_object_offset " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName , UnsignedLong object , std : : size_t offset ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) ) {
if ( object > = self . mappingBound ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %llu out of range for %llu objects " , object , self . mappingBound ( ) ) ;
throw py : : error_already_set { } ;
}
if ( offset > self . fieldSize ( * foundField ) ) {
PyErr_Format ( PyExc_IndexError , " offset %zu out of range for a field of size %zu " , offset , self . fieldSize ( * foundField ) ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < std : : size_t > found = self . findFieldObjectOffset ( * foundField , object , offset ) )
return * found ;
PyErr_Format ( PyExc_LookupError , " object %llu not found in field %S starting at offset %zu " , object , py : : cast ( fieldName ) . ptr ( ) , offset ) ;
throw py : : error_already_set { } ;
}
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Offset of an object in given name field " , py : : arg ( " field_name " ) , py : : arg ( " object " ) , py : : arg ( " offset " ) = 0 )
. def ( " field_object_offset " , [ ] ( const Trade : : SceneData & self , UnsignedInt fieldId , UnsignedLong object , std : : size_t offset ) {
if ( fieldId > = self . fieldCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , fieldId , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( object > = self . mappingBound ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %llu out of range for %llu objects " , object , self . mappingBound ( ) ) ;
throw py : : error_already_set { } ;
}
if ( offset > self . fieldSize ( fieldId ) ) {
PyErr_Format ( PyExc_IndexError , " offset %zu out of range for a field of size %zu " , offset , self . fieldSize ( fieldId ) ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < std : : size_t > found = self . findFieldObjectOffset ( fieldId , object , offset ) )
return * found ;
PyErr_Format ( PyExc_LookupError , " object %llu not found in field %S starting at offset %zu " , object , py : : cast ( self . fieldName ( fieldId ) ) . ptr ( ) , offset ) ;
throw py : : error_already_set { } ;
} , " Offset of an object in given field " , py : : arg ( " field_id " ) , py : : arg ( " object " ) , py : : arg ( " offset " ) = 0 )
. def ( " has_field_object " , [ ] ( const Trade : : SceneData & self , Trade : : SceneField fieldName , UnsignedLong object ) {
if ( const Containers : : Optional < UnsignedInt > foundField = self . findFieldId ( fieldName ) ) {
if ( object > = self . mappingBound ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %llu out of range for %llu objects " , object , self . mappingBound ( ) ) ;
throw py : : error_already_set { } ;
}
return self . hasFieldObject ( * foundField , object ) ;
}
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( fieldName ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Whether a scene field has given object " , py : : arg ( " field_name " ) , py : : arg ( " object " ) )
. def ( " has_field_object " , [ ] ( const Trade : : SceneData & self , UnsignedInt fieldId , UnsignedLong object ) {
if ( fieldId > = self . fieldCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , fieldId , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( object > = self . mappingBound ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %llu out of range for %llu objects " , object , self . mappingBound ( ) ) ;
throw py : : error_already_set { } ;
}
return self . hasFieldObject ( fieldId , object ) ;
} , " Whether a scene field has given object " , py : : arg ( " field_id " ) , py : : arg ( " object " ) )
. def ( " mapping " , [ ] ( /*const*/ Trade : : SceneData & self , Trade : : SceneField name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findFieldId ( name ) ) {
return sceneMappingView ( self . mappingType ( ) , self . mapping ( * found ) , py : : cast ( self ) ) ;
}
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( name ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Object mapping data for given named field " , py : : arg ( " name " ) )
. def ( " mapping " , [ ] ( /*const*/ Trade : : SceneData & self , UnsignedInt id ) {
if ( id < self . fieldCount ( ) )
return sceneMappingView ( self . mappingType ( ) , self . mapping ( id ) , py : : cast ( self ) ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Object mapping data for given field " , py : : arg ( " id " ) )
. def ( " mutable_mapping " , [ ] ( Trade : : SceneData & self , Trade : : SceneField name ) {
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " scene data is not mutable " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > found = self . findFieldId ( name ) )
return sceneMappingView ( self . mappingType ( ) , self . mutableMapping ( * found ) , py : : cast ( self ) ) ;
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( name ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Mutable object mapping data for given named field " , py : : arg ( " name " ) )
. def ( " mutable_mapping " , [ ] ( Trade : : SceneData & self , UnsignedInt id ) {
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " scene data is not mutable " ) ;
throw py : : error_already_set { } ;
}
if ( id < self . fieldCount ( ) )
return sceneMappingView ( self . mappingType ( ) , self . mutableMapping ( id ) , py : : cast ( self ) ) ;
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Mutable object mapping data for given field " , py : : arg ( " id " ) )
. def ( " field " , [ ] ( /*const*/ Trade : : SceneData & self , Trade : : SceneField name ) {
if ( const Containers : : Optional < UnsignedInt > found = self . findFieldId ( name ) ) {
/** @todo handle arrays (return a 2D (bit) view) */
if ( self . fieldArraySize ( * found ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array fields not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
/** @todo annotate the return type properly in the docs */
if ( self . fieldType ( * found ) = = Trade : : SceneFieldType : : Bit )
return pyCastButNotShitty ( Containers : : pyArrayViewHolder ( self . fieldBits ( * found ) , py : : cast ( self ) ) ) ;
return pyCastButNotShitty ( sceneFieldView ( self . fieldType ( * found ) , self . field ( * found ) , py : : cast ( self ) ) ) ;
}
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( name ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Data for given named field " , py : : arg ( " name " ) )
. def ( " field " , [ ] ( /*const*/ Trade : : SceneData & self , UnsignedInt id ) {
if ( id > = self . fieldCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo handle arrays (return a 2D (bit) view) */
if ( self . fieldArraySize ( id ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array fields not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
/** @todo annotate the return type properly in the docs */
if ( self . fieldType ( id ) = = Trade : : SceneFieldType : : Bit )
return pyCastButNotShitty ( Containers : : pyArrayViewHolder ( self . fieldBits ( id ) , py : : cast ( self ) ) ) ;
return pyCastButNotShitty ( sceneFieldView ( self . fieldType ( id ) , self . field ( id ) , py : : cast ( self ) ) ) ;
} , " Data for given field " , py : : arg ( " id " ) )
. def ( " mutable_field " , [ ] ( Trade : : SceneData & self , Trade : : SceneField name ) {
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " scene data is not mutable " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > found = self . findFieldId ( name ) ) {
/** @todo handle arrays (return a 2D (bit) view) */
if ( self . fieldArraySize ( * found ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array fields not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
/** @todo annotate the return type properly in the docs */
if ( self . fieldType ( * found ) = = Trade : : SceneFieldType : : Bit )
return pyCastButNotShitty ( Containers : : pyArrayViewHolder ( self . mutableFieldBits ( * found ) , py : : cast ( self ) ) ) ;
return pyCastButNotShitty ( sceneFieldView ( self . fieldType ( * found ) , self . mutableField ( * found ) , py : : cast ( self ) ) ) ;
}
PyErr_Format ( PyExc_KeyError , " %S not found among %u fields " , py : : cast ( name ) . ptr ( ) , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
} , " Mutable data for given named field " , py : : arg ( " name " ) )
. def ( " mutable_field " , [ ] ( Trade : : SceneData & self , UnsignedInt id ) {
if ( id > = self . fieldCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u fields " , id , self . fieldCount ( ) ) ;
throw py : : error_already_set { } ;
}
if ( ! ( self . dataFlags ( ) & Trade : : DataFlag : : Mutable ) ) {
PyErr_SetString ( PyExc_AttributeError , " scene data is not mutable " ) ;
throw py : : error_already_set { } ;
}
/** @todo handle arrays (return a 2D (bit) view) */
if ( self . fieldArraySize ( id ) ! = 0 ) {
PyErr_SetString ( PyExc_NotImplementedError , " array fields not implemented yet, sorry " ) ;
throw py : : error_already_set { } ;
}
/** @todo annotate the return type properly in the docs */
if ( self . fieldType ( id ) = = Trade : : SceneFieldType : : Bit )
return pyCastButNotShitty ( Containers : : pyArrayViewHolder ( self . mutableFieldBits ( id ) , py : : cast ( self ) ) ) ;
return pyCastButNotShitty ( sceneFieldView ( self . fieldType ( id ) , self . mutableField ( id ) , py : : cast ( self ) ) ) ;
} , " Mutable data for given field " , py : : arg ( " id " ) )
. def_property_readonly ( " owner " , [ ] ( Trade : : SceneData & self ) {
return pyObjectHolderFor < Trade : : PyDataHolder > ( self ) . owner ;
} , " Memory owner " ) ;
py : : enum_ < Trade : : TextureType > { m , " TextureType " , " Texture type " }
. value ( " TEXTURE1D " , Trade : : TextureType : : Texture1D )
. value ( " TEXTURE1D_ARRAY " , Trade : : TextureType : : Texture1DArray )
. value ( " TEXTURE2D " , Trade : : TextureType : : Texture2D )
. value ( " TEXTURE2D_ARRAY " , Trade : : TextureType : : Texture2DArray )
. value ( " TEXTURE3D " , Trade : : TextureType : : Texture3D )
. value ( " CUBE_MAP " , Trade : : TextureType : : CubeMap )
. value ( " CUBE_MAP_ARRAY " , Trade : : TextureType : : CubeMapArray ) ;
py : : class_ < Trade : : TextureData > { m , " TextureData " , " Texture data " }
. def_property_readonly ( " type " , & Trade : : TextureData : : type , " Texture type " )
. def_property_readonly ( " minification_filter " , & Trade : : TextureData : : minificationFilter , " Minification filter " )
. def_property_readonly ( " magnification_filter " , & Trade : : TextureData : : magnificationFilter , " Magnification filter " )
. def_property_readonly ( " mipmap_filter " , & Trade : : TextureData : : mipmapFilter , " Mipmap filter " )
. def_property_readonly ( " wrapping " , [ ] ( Trade : : TextureData & self ) {
return std : : make_tuple (
self . wrapping ( ) [ 0 ] ,
self . wrapping ( ) [ 1 ] ,
self . wrapping ( ) [ 2 ]
) ;
} , " Wrapping " )
. def_property_readonly ( " image " , & Trade : : TextureData : : image , " Image ID " ) ;
/* Importer. Skipping file callbacks and openState as those operate with
void * . Leaving the name as AbstractImporter ( instead of Importer ) to
avoid needless name differences and because in the future there * might *
be pure Python importers ( not now tho ) . */
py : : enum_ < Trade : : ImporterFeature > importerFeatures { m , " ImporterFeatures " , " Features supported by an image converter " } ;
importerFeatures
. value ( " OPEN_DATA " , Trade : : ImporterFeature : : OpenData )
. value ( " OPEN_STATE " , Trade : : ImporterFeature : : OpenState )
. value ( " FILE_CALLBACK " , Trade : : ImporterFeature : : FileCallback )
. value ( " NONE " , Trade : : ImporterFeature { } ) ;
corrade : : enumOperators ( importerFeatures ) ;
py : : enum_ < Trade : : ImporterFlag > importerFlags { m , " ImporterFlags " , " Importer flags " } ;
importerFlags
. value ( " QUIET " , Trade : : ImporterFlag : : Quiet )
. value ( " VERBOSE " , Trade : : ImporterFlag : : Verbose )
. value ( " NONE " , Trade : : ImporterFlag { } ) ;
corrade : : enumOperators ( importerFlags ) ;
py : : class_ < Trade : : AbstractImporter , PluginManager : : PyPluginHolder < Trade : : AbstractImporter > , PluginManager : : AbstractPlugin > abstractImporter { m , " AbstractImporter " , " Interface for importer plugins " } ;
corrade : : plugin ( abstractImporter ) ;
abstractImporter
. def_property_readonly ( " features " , [ ] ( Trade : : AbstractImporter & self ) {
return Trade : : ImporterFeature ( Containers : : enumCastUnderlyingType ( self . features ( ) ) ) ;
} , " Features supported by this importer " )
. def_property ( " flags " , [ ] ( Trade : : AbstractImporter & self ) {
return Trade : : ImporterFlag ( Containers : : enumCastUnderlyingType ( self . flags ( ) ) ) ;
} , [ ] ( Trade : : AbstractImporter & self , Trade : : ImporterFlag flags ) {
self . setFlags ( flags ) ;
} , " Importer flags " )
. def_property_readonly ( " is_opened " , & Trade : : AbstractImporter : : isOpened , " Whether any file is opened " )
. def ( " open_data " , [ ] ( Trade : : AbstractImporter & self , Containers : : ArrayView < const char > data ) {
if ( ! ( self . features ( ) > = Trade : : ImporterFeature : : OpenData ) ) {
PyErr_SetString ( PyExc_AssertionError , " feature not supported " ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
if ( self . openData ( data ) ) return ;
PyErr_SetString ( PyExc_RuntimeError , " opening data failed " ) ;
throw py : : error_already_set { } ;
} , " Open raw data " , py : : arg ( " data " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " open_file " , [ ] ( Trade : : AbstractImporter & self , const std : : string & filename ) {
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
if ( self . openFile (
# ifdef CORRADE_TARGET_WINDOWS
/* To allow people to conveniently use Python's os.path, we
need to convert backslashes to forward slashes as all
Corrade and Magnum APIs expect forward */
Utility : : Path : : fromNativeSeparators ( filename )
# else
filename
# endif
) ) return ;
PyErr_Format ( PyExc_RuntimeError , " opening %s failed " , filename . data ( ) ) ;
throw py : : error_already_set { } ;
} , " Open a file " , py : : arg ( " filename " ) )
. def ( " close " , & Trade : : AbstractImporter : : close , " Close currently opened file " )
. def_property_readonly ( " default_scene " , checkOpened < Int , & Trade : : AbstractImporter : : defaultScene > , " Default scene " )
. def_property_readonly ( " scene_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : sceneCount > , " Scene count " )
. def_property_readonly ( " object_count " , checkOpened < UnsignedLong , & Trade : : AbstractImporter : : objectCount > , " Object count " )
. def ( " scene_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : sceneForName > , " Scene ID for given name " , py : : arg ( " name " ) )
. def ( " object_for_name " , checkOpenedString < Long , & Trade : : AbstractImporter : : objectForName > , " Object ID for given name " , py : : arg ( " name " ) )
. def ( " scene_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : sceneName , & Trade : : AbstractImporter : : sceneCount > , " Scene name " , py : : arg ( " id " ) )
. def ( " object_name " , checkOpenedBoundsReturnsString < UnsignedLong , & Trade : : AbstractImporter : : objectName , & Trade : : AbstractImporter : : objectCount > , " Scene name " , py : : arg ( " id " ) )
. def ( " scene " , checkOpenedBoundsResult < Trade : : SceneData , & Trade : : AbstractImporter : : scene , & Trade : : AbstractImporter : : sceneCount > , " Scene " , py : : arg ( " id " ) )
. def ( " scene " , checkOpenedBoundsResultString < Trade : : SceneData , & Trade : : AbstractImporter : : scene , & Trade : : AbstractImporter : : sceneForName , & Trade : : AbstractImporter : : sceneCount > , " Scene for given name " , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " scene_field_for_name " , [ ] ( Trade : : AbstractImporter & self , const std : : string & name ) - > Containers : : Optional < Trade : : SceneField > {
const Trade : : SceneField field = self . sceneFieldForName ( name ) ;
if ( field = = Trade : : SceneField { } )
return { } ;
return field ;
} , " Scene field for given name " , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " scene_field_name " , [ ] ( Trade : : AbstractImporter & self , Trade : : SceneField name ) - > Containers : : Optional < std : : string > {
if ( const Containers : : String field = self . sceneFieldName ( name ) )
return std : : string { field } ;
return { } ;
} , " String name for given custom scene field " , py : : arg ( " name " ) )
/** @todo all other data types */
. def_property_readonly ( " mesh_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : meshCount > , " Mesh count " )
. def ( " mesh_level_count " , checkOpenedBounds < UnsignedInt , & Trade : : AbstractImporter : : meshLevelCount , & Trade : : AbstractImporter : : meshCount > , " Mesh level count " , py : : arg ( " id " ) )
. def ( " mesh_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : meshForName > , " Mesh ID for given name " , py : : arg ( " name " ) )
. def ( " mesh_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : meshName , & Trade : : AbstractImporter : : meshCount > , " Mesh name " , py : : arg ( " id " ) )
. def ( " mesh " , checkOpenedBoundsResult < Trade : : MeshData , & Trade : : AbstractImporter : : mesh , & Trade : : AbstractImporter : : meshCount , & Trade : : AbstractImporter : : meshLevelCount > , " Mesh " , py : : arg ( " id " ) , py : : arg ( " level " ) = 0 )
. def ( " mesh " , checkOpenedBoundsResultString < Trade : : MeshData , & Trade : : AbstractImporter : : mesh , & Trade : : AbstractImporter : : meshForName , & Trade : : AbstractImporter : : meshCount , & Trade : : AbstractImporter : : meshLevelCount > , " Mesh for given name " , py : : arg ( " name " ) , py : : arg ( " level " ) = 0 )
/** @todo drop std::string in favor of our own string caster */
. def ( " mesh_attribute_for_name " , [ ] ( Trade : : AbstractImporter & self , const std : : string & name ) - > Containers : : Optional < Trade : : MeshAttribute > {
const Trade : : MeshAttribute attribute = self . meshAttributeForName ( name ) ;
if ( attribute = = Trade : : MeshAttribute { } )
return { } ;
return attribute ;
} , " Mesh attribute for given name " , py : : arg ( " name " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " mesh_attribute_name " , [ ] ( Trade : : AbstractImporter & self , Trade : : MeshAttribute name ) - > Containers : : Optional < std : : string > {
if ( const Containers : : String attribute = self . meshAttributeName ( name ) )
return std : : string { attribute } ;
return { } ;
} , " String name for given custom mesh attribute " , py : : arg ( " name " ) )
. def_property_readonly ( " material_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : materialCount > , " Material count " )
. def ( " material_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : materialForName > , " Material ID for given name " , py : : arg ( " name " ) )
. def ( " material_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : materialName , & Trade : : AbstractImporter : : materialCount > , " Material name " , py : : arg ( " id " ) )
. def ( " material " , [ ] ( Trade : : AbstractImporter & self , const UnsignedInt id ) {
/** @todo drop in favor of the generic helper once the
OptionalButAlsoPointer backwards compatibility helper is gone */
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . materialCount ( ) ) {
PyErr_Format ( PyExc_IndexError , " index %u out of range for %u entries " , id , self . materialCount ( ) ) ;
throw py : : error_already_set { } ;
}
Containers : : Optional < Trade : : MaterialData > out = self . material ( id ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
} , " Material " , py : : arg ( " id " ) )
/** @todo drop std::string in favor of our own string caster */
. def ( " material " , [ ] ( Trade : : AbstractImporter & self , const std : : string & name ) {
/** @todo drop in favor of the generic helper once the
OptionalButAlsoPointer backwards compatibility helper is gone */
if ( ! self . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
const Int id = self . materialForName ( name ) ;
if ( id = = - 1 ) {
/** @todo may need extra attention when it's no longer a
null - terminated std : : string */
PyErr_Format ( PyExc_KeyError , " name %s not found among %u entries " , name . data ( ) , self . materialCount ( ) ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
Containers : : Optional < Trade : : MaterialData > out = self . material ( id ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " import failed " ) ;
throw py : : error_already_set { } ;
}
return * std : : move ( out ) ;
} , " Material for given name " , py : : arg ( " name " ) )
. def_property_readonly ( " texture_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : textureCount > , " Texture count " )
. def ( " texture_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : textureForName > , " Texture ID for given name " , py : : arg ( " name " ) )
. def ( " texture_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : textureName , & Trade : : AbstractImporter : : textureCount > , " Texture name " , py : : arg ( " id " ) )
. def ( " texture " , checkOpenedBoundsResult < Trade : : TextureData , & Trade : : AbstractImporter : : texture , & Trade : : AbstractImporter : : textureCount > , " Texture " , py : : arg ( " id " ) )
. def ( " texture " , checkOpenedBoundsResultString < Trade : : TextureData , & Trade : : AbstractImporter : : texture , & Trade : : AbstractImporter : : textureForName , & Trade : : AbstractImporter : : textureCount > , " Texture for given name " , py : : arg ( " name " ) )
. def_property_readonly ( " image1d_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : image1DCount > , " One-dimensional image count " )
. def_property_readonly ( " image2d_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : image2DCount > , " Two-dimensional image count " )
. def_property_readonly ( " image3d_count " , checkOpened < UnsignedInt , & Trade : : AbstractImporter : : image3DCount > , " Three-dimensional image count " )
. def ( " image1d_level_count " , checkOpenedBounds < UnsignedInt , & Trade : : AbstractImporter : : image1DLevelCount , & Trade : : AbstractImporter : : image1DCount > , " One-dimensional image level count " , py : : arg ( " id " ) )
. def ( " image2d_level_count " , checkOpenedBounds < UnsignedInt , & Trade : : AbstractImporter : : image2DLevelCount , & Trade : : AbstractImporter : : image2DCount > , " Two-dimensional image level count " , py : : arg ( " id " ) )
. def ( " image3d_level_count " , checkOpenedBounds < UnsignedInt , & Trade : : AbstractImporter : : image3DLevelCount , & Trade : : AbstractImporter : : image3DCount > , " Three-dimensional image level count " , py : : arg ( " id " ) )
. def ( " image1d_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : image1DForName > , " One-dimensional image ID for given name " , py : : arg ( " name " ) )
. def ( " image2d_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : image2DForName > , " Two-dimensional image ID for given name " , py : : arg ( " name " ) )
. def ( " image3d_for_name " , checkOpenedString < Int , & Trade : : AbstractImporter : : image3DForName > , " Three-dimensional image ID for given name " , py : : arg ( " name " ) )
. def ( " image1d_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : image1DName , & Trade : : AbstractImporter : : image1DCount > , " One-dimensional image name " , py : : arg ( " id " ) )
. def ( " image2d_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : image2DName , & Trade : : AbstractImporter : : image2DCount > , " Two-dimensional image name " , py : : arg ( " id " ) )
. def ( " image3d_name " , checkOpenedBoundsReturnsString < UnsignedInt , & Trade : : AbstractImporter : : image3DName , & Trade : : AbstractImporter : : image3DCount > , " Three-dimensional image name " , py : : arg ( " id " ) )
. def ( " image1d " , checkOpenedBoundsResult < Trade : : ImageData1D , & Trade : : AbstractImporter : : image1D , & Trade : : AbstractImporter : : image1DCount , & Trade : : AbstractImporter : : image1DLevelCount > , " One-dimensional image " , py : : arg ( " id " ) , py : : arg ( " level " ) = 0 )
. def ( " image1d " , checkOpenedBoundsResultString < Trade : : ImageData1D , & Trade : : AbstractImporter : : image1D , & Trade : : AbstractImporter : : image1DForName , & Trade : : AbstractImporter : : image1DCount , & Trade : : AbstractImporter : : image1DLevelCount > , " One-dimensional image for given name " , py : : arg ( " name " ) , py : : arg ( " level " ) = 0 )
. def ( " image2d " , checkOpenedBoundsResult < Trade : : ImageData2D , & Trade : : AbstractImporter : : image2D , & Trade : : AbstractImporter : : image2DCount , & Trade : : AbstractImporter : : image2DLevelCount > , " Two-dimensional image " , py : : arg ( " id " ) , py : : arg ( " level " ) = 0 )
. def ( " image2d " , checkOpenedBoundsResultString < Trade : : ImageData2D , & Trade : : AbstractImporter : : image2D , & Trade : : AbstractImporter : : image2DForName , & Trade : : AbstractImporter : : image2DCount , & Trade : : AbstractImporter : : image2DLevelCount > , " Two-dimensional image for given name " , py : : arg ( " name " ) , py : : arg ( " level " ) = 0 )
. def ( " image3d " , checkOpenedBoundsResult < Trade : : ImageData3D , & Trade : : AbstractImporter : : image3D , & Trade : : AbstractImporter : : image3DCount , & Trade : : AbstractImporter : : image3DLevelCount > , " Three-dimensional image " , py : : arg ( " id " ) , py : : arg ( " level " ) = 0 )
. def ( " image3d " , checkOpenedBoundsResultString < Trade : : ImageData3D , & Trade : : AbstractImporter : : image3D , & Trade : : AbstractImporter : : image3DForName , & Trade : : AbstractImporter : : image3DCount , & Trade : : AbstractImporter : : image3DLevelCount > , " Threee-dimensional image for given name " , py : : arg ( " name " ) , py : : arg ( " level " ) = 0 ) ;
py : : class_ < PluginManager : : Manager < Trade : : AbstractImporter > , PluginManager : : AbstractManager > importerManager { m , " ImporterManager " , " Manager for importer plugins " } ;
corrade : : manager ( importerManager ) ;
/* Image converter */
py : : enum_ < Trade : : ImageConverterFeature > imageConverterFeatures { m , " ImageConverterFeatures " , " Features supported by an image converter " } ;
imageConverterFeatures
. value ( " CONVERT1D " , Trade : : ImageConverterFeature : : Convert1D )
. value ( " CONVERT2D " , Trade : : ImageConverterFeature : : Convert2D )
. value ( " CONVERT3D " , Trade : : ImageConverterFeature : : Convert3D )
. value ( " CONVERT_COMPRESSED1D " , Trade : : ImageConverterFeature : : ConvertCompressed1D )
. value ( " CONVERT_COMPRESSED2D " , Trade : : ImageConverterFeature : : ConvertCompressed2D )
. value ( " CONVERT_COMPRESSED3D " , Trade : : ImageConverterFeature : : ConvertCompressed3D )
. value ( " CONVERT1D_TO_FILE " , Trade : : ImageConverterFeature : : Convert1DToFile )
. value ( " CONVERT2D_TO_FILE " , Trade : : ImageConverterFeature : : Convert2DToFile )
. value ( " CONVERT3D_TO_FILE " , Trade : : ImageConverterFeature : : Convert3DToFile )
. value ( " CONVERT_COMPRESSED1D_TO_FILE " , Trade : : ImageConverterFeature : : ConvertCompressed1DToFile )
. value ( " CONVERT_COMPRESSED2D_TO_FILE " , Trade : : ImageConverterFeature : : ConvertCompressed2DToFile )
. value ( " CONVERT_COMPRESSED3D_TO_FILE " , Trade : : ImageConverterFeature : : ConvertCompressed3DToFile )
. value ( " CONVERT1D_TO_DATA " , Trade : : ImageConverterFeature : : Convert1DToData )
. value ( " CONVERT2D_TO_DATA " , Trade : : ImageConverterFeature : : Convert2DToData )
. value ( " CONVERT3D_TO_DATA " , Trade : : ImageConverterFeature : : Convert3DToData )
. value ( " CONVERT_COMPRESSED1D_TO_DATA " , Trade : : ImageConverterFeature : : ConvertCompressed1DToData )
. value ( " CONVERT_COMPRESSED2D_TO_DATA " , Trade : : ImageConverterFeature : : ConvertCompressed2DToData )
. value ( " CONVERT_COMPRESSED3D_TO_DATA " , Trade : : ImageConverterFeature : : ConvertCompressed3DToData )
. value ( " LEVELS " , Trade : : ImageConverterFeature : : Levels )
. value ( " NONE " , Trade : : ImageConverterFeature { } ) ;
corrade : : enumOperators ( imageConverterFeatures ) ;
py : : enum_ < Trade : : ImageConverterFlag > imageConverterFlags { m , " ImageConverterFlags " , " Image converter flags " } ;
imageConverterFlags
. value ( " QUIET " , Trade : : ImageConverterFlag : : Quiet )
. value ( " VERBOSE " , Trade : : ImageConverterFlag : : Verbose )
. value ( " NONE " , Trade : : ImageConverterFlag { } ) ;
corrade : : enumOperators ( imageConverterFlags ) ;
py : : class_ < Trade : : AbstractImageConverter , PluginManager : : PyPluginHolder < Trade : : AbstractImageConverter > , PluginManager : : AbstractPlugin > abstractImageConverter { m , " AbstractImageConverter " , " Interface for image converter plugins " } ;
abstractImageConverter
. def_property_readonly ( " features " , [ ] ( Trade : : AbstractImageConverter & self ) {
return Trade : : ImageConverterFeature ( Containers : : enumCastUnderlyingType ( self . features ( ) ) ) ;
} , " Features supported by this converter " )
. def_property ( " flags " , [ ] ( Trade : : AbstractImageConverter & self ) {
return Trade : : ImageConverterFlag ( Containers : : enumCastUnderlyingType ( self . flags ( ) ) ) ;
} , [ ] ( Trade : : AbstractImageConverter & self , Trade : : ImageConverterFlag flags ) {
self . setFlags ( flags ) ;
} , " Converter flags " )
/* ImageData overloads should be first so they correctly dispatch to
either a compressed or a non - compressed overload . With the views
being first it ' d just pick whichever of them is earliest as
ImageData is implicitly convertible to each . */
. def ( " convert " , checkImageConverterResult < Trade : : ImageData1D , Trade : : ImageData1D , & Trade : : AbstractImageConverter : : convert > , " Convert a 1D image data " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData2D , Trade : : ImageData2D , & Trade : : AbstractImageConverter : : convert > , " Convert a 2D image data " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData3D , Trade : : ImageData3D , & Trade : : AbstractImageConverter : : convert > , " Convert a 3D image data " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData1D , ImageView1D , & Trade : : AbstractImageConverter : : convert > , " Convert a 1D image " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData2D , ImageView2D , & Trade : : AbstractImageConverter : : convert > , " Convert a 2D image " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData3D , ImageView3D , & Trade : : AbstractImageConverter : : convert > , " Convert a 3D image " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData1D , CompressedImageView1D , & Trade : : AbstractImageConverter : : convert > , " Convert a compressed 1D image " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData2D , CompressedImageView2D , & Trade : : AbstractImageConverter : : convert > , " Convert a compressed 2D image " , py : : arg ( " image " ) )
. def ( " convert " , checkImageConverterResult < Trade : : ImageData3D , CompressedImageView3D , & Trade : : AbstractImageConverter : : convert > , " Convert a compressed 3D image " , py : : arg ( " image " ) )
. def ( " convert_to_file " , checkImageConverterResult < Trade : : ImageData1D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 1D image data to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < Trade : : ImageData2D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 2D image data to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < Trade : : ImageData3D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 3D image data to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < ImageView1D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 1D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < ImageView2D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 2D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < ImageView3D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a 3D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < CompressedImageView1D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a compressed 1D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < CompressedImageView2D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a compressed 2D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) )
. def ( " convert_to_file " , checkImageConverterResult < CompressedImageView3D , & Trade : : AbstractImageConverter : : convertToFile > , " Convert a compressed 3D image to a file " , py : : arg ( " image " ) , py : : arg ( " filename " ) ) ;
corrade : : plugin ( abstractImageConverter ) ;
py : : class_ < PluginManager : : Manager < Trade : : AbstractImageConverter > , PluginManager : : AbstractManager > imageConverterManager { m , " ImageConverterManager " , " Manager for image converter plugins " } ;
corrade : : manager ( imageConverterManager ) ;
/* Scene converter */
py : : enum_ < Trade : : SceneConverterFeature > sceneConverterFeatures { m , " SceneConverterFeatures " , " Features supported by a scene converter " } ;
sceneConverterFeatures
. value ( " CONVERT_MESH " , Trade : : SceneConverterFeature : : ConvertMesh )
. value ( " CONVERT_MESH_IN_PLACE " , Trade : : SceneConverterFeature : : ConvertMeshInPlace )
. value ( " CONVERT_MESH_TO_FILE " , Trade : : SceneConverterFeature : : ConvertMeshToFile )
. value ( " CONVERT_MESH_TO_DATA " , Trade : : SceneConverterFeature : : ConvertMeshToData )
. value ( " CONVERT_MULTIPLE " , Trade : : SceneConverterFeature : : ConvertMultiple )
. value ( " CONVERT_MULTIPLE_TO_FILE " , Trade : : SceneConverterFeature : : ConvertMultipleToFile )
. value ( " CONVERT_MULTIPLE_TO_DATA " , Trade : : SceneConverterFeature : : ConvertMultipleToData )
. value ( " ADD_SCENES " , Trade : : SceneConverterFeature : : AddScenes )
. value ( " ADD_ANIMATIONS " , Trade : : SceneConverterFeature : : AddAnimations )
. value ( " ADD_LIGHTS " , Trade : : SceneConverterFeature : : AddLights )
. value ( " ADD_CAMERAS " , Trade : : SceneConverterFeature : : AddCameras )
. value ( " ADD_SKINS2D " , Trade : : SceneConverterFeature : : AddSkins2D )
. value ( " ADD_SKINS3D " , Trade : : SceneConverterFeature : : AddSkins3D )
. value ( " ADD_MESHES " , Trade : : SceneConverterFeature : : AddMeshes )
. value ( " ADD_MATERIALS " , Trade : : SceneConverterFeature : : AddMaterials )
. value ( " ADD_TEXTURES " , Trade : : SceneConverterFeature : : AddTextures )
. value ( " ADD_IMAGES1D " , Trade : : SceneConverterFeature : : AddImages1D )
. value ( " ADD_IMAGES2D " , Trade : : SceneConverterFeature : : AddImages2D )
. value ( " ADD_IMAGES3D " , Trade : : SceneConverterFeature : : AddImages3D )
. value ( " ADD_COMPRESSED_IMAGES1D " , Trade : : SceneConverterFeature : : AddCompressedImages1D )
. value ( " ADD_COMPRESSED_IMAGES2D " , Trade : : SceneConverterFeature : : AddCompressedImages2D )
. value ( " ADD_COMPRESSED_IMAGES3D " , Trade : : SceneConverterFeature : : AddCompressedImages3D )
. value ( " MESH_LEVELS " , Trade : : SceneConverterFeature : : MeshLevels )
. value ( " IMAGE_LEVELS " , Trade : : SceneConverterFeature : : ImageLevels )
. value ( " NONE " , Trade : : SceneConverterFeature { } ) ;
corrade : : enumOperators ( sceneConverterFeatures ) ;
py : : enum_ < Trade : : SceneConverterFlag > sceneConverterFlags { m , " SceneConverterFlags " , " Scene converter flags " } ;
sceneConverterFlags
. value ( " QUIET " , Trade : : SceneConverterFlag : : Quiet )
. value ( " VERBOSE " , Trade : : SceneConverterFlag : : Verbose )
. value ( " NONE " , Trade : : SceneConverterFlag { } ) ;
corrade : : enumOperators ( sceneConverterFlags ) ;
py : : enum_ < Trade : : SceneContent > sceneContents { m , " SceneContents " , " Scene contents " } ;
sceneContents
. value ( " SCENES " , Trade : : SceneContent : : Scenes )
. value ( " ANIMATIONS " , Trade : : SceneContent : : Animations )
. value ( " LIGHTS " , Trade : : SceneContent : : Lights )
. value ( " CAMERAS " , Trade : : SceneContent : : Cameras )
. value ( " SKINS2D " , Trade : : SceneContent : : Skins2D )
. value ( " SKINS3D " , Trade : : SceneContent : : Skins3D )
. value ( " MESHES " , Trade : : SceneContent : : Meshes )
. value ( " MATERIALS " , Trade : : SceneContent : : Materials )
. value ( " TEXTURES " , Trade : : SceneContent : : Textures )
. value ( " IMAGES1D " , Trade : : SceneContent : : Images1D )
. value ( " IMAGES2D " , Trade : : SceneContent : : Images2D )
. value ( " IMAGES3D " , Trade : : SceneContent : : Images3D )
. value ( " MESH_LEVELS " , Trade : : SceneContent : : MeshLevels )
. value ( " IMAGE_LEVELS " , Trade : : SceneContent : : ImageLevels )
. value ( " NAMES " , Trade : : SceneContent : : Names )
. value ( " ALL " , Trade : : SceneContent ( Containers : : enumCastUnderlyingType ( ~ Trade : : SceneContent { } ) ) )
. def ( " FOR " , [ ] ( Trade : : AbstractImporter & importer ) {
if ( ! importer . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no file opened " ) ;
throw py : : error_already_set { } ;
}
return Trade : : SceneContent ( Containers : : enumCastUnderlyingType ( Trade : : sceneContentsFor ( importer ) ) ) ;
} )
. def ( " FOR " , [ ] ( Trade : : AbstractSceneConverter & converter ) {
return Trade : : SceneContent ( Containers : : enumCastUnderlyingType ( Trade : : sceneContentsFor ( converter ) ) ) ;
} ) ;
corrade : : enumOperators ( sceneContents ) ;
py : : class_ < Trade : : AbstractSceneConverter , PluginManager : : PyPluginHolder < Trade : : AbstractSceneConverter > , PluginManager : : AbstractPlugin > abstractSceneConverter { m , " AbstractSceneConverter " , " Interface for scene converter plugins " } ;
abstractSceneConverter
. def_property_readonly ( " features " , [ ] ( Trade : : AbstractSceneConverter & self ) {
return Trade : : SceneConverterFeature ( Containers : : enumCastUnderlyingType ( self . features ( ) ) ) ;
} , " Features supported by this converter " )
. def_property ( " flags " , [ ] ( Trade : : AbstractSceneConverter & self ) {
return Trade : : SceneConverterFlag ( Containers : : enumCastUnderlyingType ( self . flags ( ) ) ) ;
} , [ ] ( Trade : : AbstractSceneConverter & self , Trade : : SceneConverterFlag flags ) {
self . setFlags ( flags ) ;
} , " Converter flags " )
. def ( " convert " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : MeshData & mesh ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : ConvertMesh ) ) {
PyErr_SetString ( PyExc_AssertionError , " mesh conversion not supported " ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
Containers : : Optional < Trade : : MeshData > out = self . convert ( mesh ) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " conversion failed " ) ;
throw py : : error_already_set { } ;
}
return out ;
} , " Convert a mesh " , py : : arg ( " mesh " ) )
. def ( " convert_in_place " , [ ] ( Trade : : AbstractSceneConverter & self , Trade : : MeshData & mesh ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : ConvertMeshInPlace ) ) {
PyErr_SetString ( PyExc_AssertionError , " mesh conversion not supported " ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
if ( ! self . convertInPlace ( mesh ) ) {
PyErr_SetString ( PyExc_RuntimeError , " conversion failed " ) ;
throw py : : error_already_set { } ;
}
} , " Convert a mesh in-place " , py : : arg ( " mesh " ) )
/** @todo conversion to data */
/** @todo drop std::string in favor of our own string caster */
. def ( " convert_to_file " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : MeshData & mesh , const std : : string & filename ) {
if ( ! ( self . features ( ) > = ( Trade : : SceneConverterFeature : : ConvertMeshToFile ) ) & &
! ( self . features ( ) > = ( Trade : : SceneConverterFeature : : ConvertMultipleToFile | Trade : : SceneConverterFeature : : AddMeshes ) ) ) {
PyErr_SetString ( PyExc_AssertionError , " mesh conversion not supported " ) ;
throw py : : error_already_set { } ;
}
/** @todo log redirection -- but we'd need assertions to not be
part of that so when it dies , the user can still see why */
bool out = self . convertToFile ( mesh ,
# ifdef CORRADE_TARGET_WINDOWS
/* To allow people to conveniently use Python's os.path, we
need to convert backslashes to forward slashes as all
Corrade and Magnum APIs expect forward */
Utility : : Path : : fromNativeSeparators ( filename )
# else
filename
# endif
) ;
if ( ! out ) {
PyErr_SetString ( PyExc_RuntimeError , " conversion failed " ) ;
throw py : : error_already_set { } ;
}
} , " Convert a mesh to a file " , py : : arg ( " mesh " ) , py : : arg ( " filename " ) )
. def_property_readonly ( " is_converting " , & Trade : : AbstractSceneConverter : : isConverting , " Whether any conversion is in progress " )
. def ( " abort " , & Trade : : AbstractSceneConverter : : abort , " Abort any in-progress conversion " )
/** @todo begin/end (MeshOptimizer), begin/end data */
/** @todo drop std::string in favor of our own string caster */
. def ( " begin_file " , [ ] ( Trade : : AbstractSceneConverter & self , const std : : string & filename ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : ConvertMultipleToFile ) & &
! ( self . features ( ) > = Trade : : SceneConverterFeature : : ConvertMeshToFile ) ) {
PyErr_SetString ( PyExc_AssertionError , " feature not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . beginFile (
# ifdef CORRADE_TARGET_WINDOWS
/* To allow people to conveniently use Python's os.path, we
need to convert backslashes to forward slashes as all
Corrade and Magnum APIs expect forward */
Utility : : Path : : fromNativeSeparators ( filename )
# else
filename
# endif
) ) {
PyErr_SetString ( PyExc_RuntimeError , " beginning the conversion failed " ) ;
throw py : : error_already_set { } ;
}
} , " Begin converting a scene to a file " , py : : arg ( " filename " ) )
. def ( " end_file " , [ ] ( Trade : : AbstractSceneConverter & self ) {
/** @todo this doesn't catch a mismatch (e.g., when beginData() was
called instead */
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . endFile ( ) ) {
PyErr_SetString ( PyExc_RuntimeError , " ending the conversion failed " ) ;
throw py : : error_already_set { } ;
}
} , " End converting a scene to a file " )
. def ( " set_default_scene " , [ ] ( Trade : : AbstractSceneConverter & self , const UnsignedInt id ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : AddScenes ) ) {
PyErr_SetString ( PyExc_AssertionError , " feature not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( id > = self . sceneCount ( ) ) {
PyErr_Format ( PyExc_AssertionError , " index %u out of range for %u scenes " , id , self . sceneCount ( ) ) ;
throw py : : error_already_set { } ;
}
self . setDefaultScene ( id ) ;
} , " Set default scene " , py : : arg ( " id " ) )
. def_property_readonly ( " scene_count " , [ ] ( Trade : : AbstractSceneConverter & self ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
return self . sceneCount ( ) ;
} , " Count of added scenes " )
/** @todo drop std::string in favor of our own string caster */
. def ( " add " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : SceneData & scene , const std : : string & name ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : AddScenes ) ) {
PyErr_SetString ( PyExc_AssertionError , " scene conversion not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > out = self . add ( scene , name ) )
return * out ;
PyErr_SetString ( PyExc_RuntimeError , " adding the scene failed " ) ;
throw py : : error_already_set { } ;
} , " Add a scene " , py : : arg ( " scene " ) , py : : arg ( " name " ) = std : : string { } )
. def ( " set_scene_field_name " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : SceneField field , const std : : string & name ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : AddScenes ) ) {
PyErr_SetString ( PyExc_AssertionError , " feature not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( ! Trade : : isSceneFieldCustom ( field ) ) {
PyErr_SetString ( PyExc_AssertionError , " not a custom field " ) ;
throw py : : error_already_set { } ;
}
self . setSceneFieldName ( field , name ) ;
} , " Set name of a custom scene field " , py : : arg ( " field " ) , py : : arg ( " name " ) )
. def_property_readonly ( " mesh_count " , [ ] ( Trade : : AbstractSceneConverter & self ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
return self . meshCount ( ) ;
} , " Count of added meshes " )
/** @todo drop std::string in favor of our own string caster */
. def ( " add " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : MeshData & mesh , const std : : string & name ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : AddMeshes ) & &
! ( self . features ( ) & ( Trade : : SceneConverterFeature : : ConvertMesh |
Trade : : SceneConverterFeature : : ConvertMeshToData |
Trade : : SceneConverterFeature : : ConvertMeshToFile ) ) ) {
PyErr_SetString ( PyExc_AssertionError , " mesh conversion not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > out = self . add ( mesh , name ) )
return * out ;
PyErr_SetString ( PyExc_RuntimeError , " adding the mesh failed " ) ;
throw py : : error_already_set { } ;
} , " Add a mesh " , py : : arg ( " mesh " ) , py : : arg ( " name " ) = std : : string { } )
/** @todo mesh levels */
. def ( " set_mesh_attribute_name " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : MeshAttribute attribute , const std : : string & name ) {
if ( ! ( self . features ( ) & ( Trade : : SceneConverterFeature : : AddMeshes |
Trade : : SceneConverterFeature : : ConvertMesh |
Trade : : SceneConverterFeature : : ConvertMeshInPlace |
Trade : : SceneConverterFeature : : ConvertMeshToData |
Trade : : SceneConverterFeature : : ConvertMeshToFile ) ) ) {
PyErr_SetString ( PyExc_AssertionError , " feature not supported " ) ;
throw py : : error_already_set { } ;
}
/* Unless single mesh conversion is supported, allow this function
to be called only if begin * ( ) was called before */
if ( ! ( self . features ( ) & ( Trade : : SceneConverterFeature : : ConvertMesh |
Trade : : SceneConverterFeature : : ConvertMeshInPlace |
Trade : : SceneConverterFeature : : ConvertMeshToData |
Trade : : SceneConverterFeature : : ConvertMeshToFile ) ) & & ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( ! Trade : : isMeshAttributeCustom ( attribute ) ) {
PyErr_SetString ( PyExc_AssertionError , " not a custom attribute " ) ;
throw py : : error_already_set { } ;
}
self . setMeshAttributeName ( attribute , name ) ;
} , " Set name of a custom mesh attribute " , py : : arg ( " attribute " ) , py : : arg ( " name " ) )
/** @todo 1D images, once we have data & plugins to test with */
. def_property_readonly ( " image2d_count " , [ ] ( Trade : : AbstractSceneConverter & self ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
return self . image2DCount ( ) ;
} , " Count of added 2D images " )
/** @todo drop std::string in favor of our own string caster */
. def ( " add " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : ImageData2D & image , const std : : string & name ) {
if ( ! image . isCompressed ( ) & & ! ( self . features ( ) & Trade : : SceneConverterFeature : : AddImages2D ) ) {
PyErr_SetString ( PyExc_AssertionError , " 2D image conversion not supported " ) ;
throw py : : error_already_set { } ;
}
if ( image . isCompressed ( ) & & ! ( self . features ( ) & Trade : : SceneConverterFeature : : AddCompressedImages2D ) ) {
PyErr_SetString ( PyExc_AssertionError , " compressed 2D image conversion not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > out = self . add ( image , name ) )
return * out ;
PyErr_SetString ( PyExc_RuntimeError , " adding the image failed " ) ;
throw py : : error_already_set { } ;
} , " Add a 2D image " , py : : arg ( " image " ) , py : : arg ( " name " ) = std : : string { } )
/** @todo 3D images, once we have data & plugins to test with */
. def_property_readonly ( " material_count " , [ ] ( Trade : : AbstractSceneConverter & self ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
return self . materialCount ( ) ;
} , " Count of added materials " )
/** @todo drop std::string in favor of our own string caster */
. def ( " add " , [ ] ( Trade : : AbstractSceneConverter & self , const Trade : : MaterialData & material , const std : : string & name ) {
if ( ! ( self . features ( ) > = Trade : : SceneConverterFeature : : AddMaterials ) ) {
PyErr_SetString ( PyExc_AssertionError , " material conversion not supported " ) ;
throw py : : error_already_set { } ;
}
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( const Containers : : Optional < UnsignedInt > out = self . add ( material , name ) )
return * out ;
PyErr_SetString ( PyExc_RuntimeError , " adding the material failed " ) ;
throw py : : error_already_set { } ;
} , " Add a material " , py : : arg ( " material " ) , py : : arg ( " name " ) = std : : string { } )
. def ( " add_importer_contents " , [ ] ( Trade : : AbstractSceneConverter & self , Trade : : AbstractImporter & importer , Trade : : SceneContent contents ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( ! importer . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " the importer is not opened " ) ;
throw py : : error_already_set { } ;
}
/** @todo check if contents present in the file are supported? or
make that a runtime failure in Magnum for easier use ? */
if ( ! self . addImporterContents ( importer , contents ) ) {
PyErr_SetString ( PyExc_RuntimeError , " adding importer contents failed " ) ;
throw py : : error_already_set { } ;
}
} , " Add importer contents " , py : : arg ( " importer " ) , py : : arg ( " contents " ) = Trade : : SceneContent ( Containers : : enumCastUnderlyingType ( ~ Trade : : SceneContent { } ) ) )
. def ( " add_supported_importer_contents " , [ ] ( Trade : : AbstractSceneConverter & self , Trade : : AbstractImporter & importer , Trade : : SceneContent contents ) {
if ( ! self . isConverting ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " no conversion in progress " ) ;
throw py : : error_already_set { } ;
}
if ( ! importer . isOpened ( ) ) {
PyErr_SetString ( PyExc_AssertionError , " the importer is not opened " ) ;
throw py : : error_already_set { } ;
}
/** @todo check if contents present in the file are supported? or
make that a runtime failure in Magnum for easier use ? */
if ( ! self . addSupportedImporterContents ( importer , contents ) ) {
PyErr_SetString ( PyExc_RuntimeError , " adding importer contents failed " ) ;
throw py : : error_already_set { } ;
}
} , " Add supported importer contents " , py : : arg ( " importer " ) , py : : arg ( " contents " ) = Trade : : SceneContent ( Containers : : enumCastUnderlyingType ( ~ Trade : : SceneContent { } ) ) ) ;
corrade : : plugin ( abstractSceneConverter ) ;
py : : class_ < PluginManager : : Manager < Trade : : AbstractSceneConverter > , PluginManager : : AbstractManager > sceneConverterManager { m , " SceneConverterManager " , " Manager for scene converter plugins " } ;
corrade : : manager ( sceneConverterManager ) ;
}
}
# ifndef MAGNUM_BUILD_STATIC
/* TODO: remove declaration when https://github.com/pybind/pybind11/pull/1863
is released */
extern " C " PYBIND11_EXPORT PyObject * PyInit_trade ( ) ;
PYBIND11_MODULE ( trade , m ) {
magnum : : trade ( m ) ;
}
# endif