From a470eae5f1396e6fb199e90f532c85bd750be388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Mar 2020 21:51:36 +0100 Subject: [PATCH] python: adapt to Trade::MeshDataXD deprecation. Right now there's no deprecation logic in place for the Python bindings, so this is a breaking change. Sorry about that. --- doc/python/magnum.trade.rst | 26 ++-- src/python/magnum/meshtools.cpp | 7 +- src/python/magnum/primitives.cpp | 11 +- src/python/magnum/test/test_primitives.py | 138 +++++++++++----------- src/python/magnum/test/test_trade.py | 38 +++--- src/python/magnum/trade.cpp | 36 ++---- 6 files changed, 112 insertions(+), 144 deletions(-) diff --git a/doc/python/magnum.trade.rst b/doc/python/magnum.trade.rst index a757b7c..f1e5622 100644 --- a/doc/python/magnum.trade.rst +++ b/doc/python/magnum.trade.rst @@ -95,29 +95,19 @@ .. py:function:: magnum.trade.AbstractImporter.open_file :raise RuntimeError: If file opening fails -.. py:property:: magnum.trade.AbstractImporter.mesh2d_count +.. py:property:: magnum.trade.AbstractImporter.mesh_count :raise RuntimeError: If no file is opened -.. py:property:: magnum.trade.AbstractImporter.mesh3d_count +.. py:function:: magnum.trade.AbstractImporter.mesh_level_count :raise RuntimeError: If no file is opened - -.. py:function:: magnum.trade.AbstractImporter.mesh2d_for_name - :raise RuntimeError: If no file is opened -.. py:function:: magnum.trade.AbstractImporter.mesh3d_for_name - :raise RuntimeError: If no file is opened - -.. py:function:: magnum.trade.AbstractImporter.mesh2d_name - :raise RuntimeError: If no file is opened - :raise ValueError: If :p:`id` is negative or not less than `mesh2d_count` -.. py:function:: magnum.trade.AbstractImporter.mesh3d_name + :raise ValueError: If :p:`id` is negative or not less than `mesh_count` +.. py:function:: magnum.trade.AbstractImporter.mesh_for_name :raise RuntimeError: If no file is opened - :raise ValueError: If :p:`id` is negative or not less than `mesh3d_count` - -.. py:function:: magnum.trade.AbstractImporter.mesh2d +.. py:function:: magnum.trade.AbstractImporter.mesh_name :raise RuntimeError: If no file is opened - :raise ValueError: If :p:`id` is negative or not less than `mesh2d_count` -.. py:function:: magnum.trade.AbstractImporter.mesh3d + :raise ValueError: If :p:`id` is negative or not less than `mesh_count` +.. py:function:: magnum.trade.AbstractImporter.mesh :raise RuntimeError: If no file is opened - :raise ValueError: If :p:`id` is negative or not less than `mesh3d_count` + :raise ValueError: If :p:`id` is negative or not less than `mesh_count` .. py:property:: magnum.trade.AbstractImporter.image1d_count :raise RuntimeError: If no file is opened diff --git a/src/python/magnum/meshtools.cpp b/src/python/magnum/meshtools.cpp index 140cc8b..d924179 100644 --- a/src/python/magnum/meshtools.cpp +++ b/src/python/magnum/meshtools.cpp @@ -26,8 +26,7 @@ #include #include #include -#include -#include +#include #include "corrade/EnumOperators.h" #include "magnum/bootstrap.h" @@ -52,9 +51,7 @@ void meshtools(py::module& m) { corrade::enumOperators(compileFlag); m - .def("compile", static_cast(&MeshTools::compile), - "Compile 2D mesh data", py::arg("mesh_data")) - .def("compile", [](const Trade::MeshData3D& meshData, MeshTools::CompileFlag flags) { + .def("compile", [](const Trade::MeshData& meshData, MeshTools::CompileFlag flags) { return MeshTools::compile(meshData, flags); }, "Compile 3D mesh data", py::arg("mesh_data"), py::arg("flags") = MeshTools::CompileFlag{}); } diff --git a/src/python/magnum/primitives.cpp b/src/python/magnum/primitives.cpp index e91e5b9..cd235bb 100644 --- a/src/python/magnum/primitives.cpp +++ b/src/python/magnum/primitives.cpp @@ -39,8 +39,7 @@ #include #include #include -#include -#include +#include #include "corrade/EnumOperators.h" #include "magnum/bootstrap.h" @@ -138,10 +137,10 @@ void primitives(py::module& m) { .def("icosphere_solid", Primitives::icosphereSolid, py::arg("subdivisions")) - .def("line2d", static_cast(Primitives::line2D), "2D line", py::arg("a"), py::arg("b")) - .def("line2d", static_cast(Primitives::line2D), "2D line in an identity transformation") - .def("line3d", static_cast(Primitives::line3D), "3D line", py::arg("a"), py::arg("b")) - .def("line3d", static_cast(Primitives::line3D), "3D line in an identity transformation") + .def("line2d", static_cast(Primitives::line2D), "2D line", py::arg("a"), py::arg("b")) + .def("line2d", static_cast(Primitives::line2D), "2D line in an identity transformation") + .def("line3d", static_cast(Primitives::line3D), "3D line", py::arg("a"), py::arg("b")) + .def("line3d", static_cast(Primitives::line3D), "3D line in an identity transformation") .def("plane_solid", Primitives::planeSolid, "Solid 3D plane", py::arg("texture_coords") = Primitives::PlaneTextureCoords::DontGenerate) .def("plane_wireframe", Primitives::planeWireframe, "Wireframe 3D plane") diff --git a/src/python/magnum/test/test_primitives.py b/src/python/magnum/test/test_primitives.py index c7b5401..5730698 100644 --- a/src/python/magnum/test/test_primitives.py +++ b/src/python/magnum/test/test_primitives.py @@ -32,253 +32,253 @@ class Axis(unittest.TestCase): def test_2d(self): a = primitives.axis2d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 2) def test_3d(self): a = primitives.axis3d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 2) class Capsule(unittest.TestCase): def test_2d_wireframe(self): a = primitives.capsule2d_wireframe(3, 3, 2.0) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertEqual(a.attribute_count, 1) def test_3d_solid(self): a = primitives.capsule3d_solid(3, 3, 10, 2.0, primitives.CapsuleTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.capsule3d_solid(3, 3, 10, 2.0) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertTrue(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_3d_wireframe(self): a = primitives.capsule3d_wireframe(5, 3, 12, 0.3) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Circle(unittest.TestCase): def test_2d_solid(self): a = primitives.circle2d_solid(5, primitives.CircleTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_FAN) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 2) b = primitives.circle2d_solid(5) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLE_FAN) - self.assertFalse(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertFalse(b.is_indexed) + self.assertEqual(b.attribute_count, 1) def test_2d_wireframe(self): a = primitives.circle2d_wireframe(5) self.assertEqual(a.primitive, MeshPrimitive.LINE_LOOP) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_3d_solid(self): a = primitives.circle3d_solid(5, primitives.CircleTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_FAN) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.circle3d_solid(5) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLE_FAN) - self.assertFalse(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertFalse(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_3d_wireframe(self): a = primitives.circle3d_wireframe(5) self.assertEqual(a.primitive, MeshPrimitive.LINE_LOOP) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) class Cone(unittest.TestCase): def test_solid(self): a = primitives.cone_solid(5, 7, 7.1, primitives.ConeFlags.GENERATE_TEXTURE_COORDS|primitives.ConeFlags.CAP_END) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.cone_solid(5, 7, 7.1) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertTrue(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_wireframe(self): a = primitives.cone_wireframe(16, 7.1) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Crosshair(unittest.TestCase): def test_2d(self): a = primitives.crosshair2d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_3d(self): a = primitives.crosshair3d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) class Cube(unittest.TestCase): def test_solid(self): a = primitives.cube_solid() self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) def test_solid_strip(self): a = primitives.cube_solid_strip() self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_wireframe(self): a = primitives.cube_wireframe() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Cylinder(unittest.TestCase): def test_solid(self): a = primitives.cylinder_solid(7, 12, 0.2, primitives.CylinderFlags.GENERATE_TEXTURE_COORDS|primitives.CylinderFlags.CAP_ENDS) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.cylinder_solid(7, 12, 0.2) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertTrue(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_wireframe(self): a = primitives.cylinder_wireframe(8, 16, 1.1) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Gradient(unittest.TestCase): def test_gradient2d(self): a = primitives.gradient2d((3.1, 2.0), Color3(), (0.2, 1.1), Color4()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 2) def test_gradient2d_horizontal(self): a = primitives.gradient2d_horizontal(Color4(), Color3()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 2) def test_gradient2d_vertical(self): a = primitives.gradient2d_vertical(Color4(), Color3()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 2) def test_gradient3d(self): a = primitives.gradient3d((3.1, 2.0, 0.1), Color3(), (0.2, 1.1, 1.2), Color4()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 3) def test_gradient3d_horizontal(self): a = primitives.gradient3d_horizontal(Color4(), Color3()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 3) def test_gradient3d_vertical(self): a = primitives.gradient3d_vertical(Color4(), Color3()) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_colors()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 3) class Grid(unittest.TestCase): def test_solid(self): a = primitives.grid3d_solid((4, 5)) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) def test_wireframe(self): a = primitives.grid3d_wireframe((2, 7)) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Icosphere(unittest.TestCase): def test(self): a = primitives.icosphere_solid(2) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) class Line(unittest.TestCase): def test_2d(self): a = primitives.line2d((1.0, 2.0), (7.0, 3.2)) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_2d_identity(self): a = primitives.line2d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_3d(self): a = primitives.line3d((1.0, 2.0, 1.1), (7.0, 3.2, 1.1)) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) def test_3d_identity(self): a = primitives.line3d() self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) class Plane(unittest.TestCase): def test_solid(self): a = primitives.plane_solid(primitives.PlaneTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.plane_solid() self.assertEqual(b.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertFalse(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_wireframe(self): a = primitives.plane_wireframe() self.assertEqual(a.primitive, MeshPrimitive.LINE_LOOP) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) class Square(unittest.TestCase): def test_solid(self): a = primitives.square_solid(primitives.SquareTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertFalse(a.is_indexed) + self.assertEqual(a.attribute_count, 2) b = primitives.square_solid() self.assertEqual(b.primitive, MeshPrimitive.TRIANGLE_STRIP) - self.assertFalse(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertFalse(b.is_indexed) + self.assertEqual(b.attribute_count, 1) def test_wireframe(self): a = primitives.square_wireframe() self.assertEqual(a.primitive, MeshPrimitive.LINE_LOOP) - self.assertFalse(a.is_indexed()) + self.assertFalse(a.is_indexed) class UVSphere(unittest.TestCase): def test_solid(self): a = primitives.uv_sphere_solid(3, 7, primitives.UVSphereTextureCoords.GENERATE) self.assertEqual(a.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(a.is_indexed()) - self.assertTrue(a.has_texture_coords2d()) + self.assertTrue(a.is_indexed) + self.assertEqual(a.attribute_count, 3) b = primitives.uv_sphere_solid(3, 7) self.assertEqual(b.primitive, MeshPrimitive.TRIANGLES) - self.assertTrue(b.is_indexed()) - self.assertFalse(b.has_texture_coords2d()) + self.assertTrue(b.is_indexed) + self.assertEqual(b.attribute_count, 2) def test_wireframe(self): a = primitives.uv_sphere_wireframe(6, 8) self.assertEqual(a.primitive, MeshPrimitive.LINES) - self.assertTrue(a.is_indexed()) + self.assertTrue(a.is_indexed) diff --git a/src/python/magnum/test/test_trade.py b/src/python/magnum/test/test_trade.py index 46216a4..496019f 100644 --- a/src/python/magnum/test/test_trade.py +++ b/src/python/magnum/test/test_trade.py @@ -94,7 +94,7 @@ class MeshData(unittest.TestCase): importer = trade.ImporterManager().load_and_instantiate('TinyGltfImporter') importer.open_file(os.path.join(os.path.dirname(__file__), 'mesh.glb')) - mesh = importer.mesh3d(0) + mesh = importer.mesh(0) self.assertEqual(mesh.primitive, MeshPrimitive.TRIANGLES) # TODO: test more, once it's exposed @@ -117,24 +117,18 @@ class Importer(unittest.TestCase): self.assertFalse(importer.is_opened) with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh2d_count + importer.mesh_count with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh3d_count + importer.mesh_level_count(0) with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh2d_for_name('') - with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh3d_for_name('') + importer.mesh_for_name('') with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh2d_name(0) - with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh3d_name(0) + importer.mesh_name(0) with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh2d(0) - with self.assertRaisesRegex(RuntimeError, "no file opened"): - importer.mesh3d(0) + importer.mesh(0) with self.assertRaisesRegex(RuntimeError, "no file opened"): importer.image1d_count @@ -176,14 +170,11 @@ class Importer(unittest.TestCase): importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) with self.assertRaises(IndexError): - importer.mesh2d_name(0) - with self.assertRaises(IndexError): - importer.mesh3d_name(0) - + importer.mesh_level_count(0) with self.assertRaises(IndexError): - importer.mesh2d(0) + importer.mesh_name(0) with self.assertRaises(IndexError): - importer.mesh3d(0) + importer.mesh(0) with self.assertRaises(IndexError): importer.image1d_level_count(0) @@ -214,15 +205,16 @@ class Importer(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, "opening data failed"): importer.open_data(b'') - def test_mesh3d(self): + def test_mesh(self): # importer refcounting tested in image2d importer = trade.ImporterManager().load_and_instantiate('TinyGltfImporter') importer.open_file(os.path.join(os.path.dirname(__file__), 'mesh.glb')) - self.assertEqual(importer.mesh3d_count, 3) - self.assertEqual(importer.mesh3d_name(0), 'Non-indexed mesh') - self.assertEqual(importer.mesh3d_for_name('Non-indexed mesh'), 0) + self.assertEqual(importer.mesh_count, 3) + self.assertEqual(importer.mesh_level_count(0), 1) + self.assertEqual(importer.mesh_name(0), 'Non-indexed mesh') + self.assertEqual(importer.mesh_for_name('Non-indexed mesh'), 0) - mesh = importer.mesh3d(0) + mesh = importer.mesh(0) self.assertEqual(mesh.primitive, MeshPrimitive.TRIANGLES) def test_image2d(self): diff --git a/src/python/magnum/trade.cpp b/src/python/magnum/trade.cpp index b52c53e..581bfe0 100644 --- a/src/python/magnum/trade.cpp +++ b/src/python/magnum/trade.cpp @@ -29,8 +29,7 @@ #include #include #include -#include -#include +#include #include "Corrade/Containers/Python.h" #include "Magnum/Python.h" @@ -137,14 +136,6 @@ template void imageData(py::class_ void meshData(py::class_& c) { - c - .def_property_readonly("primitive", &T::primitive, "Primitive") - .def("is_indexed", &T::isIndexed, "Whether the mesh is indexed") - .def("has_texture_coords2d", &T::hasTextureCoords2D, "Whether the data contain any 2D texture coordinates") - .def("has_colors", &T::hasColors, "Whether the data contain any vertex colors"); -} - /* 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. */ @@ -229,11 +220,12 @@ void trade(py::module& m) { /* AbstractImporter depends on this */ py::module::import("corrade.pluginmanager"); - py::class_ meshData2D{m, "MeshData2D", "Two-dimensional mesh data"}; - py::class_ meshData3D{m, "MeshData3D", "Three-dimensional mesh data"}; - meshData(meshData2D); - meshData(meshData3D); - meshData3D.def("has_normals", &Trade::MeshData3D::hasNormals, "Whether the data contain any normals"); + py::class_{m, "MeshData", "Mesh data"} + .def_property_readonly("primitive", &Trade::MeshData::primitive, "Primitive") + .def_property_readonly("is_indexed", &Trade::MeshData::isIndexed, "Whether the mesh is indexed") + .def_property_readonly("vertex_count", &Trade::MeshData::vertexCount) + .def_property_readonly("index_count", &Trade::MeshData::indexCount) + .def_property_readonly("attribute_count", static_cast(&Trade::MeshData::attributeCount)); py::class_ imageData1D{m, "ImageData1D", "One-dimensional image data"}; py::class_ imageData2D{m, "ImageData2D", "Two-dimensional image data"}; @@ -270,14 +262,12 @@ void trade(py::module& m) { .def("close", &Trade::AbstractImporter::close, "Close currently opened file") /** @todo all other data types */ - .def_property_readonly("mesh2d_count", checkOpened, "Two-dimensional mesh count") - .def_property_readonly("mesh3d_count", checkOpened, "Three-dimensional mesh count") - .def("mesh2d_for_name", checkOpened, "Two-dimensional mesh ID for given name") - .def("mesh3d_for_name", checkOpened, "Three-dimensional mesh ID for given name") - .def("mesh2d_name", checkOpenedBounds, "Two-dimensional mesh name", py::arg("id")) - .def("mesh3d_name", checkOpenedBounds, "Three-dimensional mesh name", py::arg("id")) - .def("mesh2d", checkOpenedBoundsResult, "Two-dimensional mesh", py::arg("id")) - .def("mesh3d", checkOpenedBoundsResult, "Three-dimensional mesh", py::arg("id")) + .def_property_readonly("mesh_count", checkOpened, "Mesh count") + .def("mesh_level_count", checkOpenedBounds, "Mesh level count", py::arg("id")) + .def("mesh_for_name", checkOpened, "Mesh ID for given name") + .def("mesh_name", checkOpenedBounds, "Mesh name", py::arg("id")) + .def("mesh", checkOpenedBoundsResult, "Mesh", py::arg("id"), py::arg("level") = 0) + /** @todo mesh_attribute_for_name / mesh_attribute_name */ .def_property_readonly("image1d_count", checkOpened, "One-dimensional image count") .def_property_readonly("image2d_count", checkOpened, "Two-dimensional image count")