Blender  V2.93
node_edit.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_light_types.h"
27 #include "DNA_material_types.h"
28 #include "DNA_node_types.h"
29 #include "DNA_text_types.h"
30 #include "DNA_world_types.h"
31 
32 #include "BLI_blenlib.h"
33 #include "BLI_math.h"
34 
35 #include "BKE_context.h"
36 #include "BKE_global.h"
37 #include "BKE_image.h"
38 #include "BKE_lib_id.h"
39 #include "BKE_main.h"
40 #include "BKE_material.h"
41 #include "BKE_node.h"
42 #include "BKE_report.h"
43 #include "BKE_scene.h"
44 #include "BKE_workspace.h"
45 
46 #include "DEG_depsgraph.h"
47 #include "DEG_depsgraph_build.h"
48 #include "DEG_depsgraph_query.h"
49 
50 #include "RE_engine.h"
51 #include "RE_pipeline.h"
52 
53 #include "ED_node.h" /* own include */
54 #include "ED_render.h"
55 #include "ED_screen.h"
56 #include "ED_select_utils.h"
57 
58 #include "RNA_access.h"
59 #include "RNA_define.h"
60 #include "RNA_enum_types.h"
61 
62 #include "WM_api.h"
63 #include "WM_types.h"
64 
65 #include "UI_view2d.h"
66 
67 #include "GPU_material.h"
68 
69 #include "IMB_imbuf_types.h"
70 
71 #include "NOD_composite.h"
72 #include "NOD_geometry.h"
73 #include "NOD_shader.h"
74 #include "NOD_texture.h"
75 #include "node_intern.h" /* own include */
76 
77 #define USE_ESC_COMPO
78 
79 /* ***************** composite job manager ********************** */
80 
81 enum {
84 };
85 
86 typedef struct CompoJob {
87  /* Input parameters. */
93  /* Evaluated state/ */
96  /* Jon system integration. */
97  const short *stop;
98  short *do_update;
99  float *progress;
101 
103 {
104  float sock_height = NODE_SOCKSIZE * 2.0f;
105  if (socket->flag & SOCK_MULTI_INPUT) {
106  sock_height += max_ii(NODE_MULTI_INPUT_LINK_GAP * 0.5f * socket->total_inputs, NODE_SOCKSIZE);
107  }
108  return sock_height;
109 }
110 
112  const float socket_y,
113  const int index,
114  const int total_inputs,
115  float r[2])
116 {
117  float offset = (total_inputs * NODE_MULTI_INPUT_LINK_GAP - NODE_MULTI_INPUT_LINK_GAP) * 0.5;
118  r[0] = socket_x - NODE_SOCKSIZE * 0.5f;
119  r[1] = socket_y - offset + (index * NODE_MULTI_INPUT_LINK_GAP);
120 }
121 
122 static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
123 {
124  LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
125  if (node->type == CMP_NODE_COMPOSITE) {
126  if (recalc_flags & COM_RECALC_COMPOSITE) {
127  node->flag |= NODE_DO_OUTPUT_RECALC;
128  }
129  }
130  else if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
131  if (recalc_flags & COM_RECALC_VIEWER) {
132  node->flag |= NODE_DO_OUTPUT_RECALC;
133  }
134  }
135  else if (node->type == NODE_GROUP) {
136  if (node->id) {
137  compo_tag_output_nodes((bNodeTree *)node->id, recalc_flags);
138  }
139  }
140  }
141 }
142 
144 {
146  int recalc_flags = 0;
147 
148  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
149  const bScreen *screen = WM_window_get_active_screen(win);
150 
151  LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
152  if (area->spacetype == SPACE_IMAGE) {
153  SpaceImage *sima = area->spacedata.first;
154  if (sima->image) {
155  if (sima->image->type == IMA_TYPE_R_RESULT) {
156  recalc_flags |= COM_RECALC_COMPOSITE;
157  }
158  else if (sima->image->type == IMA_TYPE_COMPOSITE) {
159  recalc_flags |= COM_RECALC_VIEWER;
160  }
161  }
162  }
163  else if (area->spacetype == SPACE_NODE) {
164  SpaceNode *snode = area->spacedata.first;
165  if (snode->flag & SNODE_BACKDRAW) {
166  recalc_flags |= COM_RECALC_VIEWER;
167  }
168  }
169  }
170  }
171 
172  return recalc_flags;
173 }
174 
175 /* called by compo, only to check job 'stop' value */
176 static int compo_breakjob(void *cjv)
177 {
178  CompoJob *cj = cjv;
179 
180  /* without G.is_break 'ESC' wont quit - which annoys users */
181  return (*(cj->stop)
182 #ifdef USE_ESC_COMPO
183  || G.is_break
184 #endif
185  );
186 }
187 
188 /* called by compo, wmJob sends notifier */
189 static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
190 {
191  CompoJob *cj = cjv;
192 
193  *(cj->do_update) = true;
194 }
195 
196 /* called by compo, wmJob sends notifier */
197 static void compo_redrawjob(void *cjv)
198 {
199  CompoJob *cj = cjv;
200 
201  *(cj->do_update) = true;
202 }
203 
204 static void compo_freejob(void *cjv)
205 {
206  CompoJob *cj = cjv;
207 
208  if (cj->localtree) {
209  ntreeLocalMerge(cj->bmain, cj->localtree, cj->ntree);
210  }
211  if (cj->compositor_depsgraph != NULL) {
213  }
214  MEM_freeN(cj);
215 }
216 
217 /* only now we copy the nodetree, so adding many jobs while
218  * sliding buttons doesn't frustrate */
219 static void compo_initjob(void *cjv)
220 {
221  CompoJob *cj = cjv;
222  Main *bmain = cj->bmain;
223  Scene *scene = cj->scene;
224  ViewLayer *view_layer = cj->view_layer;
225 
226  cj->compositor_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
228 
229  /* NOTE: Don't update animation to preserve unkeyed changes, this means can not use
230  * evaluate_on_framechange. */
232 
234  &cj->ntree->id);
235 
236  cj->localtree = ntreeLocalize(ntree_eval);
237 
238  if (cj->recalc_flags) {
240  }
241 }
242 
243 /* called before redraw notifiers, it moves finished previews over */
244 static void compo_updatejob(void *UNUSED(cjv))
245 {
247 }
248 
249 static void compo_progressjob(void *cjv, float progress)
250 {
251  CompoJob *cj = cjv;
252 
253  *(cj->progress) = progress;
254 }
255 
256 /* only this runs inside thread */
257 static void compo_startjob(void *cjv,
258  /* Cannot be const, this function implements wm_jobs_start_callback.
259  * NOLINTNEXTLINE: readability-non-const-parameter. */
260  short *stop,
261  short *do_update,
262  float *progress)
263 {
264  CompoJob *cj = cjv;
265  bNodeTree *ntree = cj->localtree;
266  Scene *scene = cj->scene;
267 
268  if (scene->use_nodes == false) {
269  return;
270  }
271 
272  cj->stop = stop;
273  cj->do_update = do_update;
274  cj->progress = progress;
275 
277  ntree->tbh = cj;
279  ntree->sdh = cj;
281  ntree->prh = cj;
283  ntree->udh = cj;
284 
285  // XXX BIF_store_spare();
286  /* 1 is do_previews */
287 
288  if ((cj->scene->r.scemode & R_MULTIVIEW) == 0) {
290  ntree,
291  &cj->scene->r,
292  false,
293  true,
296  "");
297  }
298  else {
300  if (BKE_scene_multiview_is_render_view_active(&scene->r, srv) == false) {
301  continue;
302  }
304  ntree,
305  &cj->scene->r,
306  false,
307  true,
310  srv->name);
311  }
312  }
313 
314  ntree->test_break = NULL;
315  ntree->stats_draw = NULL;
316  ntree->progress = NULL;
317 }
318 
326 void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner)
327 {
328  Main *bmain = CTX_data_main(C);
330  ViewLayer *view_layer = CTX_data_view_layer(C);
331 
332  /* to fix bug: T32272. */
333  if (G.is_rendering) {
334  return;
335  }
336 
337 #ifdef USE_ESC_COMPO
338  G.is_break = false;
339 #endif
340 
342  scene, BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"), false);
343 
344  wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
345  CTX_wm_window(C),
346  scene_owner,
347  "Compositing",
350  CompoJob *cj = MEM_callocN(sizeof(CompoJob), "compo job");
351 
352  /* customdata for preview thread */
353  cj->bmain = bmain;
354  cj->scene = scene;
355  cj->view_layer = view_layer;
356  cj->ntree = nodetree;
358 
359  /* setup job */
363 
364  WM_jobs_start(CTX_wm_manager(C), wm_job);
365 }
366 
367 /* ***************************************** */
368 
369 /* operator poll callback */
371 {
372  if (ED_operator_node_active(C)) {
373  SpaceNode *snode = CTX_wm_space_node(C);
374  if (ED_node_is_compositor(snode)) {
375  return true;
376  }
377  }
378  return false;
379 }
380 
381 /* operator poll callback */
383 {
385  SpaceNode *snode = CTX_wm_space_node(C);
386  if (ED_node_is_compositor(snode)) {
387  return true;
388  }
389  }
390  return false;
391 }
392 
394 {
395  Main *bmain = CTX_data_main(C);
396 
397  /* for groups, update all ID's using this */
398  if (snode->edittree != snode->nodetree) {
399  FOREACH_NODETREE_BEGIN (bmain, tntree, id) {
400  if (ntreeHasTree(tntree, snode->edittree)) {
401  DEG_id_tag_update(id, 0);
402  }
403  }
405  }
406 
407  DEG_id_tag_update(snode->id, 0);
408  DEG_id_tag_update(&snode->nodetree->id, 0);
409 }
410 
412 {
413  ID *id = snode->id;
414 
416 
417  if (ED_node_is_shader(snode)) {
418  if (GS(id->name) == ID_MA) {
420  }
421  else if (GS(id->name) == ID_LA) {
423  }
424  else if (GS(id->name) == ID_WO) {
426  }
427  }
428  else if (ED_node_is_compositor(snode)) {
430  }
431  else if (ED_node_is_texture(snode)) {
433  }
434  else if (ED_node_is_geometry(snode)) {
436  }
437 }
438 
440 {
441  if (typeinfo) {
442  BLI_strncpy(snode->tree_idname, typeinfo->idname, sizeof(snode->tree_idname));
443  }
444  else {
445  snode->tree_idname[0] = '\0';
446  }
447 }
448 
449 bool ED_node_is_compositor(struct SpaceNode *snode)
450 {
451  return STREQ(snode->tree_idname, ntreeType_Composite->idname);
452 }
453 
454 bool ED_node_is_shader(struct SpaceNode *snode)
455 {
456  return STREQ(snode->tree_idname, ntreeType_Shader->idname);
457 }
458 
459 bool ED_node_is_texture(struct SpaceNode *snode)
460 {
461  return STREQ(snode->tree_idname, ntreeType_Texture->idname);
462 }
463 
464 bool ED_node_is_geometry(struct SpaceNode *snode)
465 {
466  return STREQ(snode->tree_idname, ntreeType_Geometry->idname);
467 }
468 
469 /* assumes nothing being done in ntree yet, sets the default in/out node */
470 /* called from shading buttons or header */
472 {
473  Main *bmain = CTX_data_main(C);
474 
475  if (GS(id->name) == ID_MA) {
476  /* Materials */
478  Material *ma = (Material *)id;
479  Material *ma_default;
480 
481  if (ob && ob->type == OB_VOLUME) {
482  ma_default = BKE_material_default_volume();
483  }
484  else {
485  ma_default = BKE_material_default_surface();
486  }
487 
488  ma->nodetree = ntreeCopyTree(bmain, ma_default->nodetree);
489  ntreeUpdateTree(bmain, ma->nodetree);
490  }
491  else if (ELEM(GS(id->name), ID_WO, ID_LA)) {
492  /* Emission */
493  bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
494  bNode *shader, *output;
495 
496  if (GS(id->name) == ID_WO) {
497  World *world = (World *)id;
498  world->nodetree = ntree;
499 
503  shader,
504  nodeFindSocket(shader, SOCK_OUT, "Background"),
505  output,
506  nodeFindSocket(output, SOCK_IN, "Surface"));
507 
508  bNodeSocket *color_sock = nodeFindSocket(shader, SOCK_IN, "Color");
509  copy_v3_v3(((bNodeSocketValueRGBA *)color_sock->default_value)->value, &world->horr);
510  }
511  else {
512  Light *light = (Light *)id;
513  light->nodetree = ntree;
514 
518  shader,
519  nodeFindSocket(shader, SOCK_OUT, "Emission"),
520  output,
521  nodeFindSocket(output, SOCK_IN, "Surface"));
522  }
523 
524  shader->locx = 10.0f;
525  shader->locy = 300.0f;
526  output->locx = 300.0f;
527  output->locy = 300.0f;
529  ntreeUpdateTree(bmain, ntree);
530  }
531  else {
532  printf("ED_node_shader_default called on wrong ID type.\n");
533  return;
534  }
535 }
536 
537 /* assumes nothing being done in ntree yet, sets the default in/out node */
538 /* called from shading buttons or header */
539 void ED_node_composit_default(const bContext *C, struct Scene *sce)
540 {
541  /* but lets check it anyway */
542  if (sce->nodetree) {
543  if (G.debug & G_DEBUG) {
544  printf("error in composite initialize\n");
545  }
546  return;
547  }
548 
549  sce->nodetree = ntreeAddTree(NULL, "Compositing Nodetree", ntreeType_Composite->idname);
550 
551  sce->nodetree->chunksize = 256;
554 
556  out->locx = 300.0f;
557  out->locy = 400.0f;
558 
560  in->locx = 10.0f;
561  in->locy = 400.0f;
562  nodeSetActive(sce->nodetree, in);
563 
564  /* links from color to color */
565  bNodeSocket *fromsock = in->outputs.first;
566  bNodeSocket *tosock = out->inputs.first;
567  nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
568 
570 }
571 
572 /* assumes nothing being done in ntree yet, sets the default in/out node */
573 /* called from shading buttons or header */
575 {
576  /* but lets check it anyway */
577  if (tex->nodetree) {
578  if (G.debug & G_DEBUG) {
579  printf("error in texture initialize\n");
580  }
581  return;
582  }
583 
584  tex->nodetree = ntreeAddTree(NULL, "Texture Nodetree", ntreeType_Texture->idname);
585 
587  out->locx = 300.0f;
588  out->locy = 300.0f;
589 
591  in->locx = 10.0f;
592  in->locy = 300.0f;
593  nodeSetActive(tex->nodetree, in);
594 
595  bNodeSocket *fromsock = in->outputs.first;
596  bNodeSocket *tosock = out->inputs.first;
597  nodeAddLink(tex->nodetree, in, fromsock, out, tosock);
598 
600 }
601 
602 /* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */
604 {
605  SpaceNode *snode = CTX_wm_space_node(C);
606  bNodeTreeType *treetype = ntreeTypeFind(snode->tree_idname);
607  bNodeTree *ntree = snode->nodetree;
608  ID *id = snode->id, *from = snode->from;
609 
610  /* check the tree type */
611  if (!treetype || (treetype->poll && !treetype->poll(C, treetype))) {
612  /* invalid tree type, skip
613  * NB: not resetting the node path here, invalid bNodeTreeType
614  * may still be registered at a later point.
615  */
616  return;
617  }
618 
619  if (snode->nodetree && !STREQ(snode->nodetree->idname, snode->tree_idname)) {
620  /* current tree does not match selected type, clear tree path */
621  ntree = NULL;
622  id = NULL;
623  from = NULL;
624  }
625 
626  if (!(snode->flag & SNODE_PIN) || ntree == NULL) {
627  if (treetype->get_from_context) {
628  /* reset and update from context */
629  ntree = NULL;
630  id = NULL;
631  from = NULL;
632 
633  treetype->get_from_context(C, treetype, &ntree, &id, &from);
634  }
635  }
636 
637  if (snode->nodetree != ntree || snode->id != id || snode->from != from ||
638  (snode->treepath.last == NULL && ntree)) {
639  ED_node_tree_start(snode, ntree, id, from);
640  }
641 }
642 
644 {
645  /* XXX this only updates nodes in the current node space tree path.
646  * The function supposedly should update any potential group node linking to changed tree,
647  * this really requires a working depsgraph ...
648  */
649 
650  /* update all edited group nodes */
651  bNodeTreePath *path = snode->treepath.last;
652  if (path) {
653  bNodeTree *ngroup = path->nodetree;
654  for (path = path->prev; path; path = path->prev) {
655  nodeUpdateID(path->nodetree, (ID *)ngroup);
656  ngroup = path->nodetree;
657  }
658  }
659 
660  if (node) {
661  nodeUpdate(snode->edittree, node);
662  }
663 }
664 
665 void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
666 {
667  const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0;
668  if (r_active_texture_changed) {
669  *r_active_texture_changed = false;
670  }
671 
673 
674  if (node->type != NODE_GROUP) {
675  const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0;
676  bool do_update = false;
677 
678  /* generic node group output: set node as active output */
679  if (node->type == NODE_GROUP_OUTPUT) {
680  LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
681  if (node_iter->type == NODE_GROUP_OUTPUT) {
682  node_iter->flag &= ~NODE_DO_OUTPUT;
683  }
684  }
685 
686  node->flag |= NODE_DO_OUTPUT;
687  if (!was_output) {
688  do_update = 1;
689  }
690  }
691 
692  /* tree specific activate calls */
693  if (ntree->type == NTREE_SHADER) {
694  /* when we select a material, active texture is cleared, for buttons */
695  if (node->id && ELEM(GS(node->id->name), ID_MA, ID_LA, ID_WO)) {
697  }
698 
699  if (ELEM(node->type,
704  LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
705  if (node_iter->type == node->type) {
706  node_iter->flag &= ~NODE_DO_OUTPUT;
707  }
708  }
709 
710  node->flag |= NODE_DO_OUTPUT;
711  if (was_output == 0) {
713  }
714  }
715  else if (do_update) {
717  }
718 
719  /* if active texture changed, free glsl materials */
720  if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
721  LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
722  if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) {
723  GPU_material_free(&ma->gpumaterial);
724  }
725  }
726 
727  LISTBASE_FOREACH (World *, wo, &bmain->worlds) {
728  if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) {
729  GPU_material_free(&wo->gpumaterial);
730  }
731  }
732 
733  if (r_active_texture_changed) {
734  *r_active_texture_changed = true;
735  }
738  }
739 
741  }
742  else if (ntree->type == NTREE_COMPOSIT) {
743  /* make active viewer, currently only 1 supported... */
745  LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
746  if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
747  node_iter->flag &= ~NODE_DO_OUTPUT;
748  }
749  }
750 
751  node->flag |= NODE_DO_OUTPUT;
752  if (was_output == 0) {
754  }
755 
756  /* addnode() doesn't link this yet... */
757  node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
758  }
759  else if (node->type == CMP_NODE_COMPOSITE) {
760  if (was_output == 0) {
761  LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
762  if (node_iter->type == CMP_NODE_COMPOSITE) {
763  node_iter->flag &= ~NODE_DO_OUTPUT;
764  }
765  }
766 
767  node->flag |= NODE_DO_OUTPUT;
769  }
770  }
771  else if (do_update) {
773  }
774  }
775  else if (ntree->type == NTREE_TEXTURE) {
776  /* XXX */
777 #if 0
778  if (node->id) {
779  BIF_preview_changed(-1);
780  allqueue(REDRAWBUTSSHADING, 1);
781  allqueue(REDRAWIPO, 0);
782  }
783 #endif
784  }
785  }
786 }
787 
789 {
790  /* XXX This does not work due to layout functions relying on node->block,
791  * which only exists during actual drawing. Can we rely on valid totr rects?
792  */
793  /* make sure nodes have correct bounding boxes after transform */
794  // node_update_nodetree(C, ntree, 0.0f, 0.0f);
795 }
796 
797 /* ***************** generic operator functions for nodes ***************** */
798 
799 #if 0 /* UNUSED */
800 
801 static bool edit_node_poll(bContext *C)
802 {
803  return ED_operator_node_active(C);
804 }
805 
806 static void edit_node_properties(wmOperatorType *ot)
807 {
808  /* XXX could node be a context pointer? */
809  RNA_def_string(ot->srna, "node", NULL, MAX_NAME, "Node", "");
810  RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET);
811  RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Side", "");
812 }
813 
814 static int edit_node_invoke_properties(bContext *C, wmOperator *op)
815 {
816  if (!RNA_struct_property_is_set(op->ptr, "node")) {
818  if (!node) {
819  return 0;
820  }
821  else {
822  RNA_string_set(op->ptr, "node", node->name);
823  }
824  }
825 
826  if (!RNA_struct_property_is_set(op->ptr, "in_out")) {
827  RNA_enum_set(op->ptr, "in_out", SOCK_IN);
828  }
829 
830  if (!RNA_struct_property_is_set(op->ptr, "socket")) {
831  RNA_int_set(op->ptr, "socket", 0);
832  }
833 
834  return 1;
835 }
836 
837 static void edit_node_properties_get(
838  wmOperator *op, bNodeTree *ntree, bNode **r_node, bNodeSocket **r_sock, int *r_in_out)
839 {
840  bNode *node;
841  bNodeSocket *sock = NULL;
842  char nodename[MAX_NAME];
843  int sockindex;
844  int in_out;
845 
846  RNA_string_get(op->ptr, "node", nodename);
847  node = nodeFindNodebyName(ntree, nodename);
848 
849  in_out = RNA_enum_get(op->ptr, "in_out");
850 
851  sockindex = RNA_int_get(op->ptr, "socket");
852  switch (in_out) {
853  case SOCK_IN:
854  sock = BLI_findlink(&node->inputs, sockindex);
855  break;
856  case SOCK_OUT:
857  sock = BLI_findlink(&node->outputs, sockindex);
858  break;
859  }
860 
861  if (r_node) {
862  *r_node = node;
863  }
864  if (r_sock) {
865  *r_sock = sock;
866  }
867  if (r_in_out) {
868  *r_in_out = in_out;
869  }
870 }
871 #endif
872 
873 /* ************************** Node generic ************** */
874 
875 /* is rct in visible part of node? */
876 static bNode *visible_node(SpaceNode *snode, const rctf *rct)
877 {
879  if (BLI_rctf_isect(&node->totr, rct, NULL)) {
880  return node;
881  }
882  }
883  return NULL;
884 }
885 
886 /* ********************** size widget operator ******************** */
887 
888 typedef struct NodeSizeWidget {
889  float mxstart, mystart;
890  float oldlocx, oldlocy;
895 
896 static void node_resize_init(
897  bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
898 {
899  SpaceNode *snode = CTX_wm_space_node(C);
900 
901  NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
902 
903  op->customdata = nsw;
904  nsw->mxstart = snode->runtime->cursor[0] * UI_DPI_FAC;
905  nsw->mystart = snode->runtime->cursor[1] * UI_DPI_FAC;
906 
907  /* store old */
908  nsw->oldlocx = node->locx;
909  nsw->oldlocy = node->locy;
910  nsw->oldoffsetx = node->offsetx;
911  nsw->oldoffsety = node->offsety;
912  nsw->oldwidth = node->width;
913  nsw->oldheight = node->height;
914  nsw->directions = dir;
915 
917  /* add modal handler */
919 }
920 
921 static void node_resize_exit(bContext *C, wmOperator *op, bool cancel)
922 {
924 
925  /* Restore old data on cancel. */
926  if (cancel) {
927  SpaceNode *snode = CTX_wm_space_node(C);
928  bNode *node = nodeGetActive(snode->edittree);
929  NodeSizeWidget *nsw = op->customdata;
930 
931  node->locx = nsw->oldlocx;
932  node->locy = nsw->oldlocy;
933  node->offsetx = nsw->oldoffsetx;
934  node->offsety = nsw->oldoffsety;
935  node->width = nsw->oldwidth;
936  node->height = nsw->oldheight;
937  }
938 
939  MEM_freeN(op->customdata);
940  op->customdata = NULL;
941 }
942 
943 static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
944 {
945  SpaceNode *snode = CTX_wm_space_node(C);
946  ARegion *region = CTX_wm_region(C);
947  bNode *node = nodeGetActive(snode->edittree);
948  NodeSizeWidget *nsw = op->customdata;
949 
950  switch (event->type) {
951  case MOUSEMOVE: {
952  float mx, my;
953  UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &mx, &my);
954  float dx = (mx - nsw->mxstart) / UI_DPI_FAC;
955  float dy = (my - nsw->mystart) / UI_DPI_FAC;
956 
957  if (node) {
958  float *pwidth = &node->width;
959  float oldwidth = nsw->oldwidth;
960  float widthmin = node->typeinfo->minwidth;
961  float widthmax = node->typeinfo->maxwidth;
962 
963  {
964  if (nsw->directions & NODE_RESIZE_RIGHT) {
965  *pwidth = oldwidth + dx;
966  CLAMP(*pwidth, widthmin, widthmax);
967  }
968  if (nsw->directions & NODE_RESIZE_LEFT) {
969  float locmax = nsw->oldlocx + oldwidth;
970 
971  node->locx = nsw->oldlocx + dx;
972  CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
973  *pwidth = locmax - node->locx;
974  }
975  }
976 
977  /* height works the other way round ... */
978  {
979  float heightmin = UI_DPI_FAC * node->typeinfo->minheight;
980  float heightmax = UI_DPI_FAC * node->typeinfo->maxheight;
981  if (nsw->directions & NODE_RESIZE_TOP) {
982  float locmin = nsw->oldlocy - nsw->oldheight;
983 
984  node->locy = nsw->oldlocy + dy;
985  CLAMP(node->locy, locmin + heightmin, locmin + heightmax);
986  node->height = node->locy - locmin;
987  }
988  if (nsw->directions & NODE_RESIZE_BOTTOM) {
989  node->height = nsw->oldheight - dy;
990  CLAMP(node->height, heightmin, heightmax);
991  }
992  }
993 
994  /* XXX make callback? */
995  if (node->type == NODE_FRAME) {
996  /* keep the offset symmetric around center point */
997  if (nsw->directions & NODE_RESIZE_LEFT) {
998  node->locx = nsw->oldlocx + 0.5f * dx;
999  node->offsetx = nsw->oldoffsetx + 0.5f * dx;
1000  }
1001  if (nsw->directions & NODE_RESIZE_RIGHT) {
1002  node->locx = nsw->oldlocx + 0.5f * dx;
1003  node->offsetx = nsw->oldoffsetx - 0.5f * dx;
1004  }
1005  if (nsw->directions & NODE_RESIZE_TOP) {
1006  node->locy = nsw->oldlocy + 0.5f * dy;
1007  node->offsety = nsw->oldoffsety + 0.5f * dy;
1008  }
1009  if (nsw->directions & NODE_RESIZE_BOTTOM) {
1010  node->locy = nsw->oldlocy + 0.5f * dy;
1011  node->offsety = nsw->oldoffsety - 0.5f * dy;
1012  }
1013  }
1014  }
1015 
1016  ED_region_tag_redraw(region);
1017 
1018  break;
1019  }
1020  case LEFTMOUSE:
1021  case MIDDLEMOUSE:
1022  case RIGHTMOUSE: {
1023  if (event->val == KM_RELEASE) {
1024  node_resize_exit(C, op, false);
1026 
1027  return OPERATOR_FINISHED;
1028  }
1029  if (event->val == KM_PRESS) {
1030  node_resize_exit(C, op, true);
1031  ED_region_tag_redraw(region);
1032 
1033  return OPERATOR_CANCELLED;
1034  }
1035  break;
1036  }
1037  }
1038 
1039  return OPERATOR_RUNNING_MODAL;
1040 }
1041 
1042 static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1043 {
1044  SpaceNode *snode = CTX_wm_space_node(C);
1045  ARegion *region = CTX_wm_region(C);
1046  bNode *node = nodeGetActive(snode->edittree);
1047  int dir;
1048 
1049  if (node) {
1050  float cursor[2];
1051 
1052  /* convert mouse coordinates to v2d space */
1053  UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
1054  dir = node->typeinfo->resize_area_func(node, cursor[0], cursor[1]);
1055  if (dir != 0) {
1056  node_resize_init(C, op, event, node, dir);
1057  return OPERATOR_RUNNING_MODAL;
1058  }
1059  }
1061 }
1062 
1064 {
1065  node_resize_exit(C, op, true);
1066 }
1067 
1069 {
1070  /* identifiers */
1071  ot->name = "Resize Node";
1072  ot->idname = "NODE_OT_resize";
1073  ot->description = "Resize a node";
1074 
1075  /* api callbacks */
1080 
1081  /* flags */
1082  ot->flag = OPTYPE_BLOCKING;
1083 }
1084 
1085 /* ********************** hidden sockets ******************** */
1086 
1088 {
1089  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1090  if (sock->flag & SOCK_HIDDEN) {
1091  return true;
1092  }
1093  }
1094  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1095  if (sock->flag & SOCK_HIDDEN) {
1096  return true;
1097  }
1098  }
1099  return false;
1100 }
1101 
1103 {
1104  if (set == 0) {
1105  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1106  sock->flag &= ~SOCK_HIDDEN;
1107  }
1108  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1109  sock->flag &= ~SOCK_HIDDEN;
1110  }
1111  }
1112  else {
1113  /* hide unused sockets */
1114  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1115  if (sock->link == NULL) {
1116  sock->flag |= SOCK_HIDDEN;
1117  }
1118  }
1119  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1120  if (nodeCountSocketLinks(snode->edittree, sock) == 0) {
1121  sock->flag |= SOCK_HIDDEN;
1122  }
1123  }
1124  }
1125 }
1126 
1127 /* checks snode->mouse position, and returns found node/socket */
1128 static bool cursor_isect_multi_input_socket(const float cursor[2], const bNodeSocket *socket)
1129 {
1130  const float node_socket_height = node_socket_calculate_height(socket);
1131  const rctf multi_socket_rect = {
1132  .xmin = socket->locx - NODE_SOCKSIZE * 4.0f,
1133  .xmax = socket->locx + NODE_SOCKSIZE * 2.0f,
1134  /*.xmax = socket->locx + NODE_SOCKSIZE * 5.5f
1135  * would be the same behavior as for regular sockets.
1136  * But keep it smaller because for multi-input socket you
1137  * sometimes want to drag the link to the other side, if you may
1138  * accidentally pick the wrong link otherwise. */
1139  .ymin = socket->locy - node_socket_height,
1140  .ymax = socket->locy + node_socket_height,
1141  };
1142  if (BLI_rctf_isect_pt(&multi_socket_rect, cursor[0], cursor[1])) {
1143  return true;
1144  }
1145  return false;
1146 }
1147 
1148 /* type is SOCK_IN and/or SOCK_OUT */
1150  SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, const float cursor[2], int in_out)
1151 {
1152  rctf rect;
1153 
1154  *nodep = NULL;
1155  *sockp = NULL;
1156 
1157  /* check if we click in a socket */
1158  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1159  BLI_rctf_init_pt_radius(&rect, cursor, NODE_SOCKSIZE + 4);
1160 
1161  if (!(node->flag & NODE_HIDDEN)) {
1162  /* extra padding inside and out - allow dragging on the text areas too */
1163  if (in_out == SOCK_IN) {
1164  rect.xmax += NODE_SOCKSIZE;
1165  rect.xmin -= NODE_SOCKSIZE * 4;
1166  }
1167  else if (in_out == SOCK_OUT) {
1168  rect.xmax += NODE_SOCKSIZE * 4;
1169  rect.xmin -= NODE_SOCKSIZE;
1170  }
1171  }
1172 
1173  if (in_out & SOCK_IN) {
1174  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
1175  if (!nodeSocketIsHidden(sock)) {
1176  if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) {
1177  if (cursor_isect_multi_input_socket(cursor, sock)) {
1178  if (node == visible_node(snode, &rect)) {
1179  *nodep = node;
1180  *sockp = sock;
1181  return 1;
1182  }
1183  }
1184  }
1185  else if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1186  if (node == visible_node(snode, &rect)) {
1187  *nodep = node;
1188  *sockp = sock;
1189  return 1;
1190  }
1191  }
1192  }
1193  }
1194  }
1195  if (in_out & SOCK_OUT) {
1196  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
1197  if (!nodeSocketIsHidden(sock)) {
1198  if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1199  if (node == visible_node(snode, &rect)) {
1200  *nodep = node;
1201  *sockp = sock;
1202  return 1;
1203  }
1204  }
1205  }
1206  }
1207  }
1208  }
1209 
1210  return 0;
1211 }
1212 
1213 /* ****************** Duplicate *********************** */
1214 
1216 {
1217  bNode *parent;
1218 
1219  node->flag |= NODE_TEST;
1220 
1221  /* find first selected parent */
1222  for (parent = node->parent; parent; parent = parent->parent) {
1223  if (parent->flag & SELECT) {
1224  if (!(parent->flag & NODE_TEST)) {
1226  }
1227  break;
1228  }
1229  }
1230  /* reparent node copy to parent copy */
1231  if (parent) {
1232  nodeDetachNode(node->new_node);
1233  nodeAttachNode(node->new_node, parent->new_node);
1234  }
1235 }
1236 
1238 {
1239  Main *bmain = CTX_data_main(C);
1240  SpaceNode *snode = CTX_wm_space_node(C);
1241  bNodeTree *ntree = snode->edittree;
1242  const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
1243  bool do_tag_update = false;
1244 
1246 
1247  bNode *lastnode = ntree->nodes.last;
1249  if (node->flag & SELECT) {
1251 
1252  /* To ensure redraws or re-renders happen. */
1253  ED_node_tag_update_id(snode->id);
1254  }
1255 
1256  /* make sure we don't copy new nodes again! */
1257  if (node == lastnode) {
1258  break;
1259  }
1260  }
1261 
1262  /* copy links between selected nodes
1263  * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
1264  */
1265  bNodeLink *lastlink = ntree->links.last;
1266  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
1267  /* This creates new links between copied nodes.
1268  * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)!
1269  */
1270  if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
1271  (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) {
1272  bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
1273  newlink->flag = link->flag;
1274  newlink->tonode = link->tonode->new_node;
1275  newlink->tosock = link->tosock->new_sock;
1276  if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
1277  newlink->fromnode = link->fromnode->new_node;
1278  newlink->fromsock = link->fromsock->new_sock;
1279  }
1280  else {
1281  /* input node not copied, this keeps the original input linked */
1282  newlink->fromnode = link->fromnode;
1283  newlink->fromsock = link->fromsock;
1284  }
1285 
1286  BLI_addtail(&ntree->links, newlink);
1287  }
1288 
1289  /* make sure we don't copy new links again! */
1290  if (link == lastlink) {
1291  break;
1292  }
1293  }
1294 
1295  /* clear flags for recursive depth-first iteration */
1297  node->flag &= ~NODE_TEST;
1298  }
1299  /* reparent copied nodes */
1301  if ((node->flag & SELECT) && !(node->flag & NODE_TEST)) {
1303  }
1304 
1305  /* only has to check old nodes */
1306  if (node == lastnode) {
1307  break;
1308  }
1309  }
1310 
1311  /* deselect old nodes, select the copies instead */
1313  if (node->flag & SELECT) {
1314  /* has been set during copy above */
1315  bNode *newnode = node->new_node;
1316 
1317  nodeSetSelected(node, false);
1318  node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE);
1319  nodeSetSelected(newnode, true);
1320  newnode->flag &= ~NODE_ACTIVE_PREVIEW;
1321 
1322  do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode));
1323  }
1324 
1325  /* make sure we don't copy new nodes again! */
1326  if (node == lastnode) {
1327  break;
1328  }
1329  }
1330 
1332 
1333  snode_notify(C, snode);
1334  if (do_tag_update) {
1335  snode_dag_update(C, snode);
1336  }
1337 
1338  return OPERATOR_FINISHED;
1339 }
1340 
1342 {
1343  /* identifiers */
1344  ot->name = "Duplicate Nodes";
1345  ot->description = "Duplicate selected nodes";
1346  ot->idname = "NODE_OT_duplicate";
1347 
1348  /* api callbacks */
1351 
1352  /* flags */
1354 
1356  ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
1357 }
1358 
1360 {
1361  LISTBASE_FOREACH (bNode *, node, lb) {
1362  if (node->flag & NODE_SELECT) {
1363  return true;
1364  }
1365  }
1366 
1367  return false;
1368 }
1369 
1370 void ED_node_select_all(ListBase *lb, int action)
1371 {
1372  if (action == SEL_TOGGLE) {
1373  if (ED_node_select_check(lb)) {
1374  action = SEL_DESELECT;
1375  }
1376  else {
1377  action = SEL_SELECT;
1378  }
1379  }
1380 
1381  LISTBASE_FOREACH (bNode *, node, lb) {
1382  switch (action) {
1383  case SEL_SELECT:
1384  nodeSetSelected(node, true);
1385  break;
1386  case SEL_DESELECT:
1387  nodeSetSelected(node, false);
1388  break;
1389  case SEL_INVERT:
1390  nodeSetSelected(node, !(node->flag & SELECT));
1391  break;
1392  }
1393  }
1394 }
1395 
1396 /* ******************************** */
1397 /* XXX some code needing updating to operators. */
1398 
1399 /* goes over all scenes, reads render layers */
1401 {
1402  Main *bmain = CTX_data_main(C);
1403  SpaceNode *snode = CTX_wm_space_node(C);
1404  Scene *curscene = CTX_data_scene(C);
1405 
1407 
1408  /* first tag scenes unread */
1409  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1410  scene->id.tag |= LIB_TAG_DOIT;
1411  }
1412 
1413  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1414  if ((node->type == CMP_NODE_R_LAYERS) ||
1415  (node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER)) {
1416  ID *id = node->id;
1417  if (id == NULL) {
1418  continue;
1419  }
1420  if (id->tag & LIB_TAG_DOIT) {
1421  RE_ReadRenderResult(curscene, (Scene *)id);
1423  id->tag &= ~LIB_TAG_DOIT;
1424  }
1425  }
1426  }
1427 
1428  snode_notify(C, snode);
1429  snode_dag_update(C, snode);
1430 
1431  return OPERATOR_FINISHED;
1432 }
1433 
1435 {
1436 
1437  ot->name = "Read View Layers";
1438  ot->idname = "NODE_OT_read_viewlayers";
1439  ot->description = "Read all render layers of all used scenes";
1440 
1442 
1444 
1445  /* flags */
1446  ot->flag = 0;
1447 }
1448 
1450 {
1451  Scene *sce = CTX_data_scene(C);
1452 
1453  /* This is actually a test whether scene is used by the compositor or not.
1454  * All the nodes are using same render result, so there is no need to do
1455  * anything smart about check how exactly scene is used. */
1456  bNode *node = NULL;
1457  LISTBASE_FOREACH (bNode *, node_iter, &sce->nodetree->nodes) {
1458  if (node_iter->id == (ID *)sce) {
1459  node = node_iter;
1460  break;
1461  }
1462  }
1463 
1464  if (node) {
1465  ViewLayer *view_layer = BLI_findlink(&sce->view_layers, node->custom1);
1466 
1467  if (view_layer) {
1468  PointerRNA op_ptr;
1469 
1470  WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
1471  RNA_string_set(&op_ptr, "layer", view_layer->name);
1472  RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
1473 
1474  /* to keep keypositions */
1475  sce->r.scemode |= R_NO_FRAME_UPDATE;
1476 
1477  WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr);
1478 
1479  WM_operator_properties_free(&op_ptr);
1480 
1481  return OPERATOR_FINISHED;
1482  }
1483  }
1484  return OPERATOR_CANCELLED;
1485 }
1486 
1488 {
1489  ot->name = "Render Changed Layer";
1490  ot->idname = "NODE_OT_render_changed";
1491  ot->description = "Render current scene, when input node's layer has been changed";
1492 
1494 
1496 
1497  /* flags */
1498  ot->flag = 0;
1499 }
1500 
1501 /* ****************** Hide operator *********************** */
1502 
1503 static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
1504 {
1505  int tot_eq = 0, tot_neq = 0;
1506 
1507  /* Toggles the flag on all selected nodes.
1508  * If the flag is set on all nodes it is unset.
1509  * If the flag is not set on all nodes, it is set.
1510  */
1511 
1512  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1513  if (node->flag & SELECT) {
1514 
1515  if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) {
1516  continue;
1517  }
1518  if (toggle_flag == NODE_OPTIONS &&
1519  !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex)) {
1520  continue;
1521  }
1522 
1523  if (node->flag & toggle_flag) {
1524  tot_eq++;
1525  }
1526  else {
1527  tot_neq++;
1528  }
1529  }
1530  }
1531  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1532  if (node->flag & SELECT) {
1533 
1534  if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) {
1535  continue;
1536  }
1537  if (toggle_flag == NODE_OPTIONS &&
1538  !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex)) {
1539  continue;
1540  }
1541 
1542  if ((tot_eq && tot_neq) || tot_eq == 0) {
1543  node->flag |= toggle_flag;
1544  }
1545  else {
1546  node->flag &= ~toggle_flag;
1547  }
1548  }
1549  }
1550 }
1551 
1553 {
1554  SpaceNode *snode = CTX_wm_space_node(C);
1555 
1556  /* sanity checking (poll callback checks this already) */
1557  if ((snode == NULL) || (snode->edittree == NULL)) {
1558  return OPERATOR_CANCELLED;
1559  }
1560 
1562 
1564 
1565  return OPERATOR_FINISHED;
1566 }
1567 
1569 {
1570  /* identifiers */
1571  ot->name = "Hide";
1572  ot->description = "Toggle hiding of selected nodes";
1573  ot->idname = "NODE_OT_hide_toggle";
1574 
1575  /* callbacks */
1578 
1579  /* flags */
1581 }
1582 
1584 {
1585  SpaceNode *snode = CTX_wm_space_node(C);
1586 
1587  /* sanity checking (poll callback checks this already) */
1588  if ((snode == NULL) || (snode->edittree == NULL)) {
1589  return OPERATOR_CANCELLED;
1590  }
1591 
1593 
1595 
1596  snode_notify(C, snode);
1597 
1598  return OPERATOR_FINISHED;
1599 }
1600 
1602 {
1603  /* identifiers */
1604  ot->name = "Toggle Node Preview";
1605  ot->description = "Toggle preview display for selected nodes";
1606  ot->idname = "NODE_OT_preview_toggle";
1607 
1608  /* callbacks */
1611 
1612  /* flags */
1614 }
1615 
1617 {
1618  SpaceNode *snode = CTX_wm_space_node(C);
1619 
1620  /* sanity checking (poll callback checks this already) */
1621  if ((snode == NULL) || (snode->edittree == NULL)) {
1622  return OPERATOR_CANCELLED;
1623  }
1624 
1626 
1628 
1629  return OPERATOR_FINISHED;
1630 }
1631 
1633 {
1634  /* identifiers */
1635  ot->name = "Toggle Node Options";
1636  ot->description = "Toggle option buttons display for selected nodes";
1637  ot->idname = "NODE_OT_options_toggle";
1638 
1639  /* callbacks */
1642 
1643  /* flags */
1645 }
1646 
1648 {
1649  SpaceNode *snode = CTX_wm_space_node(C);
1650 
1651  /* sanity checking (poll callback checks this already) */
1652  if ((snode == NULL) || (snode->edittree == NULL)) {
1653  return OPERATOR_CANCELLED;
1654  }
1655 
1657 
1658  /* Toggle for all selected nodes */
1659  bool hidden = false;
1660  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1661  if (node->flag & SELECT) {
1663  hidden = true;
1664  break;
1665  }
1666  }
1667  }
1668 
1669  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1670  if (node->flag & SELECT) {
1671  node_set_hidden_sockets(snode, node, !hidden);
1672  }
1673  }
1674 
1676 
1678 
1679  return OPERATOR_FINISHED;
1680 }
1681 
1683 {
1684  /* identifiers */
1685  ot->name = "Toggle Hidden Node Sockets";
1686  ot->description = "Toggle unused node socket display";
1687  ot->idname = "NODE_OT_hide_socket_toggle";
1688 
1689  /* callbacks */
1692 
1693  /* flags */
1695 }
1696 
1697 /* ****************** Mute operator *********************** */
1698 
1700 {
1701  Main *bmain = CTX_data_main(C);
1702  SpaceNode *snode = CTX_wm_space_node(C);
1703  bool do_tag_update = false;
1704 
1706 
1707  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
1708  /* Only allow muting of nodes having a mute func! */
1709  if ((node->flag & SELECT) && node->typeinfo->update_internal_links) {
1710  node->flag ^= NODE_MUTED;
1711  snode_update(snode, node);
1712  do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node));
1713  }
1714  }
1715 
1716  do_tag_update |= ED_node_is_geometry(snode);
1717 
1718  snode_notify(C, snode);
1719  if (do_tag_update) {
1720  snode_dag_update(C, snode);
1721  }
1722 
1723  return OPERATOR_FINISHED;
1724 }
1725 
1727 {
1728  /* identifiers */
1729  ot->name = "Toggle Node Mute";
1730  ot->description = "Toggle muting of the nodes";
1731  ot->idname = "NODE_OT_mute_toggle";
1732 
1733  /* callbacks */
1734  ot->exec = node_mute_exec;
1736 
1737  /* flags */
1739 }
1740 
1741 /* ****************** Delete operator ******************* */
1742 
1744 {
1745  Main *bmain = CTX_data_main(C);
1746  SpaceNode *snode = CTX_wm_space_node(C);
1747  bool do_tag_update = false;
1748 
1750 
1752  if (node->flag & SELECT) {
1753  do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node));
1754  nodeRemoveNode(bmain, snode->edittree, node, true);
1755  }
1756  }
1757 
1758  do_tag_update |= ED_node_is_geometry(snode);
1759 
1761 
1762  snode_notify(C, snode);
1763  if (do_tag_update) {
1764  snode_dag_update(C, snode);
1765  }
1766 
1767  return OPERATOR_FINISHED;
1768 }
1769 
1771 {
1772  /* identifiers */
1773  ot->name = "Delete";
1774  ot->description = "Delete selected nodes";
1775  ot->idname = "NODE_OT_delete";
1776 
1777  /* api callbacks */
1780 
1781  /* flags */
1783 }
1784 
1785 /* ****************** Switch View ******************* */
1786 
1788 {
1789  SpaceNode *snode = CTX_wm_space_node(C);
1790 
1791  if (snode && snode->edittree) {
1792  return true;
1793  }
1794 
1795  return false;
1796 }
1797 
1799 {
1800  SpaceNode *snode = CTX_wm_space_node(C);
1801 
1803  if (node->flag & SELECT) {
1804  /* call the update function from the Switch View node */
1805  node->update = NODE_UPDATE_OPERATOR;
1806  }
1807  }
1808 
1810 
1811  snode_notify(C, snode);
1812  snode_dag_update(C, snode);
1813 
1814  return OPERATOR_FINISHED;
1815 }
1816 
1818 {
1819  /* identifiers */
1820  ot->name = "Update Views";
1821  ot->description = "Update views of selected node";
1822  ot->idname = "NODE_OT_switch_view_update";
1823 
1824  /* api callbacks */
1827 
1828  /* flags */
1830 }
1831 
1832 /* ****************** Delete with reconnect ******************* */
1834 {
1835  Main *bmain = CTX_data_main(C);
1836  SpaceNode *snode = CTX_wm_space_node(C);
1837 
1839 
1841  if (node->flag & SELECT) {
1842  nodeInternalRelink(snode->edittree, node);
1843  nodeRemoveNode(bmain, snode->edittree, node, true);
1844  }
1845  }
1846 
1848 
1849  snode_notify(C, snode);
1850  snode_dag_update(C, snode);
1851 
1852  return OPERATOR_FINISHED;
1853 }
1854 
1856 {
1857  /* identifiers */
1858  ot->name = "Delete with Reconnect";
1859  ot->description = "Delete nodes; will reconnect nodes as if deletion was muted";
1860  ot->idname = "NODE_OT_delete_reconnect";
1861 
1862  /* api callbacks */
1865 
1866  /* flags */
1868 }
1869 
1870 /* ****************** File Output Add Socket ******************* */
1871 
1873 {
1875  SpaceNode *snode = CTX_wm_space_node(C);
1876  PointerRNA ptr = CTX_data_pointer_get(C, "node");
1877  bNodeTree *ntree = NULL;
1878  bNode *node = NULL;
1879  char file_path[MAX_NAME];
1880 
1881  if (ptr.data) {
1882  node = ptr.data;
1883  ntree = (bNodeTree *)ptr.owner_id;
1884  }
1885  else if (snode && snode->edittree) {
1886  ntree = snode->edittree;
1887  node = nodeGetActive(snode->edittree);
1888  }
1889 
1890  if (!node || node->type != CMP_NODE_OUTPUT_FILE) {
1891  return OPERATOR_CANCELLED;
1892  }
1893 
1894  RNA_string_get(op->ptr, "file_path", file_path);
1896 
1897  snode_notify(C, snode);
1898 
1899  return OPERATOR_FINISHED;
1900 }
1901 
1903 {
1904  /* identifiers */
1905  ot->name = "Add File Node Socket";
1906  ot->description = "Add a new input to a file output node";
1907  ot->idname = "NODE_OT_output_file_add_socket";
1908 
1909  /* callbacks */
1912 
1913  /* flags */
1915 
1917  ot->srna, "file_path", "Image", MAX_NAME, "File Path", "Subpath of the output file");
1918 }
1919 
1920 /* ****************** Multi File Output Remove Socket ******************* */
1921 
1923 {
1924  SpaceNode *snode = CTX_wm_space_node(C);
1925  PointerRNA ptr = CTX_data_pointer_get(C, "node");
1926  bNodeTree *ntree = NULL;
1927  bNode *node = NULL;
1928 
1929  if (ptr.data) {
1930  node = ptr.data;
1931  ntree = (bNodeTree *)ptr.owner_id;
1932  }
1933  else if (snode && snode->edittree) {
1934  ntree = snode->edittree;
1935  node = nodeGetActive(snode->edittree);
1936  }
1937 
1938  if (!node || node->type != CMP_NODE_OUTPUT_FILE) {
1939  return OPERATOR_CANCELLED;
1940  }
1941 
1943  return OPERATOR_CANCELLED;
1944  }
1945 
1946  snode_notify(C, snode);
1947 
1948  return OPERATOR_FINISHED;
1949 }
1950 
1952 {
1953  /* identifiers */
1954  ot->name = "Remove File Node Socket";
1955  ot->description = "Remove active input from a file output node";
1956  ot->idname = "NODE_OT_output_file_remove_active_socket";
1957 
1958  /* callbacks */
1961 
1962  /* flags */
1964 }
1965 
1966 /* ****************** Multi File Output Move Socket ******************* */
1967 
1969 {
1970  SpaceNode *snode = CTX_wm_space_node(C);
1971  PointerRNA ptr = CTX_data_pointer_get(C, "node");
1972  bNode *node = NULL;
1973 
1974  if (ptr.data) {
1975  node = ptr.data;
1976  }
1977  else if (snode && snode->edittree) {
1978  node = nodeGetActive(snode->edittree);
1979  }
1980 
1981  if (!node || node->type != CMP_NODE_OUTPUT_FILE) {
1982  return OPERATOR_CANCELLED;
1983  }
1984 
1985  NodeImageMultiFile *nimf = node->storage;
1986 
1987  bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input);
1988  if (!sock) {
1989  return OPERATOR_CANCELLED;
1990  }
1991 
1992  int direction = RNA_enum_get(op->ptr, "direction");
1993 
1994  if (direction == 1) {
1995  bNodeSocket *before = sock->prev;
1996  if (!before) {
1997  return OPERATOR_CANCELLED;
1998  }
1999  BLI_remlink(&node->inputs, sock);
2000  BLI_insertlinkbefore(&node->inputs, before, sock);
2001  nimf->active_input--;
2002  }
2003  else {
2004  bNodeSocket *after = sock->next;
2005  if (!after) {
2006  return OPERATOR_CANCELLED;
2007  }
2008  BLI_remlink(&node->inputs, sock);
2009  BLI_insertlinkafter(&node->inputs, after, sock);
2010  nimf->active_input++;
2011  }
2012 
2013  snode_notify(C, snode);
2014 
2015  return OPERATOR_FINISHED;
2016 }
2017 
2019 {
2020  static const EnumPropertyItem direction_items[] = {
2021  {1, "UP", 0, "Up", ""}, {2, "DOWN", 0, "Down", ""}, {0, NULL, 0, NULL, NULL}};
2022 
2023  /* identifiers */
2024  ot->name = "Move File Node Socket";
2025  ot->description = "Move the active input of a file output node up or down the list";
2026  ot->idname = "NODE_OT_output_file_move_active_socket";
2027 
2028  /* callbacks */
2031 
2032  /* flags */
2034 
2035  RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", "");
2036 }
2037 
2038 /* ****************** Copy Node Color ******************* */
2039 
2041 {
2042  SpaceNode *snode = CTX_wm_space_node(C);
2043  bNodeTree *ntree = snode->edittree;
2044 
2045  if (!ntree) {
2046  return OPERATOR_CANCELLED;
2047  }
2049  if (!node) {
2050  return OPERATOR_CANCELLED;
2051  }
2052 
2053  LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
2054  if (node_iter->flag & NODE_SELECT && node_iter != node) {
2055  if (node->flag & NODE_CUSTOM_COLOR) {
2056  node_iter->flag |= NODE_CUSTOM_COLOR;
2057  copy_v3_v3(node_iter->color, node->color);
2058  }
2059  else {
2060  node_iter->flag &= ~NODE_CUSTOM_COLOR;
2061  }
2062  }
2063  }
2064 
2067 
2068  return OPERATOR_FINISHED;
2069 }
2070 
2072 {
2073  /* identifiers */
2074  ot->name = "Copy Color";
2075  ot->description = "Copy color to all selected nodes";
2076  ot->idname = "NODE_OT_node_copy_color";
2077 
2078  /* api callbacks */
2081 
2082  /* flags */
2084 }
2085 
2086 /* ****************** Copy to clipboard ******************* */
2087 
2089 {
2090  SpaceNode *snode = CTX_wm_space_node(C);
2091  bNodeTree *ntree = snode->edittree;
2092 
2094 
2095  /* clear current clipboard */
2098 
2100  if (node->flag & SELECT) {
2101  /* No ID refcounting, this node is virtual,
2102  * detached from any actual Blender data currently. */
2105  BKE_node_clipboard_add_node(new_node);
2106  }
2107  }
2108 
2110  if (node->flag & SELECT) {
2111  bNode *new_node = node->new_node;
2112 
2113  /* ensure valid pointers */
2114  if (new_node->parent) {
2115  /* parent pointer must be redirected to new node or detached if parent is
2116  * not copied */
2117  if (new_node->parent->flag & NODE_SELECT) {
2118  new_node->parent = new_node->parent->new_node;
2119  }
2120  else {
2121  nodeDetachNode(new_node);
2122  }
2123  }
2124  }
2125  }
2126 
2127  /* copy links between selected nodes
2128  * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
2129  */
2130  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
2131  /* This creates new links between copied nodes. */
2132  if (link->tonode && (link->tonode->flag & NODE_SELECT) && link->fromnode &&
2133  (link->fromnode->flag & NODE_SELECT)) {
2134  bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
2135  newlink->flag = link->flag;
2136  newlink->tonode = link->tonode->new_node;
2137  newlink->tosock = link->tosock->new_sock;
2138  newlink->fromnode = link->fromnode->new_node;
2139  newlink->fromsock = link->fromsock->new_sock;
2140 
2141  BKE_node_clipboard_add_link(newlink);
2142  }
2143  }
2144 
2145  return OPERATOR_FINISHED;
2146 }
2147 
2149 {
2150  /* identifiers */
2151  ot->name = "Copy to Clipboard";
2152  ot->description = "Copies selected nodes to the clipboard";
2153  ot->idname = "NODE_OT_clipboard_copy";
2154 
2155  /* api callbacks */
2158 
2159  /* flags */
2161 }
2162 
2163 /* ****************** Paste from clipboard ******************* */
2164 
2166 {
2167  SpaceNode *snode = CTX_wm_space_node(C);
2168  bNodeTree *ntree = snode->edittree;
2169 
2170  /* validate pointers in the clipboard */
2171  bool is_clipboard_valid = BKE_node_clipboard_validate();
2172  const ListBase *clipboard_nodes_lb = BKE_node_clipboard_get_nodes();
2173  const ListBase *clipboard_links_lb = BKE_node_clipboard_get_links();
2174 
2175  if (BLI_listbase_is_empty(clipboard_nodes_lb)) {
2176  BKE_report(op->reports, RPT_ERROR, "Clipboard is empty");
2177  return OPERATOR_CANCELLED;
2178  }
2179 
2181  BKE_report(op->reports, RPT_ERROR, "Clipboard nodes are an incompatible type");
2182  return OPERATOR_CANCELLED;
2183  }
2184 
2185  /* only warn */
2186  if (is_clipboard_valid == false) {
2187  BKE_report(op->reports,
2188  RPT_WARNING,
2189  "Some nodes references could not be restored, will be left empty");
2190  }
2191 
2192  /* make sure all clipboard nodes would be valid in the target tree */
2193  bool all_nodes_valid = true;
2194  LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
2195  const char *disabled_hint = NULL;
2196  if (!node->typeinfo->poll_instance ||
2197  !node->typeinfo->poll_instance(node, ntree, &disabled_hint)) {
2198  all_nodes_valid = false;
2199  if (disabled_hint) {
2200  BKE_reportf(op->reports,
2201  RPT_ERROR,
2202  "Cannot add node %s into node tree %s:\n %s",
2203  node->name,
2204  ntree->id.name + 2,
2205  disabled_hint);
2206  }
2207  else {
2208  BKE_reportf(op->reports,
2209  RPT_ERROR,
2210  "Cannot add node %s into node tree %s",
2211  node->name,
2212  ntree->id.name + 2);
2213  }
2214  }
2215  }
2216  if (!all_nodes_valid) {
2217  return OPERATOR_CANCELLED;
2218  }
2219 
2221 
2222  /* deselect old nodes */
2223  node_deselect_all(snode);
2224 
2225  /* calculate "barycenter" for placing on mouse cursor */
2226  float center[2] = {0.0f, 0.0f};
2227  int num_nodes = 0;
2228  LISTBASE_FOREACH_INDEX (bNode *, node, clipboard_nodes_lb, num_nodes) {
2229  center[0] += BLI_rctf_cent_x(&node->totr);
2230  center[1] += BLI_rctf_cent_y(&node->totr);
2231  }
2232  mul_v2_fl(center, 1.0 / num_nodes);
2233 
2234  /* copy nodes from clipboard */
2235  LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
2237 
2238  /* pasted nodes are selected */
2239  nodeSetSelected(new_node, true);
2240  }
2241 
2242  /* reparent copied nodes */
2243  LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
2244  bNode *new_node = node->new_node;
2245  if (new_node->parent) {
2246  new_node->parent = new_node->parent->new_node;
2247  }
2248  }
2249 
2250  LISTBASE_FOREACH (bNodeLink *, link, clipboard_links_lb) {
2252  link->fromnode->new_node,
2253  link->fromsock->new_sock,
2254  link->tonode->new_node,
2255  link->tosock->new_sock);
2256  }
2257 
2258  Main *bmain = CTX_data_main(C);
2259  ntreeUpdateTree(bmain, snode->edittree);
2260 
2261  snode_notify(C, snode);
2262  snode_dag_update(C, snode);
2263  /* Pasting nodes can create arbitrary new relations, because nodes can reference IDs. */
2264  DEG_relations_tag_update(bmain);
2265 
2266  return OPERATOR_FINISHED;
2267 }
2268 
2270 {
2271  /* identifiers */
2272  ot->name = "Paste from Clipboard";
2273  ot->description = "Pastes nodes from the clipboard to the active node tree";
2274  ot->idname = "NODE_OT_clipboard_paste";
2275 
2276  /* api callbacks */
2279 
2280  /* flags */
2282 }
2283 
2284 /********************** Add interface socket operator *********************/
2285 
2287 {
2288  LISTBASE_FOREACH (bNodeSocket *, socket, lb) {
2289  if (socket->flag & SELECT) {
2290  return socket;
2291  }
2292  }
2293  return NULL;
2294 }
2295 
2297 {
2298  SpaceNode *snode = CTX_wm_space_node(C);
2299  bNodeTree *ntree = snode->edittree;
2300 
2301  PointerRNA ntree_ptr;
2302  RNA_id_pointer_create((ID *)ntree, &ntree_ptr);
2303 
2304  const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
2305  ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
2306 
2307  const char *default_name = (in_out == SOCK_IN) ? "Input" : "Output";
2308  bNodeSocket *active_sock = ntree_get_active_interface_socket(sockets);
2309 
2310  bNodeSocket *sock;
2311  if (active_sock) {
2312  /* insert a copy of the active socket right after it */
2314  ntree, in_out, active_sock->idname, active_sock->next, active_sock->name);
2315  /* XXX this only works for actual sockets, not interface templates! */
2316  /*nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr);*/
2317  }
2318  else {
2319  /* XXX TODO define default socket type for a tree! */
2320  sock = ntreeAddSocketInterface(ntree, in_out, "NodeSocketFloat", default_name);
2321  }
2322 
2323  /* Deactivate sockets. */
2324  LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) {
2325  socket_iter->flag &= ~SELECT;
2326  }
2327  /* make the new socket active */
2328  sock->flag |= SELECT;
2329 
2331 
2332  snode_notify(C, snode);
2333  snode_dag_update(C, snode);
2334 
2336 
2337  return OPERATOR_FINISHED;
2338 }
2339 
2341 {
2342  /* identifiers */
2343  ot->name = "Add Node Tree Interface Socket";
2344  ot->description = "Add an input or output socket to the current node tree";
2345  ot->idname = "NODE_OT_tree_socket_add";
2346 
2347  /* api callbacks */
2350 
2351  /* flags */
2353 
2354  RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
2355 }
2356 
2357 /********************** Remove interface socket operator *********************/
2358 
2360 {
2361  SpaceNode *snode = CTX_wm_space_node(C);
2362  bNodeTree *ntree = snode->edittree;
2363  const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
2364 
2366  &ntree->outputs);
2367  if (iosock == NULL) {
2368  return OPERATOR_CANCELLED;
2369  }
2370 
2371  /* preferably next socket becomes active, otherwise try previous socket */
2372  bNodeSocket *active_sock = (iosock->next ? iosock->next : iosock->prev);
2374 
2375  /* set active socket */
2376  if (active_sock) {
2377  active_sock->flag |= SELECT;
2378  }
2379 
2381 
2382  snode_notify(C, snode);
2383  snode_dag_update(C, snode);
2384 
2386 
2387  return OPERATOR_FINISHED;
2388 }
2389 
2391 {
2392  /* identifiers */
2393  ot->name = "Remove Node Tree Interface Socket";
2394  ot->description = "Remove an input or output socket to the current node tree";
2395  ot->idname = "NODE_OT_tree_socket_remove";
2396 
2397  /* api callbacks */
2400 
2401  /* flags */
2403  RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
2404 }
2405 
2406 /********************** Move interface socket operator *********************/
2407 
2409  {1, "UP", 0, "Up", ""},
2410  {2, "DOWN", 0, "Down", ""},
2411  {0, NULL, 0, NULL, NULL},
2412 };
2413 
2415 {
2416  SpaceNode *snode = CTX_wm_space_node(C);
2417  bNodeTree *ntree = snode->edittree;
2418  int direction = RNA_enum_get(op->ptr, "direction");
2419 
2420  const eNodeSocketInOut in_out = RNA_enum_get(op->ptr, "in_out");
2421  ListBase *sockets = in_out == SOCK_IN ? &ntree->inputs : &ntree->outputs;
2422 
2424 
2425  if (iosock == NULL) {
2426  return OPERATOR_CANCELLED;
2427  }
2428 
2429  switch (direction) {
2430  case 1: { /* up */
2431  bNodeSocket *before = iosock->prev;
2432  BLI_remlink(sockets, iosock);
2433  if (before) {
2434  BLI_insertlinkbefore(sockets, before, iosock);
2435  }
2436  else {
2437  BLI_addhead(sockets, iosock);
2438  }
2439  break;
2440  }
2441  case 2: { /* down */
2442  bNodeSocket *after = iosock->next;
2443  BLI_remlink(sockets, iosock);
2444  if (after) {
2445  BLI_insertlinkafter(sockets, after, iosock);
2446  }
2447  else {
2448  BLI_addtail(sockets, iosock);
2449  }
2450  break;
2451  }
2452  }
2453 
2456 
2457  snode_notify(C, snode);
2458  snode_dag_update(C, snode);
2459 
2461 
2462  return OPERATOR_FINISHED;
2463 }
2464 
2466 {
2467  /* identifiers */
2468  ot->name = "Move Node Tree Socket";
2469  ot->description = "Move a socket up or down in the current node tree's sockets stack";
2470  ot->idname = "NODE_OT_tree_socket_move";
2471 
2472  /* api callbacks */
2475 
2476  /* flags */
2478 
2479  RNA_def_enum(ot->srna, "direction", move_direction_items, 1, "Direction", "");
2480  RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
2481 }
2482 
2483 /* ********************** Shader Script Update ******************/
2484 
2486 {
2489  SpaceNode *snode = CTX_wm_space_node(C);
2490 
2491  /* test if we have a render engine that supports shaders scripts */
2492  if (!(type && type->update_script_node)) {
2493  return 0;
2494  }
2495 
2496  /* see if we have a shader script node in context */
2498 
2499  if (!node && snode && snode->edittree) {
2500  node = nodeGetActive(snode->edittree);
2501  }
2502 
2503  if (node && node->type == SH_NODE_SCRIPT) {
2504  NodeShaderScript *nss = node->storage;
2505 
2506  if (node->id || nss->filepath[0]) {
2507  return ED_operator_node_editable(C);
2508  }
2509  }
2510 
2511  /* see if we have a text datablock in context */
2512  Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2513  if (text) {
2514  return 1;
2515  }
2516 
2517  /* we don't check if text datablock is actually in use, too slow for poll */
2518 
2519  return 0;
2520 }
2521 
2522 /* recursively check for script nodes in groups using this text and update */
2525  bNodeTree *ntree,
2526  Text *text)
2527 {
2528  bool found = false;
2529 
2530  ntree->done = true;
2531 
2532  /* update each script that is using this text datablock */
2534  if (node->type == NODE_GROUP) {
2535  bNodeTree *ngroup = (bNodeTree *)node->id;
2536  if (ngroup && !ngroup->done) {
2537  found |= node_shader_script_update_text_recursive(engine, type, ngroup, text);
2538  }
2539  }
2540  else if (node->type == SH_NODE_SCRIPT && node->id == &text->id) {
2541  type->update_script_node(engine, ntree, node);
2542  found = true;
2543  }
2544  }
2545 
2546  return found;
2547 }
2548 
2550 {
2551  Main *bmain = CTX_data_main(C);
2553  SpaceNode *snode = CTX_wm_space_node(C);
2555  bool found = false;
2556 
2557  /* setup render engine */
2559  RenderEngine *engine = RE_engine_create(type);
2560  engine->reports = op->reports;
2561 
2562  /* get node */
2563  bNodeTree *ntree_base = NULL;
2564  bNode *node = NULL;
2565  if (nodeptr.data) {
2566  ntree_base = (bNodeTree *)nodeptr.owner_id;
2567  node = nodeptr.data;
2568  }
2569  else if (snode && snode->edittree) {
2570  ntree_base = snode->edittree;
2571  node = nodeGetActive(snode->edittree);
2572  }
2573 
2574  if (node) {
2575  /* update single node */
2576  type->update_script_node(engine, ntree_base, node);
2577 
2578  found = true;
2579  }
2580  else {
2581  /* update all nodes using text datablock */
2582  Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2583 
2584  if (text) {
2585  /* clear flags for recursion check */
2586  FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
2587  if (ntree->type == NTREE_SHADER) {
2588  ntree->done = false;
2589  }
2590  }
2592 
2593  FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
2594  if (ntree->type == NTREE_SHADER) {
2595  if (!ntree->done) {
2596  found |= node_shader_script_update_text_recursive(engine, type, ntree, text);
2597  }
2598  }
2599  }
2601 
2602  if (!found) {
2603  BKE_report(op->reports, RPT_INFO, "Text not used by any node, no update done");
2604  }
2605  }
2606  }
2607 
2608  RE_engine_free(engine);
2609 
2610  return (found) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
2611 }
2612 
2614 {
2615  /* identifiers */
2616  ot->name = "Script Node Update";
2617  ot->description = "Update shader script node with new sockets and options from the script";
2618  ot->idname = "NODE_OT_shader_script_update";
2619 
2620  /* api callbacks */
2623 
2624  /* flags */
2626 }
2627 
2628 /* ********************** Viewer border ******************/
2629 
2631  ARegion *region,
2632  int x,
2633  int y,
2634  int backdrop_width,
2635  int backdrop_height,
2636  float *fx,
2637  float *fy)
2638 {
2639  float bufx = backdrop_width * snode->zoom;
2640  float bufy = backdrop_height * snode->zoom;
2641 
2642  *fx = (bufx > 0.0f ? ((float)x - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f);
2643  *fy = (bufy > 0.0f ? ((float)y - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f);
2644 }
2645 
2647 {
2648  Main *bmain = CTX_data_main(C);
2649  void *lock;
2650 
2652 
2653  Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
2654  ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
2655 
2656  if (ibuf) {
2657  ARegion *region = CTX_wm_region(C);
2658  SpaceNode *snode = CTX_wm_space_node(C);
2659  bNodeTree *btree = snode->nodetree;
2660  rcti rect;
2661  rctf rectf;
2662 
2663  /* get border from operator */
2665 
2666  /* convert border to unified space within backdrop image */
2668  snode, region, rect.xmin, rect.ymin, ibuf->x, ibuf->y, &rectf.xmin, &rectf.ymin);
2669 
2671  snode, region, rect.xmax, rect.ymax, ibuf->x, ibuf->y, &rectf.xmax, &rectf.ymax);
2672 
2673  /* clamp coordinates */
2674  rectf.xmin = max_ff(rectf.xmin, 0.0f);
2675  rectf.ymin = max_ff(rectf.ymin, 0.0f);
2676  rectf.xmax = min_ff(rectf.xmax, 1.0f);
2677  rectf.ymax = min_ff(rectf.ymax, 1.0f);
2678 
2679  if (rectf.xmin < rectf.xmax && rectf.ymin < rectf.ymax) {
2680  btree->viewer_border = rectf;
2681 
2682  if (rectf.xmin == 0.0f && rectf.ymin == 0.0f && rectf.xmax == 1.0f && rectf.ymax == 1.0f) {
2683  btree->flag &= ~NTREE_VIEWER_BORDER;
2684  }
2685  else {
2686  btree->flag |= NTREE_VIEWER_BORDER;
2687  }
2688 
2689  snode_notify(C, snode);
2691  }
2692  else {
2693  btree->flag &= ~NTREE_VIEWER_BORDER;
2694  }
2695  }
2696 
2697  BKE_image_release_ibuf(ima, ibuf, lock);
2698 
2699  return OPERATOR_FINISHED;
2700 }
2701 
2703 {
2704  /* identifiers */
2705  ot->name = "Viewer Region";
2706  ot->description = "Set the boundaries for viewer operations";
2707  ot->idname = "NODE_OT_viewer_border";
2708 
2709  /* api callbacks */
2715 
2716  /* flags */
2718 
2719  /* properties */
2721 }
2722 
2724 {
2725  SpaceNode *snode = CTX_wm_space_node(C);
2726  bNodeTree *btree = snode->nodetree;
2727 
2728  btree->flag &= ~NTREE_VIEWER_BORDER;
2729  snode_notify(C, snode);
2731 
2732  return OPERATOR_FINISHED;
2733 }
2734 
2736 {
2737  /* identifiers */
2738  ot->name = "Clear Viewer Region";
2739  ot->description = "Clear the boundaries for viewer operations";
2740  ot->idname = "NODE_OT_clear_viewer_border";
2741 
2742  /* api callbacks */
2745 
2746  /* flags */
2748 }
2749 
2750 /* ****************** Cryptomatte Add Socket ******************* */
2751 
2753 {
2754  SpaceNode *snode = CTX_wm_space_node(C);
2755  PointerRNA ptr = CTX_data_pointer_get(C, "node");
2756  bNodeTree *ntree = NULL;
2757  bNode *node = NULL;
2758 
2759  if (ptr.data) {
2760  node = ptr.data;
2761  ntree = (bNodeTree *)ptr.owner_id;
2762  }
2763  else if (snode && snode->edittree) {
2764  ntree = snode->edittree;
2765  node = nodeGetActive(snode->edittree);
2766  }
2767 
2768  if (!node || node->type != CMP_NODE_CRYPTOMATTE_LEGACY) {
2769  return OPERATOR_CANCELLED;
2770  }
2771 
2773 
2774  snode_notify(C, snode);
2775 
2776  return OPERATOR_FINISHED;
2777 }
2778 
2780 {
2781  /* identifiers */
2782  ot->name = "Add Cryptomatte Socket";
2783  ot->description = "Add a new input layer to a Cryptomatte node";
2784  ot->idname = "NODE_OT_cryptomatte_layer_add";
2785 
2786  /* callbacks */
2789 
2790  /* flags */
2792 }
2793 
2794 /* ****************** Cryptomatte Remove Socket ******************* */
2795 
2797 {
2798  SpaceNode *snode = CTX_wm_space_node(C);
2799  PointerRNA ptr = CTX_data_pointer_get(C, "node");
2800  bNodeTree *ntree = NULL;
2801  bNode *node = NULL;
2802 
2803  if (ptr.data) {
2804  node = ptr.data;
2805  ntree = (bNodeTree *)ptr.owner_id;
2806  }
2807  else if (snode && snode->edittree) {
2808  ntree = snode->edittree;
2809  node = nodeGetActive(snode->edittree);
2810  }
2811 
2812  if (!node || node->type != CMP_NODE_CRYPTOMATTE_LEGACY) {
2813  return OPERATOR_CANCELLED;
2814  }
2815 
2817  return OPERATOR_CANCELLED;
2818  }
2819 
2820  snode_notify(C, snode);
2821 
2822  return OPERATOR_FINISHED;
2823 }
2824 
2826 {
2827  /* identifiers */
2828  ot->name = "Remove Cryptomatte Socket";
2829  ot->description = "Remove layer from a Cryptomatte node";
2830  ot->idname = "NODE_OT_cryptomatte_layer_remove";
2831 
2832  /* callbacks */
2835 
2836  /* flags */
2838 }
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
Definition: context.c:445
struct SpaceNode * CTX_wm_space_node(const bContext *C)
Definition: context.c:854
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Definition: context.c:456
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
@ G_DEBUG
Definition: BKE_global.h:133
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
Definition: image.c:5113
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
Definition: image.c:5100
void BKE_image_backup_render(struct Scene *scene, struct Image *ima, bool free_current_slot)
Definition: image.c:3971
struct Image * BKE_image_ensure_viewer(struct Main *bmain, int type, const char *name)
Definition: image.c:3162
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
@ LIB_ID_COPY_DEFAULT
Definition: BKE_lib_id.h:139
General operations, lookup, etc. for materials.
struct Material * BKE_material_default_surface(void)
Definition: material.c:1829
struct Material * BKE_material_default_volume(void)
Definition: material.c:1834
void BKE_node_clipboard_init(const struct bNodeTree *ntree)
Definition: node.cc:3783
const struct ListBase * BKE_node_clipboard_get_links(void)
Definition: node.cc:3889
void BKE_node_clipboard_add_node(struct bNode *node)
Definition: node.cc:3849
#define SH_NODE_OUTPUT_WORLD
Definition: BKE_node.h:996
void nodeClearActiveID(struct bNodeTree *ntree, short idtype)
Definition: node.cc:3651
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:2364
#define SH_NODE_EMISSION
Definition: BKE_node.h:1009
struct bNodeTreeType * ntreeTypeFind(const char *idname)
Definition: node.cc:1207
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup)
void ntreeCompositTagRender(struct Scene *scene)
int ntreeCompositOutputFileRemoveActiveSocket(struct bNodeTree *ntree, struct bNode *node)
const struct ListBase * BKE_node_clipboard_get_nodes(void)
Definition: node.cc:3884
#define NODE_RESIZE_TOP
Definition: BKE_node.h:364
void nodeUpdate(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:4326
void ntreeRemoveSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *sock)
Definition: node.cc:3370
void ntreeCompositExecTree(struct Scene *scene, struct bNodeTree *ntree, struct RenderData *rd, int rendering, int do_previews, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, const char *view_name)
void nodeAttachNode(struct bNode *node, struct bNode *parent)
Definition: node.cc:2449
struct bNode * nodeFindNodebyName(struct bNodeTree *ntree, const char *name)
Definition: node.cc:1817
struct bNode * nodeGetActive(struct bNodeTree *ntree)
Definition: node.cc:3561
int nodeSocketIsHidden(const struct bNodeSocket *sock)
bool nodeUpdateID(struct bNodeTree *ntree, struct ID *id)
Definition: node.cc:4346
void nodeRemoveNode(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node, bool do_id_user)
Definition: node.cc:2932
int BKE_node_clipboard_get_type(void)
Definition: node.cc:3894
struct bNodeSocket * ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node, const char *name, struct ImageFormatData *im_format)
void BKE_node_clipboard_add_link(struct bNodeLink *link)
Definition: node.cc:3879
int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node)
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree)
Definition: node.cc:4262
struct bNode * BKE_node_copy_store_new_pointers(struct bNodeTree *ntree, struct bNode *node_src, const int flag)
Definition: node.cc:2155
#define CMP_NODE_CRYPTOMATTE_LEGACY
Definition: BKE_node.h:1225
#define CMP_NODE_OUTPUT_FILE
Definition: BKE_node.h:1154
#define FOREACH_NODETREE_END
Definition: BKE_node.h:945
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
Definition: node.cc:2189
#define SH_NODE_BACKGROUND
Definition: BKE_node.h:1001
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
struct bNodeTree * ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree)
void ntreeLocalMerge(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree)
Definition: node.cc:3238
void nodeSetSelected(struct bNode *node, bool select)
Definition: node.cc:3664
#define NODE_RESIZE_BOTTOM
Definition: BKE_node.h:365
#define MAX_SOCKET
Definition: BKE_node.h:41
#define TEX_NODE_OUTPUT
Definition: BKE_node.h:1325
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition: BKE_node.h:935
#define CMP_CRYPTOMATTE_SRC_RENDER
Definition: BKE_node.h:1259
bNodeSocket * ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node)
struct bNodeTree * ntreeAddTree(struct Main *bmain, const char *name, const char *idname)
Definition: node.cc:2529
#define NODE_FRAME
Definition: BKE_node.h:872
struct bNodeSocket * ntreeAddSocketInterface(struct bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, const char *name)
Definition: node.cc:3302
struct bNode * nodeAddStaticNode(const struct bContext *C, struct bNodeTree *ntree, int type)
Definition: node.cc:2004
#define CMP_NODE_R_LAYERS
Definition: BKE_node.h:1152
bool BKE_node_clipboard_validate(void)
Definition: node.cc:3806
int nodeCountSocketLinks(const struct bNodeTree *ntree, const struct bNodeSocket *sock)
void BKE_node_clipboard_clear(void)
Definition: node.cc:3788
struct bNodeSocket * ntreeInsertSocketInterface(struct bNodeTree *ntree, eNodeSocketInOut in_out, const char *idname, struct bNodeSocket *next_sock, const char *name)
Definition: node.cc:3319
void nodeDetachNode(struct bNode *node)
Definition: node.cc:2462
#define NODE_RESIZE_RIGHT
Definition: BKE_node.h:366
void nodeSetActive(struct bNodeTree *ntree, struct bNode *node)
Definition: node.cc:3694
#define NODE_RESIZE_LEFT
Definition: BKE_node.h:367
#define SH_NODE_SCRIPT
Definition: BKE_node.h:1036
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
bool BKE_scene_multiview_is_render_view_active(const struct RenderData *rd, const struct SceneRenderView *srv)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
Definition: BLI_listbase.h:184
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:352
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:180
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
bool BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y)
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition: BLI_rect.h:148
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition: BLI_rect.h:144
void BLI_rctf_init_pt_radius(struct rctf *rect, const float xy[2], float size)
Definition: rct.c:500
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
void DEG_evaluate_on_refresh(Depsgraph *graph)
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:281
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:314
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph, struct bNodeTree *nodetree)
void DEG_relations_tag_update(struct Main *bmain)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_MA
Definition: DNA_ID_enums.h:63
#define MAX_NAME
Definition: DNA_defs.h:62
@ IMA_TYPE_R_RESULT
@ IMA_TYPE_COMPOSITE
#define NODE_OPTIONS
#define NODE_ACTIVE_PREVIEW
#define NODE_CUSTOM_COLOR
#define NTREE_TEXTURE
#define NODE_TEST
#define NODE_UPDATE_OPERATOR
#define NODE_DO_OUTPUT
#define NODE_MUTED
#define NTREE_COMPOSIT
#define NODE_ACTIVE_TEXTURE
#define NTREE_VIEWER_BORDER
#define NODE_DO_OUTPUT_RECALC
#define NODE_HIDDEN
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
#define NTREE_QUALITY_HIGH
#define NODE_PREVIEW
@ SOCK_MULTI_INPUT
@ SOCK_HIDDEN
#define NODE_SELECT
#define NTREE_SHADER
@ NTREE_UPDATE_GROUP
#define NODE_ACTIVE
@ OB_VOLUME
#define R_MULTIVIEW
#define R_NO_FRAME_UPDATE
@ SNODE_PIN
@ SNODE_BACKDRAW
@ SPACE_NODE
@ SPACE_IMAGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_node_tree_start(struct SpaceNode *snode, struct bNodeTree *ntree, struct ID *id, struct ID *from)
Definition: space_node.c:59
void ED_node_tag_update_id(struct ID *id)
Definition: node_draw.cc:124
void ED_node_sort(struct bNodeTree *ntree)
Definition: node_draw.cc:253
void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node)
Definition: node_draw.cc:164
void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain)
bool ED_operator_node_active(struct bContext *C)
Definition: screen_ops.c:292
bool ED_operator_node_editable(struct bContext *C)
Definition: screen_ops.c:303
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
@ SEL_SELECT
@ SEL_INVERT
@ SEL_DESELECT
@ SEL_TOGGLE
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_material_free(struct ListBase *gpumaterial)
Definition: gpu_material.c:192
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
struct bNodeTreeType * ntreeType_Shader
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel CMP_NODE_SPLITVIEWER
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner CMP_NODE_CRYPTOMATTE
Group RGB to Bright Vector Camera CLAMP
Group RGB to Bright Vector Camera Vector Combine Material SH_NODE_OUTPUT_LIGHT
NODE_GROUP_OUTPUT
NODE_GROUP
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White CMP_NODE_VIEWER
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti TEX_NODE_CHECKER
Group RGB to Bright Vector Camera Vector Combine Material Light SH_NODE_OUTPUT_LINESTYLE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set CMP_NODE_COMPOSITE
Group RGB to Bright Vector Camera Vector Combine SH_NODE_OUTPUT_MATERIAL
struct bNodeTreeType * ntreeType_Texture
StructRNA RNA_Node
StructRNA RNA_Text
StructRNA RNA_ShaderNodeScript
#define C
Definition: RandGen.cpp:39
#define UI_DPI_FAC
Definition: UI_interface.h:309
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
@ WM_JOB_TYPE_COMPOSITE
Definition: WM_api.h:735
@ WM_JOB_EXCL_RENDER
Definition: WM_api.h:725
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
#define NC_WORLD
Definition: WM_types.h:288
#define ND_SHADING
Definition: WM_types.h:377
#define ND_WORLD
Definition: WM_types.h:353
#define NC_NODE
Definition: WM_types.h:295
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DISPLAY
Definition: WM_types.h:391
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
#define ND_COMPO_RESULT
Definition: WM_types.h:347
#define NC_SCENE
Definition: WM_types.h:279
#define ND_NODES
Definition: WM_types.h:336
#define ND_MODIFIER
Definition: WM_types.h:363
#define NA_EDITED
Definition: WM_types.h:462
#define NC_MATERIAL
Definition: WM_types.h:281
#define NC_LAMP
Definition: WM_types.h:283
#define NC_IMAGE
Definition: WM_types.h:285
#define KM_PRESS
Definition: WM_types.h:242
#define NC_TEXTURE
Definition: WM_types.h:282
#define ND_LIGHTING
Definition: WM_types.h:383
#define NC_OBJECT
Definition: WM_types.h:280
#define KM_RELEASE
Definition: WM_types.h:243
#define output
short type
#define SELECT
OperationNode * node
StackEntry * from
Scene scene
World world
bNodeTree * ntree
RenderEngine * RE_engine_create(RenderEngineType *type)
Definition: engine.c:133
RenderEngineType * RE_engines_find(const char *idname)
Definition: engine.c:108
void RE_engine_free(RenderEngine *engine)
Definition: engine.c:161
#define str(s)
#define GS(x)
Definition: iris.c:241
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void area(int d1, int d2, int e1, int e2, float weights[2])
bNodeTreeType * ntreeType_Composite
int node_get_resize_cursor(int directions)
Definition: node_draw.cc:1704
void snode_update(SpaceNode *snode, bNode *node)
Definition: node_edit.c:643
static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress)
Definition: node_edit.c:257
void NODE_OT_delete(wmOperatorType *ot)
Definition: node_edit.c:1770
void NODE_OT_hide_toggle(wmOperatorType *ot)
Definition: node_edit.c:1568
bool ED_node_is_compositor(struct SpaceNode *snode)
Definition: node_edit.c:449
static bool node_shader_script_update_text_recursive(RenderEngine *engine, RenderEngineType *type, bNodeTree *ntree, Text *text)
Definition: node_edit.c:2523
void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
Definition: node_edit.c:788
static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1400
static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1647
struct NodeSizeWidget NodeSizeWidget
static bool cursor_isect_multi_input_socket(const float cursor[2], const bNodeSocket *socket)
Definition: node_edit.c:1128
void NODE_OT_delete_reconnect(wmOperatorType *ot)
Definition: node_edit.c:1855
void NODE_OT_clipboard_paste(wmOperatorType *ot)
Definition: node_edit.c:2269
void snode_set_context(const bContext *C)
Definition: node_edit.c:603
static void node_duplicate_reparent_recursive(bNode *node)
Definition: node_edit.c:1215
static int node_duplicate_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:1237
static int compo_get_recalc_flags(const bContext *C)
Definition: node_edit.c:143
void ED_node_texture_default(const bContext *C, Tex *tex)
Definition: node_edit.c:574
static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1743
void NODE_OT_duplicate(wmOperatorType *ot)
Definition: node_edit.c:1341
static void compo_redrawjob(void *cjv)
Definition: node_edit.c:197
static int ntree_socket_remove_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2359
static void compo_updatejob(void *UNUSED(cjv))
Definition: node_edit.c:244
bool ED_node_is_texture(struct SpaceNode *snode)
Definition: node_edit.c:459
void snode_dag_update(bContext *C, SpaceNode *snode)
Definition: node_edit.c:393
static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1833
static int ntree_socket_move_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2414
static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
Definition: node_edit.c:122
static int compo_breakjob(void *cjv)
Definition: node_edit.c:176
bool composite_node_active(bContext *C)
Definition: node_edit.c:370
void NODE_OT_preview_toggle(wmOperatorType *ot)
Definition: node_edit.c:1601
bool ED_node_is_geometry(struct SpaceNode *snode)
Definition: node_edit.c:464
void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot)
Definition: node_edit.c:1951
void node_link_calculate_multi_input_position(const float socket_x, const float socket_y, const int index, const int total_inputs, float r[2])
Definition: node_edit.c:111
static void compo_freejob(void *cjv)
Definition: node_edit.c:204
static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:2040
void NODE_OT_clipboard_copy(wmOperatorType *ot)
Definition: node_edit.c:2148
static bNode * visible_node(SpaceNode *snode, const rctf *rct)
Definition: node_edit.c:876
static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:2752
static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:2723
static void viewer_border_corner_to_backdrop(SpaceNode *snode, ARegion *region, int x, int y, int backdrop_width, int backdrop_height, float *fx, float *fy)
Definition: node_edit.c:2630
static void compo_initjob(void *cjv)
Definition: node_edit.c:219
static int ntree_socket_add_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2296
static void compo_progressjob(void *cjv, float progress)
Definition: node_edit.c:249
void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
Definition: node_edit.c:439
static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1922
bool ED_node_is_shader(struct SpaceNode *snode)
Definition: node_edit.c:454
static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: node_edit.c:943
int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1449
void NODE_OT_resize(wmOperatorType *ot)
Definition: node_edit.c:1068
void NODE_OT_output_file_add_socket(wmOperatorType *ot)
Definition: node_edit.c:1902
struct CompoJob CompoJob
bool ED_node_select_check(ListBase *lb)
Definition: node_edit.c:1359
void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner)
Definition: node_edit.c:326
void NODE_OT_read_viewlayers(wmOperatorType *ot)
Definition: node_edit.c:1434
void NODE_OT_tree_socket_remove(wmOperatorType *ot)
Definition: node_edit.c:2390
void NODE_OT_mute_toggle(wmOperatorType *ot)
Definition: node_edit.c:1726
static void node_resize_exit(bContext *C, wmOperator *op, bool cancel)
Definition: node_edit.c:921
static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1583
void NODE_OT_cryptomatte_layer_add(wmOperatorType *ot)
Definition: node_edit.c:2779
void NODE_OT_tree_socket_move(wmOperatorType *ot)
Definition: node_edit.c:2465
void NODE_OT_node_copy_color(wmOperatorType *ot)
Definition: node_edit.c:2071
static int node_shader_script_update_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2549
void NODE_OT_switch_view_update(wmOperatorType *ot)
Definition: node_edit.c:1817
static bool node_switch_view_poll(bContext *C)
Definition: node_edit.c:1787
static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
Definition: node_edit.c:189
void NODE_OT_shader_script_update(wmOperatorType *ot)
Definition: node_edit.c:2613
void ED_node_composit_default(const bContext *C, struct Scene *sce)
Definition: node_edit.c:539
void snode_notify(bContext *C, SpaceNode *snode)
Definition: node_edit.c:411
#define USE_ESC_COMPO
Definition: node_edit.c:77
static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: node_edit.c:1042
static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:1968
void NODE_OT_options_toggle(wmOperatorType *ot)
Definition: node_edit.c:1632
static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2165
@ COM_RECALC_VIEWER
Definition: node_edit.c:83
@ COM_RECALC_COMPOSITE
Definition: node_edit.c:82
static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1798
bool node_has_hidden_sockets(bNode *node)
Definition: node_edit.c:1087
static int viewer_border_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:2646
void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
Definition: node_edit.c:2018
static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
Definition: node_edit.c:896
static const EnumPropertyItem move_direction_items[]
Definition: node_edit.c:2408
void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
Definition: node_edit.c:665
void NODE_OT_render_changed(wmOperatorType *ot)
Definition: node_edit.c:1487
static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:2088
float node_socket_calculate_height(const bNodeSocket *socket)
Definition: node_edit.c:102
void ED_node_shader_default(const bContext *C, ID *id)
Definition: node_edit.c:471
static void node_resize_cancel(bContext *C, wmOperator *op)
Definition: node_edit.c:1063
void NODE_OT_hide_socket_toggle(wmOperatorType *ot)
Definition: node_edit.c:1682
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
Definition: node_edit.c:1102
void NODE_OT_cryptomatte_layer_remove(wmOperatorType *ot)
Definition: node_edit.c:2825
static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:2796
static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1699
static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1616
int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, const float cursor[2], int in_out)
Definition: node_edit.c:1149
void NODE_OT_tree_socket_add(wmOperatorType *ot)
Definition: node_edit.c:2340
static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
Definition: node_edit.c:1872
void NODE_OT_viewer_border(wmOperatorType *ot)
Definition: node_edit.c:2702
static bool node_shader_script_update_poll(bContext *C)
Definition: node_edit.c:2485
void NODE_OT_clear_viewer_border(wmOperatorType *ot)
Definition: node_edit.c:2735
bool composite_node_editable(bContext *C)
Definition: node_edit.c:382
static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
Definition: node_edit.c:1503
void ED_node_select_all(ListBase *lb, int action)
Definition: node_edit.c:1370
static bNodeSocket * ntree_get_active_interface_socket(ListBase *lb)
Definition: node_edit.c:2286
static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
Definition: node_edit.c:1552
bNodeTreeType * ntreeType_Geometry
#define NODE_MULTI_INPUT_LINK_GAP
Definition: node_intern.h:333
#define NODE_SOCKSIZE
Definition: node_intern.h:332
void node_deselect_all(struct SpaceNode *snode)
Definition: node_select.c:204
bool node_connected_to_output(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node)
bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
Definition: pipeline.c:2611
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6319
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:6413
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3675
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const EnumPropertyItem rna_enum_node_socket_in_out_items[]
Definition: rna_nodetree.c:65
bNodeTree * ntree
Definition: node_edit.c:91
const short * stop
Definition: node_edit.c:97
ViewLayer * view_layer
Definition: node_edit.c:90
Main * bmain
Definition: node_edit.c:88
Scene * scene
Definition: node_edit.c:89
Depsgraph * compositor_depsgraph
Definition: node_edit.c:94
float * progress
Definition: node_edit.c:99
int recalc_flags
Definition: node_edit.c:92
short * do_update
Definition: node_edit.c:98
bNodeTree * localtree
Definition: node_edit.c:95
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
char name[66]
Definition: DNA_ID.h:283
struct bNodeTree * nodetree
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
ListBase materials
Definition: BKE_main.h:152
ListBase worlds
Definition: BKE_main.h:160
struct bNodeTree * nodetree
float oldheight
Definition: node_edit.c:892
float oldoffsetx
Definition: node_edit.c:891
float oldwidth
Definition: node_edit.c:892
float oldoffsety
Definition: node_edit.c:891
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
char engine[32]
struct ImageFormatData im_format
ListBase views
struct ReportList * reports
Definition: RE_engine.h:142
struct bNodeTree * nodetree
ColorManagedViewSettings view_settings
struct RenderData r
ListBase view_layers
char use_nodes
ColorManagedDisplaySettings display_settings
struct Image * image
char tree_idname[64]
SpaceNode_Runtime * runtime
struct ID * from
ListBase treepath
struct bNodeTree * edittree
struct ID * id
struct bNodeTree * nodetree
struct bNodeTree * nodetree
char name[64]
struct bNodeTree * nodetree
float horr
char name[64]
struct bNodeLink * link
struct bNodeSocket * new_sock
struct bNodeSocket * next
struct bNodeSocket * prev
void * default_value
short total_inputs
char idname[64]
struct bNodeTree * nodetree
struct bNodeTreePath * prev
bool(* poll)(const struct bContext *C, struct bNodeTreeType *ntreetype)
Definition: BKE_node.h:393
char idname[64]
Definition: BKE_node.h:381
void(* get_from_context)(const struct bContext *C, struct bNodeTreeType *ntreetype, struct bNodeTree **r_ntree, struct ID **r_id, struct ID **r_from)
Definition: BKE_node.h:395
void(* progress)(void *, float progress)
char idname[64]
short render_quality
int(* test_break)(void *)
void(* update_draw)(void *)
short edit_quality
void(* stats_draw)(void *, const char *str)
ListBase nodes
ListBase inputs
ListBase links
rctf viewer_border
ListBase outputs
struct bNode * new_node
float locy
ListBase inputs
struct bNode * parent
float locx
ListBase outputs
ListBase areabase
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
Definition: wm_jobs.c:73
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
#define G(x, y, z)
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:207
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:216
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_main_add_notifier(unsigned int type, void *reference)
int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:450
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:372
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
void WM_operator_properties_gesture_box(wmOperatorType *ot)
void WM_operator_properties_create(PointerRNA *ptr, const char *opstring)
Definition: wm_operators.c:590
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:711
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2372