14#define NESTED_ID_NASTY_WORKAROUND
17#define DNA_DEPRECATED_ALLOW
59#ifdef NESTED_ID_NASTY_WORKAROUND
95 if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) \
100#ifdef NESTED_ID_NASTY_WORKAROUND
101union NestedIDHackTempStorage {
114void nested_id_hack_discard_pointers(
ID *id_cow)
116 switch (
GS(id_cow->
name)) {
117# define SPECIAL_CASE(id_type, dna_type, field) \
119 ((dna_type *)id_cow)->field = nullptr; \
147 psys->part =
nullptr;
161const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage,
const ID *
id)
164# define SPECIAL_CASE(id_type, dna_type, field, variable) \
166 storage->variable = dna::shallow_copy(*(dna_type *)id); \
167 storage->variable.field = nullptr; \
168 return &storage->variable.id; \
182 storage->scene = *(
Scene *)
id;
183 storage->scene.toolsettings =
nullptr;
184 storage->scene.nodetree =
nullptr;
185 return &storage->scene.id;
197void nested_id_hack_restore_pointers(
const ID *old_id,
ID *new_id)
199 if (new_id ==
nullptr) {
202 switch (
GS(old_id->
name)) {
203# define SPECIAL_CASE(id_type, dna_type, field) \
205 ((dna_type *)(new_id))->field = ((dna_type *)(old_id))->field; \
227void ntree_hack_remap_pointers(
const Depsgraph *
depsgraph,
ID *id_cow)
229 switch (
GS(id_cow->
name)) {
230# define SPECIAL_CASE(id_type, dna_type, field, field_type) \
232 dna_type *data = (dna_type *)id_cow; \
233 if (data->field != nullptr) { \
234 ID *ntree_id_cow = depsgraph->get_cow_id(&data->field->id); \
235 if (ntree_id_cow != nullptr) { \
236 DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n", \
237 data->field->id.name, \
240 data->field = (field_type *)ntree_id_cow; \
270bool id_copy_inplace_no_main(
const ID *
id,
ID *newid)
272 const ID *id_for_copy = id;
276 if (id_type ==
ID_OB) {
277 const Object *
object =
reinterpret_cast<const Object *
>(id_for_copy);
282#ifdef NESTED_ID_NASTY_WORKAROUND
283 NestedIDHackTempStorage id_hack_storage;
284 id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage,
id);
293#ifdef NESTED_ID_NASTY_WORKAROUND
295 nested_id_hack_restore_pointers(
id, newid);
304bool scene_copy_inplace_no_main(
const Scene *scene,
Scene *new_scene)
311#ifdef NESTED_ID_NASTY_WORKAROUND
312 NestedIDHackTempStorage id_hack_storage;
313 const ID *id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage, &scene->
id);
315 const ID *id_for_copy = &scene->
id;
323#ifdef NESTED_ID_NASTY_WORKAROUND
325 nested_id_hack_restore_pointers(&scene->
id, &new_scene->
id);
341 Scene *scene_orig =
reinterpret_cast<Scene *
>(id_node->id_orig);
354void scene_minimize_unused_view_layers(
const Depsgraph *
depsgraph,
355 const IDNode *id_node,
358 if (
depsgraph->is_render_pipeline_depsgraph) {
380 view_layer_cow !=
nullptr;
381 view_layer_cow = view_layer_next)
383 view_layer_next = view_layer_cow->next;
384 if (view_layer_input !=
nullptr &&
STREQ(view_layer_input->
name, view_layer_cow->name)) {
385 view_layer_eval = view_layer_cow;
395 if (view_layer_eval !=
nullptr) {
400void scene_remove_all_bases(
Scene *scene_cow)
409void view_layer_remove_disabled_bases(
const Depsgraph *
depsgraph,
413 if (view_layer ==
nullptr) {
416 ListBase enabled_bases = {
nullptr,
nullptr};
431 if (is_object_enabled) {
435 if (base == view_layer->
basact) {
436 view_layer->
basact =
nullptr;
444void view_layer_update_orig_base_pointers(
const ViewLayer *view_layer_orig,
447 if (view_layer_orig ==
nullptr || view_layer_eval ==
nullptr) {
454 base_orig = base_orig->
next;
458void scene_setup_view_layers_before_remap(
const Depsgraph *
depsgraph,
459 const IDNode *id_node,
462 scene_minimize_unused_view_layers(
depsgraph, id_node, scene_cow);
465 if (
depsgraph->is_render_pipeline_depsgraph) {
466 scene_remove_all_bases(scene_cow);
470void scene_setup_view_layers_after_remap(
const Depsgraph *
depsgraph,
471 const IDNode *id_node,
476 view_layer_update_orig_base_pointers(view_layer_orig, view_layer_eval);
477 view_layer_remove_disabled_bases(
depsgraph, scene_cow, view_layer_eval);
484inline bool check_datablock_expanded(
const ID *id_cow)
486 return (id_cow->
name[0] !=
'\0');
492struct RemapCallbackUserData {
500 if (*id_p ==
nullptr) {
504 RemapCallbackUserData *user_data = (RemapCallbackUserData *)cb_data->
user_data;
505 const Depsgraph *
depsgraph = user_data->depsgraph;
511 " Remapping datablock for %s: id_orig=%p id_cow=%p\n", id_orig->
name, id_orig, id_cow);
517void update_armature_edit_mode_pointers(
const Depsgraph * ,
523 armature_cow->
edbo = armature_orig->
edbo;
527void update_curve_edit_mode_pointers(
const Depsgraph * ,
531 const Curve *curve_orig = (
const Curve *)id_orig;
537void update_mball_edit_mode_pointers(
const Depsgraph * ,
546void update_lattice_edit_mode_pointers(
const Depsgraph * ,
555void update_mesh_edit_mode_pointers(
const ID *id_orig,
ID *id_cow)
557 const Mesh *mesh_orig = (
const Mesh *)id_orig;
559 if (mesh_orig->
runtime->edit_mesh ==
nullptr) {
567void update_edit_mode_pointers(
const Depsgraph *
depsgraph,
const ID *id_orig,
ID *id_cow)
572 update_armature_edit_mode_pointers(
depsgraph, id_orig, id_cow);
575 update_mesh_edit_mode_pointers(id_orig, id_cow);
578 update_curve_edit_mode_pointers(
depsgraph, id_orig, id_cow);
581 update_mball_edit_mode_pointers(
depsgraph, id_orig, id_cow);
584 update_lattice_edit_mode_pointers(
depsgraph, id_orig, id_cow);
592void update_list_orig_pointers(
const ListBase *listbase_orig,
596 T *element_orig =
reinterpret_cast<T *
>(listbase_orig->
first);
597 T *element_cow =
reinterpret_cast<T *
>(listbase->
first);
601 while (element_orig !=
nullptr && element_cow !=
nullptr) {
602 element_cow->*orig_field = element_orig;
603 element_cow = element_cow->next;
604 element_orig = element_orig->next;
608 "list of pointers of different sizes, unable to reliably set orig pointer");
611void update_particle_system_orig_pointers(
const Object *object_orig,
Object *object_cow)
613 update_list_orig_pointers(
617void set_particle_system_modifiers_loaded(
Object *object_cow)
628void reset_particle_system_edit_eval(
const Depsgraph *
depsgraph,
Object *object_cow)
637 if (orig_psys->
edit !=
nullptr) {
644void update_particles_after_copy(
const Depsgraph *
depsgraph,
645 const Object *object_orig,
648 update_particle_system_orig_pointers(object_orig, object_cow);
649 set_particle_system_modifiers_loaded(object_cow);
650 reset_particle_system_edit_eval(
depsgraph, object_cow);
653void update_pose_orig_pointers(
const bPose *pose_orig,
bPose *pose_cow)
658void update_nla_strips_orig_pointers(
const ListBase *strips_orig,
ListBase *strips_cow)
662 while (strip_orig !=
nullptr) {
664 update_nla_strips_orig_pointers(&strip_orig->
strips, &strip_cow->
strips);
665 strip_cow = strip_cow->
next;
666 strip_orig = strip_orig->
next;
670void update_nla_tracks_orig_pointers(
const ListBase *tracks_orig,
ListBase *tracks_cow)
674 while (track_orig !=
nullptr) {
675 update_nla_strips_orig_pointers(&track_orig->
strips, &track_cow->
strips);
676 track_cow = track_cow->
next;
677 track_orig = track_orig->
next;
681void update_animation_data_after_copy(
const ID *id_orig,
ID *id_cow)
684 if (anim_data_orig ==
nullptr) {
696void update_id_after_copy(
const Depsgraph *
depsgraph,
697 const IDNode *id_node,
702 update_animation_data_after_copy(id_orig, id_cow);
709 object_cow->
mode = object_orig->
mode;
716 if (armature_orig->
edbo ==
nullptr) {
717 update_pose_orig_pointers(object_orig->
pose, object_cow->
pose);
721 update_particles_after_copy(
depsgraph, object_orig, object_cow);
726 const Scene *scene_orig = (
const Scene *)id_orig;
728 scene_setup_view_layers_after_remap(
depsgraph, id_node,
reinterpret_cast<Scene *
>(id_cow));
744 update_edit_mode_pointers(
depsgraph, id_orig, id_cow);
755 if (*id_p !=
nullptr) {
756 if (!check_datablock_expanded(*id_p)) {
757 data->is_valid =
false;
768ID *deg_expand_eval_copy_datablock(
const Depsgraph *
depsgraph,
const IDNode *id_node)
770 const ID *id_orig = id_node->id_orig;
771 ID *id_cow = id_node->id_cow;
772 const int id_cow_recalc = id_cow->
recalc;
781 "Expanding datablock for %s: id_orig=%p id_cow=%p\n", id_orig->
name, id_orig, id_cow);
784 BLI_assert(check_datablock_expanded(id_cow) ==
false);
804 done = scene_copy_inplace_no_main((
Scene *)id_orig, (
Scene *)id_cow);
808 scene_setup_view_layers_before_remap(
depsgraph, id_node, (
Scene *)id_cow);
821 done = id_copy_inplace_no_main(id_orig, id_cow);
824 BLI_assert_msg(0,
"No idea how to perform evaluated copy on datablock");
828 " Remapping ID links for %s: id_orig=%p id_cow=%p\n", id_orig->
name, id_orig, id_cow);
830#ifdef NESTED_ID_NASTY_WORKAROUND
831 ntree_hack_remap_pointers(
depsgraph, id_cow);
837 RemapCallbackUserData user_data = {
nullptr};
853 update_id_after_copy(
depsgraph, id_node, id_orig, id_cow);
854 id_cow->
recalc = id_cow_recalc;
888 update_edit_mode_pointers(
depsgraph, id_orig, id_cow);
896 deg_expand_eval_copy_datablock(
depsgraph, id_node);
912void discard_armature_edit_mode_pointers(
ID *id_cow)
915 armature_cow->
edbo =
nullptr;
918void discard_curve_edit_mode_pointers(
ID *id_cow)
925void discard_mball_edit_mode_pointers(
ID *id_cow)
931void discard_lattice_edit_mode_pointers(
ID *id_cow)
937void discard_mesh_edit_mode_pointers(
ID *id_cow)
940 mesh_cow->
runtime->edit_mesh =
nullptr;
943void discard_scene_pointers(
ID *id_cow)
951void discard_edit_mode_pointers(
ID *id_cow)
956 discard_armature_edit_mode_pointers(id_cow);
959 discard_mesh_edit_mode_pointers(id_cow);
962 discard_curve_edit_mode_pointers(id_cow);
965 discard_mball_edit_mode_pointers(id_cow);
968 discard_lattice_edit_mode_pointers(id_cow);
973 discard_scene_pointers(id_cow);
990 if (!check_datablock_expanded(id_cow)) {
996#ifdef NESTED_ID_NASTY_WORKAROUND
997 nested_id_hack_discard_pointers(id_cow);
1005 ob_cow->
data =
nullptr;
1006 ob_cow->
sculpt =
nullptr;
1012 discard_edit_mode_pointers(id_cow);
1017 id_cow->
name[0] =
'\0';
1034 if (id_cow ==
nullptr) {
1038 data.is_valid =
true;
1040 nullptr, id_cow, foreach_libblock_validate_callback, &
data,
IDWALK_NOP);
1041 return data.is_valid;
1057 return check_datablock_expanded(id_cow);
Blender kernel action and pose functionality.
AnimData * BKE_animdata_from_id(const ID *id)
void BKE_animsys_update_driver_array(struct ID *id)
void BKE_pose_pchan_index_rebuild(bPose *pose)
void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
void BKE_gpencil_data_update_orig_pointers(const struct bGPdata *gpd_orig, const struct bGPdata *gpd_eval)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_free_object_content(ViewLayer *view_layer)
ViewLayer * BKE_view_layer_default_render(const Scene *scene)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_libblock_free_data_py(ID *id)
void BKE_libblock_free_datablock(ID *id, int flag) ATTR_NONNULL()
void BKE_libblock_free_data(ID *id, bool do_id_user) ATTR_NONNULL()
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
@ LIB_ID_CREATE_NO_ALLOCATE
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
@ IDWALK_IGNORE_MISSING_OWNER_ID
@ IDWALK_IGNORE_EMBEDDED_ID
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, int flag)
General operations, lookup, etc. for blender objects.
void BKE_object_check_uids_unique_and_report(const Object *object)
bool BKE_object_data_is_in_editmode(const Object *ob, const ID *id)
#define BLI_assert_msg(a, msg)
#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)
void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1
bool DEG_is_active(const Depsgraph *depsgraph)
void DEG_debug_print_eval(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_USE_COPY_ON_EVAL(_id_type)
@ eParticleSystemFlag_file_loaded
@ eModifierType_ParticleSystem
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_EDITMODE(_type)
Types and defines for representing Rigid Body entities.
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between world
BPy_StructRNA * depsgraph
void init_from_id(ID *id)
void restore_to_id(ID *id)
#define SPECIAL_CASE(id_type, dna_type, field)
#define DEG_COW_PRINT(format,...)
static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
void MEM_freeN(void *vmemh)
void deg_tag_eval_copy_id(deg::Depsgraph &depsgraph, ID *id_cow, const ID *id_orig)
void deg_create_eval_copy(::Depsgraph *graph, const IDNode *id_node)
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base)
bool deg_eval_copy_is_expanded(const ID *id_cow)
void deg_free_eval_copy_datablock(ID *id_cow)
bool deg_eval_copy_is_needed(const ID *id_orig)
ID * deg_update_eval_copy_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
bool deg_validate_eval_copy_datablock(ID *id_cow)
void SEQ_relations_check_uids_unique_and_report(const Scene *scene)
struct EditFont * editfont
struct Depsgraph * depsgraph
struct ID_Runtime runtime
struct EditLatt * editlatt
MeshRuntimeHandle * runtime
struct NlaStrip * orig_strip
ObjectRuntimeHandle * runtime
struct SculptSession * sculpt
struct ParticleSystemModifierData * psmd_eval
struct ParticleSystem * psys_eval
struct PTCacheEdit * edit
struct ParticleSystem * orig_psys
struct bNodeTree * nodetree
struct ToolSettings * toolsettings
struct EditBone * act_edbone
struct bGPDlayer * gpl_orig
bGPDlayer_Runtime runtime
struct bPoseChannel * orig_pchan
bool is_cow_explicitly_tagged