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.
This commit is contained in:
parent
5faf72bb71
commit
e56ff76db5
Notes:
blender-bot
2023-02-14 05:59:31 +01:00
Referenced by issue #80519, Radeon RX5xx: Computer freezes/crashes when user performs actions in Viewport during rendering in Blender 2.90 Referenced by issue #79758, blender crashes when rendering eevee Referenced by issue #79732, Wireframe of Optimal Display stays after Converting to Mesh/Meta/Surf/Text Referenced by issue #79454, immediate crash when baking Referenced by issue #79359, Crash on CPU render when "Open Shading Language" is deselected in render settings.
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue