diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2017-04-18 17:36:33 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2017-04-18 17:36:33 +0300 |
commit | 5bdbc88ab81891eff0dafaabf7f58a9c865d6e48 (patch) | |
tree | b5a4f96c53b73b7565f245ebb620ac2c56ed412b | |
parent | 70018eb16e721f9171834afd4bf70dc017af1369 (diff) |
Alembic import/export: write curve resolution to user property
Curve resolution isn't natively supported by Alembic, hence it is stored
in a user property "blender:resolution". I've looked at a Maya curves
example file, but that also didn't contain any information about curve
resolution.
Differential Revision: https://developer.blender.org/D2634
Reviewers: kevindietrich
-rw-r--r-- | source/blender/alembic/intern/abc_curves.cc | 31 | ||||
-rw-r--r-- | source/blender/alembic/intern/abc_curves.h | 4 | ||||
-rwxr-xr-x | tests/python/alembic_tests.py | 12 |
3 files changed, 40 insertions, 7 deletions
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc index e6a5b289c6b..c096ac036b4 100644 --- a/source/blender/alembic/intern/abc_curves.cc +++ b/source/blender/alembic/intern/abc_curves.cc @@ -49,19 +49,26 @@ using Alembic::Abc::Int32ArraySamplePtr; using Alembic::Abc::FloatArraySamplePtr; using Alembic::Abc::P3fArraySamplePtr; using Alembic::Abc::UcharArraySamplePtr; +using Alembic::Abc::PropertyHeader; +using Alembic::AbcGeom::ICompoundProperty; using Alembic::AbcGeom::ICurves; using Alembic::AbcGeom::ICurvesSchema; using Alembic::AbcGeom::IFloatGeomParam; +using Alembic::AbcGeom::IInt16Property; using Alembic::AbcGeom::ISampleSelector; using Alembic::AbcGeom::kWrapExisting; using Alembic::AbcGeom::CurvePeriodicity; +using Alembic::AbcGeom::OCompoundProperty; using Alembic::AbcGeom::OCurves; using Alembic::AbcGeom::OCurvesSchema; +using Alembic::AbcGeom::OInt16Property; using Alembic::AbcGeom::ON3fGeomParam; using Alembic::AbcGeom::OV2fGeomParam; +#define ABC_CURVE_RESOLUTION_U_PROPNAME "blender:resolution" + /* ************************************************************************** */ AbcCurveWriter::AbcCurveWriter(Scene *scene, @@ -73,6 +80,11 @@ AbcCurveWriter::AbcCurveWriter(Scene *scene, { OCurves curves(parent->alembicXform(), m_name, m_time_sampling); m_schema = curves.getSchema(); + + Curve *cu = static_cast<Curve *>(m_object->data); + OCompoundProperty user_props = m_schema.getUserProperties(); + OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME); + user_prop_resolu.set(cu->resolu); } void AbcCurveWriter::do_write() @@ -205,12 +217,22 @@ void AbcCurveReader::readObjectData(Main *bmain, float time) cu->flag |= CU_DEFORM_FILL | CU_3D; cu->actvert = CU_ACT_NONE; - cu->resolu = 1; + + const ISampleSelector sample_sel(time); + ICompoundProperty user_props = m_curves_schema.getUserProperties(); + const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME); + if (header != NULL && header->isScalar() && IInt16Property::matches(*header)) { + IInt16Property resolu(user_props, header->getName()); + cu->resolu = resolu.getValue(sample_sel); + } + else { + cu->resolu = 1; + } m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str()); m_object->data = cu; - read_curve_sample(cu, m_curves_schema, time); + read_curve_sample(cu, m_curves_schema, sample_sel); if (has_animations(m_curves_schema, m_settings)) { addCacheModifier(); @@ -219,9 +241,8 @@ void AbcCurveReader::readObjectData(Main *bmain, float time) /* ************************************************************************** */ -void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time) +void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel) { - const ISampleSelector sample_sel(time); ICurvesSchema::Sample smp = schema.getValue(sample_sel); const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices(); const P3fArraySamplePtr positions = smp.getPositions(); @@ -383,7 +404,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float if (curve_count != num_vertices->size()) { BKE_nurbList_free(&curve->nurb); - read_curve_sample(curve, m_curves_schema, time); + read_curve_sample(curve, m_curves_schema, sample_sel); } else { Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first); diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h index 2757d179a47..71b0d205820 100644 --- a/source/blender/alembic/intern/abc_curves.h +++ b/source/blender/alembic/intern/abc_curves.h @@ -61,6 +61,8 @@ public: /* ************************************************************************** */ -void read_curve_sample(Curve *cu, const Alembic::AbcGeom::ICurvesSchema &schema, const float time); +void read_curve_sample(Curve *cu, + const Alembic::AbcGeom::ICurvesSchema &schema, + const Alembic::Abc::ISampleSelector &sample_selector); #endif /* __ABC_CURVES_H__ */ diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py index 845b9bd6288..155cbd545f0 100755 --- a/tests/python/alembic_tests.py +++ b/tests/python/alembic_tests.py @@ -128,6 +128,7 @@ class AbstractAlembicTest(unittest.TestCase): converters = { 'bool_t': int, 'uint8_t': int, + 'int16_t': int, 'int32_t': int, 'float64_t': float, 'float32_t': float, @@ -141,7 +142,13 @@ class AbstractAlembicTest(unittest.TestCase): info = lines.popleft() if not info: continue - proptype, valtype_and_arrsize, name_and_extent = info.split() + parts = info.split() + proptype = parts[0] + + if proptype == 'CompoundProperty': + # To read those, call self.abcprop() on it. + continue + valtype_and_arrsize, name_and_extent = parts[1:] # Parse name and extent m = self.abcls_array.match(name_and_extent) @@ -291,6 +298,9 @@ class CurveExportTest(AbstractAlembicTest): abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom') self.assertEqual(abcprop['.orders'], [4]) + abcprop = self.abcprop(abc, '/NurbsCurve/NurbsCurveShape/.geom/.userProperties') + self.assertEqual(abcprop['blender:resolution'], 10) + if __name__ == '__main__': parser = argparse.ArgumentParser() |