[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [10911] trunk/blender/source/blender: == Multires ==

Nicholas Bishop nicholasbishop at gmail.com
Sun Jun 10 23:51:11 CEST 2007


Revision: 10911
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=10911
Author:   nicholasbishop
Date:     2007-06-10 23:51:11 +0200 (Sun, 10 Jun 2007)

Log Message:
-----------
== Multires ==

* Small optimization to multires based on profiling data; calculation of edge boudndaries is now cached along with multires mapping data to improve the performance of the catmull-clark code.

* Removed an unneeded call to create the temporary data when loading files.

Modified Paths:
--------------
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/include/multires.h
    trunk/blender/source/blender/makesdna/DNA_meshdata_types.h
    trunk/blender/source/blender/src/multires.c

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2007-06-10 17:28:21 UTC (rev 10910)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2007-06-10 21:51:11 UTC (rev 10911)
@@ -2562,9 +2562,6 @@
 			lvl->faces= newdataadr(fd, lvl->faces);
 			lvl->edges= newdataadr(fd, lvl->edges);
 			lvl->colfaces= newdataadr(fd, lvl->colfaces);
-
-			/* Recalculating the maps is faster than reading them from the file */
-			multires_calc_level_maps(lvl);
 		}
 	}
 	

Modified: trunk/blender/source/blender/include/multires.h
===================================================================
--- trunk/blender/source/blender/include/multires.h	2007-06-10 17:28:21 UTC (rev 10910)
+++ trunk/blender/source/blender/include/multires.h	2007-06-10 21:51:11 UTC (rev 10911)
@@ -60,7 +60,6 @@
 void multires_set_level(struct Object *ob, struct Mesh *me, const int render);
 void multires_update_levels(struct Mesh *me, const int render);
 void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render);
-void multires_calc_level_maps(struct MultiresLevel *lvl);
 void multires_edge_level_update(void *ob, void *me);
 int multires_modifier_warning();
 

Modified: trunk/blender/source/blender/makesdna/DNA_meshdata_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_meshdata_types.h	2007-06-10 17:28:21 UTC (rev 10910)
+++ trunk/blender/source/blender/makesdna/DNA_meshdata_types.h	2007-06-10 21:51:11 UTC (rev 10911)
@@ -123,6 +123,9 @@
 	MultiresFace *faces;
 	MultiresColFace *colfaces;
 	MultiresEdge *edges;
+
+	/* Temporary connectivity data */
+	char *edge_boundary_states;
 	struct ListBase *vert_edge_map;
 	struct ListBase *vert_face_map;
 	struct MultiresMapNode *map_mem;

Modified: trunk/blender/source/blender/src/multires.c
===================================================================
--- trunk/blender/source/blender/src/multires.c	2007-06-10 17:28:21 UTC (rev 10910)
+++ trunk/blender/source/blender/src/multires.c	2007-06-10 21:51:11 UTC (rev 10911)
@@ -80,6 +80,8 @@
 
 const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT;
 
+void multires_calc_temp_data(struct MultiresLevel *lvl);
+
 int multires_test()
 {
 	Mesh *me= get_mesh(OBACT);
@@ -138,34 +140,11 @@
 	out[2]= (v1[2]+v2[2]+v3[2]+v4[2])/4;
 }
 
-short multires_edge_is_boundary(MultiresLevel *lvl, unsigned e)
-{
-	MultiresMapNode *n1= lvl->vert_face_map[lvl->edges[e].v[0]].first;
-	unsigned total= 0;
-
-	while(n1) {
-		MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[e].v[1]].first;
-		while(n2) {
-			if(n1->Index == n2->Index) {
-				++total;
-
-				if(total > 1)
-					return 0;
-			}
-
-			n2= n2->next;
-		}
-		n1= n1->next;
-	}
-
-	return 1;
-}
-
 short multires_vert_is_boundary(MultiresLevel *lvl, unsigned v)
 {
 	MultiresMapNode *node= lvl->vert_edge_map[v].first;
 	while(node) {
-		if(multires_edge_is_boundary(lvl,node->Index))
+		if(lvl->edge_boundary_states[node->Index])
 			return 1;
 		node= node->next;
 	}
@@ -324,7 +303,7 @@
 		const MultiresEdge *e= &lvl->edges[n1->Index];
 		const unsigned end= e->v[0]==i ? e->v[1] : e->v[0];
 		
-		if(multires_edge_is_boundary(lvl,n1->Index)) {
+		if(lvl->edge_boundary_states[n1->Index]) {
 			for(j=0; j<3; ++j)
 				out[j]+= get_float(array,end,j,stride);
 			++count;
@@ -638,6 +617,7 @@
 		lvl->faces= MEM_dupallocN(orig->faces);
 		lvl->colfaces= MEM_dupallocN(orig->colfaces);
 		lvl->edges= MEM_dupallocN(orig->edges);
+		lvl->edge_boundary_states = NULL;
 		lvl->vert_edge_map= lvl->vert_face_map= NULL;
 		lvl->map_mem= NULL;
 		
@@ -698,14 +678,16 @@
 	}
 }
 
-/* Free and clear the vert-edge-face maps */
-void multires_free_maps(MultiresLevel *lvl)
+/* Free and clear the temporary connectivity data */
+void multires_free_temp_data(MultiresLevel *lvl)
 {
 	if(lvl) {
+		if(lvl->edge_boundary_states) MEM_freeN(lvl->edge_boundary_states);
 		if(lvl->vert_edge_map) MEM_freeN(lvl->vert_edge_map);
 		if(lvl->vert_face_map) MEM_freeN(lvl->vert_face_map);
 		if(lvl->map_mem) MEM_freeN(lvl->map_mem);
 
+		lvl->edge_boundary_states = NULL;
 		lvl->vert_edge_map = lvl->vert_face_map = NULL;
 		lvl->map_mem = NULL;
 	}
@@ -719,7 +701,7 @@
 		if(lvl->edges) MEM_freeN(lvl->edges);
 		if(lvl->colfaces) MEM_freeN(lvl->colfaces);
 		
-		multires_free_maps(lvl);
+		multires_free_temp_data(lvl);
 	}
 }
 
@@ -888,7 +870,7 @@
 		lvl->prev->faces[i].mid= lvl->prev->totvert + lvl->prev->totedge + i;
 	}
 
-	multires_calc_level_maps(lvl->prev);
+	multires_calc_temp_data(lvl->prev);
 
 	/* Create faces
 	   ============ */
@@ -960,7 +942,7 @@
 	if(G.scene->toolsettings->multires_subdiv_type == 0) {
 		for(i=0; i<lvl->prev->totedge; ++i) {
 			const MultiresEdge *e= &lvl->prev->edges[i];
-			data.boundary= multires_edge_is_boundary(lvl->prev,i);
+			data.boundary= lvl->prev->edge_boundary_states[i];
 			edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e);
 			data.endpoint1= oldverts[e->v[0]].co;
 			data.endpoint2= oldverts[e->v[1]].co;
@@ -983,7 +965,7 @@
 		}
 	}
 
-	multires_free_maps(lvl->prev);
+	multires_free_temp_data(lvl->prev);
 	MEM_freeN(oldverts);
 
 	/* Vertex Colors
@@ -1393,7 +1375,7 @@
 	pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
 	cr_lvl= pr_lvl->next;
 	while(cr_lvl) {
-		multires_calc_level_maps(pr_lvl);
+		multires_calc_temp_data(pr_lvl);
 
 		/* Swap the old/new deltas */
 		swap_deltas= pr_deltas;
@@ -1417,7 +1399,7 @@
 
 		for(i=0; i<pr_lvl->totedge; ++i) {
 			const MultiresEdge *e= &pr_lvl->edges[i];
-			data.boundary= multires_edge_is_boundary(pr_lvl,i);
+			data.boundary= pr_lvl->edge_boundary_states[i];
 			edge_face_neighbor_midpoints_accum(&data,pr_lvl,cr_deltas,sizeof(vec3f),e);
 			data.endpoint1= &pr_deltas[e->v[0]].x;
 			data.endpoint2= &pr_deltas[e->v[1]].x;
@@ -1447,7 +1429,7 @@
 				&cr_deltas[i].x);			
 		}
 
-		multires_free_maps(pr_lvl);
+		multires_free_temp_data(pr_lvl);
 
 		pr_lvl= pr_lvl->next;
 		cr_lvl= cr_lvl->next;
@@ -1573,14 +1555,15 @@
 	multires_update_colors(me);
 }
 
-void multires_calc_level_maps(MultiresLevel *lvl)
+void multires_calc_temp_data(MultiresLevel *lvl)
 {
-	unsigned i,j;
+	unsigned i, j, emax;
 	MultiresMapNode *indexnode= NULL;
-	
+
 	lvl->map_mem= MEM_mallocN(sizeof(MultiresMapNode)*(lvl->totedge*2 + lvl->totface*4), "map_mem");
 	indexnode= lvl->map_mem;
 	
+	/* edge map */
 	lvl->vert_edge_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_edge_map");
 	for(i=0; i<lvl->totedge; ++i) {
 		for(j=0; j<2; ++j, ++indexnode) {
@@ -1589,6 +1572,7 @@
 		}
 	}
 
+	/* face map */
        	lvl->vert_face_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_face_map");
 	for(i=0; i<lvl->totface; ++i){
 		for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j, ++indexnode) {
@@ -1596,6 +1580,32 @@
 			BLI_addtail(&lvl->vert_face_map[lvl->faces[i].v[j]], indexnode);
 		}
 	}
+
+	/* edge boundaries */
+	emax = (lvl->prev ? (lvl->prev->totedge * 2) : lvl->totedge);
+	lvl->edge_boundary_states= MEM_callocN(sizeof(char)*lvl->totedge, "edge_boundary_states");
+	for(i=0; i<emax; ++i) {
+		MultiresMapNode *n1= lvl->vert_face_map[lvl->edges[i].v[0]].first;
+		unsigned total= 0;
+		
+		lvl->edge_boundary_states[i] = 1;
+		while(n1 && lvl->edge_boundary_states[i] == 1) {
+			MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[i].v[1]].first;
+			while(n2) {
+				if(n1->Index == n2->Index) {
+					++total;
+					
+					if(total > 1) {
+						lvl->edge_boundary_states[i] = 0;
+						break;
+					}
+				}
+				
+				n2= n2->next;
+			}
+			n1= n1->next;
+		}
+	}
 }
 
 void multires_edge_level_update(void *ob, void *me_v)





More information about the Bf-blender-cvs mailing list