Fix T99191: Boolean modifier creates invalid material indices
This changes the boolean modifier material index handling to be
consistent with the mesh boolean geometry nodes, which was
last changed in 1a6d0ec71c
. The issues was that the
material maps were retrieved at the object level, which doesn't
really make sense because the boolean is a geometry-level
operation. It was also confusing and prone to incorrect behavior
because it's more complex to retrieve information from two places.
Differential Revision: https://developer.blender.org/D15365
This commit is contained in:
parent
bcfabdc09d
commit
a2d59b2dac
Notes:
blender-bot
2023-02-14 02:30:11 +01:00
Referenced by commit7540842ca7
, Fix T99592: Exact Boolean: Skip empty materials, add index-based option Referenced by commitbbb389589a
, Fix T99592: Exact Boolean: Skip empty materials, add index-based option Referenced by issue #102596, Viewport display of multiple Dupli-Collections when different draw-types are used : wireframe might disappear (only selected are garuanteed to draw) Referenced by issue #100690, Blender 3.2.1 Recent Files List Not Updating Referenced by issue #100416, Crashed out when start rendering Referenced by issue #100369, Blender 3.2.1 - Particles - Particles generate differently on Linux vs Windows Referenced by issue #100156, Grease Pencil crashing Blender 3.2.0 / 3.2.1. Referenced by issue #100079, Encoding with DNxHD fails due to bad parameters Referenced by issue #99970, Difference in rendering alpha between CUDA/Optix and HIP Referenced by issue #99813, Bevel is problematic in some cases Referenced by issue #99746, Blender 3.2.1 Very Slow Startup on Ubuntu 22.04 Referenced by issue #99720, Blender Crash when i switch the viewport shading to material preview or render Referenced by issue #99592, Regression: Boolean Difference modifier - material of hole created by hidden object different for fast and exact Referenced by issue #99568, Exception during start programm. Referenced by issue #99507, Camera Background image is appearing greyish in 3D Viewport Referenced by issue #99191, Regression: Blender crashes when texture painting (caused by boolean modifers) Referenced by issue #99015, Segmentation fault while texture painting Referenced by issue #98661, 3.2: Potential candidates for corrective releases
|
@ -14,6 +14,7 @@
|
|||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_vector.hh"
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
|
@ -62,7 +63,11 @@
|
|||
|
||||
using blender::Array;
|
||||
using blender::float4x4;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
using blender::VectorSet;
|
||||
|
||||
static void initData(ModifierData *md)
|
||||
{
|
||||
|
@ -375,19 +380,20 @@ static void BMD_mesh_intersection(BMesh *bm,
|
|||
|
||||
#ifdef WITH_GMP
|
||||
|
||||
/* Get a mapping from material slot numbers in the src_ob to slot numbers in the dst_ob.
|
||||
* If a material doesn't exist in the dst_ob, the mapping just goes to the same slot
|
||||
* or to zero if there aren't enough slots in the destination.
|
||||
/* Get a mapping from material slot numbers in the source geometry to slot numbers in the result
|
||||
* geometry. The material is added to the result geometry if it doesn't already use it.
|
||||
* Caller owns the returned array. */
|
||||
static Array<short> get_material_remap(Object *dest_ob, Object *src_ob)
|
||||
static Array<short> get_material_remap(const Mesh &mesh, VectorSet<Material *> &materials)
|
||||
{
|
||||
int n = src_ob->totcol;
|
||||
if (n <= 0) {
|
||||
n = 1;
|
||||
if (mesh.totcol == 0) {
|
||||
/* Necessary for faces using the default material when there are no material slots. */
|
||||
return Array<short>({materials.index_of_or_add(nullptr)});
|
||||
}
|
||||
Array<short> remap(n);
|
||||
BKE_object_material_remap_calc(dest_ob, src_ob, remap.data());
|
||||
return remap;
|
||||
Array<short> map(mesh.totcol);
|
||||
for (const int i : IndexRange(mesh.totcol)) {
|
||||
map[i] = materials.index_of_or_add(mesh.mat[i]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
||||
|
@ -396,6 +402,8 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
|||
{
|
||||
Vector<const Mesh *> meshes;
|
||||
Vector<float4x4 *> obmats;
|
||||
|
||||
VectorSet<Material *> materials;
|
||||
Vector<Array<short>> material_remaps;
|
||||
|
||||
# ifdef DEBUG_TIME
|
||||
|
@ -409,6 +417,14 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
|||
meshes.append(mesh);
|
||||
obmats.append((float4x4 *)&ctx->object->obmat);
|
||||
material_remaps.append({});
|
||||
if (mesh->totcol == 0) {
|
||||
/* Necessary for faces using the default material when there are no material slots. */
|
||||
materials.add(nullptr);
|
||||
}
|
||||
else {
|
||||
materials.add_multiple({mesh->mat, mesh->totcol});
|
||||
}
|
||||
|
||||
if (bmd->flag & eBooleanModifierFlag_Object) {
|
||||
Mesh *mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object, false);
|
||||
if (!mesh_operand) {
|
||||
|
@ -417,7 +433,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
|||
BKE_mesh_wrapper_ensure_mdata(mesh_operand);
|
||||
meshes.append(mesh_operand);
|
||||
obmats.append((float4x4 *)&bmd->object->obmat);
|
||||
material_remaps.append(get_material_remap(ctx->object, bmd->object));
|
||||
material_remaps.append(get_material_remap(*mesh_operand, materials));
|
||||
}
|
||||
else if (bmd->flag & eBooleanModifierFlag_Collection) {
|
||||
Collection *collection = bmd->collection;
|
||||
|
@ -432,7 +448,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
|||
BKE_mesh_wrapper_ensure_mdata(collection_mesh);
|
||||
meshes.append(collection_mesh);
|
||||
obmats.append((float4x4 *)&ob->obmat);
|
||||
material_remaps.append(get_material_remap(ctx->object, ob));
|
||||
material_remaps.append(get_material_remap(*collection_mesh, materials));
|
||||
}
|
||||
}
|
||||
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
||||
|
@ -441,13 +457,18 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
|
|||
|
||||
const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0;
|
||||
const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0;
|
||||
return blender::meshintersect::direct_mesh_boolean(meshes,
|
||||
obmats,
|
||||
*(float4x4 *)&ctx->object->obmat,
|
||||
material_remaps,
|
||||
use_self,
|
||||
hole_tolerant,
|
||||
bmd->operation);
|
||||
Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes,
|
||||
obmats,
|
||||
*(float4x4 *)&ctx->object->obmat,
|
||||
material_remaps,
|
||||
use_self,
|
||||
hole_tolerant,
|
||||
bmd->operation);
|
||||
MEM_SAFE_FREE(result->mat);
|
||||
result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__);
|
||||
result->totcol = materials.size();
|
||||
MutableSpan(result->mat, result->totcol).copy_from(materials);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue