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.c2170
1 files changed, 1093 insertions, 1077 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 52e7c687694..a4da6663de8 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -21,7 +21,6 @@
* \ingroup bke
*/
-
#include <string.h>
#include <math.h>
#include <stddef.h>
@@ -78,98 +77,97 @@ static CLG_LogRef LOG = {"bke.material"};
/* called on startup, creator.c */
void init_def_material(void)
{
- BKE_material_init(&defmaterial);
+ BKE_material_init(&defmaterial);
}
/** Free (or release) any data used by this material (does not free the material itself). */
void BKE_material_free(Material *ma)
{
- BKE_animdata_free((ID *)ma, false);
+ BKE_animdata_free((ID *)ma, false);
- /* Free gpu material before the ntree */
- GPU_material_free(&ma->gpumaterial);
+ /* Free gpu material before the ntree */
+ GPU_material_free(&ma->gpumaterial);
- /* is no lib link block, but material extension */
- if (ma->nodetree) {
- ntreeFreeNestedTree(ma->nodetree);
- MEM_freeN(ma->nodetree);
- ma->nodetree = NULL;
- }
+ /* is no lib link block, but material extension */
+ if (ma->nodetree) {
+ ntreeFreeNestedTree(ma->nodetree);
+ MEM_freeN(ma->nodetree);
+ ma->nodetree = NULL;
+ }
- MEM_SAFE_FREE(ma->texpaintslot);
+ MEM_SAFE_FREE(ma->texpaintslot);
- MEM_SAFE_FREE(ma->gp_style);
+ MEM_SAFE_FREE(ma->gp_style);
- BKE_icon_id_delete((ID *)ma);
- BKE_previewimg_free(&ma->preview);
+ BKE_icon_id_delete((ID *)ma);
+ BKE_previewimg_free(&ma->preview);
}
void BKE_material_init_gpencil_settings(Material *ma)
{
- if ((ma) && (ma->gp_style == NULL)) {
- ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
-
- MaterialGPencilStyle *gp_style = ma->gp_style;
- /* set basic settings */
- gp_style->stroke_rgba[3] = 1.0f;
- gp_style->fill_rgba[3] = 1.0f;
- gp_style->pattern_gridsize = 0.1f;
- gp_style->gradient_radius = 0.5f;
- ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
- ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f);
- ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
- gp_style->texture_opacity = 1.0f;
- gp_style->texture_pixsize = 100.0f;
-
- gp_style->flag |= GP_STYLE_STROKE_SHOW;
- }
+ if ((ma) && (ma->gp_style == NULL)) {
+ ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
+
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ /* set basic settings */
+ gp_style->stroke_rgba[3] = 1.0f;
+ gp_style->fill_rgba[3] = 1.0f;
+ gp_style->pattern_gridsize = 0.1f;
+ gp_style->gradient_radius = 0.5f;
+ ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
+ ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f);
+ ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
+ gp_style->texture_opacity = 1.0f;
+ gp_style->texture_pixsize = 100.0f;
+
+ gp_style->flag |= GP_STYLE_STROKE_SHOW;
+ }
}
void BKE_material_init(Material *ma)
{
- BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ma, id));
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(ma, id));
- ma->r = ma->g = ma->b = 0.8;
- ma->specr = ma->specg = ma->specb = 1.0;
- ma->a = 1.0f;
- ma->spec = 0.5;
+ ma->r = ma->g = ma->b = 0.8;
+ ma->specr = ma->specg = ma->specb = 1.0;
+ ma->a = 1.0f;
+ ma->spec = 0.5;
- ma->roughness = 0.25f;
+ ma->roughness = 0.25f;
- ma->pr_type = MA_SPHERE;
+ ma->pr_type = MA_SPHERE;
- ma->preview = NULL;
+ ma->preview = NULL;
- ma->alpha_threshold = 0.5f;
+ ma->alpha_threshold = 0.5f;
- ma->blend_shadow = MA_BS_SOLID;
+ ma->blend_shadow = MA_BS_SOLID;
}
Material *BKE_material_add(Main *bmain, const char *name)
{
- Material *ma;
+ Material *ma;
- ma = BKE_libblock_alloc(bmain, ID_MA, name, 0);
+ ma = BKE_libblock_alloc(bmain, ID_MA, name, 0);
- BKE_material_init(ma);
+ BKE_material_init(ma);
- return ma;
+ return ma;
}
Material *BKE_material_add_gpencil(Main *bmain, const char *name)
{
- Material *ma;
+ Material *ma;
- ma = BKE_material_add(bmain, name);
+ ma = BKE_material_add(bmain, name);
- /* grease pencil settings */
- if (ma != NULL) {
- BKE_material_init_gpencil_settings(ma);
- }
- return ma;
+ /* grease pencil settings */
+ if (ma != NULL) {
+ BKE_material_init_gpencil_settings(ma);
+ }
+ return ma;
}
-
/**
* Only copy internal data of Material ID from source to already allocated/initialized destination.
* You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
@@ -180,633 +178,648 @@ Material *BKE_material_add_gpencil(Main *bmain, const char *name)
*/
void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_src, const int flag)
{
- if (ma_src->nodetree) {
- /* Note: nodetree is *not* in bmain, however this specific case is handled at lower level
- * (see BKE_libblock_copy_ex()). */
- BKE_id_copy_ex(bmain, (ID *)ma_src->nodetree, (ID **)&ma_dst->nodetree, flag);
- }
-
- if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
- BKE_previewimg_id_copy(&ma_dst->id, &ma_src->id);
- }
- else {
- ma_dst->preview = NULL;
- }
-
- if (ma_src->texpaintslot != NULL) {
- ma_dst->texpaintslot = MEM_dupallocN(ma_src->texpaintslot);
- }
-
- if (ma_src->gp_style != NULL) {
- ma_dst->gp_style = MEM_dupallocN(ma_src->gp_style);
- }
-
- BLI_listbase_clear(&ma_dst->gpumaterial);
-
- /* TODO Duplicate Engine Settings and set runtime to NULL */
+ if (ma_src->nodetree) {
+ /* Note: nodetree is *not* in bmain, however this specific case is handled at lower level
+ * (see BKE_libblock_copy_ex()). */
+ BKE_id_copy_ex(bmain, (ID *)ma_src->nodetree, (ID **)&ma_dst->nodetree, flag);
+ }
+
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&ma_dst->id, &ma_src->id);
+ }
+ else {
+ ma_dst->preview = NULL;
+ }
+
+ if (ma_src->texpaintslot != NULL) {
+ ma_dst->texpaintslot = MEM_dupallocN(ma_src->texpaintslot);
+ }
+
+ if (ma_src->gp_style != NULL) {
+ ma_dst->gp_style = MEM_dupallocN(ma_src->gp_style);
+ }
+
+ BLI_listbase_clear(&ma_dst->gpumaterial);
+
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
}
Material *BKE_material_copy(Main *bmain, const Material *ma)
{
- Material *ma_copy;
- BKE_id_copy(bmain, &ma->id, (ID **)&ma_copy);
- return ma_copy;
+ Material *ma_copy;
+ BKE_id_copy(bmain, &ma->id, (ID **)&ma_copy);
+ return ma_copy;
}
/* XXX (see above) material copy without adding to main dbase */
Material *BKE_material_localize(Material *ma)
{
- /* TODO(bastien): Replace with something like:
- *
- * Material *ma_copy;
- * BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy,
- * LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
- * false);
- * return ma_copy;
- *
- * NOTE: Only possible once nested node trees are fully converted to that too. */
+ /* TODO(bastien): Replace with something like:
+ *
+ * Material *ma_copy;
+ * BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy,
+ * LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT,
+ * false);
+ * return ma_copy;
+ *
+ * NOTE: Only possible once nested node trees are fully converted to that too. */
- Material *man = BKE_libblock_copy_for_localize(&ma->id);
+ Material *man = BKE_libblock_copy_for_localize(&ma->id);
- man->texpaintslot = NULL;
- man->preview = NULL;
+ man->texpaintslot = NULL;
+ man->preview = NULL;
- if (ma->nodetree != NULL) {
- man->nodetree = ntreeLocalize(ma->nodetree);
- }
+ if (ma->nodetree != NULL) {
+ man->nodetree = ntreeLocalize(ma->nodetree);
+ }
- if (ma->gp_style != NULL) {
- man->gp_style = MEM_dupallocN(ma->gp_style);
- }
+ if (ma->gp_style != NULL) {
+ man->gp_style = MEM_dupallocN(ma->gp_style);
+ }
- BLI_listbase_clear(&man->gpumaterial);
+ BLI_listbase_clear(&man->gpumaterial);
- /* TODO Duplicate Engine Settings and set runtime to NULL */
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
- man->id.tag |= LIB_TAG_LOCALIZED;
+ man->id.tag |= LIB_TAG_LOCALIZED;
- return man;
+ return man;
}
void BKE_material_make_local(Main *bmain, Material *ma, const bool lib_local)
{
- BKE_id_make_local_generic(bmain, &ma->id, true, lib_local);
+ BKE_id_make_local_generic(bmain, &ma->id, true, lib_local);
}
Material ***give_matarar(Object *ob)
{
- Mesh *me;
- Curve *cu;
- MetaBall *mb;
- bGPdata *gpd;
-
- if (ob->type == OB_MESH) {
- me = ob->data;
- return &(me->mat);
- }
- else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
- cu = ob->data;
- return &(cu->mat);
- }
- else if (ob->type == OB_MBALL) {
- mb = ob->data;
- return &(mb->mat);
- }
- else if (ob->type == OB_GPENCIL) {
- gpd = ob->data;
- return &(gpd->mat);
- }
- return NULL;
+ Mesh *me;
+ Curve *cu;
+ MetaBall *mb;
+ bGPdata *gpd;
+
+ if (ob->type == OB_MESH) {
+ me = ob->data;
+ return &(me->mat);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
+ cu = ob->data;
+ return &(cu->mat);
+ }
+ else if (ob->type == OB_MBALL) {
+ mb = ob->data;
+ return &(mb->mat);
+ }
+ else if (ob->type == OB_GPENCIL) {
+ gpd = ob->data;
+ return &(gpd->mat);
+ }
+ return NULL;
}
short *give_totcolp(Object *ob)
{
- Mesh *me;
- Curve *cu;
- MetaBall *mb;
- bGPdata *gpd;
-
- if (ob->type == OB_MESH) {
- me = ob->data;
- return &(me->totcol);
- }
- else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
- cu = ob->data;
- return &(cu->totcol);
- }
- else if (ob->type == OB_MBALL) {
- mb = ob->data;
- return &(mb->totcol);
- }
- else if (ob->type == OB_GPENCIL) {
- gpd = ob->data;
- return &(gpd->totcol);
- }
- return NULL;
+ Mesh *me;
+ Curve *cu;
+ MetaBall *mb;
+ bGPdata *gpd;
+
+ if (ob->type == OB_MESH) {
+ me = ob->data;
+ return &(me->totcol);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
+ cu = ob->data;
+ return &(cu->totcol);
+ }
+ else if (ob->type == OB_MBALL) {
+ mb = ob->data;
+ return &(mb->totcol);
+ }
+ else if (ob->type == OB_GPENCIL) {
+ gpd = ob->data;
+ return &(gpd->totcol);
+ }
+ return NULL;
}
/* same as above but for ID's */
Material ***give_matarar_id(ID *id)
{
- /* ensure we don't try get materials from non-obdata */
- BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
-
- switch (GS(id->name)) {
- case ID_ME:
- return &(((Mesh *)id)->mat);
- case ID_CU:
- return &(((Curve *)id)->mat);
- case ID_MB:
- return &(((MetaBall *)id)->mat);
- case ID_GD:
- return &(((bGPdata *)id)->mat);
- default:
- break;
- }
- return NULL;
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ return &(((Mesh *)id)->mat);
+ case ID_CU:
+ return &(((Curve *)id)->mat);
+ case ID_MB:
+ return &(((MetaBall *)id)->mat);
+ case ID_GD:
+ return &(((bGPdata *)id)->mat);
+ default:
+ break;
+ }
+ return NULL;
}
short *give_totcolp_id(ID *id)
{
- /* ensure we don't try get materials from non-obdata */
- BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
-
- switch (GS(id->name)) {
- case ID_ME:
- return &(((Mesh *)id)->totcol);
- case ID_CU:
- return &(((Curve *)id)->totcol);
- case ID_MB:
- return &(((MetaBall *)id)->totcol);
- case ID_GD:
- return &(((bGPdata *)id)->totcol);
- default:
- break;
- }
- return NULL;
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ return &(((Mesh *)id)->totcol);
+ case ID_CU:
+ return &(((Curve *)id)->totcol);
+ case ID_MB:
+ return &(((MetaBall *)id)->totcol);
+ case ID_GD:
+ return &(((bGPdata *)id)->totcol);
+ default:
+ break;
+ }
+ return NULL;
}
static void material_data_index_remove_id(ID *id, short index)
{
- /* ensure we don't try get materials from non-obdata */
- BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
-
- switch (GS(id->name)) {
- case ID_ME:
- BKE_mesh_material_index_remove((Mesh *)id, index);
- break;
- case ID_CU:
- BKE_curve_material_index_remove((Curve *)id, index);
- break;
- case ID_MB:
- /* meta-elems don't have materials atm */
- break;
- case ID_GD:
- BKE_gpencil_material_index_remove((bGPdata *)id, index);
- break;
- default:
- break;
- }
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ BKE_mesh_material_index_remove((Mesh *)id, index);
+ break;
+ case ID_CU:
+ BKE_curve_material_index_remove((Curve *)id, index);
+ break;
+ case ID_MB:
+ /* meta-elems don't have materials atm */
+ break;
+ case ID_GD:
+ BKE_gpencil_material_index_remove((bGPdata *)id, index);
+ break;
+ default:
+ break;
+ }
}
static void material_data_index_clear_id(ID *id)
{
- /* ensure we don't try get materials from non-obdata */
- BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
-
- switch (GS(id->name)) {
- case ID_ME:
- BKE_mesh_material_index_clear((Mesh *)id);
- break;
- case ID_CU:
- BKE_curve_material_index_clear((Curve *)id);
- break;
- case ID_MB:
- /* meta-elems don't have materials atm */
- break;
- default:
- break;
- }
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ BKE_mesh_material_index_clear((Mesh *)id);
+ break;
+ case ID_CU:
+ BKE_curve_material_index_clear((Curve *)id);
+ break;
+ case ID_MB:
+ /* meta-elems don't have materials atm */
+ break;
+ default:
+ break;
+ }
}
void BKE_material_resize_id(Main *bmain, ID *id, short totcol, bool do_id_user)
{
- Material ***matar = give_matarar_id(id);
- short *totcolp = give_totcolp_id(id);
-
- if (matar == NULL) {
- return;
- }
-
- if (do_id_user && totcol < (*totcolp)) {
- short i;
- for (i = totcol; i < (*totcolp); i++) {
- id_us_min((ID *)(*matar)[i]);
- }
- }
-
- if (totcol == 0) {
- if (*totcolp) {
- MEM_freeN(*matar);
- *matar = NULL;
- }
- }
- else {
- *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
- }
- *totcolp = totcol;
-
- DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
+ Material ***matar = give_matarar_id(id);
+ short *totcolp = give_totcolp_id(id);
+
+ if (matar == NULL) {
+ return;
+ }
+
+ if (do_id_user && totcol < (*totcolp)) {
+ short i;
+ for (i = totcol; i < (*totcolp); i++) {
+ id_us_min((ID *)(*matar)[i]);
+ }
+ }
+
+ if (totcol == 0) {
+ if (*totcolp) {
+ MEM_freeN(*matar);
+ *matar = NULL;
+ }
+ }
+ else {
+ *matar = MEM_recallocN(*matar, sizeof(void *) * totcol);
+ }
+ *totcolp = totcol;
+
+ DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
}
void BKE_material_append_id(Main *bmain, ID *id, Material *ma)
{
- Material ***matar;
- if ((matar = give_matarar_id(id))) {
- short *totcol = give_totcolp_id(id);
- Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
- if (*totcol) memcpy(mat, *matar, sizeof(void *) * (*totcol));
- if (*matar) MEM_freeN(*matar);
-
- *matar = mat;
- (*matar)[(*totcol)++] = ma;
-
- id_us_plus((ID *)ma);
- test_all_objects_materials(bmain, id);
-
- DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
+ Material ***matar;
+ if ((matar = give_matarar_id(id))) {
+ short *totcol = give_totcolp_id(id);
+ Material **mat = MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
+ if (*totcol)
+ memcpy(mat, *matar, sizeof(void *) * (*totcol));
+ if (*matar)
+ MEM_freeN(*matar);
+
+ *matar = mat;
+ (*matar)[(*totcol)++] = ma;
+
+ id_us_plus((ID *)ma);
+ test_all_objects_materials(bmain, id);
+
+ DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
}
Material *BKE_material_pop_id(Main *bmain, ID *id, int index_i, bool update_data)
{
- short index = (short)index_i;
- Material *ret = NULL;
- Material ***matar;
- if ((matar = give_matarar_id(id))) {
- short *totcol = give_totcolp_id(id);
- if (index >= 0 && index < (*totcol)) {
- ret = (*matar)[index];
- id_us_min((ID *)ret);
-
- if (*totcol <= 1) {
- *totcol = 0;
- MEM_freeN(*matar);
- *matar = NULL;
- }
- else {
- if (index + 1 != (*totcol))
- memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1)));
-
- (*totcol)--;
- *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
- test_all_objects_materials(bmain, id);
- }
-
- if (update_data) {
- /* decrease mat_nr index */
- material_data_index_remove_id(id, index);
- }
-
- DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
- }
-
- return ret;
+ short index = (short)index_i;
+ Material *ret = NULL;
+ Material ***matar;
+ if ((matar = give_matarar_id(id))) {
+ short *totcol = give_totcolp_id(id);
+ if (index >= 0 && index < (*totcol)) {
+ ret = (*matar)[index];
+ id_us_min((ID *)ret);
+
+ if (*totcol <= 1) {
+ *totcol = 0;
+ MEM_freeN(*matar);
+ *matar = NULL;
+ }
+ else {
+ if (index + 1 != (*totcol))
+ memmove((*matar) + index,
+ (*matar) + (index + 1),
+ sizeof(void *) * ((*totcol) - (index + 1)));
+
+ (*totcol)--;
+ *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
+ test_all_objects_materials(bmain, id);
+ }
+
+ if (update_data) {
+ /* decrease mat_nr index */
+ material_data_index_remove_id(id, index);
+ }
+
+ DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
+ }
+
+ return ret;
}
void BKE_material_clear_id(Main *bmain, ID *id, bool update_data)
{
- Material ***matar;
- if ((matar = give_matarar_id(id))) {
- short *totcol = give_totcolp_id(id);
-
- while ((*totcol)--) {
- id_us_min((ID *)((*matar)[*totcol]));
- }
- *totcol = 0;
- if (*matar) {
- MEM_freeN(*matar);
- *matar = NULL;
- }
-
- if (update_data) {
- /* decrease mat_nr index */
- material_data_index_clear_id(id);
- }
-
- DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(bmain);
- }
+ Material ***matar;
+ if ((matar = give_matarar_id(id))) {
+ short *totcol = give_totcolp_id(id);
+
+ while ((*totcol)--) {
+ id_us_min((ID *)((*matar)[*totcol]));
+ }
+ *totcol = 0;
+ if (*matar) {
+ MEM_freeN(*matar);
+ *matar = NULL;
+ }
+
+ if (update_data) {
+ /* decrease mat_nr index */
+ material_data_index_clear_id(id);
+ }
+
+ DEG_id_tag_update(id, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+ }
}
Material **give_current_material_p(Object *ob, short act)
{
- Material ***matarar, **ma_p;
- const short *totcolp;
-
- if (ob == NULL) return NULL;
-
- /* if object cannot have material, (totcolp == NULL) */
- totcolp = give_totcolp(ob);
- if (totcolp == NULL || ob->totcol == 0) return NULL;
-
- /* return NULL for invalid 'act', can happen for mesh face indices */
- if (act > ob->totcol)
- return NULL;
- else if (act <= 0) {
- if (act < 0) {
- CLOG_ERROR(&LOG, "Negative material index!");
- }
- return NULL;
- }
-
- if (ob->matbits && ob->matbits[act - 1]) { /* in object */
- ma_p = &ob->mat[act - 1];
- }
- else { /* in data */
-
- /* check for inconsistency */
- if (*totcolp < ob->totcol)
- ob->totcol = *totcolp;
- if (act > ob->totcol) act = ob->totcol;
-
- matarar = give_matarar(ob);
-
- if (matarar && *matarar) {
- ma_p = &(*matarar)[act - 1];
- }
- else {
- ma_p = NULL;
- }
- }
-
- return ma_p;
+ Material ***matarar, **ma_p;
+ const short *totcolp;
+
+ if (ob == NULL)
+ return NULL;
+
+ /* if object cannot have material, (totcolp == NULL) */
+ totcolp = give_totcolp(ob);
+ if (totcolp == NULL || ob->totcol == 0)
+ return NULL;
+
+ /* return NULL for invalid 'act', can happen for mesh face indices */
+ if (act > ob->totcol)
+ return NULL;
+ else if (act <= 0) {
+ if (act < 0) {
+ CLOG_ERROR(&LOG, "Negative material index!");
+ }
+ return NULL;
+ }
+
+ if (ob->matbits && ob->matbits[act - 1]) { /* in object */
+ ma_p = &ob->mat[act - 1];
+ }
+ else { /* in data */
+
+ /* check for inconsistency */
+ if (*totcolp < ob->totcol)
+ ob->totcol = *totcolp;
+ if (act > ob->totcol)
+ act = ob->totcol;
+
+ matarar = give_matarar(ob);
+
+ if (matarar && *matarar) {
+ ma_p = &(*matarar)[act - 1];
+ }
+ else {
+ ma_p = NULL;
+ }
+ }
+
+ return ma_p;
}
Material *give_current_material(Object *ob, short act)
{
- Material **ma_p = give_current_material_p(ob, act);
- return ma_p ? *ma_p : NULL;
+ Material **ma_p = give_current_material_p(ob, act);
+ return ma_p ? *ma_p : NULL;
}
MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act)
{
- Material *ma = give_current_material(ob, act);
- if (ma != NULL) {
- if (ma->gp_style == NULL) {
- BKE_material_init_gpencil_settings(ma);
- }
-
- return ma->gp_style;
- }
- else {
- return NULL;
- }
+ Material *ma = give_current_material(ob, act);
+ if (ma != NULL) {
+ if (ma->gp_style == NULL) {
+ BKE_material_init_gpencil_settings(ma);
+ }
+
+ return ma->gp_style;
+ }
+ else {
+ return NULL;
+ }
}
Material *give_node_material(Material *ma)
{
- if (ma && ma->use_nodes && ma->nodetree) {
- bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
+ if (ma && ma->use_nodes && ma->nodetree) {
+ bNode *node = nodeGetActiveID(ma->nodetree, ID_MA);
- if (node)
- return (Material *)node->id;
- }
+ if (node)
+ return (Material *)node->id;
+ }
- return NULL;
+ return NULL;
}
void BKE_material_resize_object(Main *bmain, Object *ob, const short totcol, bool do_id_user)
{
- Material **newmatar;
- char *newmatbits;
-
- if (do_id_user && totcol < ob->totcol) {
- short i;
- for (i = totcol; i < ob->totcol; i++) {
- id_us_min((ID *)ob->mat[i]);
- }
- }
-
- if (totcol == 0) {
- if (ob->totcol) {
- MEM_freeN(ob->mat);
- MEM_freeN(ob->matbits);
- ob->mat = NULL;
- ob->matbits = NULL;
- }
- }
- else if (ob->totcol < totcol) {
- newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
- newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
- if (ob->totcol) {
- memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
- memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
- MEM_freeN(ob->mat);
- MEM_freeN(ob->matbits);
- }
- ob->mat = newmatar;
- ob->matbits = newmatbits;
- }
- /* XXX, why not realloc on shrink? - campbell */
-
- ob->totcol = totcol;
- if (ob->totcol && ob->actcol == 0) ob->actcol = 1;
- if (ob->actcol > ob->totcol) ob->actcol = ob->totcol;
-
- DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_GEOMETRY);
- DEG_relations_tag_update(bmain);
+ Material **newmatar;
+ char *newmatbits;
+
+ if (do_id_user && totcol < ob->totcol) {
+ short i;
+ for (i = totcol; i < ob->totcol; i++) {
+ id_us_min((ID *)ob->mat[i]);
+ }
+ }
+
+ if (totcol == 0) {
+ if (ob->totcol) {
+ MEM_freeN(ob->mat);
+ MEM_freeN(ob->matbits);
+ ob->mat = NULL;
+ ob->matbits = NULL;
+ }
+ }
+ else if (ob->totcol < totcol) {
+ newmatar = MEM_callocN(sizeof(void *) * totcol, "newmatar");
+ newmatbits = MEM_callocN(sizeof(char) * totcol, "newmatbits");
+ if (ob->totcol) {
+ memcpy(newmatar, ob->mat, sizeof(void *) * ob->totcol);
+ memcpy(newmatbits, ob->matbits, sizeof(char) * ob->totcol);
+ MEM_freeN(ob->mat);
+ MEM_freeN(ob->matbits);
+ }
+ ob->mat = newmatar;
+ ob->matbits = newmatbits;
+ }
+ /* XXX, why not realloc on shrink? - campbell */
+
+ ob->totcol = totcol;
+ if (ob->totcol && ob->actcol == 0)
+ ob->actcol = 1;
+ if (ob->actcol > ob->totcol)
+ ob->actcol = ob->totcol;
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_GEOMETRY);
+ DEG_relations_tag_update(bmain);
}
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;
+ /* 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;
- }
+ if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
+ return;
+ }
- BKE_material_resize_object(bmain, ob, *totcol, false);
+ BKE_material_resize_object(bmain, 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;
- const short *totcol;
-
- if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
- return;
- }
-
- BKE_main_lock(bmain);
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- if (ob->data == id) {
- BKE_material_resize_object(bmain, ob, *totcol, false);
- }
- }
- BKE_main_unlock(bmain);
+ /* make the ob mat-array same size as 'ob->data' mat-array */
+ Object *ob;
+ const short *totcol;
+
+ if (id == NULL || (totcol = give_totcolp_id(id)) == NULL) {
+ return;
+ }
+
+ BKE_main_lock(bmain);
+ for (ob = bmain->objects.first; ob; ob = ob->id.next) {
+ if (ob->data == id) {
+ BKE_material_resize_object(bmain, ob, *totcol, false);
+ }
+ }
+ BKE_main_unlock(bmain);
}
void assign_material_id(Main *bmain, ID *id, Material *ma, short act)
{
- Material *mao, **matar, ***matarar;
- short *totcolp;
+ Material *mao, **matar, ***matarar;
+ short *totcolp;
- if (act > MAXMAT) return;
- if (act < 1) act = 1;
+ if (act > MAXMAT)
+ return;
+ if (act < 1)
+ act = 1;
- /* test arraylens */
+ /* test arraylens */
- totcolp = give_totcolp_id(id);
- matarar = give_matarar_id(id);
+ totcolp = give_totcolp_id(id);
+ matarar = give_matarar_id(id);
- if (totcolp == NULL || matarar == NULL) return;
+ if (totcolp == NULL || matarar == NULL)
+ return;
- if (act > *totcolp) {
- matar = MEM_callocN(sizeof(void *) * act, "matarray1");
+ if (act > *totcolp) {
+ matar = MEM_callocN(sizeof(void *) * act, "matarray1");
- if (*totcolp) {
- memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
- MEM_freeN(*matarar);
- }
+ if (*totcolp) {
+ memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
+ MEM_freeN(*matarar);
+ }
- *matarar = matar;
- *totcolp = act;
- }
+ *matarar = matar;
+ *totcolp = act;
+ }
- /* in data */
- mao = (*matarar)[act - 1];
- if (mao)
- id_us_min(&mao->id);
- (*matarar)[act - 1] = ma;
+ /* in data */
+ mao = (*matarar)[act - 1];
+ if (mao)
+ id_us_min(&mao->id);
+ (*matarar)[act - 1] = ma;
- if (ma)
- id_us_plus(&ma->id);
+ if (ma)
+ id_us_plus(&ma->id);
- test_all_objects_materials(bmain, id);
+ test_all_objects_materials(bmain, id);
}
void assign_material(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
{
- Material *mao, **matar, ***matarar;
- short *totcolp;
- char bit = 0;
-
- if (act > MAXMAT) return;
- if (act < 1) act = 1;
-
- /* prevent crashing when using accidentally */
- BLI_assert(!ID_IS_LINKED(ob));
- if (ID_IS_LINKED(ob)) return;
-
- /* test arraylens */
-
- totcolp = give_totcolp(ob);
- matarar = give_matarar(ob);
-
- if (totcolp == NULL || matarar == NULL) return;
-
- if (act > *totcolp) {
- matar = MEM_callocN(sizeof(void *) * act, "matarray1");
-
- if (*totcolp) {
- memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
- MEM_freeN(*matarar);
- }
-
- *matarar = matar;
- *totcolp = act;
- }
-
- if (act > ob->totcol) {
- /* Need more space in the material arrays */
- ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
- ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
- ob->totcol = act;
- }
-
- /* Determine the object/mesh linking */
- if (assign_type == BKE_MAT_ASSIGN_EXISTING) {
- /* keep existing option (avoid confusion in scripts),
- * intentionally ignore userpref (default to obdata). */
- bit = ob->matbits[act - 1];
- }
- else if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
- /* copy from previous material */
- bit = ob->matbits[ob->actcol - 1];
- }
- else {
- switch (assign_type) {
- case BKE_MAT_ASSIGN_OBDATA:
- bit = 0;
- break;
- case BKE_MAT_ASSIGN_OBJECT:
- bit = 1;
- break;
- case BKE_MAT_ASSIGN_USERPREF:
- default:
- bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
- break;
- }
- }
-
- /* do it */
-
- ob->matbits[act - 1] = bit;
- if (bit == 1) { /* in object */
- mao = ob->mat[act - 1];
- if (mao)
- id_us_min(&mao->id);
- ob->mat[act - 1] = ma;
- test_object_materials(bmain, ob, ob->data);
- }
- else { /* in data */
- mao = (*matarar)[act - 1];
- if (mao)
- id_us_min(&mao->id);
- (*matarar)[act - 1] = ma;
- test_all_objects_materials(bmain, ob->data); /* Data may be used by several objects... */
- }
-
- if (ma)
- id_us_plus(&ma->id);
+ Material *mao, **matar, ***matarar;
+ short *totcolp;
+ char bit = 0;
+
+ if (act > MAXMAT)
+ return;
+ if (act < 1)
+ act = 1;
+
+ /* prevent crashing when using accidentally */
+ BLI_assert(!ID_IS_LINKED(ob));
+ if (ID_IS_LINKED(ob))
+ return;
+
+ /* test arraylens */
+
+ totcolp = give_totcolp(ob);
+ matarar = give_matarar(ob);
+
+ if (totcolp == NULL || matarar == NULL)
+ return;
+
+ if (act > *totcolp) {
+ matar = MEM_callocN(sizeof(void *) * act, "matarray1");
+
+ if (*totcolp) {
+ memcpy(matar, *matarar, sizeof(void *) * (*totcolp));
+ MEM_freeN(*matarar);
+ }
+
+ *matarar = matar;
+ *totcolp = act;
+ }
+
+ if (act > ob->totcol) {
+ /* Need more space in the material arrays */
+ ob->mat = MEM_recallocN_id(ob->mat, sizeof(void *) * act, "matarray2");
+ ob->matbits = MEM_recallocN_id(ob->matbits, sizeof(char) * act, "matbits1");
+ ob->totcol = act;
+ }
+
+ /* Determine the object/mesh linking */
+ if (assign_type == BKE_MAT_ASSIGN_EXISTING) {
+ /* keep existing option (avoid confusion in scripts),
+ * intentionally ignore userpref (default to obdata). */
+ bit = ob->matbits[act - 1];
+ }
+ else if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
+ /* copy from previous material */
+ bit = ob->matbits[ob->actcol - 1];
+ }
+ else {
+ switch (assign_type) {
+ case BKE_MAT_ASSIGN_OBDATA:
+ bit = 0;
+ break;
+ case BKE_MAT_ASSIGN_OBJECT:
+ bit = 1;
+ break;
+ case BKE_MAT_ASSIGN_USERPREF:
+ default:
+ bit = (U.flag & USER_MAT_ON_OB) ? 1 : 0;
+ break;
+ }
+ }
+
+ /* do it */
+
+ ob->matbits[act - 1] = bit;
+ if (bit == 1) { /* in object */
+ mao = ob->mat[act - 1];
+ if (mao)
+ id_us_min(&mao->id);
+ ob->mat[act - 1] = ma;
+ test_object_materials(bmain, ob, ob->data);
+ }
+ else { /* in data */
+ mao = (*matarar)[act - 1];
+ if (mao)
+ id_us_min(&mao->id);
+ (*matarar)[act - 1] = ma;
+ test_all_objects_materials(bmain, ob->data); /* Data may be used by several objects... */
+ }
+
+ if (ma)
+ id_us_plus(&ma->id);
}
-
void BKE_material_remap_object(Object *ob, const unsigned int *remap)
{
- Material ***matar = give_matarar(ob);
- const short *totcol_p = give_totcolp(ob);
-
- BLI_array_permute(ob->mat, ob->totcol, remap);
-
- if (ob->matbits) {
- BLI_array_permute(ob->matbits, ob->totcol, remap);
- }
-
- if (matar) {
- BLI_array_permute(*matar, *totcol_p, remap);
- }
-
- if (ob->type == OB_MESH) {
- BKE_mesh_material_remap(ob->data, remap, ob->totcol);
- }
- else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- BKE_curve_material_remap(ob->data, remap, ob->totcol);
- }
- else if (ob->type == OB_GPENCIL) {
- BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
- }
- else {
- /* add support for this object data! */
- BLI_assert(matar == NULL);
- }
+ Material ***matar = give_matarar(ob);
+ const short *totcol_p = give_totcolp(ob);
+
+ BLI_array_permute(ob->mat, ob->totcol, remap);
+
+ if (ob->matbits) {
+ BLI_array_permute(ob->matbits, ob->totcol, remap);
+ }
+
+ if (matar) {
+ BLI_array_permute(*matar, *totcol_p, remap);
+ }
+
+ if (ob->type == OB_MESH) {
+ BKE_mesh_material_remap(ob->data, remap, ob->totcol);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ BKE_curve_material_remap(ob->data, remap, ob->totcol);
+ }
+ else if (ob->type == OB_GPENCIL) {
+ BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
+ }
+ else {
+ /* add support for this object data! */
+ BLI_assert(matar == NULL);
+ }
}
/**
@@ -815,550 +828,553 @@ void BKE_material_remap_object(Object *ob, const unsigned int *remap)
* \param remap_src_to_dst: An array the size of `ob_src->totcol`
* where index values are filled in which map to \a ob_dst materials.
*/
-void BKE_material_remap_object_calc(
- Object *ob_dst, Object *ob_src,
- short *remap_src_to_dst)
+void BKE_material_remap_object_calc(Object *ob_dst, Object *ob_src, short *remap_src_to_dst)
{
- if (ob_src->totcol == 0) {
- return;
- }
-
- GHash *gh_mat_map = BLI_ghash_ptr_new_ex(__func__, ob_src->totcol);
-
- for (int i = 0; i < ob_dst->totcol; i++) {
- Material *ma_src = give_current_material(ob_dst, i + 1);
- BLI_ghash_reinsert(gh_mat_map, ma_src, POINTER_FROM_INT(i), NULL, NULL);
- }
-
- /* setup default mapping (when materials don't match) */
- {
- int i = 0;
- if (ob_dst->totcol >= ob_src->totcol) {
- for (; i < ob_src->totcol; i++) {
- remap_src_to_dst[i] = i;
- }
- }
- else {
- for (; i < ob_dst->totcol; i++) {
- remap_src_to_dst[i] = i;
- }
- for (; i < ob_src->totcol; i++) {
- remap_src_to_dst[i] = 0;
- }
- }
- }
-
- for (int i = 0; i < ob_src->totcol; i++) {
- Material *ma_src = give_current_material(ob_src, i + 1);
-
- if ((i < ob_dst->totcol) && (ma_src == give_current_material(ob_dst, i + 1))) {
- /* when objects have exact matching materials - keep existing index */
- }
- else {
- void **index_src_p = BLI_ghash_lookup_p(gh_mat_map, ma_src);
- if (index_src_p) {
- remap_src_to_dst[i] = POINTER_AS_INT(*index_src_p);
- }
- }
- }
-
- BLI_ghash_free(gh_mat_map, NULL, NULL);
+ if (ob_src->totcol == 0) {
+ return;
+ }
+
+ GHash *gh_mat_map = BLI_ghash_ptr_new_ex(__func__, ob_src->totcol);
+
+ for (int i = 0; i < ob_dst->totcol; i++) {
+ Material *ma_src = give_current_material(ob_dst, i + 1);
+ BLI_ghash_reinsert(gh_mat_map, ma_src, POINTER_FROM_INT(i), NULL, NULL);
+ }
+
+ /* setup default mapping (when materials don't match) */
+ {
+ int i = 0;
+ if (ob_dst->totcol >= ob_src->totcol) {
+ for (; i < ob_src->totcol; i++) {
+ remap_src_to_dst[i] = i;
+ }
+ }
+ else {
+ for (; i < ob_dst->totcol; i++) {
+ remap_src_to_dst[i] = i;
+ }
+ for (; i < ob_src->totcol; i++) {
+ remap_src_to_dst[i] = 0;
+ }
+ }
+ }
+
+ for (int i = 0; i < ob_src->totcol; i++) {
+ Material *ma_src = give_current_material(ob_src, i + 1);
+
+ if ((i < ob_dst->totcol) && (ma_src == give_current_material(ob_dst, i + 1))) {
+ /* when objects have exact matching materials - keep existing index */
+ }
+ else {
+ void **index_src_p = BLI_ghash_lookup_p(gh_mat_map, ma_src);
+ if (index_src_p) {
+ remap_src_to_dst[i] = POINTER_AS_INT(*index_src_p);
+ }
+ }
+ }
+
+ BLI_ghash_free(gh_mat_map, NULL, NULL);
}
-
/* XXX - this calls many more update calls per object then are needed, could be optimized */
void assign_matarar(Main *bmain, struct Object *ob, struct Material ***matar, short totcol)
{
- int actcol_orig = ob->actcol;
- short i;
+ int actcol_orig = ob->actcol;
+ short i;
- while ((ob->totcol > totcol) &&
- BKE_object_material_slot_remove(bmain, ob))
- {
- /* pass */
- }
+ while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
+ /* pass */
+ }
- /* now we have the right number of slots */
- for (i = 0; i < totcol; i++)
- assign_material(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
+ /* now we have the right number of slots */
+ for (i = 0; i < totcol; i++)
+ assign_material(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
- if (actcol_orig > ob->totcol)
- actcol_orig = ob->totcol;
+ if (actcol_orig > ob->totcol)
+ actcol_orig = ob->totcol;
- ob->actcol = actcol_orig;
+ ob->actcol = actcol_orig;
}
-
short BKE_object_material_slot_find_index(Object *ob, Material *ma)
{
- Material ***matarar;
- short a, *totcolp;
+ Material ***matarar;
+ short a, *totcolp;
- if (ma == NULL) return 0;
+ if (ma == NULL)
+ return 0;
- totcolp = give_totcolp(ob);
- matarar = give_matarar(ob);
+ totcolp = give_totcolp(ob);
+ matarar = give_matarar(ob);
- if (totcolp == NULL || matarar == NULL) return 0;
+ if (totcolp == NULL || matarar == NULL)
+ return 0;
- for (a = 0; a < *totcolp; a++)
- if ((*matarar)[a] == ma)
- break;
- if (a < *totcolp)
- return a + 1;
- return 0;
+ for (a = 0; a < *totcolp; a++)
+ if ((*matarar)[a] == ma)
+ break;
+ if (a < *totcolp)
+ return a + 1;
+ return 0;
}
bool BKE_object_material_slot_add(Main *bmain, Object *ob)
{
- if (ob == NULL) return false;
- if (ob->totcol >= MAXMAT) return false;
-
- assign_material(bmain, ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
- ob->actcol = ob->totcol;
- return true;
+ if (ob == NULL)
+ return false;
+ if (ob->totcol >= MAXMAT)
+ return false;
+
+ assign_material(bmain, ob, NULL, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF);
+ ob->actcol = ob->totcol;
+ return true;
}
/* ****************** */
bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
{
- Material *mao, ***matarar;
- short *totcolp;
- short a, actcol;
-
- if (ob == NULL || ob->totcol == 0) {
- return false;
- }
-
- /* this should never happen and used to crash */
- if (ob->actcol <= 0) {
- CLOG_ERROR(&LOG, "invalid material index %d, report a bug!", ob->actcol);
- BLI_assert(0);
- return false;
- }
-
- /* take a mesh/curve/mball as starting point, remove 1 index,
- * AND with all objects that share the ob->data
- *
- * after that check indices in mesh/curve/mball!!!
- */
-
- totcolp = give_totcolp(ob);
- matarar = give_matarar(ob);
-
- if (ELEM(NULL, matarar, *matarar)) {
- return false;
- }
-
- /* can happen on face selection in editmode */
- if (ob->actcol > ob->totcol) {
- ob->actcol = ob->totcol;
- }
-
- /* we delete the actcol */
- mao = (*matarar)[ob->actcol - 1];
- if (mao)
- id_us_min(&mao->id);
-
- for (a = ob->actcol; a < ob->totcol; a++)
- (*matarar)[a - 1] = (*matarar)[a];
- (*totcolp)--;
-
- if (*totcolp == 0) {
- MEM_freeN(*matarar);
- *matarar = NULL;
- }
-
- actcol = ob->actcol;
-
- for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
- if (obt->data == ob->data) {
- /* Can happen when object material lists are used, see: T52953 */
- if (actcol > obt->totcol) {
- continue;
- }
- /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
- mao = obt->mat[actcol - 1];
- if (mao)
- id_us_min(&mao->id);
-
- for (a = actcol; a < obt->totcol; a++) {
- obt->mat[a - 1] = obt->mat[a];
- obt->matbits[a - 1] = obt->matbits[a];
- }
- obt->totcol--;
- if (obt->actcol > obt->totcol) obt->actcol = obt->totcol;
-
- if (obt->totcol == 0) {
- MEM_freeN(obt->mat);
- MEM_freeN(obt->matbits);
- obt->mat = NULL;
- obt->matbits = NULL;
- }
- }
- }
-
- /* check indices from mesh */
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
- material_data_index_remove_id((ID *)ob->data, actcol - 1);
- if (ob->runtime.curve_cache) {
- BKE_displist_free(&ob->runtime.curve_cache->disp);
- }
- }
-
- return true;
+ Material *mao, ***matarar;
+ short *totcolp;
+ short a, actcol;
+
+ if (ob == NULL || ob->totcol == 0) {
+ return false;
+ }
+
+ /* this should never happen and used to crash */
+ if (ob->actcol <= 0) {
+ CLOG_ERROR(&LOG, "invalid material index %d, report a bug!", ob->actcol);
+ BLI_assert(0);
+ return false;
+ }
+
+ /* take a mesh/curve/mball as starting point, remove 1 index,
+ * AND with all objects that share the ob->data
+ *
+ * after that check indices in mesh/curve/mball!!!
+ */
+
+ totcolp = give_totcolp(ob);
+ matarar = give_matarar(ob);
+
+ if (ELEM(NULL, matarar, *matarar)) {
+ return false;
+ }
+
+ /* can happen on face selection in editmode */
+ if (ob->actcol > ob->totcol) {
+ ob->actcol = ob->totcol;
+ }
+
+ /* we delete the actcol */
+ mao = (*matarar)[ob->actcol - 1];
+ if (mao)
+ id_us_min(&mao->id);
+
+ for (a = ob->actcol; a < ob->totcol; a++)
+ (*matarar)[a - 1] = (*matarar)[a];
+ (*totcolp)--;
+
+ if (*totcolp == 0) {
+ MEM_freeN(*matarar);
+ *matarar = NULL;
+ }
+
+ actcol = ob->actcol;
+
+ for (Object *obt = bmain->objects.first; obt; obt = obt->id.next) {
+ if (obt->data == ob->data) {
+ /* Can happen when object material lists are used, see: T52953 */
+ if (actcol > obt->totcol) {
+ continue;
+ }
+ /* WATCH IT: do not use actcol from ob or from obt (can become zero) */
+ mao = obt->mat[actcol - 1];
+ if (mao)
+ id_us_min(&mao->id);
+
+ for (a = actcol; a < obt->totcol; a++) {
+ obt->mat[a - 1] = obt->mat[a];
+ obt->matbits[a - 1] = obt->matbits[a];
+ }
+ obt->totcol--;
+ if (obt->actcol > obt->totcol)
+ obt->actcol = obt->totcol;
+
+ if (obt->totcol == 0) {
+ MEM_freeN(obt->mat);
+ MEM_freeN(obt->matbits);
+ obt->mat = NULL;
+ obt->matbits = NULL;
+ }
+ }
+ }
+
+ /* check indices from mesh */
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
+ material_data_index_remove_id((ID *)ob->data, actcol - 1);
+ if (ob->runtime.curve_cache) {
+ BKE_displist_free(&ob->runtime.curve_cache->disp);
+ }
+ }
+
+ return true;
}
static bNode *nodetree_uv_node_recursive(bNode *node)
{
- bNode *inode;
- bNodeSocket *sock;
-
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (sock->link) {
- inode = sock->link->fromnode;
- if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
- return inode;
- }
- else {
- return nodetree_uv_node_recursive(inode);
- }
- }
- }
-
- return NULL;
+ bNode *inode;
+ bNodeSocket *sock;
+
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (sock->link) {
+ inode = sock->link->fromnode;
+ if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
+ return inode;
+ }
+ else {
+ return nodetree_uv_node_recursive(inode);
+ }
+ }
+ }
+
+ return NULL;
}
static int count_texture_nodes_recursive(bNodeTree *nodetree)
{
- int tex_nodes = 0;
-
- for (bNode *node = nodetree->nodes.first; node; node = node->next) {
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
- tex_nodes++;
- }
- else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
- /* recurse into the node group and see if it contains any textures */
- tex_nodes += count_texture_nodes_recursive((bNodeTree *)node->id);
- }
- }
-
- return tex_nodes;
+ int tex_nodes = 0;
+
+ for (bNode *node = nodetree->nodes.first; node; node = node->next) {
+ if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
+ node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
+ tex_nodes++;
+ }
+ else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
+ /* recurse into the node group and see if it contains any textures */
+ tex_nodes += count_texture_nodes_recursive((bNodeTree *)node->id);
+ }
+ }
+
+ return tex_nodes;
}
-static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_node, Material *ma, int *index)
+static void fill_texpaint_slots_recursive(bNodeTree *nodetree,
+ bNode *active_node,
+ Material *ma,
+ int *index)
{
- for (bNode *node = nodetree->nodes.first; node; node = node->next) {
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
- if (active_node == node) {
- ma->paint_active_slot = *index;
- }
-
- ma->texpaintslot[*index].ima = (Image *)node->id;
- ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
-
- /* for new renderer, we need to traverse the treeback in search of a UV node */
- bNode *uvnode = nodetree_uv_node_recursive(node);
-
- if (uvnode) {
- NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
- ma->texpaintslot[*index].uvname = storage->uv_map;
- /* set a value to index so UI knows that we have a valid pointer for the mesh */
- ma->texpaintslot[*index].valid = true;
- }
- else {
- /* just invalidate the index here so UV map does not get displayed on the UI */
- ma->texpaintslot[*index].valid = false;
- }
- (*index)++;
- }
- else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
- /* recurse into the node group and see if it contains any textures */
- fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, index);
- }
- }
+ for (bNode *node = nodetree->nodes.first; node; node = node->next) {
+ if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
+ node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
+ if (active_node == node) {
+ ma->paint_active_slot = *index;
+ }
+
+ ma->texpaintslot[*index].ima = (Image *)node->id;
+ ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
+
+ /* for new renderer, we need to traverse the treeback in search of a UV node */
+ bNode *uvnode = nodetree_uv_node_recursive(node);
+
+ if (uvnode) {
+ NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
+ ma->texpaintslot[*index].uvname = storage->uv_map;
+ /* set a value to index so UI knows that we have a valid pointer for the mesh */
+ ma->texpaintslot[*index].valid = true;
+ }
+ else {
+ /* just invalidate the index here so UV map does not get displayed on the UI */
+ ma->texpaintslot[*index].valid = false;
+ }
+ (*index)++;
+ }
+ else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
+ /* recurse into the node group and see if it contains any textures */
+ fill_texpaint_slots_recursive((bNodeTree *)node->id, active_node, ma, index);
+ }
+ }
}
void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
{
- int count = 0;
- int index = 0;
+ int count = 0;
+ int index = 0;
- if (!ma)
- return;
+ if (!ma)
+ return;
- /* COW needed when adding texture slot on an object with no materials. */
- DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
+ /* COW needed when adding texture slot on an object with no materials. */
+ DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
- if (ma->texpaintslot) {
- MEM_freeN(ma->texpaintslot);
- ma->tot_slots = 0;
- ma->texpaintslot = NULL;
- }
+ if (ma->texpaintslot) {
+ MEM_freeN(ma->texpaintslot);
+ ma->tot_slots = 0;
+ ma->texpaintslot = NULL;
+ }
- if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
- ma->paint_active_slot = 0;
- ma->paint_clone_slot = 0;
- return;
- }
+ if (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
+ ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
+ return;
+ }
- if (!(ma->nodetree)) {
- ma->paint_active_slot = 0;
- ma->paint_clone_slot = 0;
- return;
- }
+ if (!(ma->nodetree)) {
+ ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
+ return;
+ }
- count = count_texture_nodes_recursive(ma->nodetree);
+ count = count_texture_nodes_recursive(ma->nodetree);
- if (count == 0) {
- ma->paint_active_slot = 0;
- ma->paint_clone_slot = 0;
- return;
- }
+ if (count == 0) {
+ ma->paint_active_slot = 0;
+ ma->paint_clone_slot = 0;
+ return;
+ }
- ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
+ ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
- bNode *active_node = nodeGetActiveTexture(ma->nodetree);
+ bNode *active_node = nodeGetActiveTexture(ma->nodetree);
- fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, &index);
+ fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, &index);
- ma->tot_slots = count;
+ ma->tot_slots = count;
+ if (ma->paint_active_slot >= count) {
+ ma->paint_active_slot = count - 1;
+ }
- if (ma->paint_active_slot >= count) {
- ma->paint_active_slot = count - 1;
- }
+ if (ma->paint_clone_slot >= count) {
+ ma->paint_clone_slot = count - 1;
+ }
- if (ma->paint_clone_slot >= count) {
- ma->paint_clone_slot = count - 1;
- }
-
- return;
+ return;
}
void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
{
- int i;
+ int i;
- for (i = 1; i < ob->totcol + 1; i++) {
- Material *ma = give_current_material(ob, i);
- BKE_texpaint_slot_refresh_cache(scene, ma);
- }
+ for (i = 1; i < ob->totcol + 1; i++) {
+ Material *ma = give_current_material(ob, i);
+ BKE_texpaint_slot_refresh_cache(scene, ma);
+ }
}
-
/* r_col = current value, col = new value, (fac == 0) is no change */
void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
{
- float tmp, facm = 1.0f - fac;
-
- switch (type) {
- case MA_RAMP_BLEND:
- r_col[0] = facm * (r_col[0]) + fac * col[0];
- r_col[1] = facm * (r_col[1]) + fac * col[1];
- r_col[2] = facm * (r_col[2]) + fac * col[2];
- break;
- case MA_RAMP_ADD:
- r_col[0] += fac * col[0];
- r_col[1] += fac * col[1];
- r_col[2] += fac * col[2];
- break;
- case MA_RAMP_MULT:
- r_col[0] *= (facm + fac * col[0]);
- r_col[1] *= (facm + fac * col[1]);
- r_col[2] *= (facm + fac * col[2]);
- break;
- case MA_RAMP_SCREEN:
- r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
- r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
- r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
- break;
- case MA_RAMP_OVERLAY:
- if (r_col[0] < 0.5f)
- r_col[0] *= (facm + 2.0f * fac * col[0]);
- else
- r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
- if (r_col[1] < 0.5f)
- r_col[1] *= (facm + 2.0f * fac * col[1]);
- else
- r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
- if (r_col[2] < 0.5f)
- r_col[2] *= (facm + 2.0f * fac * col[2]);
- else
- r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
- break;
- case MA_RAMP_SUB:
- r_col[0] -= fac * col[0];
- r_col[1] -= fac * col[1];
- r_col[2] -= fac * col[2];
- break;
- case MA_RAMP_DIV:
- if (col[0] != 0.0f)
- r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
- if (col[1] != 0.0f)
- r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
- if (col[2] != 0.0f)
- r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
- break;
- case MA_RAMP_DIFF:
- r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
- r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
- r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
- break;
- case MA_RAMP_DARK:
- r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
- r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
- r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
- break;
- case MA_RAMP_LIGHT:
- tmp = fac * col[0];
- if (tmp > r_col[0]) r_col[0] = tmp;
- tmp = fac * col[1];
- if (tmp > r_col[1]) r_col[1] = tmp;
- tmp = fac * col[2];
- if (tmp > r_col[2]) r_col[2] = tmp;
- break;
- case MA_RAMP_DODGE:
- if (r_col[0] != 0.0f) {
- tmp = 1.0f - fac * col[0];
- if (tmp <= 0.0f)
- r_col[0] = 1.0f;
- else if ((tmp = (r_col[0]) / tmp) > 1.0f)
- r_col[0] = 1.0f;
- else
- r_col[0] = tmp;
- }
- if (r_col[1] != 0.0f) {
- tmp = 1.0f - fac * col[1];
- if (tmp <= 0.0f)
- r_col[1] = 1.0f;
- else if ((tmp = (r_col[1]) / tmp) > 1.0f)
- r_col[1] = 1.0f;
- else
- r_col[1] = tmp;
- }
- if (r_col[2] != 0.0f) {
- tmp = 1.0f - fac * col[2];
- if (tmp <= 0.0f)
- r_col[2] = 1.0f;
- else if ((tmp = (r_col[2]) / tmp) > 1.0f)
- r_col[2] = 1.0f;
- else
- r_col[2] = tmp;
- }
- break;
- case MA_RAMP_BURN:
- tmp = facm + fac * col[0];
-
- if (tmp <= 0.0f)
- r_col[0] = 0.0f;
- else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f)
- r_col[0] = 0.0f;
- else if (tmp > 1.0f)
- r_col[0] = 1.0f;
- else
- r_col[0] = tmp;
-
- tmp = facm + fac * col[1];
- if (tmp <= 0.0f)
- r_col[1] = 0.0f;
- else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f)
- r_col[1] = 0.0f;
- else if (tmp > 1.0f)
- r_col[1] = 1.0f;
- else
- r_col[1] = tmp;
-
- tmp = facm + fac * col[2];
- if (tmp <= 0.0f)
- r_col[2] = 0.0f;
- else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f)
- r_col[2] = 0.0f;
- else if (tmp > 1.0f)
- r_col[2] = 1.0f;
- else
- r_col[2] = tmp;
- break;
- case MA_RAMP_HUE:
- {
- float rH, rS, rV;
- float colH, colS, colV;
- float tmpr, tmpg, tmpb;
- rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
- if (colS != 0) {
- rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
- hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
- r_col[0] = facm * (r_col[0]) + fac * tmpr;
- r_col[1] = facm * (r_col[1]) + fac * tmpg;
- r_col[2] = facm * (r_col[2]) + fac * tmpb;
- }
- break;
- }
- case MA_RAMP_SAT:
- {
- float rH, rS, rV;
- float colH, colS, colV;
- rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
- if (rS != 0) {
- rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
- hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
- }
- break;
- }
- case MA_RAMP_VAL:
- {
- float rH, rS, rV;
- float colH, colS, colV;
- rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
- rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
- hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
- break;
- }
- case MA_RAMP_COLOR:
- {
- float rH, rS, rV;
- float colH, colS, colV;
- float tmpr, tmpg, tmpb;
- rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
- if (colS != 0) {
- rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
- hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
- r_col[0] = facm * (r_col[0]) + fac * tmpr;
- r_col[1] = facm * (r_col[1]) + fac * tmpg;
- r_col[2] = facm * (r_col[2]) + fac * tmpb;
- }
- break;
- }
- case MA_RAMP_SOFT:
- {
- float scr, scg, scb;
-
- /* first calculate non-fac based Screen mix */
- scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
- scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
- scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
-
- r_col[0] = facm * (r_col[0]) + fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
- r_col[1] = facm * (r_col[1]) + fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
- r_col[2] = facm * (r_col[2]) + fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
- break;
- }
- case MA_RAMP_LINEAR:
- if (col[0] > 0.5f)
- r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
- else
- r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
- if (col[1] > 0.5f)
- r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
- else
- r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
- if (col[2] > 0.5f)
- r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
- else
- r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
- break;
- }
+ float tmp, facm = 1.0f - fac;
+
+ switch (type) {
+ case MA_RAMP_BLEND:
+ r_col[0] = facm * (r_col[0]) + fac * col[0];
+ r_col[1] = facm * (r_col[1]) + fac * col[1];
+ r_col[2] = facm * (r_col[2]) + fac * col[2];
+ break;
+ case MA_RAMP_ADD:
+ r_col[0] += fac * col[0];
+ r_col[1] += fac * col[1];
+ r_col[2] += fac * col[2];
+ break;
+ case MA_RAMP_MULT:
+ r_col[0] *= (facm + fac * col[0]);
+ r_col[1] *= (facm + fac * col[1]);
+ r_col[2] *= (facm + fac * col[2]);
+ break;
+ case MA_RAMP_SCREEN:
+ r_col[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - r_col[0]);
+ r_col[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - r_col[1]);
+ r_col[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - r_col[2]);
+ break;
+ case MA_RAMP_OVERLAY:
+ if (r_col[0] < 0.5f)
+ r_col[0] *= (facm + 2.0f * fac * col[0]);
+ else
+ r_col[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - r_col[0]);
+ if (r_col[1] < 0.5f)
+ r_col[1] *= (facm + 2.0f * fac * col[1]);
+ else
+ r_col[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - r_col[1]);
+ if (r_col[2] < 0.5f)
+ r_col[2] *= (facm + 2.0f * fac * col[2]);
+ else
+ r_col[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - r_col[2]);
+ break;
+ case MA_RAMP_SUB:
+ r_col[0] -= fac * col[0];
+ r_col[1] -= fac * col[1];
+ r_col[2] -= fac * col[2];
+ break;
+ case MA_RAMP_DIV:
+ if (col[0] != 0.0f)
+ r_col[0] = facm * (r_col[0]) + fac * (r_col[0]) / col[0];
+ if (col[1] != 0.0f)
+ r_col[1] = facm * (r_col[1]) + fac * (r_col[1]) / col[1];
+ if (col[2] != 0.0f)
+ r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
+ break;
+ case MA_RAMP_DIFF:
+ r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
+ r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
+ r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
+ break;
+ case MA_RAMP_DARK:
+ r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm;
+ r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm;
+ r_col[2] = min_ff(r_col[2], col[2]) * fac + r_col[2] * facm;
+ break;
+ case MA_RAMP_LIGHT:
+ tmp = fac * col[0];
+ if (tmp > r_col[0])
+ r_col[0] = tmp;
+ tmp = fac * col[1];
+ if (tmp > r_col[1])
+ r_col[1] = tmp;
+ tmp = fac * col[2];
+ if (tmp > r_col[2])
+ r_col[2] = tmp;
+ break;
+ case MA_RAMP_DODGE:
+ if (r_col[0] != 0.0f) {
+ tmp = 1.0f - fac * col[0];
+ if (tmp <= 0.0f)
+ r_col[0] = 1.0f;
+ else if ((tmp = (r_col[0]) / tmp) > 1.0f)
+ r_col[0] = 1.0f;
+ else
+ r_col[0] = tmp;
+ }
+ if (r_col[1] != 0.0f) {
+ tmp = 1.0f - fac * col[1];
+ if (tmp <= 0.0f)
+ r_col[1] = 1.0f;
+ else if ((tmp = (r_col[1]) / tmp) > 1.0f)
+ r_col[1] = 1.0f;
+ else
+ r_col[1] = tmp;
+ }
+ if (r_col[2] != 0.0f) {
+ tmp = 1.0f - fac * col[2];
+ if (tmp <= 0.0f)
+ r_col[2] = 1.0f;
+ else if ((tmp = (r_col[2]) / tmp) > 1.0f)
+ r_col[2] = 1.0f;
+ else
+ r_col[2] = tmp;
+ }
+ break;
+ case MA_RAMP_BURN:
+ tmp = facm + fac * col[0];
+
+ if (tmp <= 0.0f)
+ r_col[0] = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - (r_col[0])) / tmp)) < 0.0f)
+ r_col[0] = 0.0f;
+ else if (tmp > 1.0f)
+ r_col[0] = 1.0f;
+ else
+ r_col[0] = tmp;
+
+ tmp = facm + fac * col[1];
+ if (tmp <= 0.0f)
+ r_col[1] = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - (r_col[1])) / tmp)) < 0.0f)
+ r_col[1] = 0.0f;
+ else if (tmp > 1.0f)
+ r_col[1] = 1.0f;
+ else
+ r_col[1] = tmp;
+
+ tmp = facm + fac * col[2];
+ if (tmp <= 0.0f)
+ r_col[2] = 0.0f;
+ else if ((tmp = (1.0f - (1.0f - (r_col[2])) / tmp)) < 0.0f)
+ r_col[2] = 0.0f;
+ else if (tmp > 1.0f)
+ r_col[2] = 1.0f;
+ else
+ r_col[2] = tmp;
+ break;
+ case MA_RAMP_HUE: {
+ float rH, rS, rV;
+ float colH, colS, colV;
+ float tmpr, tmpg, tmpb;
+ rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
+ if (colS != 0) {
+ rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
+ hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb);
+ r_col[0] = facm * (r_col[0]) + fac * tmpr;
+ r_col[1] = facm * (r_col[1]) + fac * tmpg;
+ r_col[2] = facm * (r_col[2]) + fac * tmpb;
+ }
+ break;
+ }
+ case MA_RAMP_SAT: {
+ float rH, rS, rV;
+ float colH, colS, colV;
+ rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
+ if (rS != 0) {
+ rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
+ hsv_to_rgb(rH, (facm * rS + fac * colS), rV, r_col + 0, r_col + 1, r_col + 2);
+ }
+ break;
+ }
+ case MA_RAMP_VAL: {
+ float rH, rS, rV;
+ float colH, colS, colV;
+ rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
+ rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
+ hsv_to_rgb(rH, rS, (facm * rV + fac * colV), r_col + 0, r_col + 1, r_col + 2);
+ break;
+ }
+ case MA_RAMP_COLOR: {
+ float rH, rS, rV;
+ float colH, colS, colV;
+ float tmpr, tmpg, tmpb;
+ rgb_to_hsv(col[0], col[1], col[2], &colH, &colS, &colV);
+ if (colS != 0) {
+ rgb_to_hsv(r_col[0], r_col[1], r_col[2], &rH, &rS, &rV);
+ hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb);
+ r_col[0] = facm * (r_col[0]) + fac * tmpr;
+ r_col[1] = facm * (r_col[1]) + fac * tmpg;
+ r_col[2] = facm * (r_col[2]) + fac * tmpb;
+ }
+ break;
+ }
+ case MA_RAMP_SOFT: {
+ float scr, scg, scb;
+
+ /* first calculate non-fac based Screen mix */
+ scr = 1.0f - (1.0f - col[0]) * (1.0f - r_col[0]);
+ scg = 1.0f - (1.0f - col[1]) * (1.0f - r_col[1]);
+ scb = 1.0f - (1.0f - col[2]) * (1.0f - r_col[2]);
+
+ r_col[0] = facm * (r_col[0]) +
+ fac * (((1.0f - r_col[0]) * col[0] * (r_col[0])) + (r_col[0] * scr));
+ r_col[1] = facm * (r_col[1]) +
+ fac * (((1.0f - r_col[1]) * col[1] * (r_col[1])) + (r_col[1] * scg));
+ r_col[2] = facm * (r_col[2]) +
+ fac * (((1.0f - r_col[2]) * col[2] * (r_col[2])) + (r_col[2] * scb));
+ break;
+ }
+ case MA_RAMP_LINEAR:
+ if (col[0] > 0.5f)
+ r_col[0] = r_col[0] + fac * (2.0f * (col[0] - 0.5f));
+ else
+ r_col[0] = r_col[0] + fac * (2.0f * (col[0]) - 1.0f);
+ if (col[1] > 0.5f)
+ r_col[1] = r_col[1] + fac * (2.0f * (col[1] - 0.5f));
+ else
+ r_col[1] = r_col[1] + fac * (2.0f * (col[1]) - 1.0f);
+ if (col[2] > 0.5f)
+ r_col[2] = r_col[2] + fac * (2.0f * (col[2] - 0.5f));
+ else
+ r_col[2] = r_col[2] + fac * (2.0f * (col[2]) - 1.0f);
+ break;
+ }
}
/**
@@ -1371,64 +1387,64 @@ static short matcopied = 0;
void clear_matcopybuf(void)
{
- memset(&matcopybuf, 0, sizeof(Material));
- matcopied = 0;
+ memset(&matcopybuf, 0, sizeof(Material));
+ matcopied = 0;
}
void free_matcopybuf(void)
{
- if (matcopybuf.nodetree) {
- ntreeFreeLocalTree(matcopybuf.nodetree);
- MEM_freeN(matcopybuf.nodetree);
- matcopybuf.nodetree = NULL;
- }
+ if (matcopybuf.nodetree) {
+ ntreeFreeLocalTree(matcopybuf.nodetree);
+ MEM_freeN(matcopybuf.nodetree);
+ matcopybuf.nodetree = NULL;
+ }
- matcopied = 0;
+ matcopied = 0;
}
void copy_matcopybuf(Main *bmain, Material *ma)
{
- if (matcopied)
- free_matcopybuf();
+ if (matcopied)
+ free_matcopybuf();
- memcpy(&matcopybuf, ma, sizeof(Material));
+ memcpy(&matcopybuf, ma, sizeof(Material));
- if (ma->nodetree != NULL) {
- matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, bmain, false);
- }
+ if (ma->nodetree != NULL) {
+ 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;
+ matcopybuf.preview = NULL;
+ BLI_listbase_clear(&matcopybuf.gpumaterial);
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
+ matcopied = 1;
}
void paste_matcopybuf(Main *bmain, Material *ma)
{
- ID id;
+ ID id;
- if (matcopied == 0)
- return;
+ if (matcopied == 0)
+ return;
- /* Free gpu material before the ntree */
- GPU_material_free(&ma->gpumaterial);
+ /* Free gpu material before the ntree */
+ GPU_material_free(&ma->gpumaterial);
- if (ma->nodetree) {
- ntreeFreeNestedTree(ma->nodetree);
- MEM_freeN(ma->nodetree);
- }
+ if (ma->nodetree) {
+ ntreeFreeNestedTree(ma->nodetree);
+ MEM_freeN(ma->nodetree);
+ }
- id = (ma->id);
- memcpy(ma, &matcopybuf, sizeof(Material));
- (ma->id) = id;
+ id = (ma->id);
+ memcpy(ma, &matcopybuf, sizeof(Material));
+ (ma->id) = id;
- if (matcopybuf.nodetree != NULL) {
- ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
- }
+ if (matcopybuf.nodetree != NULL) {
+ ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, bmain, false);
+ }
}
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
{
- DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
- GPU_material_free(&material->gpumaterial);
+ DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
+ GPU_material_free(&material->gpumaterial);
}