Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_boolean.cc
| Show First 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | switch (operation) { | ||||
| result = mesh_self; | result = mesh_self; | ||||
| } | } | ||||
| else { | else { | ||||
| result = (Mesh *)BKE_id_copy_ex( | result = (Mesh *)BKE_id_copy_ex( | ||||
| nullptr, &mesh_operand_ob->id, nullptr, LIB_ID_COPY_LOCALIZE); | nullptr, &mesh_operand_ob->id, nullptr, LIB_ID_COPY_LOCALIZE); | ||||
| float imat[4][4]; | float imat[4][4]; | ||||
| float omat[4][4]; | float omat[4][4]; | ||||
| invert_m4_m4(imat, ob_self->obmat); | invert_m4_m4(imat, ob_self->object_to_world); | ||||
| mul_m4_m4m4(omat, imat, ob_operand_ob->obmat); | mul_m4_m4m4(omat, imat, ob_operand_ob->object_to_world); | ||||
| MutableSpan<MVert> verts = result->verts_for_write(); | MutableSpan<MVert> verts = result->verts_for_write(); | ||||
| for (const int i : verts.index_range()) { | for (const int i : verts.index_range()) { | ||||
| mul_m4_v3(omat, verts[i].co); | mul_m4_v3(omat, verts[i].co); | ||||
| } | } | ||||
| BKE_mesh_tag_coords_changed(result); | BKE_mesh_tag_coords_changed(result); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
| static BMesh *BMD_mesh_bm_create( | static BMesh *BMD_mesh_bm_create( | ||||
| Mesh *mesh, Object *object, Mesh *mesh_operand_ob, Object *operand_ob, bool *r_is_flip) | Mesh *mesh, Object *object, Mesh *mesh_operand_ob, Object *operand_ob, bool *r_is_flip) | ||||
| { | { | ||||
| #ifdef DEBUG_TIME | #ifdef DEBUG_TIME | ||||
| SCOPED_TIMER(__func__); | SCOPED_TIMER(__func__); | ||||
| #endif | #endif | ||||
| *r_is_flip = (is_negative_m4(object->obmat) != is_negative_m4(operand_ob->obmat)); | *r_is_flip = (is_negative_m4(object->object_to_world) != | ||||
| is_negative_m4(operand_ob->object_to_world)); | |||||
| const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_operand_ob); | const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_operand_ob); | ||||
| BMeshCreateParams bmesh_create_params{}; | BMeshCreateParams bmesh_create_params{}; | ||||
| BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params); | BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params); | ||||
| /* Keep `mesh` first, needed so active layers are set based on `mesh` not `mesh_operand_ob`, | /* Keep `mesh` first, needed so active layers are set based on `mesh` not `mesh_operand_ob`, | ||||
| * otherwise the wrong active render layer is used, see T92384. | * otherwise the wrong active render layer is used, see T92384. | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | #endif | ||||
| { | { | ||||
| BMIter iter; | BMIter iter; | ||||
| int i; | int i; | ||||
| const int i_verts_end = mesh_operand_ob->totvert; | const int i_verts_end = mesh_operand_ob->totvert; | ||||
| const int i_faces_end = mesh_operand_ob->totpoly; | const int i_faces_end = mesh_operand_ob->totpoly; | ||||
| float imat[4][4]; | float imat[4][4]; | ||||
| float omat[4][4]; | float omat[4][4]; | ||||
| invert_m4_m4(imat, object->obmat); | invert_m4_m4(imat, object->object_to_world); | ||||
| mul_m4_m4m4(omat, imat, operand_ob->obmat); | mul_m4_m4m4(omat, imat, operand_ob->object_to_world); | ||||
| BMVert *eve; | BMVert *eve; | ||||
| i = 0; | i = 0; | ||||
| BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { | BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { | ||||
| mul_m4_v3(omat, eve->co); | mul_m4_v3(omat, eve->co); | ||||
| if (++i == i_verts_end) { | if (++i == i_verts_end) { | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | # ifdef DEBUG_TIME | ||||
| SCOPED_TIMER(__func__); | SCOPED_TIMER(__func__); | ||||
| # endif | # endif | ||||
| if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == nullptr) { | if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == nullptr) { | ||||
| return mesh; | return mesh; | ||||
| } | } | ||||
| meshes.append(mesh); | meshes.append(mesh); | ||||
| obmats.append((float4x4 *)&ctx->object->obmat); | obmats.append((float4x4 *)&ctx->object->object_to_world); | ||||
| material_remaps.append({}); | material_remaps.append({}); | ||||
| if (mesh->totcol == 0) { | if (mesh->totcol == 0) { | ||||
| /* Necessary for faces using the default material when there are no material slots. */ | /* Necessary for faces using the default material when there are no material slots. */ | ||||
| materials.add(nullptr); | materials.add(nullptr); | ||||
| } | } | ||||
| else { | else { | ||||
| materials.add_multiple({mesh->mat, mesh->totcol}); | materials.add_multiple({mesh->mat, mesh->totcol}); | ||||
| } | } | ||||
| if (bmd->flag & eBooleanModifierFlag_Object) { | if (bmd->flag & eBooleanModifierFlag_Object) { | ||||
| Mesh *mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object); | Mesh *mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object); | ||||
| if (!mesh_operand) { | if (!mesh_operand) { | ||||
| return mesh; | return mesh; | ||||
| } | } | ||||
| BKE_mesh_wrapper_ensure_mdata(mesh_operand); | BKE_mesh_wrapper_ensure_mdata(mesh_operand); | ||||
| meshes.append(mesh_operand); | meshes.append(mesh_operand); | ||||
| obmats.append((float4x4 *)&bmd->object->obmat); | obmats.append((float4x4 *)&bmd->object->object_to_world); | ||||
| material_remaps.append(get_material_remap(*bmd->object, *mesh_operand, materials)); | material_remaps.append(get_material_remap(*bmd->object, *mesh_operand, materials)); | ||||
| } | } | ||||
| else if (bmd->flag & eBooleanModifierFlag_Collection) { | else if (bmd->flag & eBooleanModifierFlag_Collection) { | ||||
| Collection *collection = bmd->collection; | Collection *collection = bmd->collection; | ||||
| /* Allow collection to be empty; then target mesh will just removed self-intersections. */ | /* Allow collection to be empty; then target mesh will just removed self-intersections. */ | ||||
| if (collection) { | if (collection) { | ||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) { | FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) { | ||||
| if (ob->type == OB_MESH && ob != ctx->object) { | if (ob->type == OB_MESH && ob != ctx->object) { | ||||
| Mesh *collection_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob); | Mesh *collection_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob); | ||||
| if (!collection_mesh) { | if (!collection_mesh) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| BKE_mesh_wrapper_ensure_mdata(collection_mesh); | BKE_mesh_wrapper_ensure_mdata(collection_mesh); | ||||
| meshes.append(collection_mesh); | meshes.append(collection_mesh); | ||||
| obmats.append((float4x4 *)&ob->obmat); | obmats.append((float4x4 *)&ob->object_to_world); | ||||
| material_remaps.append(get_material_remap(*ob, *collection_mesh, materials)); | material_remaps.append(get_material_remap(*ob, *collection_mesh, materials)); | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | FOREACH_COLLECTION_OBJECT_RECURSIVE_END; | ||||
| } | } | ||||
| } | } | ||||
| const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0; | const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0; | ||||
| const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0; | const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0; | ||||
| Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes, | Mesh *result = blender::meshintersect::direct_mesh_boolean( | ||||
| meshes, | |||||
| obmats, | obmats, | ||||
| *(float4x4 *)&ctx->object->obmat, | *(float4x4 *)&ctx->object->object_to_world, | ||||
| material_remaps, | material_remaps, | ||||
| use_self, | use_self, | ||||
| hole_tolerant, | hole_tolerant, | ||||
| bmd->operation, | bmd->operation, | ||||
| nullptr); | nullptr); | ||||
| MEM_SAFE_FREE(result->mat); | MEM_SAFE_FREE(result->mat); | ||||
| result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__); | result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__); | ||||
| result->totcol = materials.size(); | result->totcol = materials.size(); | ||||
| MutableSpan(result->mat, result->totcol).copy_from(materials); | MutableSpan(result->mat, result->totcol).copy_from(materials); | ||||
| return result; | return result; | ||||
| } | } | ||||
| #endif | #endif | ||||
| ▲ Show 20 Lines • Show All 191 Lines • Show Last 20 Lines | |||||