From c2284590e26ea7b0818d9bf285add0655c1555ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 28 Jan 2024 23:04:29 +0100 Subject: [PATCH] python: expose scenetools.combine_fields(). Finally it's possible to create scenes from scratch from Python. --- doc/python/magnum.trade.rst | 6 +++-- src/python/magnum/scenetools.cpp | 4 +++ src/python/magnum/test/test_scenetools.py | 31 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/doc/python/magnum.trade.rst b/doc/python/magnum.trade.rst index ec23d8b..e1f1cde 100644 --- a/doc/python/magnum.trade.rst +++ b/doc/python/magnum.trade.rst @@ -705,8 +705,10 @@ .. py:class:: magnum.trade.SceneFieldData Associates a pair of typed data views with a name, type and other scene - field properties. The mapping data view is always one-dimensional. The - field data view can be either one-dimensional, for example a NumPy array: + field properties, which can be subsequently put into a :ref:`SceneData` + instance, for example with :ref:`scenetools.combine_fields()`. The mapping + data view is always one-dimensional. The field data view can be either + one-dimensional, for example a NumPy array: .. Just to verify the snippet below actually works (don't want the arrows diff --git a/src/python/magnum/scenetools.cpp b/src/python/magnum/scenetools.cpp index 8bb3976..a9bdb15 100644 --- a/src/python/magnum/scenetools.cpp +++ b/src/python/magnum/scenetools.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,9 @@ void scenetools(py::module_& m) { #endif m + .def("combine_fields", [](const Trade::SceneMappingType mappingType, UnsignedLong mappingBound, const std::vector& fields) { + return SceneTools::combineFields(mappingType, mappingBound, fields); + }, "Combine scene fields together", py::arg("mapping_type"), py::arg("mapping_bound"), py::arg("fields")) .def("filter_fields", [](const Trade::SceneData& scene, const Containers::BitArrayView fieldsToKeep) { if(fieldsToKeep.size() != scene.fieldCount()) { PyErr_Format(PyExc_AssertionError, "expected %u bits but got %zu", scene.fieldCount(), fieldsToKeep.size()); diff --git a/src/python/magnum/test/test_scenetools.py b/src/python/magnum/test/test_scenetools.py index 1de4828..911439c 100644 --- a/src/python/magnum/test/test_scenetools.py +++ b/src/python/magnum/test/test_scenetools.py @@ -23,6 +23,7 @@ # DEALINGS IN THE SOFTWARE. # +import array import os import sys import unittest @@ -32,6 +33,36 @@ from magnum import * from magnum import scenetools, trade import magnum +class Combine(unittest.TestCase): + def test(self): + mapping = array.array('I', [0, 176, 35]) + meshes = array.array('H', [26, 17, 2]) + materials = array.array('b', [-1, 104, 8]) + + scene = scenetools.combine_fields(trade.SceneMappingType.UNSIGNED_LONG, 180, [ + trade.SceneFieldData(trade.SceneField.MESH, + trade.SceneMappingType.UNSIGNED_INT, mapping, + trade.SceneFieldType.UNSIGNED_SHORT, meshes), + trade.SceneFieldData(trade.SceneField.MESH_MATERIAL, + trade.SceneMappingType.UNSIGNED_INT, mapping, + trade.SceneFieldType.BYTE, materials), + ]) + self.assertEqual(scene.mapping_type, trade.SceneMappingType.UNSIGNED_LONG) + self.assertEqual(scene.mapping_bound, 180) + self.assertEqual(scene.field_count, 2) + + self.assertEqual(scene.field_size(0), 3) + self.assertEqual(scene.field_name(0), trade.SceneField.MESH) + self.assertEqual(scene.field_type(0), trade.SceneFieldType.UNSIGNED_SHORT) + self.assertEqual(list(scene.mapping(0)), [0, 176, 35]) + self.assertEqual(list(scene.field(0)), [26, 17, 2]) + + self.assertEqual(scene.field_size(1), 3) + self.assertEqual(scene.field_name(1), trade.SceneField.MESH_MATERIAL) + self.assertEqual(scene.field_type(1), trade.SceneFieldType.BYTE) + self.assertEqual(list(scene.mapping(1)), [0, 176, 35]) + self.assertEqual(list(scene.field(1)), [-1, 104, 8]) + class Filter(unittest.TestCase): def test_fields(self): # Static builds with non-static plugins cause assertions with non-owned