[Bf-blender-cvs] [79392cc] fracture_modifier: simpler and cleaner reimplementation of clustering algorithm, caused crash before

Martin Felke noreply at git.blender.org
Sat Oct 18 10:28:18 CEST 2014


Commit: 79392ccad93f9443a9258642e881b1cb2c1d620a
Author: Martin Felke
Date:   Sat Oct 18 10:27:46 2014 +0200
Branches: fracture_modifier
https://developer.blender.org/rB79392ccad93f9443a9258642e881b1cb2c1d620a

simpler and cleaner reimplementation of clustering algorithm, caused crash before

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

M	source/blender/modifiers/intern/MOD_fracture.c

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

diff --git a/source/blender/modifiers/intern/MOD_fracture.c b/source/blender/modifiers/intern/MOD_fracture.c
index 3dc8280..7e3e74a 100644
--- a/source/blender/modifiers/intern/MOD_fracture.c
+++ b/source/blender/modifiers/intern/MOD_fracture.c
@@ -280,96 +280,57 @@ static void freeData(ModifierData *md)
 	}
 }
 
-static void growCluster(FractureModifierData *fmd, Shard *seed, int sindex, ListBase *lbVisit, KDTree *tree, int depth)
-{
-	int i = 0, count = 0;
-	float size = 0.1f;
-	KDTreeNearest *nearest;
-
-	count = BLI_kdtree_range_search(tree, seed->centroid, &nearest, size * depth);
-	for (i = 0; i < count; i++) {
-		Shard *neighbor;
-		int index = nearest[i].index;
-		neighbor = (Shard *)BLI_findlink(&fmd->frac_mesh->shard_map, index);
-		if (neighbor->cluster_colors[0] == -1) {
-			neighbor->cluster_colors[0] = sindex;
-		}
-
-		if (BLI_findindex(lbVisit, seed) == -1) {
-			BLI_addtail(lbVisit, seed);
-		}
-	}
-	MEM_freeN(nearest);
-}
-
-static void doClusters(FractureModifierData *fmd, int levels)
+static void doClusters(FractureModifierData *fmd)
 {
 	/*grow clusters from all shards */
-	ListBase lbVisit;
-	int i = 0, j = 0, k = 0, sindex = 0, counter = 0, depth = 1;
-	KDTree *tree = BLI_kdtree_new(fmd->frac_mesh->shard_count);
-
+	int k = 0;
+	KDTree *tree;
+	Shard *s, **seeds;
+	int seed_count;
 
-	lbVisit.first = NULL;
-	lbVisit.last = NULL;
+	/*for now, keep 1 hierarchy level only, should be sufficient */
+	int levels = 1;
 
-	for (j = 0; j < levels; j++) {
-		Shard **seeds, *s;
-		int seed_count;
-		/*prepare shard as list*/
-		for (s = fmd->frac_mesh->shard_map.first; s; s = s->next) {
+	/*initialize cluster "colors" -> membership of shards to clusters, initally all shards are "free" */
+	for (s = fmd->frac_mesh->shard_map.first; s; s = s->next ) {
+		if (s->cluster_colors == NULL) {
 			s->cluster_colors = MEM_mallocN(sizeof(int) * levels, "cluster_colors");
-			for (k = 0; k < levels; k++)
-			{
-				s->cluster_colors[k] = -1;
-			}
-
-			BLI_kdtree_insert(tree, i, s->centroid);
-		}
-
-		if (fmd->cluster_count < 2) {
-			BLI_kdtree_free(tree);
-			return;
-		}
-
-		BLI_kdtree_balance(tree);
-
-		seed_count = (fmd->cluster_count > fmd->frac_mesh->shard_count ? fmd->frac_mesh->shard_count : fmd->cluster_count);
-		seeds = MEM_mallocN(sizeof(Shard *) * seed_count, "seeds");
-
-		for (k = 0; k < seed_count; k++) {
-			int color = k;
-			int which_index = k * (int)(fmd->frac_mesh->shard_count / seed_count);
-			Shard *which = (Shard *)BLI_findlink(&fmd->frac_mesh->shard_map, which_index);
-			which->cluster_colors[j] = color;
-			BLI_addtail(&lbVisit, which);
-			seeds[k] = which;
+			s->cluster_colors[0] = -1;
 		}
+	}
 
-		while (BLI_countlist(&lbVisit) < fmd->frac_mesh->shard_count) {
-			Shard *seed;
+	/* zero clusters or one mean no clusters, all shards keep free */
+	if (fmd->cluster_count < 2) {
+		return;
+	}
 
-			if (sindex == seed_count)
-			{
-				sindex = 0;
-				depth++;
-			}
+	seed_count = (fmd->cluster_count > fmd->frac_mesh->shard_count ? fmd->frac_mesh->shard_count : fmd->cluster_count);
+	seeds = MEM_mallocN(sizeof(Shard *) * seed_count, "seeds");
+	tree = BLI_kdtree_new(seed_count);
 
-			seed = seeds[sindex];
-			growCluster(fmd, seed, sindex, &lbVisit, tree, depth);
-			sindex++;
+	/* pick n seed locations, randomly scattered over the object */
+	for (k = 0; k < seed_count; k++) {
+		int color = k;
+		int which_index = k * (int)(fmd->frac_mesh->shard_count / seed_count);
+		Shard *which = (Shard *)BLI_findlink(&fmd->frac_mesh->shard_map, which_index);
+		which->cluster_colors[0] = color;
+		BLI_kdtree_insert(tree, k, which->centroid);
+		seeds[k] = which;
+	}
 
-			if (counter == 10000) {
-				/*XXX emergency stop... otherwise loop might run eternally */
-				break;
-			}
+	BLI_kdtree_balance(tree);
 
-			counter++;
-		}
+	/* assign each shard to its closest center */
+	for (s = fmd->frac_mesh->shard_map.first; s; s = s->next ) {
+		KDTreeNearest n;
+		int index;
 
-		BLI_kdtree_free(tree);
-		MEM_freeN(seeds);
+		index = BLI_kdtree_find_nearest(tree, s->centroid, &n);
+		s->cluster_colors[0] = seeds[index]->cluster_colors[0];
 	}
+
+	BLI_kdtree_free(tree);
+	MEM_freeN(seeds);
 }
 
 static KDTree *build_nor_tree(DerivedMesh *dm)
@@ -989,7 +950,7 @@ static void do_fracture(FractureModifierData *fracmd, ShardID id, Object *obj, D
 
 		if (fracmd->frac_mesh->shard_count > 0)
 		{
-			doClusters(fracmd, 1);
+			doClusters(fracmd);
 		}
 
 		/* here we REALLY need to fracture so deactivate the shards to islands flag and activate afterwards */




More information about the Bf-blender-cvs mailing list