1
1

Fix object assets getting duplicated after dropping

The operator run when dropping objects would duplicate the dropped object and
place that in the scene, even though that was just appended. Addressed by
making the duplication optional for the operator. If the duplication is not
requested, the object is just added to the scene (if needed), repositioned
based on the drop location and selected (deselecting other objects).
This makes the operator work as expected when using it to drop assets.

Reviewed as part of https://developer.blender.org/D11536.

Reviewed by: Bastien Montagne
This commit is contained in:
2021-06-11 16:31:57 +02:00
parent 20ece8736f
commit c8fcea0c33
2 changed files with 53 additions and 15 deletions

View File

@@ -3462,6 +3462,19 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
* Use for drag & drop. * Use for drag & drop.
* \{ */ * \{ */
static Base *object_add_ensure_in_view_layer(Main *bmain, ViewLayer *view_layer, Object *ob)
{
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (!base) {
LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
BKE_collection_object_add(bmain, layer_collection->collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
}
return base;
}
static int object_add_named_exec(bContext *C, wmOperator *op) static int object_add_named_exec(bContext *C, wmOperator *op)
{ {
Main *bmain = CTX_data_main(C); Main *bmain = CTX_data_main(C);
@@ -3469,7 +3482,8 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C); ViewLayer *view_layer = CTX_data_view_layer(C);
Base *basen; Base *basen;
Object *ob; Object *ob;
const bool linked = RNA_boolean_get(op->ptr, "linked"); const bool duplicate = RNA_boolean_get(op->ptr, "duplicate");
const bool linked = duplicate && RNA_boolean_get(op->ptr, "linked");
const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag; const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
char name[MAX_ID_NAME - 2]; char name[MAX_ID_NAME - 2];
@@ -3483,20 +3497,30 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
} }
/* prepare dupli */ /* prepare dupli */
basen = object_add_duplicate_internal( if (duplicate) {
bmain, basen = object_add_duplicate_internal(
scene, bmain,
view_layer, scene,
ob, view_layer,
dupflag, ob,
/* Sub-process flag because the new-ID remapping (#BKE_libblock_relink_to_newid()) in this dupflag,
* function will only work if the object is already linked in the view layer, which is not /* Sub-process flag because the new-ID remapping (#BKE_libblock_relink_to_newid()) in this
* the case here. So we have to do the new-ID relinking ourselves (#copy_object_set_idnew()). * function will only work if the object is already linked in the view layer, which is not
*/ * the case here. So we have to do the new-ID relinking ourselves
LIB_ID_DUPLICATE_IS_SUBPROCESS); * (#copy_object_set_idnew()).
*/
LIB_ID_DUPLICATE_IS_SUBPROCESS);
}
else {
/* basen is actually not a new base in this case. */
basen = object_add_ensure_in_view_layer(bmain, view_layer, ob);
}
if (basen == NULL) { if (basen == NULL) {
BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated"); BKE_report(op->reports,
RPT_ERROR,
duplicate ? "Object could not be duplicated" :
"Object could not be linked to the view layer");
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
@@ -3543,11 +3567,24 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
/* flags */ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
PropertyRNA *prop;
prop = RNA_def_boolean(
ot->srna,
"duplicate",
true,
"Duplicate",
"Create a duplicate of the object. If not set, only ensures the object is linked into the "
"active view layer, positions and selects/activates it (deselecting others)");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_boolean(ot->srna, RNA_def_boolean(ot->srna,
"linked", "linked",
0, false,
"Linked", "Linked",
"Duplicate object but not object data, linking to the original data"); "Duplicate object but not object data, linking to the original data (ignored if "
"'duplicate' is false)");
RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add"); RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add");
object_add_drop_xy_props(ot); object_add_drop_xy_props(ot);

View File

@@ -625,6 +625,7 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_OB); ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_OB);
RNA_string_set(drop->ptr, "name", id->name + 2); RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_boolean_set(drop->ptr, "duplicate", false);
} }
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)