Fix T57078: Alembic curve import: better check for topology similarity
authorSybren A. Stüvel <sybren@stuvel.eu>
Fri, 28 Dec 2018 17:05:31 +0000 (18:05 +0100)
committerSybren A. Stüvel <sybren@stuvel.eu>
Fri, 28 Dec 2018 17:05:31 +0000 (18:05 +0100)
The old code assumed that if the number of curves was the same, the
entire set of curves would have the same topology (in other words, it
assumed 'same number of curves => same number of vertices for each
curve').

I've added a more thorough check that also considers the number of
vertices in each curve. This still keeps certain assumptions in place
(for example that if the topology is the same, the weights won't change,
which is not necessarily true). However, when the assumption doesn't
hold, at least now Blender doesn't crash any more.

source/blender/alembic/intern/abc_curves.cc

index f9880eda451322c00cad3a826afeca41636e9485..fa5e22148362757d74c238470e3de70ae09c9949 100644 (file)
@@ -440,18 +440,32 @@ Mesh *AbcCurveReader::read_mesh(Mesh *existing_mesh,
        const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
 
        int vertex_idx = 0;
-       int curve_idx = 0;
+       int curve_idx;
        Curve *curve = static_cast<Curve *>(m_object->data);
 
        const int curve_count = BLI_listbase_count(&curve->nurb);
+       bool same_topology = curve_count == num_vertices->size();
 
-       if (curve_count != num_vertices->size()) {
+       if (same_topology) {
+               Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+               for (curve_idx=0; nurbs; nurbs = nurbs->next, ++curve_idx) {
+                       const int num_in_alembic = (*num_vertices)[curve_idx];
+                       const int num_in_blender = nurbs->pntsu;
+
+                       if (num_in_alembic != num_in_blender) {
+                               same_topology = false;
+                               break;
+                       }
+               }
+       }
+
+       if (!same_topology) {
                BKE_nurbList_free(&curve->nurb);
                read_curve_sample(curve, m_curves_schema, sample_sel);
        }
        else {
                Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
-               for (; nurbs; nurbs = nurbs->next, ++curve_idx) {
+               for (curve_idx=0; nurbs; nurbs = nurbs->next, ++curve_idx) {
                        const int totpoint = (*num_vertices)[curve_idx];
 
                        if (nurbs->bp) {