Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/material.c')
-rw-r--r--source/blender/blenkernel/intern/material.c226
1 files changed, 47 insertions, 179 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index db5ac54ada9..17811893c03 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -61,6 +61,8 @@
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_library.h"
+#include "BKE_library_query.h"
+#include "BKE_library_remap.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -217,12 +219,12 @@ Material *BKE_material_add(Main *bmain, const char *name)
}
/* XXX keep synced with next function */
-Material *BKE_material_copy(Material *ma)
+Material *BKE_material_copy(Main *bmain, Material *ma)
{
Material *man;
int a;
- man = BKE_libblock_copy(&ma->id);
+ man = BKE_libblock_copy(bmain, &ma->id);
id_lib_extern((ID *)man->group);
@@ -237,16 +239,17 @@ Material *BKE_material_copy(Material *ma)
if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
- if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
-
if (ma->nodetree) {
- man->nodetree = ntreeCopyTree(ma->nodetree);
+ man->nodetree = ntreeCopyTree(bmain, ma->nodetree);
}
+ man->preview = BKE_previewimg_copy(ma->preview);
+
BLI_listbase_clear(&man->gpumaterial);
-
- if (ma->id.lib) {
- BKE_id_lib_local_paths(G.main, ma->id.lib, &man->id);
+
+ if (ID_IS_LINKED_DATABLOCK(ma)) {
+ BKE_id_expand_local(&man->id);
+ BKE_id_lib_local_paths(bmain, ma->id.lib, &man->id);
}
return man;
@@ -282,180 +285,33 @@ Material *localize_material(Material *ma)
return man;
}
-static void extern_local_material(Material *ma)
-{
- int i;
- for (i = 0; i < MAX_MTEX; i++) {
- if (ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex);
- }
-}
-
-void BKE_material_make_local(Material *ma)
+void BKE_material_make_local(Main *bmain, Material *ma)
{
- Main *bmain = G.main;
- Object *ob;
- Mesh *me;
- Curve *cu;
- MetaBall *mb;
- int a;
bool is_local = false, is_lib = false;
/* - only lib users: do nothing
* - only local users: set flag
* - mixed: make copy
*/
-
- if (ma->id.lib == NULL) return;
- /* One local user; set flag and return. */
- if (ma->id.us == 1) {
- id_clear_lib_data(bmain, &ma->id);
- extern_local_material(ma);
+ if (!ID_IS_LINKED_DATABLOCK(ma)) {
return;
}
- /* Check which other IDs reference this one to determine if it's used by
- * lib or local */
- /* test objects */
- ob = bmain->object.first;
- while (ob) {
- if (ob->mat) {
- for (a = 0; a < ob->totcol; a++) {
- if (ob->mat[a] == ma) {
- if (ob->id.lib) is_lib = true;
- else is_local = true;
- }
- }
- }
- ob = ob->id.next;
- }
- /* test meshes */
- me = bmain->mesh.first;
- while (me) {
- if (me->mat) {
- for (a = 0; a < me->totcol; a++) {
- if (me->mat[a] == ma) {
- if (me->id.lib) is_lib = true;
- else is_local = true;
- }
- }
- }
- me = me->id.next;
- }
- /* test curves */
- cu = bmain->curve.first;
- while (cu) {
- if (cu->mat) {
- for (a = 0; a < cu->totcol; a++) {
- if (cu->mat[a] == ma) {
- if (cu->id.lib) is_lib = true;
- else is_local = true;
- }
- }
- }
- cu = cu->id.next;
- }
- /* test mballs */
- mb = bmain->mball.first;
- while (mb) {
- if (mb->mat) {
- for (a = 0; a < mb->totcol; a++) {
- if (mb->mat[a] == ma) {
- if (mb->id.lib) is_lib = true;
- else is_local = true;
- }
- }
- }
- mb = mb->id.next;
- }
-
- /* Only local users. */
- if (is_local && is_lib == false) {
- id_clear_lib_data(bmain, &ma->id);
- extern_local_material(ma);
- }
- /* Both user and local, so copy. */
- else if (is_local && is_lib) {
- Material *ma_new = BKE_material_copy(ma);
+ BKE_library_ID_test_usages(bmain, ma, &is_local, &is_lib);
- ma_new->id.us = 0;
+ if (is_local) {
+ if (!is_lib) {
+ id_clear_lib_data(bmain, &ma->id);
+ BKE_id_expand_local(&ma->id);
+ }
+ else {
+ Material *ma_new = BKE_material_copy(bmain, ma);
- /* Remap paths of new ID using old library as base. */
- BKE_id_lib_local_paths(bmain, ma->id.lib, &ma_new->id);
+ ma_new->id.us = 0;
- /* do objects */
- ob = bmain->object.first;
- while (ob) {
- if (ob->mat) {
- for (a = 0; a < ob->totcol; a++) {
- if (ob->mat[a] == ma) {
- if (ob->id.lib == NULL) {
- ob->mat[a] = ma_new;
- id_us_plus(&ma_new->id);
- id_us_min(&ma->id);
- }
- }
- }
- }
- ob = ob->id.next;
+ BKE_libblock_remap(bmain, ma, ma_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
- /* do meshes */
- me = bmain->mesh.first;
- while (me) {
- if (me->mat) {
- for (a = 0; a < me->totcol; a++) {
- if (me->mat[a] == ma) {
- if (me->id.lib == NULL) {
- me->mat[a] = ma_new;
- id_us_plus(&ma_new->id);
- id_us_min(&ma->id);
- }
- }
- }
- }
- me = me->id.next;
- }
- /* do curves */
- cu = bmain->curve.first;
- while (cu) {
- if (cu->mat) {
- for (a = 0; a < cu->totcol; a++) {
- if (cu->mat[a] == ma) {
- if (cu->id.lib == NULL) {
- cu->mat[a] = ma_new;
- id_us_plus(&ma_new->id);
- id_us_min(&ma->id);
- }
- }
- }
- }
- cu = cu->id.next;
- }
- /* do mballs */
- mb = bmain->mball.first;
- while (mb) {
- if (mb->mat) {
- for (a = 0; a < mb->totcol; a++) {
- if (mb->mat[a] == ma) {
- if (mb->id.lib == NULL) {
- mb->mat[a] = ma_new;
- id_us_plus(&ma_new->id);
- id_us_min(&ma->id);
- }
- }
- }
- }
- mb = mb->id.next;
- }
- }
-}
-
-/* for curve, mball, mesh types */
-void extern_local_matarar(struct Material **matar, short totcol)
-{
- short i;
- for (i = 0; i < totcol; i++) {
- id_lib_extern((ID *)matar[i]);
}
}
@@ -611,7 +467,7 @@ void BKE_material_append_id(ID *id, Material *ma)
(*matar)[(*totcol)++] = ma;
id_us_plus((ID *)ma);
- test_object_materials(G.main, id);
+ test_all_objects_materials(G.main, id);
}
}
@@ -637,7 +493,7 @@ Material *BKE_material_pop_id(ID *id, int index_i, bool update_data)
(*totcol)--;
*matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
- test_object_materials(G.main, id);
+ test_all_objects_materials(G.main, id);
}
if (update_data) {
@@ -776,7 +632,19 @@ void BKE_material_resize_object(Object *ob, const short totcol, bool do_id_user)
if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
}
-void test_object_materials(Main *bmain, ID *id)
+void test_object_materials(Object *ob, ID *id)
+{
+ /* make the ob mat-array same size as 'ob->data' mat-array */
+ const short *totcol;
+
+ if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
+ return;
+ }
+
+ BKE_material_resize_object(ob, *totcol, false);
+}
+
+void test_all_objects_materials(Main *bmain, ID *id)
{
/* make the ob mat-array same size as 'ob->data' mat-array */
Object *ob;
@@ -839,7 +707,7 @@ void assign_material_id(ID *id, Material *ma, short act)
if (ma)
id_us_plus(&ma->id);
- test_object_materials(G.main, id);
+ test_all_objects_materials(G.main, id);
}
void assign_material(Object *ob, Material *ma, short act, int assign_type)
@@ -852,8 +720,8 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type)
if (act < 1) act = 1;
/* prevent crashing when using accidentally */
- BLI_assert(ob->id.lib == NULL);
- if (ob->id.lib) return;
+ BLI_assert(!ID_IS_LINKED_DATABLOCK(ob));
+ if (ID_IS_LINKED_DATABLOCK(ob)) return;
/* test arraylens */
@@ -924,7 +792,7 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type)
if (ma)
id_us_plus(&ma->id);
- test_object_materials(G.main, ob->data);
+ test_object_materials(ob, ob->data);
}
@@ -1121,7 +989,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
Group *group;
for (group = G.main->group.first; group; group = group->id.next) {
- if (!group->id.lib && STREQ(group->id.name, ma->group->id.name)) {
+ if (!ID_IS_LINKED_DATABLOCK(group) && STREQ(group->id.name, ma->group->id.name)) {
ma->group = group;
}
}
@@ -2158,7 +2026,7 @@ static void convert_tfacematerial(Main *main, Material *ma)
}
/* create a new material */
else {
- mat_new = BKE_material_copy(ma);
+ mat_new = BKE_material_copy(main, ma);
if (mat_new) {
/* rename the material*/
BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
@@ -2230,7 +2098,7 @@ int do_version_tface(Main *main)
/* 1st part: marking mesh materials to update */
for (me = main->mesh.first; me; me = me->id.next) {
- if (me->id.lib) continue;
+ if (ID_IS_LINKED_DATABLOCK(me)) continue;
/* get the active tface layer */
index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
@@ -2284,7 +2152,7 @@ int do_version_tface(Main *main)
* 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 (ma->id.lib)
+ else if (ID_IS_LINKED_DATABLOCK(ma))
continue;
/* material already marked as disputed */
@@ -2349,7 +2217,7 @@ int do_version_tface(Main *main)
/* 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 (ma->id.lib) continue;
+ if (ID_IS_LINKED_DATABLOCK(ma)) continue;
/* disputed material */
if (ma->game.flag == MAT_BGE_DISPUTED) {