[Bf-blender-cvs] [0f48c6a] fracture_modifier: attempt to make voronoi+bisect faster, but it has problems with selfintersection, so unfortunately not useable on any model out of the box

Martin Felke noreply at git.blender.org
Sat Jul 9 13:44:00 CEST 2016


Commit: 0f48c6a392b2b58d2991bffa9ce76093742e8b76
Author: Martin Felke
Date:   Sat Jul 9 01:35:43 2016 +0200
Branches: fracture_modifier
https://developer.blender.org/rB0f48c6a392b2b58d2991bffa9ce76093742e8b76

attempt to make voronoi+bisect faster, but it has problems with selfintersection, so unfortunately not useable on any
model out of the box

===================================================================

M	source/blender/blenkernel/BKE_fracture.h
M	source/blender/blenkernel/BKE_fracture_util.h
M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenkernel/intern/fracture_util.c
M	source/blender/modifiers/intern/MOD_fracture.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h
index 7a5b9e0..0094bb3 100644
--- a/source/blender/blenkernel/BKE_fracture.h
+++ b/source/blender/blenkernel/BKE_fracture.h
@@ -51,6 +51,8 @@ struct MVert;
 struct MPoly;
 struct MLoop;
 
+struct BMesh;
+
 typedef int ShardID;
 
 typedef struct FracPoint {
@@ -118,4 +120,6 @@ void BKE_fracture_free_mesh_island(struct FractureModifierData *rmd, struct Mesh
 int BKE_fracture_update_visual_mesh(struct FractureModifierData *fmd, struct Object *ob, bool do_custom_data);
 short BKE_fracture_collect_materials(struct Object* o, struct Object* ob, short matstart, struct GHash** mat_index_map);
 
+void BKE_bm_mesh_hflag_flush_vert(struct BMesh *bm, const char hflag);
+
 #endif /* BKE_FRACTURE_H */
diff --git a/source/blender/blenkernel/BKE_fracture_util.h b/source/blender/blenkernel/BKE_fracture_util.h
index 08652d2..6b769f7 100644
--- a/source/blender/blenkernel/BKE_fracture_util.h
+++ b/source/blender/blenkernel/BKE_fracture_util.h
@@ -38,6 +38,6 @@
 Shard *BKE_fracture_shard_boolean(Object *obj, DerivedMesh *dm_parent, Shard* child, short inner_material_index, int num_cuts, float fractal, Shard **other, float mat[4][4], float radius, bool use_smooth_inner, int num_levels, char uv_layer[]);
 Shard *BKE_fracture_shard_bisect(struct BMesh *bm_orig, Shard* child, float obmat[4][4], bool use_fill,
                                  bool clear_inner, bool clear_outer, int cutlimit, float centroid[],
-                                 short inner_mat_index, char uv_layer[]);
+                                 short inner_mat_index, char uv_layer[], struct KDTree *preselect_tree);
 
 #endif /* BKE_FRACTURE_UTIL_H*/
diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index 1c80164..6d67f3d 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -117,7 +117,7 @@ static BMesh *shard_to_bmesh(Shard *s)
 
 	dm_parent = BKE_shard_create_dm(s, true);
 	bm_parent = DM_to_bmesh(dm_parent, true);
-	BM_mesh_elem_table_ensure(bm_parent, BM_FACE);
+	BM_mesh_elem_table_ensure(bm_parent, BM_VERT | BM_FACE);
 
 	BM_ITER_MESH (f, &iter, bm_parent, BM_FACES_OF_MESH)
 	{
@@ -437,9 +437,9 @@ static void handle_fast_bisect(FracMesh *fm, int expected_shards, int algorithm,
 		printf("Bisecting cell %d...\n", i + 1);
 
 		s = BKE_fracture_shard_bisect(*bm_parent, t, obmat, algorithm == MOD_FRACTURE_BISECT_FAST_FILL,
-		                              false, true, index, centroid, inner_material_index, uv_layer);
+		                              false, true, index, centroid, inner_material_index, uv_layer, NULL);
 		s2 = BKE_fracture_shard_bisect(*bm_parent, t, obmat, algorithm == MOD_FRACTURE_BISECT_FAST_FILL,
-		                               true, false, index, centroid, inner_material_index, uv_layer);
+		                               true, false, index, centroid, inner_material_index, uv_layer, NULL);
 
 		if (s != NULL && s2 != NULL && tempresults != NULL) {
 			int j = 0;
@@ -573,7 +573,8 @@ static void handle_boolean_fractal(Shard* s, Shard* t, int expected_shards, Deri
 
 static bool handle_boolean_bisect(FracMesh *fm, Object *obj, int expected_shards, int algorithm, int parent_id, Shard **tempshards,
                                   DerivedMesh *dm_parent, BMesh* bm_parent, float obmat[4][4], short inner_material_index, int num_cuts,
-                                  int num_levels, float fractal, int *i, bool smooth, Shard*** tempresults, DerivedMesh **dm_p, char uv_layer[64])
+                                  int num_levels, float fractal, int *i, bool smooth, Shard*** tempresults, DerivedMesh **dm_p, char uv_layer[64],
+                                  KDTree *preselect_tree)
 {
 	Shard *s = NULL, *t = NULL;
 	if (fm->cancel == 1)
@@ -604,7 +605,8 @@ static bool handle_boolean_bisect(FracMesh *fm, Object *obj, int expected_shards
 	else if (algorithm == MOD_FRACTURE_BISECT || algorithm == MOD_FRACTURE_BISECT_FILL) {
 		float co[3] = {0, 0, 0};
 		printf("Bisecting cell %d...\n", *i);
-		s = BKE_fracture_shard_bisect(bm_parent, t, obmat, algorithm == MOD_FRACTURE_BISECT_FILL, false, true, 0, co, inner_material_index, uv_layer);
+		s = BKE_fracture_shard_bisect(bm_parent, t, obmat, algorithm == MOD_FRACTURE_BISECT_FILL, false, true, 0, co, inner_material_index, uv_layer,
+		                              preselect_tree);
 	}
 	else {
 		/* do not fracture case */
@@ -658,12 +660,13 @@ static void do_prepare_cells(FracMesh *fm, cell *cells, int expected_shards, int
 
 	if (fm->last_shard_tree)
 	{
-		if (expected_shards <= fm->last_expected_shards)
+		/*if (expected_shards <= fm->last_expected_shards)
 		{
-			copy_vn_i(deletemap, fm->shard_count, 1);
+
 		}
-		else
+		else*/
 		{
+			copy_vn_i(deletemap, fm->shard_count, 1);
 			copy_vn_i(skipmap, expected_shards, 1);
 		}
 
@@ -688,28 +691,37 @@ static void do_prepare_cells(FracMesh *fm, cell *cells, int expected_shards, int
 			j = BLI_kdtree_find_nearest(fm->last_shard_tree, cells[i].centroid, &n);
 			if (j > -1)
 			{
+				float epsilon = 0.00001;
 				Shard *t = fm->last_shards[j];
-				float dist = len_squared_v3v3(n.co, cells[i].centroid);
-				if (t != NULL && dist < max)
+				//float dist = len_squared_v3v3(n.co, cells[i].centroid);
+				if (t != NULL && n.dist < max)
 				{
-					if (dist < 0.00001) {
-						if (fabsf(cells[i].volume - t->raw_volume) < 0.00001) {
+					if (n.dist < epsilon) {
+						if ((fabsf(cells[i].volume - t->raw_volume) < epsilon))
+						{
 							//printf("Tagging skip: %d\n", i);
-							skipmap[i] = true;
+							//skipmap[i] = true;
 							deletemap[j] = false;
 						}
 						else
 						{
-							deletemap[j] = true;
+							//deletemap[j] = true;
 							skipmap[i] = false;
 						}
 					}
 					else
 					{
 						skipmap[i] = false;
-						deletemap[j] = true;
+						//deletemap[j] = true;
 					}
 				}
+				else
+				{
+					skipmap[i] = false;
+				}
+			}
+			else {
+				skipmap[i] = true;
 			}
 		}
 	}
@@ -727,7 +739,7 @@ static void do_prepare_cells(FracMesh *fm, cell *cells, int expected_shards, int
 
 		if (skipmap[i] /*&& ((t &&
 		    t->setting_id == active_setting &&
-		    t->shard_id > num_settings) || !t)*/)
+		    t->shard_id > num_settings) || !t*/)
 		{
 			printf("Skipping shard: %d\n", i);
 			(*tempshards)[i] = NULL;
@@ -825,7 +837,7 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
 	if (mode == MOD_FRACTURE_PREFRACTURED && !reset)
 	{
 		//rebuild tree
-		if (!fm->last_shard_tree && (fm->shard_count > 0) && mode == MOD_FRACTURE_PREFRACTURED)
+		if (!fm->last_shard_tree /*&& (fm->shard_count > 0)*/ && mode == MOD_FRACTURE_PREFRACTURED)
 		{
 			Shard *t;
 			int i = 0;
@@ -898,13 +910,25 @@ static void parse_cells(cell *cells, int expected_shards, ShardID parent_id, Fra
 	}
 
 	if (algorithm != MOD_FRACTURE_BISECT_FAST && algorithm != MOD_FRACTURE_BISECT_FAST_FILL) {
-		for (i = 0; i < expected_shards; i++) {
+		int totvert = p->totvert;
+		MVert *mvert = p->mvert;
+
+		KDTree *preselect_tree = BLI_kdtree_new(totvert);
+		for (i = 0; i < totvert; i++) {
+			BLI_kdtree_insert(preselect_tree, i, mvert[i].co);
+		}
+
+		BLI_kdtree_balance(preselect_tree);
+
+		for (i = 0; i < expected_shards; i++)	{
 			bool stop = handle_boolean_bisect(fm, obj, expected_shards, algorithm, parent_id, tempshards, dm_parent,
 			                      bm_parent, obmat, inner_material_index, num_cuts, num_levels, fractal,
-			                      &i, smooth, &tempresults, &dm_p, uv_layer);
+			                      &i, smooth, &tempresults, &dm_p, uv_layer, preselect_tree);
 			//if (stop)
 			//	break;
 		}
+
+		BLI_kdtree_free(preselect_tree);
 	}
 	else {
 
@@ -2903,3 +2927,40 @@ void BKE_fracture_mesh_constraint_remove_all(FractureModifierData *fmd)
 	BKE_free_constraints(fmd);
 	fmd->constraint_count = 0;
 }
+
+/* flush a hflag to from verts to edges/faces */
+void BKE_bm_mesh_hflag_flush_vert(BMesh *bm, const char hflag)
+{
+	BMEdge *e;
+	BMLoop *l_iter;
+	BMLoop *l_first;
+	BMFace *f;
+
+	BMIter eiter;
+	BMIter fiter;
+
+	int ok;
+
+	BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+		if (BM_elem_flag_test(e->v1, hflag) &&
+		    BM_elem_flag_test(e->v2, hflag))
+		{
+			BM_elem_flag_enable(e, hflag);
+		}
+		else {
+			BM_elem_flag_disable(e, hflag);
+		}
+	}
+	BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+		ok = true;
+		l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+		do {
+			if (!BM_elem_flag_test(l_iter->v, hflag)) {
+				ok = false;
+				break;
+			}
+		} while ((l_iter = l_iter->next) != l_first);
+
+		BM_elem_flag_set(f, hflag, ok);
+	}
+}
diff --git a/source/blender/blenkernel/intern/fracture_util.c b/source/blender/blenkernel/intern/fracture_util.c
index 8867644..fd2e157 100644
--- a/source/blender/blenkernel/intern/fracture_util.c
+++ b/source/blender/blenkernel/intern/fracture_util.c
@@ -44,6 +44,7 @@
 #include "BLI_math.h"
 #include "BLI_rand.h"
 #include "BLI_sys_types.h"
+#include "BLI_kdtree.h"
 
 #include "DNA_fracture_types.h"
 #include "DNA_meshdata_types.h"
@@ -788,20 +789,122 @@ static void do_bisect(BMesh* bm_parent, BMesh* bm_child, float obmat[4][4], bool
 	}
 }
 
+BMesh *do_preselection(BMesh* bm_orig, Shard *child, KDTree *preselect_tree)
+{
+	int i = 0, r = 0;
+	float max_dist = 0;
+	KDTreeNearest* n, *n2;
+	BMesh *bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
+	BMWalker walker;
+	BMEdge *e;
+	BMVert *seed = NULL;
+
+	n2 = MEM_mallocN(sizeof(KDTreeNearest) * child->totvert, "n2 kdtreenearest");
+	n = MEM_mallocN(sizeof(KDTreeNearest) * bm_orig->totvert, "n kdtreenearest");
+
+	BM_mesh_elem_toolflags_ensure(bm_new);  /* needed for 'duplicate' bmo */
+
+	CustomData_copy(&bm_orig->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_orig->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_orig->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_orig->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+	CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT);
+	CustomData_bmesh_init_pool(&bm_new->edata, b

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list