Merge branch 'blender-v2.82-release'

This commit is contained in:
Campbell Barton 2020-02-04 19:02:08 +11:00
commit 84e71195c9
7 changed files with 120 additions and 15 deletions

View File

@ -108,7 +108,8 @@ static void undoarm_free_data(UndoArmature *uarm)
static Object *editarm_object_from_context(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit && obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
if (arm->edbo != NULL) {
@ -151,8 +152,7 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain,
* outside of this list will be moved out of edit-mode when reading back undo steps. */
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, NULL, &objects_len);
Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;

View File

@ -216,8 +216,7 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
* outside of this list will be moved out of edit-mode when reading back undo steps. */
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, NULL, &objects_len);
Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;

View File

@ -23,6 +23,7 @@
#include "BLI_compiler_attrs.h"
struct Base;
struct CLG_LogRef;
struct Object;
struct UndoStack;
@ -62,6 +63,10 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
uint object_array_len,
uint object_array_stride);
struct Object **ED_undo_editmode_objects_from_view_layer(struct ViewLayer *view_layer,
uint *r_len);
struct Base **ED_undo_editmode_bases_from_view_layer(struct ViewLayer *view_layer, uint *r_len);
struct UndoStack *ED_undo_stack_get(void);
/* helpers */

View File

@ -146,7 +146,8 @@ static int validate_undoLatt(void *data, void *edata)
static Object *editlatt_object_from_context(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit && obedit->type == OB_LATTICE) {
Lattice *lt = obedit->data;
if (lt->editlatt != NULL) {
@ -189,8 +190,7 @@ static bool lattice_undosys_step_encode(struct bContext *C, Main *bmain, UndoSte
* outside of this list will be moved out of edit-mode when reading back undo steps. */
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, NULL, &objects_len);
Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;

View File

@ -672,7 +672,8 @@ static void undomesh_free_data(UndoMesh *um)
static Object *editmesh_object_from_context(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit && obedit->type == OB_MESH) {
Mesh *me = obedit->data;
if (me->edit_mesh != NULL) {
@ -715,8 +716,7 @@ static bool mesh_undosys_step_encode(struct bContext *C, struct Main *bmain, Und
* outside of this list will be moved out of edit-mode when reading back undo steps. */
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, NULL, &objects_len);
Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;

View File

@ -120,7 +120,8 @@ static void undomball_free_data(UndoMBall *umb)
static Object *editmball_object_from_context(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit && obedit->type == OB_MBALL) {
MetaBall *mb = obedit->data;
if (mb->editelems != NULL) {
@ -162,8 +163,7 @@ static bool mball_undosys_step_encode(struct bContext *C, struct Main *bmain, Un
* outside of this list will be moved out of edit-mode when reading back undo steps. */
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
view_layer, NULL, &objects_len);
Object **objects = ED_undo_editmode_objects_from_view_layer(view_layer, &objects_len);
us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
us->elems_len = objects_len;

View File

@ -774,7 +774,7 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
uint bases_len = 0;
/* Don't request unique data because we want to de-select objects when exiting edit-mode
* for that to be done on all objects we can't skip ones that share data. */
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
Base **bases = ED_undo_editmode_bases_from_view_layer(view_layer, &bases_len);
for (uint i = 0; i < bases_len; i++) {
((ID *)bases[i]->object->data)->tag |= LIB_TAG_DOIT;
}
@ -798,3 +798,104 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C,
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Undo View Layer Helper Functions
*
* Needed because view layer functions such as
* #BKE_view_layer_array_from_objects_in_edit_mode_unique_data also check visibility,
* which is not reliable when it comes to object undo operations,
* since hidden objects can be operated on in the properties editor,
* and local collections may be used.
* \{ */
static int undo_editmode_objects_from_view_layer_prepare(ViewLayer *view_layer,
Object *obact,
int *r_active_index)
{
const short object_type = obact->type;
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
ID *id = ob->data;
id->tag &= ~LIB_TAG_DOIT;
}
}
int len = 0;
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
if (ob == obact) {
*r_active_index = len;
}
ID *id = ob->data;
if ((id->tag & LIB_TAG_DOIT) == 0) {
len += 1;
id->tag |= LIB_TAG_DOIT;
}
}
}
return len;
}
Object **ED_undo_editmode_objects_from_view_layer(ViewLayer *view_layer, uint *r_len)
{
Object *obact = OBACT(view_layer);
if ((obact == NULL) || (obact->mode & OB_MODE_EDIT) == 0) {
return MEM_mallocN(0, __func__);
}
int active_index = 0;
const int len = undo_editmode_objects_from_view_layer_prepare(view_layer, obact, &active_index);
const short object_type = obact->type;
int i = 0;
Object **objects = MEM_malloc_arrayN(len, sizeof(*objects), __func__);
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
ID *id = ob->data;
if (id->tag & LIB_TAG_DOIT) {
objects[i++] = ob;
id->tag &= ~LIB_TAG_DOIT;
}
}
}
BLI_assert(i == len);
if (active_index > 0) {
SWAP(Object *, objects[0], objects[active_index]);
}
*r_len = len;
return objects;
}
Base **ED_undo_editmode_bases_from_view_layer(ViewLayer *view_layer, uint *r_len)
{
Object *obact = OBACT(view_layer);
if ((obact == NULL) || (obact->mode & OB_MODE_EDIT) == 0) {
return MEM_mallocN(0, __func__);
}
int active_index = 0;
const int len = undo_editmode_objects_from_view_layer_prepare(view_layer, obact, &active_index);
const short object_type = obact->type;
int i = 0;
Base **base_array = MEM_malloc_arrayN(len, sizeof(*base_array), __func__);
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
Object *ob = base->object;
if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) {
ID *id = ob->data;
if (id->tag & LIB_TAG_DOIT) {
base_array[i++] = base;
id->tag &= ~LIB_TAG_DOIT;
}
}
}
BLI_assert(i == len);
if (active_index > 0) {
SWAP(Base *, base_array[0], base_array[active_index]);
}
*r_len = len;
return base_array;
}
/** \} */