[Bf-blender-cvs] [02c5ca2f226] blender-v3.2-release: Fix possible issues when mixing link & append for asset drag & drop

Julian Eisel noreply at git.blender.org
Mon May 23 21:00:11 CEST 2022


Commit: 02c5ca2f2269b44cc56438847c55b8139a1c8dd2
Author: Julian Eisel
Date:   Mon May 23 20:00:33 2022 +0200
Branches: blender-v3.2-release
https://developer.blender.org/rB02c5ca2f2269b44cc56438847c55b8139a1c8dd2

Fix possible issues when mixing link & append for asset drag & drop

The operators to handle object drag and drop (from the asset browser,
outliner, etc.) used the object name to find the object to add and
place. This is problematic with linking and/or library overrides, since
this may lead to multiple objects with the same name. So the wrong
object would be used by the drop operators.

Partially fixes T97320. T95706 probably needs the same fix but for
materials.

As a side-effect, the "Name" button won't show up in the Adjust Last
Operation panel anymore. This isn't really useful, and I doubt this was
ever intentionally exposed in the UI.

===================================================================

M	source/blender/editors/object/object_add.cc
M	source/blender/editors/space_view3d/space_view3d.c

===================================================================

diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index db8860efdd8..5bd4ca3a861 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -252,6 +252,65 @@ static int object_add_drop_xy_generic_invoke(bContext *C, wmOperator *op, const
   return op->type->exec(C, op);
 }
 
+/**
+ * Tries to find an ID in \a bmain. Three needs to be either a "name" string or "session_uuid" int
+ * property defined and set. The former has priority.
+ *
+ * See #id_add_lookup_props for a helper to add the properties.
+ */
+static ID *id_add_lookup_from_name_or_session_uuid_props(Main *bmain,
+                                                         const wmOperator *op,
+                                                         const ID_Type type)
+{
+  PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name");
+  PropertyRNA *prop_session_uuid = RNA_struct_find_property(op->ptr, "session_uuid");
+
+  if (prop_name && RNA_property_is_set(op->ptr, prop_name)) {
+    char name[MAX_ID_NAME - 2];
+    RNA_property_string_get(op->ptr, prop_name, name);
+    return BKE_libblock_find_name(bmain, type, name);
+  }
+
+  if (prop_session_uuid && 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);
+    return BKE_libblock_find_session_uuid(bmain, type, session_uuid);
+  }
+
+  return nullptr;
+}
+
+/**
+ * Adds "name" and "session_uuid" properties to the operator so the caller can tell the operator
+ * which ID to add. See #id_add_find_from_name_or_session_uuid_op_props(). Both properties will be
+ * hidden in the UI.
+ *
+ * \note New operators should probably use "session_uuid" only (set \a add_name_prop to #false),
+ * since this works with linked data and/or library overrides (in both cases, multiple IDs with the
+ * same name and type may be present). The "name" property is only kept to not break compatibility
+ * with old scripts using these operators.
+ */
+static void id_add_lookup_props(wmOperatorType *ot, const bool add_name_prop = false)
+{
+  PropertyRNA *prop;
+
+  if (add_name_prop) {
+    prop = RNA_def_string(
+        ot->srna, "name", nullptr, MAX_ID_NAME - 2, "Name", "Name of the data-block to add");
+    RNA_def_property_flag(prop, (PropertyFlag)(PROP_SKIP_SAVE | PROP_HIDDEN));
+  }
+
+  prop = RNA_def_int(ot->srna,
+                     "session_uuid",
+                     0,
+                     INT32_MIN,
+                     INT32_MAX,
+                     "Session UUID",
+                     "Session UUID of the data-block to add",
+                     INT32_MIN,
+                     INT32_MAX);
+  RNA_def_property_flag(prop, (PropertyFlag)(PROP_SKIP_SAVE | PROP_HIDDEN));
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -1651,19 +1710,12 @@ static std::optional<CollectionAddInfo> collection_add_info_get_from_op(bContext
   Main *bmain = CTX_data_main(C);
 
   PropertyRNA *prop_location = RNA_struct_find_property(op->ptr, "location");
-  PropertyRNA *prop_session_uuid = RNA_struct_find_property(op->ptr, "session_uuid");
-  PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name");
+
+  add_info.collection = reinterpret_cast<Collection *>(
+      id_add_lookup_from_name_or_session_uuid_props(bmain, op, ID_GR));
 
   bool update_location_if_necessary = false;
-  if (prop_name && RNA_property_is_set(op->ptr, prop_name)) {
-    char name[MAX_ID_NAME - 2];
-    RNA_property_string_get(op->ptr, prop_name, name);
-    add_info.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);
-    add_info.collection = (Collection *)BKE_libblock_find_session_uuid(bmain, ID_GR, session_uuid);
+  if (add_info.collection) {
     update_location_if_necessary = true;
   }
   else {
@@ -3718,15 +3770,13 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
   Main *bmain = CTX_data_main(C);
   Scene *scene = CTX_data_scene(C);
   ViewLayer *view_layer = CTX_data_view_layer(C);
-  Base *basen;
-  Object *ob;
   const bool linked = RNA_boolean_get(op->ptr, "linked");
   const eDupli_ID_Flags dupflag = (linked) ? (eDupli_ID_Flags)0 : (eDupli_ID_Flags)U.dupflag;
-  char name[MAX_ID_NAME - 2];
 
-  /* find object, create fake base */
-  RNA_string_get(op->ptr, "name", name);
-  ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
+  /* Find object, create fake base. */
+
+  Object *ob = reinterpret_cast<Object *>(
+      id_add_lookup_from_name_or_session_uuid_props(bmain, op, ID_OB));
 
   if (ob == nullptr) {
     BKE_report(op->reports, RPT_ERROR, "Object not found");
@@ -3734,7 +3784,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
   }
 
   /* prepare dupli */
-  basen = object_add_duplicate_internal(
+  Base *basen = object_add_duplicate_internal(
       bmain,
       scene,
       view_layer,
@@ -3814,7 +3864,7 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
                   "Linked",
                   "Duplicate object but not object data, linking to the original data");
 
-  RNA_def_string(ot->srna, "name", nullptr, MAX_ID_NAME - 2, "Name", "Object name to add");
+  id_add_lookup_props(ot, true);
 
   prop = RNA_def_float_matrix(
       ot->srna, "matrix", 4, 4, nullptr, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
@@ -3836,14 +3886,11 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
 {
   Main *bmain = CTX_data_main(C);
   ViewLayer *view_layer = CTX_data_view_layer(C);
-  Object *ob;
 
-  if (RNA_struct_property_is_set(op->ptr, "name")) {
-    char name[MAX_ID_NAME - 2];
-    RNA_string_get(op->ptr, "name", name);
-    ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name);
-  }
-  else {
+  Object *ob = reinterpret_cast<Object *>(
+      id_add_lookup_from_name_or_session_uuid_props(bmain, op, ID_OB));
+
+  if (!ob) {
     ob = OBACT(view_layer);
   }
 
@@ -3922,12 +3969,25 @@ void OBJECT_OT_transform_to_mouse(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
   PropertyRNA *prop;
-  RNA_def_string(ot->srna,
-                 "name",
-                 nullptr,
-                 MAX_ID_NAME - 2,
-                 "Name",
-                 "Object name to place (when unset use the active object)");
+  prop = RNA_def_string(
+      ot->srna,
+      "name",
+      nullptr,
+      MAX_ID_NAME - 2,
+      "Name",
+      "Object name to place (uses the active object when this and 'session_uuid' are unset)");
+  RNA_def_property_flag(prop, (PropertyFlag)(PROP_SKIP_SAVE | PROP_HIDDEN));
+  prop = RNA_def_int(ot->srna,
+                     "session_uuid",
+                     0,
+                     INT32_MIN,
+                     INT32_MAX,
+                     "Session UUID",
+                     "Session UUID of the object to place (uses the active object when this and "
+                     "'name' are unset)",
+                     INT32_MIN,
+                     INT32_MAX);
+  RNA_def_property_flag(prop, (PropertyFlag)(PROP_SKIP_SAVE | PROP_HIDDEN));
 
   prop = RNA_def_float_matrix(
       ot->srna, "matrix", 4, 4, nullptr, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index a02058fde6b..5ddfc4fe3cc 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -716,7 +716,7 @@ static void view3d_ob_drop_copy_local_id(bContext *UNUSED(C), wmDrag *drag, wmDr
 {
   ID *id = WM_drag_get_local_ID(drag, ID_OB);
 
-  RNA_string_set(drop->ptr, "name", id->name + 2);
+  RNA_int_set(drop->ptr, "session_uuid", id->session_uuid);
   /* Don't duplicate ID's which were just imported. Only do that for existing, local IDs. */
   BLI_assert(drag->type != WM_DRAG_ASSET);
 
@@ -751,7 +751,7 @@ static void view3d_ob_drop_copy_external_asset(bContext *UNUSED(C), wmDrag *drag
   DEG_relations_tag_update(CTX_data_main(C));
   WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
 
-  RNA_string_set(drop->ptr, "name", id->name + 2);
+  RNA_int_set(drop->ptr, "session_uuid", id->session_uuid);
 
   Base *base = BKE_view_layer_base_find(view_layer, (Object *)id);
   if (base != NULL) {



More information about the Bf-blender-cvs mailing list