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:
authorJacques Lucke <jacques@blender.org>2022-09-28 18:54:59 +0300
committerJacques Lucke <jacques@blender.org>2022-09-28 18:54:59 +0300
commitc55d38f00b8c0e6ae8bda9cc66614afe28fb3fc9 (patch)
tree0fc280eec3e2d0655197afda823de1062f51ea05 /source/blender/editors/space_spreadsheet
parent2312915b9620808d29e9b20529684800638d5a2a (diff)
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d viewport (instead of just in the spreadsheet). The "viewer geometry" bypasses the group output. So it is not necessary to change the final output of the node group to be able to see the intermediate geometry. **Activation and deactivation of a viewer node** * A viewer node is activated by clicking on it. * Ctrl+shift+click on any node/socket connects it to the viewer and makes it active. * Ctrl+shift+click in empty space deactivates the active viewer. * When the active viewer is not visible anymore (e.g. another object is selected, or the current node group is exit), it is deactivated. * Clicking on the icon in the header of the Viewer node toggles whether its active or not. **Pinning** * The spreadsheet still allows pinning the active viewer as before. When pinned, the spreadsheet still references the viewer node even when it becomes inactive. * The viewport does not support pinning at the moment. It always shows the active viewer. **Attribute** * When a field is linked to the second input of the viewer node it is displayed as an overlay in the viewport. * When possible the correct domain for the attribute is determined automatically. This does not work in all cases. It falls back to the face corner domain on meshes and the point domain on curves. When necessary, the domain can be picked manually. * The spreadsheet now only shows the "Viewer" column for the domain that is selected in the Viewer node. * Instance attributes are visualized as a constant color per instance. **Viewport Options** * The attribute overlay opacity can be controlled with the "Viewer Node" setting in the overlays popover. * A viewport can be configured not to show intermediate viewer-geometry by disabling the "Viewer Node" option in the "View" menu. **Implementation Details** * The "spreadsheet context path" was generalized to a "viewer path" that is used in more places now. * The viewer node itself determines the attribute domain, evaluates the field and stores the result in a `.viewer` attribute. * A new "viewer attribute' overlay displays the data from the `.viewer` attribute. * The ground truth for the active viewer node is stored in the workspace now. Node editors, spreadsheets and viewports retrieve the active viewer from there unless they are pinned. * The depsgraph object iterator has a new "viewer path" setting. When set, the viewed geometry of the corresponding object is part of the iterator instead of the final evaluated geometry. * To support the instance attribute overlay `DupliObject` was extended to contain the information necessary for drawing the overlay. * The ctrl+shift+click operator has been refactored so that it can make existing links to viewers active again. * The auto-domain-detection in the Viewer node works by checking the "preferred domain" for every field input. If there is not exactly one preferred domain, the fallback is used. Known limitations: * Loose edges of meshes don't have the attribute overlay. This could be added separately if necessary. * Some attributes are hard to visualize as a color directly. For example, the values might have to be normalized or some should be drawn as arrays. For now, we encourage users to build node groups that generate appropriate viewer-geometry. We might include some of that functionality in future versions. Support for displaying attribute values as text in the viewport is planned as well. * There seems to be an issue with the attribute overlay for pointclouds on nvidia gpus, to be investigated. Differential Revision: https://developer.blender.org/D15954
Diffstat (limited to 'source/blender/editors/space_spreadsheet')
-rw-r--r--source/blender/editors/space_spreadsheet/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc213
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.cc591
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_context.hh13
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc73
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh2
6 files changed, 123 insertions, 771 deletions
diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt
index a551e096b48..08032ddbaeb 100644
--- a/source/blender/editors/space_spreadsheet/CMakeLists.txt
+++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt
@@ -27,7 +27,6 @@ set(SRC
space_spreadsheet.cc
spreadsheet_cache.cc
spreadsheet_column.cc
- spreadsheet_context.cc
spreadsheet_data_source.cc
spreadsheet_data_source_geometry.cc
spreadsheet_dataset_draw.cc
@@ -41,7 +40,6 @@ set(SRC
spreadsheet_cache.hh
spreadsheet_column.hh
spreadsheet_column_values.hh
- spreadsheet_context.hh
spreadsheet_data_source.hh
spreadsheet_data_source_geometry.hh
spreadsheet_dataset_draw.hh
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index d5fa0145fe5..ee43519e260 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -10,6 +10,7 @@
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_spreadsheet.h"
+#include "ED_viewer_path.hh"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -34,7 +35,6 @@
#include "BLF_api.h"
-#include "spreadsheet_context.hh"
#include "spreadsheet_data_source_geometry.hh"
#include "spreadsheet_dataset_draw.hh"
#include "spreadsheet_intern.hh"
@@ -107,9 +107,7 @@ static void spreadsheet_free(SpaceLink *sl)
LISTBASE_FOREACH_MUTABLE (SpreadsheetColumn *, column, &sspreadsheet->columns) {
spreadsheet_column_free(column);
}
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- spreadsheet_context_free(context);
- }
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
}
static void spreadsheet_init(wmWindowManager *UNUSED(wm), ScrArea *area)
@@ -143,11 +141,7 @@ static SpaceLink *spreadsheet_duplicate(SpaceLink *sl)
BLI_addtail(&sspreadsheet_new->columns, new_column);
}
- BLI_listbase_clear(&sspreadsheet_new->context_path);
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, src_context, &sspreadsheet_old->context_path) {
- SpreadsheetContext *new_context = spreadsheet_context_copy(src_context);
- BLI_addtail(&sspreadsheet_new->context_path, new_context);
- }
+ BKE_viewer_path_copy(&sspreadsheet_new->viewer_path, &sspreadsheet_old->viewer_path);
return (SpaceLink *)sspreadsheet_new;
}
@@ -163,19 +157,7 @@ static void spreadsheet_id_remap(ScrArea *UNUSED(area),
const IDRemapper *mappings)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink;
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type != SPREADSHEET_CONTEXT_OBJECT) {
- continue;
- }
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
-
- if (object_context->object != nullptr && GS(object_context->object->id.name) != ID_OB) {
- object_context->object = nullptr;
- continue;
- }
-
- BKE_id_remapper_apply(mappings, ((ID **)&object_context->object), ID_REMAP_APPLY_DEFAULT);
- }
+ BKE_viewer_path_id_remap(&sspreadsheet->viewer_path, mappings);
}
static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
@@ -201,54 +183,105 @@ static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet)
{
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
+ if (BLI_listbase_is_empty(&sspreadsheet->viewer_path.path)) {
return nullptr;
}
- SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first;
- if (root_context->type != SPREADSHEET_CONTEXT_OBJECT) {
+ ViewerPathElem *root_context = static_cast<ViewerPathElem *>(
+ sspreadsheet->viewer_path.path.first);
+ if (root_context->type != VIEWER_PATH_ELEM_TYPE_ID) {
return nullptr;
}
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context;
- return (ID *)object_context->object;
+ IDViewerPathElem *id_elem = reinterpret_cast<IDViewerPathElem *>(root_context);
+ return id_elem->id;
}
-/* Check if the pinned context still exists. If it doesn't try to find a new context. */
-static void update_pinned_context_path_if_outdated(const bContext *C)
+static void view_active_object(const bContext *C, SpaceSpreadsheet *sspreadsheet)
{
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- 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));
- }
- }
-
- if (BLI_listbase_is_empty(&sspreadsheet->context_path)) {
- /* Don't pin empty context_path, that could be annoying. */
- sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
+ Object *ob = CTX_data_active_object(C);
+ if (ob == nullptr) {
+ return;
}
+ IDViewerPathElem *id_elem = BKE_viewer_path_elem_new_id();
+ id_elem->id = &ob->id;
+ BLI_addtail(&sspreadsheet->viewer_path.path, id_elem);
+ ED_area_tag_redraw(CTX_wm_area(C));
}
-static void update_context_path_from_context(const bContext *C)
+static void spreadsheet_update_context(const bContext *C)
{
+ using blender::ed::viewer_path::ViewerPathForGeometryNodesViewer;
+
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- 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));
+ Object *active_object = CTX_data_active_object(C);
+ Object *context_object = blender::ed::viewer_path::parse_object_only(sspreadsheet->viewer_path);
+ switch (eSpaceSpreadsheet_ObjectEvalState(sspreadsheet->object_eval_state)) {
+ case SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL:
+ case SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED: {
+ if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
+ if (context_object == nullptr) {
+ /* Object is not available anymore, so clear the pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ else {
+ /* The object is still pinned, do nothing. */
+ break;
+ }
+ }
+ else {
+ if (active_object != context_object) {
+ /* The active object has changed, so view the new active object. */
+ view_active_object(C, sspreadsheet);
+ }
+ else {
+ /* Nothing changed. */
+ break;
+ }
+ }
+ break;
}
- }
-}
+ case SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE: {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
+ const std::optional<ViewerPathForGeometryNodesViewer> parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(sspreadsheet->viewer_path);
+ if (parsed_path.has_value()) {
+ if (blender::ed::viewer_path::exists_geometry_nodes_viewer(*parsed_path)) {
+ /* The pinned path is still valid, do nothing. */
+ break;
+ }
+ else {
+ /* The pinned path does not exist anymore, clear pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ }
+ else {
+ /* Unknown pinned path, clear pinning. */
+ sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED;
+ }
+ }
+ /* Now try to update the viewer path from the workspace. */
+ const std::optional<ViewerPathForGeometryNodesViewer> workspace_parsed_path =
+ blender::ed::viewer_path::parse_geometry_nodes_viewer(workspace->viewer_path);
+ if (workspace_parsed_path.has_value()) {
+ if (BKE_viewer_path_equal(&sspreadsheet->viewer_path, &workspace->viewer_path)) {
+ /* Nothing changed. */
+ break;
+ }
+ else {
+ /* Update the viewer path from the workspace. */
+ BKE_viewer_path_clear(&sspreadsheet->viewer_path);
+ BKE_viewer_path_copy(&sspreadsheet->viewer_path, &workspace->viewer_path);
+ }
+ }
+ else {
+ /* No active viewer node, change back to showing evaluated active object. */
+ sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED;
+ view_active_object(C, sspreadsheet);
+ }
-void spreadsheet_update_context_path(const bContext *C)
-{
- SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
- if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) {
- update_pinned_context_path_if_outdated(C);
- }
- else {
- update_context_path_from_context(C);
+ break;
+ }
}
}
@@ -390,7 +423,7 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
sspreadsheet->runtime->cache.set_all_unused();
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
std::unique_ptr<DataSource> data_source = get_data_source(C);
if (!data_source) {
@@ -439,6 +472,7 @@ static void spreadsheet_main_region_listener(const wmRegionListenerParams *param
{
ARegion *region = params->region;
const wmNotifier *wmn = params->notifier;
+ SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first);
switch (wmn->category) {
case NC_SCENE: {
@@ -467,6 +501,12 @@ static void spreadsheet_main_region_listener(const wmRegionListenerParams *param
ED_region_tag_redraw(region);
break;
}
+ case NC_VIEWER_PATH: {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ ED_region_tag_redraw(region);
+ }
+ break;
+ }
}
}
@@ -477,7 +517,7 @@ static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion
static void spreadsheet_header_region_draw(const bContext *C, ARegion *region)
{
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
ED_region_header(C, region);
}
@@ -489,6 +529,7 @@ static void spreadsheet_header_region_listener(const wmRegionListenerParams *par
{
ARegion *region = params->region;
const wmNotifier *wmn = params->notifier;
+ SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first);
switch (wmn->category) {
case NC_SCENE: {
@@ -515,6 +556,12 @@ static void spreadsheet_header_region_listener(const wmRegionListenerParams *par
ED_region_tag_redraw(region);
break;
}
+ case NC_VIEWER_PATH: {
+ if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
+ ED_region_tag_redraw(region);
+ }
+ break;
+ }
}
}
@@ -593,7 +640,7 @@ static void spreadsheet_dataset_region_listener(const wmRegionListenerParams *pa
static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region)
{
- spreadsheet_update_context_path(C);
+ spreadsheet_update_context(C);
ED_region_panels(C, region);
}
@@ -634,34 +681,13 @@ static void spreadsheet_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
BLO_read_data_address(reader, &column->display_name);
}
- BLO_read_list(reader, &sspreadsheet->context_path);
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- switch (context->type) {
- case SPREADSHEET_CONTEXT_NODE: {
- SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)context;
- BLO_read_data_address(reader, &node_context->node_name);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context;
- BLO_read_data_address(reader, &modifier_context->modifier_name);
- break;
- }
- case SPREADSHEET_CONTEXT_OBJECT: {
- break;
- }
- }
- }
+ BKE_viewer_path_blend_read_data(reader, &sspreadsheet->viewer_path);
}
static void spreadsheet_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- BLO_read_id_address(reader, parent_id->lib, &((SpreadsheetContextObject *)context)->object);
- }
- }
+ BKE_viewer_path_blend_read_lib(reader, parent_id->lib, &sspreadsheet->viewer_path);
}
static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl)
@@ -683,27 +709,8 @@ static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl)
* This would ideally be cleared here. */
BLO_write_string(writer, column->display_name);
}
- LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- BLO_write_struct(writer, SpreadsheetContextObject, object_context);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- SpreadsheetContextModifier *modifier_context = (SpreadsheetContextModifier *)context;
- BLO_write_struct(writer, SpreadsheetContextModifier, modifier_context);
- BLO_write_string(writer, modifier_context->modifier_name);
- break;
- }
- case SPREADSHEET_CONTEXT_NODE: {
- SpreadsheetContextNode *node_context = (SpreadsheetContextNode *)context;
- BLO_write_struct(writer, SpreadsheetContextNode, node_context);
- BLO_write_string(writer, node_context->node_name);
- break;
- }
- }
- }
+
+ BKE_viewer_path_blend_write(writer, &sspreadsheet->viewer_path);
}
void ED_spacetype_spreadsheet()
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc b/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
deleted file mode 100644
index ec9fa72edb1..00000000000
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_hash.h"
-#include "BLI_hash.hh"
-#include "BLI_hash_mm2a.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-#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()
-{
- SpreadsheetContextObject *context = MEM_cnew<SpreadsheetContextObject>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_OBJECT;
- return context;
-}
-
-static SpreadsheetContextObject *spreadsheet_context_object_copy(
- const SpreadsheetContextObject *src_context)
-{
- SpreadsheetContextObject *new_context = spreadsheet_context_object_new();
- new_context->object = src_context->object;
- return new_context;
-}
-
-static void spreadsheet_context_object_hash(const SpreadsheetContextObject *context,
- BLI_HashMurmur2A *mm2)
-{
- BLI_hash_mm2a_add(mm2, (const uchar *)&context->object, sizeof(Object *));
-}
-
-static void spreadsheet_context_object_free(SpreadsheetContextObject *context)
-{
- MEM_freeN(context);
-}
-
-static SpreadsheetContextModifier *spreadsheet_context_modifier_new()
-{
- SpreadsheetContextModifier *context = MEM_cnew<SpreadsheetContextModifier>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_MODIFIER;
- return context;
-}
-
-static SpreadsheetContextModifier *spreadsheet_context_modifier_copy(
- const SpreadsheetContextModifier *src_context)
-{
- SpreadsheetContextModifier *new_context = spreadsheet_context_modifier_new();
- if (src_context->modifier_name) {
- new_context->modifier_name = BLI_strdup(src_context->modifier_name);
- }
- return new_context;
-}
-
-static void spreadsheet_context_modifier_hash(const SpreadsheetContextModifier *context,
- BLI_HashMurmur2A *mm2)
-{
- if (context->modifier_name) {
- BLI_hash_mm2a_add(mm2, (const uchar *)context->modifier_name, strlen(context->modifier_name));
- }
-}
-
-static void spreadsheet_context_modifier_free(SpreadsheetContextModifier *context)
-{
- if (context->modifier_name) {
- MEM_freeN(context->modifier_name);
- }
- MEM_freeN(context);
-}
-
-static SpreadsheetContextNode *spreadsheet_context_node_new()
-{
- SpreadsheetContextNode *context = MEM_cnew<SpreadsheetContextNode>(__func__);
- context->base.type = SPREADSHEET_CONTEXT_NODE;
- return context;
-}
-
-static SpreadsheetContextNode *spreadsheet_context_node_copy(
- const SpreadsheetContextNode *src_context)
-{
- SpreadsheetContextNode *new_context = spreadsheet_context_node_new();
- if (src_context->node_name) {
- new_context->node_name = BLI_strdup(src_context->node_name);
- }
- return new_context;
-}
-
-static void spreadsheet_context_node_hash(const SpreadsheetContextNode *context,
- BLI_HashMurmur2A *mm2)
-{
- if (context->node_name) {
- BLI_hash_mm2a_add(mm2, (const uchar *)context->node_name, strlen(context->node_name));
- }
-}
-
-static void spreadsheet_context_node_free(SpreadsheetContextNode *context)
-{
- if (context->node_name) {
- MEM_freeN(context->node_name);
- }
- MEM_freeN(context);
-}
-
-SpreadsheetContext *spreadsheet_context_new(eSpaceSpreadsheet_ContextType type)
-{
- switch (type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return (SpreadsheetContext *)spreadsheet_context_object_new();
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return (SpreadsheetContext *)spreadsheet_context_modifier_new();
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return (SpreadsheetContext *)spreadsheet_context_node_new();
- }
- }
- BLI_assert_unreachable();
- return nullptr;
-}
-
-SpreadsheetContext *spreadsheet_context_copy(const SpreadsheetContext *old_context)
-{
- switch (old_context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return (SpreadsheetContext *)spreadsheet_context_object_copy(
- (const SpreadsheetContextObject *)old_context);
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return (SpreadsheetContext *)spreadsheet_context_modifier_copy(
- (const SpreadsheetContextModifier *)old_context);
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return (SpreadsheetContext *)spreadsheet_context_node_copy(
- (const SpreadsheetContextNode *)old_context);
- }
- }
- BLI_assert_unreachable();
- return nullptr;
-}
-
-static void spreadsheet_context_hash(const SpreadsheetContext *context, BLI_HashMurmur2A *mm2)
-{
- BLI_hash_mm2a_add_int(mm2, context->type);
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- spreadsheet_context_object_hash((const SpreadsheetContextObject *)context, mm2);
- break;
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- spreadsheet_context_modifier_hash((const SpreadsheetContextModifier *)context, mm2);
- break;
- }
- case SPREADSHEET_CONTEXT_NODE: {
- spreadsheet_context_node_hash((const SpreadsheetContextNode *)context, mm2);
- break;
- }
- }
-}
-
-void spreadsheet_context_free(SpreadsheetContext *context)
-{
- switch (context->type) {
- case SPREADSHEET_CONTEXT_OBJECT: {
- return spreadsheet_context_object_free((SpreadsheetContextObject *)context);
- }
- case SPREADSHEET_CONTEXT_MODIFIER: {
- return spreadsheet_context_modifier_free((SpreadsheetContextModifier *)context);
- }
- case SPREADSHEET_CONTEXT_NODE: {
- return spreadsheet_context_node_free((SpreadsheetContextNode *)context);
- }
- }
- BLI_assert_unreachable();
-}
-
-/**
- * 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 bool spreadsheet_context_update_tag(SpaceSpreadsheet *sspreadsheet)
-{
- using namespace blender;
- Vector<const SpreadsheetContext *> context_path = sspreadsheet->context_path;
- if (context_path.is_empty()) {
- return false;
- }
- if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) {
- return false;
- }
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context_path[0];
- Object *object = object_context->object;
- if (object == nullptr) {
- return false;
- }
- if (context_path.size() == 1) {
- /* No need to reevaluate, when the final or original object is viewed. */
- return false;
- }
-
- DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
- return true;
-}
-
-} // namespace blender::ed::spreadsheet
-
-SpreadsheetContext *ED_spreadsheet_context_new(int type)
-{
- return blender::ed::spreadsheet::spreadsheet_context_new((eSpaceSpreadsheet_ContextType)type);
-}
-
-void ED_spreadsheet_context_free(struct SpreadsheetContext *context)
-{
- blender::ed::spreadsheet::spreadsheet_context_free(context);
-}
-
-void ED_spreadsheet_context_path_clear(struct SpaceSpreadsheet *sspreadsheet)
-{
- LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- ED_spreadsheet_context_free(context);
- }
- BLI_listbase_clear(&sspreadsheet->context_path);
-}
-
-bool ED_spreadsheet_context_path_update_tag(SpaceSpreadsheet *sspreadsheet)
-{
- return blender::ed::spreadsheet::spreadsheet_context_update_tag(sspreadsheet);
-}
-
-uint64_t ED_spreadsheet_context_path_hash(const SpaceSpreadsheet *sspreadsheet)
-{
- BLI_HashMurmur2A mm2;
- BLI_hash_mm2a_init(&mm2, 1234);
- LISTBASE_FOREACH (const SpreadsheetContext *, context, &sspreadsheet->context_path) {
- blender::ed::spreadsheet::spreadsheet_context_hash(context, &mm2);
- }
- return BLI_hash_mm2a_end(&mm2);
-}
-
-void ED_spreadsheet_context_path_set_geometry_node(struct SpaceSpreadsheet *sspreadsheet,
- struct SpaceNode *snode,
- struct bNode *node)
-{
- using namespace blender::ed::spreadsheet;
-
- 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();
- context->object = object;
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- {
- SpreadsheetContextModifier *context = spreadsheet_context_modifier_new();
- context->modifier_name = BLI_strdup(modifier->name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- {
- int i;
- LISTBASE_FOREACH_INDEX (bNodeTreePath *, path, &snode->treepath, i) {
- if (i == 0) {
- continue;
- }
- SpreadsheetContextNode *context = spreadsheet_context_node_new();
- context->node_name = BLI_strdup(path->node_name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
- }
- {
- SpreadsheetContextNode *context = spreadsheet_context_node_new();
- context->node_name = BLI_strdup(node->name);
- BLI_addtail(&sspreadsheet->context_path, context);
- }
-
- 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);
-}
-
-static bScreen *find_screen_to_search_for_context(wmWindow *window,
- SpaceSpreadsheet *current_space)
-{
- bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
- if (ELEM(screen->state, SCREENMAXIMIZED, SCREENFULL)) {
- /* If the spreadsheet is maximized, try to find the context in the unmaximized screen. */
- ScrArea *main_area = (ScrArea *)screen->areabase.first;
- SpaceLink *sl = (SpaceLink *)main_area->spacedata.first;
- if (sl == (SpaceLink *)current_space) {
- return main_area->full;
- }
- }
- return screen;
-}
-
-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 = find_screen_to_search_for_context(window, sspreadsheet);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl == nullptr) {
- continue;
- }
- 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;
- }
- const bool modifier_is_active = modifier->flag & eModifierFlag_Active;
- 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 = find_screen_to_search_for_context(window, sspreadsheet);
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- SpaceLink *sl = (SpaceLink *)area->spacedata.first;
- if (sl == nullptr) {
- continue;
- }
- if (sl->spacetype != SPACE_NODE) {
- continue;
- }
- SpaceNode *snode = (SpaceNode *)sl;
- if (snode->nodetree != root_node_tree) {
- continue;
- }
- if (!modifier_is_active) {
- if (!(snode->flag & SNODE_PIN)) {
- /* Node tree has to be pinned when the modifier is not active. */
- 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 + 1]->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;
- }
- 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_context.hh b/source/blender/editors/space_spreadsheet/spreadsheet_context.hh
deleted file mode 100644
index 758ae392894..00000000000
--- a/source/blender/editors/space_spreadsheet/spreadsheet_context.hh
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-#include "DNA_space_types.h"
-
-namespace blender::ed::spreadsheet {
-
-SpreadsheetContext *spreadsheet_context_new(eSpaceSpreadsheet_ContextType type);
-SpreadsheetContext *spreadsheet_context_copy(const SpreadsheetContext *old_context);
-void spreadsheet_context_free(SpreadsheetContext *context);
-
-} // namespace blender::ed::spreadsheet
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 fd2ac4d39a1..8af12590b0f 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -98,7 +98,8 @@ void GeometryDataSource::foreach_default_column_ids(
}
SpreadsheetColumnID column_id;
column_id.name = (char *)attribute_id.name().data();
- fn(column_id, false);
+ const bool is_front = attribute_id.name() == ".viewer";
+ fn(column_id, is_front);
return true;
});
@@ -228,7 +229,12 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
return {};
}
- return std::make_unique<ColumnValues>(column_id.name, std::move(varray));
+ StringRefNull column_display_name = column_id.name;
+ if (column_display_name == ".viewer") {
+ column_display_name = "Viewer";
+ }
+
+ return std::make_unique<ColumnValues>(column_display_name, std::move(varray));
}
int GeometryDataSource::tot_rows() const
@@ -463,7 +469,7 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
}
else {
- if (BLI_listbase_count(&sspreadsheet->context_path) == 1) {
+ if (BLI_listbase_count(&sspreadsheet->viewer_path.path) == 1) {
/* Use final evaluated object. */
if (object_eval->runtime.geometry_set_eval != nullptr) {
geometry_set = *object_eval->runtime.geometry_set_eval;
@@ -471,8 +477,8 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
}
else {
if (const ViewerNodeLog *viewer_log =
- nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_spreadsheet(
- *sspreadsheet)) {
+ nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_path(
+ sspreadsheet->viewer_path)) {
geometry_set = viewer_log->geometry;
}
}
@@ -481,25 +487,6 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
return geometry_set;
}
-static void find_fields_to_evaluate(const SpaceSpreadsheet *sspreadsheet,
- Map<std::string, GField> &r_fields)
-{
- if (sspreadsheet->object_eval_state != SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) {
- return;
- }
- if (BLI_listbase_count(&sspreadsheet->context_path) <= 1) {
- /* No viewer is currently referenced by the context path. */
- return;
- }
- if (const ViewerNodeLog *viewer_log =
- nodes::geo_eval_log::GeoModifierLog::find_viewer_node_log_for_spreadsheet(
- *sspreadsheet)) {
- if (viewer_log->field) {
- r_fields.add("Viewer", viewer_log->field);
- }
- }
-}
-
class GeometryComponentCacheKey : public SpreadsheetCache::Key {
public:
/* Use the pointer to the geometry component as a key to detect when the geometry changed. */
@@ -531,38 +518,6 @@ class GeometryComponentCacheValue : public SpreadsheetCache::Value {
Map<std::pair<eAttrDomain, GField>, GArray<>> arrays;
};
-static void add_fields_as_extra_columns(SpaceSpreadsheet *sspreadsheet,
- const GeometryComponent &component,
- ExtraColumns &r_extra_columns)
-{
- Map<std::string, GField> fields_to_show;
- find_fields_to_evaluate(sspreadsheet, fields_to_show);
-
- GeometryComponentCacheValue &cache =
- sspreadsheet->runtime->cache.lookup_or_add<GeometryComponentCacheValue>(
- std::make_unique<GeometryComponentCacheKey>(component));
-
- const eAttrDomain domain = (eAttrDomain)sspreadsheet->attribute_domain;
- const int domain_num = component.attribute_domain_size(domain);
- for (const auto item : fields_to_show.items()) {
- const StringRef name = item.key;
- const GField &field = item.value;
-
- /* Use the cached evaluated array if it exists, otherwise evaluate the field now. */
- GArray<> &evaluated_array = cache.arrays.lookup_or_add_cb({domain, field}, [&]() {
- GArray<> evaluated_array(field.cpp_type(), domain_num);
-
- bke::GeometryFieldContext field_context{component, domain};
- fn::FieldEvaluator field_evaluator{field_context, domain_num};
- field_evaluator.add_with_destination(field, evaluated_array);
- field_evaluator.evaluate();
- return evaluated_array;
- });
-
- r_extra_columns.add(name, evaluated_array.as_span());
- }
-}
-
std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval)
{
SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C);
@@ -574,15 +529,11 @@ std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object
return {};
}
- const GeometryComponent &component = *geometry_set.get_component_for_read(component_type);
- ExtraColumns extra_columns;
- add_fields_as_extra_columns(sspreadsheet, component, extra_columns);
-
if (component_type == GEO_COMPONENT_TYPE_VOLUME) {
return std::make_unique<VolumeDataSource>(std::move(geometry_set));
}
return std::make_unique<GeometryDataSource>(
- object_eval, std::move(geometry_set), component_type, domain, std::move(extra_columns));
+ object_eval, std::move(geometry_set), component_type, domain);
}
} // namespace blender::ed::spreadsheet
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
index 71bc4768949..478b3372427 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh
@@ -54,7 +54,7 @@ class GeometryDataSource : public DataSource {
GeometrySet geometry_set,
const GeometryComponentType component_type,
const eAttrDomain domain,
- ExtraColumns extra_columns)
+ ExtraColumns extra_columns = {})
: object_eval_(object_eval),
geometry_set_(std::move(geometry_set)),
component_(geometry_set_.get_component_for_read(component_type)),