From a0e1080428abb991c443a40b29d2ae3948eb4a56 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 2 Apr 2021 00:16:01 -0500 Subject: Cleanup: Remove unecessary C API for direct mesh boolean The main goal here is to remove the need for a C API to the code in `mesh_boolean_convert.cc`. This is achieved by moving `MOD_boolean.c` to C++ and making the necessary changes for it to compile. On top of that there are some other slight simplifications possible to the direct mesh boolean code: it doesn't need to copy the material remaps, and the modifier code can use some other C++ types directly. --- .../blenkernel/intern/mesh_boolean_convert.cc | 106 +++++++-------------- 1 file changed, 32 insertions(+), 74 deletions(-) (limited to 'source/blender/blenkernel/intern/mesh_boolean_convert.cc') diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index de9ad00ebde..ecf70c779e5 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -28,9 +28,10 @@ #include "BKE_customdata.h" #include "BKE_material.h" #include "BKE_mesh.h" -#include "BKE_mesh_boolean_convert.h" +#include "BKE_mesh_boolean_convert.hh" #include "BLI_alloca.h" +#include "BLI_array.hh" #include "BLI_float2.hh" #include "BLI_float4x4.hh" #include "BLI_math.h" @@ -97,7 +98,7 @@ class MeshesToIMeshInfo { Array to_target_transform; /* For each input mesh, how to remap the material slot numbers to * the material slots in the first mesh. */ - Array material_remaps; + Span> material_remaps; /* Total number of input mesh vertices. */ int tot_meshes_verts; /* Total number of input mesh edges. */ @@ -243,7 +244,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index, */ static IMesh meshes_to_imesh(Span meshes, Span obmats, - Span material_remaps, + Span> material_remaps, const float4x4 &target_transform, IMeshArena &arena, MeshesToIMeshInfo *r_info) @@ -274,7 +275,7 @@ static IMesh meshes_to_imesh(Span meshes, r_info->mesh_edge_offset = Array(nmeshes); r_info->mesh_poly_offset = Array(nmeshes); r_info->to_target_transform = Array(nmeshes); - r_info->material_remaps = Array(nmeshes); + r_info->material_remaps = material_remaps; int v = 0; int e = 0; int f = 0; @@ -307,13 +308,6 @@ static IMesh meshes_to_imesh(Span meshes, clean_obmat(*obmats[mi]); r_info->to_target_transform[mi] = inv_target_mat * objn_mat; - if (mi < material_remaps.size() && mi != 0) { - r_info->material_remaps[mi] = material_remaps[mi]; - } - else { - r_info->material_remaps[mi] = nullptr; - } - /* Skip the matrix multiplication for each point when there is no transform for a mesh, * for example when the first mesh is already in the target space. (Note the logic directly * above, which uses an identity matrix with a null input transform). */ @@ -393,14 +387,14 @@ static void copy_poly_attributes(Mesh *dest_mesh, const Mesh *orig_me, int mp_index, int index_in_orig_me, - const short *material_remap) + Span material_remap) { mp->mat_nr = orig_mp->mat_nr; if (mp->mat_nr >= dest_mesh->totcol) { mp->mat_nr = 0; } else { - if (material_remap) { + if (material_remap.size() > 0) { short mat_nr = material_remap[orig_mp->mat_nr]; if (mat_nr >= 0 && mat_nr < dest_mesh->totcol) { mp->mat_nr = mat_nr; @@ -733,8 +727,15 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) ++cur_loop_index; } - copy_poly_attributes( - result, mp, orig_mp, orig_me, fi, index_in_orig_me, mim.material_remaps[orig_me_index]); + copy_poly_attributes(result, + mp, + orig_mp, + orig_me, + fi, + index_in_orig_me, + (mim.material_remaps.size() > 0) ? + mim.material_remaps[orig_me_index].as_span() : + Span()); copy_or_interp_loop_attributes(result, f, mp, orig_mp, orig_me, orig_me_index, mim); } @@ -771,26 +772,33 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) #endif // WITH_GMP /** - * Do Exact Boolean directly, without a round trip through #BMesh. - * The Mesh operands are in `meshes`, with corresponding transforms in in `obmats`. + * Do a mesh boolean operation directly on meshes (without going back and forth to BMesh). + * \param meshes: An array of of Mesh pointers. + * \param obmats: An array of pointers to the obmat matrices that transform local + * coordinates to global ones. It is allowed for the pointers to be null, meaning the + * transformation is the identity. + * \param material_remaps: An array of pointers to arrays of maps from material slot numbers in the + * corresponding mesh to the material slot in the first mesh. It is OK for material_remaps or any + * of its constituent arrays to be empty. */ Mesh *direct_mesh_boolean(Span meshes, Span obmats, const float4x4 &target_transform, - Span material_remaps, + Span> material_remaps, const bool use_self, const bool hole_tolerant, const int boolean_mode) { #ifdef WITH_GMP - const int dbg_level = 0; BLI_assert(meshes.size() == obmats.size()); - const int meshes_len = meshes.size(); - if (meshes_len <= 0) { + BLI_assert(material_remaps.size() == 0 || material_remaps.size() == meshes.size()); + if (meshes.size() <= 0) { return nullptr; } + + const int dbg_level = 0; if (dbg_level > 0) { - std::cout << "\nDIRECT_MESH_INTERSECT, nmeshes = " << meshes_len << "\n"; + std::cout << "\nDIRECT_MESH_INTERSECT, nmeshes = " << meshes.size() << "\n"; } MeshesToIMeshInfo mim; IMeshArena arena; @@ -805,13 +813,13 @@ Mesh *direct_mesh_boolean(Span meshes, }; IMesh m_out = boolean_mesh(m_in, static_cast(boolean_mode), - meshes_len, + meshes.size(), shape_fn, use_self, hole_tolerant, nullptr, &arena); - if (dbg_level > 1) { + if (dbg_level > 0) { std::cout << m_out; write_obj_mesh(m_out, "m_out"); } @@ -825,53 +833,3 @@ Mesh *direct_mesh_boolean(Span meshes, } } // namespace blender::meshintersect - -extern "C" { - -#ifdef WITH_GMP -/* Do a mesh boolean directly on meshes (without going back and forth to BMesh). - * The \a meshes argument is an array of \a meshes_len of Mesh pointers. - * The \a obmats argument is an array of \a meshes_len of pointers to the obmat - * The \a material_remaps is an array of pointers to arrays of maps from material - * slot numbers in the corresponding mesh to the material slot in the first mesh. - * It is OK for material_remaps or any of its constituent arrays to be NULL. - * matrices that transform local coordinates to global ones. It is allowed - * for the pointers to be nullptr, meaning the transformation is the identity. */ -Mesh *BKE_mesh_boolean(const Mesh **meshes, - const float (*obmats[])[4][4], - const float (*target_transform)[4][4], - const short **material_remaps, - const int meshes_len, - const bool use_self, - const bool hole_tolerant, - const int boolean_mode) -{ - const blender::float4x4 **transforms = (const blender::float4x4 **)obmats; - const blender::float4x4 &target_float4x4 = *(const blender::float4x4 *)target_transform; - return blender::meshintersect::direct_mesh_boolean( - blender::Span(meshes, meshes_len), - blender::Span(transforms, meshes_len), - target_float4x4, - blender::Span(material_remaps, material_remaps ? meshes_len : 0), - use_self, - hole_tolerant, - boolean_mode); -} - -#else -Mesh *BKE_mesh_boolean(const Mesh **UNUSED(meshes), - const float (*obmats[])[4][4], - const float (*target_transform)[4][4], - const short **UNUSED(material_remaps), - const int UNUSED(meshes_len), - const bool UNUSED(use_self), - const bool UNUSED(hole_tolerant), - const int UNUSED(boolean_mode)) -{ - UNUSED_VARS(obmats, target_transform); - return NULL; -} - -#endif - -} // extern "C" -- cgit v1.2.3