[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