Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Fri, 29 Jun 2018 07:25:40 +0000 (09:25 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 29 Jun 2018 07:25:40 +0000 (09:25 +0200)
49 files changed:
1  2 
source/CMakeLists.txt
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_cdderivedmesh.h
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_effect.h
source/blender/blenkernel/BKE_fluidsim.h
source/blender/blenkernel/BKE_freestyle.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_mesh_tangent.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_softbody.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/BKE_world.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/boids.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/fluidsim.c
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/idprop.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/object_deform.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/workspace.c
source/blender/blenloader/intern/readfile.h
source/blender/draw/engines/workbench/workbench_materials.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_effect_types.h
source/blender/makesdna/DNA_fileglobal_types.h
source/blender/makesdna/DNA_lamp_types.h
source/blender/makesdna/DNA_lattice_types.h
source/blender/makesdna/DNA_layer_types.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_object_force_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_outliner_types.h
source/blender/makesdna/DNA_rigidbody_types.h
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_view2d_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/modifiers/intern/MOD_fluidsim_util.h
source/blender/modifiers/intern/MOD_subsurf.c

@@@ -23,9 -23,8 +23,8 @@@
  #
  # ***** END GPL LICENSE BLOCK *****
  
 -add_subdirectory(blender)
 -
 -if(WITH_GAMEENGINE)
 -      add_subdirectory(gameengine)
 +if(WITH_LEGACY_OPENGL)
 +      add_definitions(-DWITH_LEGACY_OPENGL)
  endif()
 +
 +add_subdirectory(blender)
Simple merge
Simple merge
index cb3100c,0000000..6d359a0
mode 100644,000000..100644
--- /dev/null
@@@ -1,61 -1,0 +1,60 @@@
 +/*
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +#ifndef __BKE_MESH_TANGENT_H__
 +#define __BKE_MESH_TANGENT_H__
 +
 +void BKE_mesh_calc_loop_tangent_single_ex(
 +        const struct MVert *mverts, const int numVerts, const struct MLoop *mloops,
 +        float (*r_looptangent)[4], float (*loopnors)[3], const struct MLoopUV *loopuv,
 +        const int numLoops, const struct MPoly *mpolys, const int numPolys,
 +        struct ReportList *reports);
 +void BKE_mesh_calc_loop_tangent_single(
 +        struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports);
 +
 +void BKE_mesh_calc_loop_tangent_ex(
 +        const struct MVert *mvert,
 +        const struct MPoly *mpoly, const uint mpoly_len,
 +        const struct MLoop *mloop,
 +        const struct MLoopTri *looptri, const uint looptri_len,
 +
 +        struct CustomData *loopdata,
 +        bool calc_active_tangent,
 +        const char (*tangent_names)[64], int tangent_names_len,
 +        const float (*poly_normals)[3],
 +        const float (*loop_normals)[3],
 +        const float (*vert_orco)[3],
 +        /* result */
 +        struct CustomData *loopdata_out,
 +        const uint  loopdata_out_len,
 +        short *tangent_mask_curr_p);
 +
 +/* Helpers */
 +void BKE_mesh_add_loop_tangent_named_layer_for_uv(
 +        struct CustomData *uv_data, struct CustomData *tan_data, int numLoopData,
 +        const char *layer_name);
 +
 +#define DM_TANGENT_MASK_ORCO (1 << 9)
 +void BKE_mesh_calc_loop_tangent_step_0(
 +        const struct CustomData *loopData, bool calc_active_tangent,
 +        const char (*tangent_names)[64], int tangent_names_count,
 +        bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
 +        char *ract_uv_name, char *rren_uv_name, short *rtangent_mask);
 +
 +#endif /* __BKE_MESH_TANGENT_H__ */
@@@ -490,75 -457,4 +490,74 @@@ void modwrap_deformVertsEM
          struct BMEditMesh *em, struct DerivedMesh *dm,
          float (*vertexCos)[3], int numVerts);
  
 +/* wrappers for modifier callbacks that accept Mesh and select the proper implementation
 + * depending on if the modifier has been ported to Mesh or is still using DerivedMesh
 + */
 +
 +void modifier_deformVerts(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct Mesh *mesh, float (*vertexCos)[3], int numVerts);
 +
 +void modifier_deformVerts_ensure_normals(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct Mesh *mesh, float (*vertexCos)[3], int numVerts);
 +
 +void modifier_deformMatrices(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
 +
 +void modifier_deformVertsEM(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct Mesh *mesh,
 +        float (*vertexCos)[3], int numVerts);
 +
 +void modifier_deformMatricesEM(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct Mesh *mesh,
 +        float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
 +
 +struct Mesh *modifier_applyModifier(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct Mesh *mesh);
 +
 +struct Mesh *modifier_applyModifier_ensure_normals(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct Mesh *mesh);
 +
 +struct Mesh *modifier_applyModifierEM(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct Mesh *mesh);
 +
 +/* depricated variants of above that accept DerivedMesh */
 +
 +void modifier_deformVerts_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
 +
 +void modifier_deformMatrices_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct DerivedMesh *dm,
 +        float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
 +
 +void modifier_deformVertsEM_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct DerivedMesh *dm,
 +        float (*vertexCos)[3], int numVerts);
 +
 +void modifier_deformMatricesEM_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct DerivedMesh *dm,
 +        float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
 +
 +struct DerivedMesh *modifier_applyModifier_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct DerivedMesh *dm);
 +
 +struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(
 +        struct ModifierData *md, const struct ModifierEvalContext *ctx,
 +        struct BMEditMesh *editData, struct DerivedMesh *dm);
 +
 +struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(
 +        struct Object *ob_eval, bool *r_free_mesh);
 +
  #endif
@@@ -44,11 -44,4 +44,10 @@@ struct World *BKE_world_copy(struct Mai
  struct World *BKE_world_localize(struct World *wrld);
  void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
  
 -#endif  /* __BKE_WORLD_H__ */
 +/* Evaluation. */
 +
 +struct Depsgraph;
 +
 +void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
 +
 +#endif
@@@ -1456,7 -1498,6 +1456,6 @@@ void what_does_obaction(Object *ob, Obj
                adt.action = act;
  
                /* execute effects of Action on to workob (or it's PoseChannels) */
 -              BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM);
 +              BKE_animsys_evaluate_animdata(NULL, NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM);
        }
  }
@@@ -1506,6 -1505,5 +1506,5 @@@ static int cloth_build_springs ( ClothM
  
  } /* cloth_build_springs */
  /***************************************************************************************
 - * SPRING NETWORK BUILDING IMPLEMENTATION END
 + * SPRING NETWORK GWN_BATCH_BUILDING IMPLEMENTATION END
   ***************************************************************************************/
@@@ -696,128 -649,21 +696,127 @@@ void BKE_icon_id_delete(struct ID *id
  /**
   * Remove icon and free data.
   */
 -void BKE_icon_delete(const int icon_id)
 +bool BKE_icon_delete(const int icon_id)
  {
 -      Icon *icon;
 +      if (icon_id == 0) {
 +              /* no icon defined for library object */
 +              return false;
 +      }
  
 -      if (!icon_id) return;  /* no icon defined for library object */
 +      Icon *icon = BLI_ghash_popkey(gIcons, SET_INT_IN_POINTER(icon_id), NULL);
 +      if (icon) {
 +              icon_free_data(icon_id, icon);
 +              icon_free(icon);
 +              return true;
 +      }
 +      else {
 +              return false;
 +      }
 +}
  
 -      icon = BLI_ghash_popkey(gIcons, SET_INT_IN_POINTER(icon_id), NULL);
 +bool BKE_icon_delete_unmanaged(const int icon_id)
 +{
 +      if (icon_id == 0) {
 +              /* no icon defined for library object */
 +              return false;
 +      }
  
 +      Icon *icon = BLI_ghash_popkey(gIcons, SET_INT_IN_POINTER(icon_id), NULL);
        if (icon) {
 -              if (icon->id_type != 0) {
 -                      ((ID *)(icon->obj))->icon_id = 0;
 +              if (UNLIKELY(icon->flag & ICON_FLAG_MANAGED)) {
 +                      BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(icon_id), icon);
 +                      return false;
                }
                else {
 -                      ((PreviewImage *)(icon->obj))->icon_id = 0;
 +                      icon_free_data(icon_id, icon);
 +                      icon_free(icon);
 +                      return true;
                }
 -              icon_free(icon);
        }
 +      else {
 +              return false;
 +      }
 +}
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Geometry Icon
 + * \{ */
 +
 +int BKE_icon_geom_ensure(struct Icon_Geom *geom)
 +{
 +      BLI_assert(BLI_thread_is_main());
 +
 +      if (geom->icon_id) {
 +              return geom->icon_id;
 +      }
 +
 +      geom->icon_id = get_next_free_id();
 +
 +      icon_create(geom->icon_id, ICON_DATA_GEOM, geom);
 +      /* Not managed for now, we may want this to be configurable per icon). */
 +
 +      return geom->icon_id;
 +}
 +
 +struct Icon_Geom *BKE_icon_geom_from_memory(const uchar *data, size_t data_len)
 +{
 +      BLI_assert(BLI_thread_is_main());
 +      if (data_len <= 8) {
 +              goto fail;
 +      }
 +      /* Skip the header. */
 +      data_len -= 8;
 +      const int div = 3 * 2 * 3;
 +      const int coords_len = data_len / div;
 +      if (coords_len * div != data_len) {
 +              goto fail;
 +      }
 +
 +      const uchar header[4] = {'V', 'C', 'O', 0};
 +      const uchar *p = data;
 +      if (memcmp(p, header, ARRAY_SIZE(header)) != 0) {
 +              goto fail;
 +      }
 +      p += 4;
 +
 +      struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
 +      geom->coords_range[0] = (int)*p++;
 +      geom->coords_range[1] = (int)*p++;
 +      /* x, y ignored for now */
 +      p += 2;
 +
 +      geom->coords_len = coords_len;
 +      geom->coords = (const void *)p;
 +      geom->colors = (const void *)(p + (data_len / 3));
 +      geom->icon_id = 0;
 +      geom->mem = data;
 +      return geom;
 +
 +fail:
 +      MEM_freeN((void *)data);
 +      return NULL;
 +}
 +
 +struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
 +{
 +      BLI_assert(BLI_thread_is_main());
 +      size_t data_len;
 +      uchar *data = BLI_file_read_binary_as_mem(filename, 0, &data_len);
 +      if (data == NULL) {
 +              return NULL;
 +      }
 +      return BKE_icon_geom_from_memory(data, data_len);
 +}
 +
 +/** \} */
 +
 +/** \name Studio Light Icon
 + * \{ */
 +int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
 +{
 +      int icon_id = get_next_free_id();
 +      Icon *icon = icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
 +      icon->id_type = id_type;
 +      return icon_id;
  }
 +/** \} */
@@@ -1094,16 -1067,4 +1094,15 @@@ void IDP_ClearProperty(IDProperty *prop
        prop->len = prop->totallen = 0;
  }
  
 +void IDP_Reset(IDProperty *prop, const IDProperty *reference)
 +{
 +      if (prop == NULL) {
 +              return;
 +      }
 +      IDP_ClearProperty(prop);
 +      if (reference != NULL) {
 +              IDP_MergeGroup(prop, reference, true);
 +      }
 +}
 +
  /** \} */
index 2e5798c,0000000..f0f57e8
mode 100644,000000..100644
--- /dev/null
@@@ -1,541 -1,0 +1,540 @@@
 +/*
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +
 +/** \file blender/blenkernel/intern/workspace.c
 + *  \ingroup bke
 + */
 +
 +/* allow accessing private members of DNA_workspace_types.h */
 +#define DNA_PRIVATE_WORKSPACE_ALLOW
 +
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#include "BLI_utildefines.h"
 +#include "BLI_string.h"
 +#include "BLI_string_utf8.h"
 +#include "BLI_string_utils.h"
 +#include "BLI_listbase.h"
 +
 +#include "BKE_global.h"
 +#include "BKE_idprop.h"
 +#include "BKE_library.h"
 +#include "BKE_main.h"
 +#include "BKE_scene.h"
 +#include "BKE_screen.h"
 +#include "BKE_object.h"
 +#include "BKE_workspace.h"
 +
 +#include "DNA_object_types.h"
 +#include "DNA_scene_types.h"
 +#include "DNA_screen_types.h"
 +#include "DNA_workspace_types.h"
 +
 +#include "DEG_depsgraph.h"
 +
 +#include "MEM_guardedalloc.h"
 +
 +
 +/* -------------------------------------------------------------------- */
 +/* Internal utils */
 +
 +static void workspace_layout_name_set(
 +        WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name)
 +{
 +      BLI_strncpy(layout->name, new_name, sizeof(layout->name));
 +      BLI_uniquename(&workspace->layouts, layout, "Layout", '.', offsetof(WorkSpaceLayout, name), sizeof(layout->name));
 +}
 +
 +/**
 + * This should only be used directly when it is to be expected that there isn't
 + * a layout within \a workspace that wraps \a screen. Usually - especially outside
 + * of BKE_workspace - #BKE_workspace_layout_find should be used!
 + */
 +static WorkSpaceLayout *workspace_layout_find_exec(
 +        const WorkSpace *workspace, const bScreen *screen)
 +{
 +      return BLI_findptr(&workspace->layouts, screen, offsetof(WorkSpaceLayout, screen));
 +}
 +
 +static void workspace_relation_add(
 +        ListBase *relation_list, void *parent, void *data)
 +{
 +      WorkSpaceDataRelation *relation = MEM_callocN(sizeof(*relation), __func__);
 +      relation->parent = parent;
 +      relation->value = data;
 +      /* add to head, if we switch back to it soon we find it faster. */
 +      BLI_addhead(relation_list, relation);
 +}
 +static void workspace_relation_remove(
 +        ListBase *relation_list, WorkSpaceDataRelation *relation)
 +{
 +      BLI_remlink(relation_list, relation);
 +      MEM_freeN(relation);
 +}
 +
 +static void workspace_relation_ensure_updated(
 +        ListBase *relation_list, void *parent, void *data)
 +{
 +      WorkSpaceDataRelation *relation = BLI_findptr(relation_list, parent, offsetof(WorkSpaceDataRelation, parent));
 +      if (relation != NULL) {
 +              relation->value = data;
 +              /* reinsert at the head of the list, so that more commonly used relations are found faster. */
 +              BLI_remlink(relation_list, relation);
 +              BLI_addhead(relation_list, relation);
 +      }
 +      else {
 +              /* no matching relation found, add new one */
 +              workspace_relation_add(relation_list, parent, data);
 +      }
 +}
 +
 +static void *workspace_relation_get_data_matching_parent(
 +        const ListBase *relation_list, const void *parent)
 +{
 +      WorkSpaceDataRelation *relation = BLI_findptr(relation_list, parent, offsetof(WorkSpaceDataRelation, parent));
 +      if (relation != NULL) {
 +              return relation->value;
 +      }
 +      else {
 +              return NULL;
 +      }
 +}
 +
 +/**
 + * Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
 + * WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
 + * Hence, this should only be used as assert check before assigining a screen to a workspace.
 + */
 +#ifndef NDEBUG
 +static bool workspaces_is_screen_used
 +#else
 +static bool UNUSED_FUNCTION(workspaces_is_screen_used)
 +#endif
 +        (const Main *bmain, bScreen *screen)
 +{
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              if (workspace_layout_find_exec(workspace, screen)) {
 +                      return true;
 +              }
 +      }
 +
 +      return false;
 +}
 +
 +/* -------------------------------------------------------------------- */
 +/* Create, delete, init */
 +
 +WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
 +{
 +      WorkSpace *new_workspace = BKE_libblock_alloc(bmain, ID_WS, name, 0);
 +      return new_workspace;
 +}
 +
 +/**
 + * The function that actually frees the workspace data (not workspace itself). It shouldn't be called
 + * directly, instead #BKE_workspace_remove should be, which calls this through #BKE_libblock_free then.
 + *
 + * Should something like a bke_internal.h be added, this should go there!
 + */
 +void BKE_workspace_free(WorkSpace *workspace)
 +{
 +      BKE_workspace_relations_free(&workspace->hook_layout_relations);
 +      BLI_freelistN(&workspace->scene_layer_relations);
 +
 +      BLI_freelistN(&workspace->owner_ids);
 +      BLI_freelistN(&workspace->layouts);
 +
 +      for (bToolRef *tref = workspace->tools.first, *tref_next; tref; tref = tref_next) {
 +              tref_next = tref->next;
 +              if (tref->runtime) {
 +                      MEM_freeN(tref->runtime);
 +                      if (tref->properties) {
 +                              IDP_FreeProperty(tref->properties);
 +                              MEM_freeN(tref->properties);
 +                      }
 +              }
 +      }
 +      BLI_freelistN(&workspace->tools);
 +
 +      if (workspace->status_text) {
 +              MEM_freeN(workspace->status_text);
 +              workspace->status_text = NULL;
 +      }
 +}
 +
 +/**
 + * Remove \a workspace by freeing itself and its data. This is a higher-level wrapper that
 + * calls #BKE_workspace_free (through #BKE_libblock_free) to free the workspace data, and frees
 + * other data-blocks owned by \a workspace and its layouts (currently that is screens only).
 + *
 + * Always use this to remove (and free) workspaces. Don't free non-ID workspace members here.
 + */
 +void BKE_workspace_remove(Main *bmain, WorkSpace *workspace)
 +{
 +      for (WorkSpaceLayout *layout = workspace->layouts.first, *layout_next; layout; layout = layout_next) {
 +              layout_next = layout->next;
 +              BKE_workspace_layout_remove(bmain, workspace, layout);
 +      }
 +      BKE_libblock_free(bmain, workspace);
 +}
 +
 +WorkSpaceInstanceHook *BKE_workspace_instance_hook_create(const Main *bmain)
 +{
 +      WorkSpaceInstanceHook *hook = MEM_callocN(sizeof(WorkSpaceInstanceHook), __func__);
 +
 +      /* set an active screen-layout for each possible window/workspace combination */
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              BKE_workspace_hook_layout_for_workspace_set(hook, workspace, workspace->layouts.first);
 +      }
 +
 +      return hook;
 +}
 +void BKE_workspace_instance_hook_free(const Main *bmain, WorkSpaceInstanceHook *hook)
 +{
 +      /* workspaces should never be freed before wm (during which we call this function) */
 +      BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces));
 +
 +      /* Free relations for this hook */
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              for (WorkSpaceDataRelation *relation = workspace->hook_layout_relations.first, *relation_next;
 +                   relation;
 +                   relation = relation_next)
 +              {
 +                      relation_next = relation->next;
 +                      if (relation->parent == hook) {
 +                              workspace_relation_remove(&workspace->hook_layout_relations, relation);
 +                      }
 +              }
 +      }
 +
 +      MEM_freeN(hook);
 +}
 +
 +/**
 + * Add a new layout to \a workspace for \a screen.
 + */
 +WorkSpaceLayout *BKE_workspace_layout_add(
 +        Main *bmain,
 +        WorkSpace *workspace,
 +        bScreen *screen,
 +        const char *name)
 +{
 +      WorkSpaceLayout *layout = MEM_callocN(sizeof(*layout), __func__);
 +
 +      BLI_assert(!workspaces_is_screen_used(bmain, screen));
 +#ifndef DEBUG
 +      UNUSED_VARS(bmain);
 +#endif
 +      layout->screen = screen;
 +      workspace_layout_name_set(workspace, layout, name);
 +      BLI_addtail(&workspace->layouts, layout);
 +
 +      return layout;
 +}
 +
 +void BKE_workspace_layout_remove(
 +        Main *bmain,
 +        WorkSpace *workspace, WorkSpaceLayout *layout)
 +{
 +      BKE_libblock_free(bmain, BKE_workspace_layout_screen_get(layout));
 +      BLI_freelinkN(&workspace->layouts, layout);
 +}
 +
 +void BKE_workspace_relations_free(
 +        ListBase *relation_list)
 +{
 +      for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
 +              relation_next = relation->next;
 +              workspace_relation_remove(relation_list, relation);
 +      }
 +}
 +
 +void BKE_workspace_scene_relations_free_invalid(
 +        WorkSpace *workspace)
 +{
 +      for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first, *relation_next; relation; relation = relation_next) {
 +              relation_next = relation->next;
 +
 +              if (relation->scene == NULL) {
 +                      BLI_freelinkN(&workspace->scene_layer_relations, relation);
 +              }
 +              else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) {
 +                      BLI_freelinkN(&workspace->scene_layer_relations, relation);
 +              }
 +      }
 +}
 +
 +/* -------------------------------------------------------------------- */
 +/* General Utils */
 +
 +void BKE_workspace_view_layer_rename(
 +        const Main *bmain,
 +        const Scene *scene,
 +        const char *old_name,
 +        const char *new_name)
 +{
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) {
 +                      if (relation->scene == scene && STREQ(relation->view_layer, old_name)) {
 +                              STRNCPY(relation->view_layer, new_name);
 +                      }
 +              }
 +      }
 +}
 +
 +void BKE_workspace_view_layer_remove(
 +        const Main *bmain,
 +        const ViewLayer *UNUSED(view_layer))
 +{
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              BKE_workspace_scene_relations_free_invalid(workspace);
 +      }
 +}
 +
 +WorkSpaceLayout *BKE_workspace_layout_find(
 +        const WorkSpace *workspace, const bScreen *screen)
 +{
 +      WorkSpaceLayout *layout = workspace_layout_find_exec(workspace, screen);
 +      if (layout) {
 +              return layout;
 +      }
 +
 +      printf("%s: Couldn't find layout in this workspace: '%s' screen: '%s'. "
 +             "This should not happen!\n",
 +             __func__, workspace->id.name + 2, screen->id.name + 2);
 +
 +      return NULL;
 +}
 +
 +/**
 + * Find the layout for \a screen without knowing which workspace to look in.
 + * Can also be used to find the workspace that contains \a screen.
 + *
 + * \param r_workspace: Optionally return the workspace that contains the looked up layout (if found).
 + */
 +WorkSpaceLayout *BKE_workspace_layout_find_global(
 +        const Main *bmain, const bScreen *screen,
 +        WorkSpace **r_workspace)
 +{
 +      WorkSpaceLayout *layout;
 +
 +      if (r_workspace) {
 +              *r_workspace = NULL;
 +      }
 +
 +      for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
 +              if ((layout = workspace_layout_find_exec(workspace, screen))) {
 +                      if (r_workspace) {
 +                              *r_workspace = workspace;
 +                      }
 +
 +                      return layout;
 +              }
 +      }
 +
 +      return NULL;
 +}
 +
 +/**
 + * Circular workspace layout iterator.
 + *
 + * \param callback: Custom function which gets executed for each layout. Can return false to stop iterating.
 + * \param arg: Custom data passed to each \a callback call.
 + *
 + * \return the layout at which \a callback returned false.
 + */
 +WorkSpaceLayout *BKE_workspace_layout_iter_circular(
 +        const WorkSpace *workspace, WorkSpaceLayout *start,
 +        bool (*callback)(const WorkSpaceLayout *layout, void *arg),
 +        void *arg, const bool iter_backward)
 +{
 +      WorkSpaceLayout *iter_layout;
 +
 +      if (iter_backward) {
 +              LISTBASE_CIRCULAR_BACKWARD_BEGIN(&workspace->layouts, iter_layout, start)
 +              {
 +                      if (!callback(iter_layout, arg)) {
 +                              return iter_layout;
 +                      }
 +              }
 +              LISTBASE_CIRCULAR_BACKWARD_END(&workspace->layouts, iter_layout, start);
 +      }
 +      else {
 +              LISTBASE_CIRCULAR_FORWARD_BEGIN(&workspace->layouts, iter_layout, start)
 +              {
 +                      if (!callback(iter_layout, arg)) {
 +                              return iter_layout;
 +                      }
 +              }
 +              LISTBASE_CIRCULAR_FORWARD_END(&workspace->layouts, iter_layout, start)
 +      }
 +
 +      return NULL;
 +}
 +
 +
 +/* -------------------------------------------------------------------- */
 +/* Getters/Setters */
 +
 +WorkSpace *BKE_workspace_active_get(WorkSpaceInstanceHook *hook)
 +{
 +      return hook->active;
 +}
 +void BKE_workspace_active_set(WorkSpaceInstanceHook *hook, WorkSpace *workspace)
 +{
 +      hook->active = workspace;
 +      if (workspace) {
 +              WorkSpaceLayout *layout = workspace_relation_get_data_matching_parent(&workspace->hook_layout_relations, hook);
 +              if (layout) {
 +                      hook->act_layout = layout;
 +              }
 +      }
 +}
 +
 +WorkSpaceLayout *BKE_workspace_active_layout_get(const WorkSpaceInstanceHook *hook)
 +{
 +      return hook->act_layout;
 +}
 +void BKE_workspace_active_layout_set(WorkSpaceInstanceHook *hook, WorkSpaceLayout *layout)
 +{
 +      hook->act_layout = layout;
 +}
 +
 +bScreen *BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook)
 +{
 +      return hook->act_layout->screen;
 +}
 +void BKE_workspace_active_screen_set(WorkSpaceInstanceHook *hook, WorkSpace *workspace, bScreen *screen)
 +{
 +      /* we need to find the WorkspaceLayout that wraps this screen */
 +      WorkSpaceLayout *layout = BKE_workspace_layout_find(hook->active, screen);
 +      BKE_workspace_hook_layout_for_workspace_set(hook, workspace, layout);
 +}
 +
 +Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene)
 +{
 +      ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
 +      return view_layer->basact;
 +}
 +
 +ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene)
 +{
 +      WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
 +      return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL;
 +}
 +
 +ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
 +{
 +      ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene);
 +
 +      if (layer == NULL) {
 +              BKE_workspace_view_layer_set((WorkSpace *)workspace, scene->view_layers.first, (Scene *)scene);
 +              layer = scene->view_layers.first;
 +      }
 +
 +      return layer;
 +}
 +
 +void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
 +{
 +      WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
 +      if (relation == NULL) {
 +              relation = MEM_callocN(sizeof(*relation), __func__);
 +      }
 +      else {
 +              BLI_remlink(&workspace->scene_layer_relations, relation);
 +      }
 +
 +      /* (Re)insert at the head of the list, for faster lookups. */
 +      relation->scene = scene;
 +      STRNCPY(relation->view_layer, layer->name);
 +      BLI_addhead(&workspace->scene_layer_relations, relation);
 +}
 +
 +ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
 +{
 +      return &workspace->layouts;
 +}
 +
 +const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout)
 +{
 +      return layout->name;
 +}
 +void BKE_workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name)
 +{
 +      workspace_layout_name_set(workspace, layout, new_name);
 +}
 +
 +bScreen *BKE_workspace_layout_screen_get(const WorkSpaceLayout *layout)
 +{
 +      return layout->screen;
 +}
 +void BKE_workspace_layout_screen_set(WorkSpaceLayout *layout, bScreen *screen)
 +{
 +      layout->screen = screen;
 +}
 +
 +WorkSpaceLayout *BKE_workspace_hook_layout_for_workspace_get(
 +        const WorkSpaceInstanceHook *hook, const WorkSpace *workspace)
 +{
 +      return workspace_relation_get_data_matching_parent(&workspace->hook_layout_relations, hook);
 +}
 +void BKE_workspace_hook_layout_for_workspace_set(
 +        WorkSpaceInstanceHook *hook, WorkSpace *workspace, WorkSpaceLayout *layout)
 +{
 +      hook->act_layout = layout;
 +      workspace_relation_ensure_updated(&workspace->hook_layout_relations, hook, layout);
 +}
 +
 +/* Update / evaluate */
 +
 +void BKE_workspace_update_tagged(Main *bmain,
 +                                 WorkSpace *workspace,
 +                                 Scene *scene)
 +{
 +      ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
 +      struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene,
 +                                                            view_layer,
 +                                                            true);
 +      /* TODO(sergey): For now all dependency graphs which are evaluated from
 +       * workspace are considered active. This will work all fine with "locked"
 +       * view layer and time across windows. This is to be granted separately,
 +       * and for until then we have to accept ambiguities when object is shared
 +       * across visible view layers and has overrides on it.
 +       */
 +      DEG_make_active(depsgraph);
 +      BKE_scene_graph_update_tagged(depsgraph, bmain);
 +}
 +
 +
 +bool BKE_workspace_owner_id_check(
 +        const WorkSpace *workspace, const char *owner_id)
 +{
 +      if ((*owner_id == '\0') ||
 +          ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0))
 +      {
 +              return true;
 +      }
 +      else {
 +              /* we could use hash lookup, for now this list is highly under < ~16 items. */
 +              return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
 +      }
 +}
@@@ -173,10 -171,7 +173,9 @@@ void blo_do_versions_pre250(struct File
  void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *bmain);
  void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *bmain);
  void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *bmain);
 +void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *bmain);
  
  void do_versions_after_linking_270(struct Main *bmain);
 +void do_versions_after_linking_280(struct Main *bmain);
  
  #endif
index bddfa70,0000000..69900ca
mode 100644,000000..100644
--- /dev/null
@@@ -1,194 -1,0 +1,194 @@@
- }
 +
 +
 +#include "workbench_private.h"
 +
 +#include "BLI_dynstr.h"
 +
 +#define HSV_SATURATION 0.5
 +#define HSV_VALUE 0.9
 +
 +void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data)
 +{
 +      /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
 +      int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
 +      static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
 +      static float default_specular_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
 +      copy_v4_v4(data->diffuse_color, default_diffuse_color);
 +      copy_v4_v4(data->specular_color, default_specular_color);
 +      data->roughness = 0.5f;
 +
 +      if (color_type == V3D_SHADING_SINGLE_COLOR) {
 +              copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
 +      }
 +      else if (color_type == V3D_SHADING_RANDOM_COLOR) {
 +              uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
 +              if (ob->id.lib) {
 +                      hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name);
 +              }
 +              float offset = fmodf((hash / 100000.0) * M_GOLDEN_RATION_CONJUGATE, 1.0);
 +
 +              float hsv[3] = {offset, HSV_SATURATION, HSV_VALUE};
 +              hsv_to_rgb_v(hsv, data->diffuse_color);
 +      }
 +      else {
 +              /* V3D_SHADING_MATERIAL_COLOR */
 +              if (mat) {
 +                      copy_v3_v3(data->diffuse_color, &mat->r);
 +                      copy_v3_v3(data->specular_color, &mat->specr);
 +                      data->roughness = mat->roughness;
 +              }
 +      }
 +}
 +
 +char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
 +{
 +      char *str = NULL;
 +
 +      DynStr *ds = BLI_dynstr_new();
 +
 +      if (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) {
 +              BLI_dynstr_appendf(ds, "#define V3D_SHADING_OBJECT_OUTLINE\n");
 +      }
 +      if (wpd->shading.flag & V3D_SHADING_SHADOW) {
 +              BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
 +      }
 +      if (CAVITY_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define V3D_SHADING_CAVITY\n");
 +      }
 +      if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
 +      }
 +      if (STUDIOLIGHT_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n");
 +      }
 +      if (FLAT_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_FLAT\n");
 +      }
 +      if (MATCAP_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_MATCAP\n");
 +      }
 +      if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
 +      }
 +      if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
 +      }
 +      if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL\n");
 +      }
 +      if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
 +              BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
 +      }
 +      if (use_textures) {
 +              BLI_dynstr_appendf(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
 +      }
 +      if (NORMAL_ENCODING_ENABLED()) {
 +              BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
 +      }
 +      if (is_hair) {
 +              BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
 +      }
 +
 +#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 0
 +      BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 0\n");
 +#endif
 +#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 1
 +      BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 1\n");
 +#endif
 +#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 2
 +      BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 2\n");
 +#endif
 +      BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 9\n");
 +
 +      str = BLI_dynstr_get_cstring(ds);
 +      BLI_dynstr_free(ds);
 +      return str;
 +}
 +
 +uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
 +{
 +      uint input[4];
 +      uint result;
 +      float *color = material_template->diffuse_color;
 +      input[0] = (uint)(color[0] * 512);
 +      input[1] = (uint)(color[1] * 512);
 +      input[2] = (uint)(color[2] * 512);
 +      input[3] = material_template->object_id;
 +      result = BLI_ghashutil_uinthash_v4_murmur(input);
 +
 +      color = material_template->specular_color;
 +      input[0] = (uint)(color[0] * 512);
 +      input[1] = (uint)(color[1] * 512);
 +      input[2] = (uint)(color[2] * 512);
 +      input[3] = (uint)(material_template->roughness * 512);
 +      result += BLI_ghashutil_uinthash_v4_murmur(input);
 +
 +      /* add texture reference */
 +      if (material_template->ima)
 +      {
 +              result += BLI_ghashutil_inthash_p_murmur(material_template->ima);
 +      }
 +
 +      return result;
 +}
 +
 +int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
 +{
 +      /* NOTE: change MAX_SHADERS accordingly when modifying this function. */
 +      int index = 0;
 +      /* 1 bit V3D_SHADING_TEXTURE_COLOR */
 +      SET_FLAG_FROM_TEST(index, use_textures, 1 << 0);
 +      /* 2 bits FLAT/STUDIO/MATCAP/SCENE */
 +      SET_FLAG_FROM_TEST(index, wpd->shading.light, wpd->shading.light << 1);
 +      /* 1 bit V3D_SHADING_SPECULAR_HIGHLIGHT */
 +      SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT, 1 << 3);
 +      SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 4);
 +      SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 5);
 +      SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 6);
 +      /* 2 bits STUDIOLIGHT_ORIENTATION */
 +      SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 1 << 7);
 +      SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL, 1 << 8);
 +      /* 1 bit for hair */
 +      SET_FLAG_FROM_TEST(index, is_hair, 1 << 9);
 +      return index;
 +}
 +
 +void workbench_material_set_normal_world_matrix(
 +        DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
 +{
 +      if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
 +              float view_matrix_inverse[4][4];
 +              float rot_matrix[4][4];
 +              float matrix[4][4];
 +              axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
 +              DRW_viewport_matrix_get(view_matrix_inverse, DRW_MAT_VIEWINV);
 +              mul_m4_m4m4(matrix, rot_matrix, view_matrix_inverse);
 +              copy_m3_m4(persistent_matrix, matrix);
 +              DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", persistent_matrix);
 +      }
 +}
 +
 +int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima)
 +{
 +      int color_type = wpd->shading.color_type;
 +      if (color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) {
 +              color_type = V3D_SHADING_MATERIAL_COLOR;
 +      }
 +      return color_type;
 +}
 +
 +void workbench_material_shgroup_uniform(DRWShadingGroup *grp, WORKBENCH_MaterialData *material)
 +{
 +      DRW_shgroup_uniform_vec4(grp, "materialDiffuseColor", material->diffuse_color, 1);
 +      DRW_shgroup_uniform_vec4(grp, "materialSpecularColor", material->specular_color, 1);
 +      DRW_shgroup_uniform_float(grp, "materialRoughness", &material->roughness, 1);
 +}
 +
 +void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material)
 +{
 +      dest_material->object_id = source_material->object_id;
 +      copy_v4_v4(dest_material->diffuse_color, source_material->diffuse_color);
 +      copy_v4_v4(dest_material->specular_color, source_material->specular_color);
 +      dest_material->roughness = source_material->roughness;
 +      dest_material->ima = source_material->ima;
++}
@@@ -148,8 -190,25 +148,7 @@@ typedef struct Lamp 
  #define LA_AREA_RECT  1
  #define LA_AREA_CUBE  2
  #define LA_AREA_BOX           3
 -
 -/* ray_samp_method */
 -#define LA_SAMP_CONSTANT                      0
 -#define LA_SAMP_HALTON                                1
 -#define LA_SAMP_HAMMERSLEY                    2
 -
 -
 -/* ray_samp_type */
 -// #define LA_SAMP_ROUND      1  // UNUSED
 -#define LA_SAMP_UMBRA 2
 -#define LA_SAMP_DITHER        4
 -#define LA_SAMP_JITTER        8
 -
 -/* mapto */
 -#define LAMAP_COL             1
 -#define LAMAP_SHAD            2
 -
 -/* shadowmap_type */
 -#define LA_SHADMAP_SIMPLE     0
 -#define LA_SHADMAP_VARIANCE   1
 +#define LA_AREA_DISK  4
 +#define LA_AREA_ELLIPSE       5
  
  #endif /* __DNA_LAMP_TYPES_H__ */
index 614e065,0000000..bfdd218
mode 100644,000000..100644
--- /dev/null
@@@ -1,159 -1,0 +1,158 @@@
 +/*
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + *
 + * Contributor(s): Dalai Felinto
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +
 +/** \file DNA_layer_types.h
 + *  \ingroup DNA
 + */
 +
 +#ifndef __DNA_LAYER_TYPES_H__
 +#define __DNA_LAYER_TYPES_H__
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +#include "DNA_freestyle_types.h"
 +#include "DNA_listBase.h"
 +
 +typedef struct Base {
 +      struct Base *next, *prev;
 +      short flag;
 +      short pad;
 +      short sx, sy;
 +      struct Object *object;
 +      unsigned int lay;
 +      int flag_legacy;
 +} Base;
 +
 +typedef struct ViewLayerEngineData {
 +      struct ViewLayerEngineData *next, *prev;
 +      struct DrawEngineType *engine_type;
 +      void *storage;
 +      void (*free)(void *storage);
 +} ViewLayerEngineData;
 +
 +typedef struct LayerCollection {
 +      struct LayerCollection *next, *prev;
 +      struct Collection *collection;
 +      struct SceneCollection *scene_collection DNA_DEPRECATED;
 +      short flag;
 +      short runtime_flag;
 +      short pad[2];
 +      ListBase layer_collections; /* synced with collection->children */
 +} LayerCollection;
 +
 +typedef struct ViewLayer {
 +      struct ViewLayer *next, *prev;
 +      char name[64]; /* MAX_NAME */
 +      short flag;
 +      short runtime_flag;
 +      short pad[2];
 +      ListBase object_bases;      /* ObjectBase */
 +      struct SceneStats *stats;   /* default allocated now */
 +      struct Base *basact;
 +      ListBase layer_collections; /* LayerCollection */
 +      LayerCollection *active_collection;
 +
 +      /* Old SceneRenderLayer data. */
 +      int layflag;
 +      int passflag;                   /* pass_xor has to be after passflag */
 +      int pass_xor;
 +      float pass_alpha_threshold;
 +
 +      struct IDProperty *id_properties; /* Equivalent to datablocks ID properties. */
 +
 +      struct FreestyleConfig freestyle_config;
 +
 +      /* Runtime data */
 +      ListBase drawdata;    /* ViewLayerEngineData */
 +      struct Base **object_bases_array;
 +      struct GHash *object_bases_hash;
 +} ViewLayer;
 +
 +/* Base->flag */
 +enum {
 +      /* User controlled flags. */
 +      BASE_SELECTED         = (1 << 0), /* Object is selected. */
 +      BASE_HIDDEN           = (1 << 8), /* Object is hidden for editing. */
 +
 +      /* Runtime evaluated flags. */
 +      BASE_VISIBLE          = (1 << 1), /* Object is enabled and visible. */
 +      BASE_SELECTABLE       = (1 << 2), /* Object can be selected. */
 +      BASE_FROMDUPLI        = (1 << 3), /* Object comes from duplicator. */
 +      /* BASE_DEPRECATED    = (1 << 4), */
 +      BASE_FROM_SET         = (1 << 5), /* Object comes from set. */
 +      BASE_ENABLED_VIEWPORT = (1 << 6), /* Object is enabled in viewport. */
 +      BASE_ENABLED_RENDER   = (1 << 7), /* Object is enabled in final render */
 +      BASE_ENABLED          = (1 << 9), /* Object is enabled. */
 +};
 +
 +/* LayerCollection->flag */
 +enum {
 +      /* LAYER_COLLECTION_DEPRECATED0 = (1 << 0), */
 +      /* LAYER_COLLECTION_DEPRECATED1 = (1 << 1), */
 +      /* LAYER_COLLECTION_DEPRECATED2 = (1 << 2), */
 +      /* LAYER_COLLECTION_DEPRECATED3 = (1 << 3), */
 +      LAYER_COLLECTION_EXCLUDE = (1 << 4),
 +};
 +
 +/* Layer Collection->runtime_flag */
 +enum {
 +      LAYER_COLLECTION_HAS_OBJECTS = (1 << 0),
 +      LAYER_COLLECTION_HAS_VISIBLE_OBJECTS = (1 << 1),
 +      LAYER_COLLECTION_HAS_ENABLED_OBJECTS = (1 << 2),
 +};
 +
 +/* ViewLayer->flag */
 +enum {
 +      VIEW_LAYER_RENDER = (1 << 0),
 +      /* VIEW_LAYER_DEPRECATED  = (1 << 1), */
 +      VIEW_LAYER_FREESTYLE = (1 << 2),
 +};
 +
 +/* ViewLayer->runtime_flag */
 +enum {
 +      VIEW_LAYER_HAS_HIDE = (1 << 0),
 +};
 +
 +/****************************** Deprecated ******************************/
 +
 +/* Compatibility with collections saved in early 2.8 versions,
 + * used in file reading and versioning code. */
 +#define USE_COLLECTION_COMPAT_28
 +
 +typedef struct SceneCollection {
 +      struct SceneCollection *next, *prev;
 +      char name[64]; /* MAX_NAME */
 +      int active_object_index; /* for UI */
 +      short flag;
 +      char type;
 +      char pad;
 +      ListBase objects;           /* (Object *)LinkData->data */
 +      ListBase scene_collections; /* nested collections */
 +} SceneCollection;
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif  /* __DNA_LAYER_TYPES_H__ */
@@@ -203,31 -458,23 +203,30 @@@ typedef struct Material 
  #define MA_HAIR                       10
  #define MA_ATMOS              11
  
 -/* sss_flag */
 -#define MA_DIFF_SSS           1
 -
 -/* vol_stepsize_type */
 -#define MA_VOL_STEP_RANDOMIZED        0
 -#define MA_VOL_STEP_CONSTANT  1
 -#define MA_VOL_STEP_ADAPTIVE  2
 -
 -/* vol_shadeflag */
 -#define MA_VOL_RECV_EXT_SHADOW        1
 -#define MA_VOL_PRECACHESHADING        8
 -
 -/* vol_shading_type */
 -#define MA_VOL_SHADE_SHADELESS                                        0
 -#define MA_VOL_SHADE_SHADOWED                                 2
 -#define MA_VOL_SHADE_SHADED                                           1
 -#define MA_VOL_SHADE_MULTIPLE                                 3
 -#define MA_VOL_SHADE_SHADEDPLUSMULTIPLE                       4
 +/* blend_method */
 +enum {
 +      MA_BM_SOLID,
 +      MA_BM_ADD,
 +      MA_BM_MULTIPLY,
 +      MA_BM_CLIP,
 +      MA_BM_HASHED,
 +      MA_BM_BLEND,
 +};
 +
 +/* blend_flag */
 +enum {
 +      MA_BL_HIDE_BACKSIDE =        (1 << 0),
 +      MA_BL_SS_REFRACTION =        (1 << 1),
 +      MA_BL_SS_SUBSURFACE =        (1 << 2),
 +      MA_BL_TRANSLUCENCY =         (1 << 3),
 +};
 +
 +/* blend_shadow */
 +enum {
 +      MA_BS_NONE = 0,
 +      MA_BS_SOLID,
 +      MA_BS_CLIP,
 +      MA_BS_HASHED,
 +};
  
  #endif
@@@ -499,6 -415,4 +499,5 @@@ enum 
  #define RGN_DRAW_PARTIAL      2
  #define RGN_DRAWING                   4
  #define RGN_DRAW_REFRESH_UI   8  /* re-create uiBlock's where possible */
 +#define RGN_DRAW_NO_REBUILD   16
  #endif
@@@ -45,8 -44,7 +45,7 @@@ void fluidsim_free(struct FluidsimModif
  
  struct DerivedMesh *fluidsimModifier_do(
          struct FluidsimModifierData *fluidmd,
 -        struct Scene *scene, struct Object *ob, struct DerivedMesh *dm,
 -        int useRenderParams, int isFinalCalc);
 +        const struct ModifierEvalContext *ctx,
 +        struct DerivedMesh *dm);
  
  #endif