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