From ac88a3942e49f73f6ccf050f7275b9fb34888743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 15 Aug 2017 12:34:40 +0200 Subject: Alembic import: fix crash when face color index is out of bounds. This can happen with Alembic files exported from Maya. I'm unsure as to the root cause, but at least this fixes the crash itself. Thanks to @looch for reporting this with a test file. The test file has to remain confidential, though, so it's on my workstation only. --- source/blender/alembic/intern/abc_customdata.cc | 33 ++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'source/blender/alembic') diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc index 1d2bc689027..3380aaf222e 100644 --- a/source/blender/alembic/intern/abc_customdata.cc +++ b/source/blender/alembic/intern/abc_customdata.cc @@ -252,6 +252,26 @@ static void read_uvs(const CDStreamConfig &config, void *data, } } +static size_t mcols_out_of_bounds_check( + const size_t color_index, + const size_t array_size, + const PropertyHeader &prop_header, + bool &r_bounds_warning_given) +{ + if (color_index < array_size) { + return color_index; + } + + if (!r_bounds_warning_given) { + std::cerr << "Alembic import: color index out of bounds " + "reading face colors for property " + << prop_header.getName() << std::endl; + r_bounds_warning_given = true; + } + + return 0; +} + static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, const PropertyHeader &prop_header, const CDStreamConfig &config, @@ -303,6 +323,8 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, size_t face_index = 0; size_t color_index; + bool bounds_warning_given = false; + for (int i = 0; i < config.totpoly; ++i) { MPoly *poly = &mpolys[i]; MCol *cface = &cfaces[poly->loopstart + poly->totloop]; @@ -311,9 +333,13 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, for (int j = 0; j < poly->totloop; ++j, ++face_index) { --cface; --mloop; - color_index = is_facevarying ? face_index : mloop->v; if (use_c3f_ptr) { + color_index = mcols_out_of_bounds_check( + is_facevarying ? face_index : mloop->v, + c3f_ptr->size(), + prop_header, bounds_warning_given); + const Imath::C3f &color = (*c3f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); cface->r = FTOCHAR(color[1]); @@ -321,6 +347,11 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, cface->b = 255; } else { + color_index = mcols_out_of_bounds_check( + is_facevarying ? face_index : mloop->v, + c4f_ptr->size(), + prop_header, bounds_warning_given); + const Imath::C4f &color = (*c4f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); cface->r = FTOCHAR(color[1]); -- cgit v1.2.3 From f20d7bed1426ca3d1268182835f04e7ab8212cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 15 Aug 2017 12:43:17 +0200 Subject: Alembic import: report object name in face color index out of bounds error --- source/blender/alembic/intern/abc_customdata.cc | 23 ++++++++++++++++------- source/blender/alembic/intern/abc_customdata.h | 3 ++- source/blender/alembic/intern/abc_mesh.cc | 18 ++++++++++++------ 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'source/blender/alembic') diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc index 3380aaf222e..d6e7a80d174 100644 --- a/source/blender/alembic/intern/abc_customdata.cc +++ b/source/blender/alembic/intern/abc_customdata.cc @@ -255,6 +255,7 @@ static void read_uvs(const CDStreamConfig &config, void *data, static size_t mcols_out_of_bounds_check( const size_t color_index, const size_t array_size, + const std::string & iobject_full_name, const PropertyHeader &prop_header, bool &r_bounds_warning_given) { @@ -263,8 +264,10 @@ static size_t mcols_out_of_bounds_check( } if (!r_bounds_warning_given) { - std::cerr << "Alembic import: color index out of bounds " - "reading face colors for property " + std::cerr << "Alembic: color index out of bounds " + "reading face colors for object " + << iobject_full_name + << ", property " << prop_header.getName() << std::endl; r_bounds_warning_given = true; } @@ -272,7 +275,8 @@ static size_t mcols_out_of_bounds_check( return 0; } -static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, +static void read_custom_data_mcols(const std::string & iobject_full_name, + const ICompoundProperty &arbGeomParams, const PropertyHeader &prop_header, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss) @@ -338,7 +342,8 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, color_index = mcols_out_of_bounds_check( is_facevarying ? face_index : mloop->v, c3f_ptr->size(), - prop_header, bounds_warning_given); + iobject_full_name, prop_header, + bounds_warning_given); const Imath::C3f &color = (*c3f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); @@ -350,7 +355,8 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, color_index = mcols_out_of_bounds_check( is_facevarying ? face_index : mloop->v, c4f_ptr->size(), - prop_header, bounds_warning_given); + iobject_full_name, prop_header, + bounds_warning_given); const Imath::C4f &color = (*c4f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); @@ -387,7 +393,10 @@ static void read_custom_data_uvs(const ICompoundProperty &prop, read_uvs(config, cd_data, sample.getVals(), sample.getIndices()); } -void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss) +void read_custom_data(const std::string & iobject_full_name, + const ICompoundProperty &prop, + const CDStreamConfig &config, + const Alembic::Abc::ISampleSelector &iss) { if (!prop.valid()) { return; @@ -417,7 +426,7 @@ void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &confi continue; } - read_custom_data_mcols(prop, prop_header, config, iss); + read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss); continue; } } diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h index 9e671fde386..b3072a2c9f7 100644 --- a/source/blender/alembic/intern/abc_customdata.h +++ b/source/blender/alembic/intern/abc_customdata.h @@ -96,7 +96,8 @@ void write_custom_data(const OCompoundProperty &prop, CustomData *data, int data_type); -void read_custom_data(const ICompoundProperty &prop, +void read_custom_data(const std::string & iobject_full_name, + const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss); diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 456d16b3e0d..6545ced8e4a 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -943,7 +943,8 @@ static void get_weight_and_index(CDStreamConfig &config, config.ceil_index = i1; } -static void read_mesh_sample(ImportSettings *settings, +static void read_mesh_sample(const std::string & iobject_full_name, + ImportSettings *settings, const IPolyMeshSchema &schema, const ISampleSelector &selector, CDStreamConfig &config, @@ -981,7 +982,8 @@ static void read_mesh_sample(ImportSettings *settings, } if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { - read_custom_data(schema.getArbGeomParams(), config, selector); + read_custom_data(iobject_full_name, + schema.getArbGeomParams(), config, selector); } } @@ -1110,7 +1112,8 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, config.time = sample_sel.getRequestedTime(); bool do_normals = false; - read_mesh_sample(&settings, m_schema, sample_sel, config, do_normals); + read_mesh_sample(m_iobject.getFullName(), + &settings, m_schema, sample_sel, config, do_normals); if (new_dm) { /* Check if we had ME_SMOOTH flag set to restore it. */ @@ -1217,7 +1220,8 @@ ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2) return NULL; } -static void read_subd_sample(ImportSettings *settings, +static void read_subd_sample(const std::string & iobject_full_name, + ImportSettings *settings, const ISubDSchema &schema, const ISampleSelector &selector, CDStreamConfig &config) @@ -1252,7 +1256,8 @@ static void read_subd_sample(ImportSettings *settings, } if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { - read_custom_data(schema.getArbGeomParams(), config, selector); + read_custom_data(iobject_full_name, + schema.getArbGeomParams(), config, selector); } } @@ -1382,7 +1387,8 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, /* Only read point data when streaming meshes, unless we need to create new ones. */ CDStreamConfig config = get_config(new_dm ? new_dm : dm); config.time = sample_sel.getRequestedTime(); - read_subd_sample(&settings, m_schema, sample_sel, config); + read_subd_sample(m_iobject.getFullName(), + &settings, m_schema, sample_sel, config); if (new_dm) { /* Check if we had ME_SMOOTH flag set to restore it. */ -- cgit v1.2.3