Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Mon, 26 Jun 2017 23:57:40 +0000 (09:57 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 26 Jun 2017 23:59:36 +0000 (09:59 +1000)
1  2 
CMakeLists.txt
GNUmakefile
build_files/build_environment/install_deps.sh
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/library_remap.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/windowmanager/intern/wm_files_link.c

diff --combined CMakeLists.txt
index 3da27fb52d5bc64e1fb8344fef7d2237981243c4,04237812d8709995298c167182b150684769c188..3adf5825fa45a6c3f3daece11a89bcb02fb1750c
@@@ -58,7 -58,9 +58,9 @@@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/platform")
  
  # avoid having empty buildtype
- set(CMAKE_BUILD_TYPE_INIT "Release")
+ if(NOT DEFINED CMAKE_BUILD_TYPE_INIT)
+       set(CMAKE_BUILD_TYPE_INIT "Release")
+ endif()
  
  # quiet output for Makefiles, 'make -s' helps too
  # set_property(GLOBAL PROPERTY RULE_MESSAGES OFF)
@@@ -242,8 -244,6 +244,8 @@@ endif(
  option(WITH_PLAYER        "Build Player" OFF)
  option(WITH_OPENCOLORIO   "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
  
 +option(WITH_CLAY_ENGINE    "Enable Clay engine" ON)
 +
  # Compositor
  option(WITH_COMPOSITOR         "Enable the tile based nodal compositor" ON)
  
@@@ -464,16 -464,28 +466,16 @@@ endif(
  
  # OpenGL
  
 -option(WITH_GLEW_MX             "Support multiple GLEW contexts (experimental)"                                                                     OFF )
  option(WITH_GLEW_ES             "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
  option(WITH_GL_EGL              "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, glX, or WGL)"       OFF)
 -option(WITH_GL_PROFILE_COMPAT   "Support using the OpenGL 'compatibility' profile. (deprecated)"                                                    ON )
 -option(WITH_GL_PROFILE_CORE     "Support using the OpenGL 3.2+ 'core' profile."                                                                     OFF)
  option(WITH_GL_PROFILE_ES20     "Support using OpenGL ES 2.0. (thru either EGL or the AGL/WGL/XGL 'es20' profile)"                                  OFF)
  
  mark_as_advanced(
 -      WITH_GLEW_MX
        WITH_GLEW_ES
        WITH_GL_EGL
 -      WITH_GL_PROFILE_COMPAT
 -      WITH_GL_PROFILE_CORE
        WITH_GL_PROFILE_ES20
  )
  
 -if(WITH_GL_PROFILE_COMPAT)
 -      set(WITH_GLU ON)
 -else()
 -      set(WITH_GLU OFF)
 -endif()
 -
  if(WIN32)
        option(WITH_GL_ANGLE "Link with the ANGLE library, an OpenGL ES 2.0 implementation based on Direct3D, instead of the system OpenGL library." OFF)
        mark_as_advanced(WITH_GL_ANGLE)
@@@ -494,10 -506,11 +496,10 @@@ endif(
  # We default options to whatever default standard in the current compiler.
  if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11))
        set(_c11_init ON)
 -      set(_cxx11_init ON)
  else()
        set(_c11_init OFF)
 -      set(_cxx11_init OFF)
  endif()
 +set(_cxx11_init ON)
  
  option(WITH_C11 "Build with C11 standard enabled, for development use only!" ${_c11_init})
  mark_as_advanced(WITH_C11)
@@@ -511,8 -524,8 +513,8 @@@ if(CMAKE_COMPILER_IS_GNUCC
  endif()
  
  # Dependency graph
 -option(WITH_LEGACY_DEPSGRAPH "Build Blender with legacy dependency graph" ON)
 -mark_as_advanced(WITH_LEGACY_DEPSGRAPH)
 +option(WITH_DEPSGRAPH_COPY_ON_WRITE "Build Blender with copy-on-write support for dependency graph" OFF)
 +mark_as_advanced(WITH_DEPSGRAPH_COPY_ON_WRITE)
  
  if(WIN32)
        # Use hardcoded paths or find_package to find externals
@@@ -950,11 -963,19 +952,11 @@@ endif(
  find_package(OpenGL)
  blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
  
 -if(WITH_GLU)
 -      list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_glu_LIBRARY}")
 -      list(APPEND GL_DEFINITIONS -DWITH_GLU)
 -endif()
 -
  if(WITH_SYSTEM_GLES)
        find_package_wrapper(OpenGLES)
  endif()
  
 -if(WITH_GL_PROFILE_COMPAT OR WITH_GL_PROFILE_CORE)
 -      list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_gl_LIBRARY}")
 -
 -elseif(WITH_GL_PROFILE_ES20)
 +if(WITH_GL_PROFILE_ES20)
        if(WITH_SYSTEM_GLES)
                if(NOT OPENGLES_LIBRARY)
                        message(FATAL_ERROR
  
        endif()
  
 +else()
 +      list(APPEND BLENDER_GL_LIBRARIES "${OPENGL_gl_LIBRARY}")
 +
  endif()
  
  if(WITH_GL_EGL)
  
  endif()
  
 -if(WITH_GL_PROFILE_COMPAT)
 -      list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_COMPAT)
 -endif()
 -
 -if(WITH_GL_PROFILE_CORE)
 -      list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_CORE)
 -endif()
 -
  if(WITH_GL_PROFILE_ES20)
        list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_ES20)
 +else()
 +      list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_CORE)
  endif()
  
  if(WITH_GL_EGL)
@@@ -1104,6 -1128,10 +1106,6 @@@ endif(
  #-----------------------------------------------------------------------------
  # Configure GLEW
  
 -if(WITH_GLEW_MX)
 -      list(APPEND GL_DEFINITIONS -DWITH_GLEW_MX)
 -endif()
 -
  if(WITH_SYSTEM_GLEW)
        find_package(GLEW)
  
                message(FATAL_ERROR "GLEW is required to build Blender. Install it or disable WITH_SYSTEM_GLEW.")
        endif()
  
 -      if(WITH_GLEW_MX)
 -              set(BLENDER_GLEW_LIBRARIES ${GLEW_MX_LIBRARY})
 -      else()
 -              set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
 -      endif()
 +      set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
  else()
        if(WITH_GLEW_ES)
                set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew-es/include")
                list(APPEND GL_DEFINITIONS -DGLEW_STATIC -DWITH_GLEW_ES)
  
                # These definitions remove APIs from glew.h, making GLEW smaller, and catching unguarded API usage
 -              if(NOT WITH_GL_PROFILE_ES20)
 +              if(WITH_GL_PROFILE_ES20)
 +                      list(APPEND GL_DEFINITIONS -DGLEW_ES_ONLY)
 +              else()
                        # No ES functions are needed
                        list(APPEND GL_DEFINITIONS -DGLEW_NO_ES)
 -              elseif(NOT (WITH_GL_PROFILE_CORE OR WITH_GL_PROFILE_COMPAT))
 -                      # ES is enabled, but the other functions are all disabled
 -                      list(APPEND GL_DEFINITIONS -DGLEW_ES_ONLY)
                endif()
  
                if(WITH_GL_PROFILE_ES20)
  
  endif()
  
 -if(NOT WITH_GLU)
 -      list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
 -endif()
 +list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
  
  #-----------------------------------------------------------------------------
  # Configure Bullet
@@@ -1707,7 -1742,10 +1709,7 @@@ if(FIRST_RUN
  
        info_cfg_text("OpenGL:")
        info_cfg_option(WITH_GLEW_ES)
 -      info_cfg_option(WITH_GLU)
        info_cfg_option(WITH_GL_EGL)
 -      info_cfg_option(WITH_GL_PROFILE_COMPAT)
 -      info_cfg_option(WITH_GL_PROFILE_CORE)
        info_cfg_option(WITH_GL_PROFILE_ES20)
        if(WIN32)
                info_cfg_option(WITH_GL_ANGLE)
diff --combined GNUmakefile
index 7ee011911f82c96fc6b385341bf1c706ee5597de,ba7f89c3097317b5f3a06be36323748fca941872..dbba6ffab8e9cf21556921e8a291bda55188606e
@@@ -104,7 -104,7 +104,7 @@@ endi
  CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \
                       -H"$(BLENDER_DIR)" \
                       -B"$(BUILD_DIR)" \
-                      -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE)
+                      -DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE)
  
  
  # -----------------------------------------------------------------------------
@@@ -402,7 -402,7 +402,7 @@@ update: .FORC
                svn update ../lib/* ; \
        fi
        git pull --rebase
 -      git submodule foreach git pull --rebase origin master
 +      git submodule update --remote
  
  
  # -----------------------------------------------------------------------------
index cab67e68e0ee129ec3db1a5341e165a8c5a7b385,3852b4fe7057d103b8205a5b0a0288783cb6ab10..ad9ef3f8594ceb9d3f2ee173276698b429dd0936
@@@ -25,8 -25,8 +25,8 @@@
  ARGS=$( \
  getopt \
  -o s:i:t:h \
 ---long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,use-cxx11,\
 +--long source:,install:,tmp:,info:,threads:,help,show-deps,no-sudo,no-build,no-confirm,\
- with-all,with-opencollada,\
+ with-all,with-opencollada,with-jack,\
  ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\
  force-all,force-python,force-numpy,force-boost,\
  force-ocio,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\
@@@ -104,6 -104,11 +104,6 @@@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENT
      --no-confirm
          Disable any interaction with user (suitable for automated run).
  
 -    --use-cxx11
 -        Build all libraries in cpp11 'mode' (will be mandatory soon in blender2.8 branch).
 -        NOTE: If your compiler is gcc-6.0 or above, you probably *want* to enable this option (since it's default
 -              standard starting from this version).
 -
      --with-all
          By default, a number of optional and not-so-often needed libraries are not installed.
          This option will try to install them, at the cost of potential conflicts (depending on
      --with-opencollada
          Build and install the OpenCOLLADA libraries.
  
+     --with-jack
+         Install the jack libraries.
      --ver-ocio=<ver>
          Force version of OCIO library.
  
@@@ -282,7 -290,7 +285,7 @@@ SUDO="sudo
  
  NO_BUILD=false
  NO_CONFIRM=false
 -USE_CXX11=false
 +USE_CXX11=true  # Mandatory in blender2.8
  
  PYTHON_VERSION="3.5.3"
  PYTHON_VERSION_MIN="3.5"
@@@ -493,12 -501,18 +496,15 @@@ while true; d
      --no-confirm)
        NO_CONFIRM=true; shift; continue
      ;;
 -    --use-cxx11)
 -      USE_CXX11=true; shift; continue
 -    ;;
      --with-all)
        WITH_ALL=true; shift; continue
      ;;
      --with-opencollada)
        WITH_OPENCOLLADA=true; shift; continue
      ;;
+     --with-jack)
+       WITH_JACK=true; shift; continue;
+     ;;
      --ver-ocio)
        OCIO_VERSION="$2"
        OCIO_VERSION_MIN=$OCIO_VERSION
@@@ -702,6 -716,9 +708,9 @@@ don
  if [ "$WITH_ALL" = true -a "$OPENCOLLADA_SKIP" = false ]; then
    WITH_OPENCOLLADA=true
  fi
+ if [ "$WITH_ALL" = true ]; then
+   WITH_JACK=true
+ fi
  
  
  WARNING "****WARNING****"
@@@ -787,7 -804,7 +796,7 @@@ FFMPEG_SOURCE=( "http://ffmpeg.org/rele
  
  CXXFLAGS_BACK=$CXXFLAGS
  if [ "$USE_CXX11" = true ]; then
 -  WARNING "You are trying to use c++11, this *should* go smoothely with any very recent distribution
 +  WARNING "C++11 is now mandatory for blender2.8, this *should* go smoothly with any very recent distribution.
  However, if you are experiencing linking errors (also when building Blender itself), please try the following:
      * Re-run this script with '--build-all --force-all' options.
      * Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above.
@@@ -2644,7 -2661,7 +2653,7 @@@ install_DEB() 
      PRINT ""
    fi
  
-   if [ "$WITH_ALL" = true ]; then
+   if [ "$WITH_JACK" = true ]; then
      _packages="$_packages libspnav-dev"
      # Only install jack if jack2 is not already installed!
      JACK="libjack-dev"
@@@ -3181,7 -3198,7 +3190,7 @@@ install_RPM() 
    if [ "$RPM" = "FEDORA" -o "$RPM" = "RHEL" ]; then
      _packages="$_packages freetype-devel tbb-devel"
  
-     if [ "$WITH_ALL" = true ]; then
+     if [ "$WITH_JACK" = true ]; then
        _packages="$_packages jack-audio-connection-kit-devel"
      fi
  
@@@ -3655,7 -3672,11 +3664,11 @@@ install_ARCH() 
    THEORA_USE=true
  
    if [ "$WITH_ALL" = true ]; then
-     _packages="$_packages jack libspnav"
+     _packages="$_packages libspnav"
+   fi
+   if [ "$WITH_JACK" = true ]; then
+     _packages="$_packages jack"
    fi
  
    PRINT ""
@@@ -4317,6 -4338,14 +4330,14 @@@ print_info() 
      _buildargs="$_buildargs $_1"
    fi
  
+   if [ "$WITH_JACK" = true ]; then
+     _1="-D WITH_JACK=ON"
+     _2="-D WITH_JACK_DYNLOAD=ON"
+     PRINT "  $_1"
+     PRINT "  $_2"
+     _buildargs="$_buildargs $_1 $_2"
+   fi
    if [ "$ALEMBIC_SKIP" = false ]; then
      _1="-D WITH_ALEMBIC=ON"
      PRINT "  $_1"
index 8a42a3334bd83ab5718146591afa8b13a266349f,d1f0c87183d86d2763cad1546f192dae340b5af1..e397dcf76674eb8b20d137fa9d16d365bf25c0c1
@@@ -52,7 -52,6 +52,7 @@@
  #include "DNA_mask_types.h"
  #include "DNA_node_types.h"
  #include "DNA_object_force.h"
 +#include "DNA_lightprobe_types.h"
  #include "DNA_rigidbody_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_sensor_types.h"
@@@ -62,8 -61,6 +62,8 @@@
  #include "DNA_sound_types.h"
  #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_utildefines.h"
@@@ -72,7 -69,6 +72,7 @@@
  #include "BLI_linklist_stack.h"
  
  #include "BKE_animsys.h"
 +#include "BKE_collection.h"
  #include "BKE_constraint.h"
  #include "BKE_fcurve.h"
  #include "BKE_idprop.h"
@@@ -86,7 -82,6 +86,7 @@@
  #include "BKE_sca.h"
  #include "BKE_sequencer.h"
  #include "BKE_tracking.h"
 +#include "BKE_workspace.h"
  
  
  #define FOREACH_FINALIZE _finalize
@@@ -408,7 -403,7 +408,7 @@@ void BKE_library_foreach_ID_link(Main *
                                Scene *scene = (Scene *) id;
                                ToolSettings *toolsett = scene->toolsettings;
                                SceneRenderLayer *srl;
 -                              Base *base;
 +                              BaseLegacy *legacy_base;
  
                                CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
                                CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
  
                                CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
  
 -                              for (base = scene->base.first; base; base = base->next) {
 -                                      CALLBACK_INVOKE(base->object, IDWALK_CB_USER);
 +                              for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
 +                                      CALLBACK_INVOKE(legacy_base->object, IDWALK_CB_USER);
 +                              }
 +
 +                              FOREACH_SCENE_COLLECTION(scene, sc)
 +                              {
 +                                      for (LinkData *link = sc->objects.first; link; link = link->next) {
 +                                              CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
 +                                      }
 +
 +                                      for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
 +                                              CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
 +                                      }
 +                              }
 +                              FOREACH_SCENE_COLLECTION_END
 +
 +                              SceneLayer *sl;
 +                              for (sl = scene->render_layers.first; sl; sl = sl->next) {
 +                                      for (Base *base = sl->object_bases.first; base; base = base->next) {
 +                                              CALLBACK_INVOKE(base->object, IDWALK_NOP);
 +                                      }
                                }
  
                                for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {
  
                                /* Object is special, proxies make things hard... */
                                const int data_cb_flag = data.cb_flag;
-                               const int proxy_cb_flag = (object->proxy || object->proxy_group) ? IDWALK_CB_INDIRECT_USAGE : 0;
+                               const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 && (object->proxy || object->proxy_group)) ?
+                                                             IDWALK_CB_INDIRECT_USAGE : 0;
  
                                /* object data special case */
                                data.cb_flag |= proxy_cb_flag;
                                for (i = 0; i < mesh->totcol; i++) {
                                        CALLBACK_INVOKE(mesh->mat[i], IDWALK_CB_USER);
                                }
 -
 -                              /* XXX Really not happy with this - probably texface should rather use some kind of
 -                               * 'texture slots' and just set indices in each poly/face item - would also save some memory.
 -                               * Maybe a nice TODO for blender2.8? */
 -                              if (mesh->mtface || mesh->mtpoly) {
 -                                      for (i = 0; i < mesh->pdata.totlayer; i++) {
 -                                              if (mesh->pdata.layers[i].type == CD_MTEXPOLY) {
 -                                                      MTexPoly *txface = (MTexPoly *)mesh->pdata.layers[i].data;
 -
 -                                                      for (int j = 0; j < mesh->totpoly; j++, txface++) {
 -                                                              CALLBACK_INVOKE(txface->tpage, IDWALK_CB_USER_ONE);
 -                                                      }
 -                                              }
 -                                      }
 -
 -                                      for (i = 0; i < mesh->fdata.totlayer; i++) {
 -                                              if (mesh->fdata.layers[i].type == CD_MTFACE) {
 -                                                      MTFace *tface = (MTFace *)mesh->fdata.layers[i].data;
 -
 -                                                      for (int j = 0; j < mesh->totface; j++, tface++) {
 -                                                              CALLBACK_INVOKE(tface->tpage, IDWALK_CB_USER_ONE);
 -                                                      }
 -                                              }
 -                                      }
 -                              }
                                break;
                        }
  
                                        library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data);
                                }
                                CALLBACK_INVOKE(material->group, IDWALK_CB_USER);
 +                              CALLBACK_INVOKE(material->edit_image, IDWALK_CB_USER);
                                break;
                        }
  
                                break;
                        }
  
 -                      case ID_SCR:
 -                      {
 -                              bScreen *screen = (bScreen *) id;
 -                              CALLBACK_INVOKE(screen->scene, IDWALK_CB_USER_ONE);
 -                              break;
 -                      }
 -
                        case ID_WO:
                        {
                                World *world = (World *) id;
                                break;
                        }
  
 +                      case ID_LP:
 +                      {
 +                              LightProbe *probe = (LightProbe *) id;
 +                              CALLBACK_INVOKE(probe->image, IDWALK_CB_USER);
 +                              break;
 +                      }
 +
                        case ID_GR:
                        {
                                Group *group = (Group *) id;
                                }
                                break;
                        }
 +
 +                      case ID_WM:
 +                      {
 +                              wmWindowManager *wm = (wmWindowManager *)id;
 +
 +                              for (wmWindow *win = wm->windows.first; win; win = win->next) {
 +                                      ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
 +
 +                                      CALLBACK_INVOKE(win->scene, IDWALK_CB_USER_ONE);
 +
 +                                      CALLBACK_INVOKE_ID(workspace, IDWALK_CB_NOP);
 +                                      /* allow callback to set a different workspace */
 +                                      BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
 +                              }
 +                              break;
 +                      }
 +
 +                      case ID_WS:
 +                      {
 +                              WorkSpace *workspace = (WorkSpace *)id;
 +                              ListBase *layouts = BKE_workspace_layouts_get(workspace);
 +
 +                              for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
 +                                      bScreen *screen = BKE_workspace_layout_screen_get(layout);
 +
 +                                      CALLBACK_INVOKE(screen, IDWALK_CB_NOP);
 +                                      /* allow callback to set a different screen */
 +                                      BKE_workspace_layout_screen_set(layout, screen);
 +                              }
 +
 +                              break;
 +                      }
                        case ID_GD:
                        {
                                bGPdata *gpencil = (bGPdata *) id;
                        }
  
                        /* Nothing needed for those... */
 +                      case ID_SCR:
                        case ID_IM:
                        case ID_VF:
                        case ID_TXT:
                        case ID_SO:
 -                      case ID_WM:
                        case ID_PAL:
                        case ID_PC:
                        case ID_CF:
@@@ -1142,9 -1111,6 +1143,9 @@@ bool BKE_library_id_can_use_idtype(ID *
                        return ELEM(id_type_used, ID_MC);  /* WARNING! mask->parent.id, not typed. */
                case ID_LS:
                        return (ELEM(id_type_used, ID_TE, ID_OB));
 +              case ID_LP:
 +                      return ELEM(id_type_used, ID_IM);
 +              case ID_WS:
                case ID_IM:
                case ID_VF:
                case ID_TXT:
index f855de0dac5f21cec0cd2142d9c06c6bbaa3e572,5e5ba44f0399c5d3f4d32b63ed344a4578a7fb6a..a260dffea2f2d16cd7caccdd7fabf0358a0dc571
@@@ -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;
                        }
                }
        }
@@@ -447,6 -419,7 +447,7 @@@ ATTR_NONNULL(1) static void libblock_re
        IDRemap id_remap_data;
        ListBase *lb_array[MAX_LIBARRAY];
        int i;
+       const int foreach_id_flags = (remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ? IDWALK_NO_INDIRECT_PROXY_DATA_USAGE : IDWALK_NOP;
  
        if (r_id_remap_data == NULL) {
                r_id_remap_data = &id_remap_data;
  #endif
                r_id_remap_data->id = id;
                libblock_remap_data_preprocess(r_id_remap_data);
-               BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+               BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags);
        }
        else {
                i = set_listbasepointers(bmain, lb_array);
                                        r_id_remap_data->id = id_curr;
                                        libblock_remap_data_preprocess(r_id_remap_data);
                                        BKE_library_foreach_ID_link(
-                                                   NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+                                                   NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags);
                                }
                        }
                }
@@@ -605,7 -578,7 +606,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)
@@@ -820,9 -793,6 +821,9 @@@ void BKE_libblock_free_datablock(ID *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;
        }
  }
  
@@@ -889,7 -856,7 +890,7 @@@ void BKE_libblock_free_ex(Main *bmain, 
        short type = GS(id->name);
        ListBase *lb = which_libbase(bmain, type);
  
 -      DAG_id_type_tag(bmain, type);
 +      DEG_id_type_tag(bmain, type);
  
  #ifdef WITH_PYTHON
        BPY_id_release(id);
index 49d7c6856b94e77205db64c167490b9a1ba874b1,265a19b9e7eeb486107aafa872575c17fd0989e9..17d7c8967dece1408fd902768c9c27c6582ec4ae
@@@ -51,9 -51,9 +51,9 @@@
  
  #include "BKE_animsys.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_idcode.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_library_query.h"
  #include "BKE_library_remap.h"
@@@ -64,8 -64,6 +64,8 @@@
  #include "BKE_material.h"
  #include "BKE_group.h"
  
 +#include "DEG_depsgraph_build.h"
 +
  #include "../blenloader/BLO_readfile.h"
  
  #include "ED_object.h"
@@@ -150,46 -148,8 +150,46 @@@ TreeElement *outliner_dropzone_find(con
        return NULL;
  }
  
 +
  /* ************************************************************** */
 -/* Click Activated */
 +
 +/* Highlight --------------------------------------------------- */
 +
 +static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
 +{
 +      ARegion *ar = CTX_wm_region(C);
 +      SpaceOops *soops = CTX_wm_space_outliner(C);
 +      const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
 +
 +      TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
 +      bool changed = false;
 +
 +      if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
 +              changed = outliner_set_flag(&soops->tree, TSE_HIGHLIGHTED, false);
 +              if (hovered_te) {
 +                      hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
 +                      changed = true;
 +              }
 +      }
 +
 +      if (changed) {
 +              soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
 +              ED_region_tag_redraw(ar);
 +      }
 +
 +      return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
 +}
 +
 +void OUTLINER_OT_highlight_update(wmOperatorType *ot)
 +{
 +      ot->name = "Update Highlight";
 +      ot->idname = "OUTLINER_OT_highlight_update";
 +      ot->description = "Update the item highlight based on the current mouse position";
 +
 +      ot->invoke = outliner_highlight_update;
 +
 +      ot->poll = ED_operator_outliner_active;
 +}
  
  /* Toggle Open/Closed ------------------------------------------- */
  
@@@ -256,11 -216,8 +256,11 @@@ void OUTLINER_OT_item_openclose(wmOpera
  
  /* Rename --------------------------------------------------- */
  
 -static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports)
 +static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
 +                           ReportList *reports)
  {
 +      bool add_textbut = false;
 +
        /* can't rename rna datablocks entries or listbases */
        if (ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) {
                /* do nothing */;
        else if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
                BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
        }
 +      else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
 +              SceneCollection *master = BKE_collection_master(scene);
 +
 +              if ((tselem->type == TSE_SCENE_COLLECTION && te->directdata == master) ||
 +                  (((LayerCollection *)te->directdata)->scene_collection == master))
 +              {
 +                      BKE_report(reports, RPT_WARNING, "Cannot edit name of master collection");
 +              }
 +              else {
 +                      add_textbut = true;
 +              }
 +      }
        else if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
                BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
        }
                BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library");
        }
        else {
 +              add_textbut = true;
 +      }
 +
 +      if (add_textbut) {
                tselem->flag |= TSE_TEXTBUT;
                ED_region_tag_redraw(ar);
        }
  }
  
  void item_rename_cb(
 -        bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *te,
 +        bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
          TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
  {
        ARegion *ar = CTX_wm_region(C);
 -      do_item_rename(ar, te, tselem, reports);
 +      do_item_rename(scene, ar, te, tselem, reports);
  }
  
 -static int do_outliner_item_rename(ReportList *reports, ARegion *ar, TreeElement *te, const float mval[2])
 +static int do_outliner_item_rename(const Scene *scene, ReportList *reports, ARegion *ar, TreeElement *te,
 +                                   const float mval[2])
  {
        if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
                TreeStoreElem *tselem = TREESTORE(te);
                
                /* click on name */
                if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
 -                      do_item_rename(ar, te, tselem, reports);
 +                      do_item_rename(scene, ar, te, tselem, reports);
                        return 1;
                }
                return 0;
        }
        
        for (te = te->subtree.first; te; te = te->next) {
 -              if (do_outliner_item_rename(reports, ar, te, mval)) return 1;
 +              if (do_outliner_item_rename(scene, reports, ar, te, mval)) return 1;
        }
        return 0;
  }
@@@ -340,7 -280,7 +340,7 @@@ static int outliner_item_rename(bContex
        UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
        
        for (te = soops->tree.first; te; te = te->next) {
 -              if (do_outliner_item_rename(op->reports, ar, te, fmval)) {
 +              if (do_outliner_item_rename(CTX_data_scene(C), op->reports, ar, te, fmval)) {
                        changed = true;
                        break;
                }
@@@ -493,7 -433,7 +493,7 @@@ static int outliner_id_remap_exec(bCont
        BKE_main_lib_objects_recalc_all(bmain);
  
        /* recreate dependency graph to include new objects */
 -      DAG_scene_relations_rebuild(bmain, scene);
 +      DEG_scene_relations_rebuild(bmain, scene);
  
        /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
        GPU_materials_free();
@@@ -804,34 -744,17 +804,34 @@@ int outliner_has_one_flag(ListBase *lb
        return 0;
  }
  
 -void outliner_set_flag(ListBase *lb, short flag, short set)
 +/**
 + * Set or unset \a flag for all outliner elements in \a lb and sub-trees.
 + * \return if any flag was modified.
 + */
 +bool outliner_set_flag(ListBase *lb, short flag, short set)
  {
        TreeElement *te;
        TreeStoreElem *tselem;
 -      
 +      bool changed = false;
 +      bool has_flag;
 +
        for (te = lb->first; te; te = te->next) {
                tselem = TREESTORE(te);
 -              if (set == 0) tselem->flag &= ~flag;
 -              else tselem->flag |= flag;
 -              outliner_set_flag(&te->subtree, flag, set);
 +              has_flag = (tselem->flag & flag);
 +              if (set == 0) {
 +                      if (has_flag) {
 +                              tselem->flag &= ~flag;
 +                              changed = true;
 +                      }
 +              }
 +              else if (!has_flag) {
 +                      tselem->flag |= flag;
 +                      changed = true;
 +              }
 +              changed |= outliner_set_flag(&te->subtree, flag, set);
        }
 +
 +      return changed;
  }
  
  /* Restriction Columns ------------------------------- */
@@@ -858,6 -781,181 +858,6 @@@ int common_restrict_check(bContext *C, 
        return 1;
  }
  
 -/* =============================================== */
 -/* Restriction toggles */
 -
 -/* Toggle Visibility ---------------------------------------- */
 -
 -void object_toggle_visibility_cb(
 -        bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Base *base = (Base *)te->directdata;
 -      Object *ob = (Object *)tselem->id;
 -
 -      if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
 -              BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
 -              return;
 -      }
 -
 -      /* add check for edit mode */
 -      if (!common_restrict_check(C, ob)) return;
 -      
 -      if (base || (base = BKE_scene_base_find(scene, ob))) {
 -              if ((base->object->restrictflag ^= OB_RESTRICT_VIEW)) {
 -                      ED_base_object_select(base, BA_DESELECT);
 -              }
 -      }
 -}
 -
 -void group_toggle_visibility_cb(
 -        bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Group *group = (Group *)tselem->id;
 -      restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_VIEW);
 -}
 -
 -static int outliner_toggle_visibility_exec(bContext *C, wmOperator *op)
 -{
 -      Main *bmain = CTX_data_main(C);
 -      SpaceOops *soops = CTX_wm_space_outliner(C);
 -      Scene *scene = CTX_data_scene(C);
 -      ARegion *ar = CTX_wm_region(C);
 -      
 -      outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_visibility_cb);
 -      
 -      DAG_id_type_tag(bmain, ID_OB);
 -      WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
 -      ED_region_tag_redraw(ar);
 -      
 -      return OPERATOR_FINISHED;
 -}
 -
 -void OUTLINER_OT_visibility_toggle(wmOperatorType *ot)
 -{
 -      /* identifiers */
 -      ot->name = "Toggle Visibility";
 -      ot->idname = "OUTLINER_OT_visibility_toggle";
 -      ot->description = "Toggle the visibility of selected items";
 -      
 -      /* callbacks */
 -      ot->exec = outliner_toggle_visibility_exec;
 -      ot->poll = ED_operator_outliner_active_no_editobject;
 -      
 -      ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 -}
 -
 -/* Toggle Selectability ---------------------------------------- */
 -
 -void object_toggle_selectability_cb(
 -        bContext *UNUSED(C), ReportList *reports, Scene *scene, TreeElement *te,
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Base *base = (Base *)te->directdata;
 -
 -      if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
 -              BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
 -              return;
 -      }
 -
 -      if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
 -      if (base) {
 -              base->object->restrictflag ^= OB_RESTRICT_SELECT;
 -      }
 -}
 -
 -void group_toggle_selectability_cb(
 -        bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Group *group = (Group *)tselem->id;
 -      restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_SELECT);
 -}
 -
 -static int outliner_toggle_selectability_exec(bContext *C, wmOperator *op)
 -{
 -      SpaceOops *soops = CTX_wm_space_outliner(C);
 -      Scene *scene = CTX_data_scene(C);
 -      ARegion *ar = CTX_wm_region(C);
 -      
 -      outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_selectability_cb);
 -      
 -      WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 -      ED_region_tag_redraw(ar);
 -      
 -      return OPERATOR_FINISHED;
 -}
 -
 -void OUTLINER_OT_selectability_toggle(wmOperatorType *ot)
 -{
 -      /* identifiers */
 -      ot->name = "Toggle Selectability";
 -      ot->idname = "OUTLINER_OT_selectability_toggle";
 -      ot->description = "Toggle the selectability";
 -      
 -      /* callbacks */
 -      ot->exec = outliner_toggle_selectability_exec;
 -      ot->poll = ED_operator_outliner_active_no_editobject;
 -      
 -      ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 -}
 -
 -/* Toggle Renderability ---------------------------------------- */
 -
 -void object_toggle_renderability_cb(
 -        bContext *UNUSED(C), ReportList *reports, Scene *scene, TreeElement *te,
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Base *base = (Base *)te->directdata;
 -
 -      if (ID_IS_LINKED_DATABLOCK(tselem->id)) {
 -              BKE_report(reports, RPT_WARNING, "Cannot edit external libdata");
 -              return;
 -      }
 -
 -      if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id);
 -      if (base) {
 -              base->object->restrictflag ^= OB_RESTRICT_RENDER;
 -      }
 -}
 -
 -void group_toggle_renderability_cb(
 -        bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *UNUSED(te),
 -        TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
 -{
 -      Group *group = (Group *)tselem->id;
 -      restrictbutton_gr_restrict_flag(scene, group, OB_RESTRICT_RENDER);
 -}
 -
 -static int outliner_toggle_renderability_exec(bContext *C, wmOperator *op)
 -{
 -      Main *bmain = CTX_data_main(C);
 -      SpaceOops *soops = CTX_wm_space_outliner(C);
 -      Scene *scene = CTX_data_scene(C);
 -      
 -      outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_toggle_renderability_cb);
 -      
 -      DAG_id_type_tag(bmain, ID_OB);
 -      WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
 -      
 -      return OPERATOR_FINISHED;
 -}
 -
 -void OUTLINER_OT_renderability_toggle(wmOperatorType *ot)
 -{
 -      /* identifiers */
 -      ot->name = "Toggle Renderability";
 -      ot->idname = "OUTLINER_OT_renderability_toggle";
 -      ot->description = "Toggle the renderability of selected items";
 -      
 -      /* callbacks */
 -      ot->exec = outliner_toggle_renderability_exec;
 -      ot->poll = ED_operator_outliner_active;
 -      
 -      ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 -}
 -
  /* =============================================== */
  /* Outliner setting toggles */
  
@@@ -979,14 -1077,14 +979,14 @@@ static int outliner_open_back(TreeEleme
  static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
  {
        SpaceOops *so = CTX_wm_space_outliner(C);
 -      Scene *scene = CTX_data_scene(C);
 +      SceneLayer *sl = CTX_data_scene_layer(C);
        ARegion *ar = CTX_wm_region(C);
        View2D *v2d = &ar->v2d;
        
        TreeElement *te;
        int xdelta, ytop;
  
 -      Object *obact = OBACT;
 +      Object *obact = OBACT_NEW;
  
        if (!obact)
                return OPERATOR_CANCELLED;
@@@ -1846,7 -1944,7 +1846,7 @@@ static int outliner_orphans_purge_invok
  {
        /* present a prompt to informing users that this change is irreversible */
        return WM_operator_confirm_message(C, op,
-                                          "Purging unused data-blocks cannot be undone. "
+                                          "Purging unused data-blocks cannot be undone and saves to current .blend file. "
                                           "Click here to proceed...");
  }
  
@@@ -1868,7 -1966,8 +1868,8 @@@ void OUTLINER_OT_orphans_purge(wmOperat
        /* identifiers */
        ot->idname = "OUTLINER_OT_orphans_purge";
        ot->name = "Purge All";
-       ot->description = "Clear all orphaned data-blocks without any users from the file (cannot be undone)";
+       ot->description = "Clear all orphaned data-blocks without any users from the file "
+                         "(cannot be undone, saves to current .blend file)";
        
        /* callbacks */
        ot->invoke = outliner_orphans_purge_invoke;
@@@ -1905,7 -2004,7 +1906,7 @@@ static int parent_drop_exec(bContext *C
  
        ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, false, false, NULL);
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
        WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
        WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
  
@@@ -1921,7 -2020,6 +1922,7 @@@ static int parent_drop_invoke(bContext 
        Main *bmain = CTX_data_main(C);
        Scene *scene = NULL;
        TreeElement *te = NULL;
 +      TreeStoreElem *tselem;
        char childname[MAX_ID_NAME];
        char parname[MAX_ID_NAME];
        int partype = 0;
  
        /* Find object hovered over */
        te = outliner_dropzone_find(soops, fmval, true);
 +      tselem = te ? TREESTORE(te) : NULL;
  
 -      if (te) {
 +      if (tselem && ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
 +              SceneCollection *sc = outliner_scene_collection_from_tree_element(te);
 +
 +              scene = BKE_scene_find_from_collection(bmain, sc);
 +              BLI_assert(scene);
 +              RNA_string_get(op->ptr, "child", childname);
 +              ob = (Object *)BKE_libblock_find_name(ID_OB, childname);
 +              BKE_collection_object_add(scene, sc, ob);
 +
 +              DEG_relations_tag_update(bmain);
 +              WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
 +      }
 +      else if (te) {
                RNA_string_set(op->ptr, "parent", te->name);
                /* Identify parent and child */
                RNA_string_get(op->ptr, "child", childname);
  
                if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) {
                        if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype, false, false, NULL)) {
 -                              DAG_relations_tag_update(bmain);
 +                              DEG_relations_tag_update(bmain);
                                WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
                                WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
                        }
@@@ -2106,7 -2191,7 +2107,7 @@@ static int parent_clear_invoke(bContex
  
        ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type"));
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
        WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
        WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL);
        return OPERATOR_FINISHED;
@@@ -2149,6 -2234,8 +2150,6 @@@ static int scene_drop_invoke(bContext *
        te = outliner_dropzone_find(soops, fmval, false);
  
        if (te) {
 -              Base *base;
 -
                RNA_string_set(op->ptr, "scene", te->name);
                scene = (Scene *)BKE_libblock_find_name(ID_SCE, te->name);
  
                        return OPERATOR_CANCELLED;
                }
  
 -              base = ED_object_scene_link(scene, ob);
 -
 -              if (base == NULL) {
 +              if (BKE_scene_has_object(scene, ob)) {
                        return OPERATOR_CANCELLED;
                }
  
 -              if (scene == CTX_data_scene(C)) {
 -                      /* when linking to an inactive scene don't touch the layer */
 -                      ob->lay = base->lay;
 -                      ED_base_object_select(base, BA_SELECT);
 +              SceneCollection *sc;
 +              if (scene != CTX_data_scene(C)) {
 +                      /* when linking to an inactive scene link to the master collection */
 +                      sc = BKE_collection_master(scene);
 +              }
 +              else {
 +                      sc = CTX_data_scene_collection(C);
 +              }
 +
 +              BKE_collection_object_add(scene, sc, ob);
 +
 +              for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
 +                      Base *base = BKE_scene_layer_base_find(sl, ob);
 +                      if (base) {
 +                              ED_object_base_select(base, BA_SELECT);
 +                      }
                }
  
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
  
                WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
  
@@@ -2273,6 -2350,7 +2274,6 @@@ static int group_link_invoke(bContext *
        Main *bmain = CTX_data_main(C);
        Group *group = NULL;
        Object *ob = NULL;
 -      Scene *scene = CTX_data_scene(C);
        SpaceOops *soops = CTX_wm_space_outliner(C);
        ARegion *ar = CTX_wm_region(C);
        TreeElement *te = NULL;
                        return OPERATOR_CANCELLED;
                }
  
 -              BKE_group_object_add(group, ob, scene, NULL);
 +              BKE_group_object_add(group, ob);
                WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
  
                return OPERATOR_FINISHED;
index 3c7a48662f813c20376929548e4e5a5c25f63e41,f19c999a4f1f6495d705e916712efc1de6009316..ff37765b683a00b6384ad2542b657e991914b756
@@@ -59,7 -59,7 +59,7 @@@
  #include "BLO_readfile.h"
  
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_library_remap.h"
  #include "BKE_global.h"
@@@ -69,8 -69,6 +69,8 @@@
  
  #include "BKE_idcode.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
  
  #include "IMB_colormanagement.h"
  
@@@ -133,8 -131,8 +133,8 @@@ static short wm_link_append_flag(wmOper
  
        if (RNA_boolean_get(op->ptr, "autoselect"))
                flag |= FILE_AUTOSELECT;
 -      if (RNA_boolean_get(op->ptr, "active_layer"))
 -              flag |= FILE_ACTIVELAY;
 +      if (RNA_boolean_get(op->ptr, "active_collection"))
 +              flag |= FILE_ACTIVE_COLLECTION;
        if ((prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop))
                flag |= FILE_RELPATH;
        if (RNA_boolean_get(op->ptr, "link"))
@@@ -214,7 -212,7 +214,7 @@@ static WMLinkAppendDataItem *wm_link_ap
  }
  
  static void wm_link_do(
 -        WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d,
 +        WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, SceneLayer *sl,
          const bool use_placeholders, const bool force_indirect)
  {
        Main *mainl;
                        }
  
                        new_id = BLO_library_link_named_part_ex(
 -                                   mainl, &bh, item->idcode, item->name, flag, scene, v3d, use_placeholders, force_indirect);
 +                                   mainl, &bh, item->idcode, item->name, flag, scene, sl, use_placeholders, force_indirect);
  
                        if (new_id) {
                                /* If the link is successful, clear item's libs 'todo' flags.
                        }
                }
  
 -              BLO_library_link_end(mainl, &bh, flag, scene, v3d);
 +              BLO_library_link_end(mainl, &bh, flag, scene, sl);
                BLO_blendhandle_close(bh);
        }
  }
  
 +/**
 + * Check if an item defined by \a name and \a group can be appended/linked.
 + *
 + * \param reports: Optionally report an error when an item can't be appended/linked.
 + */
 +static bool wm_link_append_item_poll(
 +        ReportList *reports, const char *path, const char *group, const char *name, const bool do_append)
 +{
 +      short idcode;
 +
 +      if (!group || !name) {
 +              printf("skipping %s\n", path);
 +              return false;
 +      }
 +
 +      idcode = BKE_idcode_from_name(group);
 +
 +      /* XXX For now, we do a nasty exception for workspace, forbid linking them.
 +       *     Not nice, ultimately should be solved! */
 +      if (!BKE_idcode_is_linkable(idcode) && (do_append || idcode != ID_WS)) {
 +              if (reports) {
 +                      if (do_append) {
 +                              BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't append data-block '%s' of type '%s'", name, group);
 +                      }
 +                      else {
 +                              BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't link data-block '%s' of type '%s'", name, group);
 +                      }
 +              }
 +              return false;
 +      }
 +
 +      return true;
 +}
 +
  static int wm_link_append_exec(bContext *C, wmOperator *op)
  {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
 +      SceneLayer *sl = CTX_data_scene_layer(C);
        PropertyRNA *prop;
        WMLinkAppendData *lapp_data;
        char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
        char *group, *name;
        int totfiles = 0;
        short flag;
 +      bool has_item = false;
 +      bool do_append;
  
        RNA_string_get(op->ptr, "filename", relname);
        RNA_string_get(op->ptr, "directory", root);
        }
  
        flag = wm_link_append_flag(op);
 +      do_append = (flag & FILE_LINK) == 0;
  
        /* sanity checks for flag */
        if (scene && scene->id.lib) {
  
        /* from here down, no error returns */
  
 -      if (scene && RNA_boolean_get(op->ptr, "autoselect")) {
 -              BKE_scene_base_deselect_all(scene);
 +      if (sl && RNA_boolean_get(op->ptr, "autoselect")) {
 +              BKE_scene_layer_base_deselect_all(sl);
        }
        
        /* tag everything, all untagged data can be made local
                        BLI_join_dirfile(path, sizeof(path), root, relname);
  
                        if (BLO_library_path_explode(path, libname, &group, &name)) {
 -                              if (!group || !name) {
 +                              if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) {
                                        continue;
                                }
  
                                        BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx));
                                        lib_idx++;
                                        wm_link_append_data_library_add(lapp_data, libname);
 +                                      has_item = true;
                                }
                        }
                }
  
                        if (BLO_library_path_explode(path, libname, &group, &name)) {
                                WMLinkAppendDataItem *item;
 -                              if (!group || !name) {
 -                                      printf("skipping %s\n", path);
 +
 +                              if (!wm_link_append_item_poll(op->reports, path, group, name, do_append)) {
                                        continue;
                                }
  
  
                                item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
                                BLI_BITMAP_ENABLE(item->libraries, lib_idx);
 +                              has_item = true;
                        }
                }
                RNA_END;
                wm_link_append_data_library_add(lapp_data, libname);
                item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
                BLI_BITMAP_ENABLE(item->libraries, 0);
 +              has_item = true;
 +      }
 +
 +      if (!has_item) {
 +              wm_link_append_data_free(lapp_data);
 +              return OPERATOR_CANCELLED;
        }
  
        /* XXX We'd need re-entrant locking on Main for this to work... */
        /* BKE_main_lock(bmain); */
  
 -      wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C), false, false);
 +      wm_link_do(lapp_data, op->reports, bmain, scene, sl, false, false);
  
        /* BKE_main_unlock(bmain); */
  
        IMB_colormanagement_check_file_config(bmain);
  
        /* append, rather than linking */
 -      if ((flag & FILE_LINK) == 0) {
 +      if (do_append) {
                const bool set_fake = RNA_boolean_get(op->ptr, "set_fake");
                const bool use_recursive = RNA_boolean_get(op->ptr, "use_recursive");
  
         * link into other scenes from this blend file */
        BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
  
 +      /* TODO(sergey): Use proper flag for tagging here. */
 +
 +      /* TODO (dalai): Temporary solution!
 +       * Ideally we only need to tag the new objects themselves, not the scene. This way we'll avoid flush of
 +       * collection properties to all objects and limit update to the particular object only.
 +       * But afraid first we need to change collection evaluation in DEG according to depsgraph manifesto.
 +       */
 +      DEG_id_tag_update(&scene->id, 0);
 +
        /* recreate dependency graph to include new objects */
 -      DAG_scene_relations_rebuild(bmain, scene);
 +      DEG_scene_relations_rebuild(bmain, scene);
        
        /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
        GPU_materials_free();
@@@ -528,8 -471,8 +528,8 @@@ static void wm_link_append_properties_c
        prop = RNA_def_boolean(ot->srna, "autoselect", true,
                               "Select", "Select new objects");
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 -      prop = RNA_def_boolean(ot->srna, "active_layer", true,
 -                             "Active Layer", "Put new objects on the active layer");
 +      prop = RNA_def_boolean(ot->srna, "active_collection", true,
 +                             "Active Collection", "Put new objects on the active collection");
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);
        prop = RNA_def_boolean(ot->srna, "instance_groups", is_link,
                               "Instance Groups", "Create Dupli-Group instances for each group");
@@@ -617,7 -560,6 +617,7 @@@ static void lib_relocate_do
  
        LinkNode *itemlink;
        int item_idx;
 +      bool has_item = false;
  
        /* Remove all IDs to be reloaded from Main. */
        lba_idx = set_listbasepointers(bmain, lbarray);
                                BLI_remlink(lbarray[lba_idx], id);
                                item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
                                BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
 +                              has_item = true;
  
  #ifdef PRINT_DEBUG
                                printf("\tdatablock to seek for: %s\n", id->name);
                }
        }
  
 +      if (!has_item) {
 +              /* nothing to relocate */
 +              return;
 +      }
 +
        BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
  
        /* We do not want any instanciation here! */
        }
  
        /* Note that in reload case, we also want to replace indirect usages. */
-       const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
+       const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE |
+                                 (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
        for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
                WMLinkAppendDataItem *item = itemlink->link;
                ID *old_id = item->customdata;
        BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
  
        /* recreate dependency graph to include new objects */
 -      DAG_scene_relations_rebuild(bmain, scene);
 +      DEG_scene_relations_rebuild(bmain, scene);
  
        /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
        GPU_materials_free();