[Bf-blender-cvs] [2067d4f] bmesh-boolean-experiment: Initial bmesh-boolean experiment

Campbell Barton noreply at git.blender.org
Sat Nov 22 14:16:36 CET 2014


Commit: 2067d4fce33ee4bcdd8ef85b3528d1af3ffc680c
Author: Campbell Barton
Date:   Sat Nov 22 14:01:01 2014 +0100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rB2067d4fce33ee4bcdd8ef85b3528d1af3ffc680c

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 22e5050..c06872a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -86,8 +86,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 49c0c09..d404423 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -33,6 +33,10 @@
  *  \ingroup modifiers
  */
 
+#ifdef WITH_MOD_BOOLEAN
+#  define USE_BMESH
+#endif
+
 #include <stdio.h>
 
 #include "DNA_object_types.h"
@@ -50,6 +54,16 @@
 #include "MOD_util.h"
 
 #include "PIL_time.h"
+#include "PIL_time_utildefines.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
 
 static void copyData(ModifierData *md, ModifierData *target)
 {
@@ -118,6 +132,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)
@@ -157,6 +264,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