Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_spreadsheet')
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc44
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.cc301
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc2
3 files changed, 299 insertions, 48 deletions
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 07517f9e60f..fcc92345bea 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -222,24 +222,11 @@ ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet)
static void update_pinned_context_path_if_outdated(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
-
- /* Currently, this only checks if the object has been deleted. In the future we can have a more
- * sophisticated check for the entire context (including modifier and nodes). */
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- if (object_context->object == nullptr) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- break;
- }
- }
- }
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- Object *active_object = CTX_data_active_object(C);
- if (active_object != nullptr) {
- SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT);
- ((SpreadsheetContextObject *)new_context)->object = active_object;
- BLI_addtail(&sspreadsheet->context_path, new_context);
+ Main *bmain = CTX_data_main(C);
+ if (!ED_spreadsheet_context_path_exists(bmain, sspreadsheet)) {
+ ED_spreadsheet_context_path_guess(C, sspreadsheet);
+ if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
+ ED_area_tag_redraw(CTX_wm_area(C));
}
}
@@ -252,25 +239,12 @@ static void update_pinned_context_path_if_outdated(const bContext *C)
static void update_context_path_from_context(const bContext *C)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- Object *active_object = CTX_data_active_object(C);
- if (active_object == nullptr) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- return;
- }
- if (!BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first;
- if (root_context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context;
- if (object_context->object != active_object) {
- ED_spreadsheet_context_path_clear(sspreadsheet);
- }
+ if (!ED_spreadsheet_context_path_is_active(C, sspreadsheet)) {
+ ED_spreadsheet_context_path_guess(C, sspreadsheet);
+ if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) {
+ ED_area_tag_redraw(CTX_wm_area(C));
}
}
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- SpreadsheetContext *new_context = spreadsheet_context_new(SPREADSHEET_CONTEXT_OBJECT);
- ((SpreadsheetContextObject *)new_context)->object = active_object;
- BLI_addtail(&sspreadsheet->context_path, new_context);
- }
}
void spreadsheet_update_context_path(const bContext *C)
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
index af6ab5d1b92..93d7c6d9804 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
@@ -24,16 +24,28 @@
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
+#include "ED_screen.h"
#include "ED_spreadsheet.h"
#include "DEG_depsgraph.h"
+#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_workspace.h"
+
+#include "DNA_modifier_types.h"
+#include "DNA_windowmanager_types.h"
#include "spreadsheet_context.hh"
+using blender::IndexRange;
+using blender::Span;
+using blender::StringRef;
+using blender::Vector;
+
namespace blender::ed::spreadsheet {
static SpreadsheetContextObject *spreadsheet_context_object_new()
@@ -206,28 +218,30 @@ void spreadsheet_context_free(SpreadsheetContext *context)
/**
* Tag any data relevant to the spreadsheet's context for recalculation in order to collect
* information to display in the editor, which may be cached during evaluation.
+ * \return True when any data has been tagged for update.
*/
-static void spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
+static bool spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
{
using namespace blender;
Vector<const SpreadsheetContext *> context_path = sspreadsheet->context_path;
if (context_path.is_empty()) {
- return;
+ return false;
}
if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return;
+ return false;
}
SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0];
Object *object = object_context->object;
if (object == nullptr) {
- return;
+ return false;
}
if (context_path.size() == 1) {
/* No need to reevaluate, when the final or original object is viewed. */
- return;
+ return false;
}
DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
+ return true;
}
} // namespace blender::ed::spreadsheet
@@ -250,9 +264,9 @@ void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet)
BLI_listbase_clear(&sspreadsheet->context_path);
}
-void ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
+bool ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
{
- blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
+ return blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
}
uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
@@ -265,15 +279,32 @@ uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
return BLI_hash_mm2a_end(&mm2);
}
-void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node)
+void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
+ struct SpaceNode *snode,
+ struct bNode *node)
{
using namespace blender::ed::spreadsheet;
- ED_spreadsheet_context_path_clear(sspreadsheet);
Object *object = (Object *)snode->id;
+ /* Try to find the modifier the node tree belongs to. */
ModifierData *modifier = BKE_object_active_modifier(object);
+ if (modifier && modifier->type != eModifierType_Nodes) {
+ modifier = nullptr;
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Nodes) {
+ NodesModifierData *nmd = (NodesModifierData *)md;
+ if (nmd->node_group == snode->nodetree) {
+ modifier = md;
+ break;
+ }
+ }
+ }
+ }
+ if (modifier == nullptr) {
+ return;
+ }
+
+ ED_spreadsheet_context_path_clear(sspreadsheet);
{
SpreadsheetContextObject *context = spreadsheet_context_object_new();
@@ -302,5 +333,251 @@ void ED_spreadsheet_set_geometry_node_context(struct SpaceSpreadsheet *sspreadsh
BLI_addtail(&sspreadsheet->context_path, context);
}
- sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED;
+ sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE;
+}
+
+void ED_spreadsheet_context_paths_set_geometry_node(Main *bmain, SpaceNode *snode, bNode *node)
+{
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+ 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) {
+ const uint64_t context_hash_before = ED_spreadsheet_context_path_hash(sspreadsheet);
+ ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
+ const uint64_t context_hash_after = ED_spreadsheet_context_path_hash(sspreadsheet);
+ if (context_hash_before != context_hash_after) {
+ ED_spreadsheet_context_path_update_tag(sspreadsheet);
+ }
+ ED_area_tag_redraw(area);
+ }
+ }
+ }
+ }
+}
+
+void ED_spreadsheet_context_path_set_evaluated_object(SpaceSpreadsheet *sspreadsheet,
+ Object *object)
+{
+ using namespace blender::ed::spreadsheet;
+ ED_spreadsheet_context_path_clear(sspreadsheet);
+
+ SpreadsheetContextObject *context = spreadsheet_context_object_new();
+ context->object = object;
+ BLI_addtail(&sspreadsheet->context_path, context);
+}
+
+void ED_spreadsheet_context_path_guess(const bContext *C, SpaceSpreadsheet *sspreadsheet)
+{
+ ED_spreadsheet_context_path_clear(sspreadsheet);
+
+ Main *bmain = CTX_data_main(C);
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ 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_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+ if (snode->edittree != nullptr) {
+ if (snode->edittree->type == NTREE_GEOMETRY) {
+ LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
+ if (node->type == GEO_NODE_VIEWER) {
+ if (node->flag & NODE_DO_OUTPUT) {
+ ED_spreadsheet_context_path_set_geometry_node(sspreadsheet, snode, node);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Object *active_object = CTX_data_active_object(C);
+ if (active_object != nullptr) {
+ ED_spreadsheet_context_path_set_evaluated_object(sspreadsheet, active_object);
+ return;
+ }
+}
+
+bool ED_spreadsheet_context_path_is_active(const bContext *C, SpaceSpreadsheet *sspreadsheet)
+{
+ Main *bmain = CTX_data_main(C);
+ wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
+ if (wm == nullptr) {
+ return false;
+ }
+ Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
+ if (context_path.is_empty()) {
+ return false;
+ }
+ if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
+ return false;
+ }
+ Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
+ if (object == nullptr) {
+ return false;
+ }
+ if (context_path.size() == 1) {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ return false;
+ }
+ Object *active_object = CTX_data_active_object(C);
+ return object == active_object;
+ }
+ if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ return false;
+ }
+ if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
+ return false;
+ }
+ const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
+ const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (!(modifier->flag & eModifierFlag_Active)) {
+ return false;
+ }
+ if (modifier->type != eModifierType_Nodes) {
+ return false;
+ }
+ bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
+ if (root_node_tree == nullptr) {
+ return false;
+ }
+ const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
+ if (node_context_path.is_empty()) {
+ return false;
+ }
+
+ 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_NODE) {
+ continue;
+ }
+ SpaceNode *snode = (SpaceNode *)sl;
+ if (snode->nodetree != root_node_tree) {
+ continue;
+ }
+ if (snode->id != &object->id) {
+ continue;
+ }
+ Vector<bNodeTreePath *> tree_path = snode->treepath;
+ if (node_context_path.size() != tree_path.size()) {
+ continue;
+ }
+ int valid_count = 0;
+ for (const int i : IndexRange(tree_path.size() - 1)) {
+ if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
+ break;
+ }
+ SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)node_context_path[i];
+ if (!STREQ(node_context->node_name, tree_path[i]->node_name)) {
+ break;
+ }
+ valid_count++;
+ }
+ if (valid_count != tree_path.size() - 1) {
+ continue;
+ }
+ SpreadsheetContext *last_context = node_context_path.last();
+ if (last_context->type != SPREADSHEET_CONTEXT_NODE) {
+ return false;
+ }
+ const char *node_name = ((SpreadsheetContextNode *)last_context)->node_name;
+ bNode *node = nodeFindNodebyName(snode->edittree, node_name);
+ if (node == nullptr) {
+ return false;
+ }
+ if (node->type != GEO_NODE_VIEWER) {
+ return false;
+ }
+ if (!(node->flag & NODE_DO_OUTPUT)) {
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ED_spreadsheet_context_path_exists(Main *UNUSED(bmain), SpaceSpreadsheet *sspreadsheet)
+{
+ Vector<SpreadsheetContext *> context_path = sspreadsheet->context_path;
+ if (context_path.is_empty()) {
+ return false;
+ }
+ if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
+ return false;
+ }
+ Object *object = ((SpreadsheetContextObject *)context_path[0])->object;
+ if (object == nullptr) {
+ return false;
+ }
+ if (context_path.size() == 1) {
+ return true;
+ }
+ if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) {
+ return false;
+ }
+ const char *modifier_name = ((SpreadsheetContextModifier *)context_path[1])->modifier_name;
+ const ModifierData *modifier = BKE_modifiers_findby_name(object, modifier_name);
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->type != eModifierType_Nodes) {
+ return false;
+ }
+ bNodeTree *root_node_tree = ((NodesModifierData *)modifier)->node_group;
+ if (root_node_tree == nullptr) {
+ return false;
+ }
+ const Span<SpreadsheetContext *> node_context_path = context_path.as_span().drop_front(2);
+ if (node_context_path.is_empty()) {
+ return false;
+ }
+ bNodeTree *node_tree = root_node_tree;
+ for (const int i : node_context_path.index_range()) {
+ if (node_context_path[i]->type != SPREADSHEET_CONTEXT_NODE) {
+ return false;
+ }
+ const char *node_name = ((SpreadsheetContextNode *)node_context_path[i])->node_name;
+ bNode *node = nodeFindNodebyName(node_tree, node_name);
+ if (node == nullptr) {
+ return false;
+ }
+ if (node->type == GEO_NODE_VIEWER) {
+ if (i == node_context_path.index_range().last()) {
+ return true;
+ }
+ return false;
+ }
+ else if (node->id != nullptr) {
+ if (GS(node->id->name) != ID_NT) {
+ return false;
+ }
+ node_tree = (bNodeTree *)node->id;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 6d244a1bda6..f730f199ca4 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -419,7 +419,7 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly);
}
}
- else if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED) {
+ else {
if (used_component_type == GEO_COMPONENT_TYPE_MESH && object_eval->mode == OB_MODE_EDIT) {
Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(object_eval, false);
if (mesh == nullptr) {