[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