diff options
Diffstat (limited to 'tests/python')
-rw-r--r-- | tests/python/alembic_export_tests.py | 70 |
1 files changed, 59 insertions, 11 deletions
diff --git a/tests/python/alembic_export_tests.py b/tests/python/alembic_export_tests.py index 800e450776c..cacd2f2dd0e 100644 --- a/tests/python/alembic_export_tests.py +++ b/tests/python/alembic_export_tests.py @@ -32,6 +32,7 @@ import pathlib import subprocess import sys import unittest +from typing import Tuple from modules.test_utils import ( with_tempdir, @@ -59,19 +60,13 @@ class AbstractAlembicTest(AbstractBlenderRunnerTest): # 'abcls' array notation, like "name[16]" cls.abcls_array = re.compile(r'^(?P<name>[^\[]+)(\[(?P<arraysize>\d+)\])?$') - def abcprop(self, filepath: pathlib.Path, proppath: str) -> dict: - """Uses abcls to obtain compound property values from an Alembic object. - - A dict of subproperties is returned, where the values are Python values. + def abcls(self, *arguments) -> Tuple[int, str]: + """Uses abcls and return its output. - The Python bindings for Alembic are old, and only compatible with Python 2.x, - so that's why we can't use them here, and have to rely on other tooling. + :return: tuple (process exit status code, stdout) """ - import collections - abcls = self.alembic_root / 'bin' / 'abcls' - - command = (str(abcls), '-vl', '%s%s' % (filepath, proppath)) + command = (self.alembic_root / 'bin' / 'abcls', *arguments) proc = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=30) @@ -84,7 +79,25 @@ class AbstractAlembicTest(AbstractBlenderRunnerTest): output = output.replace('\r\n', '\n').replace('\r', '\n') if proc.returncode: - raise AbcPropError('Error %d running %s:\n%s' % (proc.returncode, ' '.join(command), output)) + str_command = " ".join(str(c) for c in command) + print(f'command {str_command} failed with status {proc.returncode}') + + return (proc.returncode, output) + + def abcprop(self, filepath: pathlib.Path, proppath: str) -> dict: + """Uses abcls to obtain compound property values from an Alembic object. + + A dict of subproperties is returned, where the values are Python values. + + The Python bindings for Alembic are old, and only compatible with Python 2.x, + so that's why we can't use them here, and have to rely on other tooling. + """ + import collections + + command = ('-vl', '%s%s' % (filepath, proppath)) + returncode, output = self.abcls(*command) + if returncode: + raise AbcPropError('Error %d running abcls:\n%s' % (returncode, output)) # Mapping from value type to callable that can convert a string to Python values. converters = { @@ -536,6 +549,41 @@ class LongNamesExportTest(AbstractAlembicTest): self.assertIn('.faceCounts', abcprop) +class InvisibleObjectExportTest(AbstractAlembicTest): + """Export an object which is invisible. + + This test only tests a small subset of the functionality that is required to + export invisible objects. It just tests that the visibility property is + written, and that it has the correct initial value. This is a limitation + caused by these tests relying on `abcls`. + """ + + @with_tempdir + def test_hierarchical_export(self, tempdir: pathlib.Path): + abc = tempdir / 'visibility.abc' + script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=2, " \ + "renderable_only=False, visible_objects_only=False)" % abc.as_posix() + self.run_blender('visibility.blend', script) + + def test(cube_name: str, expect_visible: bool): + returncode, output = self.abcls('-va', f'{abc}/{cube_name}') + if returncode: + self.fail(f"abcls failed: {output}") + output = output.strip() + self.assertEqual(f'Cube .xform visible {int(expect_visible)}', output) + + # This cube is always visible. + test('VisibleCube', True) + + # This cube is never visible, and thus will not be pulled into the + # depsgraph by the standard builder, only by the all-objects builder. + test('InvisibleCube', False) + + # This cube has animated visibility, and thus will be pulled into the + # depsgraph by the standard builder as well as the all-objects builder. + test('InvisibleAnimatedCube', False) + + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--blender', required=True) |