Blender V4.5
ed_util.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cmath>
10#include <cstdlib>
11#include <cstring>
12
13#include "BLI_listbase.h"
14#include "BLI_path_utils.hh"
15#include "BLI_string.h"
16
17#include "BLT_translation.hh"
18
19#include "BKE_collection.hh"
20#include "BKE_global.hh"
21#include "BKE_layer.hh"
22#include "BKE_lib_id.hh"
23#include "BKE_lib_remap.hh"
24#include "BKE_main.hh"
25#include "BKE_material.hh"
26#include "BKE_multires.hh"
27#include "BKE_object.hh"
28#include "BKE_packedFile.hh"
29#include "BKE_paint.hh"
30#include "BKE_scene.hh"
31#include "BKE_screen.hh"
32#include "BKE_undo_system.hh"
33
34#include "DEG_depsgraph.hh"
35
36#include "ED_armature.hh"
37#include "ED_asset.hh"
38#include "ED_gpencil_legacy.hh"
39#include "ED_image.hh"
40#include "ED_mesh.hh"
41#include "ED_object.hh"
42#include "ED_paint.hh"
43#include "ED_screen.hh"
44#include "ED_sculpt.hh"
45#include "ED_space_api.hh"
46#include "ED_util.hh"
47#include "ED_view3d.hh"
48
49#include "UI_interface.hh"
50#include "UI_resources.hh"
51
52#include "RNA_access.hh"
53#include "WM_api.hh"
54#include "WM_types.hh"
55
56/* ********* general editor util functions, not BKE stuff please! ********* */
57
59{
60 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
61 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
64 BKE_view_layer_synced_ensure(scene, view_layer);
66 if (ob && (ob->mode & OB_MODE_TEXTURE_PAINT)) {
68 ED_paint_proj_mesh_data_check(*scene, *ob, nullptr, nullptr, nullptr, nullptr);
69 }
70
71 /* UI Updates. */
72 /* Flag local View3D's to check and exit if they are empty. */
73 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
74 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
75 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
76 if (sl->spacetype == SPACE_VIEW3D) {
77 View3D *v3d = reinterpret_cast<View3D *>(sl);
78 if (v3d->localvd) {
80 }
81 }
82 }
83 }
84 }
85 }
86}
87
89{
90 using namespace blender::ed;
92 Main *bmain = CTX_data_main(C);
93 Scene *scene = CTX_data_scene(C);
95
96 /* This is called during initialization, so we don't want to store any reports */
98 int reports_flag_prev = reports->flag & ~RPT_STORE;
99
100 std::swap(reports->flag, reports_flag_prev);
101
102 /* Don't do undo pushes when calling an operator. */
103 wm->op_undo_depth++;
104
105 /* toggle on modes for objects that were saved with these enabled. for
106 * e.g. linked objects we have to ensure that they are actually the
107 * active object in this scene. */
109 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
110 int mode = ob->mode;
111 if (mode == OB_MODE_OBJECT) {
112 continue;
113 }
114 if (BKE_object_has_mode_data(ob, eObjectMode(mode))) {
115 /* For multi-edit mode we may already have mode data. */
116 continue;
117 }
118
119 /* Reset object to Object mode, so that code below can properly re-switch it to its
120 * previous mode if possible, re-creating its mode data, etc. */
121 ID *ob_data = static_cast<ID *>(ob->data);
122 ob->mode = OB_MODE_OBJECT;
124
125 /* Object mode is enforced if there is no active object, or if the active object's type is
126 * different. */
127 if (obact == nullptr || ob->type != obact->type) {
128 continue;
129 }
130 /* Object mode is enforced for non-editable data (or their obdata). */
131 if (!BKE_id_is_editable(bmain, &ob->id) ||
132 (ob_data != nullptr && !BKE_id_is_editable(bmain, ob_data)))
133 {
134 continue;
135 }
136
137 /* Pose mode is very similar to Object one, we can apply it even on objects not in current
138 * scene. */
139 if (mode == OB_MODE_POSE) {
141 }
142
143 /* Other edit/paint/etc. modes are only settable for objects visible in active scene currently.
144 * Otherwise, they (and their obdata) may not be (fully) evaluated, which is mandatory for some
145 * modes like Sculpt.
146 * Ref. #98225. */
148 !BKE_scene_has_object(scene, ob) || (ob->visibility_flag & OB_HIDE_VIEWPORT) != 0)
149 {
150 continue;
151 }
152
153 if (mode == OB_MODE_EDIT) {
154 object::editmode_enter_ex(bmain, scene, ob, 0);
155 }
156 else if (mode & OB_MODE_ALL_SCULPT) {
157 if (obact == ob) {
158 if (mode == OB_MODE_SCULPT) {
160 *bmain, *depsgraph, *scene, *ob, true, reports);
161 }
162 else if (mode == OB_MODE_VERTEX_PAINT) {
163 ED_object_vpaintmode_enter_ex(*bmain, *depsgraph, *scene, *ob);
164 }
165 else if (mode == OB_MODE_WEIGHT_PAINT) {
166 ED_object_wpaintmode_enter_ex(*bmain, *depsgraph, *scene, *ob);
167 }
168 else {
170 }
171 }
172 else {
173 /* Create data for non-active objects which need it for
174 * mode-switching but don't yet support multi-editing. */
175 if (mode & OB_MODE_ALL_SCULPT) {
176 ob->mode = mode;
178 }
179 }
180 }
181 else {
182 /* TODO(@ideasman42): avoid operator calls. */
183 if (obact == ob) {
185 }
186 }
187 }
188
189 /* image editor paint mode */
190 if (scene) {
191 ED_space_image_paint_update(bmain, wm, scene);
192 }
193
194 /* Enforce a full redraw for the first time areas/regions get drawn. Further region init/refresh
195 * just triggers non-rebuild redraws (#RGN_DRAW_NO_REBUILD). Usually a full redraw would be
196 * triggered by a `NC_WM | ND_FILEREAD` notifier, but if a startup script calls an operator that
197 * redraws the window, notifiers are not handled before the operator runs. See #98461. */
198 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
199 const bScreen *screen = WM_window_get_active_screen(win);
200
201 ED_screen_areas_iter (win, screen, area) {
202 ED_area_tag_redraw(area);
203 }
204 }
205
207
208 std::swap(reports->flag, reports_flag_prev);
209 wm->op_undo_depth--;
210}
211
212void ED_editors_exit(Main *bmain, bool do_undo_system)
213{
214 using namespace blender::ed;
215 if (!bmain) {
216 return;
217 }
218
219 /* Frees all edit-mode undo-steps. */
220 if (do_undo_system && G_MAIN->wm.first) {
221 wmWindowManager *wm = static_cast<wmWindowManager *>(G_MAIN->wm.first);
222 /* normally we don't check for null undo stack,
223 * do here since it may run in different context. */
224 if (wm->undo_stack) {
225 BKE_undosys_stack_destroy(wm->undo_stack);
226 wm->undo_stack = nullptr;
227 }
228 }
229
230 /* On undo, tag for update so the depsgraph doesn't use stale edit-mode data,
231 * this is possible when mixing edit-mode and memory-file undo.
232 *
233 * By convention, objects are not left in edit-mode - so this isn't often problem in practice,
234 * since exiting edit-mode will tag the objects too.
235 *
236 * However there is no guarantee the active object _never_ changes while in edit-mode.
237 * Python for example can do this, some callers to #object::base_activate
238 * don't handle modes either (doing so isn't always practical).
239 *
240 * To reproduce the problem where stale data is used, see: #84920. */
241 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
242 if (object::editmode_free_ex(bmain, ob)) {
243 if (do_undo_system == false) {
245 }
246 }
247 }
248
249 /* global in meshtools... */
252}
253
255 Object *ob,
256 bool for_render,
257 bool check_needs_flush)
258{
259 using namespace blender::ed;
260 bool has_edited = false;
261 if (ob->mode & OB_MODE_SCULPT) {
262 /* Don't allow flushing while in the middle of a stroke (frees data in use).
263 * Auto-save prevents this from happening but scripts
264 * may cause a flush on saving: #53986. */
265 if (ob->sculpt != nullptr && ob->sculpt->cache == nullptr) {
266 if (check_needs_flush && !ob->sculpt->needs_flush_to_id) {
267 return false;
268 }
269 ob->sculpt->needs_flush_to_id = false;
270
271 /* flush multires changes (for sculpt) */
273 has_edited = true;
274
275 if (for_render) {
276 /* flush changes from dynamic topology sculpt */
278 }
279 else {
280 /* Set reorder=false so that saving the file doesn't reorder
281 * the BMesh's elements */
283 }
284 }
285 }
286 else if (ob->mode & OB_MODE_EDIT) {
287
288 char *needs_flush_ptr = BKE_object_data_editmode_flush_ptr_get(static_cast<ID *>(ob->data));
289 if (needs_flush_ptr != nullptr) {
290 if (check_needs_flush && (*needs_flush_ptr == 0)) {
291 return false;
292 }
293 *needs_flush_ptr = 0;
294 }
295
296 /* get editmode results */
297 has_edited = true;
298 object::editmode_load(bmain, ob);
299 }
300 return has_edited;
301}
302
304{
305 return ED_editors_flush_edits_for_object_ex(bmain, ob, false, false);
306}
307
308bool ED_editors_flush_edits_ex(Main *bmain, bool for_render, bool check_needs_flush)
309{
310 bool has_edited = false;
311
312 /* loop through all data to find edit mode or object mode, because during
313 * exiting we might not have a context for edit object and multiple sculpt
314 * objects can exist at the same time */
315 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
316 has_edited |= ED_editors_flush_edits_for_object_ex(bmain, ob, for_render, check_needs_flush);
317 }
318
319 bmain->is_memfile_undo_flush_needed = false;
320
321 return has_edited;
322}
323
325{
326 return ED_editors_flush_edits_ex(bmain, false, false);
327}
328
329/* ***** XXX: functions are using old blender names, cleanup later ***** */
330
332 bool shift, bool ctrl, float *val, float fac1, float fac2, float fac3, int invert)
333{
334 /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
335 if (invert) {
336 ctrl = !ctrl;
337 }
338
339 if (ctrl && shift) {
340 if (fac3 != 0.0f) {
341 *val = fac3 * floorf(*val / fac3 + 0.5f);
342 }
343 }
344 else if (ctrl) {
345 if (fac2 != 0.0f) {
346 *val = fac2 * floorf(*val / fac2 + 0.5f);
347 }
348 }
349 else {
350 if (fac1 != 0.0f) {
351 *val = fac1 * floorf(*val / fac1 + 0.5f);
352 }
353 }
354}
355
357 const char *opname,
358 const char *id_name,
359 const char *abs_name,
360 const char *folder,
361 PackedFile *pf)
362{
363 Main *bmain = CTX_data_main(C);
364 PointerRNA props_ptr;
365 uiPopupMenu *pup;
366 uiLayout *layout;
367 char line[FILE_MAX + 100];
368 wmOperatorType *ot = WM_operatortype_find(opname, true);
369 const char *blendfile_path = BKE_main_blendfile_path(bmain);
370
371 pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE);
372 layout = UI_popup_menu_layout(pup);
373
374 props_ptr = layout->op(ot, IFACE_("Remove Pack"), ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
375 RNA_enum_set(&props_ptr, "method", PF_REMOVE);
376 RNA_string_set(&props_ptr, "id", id_name);
377
378 if (blendfile_path[0] != '\0') {
379 char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
380
381 BLI_path_split_file_part(abs_name, fi, sizeof(fi));
382 BLI_path_join(local_name, sizeof(local_name), "//", folder, fi);
383 if (!STREQ(abs_name, local_name)) {
384 switch (BKE_packedfile_compare_to_file(blendfile_path, local_name, pf)) {
385 case PF_CMP_NOFILE:
386 SNPRINTF(line, IFACE_("Create %s"), local_name);
387 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
388 RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
389 RNA_string_set(&props_ptr, "id", id_name);
390
391 break;
392 case PF_CMP_EQUAL:
393 SNPRINTF(line, IFACE_("Use %s (identical)"), local_name);
394 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_USE_LOCAL);
395 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
396 RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
397 RNA_string_set(&props_ptr, "id", id_name);
398
399 break;
400 case PF_CMP_DIFFERS:
401 SNPRINTF(line, IFACE_("Use %s (differs)"), local_name);
402 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_USE_LOCAL);
403 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
404 RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
405 RNA_string_set(&props_ptr, "id", id_name);
406
407 SNPRINTF(line, IFACE_("Overwrite %s"), local_name);
408 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_WRITE_LOCAL);
409 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
410 RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
411 RNA_string_set(&props_ptr, "id", id_name);
412 break;
413 }
414 }
415 }
416
417 switch (BKE_packedfile_compare_to_file(blendfile_path, abs_name, pf)) {
418 case PF_CMP_NOFILE:
419 SNPRINTF(line, IFACE_("Create %s"), abs_name);
420 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_WRITE_ORIGINAL);
421 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
422 RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
423 RNA_string_set(&props_ptr, "id", id_name);
424 break;
425 case PF_CMP_EQUAL:
426 SNPRINTF(line, IFACE_("Use %s (identical)"), abs_name);
427 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_USE_ORIGINAL);
428 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
429 RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
430 RNA_string_set(&props_ptr, "id", id_name);
431 break;
432 case PF_CMP_DIFFERS:
433 SNPRINTF(line, IFACE_("Use %s (differs)"), abs_name);
434 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_USE_ORIGINAL);
435 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
436 RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
437 RNA_string_set(&props_ptr, "id", id_name);
438
439 SNPRINTF(line, IFACE_("Overwrite %s"), abs_name);
440 // uiItemEnumO_ptr(layout, ot, line, ICON_NONE, "method", PF_WRITE_ORIGINAL);
441 props_ptr = layout->op(ot, line, ICON_NONE, WM_OP_EXEC_DEFAULT, UI_ITEM_NONE);
442 RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
443 RNA_string_set(&props_ptr, "id", id_name);
444 break;
445 }
446
447 UI_popup_menu_end(C, pup);
448}
449
451 SpaceLink *sl,
452 const blender::bke::id::IDRemapper &mappings)
453{
455 if (st && st->id_remap) {
456 st->id_remap(area, sl, mappings);
457 }
458}
459
460void ED_spacedata_id_remap_single(ScrArea *area, SpaceLink *sl, ID *old_id, ID *new_id)
461{
463
464 if (st && st->id_remap) {
466 mappings.add(old_id, new_id);
467 st->id_remap(area, sl, mappings);
468 }
469}
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
ReportList * CTX_wm_reports(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define G_MAIN
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
bool BKE_scene_has_object(Scene *scene, Object *ob)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2503
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:877
General operations, lookup, etc. for materials.
void BKE_texpaint_slots_refresh_object(Scene *scene, Object *ob)
void multires_flush_sculpt_updates(Object *object)
Definition multires.cc:388
General operations, lookup, etc. for blender objects.
bool BKE_object_has_mode_data(const Object *ob, eObjectMode object_mode)
void BKE_object_sculpt_data_create(Object *ob)
char * BKE_object_data_editmode_flush_ptr_get(ID *id)
@ PF_CMP_EQUAL
@ PF_CMP_NOFILE
@ PF_CMP_DIFFERS
ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name, const char *filepath_rel, const PackedFile *pf)
@ PF_USE_ORIGINAL
@ PF_USE_LOCAL
@ PF_REMOVE
@ PF_WRITE_ORIGINAL
@ PF_WRITE_LOCAL
void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
Definition paint.cc:2135
void BKE_sculptsession_bm_to_me_for_render(Object *object)
Definition paint.cc:2170
SpaceType * BKE_spacetype_from_id(int spaceid)
Definition screen.cc:251
void BKE_undosys_stack_destroy(UndoStack *ustack)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define LISTBASE_FOREACH(type, var, list)
#define FILE_MAX
#define BLI_path_join(...)
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
#define FILE_MAXDIR
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
#define STREQ(a, b)
#define IFACE_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:962
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
eObjectMode
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_VERTEX_PAINT
#define OB_MODE_ALL_SCULPT
@ OB_HIDE_VIEWPORT
@ SPACE_VIEW3D
@ V3D_RUNTIME_LOCAL_MAYBE_EMPTY
void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene)
void ED_mesh_mirror_topo_table_end(Object *ob)
Definition meshtools.cc:867
void ED_mesh_mirror_spatial_table_end(Object *ob)
void ED_object_wpaintmode_enter_ex(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
void ED_object_vpaintmode_enter_ex(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
bool ED_paint_proj_mesh_data_check(Scene &scene, Object &ob, bool *r_has_uvs, bool *r_has_mat, bool *r_has_tex, bool *r_has_stencil)
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:714
#define ED_screen_areas_iter(win, screen, area_name)
Definition ED_screen.hh:288
#define C
Definition RandGen.cpp:29
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
#define UI_ITEM_NONE
ReportList * reports
Definition WM_types.hh:1025
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:245
BPy_StructRNA * depsgraph
void add(ID *old_id, ID *new_id)
std::string id_name(void *id)
#define floorf(x)
void ED_editors_exit(Main *bmain, bool do_undo_system)
Definition ed_util.cc:212
bool ED_editors_flush_edits_for_object(Main *bmain, Object *ob)
Definition ed_util.cc:303
void ED_spacedata_id_remap_single(ScrArea *area, SpaceLink *sl, ID *old_id, ID *new_id)
Definition ed_util.cc:460
bool ED_editors_flush_edits_for_object_ex(Main *bmain, Object *ob, bool for_render, bool check_needs_flush)
Definition ed_util.cc:254
bool ED_editors_flush_edits(Main *bmain)
Definition ed_util.cc:324
void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, PackedFile *pf)
Definition ed_util.cc:356
void apply_keyb_grid(bool shift, bool ctrl, float *val, float fac1, float fac2, float fac3, int invert)
Definition ed_util.cc:331
void ED_editors_init_for_undo(Main *bmain)
Definition ed_util.cc:58
void ED_spacedata_id_remap(ScrArea *area, SpaceLink *sl, const blender::bke::id::IDRemapper &mappings)
Definition ed_util.cc:450
bool ED_editors_flush_edits_ex(Main *bmain, bool for_render, bool check_needs_flush)
Definition ed_util.cc:308
void ED_editors_init(bContext *C)
Definition ed_util.cc:88
#define pf(_x, _i)
Prefetch 64.
Definition gim_memory.h:48
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
bool editmode_free_ex(Main *bmain, Object *obedit)
bool editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
bool mode_set(bContext *C, eObjectMode mode)
bool editmode_load(Main *bmain, Object *obedit)
void object_sculpt_mode_enter(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, bool force_dyntopo, ReportList *reports)
bool ED_object_posemode_enter_ex(Main *bmain, Object *ob)
Definition pose_edit.cc:77
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition DNA_ID.h:404
void * first
ListBase wm
Definition BKE_main.hh:276
bool is_memfile_undo_flush_needed
Definition BKE_main.hh:185
ListBase screens
Definition BKE_main.hh:261
ListBase objects
Definition BKE_main.hh:247
struct SculptSession * sculpt
struct Collection * master_collection
bool needs_flush_to_id
Definition BKE_paint.hh:521
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:437
void(* id_remap)(ScrArea *area, SpaceLink *sl, const blender::bke::id::IDRemapper &mappings)
View3D_Runtime runtime
struct View3D * localvd
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
wmOperatorType * ot
Definition wm_files.cc:4226
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Scene * WM_window_get_active_scene(const wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)