From aa83fb0337d279182f1eba223c967276a39e04bf Mon Sep 17 00:00:00 2001 From: Daybreak Date: Tue, 29 Aug 2023 15:51:18 +0200 Subject: [PATCH] Geometry Nodes: Support drag & drop for Materials Allows for materials to be dragged and dropped into the geometry nodes editor, similar to collections or objects. Pull Request: https://projects.blender.org/blender/blender/pulls/111368 --- source/blender/editors/space_node/node_add.cc | 76 +++++++++++++++++++ .../blender/editors/space_node/node_intern.hh | 1 + source/blender/editors/space_node/node_ops.cc | 1 + .../blender/editors/space_node/space_node.cc | 11 +++ 4 files changed, 89 insertions(+) diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 019b7368f5e..5a026d8a237 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -843,6 +843,82 @@ void NODE_OT_add_mask(wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Add Material Operator + * \{ */ + +static int node_add_material_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + + Material *material = reinterpret_cast( + WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_MA)); + + if (!material) { + return OPERATOR_CANCELLED; + } + + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); + + bNode *material_node = add_static_node(*C, GEO_NODE_INPUT_MATERIAL, snode->runtime->cursor); + if (!material_node) { + BKE_report(op->reports, RPT_WARNING, "Could not add material"); + return OPERATOR_CANCELLED; + } + + material_node->id = &material->id; + id_us_plus(&material->id); + + ED_node_tree_propagate_change(C, bmain, ntree); + DEG_relations_tag_update(bmain); + + return OPERATOR_FINISHED; +} + +static int node_add_material_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *region = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + + /* Convert mouse coordinates to v2d space. */ + UI_view2d_region_to_view(®ion->v2d, + event->mval[0], + event->mval[1], + &snode->runtime->cursor[0], + &snode->runtime->cursor[1]); + + snode->runtime->cursor[0] /= UI_SCALE_FAC; + snode->runtime->cursor[1] /= UI_SCALE_FAC; + + return node_add_material_exec(C, op); +} + +static bool node_add_material_poll(bContext *C) +{ + const SpaceNode *snode = CTX_wm_space_node(C); + return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY); +} + +void NODE_OT_add_material(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Material"; + ot->description = "Add a material node to the current node editor"; + ot->idname = "NODE_OT_add_material"; + + /* callbacks */ + ot->exec = node_add_material_exec; + ot->invoke = node_add_material_invoke; + ot->poll = node_add_material_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + WM_operator_properties_id_lookup(ot, true); +} + /* -------------------------------------------------------------------- */ /** \name New Node Tree Operator * \{ */ diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index cf23d1b6f8e..525ec67f54d 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -290,6 +290,7 @@ void NODE_OT_add_object(wmOperatorType *ot); void NODE_OT_add_collection(wmOperatorType *ot); void NODE_OT_add_file(wmOperatorType *ot); void NODE_OT_add_mask(wmOperatorType *ot); +void NODE_OT_add_material(wmOperatorType *ot); void NODE_OT_new_node_tree(wmOperatorType *ot); /* `node_group.cc` */ diff --git a/source/blender/editors/space_node/node_ops.cc b/source/blender/editors/space_node/node_ops.cc index caabbb40d96..d468bd7a4ac 100644 --- a/source/blender/editors/space_node/node_ops.cc +++ b/source/blender/editors/space_node/node_ops.cc @@ -84,6 +84,7 @@ void node_operatortypes() WM_operatortype_append(NODE_OT_add_collection); WM_operatortype_append(NODE_OT_add_file); WM_operatortype_append(NODE_OT_add_mask); + WM_operatortype_append(NODE_OT_add_material); WM_operatortype_append(NODE_OT_new_node_tree); diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 848b2bbdce9..8ac65616dd6 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -702,6 +702,11 @@ static bool node_mask_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * return WM_drag_is_ID_type(drag, ID_MSK); } +static bool node_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent * /*event*/) +{ + return WM_drag_is_ID_type(drag, ID_MA) && !UI_but_active_drop_name(C); +} + static void node_group_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) { ID *id = WM_drag_get_local_ID_or_import_from_asset(C, drag, 0); @@ -771,6 +776,12 @@ static void node_dropboxes() node_id_drop_copy, WM_drag_free_imported_drag_ID, nullptr); + WM_dropbox_add(lb, + "NODE_OT_add_material", + node_material_drop_poll, + node_id_drop_copy, + WM_drag_free_imported_drag_ID, + nullptr); } /* ************* end drop *********** */