Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 14 Jun 2017 08:48:20 +0000 (10:48 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 14 Jun 2017 08:48:20 +0000 (10:48 +0200)
1  2 
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/library_remap.c

index ef2fa5a1b651f73a92caac67750812b85c0cf6b8,f1c0563b731f87f1e727461065eda7ee1609764b..f0ff719a619b15b8ca1c4be98b1b91e203f5ef56
@@@ -65,6 -65,7 +65,7 @@@ struct ID *BKE_libblock_find_name(cons
  
  /* library_remap.c (keep here since they're general functions) */
  void  BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
+ void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL();
  void  BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
  void  BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
  void  BKE_libblock_free_data(struct Main *bmain, struct ID *id, const bool do_id_user) ATTR_NONNULL();
@@@ -96,7 -97,7 +97,7 @@@ void id_clear_lib_data_ex(struct Main *
  
  struct ListBase *which_libbase(struct Main *mainlib, short type);
  
 -#define MAX_LIBARRAY    35
 +#define MAX_LIBARRAY    37
  int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
  
  /* Main API */
index be16e7ce448db370e6a3086c11259a680c9bfe91,668962cf6e411420421f94a96051ca45cfeb61a3..a5e8e41e738a2f99954b42dde0306beb4649e728
@@@ -53,7 -53,6 +53,7 @@@
  #include "DNA_mask_types.h"
  #include "DNA_node_types.h"
  #include "DNA_object_types.h"
 +#include "DNA_lightprobe_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_screen_types.h"
  #include "DNA_speaker_types.h"
@@@ -61,7 -60,6 +61,7 @@@
  #include "DNA_text_types.h"
  #include "DNA_vfont_types.h"
  #include "DNA_windowmanager_types.h"
 +#include "DNA_workspace_types.h"
  #include "DNA_world_types.h"
  
  #include "BLI_blenlib.h"
@@@ -73,8 -71,8 +73,8 @@@
  #include "BKE_brush.h"
  #include "BKE_camera.h"
  #include "BKE_cachefile.h"
 +#include "BKE_collection.h"
  #include "BKE_curve.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_fcurve.h"
  #include "BKE_font.h"
  #include "BKE_group.h"
  #include "BKE_object.h"
  #include "BKE_paint.h"
  #include "BKE_particle.h"
 +#include "BKE_lightprobe.h"
  #include "BKE_sca.h"
  #include "BKE_speaker.h"
  #include "BKE_sound.h"
  #include "BKE_scene.h"
  #include "BKE_text.h"
  #include "BKE_texture.h"
 +#include "BKE_workspace.h"
  #include "BKE_world.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +
  #ifdef WITH_PYTHON
  #include "BPY_extern.h"
  #endif
@@@ -226,7 -219,7 +226,7 @@@ static int foreach_libblock_remap_callb
                else {
                        if (!is_never_null) {
                                *id_p = new_id;
 -                              DAG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +                              DEG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
                        }
                        if (cb_flag & IDWALK_CB_USER) {
                                id_us_min(old_id);
  
  /* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
  static void libblock_remap_data_preprocess_scene_base_unlink(
 -        IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
 +        IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
  {
        if (skip_indirect && is_indirect) {
                r_id_remap_data->skipped_indirect++;
        }
  }
  
 +/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
 +static void libblock_remap_data_preprocess_scene_object_unlink(
 +        IDRemap *r_id_remap_data, Scene *sce, Object *ob, const bool skip_indirect, const bool is_indirect)
 +{
 +      if (skip_indirect && is_indirect) {
 +              r_id_remap_data->skipped_indirect++;
 +              r_id_remap_data->skipped_refcounted++;
 +      }
 +      else {
 +              BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
 +              if (!is_indirect) {
 +                      r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
 +              }
 +      }
 +}
 +
  static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
  {
        switch (GS(r_id_remap_data->id->name)) {
                                /* In case we are unlinking... */
                                if (!r_id_remap_data->old_id) {
                                        /* ... everything from scene. */
 -                                      Base *base, *base_next;
 +                                      FOREACH_SCENE_OBJECT(sce, ob_iter)
 +                                      {
 +                                              libblock_remap_data_preprocess_scene_object_unlink(
 +                                                          r_id_remap_data, sce, ob_iter, skip_indirect, is_indirect);
 +                                      }
 +                                      FOREACH_SCENE_OBJECT_END
 +
 +
 +                                      BaseLegacy *base, *base_next;
                                        for (base = sce->base.first; base; base = base_next) {
                                                base_next = base->next;
                                                libblock_remap_data_preprocess_scene_base_unlink(
                                else if (GS(r_id_remap_data->old_id->name) == ID_OB) {
                                        /* ... a specific object from scene. */
                                        Object *old_ob = (Object *)r_id_remap_data->old_id;
 -                                      Base *base = BKE_scene_base_find(sce, old_ob);
  
 +                                      libblock_remap_data_preprocess_scene_object_unlink(
 +                                                  r_id_remap_data, sce, old_ob, skip_indirect, is_indirect);
 +
 +                                      BaseLegacy *base = BKE_scene_base_find(sce, old_ob);
                                        if (base) {
                                                libblock_remap_data_preprocess_scene_base_unlink(
                                                            r_id_remap_data, sce, base, skip_indirect, is_indirect);
@@@ -364,7 -330,7 +364,7 @@@ static void libblock_remap_data_postpro
                }
                if (new_ob == NULL) {  /* We need to remove NULL-ified groupobjects... */
                        for (Group *group = bmain->group.first; group; group = group->id.next) {
 -                              BKE_group_object_unlink(group, NULL, NULL, NULL);
 +                              BKE_group_object_unlink(group, NULL);
                        }
                }
                else {
@@@ -377,17 -343,23 +377,17 @@@ static void libblock_remap_data_postpro
  {
        /* Note that here we assume no object has no base (i.e. all objects are assumed instanced
         * in one scene...). */
 -      for (Base *base = sce->base.first; base; base = base->next) {
 -              if (base->flag & OB_FROMGROUP) {
 -                      Object *ob = base->object;
 -
 -                      if (ob->flag & OB_FROMGROUP) {
 -                              Group *grp = BKE_group_object_find(NULL, ob);
 -
 -                              /* Unlinked group (old_id) is still in bmain... */
 -                              if (grp && (&grp->id == old_id || grp->id.us == 0)) {
 -                                      grp = BKE_group_object_find(grp, ob);
 -                              }
 -                              if (!grp) {
 -                                      ob->flag &= ~OB_FROMGROUP;
 -                              }
 +      for (BaseLegacy *base = sce->base.first; base; base = base->next) {
 +              Object *ob = base->object;
 +              if (ob->flag & OB_FROMGROUP) {
 +                      Group *grp = BKE_group_object_find(NULL, ob);
 +
 +                      /* Unlinked group (old_id) is still in bmain... */
 +                      if (grp && (&grp->id == old_id || grp->id.us == 0)) {
 +                              grp = BKE_group_object_find(grp, ob);
                        }
 -                      if (!(ob->flag & OB_FROMGROUP)) {
 -                              base->flag &= ~OB_FROMGROUP;
 +                      if (!grp) {
 +                              ob->flag &= ~OB_FROMGROUP;
                        }
                }
        }
@@@ -605,7 -577,7 +605,7 @@@ void BKE_libblock_remap_locked
        BKE_main_lock(bmain);
  
        /* Full rebuild of DAG! */
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
  }
  
  void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
@@@ -759,30 -731,9 +759,9 @@@ void BKE_libblock_free_data(Main *UNUSE
        }
  }
  
- /**
-  * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
-  *
-  * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
-  *                    (only applies to main database)
-  * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
-  *                    \a id.
-  */
- void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+ void BKE_libblock_free_datablock(ID *id)
  {
-       ID *id = idv;
-       short type = GS(id->name);
-       ListBase *lb = which_libbase(bmain, type);
-       DEG_id_type_tag(bmain, type);
- #ifdef WITH_PYTHON
-       BPY_id_release(id);
- #endif
-       if (do_id_user) {
-               BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
-       }
+       const short type = GS(id->name);
        switch (type) {
                case ID_SCE:
                        BKE_scene_free((Scene *)id);
                case ID_SPK:
                        BKE_speaker_free((Speaker *)id);
                        break;
 +              case ID_LP:
 +                      BKE_lightprobe_free((LightProbe *)id);
 +                      break;
                case ID_SO:
                        BKE_sound_free((bSound *)id);
                        break;
                case ID_CF:
                        BKE_cachefile_free((CacheFile *)id);
                        break;
 +              case ID_WS:
 +                      BKE_workspace_free((WorkSpace *)id);
 +                      break;
        }
 -      DAG_id_type_tag(bmain, type);
+ }
+ /**
+  * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
+  *
+  * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
+  *                    (only applies to main database)
+  * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
+  *                    \a id.
+  */
+ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+ {
+       ID *id = idv;
+       short type = GS(id->name);
+       ListBase *lb = which_libbase(bmain, type);
++      DEG_id_type_tag(bmain, type);
+ #ifdef WITH_PYTHON
+       BPY_id_release(id);
+ #endif
+       if (do_id_user) {
+               BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+       }
+       BKE_libblock_free_datablock(id);
  
        /* avoid notifying on removed data */
        BKE_main_lock(bmain);