Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2021-04-02 08:16:01 +0300
committerHans Goudey <h.goudey@me.com>2021-04-02 08:16:23 +0300
commita0e1080428abb991c443a40b29d2ae3948eb4a56 (patch)
tree735c26798d07a07690ebe827d604ee438afcc3e9 /source/blender
parent77f685774090c18b8da7a9860861664ed0fdd81e (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_mesh_boolean_convert.hh (renamed from source/blender/blenkernel/BKE_mesh_boolean_convert.h)30
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc106
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.h8
-rw-r--r--source/blender/modifiers/CMakeLists.txt2
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.cc (renamed from source/blender/modifiers/intern/MOD_boolean.c)305
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc2
7 files changed, 167 insertions, 288 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_boolean_convert.h b/source/blender/blenkernel/BKE_mesh_boolean_convert.hh
index 7e285d3676e..59f6e75183e 100644
--- a/source/blender/blenkernel/BKE_mesh_boolean_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_boolean_convert.hh
@@ -23,39 +23,21 @@
* \ingroup bke
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "BLI_array.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_mesh_boolean.hh"
+#include "BLI_span.hh"
-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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-
-# include "BLI_float4x4.hh"
-# include "BLI_mesh_boolean.hh"
-# include "BLI_span.hh"
+struct Mesh;
namespace blender::meshintersect {
Mesh *direct_mesh_boolean(blender::Span<const Mesh *> meshes,
blender::Span<const float4x4 *> obmats,
const float4x4 &target_transform,
- blender::Span<const short *> material_remaps,
+ blender::Span<blender::Array<short>> material_remaps,
const bool use_self,
const bool hole_tolerant,
const int boolean_mode);
} // namespace blender::meshintersect
-
-#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f1f08b3ad3a..59e2c74ead1 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -371,7 +371,7 @@ set(SRC
BKE_mball.h
BKE_mball_tessellate.h
BKE_mesh.h
- BKE_mesh_boolean_convert.h
+ BKE_mesh_boolean_convert.hh
BKE_mesh_fair.h
BKE_mesh_iterators.h
BKE_mesh_mapping.h
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<float4x4> to_target_transform;
/* For each input mesh, how to remap the material slot numbers to
* the material slots in the first mesh. */
- Array<const short *> material_remaps;
+ Span<Array<short>> 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<const Mesh *> meshes,
Span<const float4x4 *> obmats,
- Span<const short *> material_remaps,
+ Span<Array<short>> material_remaps,
const float4x4 &target_transform,
IMeshArena &arena,
MeshesToIMeshInfo *r_info)
@@ -274,7 +275,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
r_info->mesh_edge_offset = Array<int>(nmeshes);
r_info->mesh_poly_offset = Array<int>(nmeshes);
r_info->to_target_transform = Array<float4x4>(nmeshes);
- r_info->material_remaps = Array<const short *>(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<const Mesh *> 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<short> 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<short>());
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<const Mesh *> meshes,
Span<const float4x4 *> obmats,
const float4x4 &target_transform,
- Span<const short *> material_remaps,
+ Span<Array<short>> 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<const Mesh *> meshes,
};
IMesh m_out = boolean_mesh(m_in,
static_cast<BoolOpType>(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<const Mesh *> 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"
diff --git a/source/blender/bmesh/tools/bmesh_intersect.h b/source/blender/bmesh/tools/bmesh_intersect.h
index adb88f2fd76..d09ea67a3bb 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.h
+++ b/source/blender/bmesh/tools/bmesh_intersect.h
@@ -20,6 +20,10 @@
* \ingroup bmesh
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool BM_mesh_intersect(BMesh *bm,
struct BMLoop *(*looptris)[3],
const int looptris_tot,
@@ -41,3 +45,7 @@ enum {
BMESH_ISECT_BOOLEAN_UNION = 1,
BMESH_ISECT_BOOLEAN_DIFFERENCE = 2,
};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index c19782df44b..5fc88846527 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -50,7 +50,7 @@ set(SRC
intern/MOD_armature.c
intern/MOD_array.c
intern/MOD_bevel.c
- intern/MOD_boolean.c
+ intern/MOD_boolean.cc
intern/MOD_build.c
intern/MOD_cast.c
intern/MOD_cloth.c
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.cc
index d92f0d4219e..c49bcce2dd3 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.cc
@@ -21,16 +21,15 @@
* \ingroup modifiers
*/
-// #define DEBUG_TIME
-
-#include <stdio.h>
+#include <cstdio>
#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
-#include "BLI_array.h"
+#include "BLI_array.hh"
+#include "BLI_float4x4.hh"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
+#include "BLI_vector.hh"
#include "BLT_translation.h"
@@ -49,10 +48,9 @@
#include "BKE_lib_query.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
-#include "BKE_mesh_boolean_convert.h"
+#include "BKE_mesh_boolean_convert.hh"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
-#include "BKE_screen.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -71,11 +69,16 @@
#include "tools/bmesh_boolean.h"
#include "tools/bmesh_intersect.h"
+// #define DEBUG_TIME
+
#ifdef DEBUG_TIME
-# include "PIL_time.h"
-# include "PIL_time_utildefines.h"
+# include "BLI_timeit.hh"
#endif
+using blender::Array;
+using blender::float4x4;
+using blender::Vector;
+
static void initData(ModifierData *md)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
@@ -113,14 +116,14 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
- if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object != NULL) {
+ if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object != nullptr) {
DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_GEOMETRY, "Boolean Modifier");
}
Collection *col = bmd->collection;
- if ((bmd->flag & eBooleanModifierFlag_Collection) && col != NULL) {
+ if ((bmd->flag & eBooleanModifierFlag_Collection) && col != nullptr) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) {
if (operand_ob->type == OB_MESH && operand_ob != ctx->object) {
DEG_add_object_relation(ctx->node, operand_ob, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
@@ -136,7 +139,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
static Mesh *get_quick_mesh(
Object *ob_self, Mesh *mesh_self, Object *ob_operand_ob, Mesh *mesh_operand_ob, int operation)
{
- Mesh *result = NULL;
+ Mesh *result = nullptr;
if (mesh_self->totpoly == 0 || mesh_operand_ob->totpoly == 0) {
switch (operation) {
@@ -149,11 +152,11 @@ static Mesh *get_quick_mesh(
result = mesh_self;
}
else {
- result = (Mesh *)BKE_id_copy_ex(NULL, &mesh_operand_ob->id, NULL, LIB_ID_COPY_LOCALIZE);
+ result = (Mesh *)BKE_id_copy_ex(
+ nullptr, &mesh_operand_ob->id, nullptr, LIB_ID_COPY_LOCALIZE);
float imat[4][4];
float omat[4][4];
-
invert_m4_m4(imat, ob_self->obmat);
mul_m4_m4m4(omat, imat, ob_operand_ob->obmat);
@@ -189,9 +192,10 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
-static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *col)
+static bool BMD_error_messages(const Object *ob, ModifierData *md)
{
BooleanModifierData *bmd = (BooleanModifierData *)md;
+ Collection *col = bmd->collection;
bool error_returns_result = false;
@@ -239,22 +243,20 @@ static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *c
static BMesh *BMD_mesh_bm_create(
Mesh *mesh, Object *object, Mesh *mesh_operand_ob, Object *operand_ob, bool *r_is_flip)
{
- BMesh *bm;
+#ifdef DEBUG_TIME
+ SCOPED_TIMER(__func__)
+#endif
*r_is_flip = (is_negative_m4(object->obmat) != is_negative_m4(operand_ob->obmat));
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_operand_ob);
- bm = BM_mesh_create(&allocsize,
- &((struct BMeshCreateParams){
- .use_toolflags = false,
- }));
+ BMeshCreateParams bmcp = {false};
+ BMesh *bm = BM_mesh_create(&allocsize, &bmcp);
- BM_mesh_bm_from_me(bm,
- mesh_operand_ob,
- &((struct BMeshFromMeshParams){
- .calc_face_normal = true,
- }));
+ BMeshFromMeshParams params{};
+ params.calc_face_normal = true;
+ BM_mesh_bm_from_me(bm, mesh_operand_ob, &params);
if (UNLIKELY(*r_is_flip)) {
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
@@ -265,11 +267,7 @@ static BMesh *BMD_mesh_bm_create(
}
}
- BM_mesh_bm_from_me(bm,
- mesh,
- &((struct BMeshFromMeshParams){
- .calc_face_normal = true,
- }));
+ BM_mesh_bm_from_me(bm, mesh, &params);
return bm;
}
@@ -282,13 +280,18 @@ static void BMD_mesh_intersection(BMesh *bm,
Object *operand_ob,
bool is_flip)
{
+#ifdef DEBUG_TIME
+ SCOPED_TIMER(__func__)
+#endif
+
BooleanModifierData *bmd = (BooleanModifierData *)md;
/* main bmesh intersection setup */
/* create tessface & intersect */
const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
int tottri;
- BMLoop *(*looptris)[3] = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
+ BMLoop *(*looptris)[3] = (BMLoop * (*)[3])
+ MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
@@ -324,12 +327,11 @@ static void BMD_mesh_intersection(BMesh *bm,
negate_m3(nmat);
}
- const short ob_src_totcol = operand_ob->totcol;
- short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
+ Array<short> material_remap(operand_ob->totcol ? operand_ob->totcol : 1);
/* Using original (not evaluated) object here since we are writing to it. */
/* XXX Pretty sure comment above is fully wrong now with CoW & co ? */
- BKE_object_material_remap_calc(ctx->object, operand_ob, material_remap);
+ BKE_object_material_remap_calc(ctx->object, operand_ob, material_remap.data());
BMFace *efa;
i = 0;
@@ -341,7 +343,7 @@ static void BMD_mesh_intersection(BMesh *bm,
BM_elem_flag_enable(efa, BM_FACE_TAG);
/* remap material */
- if (LIKELY(efa->mat_nr < ob_src_totcol)) {
+ if (LIKELY(efa->mat_nr < operand_ob->totcol)) {
efa->mat_nr = material_remap[efa->mat_nr];
}
@@ -370,7 +372,7 @@ static void BMD_mesh_intersection(BMesh *bm,
looptris,
tottri,
bm_face_isect_pair,
- NULL,
+ nullptr,
false,
use_separate,
use_dissolve,
@@ -388,59 +390,50 @@ static void BMD_mesh_intersection(BMesh *bm,
/* 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.
- * Caller must MEM_freeN the returned array. */
-static short *get_material_remap(Object *dest_ob, Object *src_ob)
+ * Caller owns the returned array. */
+static Array<short> get_material_remap(Object *dest_ob, Object *src_ob)
{
- short *remap;
int n = dest_ob->totcol;
if (n <= 0) {
n = 1;
}
- remap = MEM_mallocN(n * sizeof(short), __func__);
- BKE_object_material_remap_calc(dest_ob, src_ob, remap);
+ Array<short> remap(n);
+ BKE_object_material_remap_calc(dest_ob, src_ob, remap.data());
return remap;
}
-/* New method: bypass trip through BMesh. */
static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
const ModifierEvalContext *ctx,
Mesh *mesh)
{
- Mesh *result;
- Mesh *mesh_operand;
- short *remap;
- Mesh **meshes = NULL;
- const float(**obmats)[4][4] = NULL;
- short **material_remaps = NULL;
- BLI_array_declare(meshes);
- BLI_array_declare(obmats);
- BLI_array_declare(material_remaps);
+ Vector<const Mesh *> meshes;
+ Vector<float4x4 *> obmats;
+ Vector<Array<short>> material_remaps;
# ifdef DEBUG_TIME
- TIMEIT_START(boolean_bmesh);
+ SCOPED_TIMER(__func__)
# endif
- if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == NULL) {
+ if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == nullptr) {
return mesh;
}
- BLI_array_append(meshes, mesh);
- BLI_array_append(obmats, &ctx->object->obmat);
- BLI_array_append(material_remaps, NULL);
+ meshes.append(mesh);
+ obmats.append((float4x4 *)&ctx->object->obmat);
+ material_remaps.append({});
if (bmd->flag & eBooleanModifierFlag_Object) {
- mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object, false);
+ Mesh *mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object, false);
if (!mesh_operand) {
return mesh;
}
BKE_mesh_wrapper_ensure_mdata(mesh_operand);
- BLI_array_append(meshes, mesh_operand);
- BLI_array_append(obmats, &bmd->object->obmat);
- remap = get_material_remap(ctx->object, bmd->object);
- BLI_array_append(material_remaps, remap);
+ meshes.append(mesh_operand);
+ obmats.append((float4x4 *)&bmd->object->obmat);
+ material_remaps.append(get_material_remap(ctx->object, bmd->object));
}
else if (bmd->flag & eBooleanModifierFlag_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) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
if (ob->type == OB_MESH && ob != ctx->object) {
@@ -449,10 +442,9 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
continue;
}
BKE_mesh_wrapper_ensure_mdata(collection_mesh);
- BLI_array_append(meshes, collection_mesh);
- BLI_array_append(obmats, &ob->obmat);
- remap = get_material_remap(ctx->object, ob);
- BLI_array_append(material_remaps, remap);
+ meshes.append(collection_mesh);
+ obmats.append((float4x4 *)&ob->obmat);
+ material_remaps.append(get_material_remap(ctx->object, ob));
}
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -461,30 +453,13 @@ 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;
- result = BKE_mesh_boolean((const Mesh **)meshes,
- (const float(**)[4][4])obmats,
- &ctx->object->obmat,
- (const short **)material_remaps,
- BLI_array_len(meshes),
- use_self,
- hole_tolerant,
- bmd->operation);
-
- BLI_array_free(meshes);
- BLI_array_free(obmats);
- for (int i = 0; i < BLI_array_len(material_remaps); i++) {
- remap = material_remaps[i];
- if (remap) {
- MEM_freeN(remap);
- }
- }
- BLI_array_free(material_remaps);
-
-# ifdef DEBUG_TIME
- TIMEIT_END(boolean_bmesh);
-# endif
-
- return result;
+ return blender::meshintersect::direct_mesh_boolean(meshes,
+ obmats,
+ *(float4x4 *)&ctx->object->obmat,
+ material_remaps,
+ use_self,
+ hole_tolerant,
+ bmd->operation);
}
#endif
@@ -493,12 +468,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BooleanModifierData *bmd = (BooleanModifierData *)md;
Object *object = ctx->object;
Mesh *result = mesh;
- Mesh *mesh_operand_ob;
- BMesh *bm;
Collection *collection = bmd->collection;
- bool is_flip = false;
- const bool confirm_return = true;
+ /* Return result for certain errors. */
+ if (BMD_error_messages(ctx->object, md)) {
+ return result;
+ }
+
#ifdef WITH_GMP
if (bmd->solver == eBooleanModifierSolver_Exact) {
return exact_boolean_mesh(bmd, ctx, mesh);
@@ -506,27 +482,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
#endif
#ifdef DEBUG_TIME
- TIMEIT_START(boolean_bmesh);
+ SCOPED_TIMER(__func__)
#endif
if (bmd->flag & eBooleanModifierFlag_Object) {
- if (bmd->object == NULL) {
+ if (bmd->object == nullptr) {
return result;
}
- BMD_error_messages(ctx->object, md, NULL);
-
Object *operand_ob = bmd->object;
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_INIT(operand_get_evaluated_mesh);
- TIMEIT_BLOCK_START(operand_get_evaluated_mesh);
-#endif
- mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob, false);
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_END(operand_get_evaluated_mesh);
- TIMEIT_BLOCK_STATS(operand_get_evaluated_mesh);
-#endif
+ Mesh *mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob,
+ false);
if (mesh_operand_ob) {
/* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
@@ -537,80 +504,49 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* Returning mesh is depended on modifiers operation (sergey) */
result = get_quick_mesh(object, mesh, operand_ob, mesh_operand_ob, bmd->operation);
- if (result == NULL) {
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_INIT(object_BMD_mesh_bm_create);
- TIMEIT_BLOCK_START(object_BMD_mesh_bm_create);
-#endif
- bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_END(object_BMD_mesh_bm_create);
- TIMEIT_BLOCK_STATS(object_BMD_mesh_bm_create);
-#endif
+ if (result == nullptr) {
+ bool is_flip;
+ BMesh *bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_INIT(BMD_mesh_intersection);
- TIMEIT_BLOCK_START(BMD_mesh_intersection);
-#endif
BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_END(BMD_mesh_intersection);
- TIMEIT_BLOCK_STATS(BMD_mesh_intersection);
-#endif
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_INIT(BKE_mesh_from_bmesh_for_eval_nomain);
- TIMEIT_BLOCK_START(BKE_mesh_from_bmesh_for_eval_nomain);
-#endif
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
-#ifdef DEBUG_TIME
- TIMEIT_BLOCK_END(BKE_mesh_from_bmesh_for_eval_nomain);
- TIMEIT_BLOCK_STATS(BKE_mesh_from_bmesh_for_eval_nomain);
-#endif
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh);
+
BM_mesh_free(bm);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
- /* if new mesh returned, return it; otherwise there was
- * an error, so delete the modifier object */
- if (result == NULL) {
+ if (result == nullptr) {
BKE_modifier_set_error(object, md, "Cannot execute boolean operation");
}
}
}
else {
- if (collection == NULL) {
- return result;
- }
-
- /* Return result for certain errors. */
- if (BMD_error_messages(ctx->object, md, collection) == confirm_return) {
+ if (collection == nullptr) {
return result;
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, operand_ob) {
if (operand_ob->type == OB_MESH && operand_ob != ctx->object) {
-
- mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob, false);
+ Mesh *mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob,
+ false);
if (mesh_operand_ob) {
/* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
* But for 2.90 better not try to be smart here. */
BKE_mesh_wrapper_ensure_mdata(mesh_operand_ob);
- bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
+ bool is_flip;
+ BMesh *bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
/* Needed for multiple objects to work. */
- BM_mesh_bm_to_me(NULL,
- bm,
- mesh,
- (&(struct BMeshToMeshParams){
- .calc_object_remap = false,
- }));
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+ BMeshToMeshParams params{};
+ params.calc_object_remap = false;
+ BM_mesh_bm_to_me(nullptr, bm, mesh, &params);
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh);
BM_mesh_free(bm);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
@@ -619,10 +555,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
-#ifdef DEBUG_TIME
- TIMEIT_END(boolean_bmesh);
-#endif
-
return result;
}
@@ -638,22 +570,21 @@ static void requiredDataMask(Object *UNUSED(ob),
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
-
- uiItemR(layout, ptr, "operation", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "operation", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
uiLayoutSetPropSep(layout, true);
- uiItemR(layout, ptr, "operand_type", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "operand_type", 0, nullptr, ICON_NONE);
if (RNA_enum_get(ptr, "operand_type") == eBooleanModifierFlag_Object) {
- uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "object", 0, nullptr, ICON_NONE);
}
else {
- uiItemR(layout, ptr, "collection", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "collection", 0, nullptr, ICON_NONE);
}
- uiItemR(layout, ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "solver", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
@@ -661,8 +592,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void solver_options_panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
-
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr);
const bool use_exact = RNA_enum_get(ptr, "solver") == eBooleanModifierSolver_Exact;
@@ -672,16 +602,16 @@ static void solver_options_panel_draw(const bContext *UNUSED(C), Panel *panel)
if (use_exact) {
/* When operand is collection, we always use_self. */
if (RNA_enum_get(ptr, "operand_type") == eBooleanModifierFlag_Object) {
- uiItemR(col, ptr, "use_self", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_self", 0, nullptr, ICON_NONE);
}
- uiItemR(col, ptr, "use_hole_tolerant", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_hole_tolerant", 0, nullptr, ICON_NONE);
}
else {
- uiItemR(col, ptr, "double_threshold", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "double_threshold", 0, nullptr, ICON_NONE);
}
if (G.debug) {
- uiItemR(col, ptr, "debug_options", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "debug_options", 0, nullptr, ICON_NONE);
}
}
@@ -689,7 +619,7 @@ static void panelRegister(ARegionType *region_type)
{
PanelType *panel = modifier_panel_register(region_type, eModifierType_Boolean, panel_draw);
modifier_subpanel_register(
- region_type, "solver_options", "Solver Options", NULL, solver_options_panel_draw, panel);
+ region_type, "solver_options", "Solver Options", nullptr, solver_options_panel_draw, panel);
}
ModifierTypeInfo modifierType_Boolean = {
@@ -698,31 +628,32 @@ ModifierTypeInfo modifierType_Boolean = {
/* structSize */ sizeof(BooleanModifierData),
/* srna */ &RNA_BooleanModifier,
/* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* flags */
+ (ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode),
/* icon */ ICON_MOD_BOOLEAN,
/* copyData */ BKE_modifier_copydata_generic,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
+ /* deformVerts */ nullptr,
+ /* deformMatrices */ nullptr,
+ /* deformVertsEM */ nullptr,
+ /* deformMatricesEM */ nullptr,
/* modifyMesh */ modifyMesh,
- /* modifyHair */ NULL,
- /* modifyGeometrySet */ NULL,
- /* modifyVolume */ NULL,
+ /* modifyHair */ nullptr,
+ /* modifyGeometrySet */ nullptr,
+ /* modifyVolume */ nullptr,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
+ /* freeData */ nullptr,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnTime */ nullptr,
+ /* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* foreachTexLink */ nullptr,
+ /* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ nullptr,
+ /* blendRead */ nullptr,
};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index c3017dc2610..6be5bc4f8b4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -17,7 +17,7 @@
#include "DNA_mesh_types.h"
#include "BKE_mesh.h"
-#include "BKE_mesh_boolean_convert.h"
+#include "BKE_mesh_boolean_convert.hh"
#include "UI_interface.h"
#include "UI_resources.h"