forked from bartvdbraak/blender
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.
This commit is contained in:
parent
8825a8e951
commit
d24578b676
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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__':
|
||||
|
Loading…
Reference in New Issue
Block a user