10#include <fmt/format.h>
73#include "RNA_prototypes.hh"
110 nmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
111 nmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
118 if (ID *id = IDP_ID_get(property)) {
119 deps.add_generic_id_full(id);
150 if (
object.type ==
OB_EMPTY &&
object.instance_collection !=
nullptr) {
185 if (curves_id->
surface !=
nullptr) {
240 if (
tree ==
nullptr) {
262 walk(user_data, ob, (ID **)&id_prop->data.pointer, IDWALK_CB_USER);
277 walk(user_data, ob, md, &
ptr, prop);
318 *nmd->
node_group, old_properties, *new_properties);
320 if (old_properties !=
nullptr) {
331 nmd.
runtime->cache = std::make_shared<bake::ModifierCache>();
334 std::lock_guard
lock{modifier_cache.
mutex};
338 existing_bake_ids.
add(
bake.id);
341 auto remove_predicate = [&](
auto item) {
return !existing_bake_ids.
contains(item.key); };
360 new_bake_ids.
append(ref.id);
363 else if (old_bake_by_id.
contains(ref.id)) {
366 new_bake_ids.
append(ref.id);
374 const int id = new_bake_ids[
i];
378 new_bake = *old_bake;
383 old_bake->
packed =
nullptr;
398 nmd.
bakes = new_bake_data;
408 old_panel_by_id.
add(panel.id, &panel);
432 new_panel = *old_panel;
455 nmd->
runtime->usage_cache.reset();
484 const int final_node_id,
494 compute_context_vec.
append(c);
496 std::reverse(compute_context_vec.
begin(), compute_context_vec.
end());
499 compute_context_vec[0]);
500 if (modifier_compute_context ==
nullptr) {
517 if (current_zones ==
nullptr) {
521 if (lf_graph_info ==
nullptr) {
525 compute_context_generic->parent()->
hash();
527 compute_context_generic))
530 compute_context->output_node_id());
531 if (simulation_zone ==
nullptr) {
534 if (simulation_zone->
parent_zone != current_zone) {
537 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
538 simulation_zone,
nullptr);
539 if (lf_zone_node ==
nullptr) {
543 lf_graph_info->mapping.possible_side_effect_node_map.lookup_default(
545 if (lf_simulation_output_node ==
nullptr) {
548 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
551 local_side_effect_nodes.
nodes_by_context.add(compute_context_generic->hash(),
552 lf_simulation_output_node);
554 current_zone = simulation_zone;
557 compute_context_generic))
560 compute_context->output_node_id());
561 if (repeat_zone ==
nullptr) {
567 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
568 repeat_zone,
nullptr);
569 if (lf_zone_node ==
nullptr) {
572 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
574 {parent_compute_context_hash, compute_context->output_node_id()},
575 compute_context->iteration());
576 current_zone = repeat_zone;
578 else if (
const auto *compute_context =
580 compute_context_generic))
583 compute_context->output_node_id());
584 if (foreach_zone ==
nullptr) {
590 const lf::FunctionNode *lf_zone_node = lf_graph_info->mapping.zone_node_map.lookup_default(
591 foreach_zone,
nullptr);
592 if (lf_zone_node ==
nullptr) {
595 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_zone_node);
597 {parent_compute_context_hash, compute_context->output_node_id()},
598 compute_context->index());
599 current_zone = foreach_zone;
602 compute_context_generic))
604 const bNode *group_node = current_tree->node_by_id(compute_context->node_id());
605 if (group_node ==
nullptr) {
608 if (group_node->
id ==
nullptr) {
611 if (group_node->is_muted()) {
617 const lf::FunctionNode *lf_group_node = lf_graph_info->mapping.group_node_map.lookup_default(
618 group_node,
nullptr);
619 if (lf_group_node ==
nullptr) {
622 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_group_node);
623 current_tree =
reinterpret_cast<const bNodeTree *
>(group_node->
id);
624 current_zone =
nullptr;
626 else if (
const auto *compute_context =
629 const bNode *evaluate_node = current_tree->node_by_id(compute_context->node_id());
630 if (!evaluate_node) {
633 if (evaluate_node->is_muted()) {
639 const std::optional<nodes::ClosureSourceLocation> &source_location =
640 compute_context->closure_source_location();
641 if (!source_location) {
644 if (!source_location->tree->zones()) {
648 lf_graph_info->mapping.possible_side_effect_node_map.lookup_default(evaluate_node,
650 if (!lf_evaluate_node) {
656 source_location->tree :
659 ctx.
depsgraph, &source_location->tree->id));
660 const bNode *closure_output_node = eval_closure_tree->node_by_id(
661 source_location->closure_output_node_id);
662 if (!closure_output_node) {
665 local_side_effect_nodes.
nodes_by_context.add(parent_compute_context_hash, lf_evaluate_node);
666 current_tree = eval_closure_tree;
667 current_zone = eval_closure_tree->zones()->get_zone_by_node(closure_output_node->
identifier);
673 const bNode *final_node = current_tree->node_by_id(final_node_id);
674 if (final_node ==
nullptr) {
678 if (lf_graph_info ==
nullptr) {
682 if (tree_zones ==
nullptr) {
689 lf_graph_info->mapping.possible_side_effect_node_map.lookup_default(final_node,
nullptr);
690 if (lf_node ==
nullptr) {
710 const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path =
712 if (!parsed_path.has_value()) {
726 *elem, compute_context_cache, current);
738 const int root_nested_node_id,
744 int nested_node_id = root_nested_node_id;
763 if (node->is_group()) {
818 compute_context_cache,
820 const bNode &gizmo_node,
823 ctx, compute_context, gizmo_node.
identifier, nmd, r_side_effect_nodes);
824 r_socket_log_contexts.
add(compute_context.
hash());
827 compute_context, gizmo_node, gizmo_socket, [&](
const ComputeContext &node_context) {
830 r_socket_log_contexts.
add(node_context.
hash());
857 const View3D &v3d = *
reinterpret_cast<const View3D *
>(sl);
865 nmd, ctx, *
wm, r_side_effect_nodes, r_socket_log_contexts);
892 compute_context_cache);
894 r_socket_log_contexts.
add(
hash);
911 int geometry_socket_count = 0;
916 for (
const int i : nmd->
node_group->interface_inputs().index_range()) {
921 geometry_socket_count++;
927 if (
ELEM(input_structure_types[
i], nodes::StructureType::Grid, nodes::StructureType::List)) {
932 if (property ==
nullptr) {
935 ob, md,
"Missing property for input socket \"%s\"", socket->
name ? socket->
name :
"");
943 "Property type does not match input socket \"(%s)\"",
949 if (geometry_socket_count == 1) {
972 if (this->old_mappings.
contains(key)) {
976 std::lock_guard
lock{mutex_};
983 if (this->old_mappings.
contains(key)) {
986 std::lock_guard
lock{mutex_};
993 const std::optional<ID_Type> &type)
999 if (type &&
GS(id->
name) != *type) {
1016 const Span<std::unique_ptr<bake::FrameCache>> frame_caches,
const SubFrame frame)
1019 if (!frame_caches.is_empty()) {
1022 [&](
const std::unique_ptr<bake::FrameCache> &value) {
return value->frame > frame; });
1023 frame_indices.
next = (first_future_frame_index == frame_caches.size()) ?
1025 std::optional<int>(first_future_frame_index);
1026 if (first_future_frame_index > 0) {
1027 const int index = first_future_frame_index - 1;
1028 if (frame_caches[index]->frame < frame) {
1029 frame_indices.
prev = index;
1032 BLI_assert(frame_caches[index]->frame == frame);
1033 frame_indices.
current = index;
1035 frame_indices.
prev = index - 1;
1040 return frame_indices;
1053 const std::string meta_str{
reinterpret_cast<const char *
>(meta_buffer->data()),
1054 size_t(meta_buffer->size())};
1055 std::istringstream meta_stream{meta_str};
1058 if (!bake_state.has_value()) {
1061 frame_cache.
state = std::move(*bake_state);
1068 const auto *meta_path = std::get_if<std::string>(&*frame_cache.
meta_data_source);
1073 fstream meta_file{*meta_path};
1076 if (!bake_state.has_value()) {
1079 frame_cache.
state = std::move(*bake_state);
1090 if (
bake.packed->meta_files_num == 0) {
1096 Span{
bake.packed->meta_files,
bake.packed->meta_files_num})
1102 if (!file_by_frame.
add(*frame, &meta_file)) {
1111 for (
const SubFrame &frame : frames) {
1113 auto frame_cache = std::make_unique<bake::FrameCache>();
1114 frame_cache->frame = frame;
1115 frame_cache->meta_data_source = meta_file.data();
1116 bake_cache.
frames.append(std::move(frame_cache));
1121 Span{
bake.packed->blob_files,
bake.packed->blob_files_num})
1125 bake_cache.
blob_sharing = std::make_unique<bake::BlobReadSharing>();
1139 auto frame_cache = std::make_unique<bake::FrameCache>();
1140 frame_cache->frame = meta_file.frame;
1141 frame_cache->meta_data_source = meta_file.path;
1142 bake_cache.
frames.append(std::move(frame_cache));
1144 bake_cache.
blobs_dir = bake_path->blobs_dir;
1145 bake_cache.
blob_sharing = std::make_unique<bake::BlobReadSharing>();
1151 static constexpr float max_delta_frames = 1.0f;
1156 const Scene *scene_;
1158 bool use_frame_cache_;
1159 bool depsgraph_is_active_;
1162 bool has_invalid_simulation_ =
false;
1173 : nmd_(nmd), ctx_(ctx)
1175 const Depsgraph *
depsgraph = ctx_.depsgraph;
1182 modifier_cache_ = nmd.
runtime->cache.get();
1183 fps_ = scene->frames_per_second();
1185 if (!modifier_cache_) {
1188 std::lock_guard
lock{modifier_cache_->mutex};
1189 if (depsgraph_is_active_) {
1192 for (std::unique_ptr<bake::SimulationNodeCache> &node_cache :
1193 modifier_cache_->simulation_cache_by_id.values())
1197 if (!node_cache->bake.frames.is_empty()) {
1198 if (node_cache->bake.frames.last()->frame == current_frame_) {
1201 node_cache->bake.frames.pop_last();
1209 for (
const std::unique_ptr<bake::SimulationNodeCache> &node_cache_ptr :
1210 modifier_cache_->simulation_cache_by_id.values())
1214 has_invalid_simulation_ =
true;
1222 for (
auto item : modifier_cache_->simulation_cache_by_id.items()) {
1223 const int id = item.key;
1229 *scene_, *ctx_.object, nmd_,
id);
1230 if (!sim_frame_range.has_value()) {
1233 const SubFrame start_frame{int(sim_frame_range->start())};
1234 if (current_frame_ <= start_frame) {
1238 current_frame_ < node_cache.
bake.
frames.first()->frame)
1247 if (!modifier_cache_) {
1250 std::lock_guard
lock{modifier_cache_->mutex};
1251 return &this->data_by_zone_id
1254 auto data = std::make_unique<DataPerZone>();
1255 data->behavior.data_block_map = &
data->data_block_map;
1257 zone_id,
data->behavior,
data->data_block_map);
1268 *modifier_cache_->simulation_cache_by_id.lookup_or_add_cb(
1269 zone_id, []() {
return std::make_unique<bake::SimulationNodeCache>(); });
1272 *scene_, *ctx_.object, nmd_, zone_id);
1273 const SubFrame sim_start_frame{int(sim_frame_range.
first())};
1274 const SubFrame sim_end_frame{int(sim_frame_range.
last())};
1276 if (!modifier_cache_->requested_bakes.contains(zone_id)) {
1294 data_block_map.
old_mappings.add(data_block, data_block.id);
1304 if (use_frame_cache_) {
1307 if (depsgraph_is_active_) {
1309 if (current_frame_ < sim_start_frame || current_frame_ > sim_end_frame) {
1316 if (current_frame_ > sim_start_frame || has_invalid_simulation_) {
1323 if (frame_indices.
prev && !frame_indices.
current && !frame_indices.
next &&
1324 current_frame_ <= sim_end_frame)
1327 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
1329 const float real_delta_frames =
float(current_frame_) -
float(prev_frame_cache.frame);
1330 if (real_delta_frames != 1) {
1333 const float delta_frames = std::min(max_delta_frames, real_delta_frames);
1334 output_copy_info.delta_time = delta_frames / fps_;
1335 output_copy_info.state = prev_frame_cache.state;
1346 if (node_cache.
prev_cache->frame < current_frame_) {
1348 const float delta_frames = std::min(
1349 max_delta_frames,
float(current_frame_) -
float(node_cache.
prev_cache->frame));
1350 auto &output_move_info = zone_behavior.
input.emplace<sim_input::OutputMove>();
1351 output_move_info.delta_time = delta_frames / fps_;
1352 output_move_info.state = std::move(node_cache.
prev_cache->state);
1356 if (node_cache.
prev_cache->frame == current_frame_) {
1358 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
1359 output_copy_info.delta_time = 0.0f;
1360 output_copy_info.state = node_cache.
prev_cache->state;
1361 auto &read_single_info = zone_behavior.
output.emplace<sim_output::ReadSingle>();
1362 read_single_info.state = node_cache.
prev_cache->state;
1365 if (!depsgraph_is_active_) {
1368 zone_behavior.
input.emplace<sim_input::PassThrough>();
1369 zone_behavior.
output.emplace<sim_output::PassThrough>();
1375 zone_behavior.
input.emplace<sim_input::PassThrough>();
1376 if (depsgraph_is_active_) {
1381 zone_behavior.
output.emplace<sim_output::PassThrough>();
1387 zone_behavior.
input.emplace<sim_input::PassThrough>();
1392 zone_behavior.
output.emplace<sim_output::PassThrough>();
1398 auto &store_new_state_info = zone_behavior.
output.emplace<sim_output::StoreNewState>();
1399 store_new_state_info.store_fn = [simulation_cache = modifier_cache_,
1400 node_cache = &node_cache,
1402 std::lock_guard
lock{simulation_cache->mutex};
1403 auto frame_cache = std::make_unique<bake::FrameCache>();
1404 frame_cache->frame = current_frame;
1405 frame_cache->state = std::move(
state);
1406 node_cache->
bake.
frames.append(std::move(frame_cache));
1413 auto &store_new_state_info = zone_behavior.
output.emplace<sim_output::StoreNewState>();
1414 store_new_state_info.store_fn = [simulation_cache = modifier_cache_,
1415 node_cache = &node_cache,
1417 std::lock_guard
lock{simulation_cache->mutex};
1422 node_cache->
prev_cache->frame = current_frame;
1430 if (frame_indices.
prev) {
1431 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
1433 const float delta_frames = std::min(max_delta_frames,
1434 float(current_frame_) -
float(frame_cache.frame));
1435 output_copy_info.delta_time = delta_frames / fps_;
1436 output_copy_info.state = frame_cache.state;
1439 zone_behavior.
input.emplace<sim_input::PassThrough>();
1444 else if (frame_indices.
next) {
1445 if (frame_indices.
prev) {
1447 *frame_indices.
prev, *frame_indices.
next, node_cache, zone_behavior);
1453 else if (frame_indices.
prev) {
1467 auto &read_single_info = zone_behavior.
output.emplace<sim_output::ReadSingle>();
1468 read_single_info.state = frame_cache.
state;
1472 const int next_frame_index,
1480 auto &read_interpolated_info = zone_behavior.
output.emplace<sim_output::ReadInterpolated>();
1481 read_interpolated_info.mix_factor = (
float(current_frame_) -
float(prev_frame_cache.
frame)) /
1482 (
float(next_frame_cache.
frame) -
1483 float(prev_frame_cache.
frame));
1484 read_interpolated_info.prev_state = prev_frame_cache.
state;
1485 read_interpolated_info.next_state = next_frame_cache.
state;
1496 bool depsgraph_is_active_;
1507 : nmd_(nmd), ctx_(ctx)
1509 const Depsgraph *
depsgraph = ctx_.depsgraph;
1511 modifier_cache_ = nmd.
runtime->cache.get();
1518 if (!modifier_cache_) {
1521 std::lock_guard
lock{modifier_cache_->mutex};
1522 return &this->data_by_node_id
1525 auto data = std::make_unique<DataPerNode>();
1526 data->behavior.data_block_map = &
data->data_block_map;
1527 this->init_bake_behavior(
1528 id,
data->behavior,
data->data_block_map);
1536 void init_bake_behavior(
const int id,
1541 id, []() {
return std::make_unique<bake::BakeNodeCache>(); });
1545 data_block_map.
old_mappings.add(data_block, data_block.id);
1548 if (depsgraph_is_active_) {
1549 if (modifier_cache_->requested_bakes.contains(
id)) {
1551 auto &store_info = behavior.
behavior.emplace<sim_output::StoreNewState>();
1552 store_info.store_fn = [modifier_cache = modifier_cache_,
1553 node_cache = &node_cache,
1554 current_frame = current_frame_](bake::BakeState
state) {
1555 std::lock_guard
lock{modifier_cache->mutex};
1556 auto frame_cache = std::make_unique<bake::FrameCache>();
1557 frame_cache->frame = current_frame;
1558 frame_cache->state = std::move(
state);
1559 auto &frames = node_cache->bake.frames;
1561 frames, [&](
const std::unique_ptr<bake::FrameCache> &frame_cache) {
1562 return frame_cache->frame > current_frame;
1564 frames.insert(insert_index, std::move(frame_cache));
1571 if (node_cache.bake.frames.is_empty()) {
1572 if (!node_cache.bake.failed_finding_bake) {
1574 node_cache.bake.failed_finding_bake =
true;
1579 if (node_cache.bake.frames.is_empty()) {
1580 behavior.
behavior.emplace<sim_output::PassThrough>();
1586 this->read_single(*frame_indices.
current, node_cache, behavior);
1589 if (frame_indices.
prev && frame_indices.
next) {
1590 this->read_interpolated(*frame_indices.
prev, *frame_indices.
next, node_cache, behavior);
1593 if (frame_indices.
prev) {
1594 this->read_single(*frame_indices.
prev, node_cache, behavior);
1597 if (frame_indices.
next) {
1598 this->read_single(*frame_indices.
next, node_cache, behavior);
1604 void read_single(
const int frame_index,
1605 bake::BakeNodeCache &node_cache,
1606 nodes::BakeNodeBehavior &behavior)
const
1608 bake::FrameCache &frame_cache = *node_cache.
bake.
frames[frame_index];
1610 if (this->check_read_error(frame_cache, behavior)) {
1613 auto &read_single_info = behavior.
behavior.emplace<sim_output::ReadSingle>();
1614 read_single_info.state = frame_cache.
state;
1617 void read_interpolated(
const int prev_frame_index,
1618 const int next_frame_index,
1619 bake::BakeNodeCache &node_cache,
1620 nodes::BakeNodeBehavior &behavior)
const
1622 bake::FrameCache &prev_frame_cache = *node_cache.
bake.
frames[prev_frame_index];
1623 bake::FrameCache &next_frame_cache = *node_cache.
bake.
frames[next_frame_index];
1626 if (this->check_read_error(prev_frame_cache, behavior) ||
1627 this->check_read_error(next_frame_cache, behavior))
1631 auto &read_interpolated_info = behavior.
behavior.emplace<sim_output::ReadInterpolated>();
1632 read_interpolated_info.mix_factor = (
float(current_frame_) -
float(prev_frame_cache.
frame)) /
1633 (
float(next_frame_cache.
frame) -
1634 float(prev_frame_cache.
frame));
1635 read_interpolated_info.prev_state = prev_frame_cache.
state;
1636 read_interpolated_info.next_state = next_frame_cache.
state;
1639 [[nodiscard]]
bool check_read_error(
const bake::FrameCache &frame_cache,
1640 nodes::BakeNodeBehavior &behavior)
const
1643 auto &read_error_info = behavior.
behavior.emplace<sim_output::ReadError>();
1644 read_error_info.message =
RPT_(
"Cannot load the baked data");
1656 const int old_num =
bake.data_blocks_num;
1657 const int new_num = old_num + missing.
size();
1669 ID *
id = get_data_block(key);
1674 bake.data_blocks_num = new_num;
1701 struct DataPerBake {
1702 bool reset_first =
false;
1709 if (item.value->data_block_map.old_mappings.size() <
bake.data_blocks_num) {
1710 data.reset_first =
true;
1716 if (!node_cache->
bake.
frames.is_empty() || node_cache->prev_cache.has_value()) {
1717 data.new_mappings = std::move(item.value->data_block_map.new_mappings);
1720 if (
data.reset_first || !
data.new_mappings.is_empty()) {
1721 writeback_data.
add(item.key, std::move(
data));
1729 data.new_mappings = std::move(item.value->data_block_map.new_mappings);
1730 writeback_data.
add(item.key, std::move(
data));
1742 [object_eval = ctx.
object,
1746 writeback_data = std::move(writeback_data)]() {
1747 for (auto item : writeback_data.items()) {
1748 const int bake_id = item.key;
1749 DataPerBake data = item.value;
1751 NodesModifierBake &bake_orig = *nmd_orig.find_bake(bake_id);
1752 NodesModifierBake &bake_eval = *nmd_eval.find_bake(bake_id);
1754 if (data.reset_first) {
1756 dna::array::clear<NodesModifierDataBlock>(&bake_orig.data_blocks,
1757 &bake_orig.data_blocks_num,
1758 &bake_orig.active_data_block,
1759 [](NodesModifierDataBlock *data_block) {
1760 nodes_modifier_data_block_destruct(
1764 dna::array::clear<NodesModifierDataBlock>(&bake_eval.data_blocks,
1765 &bake_eval.data_blocks_num,
1766 &bake_eval.active_data_block,
1767 [](NodesModifierDataBlock *data_block) {
1768 nodes_modifier_data_block_destruct(
1773 Vector<bake::BakeDataBlockID> sorted_new_mappings;
1774 sorted_new_mappings.extend(data.new_mappings.keys().begin(),
1775 data.new_mappings.keys().end());
1776 bool needs_reevaluation = false;
1779 add_missing_data_block_mappings(
1780 bake_orig, sorted_new_mappings, [&](const bake::BakeDataBlockID &key) -> ID * {
1781 ID *id_orig = nullptr;
1782 if (ID *id_eval = data.new_mappings.lookup_default(key, nullptr)) {
1783 id_orig = DEG_get_original(id_eval);
1786 needs_reevaluation = true;
1787 id_orig = BKE_libblock_find_name_and_library(
1788 bmain, short(key.type), key.id_name.c_str(), key.lib_name.c_str());
1791 id_us_plus(id_orig);
1799 add_missing_data_block_mappings(
1800 bake_eval, sorted_new_mappings, [&](const bake::BakeDataBlockID &key) -> ID * {
1801 return data.new_mappings.lookup_default(key, nullptr);
1804 if (needs_reevaluation) {
1805 Object *object_orig = DEG_get_original(object_eval);
1806 DEG_id_tag_update(&object_orig->id, ID_RECALC_GEOMETRY);
1807 DEG_relations_tag_update(bmain);
1831 tree.ensure_topology_cache();
1832 const bNode *output_node =
tree.group_output_node();
1833 if (output_node ==
nullptr) {
1835 geometry_set.
clear();
1842 geometry_set.
clear();
1846 const bNodeSocket *first_output_socket = group_outputs[0];
1847 if (!
STREQ(first_output_socket->
idname,
"NodeSocketGeometry")) {
1849 geometry_set.
clear();
1855 if (lf_graph_info ==
nullptr) {
1857 geometry_set.
clear();
1861 bool use_orig_index_verts =
false;
1862 bool use_orig_index_edges =
false;
1863 bool use_orig_index_faces =
false;
1875 auto eval_log = std::make_unique<geo_log::GeoNodesLog>();
1885 call_data.
eval_log = eval_log.get();
1899 modifier_compute_context,
1901 std::move(geometry_set));
1904 nmd_orig->
runtime->eval_log = std::move(eval_log);
1911 if (use_orig_index_verts || use_orig_index_edges || use_orig_index_faces) {
1916 if (use_orig_index_verts) {
1919 if (use_orig_index_edges) {
1922 if (use_orig_index_faces) {
1937 if (mesh_component.
get() != mesh) {
1944 if (new_mesh ==
nullptr) {
1968 tree.ensure_interface_cache();
1969 tree.ensure_topology_cache();
1976 XXH3_state_t *
state = XXH3_createState();
1977 XXH3_64bits_reset(
state);
1981 XXH3_64bits_update(
state, &input_i,
sizeof(input_i));
1985 const CPPType &base_type = *io_socket.socket_typeinfo()->base_cpp_type;
1987 XXH3_64bits_update(
state, &value_hash,
sizeof(value_hash));
1990 const uint64_t new_input_values_hash = XXH3_64bits_digest(
state);
1991 if (new_input_values_hash == input_values_hash_) {
1992 if (this->
inputs.size() ==
tree.interface_inputs().size() &&
1993 this->outputs.size() ==
tree.interface_outputs().size())
2000 this->
inputs.reinitialize(
tree.interface_inputs().size());
2001 this->
outputs.reinitialize(
tree.interface_outputs().size());
2004 input_values_hash_ = new_input_values_hash;
2009 input_values_hash_ = 0;
2046 prop->ui_data =
nullptr;
2073 if (bake_file.packed_file) {
2078 Span{
bake.packed->meta_files,
bake.packed->meta_files_num})
2080 write_bake_file(meta_file);
2083 Span{
bake.packed->blob_files,
bake.packed->blob_files_num})
2085 write_bake_file(blob_file);
2148 if (bake_file.packed_file) {
2155 read_bake_file(meta_file);
2160 read_bake_file(blob_file);
2166 nmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
2167 nmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
2181 if (
bake.directory) {
2184 if (
bake.data_blocks) {
2199 const int bake_files_num) {
2206 if (bake_file.packed_file) {
2211 copy_bake_files_inplace(&
bake.packed->meta_files,
bake.packed->meta_files_num);
2212 copy_bake_files_inplace(&
bake.packed->blob_files,
bake.packed->blob_files_num);
2221 tnmd->
runtime = MEM_new<NodesModifierRuntime>(__func__);
2230 tnmd->
runtime->cache = std::make_shared<bake::ModifierCache>();
2245 if (file.packed_file) {
2302 N_(
"GeometryNodes"),
2303 "NodesModifierData",
2311 ICON_GEOMETRY_NODES,
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_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
#define IDP_BlendDataRead(reader, prop)
void IDP_FreeProperty(IDProperty *prop)
IDProperty * IDP_GetPropertyFromGroup_null(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT
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)
@ 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(*)(void *user_data, Object *ob, ID **idpoin, LibraryForeachIDCallbackFlag cb_flag) IDWalkFunc
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsCVs
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
void(*)(void *user_data, Object *ob, ModifierData *md, const PointerRNA *ptr, PropertyRNA *texture_prop) TexWalkFunc
#define GEO_NODE_SIMULATION_OUTPUT
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 LISTBASE_FOREACH(type, var, list)
#define BLI_SCOPED_DEFER(function_to_defer)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
#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)
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)
bool DEG_is_evaluated(const T *id)
Main * DEG_get_bmain(const Depsgraph *graph)
T * DEG_get_original(T *id)
Scene * DEG_get_input_scene(const Depsgraph *graph)
ID * DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
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
@ NODES_MODIFIER_PANEL_OPEN
struct NodesModifierBake NodesModifierBake
@ NODES_MODIFIER_BAKE_MODE_STILL
@ NODES_MODIFIER_BAKE_MODE_ANIMATION
@ NODE_INTERFACE_PANEL_DEFAULT_CLOSED
Object is a sort of wrapper for general info.
@ OB_FLAG_USE_SIMULATION_CACHE
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
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
BMesh const char void * data
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
void reset()
clear internal cached data and reset random seed
SubIterator begin() const
ValueIterator values() const &
bool contains(const Key &key) const
uint64_t hash_or_fallback(const void *value, uint64_t fallback_hash) const
const ComputeContext * parent() const
const ComputeContextHash & hash() const
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
const Value * lookup_ptr(const Key &key) const
bool add_overwrite(const Key &key, const Value &value)
ValueIterator values() const &
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
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
void add_new(const Key &key, const Value &value)
KeyIterator keys() 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
NodesModifierBakeParams(NodesModifierData &nmd, const ModifierEvalContext &ctx)
Map< int, std::unique_ptr< DataPerNode > > data_by_node_id
nodes::BakeNodeBehavior * get(const int id) const override
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
Array< nodes::socket_usage_inference::SocketUsage > outputs
Array< nodes::socket_usage_inference::SocketUsage > inputs
void ensure(const NodesModifierData &nmd)
bool contains(const Key &key) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void extend(Span< T > array)
Span< T > as_span() const
const ModifierComputeContext & for_modifier(const ComputeContext *parent, const NodesModifierData &nmd)
const GroupNodeComputeContext & for_group_node(const ComputeContext *parent, int32_t node_id, const bNodeTree *tree=nullptr)
void ensure_owns_direct_data() override
bNodeTreeZone * parent_zone
const bNode * output_node() const
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
bool is_primitive_value() const
const void * get_primitive_ptr() const
static Map< const bke::bNodeTreeZone *, ComputeContextHash > get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, bke::ComputeContextCache &compute_context_cache)
static void update_depsgraph(tGraphSliderOp *gso)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
static int64_t first_if(Iterator begin, Iterator end, Predicate &&predicate)
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)
std::optional< BakeState > deserialize_bake(std::istream &stream, const BlobReader &blob_reader, const BlobReadSharing &blob_sharing)
std::optional< SubFrame > file_name_to_frame(StringRef file_name)
Vector< MetaFile > find_sorted_meta_files(StringRefNull meta_dir)
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRef prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
void add(Depsgraph &depsgraph, std::function< void()> fn)
bool node_editor_is_for_geometry_nodes_modifier(const SpaceNode &snode, const Object &object, const NodesModifierData &nmd)
std::optional< ViewerPathForGeometryNodesViewer > parse_geometry_nodes_viewer(const ViewerPath &viewer_path)
const ComputeContext * compute_context_for_viewer_path_elem(const ViewerPathElem &elem, bke::ComputeContextCache &compute_context_cache, const ComputeContext *parent_compute_context)
void foreach_active_gizmo_in_modifier(const Object &object, const NodesModifierData &nmd, const wmWindowManager &wm, bke::ComputeContextCache &compute_context_cache, 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)
void infer_group_interface_usage(const bNodeTree &group, const Span< InferenceValue > group_input_values, const MutableSpan< SocketUsage > r_input_usages, const std::optional< MutableSpan< SocketUsage > > r_output_usages)
void update_input_properties_from_node_tree(const bNodeTree &tree, const IDProperty *old_properties, IDProperty &properties, const bool use_name_for_ids)
bool id_property_type_matches_socket(const bNodeTreeInterfaceSocket &socket, const IDProperty &property, const bool use_name_for_ids)
bke::GeometrySet execute_geometry_nodes_on_geometry(const bNodeTree &btree, const IDProperty *properties, const ComputeContext &base_compute_context, GeoNodesCallData &call_data, bke::GeometrySet input_geometry)
void draw_geometry_nodes_modifier_ui(const bContext &C, PointerRNA *modifier_ptr, uiLayout &layout)
const GeometryNodesLazyFunctionGraphInfo * ensure_geometry_nodes_lazy_function_graph(const bNodeTree &btree)
void update_output_properties_from_node_tree(const bNodeTree &tree, const IDProperty *old_properties, IDProperty &properties)
Vector< InferenceValue > get_geometry_nodes_input_inference_values(const bNodeTree &btree, const IDProperty *properties, ResourceScope &scope)
GeometryNodesEvalDependencies gather_geometry_nodes_eval_dependencies_recursive(const bNodeTree &ntree)
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 blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static void find_dependencies_from_settings(const NodesModifierSettings &settings, nodes::GeometryNodesEvalDependencies &deps)
static void init_data(ModifierData *md)
static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Object &object, const nodes::GeometryNodesEvalDependencies::ObjectDependencyInfo &info)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void panel_draw(const bContext *C, Panel *panel)
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 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 try_add_side_effect_node(const ModifierEvalContext &ctx, const ComputeContext &final_compute_context, const int final_node_id, const NodesModifierData &nmd, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
void nodes_modifier_data_block_destruct(NodesModifierDataBlock *data_block, const bool do_id_user)
void nodes_modifier_bake_destruct(NodesModifierBake *bake, const bool do_id_user)
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 Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
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 check_property_socket_sync(const Object *ob, const IDProperty *properties, ModifierData *md)
static void remove_outdated_bake_caches(NodesModifierData &nmd)
static void ensure_bake_loaded(bake::NodeBakeCache &bake_cache, bake::FrameCache &frame_cache)
static void find_side_effect_nodes_for_nested_node(const ModifierEvalContext &ctx, const NodesModifierData &nmd, const int root_nested_node_id, nodes::GeoNodesSideEffectNodes &r_side_effect_nodes)
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 update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
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 bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
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 update_panels_from_node_group(NodesModifierData &nmd)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
uint16_t layout_panel_open_flag
NodesModifierDataBlock * data_blocks
NodesModifierPackedBake * packed
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
SpreadsheetTableIDGeometry geometry_id
bNodeTreeRuntimeHandle * runtime
bNodeTreeInterface tree_interface
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)
static GeometrySet from_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
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
const Set< ComputeContextHash > * socket_log_contexts
GeoNodesBakeParams * bake_params
geo_eval_log::GeoNodesLog * eval_log
const GeoNodesSideEffectNodes * side_effect_nodes
const Object * self_object
MultiValueMap< std::pair< ComputeContextHash, int32_t >, int > iterations_by_iteration_zone
MultiValueMap< ComputeContextHash, const lf::FunctionNode * > nodes_by_context
Map< uint32_t, ObjectDependencyInfo > objects_info
void add_generic_id_full(ID *id)
bool needs_scene_render_params
void add_object(Object *object, const ObjectDependencyInfo &object_deps=all_object_deps)
Map< uint32_t, ID * > ids
sim_output::Behavior output
sim_input::Behavior input