[Bf-blender-cvs] [1b4adf1] bmesh-boolean-experiment: Initial bmesh-boolean experiment
Campbell Barton
noreply at git.blender.org
Tue Oct 27 18:17:20 CET 2015
Commit: 1b4adf11d3ff1a449bbe73a743aa76524c765ffb
Author: Campbell Barton
Date: Sat Nov 22 14:01:01 2014 +0100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rB1b4adf11d3ff1a449bbe73a743aa76524c765ffb
Initial bmesh-boolean experiment
Currently only intersect
===================================================================
M source/blender/bmesh/intern/bmesh_mesh.h
M source/blender/modifiers/intern/MOD_boolean.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index b157237..b9cdc4c 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -94,8 +94,26 @@ extern const BMAllocTemplate bm_mesh_chunksize_default;
(bm)->totvert), (bm)->totedge, (bm)->totloop, (bm)->totface}
#define BMALLOC_TEMPLATE_FROM_ME(me) { (CHECK_TYPE_INLINE(me, Mesh *), \
(me)->totvert), (me)->totedge, (me)->totloop, (me)->totpoly}
-#define BMALLOC_TEMPLATE_FROM_DM(dm) { (CHECK_TYPE_INLINE(dm, DerivedMesh *), \
- (dm)->getNumVerts(dm)), (dm)->getNumEdges(dm), (dm)->getNumLoops(dm), (dm)->getNumPolys(dm)}
+
+#define _VA_BMALLOC_TEMPLATE_FROM_DM_1(dm) { \
+ (CHECK_TYPE_INLINE(dm, DerivedMesh *), \
+ (dm)->getNumVerts(dm)), \
+ (dm)->getNumEdges(dm), \
+ (dm)->getNumLoops(dm), \
+ (dm)->getNumPolys(dm), \
+ }
+#define _VA_BMALLOC_TEMPLATE_FROM_DM_2(dm_a, dm_b) { \
+ (CHECK_TYPE_INLINE(dm_a, DerivedMesh *), \
+ CHECK_TYPE_INLINE(dm_b, DerivedMesh *), \
+ (dm_a)->getNumVerts(dm_a)) + (dm_b)->getNumVerts(dm_b), \
+ (dm_a)->getNumEdges(dm_a) + (dm_b)->getNumEdges(dm_b), \
+ (dm_a)->getNumLoops(dm_a) + (dm_b)->getNumLoops(dm_b), \
+ (dm_a)->getNumPolys(dm_a) + (dm_b)->getNumPolys(dm_b), \
+ }
+
+#define BMALLOC_TEMPLATE_FROM_DM(...) VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_DM_, __VA_ARGS__)
+
+
enum {
BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0)
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 3fd2c8a..6a31fbc 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -48,6 +48,18 @@
#include "MOD_boolean_util.h"
#include "MOD_util.h"
+#ifdef USE_BMESH
+#include "BLI_math_geom.h"
+#include "MEM_guardedalloc.h"
+
+#include "bmesh.h"
+#include "bmesh_tools.h"
+#include "tools/bmesh_intersect.h"
+#endif
+
+#include "PIL_time.h"
+#include "PIL_time_utildefines.h"
+
static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
@@ -130,6 +142,99 @@ static DerivedMesh *get_quick_derivedMesh(DerivedMesh *derivedData, DerivedMesh
return result;
}
+#ifdef USE_BMESH
+
+struct BMIsectUserData {
+ int face_tot_first_mesh;
+};
+
+/**
+ * Compare selected/unselected.
+ */
+static int bm_face_isect_pair(BMFace *f, void *user_data)
+{
+ struct BMIsectUserData *data = user_data;
+
+ return (BM_elem_index_get(f) < data->face_tot_first_mesh);
+}
+
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *derivedData,
+ ModifierApplyFlag flag)
+{
+ BooleanModifierData *bmd = (BooleanModifierData *) md;
+ DerivedMesh *dm;
+
+ if (!bmd->object)
+ return derivedData;
+
+ dm = get_dm_for_modifier(bmd->object, flag);
+
+ if (dm) {
+ DerivedMesh *result;
+
+ /* when one of objects is empty (has got no faces) we could speed up
+ * calculation a bit returning one of objects' derived meshes (or empty one)
+ * Returning mesh is depended on modifiers operation (sergey) */
+ result = get_quick_derivedMesh(derivedData, dm, bmd->operation);
+
+ if (result == NULL) {
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_DM(derivedData, dm);
+ (void)ob;
+
+ TIMEIT_START(NewBooleanDerivedMesh);
+ bm = BM_mesh_create(&allocsize);
+
+ DM_to_bmesh_ex(derivedData, bm, true);
+ DM_to_bmesh_ex(dm, bm, true);
+
+
+ if (1) {
+ /* create tessface & intersect */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ int tottri;
+ BMLoop *(*looptris)[3];
+
+ struct BMIsectUserData user_data = {0};
+
+ looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__);
+
+ BM_bmesh_calc_tessellation(bm, looptris, &tottri);
+
+ user_data.face_tot_first_mesh = dm->getNumPolys(dm);
+
+ BM_mesh_intersect(
+ bm,
+ looptris, tottri,
+ bm_face_isect_pair, &user_data,
+ false, true, FLT_EPSILON);
+
+ MEM_freeN(looptris);
+ }
+
+ result = CDDM_from_bmesh(bm, true);
+
+ BM_mesh_free(bm);
+
+ result->dirty |= DM_DIRTY_NORMALS;
+
+ TIMEIT_END(NewBooleanDerivedMesh);
+
+ return result;
+ }
+
+ /* if new mesh returned, return it; otherwise there was
+ * an error, so delete the modifier object */
+ if (result)
+ return result;
+ else
+ modifier_setError(md, "Cannot execute boolean operation");
+ }
+
+ return derivedData;
+}
+#else // USE_BMESH
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *derivedData,
ModifierApplyFlag flag)
@@ -169,6 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return derivedData;
}
+#endif // USE_BMESH
#else // WITH_MOD_BOOLEAN
static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob),
DerivedMesh *derivedData,
More information about the Bf-blender-cvs
mailing list