Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-09-06 11:35:27 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-09-06 11:42:16 +0300
commite56ff76db5b44ae6784a26ff6daf9864b2387712 (patch)
tree03ffd243bb948574d95556f593c8770730b24e9a /source/blender/editors/object
parent5faf72bb719b075e8ef4bf4371cc13c35557eba9 (diff)
Viewport: support dropping object-data to create instances
This allows orphan object data for example (meshes, curves, etc) to be dropped into the 3D View from the outliner, creating a new object instance. Previously the only way to do this was to add the same type of object then swap it's data through the ID selector drop-down.
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_add.c86
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
3 files changed, 88 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 72180d58ecb..d35ac4840bd 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1489,6 +1489,92 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Add Data Instance Operator
+ *
+ * Use for dropping ID's from the outliner.
+ * \{ */
+
+static int object_data_instance_add_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ ID *id = NULL;
+ ushort local_view_bits;
+ float loc[3], rot[3];
+
+ PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name");
+ PropertyRNA *prop_type = RNA_struct_find_property(op->ptr, "type");
+ PropertyRNA *prop_location = RNA_struct_find_property(op->ptr, "location");
+
+ /* These shouldn't fail when created by outliner dropping as it checks the ID is valid. */
+ if (!RNA_property_is_set(op->ptr, prop_name) || !RNA_property_is_set(op->ptr, prop_type)) {
+ return OPERATOR_CANCELLED;
+ }
+ const short id_type = RNA_property_enum_get(op->ptr, prop_type);
+ char name[MAX_ID_NAME - 2];
+ RNA_property_string_get(op->ptr, prop_name, name);
+ id = BKE_libblock_find_name(bmain, id_type, name);
+ if (id == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+ const int object_type = BKE_object_obdata_to_type(id);
+ if (object_type == -1) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!RNA_property_is_set(op->ptr, prop_location)) {
+ const wmEvent *event = CTX_wm_window(C)->eventstate;
+ ARegion *region = CTX_wm_region(C);
+ const int mval[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin};
+ ED_object_location_from_view(C, loc);
+ ED_view3d_cursor3d_position(C, mval, false, loc);
+ RNA_property_float_set_array(op->ptr, prop_location, loc);
+ }
+
+ if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+
+ Object *ob = ED_object_add_type(C, object_type, id->name + 2, loc, rot, false, local_view_bits);
+ ob->data = id;
+ id_us_plus(id);
+
+ BKE_object_materials_test(bmain, ob, ob->data);
+
+ /* Works without this except if you try render right after, see: T22027. */
+ DEG_relations_tag_update(bmain);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_data_instance_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Object Data Instance";
+ ot->description = "Add an object data instance";
+ ot->idname = "OBJECT_OT_data_instance_add";
+
+ /* api callbacks */
+ ot->exec = object_data_instance_add_exec;
+ ot->poll = ED_operator_objectmode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_string(ot->srna, "name", "Name", MAX_ID_NAME - 2, "Name", "ID name to add");
+ PropertyRNA *prop = RNA_def_enum(ot->srna, "type", rna_enum_id_type_items, 0, "Type", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
+ ED_object_add_generic_props(ot, false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Add Speaker Operator
* \{ */
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 50825ae1ae4..99e139b823e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -117,6 +117,7 @@ void OBJECT_OT_speaker_add(struct wmOperatorType *ot);
void OBJECT_OT_hair_add(struct wmOperatorType *ot);
void OBJECT_OT_pointcloud_add(struct wmOperatorType *ot);
void OBJECT_OT_collection_instance_add(struct wmOperatorType *ot);
+void OBJECT_OT_data_instance_add(struct wmOperatorType *ot);
void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot);
void OBJECT_OT_duplicate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 92880e5a114..8b3837edce2 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -117,6 +117,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_add_named);
WM_operatortype_append(OBJECT_OT_effector_add);
WM_operatortype_append(OBJECT_OT_collection_instance_add);
+ WM_operatortype_append(OBJECT_OT_data_instance_add);
WM_operatortype_append(OBJECT_OT_metaball_add);
WM_operatortype_append(OBJECT_OT_duplicates_make_real);
WM_operatortype_append(OBJECT_OT_duplicate);