32#include "RNA_prototypes.hh"
44namespace bake = bke::bake;
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__);
152 STRNCPY(list->idname,
"DATA_UL_bake_node_items");
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_};
274 std::lock_guard
lock{mutex_};
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(
300 item.
name, type, lf::ValueUsage::Maybe);
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}});
378 std::optional<bake::BakeState> bake_state = this->get_bake_state_from_inputs(
params,
385 for (
const int i : bake_items_.index_range()) {
386 output_values[i] =
params.get_output_data_ptr(i);
388 this->move_bake_state_to_values(std::move(*bake_state),
393 for (
const int i : bake_items_.index_range()) {
403 std::optional<bake::BakeState> bake_state = this->get_bake_state_from_inputs(
params,
409 this->output_cached_state(
params, user_data, data_block_map, *bake_state);
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);
422 this->copy_bake_state_to_values(bake_state,
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);
444 this->copy_bake_state_to_values(
445 prev_state, data_block_map, self_object, compute_context, output_values);
449 for (
const int i : bake_items_.index_range()) {
450 const CPPType &type = *outputs_[i].type;
451 next_values[i] = allocator.
allocate(type.size(), type.alignment());
453 this->copy_bake_state_to_values(
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()) {
464 const CPPType &type = *outputs_[i].type;
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) {
516 return this->make_attribute_field(self_object, compute_context, bake_items_[i], type);
523 const Object &self_object,
530 bake_items.
append(bake_item ? *bake_item :
nullptr);
536 [&](
const int i,
const CPPType &type) {
537 return this->make_attribute_field(self_object, compute_context, bake_items_[i], 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");
628 if (!BakeItemsAccessor::supports_socket_type(type)) {
634 socket_items::add_item_with_socket_type_and_name<BakeItemsAccessor>(
635 node, type,
params.socket.name);
636 params.update_and_connect_available_socket(node,
params.socket.name);
665 BLI_assert(
ELEM(node.type, GEO_NODE_BAKE, GEO_NODE_SIMULATION_OUTPUT));
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();
725 r_ctx.
bake_still = node.type == GEO_NODE_BAKE &&
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__);
940 STRNCPY(list->idname,
"DATA_UL_nodes_modifier_data_blocks");
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 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)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
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)
Span< T > as_span() const
void destruct(void *ptr) const
const ComputeContextHash & hash() const
void * allocate(const int64_t size, const int64_t alignment)
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
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)
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)
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)
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]
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)