[Bf-blender-cvs] [c61c312] master: Use material remapping for bmesh-boolean

Campbell Barton noreply at git.blender.org
Sat Dec 12 14:48:23 CET 2015


Commit: c61c312f97f6e23dabb8e4a6c488ddf4097369be
Author: Campbell Barton
Date:   Sun Dec 13 00:34:09 2015 +1100
Branches: master
https://developer.blender.org/rBc61c312f97f6e23dabb8e4a6c488ddf4097369be

Use material remapping for bmesh-boolean

===================================================================

M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/intern/material.c
M	source/blender/modifiers/intern/MOD_boolean.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index d32d679..87e5988 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -51,6 +51,7 @@ void test_object_materials(struct Main *bmain, struct ID *id);
 void BKE_material_resize_object(struct Object *ob, const short totcol, bool do_id_user);
 void BKE_material_init(struct Material *ma);
 void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
+void BKE_material_remap_object_calc(struct  Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
 struct Material *BKE_material_add(struct Main *bmain, const char *name);
 struct Material *BKE_material_copy(struct Material *ma);
 struct Material *localize_material(struct Material *ma);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 8614ded..b913e6d 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -969,6 +969,62 @@ void BKE_material_remap_object(Object *ob, const unsigned int *remap)
 	}
 }
 
+/**
+ * Calculate a material remapping from \a ob_src to \a ob_dst.
+ *
+ * \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)
+{
+	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, SET_INT_IN_POINTER(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] = GET_INT_FROM_POINTER(*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(struct Object *ob, struct Material ***matar, short totcol)
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 57318e4..9257026 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -54,7 +54,9 @@
 #include "MOD_util.h"
 
 #ifdef USE_BMESH
+#include "BLI_alloca.h"
 #include "BLI_math_geom.h"
+#include "BKE_material.h"
 #include "MEM_guardedalloc.h"
 
 #include "bmesh.h"
@@ -238,17 +240,30 @@ static DerivedMesh *applyModifier_bmesh(
 
 					/* we need face normals because of 'BM_face_split_edgenet'
 					 * we could calculate on the fly too (before calling split). */
-					float nmat[4][4];
-					invert_m4_m4(nmat, omat);
-
-					BMFace *efa;
-					i = 0;
-					BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-						mul_transposed_mat3_m4_v3(nmat, efa->no);
-						normalize_v3(efa->no);
-						BM_elem_flag_enable(efa, BM_FACE_TAG);  /* temp tag to test which side split faces are from */
-						if (++i == i_faces_end) {
-							break;
+					{
+						float nmat[4][4];
+						invert_m4_m4(nmat, omat);
+
+						const short ob_src_totcol = bmd->object->totcol;
+						short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
+
+						BKE_material_remap_object_calc(ob, bmd->object, material_remap);
+
+						BMFace *efa;
+						i = 0;
+						BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+							mul_transposed_mat3_m4_v3(nmat, efa->no);
+							normalize_v3(efa->no);
+							BM_elem_flag_enable(efa, BM_FACE_TAG);  /* temp tag to test which side split faces are from */
+
+							/* remap material */
+							if (LIKELY(efa->mat_nr < ob_src_totcol)) {
+								efa->mat_nr = material_remap[efa->mat_nr];
+							}
+
+							if (++i == i_faces_end) {
+								break;
+							}
 						}
 					}
 				}




More information about the Bf-blender-cvs mailing list