[Bf-blender-cvs] [d24578b676d] master: Alembic export: fixed curve type and order.

Sybren A. Stüvel noreply at git.blender.org
Tue Apr 18 13:59:05 CEST 2017


Commit: d24578b676d28ddbd8440efc1b6622452585b5c2
Author: Sybren A. Stüvel
Date:   Tue Apr 18 12:17:07 2017 +0200
Branches: master
https://developer.blender.org/rBd24578b676d28ddbd8440efc1b6622452585b5c2

Alembic export: fixed curve type and order.

The order number written to Alembic is the same as we use in memory, so
the +1 wasn't needed, at least according to the reference Maya exporter
maya/AbcExport/MayaNurbsCurveWriter.cpp, function
MayaNurbsCurveWriter::write(), in the Alembic source code.

Furthermore, when writing an array of nurb orders, the curve type should
be set to kVariableOrder, otherwise the importer will ignore it.

===================================================================

M	source/blender/alembic/intern/abc_curves.cc
M	tests/python/alembic_tests.py

===================================================================

diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 28e75db2862..58b8d7e05cd 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -95,7 +95,7 @@ void AbcCurveWriter::do_write()
 	for (; nurbs; nurbs = nurbs->next) {
 		if (nurbs->bp) {
 			curve_basis = Alembic::AbcGeom::kNoBasis;
-			curve_type = Alembic::AbcGeom::kLinear;
+			curve_type = Alembic::AbcGeom::kVariableOrder;
 
 			const int totpoint = nurbs->pntsu * nurbs->pntsv;
 
@@ -160,7 +160,7 @@ void AbcCurveWriter::do_write()
 			}
 		}
 
-		orders.push_back(nurbs->orderu + 1);
+		orders.push_back(nurbs->orderu);
 		vert_counts.push_back(verts.size());
 	}
 
diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py
index 209b34a8634..14c817549a9 100755
--- a/tests/python/alembic_tests.py
+++ b/tests/python/alembic_tests.py
@@ -116,6 +116,7 @@ class AbstractAlembicTest(unittest.TestCase):
         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
 
         abcls = self.alembic_root / 'bin' / 'abcls'
 
@@ -133,14 +134,19 @@ class AbstractAlembicTest(unittest.TestCase):
         converters = {
             'bool_t': int,
             'uint8_t': int,
+            'int32_t': int,
             'float64_t': float,
+            'float32_t': float,
         }
 
         result = {}
 
         # Ideally we'd get abcls to output JSON, see https://github.com/alembic/alembic/issues/121
-        lines = output.split('\n')
-        for info, value in zip(lines[0::2], lines[1::2]):
+        lines = collections.deque(output.split('\n'))
+        while lines:
+            info = lines.popleft()
+            if not info:
+                continue
             proptype, valtype_and_arrsize, name_and_extent = info.split()
 
             # Parse name and extent
@@ -152,22 +158,41 @@ class AbstractAlembicTest(unittest.TestCase):
             if extent != '1':
                 self.fail('Unsupported extent %s for property %s/%s' % (extent, proppath, name))
 
-            # Parse type and convert values
+            # Parse type
             m = self.abcls_array.match(valtype_and_arrsize)
             if not m:
                 self.fail('Unparsable value type from abcls: %s' % valtype_and_arrsize)
-            valtype, arraysize = m.group('name'), m.group('arraysize')
+            valtype, scalarsize = m.group('name'), m.group('arraysize')
 
+            # Convert values
             try:
                 conv = converters[valtype]
             except KeyError:
                 self.fail('Unsupported type %s for property %s/%s' % (valtype, proppath, name))
 
-            if arraysize is None:
-                result[name] = conv(value)
+            def convert_single_line(linevalue):
+                try:
+                    if scalarsize is None:
+                        return conv(linevalue)
+                    else:
+                        return [conv(v.strip()) for v in linevalue.split(',')]
+                except ValueError as ex:
+                    return str(ex)
+
+            if proptype == 'ScalarProperty':
+                value = lines.popleft()
+                result[name] = convert_single_line(value)
+            elif proptype == 'ArrayProperty':
+                arrayvalue = []
+                # Arrays consist of a variable number of items, and end in a blank line.
+                while True:
+                    linevalue = lines.popleft()
+                    if not linevalue:
+                        break
+                    arrayvalue.append(convert_single_line(linevalue))
+                result[name] = arrayvalue
             else:
-                values = [conv(v.strip()) for v in value.split(',')]
-                result[name] = values
+                self.fail('Unsupported type %s for property %s/%s' % (proptype, proppath, name))
 
         return result
 
@@ -260,6 +285,17 @@ class DupliGroupExportTest(AbstractAlembicTest):
         )
 
 
+class CurveExportTest(AbstractAlembicTest):
+    @with_tempdir
+    def test_export_single_curve(self, tempdir: pathlib.Path):
+        abc = tempdir / 'single-curve.abc'
+        script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \
+                 "renderable_only=True, visible_layers_only=True, flatten=False)" % abc
+        self.run_blender('single-curve.blend', script)
+
+        # Now check the resulting Alembic file.
+        abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom')
+        self.assertEqual(abcprop['.orders'], [4])
 
 
 if __name__ == '__main__':




More information about the Bf-blender-cvs mailing list