[Bf-blender-cvs] [1051f71] fracture_modifier: fix for material loading in FM external mode and generally decreased file loading times, especially noticeable with large FM objects, by using sorted fd->datamap in readfile.c (avoids linear search)

Martin Felke noreply at git.blender.org
Tue Feb 9 17:45:51 CET 2016


Commit: 1051f712910feaad13ef22e03e444f319b5eba9c
Author: Martin Felke
Date:   Tue Feb 9 17:45:34 2016 +0100
Branches: fracture_modifier
https://developer.blender.org/rB1051f712910feaad13ef22e03e444f319b5eba9c

fix for material loading in FM external mode and generally decreased file loading times, especially noticeable with large FM objects, by using sorted fd->datamap in readfile.c (avoids linear search)

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

M	source/blender/blenkernel/intern/fracture.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c

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

diff --git a/source/blender/blenkernel/intern/fracture.c b/source/blender/blenkernel/intern/fracture.c
index 0ed6af9..39bd38b 100644
--- a/source/blender/blenkernel/intern/fracture.c
+++ b/source/blender/blenkernel/intern/fracture.c
@@ -1821,6 +1821,7 @@ DerivedMesh *BKE_shard_create_dm(Shard *s, bool doCustomData)
 	memcpy(mloops, s->mloop, s->totloop * sizeof(MLoop));
 	memcpy(mpolys, s->mpoly, s->totpoly * sizeof(MPoly));
 
+	CustomData_free(&dm->edgeData, 0);
 	CDDM_calc_edges(dm);
 
 	dm->dirty |= DM_DIRTY_NORMALS;
@@ -2361,7 +2362,7 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, Object *ob, bool
 	DerivedMesh *dm = fmd->visible_mesh_cached;
 	int vertstart = 0, totvert = 0, totpoly = 0, polystart = 0, matstart = 1, defstart = 0;
 	MVert *mv = NULL;
-	MPoly *mp = NULL, *mpoly = NULL;
+	MPoly *mp = NULL, *mpoly = NULL, *ppoly = NULL, *pp = NULL;
 	int i = 0, j = 0;
 	MDeformVert *dvert = NULL;
 
@@ -2461,6 +2462,8 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, Object *ob, bool
 						if (dw->def_nr == l)
 							dw->def_nr = index;
 					}
+
+					//XXX TODO store this on physics mesh too ? to be able to reload it from blend
 				}
 			}
 		}
@@ -2468,7 +2471,8 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, Object *ob, bool
 		defstart += mi->totdef;
 
 		totpoly = mi->physics_mesh->getNumPolys(mi->physics_mesh);
-		for (j = 0, mp = mpoly + polystart; j < totpoly; j++, mp++)
+		ppoly = s->mpoly;
+		for (j = 0, mp = mpoly + polystart, pp = ppoly; j < totpoly; j++, mp++, pp++)
 		{
 			/* material index lookup and correction, avoid having the same material in different slots */
 			int index = GET_INT_FROM_POINTER(BLI_ghash_lookup(fmd->material_index_map,
@@ -2478,6 +2482,9 @@ int BKE_fracture_update_visual_mesh(FractureModifierData *fmd, Object *ob, bool
 				index--;
 
 			mp->mat_nr = index;
+			//store this on physics mesh as well, so for being able to reload it from blend later (without
+			// having a materialmap then)
+			pp->mat_nr = index;
 		}
 
 		/* fortunately we know how many faces "belong" to this meshisland, too */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9286abb..0f2eeb0 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -373,6 +373,22 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_
 	int i;
 	
 	if (addr == NULL) return NULL;
+
+	/* try sorted approach here too, maybe it helps */
+	if (onm->sorted) {
+		OldNew entry_s, *entry = NULL;
+
+		entry_s.old = addr;
+
+		entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
+		if (entry) {
+			if (increase_users)
+				entry->nr++;
+			return entry->newp;
+		}
+
+		return NULL;
+	}
 	
 	if (onm->lasthit < onm->nentries-1) {
 		OldNew *entry = &onm->entries[++onm->lasthit];
@@ -1836,20 +1852,20 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
 
 typedef void (*link_list_cb)(FileData *fd, void *data);
 
-static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback)		/* only direct data */
+static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback, bool increase_lasthit)		/* only direct data */
 {
 	Link *ln, *prev;
 	
 	if (BLI_listbase_is_empty(lb)) return;
 	
-	lb->first = newdataadr(fd, lb->first);
+	lb->first = newdataadr_ex(fd, lb->first, increase_lasthit);
 	if (callback != NULL) {
 		callback(fd, lb->first);
 	}
 	ln = lb->first;
 	prev = NULL;
 	while (ln) {
-		ln->next = newdataadr(fd, ln->next);
+		ln->next = newdataadr_ex(fd, ln->next, increase_lasthit);
 		if (ln->next != NULL && callback != NULL) {
 			callback(fd, ln->next);
 		}
@@ -1862,7 +1878,7 @@ static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback)		/*
 
 static void link_list(FileData *fd, ListBase *lb)		/* only direct data */
 {
-	link_list_ex(fd, lb, NULL);
+	link_list_ex(fd, lb, NULL, true);
 }
 
 static void link_glob_list(FileData *fd, ListBase *lb)		/* for glob data */
@@ -3926,7 +3942,7 @@ static void direct_link_pointcache_cb(FileData *fd, void *data)
 static void direct_link_pointcache(FileData *fd, PointCache *cache)
 {
 	if ((cache->flag & PTCACHE_DISK_CACHE)==0) {
-		link_list_ex(fd, &cache->mem_cache, direct_link_pointcache_cb);
+		link_list_ex(fd, &cache->mem_cache, direct_link_pointcache_cb, true);
 	}
 	else
 		BLI_listbase_clear(&cache->mem_cache);
@@ -5000,9 +5016,11 @@ static void read_meshIsland(FileData *fd, MeshIsland **address)
 	mi->vertices_cached = NULL;
 	mi->vertco = newdataadr(fd, mi->vertco);
 	mi->temp = newdataadr(fd, mi->temp);
+#if 0
 	read_shard(fd, &(mi->temp));
 	mi->physics_mesh = BKE_shard_create_dm(mi->temp, true);
 	BKE_shard_free(mi->temp, true);
+#endif
 	mi->temp = NULL;
 	mi->vertno = newdataadr(fd, mi->vertno);
 
@@ -5179,7 +5197,7 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 		MeshIsland *mi;
 		MVert *mverts;
 		int vertstart = 0;
-		Shard *s;
+		Shard *s, **shards = NULL;
 		int count = 0;
 
 		fm->last_shard_tree = NULL;
@@ -5188,17 +5206,28 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 		if (fmd->fracture_mode == MOD_FRACTURE_PREFRACTURED ||
 		    fmd->fracture_mode == MOD_FRACTURE_EXTERNAL)
 		{
+			/*create temp array for quicker lookups*/
+			int count = 0;
+			int i = 0;
+
 			link_list(fd, &fmd->frac_mesh->shard_map);
+			link_list(fd, &fmd->islandShards);
+			count = BLI_listbase_count(&fmd->frac_mesh->shard_map) + BLI_listbase_count(&fmd->islandShards);
+
+			shards = MEM_callocN(sizeof(Shard*) * count, "readfile shard_lookup_array");
 			for (s = fmd->frac_mesh->shard_map.first; s; s = s->next) {
 				read_shard(fd, &s);
+				shards[i] = s;
+				i++;
 			}
 
 			fmd->dm = NULL;
 			fmd->visible_mesh = NULL;
 
-			link_list(fd, &fmd->islandShards);
 			for (s = fmd->islandShards.first; s; s = s->next) {
 				read_shard(fd, &s);
+				shards[i] = s;
+				i++;
 			}
 
 			link_list(fd, &fmd->meshIslands);
@@ -5232,9 +5261,17 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 			/* re-init cached verts here... */
 			mverts = CDDM_get_verts(fmd->visible_mesh_cached);
 
+			i = 0;
 			for (mi = fmd->meshIslands.first; mi; mi = mi->next) {
-				read_meshIsland(fd, &mi);
-				vertstart += initialize_meshisland(fmd, &mi, mverts, vertstart, ob, -1, -1);
+				Shard *s = NULL;
+				s = shards[i];
+				if (s)
+				{
+					mi->physics_mesh = BKE_shard_create_dm(s, true);
+					read_meshIsland(fd, &mi);
+					vertstart += initialize_meshisland(fmd, &mi, mverts, vertstart, ob, -1, -1);
+				}
+				i++;
 			}
 
 			if (fmd->fracture_mode == MOD_FRACTURE_EXTERNAL)
@@ -5250,19 +5287,23 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 					con->flag |= RBC_FLAG_NEEDS_VALIDATE;
 				}
 			}
+
+			MEM_freeN(shards);
 		}
 		else if (fmd->fracture_mode == MOD_FRACTURE_DYNAMIC && !fd->memfile)
 		{
 			ShardSequence *ssq = NULL;
 			MeshIslandSequence *msq = NULL;
-			fmd->dm = NULL;
 
+			fmd->dm = NULL;
 			link_list(fd, &fmd->shard_sequence);
+
 			for (ssq = fmd->shard_sequence.first; ssq; ssq = ssq->next)
 			{
 				ssq->is_new = false;
 				ssq->frac_mesh = newdataadr(fd, ssq->frac_mesh);
 				link_list(fd, &ssq->frac_mesh->shard_map);
+
 				for (s = ssq->frac_mesh->shard_map.first; s; s = s->next) {
 					read_shard(fd, &s);
 				}
@@ -5289,6 +5330,7 @@ static void load_fracture_modifier(FileData* fd, FractureModifierData *fmd, Obje
 				link_list(fd, &msq->meshIslands);
 				for (mi = msq->meshIslands.first; mi; mi = mi->next) {
 					read_meshIsland(fd, &mi);
+					mi->physics_mesh = BKE_shard_create_dm(sh, true);
 					vertstart += initialize_meshisland(fmd, &mi, mverts, vertstart, ob, sh->parent_id, sh->shard_id);
 					sh = sh->next;
 				}
@@ -8267,6 +8309,9 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a
 		
 		bhead = blo_nextbhead(fd, bhead);
 	}
+
+	qsort(fd->datamap->entries, fd->datamap->nentries, sizeof(OldNew), verg_oldnewmap);
+	fd->datamap->sorted = 1;
 	
 	return bhead;
 }
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 5175b0d..8b2ed9f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1568,19 +1568,22 @@ static void write_shard(WriteData* wd, Shard* s)
 
 static void write_meshIsland(WriteData* wd, MeshIsland* mi)
 {
+#if 0
 	DerivedMesh *dm = mi->physics_mesh;
 	mi->temp = BKE_create_fracture_shard(dm->getVertArray(dm), dm->getPolyArray(dm), dm->getLoopArray(dm),
 	                                        dm->getNumVerts(dm), dm->getNumPolys(dm), dm->getNumLoops(dm), true);
 	mi->temp = BKE_custom_data_to_shard(mi->temp, dm);
-
+#endif
 	writestruct(wd, DATA, "MeshIsland", 1, mi);
 	writedata(wd, DATA, sizeof(float) * 3 * mi->vertex_count, mi->vertco);
+#if 0
 	/* write derivedmesh as shard... */
 	mi->temp->next = NULL;
 	mi->temp->prev = NULL;
 	write_shard(wd, mi->temp);
 	BKE_shard_free(mi->temp, true);
 	mi->temp = NULL;
+#endif
 
 	writedata(wd, DATA, sizeof(short) * 3 * mi->vertex_count, mi->vertno);




More information about the Bf-blender-cvs mailing list