[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16304] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Minor refactoring to simplify code and reduce the number of allocations for LampRens .

Davide Vercelli davide.vercelli at gmail.com
Fri Aug 29 22:10:18 CEST 2008


Revision: 16304
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16304
Author:   unclezeiv
Date:     2008-08-29 22:09:25 +0200 (Fri, 29 Aug 2008)

Log Message:
-----------
Minor refactoring to simplify code and reduce the number of allocations for LampRens. It also fixes a bug that could cause crashes when creating the mesh to visualize vpl placement.

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c

Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-08-29 14:19:34 UTC (rev 16303)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-08-29 20:09:25 UTC (rev 16304)
@@ -176,10 +176,12 @@
 
 typedef struct LightcutsData {
 	/* NOTE: conservative space estimation */
-	ListBase pointlights;
+	LampRen **pointlights;
+	LampRen *lampren_pool;
 
 	LightcutsTree trees[_TREES_SIZE];
 
+	int pool_counter;
 	int light_counter;
 	int vpl_counter;
 
@@ -411,21 +413,22 @@
 	}
 }
 
-static void lightcuts_fill_array(ListBase *pointlights, LightcutsTree *tree, int cur_type, float *colw)
+static void lightcuts_fill_array(LightcutsData *lcd, int cur_type)
 {
-	GroupObject *go;
 	LampRen *lar;
 	LightcutsCluster *clus;
+	LightcutsTree *tree= &lcd->trees[cur_type];
+	float *colw= lcd->colw;
+	int i;
 
 	tree->array= MEM_callocN(sizeof(LightcutsCluster) * tree->counter * 2, array_names[cur_type]);
 	tree->free= 0;
 
 	clus= tree->array;
 
-	for(go = pointlights->first; go; go = go->next) {
-		lar = go->lampren;
-		if (lar==NULL) continue;
-
+	for(i= 0; i < lcd->light_counter; i++) {
+		lar = lcd->pointlights[i];
+		
 		if (lar->type!=cur_type)
 			continue;
 
@@ -869,7 +872,6 @@
 static void lamp_delete(LampRen * lar)
 {
 	MEM_freeN(lar->shadsamp);
-	MEM_freeN(lar);
 }
 
 static void create_lamp_oriented(Render * re, LampRen * lar, LampRen * orig)
@@ -898,7 +900,6 @@
 
 static void convert_environment_map(Render *re, LightcutsData *lcd, int n, float fac)
 {
-	GroupObject *gonew;
 	LampRen *lar;
 	int k, kk, i;
 	float t, p, phi, phirad, st;
@@ -945,19 +946,8 @@
 		/* XXX: arbitrary limit */
 		if (INPR(lcd->colw, col) < LC_LUMINOSITY_LIMIT)
 			continue;
-		
-		gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
-		BLI_addtail(&lcd->pointlights, gonew);
-		/* gonew->recalc= go->recalc; // XXX: what is this? */
-		/*
-		 * XXX: probably wrong, more a test to see if it is used somewhere
-		 * or deallocated
-		 * The point here is that we create new lights with no corresponding
-		 * objects... do we need objects there?
-		 */
-		gonew->ob= 0;
-		
-		lar = (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+				
+		lar = &lcd->lampren_pool[lcd->pool_counter++];
 		lamp_init(re, lar);
 		lar->type = LA_SUN;
 		
@@ -1000,12 +990,8 @@
 			continue;
 		}
 
-		BLI_addtail(&re->lampren, lar);
-		/* check deallocation */
-		gonew->lampren= lar;
-
+		lcd->pointlights[lcd->light_counter++]= lar;
 		lcd->trees[TREE_SUN].counter++;
-		lcd->light_counter++;
 		lar->ray_samp_method = LA_SAMP_CONSTANT;
 	}
 }
@@ -1336,7 +1322,6 @@
 
 static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen *orig, float *col, int lev)
 {
-	GroupObject *go;
 	LampRen *lar;
 	VlakRen *vla;
 	Isect isec;
@@ -1406,7 +1391,7 @@
 	}
 #endif
 	
-	lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+	lar= &lcd->lampren_pool[lcd->pool_counter++];
 	lamp_init(re, lar);
 	lar->dist= lcd->indir_dist;
 	lar->distkw= lar->dist * lar->dist;
@@ -1446,16 +1431,9 @@
 	
 	if (lcd->options & LC_OPT_INDIR_MESH)
 		VECCOPY(lcd->dbg_vis_vpl + 3 * lcd->vpl_counter, co);
-	
-	/* XXX: see remarks on similar code in convert_environment_map */
-	go= MEM_callocN(sizeof(GroupObject), "groupobject");
-	BLI_addtail(&lcd->pointlights, go);
-	go->ob= 0;
-	BLI_addtail(&re->lampren, lar);
-	go->lampren= lar;
 
+	lcd->pointlights[lcd->light_counter++]= lar;
 	lcd->trees[TREE_SPOT].counter++;
-	lcd->light_counter++;
 	lcd->vpl_counter++;
 	
 	if (lev > 0)
@@ -1469,7 +1447,6 @@
 
 static void convert_area_light(Render * re, LightcutsData *lcd, LampRen *orig)
 {
-	GroupObject *go;
 	LampRen *lar;
 	float factor, area;
 	float xdir[3], ydir[3], col[3];
@@ -1536,12 +1513,7 @@
 		if (INPR(lcd->colw, col) < LC_LUMINOSITY_LIMIT)
 			continue;
 		
-		/* XXX: see remarks on similar code in convert_environment_map */
-		go= MEM_callocN(sizeof(GroupObject), "groupobject");
-		BLI_addtail(&lcd->pointlights, go);
-		go->ob= 0;
-		
-		lar = (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+		lar= &lcd->lampren_pool[lcd->pool_counter++];
 
 		create_lamp_oriented(re, lar, orig);
 		
@@ -1564,13 +1536,9 @@
 			lamp_delete(lar);
 			continue;
 		}
-		
-		BLI_addtail(&re->lampren, lar);
-		/* check deallocation */
-		go->lampren= lar;
 
+		lcd->pointlights[lcd->light_counter++]= lar;
 		lcd->trees[TREE_SPOT].counter++;
-		lcd->light_counter++;
 		lar->ray_samp_method = LA_SAMP_CONSTANT;
 	}
 }
@@ -1578,9 +1546,8 @@
 void lightcuts_init(Render * re)
 {
 	LightcutsData *lcd;
-	GroupObject *go, *gonew;
+	GroupObject *go;
 	ListBase *lights = &re->lights;
-	ListBase *pointlights;
 	LampRen *lar;
 	char tree_time_str[12]; /* length 12 required by BLI_timestr */
 	int i;
@@ -1590,7 +1557,6 @@
 	
 	/* initialize LightcutsData */
 	re->lcdata = lcd = MEM_callocN(sizeof(LightcutsData), "LightcutsData");
-	pointlights= &lcd->pointlights;
 	lcd->indir_fac= re->r.lightcuts_indir_fac;
 	lcd->indir_dist= re->r.lightcuts_indir_dist;
 	lcd->do_indir= re->r.lightcuts_indirect;
@@ -1633,23 +1599,35 @@
 	else if (lcd->options & LC_OPT_ENV_LIGHT && re->r.lightcuts_env_map > 0)
 		R= *re;
 	
-	if (lcd->options & LC_OPT_INDIR_MESH) {
-		/* allocate array to hold coordinates for all possible virtual point lights */
-		int max_vpl;
-		int nlights= 0;
+	{
+		int n_orig= 0;
+		int n_vpl= 0;
+		int n_generated= re->r.lightcuts_area_lights + re->r.lightcuts_env_map; 
 		
 		for(go=lights->first; go; go= go->next) {
 			lar= go->lampren;
 			if(lar==NULL) continue;
 			
 			if (ELEM3(lar->type, LA_LOCAL, LA_SUN, LA_SPOT))
-				nlights++;
+				n_orig++;
 		}
 		
-		max_vpl= (nlights + re->r.lightcuts_area_lights + re->r.lightcuts_env_map) * lcd->do_indir;
+		if (lcd->do_indir > 0) {
+			n_vpl= (n_orig + n_generated) * lcd->do_indir;
+			
+			if (lcd->options & LC_OPT_2ND_BOUNCE)
+				n_vpl += n_vpl * lcd->do_indir;
+			
+			/* allocate array to hold coordinates for all possible virtual point lights */
+			if (lcd->options & LC_OPT_INDIR_MESH && n_vpl != 0)
+				lcd->dbg_vis_vpl= MEM_callocN(sizeof(float) * 3 * n_vpl, "lc_vpl_visualization");
+			
+			n_generated+= n_vpl;
+		}
 		
-		if (max_vpl != 0)
-			lcd->dbg_vis_vpl= MEM_callocN(sizeof(float) * 3 * max_vpl, "lc_vpl_visualization");
+		/* here we create our (conservative) arrays for holding LampRens and pointers to them */
+		lcd->pointlights= MEM_callocN(sizeof(LampRen*) * n_generated, "lc_pointlights");
+		lcd->lampren_pool= MEM_callocN(sizeof(LampRen) * n_generated, "lc_lampren_pool");
 	}
 	
 	/* TODO: we could do some form of importance sampling here */
@@ -1693,14 +1671,7 @@
 			if (lcd->options & LC_OPT_ONLY_INDIR)
 				continue;
 		}
-
-		/* first copy the initial light */
-		gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
-		BLI_addtail(pointlights, gonew);
-		gonew->lampren= lar;
-		gonew->ob= 0;
-		gonew->recalc= go->recalc;
-
+		
 		switch (lar->type) {
 		case LA_LOCAL:
 			lcd->trees[TREE_LOCAL].counter++;
@@ -1715,9 +1686,10 @@
 		default:
 			continue;
 		}
+		
+		/* this kind of lights are not part of our pool */
+		lcd->pointlights[lcd->light_counter++]= lar;
 
-		lcd->light_counter++;
-
 		/*
 		 * each light will contribute only marginally to the shadowing
 		 * that's why here I set a simpler sampling method
@@ -1737,7 +1709,7 @@
 	/* build light trees */
 	for (i= 0; i < _TREES_SIZE; i++) {
 		if (lcd->trees[i].counter > 0) {
-			lightcuts_fill_array(pointlights, &lcd->trees[i], i, lcd->colw);
+			lightcuts_fill_array(lcd, i);
 			printf("Lightcuts: building %s tree - ", tree_names[i]);
 			lightcuts_build_tree2(lcd, i);
 		}
@@ -2458,7 +2430,10 @@
 		for (i= 0; i < _TREES_SIZE; i++)
 			if (lcd->trees[i].array)
 				MEM_freeN(lcd->trees[i].array);
-		BLI_freelistN(&lcd->pointlights);
+		for (i= 0; i < lcd->pool_counter; i++)
+			lamp_delete(&lcd->lampren_pool[i]);
+		MEM_freeN(lcd->lampren_pool);
+		MEM_freeN(lcd->pointlights);
 		MEM_freeN(lcd->cut_nodes);
 		if (lcd->dbg_vis_vpl)
 			MEM_freeN(lcd->dbg_vis_vpl);





More information about the Bf-blender-cvs mailing list