From b983d29acfd465a79fc1819654522173954c166e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 29 Sep 2022 20:17:43 +0200 Subject: [PATCH] python: avoid an assertion in trade.MeshData.index_count. Emit a Python exception instead. --- doc/python/magnum.trade.rst | 3 +++ src/python/magnum/test/test_trade.py | 19 +++++++++++++++++++ src/python/magnum/trade.cpp | 9 ++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/python/magnum.trade.rst b/doc/python/magnum.trade.rst index 42b282b..f6489cc 100644 --- a/doc/python/magnum.trade.rst +++ b/doc/python/magnum.trade.rst @@ -66,6 +66,9 @@ .. py:property:: magnum.trade.ImageData3D.pixels :raise AttributeError: If :ref:`is_compressed` is :py:`True` +.. py:property:: magnum.trade.MeshData.index_count + :raise AttributeError: If :ref:`is_indexed` is :py:`False` + .. py:class:: magnum.trade.ImporterManager :summary: Manager for :ref:`AbstractImporter` plugin instances diff --git a/src/python/magnum/test/test_trade.py b/src/python/magnum/test/test_trade.py index a3e60fe..b5bfeb9 100644 --- a/src/python/magnum/test/test_trade.py +++ b/src/python/magnum/test/test_trade.py @@ -107,7 +107,11 @@ class MeshData(unittest.TestCase): mesh = importer.mesh(1) mesh_refcount = sys.getrefcount(mesh) + self.assertTrue(mesh.is_indexed) self.assertEqual(mesh.primitive, MeshPrimitive.TRIANGLES) + self.assertEqual(mesh.vertex_count, 3) + self.assertEqual(mesh.index_count, 3) + self.assertEqual(mesh.attribute_count, 2) # TODO: test more, once it's exposed index_data = mesh.index_data @@ -126,6 +130,21 @@ class MeshData(unittest.TestCase): del vertex_data self.assertEqual(sys.getrefcount(mesh), mesh_refcount) + def test_nonindexed(self): + # The only way to get a mesh instance is through a manager + importer = trade.ImporterManager().load_and_instantiate('GltfImporter') + importer.open_file(os.path.join(os.path.dirname(__file__), 'mesh.glb')) + + mesh = importer.mesh(0) + self.assertFalse(mesh.is_indexed) + + # Accessing the index data should be possible, they're just empty + self.assertEqual(len(mesh.index_data), 0) + + # Accessing any other index-related info should cause an exception + with self.assertRaisesRegex(AttributeError, "mesh is not indexed"): + mesh.index_count + class Importer(unittest.TestCase): def test(self): manager = trade.ImporterManager() diff --git a/src/python/magnum/trade.cpp b/src/python/magnum/trade.cpp index 2b9a136..391c3a0 100644 --- a/src/python/magnum/trade.cpp +++ b/src/python/magnum/trade.cpp @@ -314,7 +314,14 @@ void trade(py::module_& m) { return Containers::pyArrayViewHolder(self.vertexData(), py::cast(self)); }, "Raw vertex data") .def_property_readonly("is_indexed", &Trade::MeshData::isIndexed, "Whether the mesh is indexed") - .def_property_readonly("index_count", &Trade::MeshData::indexCount) + .def_property_readonly("index_count", [](Trade::MeshData& self) { + if(!self.isIndexed()) { + PyErr_SetString(PyExc_AttributeError, "mesh is not indexed"); + throw py::error_already_set{}; + } + + return self.indexCount(); + }) .def_property_readonly("vertex_count", &Trade::MeshData::vertexCount) .def_property_readonly("attribute_count", static_cast(&Trade::MeshData::attributeCount));