Use material remapping for bmesh-boolean
This commit is contained in:
parent
c1cfdc59a3
commit
c61c312f97
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue