Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 29 May 2018 13:59:18 +0000 (15:59 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 29 May 2018 14:02:53 +0000 (16:02 +0200)
Conflicts:
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/library_remap.c
source/blender/blenkernel/intern/material.c
source/blender/editors/object/object_relations.c
source/blender/editors/render/render_preview.c
source/blender/makesrna/intern/rna_object.c

16 files changed:
1  2 
source/blender/alembic/intern/abc_mesh.cc
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/library_remap.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mesh.c
source/blender/collada/MeshImporter.cpp
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/object/object_relations.c
source/blender/editors/render/render_shading.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_object.c

@@@ -102,14 -109,14 +102,14 @@@ void ramp_blend(int type, float r_col[3
  /* copy/paste */
  void clear_matcopybuf(void);
  void free_matcopybuf(void);
- void copy_matcopybuf(struct Material *ma);
- void paste_matcopybuf(struct Material *ma);
+ void copy_matcopybuf(struct Main *bmain, struct Material *ma);
+ void paste_matcopybuf(struct Main *bmain, struct Material *ma);
  
 -/* handle backward compatibility for tface/materials called from doversion */ 
 -int do_version_tface(struct Main *main);
 +/* Evaluation. */
 +
 +struct Depsgraph;
 +
 +void BKE_material_eval(struct Depsgraph *depsgraph, struct Material *material);
  
  #ifdef __cplusplus
  }
@@@ -127,23 -99,7 +127,23 @@@ float (*BKE_mesh_orco_verts_get(struct 
  void   BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);
  int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
  struct Mesh *BKE_mesh_from_object(struct Object *ob);
- void BKE_mesh_assign_object(struct Object *ob, struct Mesh *me);
+ void BKE_mesh_assign_object(struct Main *bmain, struct Object *ob, struct Mesh *me);
 +void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me);
 +int  BKE_mesh_nurbs_to_mdata(
 +        struct Object *ob, struct MVert **r_allvert, int *r_totvert,
 +        struct MEdge **r_alledge, int *r_totedge, struct MLoop **r_allloop, struct MPoly **r_allpoly,
 +        int *r_totloop, int *r_totpoly);
 +int BKE_mesh_nurbs_displist_to_mdata(
 +        struct Object *ob, const struct ListBase *dispbase,
 +        struct MVert **r_allvert, int *r_totvert,
 +        struct MEdge **r_alledge, int *r_totedge,
 +        struct MLoop **r_allloop, struct MPoly **r_allpoly,
 +        struct MLoopUV **r_alluv, int *r_totloop, int *r_totpoly);
 +void BKE_mesh_from_nurbs_displist(
 +        struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name);
 +void BKE_mesh_from_nurbs(struct Object *ob);
 +void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
 +void BKE_mesh_to_curve(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
  void BKE_mesh_material_index_remove(struct Mesh *me, short index);
  void BKE_mesh_material_index_clear(struct Mesh *me);
  void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len);
@@@ -532,10 -631,10 +532,10 @@@ void BKE_material_resize_object(Main *b
        if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
        if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
  }
  
- void test_object_materials(Object *ob, ID *id)
+ void test_object_materials(Main *bmain, Object *ob, ID *id)
  {
        /* make the ob mat-array same size as 'ob->data' mat-array */
        const short *totcol;
@@@ -837,9 -936,279 +837,9 @@@ bool BKE_object_material_slot_add(Main 
        return true;
  }
  
 -static void do_init_render_material(Main *bmain, Material *ma, int r_mode, float *amb)
 -{
 -      MTex *mtex;
 -      int a, needuv = 0, needtang = 0;
 -      
 -      if (ma->flarec == 0) ma->flarec = 1;
 -
 -      /* add all texcoflags from mtex, texco and mapto were cleared in advance */
 -      for (a = 0; a < MAX_MTEX; a++) {
 -              
 -              /* separate tex switching */
 -              if (ma->septex & (1 << a)) continue;
 -
 -              mtex = ma->mtex[a];
 -              if (mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) {
 -                      
 -                      ma->texco |= mtex->texco;
 -                      ma->mapto |= mtex->mapto;
 -
 -                      /* always get derivatives for these textures */
 -                      if (ELEM(mtex->tex->type, TEX_IMAGE, TEX_ENVMAP)) ma->texco |= TEXCO_OSA;
 -                      else if (mtex->texflag & (MTEX_COMPAT_BUMP | MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)) ma->texco |= TEXCO_OSA;
 -                      
 -                      if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1;
 -                      else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1;
 -                      else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW)) needuv = 1;
 -
 -                      if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
 -                              needtang = 1;
 -              }
 -      }
 -
 -      if (needtang) ma->mode |= MA_NORMAP_TANG;
 -      else ma->mode &= ~MA_NORMAP_TANG;
 -      
 -      if (ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
 -              needuv = 1;
 -              if (r_mode & R_OSA) ma->texco |= TEXCO_OSA;     /* for texfaces */
 -      }
 -      if (needuv) ma->texco |= NEED_UV;
 -      
 -      /* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */
 -      if (r_mode & R_RAYTRACE) {
 -              if ((ma->mode & (MA_RAYMIRROR | MA_SHADOW_TRA)) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) {
 -                      ma->texco |= NEED_UV | TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM;
 -                      if (r_mode & R_OSA) ma->texco |= TEXCO_OSA;
 -              }
 -      }
 -      
 -      if (amb) {
 -              ma->ambr = ma->amb * amb[0];
 -              ma->ambg = ma->amb * amb[1];
 -              ma->ambb = ma->amb * amb[2];
 -      }
 -
 -      /* local group override */
 -      if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) {
 -              Group *group;
 -
 -              for (group = bmain->group.first; group; group = group->id.next) {
 -                      if (!ID_IS_LINKED(group) && STREQ(group->id.name, ma->group->id.name)) {
 -                              ma->group = group;
 -                      }
 -              }
 -      }
 -}
 -
 -static void init_render_nodetree(Main *bmain, bNodeTree *ntree, Material *basemat, int r_mode, float *amb)
 -{
 -      bNode *node;
 -
 -      /* parses the geom+tex nodes */
 -      ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l);
 -      for (node = ntree->nodes.first; node; node = node->next) {
 -              if (node->id) {
 -                      if (GS(node->id->name) == ID_MA) {
 -                              Material *ma = (Material *)node->id;
 -                              if (ma != basemat) {
 -                                      do_init_render_material(bmain, ma, r_mode, amb);
 -                                      basemat->texco |= ma->texco;
 -                              }
 -
 -                              basemat->mode_l |= ma->mode & ~(MA_MODE_PIPELINE | MA_SHLESS);
 -                              basemat->mode2_l |= ma->mode2 & ~MA_MODE2_PIPELINE;
 -                              /* basemat only considered shadeless if all node materials are too */
 -                              if (!(ma->mode & MA_SHLESS))
 -                                      basemat->mode_l &= ~MA_SHLESS;
 -
 -                              if (ma->strand_surfnor > 0.0f)
 -                                      basemat->mode_l |= MA_STR_SURFDIFF;
 -                      }
 -                      else if (node->type == NODE_GROUP)
 -                              init_render_nodetree(bmain, (bNodeTree *)node->id, basemat, r_mode, amb);
 -              }
 -              else if (node->typeinfo->type == SH_NODE_NORMAL_MAP) {
 -                      basemat->mode2_l |= MA_TANGENT_CONCRETE;
 -                      NodeShaderNormalMap *nm = node->storage;
 -                      bool taken_into_account = false;
 -                      for (int i = 0; i < basemat->nmap_tangent_names_count; i++) {
 -                              if (STREQ(basemat->nmap_tangent_names[i], nm->uv_map)) {
 -                                      taken_into_account = true;
 -                                      break;
 -                              }
 -                      }
 -                      if (!taken_into_account) {
 -                              BLI_assert(basemat->nmap_tangent_names_count < MAX_MTFACE + 1);
 -                              strcpy(basemat->nmap_tangent_names[basemat->nmap_tangent_names_count++], nm->uv_map);
 -                      }
 -              }
 -      }
 -}
 -
 -void init_render_material(Main *bmain, Material *mat, int r_mode, float *amb)
 -{
 -      
 -      do_init_render_material(bmain, mat, r_mode, amb);
 -      
 -      if (mat->nodetree && mat->use_nodes) {
 -              /* mode_l will take the pipeline options from the main material, and the or-ed
 -               * result of non-pipeline options from the nodes. shadeless is an exception,
 -               * mode_l will have it set when all node materials are shadeless. */
 -              mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS;
 -              mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE;
 -              mat->nmap_tangent_names_count = 0;
 -              init_render_nodetree(bmain, mat->nodetree, mat, r_mode, amb);
 -              
 -              if (!mat->nodetree->execdata)
 -                      mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
 -      }
 -      else {
 -              mat->mode_l = mat->mode;
 -              mat->mode2_l = mat->mode2;
 -
 -              if (mat->strand_surfnor > 0.0f)
 -                      mat->mode_l |= MA_STR_SURFDIFF;
 -      }
 -}
 -
 -void init_render_materials(Main *bmain, int r_mode, float *amb, bool do_default_material)
 -{
 -      Material *ma;
 -      
 -      /* clear these flags before going over materials, to make sure they
 -       * are cleared only once, otherwise node materials contained in other
 -       * node materials can go wrong */
 -      for (ma = bmain->mat.first; ma; ma = ma->id.next) {
 -              if (ma->id.us) {
 -                      ma->texco = 0;
 -                      ma->mapto = 0;
 -              }
 -      }
 -
 -      /* two steps, first initialize, then or the flags for layers */
 -      for (ma = bmain->mat.first; ma; ma = ma->id.next) {
 -              /* is_used flag comes back in convertblender.c */
 -              ma->flag &= ~MA_IS_USED;
 -              if (ma->id.us) 
 -                      init_render_material(bmain, ma, r_mode, amb);
 -      }
 -
 -      if (do_default_material) {
 -              init_render_material(bmain, &defmaterial, r_mode, amb);
 -      }
 -}
 -
 -/* only needed for nodes now */
 -void end_render_material(Material *mat)
 -{
 -      if (mat && mat->nodetree && mat->use_nodes) {
 -              if (mat->nodetree->execdata)
 -                      ntreeShaderEndExecTree(mat->nodetree->execdata);
 -      }
 -}
 -
 -void end_render_materials(Main *bmain)
 -{
 -      Material *ma;
 -      for (ma = bmain->mat.first; ma; ma = ma->id.next)
 -              if (ma->id.us) 
 -                      end_render_material(ma);
 -}
 -
 -static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
 -{
 -      bNode *node;
 -
 -      for (node = ntree->nodes.first; node; node = node->next) {
 -              if (node->id) {
 -                      if (GS(node->id->name) == ID_MA) {
 -                              if (node->id == (ID *)mat) {
 -                                      return true;
 -                              }
 -                      }
 -                      else if (node->type == NODE_GROUP) {
 -                              if (material_in_nodetree((bNodeTree *)node->id, mat)) {
 -                                      return true;
 -                              }
 -                      }
 -              }
 -      }
 -
 -      return false;
 -}
 -
 -bool material_in_material(Material *parmat, Material *mat)
 -{
 -      if (parmat == mat)
 -              return true;
 -      else if (parmat->nodetree && parmat->use_nodes)
 -              return material_in_nodetree(parmat->nodetree, mat);
 -      else
 -              return false;
 -}
 -
 -
  /* ****************** */
  
- bool BKE_object_material_slot_remove(Object *ob)
 -/* Update drivers for materials in a nodetree */
 -static void material_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime)
 -{
 -      bNode *node;
 -
 -      /* nodetree itself */
 -      if (ntree->adt && ntree->adt->drivers.first) {
 -              BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -      
 -      /* nodes */
 -      for (node = ntree->nodes.first; node; node = node->next) {
 -              if (node->id) {
 -                      if (GS(node->id->name) == ID_MA) {
 -                              material_drivers_update(scene, (Material *)node->id, ctime);
 -                      }
 -                      else if (node->type == NODE_GROUP) {
 -                              material_node_drivers_update(scene, (bNodeTree *)node->id, ctime);
 -                      }
 -              }
 -      }
 -}
 -
 -/* Calculate all drivers for materials 
 - * FIXME: this is really a terrible method which may result in some things being calculated
 - * multiple times. However, without proper despgraph support for these things, we are forced
 - * into this sort of thing...
 - */
 -void material_drivers_update(Scene *scene, Material *ma, float ctime)
 -{
 -      //if (G.f & G_DEBUG)
 -      //      printf("material_drivers_update(%s, %s)\n", scene->id.name, ma->id.name);
 -      
 -      /* Prevent infinite recursion by checking (and tagging the material) as having been visited already
 -       * (see BKE_scene_update_tagged()). This assumes ma->id.tag & LIB_TAG_DOIT isn't set by anything else
 -       * in the meantime... [#32017]
 -       */
 -      if (ma->id.tag & LIB_TAG_DOIT)
 -              return;
 -
 -      ma->id.tag |= LIB_TAG_DOIT;
 -      
 -      /* material itself */
 -      if (ma->adt && ma->adt->drivers.first) {
 -              BKE_animsys_evaluate_animdata(scene, &ma->id, ma->adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -      
 -      /* nodes */
 -      if (ma->nodetree) {
 -              material_node_drivers_update(scene, ma->nodetree, ctime);
 -      }
 -
 -      ma->id.tag &= ~LIB_TAG_DOIT;
 -}
 -
+ bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
  {
        Material *mao, ***matarar;
        short *totcolp;
@@@ -1276,22 -1709,34 +1276,22 @@@ void free_matcopybuf(void
        matcopied = 0;
  }
  
- void copy_matcopybuf(Material *ma)
+ void copy_matcopybuf(Main *bmain, Material *ma)
  {
 -      int a;
 -      MTex *mtex;
 -
        if (matcopied)
                free_matcopybuf();
  
        memcpy(&matcopybuf, ma, sizeof(Material));
 -      if (matcopybuf.ramp_col) matcopybuf.ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
 -      if (matcopybuf.ramp_spec) matcopybuf.ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
  
-       matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false);
 -      for (a = 0; a < MAX_MTEX; a++) {
 -              mtex = matcopybuf.mtex[a];
 -              if (mtex) {
 -                      matcopybuf.mtex[a] = MEM_dupallocN(mtex);
 -              }
 -      }
+       matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, bmain, false);
        matcopybuf.preview = NULL;
        BLI_listbase_clear(&matcopybuf.gpumaterial);
 +      /* TODO Duplicate Engine Settings and set runtime to NULL */
        matcopied = 1;
  }
  
- void paste_matcopybuf(Material *ma)
+ void paste_matcopybuf(Main *bmain, Material *ma)
  {
 -      int a;
 -      MTex *mtex;
        ID id;
  
        if (matcopied == 0)
        memcpy(ma, &matcopybuf, sizeof(Material));
        (ma->id) = id;
  
-       ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, G.main, false);
 -      if (matcopybuf.ramp_col) ma->ramp_col = MEM_dupallocN(matcopybuf.ramp_col);
 -      if (matcopybuf.ramp_spec) ma->ramp_spec = MEM_dupallocN(matcopybuf.ramp_spec);
 -
 -      for (a = 0; a < MAX_MTEX; a++) {
 -              mtex = ma->mtex[a];
 -              if (mtex) {
 -                      ma->mtex[a] = MEM_dupallocN(mtex);
 -                      if (mtex->tex) {
 -                              /* first check this is in main (we may have loaded another file) [#35500] */
 -                              if (BLI_findindex(&bmain->tex, mtex->tex) != -1) {
 -                                      id_us_plus((ID *)mtex->tex);
 -                              }
 -                              else {
 -                                      ma->mtex[a]->tex = NULL;
 -                              }
 -                      }
 -              }
 -      }
 -
+       ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
  }
  
 -
 -/*********************** texface to material convert functions **********************/
 -/* encode all the TF information into a single int */
 -static int encode_tfaceflag(MTFace *tf, int convertall)
 -{
 -      /* calculate the flag */
 -      int flag = tf->mode;
 -
 -      /* options that change the material offline render */
 -      if (!convertall) {
 -              flag &= ~TF_OBCOL;
 -      }
 -
 -      /* clean flags that are not being converted */
 -      flag &= ~TF_TEX;
 -      flag &= ~TF_SHAREDVERT;
 -      flag &= ~TF_SHAREDCOL;
 -      flag &= ~TF_CONVERTED;
 -
 -      /* light tface flag is ignored in GLSL mode */
 -      flag &= ~TF_LIGHT;
 -      
 -      /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */
 -      flag |= tf->transp << 15;
 -      
 -      /* increase 1 so flag 0 is different than no flag yet */
 -      return flag + 1;
 -}
 -
 -/* set the material options based in the tface flag */
 -static void decode_tfaceflag(Material *ma, int flag, int convertall)
 -{
 -      int alphablend;
 -      GameSettings *game = &ma->game;
 -
 -      /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
 -      flag -= 1;
 -
 -      alphablend = flag >> 15;  /* encoded in the encode_tfaceflag function */
 -      (*game).flag = 0;
 -      
 -      /* General Material Options */
 -      if ((flag & TF_DYNAMIC) == 0) (*game).flag    |= GEMAT_NOPHYSICS;
 -      
 -      /* Material Offline Rendering Properties */
 -      if (convertall) {
 -              if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR;
 -      }
 -      
 -      /* Special Face Properties */
 -      if ((flag & TF_TWOSIDE) == 0) (*game).flag |= GEMAT_BACKCULL;
 -      if (flag & TF_INVISIBLE) (*game).flag |= GEMAT_INVISIBLE;
 -      if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT;
 -      
 -      /* Face Orientation */
 -      if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO;
 -      else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD;
 -      else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW;
 -      
 -      /* Alpha Blend */
 -      if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT;
 -      else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA;
 -      else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD;
 -      else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP;
 -}
 -
 -/* boolean check to see if the mesh needs a material */
 -static int check_tfaceneedmaterial(int flag)
 -{
 -      /* check if the flags we have are not deprecated != than default material options
 -       * also if only flags are visible and collision see if all objects using this mesh have this option in physics */
 -
 -      /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
 -      flag -= 1;
 -
 -      /* deprecated flags */
 -      flag &= ~TF_OBCOL;
 -      flag &= ~TF_SHAREDVERT;
 -      flag &= ~TF_SHAREDCOL;
 -
 -      /* light tface flag is ignored in GLSL mode */
 -      flag &= ~TF_LIGHT;
 -      
 -      /* automatic detected if tex image has alpha */
 -      flag &= ~(TF_ALPHA << 15);
 -      /* automatic detected if using texture */
 -      flag &= ~TF_TEX;
 -
 -      /* settings for the default NoMaterial */
 -      if (flag == TF_DYNAMIC)
 -              return 0;
 -
 -      else
 -              return 1;
 -}
 -
 -/* return number of digits of an integer */
 -/* XXX to be optmized or replaced by an equivalent blender internal function */
 -static int integer_getdigits(int number)
 +void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
  {
 -      int i = 0;
 -      if (number == 0) return 1;
 -
 -      while (number != 0) {
 -              number = (int)(number / 10);
 -              i++;
 +      DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
 +      if ((BLI_listbase_is_empty(&material->gpumaterial) == false)) {
 +              GPU_material_uniform_buffer_tag_dirty(&material->gpumaterial);
        }
 -      return i;
  }
 -
 -static void calculate_tface_materialname(char *matname, char *newname, int flag)
 -{
 -      /* if flag has only light and collision and material matches those values
 -       * you can do strcpy(name, mat_name);
 -       * otherwise do: */
 -      int digits = integer_getdigits(flag);
 -      /* clamp the old name, remove the MA prefix and add the .TF.flag suffix
 -       * e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */
 -      BLI_snprintf(newname, MAX_ID_NAME, "%.*s.TF.%0*d", MAX_ID_NAME - (digits + 5), matname, digits, flag);
 -}
 -
 -/* returns -1 if no match */
 -static short mesh_getmaterialnumber(Mesh *me, Material *ma)
 -{
 -      short a;
 -
 -      for (a = 0; a < me->totcol; a++) {
 -              if (me->mat[a] == ma) {
 -                      return a;
 -              }
 -      }
 -
 -      return -1;
 -}
 -
 -/* append material */
 -static short mesh_addmaterial(Main *bmain, Mesh *me, Material *ma)
 -{
 -      BKE_material_append_id(bmain, &me->id, NULL);
 -      me->mat[me->totcol - 1] = ma;
 -
 -      id_us_plus(&ma->id);
 -
 -      return me->totcol - 1;
 -}
 -
 -static void set_facetexture_flags(Material *ma, Image *image)
 -{
 -      if (image) {
 -              ma->mode |= MA_FACETEXTURE;
 -              /* we could check if the texture has alpha, but then more meshes sharing the same
 -               * material may need it. Let's make it simple. */
 -              if (BKE_image_has_alpha(image))
 -                      ma->mode |= MA_FACETEXTURE_ALPHA;
 -      }
 -}
 -
 -/* returns material number */
 -static short convert_tfacenomaterial(Main *bmain, Mesh *me, MTFace *tf, int flag)
 -{
 -      Material *ma;
 -      char idname[MAX_ID_NAME];
 -      short mat_nr = -1;
 -      
 -      /* new material, the name uses the flag*/
 -      BLI_snprintf(idname, sizeof(idname), "MAMaterial.TF.%0*d", integer_getdigits(flag), flag);
 -
 -      if ((ma = BLI_findstring(&bmain->mat, idname + 2, offsetof(ID, name) + 2))) {
 -              mat_nr = mesh_getmaterialnumber(me, ma);
 -              /* assign the material to the mesh */
 -              if (mat_nr == -1) mat_nr = mesh_addmaterial(bmain, me, ma);
 -
 -              /* if needed set "Face Textures [Alpha]" Material options */
 -              set_facetexture_flags(ma, tf->tpage);
 -      }
 -      /* create a new material */
 -      else {
 -              ma = BKE_material_add(bmain, idname + 2);
 -
 -              if (ma) {
 -                      printf("TexFace Convert: Material \"%s\" created.\n", idname + 2);
 -                      mat_nr = mesh_addmaterial(bmain, me, ma);
 -                      
 -                      /* if needed set "Face Textures [Alpha]" Material options */
 -                      set_facetexture_flags(ma, tf->tpage);
 -
 -                      decode_tfaceflag(ma, flag, 1);
 -                      /* the final decoding will happen after, outside the main loop
 -                       * for now store the flag into the material and change light/tex/collision
 -                       * store the flag as a negative number */
 -                      ma->game.flag = -flag;
 -                      id_us_min((ID *)ma);
 -              }
 -              else {
 -                      printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
 -              }
 -      }
 -
 -      /* set as converted, no need to go bad to this face */
 -      tf->mode |= TF_CONVERTED;
 -      return mat_nr;
 -}
 -
 -/* Function to fully convert materials */
 -static void convert_tfacematerial(Main *bmain, Material *ma)
 -{
 -      Mesh *me;
 -      Material *mat_new;
 -      MFace *mf;
 -      MTFace *tf;
 -      int flag, index;
 -      int a;
 -      short mat_nr;
 -      CustomDataLayer *cdl;
 -      char idname[MAX_ID_NAME];
 -
 -      for (me = bmain->mesh.first; me; me = me->id.next) {
 -              /* check if this mesh uses this material */
 -              for (a = 0; a < me->totcol; a++)
 -                      if (me->mat[a] == ma) break;
 -                      
 -              /* no material found */
 -              if (a == me->totcol) continue;
 -
 -              /* get the active tface layer */
 -              index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
 -              cdl = (index == -1) ? NULL : &me->fdata.layers[index];
 -              if (!cdl) continue;
 -
 -              /* loop over all the faces and stop at the ones that use the material*/
 -              for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
 -                      if (me->mat[mf->mat_nr] != ma) continue;
 -
 -                      /* texface data for this face */
 -                      tf = ((MTFace *)cdl->data) + a;
 -                      flag = encode_tfaceflag(tf, 1);
 -
 -                      /* the name of the new material */
 -                      calculate_tface_materialname(ma->id.name, (char *)&idname, flag);
 -
 -                      if ((mat_new = BLI_findstring(&bmain->mat, idname + 2, offsetof(ID, name) + 2))) {
 -                              /* material already existent, see if the mesh has it */
 -                              mat_nr = mesh_getmaterialnumber(me, mat_new);
 -                              /* material is not in the mesh, add it */
 -                              if (mat_nr == -1) mat_nr = mesh_addmaterial(bmain, me, mat_new);
 -                      }
 -                      /* create a new material */
 -                      else {
 -                              mat_new = BKE_material_copy(bmain, ma);
 -                              if (mat_new) {
 -                                      /* rename the material*/
 -                                      BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
 -                                      id_us_min((ID *)mat_new);
 -
 -                                      mat_nr = mesh_addmaterial(bmain, me, mat_new);
 -                                      decode_tfaceflag(mat_new, flag, 1);
 -                              }
 -                              else {
 -                                      printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname + 2, me->id.name + 2);
 -                                      mat_nr = mf->mat_nr;
 -                                      continue;
 -                              }
 -                      }
 -                      
 -                      /* if the material has a texture but no texture channel
 -                       * set "Face Textures [Alpha]" Material options 
 -                       * actually we need to run it always, because of old behavior
 -                       * of using face texture if any texture channel was present (multitex) */
 -                      //if ((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex))
 -                      set_facetexture_flags(mat_new, tf->tpage);
 -
 -                      /* set the material number to the face*/
 -                      mf->mat_nr = mat_nr;
 -              }
 -              /* remove material from mesh */
 -              for (a = 0; a < me->totcol; ) {
 -                      if (me->mat[a] == ma) {
 -                              BKE_material_pop_id(bmain, &me->id, a, true);
 -                      }
 -                      else {
 -                              a++;
 -                      }
 -              }
 -      }
 -}
 -
 -
 -#define MAT_BGE_DISPUTED -99999
 -
 -int do_version_tface(Main *main)
 -{
 -      Mesh *me;
 -      Material *ma;
 -      MFace *mf;
 -      MTFace *tf;
 -      CustomDataLayer *cdl;
 -      int a;
 -      int flag;
 -      int index;
 -      
 -      /* Operator in help menu has been removed for 2.7x */
 -      int fileload = 1;
 -
 -      /* sometimes mesh has no materials but will need a new one. In those
 -       * cases we need to ignore the mf->mat_nr and only look at the face
 -       * mode because it can be zero as uninitialized or the 1st created material
 -       */
 -      int nomaterialslots;
 -
 -      /* alert to user to check the console */
 -      int nowarning = 1;
 -
 -      /* mark all the materials to conversion with a flag
 -       * if there is tface create a complete flag for that storing in flag
 -       * if there is tface and flag > 0: creates a new flag based on this face
 -       * if flags are different set flag to -1  
 -       */
 -      
 -      /* 1st part: marking mesh materials to update */
 -      for (me = main->mesh.first; me; me = me->id.next) {
 -              if (ID_IS_LINKED(me)) continue;
 -
 -              /* get the active tface layer */
 -              index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
 -              cdl = (index == -1) ? NULL : &me->fdata.layers[index];
 -              if (!cdl) continue;
 -
 -              nomaterialslots = (me->totcol == 0 ? 1 : 0);
 -              
 -              /* loop over all the faces*/
 -              for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
 -                      /* texface data for this face */
 -                      tf = ((MTFace *)cdl->data) + a;
 -
 -                      /* conversion should happen only once */
 -                      if (fileload)
 -                              tf->mode &= ~TF_CONVERTED;
 -                      else {
 -                              if ((tf->mode & TF_CONVERTED)) continue;
 -                              else tf->mode |= TF_CONVERTED;
 -                      }
 -                      
 -                      /* no material slots */
 -                      if (nomaterialslots) {
 -                              flag = encode_tfaceflag(tf, 1);
 -                              
 -                              /* create/find a new material and assign to the face */
 -                              if (check_tfaceneedmaterial(flag)) {
 -                                      mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
 -                              }
 -                              /* else mark them as no-material to be reverted to 0 later */
 -                              else {
 -                                      mf->mat_nr = -1;
 -                              }
 -                      }
 -                      else if (mf->mat_nr < me->totcol) {
 -                              ma = me->mat[mf->mat_nr];
 -                              
 -                              /* no material create one if necessary */
 -                              if (!ma) {
 -                                      /* find a new material and assign to the face */
 -                                      flag = encode_tfaceflag(tf, 1);
 -
 -                                      /* create/find a new material and assign to the face */
 -                                      if (check_tfaceneedmaterial(flag))
 -                                              mf->mat_nr = convert_tfacenomaterial(main, me, tf, flag);
 -
 -                                      continue;
 -                              }
 -
 -                              /* we can't read from this if it comes from a library,
 -                               * at doversion time: direct_link might not have happened on it,
 -                               * so ma->mtex is not pointing to valid memory yet.
 -                               * later we could, but it's better not */
 -                              else if (ID_IS_LINKED(ma))
 -                                      continue;
 -                              
 -                              /* material already marked as disputed */
 -                              else if (ma->game.flag == MAT_BGE_DISPUTED)
 -                                      continue;
 -
 -                              /* found a material */
 -                              else {
 -                                      flag = encode_tfaceflag(tf, ((fileload) ? 0 : 1));
 -
 -                                      /* first time changing this material */
 -                                      if (ma->game.flag == 0)
 -                                              ma->game.flag = -flag;
 -                      
 -                                      /* mark material as disputed */
 -                                      else if (ma->game.flag != -flag) {
 -                                              ma->game.flag = MAT_BGE_DISPUTED;
 -                                              continue;
 -                                      }
 -                      
 -                                      /* material ok so far */
 -                                      else {
 -                                              ma->game.flag = -flag;
 -                                              
 -                                              /* some people uses multitexture with TexFace by creating a texture
 -                                               * channel which not necessarily the tf->tpage image. But the game engine
 -                                               * was enabling it. Now it's required to set "Face Texture [Alpha] in the
 -                                               * material settings. */
 -                                              if (!fileload)
 -                                                      set_facetexture_flags(ma, tf->tpage);
 -                                      }
 -                              }
 -                      }
 -                      else {
 -                              continue;
 -                      }
 -              }
 -
 -              /* if we didn't have material slot and now we do, we need to
 -               * make sure the materials are correct */
 -              if (nomaterialslots) {
 -                      if (me->totcol > 0) {
 -                              for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
 -                                      if (mf->mat_nr == -1) {
 -                                              /* texface data for this face */
 -                                              tf = ((MTFace *)cdl->data) + a;
 -                                              mf->mat_nr = convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1));
 -                                      }
 -                              }
 -                      }
 -                      else {
 -                              for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
 -                                      mf->mat_nr = 0;
 -                              }
 -                      }
 -              }
 -
 -      }
 -      
 -      /* 2nd part - conversion */
 -      /* skip library files */
 -
 -      /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */
 -      for (ma = main->mat.first, a = 0; ma; ma = ma->id.next, a++) {
 -              if (ID_IS_LINKED(ma)) continue;
 -
 -              /* disputed material */
 -              if (ma->game.flag == MAT_BGE_DISPUTED) {
 -                      ma->game.flag = 0;
 -                      if (fileload) {
 -                              printf("Warning: material \"%s\" skipped.\n", ma->id.name + 2);
 -                              nowarning = 0;
 -                      }
 -                      else {
 -                              convert_tfacematerial(main, ma);
 -                      }
 -                      continue;
 -              }
 -      
 -              /* no conflicts in this material - 90% of cases
 -               * convert from tface system to material */
 -              else if (ma->game.flag < 0) {
 -                      decode_tfaceflag(ma, -(ma->game.flag), 1);
 -
 -                      /* material is good make sure all faces using
 -                       * this material are set to converted */
 -                      if (fileload) {
 -                              for (me = main->mesh.first; me; me = me->id.next) {
 -                                      /* check if this mesh uses this material */
 -                                      for (a = 0; a < me->totcol; a++)
 -                                              if (me->mat[a] == ma) break;
 -                                              
 -                                      /* no material found */
 -                                      if (a == me->totcol) continue;
 -                      
 -                                      /* get the active tface layer */
 -                                      index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
 -                                      cdl = (index == -1) ? NULL : &me->fdata.layers[index];
 -                                      if (!cdl) continue;
 -                      
 -                                      /* loop over all the faces and stop at the ones that use the material*/
 -                                      for (a = 0, mf = me->mface; a < me->totface; a++, mf++) {
 -                                              if (me->mat[mf->mat_nr] == ma) {
 -                                                      /* texface data for this face */
 -                                                      tf = ((MTFace *)cdl->data) + a;
 -                                                      tf->mode |= TF_CONVERTED;
 -                                              }
 -                                      }
 -                              }
 -                      }
 -              }
 -              /* material is not used by faces with texface
 -               * set the default flag - do it only once */
 -              else {
 -                      if (fileload) {
 -                              ma->game.flag = GEMAT_BACKCULL;
 -                      }
 -              }
 -      }
 -
 -      return nowarning;
 -}
 -
@@@ -1035,8 -1077,29 +1035,8 @@@ void MeshImporter::assign_material_to_g
        // Attention! This temporaly assigns material to object on purpose!
        // See note above.
        ob->actcol=0;
-       assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); 
+       assign_material(G.main, ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);
        
 -      COLLADAFW::TextureCoordinateBindingArray& tex_array = 
 -          cmaterial.getTextureCoordinateBindingArray();
 -      TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
 -      unsigned int i;
 -      // loop through <bind_vertex_inputs>
 -      for (i = 0; i < tex_array.getCount(); i++) {
 -              
 -              color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
 -                                                          color_texture);
 -      }
 -      
 -      // set texture face
 -      if (color_texture &&
 -          strlen((color_texture)->uvname) &&
 -          !STREQ(layername, color_texture->uvname))
 -      {
 -              texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
 -                                                                  color_texture->uvname);
 -              strcpy(layername, color_texture->uvname);
 -      }
 -      
        MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
        COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
        
@@@ -3622,11 -3205,11 +3622,11 @@@ static Base *mesh_separate_tagged(Main 
        CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
        CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
  
 -      base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
 +      base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, USER_DUP_MESH);
        /* DAG_relations_tag_update(bmain); */ /* normally would call directly after but in this case delay recalc */
-       assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
+       assign_matarar(bmain, base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
  
 -      ED_base_object_select(base_new, BA_SELECT);
 +      ED_object_base_select(base_new, BA_SELECT);
  
        BMO_op_callf(bm_old, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
                     "duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
@@@ -1454,20 -1570,20 +1454,20 @@@ static int make_links_data_exec(bContex
                                                ob_dst->data = obdata_id;
  
                                                /* if amount of material indices changed: */
-                                               test_object_materials(ob_dst, ob_dst->data);
+                                               test_object_materials(bmain, ob_dst, ob_dst->data);
  
 -                                              DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
 +                                              DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
                                                break;
                                        case MAKE_LINKS_MATERIALS:
                                                /* new approach, using functions from kernel */
                                                for (a = 0; a < ob_src->totcol; a++) {
                                                        Material *ma = give_current_material(ob_src, a + 1);
-                                                       assign_material(ob_dst, ma, a + 1, BKE_MAT_ASSIGN_USERPREF); /* also works with ma==NULL */
+                                                       assign_material(bmain, ob_dst, ma, a + 1, BKE_MAT_ASSIGN_USERPREF); /* also works with ma==NULL */
                                                }
 -                                              DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
 +                                              DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
                                                break;
                                        case MAKE_LINKS_ANIMDATA:
 -                                              BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, false);
 +                                              BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, false, true);
                                                if (ob_dst->data && ob_src->data) {
                                                        if (ID_IS_LINKED(obdata_id)) {
                                                                is_lib = true;
@@@ -1875,7 -1978,20 +1875,7 @@@ static void single_mat_users(Main *bmai
                                                BKE_animdata_copy_id_action(&man->id, false);
  
                                                man->id.us = 0;
-                                               assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF);
+                                               assign_material(bmain, ob, man, a, BKE_MAT_ASSIGN_USERPREF);
 -
 -                                              if (do_textures) {
 -                                                      for (b = 0; b < MAX_MTEX; b++) {
 -                                                              if (ma->mtex[b] && (tex = ma->mtex[b]->tex)) {
 -                                                                      if (tex->id.us > 1) {
 -                                                                              id_us_min(&tex->id);
 -                                                                              tex = BKE_texture_copy(bmain, tex);
 -                                                                              BKE_animdata_copy_id_action(&tex->id, false);
 -                                                                              man->mtex[b]->tex = tex;
 -                                                                      }
 -                                                              }
 -                                                      }
 -                                              }
                                        }
                                }
                        }
@@@ -2513,9 -2494,9 +2513,9 @@@ static int drop_named_material_invoke(b
        if (base == NULL || ma == NULL)
                return OPERATOR_CANCELLED;
  
-       assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
+       assign_material(CTX_data_main(C), base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
  
 -      DAG_id_tag_update(&base->object->id, OB_RECALC_OB);
 +      DEG_id_tag_update(&base->object->id, OB_RECALC_OB);
  
        WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, base->object);
        WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
@@@ -249,9 -241,10 +249,9 @@@ static Object *rna_Main_objects_new(Mai
        }
  
        ob = BKE_object_add_only_object(bmain, type, safe_name);
 -      id_us_min(&ob->id);
  
        ob->data = data;
-       test_object_materials(ob, ob->data);
+       test_object_materials(bmain, ob, ob->data);
  
        return ob;
  }
@@@ -744,8 -712,8 +744,8 @@@ static void rna_Object_active_material_
  {
        Object *ob = (Object *)ptr->id.data;
  
 -      DAG_id_tag_update(value.data, 0);
 +      DEG_id_tag_update(value.data, 0);
-       assign_material(ob, value.data, ob->actcol, BKE_MAT_ASSIGN_EXISTING);
+       assign_material(G.main, ob, value.data, ob->actcol, BKE_MAT_ASSIGN_EXISTING);
  }
  
  static int rna_Object_active_material_editable(PointerRNA *ptr, const char **UNUSED(r_info))