Alembic import: greatly improved curve/hair import performance
authorSybren A. Stüvel <sybren@stuvel.eu>
Fri, 14 Apr 2017 13:26:45 +0000 (15:26 +0200)
committerSybren A. Stüvel <sybren@stuvel.eu>
Fri, 14 Apr 2017 13:26:45 +0000 (15:26 +0200)
The U-resolution of the imported curves was kept at the default value
of 12, which is way too high for imported hair. We export hair at a
fairly high resolution already, so it's not needed to subdivide even
further when importing.

Of course this may have an impact on other curves that do require this
U-resolution to be higher. In that case the resolution can be
increased after importing.

I removed the default nu->orderu = num_verts, as that allowed every
point to influence the entire spline, which was more expensive for the
CPU, and unlikely to be needed. The orderu computations had off-by-one
errors in the curve importer, which are now also fixed. The correct
values are:

    - Linear: orderu = 2
    - Quadratic: orderu = 3
    - Cubic: orderu = 4

These values are also what is stored in the Alembic file for curves of
type kVariableOrder, according to the reference Maya exporter
maya/AbcExport/MayaNurbsCurveWriter.cpp, function
MayaNurbsCurveWriter::write(), in the Alembic source code.

The result is a frame rate increase of roughly 100x (tested with one
100-hair test on one machine, so take with grain of salt).

source/blender/alembic/intern/abc_curves.cc

index 0542255d84b648a46e7f95d161ca772f0f65e610..28e75db2862538006cdd4018993dc1af3f1035c2 100644 (file)
@@ -205,6 +205,7 @@ void AbcCurveReader::readObjectData(Main *bmain, float time)
 
        cu->flag |= CU_DEFORM_FILL | CU_3D;
        cu->actvert = CU_ACT_NONE;
+       cu->resolu = 1;
 
        m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
        m_object->data = cu;
@@ -250,13 +251,18 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
                nu->pntsv = 1;
                nu->flag |= CU_SMOOTH;
 
-               nu->orderu = num_verts;
-
-               if (smp.getType() == Alembic::AbcGeom::kCubic) {
-                       nu->orderu = 3;
-               }
-               else if (orders && orders->size() > i) {
-                       nu->orderu = static_cast<short>((*orders)[i] - 1);
+               switch (smp.getType()) {
+                       case Alembic::AbcGeom::kCubic:
+                               nu->orderu = 4;
+                               break;
+                       case Alembic::AbcGeom::kVariableOrder:
+                               if (orders && orders->size() > i) {
+                                       nu->orderu = static_cast<short>((*orders)[i]);
+                               }
+                               break;
+                       case Alembic::AbcGeom::kLinear:
+                       default:
+                               nu->orderu = 2;
                }
 
                if (periodicity == Alembic::AbcGeom::kNonPeriodic) {