Fix #141887: Crash/assert hit after reading Grease Pencil
Since 5.0 (subversion 33) `CurvesGeometry` data is read from and written
to the new attribute storage. See 68759af516.
For backwards compatibility, the `CustomData curve_data`
became `curve_data_legacy` and was only read and then converted in
the versioning code to the attribute storage format.
But since `CurvesGeometry::blend_read` is still reading
`curve_data_legacy`, we need to ensure that this data is valid.
When e.g. duplicating `CurvesGeometry`, the `curve_data_legacy` was left
uninitialized, so in an invalid state. Then the writing code would write
the embedded `CustomData` struct and the reading code would fail.
This could in theory also happen for other IDs that store legacy
custom data.
To ensure that the data is valid when reading, we do the following:
1) After the conversion code ran, we reset the legacy data. This makes
sure that we don't keep the legacy data around at runtime and
potentially when writing the embedded struct.
2) Before writing, we also reset the legacy data. This makes sure that
in case there is some garbage data in the unused struct (e.g. from
copying the ID), we don't write the garbage to file.
Pull Request: https://projects.blender.org/blender/blender/pulls/142327
This commit is contained in:
@@ -276,6 +276,7 @@ void curves_convert_customdata_to_storage(CurvesGeometry &curves)
|
||||
{{AttrDomain::Point, {curves.point_data, curves.points_num()}},
|
||||
{AttrDomain::Curve, {curves.curve_data_legacy, curves.curves_num()}}},
|
||||
curves.attribute_storage.wrap());
|
||||
CustomData_reset(&curves.curve_data_legacy);
|
||||
/* Update the curve type count again (the first time was done on file-read, where
|
||||
* #AttributeStorage data doesn't exist yet for older files). */
|
||||
curves.update_curve_types();
|
||||
@@ -286,6 +287,7 @@ void pointcloud_convert_customdata_to_storage(PointCloud &pointcloud)
|
||||
attribute_legacy_convert_customdata_to_storage(
|
||||
{{AttrDomain::Point, {pointcloud.pdata_legacy, pointcloud.totpoint}}},
|
||||
pointcloud.attribute_storage.wrap());
|
||||
CustomData_reset(&pointcloud.pdata_legacy);
|
||||
}
|
||||
|
||||
void grease_pencil_convert_customdata_to_storage(GreasePencil &grease_pencil)
|
||||
@@ -294,6 +296,7 @@ void grease_pencil_convert_customdata_to_storage(GreasePencil &grease_pencil)
|
||||
{{AttrDomain::Layer,
|
||||
{grease_pencil.layers_data_legacy, int(grease_pencil.layers().size())}}},
|
||||
grease_pencil.attribute_storage.wrap());
|
||||
CustomData_reset(&grease_pencil.layers_data_legacy);
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
@@ -1916,6 +1916,7 @@ CurvesGeometry::BlendWriteData::BlendWriteData(ResourceScope &scope)
|
||||
|
||||
void CurvesGeometry::blend_write_prepare(CurvesGeometry::BlendWriteData &write_data)
|
||||
{
|
||||
CustomData_reset(&this->curve_data_legacy);
|
||||
attribute_storage_blend_write_prepare(this->attribute_storage.wrap(), write_data.attribute_data);
|
||||
CustomData_blend_write_prepare(this->point_data,
|
||||
AttrDomain::Point,
|
||||
|
||||
@@ -288,6 +288,8 @@ static void grease_pencil_blend_write(BlendWriter *writer, ID *id, const void *i
|
||||
grease_pencil->attribute_storage.dna_attributes = attribute_data.attributes.data();
|
||||
grease_pencil->attribute_storage.dna_attributes_num = attribute_data.attributes.size();
|
||||
|
||||
CustomData_reset(&grease_pencil->layers_data_legacy);
|
||||
|
||||
/* Write LibData */
|
||||
BLO_write_id_struct(writer, GreasePencil, id_address, &grease_pencil->id);
|
||||
BKE_id_blend_write(writer, &grease_pencil->id);
|
||||
|
||||
@@ -121,7 +121,7 @@ static void pointcloud_blend_write(BlendWriter *writer, ID *id, const void *id_a
|
||||
ResourceScope scope;
|
||||
bke::AttributeStorage::BlendWriteData attribute_data{scope};
|
||||
attribute_storage_blend_write_prepare(pointcloud->attribute_storage.wrap(), attribute_data);
|
||||
BLI_assert(pointcloud->pdata_legacy.totlayer == 0);
|
||||
|
||||
if (attribute_data.attributes.is_empty()) {
|
||||
pointcloud->attribute_storage.dna_attributes = nullptr;
|
||||
pointcloud->attribute_storage.dna_attributes_num = 0;
|
||||
@@ -131,6 +131,8 @@ static void pointcloud_blend_write(BlendWriter *writer, ID *id, const void *id_a
|
||||
pointcloud->attribute_storage.dna_attributes_num = attribute_data.attributes.size();
|
||||
}
|
||||
|
||||
CustomData_reset(&pointcloud->pdata_legacy);
|
||||
|
||||
/* Write LibData */
|
||||
BLO_write_id_struct(writer, PointCloud, id_address, &pointcloud->id);
|
||||
BKE_id_blend_write(writer, &pointcloud->id);
|
||||
|
||||
Reference in New Issue
Block a user