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);


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to