[Bf-blender-cvs] [b5ea0d2f411] geometry-nodes-simulation: Add frame around nodes in simulation
Jacques Lucke
noreply at git.blender.org
Thu Nov 24 16:35:54 CET 2022
Commit: b5ea0d2f411ba88ae5e1c3253e3ad9e813b02279
Author: Jacques Lucke
Date: Thu Nov 24 16:35:40 2022 +0100
Branches: geometry-nodes-simulation
https://developer.blender.org/rBb5ea0d2f411ba88ae5e1c3253e3ad9e813b02279
Add frame around nodes in simulation
===================================================================
M source/blender/editors/space_node/CMakeLists.txt
M source/blender/editors/space_node/drawnode.cc
M source/blender/editors/space_node/node_draw.cc
===================================================================
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index f8289b42463..10e44455842 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -12,6 +12,7 @@ set(INC
../../depsgraph
../../draw
../../functions
+ ../../geometry
../../gpu
../../imbuf
../../makesdna
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index 708efc0c7a6..944fbb25a37 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -2209,8 +2209,10 @@ void node_draw_link(const bContext &C,
node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3, selected);
}
-static std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &snode,
- const bNodeLink &link)
+std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &snode,
+ const bNodeLink &link);
+std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &snode,
+ const bNodeLink &link)
{
const float2 cursor = snode.runtime->cursor * UI_DPI_FAC;
std::array<float2, 4> points;
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 67adf3865be..7e2d57e1d52 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -22,6 +22,7 @@
#include "DNA_world_types.h"
#include "BLI_array.hh"
+#include "BLI_convexhull_2d.h"
#include "BLI_map.hh"
#include "BLI_set.hh"
#include "BLI_span.hh"
@@ -32,6 +33,7 @@
#include "BKE_compute_contexts.hh"
#include "BKE_context.h"
+#include "BKE_curves.hh"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@@ -77,6 +79,8 @@
#include "FN_field.hh"
#include "FN_field_cpp_type.hh"
+#include "GEO_fillet_curves.hh"
+
#include "node_intern.hh" /* own include */
namespace geo_log = blender::nodes::geo_eval_log;
@@ -90,6 +94,14 @@ extern void ui_draw_dropshadow(
const rctf *rct, float radius, float aspect, float alpha, int select);
}
+namespace blender::ed::space_node {
+struct SubContext {
+ float3 color;
+ Vector<const bNode *> input_nodes;
+ Vector<const bNode *> output_nodes;
+};
+} // namespace blender::ed::space_node
+
/**
* This is passed to many functions which draw the node editor.
*/
@@ -111,6 +123,8 @@ struct TreeDrawContext {
* True if there is an active realtime compositor using the node tree, false otherwise.
*/
bool used_by_realtime_compositor = false;
+
+ Vector<blender::ed::space_node::SubContext> sub_contexts;
};
float ED_node_grid_size()
@@ -2100,7 +2114,9 @@ static void node_draw_basis(const bContext &C,
}
/* Shadow. */
- node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
+ if (!ELEM(node.type, GEO_NODE_SIMULATION_INPUT, GEO_NODE_SIMULATION_OUTPUT)) {
+ node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
+ }
const rctf &rct = node.runtime->totr;
float color[4];
@@ -2369,6 +2385,23 @@ static void node_draw_basis(const bContext &C,
else if (nodeTypeUndefined(&node)) {
UI_GetThemeColor4fv(TH_REDALERT, color_outline);
}
+ else if (ELEM(node.type, GEO_NODE_SIMULATION_INPUT, GEO_NODE_SIMULATION_OUTPUT)) {
+ const SubContext *context = [&]() -> const SubContext * {
+ for (const SubContext &context : tree_draw_ctx.sub_contexts) {
+ if (context.input_nodes.contains(&node) || context.output_nodes.contains(&node)) {
+ return &context;
+ }
+ }
+ return nullptr;
+ }();
+ if (context == nullptr) {
+ UI_GetThemeColor4fv(TH_REDALERT, color_outline);
+ }
+ else {
+ copy_v3_v3(color_outline, context->color);
+ color_outline[3] = 1.0f;
+ }
+ }
else {
UI_GetThemeColorBlendShade4fv(TH_BACK, TH_NODE, 0.4f, -20, color_outline);
}
@@ -2988,6 +3021,149 @@ static void node_draw(const bContext &C,
}
}
+static Set<const bNode *> find_nodes_in_sub_context(const Span<const bNode *> context_inputs,
+ const Span<const bNode *> context_outputs)
+{
+ Set<const bNode *> nodes_in_context;
+ Stack<const bNode *> nodes_to_check;
+
+ nodes_in_context.add_multiple(context_inputs);
+ nodes_in_context.add_multiple(context_outputs);
+ nodes_to_check.push_multiple(context_inputs);
+
+ while (!nodes_to_check.is_empty()) {
+ const bNode &node = *nodes_to_check.pop();
+ for (const bNodeSocket *output_socket : node.output_sockets()) {
+ if (!output_socket->is_available()) {
+ continue;
+ }
+ for (const bNodeLink *link : output_socket->directly_linked_links()) {
+ const bNode *target_node = link->tonode;
+ if (nodes_in_context.add(target_node)) {
+ nodes_to_check.push(target_node);
+ }
+ }
+ }
+ }
+
+ return nodes_in_context;
+}
+
+static void add_rect_corner_positions(Vector<float2> &positions, const rctf &rect)
+{
+ positions.append({rect.xmin, rect.ymin});
+ positions.append({rect.xmin, rect.ymax});
+ positions.append({rect.xmax, rect.ymin});
+ positions.append({rect.xmax, rect.ymax});
+}
+
+std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &snode,
+ const bNodeLink &link);
+
+static void node_draw_sub_context_frames(TreeDrawContext &tree_draw_ctx,
+ SpaceNode &snode,
+ bNodeTree &ntree)
+{
+ const Span<const bNode *> all_simulation_inputs = ntree.nodes_by_type(
+ "GeometryNodeSimulationInput");
+ const Span<const bNode *> all_simulation_outputs = ntree.nodes_by_type(
+ "GeometryNodeSimulationOutput");
+ if (all_simulation_inputs.is_empty() || all_simulation_outputs.is_empty()) {
+ return;
+ }
+ Vector<SubContext> sub_contexts;
+ sub_contexts.append({float3(0.0f, 0.0f, 0.0f), all_simulation_inputs, all_simulation_outputs});
+
+ for (SubContext &sub_context : sub_contexts) {
+ const Span<const bNode *> context_inputs = sub_context.input_nodes;
+ const Span<const bNode *> context_outputs = sub_context.output_nodes;
+ const Set<const bNode *> nodes_in_context = find_nodes_in_sub_context(context_inputs,
+ context_outputs);
+
+ Vector<float2> possible_boundary_positions;
+ const float padding = UI_UNIT_X;
+ for (const bNode *node : nodes_in_context) {
+ const rctf &totr = node->runtime->totr;
+ rctf rect = totr;
+ BLI_rctf_pad(&rect, padding, padding);
+ if (context_inputs.contains(node)) {
+ rect.xmin = math::interpolate(rect.xmin, rect.xmax, 0.5f);
+ }
+ else if (context_outputs.contains(node)) {
+ rect.xmax = math::interpolate(rect.xmin, rect.xmax, 0.5f);
+ }
+ add_rect_corner_positions(possible_boundary_positions, rect);
+ }
+
+ if (snode.runtime->linkdrag) {
+ for (const bNodeLink *link : snode.runtime->linkdrag->links) {
+ if (link->fromnode == nullptr) {
+ continue;
+ }
+ if (nodes_in_context.contains(link->fromnode) &&
+ !context_outputs.contains(link->fromnode)) {
+ const float2 pos = node_link_bezier_points_dragged(snode, *link)[3];
+ rctf rect;
+ BLI_rctf_init_pt_radius(&rect, pos, padding);
+ add_rect_corner_positions(possible_boundary_positions, rect);
+ }
+ }
+ }
+
+ Vector<int> convex_indices(possible_boundary_positions.size());
+ const int num_convex_positions = BLI_convexhull_2d(
+ reinterpret_cast<float(*)[2]>(possible_boundary_positions.data()),
+ possible_boundary_positions.size(),
+ convex_indices.data());
+ convex_indices.resize(num_convex_positions);
+
+ bke::CurvesGeometry boundary_curve(num_convex_positions, 1);
+ boundary_curve.cyclic_for_write().first() = true;
+ boundary_curve.fill_curve_types(CURVE_TYPE_POLY);
+ MutableSpan<float3> boundary_curve_positions = boundary_curve.positions_for_write();
+ MutableSpan<int> boundary_curve_offsets = boundary_curve.offsets_for_write();
+ boundary_curve_offsets[0] = 0;
+ boundary_curve_offsets[1] = num_convex_positions;
+ for (const int i : convex_indices.index_range()) {
+ boundary_curve_positions[i] = float3(possible_boundary_positions[convex_indices[i]], 0.0f);
+ }
+ boundary_curve.tag_topology_changed();
+
+ bke::CurvesGeometry fillet_curve = geometry::fillet_curves_poly(
+ boundary_curve,
+ IndexRange(1),
+ VArray<float>::ForSingle(UI_UNIT_X / 2, num_convex_positions),
+ VArray<int>::ForSingle(5, num_convex_positions),
+ true);
+ const Span<float3> boundary_positions = fillet_curve.positions();
+
+ const uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+
+ GPU_blend(GPU_BLEND_ALPHA);
+ immUniformColor4f(sub_context.color[0], sub_context.color[1], sub_context.color[2], 0.2f);
+ immBegin(GPU_PRIM_TRI_FAN, boundary_positions.size() + 1);
+ for (const float3 &p : boundary_positions) {
+ immVertex3fv(pos, p);
+ }
+ immVertex3fv(pos, boundary_positions[0]);
+ immEnd();
+ immUniformColor4f(sub_context.color[0], sub_context.color[1], sub_context.color[2], 1.0f);
+ immBegin(GPU_PRIM_LINE_STRIP, boundary_positions.size() + 1);
+ for (const float3 &p : boundary_positions) {
+ immVertex3fv(pos, p);
+ }
+ immVertex3fv(pos, boundary_positions[0]);
+ immEnd();
+
+ immUnbindProgram();
+ GPU_blend(GPU_BLEND_NONE);
+ }
+
+ tree_draw_ctx.sub_contexts = sub_contexts;
+}
+
#define USE_DRAW_TOT_UPDATE
static void node_draw_nodetree(const bContext &C,
@@ -3163,6 +3339,7 @@ static void draw_nodetree(const bContext &C,
}
node_update_nodetree(C, tree_draw_c
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list