1
1

Compare commits

...

14 Commits

23 changed files with 125 additions and 121 deletions

View File

@@ -306,64 +306,6 @@ class NODE_OT_tree_path_parent(Operator):
return {'FINISHED'}
class NODE_OT_active_preview_toggle(Operator):
'''Toggle active preview state of node'''
bl_idname = "node.active_preview_toggle"
bl_label = "Toggle Active Preview"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
space = context.space_data
if space is None:
return False
if space.type != 'NODE_EDITOR':
return False
if space.edit_tree is None:
return False
if space.edit_tree.nodes.active is None:
return False
return True
def execute(self, context):
node_editor = context.space_data
ntree = node_editor.edit_tree
active_node = ntree.nodes.active
if active_node.active_preview:
self.disable_preview(context, ntree, active_node)
else:
self.enable_preview(context, node_editor, ntree, active_node)
return {'FINISHED'}
def enable_preview(self, context, node_editor, ntree, active_node):
spreadsheets = self.find_unpinned_spreadsheets(context)
for spreadsheet in spreadsheets:
spreadsheet.set_geometry_node_context(node_editor, active_node)
for node in ntree.nodes:
node.active_preview = False
active_node.active_preview = True
def disable_preview(self, context, ntree, active_node):
spreadsheets = self.find_unpinned_spreadsheets(context)
for spreadsheet in spreadsheets:
spreadsheet.context_path.clear()
active_node.active_preview = False
def find_unpinned_spreadsheets(self, context):
spreadsheets = []
for window in context.window_manager.windows:
for area in window.screen.areas:
space = area.spaces.active
if space.type == 'SPREADSHEET' and not space.is_pinned:
spreadsheets.append(space)
return spreadsheets
classes = (
NodeSetting,
@@ -372,5 +314,4 @@ classes = (
NODE_OT_add_search,
NODE_OT_collapse_hide_unused_toggle,
NODE_OT_tree_path_parent,
NODE_OT_active_preview_toggle,
)

View File

@@ -56,7 +56,7 @@ class SPREADSHEET_OT_toggle_pin(Operator):
for node_editor in node_editors:
ntree = node_editor.edit_tree
for node in ntree.nodes:
if node.active_preview:
if node.bl_idname == "GeometryNodeViewer":
space.set_geometry_node_context(node_editor, node)
return

View File

@@ -566,6 +566,9 @@ geometry_node_categories = [
NodeItem("ShaderNodeVectorMath"),
NodeItem("ShaderNodeVectorRotate"),
]),
GeometryNodeCategory("GEO_OUTPUT", "Output", items=[
NodeItem("GeometryNodeViewer"),
]),
GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
NodeItem("GeometryNodePointsToVolume"),
NodeItem("GeometryNodeVolumeToMesh"),

View File

@@ -1431,6 +1431,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define GEO_NODE_MATERIAL_REPLACE 1051
#define GEO_NODE_MESH_TO_CURVE 1052
#define GEO_NODE_DELETE_GEOMETRY 1053
#define GEO_NODE_VIEWER 1054
/** \} */

View File

@@ -3147,8 +3147,8 @@ void ntreeSetOutput(bNodeTree *ntree)
if (ntree->type == NTREE_COMPOSIT) {
/* same type, exception for viewer */
if (tnode->type == node->type ||
(ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
(ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER) &&
ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER))) {
if (tnode->flag & NODE_DO_OUTPUT) {
output++;
if (output > 1) {
@@ -5082,6 +5082,7 @@ static void registerGeometryNodes()
register_node_type_geo_switch();
register_node_type_geo_transform();
register_node_type_geo_triangulate();
register_node_type_geo_viewer();
register_node_type_geo_volume_to_mesh();
}

View File

@@ -40,6 +40,7 @@ struct bNodeSocketType;
struct bNodeTree;
struct bNodeTreeType;
struct bNodeType;
struct SpaceNode;
typedef enum {
NODE_TOP = 1,
@@ -109,6 +110,7 @@ bool ED_node_select_check(ListBase *lb);
void ED_node_select_all(ListBase *lb, int action);
void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree);
void ED_node_set_active(struct Main *bmain,
struct SpaceNode *snode,
struct bNodeTree *ntree,
struct bNode *node,
bool *r_active_texture_changed);

View File

@@ -451,7 +451,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)
/* set user as active */
if (user->node) {
ED_node_set_active(CTX_data_main(C), user->ntree, user->node, NULL);
ED_node_set_active(CTX_data_main(C), NULL, user->ntree, user->node, NULL);
ct->texture = NULL;
/* Not totally sure if we should also change selection? */

View File

@@ -90,7 +90,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
nodeSetSelected(node, true);
ntreeUpdateTree(bmain, snode->edittree);
ED_node_set_active(bmain, snode->edittree, node, NULL);
ED_node_set_active(bmain, snode, snode->edittree, node, NULL);
snode_update(snode, node);

View File

@@ -1404,28 +1404,6 @@ static void node_draw_basis(const bContext *C,
"");
UI_block_emboss_set(node->block, UI_EMBOSS);
}
if (ntree->type == NTREE_GEOMETRY) {
/* Active preview toggle. */
iconofs -= iconbutw;
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
int icon = (node->flag & NODE_ACTIVE_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON;
uiBut *but = uiDefIconBut(node->block,
UI_BTYPE_BUT_TOGGLE,
0,
icon,
iconofs,
rct->ymax - NODE_DY,
iconbutw,
UI_UNIT_Y,
nullptr,
0,
0,
0,
0,
"Show this node's geometry output in the spreadsheet");
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_active_preview_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
}
node_add_error_message_button(C, *ntree, *node, *rct, iconofs);

View File

@@ -54,6 +54,7 @@
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
#include "ED_spreadsheet.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -383,7 +384,7 @@ bool composite_node_editable(bContext *C)
{
if (ED_operator_node_editable(C)) {
SpaceNode *snode = CTX_wm_space_node(C);
if (ED_node_is_compositor(snode)) {
if (ED_node_is_compositor(snode) || ED_node_is_geometry(snode)) {
return true;
}
}
@@ -662,7 +663,8 @@ void snode_update(SpaceNode *snode, bNode *node)
}
}
void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
void ED_node_set_active(
Main *bmain, SpaceNode *snode, bNodeTree *ntree, bNode *node, bool *r_active_texture_changed)
{
const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0;
if (r_active_texture_changed) {
@@ -782,6 +784,30 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti
}
#endif
}
else if (ntree->type == NTREE_GEOMETRY) {
if (node->type == GEO_NODE_VIEWER) {
LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) {
if (node_iter->type == GEO_NODE_VIEWER) {
node_iter->flag &= ~NODE_DO_OUTPUT;
}
}
node->flag |= NODE_DO_OUTPUT;
wmWindowManager *wm = bmain->wm.first;
LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
SpaceLink *sl = (SpaceLink *)area->spacedata.first;
if (sl->spacetype == SPACE_SPREADSHEET) {
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
if ((sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) == 0) {
ED_spreadsheet_set_geometry_node_context(sspreadsheet, snode, node);
ED_area_tag_redraw(area);
}
}
}
}
}
}
}
}
@@ -1317,7 +1343,6 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
nodeSetSelected(node, false);
node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE);
nodeSetSelected(newnode, true);
newnode->flag &= ~NODE_ACTIVE_PREVIEW;
do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode));
}

View File

@@ -275,7 +275,6 @@ void NODE_OT_hide_toggle(struct wmOperatorType *ot);
void NODE_OT_hide_socket_toggle(struct wmOperatorType *ot);
void NODE_OT_preview_toggle(struct wmOperatorType *ot);
void NODE_OT_options_toggle(struct wmOperatorType *ot);
void NODE_OT_active_preview_toggle(struct wmOperatorType *ot);
void NODE_OT_node_copy_color(struct wmOperatorType *ot);
void NODE_OT_read_viewlayers(struct wmOperatorType *ot);

View File

@@ -158,6 +158,11 @@ bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node)
return true;
}
}
if (current_node->type == GEO_NODE_VIEWER) {
if (ntree_check_nodes_connected(ntree, node, current_node)) {
return true;
}
}
}
return false;
}
@@ -598,14 +603,14 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
if (tonode == NULL || BLI_listbase_is_empty(&tonode->outputs)) {
return OPERATOR_CANCELLED;
}
if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
if (ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
return OPERATOR_CANCELLED;
}
/* get viewer */
bNode *viewer_node = NULL;
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
if (node->flag & NODE_DO_OUTPUT) {
viewer_node = node;
break;
@@ -615,7 +620,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
/* no viewer, we make one active */
if (viewer_node == NULL) {
LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER)) {
node->flag |= NODE_DO_OUTPUT;
viewer_node = node;
break;

View File

@@ -468,7 +468,7 @@ void node_select_single(bContext *C, bNode *node)
}
nodeSetSelected(node, true);
ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed);
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
@@ -605,12 +605,15 @@ static int node_mouse_select(bContext *C,
/* update node order */
if (ret_value != OPERATOR_CANCELLED) {
bool active_texture_changed = false;
bool viewer_node_changed = false;
if (node != NULL && ret_value != OPERATOR_RUNNING_MODAL) {
ED_node_set_active(bmain, snode->edittree, node, &active_texture_changed);
ED_node_set_active(bmain, snode, snode->edittree, node, &active_texture_changed);
viewer_node_changed = node->type == GEO_NODE_VIEWER;
}
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
if (active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) {
if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) ||
viewer_node_changed) {
DEG_id_tag_update(&snode->edittree->id, ID_RECALC_COPY_ON_WRITE);
}

View File

@@ -24,6 +24,7 @@
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
#include "ED_screen.h"
#include "ED_spreadsheet.h"
#include "DEG_depsgraph.h"

View File

@@ -320,6 +320,7 @@ typedef struct bNode {
#define NODE_HIDDEN 8
#define NODE_ACTIVE 16
#define NODE_ACTIVE_ID 32
/* Used to indicate which group output node is used and which viewer node is active. */
#define NODE_DO_OUTPUT 64
#define __NODE_GROUP_EDIT 128 /* DEPRECATED */
/* free test flag, undefined */
@@ -354,7 +355,7 @@ typedef struct bNode {
*/
#define NODE_DO_OUTPUT_RECALC (1 << 17)
/* A preview for the data in this node can be displayed in the spreadsheet editor. */
#define NODE_ACTIVE_PREVIEW (1 << 18)
#define __NODE_ACTIVE_PREVIEW (1 << 18) /* deprecated */
/* node->update */
/* XXX NODE_UPDATE is a generic update flag. More fine-grained updates

View File

@@ -11163,12 +11163,6 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Texture", "Display node in viewport textured shading mode");
RNA_def_property_update(prop, 0, "rna_Node_update");
prop = RNA_def_property(srna, "active_preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_ACTIVE_PREVIEW);
RNA_def_property_ui_text(prop, "Active Preview", "Node is previewed in other editor");
RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
RNA_def_property_update(prop, NC_NODE, NULL);
/* generic property update function */
func = RNA_def_function(srna, "socket_value_update", "rna_Node_socket_value_update");
RNA_def_function_ui_description(func, "Update after property changes");

View File

@@ -768,22 +768,6 @@ static Vector<SpaceSpreadsheet *> find_spreadsheet_editors(Main *bmain)
using PreviewSocketMap = blender::MultiValueMap<DSocket, uint64_t>;
static DSocket try_find_preview_socket_in_node(const DNode node)
{
for (const SocketRef *socket : node->outputs()) {
if (socket->bsocket()->type == SOCK_GEOMETRY) {
return {node.context(), socket};
}
}
for (const SocketRef *socket : node->inputs()) {
if (socket->bsocket()->type == SOCK_GEOMETRY &&
(socket->bsocket()->flag & SOCK_MULTI_INPUT) == 0) {
return {node.context(), socket};
}
}
return {};
}
static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspreadsheet,
NodesModifierData *nmd,
const ModifierEvalContext *ctx,
@@ -839,7 +823,17 @@ static DSocket try_get_socket_to_preview_for_spreadsheet(SpaceSpreadsheet *sspre
const NodeTreeRef &tree_ref = context->tree();
for (const NodeRef *node_ref : tree_ref.nodes()) {
if (node_ref->name() == last_context->node_name) {
return try_find_preview_socket_in_node({context, node_ref});
const DNode viewer_node{context, node_ref};
DSocket socket_to_view;
viewer_node.input(0).foreach_origin_socket(
[&](const DSocket socket) { socket_to_view = socket; });
if (!socket_to_view) {
return {};
}
bNodeSocket *bsocket = socket_to_view->bsocket();
if (bsocket->type == SOCK_GEOMETRY && bsocket->flag != SOCK_MULTI_INPUT) {
return socket_to_view;
}
}
}
return {};
@@ -975,6 +969,8 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
blender::modifiers::geometry_nodes::GeometryNodesEvaluationParams eval_params;
eval_params.input_values = group_inputs;
eval_params.output_sockets = group_outputs;
eval_params.force_compute_sockets.extend(preview_sockets.keys().begin(),
preview_sockets.keys().end());
eval_params.mf_by_node = &mf_by_node;
eval_params.modifier_ = nmd;
eval_params.depsgraph = ctx->depsgraph;

View File

@@ -404,6 +404,9 @@ class GeometryNodesEvaluator {
for (const DInputSocket &socket : params_.output_sockets) {
nodes_to_check.push(socket.node());
}
for (const DSocket &socket : params_.force_compute_sockets) {
nodes_to_check.push(socket.node());
}
/* Use the local allocator because the states do not need to outlive the evaluator. */
LinearAllocator<> &allocator = local_allocators_.local();
while (!nodes_to_check.is_empty()) {
@@ -500,7 +503,8 @@ class GeometryNodesEvaluator {
},
{});
if (output_state.potential_users == 0) {
/* If it does not have any potential users, it is unused. */
/* If it does not have any potential users, it is unused. It might become required again if
* the output itself is needed. */
output_state.output_usage = ValueUsage::Unused;
}
}
@@ -573,6 +577,21 @@ class GeometryNodesEvaluator {
/* Setting an input as required will schedule any linked node. */
this->set_input_required(locked_node, socket);
}
for (const DSocket socket : params_.force_compute_sockets) {
const DNode node = socket.node();
NodeState &node_state = this->get_node_state(node);
LockedNode locked_node{*this, node, node_state};
if (socket->is_input()) {
this->set_input_required(locked_node, DInputSocket(socket));
}
else {
OutputState &output_state = node_state.outputs[socket->index()];
output_state.output_usage = ValueUsage::Required;
/* Add a fake user for this output. */
output_state.potential_users += 1;
this->schedule_node(locked_node);
}
}
}
void schedule_node(LockedNode &locked_node)

View File

@@ -38,6 +38,7 @@ struct GeometryNodesEvaluationParams {
Map<DOutputSocket, GMutablePointer> input_values;
Vector<DInputSocket> output_sockets;
Vector<DSocket> force_compute_sockets;
nodes::MultiFunctionByNode *mf_by_node;
const NodesModifierData *modifier_;
Depsgraph *depsgraph;

View File

@@ -193,6 +193,7 @@ set(SRC
geometry/nodes/node_geo_switch.cc
geometry/nodes/node_geo_transform.cc
geometry/nodes/node_geo_triangulate.cc
geometry/nodes/node_geo_viewer.cc
geometry/nodes/node_geo_volume_to_mesh.cc
geometry/node_geometry_exec.cc
geometry/node_geometry_tree.cc

View File

@@ -82,6 +82,7 @@ void register_node_type_geo_subdivision_surface(void);
void register_node_type_geo_switch(void);
void register_node_type_geo_transform(void);
void register_node_type_geo_triangulate(void);
void register_node_type_geo_viewer(void);
void register_node_type_geo_volume_to_mesh(void);
#ifdef __cplusplus

View File

@@ -320,6 +320,7 @@ DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, 0, "SUBDIVISION_SURFACE", Su
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "")
DefNode(GeometryNode, GEO_NODE_TRANSFORM, 0, "TRANSFORM", Transform, "Transform", "")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "")
DefNode(GeometryNode, GEO_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "")
DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_TO_MESH", VolumeToMesh, "Volume to Mesh", "")
/* undefine macros */

View File

@@ -0,0 +1,31 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "node_geometry_util.hh"
static bNodeSocketTemplate geo_node_viewer_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{-1, ""},
};
void register_node_type_geo_viewer()
{
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, 0);
node_type_socket_templates(&ntype, geo_node_viewer_in, nullptr);
nodeRegisterType(&ntype);
}