Undo: support implicit-sharing in memfile undo step #106903
|
@ -5150,48 +5150,52 @@ void CustomData_blend_write(BlendWriter *writer,
|
|||
writer, CustomDataLayer, data->totlayer, data->layers, layers_to_write.data());
|
||||
|
||||
for (const CustomDataLayer &layer : layers_to_write) {
|
||||
switch (layer.type) {
|
||||
case CD_MDEFORMVERT:
|
||||
BKE_defvert_blend_write(writer, count, static_cast<const MDeformVert *>(layer.data));
|
||||
break;
|
||||
case CD_MDISPS:
|
||||
write_mdisps(
|
||||
writer, count, static_cast<const MDisps *>(layer.data), layer.flag & CD_FLAG_EXTERNAL);
|
||||
break;
|
||||
case CD_PAINT_MASK:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_SCULPT_FACE_SETS:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_GRID_PAINT_MASK:
|
||||
write_grid_paint_mask(writer, count, static_cast<const GridPaintMask *>(layer.data));
|
||||
break;
|
||||
case CD_FACEMAP:
|
||||
BLO_write_raw(writer, sizeof(int) * count, static_cast<const int *>(layer.data));
|
||||
break;
|
||||
case CD_PROP_BOOL:
|
||||
BLO_write_raw(writer, sizeof(bool) * count, static_cast<const bool *>(layer.data));
|
||||
break;
|
||||
case CD_CREASE:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
default: {
|
||||
const char *structname;
|
||||
int structnum;
|
||||
CustomData_file_write_info(eCustomDataType(layer.type), &structname, &structnum);
|
||||
if (structnum) {
|
||||
int datasize = structnum * count;
|
||||
BLO_write_struct_array_by_name(writer, structname, datasize, layer.data);
|
||||
}
|
||||
else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */
|
||||
printf("%s error: layer '%s':%d - can't be written to file\n",
|
||||
__func__,
|
||||
structname,
|
||||
layer.type);
|
||||
BLO_write_shared(writer, layer.data, layer.sharing_info, [&]() {
|
||||
switch (layer.type) {
|
||||
case CD_MDEFORMVERT:
|
||||
BKE_defvert_blend_write(writer, count, static_cast<const MDeformVert *>(layer.data));
|
||||
break;
|
||||
JacquesLucke marked this conversation as resolved
Outdated
|
||||
case CD_MDISPS:
|
||||
write_mdisps(writer,
|
||||
count,
|
||||
static_cast<const MDisps *>(layer.data),
|
||||
layer.flag & CD_FLAG_EXTERNAL);
|
||||
break;
|
||||
case CD_PAINT_MASK:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_SCULPT_FACE_SETS:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_GRID_PAINT_MASK:
|
||||
write_grid_paint_mask(writer, count, static_cast<const GridPaintMask *>(layer.data));
|
||||
break;
|
||||
case CD_FACEMAP:
|
||||
BLO_write_raw(writer, sizeof(int) * count, static_cast<const int *>(layer.data));
|
||||
break;
|
||||
case CD_PROP_BOOL:
|
||||
BLO_write_raw(writer, sizeof(bool) * count, static_cast<const bool *>(layer.data));
|
||||
break;
|
||||
case CD_CREASE:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
default: {
|
||||
const char *structname;
|
||||
int structnum;
|
||||
CustomData_file_write_info(eCustomDataType(layer.type), &structname, &structnum);
|
||||
if (structnum) {
|
||||
int datasize = structnum * count;
|
||||
BLO_write_struct_array_by_name(writer, structname, datasize, layer.data);
|
||||
}
|
||||
else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */
|
||||
printf("%s error: layer '%s':%d - can't be written to file\n",
|
||||
__func__,
|
||||
structname,
|
||||
layer.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (data->external) {
|
||||
|
@ -5267,31 +5271,34 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
|
|||
layer->sharing_info = nullptr;
|
||||
|
||||
if (CustomData_verify_versions(data, i)) {
|
||||
BLO_read_data_address(reader, &layer->data);
|
||||
if (layer->data != nullptr) {
|
||||
layer->sharing_info = BLO_read_shared(reader, &layer->data, [&]() {
|
||||
BLO_read_data_address(reader, &layer->data);
|
||||
if (CustomData_layer_ensure_data_exists(layer, count)) {
|
||||
/* Under normal operations, this shouldn't happen, but...
|
||||
* For a CD_PROP_BOOL example, see #84935.
|
||||
* For a CD_MLOOPUV example, see #90620. */
|
||||
CLOG_WARN(
|
||||
&LOG,
|
||||
"Allocated custom data layer that was not saved correctly for layer->type = %d.",
|
||||
layer->type);
|
||||
}
|
||||
|
||||
if (layer->type == CD_MDISPS) {
|
||||
blend_read_mdisps(
|
||||
reader, count, static_cast<MDisps *>(layer->data), layer->flag & CD_FLAG_EXTERNAL);
|
||||
}
|
||||
else if (layer->type == CD_GRID_PAINT_MASK) {
|
||||
blend_read_paint_mask(reader, count, static_cast<GridPaintMask *>(layer->data));
|
||||
}
|
||||
else if (layer->type == CD_MDEFORMVERT) {
|
||||
BKE_defvert_blend_read(reader, count, static_cast<MDeformVert *>(layer->data));
|
||||
}
|
||||
});
|
||||
if (layer->data != nullptr && layer->sharing_info == nullptr) {
|
||||
/* Make layer data shareable. */
|
||||
layer->sharing_info = make_implicit_sharing_info_for_layer(
|
||||
eCustomDataType(layer->type), layer->data, count);
|
||||
}
|
||||
if (CustomData_layer_ensure_data_exists(layer, count)) {
|
||||
/* Under normal operations, this shouldn't happen, but...
|
||||
* For a CD_PROP_BOOL example, see #84935.
|
||||
* For a CD_MLOOPUV example, see #90620. */
|
||||
CLOG_WARN(&LOG,
|
||||
"Allocated custom data layer that was not saved correctly for layer->type = %d.",
|
||||
layer->type);
|
||||
}
|
||||
|
||||
if (layer->type == CD_MDISPS) {
|
||||
blend_read_mdisps(
|
||||
reader, count, static_cast<MDisps *>(layer->data), layer->flag & CD_FLAG_EXTERNAL);
|
||||
}
|
||||
else if (layer->type == CD_GRID_PAINT_MASK) {
|
||||
blend_read_paint_mask(reader, count, static_cast<GridPaintMask *>(layer->data));
|
||||
}
|
||||
else if (layer->type == CD_MDEFORMVERT) {
|
||||
BKE_defvert_blend_read(reader, count, static_cast<MDeformVert *>(layer->data));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
|
||||
#include "DNA_windowmanager_types.h" /* for eReportType */
|
||||
|
||||
#include "BLI_implicit_sharing.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include "BLI_function_ref.hh"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -175,6 +181,13 @@ void BLO_write_string(BlendWriter *writer, const char *data_ptr);
|
|||
|
||||
/* Misc. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
void BLO_write_shared(BlendWriter *writer,
|
||||
const void *data,
|
||||
const ImplicitSharingInfoHandle *sharing_info,
|
||||
blender::FunctionRef<void()> write_cb);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Sometimes different data is written depending on whether the file is saved to disk or used for
|
||||
* undo. This function returns true when the current file-writing is done for undo.
|
||||
|
@ -238,6 +251,12 @@ void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p);
|
|||
|
||||
/* Misc. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
const ImplicitSharingInfoHandle *BLO_read_shared(BlendDataReader *reader,
|
||||
void **data_ptr,
|
||||
blender::FunctionRef<void()> read_cb);
|
||||
#endif
|
||||
|
||||
int BLO_read_fileversion_get(BlendDataReader *reader);
|
||||
bool BLO_read_requires_endian_switch(BlendDataReader *reader);
|
||||
bool BLO_read_data_is_undo(BlendDataReader *reader);
|
||||
|
|
|
@ -5150,6 +5150,15 @@ void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
|
|||
*ptr_p = final_array;
|
||||
}
|
||||
|
||||
const ImplicitSharingInfoHandle *BLO_read_shared(BlendDataReader *reader,
|
||||
void **data_ptr,
|
||||
blender::FunctionRef<void()> read_cb)
|
||||
{
|
||||
UNUSED_VARS(reader, data_ptr);
|
||||
read_cb();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BLO_read_data_is_undo(BlendDataReader *reader)
|
||||
{
|
||||
return (reader->fd->flags & FD_FLAGS_IS_MEMFILE);
|
||||
|
|
|
@ -1692,6 +1692,15 @@ void BLO_write_string(BlendWriter *writer, const char *data_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
void BLO_write_shared(BlendWriter *writer,
|
||||
const void *data,
|
||||
const ImplicitSharingInfoHandle *sharing_info,
|
||||
blender::FunctionRef<void()> write_cb)
|
||||
{
|
||||
UNUSED_VARS(writer, data, sharing_info);
|
||||
write_cb();
|
||||
}
|
||||
|
||||
bool BLO_write_is_undo(BlendWriter *writer)
|
||||
{
|
||||
return writer->wd->use_memfile;
|
||||
|
|
Loading…
Reference in New Issue
I would rather not have such long callbacks as lambda, makes it very difficult to decipher the code imho.
Same for the reader below.