[Bf-blender-cvs] [e56ff76db5b] master: Viewport: support dropping object-data to create instances

Campbell Barton noreply at git.blender.org
Sun Sep 6 10:44:14 CEST 2020


Commit: e56ff76db5b44ae6784a26ff6daf9864b2387712
Author: Campbell Barton
Date:   Sun Sep 6 18:35:27 2020 +1000
Branches: master
https://developer.blender.org/rBe56ff76db5b44ae6784a26ff6daf9864b2387712

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.

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

M	source/blender/editors/object/object_add.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/space_view3d/space_view3d.c

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

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
@@ -1488,6 +1488,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);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index de0b420a3b5..4fdfc18c9ff 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -37,6 +37,8 @@
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
+#include "BLT_translation.h"
+
 #include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_global.h"
@@ -459,16 +461,24 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *region)
   ED_view3d_stop_render_preview(wm, region);
 }
 
-static bool view3d_drop_id_in_main_region_poll(bContext *C,
-                                               wmDrag *drag,
-                                               const wmEvent *event,
-                                               ID_Type id_type)
+static ID *view3d_drop_id_in_main_region_poll_id(bContext *C,
+                                                 wmDrag *drag,
+                                                 const wmEvent *event,
+                                                 ID_Type id_type)
 {
   ScrArea *area = CTX_wm_area(C);
   if (ED_region_overlap_isect_any_xy(area, &event->x)) {
     return false;
   }
-  return WM_drag_ID(drag, id_type) != NULL;
+  return WM_drag_ID(drag, id_type);
+}
+
+static bool view3d_drop_id_in_main_region_poll(bContext *C,
+                                               wmDrag *drag,
+                                               const wmEvent *event,
+                                               ID_Type id_type)
+{
+  return (view3d_drop_id_in_main_region_poll_id(C, drag, event, id_type) != NULL);
 }
 
 static bool view3d_ob_drop_poll(bContext *C,
@@ -495,6 +505,21 @@ static bool view3d_mat_drop_poll(bContext *C,
   return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA);
 }
 
+static bool view3d_object_data_drop_poll(bContext *C,
+                                         wmDrag *drag,
+                                         const wmEvent *event,
+                                         const char **r_tooltip)
+{
+  ID *id = view3d_drop_id_in_main_region_poll_id(C, drag, event, 0);
+  if (id != NULL) {
+    if (BKE_object_obdata_to_type(id) != -1) {
+      *r_tooltip = TIP_("Create object instance from object-data");
+      return true;
+    }
+  }
+  return false;
+}
+
 static bool view3d_ima_drop_poll(bContext *C,
                                  wmDrag *drag,
                                  const wmEvent *event,
@@ -591,6 +616,14 @@ static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
   RNA_string_set(drop->ptr, "name", id->name + 2);
 }
 
+static void view3d_id_drop_copy_with_type(wmDrag *drag, wmDropBox *drop)
+{
+  ID *id = WM_drag_ID(drag, 0);
+
+  RNA_string_set(drop->ptr, "name", id->name + 2);
+  RNA_enum_set(drop->ptr, "type", GS(id->name));
+}
+
 static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
   ID *id = WM_drag_ID(drag, 0);
@@ -642,6 +675,10 @@ static void view3d_dropboxes(void)
                  "OBJECT_OT_collection_instance_add",
                  view3d_collection_drop_poll,
                  view3d_collection_drop_copy);
+  WM_dropbox_add(lb,
+                 "OBJECT_OT_data_instance_add",
+                 view3d_object_data_drop_poll,
+                 view3d_id_drop_copy_with_type);
 }
 
 static void view3d_widgets(void)



More information about the Bf-blender-cvs mailing list