Welcome to Python-flavored Magnum! Please note that, while already being rather stable, this functionality is still considered experimental and some APIs might get changed without preserving full backwards compatibility.

magnum.trade.MeshData class

Mesh data

Memory ownership and reference counting

The class can be both owning an non-owning depending on the value of index_data_flags and vertex_data_flags. If they contain neither DataFlags.OWNED nor DataFlags.GLOBAL, the owner property references the object actually owning the index and vertex data the mesh points to. This ensures calling del on the original object will not invalidate the data.

Index and attribute data access

The class makes use of Python’s dynamic nature and provides direct access to index and attribute data in their concrete types via indices and attribute(). The returned views point to the underlying mesh data, element access coverts to a type corresponding to a particular VertexFormat and for performance-oriented access the view implements a buffer protocol with a corresponding type annotation:

>>> mesh = primitives.cube_solid()
>>> list(mesh.indices)[:10]
[0, 1, 2, 0, 2, 3, 4, 5, 6, 4]
>>> list(mesh.attribute(trade.MeshAttribute.POSITION))[:3]
[Vector(-1, -1, 1), Vector(1, -1, 1), Vector(1, 1, 1)]
>>> np.array(mesh.attribute(trade.MeshAttribute.NORMAL), copy=False)[2]
array([0., 0., 1.], dtype=float32)

Depending on the value of index_data_flags / vertex_data_flags it’s also possible to access the data in a mutable way via mutable_indices and mutable_attribute(), for example to perform a static transformation of the mesh before passing it to OpenGL.

Normalized formats (such as VertexFormat.VECTOR3UB_NORMALIZED) are unpacked to a corresponding floating-point representation in element access and packed from a floating-point representation in mutable acess. The type annotation is however still matching the original type (such as '3B' in this case), so code consuming these via the buffer protocol needs to handle the normalization explicitly if needed.

Methods

def attribute(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> corrade.containers.StridedArrayView1D
Data for given named attribute
def attribute(self, id: int) -> corrade.containers.StridedArrayView1D
Data for given attribute
def attribute_array_size(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int
Array size of a named attribute
def attribute_array_size(self, id: int) -> int
Attribute array size
def attribute_count(self, /) -> int
Attribute array count
def attribute_count(self, name: MeshAttribute, *, morph_target_id: int = -1) -> int
Count of given named attribute
def attribute_count(self, *, morph_target_id: int) -> int
Attribute array count for given morph target
def attribute_format(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> VertexFormat
Format of a named attribute
def attribute_format(self, id: int) -> VertexFormat
Attribute format
def attribute_id(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int
Absolute ID of a named attribute
def attribute_id(self, id: int) -> int
Attribute ID in a set of attributes of the same name
def attribute_name(self, id: int) -> MeshAttribute
Attribute name
def attribute_offset(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int
Offset of a named attribute
def attribute_offset(self, id: int) -> int
Attribute offset
def attribute_stride(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int
Stride of a named attribute
def attribute_stride(self, id: int) -> int
Attribute stride
def has_attribute(self, name: MeshAttribute, *, morph_target_id: int = -1) -> bool
Whether the mesh has given attribute
def mutable_attribute(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> corrade.containers.MutableStridedArrayView1D
Mutable data for given named attribute
def mutable_attribute(self, id: int) -> corrade.containers.MutableStridedArrayView1D
Mutable data for given attribute

Special methods

def __init__(self, primitive: MeshPrimitive, vertex_count: int) -> None
Construct an index-less attribute-less mesh data

Properties

index_count: int get
Index count
index_data: corrade.containers.ArrayView get
Raw index data
index_data_flags: DataFlags get
Index data flags
index_offset: int get
Index offset
index_stride: int get
Index stride
index_type: MeshIndexType get
Index type
indices: corrade.containers.StridedArrayView1D get
Indices
is_indexed: bool get
Whether the mesh is indexed
mutable_index_data: corrade.containers.MutableArrayView get
Mutable raw index data
mutable_indices: corrade.containers.MutableStridedArrayView1D get
Mutable indices
mutable_vertex_data: corrade.containers.MutableArrayView get
Mutable raw vertex data
owner: object get
Memory owner
primitive: MeshPrimitive get
Primitive
vertex_count: int get
Vertex count
vertex_data: corrade.containers.ArrayView get
Raw vertex data
vertex_data_flags: DataFlags get
Vertex data flags

Method documentation

def magnum.trade.MeshData.attribute(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> corrade.containers.StridedArrayView1D

Data for given named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id
NotImplementedError if attribute_array_size() for given attribute isn’t 0

def magnum.trade.MeshData.attribute(self, id: int) -> corrade.containers.StridedArrayView1D

Data for given attribute

Exceptions
IndexError If id is negative or not less than attribute_count()
NotImplementedError if attribute_array_size() for given attribute isn’t 0

def magnum.trade.MeshData.attribute_array_size(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int

Array size of a named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id

def magnum.trade.MeshData.attribute_array_size(self, id: int) -> int

Attribute array size

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.attribute_format(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> VertexFormat

Format of a named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id

def magnum.trade.MeshData.attribute_format(self, id: int) -> VertexFormat

Attribute format

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.attribute_id(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int

Absolute ID of a named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id

Compared to the C++ API, there’s no Trade::MeshData::findAttributeId(), the desired workflow is instead calling attribute_id() and catching an exception if not found.

def magnum.trade.MeshData.attribute_id(self, id: int) -> int

Attribute ID in a set of attributes of the same name

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.attribute_name(self, id: int) -> MeshAttribute

Attribute name

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.attribute_offset(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int

Offset of a named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id

def magnum.trade.MeshData.attribute_offset(self, id: int) -> int

Attribute offset

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.attribute_stride(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> int

Stride of a named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id

def magnum.trade.MeshData.attribute_stride(self, id: int) -> int

Attribute stride

Exceptions
IndexError If id is negative or not less than attribute_count()

def magnum.trade.MeshData.mutable_attribute(self, name: MeshAttribute, *, id: int = 0, morph_target_id: int = -1) -> corrade.containers.MutableStridedArrayView1D

Mutable data for given named attribute

Exceptions
KeyError If id is negative or not less than attribute_count() for name and morph_target_id
AttributeError If vertex_data_flags doesn’t contain DataFlags.MUTABLE
NotImplementedError if attribute_array_size() for given attribute isn’t 0

def magnum.trade.MeshData.mutable_attribute(self, id: int) -> corrade.containers.MutableStridedArrayView1D

Mutable data for given attribute

Exceptions
IndexError If id is negative or not less than attribute_count()
AttributeError If vertex_data_flags doesn’t contain DataFlags.MUTABLE
NotImplementedError if attribute_array_size() for given attribute isn’t 0

Property documentation

magnum.trade.MeshData.index_count: int get

Index count

Exceptions
AttributeError If is_indexed is False

magnum.trade.MeshData.index_offset: int get

Index offset

Exceptions
AttributeError If is_indexed is False

magnum.trade.MeshData.index_stride: int get

Index stride

Exceptions
AttributeError If is_indexed is False

magnum.trade.MeshData.index_type: MeshIndexType get

Index type

Exceptions
AttributeError If is_indexed is False

magnum.trade.MeshData.mutable_index_data: corrade.containers.MutableArrayView get

Mutable raw index data

Exceptions
AttributeError If index_data_flags doesn’t contain DataFlags.MUTABLE

magnum.trade.MeshData.mutable_indices: corrade.containers.MutableStridedArrayView1D get

Mutable indices

Exceptions
AttributeError If index_data_flags doesn’t contain DataFlags.MUTABLE

magnum.trade.MeshData.mutable_vertex_data: corrade.containers.MutableArrayView get

Mutable raw vertex data

Exceptions
AttributeError If vertex_data_flags doesn’t contain DataFlags.MUTABLE