10#include <fmt/format.h>
77#include "RNA_prototypes.hh"
118 nmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
119 nmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
125 if (ID *id = IDP_Id(property)) {
149 if (
object.type ==
OB_EMPTY &&
object.instance_collection !=
nullptr) {
168 bool needs_own_transform_relation =
false;
169 bool needs_scene_camera_relation =
false;
172 nodes::find_node_tree_dependencies(
173 *nmd->
node_group, used_ids, needs_own_transform_relation, needs_scene_camera_relation);
177 if (curves_id->
surface !=
nullptr) {
185 used_ids.
add(data_block.id);
190 for (
ID *
id : used_ids) {
215 if (needs_own_transform_relation) {
218 if (needs_scene_camera_relation) {
227 if (!checked_groups.
add(&
tree)) {
230 tree.ensure_topology_cache();
231 if (!
tree.nodes_by_type(
"GeometryNodeInputSceneTime").is_empty()) {
234 if (!
tree.nodes_by_type(
"GeometryNodeSimulationInput").is_empty()) {
237 for (
const bNode *node :
tree.group_nodes()) {
251 if (
tree ==
nullptr) {
269 walk(user_data, ob, (ID **)&id_prop->data.pointer, IDWALK_CB_USER);
284 walk(user_data, ob, md, &
ptr, prop);
320 nmd->
settings.
properties = bke::idprop::create_group(
"Nodes Modifier Settings").release();
323 nodes::update_input_properties_from_node_tree(*nmd->
node_group, old_properties, *new_properties);
324 nodes::update_output_properties_from_node_tree(
325 *nmd->
node_group, old_properties, *new_properties);
327 if (old_properties !=
nullptr) {
338 nmd.
runtime->cache = std::make_shared<bake::ModifierCache>();
341 std::lock_guard
lock{modifier_cache.
mutex};
345 existing_bake_ids.
add(
bake.id);
348 auto remove_predicate = [&](
auto item) {
return !existing_bake_ids.
contains(item.key); };
366 if (
ELEM(node->type, GEO_NODE_SIMULATION_OUTPUT, GEO_NODE_BAKE)) {
367 new_bake_ids.
append(ref.id);
370 else if (old_bake_by_id.
contains(ref.id)) {
373 new_bake_ids.
append(ref.id);
381 const int id = new_bake_ids[i];
385 new_bake = *old_bake;
402 nmd.
bakes = new_bake_data;
412 old_panel_by_id.
add(panel.id, &panel);
430 for (
const int i : interface_panels.
index_range()) {
436 new_panel = *old_panel;
456 update_id_properties_from_node_group(nmd);
457 update_bakes_from_node_group(*nmd);
458 update_panels_from_node_group(*nmd);
486 const int final_node_id,
496 compute_context_vec.
append(c);
498 std::reverse(compute_context_vec.
begin(), compute_context_vec.
end());
501 compute_context_vec[0]);
502 if (modifier_compute_context ==
nullptr) {
505 if (modifier_compute_context->modifier_name() != nmd.
modifier.
name) {
519 if (current_zones ==
nullptr) {
523 if (lf_graph_info ==
nullptr) {
527 compute_context_generic->parent()->
hash();
529 compute_context_generic))
532 compute_context->output_node_id());
533 if (simulation_zone ==
nullptr) {
536 if (simulation_zone->
parent_zone != current_zone) {
539 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
540 simulation_zone,
nullptr);
541 if (lf_zone_node ==
nullptr) {
545 lf_graph_info->mapping.possible_side_effect_node_map.lookup_default(
547 if (lf_simulation_output_node ==
nullptr) {
550 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
553 local_side_effect_nodes.
nodes_by_context.add(compute_context_generic->hash(),
554 lf_simulation_output_node);
556 current_zone = simulation_zone;
559 compute_context_generic))
562 compute_context->output_node_id());
563 if (repeat_zone ==
nullptr) {
569 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
570 repeat_zone,
nullptr);
571 if (lf_zone_node ==
nullptr) {
574 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
576 {parent_compute_context_hash, compute_context->output_node_id()},
577 compute_context->iteration());
578 current_zone = repeat_zone;
580 else if (
const auto *compute_context =
582 compute_context_generic))
585 compute_context->output_node_id());
586 if (foreach_zone ==
nullptr) {
592 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
593 foreach_zone,
nullptr);
594 if (lf_zone_node ==
nullptr) {
597 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
599 {parent_compute_context_hash, compute_context->output_node_id()},
600 compute_context->index());
601 current_zone = foreach_zone;
604 compute_context_generic))
606 const bNode *group_node = current_tree->node_by_id(compute_context->node_id());
607 if (group_node ==
nullptr) {
610 if (group_node->
id ==
nullptr) {
613 if (group_node->is_muted()) {
619 const lf::FunctionNode *lf_group_node = lf_graph_info->mapping.group_node_map.lookup_default(
620 group_node,
nullptr);
621 if (lf_group_node ==
nullptr) {
624 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_group_node);
625 current_tree =
reinterpret_cast<const bNodeTree *
>(group_node->
id);
626 current_zone =
nullptr;
632 const bNode *final_node = current_tree->node_by_id(final_node_id);
633 if (final_node ==
nullptr) {
637 if (lf_graph_info ==
nullptr) {
641 if (tree_zones ==
nullptr) {
648 lf_graph_info->mapping.possible_side_effect_node_map.lookup_default(final_node,
nullptr);
649 if (lf_node ==
nullptr) {
669 const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
671 if (!parsed_path.has_value()) {
692 *compute_context_builder.
current(), parsed_path->viewer_node_id, nmd, r_side_effect_nodes);
697 const int root_nested_node_id,
703 int nested_node_id = root_nested_node_id;
722 if (node->is_group()) {
777 compute_context_builder,
779 const bNode &gizmo_node,
782 r_socket_log_contexts.
add(compute_context.
hash());
785 compute_context, gizmo_node, gizmo_socket, [&](
const ComputeContext &node_context) {
788 r_socket_log_contexts.
add(node_context.
hash());
812 sspreadsheet.
viewer_path, nmd, ctx, r_side_effect_nodes);
815 const View3D &v3d = *
reinterpret_cast<const View3D *
>(sl);
823 nmd, ctx, *wm, r_side_effect_nodes, r_socket_log_contexts);
845 geo_log::GeoModifierLog::get_context_hash_by_zone_for_node_editor(snode,
848 r_socket_log_contexts.
add(
hash);
863 int geometry_socket_count = 0;
866 for (
const int i : nmd->
node_group->interface_inputs().index_range()) {
872 geometry_socket_count++;
877 if (property ==
nullptr) {
879 geometry_socket_count++;
883 ob, md,
"Missing property for input socket \"%s\"", socket->
name ? socket->
name :
"");
891 "Property type does not match input socket \"(%s)\"",
897 if (geometry_socket_count == 1) {
920 if (this->old_mappings.
contains(key)) {
924 std::lock_guard
lock{mutex_};
931 if (this->old_mappings.
contains(key)) {
934 std::lock_guard
lock{mutex_};
941 const std::optional<ID_Type> &type)
943 ID *
id = map.lookup_default(key,
nullptr);
947 if (type &&
GS(id->name) != *type) {
954namespace sim_input = nodes::sim_input;
955namespace sim_output = nodes::sim_output;
964 const Span<std::unique_ptr<bake::FrameCache>> frame_caches,
const SubFrame frame)
967 if (!frame_caches.is_empty()) {
970 [&](
const std::unique_ptr<bake::FrameCache> &value) {
return value->frame > frame; });
971 frame_indices.
next = (first_future_frame_index == frame_caches.size()) ?
973 std::optional<int>(first_future_frame_index);
974 if (first_future_frame_index > 0) {
975 const int index = first_future_frame_index - 1;
976 if (frame_caches[index]->frame < frame) {
977 frame_indices.
prev = index;
980 BLI_assert(frame_caches[index]->frame == frame);
983 frame_indices.
prev = index - 1;
988 return frame_indices;
1001 const std::string meta_str{
reinterpret_cast<const char *
>(meta_buffer->data()),
1002 size_t(meta_buffer->size())};
1003 std::istringstream meta_stream{meta_str};
1006 if (!bake_state.has_value()) {
1009 frame_cache.
state = std::move(*bake_state);
1016 const auto *meta_path = std::get_if<std::string>(&*frame_cache.
meta_data_source);
1021 fstream meta_file{*meta_path};
1024 if (!bake_state.has_value()) {
1027 frame_cache.
state = std::move(*bake_state);
1038 if (
bake.packed->meta_files_num == 0) {
1044 Span{
bake.packed->meta_files,
bake.packed->meta_files_num})
1050 if (!file_by_frame.
add(*frame, &meta_file)) {
1059 for (
const SubFrame &frame : frames) {
1061 auto frame_cache = std::make_unique<bake::FrameCache>();
1062 frame_cache->frame = frame;
1063 frame_cache->meta_data_source = meta_file.data();
1064 bake_cache.
frames.append(std::move(frame_cache));
1069 Span{
bake.packed->blob_files,
bake.packed->blob_files_num})
1073 bake_cache.
blob_sharing = std::make_unique<bake::BlobReadSharing>();
1087 auto frame_cache = std::make_unique<bake::FrameCache>();
1088 frame_cache->frame = meta_file.frame;
1089 frame_cache->meta_data_source = meta_file.path;
1090 bake_cache.
frames.append(std::move(frame_cache));
1092 bake_cache.
blobs_dir = bake_path->blobs_dir;
1093 bake_cache.
blob_sharing = std::make_unique<bake::BlobReadSharing>();
1099 static constexpr float max_delta_frames = 1.0f;
1104 const Scene *scene_;
1106 bool use_frame_cache_;
1107 bool depsgraph_is_active_;
1110 bool has_invalid_simulation_ =
false;
1121 : nmd_(nmd), ctx_(ctx)
1130 modifier_cache_ = nmd.
runtime->cache.get();
1133 if (!modifier_cache_) {
1136 std::lock_guard
lock{modifier_cache_->
mutex};
1137 if (depsgraph_is_active_) {
1140 for (std::unique_ptr<bake::SimulationNodeCache> &node_cache :
1143 if (node_cache->cache_status != bake::CacheStatus::Baked) {
1144 node_cache->cache_status = bake::CacheStatus::Invalid;
1145 if (!node_cache->bake.frames.is_empty()) {
1146 if (node_cache->bake.frames.last()->frame == current_frame_) {
1149 node_cache->bake.frames.pop_last();
1157 for (
const std::unique_ptr<bake::SimulationNodeCache> &node_cache_ptr :
1161 if (node_cache.
cache_status == bake::CacheStatus::Invalid) {
1162 has_invalid_simulation_ =
true;
1171 const int id = item.key;
1173 if (node_cache.
cache_status != bake::CacheStatus::Invalid) {
1177 *scene_, *ctx_.
object, nmd_,
id);
1178 if (!sim_frame_range.has_value()) {
1181 const SubFrame start_frame{
int(sim_frame_range->start())};
1182 if (current_frame_ <= start_frame) {
1186 current_frame_ < node_cache.
bake.
frames.first()->frame)
1195 if (!modifier_cache_) {
1198 std::lock_guard
lock{modifier_cache_->
mutex};
1199 return &this->data_by_zone_id
1202 auto data = std::make_unique<DataPerZone>();
1203 data->behavior.data_block_map = &data->data_block_map;
1205 zone_id, data->behavior, data->data_block_map);
1217 zone_id, []() {
return std::make_unique<bake::SimulationNodeCache>(); });
1220 *scene_, *ctx_.
object, nmd_, zone_id);
1227 if (node_cache.
cache_status != bake::CacheStatus::Baked) {
1242 data_block_map.
old_mappings.add(data_block, data_block.id);
1248 if (node_cache.
cache_status == bake::CacheStatus::Baked) {
1252 if (use_frame_cache_) {
1255 if (depsgraph_is_active_) {
1257 if (current_frame_ < sim_start_frame || current_frame_ > sim_end_frame) {
1264 if (current_frame_ > sim_start_frame || has_invalid_simulation_) {
1271 if (frame_indices.
prev && !frame_indices.
current && !frame_indices.
next &&
1272 current_frame_ <= sim_end_frame)
1277 const float real_delta_frames =
float(current_frame_) -
float(prev_frame_cache.frame);
1278 if (real_delta_frames != 1) {
1281 const float delta_frames = std::min(max_delta_frames, real_delta_frames);
1282 output_copy_info.delta_time = delta_frames / fps_;
1283 output_copy_info.state = prev_frame_cache.state;
1294 if (node_cache.
prev_cache->frame < current_frame_) {
1296 const float delta_frames = std::min(
1297 max_delta_frames,
float(current_frame_) -
float(node_cache.
prev_cache->frame));
1299 output_move_info.
delta_time = delta_frames / fps_;
1300 output_move_info.state = std::move(node_cache.
prev_cache->state);
1304 if (node_cache.
prev_cache->frame == current_frame_) {
1308 output_copy_info.state = node_cache.
prev_cache->state;
1313 if (!depsgraph_is_active_) {
1324 if (depsgraph_is_active_) {
1347 store_new_state_info.
store_fn = [simulation_cache = modifier_cache_,
1348 node_cache = &node_cache,
1350 std::lock_guard
lock{simulation_cache->mutex};
1351 auto frame_cache = std::make_unique<bake::FrameCache>();
1352 frame_cache->frame = current_frame;
1353 frame_cache->state = std::move(
state);
1354 node_cache->
bake.
frames.append(std::move(frame_cache));
1362 store_new_state_info.
store_fn = [simulation_cache = modifier_cache_,
1363 node_cache = &node_cache,
1365 std::lock_guard
lock{simulation_cache->mutex};
1370 node_cache->
prev_cache->frame = current_frame;
1378 if (frame_indices.
prev) {
1381 const float delta_frames = std::min(max_delta_frames,
1382 float(current_frame_) -
float(frame_cache.frame));
1383 output_copy_info.delta_time = delta_frames / fps_;
1384 output_copy_info.state = frame_cache.state;
1392 else if (frame_indices.
next) {
1393 if (frame_indices.
prev) {
1395 *frame_indices.
prev, *frame_indices.
next, node_cache, zone_behavior);
1401 else if (frame_indices.
prev) {
1420 const int next_frame_index,
1430 (
float(next_frame_cache.
frame) -
1432 read_interpolated_info.prev_state = prev_frame_cache.
state;
1433 read_interpolated_info.next_state = next_frame_cache.
state;
1444 bool depsgraph_is_active_;
1455 : nmd_(nmd), ctx_(ctx)
1459 modifier_cache_ = nmd.
runtime->cache.get();
1466 if (!modifier_cache_) {
1469 std::lock_guard
lock{modifier_cache_->
mutex};
1470 return &this->data_by_node_id
1473 auto data = std::make_unique<DataPerNode>();
1474 data->behavior.data_block_map = &data->data_block_map;
1475 this->init_bake_behavior(
1476 id, data->behavior, data->data_block_map);
1484 void init_bake_behavior(
const int id,
1489 id, []() {
return std::make_unique<bake::BakeNodeCache>(); });
1493 data_block_map.
old_mappings.add(data_block, data_block.id);
1496 if (depsgraph_is_active_) {
1500 store_info.
store_fn = [modifier_cache = modifier_cache_,
1501 node_cache = &node_cache,
1503 std::lock_guard
lock{modifier_cache->mutex};
1504 auto frame_cache = std::make_unique<bake::FrameCache>();
1505 frame_cache->frame = current_frame;
1506 frame_cache->state = std::move(
state);
1507 auto &frames = node_cache->bake.frames;
1509 frames, [&](
const std::unique_ptr<bake::FrameCache> &frame_cache) {
1510 return frame_cache->frame > current_frame;
1512 frames.insert(insert_index, std::move(frame_cache));
1519 if (node_cache.bake.frames.is_empty()) {
1520 if (!node_cache.bake.failed_finding_bake) {
1522 node_cache.bake.failed_finding_bake =
true;
1527 if (node_cache.bake.frames.is_empty()) {
1534 this->read_single(*frame_indices.
current, node_cache, behavior);
1537 if (frame_indices.
prev && frame_indices.
next) {
1538 this->read_interpolated(*frame_indices.
prev, *frame_indices.
next, node_cache, behavior);
1541 if (frame_indices.
prev) {
1542 this->read_single(*frame_indices.
prev, node_cache, behavior);
1545 if (frame_indices.
next) {
1546 this->read_single(*frame_indices.
next, node_cache, behavior);
1552 void read_single(
const int frame_index,
1558 if (this->check_read_error(frame_cache, behavior)) {
1565 void read_interpolated(
const int prev_frame_index,
1566 const int next_frame_index,
1574 if (this->check_read_error(prev_frame_cache, behavior) ||
1575 this->check_read_error(next_frame_cache, behavior))
1581 (
float(next_frame_cache.
frame) -
1583 read_interpolated_info.prev_state = prev_frame_cache.
state;
1584 read_interpolated_info.next_state = next_frame_cache.
state;
1592 read_error_info.
message =
RPT_(
"Cannot load the baked data");
1604 const int old_num =
bake.data_blocks_num;
1605 const int new_num = old_num + missing.
size();
1617 ID *
id = get_data_block(key);
1622 bake.data_blocks_num = new_num;
1649 struct DataPerBake {
1650 bool reset_first =
false;
1657 if (item.value->data_block_map.old_mappings.size() <
bake.data_blocks_num) {
1658 data.reset_first =
true;
1664 if (!node_cache->
bake.
frames.is_empty() || node_cache->prev_cache.has_value()) {
1665 data.new_mappings = std::move(item.value->data_block_map.new_mappings);
1668 if (data.reset_first || !data.new_mappings.is_empty()) {
1669 writeback_data.
add(item.key, std::move(data));
1677 data.new_mappings = std::move(item.value->data_block_map.new_mappings);
1678 writeback_data.
add(item.key, std::move(data));
1690 [object_eval = ctx.
object,
1694 writeback_data = std::move(writeback_data)]() {
1695 for (auto item : writeback_data.items()) {
1696 const int bake_id = item.key;
1697 DataPerBake data = item.value;
1699 NodesModifierBake &bake_orig = *nmd_orig.find_bake(bake_id);
1700 NodesModifierBake &bake_eval = *nmd_eval.find_bake(bake_id);
1702 if (data.reset_first) {
1704 dna::array::clear<NodesModifierDataBlock>(&bake_orig.data_blocks,
1705 &bake_orig.data_blocks_num,
1706 &bake_orig.active_data_block,
1707 [](NodesModifierDataBlock *data_block) {
1708 nodes_modifier_data_block_destruct(
1712 dna::array::clear<NodesModifierDataBlock>(&bake_eval.data_blocks,
1713 &bake_eval.data_blocks_num,
1714 &bake_eval.active_data_block,
1715 [](NodesModifierDataBlock *data_block) {
1716 nodes_modifier_data_block_destruct(
1721 Vector<bake::BakeDataBlockID> sorted_new_mappings;
1722 sorted_new_mappings.extend(data.new_mappings.keys().begin(),
1723 data.new_mappings.keys().end());
1724 bool needs_reevaluation = false;
1727 add_missing_data_block_mappings(
1728 bake_orig, sorted_new_mappings, [&](const bake::BakeDataBlockID &key) -> ID * {
1729 ID *id_orig = nullptr;
1730 if (ID *id_eval = data.new_mappings.lookup_default(key, nullptr)) {
1731 id_orig = DEG_get_original_id(id_eval);
1734 needs_reevaluation = true;
1735 id_orig = BKE_libblock_find_name_and_library(
1736 bmain, short(key.type), key.id_name.c_str(), key.lib_name.c_str());
1739 id_us_plus(id_orig);
1747 add_missing_data_block_mappings(
1748 bake_eval, sorted_new_mappings, [&](const bake::BakeDataBlockID &key) -> ID * {
1749 return data.new_mappings.lookup_default(key, nullptr);
1752 if (needs_reevaluation) {
1753 Object *object_orig = DEG_get_original_object(object_eval);
1754 DEG_id_tag_update(&object_orig->id, ID_RECALC_GEOMETRY);
1755 DEG_relations_tag_update(bmain);
1776 tree.ensure_topology_cache();
1777 const bNode *output_node =
tree.group_output_node();
1778 if (output_node ==
nullptr) {
1780 geometry_set.
clear();
1787 geometry_set.
clear();
1791 const bNodeSocket *first_output_socket = group_outputs[0];
1792 if (!
STREQ(first_output_socket->
idname,
"NodeSocketGeometry")) {
1794 geometry_set.
clear();
1799 nodes::ensure_geometry_nodes_lazy_function_graph(
tree);
1800 if (lf_graph_info ==
nullptr) {
1802 geometry_set.
clear();
1806 bool use_orig_index_verts =
false;
1807 bool use_orig_index_edges =
false;
1808 bool use_orig_index_faces =
false;
1819 modifier_eval_data.self_object = ctx->
object;
1820 auto eval_log = std::make_unique<geo_log::GeoModifierLog>();
1830 call_data.
eval_log = eval_log.get();
1842 geometry_set = nodes::execute_geometry_nodes_on_geometry(
tree,
1844 modifier_compute_context,
1846 std::move(geometry_set));
1849 nmd_orig->
runtime->eval_log = std::move(eval_log);
1856 if (use_orig_index_verts || use_orig_index_edges || use_orig_index_faces) {
1861 if (use_orig_index_verts) {
1864 if (use_orig_index_edges) {
1867 if (use_orig_index_faces) {
1877 mesh, bke::GeometryOwnershipType::Editable);
1882 if (new_mesh ==
nullptr) {
1916 &bmain,
ID_OB, data.object_session_uid);
1917 if (
object ==
nullptr) {
1921 if (md ==
nullptr) {
1934 return &nmd.
runtime->eval_log->get_tree_log(compute_context.hash());
1942 if (nmd ==
nullptr) {
1949 if (tree_log ==
nullptr) {
1956 if (data.is_output) {
1957 for (
const bNode *node : nmd->
node_group->nodes_by_type(
"NodeGroupOutput")) {
1958 for (
const bNodeSocket *socket : node->input_sockets()) {
1960 sockets_to_check.
append(socket);
1967 for (
const bNodeSocket *socket : node->output_sockets()) {
1969 sockets_to_check.
append(socket);
1976 for (
const bNodeSocket *socket : sockets_to_check) {
1978 if (value_log ==
nullptr) {
1983 if (names.
add(attribute.name)) {
1984 attributes.append(&attribute);
1989 ui::attribute_search_add_items(
str, data.is_output, attributes.as_span(), items, is_first);
1994 if (item_v ==
nullptr) {
2000 if (nmd ==
nullptr) {
2004 const std::string attribute_prop_name = data.socket_identifier +
2005 nodes::input_attribute_name_suffix();
2007 attribute_prop_name.c_str());
2019 const bool is_output)
2037 rna_path_attribute_name.
c_str(),
2043 const Object *
object = ed::object::context_object(&C);
2045 if (
object ==
nullptr) {
2050 data->object_session_uid =
object->id.session_uid;
2053 data->is_output = is_output;
2060 static_cast<void *
>(data),
2067 md_ptr, rna_path_attribute_name.
c_str(),
nullptr, 0,
nullptr);
2068 const bool access_allowed = bke::allow_procedural_attribute_access(attribute_name);
2070 if (!access_allowed) {
2085 BLI_str_escape(socket_id_esc, identifier.c_str(),
sizeof(socket_id_esc));
2086 const std::string rna_path =
"[\"" + std::string(socket_id_esc) +
"\"]";
2087 const std::string rna_path_attribute_name =
"[\"" + std::string(socket_id_esc) +
2088 nodes::input_attribute_name_suffix() +
"\"]";
2097 const std::optional<StringRef> attribute_name = nodes::input_attribute_name_get(
2100 uiItemL(name_row,
"", ICON_NONE);
2112 if (attribute_name) {
2114 uiItemL(layout,
"", ICON_BLANK1);
2124 "object.geometry_nodes_input_attribute_toggle",
2151 if (property ==
nullptr || !nodes::id_property_type_matches_socket(socket, *property)) {
2156 BLI_str_escape(socket_id_esc, identifier.c_str(),
sizeof(socket_id_esc));
2158 char rna_path[
sizeof(socket_id_esc) + 4];
2159 SNPRINTF(rna_path,
"[\"%s\"]", socket_id_esc);
2164 const int input_index =
2175 uiItemPointerR(row, md_ptr, rna_path, bmain_ptr,
"objects", name, ICON_OBJECT_DATA);
2180 row, md_ptr, rna_path, bmain_ptr,
"collections", name, ICON_OUTLINER_COLLECTION);
2184 uiItemPointerR(row, md_ptr, rna_path, bmain_ptr,
"materials", name, ICON_MATERIAL);
2188 uiItemPointerR(row, md_ptr, rna_path, bmain_ptr,
"textures", name, ICON_TEXTURE);
2192 uiItemPointerR(row, md_ptr, rna_path, bmain_ptr,
"images", name, ICON_IMAGE);
2203 if (nodes::input_has_attribute_toggle(*nmd->
node_group, input_index)) {
2211 if (!nodes::input_has_attribute_toggle(*nmd->
node_group, input_index)) {
2212 uiItemL(row,
"", ICON_BLANK1);
2224 BLI_str_escape(socket_id_esc, identifier.c_str(),
sizeof(socket_id_esc));
2225 const std::string rna_path_attribute_name =
"[\"" +
StringRef(socket_id_esc) +
2226 nodes::input_attribute_name_suffix() +
"\"]";
2279 modifier_ptr->
owner_id, &RNA_NodesModifierPanel, panel);
2284 [](
bContext * ,
void *panel_arg,
const char * ) -> std::string {
2285 const auto *panel = static_cast<bNodeTreeInterfacePanel *>(panel_arg);
2286 return StringRef(panel->description);
2291 if (panel_layout.
body) {
2314 if (nodes::socket_type_has_attribute_toggle(type)) {
2331 if (nodes::socket_type_has_attribute_toggle(type)) {
2350 if (tree_log ==
nullptr) {
2358 if (usage_by_attribute.
is_empty()) {
2359 uiItemL(layout,
RPT_(
"No named attributes used"), ICON_INFO);
2363 struct NameWithUsage {
2369 for (
auto &&item : usage_by_attribute.
items()) {
2370 sorted_used_attribute.
append({item.key, item.value});
2372 std::sort(sorted_used_attribute.
begin(),
2373 sorted_used_attribute.
end(),
2374 [](
const NameWithUsage &a,
const NameWithUsage &
b) {
2375 return BLI_strcasecmp_natural(a.name.c_str(), b.name.c_str()) < 0;
2378 for (
const NameWithUsage &attribute : sorted_used_attribute) {
2385 std::stringstream ss;
2387 if ((usage & geo_log::NamedAttributeUsage::Read) != geo_log::NamedAttributeUsage::None) {
2390 if ((usage & geo_log::NamedAttributeUsage::Write) != geo_log::NamedAttributeUsage::None) {
2393 if ((usage & geo_log::NamedAttributeUsage::Remove) != geo_log::NamedAttributeUsage::None) {
2398 if (i < usages.size() - 1) {
2406 uiItemL(row, ss.str().c_str(), ICON_NONE);
2419 C, layout, modifier_ptr,
"open_bake_panel",
IFACE_(
"Bake")))
2424 C, layout, modifier_ptr,
"open_named_attributes_panel",
IFACE_(
"Named Attributes")))
2440 tree_log->ensure_node_warnings(nmd.
node_group);
2441 const int warnings_num = tree_log->all_warnings.size();
2442 if (warnings_num == 0) {
2446 uiItemL(panel.
header, fmt::format(
IFACE_(
"Warnings ({})"), warnings_num).c_str(), ICON_NONE);
2451 for (
const int i : warnings.index_range()) {
2452 warnings[i] = &tree_log->all_warnings[i];
2454 std::sort(warnings.begin(), warnings.end(), [](
const NodeWarning *a,
const NodeWarning *
b) {
2455 const int severity_a = node_warning_type_severity(a->type);
2456 const int severity_b = node_warning_type_severity(b->type);
2457 if (severity_a > severity_b) {
2460 if (severity_a < severity_b) {
2467 for (
const NodeWarning *warning : warnings) {
2468 const int icon = node_warning_type_icon(warning->type);
2469 uiItemL(
col, warning->message.c_str(), icon);
2486 const char *newop = (nmd->
node_group ==
nullptr) ?
"node.new_geometry_node_group_assign" :
2487 "object.geometry_node_tree_copy_assign";
2502 C, layout,
ptr,
"open_output_attributes_panel",
IFACE_(
"Output Attributes")))
2508 C, layout,
ptr,
"open_manage_panel",
IFACE_(
"Manage")))
2539 prop->ui_data =
nullptr;
2566 if (bake_file.packed_file) {
2571 Span{
bake.packed->meta_files,
bake.packed->meta_files_num})
2573 write_bake_file(meta_file);
2576 Span{
bake.packed->blob_files,
bake.packed->blob_files_num})
2578 write_bake_file(blob_file);
2640 if (bake_file.packed_file) {
2647 read_bake_file(meta_file);
2652 read_bake_file(blob_file);
2658 nmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
2659 nmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
2673 if (
bake.directory) {
2676 if (
bake.data_blocks) {
2691 const int bake_files_num) {
2698 if (bake_file.packed_file) {
2703 copy_bake_files_inplace(&
bake.packed->meta_files,
bake.packed->meta_files_num);
2704 copy_bake_files_inplace(&
bake.packed->blob_files,
bake.packed->blob_files_num);
2713 tnmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
2722 tnmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
2737 if (file.packed_file) {
2790 N_(
"GeometryNodes"),
2791 "NodesModifierData",
2800 ICON_GEOMETRY_NODES,
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
void IDP_AssignString(IDProperty *prop, const char *st) ATTR_NONNULL()
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define IDP_BlendDataRead(reader, prop)
void IDP_FreeProperty(IDProperty *prop)
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
void IDP_FreeProperty_ex(IDProperty *prop, bool do_id_user)
ID * BKE_libblock_find_session_uid(Main *bmain, short type, uint32_t session_uid)
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
void(*)(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop) TexWalkFunc
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
ModifierData * BKE_modifiers_findby_name(const Object *ob, const char *name)
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
General operations, lookup, etc. for blender objects.
PackedFile * BKE_packedfile_duplicate(const PackedFile *pf_src)
void BKE_packedfile_free(PackedFile *pf)
void BKE_packedfile_blend_write(BlendWriter *writer, const PackedFile *pf)
void BKE_packedfile_blend_read(BlendDataReader *reader, PackedFile **pf_p, blender::StringRefNull filepath)
General operations for point clouds.
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
WorkSpace * BKE_workspace_active_get(WorkSpaceInstanceHook *hook) GETTER_ATTRS
#define BLI_assert_unreachable()
#define BLI_STATIC_ASSERT(a, msg)
#define LISTBASE_FOREACH(type, var, list)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
int char char int int int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define SET_FLAG_FROM_TEST(value, test, flag)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define BLO_read_struct(reader, struct_name, ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
bool DEG_is_active(const Depsgraph *depsgraph)
void DEG_add_scene_camera_relation(DepsNodeHandle *node_handle, Scene *scene, eDepsObjectComponentType component, const char *description)
void DEG_add_generic_id_relation(DepsNodeHandle *node_handle, ID *id, const char *description)
void DEG_add_depends_on_transform_relation(DepsNodeHandle *node_handle, const char *description)
@ DEG_SCENE_COMP_PARAMETERS
void DEG_add_customdata_mask(DepsNodeHandle *handle, Object *object, const CustomData_MeshMasks *masks)
void DEG_add_collection_geometry_relation(DepsNodeHandle *node_handle, Collection *collection, const char *description)
void DEG_add_scene_relation(DepsNodeHandle *node_handle, Scene *scene, eDepsSceneComponentType component, const char *description)
bool DEG_object_has_geometry_component(Object *object)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_collection_geometry_customdata_mask(DepsNodeHandle *node_handle, Collection *collection, const CustomData_MeshMasks *masks)
void DEG_add_node_tree_output_relation(DepsNodeHandle *node_handle, bNodeTree *node_tree, const char *description)
float DEG_get_ctime(const Depsgraph *graph)
Main * DEG_get_bmain(const Depsgraph *graph)
Scene * DEG_get_input_scene(const Depsgraph *graph)
Object * DEG_get_original_object(Object *object)
Object groups, one object can be in many groups at once.
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ eModifierFlag_UserModified
@ NODES_MODIFIER_PANEL_WARNINGS
struct NodesModifierData NodesModifierData
@ NODES_MODIFIER_PANEL_OPEN
@ NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR
@ NODES_MODIFIER_BAKE_MODE_STILL
@ NODES_MODIFIER_BAKE_MODE_ANIMATION
@ NODE_INTERFACE_PANEL_DEFAULT_CLOSED
@ NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER
@ NODE_INTERFACE_SOCKET_INPUT
Object is a sort of wrapper for general info.
@ OB_FLAG_USE_SIMULATION_CACHE
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_undo_push(bContext *C, const char *str)
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void free_data(ModifierData *md)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static bool depends_on_time(Scene *, ModifierData *)
static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
ModifierTypeInfo modifierType_Nodes
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void uiLayoutSetActive(uiLayout *layout, bool active)
void UI_but_func_search_set_results_are_suggestions(uiBut *but, bool value)
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
void uiLayoutSetTooltipFunc(uiLayout *layout, uiButToolTipFunc func, void *arg, uiCopyArgFunc copy_arg, uiFreeArgFunc free_arg)
void uiItemDecoratorR(uiLayout *layout, PointerRNA *ptr, const char *propname, int index)
uiBut * uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, const char *tip)
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
PanelLayout uiLayoutPanelProp(const bContext *C, uiLayout *layout, PointerRNA *open_prop_owner, const char *open_prop_name)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter=UI_TEMPLATE_ID_FILTER_ALL, bool live_icon=false, const char *text=nullptr)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
void UI_but_flag_enable(uiBut *but, int flag)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
const ComputeContext * current() const
void push(Args &&...args)
const ComputeContext * parent() const
const ComputeContextHash & hash() const
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
SubIterator begin() const
const Value * lookup_ptr(const Key &key) const
bool add_overwrite(const Key &key, const Value &value)
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) const
ValueIterator values() const
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
void add_new(const Key &key, const Value &value)
ItemIterator items() const
bool contains(const Key &key) const
Value & lookup_or_add(const Key &key, const Value &value)
ID * lookup_or_remember_missing(const bake::BakeDataBlockID &key) override
Map< bake::BakeDataBlockID, ID * > old_mappings
Map< bake::BakeDataBlockID, ID * > new_mappings
void try_add(ID &id) override
nodes::BakeNodeBehavior * get(const int id) const
NodesModifierBakeParams(NodesModifierData &nmd, const ModifierEvalContext &ctx)
Map< int, std::unique_ptr< DataPerNode > > data_by_node_id
NodesModifierSimulationParams(NodesModifierData &nmd, const ModifierEvalContext &ctx)
void input_pass_through(nodes::SimulationZoneBehavior &zone_behavior) const
void output_store_frame_cache(bake::SimulationNodeCache &node_cache, nodes::SimulationZoneBehavior &zone_behavior) const
void store_as_prev_items(bake::SimulationNodeCache &node_cache, nodes::SimulationZoneBehavior &zone_behavior) const
void read_single(const int frame_index, bake::SimulationNodeCache &node_cache, nodes::SimulationZoneBehavior &zone_behavior) const
void reset_invalid_node_bakes()
void read_interpolated(const int prev_frame_index, const int next_frame_index, bake::SimulationNodeCache &node_cache, nodes::SimulationZoneBehavior &zone_behavior) const
void read_from_cache(const BakeFrameIndices &frame_indices, bake::SimulationNodeCache &node_cache, nodes::SimulationZoneBehavior &zone_behavior) const
void output_pass_through(nodes::SimulationZoneBehavior &zone_behavior) const
Map< int, std::unique_ptr< DataPerZone > > data_by_zone_id
nodes::SimulationZoneBehavior * get(const int zone_id) const override
void init_simulation_info(const int zone_id, nodes::SimulationZoneBehavior &zone_behavior, NodesModifierBakeDataBlockMap &data_block_map) const
bool contains(const Key &key) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
IndexRange index_range() const
void extend(Span< T > array)
Span< T > as_span() const
const bNode * output_node
bNodeTreeZone * parent_zone
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
Vector< std::unique_ptr< bNodeTreeZone > > zones
void ensure_used_named_attributes()
void ensure_existing_attributes()
Map< StringRefNull, NamedAttributeUsage > used_named_attributes
ValueLog * find_socket_value_log(const bNodeSocket &query_socket)
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static void update_depsgraph(tGraphSliderOp *gso)
static const char * modifier_name[LS_MODIFIER_NUM]
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
int64_t find_predicate_begin(Iterator begin, Iterator end, Predicate &&predicate)
std::optional< SubFrame > file_name_to_frame(const StringRef file_name)
std::optional< BakePath > get_node_bake_path(const Main &bmain, const Object &object, const NodesModifierData &nmd, int node_id)
std::optional< IndexRange > get_node_bake_frame_range(const Scene &scene, const Object &object, const NodesModifierData &nmd, int node_id)
Vector< MetaFile > find_sorted_meta_files(const StringRefNull meta_dir)
std::optional< BakeState > deserialize_bake(std::istream &stream, const BlobReader &blob_reader, const BlobReadSharing &blob_sharing)
void add(Depsgraph &depsgraph, std::function< void()> fn)
bool add_compute_context_for_viewer_path_elem(const ViewerPathElem &elem, ComputeContextBuilder &compute_context_builder)
std::optional< ViewerPathForGeometryNodesViewer > parse_geometry_nodes_viewer(const ViewerPath &viewer_path)
void foreach_active_gizmo_in_modifier(const Object &object, const NodesModifierData &nmd, const wmWindowManager &wm, ComputeContextBuilder &compute_context_builder, const ForeachGizmoInModifierFn fn)
void foreach_compute_context_on_gizmo_path(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket, FunctionRef< void(const ComputeContext &context)> fn)
bool id_property_type_matches_socket(const bNodeTreeInterfaceSocket &socket, const IDProperty &property, const bool use_name_for_ids)
const GeometryNodesLazyFunctionGraphInfo * ensure_geometry_nodes_lazy_function_graph(const bNodeTree &btree)
static bool depends_on_time(Scene *, ModifierData *md)
static bool logging_enabled(const ModifierEvalContext *ctx)
static void find_side_effect_nodes_for_baking(const NodesModifierData &nmd, const ModifierEvalContext &ctx, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void add_attribute_search_button(const bContext &C, uiLayout *layout, const NodesModifierData &nmd, PointerRNA *md_ptr, const StringRefNull rna_path_attribute_name, const bNodeTreeInterfaceSocket &socket, const bool is_output)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static void draw_bake_panel(uiLayout *layout, PointerRNA *modifier_ptr)
static void init_data(ModifierData *md)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void find_side_effect_nodes_for_nested_node(const NodesModifierData &nmd, const int root_nested_node_id, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
static void check_property_socket_sync(const Object *ob, ModifierData *md)
static void draw_named_attributes_panel(uiLayout *layout, NodesModifierData &nmd)
static NodesModifierData * get_modifier_data(Main &bmain, const wmWindowManager &wm, const AttributeSearchData &data)
static BakeFrameIndices get_bake_frame_indices(const Span< std::unique_ptr< bake::FrameCache > > frame_caches, const SubFrame frame)
static void add_missing_data_block_mappings(NodesModifierBake &bake, const Span< bake::BakeDataBlockID > missing, FunctionRef< ID *(const bake::BakeDataBlockID &)> get_data_block)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet *geometry_set)
static void add_attribute_search_or_value_buttons(const bContext &C, uiLayout *layout, const NodesModifierData &nmd, PointerRNA *md_ptr, const bNodeTreeInterfaceSocket &socket)
static bool interace_panel_has_socket(const bNodeTreeInterfacePanel &interface_panel)
static void find_side_effect_nodes_for_viewer_path(const ViewerPath &viewer_path, const NodesModifierData &nmd, const ModifierEvalContext &ctx, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
static void draw_output_attributes_panel(const bContext *C, uiLayout *layout, const NodesModifierData &nmd, PointerRNA *ptr)
void nodes_modifier_data_block_destruct(NodesModifierDataBlock *data_block, const bool do_id_user)
static void draw_property_for_output_socket(const bContext &C, uiLayout *layout, const NodesModifierData &nmd, PointerRNA *md_ptr, const bNodeTreeInterfaceSocket &socket)
static const CustomData_MeshMasks dependency_data_mask
static void free_data(ModifierData *md)
static void update_bakes_from_node_group(NodesModifierData &nmd)
static void panel_register(ARegionType *region_type)
static void find_side_effect_nodes_for_active_gizmos(const NodesModifierData &nmd, const ModifierEvalContext &ctx, const wmWindowManager &wm, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes, Set< ComputeContextHash > &r_socket_log_contexts)
static void add_data_block_items_writeback(const ModifierEvalContext &ctx, NodesModifierData &nmd_eval, NodesModifierData &nmd_orig, NodesModifierSimulationParams &simulation_params, NodesModifierBakeParams &bake_params)
static bool has_output_attribute(const NodesModifierData &nmd)
static void draw_warnings(const bContext *C, const NodesModifierData &nmd, uiLayout *layout, PointerRNA *md_ptr)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void draw_interface_panel_content(const bContext *C, uiLayout *layout, PointerRNA *modifier_ptr, NodesModifierData &nmd, const bNodeTreeInterfacePanel &interface_panel)
static void try_add_side_effect_node(const ComputeContext &final_compute_context, const int final_node_id, const NodesModifierData &nmd, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
static bool check_tree_for_time_node(const bNodeTree &tree, Set< const bNodeTree * > &checked_groups)
static void foreach_tex_link(ModifierData *md, Object *ob, TexWalkFunc walk, void *user_data)
static void update_id_properties_from_node_group(NodesModifierData *nmd)
static void modifyGeometry(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet &geometry_set)
static void remove_outdated_bake_caches(NodesModifierData &nmd)
static void ensure_bake_loaded(bake::NodeBakeCache &bake_cache, bake::FrameCache &frame_cache)
static NodesModifierPanel * find_panel_by_id(NodesModifierData &nmd, const int id)
static bool try_find_baked_data(const NodesModifierBake &bake, bake::NodeBakeCache &bake_cache, const Main &bmain, const Object &object, const NodesModifierData &nmd, const int id)
static void draw_manage_panel(const bContext *C, uiLayout *layout, PointerRNA *modifier_ptr, NodesModifierData &nmd)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static void draw_property_for_socket(const bContext &C, uiLayout *layout, NodesModifierData *nmd, PointerRNA *bmain_ptr, PointerRNA *md_ptr, const bNodeTreeInterfaceSocket &socket)
static void find_socket_log_contexts(const NodesModifierData &nmd, const ModifierEvalContext &ctx, Set< ComputeContextHash > &r_socket_log_contexts)
void nodes_modifier_packed_bake_free(NodesModifierPackedBake *packed_bake)
static void attribute_search_update_fn(const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
static geo_log::GeoTreeLog * get_root_tree_log(const NodesModifierData &nmd)
static bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Object &object)
static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v)
static void add_collection_relation(const ModifierUpdateDepsgraphContext *ctx, Collection &collection)
static void find_side_effect_nodes(const NodesModifierData &nmd, const ModifierEvalContext &ctx, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes, Set< ComputeContextHash > &r_socket_log_contexts)
static void find_used_ids_from_settings(const NodesModifierSettings &settings, Set< ID * > &ids)
static void update_panels_from_node_group(NodesModifierData &nmd)
bool is_layer_selection_field(const bNodeTreeInterfaceSocket &socket)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
PointerRNA RNA_main_pointer_create(Main *main)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
#define UI_MENU_ARROW_SEP
uint16_t layout_panel_open_flag
NodesModifierPanel * panels
struct bNodeTree * node_group
NodesModifierRuntimeHandle * runtime
struct NodesModifierSettings settings
NodesModifierBake * bakes
NodesModifierBakeFile * meta_files
NodesModifierBakeFile * blob_files
struct IDProperty * properties
struct bNodeTree * edittree
bNodeTreeInterfacePanel root_panel
bNodeTreeInterface tree_interface
uint32_t object_session_uid
std::optional< int > current
std::optional< int > prev
std::optional< int > next
NodesModifierBakeDataBlockMap data_block_map
nodes::BakeNodeBehavior behavior
nodes::SimulationZoneBehavior behavior
NodesModifierBakeDataBlockMap data_block_map
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
const Mesh * get_mesh() const
Mesh * get_mesh_for_write()
Map< int, std::unique_ptr< BakeItem > > items_by_id
std::optional< std::variant< std::string, Span< std::byte > > > meta_data_source
Map< int, std::unique_ptr< SimulationNodeCache > > simulation_cache_by_id
Map< int, std::unique_ptr< BakeNodeCache > > bake_cache_by_id
Set< int > requested_bakes
std::unique_ptr< MemoryBlobReader > memory_blob_reader
Vector< std::unique_ptr< FrameCache > > frames
std::unique_ptr< BlobReadSharing > blob_sharing
std::optional< std::string > blobs_dir
std::optional< PrevCache > prev_cache
sim_output::Behavior behavior
GeoNodesSimulationParams * simulation_params
GeoNodesModifierData * modifier_data
geo_eval_log::GeoModifierLog * eval_log
const Set< ComputeContextHash > * socket_log_contexts
GeoNodesBakeParams * bake_params
const GeoNodesSideEffectNodes * side_effect_nodes
MultiValueMap< std::pair< ComputeContextHash, int32_t >, int > iterations_by_iteration_zone
MultiValueMap< ComputeContextHash, const lf::FunctionNode * > nodes_by_context
sim_output::Behavior output
sim_input::Behavior input
bke::bake::BakeStateRef state
std::function< void(bke::bake::BakeState state)> store_fn