Fix T87912: use session id instead of name to identify dropped object

The old code did not work when there were multiple ids with
the same name (which can happen when ids are linked in).
The solution is to use the session ids instead. Those are different
even when two ids have the same name.

Differential Revision: https://developer.blender.org/D11116
This commit is contained in:
Jacques Lucke 2021-11-19 15:28:44 +01:00
parent a20e703d1a
commit 04ec36f677
Notes: blender-bot 2023-02-14 11:21:43 +01:00
Referenced by issue #87912, Dragging objects/collections into geometry nodes references the wrong datablock for duplicate names
4 changed files with 94 additions and 33 deletions

View File

@ -1657,12 +1657,25 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name");
PropertyRNA *prop_location = RNA_struct_find_property(op->ptr, "location");
PropertyRNA *prop_session_uuid = RNA_struct_find_property(op->ptr, "session_uuid");
bool update_location_if_necessary = false;
if (RNA_property_is_set(op->ptr, prop_name)) {
char name[MAX_ID_NAME - 2];
RNA_property_string_get(op->ptr, prop_name, name);
collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
update_location_if_necessary = true;
}
else if (RNA_property_is_set(op->ptr, prop_session_uuid)) {
const uint32_t session_uuid = (uint32_t)RNA_property_int_get(op->ptr, prop_session_uuid);
collection = (Collection *)BKE_libblock_find_session_uuid(bmain, ID_GR, session_uuid);
update_location_if_necessary = true;
}
else {
collection = BLI_findlink(&bmain->collections, RNA_enum_get(op->ptr, "collection"));
}
if (update_location_if_necessary) {
int mval[2];
if (!RNA_property_is_set(op->ptr, prop_location) && object_add_drop_xy_get(C, op, &mval)) {
ED_object_location_from_view(C, loc);
@ -1670,9 +1683,6 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
RNA_property_float_set_array(op->ptr, prop_location, loc);
}
}
else {
collection = BLI_findlink(&bmain->collections, RNA_enum_get(op->ptr, "collection"));
}
if (collection == NULL) {
return OPERATOR_CANCELLED;
@ -1707,7 +1717,8 @@ static int object_instance_add_invoke(bContext *C, wmOperator *op, const wmEvent
RNA_int_set(op->ptr, "drop_y", event->xy[1]);
}
if (!RNA_struct_property_is_set(op->ptr, "name")) {
if (!RNA_struct_property_is_set(op->ptr, "name") &&
!RNA_struct_property_is_set(op->ptr, "session_uuid")) {
return WM_enum_search_invoke(C, op, event);
}
return op->type->exec(C, op);
@ -1740,6 +1751,16 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
ot->prop = prop;
ED_object_add_generic_props(ot, false);
RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the collection to add",
INT32_MIN,
INT32_MAX);
object_add_drop_xy_props(ot);
}

View File

@ -445,15 +445,14 @@ void NODE_OT_add_group(wmOperatorType *ot)
static Object *node_add_object_get_and_poll_object_node_tree(Main *bmain, wmOperator *op)
{
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
Object *object = (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
if (!object) {
return nullptr;
if (RNA_struct_property_is_set(op->ptr, "session_uuid")) {
const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
return (Object *)BKE_libblock_find_session_uuid(bmain, ID_OB, session_uuid);
}
return object;
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
return (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
}
static int node_add_object_exec(bContext *C, wmOperator *op)
@ -539,6 +538,15 @@ void NODE_OT_add_object(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
RNA_def_string(ot->srna, "name", "Object", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the data-block to assign",
INT32_MIN,
INT32_MAX);
}
/** \} */
@ -549,15 +557,14 @@ void NODE_OT_add_object(wmOperatorType *ot)
static Tex *node_add_texture_get_and_poll_texture_node_tree(Main *bmain, wmOperator *op)
{
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
Tex *texture = (Tex *)BKE_libblock_find_name(bmain, ID_TE, name);
if (!texture) {
return nullptr;
if (RNA_struct_property_is_set(op->ptr, "session_uuid")) {
const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
return (Tex *)BKE_libblock_find_session_uuid(bmain, ID_TE, session_uuid);
}
return texture;
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
return (Tex *)BKE_libblock_find_name(bmain, ID_TE, name);
}
static int node_add_texture_exec(bContext *C, wmOperator *op)
@ -640,6 +647,15 @@ void NODE_OT_add_texture(wmOperatorType *ot)
RNA_def_string(
ot->srna, "name", "Texture", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the data-block to assign",
INT32_MIN,
INT32_MAX);
}
/** \} */
@ -651,15 +667,14 @@ void NODE_OT_add_texture(wmOperatorType *ot)
static Collection *node_add_collection_get_and_poll_collection_node_tree(Main *bmain,
wmOperator *op)
{
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
Collection *collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
if (!collection) {
return nullptr;
if (RNA_struct_property_is_set(op->ptr, "session_uuid")) {
const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
return (Collection *)BKE_libblock_find_session_uuid(bmain, ID_GR, session_uuid);
}
return collection;
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
return (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
}
static int node_add_collection_exec(bContext *C, wmOperator *op)
@ -746,6 +761,15 @@ void NODE_OT_add_collection(wmOperatorType *ot)
RNA_def_string(
ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the data-block to assign",
INT32_MIN,
INT32_MAX);
}
/** \} */
@ -877,6 +901,18 @@ void NODE_OT_add_file(wmOperatorType *ot)
/** \name Add Mask Node Operator
* \{ */
static ID *node_add_mask_get_and_poll_mask(Main *bmain, wmOperator *op)
{
if (RNA_struct_property_is_set(op->ptr, "session_uuid")) {
const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
return BKE_libblock_find_session_uuid(bmain, ID_MSK, session_uuid);
}
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
return BKE_libblock_find_name(bmain, ID_MSK, name);
}
static bool node_add_mask_poll(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
@ -889,14 +925,9 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
ID *mask = nullptr;
/* check input variables */
char name[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "name", name);
mask = BKE_libblock_find_name(bmain, ID_MSK, name);
ID *mask = node_add_mask_get_and_poll_mask(bmain, op);
if (!mask) {
BKE_reportf(op->reports, RPT_ERROR, "Mask '%s' not found", name);
return OPERATOR_CANCELLED;
}
@ -935,6 +966,15 @@ void NODE_OT_add_mask(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
RNA_def_string(ot->srna, "name", "Mask", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the data-block to assign",
INT32_MIN,
INT32_MAX);
}
/** \} */

View File

@ -692,7 +692,7 @@ static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)

View File

@ -784,7 +784,7 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_GR);
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
}
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)