LibOverride: Fix lots of poll functions for Object operators.

Prevent operators that should not perform on override data to be
callable in those cases.
This commit is contained in:
Bastien Montagne 2020-06-30 17:51:41 +02:00
parent 438bd82371
commit 6add0cc88a
Notes: blender-bot 2023-02-14 09:48:23 +01:00
Referenced by commit 473d9507fa, Fix T78536: Crash calling object.modifier_apply on an empty
Referenced by issue #81275, [Bug] Add library overrides and edit mode issue
Referenced by issue #78536, Crash in poll() function of object.modifier_apply
8 changed files with 83 additions and 74 deletions

View File

@ -2210,8 +2210,13 @@ static bool object_convert_poll(bContext *C)
Base *base_act = CTX_data_active_base(C);
Object *obact = base_act ? base_act->object : NULL;
return (!ID_IS_LINKED(scene) && obact && (BKE_object_is_in_editmode(obact) == false) &&
(base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact));
if (obact == NULL || obact->data == NULL || ID_IS_LINKED(obact) ||
ID_IS_OVERRIDE_LIBRARY(obact) || ID_IS_OVERRIDE_LIBRARY(obact->data)) {
return false;
}
return (!ID_IS_LINKED(scene) && (BKE_object_is_in_editmode(obact) == false) &&
(base_act->flag & BASE_SELECTED));
}
/* Helper for object_convert_exec */
@ -3063,15 +3068,16 @@ static bool object_join_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (!ob || ID_IS_LINKED(ob)) {
return 0;
if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL)) {
return ED_operator_screenactive(C);
}
else {
return 0;
return false;
}
}
@ -3136,8 +3142,9 @@ static bool join_shapes_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (!ob || ID_IS_LINKED(ob)) {
return 0;
if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
/* only meshes supported at the moment */
@ -3145,7 +3152,7 @@ static bool join_shapes_poll(bContext *C)
return ED_operator_screenactive(C);
}
else {
return 0;
return false;
}
}

View File

@ -381,7 +381,7 @@ static bool data_transfer_exec_is_object_valid(wmOperator *op,
me->id.tag &= ~LIB_TAG_DOIT;
return true;
}
else if (!ID_IS_LINKED(me)) {
else if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
/* Do not apply transfer operation more than once. */
/* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
BKE_reportf(
@ -446,8 +446,8 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
if (reverse_transfer && ID_IS_LINKED(ob_src->data)) {
/* Do not transfer to linked data, not supported. */
if (reverse_transfer && (ID_IS_LINKED(ob_src->data) || ID_IS_OVERRIDE_LIBRARY(ob_src->data))) {
/* Do not transfer to linked or override data, not supported. */
return OPERATOR_CANCELLED;
}
@ -530,7 +530,7 @@ static bool data_transfer_poll(bContext *C)
{
Object *ob = ED_object_active_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && ob->type == OB_MESH && data);
return (ob != NULL && ob->type == OB_MESH && data != NULL);
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
@ -786,7 +786,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
const bool use_delete = false; /* Never when used from modifier, for now. */
if (!ob_src) {
if (!ob_src || ID_IS_LINKED(ob_dst) || ID_IS_OVERRIDE_LIBRARY(ob_dst)) {
return OPERATOR_CANCELLED;
}

View File

@ -600,7 +600,8 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
{
bool ok = false;
if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob)) {
if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
@ -695,14 +696,10 @@ bool ED_object_editmode_enter(bContext *C, int flag)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob;
/* Active layer checked here for view3d,
* callers that don't want view context can call the extended version. */
ob = CTX_data_active_object(C);
if ((ob == NULL) || ID_IS_LINKED(ob)) {
return false;
}
Object *ob = CTX_data_active_object(C);
return ED_object_editmode_enter_ex(bmain, scene, ob, flag);
}
@ -760,7 +757,8 @@ static bool editmode_toggle_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
/* covers proxies too */
if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) {
if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob) ||
ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return 0;
}
@ -1368,7 +1366,8 @@ static bool shade_poll(bContext *C)
Object *obact = OBACT(view_layer);
if (obact != NULL) {
/* Doesn't handle edit-data, sculpt dynamic-topology, or their undo systems. */
if (obact->mode & (OB_MODE_EDIT | OB_MODE_SCULPT)) {
if (obact->mode & (OB_MODE_EDIT | OB_MODE_SCULPT) || obact->data == NULL ||
ID_IS_OVERRIDE_LIBRARY(obact) || ID_IS_OVERRIDE_LIBRARY(obact->data)) {
return false;
}
}

View File

@ -171,14 +171,15 @@ static bool face_map_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib);
return (ob && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && ob->type == OB_MESH && data &&
!ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
static bool face_map_supported_edit_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib) {
if (face_map_supported_poll(C)) {
if (ob->mode == OB_MODE_EDIT) {
return true;
}

View File

@ -1347,6 +1347,10 @@ static bool modifier_apply_poll(bContext *C)
Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
ModifierData *md = ptr.data; /* May be NULL. */
if (ID_IS_OVERRIDE_LIBRARY(ob) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
return false;
}
if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
return false;
@ -2070,8 +2074,9 @@ static bool skin_poll(bContext *C)
static bool skin_edit_poll(bContext *C)
{
return (CTX_data_edit_object(C) &&
edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true));
Object *ob = CTX_data_edit_object(C);
return (ob != NULL && edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true) &&
!ID_IS_OVERRIDE_LIBRARY(ob) && !ID_IS_OVERRIDE_LIBRARY(ob->data));
}
static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)

View File

@ -100,7 +100,12 @@ static bool object_remesh_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (ob == NULL) {
if (ob == NULL || ob->data == NULL) {
return false;
}
if (ID_IS_LINKED(ob) || ID_IS_LINKED(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
CTX_wm_operator_poll_msg_set(C, "The remesher cannot worked on linked or override data");
return false;
}

View File

@ -216,40 +216,38 @@ static bool object_shape_key_mirror(
/********************** shape key operators *********************/
static bool shape_key_mode_poll(bContext *C)
static bool shape_key_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT);
return (ob != NULL && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && data != NULL &&
!ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
static bool shape_key_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
return (shape_key_poll(C) && ob->mode != OB_MODE_EDIT);
}
static bool shape_key_mode_exists_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
/* same as shape_key_mode_poll */
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) &&
/* check a keyblock exists */
(BKE_keyblock_from_object(ob) != NULL);
return (shape_key_mode_poll(C) &&
/* check a keyblock exists */
(BKE_keyblock_from_object(ob) != NULL));
}
static bool shape_key_move_poll(bContext *C)
{
/* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
Key *key = BKE_key_from_object(ob);
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT &&
key && key->totkey > 1);
}
static bool shape_key_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data));
return (shape_key_mode_poll(C) && key != NULL && key->totkey > 1);
}
static int shape_key_add_exec(bContext *C, wmOperator *op)

View File

@ -2659,46 +2659,43 @@ static void vgroup_assign_verts(Object *ob, const float weight)
/** \name Shared Operator Poll Functions
* \{ */
static bool vertex_group_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) &&
OB_TYPE_SUPPORT_VGROUP(ob->type) && ob->defbase.first);
}
static bool vertex_group_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) && data &&
!ID_IS_LINKED(data));
return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) &&
!ID_IS_OVERRIDE_LIBRARY(ob) && data && !ID_IS_LINKED(data) &&
!ID_IS_OVERRIDE_LIBRARY(data));
}
static bool vertex_group_poll(bContext *C)
{
Object *ob = ED_object_context(C);
return (vertex_group_supported_poll(C) && ob->defbase.first);
}
static bool vertex_group_mesh_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->type == OB_MESH &&
ob->defbase.first);
return (vertex_group_poll(C) && ob->type == OB_MESH);
}
static bool UNUSED_FUNCTION(vertex_group_mesh_supported_poll)(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && ob->type == OB_MESH && data && !ID_IS_LINKED(data));
return (vertex_group_supported_poll(C) && ob->type == OB_MESH);
}
static bool UNUSED_FUNCTION(vertex_group_poll_edit)(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
return 0;
if (!vertex_group_supported_poll(C)) {
return false;
}
return BKE_object_is_in_editmode_vgroup(ob);
@ -2710,9 +2707,8 @@ static bool vertex_group_vert_poll_ex(bContext *C,
const short ob_type_flag)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
if (!vertex_group_supported_poll(C)) {
return false;
}
@ -2770,14 +2766,13 @@ static bool vertex_group_mesh_vert_select_poll(bContext *C)
static bool vertex_group_vert_select_unlocked_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
return 0;
if (!vertex_group_supported_poll(C)) {
return false;
}
if (!(BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob))) {
return 0;
return false;
}
if (ob->actdef != 0) {
@ -2786,21 +2781,20 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
return !(dg->flag & DG_LOCK_WEIGHT);
}
}
return 1;
return true;
}
static bool vertex_group_vert_select_mesh_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
return 0;
if (!vertex_group_supported_poll(C)) {
return false;
}
/* only difference to #vertex_group_vert_select_poll */
if (ob->type != OB_MESH) {
return 0;
return false;
}
return (BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob));