Blender V4.5
undo.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_task.hh"
10
11#include "BKE_context.hh"
12#include "BKE_customdata.hh"
13#include "BKE_main.hh"
14#include "BKE_object.hh"
15#include "BKE_pointcloud.hh"
16#include "BKE_undo_system.hh"
17
18#include "CLG_log.h"
19
20#include "DEG_depsgraph.hh"
21
22#include "ED_pointcloud.hh"
23#include "ED_undo.hh"
24
25#include "WM_api.hh"
26#include "WM_types.hh"
27
28static CLG_LogRef LOG = {"ed.undo.pointcloud"};
29
31namespace undo {
32
33/* -------------------------------------------------------------------- */
38
39struct StepObject {
40 UndoRefID_Object obedit_ref = {};
42 int totpoint = 0;
43 /* Store the bounds caches because they are small. */
46};
47
54
55static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p)
56{
57 PointCloudUndoStep *us = reinterpret_cast<PointCloudUndoStep *>(us_p);
58
59 Scene *scene = CTX_data_scene(C);
60 ViewLayer *view_layer = CTX_data_view_layer(C);
62
63 us->scene_ref.ptr = scene;
64 new (&us->objects) Array<StepObject>(objects.size());
65
66 threading::parallel_for(us->objects.index_range(), 8, [&](const IndexRange range) {
67 for (const int i : range) {
68 Object *ob = objects[i];
69 StepObject &object = us->objects[i];
70 PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
71 object.obedit_ref.ptr = ob;
72 CustomData_init_from(
73 &pointcloud.pdata, &object.custom_data, CD_MASK_ALL, pointcloud.totpoint);
74 object.bounds_cache = pointcloud.runtime->bounds_cache;
75 object.bounds_with_radius_cache = pointcloud.runtime->bounds_with_radius_cache;
76 object.totpoint = pointcloud.totpoint;
77 }
78 });
79
80 bmain->is_memfile_undo_flush_needed = true;
81
82 return true;
83}
84
85static void step_decode(
86 bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/)
87{
88 PointCloudUndoStep *us = reinterpret_cast<PointCloudUndoStep *>(us_p);
89 Scene *scene = CTX_data_scene(C);
90 ViewLayer *view_layer = CTX_data_view_layer(C);
91
93 CTX_wm_manager(C), us->scene_ref.ptr, &scene, &view_layer);
95 view_layer,
96 &us->objects.first().obedit_ref.ptr,
97 us->objects.size(),
98 sizeof(decltype(us->objects)::value_type));
99
100 BLI_assert(BKE_object_is_in_editmode(us->objects.first().obedit_ref.ptr));
101
102 for (const StepObject &object : us->objects) {
103 PointCloud &pointcloud = *static_cast<PointCloud *>(object.obedit_ref.ptr->data);
104 const bool positions_changed =
106 CustomData_get_layer_named(&object.custom_data, CD_PROP_FLOAT3, "position");
107
109 CustomData_init_from(&object.custom_data, &pointcloud.pdata, CD_MASK_ALL, object.totpoint);
110 pointcloud.totpoint = object.totpoint;
111 pointcloud.runtime->bounds_cache = object.bounds_cache;
112 pointcloud.runtime->bounds_with_radius_cache = object.bounds_with_radius_cache;
113 if (positions_changed) {
114 pointcloud.runtime->bvh_cache.tag_dirty();
115 }
117 }
118
120 scene, view_layer, us->objects.first().obedit_ref.ptr, us_p->name, &LOG);
121
122 bmain->is_memfile_undo_flush_needed = true;
123
125}
126
127static void step_free(UndoStep *us_p)
128{
129 PointCloudUndoStep *us = reinterpret_cast<PointCloudUndoStep *>(us_p);
130 for (StepObject &object : us->objects) {
131 CustomData_free(&object.custom_data);
132 }
133 us->objects.~Array();
134}
135
136static void foreach_ID_ref(UndoStep *us_p,
137 UndoTypeForEachIDRefFn foreach_ID_ref_fn,
138 void *user_data)
139{
140 PointCloudUndoStep *us = reinterpret_cast<PointCloudUndoStep *>(us_p);
141
142 foreach_ID_ref_fn(user_data, ((UndoRefID *)&us->scene_ref));
143 for (const StepObject &object : us->objects) {
144 foreach_ID_ref_fn(user_data, ((UndoRefID *)&object.obedit_ref));
145 }
146}
147
149
150} // namespace undo
151
166
167} // namespace blender::ed::pointcloud
Scene * CTX_data_scene(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_free(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
General operations for point clouds.
@ UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE
void(*)(void *user_data, UndoRefID *id_ref) UndoTypeForEachIDRefFn
eUndoStepDir
#define BLI_assert(a)
Definition BLI_assert.h:46
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ CD_PROP_FLOAT3
void ED_undo_object_set_active_or_warn(Scene *scene, ViewLayer *view_layer, Object *ob, const char *info, CLG_LogRef *log)
Definition ed_undo.cc:774
void ED_undo_object_editmode_restore_helper(Scene *scene, ViewLayer *view_layer, Object **object_array, uint object_array_len, uint object_array_stride)
Definition ed_undo.cc:810
blender::Vector< Object * > ED_undo_editmode_objects_from_view_layer(const Scene *scene, ViewLayer *view_layer)
Definition ed_undo.cc:855
void ED_undo_object_editmode_validate_scene_from_windows(wmWindowManager *wm, const Scene *scene_ref, Scene **scene_p, ViewLayer **view_layer_p)
Definition ed_undo.cc:793
#define C
Definition RandGen.cpp:29
#define NC_GEOM
Definition WM_types.hh:390
#define ND_DATA
Definition WM_types.hh:506
int64_t size() const
#define CD_MASK_ALL
#define LOG(severity)
Definition log.h:32
static void foreach_ID_ref(UndoStep *us_p, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
Definition undo.cc:136
static void step_free(UndoStep *us_p)
Definition undo.cc:127
static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p)
Definition undo.cc:55
static void step_decode(bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir, bool)
Definition undo.cc:85
bool editable_pointcloud_in_edit_mode_poll(bContext *C)
Definition operators.cc:72
void undosys_type_register(UndoType *ut)
Definition undo.cc:152
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
bool is_memfile_undo_flush_needed
Definition BKE_main.hh:185
char name[64]
void(* step_foreach_ID_ref)(UndoStep *us, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
const char * name
void(* step_free)(UndoStep *us)
bool(* poll)(struct bContext *C)
void(* step_decode)(bContext *C, Main *bmain, UndoStep *us, eUndoStepDir dir, bool is_final)
bool(* step_encode)(bContext *C, Main *bmain, UndoStep *us)
SharedCache< Bounds< float3 > > bounds_with_radius_cache
Definition undo.cc:45
SharedCache< Bounds< float3 > > bounds_cache
Definition undo.cc:44
void WM_event_add_notifier(const bContext *C, uint type, void *reference)