32#include "RNA_prototypes.hh"
50 b.use_custom_socket_order();
51 b.allow_any_socket_order();
54 const bNode *node =
b.node_or_null();
65 auto &input_decl =
b.add_input(socket_type, name, identifier)
68 auto &output_decl =
b.add_output(socket_type, name, identifier).align_with_previous();
70 input_decl.supports_field();
72 output_decl.field_source();
75 output_decl.dependent_field({input_decl.index()});
80 b.add_output<
decl::Extend>(
"",
"__extend__").align_with_previous();
87 data->items = MEM_cnew_array<NodeGeometryBakeItem>(1, __func__);
108 auto *dst_storage = MEM_cnew<NodeGeometryBake>(__func__, src_storage);
109 dst_node->
storage = dst_storage;
117 *ntree, *node, *node, *link);
150 static const uiListType *bake_items_list = []() {
151 uiListType *list = MEM_cnew<uiListType>(__func__);
181 uiItemO(add_remove_col,
"", ICON_ADD,
"node.bake_node_item_add");
182 uiItemO(add_remove_col,
"", ICON_REMOVE,
"node.bake_node_item_remove");
186 uiItemEnumO(up_down_col,
"node.bake_node_item_move",
"", ICON_TRIA_UP,
"direction", 0);
187 uiItemEnumO(up_down_col,
"node.bake_node_item_move",
"", ICON_TRIA_DOWN,
"direction", 1);
210 ot,
"Remove Bake Item", __func__,
"Remove active bake item");
221 ot,
"Move Bake Item", __func__,
"Move active bake item");
234 const int items_num = bake_items.
size();
240 int last_geometry_index = -1;
241 for (
const int item_i : bake_items.
index_range()) {
247 last_geometry_index = item_i;
249 else if (last_geometry_index != -1) {
268 std::lock_guard
lock{mutex_};
269 return map_.lookup_default(key,
nullptr);
274 std::lock_guard
lock{mutex_};
294 for (
const int i : bake_items_.index_range()) {
296 const bNodeSocket &input_bsocket = node.input_socket(i);
297 const bNodeSocket &output_bsocket = node.output_socket(i);
299 lf_index_by_bsocket[input_bsocket.index_in_tree()] =
inputs_.append_and_get_index_as(
301 lf_index_by_bsocket[output_bsocket.index_in_tree()] =
outputs_.append_and_get_index_as(
312 context.local_user_data);
322 std::optional<FoundNestedNodeID> found_id =
find_nested_node_id(user_data, node_.identifier);
327 if (found_id->is_in_loop) {
337 if (
auto *info = std::get_if<sim_output::ReadSingle>(&behavior->
behavior)) {
340 else if (
auto *info = std::get_if<sim_output::ReadInterpolated>(&behavior->
behavior)) {
349 else if (std::get_if<sim_output::PassThrough>(&behavior->
behavior)) {
352 else if (
auto *info = std::get_if<sim_output::StoreNewState>(&behavior->
behavior)) {
355 else if (
auto *info = std::get_if<sim_output::ReadError>(&behavior->
behavior)) {
359 tree_logger->node_warnings.append(
360 *tree_logger->allocator, {node_.identifier, {NodeWarningType::Error, info->message}});
385 for (
const int i : bake_items_.index_range()) {
386 output_values[i] =
params.get_output_data_ptr(i);
393 for (
const int i : bake_items_.index_range()) {
410 info.
store_fn(std::move(*bake_state));
419 for (
const int i : bake_items_.index_range()) {
420 output_values[i] =
params.get_output_data_ptr(i);
427 for (
const int i : bake_items_.index_range()) {
434 const Object &self_object,
438 const float mix_factor)
const
441 for (
const int i : bake_items_.index_range()) {
442 output_values[i] =
params.get_output_data_ptr(i);
445 prev_state, data_block_map, self_object, compute_context, output_values);
449 for (
const int i : bake_items_.index_range()) {
454 next_state, data_block_map, self_object, compute_context, next_values);
456 for (
const int i : bake_items_.index_range()) {
463 for (
const int i : bake_items_.index_range()) {
468 for (
const int i : bake_items_.index_range()) {
477 for (
const int i : bake_items_.index_range()) {
478 input_values[i] =
params.try_get_input_data_ptr_or_request(i);
480 if (input_values.
as_span().contains(
nullptr)) {
486 input_values, bake_socket_config_, data_block_map);
489 for (
const int i : bake_items_.index_range()) {
491 std::unique_ptr<bake::BakeItem> &bake_item = bake_items[i];
501 const Object &self_object,
507 std::unique_ptr<bake::BakeItem> *bake_item = bake_state.
items_by_id.lookup_ptr(
509 bake_items.
append(bake_item ? bake_item->get() :
nullptr);
515 [&](
const int i,
const CPPType &type) {
523 const Object &self_object,
530 bake_items.
append(bake_item ? *bake_item :
nullptr);
536 [&](
const int i,
const CPPType &type) {
550 node_.label_or_name(), item.
name);
551 return std::make_shared<AttributeFieldInput>(
552 std::move(attribute_name), type, std::move(socket_inspection_name));
565 params.rows.append(std::move(row));
610 uiItemL(row, bake_state_str->c_str(), ICON_NONE);
624 params.connect_available_socket(node,
"Geometry");
635 node, type,
params.socket.name);
636 params.update_and_connect_available_socket(node,
params.socket.name);
671 std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
673 if (!object_and_modifier) {
676 r_ctx.
object = object_and_modifier->object;
677 r_ctx.
nmd = object_and_modifier->nmd;
683 r_ctx.
bake =
nullptr;
685 if (iter_bake.id == *bake_id) {
686 r_ctx.
bake = &iter_bake;
695 const_cast<ID *
>(&r_ctx.
object->
id), &RNA_NodesModifierBake, (
void *)r_ctx.
bake);
699 if (
const std::unique_ptr<bke::bake::BakeNodeCache> *node_cache_ptr =
704 const int first_frame = node_cache.
bake.
frames.first()->frame.frame();
705 const int last_frame = node_cache.
bake.
frames.last()->frame.frame();
709 else if (
const std::unique_ptr<bke::bake::SimulationNodeCache> *node_cache_ptr =
716 const int first_frame = node_cache.
bake.
frames.first()->frame.frame();
717 const int last_frame = node_cache.
bake.
frames.last()->frame.frame();
743 if (
G.is_rendering) {
752 return fmt::format(
RPT_(
"{} ({} packed)"), baked_str, size_str);
754 return fmt::format(
RPT_(
"{} ({} on disk)"), baked_str, size_str);
770 const char *bake_label =
IFACE_(
"Bake");
778 "OBJECT_OT_geometry_node_bake_single",
797 "OBJECT_OT_geometry_node_bake_unpack_single",
811 "OBJECT_OT_geometry_node_bake_pack_single",
829 "OBJECT_OT_geometry_node_bake_pack_single",
841 "OBJECT_OT_geometry_node_bake_delete_single",
875 char placeholder_path[
FILE_MAX] =
"";
878 bake_path->bake_dir.has_value())
880 STRNCPY(placeholder_path, bake_path->bake_dir->c_str());
900 "use_custom_simulation_frame_range",
927 name = data_block.id_name;
930 name = fmt::format(
"{} [{}]", data_block.id_name, data_block.lib_name);
938 static const uiListType *data_block_list = []() {
939 uiListType *list = MEM_cnew<uiListType>(__func__);
947 bake_rna.
owner_id, &RNA_NodesModifierBakeDataBlocks, bake_rna.
data);
950 C, layout,
"data_block_references",
true,
TIP_(
"Data-Block References")))
974 return std::make_unique<file_ns::LazyFunctionForBakeNode>(node, lf_graph_info);
SpaceNode * CTX_wm_space_node(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_SIMULATION_OUTPUT
#define BLI_assert_unreachable()
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
#define STRNCPY(dst, src)
#define BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE
void BLI_str_format_byte_unit(char dst[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE], long long int bytes, bool base_10) ATTR_NONNULL(1)
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 ID_IS_EDITABLE(_id)
@ NODES_MODIFIER_BAKE_TARGET_DISK
@ NODES_MODIFIER_BAKE_CUSTOM_PATH
@ NODES_MODIFIER_BAKE_CUSTOM_SIMULATION_FRAME_RANGE
@ NODES_MODIFIER_BAKE_MODE_STILL
@ GEO_NODE_BAKE_ITEM_IS_ATTRIBUTE
#define NOD_REGISTER_NODE(REGISTER_FUNC)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
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)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, const char *name, int icon, const char *placeholder=nullptr)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value)
void uiTemplateList(uiLayout *layout, const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
PanelLayout uiLayoutPanel(const bContext *C, uiLayout *layout, const char *idname, bool default_closed)
void uiTemplateNodeSocket(uiLayout *layout, bContext *C, const float color[4])
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
@ UI_TEMPLATE_LIST_FLAG_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
void resize(const int64_t new_size)
Span< T > as_span() const
void destruct(void *ptr) const
int64_t alignment() const
const ComputeContextHash & hash() const
void * allocate(const int64_t size, const int64_t alignment)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void append(const T &value)
void resize(const int64_t new_size)
Vector< Output > outputs_
virtual BakeNodeBehavior * get(const int id) const =0
void set_default_outputs(lf::Params ¶ms) const
void output_mixed_cached_state(lf::Params ¶ms, bke::bake::BakeDataBlockMap *data_block_map, const Object &self_object, const ComputeContext &compute_context, const bake::BakeStateRef &prev_state, const bake::BakeStateRef &next_state, const float mix_factor) const
void copy_bake_state_to_values(const bake::BakeStateRef &bake_state, bke::bake::BakeDataBlockMap *data_block_map, const Object &self_object, const ComputeContext &compute_context, Span< void * > r_output_values) const
LazyFunctionForBakeNode(const bNode &node, GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
void move_bake_state_to_values(bake::BakeState bake_state, bke::bake::BakeDataBlockMap *data_block_map, const Object &self_object, const ComputeContext &compute_context, Span< void * > r_output_values) const
std::shared_ptr< AttributeFieldInput > make_attribute_field(const Object &self_object, const ComputeContext &compute_context, const NodeGeometryBakeItem &item, const CPPType &type) const
void execute_impl(lf::Params ¶ms, const lf::Context &context) const final
void pass_through(lf::Params ¶ms, GeoNodesLFUserData &user_data, bke::bake::BakeDataBlockMap *data_block_map) const
void store(lf::Params ¶ms, GeoNodesLFUserData &user_data, bke::bake::BakeDataBlockMap *data_block_map, const sim_output::StoreNewState &info) const
std::optional< bake::BakeState > get_bake_state_from_inputs(lf::Params ¶ms, bke::bake::BakeDataBlockMap *data_block_map) const
void output_cached_state(lf::Params ¶ms, GeoNodesLFUserData &user_data, bke::bake::BakeDataBlockMap *data_block_map, const bake::BakeStateRef &bake_state) const
local_group_size(16, 16) .push_constant(Type b
void MEM_freeN(void *vmemh)
std::optional< NodesModifierBakeTarget > get_node_bake_target(const Object &object, const NodesModifierData &nmd, int node_id)
Array< std::unique_ptr< BakeItem > > move_socket_values_to_bake_items(Span< void * > socket_values, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map)
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)
void copy_bake_items_to_socket_values(Span< const BakeItem * > bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, FunctionRef< std::shared_ptr< AttributeFieldInput >(int, const CPPType &)> make_attribute_field, Span< void * > r_socket_values)
void move_bake_items_to_socket_values(Span< BakeItem * > bake_items, const BakeSocketConfig &config, BakeDataBlockMap *data_block_map, FunctionRef< std::shared_ptr< AttributeFieldInput >(int socket_index, const CPPType &)> make_attribute_field, Span< void * > r_socket_values)
bNodeSocketType * node_socket_type_find(const char *idname)
const char * node_static_socket_type(int type, int subtype)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
std::string hash_to_anonymous_attribute_name(Args &&...args)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
std::optional< int32_t > find_nested_node_id_in_root(const SpaceNode &snode, const bNode &node)
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_register()
static void node_layout(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void draw_bake_item(uiList *, const bContext *C, uiLayout *layout, PointerRNA *, PointerRNA *itemptr, int, PointerRNA *, const char *, int, int)
static bool node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link)
static void draw_bake_items(const bContext *C, uiLayout *layout, PointerRNA node_ptr)
static const CPPType & get_item_cpp_type(const eNodeSocketDatatype socket_type)
static void NODE_OT_bake_node_item_remove(wmOperatorType *ot)
static bake::BakeSocketConfig make_bake_socket_config(const Span< NodeGeometryBakeItem > bake_items)
static void node_extra_info(NodeExtraInfoParams ¶ms)
static void NODE_OT_bake_node_item_add(wmOperatorType *ot)
static void NODE_OT_bake_node_item_move(wmOperatorType *ot)
static void node_free_storage(bNode *node)
static void node_operators()
static void node_copy_storage(bNodeTree *, bNode *dst_node, const bNode *src_node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_init(bNodeTree *, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
void move_active_item(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void remove_active_item(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void add_item(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void destruct_array(bNode &node)
void copy_array(const bNode &src_node, bNode &dst_node)
Accessor::ItemT * add_item_with_socket_type_and_name(bNode &node, const eNodeSocketDatatype socket_type, const char *name)
bool try_add_item_via_any_extend_socket(bNodeTree &ntree, bNode &extend_node, bNode &storage_node, bNodeLink &link, const std::optional< StringRef > socket_identifier=std::nullopt)
bool get_bake_draw_context(const bContext *C, const bNode &node, BakeDrawContext &r_ctx)
void draw_data_blocks(const bContext *C, uiLayout *layout, PointerRNA &bake_rna)
static void draw_bake_data_block_list_item(uiList *, const bContext *, uiLayout *layout, PointerRNA *, PointerRNA *itemptr, int, PointerRNA *, const char *, int, int)
void draw_common_bake_settings(bContext *C, BakeDrawContext &ctx, uiLayout *layout)
void draw_bake_button_row(const BakeDrawContext &ctx, uiLayout *layout, bool is_in_sidebar=false)
std::string make_anonymous_attribute_socket_inspection_string(const bNodeSocket &socket)
std::unique_ptr< LazyFunction > get_bake_lazy_function(const bNode &node, GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
void set_default_remaining_node_outputs(lf::Params ¶ms, const bNode &node)
std::optional< FoundNestedNodeID > find_nested_node_id(const GeoNodesLFUserData &user_data, const int node_id)
std::optional< std::string > get_bake_state_string(const BakeDrawContext &ctx)
void mix_baked_data_item(eNodeSocketDatatype socket_type, void *prev, const void *next, const float factor)
std::string get_baked_string(const BakeDrawContext &ctx)
VecBase< float, 4 > float4
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
NodeGeometryBakeItem * items
NodesModifierPackedBake * packed
NodesModifierRuntimeHandle * runtime
NodesModifierBake * bakes
const blender::CPPType * geometry_nodes_cpp_type
void(* initfunc)(bNodeTree *ntree, bNode *node)
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeExtraInfoFunction get_extra_info
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
bool(* insert_link)(bNodeTree *ntree, bNode *node, bNodeLink *link)
NodeDeclareFunction declare
void(* register_operators)()
Vector< Vector< int, 1 > > geometries_by_attribute
Vector< StringRef > names
Vector< eNodeSocketDatatype > types
Vector< AttrDomain > domains
Map< int, const BakeItem * > items_by_id
Map< int, std::unique_ptr< BakeItem > > items_by_id
Map< int, std::unique_ptr< SimulationNodeCache > > simulation_cache_by_id
Map< int, std::unique_ptr< BakeNodeCache > > bake_cache_by_id
Vector< std::unique_ptr< FrameCache > > frames
std::optional< NodesModifierBakeTarget > bake_target
std::optional< IndexRange > frame_range
const NodesModifierData * nmd
std::optional< IndexRange > baked_range
const NodesModifierBake * bake
static StructRNA * item_srna
static std::string socket_identifier_for_item(const NodeGeometryBakeItem &item)
static void blend_read_data(BlendDataReader *reader, bNode &node)
static void blend_write(BlendWriter *writer, const bNode &node)
static bool supports_socket_type(const eNodeSocketDatatype socket_type)
bke::bake::BakeDataBlockMap * data_block_map
sim_output::Behavior behavior
const Object * self_object() const
GeoNodesBakeParams * bake_params
geo_eval_log::GeoTreeLogger * try_get_tree_logger(const GeoNodesLFUserData &user_data) const
const ComputeContext * compute_context
const GeoNodesCallData * call_data
Array< int > lf_index_by_bsocket
GeometryNodeLazyFunctionGraphMapping mapping
ID * lookup_or_remember_missing(const bake::BakeDataBlockID &key) override
void try_add(ID &id) override
std::function< void(bke::bake::BakeState state)> store_fn
char idname[BKE_ST_MAXNAME]
uiListDrawItemFunc draw_item
void WM_operator_properties_id_lookup_set_from_id(PointerRNA *ptr, const ID *id)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
bool WM_uilisttype_add(uiListType *ult)