Commit: 66a367190447773f87cb31854a39f67b91d519f1
Author: Kévin Dietrich
Date:   Wed Nov 30 09:20:45 2016 +0100
Branches: master
https://developer.blender.org/rB66a367190447773f87cb31854a39f67b91d519f1

Fix T49813: crash after changing Alembic cache topology.

Crash is due by mismatching loops and faces counts between the Alembic
data and the Blender derivedmesh which does not appear so
straightforward to fix (the crash happens deep in the derivedmesh code).

So for now, try to detect if the topology has changed and if so, both
only read vertices (vertex colors and UVs won't be read, as tied to face
loops) and add a warning message in the modifier's UI to let the user
know.

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

M       source/blender/alembic/intern/abc_curves.cc
M       source/blender/alembic/intern/abc_curves.h
M       source/blender/alembic/intern/abc_mesh.cc
M       source/blender/alembic/intern/abc_mesh.h
M       source/blender/alembic/intern/abc_object.h
M       source/blender/alembic/intern/abc_points.cc
M       source/blender/alembic/intern/abc_points.h
M       source/blender/alembic/intern/alembic_capi.cc

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

diff --git a/source/blender/alembic/intern/abc_curves.cc 
b/source/blender/alembic/intern/abc_curves.cc
index 7e5ea3b..4ecb9d9 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -361,7 +361,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema 
&schema, const float time)
  * object directly and create a new DerivedMesh from that. Also we might need 
to
  * create new or delete existing NURBS in the curve.
  */
-DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float 
time, int /*read_flag*/)
+DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float 
time, int /*read_flag*/, const char **/*err_str*/)
 {
        ISampleSelector sample_sel(time);
        const ICurvesSchema::Sample sample = 
m_curves_schema.getValue(sample_sel);
diff --git a/source/blender/alembic/intern/abc_curves.h 
b/source/blender/alembic/intern/abc_curves.h
index 979ee8a..2757d17 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -56,7 +56,7 @@ public:
        bool valid() const;
 
        void readObjectData(Main *bmain, float time);
-       DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int);
+       DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int 
read_flag, const char **err_str);
 };
 
 /* ************************************************************************** 
*/
diff --git a/source/blender/alembic/intern/abc_mesh.cc 
b/source/blender/alembic/intern/abc_mesh.cc
index 5b282e3..395c3e6 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -896,7 +896,7 @@ void AbcMeshReader::readObjectData(Main *bmain, float time)
        const ISampleSelector sample_sel(time);
 
        DerivedMesh *dm = CDDM_from_mesh(mesh);
-       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 
MOD_MESHSEQ_READ_ALL);
+       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 
MOD_MESHSEQ_READ_ALL, NULL);
 
        if (ndm != dm) {
                dm->release(dm);
@@ -978,7 +978,7 @@ CDStreamConfig get_config(DerivedMesh *dm)
        return config;
 }
 
-DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag)
+DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag, const char **err_str)
 {
        ISampleSelector sample_sel(time);
        const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
@@ -1003,6 +1003,21 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh 
*dm, const float time,
 
                settings.read_flag |= MOD_MESHSEQ_READ_ALL;
        }
+       else {
+               /* If the face count changed (e.g. by triangulation), only read 
points.
+                * This prevents crash from T49813
+                * TODO(kevin): perhaps find a better way to do this? */
+               if (face_counts->size() != dm->getNumPolys(dm) ||
+                   face_indices->size() != dm->getNumLoops(dm))
+               {
+                       settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+                       if (err_str) {
+                               *err_str = "Topology has changed, perhaps by 
triangulating the"
+                                          " mesh. Only vertices will be read!";
+                       }
+               }
+       }
 
        CDStreamConfig config = get_config(new_dm ? new_dm : dm);
        config.time = time;
@@ -1177,7 +1192,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float 
time)
        m_object->data = mesh;
 
        DerivedMesh *dm = CDDM_from_mesh(mesh);
-       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 
MOD_MESHSEQ_READ_ALL);
+       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 
MOD_MESHSEQ_READ_ALL, NULL);
 
        if (ndm != dm) {
                dm->release(dm);
@@ -1257,7 +1272,7 @@ void read_subd_sample(ImportSettings *settings,
        /* TODO: face sets */
 }
 
-DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag)
+DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag, const char **err_str)
 {
        ISampleSelector sample_sel(time);
        const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
@@ -1281,6 +1296,21 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh 
*dm, const float time,
 
                settings.read_flag |= MOD_MESHSEQ_READ_ALL;
        }
+       else {
+               /* If the face count changed (e.g. by triangulation), only read 
points.
+                * This prevents crash from T49813
+                * TODO(kevin): perhaps find a better way to do this? */
+               if (face_counts->size() != dm->getNumPolys(dm) ||
+                   face_indices->size() != dm->getNumLoops(dm))
+               {
+                       settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+                       if (err_str) {
+                               *err_str = "Topology has changed, perhaps by 
triangulating the"
+                                          " mesh. Only vertices will be read!";
+                       }
+               }
+       }
 
        /* Only read point data when streaming meshes, unless we need to create 
new ones. */
        CDStreamConfig config = get_config(new_dm ? new_dm : dm);
diff --git a/source/blender/alembic/intern/abc_mesh.h 
b/source/blender/alembic/intern/abc_mesh.h
index 66e6585..28d1710 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -102,7 +102,7 @@ public:
 
        void readObjectData(Main *bmain, float time);
 
-       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag);
+       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag, const char **err_str);
 
 private:
        void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
@@ -128,7 +128,7 @@ public:
        bool valid() const;
 
        void readObjectData(Main *bmain, float time);
-       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag);
+       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag, const char **err_str);
 };
 
 void read_subd_sample(ImportSettings *settings,
diff --git a/source/blender/alembic/intern/abc_object.h 
b/source/blender/alembic/intern/abc_object.h
index 7ff927b..d1bcbbe 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -165,10 +165,11 @@ public:
 
        virtual void readObjectData(Main *bmain, float time) = 0;
 
-       virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag)
+       virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float 
time, int read_flag, const char **err_str)
        {
                (void)time;
                (void)read_flag;
+               (void)err_str;
                return dm;
        }
 
diff --git a/source/blender/alembic/intern/abc_points.cc 
b/source/blender/alembic/intern/abc_points.cc
index c16da62..6ddba35 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -156,7 +156,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float 
time)
        Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
 
        DerivedMesh *dm = CDDM_from_mesh(mesh);
-       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0);
+       DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL);
 
        if (ndm != dm) {
                dm->release(dm);
@@ -199,7 +199,7 @@ void read_points_sample(const IPointsSchema &schema,
        read_mverts(config.mvert, positions, vnormals);
 }
 
-DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int /*read_flag*/)
+DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float 
time, int /*read_flag*/, const char **/*err_str*/)
 {
        ISampleSelector sample_sel(time);
        const IPointsSchema::Sample sample = m_schema.getValue(sample_sel);
diff --git a/source/blender/alembic/intern/abc_points.h 
b/source/blender/alembic/intern/abc_points.h
index 54873ee..792283f 100644
--- a/source/blender/alembic/intern/abc_points.h
+++ b/source/blender/alembic/intern/abc_points.h
@@ -61,7 +61,7 @@ public:
 
        void readObjectData(Main *bmain, float time);
 
-       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag);
+       DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int 
read_flag, const char **err_str);
 };
 
 void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
diff --git a/source/blender/alembic/intern/alembic_capi.cc 
b/source/blender/alembic/intern/alembic_capi.cc
index e690a25..d0eb990 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -816,7 +816,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
                        return NULL;
                }
 
-               return abc_reader->read_derivedmesh(dm, time, read_flag);
+               return abc_reader->read_derivedmesh(dm, time, read_flag, 
err_str);
        }
        else if (ISubD::matches(header)) {
                if (ob->type != OB_MESH) {
@@ -824,7 +824,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
                        return NULL;
                }
 
-               return abc_reader->read_derivedmesh(dm, time, read_flag);
+               return abc_reader->read_derivedmesh(dm, time, read_flag, 
err_str);
        }
        else if (IPoints::matches(header)) {
                if (ob->type != OB_MESH) {
@@ -832,7 +832,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
                        return NULL;
                }
 
-               return abc_reader->read_derivedmesh(dm, time, read_flag);
+               return abc_reader->read_derivedmesh(dm, time, read_flag, 
err_str);
        }
        else if (ICurves::matches(header)) {
                if (ob->type != OB_CURVE) {
@@ -840,7 +840,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
                        return NULL;
                }
 
-               return abc_reader->read_derivedmesh(dm, time, read_flag);
+               return abc_reader->read_derivedmesh(dm, time, read_flag, 
err_str);
        }
 
        *err_str = "Unsupported object type: verify object path"; // or poke 
developer

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to