111 id_info.new_id.reset();
112 if (!id_info.library_path.empty() && !libraries_path_to_id.
contains(id_info.library_path)) {
113 libraries_path_to_id.
add(
114 id_info.library_path,
116 id_info.library_path.c_str(),
127 auto validate_id_fn = [
this, &
is_valid, &bmain, &bmain_id_map, &libraries_path_to_id](
129 ID *old_id = *(cb_data->id_pointer);
133 if (!this->old_ids_to_idinfo.
contains(old_id)) {
135 0,
"Missing entry in the old ID data of the node clipboard, should not happen");
148 bmain_id_map,
GS(id_info.
id_name.c_str()), id_info.
id_name.c_str() + 2, new_id_lib);
155 if (*(id_info.
new_id) ==
nullptr) {
173 bmain_id_map =
nullptr;
186 ID *old_id = *(cb_data->id_pointer);
190 if (!this->old_ids_to_idinfo.
contains(old_id)) {
192 0,
"Missing entry in the old ID data of the node clipboard, should not happen");
193 *(cb_data->id_pointer) =
nullptr;
201 "Unset new ID value for an old ID reference in the node clipboard, should not happen");
202 *(cb_data->id_pointer) =
nullptr;
205 *(cb_data->id_pointer) = *(id_info.
new_id);
230 node_map.
add_new(&node, new_node);
234 ID *old_id = *(cb_data->id_pointer);
237 if (this->old_ids_to_idinfo.
contains(old_id)) {
248 this->old_ids_to_idinfo.
add(old_id, std::move(id_info));
264 item.node = new_node;
265 this->nodes.
append(std::move(item));
292 for (
const bNode *node :
tree.all_nodes()) {
293 if (node->flag &
SELECT) {
300 if (new_node->parent) {
301 if (node_map.
contains(new_node->parent)) {
302 new_node->parent = node_map.
lookup(new_node->parent);
315 clipboard.
links.append({});
317 new_link.
flag = link->flag;
320 new_link.
to_socket = link->tosock->identifier;
331 ot->
name =
"Copy to Clipboard";
332 ot->
description =
"Copy the selected nodes to the internal clipboard";
333 ot->
idname =
"NODE_OT_clipboard_copy";
354 if (clipboard.
nodes.is_empty()) {
362 "Some nodes references to other IDs could not be restored, will be left empty");
374 const bNode &node = *item.node;
375 const char *disabled_hint =
nullptr;
376 if (node.typeinfo->poll_instance && node.typeinfo->poll_instance(&node, &
tree, &disabled_hint))
391 node_map.
add_new(&node, new_node);
397 "Cannot add node %s into node tree %s: %s",
405 "Cannot add node %s into node tree %s",
415 new_node->flag &= ~NODE_ACTIVE;
418 if (new_node->parent) {
419 if (node_map.
contains(new_node->parent)) {
420 new_node->parent = node_map.
lookup(new_node->parent);
433 center /= clipboard.
nodes.size();
441 if (new_node->parent ==
nullptr) {
442 new_node->locx += offset.x;
443 new_node->locy += offset.y;
458 if (!from_node || !to_node) {
470 tree.ensure_topology_cache();
494 ot->
name =
"Paste from Clipboard";
495 ot->
description =
"Paste nodes from the internal clipboard to the active node tree";
496 ot->
idname =
"NODE_OT_clipboard_paste";
512 "The 2D view location for the center of the new nodes, or unchanged if not set",
SpaceNode * CTX_wm_space_node(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void BKE_library_foreach_subdata_id(Main *bmain, ID *owner_id, ID *self_id, blender::FunctionRef< void(LibraryForeachIDData *data)> subdata_foreach_id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, const int flag)
IDNameLib_Map * BKE_main_idmap_create(Main *bmain, bool create_valid_ids_set, Main *old_bmain, int idmap_types) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BKE_main_idmap_destroy(IDNameLib_Map *id_map) ATTR_NONNULL()
ID * BKE_main_idmap_lookup_name(IDNameLib_Map *id_map, short id_type, const char *name, const Library *lib) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_msg(a, msg)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
void DEG_relations_tag_update(Main *bmain)
#define ID_IS_LINKED(_id)
@ SOCK_DISPLAY_SHAPE_CIRCLE
void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ntree)
void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain)
bool ED_operator_node_editable(bContext *C)
bool ED_operator_node_active(bContext *C)
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) const
ValueIterator values() const
void add_new(const Key &key, const Value &value)
bool contains(const Key &key) const
void append(const T &value)
void ED_node_clipboard_free()
void node_detach_node(bNodeTree *ntree, bNode *node)
bNode * node_copy_with_mapping(bNodeTree *dst_tree, const bNode &node_src, int flag, bool use_unique, Map< const bNodeSocket *, bNodeSocket * > &new_socket_map)
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
void node_node_foreach_id(bNode *node, LibraryForeachIDData *data)
bool node_set_selected(bNode *node, bool select)
bool node_declaration_ensure(bNodeTree *ntree, bNode *node)
void node_free_node(bNodeTree *tree, bNode *node)
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)
static int node_clipboard_copy_exec(bContext *C, wmOperator *)
void NODE_OT_clipboard_copy(wmOperatorType *ot)
void node_select_paired(bNodeTree &node_tree)
bool node_deselect_all(bNodeTree &node_tree)
static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void NODE_OT_clipboard_paste(wmOperatorType *ot)
void remap_node_pairing(bNodeTree &dst_tree, const Map< const bNode *, bNode * > &node_map)
static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
static NodeClipboard & get_node_clipboard()
void update_multi_input_indices_for_removed_links(bNode &node)
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
PropertyRNA * RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
struct Library_Runtime runtime
struct bNodeTree * edittree
std::optional< ID * > new_id
Vector< NodeClipboardItem > nodes
void paste_update_node_id_references(bNode &node)
bool paste_validate_id_references(Main &bmain)
Map< ID *, NodeClipboardItemIDInfo > old_ids_to_idinfo
Vector< ClipboardLink > links
void copy_add_node(const bNode &node, Map< const bNode *, bNode * > &node_map, Map< const bNodeSocket *, bNodeSocket * > &socket_map)
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports