Blender  V3.3
COM_Debug.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. */
3 
4 #include "COM_Debug.h"
5 
6 extern "C" {
7 #include "BLI_fileops.h"
8 #include "BLI_path_util.h"
9 
10 #include "BKE_appdir.h"
11 #include "IMB_imbuf.h"
12 #include "IMB_imbuf_types.h"
13 }
14 
15 #include "COM_ExecutionGroup.h"
17 #include "COM_SetValueOperation.h"
18 #include "COM_ViewerOperation.h"
20 
21 namespace blender::compositor {
22 
23 int DebugInfo::file_index_ = 0;
24 DebugInfo::NodeNameMap DebugInfo::node_names_;
25 DebugInfo::OpNameMap DebugInfo::op_names_;
26 std::string DebugInfo::current_node_name_;
27 std::string DebugInfo::current_op_name_;
28 DebugInfo::GroupStateMap DebugInfo::group_states_;
29 
30 static std::string operation_class_name(const NodeOperation *op)
31 {
32  std::string full_name = typeid(*op).name();
33  /* Remove name-spaces. */
34  size_t pos = full_name.find_last_of(':');
35  BLI_assert(pos != std::string::npos);
36  return full_name.substr(pos + 1);
37 }
38 
39 std::string DebugInfo::node_name(const Node *node)
40 {
41  NodeNameMap::const_iterator it = node_names_.find(node);
42  if (it != node_names_.end()) {
43  return it->second;
44  }
45  return "";
46 }
47 
49 {
50  OpNameMap::const_iterator it = op_names_.find(op);
51  if (it != op_names_.end()) {
52  return it->second;
53  }
54  return "";
55 }
56 
58  NodeOperation *operation,
59  const ExecutionGroup *group,
60  char *str,
61  int maxlen)
62 {
63  int len = 0;
64 
65  std::string fillcolor = "gainsboro";
66  if (operation->get_flags().is_viewer_operation) {
67  const ViewerOperation *viewer = (const ViewerOperation *)operation;
68  if (viewer->is_active_viewer_output()) {
69  fillcolor = "lightskyblue1";
70  }
71  else {
72  fillcolor = "lightskyblue3";
73  }
74  }
75  else if (operation->is_output_operation(system->get_context().is_rendering())) {
76  fillcolor = "dodgerblue1";
77  }
78  else if (operation->get_flags().is_set_operation) {
79  fillcolor = "khaki1";
80  }
81  else if (operation->get_flags().is_read_buffer_operation) {
82  fillcolor = "darkolivegreen3";
83  }
84  else if (operation->get_flags().is_write_buffer_operation) {
85  fillcolor = "darkorange";
86  }
87 
88  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// OPERATION: %p\r\n", operation);
89  if (group) {
90  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\"O_%p_%p\"", operation, group);
91  }
92  else {
93  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\"O_%p\"", operation);
94  }
95  len += snprintf(str + len,
96  maxlen > len ? maxlen - len : 0,
97  " [fillcolor=%s,style=filled,shape=record,label=\"{",
98  fillcolor.c_str());
99 
100  int totinputs = operation->get_number_of_input_sockets();
101  if (totinputs != 0) {
102  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{");
103  for (int k = 0; k < totinputs; k++) {
104  NodeOperationInput *socket = operation->get_input_socket(k);
105  if (k != 0) {
106  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
107  }
108  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<IN_%p>", socket);
109  switch (socket->get_data_type()) {
110  case DataType::Value:
111  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value");
112  break;
113  case DataType::Vector:
114  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Vector");
115  break;
116  case DataType::Color:
117  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Color");
118  break;
119  }
120  }
121  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}");
122  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
123  }
124 
126  std::string op_node_name = operation->get_name();
127  if (!op_node_name.empty()) {
128  len += snprintf(
129  str + len, maxlen > len ? maxlen - len : 0, "%s\\n", (op_node_name + " Node").c_str());
130  }
131  }
132 
133  len += snprintf(str + len,
134  maxlen > len ? maxlen - len : 0,
135  "%s\\n",
136  operation_class_name(operation).c_str());
137 
138  len += snprintf(str + len,
139  maxlen > len ? maxlen - len : 0,
140  "#%d (%i,%i) (%u,%u)",
141  operation->get_id(),
142  operation->get_canvas().xmin,
143  operation->get_canvas().ymin,
144  operation->get_width(),
145  operation->get_height());
146 
147  int totoutputs = operation->get_number_of_output_sockets();
148  if (totoutputs != 0) {
149  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
150  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{");
151  for (int k = 0; k < totoutputs; k++) {
152  NodeOperationOutput *socket = operation->get_output_socket(k);
153  if (k != 0) {
154  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|");
155  }
156  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<OUT_%p>", socket);
157  switch (socket->get_data_type()) {
158  case DataType::Value: {
159  ConstantOperation *constant = operation->get_flags().is_constant_operation ?
160  static_cast<ConstantOperation *>(operation) :
161  nullptr;
162  if (constant && constant->can_get_constant_elem()) {
163  const float value = *constant->get_constant_elem();
164  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value\\n%12.4g", value);
165  }
166  else {
167  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value");
168  }
169  break;
170  }
171  case DataType::Vector: {
172  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Vector");
173  break;
174  }
175  case DataType::Color: {
176  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Color");
177  break;
178  }
179  }
180  }
181  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}");
182  }
183  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\"]");
184  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n");
185 
186  return len;
187 }
188 
189 int DebugInfo::graphviz_legend_color(const char *name, const char *color, char *str, int maxlen)
190 {
191  int len = 0;
192  len += snprintf(str + len,
193  maxlen > len ? maxlen - len : 0,
194  "<TR><TD>%s</TD><TD BGCOLOR=\"%s\"></TD></TR>\r\n",
195  name,
196  color);
197  return len;
198 }
199 
201  const char * /*name*/, const char * /*color*/, const char * /*style*/, char *str, int maxlen)
202 {
203  /* XXX TODO */
204  int len = 0;
205  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n");
206  return len;
207 }
208 
210  const char *name, const char *color, const char * /*style*/, char *str, int maxlen)
211 {
212  int len = 0;
213  len += snprintf(str + len,
214  maxlen > len ? maxlen - len : 0,
215  "<TR><TD>%s</TD><TD CELLPADDING=\"4\"><TABLE BORDER=\"1\" CELLBORDER=\"0\" "
216  "CELLSPACING=\"0\" CELLPADDING=\"0\"><TR><TD "
217  "BGCOLOR=\"%s\"></TD></TR></TABLE></TD></TR>\r\n",
218  name,
219  color);
220  return len;
221 }
222 
223 int DebugInfo::graphviz_legend(char *str, int maxlen, const bool has_execution_groups)
224 {
225  int len = 0;
226 
227  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{\r\n");
228  if (has_execution_groups) {
229  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "rank = sink;\r\n");
230  }
231  len += snprintf(
232  str + len, maxlen > len ? maxlen - len : 0, "Legend [shape=none, margin=0, label=<\r\n");
233 
234  len += snprintf(
235  str + len,
236  maxlen > len ? maxlen - len : 0,
237  " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\r\n");
238  len += snprintf(str + len,
239  maxlen > len ? maxlen - len : 0,
240  "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>\r\n");
241 
243  "NodeOperation", "gainsboro", str + len, maxlen > len ? maxlen - len : 0);
245  "Output", "dodgerblue1", str + len, maxlen > len ? maxlen - len : 0);
247  "Viewer", "lightskyblue3", str + len, maxlen > len ? maxlen - len : 0);
249  "Active Viewer", "lightskyblue1", str + len, maxlen > len ? maxlen - len : 0);
250  if (has_execution_groups) {
252  "Write Buffer", "darkorange", str + len, maxlen > len ? maxlen - len : 0);
254  "Read Buffer", "darkolivegreen3", str + len, maxlen > len ? maxlen - len : 0);
255  }
257  "Input Value", "khaki1", str + len, maxlen > len ? maxlen - len : 0);
258 
259  if (has_execution_groups) {
260  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "<TR><TD></TD></TR>\r\n");
262  "Group Waiting", "white", "dashed", str + len, maxlen > len ? maxlen - len : 0);
264  "Group Running", "firebrick1", "solid", str + len, maxlen > len ? maxlen - len : 0);
266  "Group Finished", "chartreuse4", "solid", str + len, maxlen > len ? maxlen - len : 0);
267  }
268 
269  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "</TABLE>\r\n");
270  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, ">];\r\n");
271  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n");
272 
273  return len;
274 }
275 
276 bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int maxlen)
277 {
278  char strbuf[64];
279  int len = 0;
280 
281  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "digraph compositorexecution {\r\n");
282  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "ranksep=1.5\r\n");
283  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "rankdir=LR\r\n");
284  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "splines=false\r\n");
285 
286  std::map<NodeOperation *, std::vector<std::string>> op_groups;
287  int index = 0;
288  for (const ExecutionGroup *group : system->groups_) {
289  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// GROUP: %d\r\n", index);
290  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "subgraph cluster_%d{\r\n", index);
291  /* used as a check for executing group */
292  if (group_states_[group] == EG_WAIT) {
293  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "style=dashed\r\n");
294  }
295  else if (group_states_[group] == EG_RUNNING) {
296  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "style=filled\r\n");
297  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "color=black\r\n");
298  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "fillcolor=firebrick1\r\n");
299  }
300  else if (group_states_[group] == EG_FINISHED) {
301  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "style=filled\r\n");
302  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "color=black\r\n");
303  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "fillcolor=chartreuse4\r\n");
304  }
305 
306  for (NodeOperation *operation : group->operations_) {
307 
308  sprintf(strbuf, "_%p", group);
309  op_groups[operation].push_back(std::string(strbuf));
310 
312  system, operation, group, str + len, maxlen > len ? maxlen - len : 0);
313  }
314 
315  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n");
316  index++;
317  }
318 
319  /* operations not included in any group */
320  for (NodeOperation *operation : system->operations_) {
321  if (op_groups.find(operation) != op_groups.end()) {
322  continue;
323  }
324 
325  op_groups[operation].push_back(std::string(""));
326 
328  system, operation, nullptr, str + len, maxlen > len ? maxlen - len : 0);
329  }
330 
331  for (NodeOperation *operation : system->operations_) {
332  if (operation->get_flags().is_read_buffer_operation) {
333  ReadBufferOperation *read = (ReadBufferOperation *)operation;
335  std::vector<std::string> &read_groups = op_groups[read];
336  std::vector<std::string> &write_groups = op_groups[write];
337 
338  for (int k = 0; k < write_groups.size(); k++) {
339  for (int l = 0; l < read_groups.size(); l++) {
340  len += snprintf(str + len,
341  maxlen > len ? maxlen - len : 0,
342  "\"O_%p%s\" -> \"O_%p%s\" [style=dotted]\r\n",
343  write,
344  write_groups[k].c_str(),
345  read,
346  read_groups[l].c_str());
347  }
348  }
349  }
350  }
351 
352  for (NodeOperation *op : system->operations_) {
353  for (NodeOperationInput &to : op->inputs_) {
355 
356  if (!from) {
357  continue;
358  }
359 
360  std::string color;
361  switch (from->get_data_type()) {
362  case DataType::Value:
363  color = "gray";
364  break;
365  case DataType::Vector:
366  color = "blue";
367  break;
368  case DataType::Color:
369  color = "orange";
370  break;
371  }
372 
373  NodeOperation *to_op = &to.get_operation();
374  NodeOperation *from_op = &from->get_operation();
375  std::vector<std::string> &from_groups = op_groups[from_op];
376  std::vector<std::string> &to_groups = op_groups[to_op];
377 
378  len += snprintf(str + len,
379  maxlen > len ? maxlen - len : 0,
380  "// CONNECTION: %p.%p -> %p.%p\r\n",
381  from_op,
382  from,
383  to_op,
384  &to);
385  for (int k = 0; k < from_groups.size(); k++) {
386  for (int l = 0; l < to_groups.size(); l++) {
387  len += snprintf(str + len,
388  maxlen > len ? maxlen - len : 0,
389  R"("O_%p%s":"OUT_%p":e -> "O_%p%s":"IN_%p":w)",
390  from_op,
391  from_groups[k].c_str(),
392  from,
393  to_op,
394  to_groups[l].c_str(),
395  &to);
396  len += snprintf(
397  str + len, maxlen > len ? maxlen - len : 0, " [color=%s]", color.c_str());
398  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n");
399  }
400  }
401  }
402  }
403 
404  const bool has_execution_groups = system->get_context().get_execution_model() ==
406  system->groups_.size() > 0;
407  len += graphviz_legend(str + len, maxlen > len ? maxlen - len : 0, has_execution_groups);
408 
409  len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n");
410 
411  return (len < maxlen);
412 }
413 
415 {
416  if (!COM_EXPORT_GRAPHVIZ) {
417  return;
418  }
419  const int max_textlength = 1000000;
420  char *str = (char *)MEM_mallocN(max_textlength, __func__);
421  if (graphviz_system(system, str, max_textlength - 1)) {
422  char basename[FILE_MAX];
423  char filepath[FILE_MAX];
424 
425  if (name.is_empty()) {
426  BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", file_index_);
427  }
428  else {
429  BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename));
430  }
431  BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_session(), basename);
432  file_index_++;
433 
434  std::cout << "Writing compositor debug to: " << filepath << "\n";
435 
436  FILE *fp = BLI_fopen(filepath, "wb");
437  fputs(str, fp);
438  fclose(fp);
439  }
440  MEM_freeN(str);
441 }
442 
443 static std::string get_operations_export_dir()
444 {
445  return std::string(BKE_tempdir_session()) + "COM_operations" + SEP_STR;
446 }
447 
449 {
450  const int width = render->get_width();
451  const int height = render->get_height();
452  const int num_channels = render->get_num_channels();
453 
454  ImBuf *ibuf = IMB_allocImBuf(width, height, 8 * num_channels, IB_rectfloat);
455  MemoryBuffer mem_ibuf(ibuf->rect_float, 4, width, height);
456  mem_ibuf.copy_from(render, render->get_rect(), 0, num_channels, 0);
457 
458  const std::string file_name = operation_class_name(op) + "_" + std::to_string(op->get_id()) +
459  ".png";
460  const std::string path = get_operations_export_dir() + file_name;
461  BLI_make_existing_file(path.c_str());
462  IMB_saveiff(ibuf, path.c_str(), ibuf->flags);
463  IMB_freeImBuf(ibuf);
464 }
465 
467 {
468  const std::string dir = get_operations_export_dir();
469  if (BLI_exists(dir.c_str())) {
470  struct direntry *file_list;
471  int file_list_num = BLI_filelist_dir_contents(dir.c_str(), &file_list);
472  for (int i = 0; i < file_list_num; i++) {
473  direntry *file = &file_list[i];
474  const eFileAttributes file_attrs = BLI_file_attributes(file->path);
475  if (file_attrs & FILE_ATTR_ANY_LINK) {
476  continue;
477  }
478 
479  if (BLI_is_file(file->path) && BLI_path_extension_check(file->path, ".png")) {
480  BLI_delete(file->path, false, false);
481  }
482  }
483  BLI_filelist_free(file_list, file_list_num);
484  }
485 }
486 
487 } // namespace blender::compositor
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
eFileAttributes BLI_file_attributes(const char *path)
Definition: storage.c:198
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:314
#define FILE_ATTR_ANY_LINK
Definition: BLI_fileops.h:105
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:906
bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:402
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
Definition: fileops.c:934
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
Definition: BLI_filelist.c:218
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
Definition: BLI_filelist.c:420
eFileAttributes
Definition: BLI_fileops.h:86
bool BLI_make_existing_file(const char *name)
Definition: path_util.c:1197
#define FILE_MAX
bool BLI_path_extension_check(const char *str, const char *ext) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1299
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define snprintf
Definition: BLI_winstuff.h:53
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 width
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags)
Definition: writeimage.c:22
Contains defines and structs used throughout the imbuf module.
@ IB_rectfloat
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
ATTR_WARN_UNUSED_RESULT const BMLoop * l
constexpr bool is_empty() const
bool is_rendering() const
get the rendering field of the context
virtual const float * get_constant_elem()=0
static std::string node_name(const Node *node)
Definition: COM_Debug.cc:39
static int graphviz_operation(const ExecutionSystem *system, NodeOperation *operation, const ExecutionGroup *group, char *str, int maxlen)
Definition: COM_Debug.cc:57
static void delete_operation_exports()
Definition: COM_Debug.cc:466
static int graphviz_legend(char *str, int maxlen, bool has_execution_groups)
Definition: COM_Debug.cc:223
static std::string operation_name(const NodeOperation *op)
Definition: COM_Debug.cc:48
static int graphviz_legend_line(const char *name, const char *color, const char *style, char *str, int maxlen)
Definition: COM_Debug.cc:200
static bool graphviz_system(const ExecutionSystem *system, char *str, int maxlen)
Definition: COM_Debug.cc:276
std::map< const Node *, std::string > NodeNameMap
Definition: COM_Debug.h:32
static void export_operation(const NodeOperation *op, MemoryBuffer *render)
Definition: COM_Debug.cc:448
std::map< const NodeOperation *, std::string > OpNameMap
Definition: COM_Debug.h:33
static int graphviz_legend_color(const char *name, const char *color, char *str, int maxlen)
Definition: COM_Debug.cc:189
std::map< const ExecutionGroup *, GroupState > GroupStateMap
Definition: COM_Debug.h:34
static void graphviz(const ExecutionSystem *system, StringRefNull name="")
Definition: COM_Debug.cc:414
static int graphviz_legend_group(const char *name, const char *color, const char *style, char *str, int maxlen)
Definition: COM_Debug.cc:209
Class ExecutionGroup is a group of Operations that are executed as one. This grouping is used to comb...
the ExecutionSystem contains the whole compositor tree.
const CompositorContext & get_context() const
get the reference to the compositor context
a MemoryBuffer contains access to the data of a chunk
void copy_from(const MemoryBuffer *src, const rcti &area)
const rcti & get_rect() const
get the rect of this MemoryBuffer
const int get_width() const
get the width of this MemoryBuffer
const int get_height() const
get the height of this MemoryBuffer
WriteBufferOperation * get_write_buffer_operation() const
get the WriteBufferOperation that is responsible for writing to this MemoryProxy
NodeOperationOutput * get_link() const
NodeOperation contains calculation logic.
unsigned int get_number_of_output_sockets() const
virtual bool is_output_operation(bool) const
is_output_operation determines whether this operation is an output of the ExecutionSystem during rend...
const NodeOperationFlags get_flags() const
unsigned int get_number_of_input_sockets() const
NodeOperationOutput * get_output_socket(unsigned int index=0)
NodeOperationInput * get_input_socket(unsigned int index)
const std::string get_name() const
bool is_active_viewer_output() const override
is this operation the active viewer output user can select an ViewerNode to be active (the result of ...
static char * basename(char *string)
Definition: datatoc.c:17
OperationNode * node
StackEntry * from
FILE * file
int len
Definition: draw_manager.c:108
#define str(s)
uint pos
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
@ Vector
Vector data type.
void * BKE_tempdir_session
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static constexpr bool COM_EXPORT_GRAPHVIZ
Definition: COM_Debug.h:17
static std::string get_operations_export_dir()
Definition: COM_Debug.cc:443
static std::string operation_class_name(const NodeOperation *op)
Definition: COM_Debug.cc:30
static constexpr bool COM_GRAPHVIZ_SHOW_NODE_NAME
Definition: COM_Debug.h:18
std::string to_string(const T &n)
float * rect_float
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
#define SEP_STR
Definition: unit.c:33