diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/object/object_add.cc | 124 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 4 |
2 files changed, 94 insertions, 34 deletions
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) { |