85#include "RNA_prototypes.hh"
100#include <fmt/format.h>
153 snode_set_context(*C);
177 if (
id ==
nullptr || ntree ==
nullptr) {
191 else if (
GS(id->name) ==
ID_LA) {
194 else if (
GS(id->name) ==
ID_WO) {
208 else if (
id == &ntree->
id) {
223 if (socket.
runtime->declaration ==
nullptr) {
230 if (translation_context.
is_empty()) {
234 return translation_context.
data();
250 for (
bNode *parent = a->
parent; parent; parent = parent->parent) {
263 for (
bNode *parent =
b->parent; parent; parent = parent->parent) {
286 if (a_active && !b_active) {
289 if (b_active && !a_active) {
292 if (!b_select && (a_active || a_select)) {
295 if (!a_select && (b_active || b_select)) {
306 return a->ui_order < b->ui_order;
310 sort_nodes[i]->ui_order = i;
317 if (nodes.is_empty()) {
320 std::sort(nodes.begin(), nodes.end(), [](
const bNode *a,
const bNode *
b) {
321 return a->ui_order < b->ui_order;
329 if (nodes.is_empty()) {
332 std::sort(nodes.begin(), nodes.end(), [](
const bNode *a,
const bNode *
b) {
333 return a->ui_order > b->ui_order;
342 for (
const int i : nodes.index_range()) {
343 const bNode &node = *nodes[i];
344 std::string block_name =
"node_" + std::string(node.name);
346 blocks[node.index()] = block;
363 r_rect.
xmin = xmin_ymax.x;
364 r_rect.
ymax = xmin_ymax.y;
366 {node.offsetx + node.width, node.offsety - node.height});
367 r_rect.
xmax = xmax_ymin.x;
368 r_rect.
ymin = xmax_ymin.y;
379 return node.declaration() && node.declaration()->use_custom_socket_order;
391 const bool node_options = draw_buttons && (node.flag &
NODE_OPTIONS);
401 loc.x = round(loc.x);
402 loc.y = round(loc.y);
422 draw_buttons(layout, (
bContext *)&C, &nodeptr);
439 if (socket_short_label) {
440 return CTX_IFACE_(socket_translation_context, socket_short_label);
444 const char *translated_socket_label =
CTX_IFACE_(socket_translation_context, socket_label);
448 const int len_prefix = strlen(panel_label);
449 if (
STREQLEN(translated_socket_label, panel_label, len_prefix) &&
450 translated_socket_label[len_prefix] ==
' ')
452 return translated_socket_label + len_prefix + 1;
457 return translated_socket_label;
463 const char *panel_label,
470 if ((!input_socket || !input_socket->is_visible()) &&
471 (!output_socket || !output_socket->is_visible()))
476 const int topy = locy;
481 const float multi_input_socket_offset = is_multi_input ?
482 std::max(input_socket->
runtime->total_inputs - 2,
486 locy -= multi_input_socket_offset * 0.5f;
549 locy = buty - multi_input_socket_offset * 0.5;
576 :
socket_decl(_socket_decl), input(_input), output(_output)
596 return this->socket_decl && (input ||
output);
602 return this->panel_decl && this->state && this->
runtime;
623 BLI_assert(node.runtime->panels.size() == node.num_panel_states);
625 ItemDeclIterator item_decl = node.declaration()->items.begin();
626 SocketIterator input = node.input_sockets().begin();
627 SocketIterator output = node.output_sockets().begin();
628 PanelStateIterator panel_state = node.panel_states().begin();
629 PanelRuntimeIterator panel_runtime = node.runtime->panels.begin();
630 const ItemDeclIterator item_decl_end = node.declaration()->items.end();
631 const SocketIterator input_end = node.input_sockets().end();
632 const SocketIterator output_end = node.output_sockets().end();
633 const PanelStateIterator panel_state_end = node.panel_states().end();
634 const PanelRuntimeIterator panel_runtime_end = node.runtime->panels.end();
638 result.
reserve(node.declaration()->items.size());
640 while (item_decl != item_decl_end) {
644 if (socket_decl->align_with_previous_socket) {
646 switch (socket_decl->in_out) {
650 last_item.
input = *input;
662 switch (socket_decl->in_out) {
665 result.append({socket_decl, *input,
nullptr});
670 result.append({socket_decl,
nullptr, *output});
681 BLI_assert(panel_runtime != panel_runtime_end);
682 result.append({panel_decl, panel_state, panel_runtime});
709 const bool is_parent_collapsed,
713 parent_state.
flag &= ~NODE_PANEL_CONTENT_VISIBLE;
717 if (num_items == 0) {
720 else if (num_items > 0) {
729 const bool is_collapsed = is_parent_collapsed || item.
state->is_collapsed();
744 if (item.
input->is_visible()) {
750 if (item.
output->is_visible()) {
791 const bool is_parent_collapsed,
792 const char *parent_label,
799 if (num_items == 0) {
802 else if (num_items > 0) {
810 if (!
state.buttons_drawn) {
811 state.buttons_drawn =
true;
813 C, ntree, node, node.
typeinfo->draw_buttons, block, locy);
817 if (item.
state->has_visible_content()) {
818 if (!is_parent_collapsed) {
820 state.is_first =
false;
824 const bool is_collapsed = is_parent_collapsed || item.
state->is_collapsed();
853 bool need_socket_spacing =
false;
856 if (!
state.buttons_drawn) {
857 state.buttons_drawn =
true;
859 C, ntree, node, node.
typeinfo->draw_buttons, block, locy);
862 if (is_parent_collapsed) {
867 if (!
state.is_first && item.
input->is_visible()) {
868 need_socket_spacing =
true;
873 if (is_parent_collapsed) {
879 if (!
state.is_first && item.
output->is_visible()) {
880 need_socket_spacing =
true;
884 if (need_socket_spacing) {
888 if (!is_parent_collapsed &&
890 C, ntree, node, parent_label, item.
input, item.
output, block, locx, locy))
892 state.is_first =
false;
893 state.need_spacer_after_item =
true;
897 if (!is_parent_collapsed) {
919 if (!is_parent_collapsed) {
920 if (parent_runtime) {
935 BLI_assert(node.runtime->panels.size() == node.num_panel_states);
953 if (node.declaration()->allow_any_socket_order) {
956 C, ntree, node, node.
typeinfo->draw_buttons, block, locy);
960 C, ntree, node, block, locx, locy, -1,
false,
"",
nullptr, location_state);
965 C, ntree, node, node.
typeinfo->draw_buttons, block, locy);
981 bool add_output_space =
false;
983 for (
bNodeSocket *socket : node.output_sockets()) {
985 socket->flag &= ~SOCK_PANEL_COLLAPSED;
991 add_output_space =
true;
995 if (add_output_space) {
1000 C, ntree, node, node.
typeinfo->draw_buttons, block, locy);
1002 bool add_input_space =
false;
1005 for (
bNodeSocket *socket : node.input_sockets()) {
1007 socket->flag &= ~SOCK_PANEL_COLLAPSED;
1013 add_input_space =
true;
1018 if (add_input_space || add_button_space) {
1035 loc.x = round(loc.x);
1036 loc.y = round(loc.y);
1050 node.runtime->totr.xmin = loc.x;
1051 node.runtime->totr.xmax = loc.x +
NODE_WIDTH(node);
1052 node.runtime->totr.ymax = loc.y;
1059 node.runtime->totr.ymin,
1061 node.runtime->totr.ymax);
1069 int totin = 0, totout = 0;
1074 loc.x = round(loc.x);
1075 loc.y = round(loc.y);
1078 for (
const bNodeSocket *socket : node.input_sockets()) {
1079 if (socket->is_visible()) {
1083 for (
const bNodeSocket *socket : node.output_sockets()) {
1084 if (socket->is_visible()) {
1090 float tot = std::max(totin, totout);
1092 hiddenrad += 5.0f *
float(tot - 4);
1095 node.runtime->totr.xmin = loc.x;
1097 node.runtime->totr.ymax = loc.y + (hiddenrad - 0.5f *
NODE_DY);
1098 node.runtime->totr.ymin = node.runtime->totr.ymax - 2 * hiddenrad;
1104 for (
bNodeSocket *socket : node.output_sockets()) {
1105 if (socket->is_visible()) {
1107 socket->runtime->location = {
1108 round(node.runtime->totr.xmax - hiddenrad +
sinf(rad) * hiddenrad),
1109 round(node.runtime->totr.ymin + hiddenrad +
cosf(rad) * hiddenrad)};
1117 for (
bNodeSocket *socket : node.input_sockets()) {
1118 if (socket->is_visible()) {
1120 socket->runtime->location = {
1121 round(node.runtime->totr.xmin + hiddenrad +
sinf(rad) * hiddenrad),
1122 round(node.runtime->totr.ymin + hiddenrad +
cosf(rad) * hiddenrad)};
1131 node.runtime->totr.ymin,
1133 node.runtime->totr.ymax);
1138 const int nclass = (node.typeinfo->ui_class ==
nullptr) ? node.typeinfo->nclass :
1139 node.typeinfo->ui_class(&node);
1144 if (node.type == GEO_NODE_VIEWER) {
1148 (node.type == CMP_NODE_OUTPUT_FILE);
1193 for (
const bNodeLink &link : node.internal_links()) {
1203 const float color[4],
1204 const float color_outline[4],
1212 uint outline_col_id)
1249 const int socket_index_in_tree,
1261 location.x - size.x / 2.0f,
1262 location.y - size.y / 2.0f,
1272 [](
bContext *C,
void *argN,
const char * ) {
1276 ntree.ensure_topology_cache();
1287 const int index_in_tree,
1290 const float color[4],
1291 const float color_outline[4],
1292 const float2 tooltip_size)
1303 location.x - draw_size.x + half_outline_width,
1304 location.x + draw_size.x + half_outline_width,
1305 location.y - draw_size.y + half_outline_width,
1306 location.y + draw_size.y + half_outline_width,
1315 half_outline_width * 2.0f,
1316 draw_size.x - half_outline_width);
1324 const int socket_type,
1325 float r_outline_color[4])
1337 r_outline_color[3] = 1.0f;
1349 if (sock.
typeinfo->draw_color_simple) {
1360 &
const_cast<ID &
>(ntree.
id), &RNA_NodeSocket, &
const_cast<bNodeSocket &
>(sock));
1366 fmt::memory_buffer &buf)
1368 auto id_to_inspection_string = [&](
const ID *id,
const short idcode) {
1369 fmt::format_to(fmt::appender(buf), (
id ? id->name + 2 :
TIP_(
"None")));
1370 fmt::format_to(fmt::appender(buf),
" (");
1372 fmt::format_to(fmt::appender(buf),
")");
1375 const CPPType &value_type = *value.type();
1376 const void *buffer = value.
get();
1378 id_to_inspection_string(*
static_cast<const ID *
const *
>(buffer),
ID_OB);
1382 id_to_inspection_string(*
static_cast<const ID *
const *
>(buffer),
ID_MA);
1385 if (value_type.
is<
Tex *>()) {
1386 id_to_inspection_string(*
static_cast<const ID *
const *
>(buffer),
ID_TE);
1389 if (value_type.
is<
Image *>()) {
1390 id_to_inspection_string(*
static_cast<const ID *
const *
>(buffer),
ID_IM);
1394 id_to_inspection_string(*
static_cast<const ID *
const *
>(buffer),
ID_GR);
1397 if (value_type.
is<std::string>()) {
1399 fmt::appender(buf),
TIP_(
"{} (String)"), *
static_cast<const std::string *
>(buffer));
1406 if (!value_type.
is<
int>()) {
1409 const int item_identifier = *
static_cast<const int *
>(buffer);
1411 if (!socket_storage->enum_items) {
1414 if (socket_storage->has_conflict()) {
1418 socket_storage->enum_items->find_item_by_identifier(item_identifier);
1422 fmt::format_to(fmt::appender(buf),
TIP_(
"{} (Menu)"), enum_item->
name);
1427 if (value_type != socket_type) {
1428 if (!convert.is_convertible(value_type, socket_type)) {
1434 convert.convert_to_uninitialized(value_type, socket_type, buffer, socket_value);
1437 if (socket_type.
is<
int>()) {
1438 fmt::format_to(fmt::appender(buf),
TIP_(
"{} (Integer)"), *
static_cast<int *
>(socket_value));
1440 else if (socket_type.
is<
float>()) {
1441 const float float_value = *
static_cast<float *
>(socket_value);
1443 if (std::abs(float_value) > (1 << 24)) {
1446 fmt::format_to(fmt::appender(buf),
TIP_(
"{:.10} (Float)"), float_value);
1449 fmt::format_to(fmt::appender(buf),
TIP_(
"{} (Float)"), float_value);
1460 fmt::appender(buf),
TIP_(
"({}, {}, {}, {}) (Color)"), color.r, color.g, color.b, color.a);
1465 fmt::format_to(fmt::appender(buf),
1471 fmt::format_to(fmt::appender(buf),
TIP_(
"(Rotation)"));
1473 else if (socket_type.
is<
bool>()) {
1474 fmt::format_to(fmt::appender(buf),
1475 TIP_(
"{} (Boolean)"),
1476 ((*
static_cast<bool *
>(socket_value)) ?
TIP_(
"True") :
TIP_(
"False")));
1481 std::stringstream ss;
1482 ss << value[0] <<
",\n";
1483 ss << value[1] <<
",\n";
1484 ss << value[2] <<
",\n";
1485 ss << value[3] <<
",\n";
1486 buf.append(ss.str());
1487 fmt::format_to(fmt::appender(buf),
TIP_(
"(Matrix)"));
1493 fmt::memory_buffer &buf)
1501 fmt::format_to(fmt::appender(buf),
TIP_(
"Value has not been logged"));
1504 if (socket_type.
is<
int>()) {
1505 fmt::format_to(fmt::appender(buf),
TIP_(
"Integer field based on:"));
1507 else if (socket_type.
is<
float>()) {
1508 fmt::format_to(fmt::appender(buf),
TIP_(
"Float field based on:"));
1511 fmt::format_to(fmt::appender(buf),
TIP_(
"Vector field based on:"));
1513 else if (socket_type.
is<
bool>()) {
1514 fmt::format_to(fmt::appender(buf),
TIP_(
"Boolean field based on:"));
1516 else if (socket_type.
is<std::string>()) {
1517 fmt::format_to(fmt::appender(buf),
TIP_(
"String field based on:"));
1520 fmt::format_to(fmt::appender(buf),
TIP_(
"Color field based on:"));
1523 fmt::format_to(fmt::appender(buf),
TIP_(
"Rotation field based on:"));
1525 fmt::format_to(fmt::appender(buf),
"\n");
1527 for (
const int i : input_tooltips.
index_range()) {
1529 fmt::format_to(fmt::appender(buf),
TIP_(
"\u2022 {}"),
TIP_(tooltip.
c_str()));
1530 if (i < input_tooltips.
size() - 1) {
1531 fmt::format_to(fmt::appender(buf),
".\n");
1538 fmt::memory_buffer &buf)
1540 auto to_string = [](
int value) {
1543 return std::string(
str);
1547 const geo_log::GeometryInfoLog::GridInfo &grid_info = *value_log.
grid_info;
1548 fmt::format_to(fmt::appender(buf),
1549 grid_info.is_empty ?
TIP_(
"Empty Grid") :
TIP_(
"\u2022 Grid"));
1555 fmt::format_to(fmt::appender(buf),
TIP_(
"Empty Geometry"));
1559 fmt::format_to(fmt::appender(buf),
TIP_(
"Geometry:"));
1560 if (!value_log.
name.empty()) {
1561 fmt::format_to(fmt::appender(buf),
" \"{}\"", value_log.
name);
1563 fmt::format_to(fmt::appender(buf),
"\n");
1567 const geo_log::GeometryInfoLog::MeshInfo &mesh_info = *value_log.
mesh_info;
1568 fmt::format_to(fmt::appender(buf),
1569 TIP_(
"\u2022 Mesh: {} vertices, {} edges, {} faces"),
1571 to_string(mesh_info.edges_num),
1572 to_string(mesh_info.faces_num));
1576 const geo_log::GeometryInfoLog::PointCloudInfo &pointcloud_info =
1578 fmt::format_to(fmt::appender(buf),
1579 TIP_(
"\u2022 Point Cloud: {} points"),
1584 const geo_log::GeometryInfoLog::CurveInfo &curve_info = *value_log.
curve_info;
1585 fmt::format_to(fmt::appender(buf),
1586 TIP_(
"\u2022 Curve: {} points, {} splines"),
1588 to_string(curve_info.splines_num));
1592 const geo_log::GeometryInfoLog::InstancesInfo &instances_info = *value_log.
instances_info;
1593 fmt::format_to(fmt::appender(buf),
1594 TIP_(
"\u2022 Instances: {}"),
1595 to_string(instances_info.instances_num));
1599 const geo_log::GeometryInfoLog::VolumeInfo &volume_info = *value_log.
volume_info;
1600 fmt::format_to(fmt::appender(buf),
TIP_(
"\u2022 Volume: {} grids"), volume_info.grids_num);
1605 const geo_log::GeometryInfoLog::EditDataInfo &edit_info = *value_log.
edit_data_info;
1606 fmt::format_to(fmt::appender(buf),
1607 TIP_(
"\u2022 Edit: {}, {}, {}"),
1608 edit_info.has_deformed_positions ?
TIP_(
"positions") :
1609 TIP_(
"no positions"),
1610 edit_info.has_deform_matrices ?
TIP_(
"matrices") :
TIP_(
"no matrices"),
1611 edit_info.gizmo_transforms_num > 0 ?
TIP_(
"gizmos") :
TIP_(
"no gizmos"));
1616 const geo_log::GeometryInfoLog::GreasePencilInfo &grease_pencil_info =
1618 fmt::format_to(fmt::appender(buf),
1619 TIP_(
"\u2022 Grease Pencil: {} layers"),
1620 to_string(grease_pencil_info.layers_num));
1624 if (type != component_types.
last()) {
1625 fmt::format_to(fmt::appender(buf),
".\n");
1641 fmt::format_to(fmt::appender(buf),
TIP_(
"Supported: All Types"));
1645 fmt::format_to(fmt::appender(buf),
TIP_(
"Supported: "));
1649 fmt::format_to(fmt::appender(buf),
TIP_(
"Mesh"));
1653 fmt::format_to(fmt::appender(buf),
TIP_(
"Point Cloud"));
1657 fmt::format_to(fmt::appender(buf),
TIP_(
"Curve"));
1661 fmt::format_to(fmt::appender(buf),
TIP_(
"Instances"));
1672 fmt::format_to(fmt::appender(buf),
TIP_(
"Grease Pencil"));
1676 if (type != supported_types.
last()) {
1677 fmt::format_to(fmt::appender(buf),
", ");
1683 fmt::memory_buffer &buf)
1685 if (!socket.is_input()) {
1688 if (socket.is_multi_input()) {
1691 if (socket.owner_node().is_reroute()) {
1695 if (!connected_sockets.
is_empty() && !connected_sockets[0]->owner_node().is_dangling_reroute()) {
1703 if (socket.
typeinfo->base_cpp_type ==
nullptr) {
1716 if (socket.
runtime->declaration ==
nullptr) {
1717 return std::nullopt;
1722 return std::nullopt;
1733 if (geo_tree_log ==
nullptr) {
1734 return std::nullopt;
1736 if (socket.
typeinfo->base_cpp_type ==
nullptr) {
1737 return std::nullopt;
1742 fmt::memory_buffer buf;
1759 std::string
str = fmt::to_string(buf);
1761 return std::nullopt;
1768 fmt::memory_buffer buf;
1775 std::string
str = fmt::to_string(buf);
1777 return std::nullopt;
1797 std::istringstream text_stream(text);
1798 for (std::string line; std::getline(text_stream, line);) {
1799 result.append(line);
1807 if (!socket.is_multi_input()) {
1808 return std::nullopt;
1814 for (
const int index : connected_links.
index_range()) {
1815 const bNodeLink *link = connected_links[index];
1816 const int connection_number = index + 1;
1817 if (!link->is_used()) {
1823 if (link->
fromnode->is_dangling_reroute()) {
1828 ntree, connected_socket, tree_draw_ctx);
1831 if (!input_log.has_value()) {
1834 numerated_info.
append({connection_number, std::move(*input_log)});
1838 return std::nullopt;
1841 fmt::memory_buffer buf;
1842 for (
const std::pair<int, std::string> &info : numerated_info) {
1844 fmt::format_to(fmt::appender(buf),
"{}", info.first);
1845 fmt::format_to(fmt::appender(buf),
". ");
1846 fmt::format_to(fmt::appender(buf), lines.
first());
1847 for (
const std::string &line : lines.
as_span().drop_front(1)) {
1848 fmt::format_to(fmt::appender(buf),
"\n {}", line);
1850 if (&info != &numerated_info.
last()) {
1855 const std::string
str = fmt::to_string(buf);
1857 return std::nullopt;
1865 fmt::memory_buffer buf;
1868 std::string
str = fmt::to_string(buf);
1870 return std::nullopt;
1879 visited_nodes.
add(&reroute_output.owner_node());
1882 if (linked_sockets.
size() != 1) {
1885 const bNode &target_node = linked_sockets[0]->owner_node();
1886 if (!visited_nodes.
add(&target_node)) {
1889 if (!target_node.is_dangling_reroute()) {
1890 return linked_sockets[0];
1892 output = target_node.output_sockets()[0];
1900 return std::nullopt;
1903 const bNode &node = socket.owner_node();
1904 if (!node.is_dangling_reroute()) {
1905 return std::nullopt;
1908 const bNodeSocket &output_socket = *node.output_sockets()[0];
1911 if (target_socket ==
nullptr) {
1912 if (!output_socket.directly_linked_sockets().is_empty()) {
1913 return TIP_(
"Dangling reroute is ignored by all targets");
1915 return std::nullopt;
1918 if (target_socket->is_multi_input()) {
1919 return TIP_(
"Dangling reroute branch is ignored by multi input socket");
1922 fmt::memory_buffer buf;
1924 std::string
str = fmt::to_string(buf);
1926 return TIP_(
"Dangling reroute is ignored");
1928 fmt::format_to(fmt::appender(buf),
".\n\n");
1929 fmt::format_to(fmt::appender(buf),
1930 TIP_(
"Dangling reroute is ignored, default value of target socket is used"));
1939 if (snode !=
nullptr) {
1942 geo_log::GeoModifierLog::get_tree_log_by_zone_for_node_editor(*snode);
1951 inspection_strings.
append(std::move(*info));
1954 inspection_strings.
append(std::move(*info));
1959 inspection_strings.
append(std::move(*info));
1962 inspection_strings.
append(std::move(*info));
1965 ntree, socket, tree_draw_ctx))
1967 inspection_strings.
append(std::move(*info));
1970 inspection_strings.
append(std::move(*info));
1973 std::stringstream
output;
1974 for (
const std::string &info : inspection_strings) {
1976 if (&info != &inspection_strings.
last()) {
1981 if (inspection_strings.
is_empty()) {
1982 const bool is_extend =
StringRef(socket.
idname) ==
"NodeSocketVirtual";
1983 const bNode &node = socket.owner_node();
1984 if (node.is_reroute()) {
1986 bke::nodeLabel(&ntree, &node, reroute_name,
sizeof(reroute_name));
1987 output << reroute_name;
1989 else if (is_extend) {
1990 output <<
TIP_(
"Connect a link to create a new socket");
1999 "Unknown socket value. Either the socket was not used or its value was not logged "
2000 "during the last evaluation");
2004 return output.str();
2011 [](
bContext *C,
void *argN,
const char * ) {
2015 ntree.ensure_topology_cache();
2025 struct SocketTooltipData {
2030 SocketTooltipData *data = MEM_cnew<SocketTooltipData>(__func__);
2031 data->ntree = &ntree;
2032 data->socket = &sock;
2036 [](
bContext *C,
void *argN,
const char * ) {
2037 SocketTooltipData *data =
static_cast<SocketTooltipData *
>(argN);
2053 const uint shape_id,
2055 const uint outline_col_id,
2057 const bool selected)
2062 float outline_color[4];
2084 rcti draw_rect = *rect;
2085 float outline_color[4] = {0};
2130#define NODE_TREE_SCALE_SMALL 0.2f
2148 immUniform4f(
"color1", checker_dark, checker_dark, checker_dark, 1.0f);
2149 immUniform4f(
"color2", checker_light, checker_light, checker_light, 1.0f);
2160 float xscale = xrect /
float(preview->
x);
2161 float yscale = yrect /
float(preview->
y);
2165 rctf draw_rect = *prv;
2166 if (xscale < yscale) {
2167 float offset = 0.5f * (yrect -
float(preview->
y) * xscale);
2168 draw_rect.
ymin += offset;
2169 draw_rect.
ymax -= offset;
2173 float offset = 0.5f * (xrect -
float(preview->
x) * yscale);
2174 draw_rect.
xmin += offset;
2175 draw_rect.
xmax -= offset;
2189 &scene->view_settings,
2190 &scene->display_settings,
2196 float black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
2198 const float outline_width = 1.0f;
2199 draw_rect.
xmin -= outline_width;
2200 draw_rect.
xmax += outline_width;
2201 draw_rect.
ymin -= outline_width;
2202 draw_rect.
ymax += outline_width;
2212 const char *opname = (
const char *)op_argv;
2225 const rctf &rct = node.runtime->totr;
2228 const float shadow_width = 0.6f *
U.widget_unit;
2229 const float shadow_alpha = 0.5f * alpha;
2234 const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
2237 rect.xmax = rct.
xmax + 0.5f;
2238 rect.ymin = rct.
ymin - 0.5f;
2239 rect.ymax = rct.
ymax + 0.5f;
2248 const bool draw_outputs,
2249 const bool select_all)
2251 if (node.input_sockets().is_empty() && node.output_sockets().is_empty()) {
2255 bool selected =
false;
2275 scale *= socket_draw_size;
2282 &
const_cast<ID &
>(ntree.
id), &RNA_Node, &
const_cast<bNode &
>(node));
2285 int selected_input_len = 0;
2286 for (
const bNodeSocket *sock : node.input_sockets()) {
2288 if (!node.is_socket_icon_drawn(*sock)) {
2291 if (select_all || (sock->flag &
SELECT)) {
2294 selected_input_len++;
2318 int selected_output_len = 0;
2320 for (
const bNodeSocket *sock : node.output_sockets()) {
2322 if (!node.is_socket_icon_drawn(*sock)) {
2325 if (select_all || (sock->flag &
SELECT)) {
2326 selected_output_len++;
2350 if (selected_input_len + selected_output_len > 0) {
2357 if (selected_input_len) {
2359 for (
const bNodeSocket *sock : node.input_sockets()) {
2360 if (!node.is_socket_icon_drawn(*sock)) {
2367 if (select_all || (sock->flag &
SELECT)) {
2380 if (--selected_input_len == 0) {
2388 if (selected_output_len) {
2390 for (
const bNodeSocket *sock : node.output_sockets()) {
2391 if (!node.is_socket_icon_drawn(*sock)) {
2394 if (select_all || (sock->flag &
SELECT)) {
2407 if (--selected_output_len == 0) {
2425 for (
const bNodeSocket *socket : node.input_sockets()) {
2426 if (!node.is_socket_icon_drawn(*socket)) {
2433 const bool is_node_hidden = (node.flag &
NODE_HIDDEN);
2434 const float width = 0.5f * socket_draw_size;
2438 float outline_color[4];
2442 const int index_in_tree = socket->index_in_tree();
2443 const float2 location = socket->runtime->location;
2444 const float2 draw_size(width, height);
2445 const float2 tooltip_size(scale, height * 2.0f - socket_draw_size + scale);
2447 block, index_in_tree, location, draw_size, color, outline_color, tooltip_size);
2468 BLI_assert(node.runtime->panels.size() == node.panel_states().size());
2471 const rctf &rct = node.runtime->totr;
2472 float color_panel[4];
2476 bool is_last_panel_visible =
false;
2477 float last_panel_content_y = 0.0f;
2483 if (panel_decl ==
nullptr) {
2492 const bool is_background_visible =
state.has_visible_content() &&
2493 !(
state.is_collapsed() ||
state.is_parent_collapsed());
2494 is_last_panel_visible = is_background_visible;
2496 if (!is_background_visible) {
2514 if (is_last_panel_visible) {
2517 const rctf content_rect = {rct.
xmin, rct.
xmax, rct.
ymin, last_panel_content_y};
2530 BLI_assert(node.runtime->panels.size() == node.panel_states().size());
2533 const rctf &rct = node.runtime->totr;
2539 if (panel_decl ==
nullptr) {
2546 const bool is_header_visible =
state.has_visible_content() && !
state.is_parent_collapsed();
2547 if (!is_header_visible) {
2563 const int but_size =
U.widget_unit * 0.8f;
2567 state.is_collapsed() ? ICON_RIGHTARROW : ICON_DOWNARROW_HLT,
2600 rect.
xmin + header_but_margin,
2602 std::max(
int(rect.
xmax - rect.
xmin - 2 * header_but_margin), 0),
2620 int highest_priority = 0;
2623 const int priority = node_warning_type_severity(warning.type);
2624 if (priority > highest_priority) {
2625 highest_priority = priority;
2626 highest_priority_type = warning.type;
2629 return highest_priority_type;
2640 std::string complete_string;
2643 complete_string += warning.message;
2646 complete_string +=
'.';
2647 complete_string +=
'\n';
2651 complete_string += data.
warnings.last().message;
2653 return complete_string;
2656#define NODE_HEADER_ICON_SIZE (0.8f * U.widget_unit)
2676 TIP_(node.typeinfo->realtime_compositor_unsupported_message));
2687 node.typeinfo->realtime_compositor_unsupported_message)
2699 if (zone &&
ELEM(&node, zone->input_node, zone->output_node)) {
2708 if (node_log !=
nullptr) {
2712 if (warnings.is_empty()) {
2751 if (zone &&
ELEM(&node, zone->input_node, zone->output_node)) {
2757 if (tree_log ==
nullptr) {
2758 return std::nullopt;
2763 if (node.is_frame()) {
2765 std::chrono::nanoseconds run_time{0};
2766 bool found_node =
false;
2768 for (
const bNode *tnode : node.direct_children_in_frame()) {
2769 if (tnode->is_frame()) {
2771 tree_draw_ctx, snode, *tnode);
2772 if (sub_frame_run_time.has_value()) {
2773 run_time += *sub_frame_run_time;
2781 run_time += node_log->execution_time;
2788 return std::nullopt;
2791 return node_log->execution_time;
2793 return std::nullopt;
2818 bool has_any_execution_time =
false;
2820 for (
const bNode *current_node : node.direct_children_in_frame()) {
2825 frame_execution_time += *node_execution_time;
2826 has_any_execution_time =
true;
2830 if (!has_any_execution_time) {
2831 return std::nullopt;
2834 return frame_execution_time;
2843 if (node.is_frame()) {
2853 return *execution_time;
2856 return std::nullopt;
2868 return std::nullopt;
2876 tree_draw_ctx, snode, node);
2878 if (!exec_time.has_value()) {
2879 return std::string(
"");
2883 std::chrono::duration_cast<std::chrono::microseconds>(*exec_time).count();
2886 if (exec_time_us == 0) {
2887 return std::string(
"-");
2889 if (exec_time_us < 100) {
2890 return std::string(
"< 0.1 ms");
2895 if (exec_time_us < 1000) {
2898 else if (exec_time_us < 10000) {
2902 std::stringstream stream;
2903 stream << std::fixed << std::setprecision(precision) << (exec_time_us / 1000.0f);
2904 return stream.str() +
" ms";
2915 fmt::memory_buffer buf;
2916 fmt::format_to(fmt::appender(buf),
TIP_(
"Accessed named attributes:"));
2917 fmt::format_to(fmt::appender(buf),
"\n");
2919 struct NameWithUsage {
2926 sorted_used_attribute.
append({item.key, item.value});
2928 std::sort(sorted_used_attribute.
begin(),
2929 sorted_used_attribute.
end(),
2930 [](
const NameWithUsage &a,
const NameWithUsage &
b) {
2931 return BLI_strcasecmp_natural(a.name.c_str(), b.name.c_str()) < 0;
2934 for (
const NameWithUsage &attribute : sorted_used_attribute) {
2937 fmt::format_to(fmt::appender(buf),
TIP_(
" \u2022 \"{}\": "), name);
2939 if ((usage & geo_log::NamedAttributeUsage::Read) != geo_log::NamedAttributeUsage::None) {
2942 if ((usage & geo_log::NamedAttributeUsage::Write) != geo_log::NamedAttributeUsage::None) {
2945 if ((usage & geo_log::NamedAttributeUsage::Remove) != geo_log::NamedAttributeUsage::None) {
2949 fmt::format_to(fmt::appender(buf), usages[i]);
2950 if (i < usages.
size() - 1) {
2951 fmt::format_to(fmt::appender(buf),
", ");
2954 fmt::format_to(fmt::appender(buf),
"\n");
2956 fmt::format_to(fmt::appender(buf),
"\n");
2957 fmt::format_to(fmt::appender(buf),
2958 TIP_(
"Attributes with these names used within the group may conflict with "
2959 "existing attributes"));
2960 return fmt::to_string(buf);
2966 const int attributes_num = usage_by_attribute_name.
size();
2969 row.
text = std::to_string(attributes_num) +
2970 (attributes_num == 1 ?
RPT_(
" Named Attribute") :
RPT_(
" Named Attributes"));
2971 row.
icon = ICON_SPREADSHEET;
2989 if (geo_tree_log ==
nullptr) {
2990 return std::nullopt;
2993 GEO_NODE_STORE_NAMED_ATTRIBUTE,
2994 GEO_NODE_REMOVE_ATTRIBUTE,
2995 GEO_NODE_INPUT_NAMED_ATTRIBUTE))
2998 for (
const bNodeSocket *socket : node.input_sockets()) {
2999 if (
STREQ(socket->name,
"Name")) {
3000 if (!socket->is_directly_linked()) {
3001 return std::nullopt;
3008 if (node_log ==
nullptr) {
3009 return std::nullopt;
3012 return std::nullopt;
3022 if (row.
text.empty()) {
3023 return std::nullopt;
3026 "The execution time from the node tree's latest evaluation. For frame and group "
3027 "nodes, the time for all sub-nodes");
3028 row.
icon = ICON_PREVIEW_RANGE;
3039 tree_draw_ctx, snode, node);
3040 if (row.has_value()) {
3041 rows.
append(std::move(*row));
3061 const bNode &node = *
static_cast<const bNode *
>(arg);
3064 std::stringstream ss;
3068 if (already_added_errors.
add_as(tooltip)) {
3069 ss <<
"\u2022 " << tooltip <<
"\n";
3073 ss <<
"Any invalid links are highlighted";
3077 row.
icon = ICON_ERROR;
3078 rows.
append(std::move(row));
3088 if (node.typeinfo->get_extra_info) {
3090 node.typeinfo->get_extra_info(
params);
3093 if (node.typeinfo->deprecation_notice) {
3096 row.
icon = ICON_INFO;
3097 row.
tooltip =
TIP_(node.typeinfo->deprecation_notice);
3098 rows.
append(std::move(row));
3117 rows.
append(std::move(*row));
3126 GEO_NODE_SIMULATION_OUTPUT,
3127 GEO_NODE_REPEAT_OUTPUT,
3128 GEO_NODE_FOREACH_GEOMETRY_ELEMENT_OUTPUT)))
3131 tree_draw_ctx, snode, node);
3132 if (row.has_value()) {
3133 rows.
append(std::move(*row));
3149 if (node_log !=
nullptr) {
3153 row.
icon = ICON_INFO;
3154 rows.
append(std::move(row));
3170 const float but_icon_right = but_icon_left + but_icon_width;
3176 extra_info_row.
icon,
3193 const float but_text_left = but_icon_right + 6.0f *
UI_SCALE_FAC;
3194 const float but_text_right = rect.
xmax;
3195 const float but_text_width = but_text_right - but_text_left;
3200 extra_info_row.
text.c_str(),
3203 short(but_text_width),
3224 const rctf &node_rect = node.runtime->totr;
3225 rctf panel_back_rect = extra_info_rect;
3243 const float outline_width =
U.pixelsize;
3244 BLI_rctf_pad(&panel_back_rect, outline_width, outline_width);
3248 &panel_back_rect, color,
nullptr, 0.0f, color_outline, outline_width,
BASIS_RAD);
3262 if (preview && !(preview->
x > 0 && preview->
y > 0)) {
3267 if (extra_info_rows.
is_empty() && !preview) {
3271 const rctf &rct = node.runtime->totr;
3272 rctf extra_info_rect;
3274 if (node.is_frame()) {
3288 float preview_height = 0.0f;
3292 if (preview->
x > preview->
y) {
3293 preview_height = (width - 2.0f *
padding) *
float(preview->
y) /
float(preview->
x) +
3299 extra_info_rect.
ymax += preview_height;
3302 preview_height = width;
3303 const float preview_width = (width - 2.0f *
padding) *
float(preview->
x) /
3308 preview_rect.
xmin = extra_info_rect.
xmin +
padding + (width - preview_width) / 2;
3309 preview_rect.
xmax = extra_info_rect.
xmax -
padding - (width - preview_width) / 2;
3310 extra_info_rect.
ymax += preview_height;
3321 extra_info_rect.
ymin += preview_height;
3342 (
U.experimental.use_shader_node_previews ||
3346 rctf rect_with_preview = node.runtime->totr;
3360 const rctf &rct = node.runtime->totr;
3368 bool drawn_with_previews =
false;
3375 if (previews_shader) {
3379 drawn_with_previews =
true;
3381 else if (previews_compo) {
3384 if (preview_compositor) {
3386 C, tree_draw_ctx, snode, node, preview_compositor->
ibuf, block);
3387 drawn_with_previews =
true;
3392 if (drawn_with_previews ==
false) {
3409 float color_header[4];
3424 float iconofs = rct.
xmax - 0.35f *
U.widget_unit;
3428 iconofs -= iconbutw;
3445 (
void *)
"NODE_OT_group_edit");
3454 iconofs -= iconbutw;
3459 is_active ? ICON_HIDE_OFF : ICON_HIDE_ON,
3471 (
void *)
"NODE_OT_preview_toggle");
3475 iconofs -= iconbutw;
3480 node.typeinfo->ui_icon,
3491 if (node.type == GEO_NODE_VIEWER) {
3493 iconofs -= iconbutw;
3498 is_active ? ICON_HIDE_OFF : ICON_HIDE_ON,
3508 const char *operator_idname = is_active ?
"NODE_OT_deactivate_viewer" :
"NODE_OT_select";
3517 if (node.flag &
SELECT) {
3526 const int but_size =
U.widget_unit * 0.8f;
3545 (
void *)
"NODE_OT_hide_toggle");
3563 TIP_(node.typeinfo->ui_description));
3566 [](
bContext * ,
void *arg,
const char *tip) -> std::string {
3567 const bNode &node = *
static_cast<const bNode *
>(arg);
3568 if (node.typeinfo->ui_description_fn) {
3569 return node.
typeinfo->ui_description_fn(node);
3586 const float outline_width =
U.pixelsize;
3604 if (node.flag &
SELECT) {
3631 float color_underline[4];
3635 color_underline[3] = 1.0f;
3655 rct.
xmin - outline_width,
3656 rct.
xmax + outline_width,
3657 rct.
ymin - outline_width,
3658 rct.
ymax + outline_width,
3662 float color_outline[4];
3664 if (node.flag &
SELECT) {
3672 color_outline[3] = 1.0f;
3703 const rctf &rct = node.runtime->totr;
3741 if (node.flag &
SELECT) {
3763 if (node.flag &
SELECT) {
3772 const int but_size =
U.widget_unit * 1.0f;
3780 centy - but_size / 2,
3791 (
void *)
"NODE_OT_hide_toggle");
3809 TIP_(node.typeinfo->ui_description));
3813 const float outline_width =
U.pixelsize;
3815 rct.
xmin - outline_width,
3816 rct.
xmax + outline_width,
3817 rct.
ymin - outline_width,
3818 rct.
ymax + outline_width,
3822 float color_outline[4];
3824 if (node.flag &
SELECT) {
3848 float dx = 0.5f *
U.widget_unit;
3850 const float dy = 0.2f *
U.widget_unit;
3882 if (directions == 0) {
3907 if (ntree ==
nullptr) {
3937 for (
bNode *node : ntree.all_nodes()) {
3938 for (
bNodeSocket *socket : node->input_sockets()) {
3939 if (socket->is_multi_input()) {
3940 socket->runtime->total_inputs = socket->directly_linked_links().size();
3948 link.tosock->runtime->total_inputs++;
3959#define NODE_FRAME_MARGIN (1.5f * U.widget_unit)
3969 const float has_label = node.label[0] !=
'\0';
3974 const float margin_top = 0.5f * margin + (has_label ? 1.25f * label_height : 0.5f * margin);
3985 for (
const bNode *tnode : nodes) {
3986 if (tnode->parent != &node) {
3991 rctf noderect = tnode->runtime->totr;
3992 noderect.
xmin -= margin;
3993 noderect.
xmax += margin;
3994 noderect.
ymin -= margin;
3995 noderect.
ymax += margin_top;
4001 data->flag &= ~NODE_FRAME_RESIZEABLE;
4010 node.offsetx = offset.x;
4011 node.offsety = offset.y;
4013 node.width = max.x - node.offsetx;
4014 node.height = -max.y + node.offsety;
4016 node.runtime->totr = rect;
4024 node.input_socket(0).runtime->location = loc;
4025 node.output_socket(0).runtime->location = loc;
4027 const float size = 8.0f;
4028 node.width = size * 2;
4029 node.runtime->totr.xmin = loc.x -
size;
4030 node.runtime->totr.xmax = loc.x +
size;
4031 node.runtime->totr.ymax = loc.y +
size;
4032 node.runtime->totr.ymin = loc.y -
size;
4046 for (
const int i : nodes.index_range()) {
4047 bNode &node = *nodes[i];
4048 uiBlock &block = *blocks[node.index()];
4049 if (node.is_frame()) {
4054 if (node.is_reroute()) {
4069 for (
int i = nodes.size() - 1; i >= 0; i--) {
4070 if (nodes[i]->is_frame()) {
4085 const float font_size = data->label_size / aspect;
4104 const rctf &rct = node.runtime->totr;
4106 const float label_y = rct.
ymax - label_height - (0.5f * margin);
4109 const bool has_label = node.label[0] !=
'\0';
4119 const float line_spacing = (line_height_max * aspect);
4120 const float line_width = (
BLI_rctf_size_x(&rct) - 2 * margin) / aspect;
4122 const float x = rct.
xmin + margin;
4123 float y = rct.
ymax - label_height - (has_label ? line_spacing + margin : 0);
4125 const int y_min = rct.
ymin + margin;
4133 if (line->line[0]) {
4136 BLF_draw(fontid, line->line, line->len, &info);
4137 y -= line_spacing * info.
lines;
4158 if (
BLI_rctf_isect(&node.runtime->totr, ®ion.v2d.cur,
nullptr) ==
false) {
4164 const float alpha = color[3];
4175 const rctf &rct = node.runtime->totr;
4180 if (node.flag &
SELECT) {
4201 if (
BLI_rctf_isect(&node.runtime->totr, ®ion.v2d.cur,
nullptr) ==
false) {
4218 const std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
4220 if (!object_and_modifier) {
4223 snode.
edittree->ensure_topology_cache();
4226 std::optional<ComputeContextHash> current_compute_context_hash =
4227 [&]() -> std::optional<ComputeContextHash> {
4230 object_and_modifier->nmd->modifier.name);
4232 return std::nullopt;
4236 if (!current_compute_context_hash) {
4245 compute_context_builder,
4246 [&](
const Object &gizmo_object,
4249 const bNode &gizmo_node,
4251 if (&gizmo_object != object_and_modifier->object) {
4254 if (&gizmo_nmd != object_and_modifier->nmd) {
4264 if (compute_context.hash() == *current_compute_context_hash) {
4265 sockets_on_gizmo_paths.add(&socket);
4270 return sockets_on_gizmo_paths;
4280 const bNodeSocket *input_socket = reroute.input_sockets().first();
4281 if (input_socket->directly_linked_links().is_empty()) {
4284 const bNodeLink *input_link = input_socket->directly_linked_links().first();
4286 return from_node->is_reroute() ? from_node :
nullptr;
4294 const bNode &src_reroute)
4298 if (src_reroute.
label[0] !=
'\0') {
4308 for (
const bNode *reroute = &src_reroute; reroute;
4311 reroute_path.
append(reroute);
4316 if (reroute->label[0] !=
'\0') {
4317 label = reroute->label;
4321 reroute_auto_labels.
add(reroute,
"");
4325 for (
const bNode *reroute : reroute_path) {
4337 const bool has_label = node.label[0] !=
'\0';
4341 if (!has_label && !use_auto_label) {
4354 const short width = 512;
4356 const int y = node.runtime->totr.ymax;
4359 &block,
UI_BTYPE_LABEL, 0, showname, x, y, width,
short(
NODE_DY),
nullptr, 0, 0,
nullptr);
4363 if (use_auto_label && !(node.flag &
NODE_SELECT)) {
4377 const rctf &rct = node.runtime->totr;
4378 if (rct.
xmax < region.v2d.cur.xmin || rct.
xmin > region.v2d.cur.xmax ||
4379 rct.
ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax)
4404 if (node.is_frame()) {
4408 else if (node.is_reroute()) {
4412 const View2D &v2d = region.v2d;
4417 node_draw_basis(C, tree_draw_ctx, v2d, snode, ntree, node, block, key);
4424 positions.append({rect.
xmin, rect.
ymin});
4425 positions.append({rect.
xmin, rect.
ymax});
4426 positions.append({rect.
xmax, rect.
ymin});
4427 positions.append({rect.
xmax, rect.
ymax});
4432 const Span<std::unique_ptr<bNodeTreeZone>> all_zones,
4436 const float zone_padding = 0.3f *
UI_UNIT_X;
4439 if (!
bounds.is_empty()) {
4446 const Span<float2> child_bounds = r_bounds_by_zone[child_zone->index];
4447 for (
const float2 &
pos : child_bounds) {
4453 for (
const bNode *child_node : zone.child_nodes) {
4454 rctf rect = child_node->runtime->totr;
4458 if (zone.input_node) {
4459 const rctf &totr = zone.input_node->runtime->totr;
4465 if (zone.output_node) {
4466 const rctf &totr = zone.output_node->runtime->totr;
4473 if (snode.
runtime->linkdrag) {
4475 if (link.fromnode ==
nullptr) {
4478 if (zone.contains_node_recursively(*link.fromnode) && zone.output_node != link.fromnode) {
4489 reinterpret_cast<float(*)[2]
>(possible_bounds.
data()),
4490 possible_bounds.
size(),
4491 convex_indices.
data());
4492 convex_indices.
resize(convex_positions_num);
4494 for (
const int i : convex_indices) {
4495 bounds.append(possible_bounds[i]);
4507 const int zones_num = zones ? zones->
zones.size() : 0;
4514 for (
const int zone_i :
IndexRange(zones_num)) {
4518 const Span<float2> boundary_positions = bounds_by_zone[zone_i];
4519 const int boundary_positions_num = boundary_positions.
size();
4521 const Bounds<float2> bounding_box = *bounds::min_max(boundary_positions);
4522 const float bounding_box_width = bounding_box.
max.x - bounding_box.
min.x;
4523 bounding_box_width_by_zone[zone_i] = bounding_box_width;
4530 for (
const int i : boundary_positions.
index_range()) {
4531 boundary_curve_positions[i] =
float3(boundary_positions[i], 0.0f);
4534 fillet_curve_by_zone[zone_i] = geometry::fillet_curves_poly(
4543 const View2D &v2d = region.v2d;
4546 float line_width = 1.0f * scale;
4547 float viewport[4] = {};
4550 const auto get_theme_id = [&](
const int zone_i) {
4551 const bNode *node = zones->
zones[zone_i]->output_node;
4552 return bke::zone_type_by_node_type(node->type)->theme_id;
4558 using ZoneOrNode = std::variant<const bNodeTreeZone *, const bNode *>;
4560 for (
const int zone_i :
IndexRange(zones_num)) {
4563 for (
const bNode *node : ntree.all_nodes()) {
4568 auto get_zone_or_node_width = [&](
const ZoneOrNode &zone_or_node) {
4569 if (
const bNodeTreeZone *
const *zone_p = std::get_if<const bNodeTreeZone *>(&zone_or_node)) {
4571 return bounding_box_width_by_zone[zone.index];
4573 if (
const bNode *
const *node_p = std::get_if<const bNode *>(&zone_or_node)) {
4574 const bNode &node = **node_p;
4580 std::sort(draw_order.
begin(), draw_order.
end(), [&](
const ZoneOrNode &a,
const ZoneOrNode &
b) {
4582 return get_zone_or_node_width(a) > get_zone_or_node_width(b);
4585 for (
const ZoneOrNode &zone_or_node : draw_order) {
4586 if (
const bNodeTreeZone *
const *zone_p = std::get_if<const bNodeTreeZone *>(&zone_or_node)) {
4588 const int zone_i = zone.
index;
4589 float zone_color[4];
4591 if (zone_color[3] == 0.0f) {
4594 const Span<float3> fillet_boundary_positions = fillet_curve_by_zone[zone_i].positions();
4600 for (
const float3 &p : fillet_boundary_positions) {
4608 if (
const bNode *
const *node_p = std::get_if<const bNode *>(&zone_or_node)) {
4609 const bNode &node = **node_p;
4617 for (
const ZoneOrNode &zone_or_node : draw_order) {
4618 const bNodeTreeZone *
const *zone_p = std::get_if<const bNodeTreeZone *>(&zone_or_node);
4623 const int zone_i = zone.
index;
4624 const Span<float3> fillet_boundary_positions = fillet_curve_by_zone[zone_i].positions();
4633 for (
const float3 &p : fillet_boundary_positions) {
4645 for (
const ZoneOrNode &zone_or_node : draw_order) {
4646 if (
const bNode *
const *node_p = std::get_if<const bNode *>(&zone_or_node)) {
4647 const bNode &node = **node_p;
4653#define USE_DRAW_TOT_UPDATE
4664#ifdef USE_DRAW_TOT_UPDATE
4668 for (
const int i : nodes.index_range()) {
4669#ifdef USE_DRAW_TOT_UPDATE
4680 for (
const bNodeLink *link : ntree.all_links()) {
4681 if (!bke::node_link_is_hidden(link) && !bke::node_link_is_selected(link)) {
4687 for (
const bNodeLink *link : ntree.all_links()) {
4688 if (!bke::node_link_is_hidden(link) && bke::node_link_is_selected(link)) {
4697 for (
const int i : nodes.index_range()) {
4698 bNode &node = *nodes[i];
4704 const bNodeInstanceKey key = bke::node_instance_key(parent_key, &ntree, &node);
4705 node_draw(C, tree_draw_ctx, region, snode, ntree, node, *blocks[node.index()], key);
4719 const int x = rect->
xmin + padding_x;
4720 const int y = region.winy -
UI_UNIT_Y * 0.6f;
4728 ui::template_breadcrumbs(*layout, context_path);
4739 View2D &v2d = region.v2d;
4752 if (!scene->use_nodes) {
4756 if (!scene->nodetree) {
4770 const View3D &view_3d =
reinterpret_cast<const View3D &
>(space);
4794 ntree.ensure_topology_cache();
4804 tree_draw_ctx.
geo_log_by_zone = geo_log::GeoModifierLog::get_tree_log_by_zone_for_node_editor(
4807 log->ensure_node_warnings(&ntree);
4808 log->ensure_execution_times();
4822 &scene->runtime->compositor.per_node_execution_time;
4824 else if (ntree.
type ==
NTREE_SHADER &&
U.experimental.use_shader_node_previews &&
4834 node_draw_nodetree(C, tree_draw_ctx, region, *snode, ntree, nodes, blocks, parent_key);
4842 const int max_tree_length = 3;
4843 const float bright_factor = 0.25f;
4850 const int depth =
max_ii(0, clamped_tree_path_length - 1);
4854 mul_v3_fl(color, 1.0f + bright_factor * depth);
4862 View2D &v2d = region.v2d;
4927 float original_proj[4][4];
4947 if (snode.
runtime->linkdrag) {
void ED_draw_imbuf(ImBuf *ibuf, float x, float y, bool use_filter, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, float zoom_x, float zoom_y)
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
WorkSpace * CTX_wm_workspace(const bContext *C)
SpaceNode * CTX_wm_space_node(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
Low-level operations for curves.
const char * BKE_idtype_idcode_to_name(short idcode)
void id_us_ensure_real(ID *id)
#define NODE_CLASS_OUTPUT
#define NODE_CLASS_INTERFACE
#define NODE_CUSTOM_GROUP
#define NODE_CLASS_CONVERTER
#define NODE_CLASS_PATTERN
#define NODE_CLASS_GEOMETRY
#define NODE_GROUP_OUTPUT
#define NODE_CLASS_DISTORT
#define NODE_CLASS_OP_VECTOR
#define NODE_CLASS_LAYOUT
#define NODE_CLASS_OP_COLOR
#define NODE_CLASS_OP_FILTER
#define NODE_CLASS_ATTRIBUTE
#define NODE_CLASS_TEXTURE
#define NODE_CLASS_SHADER
#define NODE_CLASS_SCRIPT
General operations, lookup, etc. for blender objects.
bool BKE_scene_uses_shader_previews(const Scene *scene)
void BLF_size(int fontid, float size)
void BLF_aspect(int fontid, float x, float y, float z)
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
void BLF_disable(int fontid, int option)
void BLF_draw(int fontid, const char *str, size_t str_len, ResultBLF *r_info=nullptr) ATTR_NONNULL(2)
void BLF_enable(int fontid, int option)
float BLF_width(int fontid, const char *str, size_t str_len, ResultBLF *r_info=nullptr) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2)
int BLF_height_max(int fontid) ATTR_WARN_UNUSED_RESULT
void BLF_wordwrap(int fontid, int wrap_width)
void BLF_position(int fontid, float x, float y, float z)
#define BLI_assert_unreachable()
int BLI_convexhull_2d(const float(*points)[2], int points_num, int r_points[])
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count_at_most(const struct ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int round_fl_to_int(float a)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE void rgba_float_args_set(float col[4], float r, float g, float b, float a)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
#define BLI_SCOPED_DEFER(function_to_defer)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
void BLI_rctf_union(struct rctf *rct_a, const struct rctf *rct_b)
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
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)
void BLI_rcti_resize(struct rcti *rect, int x, int y)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
void BLI_rctf_pad(struct rctf *rect, float pad_x, float pad_y)
bool BLI_rctf_isect_pt(const struct rctf *rect, float x, float y)
BLI_INLINE int BLI_rcti_cent_y(const struct rcti *rct)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
void BLI_rctf_init_pt_radius(struct rctf *rect, const float xy[2], float size)
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct)
void BLI_rctf_init_minmax(struct rctf *rect)
size_t BLI_str_format_int_grouped(char dst[BLI_STR_FORMAT_INT32_GROUPED_SIZE], int num) ATTR_NONNULL(1)
#define STRNCPY(dst, src)
#define BLI_STR_FORMAT_INT32_GROUPED_SIZE
#define BLI_STR_UTF8_DEGREE_SIGN
#define STREQLEN(a, b, n)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define POINTER_AS_INT(i)
#define BLT_I18NCONTEXT_ID_ID
#define CTX_IFACE_(context, msgid)
#define CTX_TIP_(context, msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_REAL_USERS(id)
@ SOCK_DISPLAY_SHAPE_CIRCLE_DOT
@ SOCK_DISPLAY_SHAPE_CIRCLE
@ SOCK_DISPLAY_SHAPE_SQUARE_DOT
@ SOCK_DISPLAY_SHAPE_SQUARE
@ SOCK_DISPLAY_SHAPE_DIAMOND
@ SOCK_DISPLAY_SHAPE_DIAMOND_DOT
@ NODE_PANEL_PARENT_COLLAPSED
@ NODE_PANEL_CONTENT_VISIBLE
@ SCE_COMPOSITOR_DEVICE_GPU
@ SN_OVERLAY_SHOW_PREVIEWS
@ SN_OVERLAY_SHOW_REROUTE_AUTO_LABELS
@ SN_OVERLAY_SHOW_TIMINGS
@ SN_OVERLAY_SHOW_OVERLAYS
@ SN_OVERLAY_SHOW_NAMED_ATTRIBUTES
@ V3D_SHADING_USE_COMPOSITOR_DISABLED
void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ntree)
#define NODE_GRID_STEP_SIZE
const rcti * ED_region_visible_rect(ARegion *region)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
#define REGION_DRAW_POST_VIEW
#define REGION_DRAW_PRE_VIEW
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *framebuffer)
void GPU_clear_color(float red, float green, float blue, float alpha)
void GPU_matrix_identity_set()
void GPU_matrix_push_projection()
void GPU_matrix_pop_projection()
#define GPU_matrix_projection_get(x)
#define GPU_matrix_projection_set(x)
@ GPU_SHADER_KEYFRAME_SHAPE
@ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_KEYFRAME_SHAPE_INNER_DOT
@ GPU_KEYFRAME_SHAPE_CIRCLE
@ GPU_KEYFRAME_SHAPE_SQUARE
@ GPU_KEYFRAME_SHAPE_DIAMOND
void GPU_program_point_size(bool enable)
void GPU_blend(eGPUBlend blend)
void GPU_scissor_test(bool enable)
void GPU_line_width(float width)
eGPUBlend GPU_blend_get()
void GPU_line_smooth(bool enable)
void GPU_depth_test(eGPUDepthTest test)
void GPU_viewport_size_get_f(float coords[4])
GPUFrameBuffer * GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
Read Guarded memory(de)allocation.
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
void UI_but_func_pushed_state_set(uiBut *but, std::function< bool(const uiBut &)> func)
#define UI_ALPHA_CHECKER_LIGHT
void uiLayoutSetActive(uiLayout *layout, bool active)
eUIEmbossType UI_block_emboss_get(uiBlock *block)
void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
void ui_draw_dropshadow(const rctf *rct, float radius, float width, float aspect, float alpha)
void UI_but_icon_indicator_number_set(uiBut *but, const int indicator_number)
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
uiBut * uiDefBut(uiBlock *block, int type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, const char *tip)
void UI_draw_roundbox_4fv_ex(const rctf *rect, const float inner1[4], const float inner2[4], float shade_dir, const float outline[4], float outline_width, float rad)
#define UI_ALPHA_CHECKER_DARK
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const uiStyle *style)
const uiStyle * UI_style_get_dpi()
uiBut * uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, const char *tip)
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, eUIEmbossType emboss)
void UI_draw_roundbox_corner_set(int type)
void uiItemS_ex(uiLayout *layout, float factor, LayoutSeparatorType type=LayoutSeparatorType::Auto)
const uiStyle * UI_style_get()
void uiLayoutSetTooltipFunc(uiLayout *layout, uiButToolTipFunc func, void *arg, uiCopyArgFunc copy_arg, uiFreeArgFunc free_arg)
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
void UI_but_drawflag_disable(uiBut *but, int flag)
void UI_block_draw(const bContext *C, uiBlock *block)
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
void UI_block_flag_enable(uiBlock *block, int flag)
void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
void UI_block_end(const bContext *C, uiBlock *block)
void UI_but_flag_enable(uiBut *but, int flag)
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *ptr)
void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy)
void UI_block_align_end(uiBlock *block)
void UI_GetThemeColor3fv(int colorid, float col[3])
int UI_GetThemeValueType(int colorid, int spacetype)
void UI_GetThemeColorBlend4f(int colorid1, int colorid2, float fac, float r_col[4])
void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4])
void UI_GetThemeColor4fv(int colorid, float col[4])
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
void UI_GetThemeColorBlendShade3ubv(int colorid1, int colorid2, float fac, int offset, unsigned char col[3])
void UI_view2d_scrollers_draw(View2D *v2d, const rcti *mask_custom)
void UI_view2d_view_restore(const bContext *C)
void UI_view2d_center_get(const View2D *v2d, float *r_x, float *r_y)
void UI_view2d_view_ortho(const View2D *v2d)
void UI_view2d_scale_get(const View2D *v2d, float *r_x, float *r_y)
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
void UI_view2d_center_set(View2D *v2d, float x, float y)
void UI_view2d_dot_grid_draw(const View2D *v2d, int grid_color_id, float min_step, int grid_subdivisions)
@ WM_GIZMOMAP_DRAWSTEP_2D
void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
IndexRange index_range() const
static const CPPType & get()
void destruct(void *ptr) const
const ComputeContext * current() const
void push(Args &&...args)
const ComputeContextHash & hash() const
const Value * lookup_ptr(const Key &key) const
bool add_overwrite(const Key &key, const Value &value)
bool add(const Key &key, const Value &value)
constexpr T & first() const
constexpr void copy_from(Span< T > values) const
bool add_as(ForwardKey &&key)
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool is_empty() const
constexpr const char * data() const
constexpr const char * c_str() const
void append(const T &value)
const T & last(const int64_t n=0) const
IndexRange index_range() const
void resize(const int64_t new_size)
void reserve(const int64_t min_capacity)
Span< T > as_span() const
MutableSpan< float3 > positions_for_write()
void fill_curve_types(CurveType type)
MutableSpan< int > offsets_for_write()
MutableSpan< bool > cyclic_for_write()
bNodeTreeZone * parent_zone
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
Vector< std::unique_ptr< bNodeTreeZone > > zones
const bNodeTreeZone * get_zone_by_socket(const bNodeSocket &socket) const
Vector< ItemDeclarationPtr > items
PanelDrawButtonsFunction draw_buttons
Span< bke::GeometryComponent::Type > supported_types() const
Vector< std::string > input_tooltips
Map< StringRefNull, NamedAttributeUsage > used_named_attributes
VectorSet< NodeWarning > warnings
Vector< StringRefNull > debug_messages
void ensure_used_named_attributes()
void ensure_socket_values()
std::chrono::nanoseconds execution_time
Map< int32_t, GeoNodeLog > nodes
void ensure_debug_messages()
ValueLog * find_socket_value_log(const bNodeSocket &query_socket)
std::optional< EditDataInfo > edit_data_info
std::optional< GridInfo > grid_info
std::optional< MeshInfo > mesh_info
std::optional< GreasePencilInfo > grease_pencil_info
std::optional< PointCloudInfo > pointcloud_info
Vector< bke::GeometryComponent::Type > component_types
std::optional< InstancesInfo > instances_info
std::optional< VolumeInfo > volume_info
std::optional< CurveInfo > curve_info
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
static const char * to_string(const Interpolation &interp)
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float3 log(float3 v)
const bNodeZoneType * zone_type_by_node_type(const int node_type)
float2 node_to_view(const bNode *node, float2 loc)
bool node_type_is_undefined(const bNode *node)
bool node_link_is_hidden(const bNodeLink *link)
void * node_instance_hash_lookup(bNodeInstanceHash *hash, bNodeInstanceKey key)
const DataTypeConversions & get_implicit_type_conversions()
void nodeLabel(const bNodeTree *ntree, const bNode *node, char *label, int maxlen)
const char * nodeSocketShortLabel(const bNodeSocket *sock)
bNodeInstanceKey node_instance_key(bNodeInstanceKey parent_key, const bNodeTree *ntree, const bNode *node)
Span< int > all_zone_node_types()
const char * nodeSocketLabel(const bNodeSocket *sock)
bNodeTree * node_tree_from_id(ID *id)
float2 node_from_view(const bNode *node, float2 view_loc)
static bool compare_node_depth(const bNode *a, const bNode *b)
static void node_draw_zones_and_frames(const bContext &C, TreeDrawContext &tree_draw_ctx, const ARegion ®ion, const SpaceNode &snode, const bNodeTree &ntree, Span< uiBlock * > blocks)
static bool node_update_basis_socket(const bContext &C, bNodeTree &ntree, bNode &node, const char *panel_label, bNodeSocket *input_socket, bNodeSocket *output_socket, uiBlock &block, const int &locx, int &locy)
float node_socket_calculate_height(const bNodeSocket &socket)
rctf node_frame_rect_inside(const SpaceNode &snode, const bNode &node)
static bNodeInstanceKey current_node_instance_key(const SpaceNode &snode, const bNode &node)
int node_get_resize_cursor(NodeResizeDirection directions)
static void reroute_node_draw(const bContext &C, TreeDrawContext &tree_draw_ctx, ARegion ®ion, const SpaceNode &snode, bNodeTree &ntree, const bNode &node, uiBlock &block)
static void node_socket_outline_color_get(const bool selected, const int socket_type, float r_outline_color[4])
void nodelink_batch_start(SpaceNode &)
static geo_log::GeoTreeLog * geo_tree_log_for_socket(const bNodeTree &ntree, const bNodeSocket &socket, TreeDrawContext &tree_draw_ctx)
static const bNode * reroute_node_get_linked_reroute(const bNode &reroute)
static std::string node_errors_tooltip_fn(bContext *, void *argN, const char *)
void tree_draw_order_update(bNodeTree &ntree)
void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale)
Vector< NodeInterfaceItemData >::const_iterator ItemIterator
static std::optional< std::string > create_description_inspection_string(const bNodeSocket &socket)
static void draw_nodetree(const bContext &C, ARegion ®ion, bNodeTree &ntree, bNodeInstanceKey parent_key)
static void node_update_nodetree(const bContext &C, TreeDrawContext &tree_draw_ctx, bNodeTree &ntree, Span< bNode * > nodes, Span< uiBlock * > blocks)
static float node_tree_view_scale(const SpaceNode &snode)
static std::optional< std::string > create_log_inspection_string(geo_log::GeoTreeLog *geo_tree_log, const bNodeSocket &socket)
static void frame_node_draw_background(const ARegion ®ion, const SpaceNode &snode, const bNode &node)
static void node_socket_draw_multi_input(uiBlock &block, const int index_in_tree, const float2 location, const float2 draw_size, const float color[4], const float color_outline[4], const float2 tooltip_size)
void node_draw_link_bezier(const bContext &C, const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, const int th_col1, const int th_col2, const int th_col3, const bool selected)
static void draw_background_color(const SpaceNode &snode)
static std::optional< std::chrono::nanoseconds > node_get_execution_time(const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static void create_inspection_string_for_geometry_info(const geo_log::GeometryInfoLog &value_log, fmt::memory_buffer &buf)
bool push_compute_context_for_tree_path(const SpaceNode &snode, ComputeContextBuilder &compute_context_builder)
void nodelink_batch_end(SpaceNode &snode)
static std::optional< std::chrono::nanoseconds > compositor_accumulate_frame_node_execution_time(const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static void add_panel_items_recursive(const bContext &C, bNodeTree &ntree, bNode &node, uiBlock &block, const int locx, int &locy, int num_items, const bool is_parent_collapsed, const char *parent_label, bke::bNodePanelRuntime *parent_runtime, LocationUpdateState &state)
static void reroute_node_draw_label(TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node, uiBlock &block)
ImBuf * node_preview_acquire_ibuf(bNodeTree &ntree, NestedTreePreviews &tree_previews, const bNode &node)
std::array< float2, 4 > node_link_bezier_points_dragged(const SpaceNode &snode, const bNodeLink &link)
bNodeSocket * node_find_indicated_socket(SpaceNode &snode, ARegion ®ion, const float2 &cursor, const eNodeSocketInOut in_out)
static bool realtime_compositor_is_in_use(const bContext &context)
static void node_draw_hidden(const bContext &C, TreeDrawContext &tree_draw_ctx, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, bNode &node, uiBlock &block)
static std::optional< NodeExtraInfoRow > node_get_accessed_attributes_row(TreeDrawContext &tree_draw_ctx, const bNode &node)
void node_socket_color_get(const bContext &C, const bNodeTree &ntree, PointerRNA &node_ptr, const bNodeSocket &sock, float r_color[4])
Array< bNode * > tree_draw_order_calc_nodes_reversed(bNodeTree &ntree)
static void node_get_compositor_extra_info(TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node, Vector< NodeExtraInfoRow > &rows)
void node_set_cursor(wmWindow &win, ARegion ®ion, SpaceNode &snode, const float2 &cursor)
void node_draw_link(const bContext &C, const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, const bool selected)
static const bNodeSocket * target_for_reroute(const bNodeSocket &reroute_output)
static void node_draw_mute_line(const bContext &C, const View2D &v2d, const SpaceNode &snode, const bNode &node)
static void reroute_node_prepare_for_draw(bNode &node)
static Vector< NodeInterfaceItemData > node_build_item_data(bNode &node)
static const bNode * find_node_under_cursor(SpaceNode &snode, const float2 &cursor)
static bool is_node_panels_supported(const bNode &node)
static NodeExtraInfoRow row_from_used_named_attribute(const Map< StringRefNull, geo_log::NamedAttributeUsage > &usage_by_attribute_name)
void node_draw_link_dragged(const bContext &C, const View2D &v2d, const SpaceNode &snode, const bNodeLink &link)
static bool node_update_basis_buttons(const bContext &C, bNodeTree &ntree, bNode &node, nodes::PanelDrawButtonsFunction draw_buttons, uiBlock &block, int &dy)
static void node_add_unsupported_compositor_operation_error_message_button(const bNode &node, uiBlock &block, const rctf &rect, float &icon_offset)
static std::optional< std::chrono::nanoseconds > compositor_node_get_execution_time(const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static void find_bounds_by_zone_recursive(const SpaceNode &snode, const bNodeTreeZone &zone, const Span< std::unique_ptr< bNodeTreeZone > > all_zones, MutableSpan< Vector< float2 > > r_bounds_by_zone)
static void node_toggle_button_cb(bContext *C, void *node_argv, void *op_argv)
static Array< uiBlock * > node_uiblocks_init(const bContext &C, const Span< bNode * > nodes)
static void add_rect_corner_positions(Vector< float2 > &positions, const rctf &rect)
bool node_is_previewable(const SpaceNode &snode, const bNodeTree &ntree, const bNode &node)
static void node_socket_tooltip_set(uiBlock &block, const int socket_index_in_tree, const float2 location, const float2 size)
void draw_nodespace_back_pix(const bContext &C, ARegion ®ion, SpaceNode &snode, bNodeInstanceKey parent_key)
static std::optional< std::string > create_default_value_inspection_string(const bNodeSocket &socket)
static StringRefNull reroute_node_get_auto_label(TreeDrawContext &tree_draw_ctx, const bNode &src_reroute)
static float frame_node_label_height(const NodeFrame &frame_data)
static std::optional< std::chrono::nanoseconds > geo_node_get_execution_time(const TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static void node_draw_basis(const bContext &C, TreeDrawContext &tree_draw_ctx, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, const bNode &node, uiBlock &block, bNodeInstanceKey key)
static void node_draw_extra_info_panel_back(const bNode &node, const rctf &extra_info_rect)
static void node_draw_extra_info_panel(const bContext &C, TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node, ImBuf *preview, uiBlock &block)
static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode)
static void node_update_basis_from_declaration(const bContext &C, bNodeTree &ntree, bNode &node, uiBlock &block, const int locx, int &locy)
static void node_update_basis(const bContext &C, const TreeDrawContext &, bNodeTree &ntree, bNode &node, uiBlock &block)
const char * node_socket_get_label(const bNodeSocket *socket, const char *panel_label)
static void create_inspection_string_for_geometry_socket(fmt::memory_buffer &buf, const nodes::decl::Geometry *socket_decl)
static std::string node_get_execution_time_label(TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static void create_inspection_string_for_default_socket_value(const bNodeSocket &socket, fmt::memory_buffer &buf)
static void node_draw_extra_info_row(const bNode &node, uiBlock &block, const rctf &rect, const int row, const NodeExtraInfoRow &extra_info_row)
static void node_draw_preview(const Scene *scene, ImBuf *preview, const rctf *prv)
static void node_draw_nodetree(const bContext &C, TreeDrawContext &tree_draw_ctx, ARegion ®ion, SpaceNode &snode, bNodeTree &ntree, Span< bNode * > nodes, Span< uiBlock * > blocks, bNodeInstanceKey parent_key)
static void node_update_basis_from_socket_lists(const bContext &C, bNodeTree &ntree, bNode &node, uiBlock &block, const int locx, int &locy)
Array< bNode * > tree_draw_order_calc_nodes(bNodeTree &ntree)
static std::string named_attribute_tooltip(bContext *, void *argN, const char *)
static void node_update_hidden(bNode &node, uiBlock &block)
void node_select_single(bContext &C, bNode &node)
static Vector< NodeExtraInfoRow > node_get_extra_info(const bContext &C, TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
NestedTreePreviews * get_nested_previews(const bContext &C, SpaceNode &snode)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
static std::optional< std::string > create_dangling_reroute_inspection_string(const bNodeTree &ntree, const bNodeSocket &socket)
static std::optional< NodeExtraInfoRow > node_get_execution_time_label_row(TreeDrawContext &tree_draw_ctx, const SpaceNode &snode, const bNode &node)
static std::optional< std::string > create_declaration_inspection_string(const bNodeSocket &socket)
static void node_update_panel_items_visibility_recursive(int num_items, const bool is_parent_collapsed, bNodePanelState &parent_state, VisibilityUpdateState &state)
static const float virtual_node_socket_outline_color[4]
static void create_inspection_string_for_field_info(const bNodeSocket &socket, const geo_log::FieldInfoLog &value_log, fmt::memory_buffer &buf)
static void node_draw_sockets(const View2D &v2d, const bContext &C, const bNodeTree &ntree, const bNode &node, uiBlock &block, const bool draw_outputs, const bool select_all)
float2 node_to_view(const bNode &node, const float2 &co)
void snode_set_context(const bContext &C)
static void node_socket_add_tooltip_in_node_editor(const bNodeSocket &sock, uiLayout &layout)
static void node_panel_toggle_button_cb(bContext *C, void *panel_state_argv, void *ntree_argv)
NodeResizeDirection node_get_resize_direction(const SpaceNode &snode, const bNode *node, const int x, const int y)
static const char * node_socket_get_translation_context(const bNodeSocket &socket)
static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, const bNodeTree &ntree, const bNode &node, const SpaceNode &snode)
static void node_draw(const bContext &C, TreeDrawContext &tree_draw_ctx, ARegion ®ion, const SpaceNode &snode, bNodeTree &ntree, bNode &node, uiBlock &block, bNodeInstanceKey key)
void node_release_preview_ibuf(NestedTreePreviews &tree_previews)
static std::optional< std::string > create_multi_input_log_inspection_string(const bNodeTree &ntree, const bNodeSocket &socket, TreeDrawContext &tree_draw_ctx)
static void create_inspection_string_for_generic_value(const bNodeSocket &socket, const GPointer value, fmt::memory_buffer &buf)
void node_to_updated_rect(const bNode &node, rctf &r_rect)
static std::string node_socket_get_tooltip(const SpaceNode *snode, const bNodeTree &ntree, const bNodeSocket &socket)
static void node_add_error_message_button(const TreeDrawContext &tree_draw_ctx, const bNode &node, uiBlock &block, const rctf &rect, float &icon_offset)
void node_draw_space(const bContext &C, ARegion ®ion)
static void node_draw_preview_background(rctf *rect)
static void node_draw_panels(bNodeTree &ntree, const bNode &node, uiBlock &block)
static void node_draw_shadow(const SpaceNode &snode, const bNode &node, const float radius, const float alpha)
static geo_log::NodeWarningType node_error_highest_priority(Span< geo_log::NodeWarning > warnings)
static void draw_tree_path(const bContext &C, ARegion ®ion)
static Vector< std::string > lines_of_text(std::string text)
static void node_draw_panels_background(const bNode &node, uiBlock &block)
static Set< const bNodeSocket * > find_sockets_on_active_gizmo_paths(const bContext &C, const SpaceNode &snode)
void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout)
static void frame_node_draw_overlay(const bContext &C, TreeDrawContext &tree_draw_ctx, const ARegion ®ion, const SpaceNode &snode, const bNodeTree &ntree, const bNode &node, uiBlock &block)
static void node_socket_draw_nested(const bContext &C, const bNodeTree &ntree, PointerRNA &node_ptr, uiBlock &block, const bNodeSocket &sock, const uint pos_id, const uint col_id, const uint shape_id, const uint size_id, const uint outline_col_id, const float size, const bool selected)
float2 node_from_view(const bNode &node, const float2 &co)
static int node_get_colorid(TreeDrawContext &tree_draw_ctx, const bNode &node)
static void node_get_invalid_links_extra_info(const SpaceNode &snode, const bNode &node, Vector< NodeExtraInfoRow > &rows)
static void frame_node_prepare_for_draw(bNode &node, Span< bNode * > nodes)
static void snode_setup_v2d(SpaceNode &snode, ARegion ®ion, const float2 ¢er)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
T interpolate(const T &a, const T &b, const FactorT &t)
Euler3Base< T > to_euler(const AxisAngleBase< T, AngleT > &axis_angle, EulerOrder order)
int node_warning_type_icon(const NodeWarningType type)
void foreach_active_gizmo(const bContext &C, ComputeContextBuilder &compute_context_builder, const ForeachGizmoFn fn)
void foreach_socket_on_gizmo_path(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket, FunctionRef< void(const ComputeContext &context, const bNodeSocket &socket, const ie::ElemVariant &elem)> fn)
void(*)(uiLayout *, bContext *, PointerRNA *) PanelDrawButtonsFunction
std::unique_ptr< ItemDeclaration > ItemDeclarationPtr
std::chrono::nanoseconds Nanoseconds
VecBase< float, 4 > float4
VecBase< float, 2 > float2
#define NODE_HEADER_ICON_SIZE
static bNodeTree * node_tree_from_ID(ID *id)
float ED_node_grid_size()
void ED_node_tag_update_id(ID *id)
#define NODE_TREE_SCALE_SMALL
#define NODE_FRAME_MARGIN
void ED_node_tree_update(const bContext *C)
#define NODE_SOCK_OUTLINE_SCALE
#define NODE_MULTI_INPUT_LINK_GAP
#define NODE_SOCKSIZE_DRAW_MULIPLIER
#define NODE_ITEM_SPACING_Y
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
unsigned __int64 uint64_t
SpaceNode_Runtime * runtime
struct bNodeTree * edittree
struct bNodeTree * nodetree
const bNode * active_geometry_nodes_viewer
bool used_by_realtime_compositor
blender::Map< const bNode *, blender::StringRefNull > reroute_auto_labels
blender::Map< const bNodeTreeZone *, geo_log::GeoTreeLog * > geo_log_by_zone
blender::Map< bNodeInstanceKey, blender::timeit::Nanoseconds > * compositor_per_node_execution_time
NestedTreePreviews * nested_group_infos
bNodeSocketRuntimeHandle * runtime
bNodeSocketTypeHandle * typeinfo
struct bNodeTree * nodetree
bNodeInstanceKey parent_key
bNodeTreeRuntimeHandle * runtime
bNodeTreeTypeHandle * typeinfo
bNodeTypeHandle * typeinfo
bool need_spacer_after_item
const ItemIterator item_end
LocationUpdateState(const Span< NodeInterfaceItemData > items)
bool is_valid_separator() const
const nodes::SocketDeclaration * socket_decl
bke::bNodePanelRuntime * runtime
const nodes::PanelDeclaration * panel_decl
static NodeInterfaceItemData separator()
NodeInterfaceItemData(const nodes::PanelDeclaration *_panel_decl, bNodePanelState *_state, bke::bNodePanelRuntime *_runtime)
bool is_valid_socket() const
bool is_valid_panel() const
NodeInterfaceItemData(const nodes::SocketDeclaration *_socket_decl, bNodeSocket *_input, bNodeSocket *_output)
std::unique_ptr< bNodeLinkDrag > linkdrag
VisibilityUpdateState(const Span< NodeInterfaceItemData > items)
const ItemIterator item_end
struct wmEvent * eventstate
void WM_cursor_set(wmWindow *win, int curs)
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
void WM_main_add_notifier(uint type, void *reference)
int WM_operator_name_call(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
void WM_gizmomap_draw(wmGizmoMap *gzmap, const bContext *C, const eWM_GizmoFlagMapDrawStep drawstep)
void wmOrtho2_pixelspace(const float x, const float y)
void wmOrtho2_region_pixelspace(const ARegion *region)
bScreen * WM_window_get_active_screen(const wmWindow *win)