Browse Source

python: expose scenetools.filter_objects().

next
Vladimír Vondruš 3 years ago
parent
commit
3b799fcad9
  1. 4
      doc/python/magnum.scenetools.rst
  2. 11
      src/python/magnum/scenetools.cpp
  3. 38
      src/python/magnum/test/test_scenetools.py

4
doc/python/magnum.scenetools.rst

@ -35,6 +35,10 @@
:raise AssertionError: If size of any array in :p:`entries_to_keep` does
not match :ref:`trade.SceneData.field_size()` for given field
.. py:function:: magnum.scenetools.filter_objects
:raise AssertionError: If size of :p:`objects_to_keep` is different than
:ref:`trade.SceneData.mapping_bound`
.. py:function:: magnum.scenetools.absolute_field_transformations2d
:raise KeyError: If :p:`field` does not exist in :p:`scene`
:raise IndexError: If :p:`field_id` negative or not less than

11
src/python/magnum/scenetools.cpp

@ -150,6 +150,17 @@ void scenetools(py::module_& m) {
return SceneTools::filterFieldEntries(scene, entriesToKeep);
}, "Filter individual entries of fields in a scene", py::arg("scene"), py::arg("entries_to_keep"))
.def("filter_objects", [](const Trade::SceneData& scene, const Containers::BitArrayView objectsToKeep) {
if(objectsToKeep.size() != scene.mappingBound()) {
PyErr_Format(PyExc_AssertionError, "expected %llu bits but got %zu", scene.mappingBound(), objectsToKeep.size());
throw py::error_already_set{};
}
/** @todo this will blow up if any objects have a bit / string
field, implement that already so it's not needed to check
here */
return SceneTools::filterObjects(scene, objectsToKeep);
}, "Filter objects in a scene", py::arg("scene"), py::arg("objects_to_keep"))
.def("absolute_field_transformations2d", [](const Trade::SceneData& scene, Trade::SceneField field, const Matrix3& globalTransformation) {
const Containers::Optional<UnsignedInt> fieldId = scene.findFieldId(field);
if(!fieldId) {

38
src/python/magnum/test/test_scenetools.py

@ -274,6 +274,44 @@ class Filter(unittest.TestCase):
(importer.scene_field_for_name('yes'), containers.BitArray.value_init(2))
])
def test_objects(self):
importer = trade.ImporterManager().load_and_instantiate('GltfImporter')
importer.open_file(os.path.join(os.path.dirname(__file__), "scene.gltf"))
scene = importer.scene(0)
scene_refcount = sys.getrefcount(scene)
self.assertEqual(scene.mapping_bound, 4)
self.assertEqual(scene.field_count, 8)
self.assertEqual(scene.field_size(trade.SceneField.PARENT), 4)
self.assertEqual(scene.field_size(trade.SceneField.TRANSFORMATION), 4)
self.assertEqual(scene.field_size(trade.SceneField.TRANSLATION), 3)
self.assertEqual(scene.field_size(trade.SceneField.CAMERA), 2)
# Two parents, transformations and translations gone
objects_to_keep = containers.BitArray.direct_init(scene.mapping_bound, True)
objects_to_keep[0] = False
objects_to_keep[1] = False
filtered = scenetools.filter_objects(scene, objects_to_keep)
self.assertEqual(filtered.mapping_bound, 4)
self.assertEqual(filtered.field_count, 8)
self.assertEqual(filtered.field_size(trade.SceneField.PARENT), 2)
self.assertEqual(filtered.field_size(trade.SceneField.TRANSFORMATION), 2)
self.assertEqual(filtered.field_size(trade.SceneField.TRANSLATION), 1)
self.assertEqual(filtered.field_size(trade.SceneField.CAMERA), 2)
# The original scene isn't referenced by this one, it's a full copy
self.assertEqual(sys.getrefcount(scene), scene_refcount)
def test_objects_invalid_size(self):
importer = trade.ImporterManager().load_and_instantiate('GltfImporter')
importer.open_file(os.path.join(os.path.dirname(__file__), "scene.gltf"))
scene = importer.scene(0)
self.assertEqual(scene.mapping_bound, 4)
with self.assertRaisesRegex(AssertionError, "expected 4 bits but got 3"):
scenetools.filter_objects(scene, containers.BitArray.value_init(3))
class Hierarchy(unittest.TestCase):
def test_absolute_field_transformations2d(self):
# Static builds with non-static plugins cause assertions with non-owned

Loading…
Cancel
Save