29 #define NESTED_ID_NASTY_WORKAROUND
32 #define DNA_DEPRECATED_ALLOW
71 #ifdef NESTED_ID_NASTY_WORKAROUND
106 #define DEBUG_PRINT \
107 if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) \
112 #ifdef NESTED_ID_NASTY_WORKAROUND
113 union NestedIDHackTempStorage {
127 void nested_id_hack_discard_pointers(
ID *id_cow)
129 switch (
GS(id_cow->
name)) {
130 # define SPECIAL_CASE(id_type, dna_type, field) \
132 ((dna_type *)id_cow)->field = nullptr; \
161 psys->part =
nullptr;
175 const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage,
const ID *
id)
178 # define SPECIAL_CASE(id_type, dna_type, field, variable) \
180 storage->variable = *(dna_type *)id; \
181 storage->variable.field = nullptr; \
182 return &storage->variable.id; \
197 storage->scene = *(
Scene *)
id;
198 storage->scene.toolsettings =
nullptr;
199 storage->scene.nodetree =
nullptr;
200 return &storage->scene.id;
212 void nested_id_hack_restore_pointers(
const ID *old_id,
ID *new_id)
214 if (new_id ==
nullptr) {
217 switch (
GS(old_id->
name)) {
218 # define SPECIAL_CASE(id_type, dna_type, field) \
220 ((dna_type *)(new_id))->field = ((dna_type *)(old_id))->field; \
245 switch (
GS(id_cow->
name)) {
246 # define SPECIAL_CASE(id_type, dna_type, field, field_type) \
248 dna_type *data = (dna_type *)id_cow; \
249 if (data->field != nullptr) { \
250 ID *ntree_id_cow = depsgraph->get_cow_id(&data->field->id); \
251 if (ntree_id_cow != nullptr) { \
252 DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n", \
253 data->field->id.name, \
256 data->field = (field_type *)ntree_id_cow; \
281 struct ValidateData {
287 bool id_copy_inplace_no_main(
const ID *
id,
ID *newid)
289 const ID *id_for_copy =
id;
293 if (id_type ==
ID_OB) {
294 const Object *
object =
reinterpret_cast<const Object *
>(id_for_copy);
299 #ifdef NESTED_ID_NASTY_WORKAROUND
300 NestedIDHackTempStorage id_hack_storage;
301 id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage,
id);
310 #ifdef NESTED_ID_NASTY_WORKAROUND
312 nested_id_hack_restore_pointers(
id, newid);
329 #ifdef NESTED_ID_NASTY_WORKAROUND
330 NestedIDHackTempStorage id_hack_storage;
331 id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage, &
scene->
id);
340 #ifdef NESTED_ID_NASTY_WORKAROUND
342 nested_id_hack_restore_pointers(&
scene->
id, &new_scene->id);
387 view_layer->basact =
nullptr;
394 view_layer_input =
nullptr;
404 view_layer_cow !=
nullptr;
405 view_layer_cow = view_layer_next) {
406 view_layer_next = view_layer_cow->
next;
407 if (view_layer_input !=
nullptr &&
STREQ(view_layer_input->
name, view_layer_cow->name)) {
408 view_layer_eval = view_layer_cow;
415 if (view_layer_eval !=
nullptr) {
416 view_layer_eval->
prev = view_layer_eval->
next =
nullptr;
422 void scene_remove_all_bases(
Scene *scene_cow)
433 if (view_layer ==
nullptr) {
436 ListBase enabled_bases = {
nullptr,
nullptr};
450 if (is_object_enabled) {
454 if (base == view_layer->
basact) {
455 view_layer->
basact =
nullptr;
463 void view_layer_update_orig_base_pointers(
const ViewLayer *view_layer_orig,
466 if (view_layer_orig ==
nullptr || view_layer_eval ==
nullptr) {
472 base_eval->base_orig = base_orig;
473 base_orig = base_orig->
next;
485 scene_remove_all_bases(scene_cow);
495 view_layer_update_orig_base_pointers(view_layer_orig, view_layer_eval);
496 view_layer_remove_disabled_bases(
depsgraph, view_layer_eval);
503 inline bool check_datablock_expanded(
const ID *id_cow)
505 return (id_cow->
name[0] !=
'\0');
511 struct RemapCallbackUserData {
525 if (*id_p ==
nullptr) {
543 const ID_Type id_type =
GS(id_orig->name);
555 id_cow =
user_data->node_builder->ensure_cow_id(id_orig);
563 " Remapping datablock for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
569 void update_armature_edit_mode_pointers(
const Depsgraph * ,
575 armature_cow->
edbo = armature_orig->
edbo;
579 void update_curve_edit_mode_pointers(
const Depsgraph * ,
583 const Curve *curve_orig = (
const Curve *)id_orig;
589 void update_mball_edit_mode_pointers(
const Depsgraph * ,
598 void update_lattice_edit_mode_pointers(
const Depsgraph * ,
607 void update_mesh_edit_mode_pointers(
const ID *id_orig,
ID *id_cow)
615 const Mesh *mesh_orig = (
const Mesh *)id_orig;
632 update_armature_edit_mode_pointers(
depsgraph, id_orig, id_cow);
635 update_mesh_edit_mode_pointers(id_orig, id_cow);
638 update_curve_edit_mode_pointers(
depsgraph, id_orig, id_cow);
641 update_mball_edit_mode_pointers(
depsgraph, id_orig, id_cow);
644 update_lattice_edit_mode_pointers(
depsgraph, id_orig, id_cow);
652 void update_list_orig_pointers(
const ListBase *listbase_orig,
656 T *element_orig =
reinterpret_cast<T *
>(listbase_orig->
first);
657 T *element_cow =
reinterpret_cast<T *
>(listbase->
first);
661 while (element_orig !=
nullptr && element_cow !=
nullptr) {
662 element_cow->*orig_field = element_orig;
663 element_cow = element_cow->next;
664 element_orig = element_orig->next;
667 BLI_assert((element_orig ==
nullptr && element_cow ==
nullptr) ||
668 !
"list of pointers of different sizes, unable to reliably set orig pointer");
671 void update_particle_system_orig_pointers(
const Object *object_orig,
Object *object_cow)
673 update_list_orig_pointers(
677 void set_particle_system_modifiers_loaded(
Object *object_cow)
697 if (orig_psys->
edit !=
nullptr) {
705 const Object *object_orig,
708 update_particle_system_orig_pointers(object_orig, object_cow);
709 set_particle_system_modifiers_loaded(object_cow);
710 reset_particle_system_edit_eval(
depsgraph, object_cow);
713 void update_pose_orig_pointers(
const bPose *pose_orig,
bPose *pose_cow)
718 void update_modifiers_orig_pointers(
const Object *object_orig,
Object *object_cow)
720 update_list_orig_pointers(
724 void update_nla_strips_orig_pointers(
const ListBase *strips_orig,
ListBase *strips_cow)
728 while (strip_orig !=
nullptr) {
730 update_nla_strips_orig_pointers(&strip_orig->
strips, &strip_cow->
strips);
731 strip_cow = strip_cow->
next;
732 strip_orig = strip_orig->
next;
736 void update_nla_tracks_orig_pointers(
const ListBase *tracks_orig,
ListBase *tracks_cow)
740 while (track_orig !=
nullptr) {
741 update_nla_strips_orig_pointers(&track_orig->
strips, &track_cow->
strips);
742 track_cow = track_cow->
next;
743 track_orig = track_orig->
next;
747 void update_animation_data_after_copy(
const ID *id_orig,
ID *id_cow)
750 if (anim_data_orig ==
nullptr) {
762 const Object *object_orig,
765 if (object_cow->
proxy !=
nullptr) {
767 object_cow->
proxy =
nullptr;
787 update_animation_data_after_copy(id_orig, id_cow);
794 object_cow->
mode = object_orig->
mode;
801 if (armature_orig->
edbo ==
nullptr) {
802 update_pose_orig_pointers(object_orig->
pose, object_cow->
pose);
809 update_particles_after_copy(
depsgraph, object_orig, object_cow);
810 update_modifiers_orig_pointers(object_orig, object_cow);
811 update_proxy_pointers_after_copy(
depsgraph, object_orig, object_cow);
816 const Scene *scene_orig = (
const Scene *)id_orig;
825 update_edit_mode_pointers(
depsgraph, id_orig, id_cow);
836 if (*id_p !=
nullptr) {
837 if (!check_datablock_expanded(*id_p)) {
838 data->is_valid =
false;
858 const int id_cow_recalc = id_cow->
recalc;
865 "Expanding datablock for %s: id_orig=%p id_cow=%p\n", id_orig->
name, id_orig, id_cow);
890 done = scene_copy_inplace_no_main((
Scene *)id_orig, (
Scene *)id_cow);
907 done = id_copy_inplace_no_main(id_orig, id_cow);
910 BLI_assert(!
"No idea how to perform CoW on datablock");
914 " Remapping ID links for %s: id_orig=%p id_cow=%p\n", id_orig->
name, id_orig, id_cow);
916 #ifdef NESTED_ID_NASTY_WORKAROUND
917 ntree_hack_remap_pointers(
depsgraph, id_cow);
923 RemapCallbackUserData
user_data = {
nullptr};
935 id_cow->
recalc = id_cow_recalc;
976 void discard_armature_edit_mode_pointers(
ID *id_cow)
979 armature_cow->
edbo =
nullptr;
982 void discard_curve_edit_mode_pointers(
ID *id_cow)
989 void discard_mball_edit_mode_pointers(
ID *id_cow)
995 void discard_lattice_edit_mode_pointers(
ID *id_cow)
1001 void discard_mesh_edit_mode_pointers(
ID *id_cow)
1012 void discard_scene_pointers(
ID *id_cow)
1021 void discard_edit_mode_pointers(
ID *id_cow)
1026 discard_armature_edit_mode_pointers(id_cow);
1029 discard_mesh_edit_mode_pointers(id_cow);
1032 discard_curve_edit_mode_pointers(id_cow);
1035 discard_mball_edit_mode_pointers(id_cow);
1038 discard_lattice_edit_mode_pointers(id_cow);
1043 discard_scene_pointers(id_cow);
1058 if (!check_datablock_expanded(id_cow)) {
1064 #ifdef NESTED_ID_NASTY_WORKAROUND
1065 nested_id_hack_discard_pointers(id_cow);
1073 ob_cow->
data =
nullptr;
1074 ob_cow->
sculpt =
nullptr;
1080 discard_edit_mode_pointers(id_cow);
1084 id_cow->
name[0] =
'\0';
1101 if (id_cow ==
nullptr) {
1105 data.is_valid =
true;
1107 nullptr, id_cow, foreach_libblock_validate_callback, &
data,
IDWALK_NOP);
1108 return data.is_valid;
1123 return check_datablock_expanded(id_cow);
Blender kernel action and pose functionality.
struct AnimData * BKE_animdata_from_id(struct ID *id)
void BKE_animsys_update_driver_array(struct ID *id)
void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose)
void BKE_pose_pchan_index_rebuild(struct bPose *pose)
void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval)
void BKE_view_layer_free_ex(struct ViewLayer *view_layer, const bool do_id_user)
struct ViewLayer * BKE_view_layer_default_render(const struct Scene *scene)
void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL()
@ LIB_ID_CREATE_NO_ALLOCATE
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_libblock_free_datablock(struct ID *id, const int flag) ATTR_NONNULL()
@ IDWALK_IGNORE_EMBEDDED_ID
void BKE_library_foreach_ID_link(struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
General operations, lookup, etc. for blender objects.
void BKE_object_check_uuids_unique_and_report(const struct Object *object)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
struct Depsgraph Depsgraph
bool DEG_is_active(const struct Depsgraph *depsgraph)
void DEG_debug_print_eval(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
ID and Library types, which are fundamental for sdna.
#define ID_TYPE_IS_COW(_id_type)
@ LIB_TAG_COPIED_ON_WRITE
@ eParticleSystemFlag_file_loaded
@ eModifierType_ParticleSystem
Object is a sort of wrapper for general info.
Types and defines for representing Rigid Body entities.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
void restore_to_id(ID *id)
void init_from_id(ID *id)
FreestyleLineStyle linestyle
#define SPECIAL_CASE(id_type, dna_type, field)
DepsgraphNodeBuilder * node_builder
const Depsgraph * depsgraph
#define DEG_COW_PRINT(format,...)
static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base)
ID * deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
bool deg_copy_on_write_is_needed(const ID *id_orig)
ID * deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode *id_node, DepsgraphNodeBuilder *node_builder, bool create_placeholders)
void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig)
bool deg_validate_copy_on_write_datablock(ID *id_cow)
@ DEG_ID_LINKED_INDIRECTLY
bool deg_copy_on_write_is_expanded(const ID *id_cow)
void deg_evaluate_copy_on_write(struct ::Depsgraph *graph, const IDNode *id_node)
bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig)
void deg_free_copy_on_write_datablock(ID *id_cow)
void SEQ_relations_check_uuids_unique_and_report(const Scene *scene)
struct Mesh * mesh_eval_final
struct Mesh * mesh_eval_cage
struct EditFont * editfont
struct EditLatt * editlatt
struct BMEditMesh * edit_mesh
struct ModifierData * orig_modifier_data
struct NlaStrip * orig_strip
struct Object * proxy_group
struct SculptSession * sculpt
struct ParticleSystemModifierData * psmd_eval
struct ParticleSystem * psys_eval
struct PTCacheEdit * edit
struct ParticleSystem * orig_psys
struct LightCache * light_cache_data
struct bNodeTree * nodetree
struct ToolSettings * toolsettings
struct EditBone * act_edbone
struct bPoseChannel * orig_pchan
ID * get_cow_id(const ID *id_orig) const
IDNode * find_id_node(const ID *id) const
bool is_render_pipeline_depsgraph
eDepsNode_LinkedState_Type linked_state