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;
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);
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); };
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;
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);
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)
947 if (type &&
GS(id->
name) != *type) {
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)
1123 const Depsgraph *
depsgraph = ctx_.depsgraph;
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 :
1141 modifier_cache_->simulation_cache_by_id.values())
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 :
1158 modifier_cache_->simulation_cache_by_id.values())
1162 has_invalid_simulation_ =
true;
1170 for (
auto item : modifier_cache_->simulation_cache_by_id.items()) {
1171 const int id = item.key;
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);
1216 *modifier_cache_->simulation_cache_by_id.lookup_or_add_cb(
1217 zone_id, []() {
return std::make_unique<bake::SimulationNodeCache>(); });
1220 *scene_, *ctx_.object, nmd_, zone_id);
1224 if (!modifier_cache_->requested_bakes.contains(zone_id)) {
1242 data_block_map.
old_mappings.add(data_block, data_block.id);
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)
1275 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
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));
1298 auto &output_move_info = zone_behavior.
input.emplace<sim_input::OutputMove>();
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_) {
1306 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
1307 output_copy_info.delta_time = 0.0f;
1308 output_copy_info.state = node_cache.
prev_cache->state;
1309 auto &read_single_info = zone_behavior.
output.emplace<sim_output::ReadSingle>();
1310 read_single_info.state = node_cache.
prev_cache->state;
1313 if (!depsgraph_is_active_) {
1316 zone_behavior.
input.emplace<sim_input::PassThrough>();
1317 zone_behavior.
output.emplace<sim_output::PassThrough>();
1323 zone_behavior.
input.emplace<sim_input::PassThrough>();
1324 if (depsgraph_is_active_) {
1329 zone_behavior.
output.emplace<sim_output::PassThrough>();
1335 zone_behavior.
input.emplace<sim_input::PassThrough>();
1340 zone_behavior.
output.emplace<sim_output::PassThrough>();
1346 auto &store_new_state_info = zone_behavior.
output.emplace<sim_output::StoreNewState>();
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));
1361 auto &store_new_state_info = zone_behavior.
output.emplace<sim_output::StoreNewState>();
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) {
1379 auto &output_copy_info = zone_behavior.
input.emplace<sim_input::OutputCopy>();
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;
1387 zone_behavior.
input.emplace<sim_input::PassThrough>();
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) {
1415 auto &read_single_info = zone_behavior.
output.emplace<sim_output::ReadSingle>();
1416 read_single_info.state = frame_cache.
state;
1420 const int next_frame_index,
1428 auto &read_interpolated_info = zone_behavior.
output.emplace<sim_output::ReadInterpolated>();
1429 read_interpolated_info.mix_factor = (
float(current_frame_) -
float(prev_frame_cache.
frame)) /
1430 (
float(next_frame_cache.
frame) -
1431 float(prev_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)
1457 const Depsgraph *
depsgraph = ctx_.depsgraph;
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_) {
1497 if (modifier_cache_->requested_bakes.contains(
id)) {
1499 auto &store_info = behavior.
behavior.emplace<sim_output::StoreNewState>();
1500 store_info.store_fn = [modifier_cache = modifier_cache_,
1501 node_cache = &node_cache,
1502 current_frame = current_frame_](bake::BakeState
state) {
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()) {
1528 behavior.
behavior.emplace<sim_output::PassThrough>();
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,
1553 bake::BakeNodeCache &node_cache,
1554 nodes::BakeNodeBehavior &behavior)
const
1556 bake::FrameCache &frame_cache = *node_cache.
bake.
frames[frame_index];
1558 if (this->check_read_error(frame_cache, behavior)) {
1561 auto &read_single_info = behavior.
behavior.emplace<sim_output::ReadSingle>();
1562 read_single_info.state = frame_cache.
state;
1565 void read_interpolated(
const int prev_frame_index,
1566 const int next_frame_index,
1567 bake::BakeNodeCache &node_cache,
1568 nodes::BakeNodeBehavior &behavior)
const
1570 bake::FrameCache &prev_frame_cache = *node_cache.
bake.
frames[prev_frame_index];
1571 bake::FrameCache &next_frame_cache = *node_cache.
bake.
frames[next_frame_index];
1574 if (this->check_read_error(prev_frame_cache, behavior) ||
1575 this->check_read_error(next_frame_cache, behavior))
1579 auto &read_interpolated_info = behavior.
behavior.emplace<sim_output::ReadInterpolated>();
1580 read_interpolated_info.mix_factor = (
float(current_frame_) -
float(prev_frame_cache.
frame)) /
1581 (
float(next_frame_cache.
frame) -
1582 float(prev_frame_cache.
frame));
1583 read_interpolated_info.prev_state = prev_frame_cache.
state;
1584 read_interpolated_info.next_state = next_frame_cache.
state;
1587 [[nodiscard]]
bool check_read_error(
const bake::FrameCache &frame_cache,
1588 nodes::BakeNodeBehavior &behavior)
const
1591 auto &read_error_info = behavior.
behavior.emplace<sim_output::ReadError>();
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();
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;
1820 auto eval_log = std::make_unique<geo_log::GeoModifierLog>();
1830 call_data.
eval_log = eval_log.get();
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) {
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) {
1994 if (item_v ==
nullptr) {
2000 if (nmd ==
nullptr) {
2004 const std::string attribute_prop_name =
data.socket_identifier +
2007 attribute_prop_name.c_str());
2019 const bool is_output)
2037 rna_path_attribute_name.
c_str(),
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);
2070 if (!access_allowed) {
2086 const std::string rna_path =
"[\"" + std::string(socket_id_esc) +
"\"]";
2087 const std::string rna_path_attribute_name =
"[\"" + std::string(socket_id_esc) +
2100 uiItemL(name_row,
"", ICON_NONE);
2112 if (attribute_name) {
2114 uiItemL(layout,
"", ICON_BLANK1);
2124 "object.geometry_nodes_input_attribute_toggle",
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);
2212 uiItemL(row,
"", ICON_BLANK1);
2225 const std::string rna_path_attribute_name =
"[\"" +
StringRef(socket_id_esc) +
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) {
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;
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);
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
#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 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
@ NODES_MODIFIER_PANEL_OPEN
@ NODES_MODIFIER_HIDE_DATABLOCK_SELECTOR
struct NodesModifierBake NodesModifierBake
@ 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)
static void split(const char *text, const char *seps, char ***str, int *count)
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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
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)
BPy_StructRNA * depsgraph
SubIterator begin() const
bool contains(const Key &key) const
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
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
static Map< const bke::bNodeTreeZone *, ComputeContextHash > get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name)
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
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)
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)
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRefNull prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
bool allow_procedural_attribute_access(StringRef attribute_name)
void add(Depsgraph &depsgraph, std::function< void()> fn)
Object * context_object(const bContext *C)
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)
StringRef input_attribute_name_suffix()
void update_input_properties_from_node_tree(const bNodeTree &tree, const IDProperty *old_properties, IDProperty &properties, const bool use_name_for_ids)
bool input_has_attribute_toggle(const bNodeTree &node_tree, const int socket_index)
void find_node_tree_dependencies(const bNodeTree &tree, Set< ID * > &r_ids, bool &r_needs_own_transform_relation, bool &r_needs_scene_camera_relation)
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)
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)
bool socket_type_has_attribute_toggle(const eNodeSocketDatatype type)
std::optional< StringRef > input_attribute_name_get(const IDProperty &props, const bNodeTreeInterfaceSocket &io_input)
void attribute_search_add_items(StringRefNull str, bool can_create_attribute, Span< const nodes::geo_eval_log::GeometryAttributeInfo * > infos, uiSearchItems *items, bool is_first)
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 panel_draw(const bContext *C, Panel *panel)
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
char modifier_name[MAX_NAME]
char socket_identifier[MAX_NAME]
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)
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
geo_eval_log::GeoModifierLog * eval_log
const Set< ComputeContextHash > * socket_log_contexts
GeoNodesBakeParams * bake_params
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
sim_output::Behavior output
sim_input::Behavior input