Geometry Nodes: make evaluation and logging system aware of zones #109029

Closed
Jacques Lucke wants to merge 93 commits from JacquesLucke/blender:zone-evaluation into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 173 additions and 12 deletions
Showing only changes of commit 742c184734 - Show all commits

View File

@ -2166,7 +2166,7 @@ static bool ui_but_drag_init(bContext *C,
else if (but->type == UI_BTYPE_VIEW_ITEM) {
const uiButViewItem *view_item_but = (uiButViewItem *)but;
if (view_item_but->view_item) {
UI_view_item_drag_start(C, view_item_but->view_item);
return UI_view_item_drag_start(C, view_item_but->view_item);
}
}
else {
@ -11347,6 +11347,10 @@ static int ui_handle_menus_recursive(bContext *C,
}
}
if (!menu->retvalue) {
ui_handle_viewlist_items_hover(event, menu->region);
}
if (do_towards_reinit) {
ui_mouse_motion_towards_reinit(menu, event->xy);
}

View File

@ -108,7 +108,7 @@ AbstractTreeViewItem *AbstractTreeView::find_matching_child(
const AbstractTreeViewItem &lookup_item, const TreeViewOrItem &items)
{
for (const auto &iter_item : items.children_) {
if (lookup_item.matches_single(*iter_item)) {
if (lookup_item.matches(*iter_item)) {
/* We have a matching item! */
return iter_item.get();
}
@ -176,7 +176,7 @@ void AbstractTreeViewItem::collapse_chevron_click_fn(bContext *C,
* lookup the hovered item via context here. */
const wmWindow *win = CTX_wm_window(C);
const ARegion *region = CTX_wm_region(C);
const ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C);
uiViewItemHandle *hovered_item_handle = UI_region_views_find_item_at(region,
win->eventstate->xy);
@ -474,14 +474,16 @@ void TreeViewLayoutBuilder::build_row(AbstractTreeViewItem &item) const
uiLayoutSetActive(overlap, false);
}
uiLayoutRow(overlap, false);
uiLayout *row = uiLayoutRow(overlap, false);
/* Enable emboss for mouse hover highlight. */
uiLayoutSetEmboss(row, UI_EMBOSS);
/* Every item gets one! Other buttons can be overlapped on top. */
item.add_treerow_button(block_);
/* After adding tree-row button (would disable hover highlighting). */
UI_block_emboss_set(&block_, UI_EMBOSS_NONE);
uiLayout *row = uiLayoutRow(overlap, true);
row = uiLayoutRow(overlap, true);
item.add_indent(*row);
item.add_collapse_chevron(block_);

View File

@ -51,6 +51,10 @@
#include "object_intern.h"
#include "WM_api.h"
#include "UI_interface.h"
namespace blender::ed::object::bake_simulation {
static bool calculate_to_frame_poll(bContext *C)
@ -252,10 +256,6 @@ static void bake_simulation_job_startjob(void *customdata,
if (md->type == eModifierType_Nodes) {
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
nmd->simulation_cache->ptr->reset();
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
nmd->simulation_bake_directory = BLI_strdup(
bke::sim::get_default_modifier_bake_directory(*job.bmain, *object, *md).c_str());
}
char absolute_bake_dir[FILE_MAX];
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
BLI_path_abs(absolute_bake_dir, base_path);
@ -362,7 +362,7 @@ static void bake_simulation_job_endjob(void *customdata)
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, nullptr);
}
static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
static int bake_simulation_execute(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = CTX_data_scene(C);
@ -405,6 +405,160 @@ static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /
return OPERATOR_RUNNING_MODAL;
}
struct PathStringHash {
uint64_t operator()(const StringRef s) const
{
/* Normalize the paths so we can compare them. */
DynamicStackBuffer<256> norm_buf(s.size() + 1, 8);
memcpy(norm_buf.buffer(), s.data(), s.size() + 1);
char *norm = static_cast<char *>(norm_buf.buffer());
BLI_path_slash_native(norm);
/* Strip ending slash. */
BLI_path_slash_rstrip(norm);
BLI_path_normalize(norm);
return get_default_hash(norm);
}
};
struct PathStringEquality {
bool operator()(const StringRef a, const StringRef b) const
{
return BLI_path_cmp_normalized(a.data(), b.data()) == 0;
}
};
static bool bake_directory_has_data(const StringRefNull absolute_bake_dir)
{
char meta_dir[FILE_MAX];
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir.c_str(), "meta");
char bdata_dir[FILE_MAX];
BLI_path_join(bdata_dir, sizeof(bdata_dir), absolute_bake_dir.c_str(), "bdata");
if (!BLI_is_dir(meta_dir) || !BLI_is_dir(bdata_dir)) {
return false;
}
return true;
}
static void bake_simulation_validate_paths(bContext *C,
wmOperator *op,
const Span<Object *> objects)
{
Main *bmain = CTX_data_main(C);
for (Object *object : objects) {
if (!BKE_id_is_editable(bmain, &object->id)) {
continue;
}
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
BKE_reportf(op->reports,
RPT_INFO,
"Bake directory of object %s, modifier %s is empty, setting default path",
object->id.name + 2,
md->name);
nmd->simulation_bake_directory = BLI_strdup(
bke::sim::get_default_modifier_bake_directory(*bmain, *object, *md).c_str());
}
}
}
}
/* Map for counting path references. */
using PathUsersMap = Map<std::string,
int,
default_inline_buffer_capacity(sizeof(std::string)),
DefaultProbingStrategy,
PathStringHash,
PathStringEquality>;
static PathUsersMap bake_simulation_get_path_users(bContext *C, const Span<Object *> objects)
{
Main *bmain = CTX_data_main(C);
PathUsersMap path_users;
for (const Object *object : objects) {
const char *base_path = ID_BLEND_PATH(bmain, &object->id);
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type != eModifierType_Nodes) {
continue;
}
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
continue;
}
char absolute_bake_dir[FILE_MAX];
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
BLI_path_abs(absolute_bake_dir, base_path);
path_users.add_or_modify(
absolute_bake_dir, [](int *value) { *value = 1; }, [](int *value) { ++(*value); });
}
}
return path_users;
}
static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
Vector<Object *> objects;
if (RNA_boolean_get(op->ptr, "selected")) {
CTX_DATA_BEGIN (C, Object *, object, selected_objects) {
objects.append(object);
}
CTX_DATA_END;
}
else {
if (Object *object = CTX_data_active_object(C)) {
objects.append(object);
}
}
/* Set empty paths to default. */
bake_simulation_validate_paths(C, op, objects);
PathUsersMap path_users = bake_simulation_get_path_users(C, objects);
bool has_path_conflict = false;
bool has_existing_bake_data = false;
for (const auto &item : path_users.items()) {
/* Check if multiple caches are writing to the same bake directory. */
if (item.value > 1) {
BKE_reportf(op->reports,
RPT_ERROR,
"Path conflict: %d caches set to path %s",
item.value,
item.key.data());
has_path_conflict = true;
}
/* Check if path exists and contains bake data already. */
if (bake_directory_has_data(item.key.data())) {
has_existing_bake_data = true;
}
}
if (has_path_conflict) {
UI_popup_menu_reports(C, op->reports);
return OPERATOR_CANCELLED;
}
if (has_existing_bake_data) {
return WM_operator_confirm_message(C, op, "Overwrite existing bake data");
}
return bake_simulation_execute(C, op);
}
static int bake_simulation_modal(bContext *C, wmOperator * /*op*/, const wmEvent * /*event*/)
{
if (!WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_BAKE_SIMULATION_NODES)) {
@ -493,6 +647,7 @@ void OBJECT_OT_simulation_nodes_cache_bake(wmOperatorType *ot)
ot->description = "Bake simulations in geometry nodes modifiers";
ot->idname = __func__;
ot->exec = bake_simulation_execute;
ot->invoke = bake_simulation_invoke;
ot->modal = bake_simulation_modal;
ot->poll = bake_simulation_poll;

View File

@ -412,7 +412,7 @@ static void nla_main_region_message_subscribe(const wmRegionMessageSubscribePara
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw;
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {};
msg_sub_value_region_tag_redraw.owner = region;
msg_sub_value_region_tag_redraw.user_data = region;
msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
@ -488,7 +488,7 @@ static void nla_channel_region_message_subscribe(const wmRegionMessageSubscribeP
PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_SpaceNLA, area->spacedata.first, &ptr);
wmMsgSubscribeValue msg_sub_value_region_tag_redraw;
wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {};
msg_sub_value_region_tag_redraw.owner = region;
msg_sub_value_region_tag_redraw.user_data = region;
msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;