Fix for bug #7936: render baking selected to active now has a Bias
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 18 Feb 2008 18:14:19 +0000 (18:14 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 18 Feb 2008 18:14:19 +0000 (18:14 +0000)
value that is an offset along the normal when looking for the nearest
face, which allows baking faces further away, e.g. an ID badge onto a
shirt.

Also fixes a bug baking to float images, for things other than
displacement it didn't work sometimes, and a memory leak in the
extend filter.

source/blender/imbuf/intern/filter.c
source/blender/makesdna/DNA_scene_types.h
source/blender/render/intern/source/rendercore.c
source/blender/src/buttons_scene.c

index 6c82a1e24a7c830d5ae71c9bf88aae013866b5bc..156e26fd5d6adc09ce2f65db6b2711de59ccecd1 100644 (file)
@@ -299,6 +299,8 @@ void IMB_filter_extend(struct ImBuf *ibuf)
                                }
                        }
                }
+
+               MEM_freeN(temprect);
        }
        else if(ibuf->rect) {
                int *temprect;
index aa96d5d68202418df5936d44296de1921612cc6b..67126c502336cdfd461c1cb3bc28909ba7e4391e 100644 (file)
@@ -273,7 +273,7 @@ typedef struct RenderData {
        /* Bake Render options */
        short bake_osa, bake_filter, bake_mode, bake_flag;
        short bake_normal_space, bpad;
-       float bake_maxdist;
+       float bake_maxdist, bake_biasdist, bake_pad;
        
        /* yafray: global panel params. TODO: move elsewhere */
        short GIquality, GIcache, GImethod, GIphotons, GIdirect;
index da468e66d48fa22b2a7a571d77e0a33e5be516fc..051f9ed4e89d3ee00c9de672ebf8c854a7aeb810 100644 (file)
@@ -1889,26 +1889,26 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int
                }
        }
        
-       if(bs->rect) {
+       if(bs->rect_float) {
+               float *col= bs->rect_float + 4*(bs->rectx*y + x);
+               VECCOPY(col, shr.combined);
+               col[3]= 1.0f;
+       }
+       else {
                char *col= (char *)(bs->rect + bs->rectx*y + x);
                col[0]= FTOCHAR(shr.combined[0]);
                col[1]= FTOCHAR(shr.combined[1]);
                col[2]= FTOCHAR(shr.combined[2]);
                col[3]= 255;
        }
-       else {
-               float *col= bs->rect_float + 4*(bs->rectx*y + x);
-               VECCOPY(col, shr.combined);
-               col[3]= 1.0f;
-       }
 }
 
-static void bake_displacement(void *handle, ShadeInput *shi, Isect *isec, int dir, int x, int y)
+static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y)
 {
        BakeShade *bs= handle;
        float disp;
        
-       disp = 0.5 + (isec->labda*VecLength(isec->vec) * -dir);
+       disp = 0.5 + dist;
        
        if(bs->rect_float) {
                float *col= bs->rect_float + 4*(bs->rectx*y + x);
@@ -1933,7 +1933,7 @@ static int bake_check_intersect(Isect *is, int ob, RayFace *face)
        return (R.objectinstance[ob].obr->ob != bs->actob);
 }
 
-static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco)
+static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
 {
        float maxdist;
        int hit;
@@ -1942,7 +1942,9 @@ static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float
        if(R.r.bake_maxdist > 0.0f)
                maxdist= R.r.bake_maxdist;
        else
-               maxdist= RE_ray_tree_max_size(R.raytree);
+               maxdist= RE_ray_tree_max_size(R.raytree) + R.r.bake_biasdist;
+       
+       VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
 
        isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
        isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
@@ -1953,6 +1955,8 @@ static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float
                hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
                hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
                hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
+
+               *dist= VecLenf(start, hitco);
        }
 
        return hit;
@@ -2007,7 +2011,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
        /* if we are doing selected to active baking, find point on other face */
        if(bs->actob) {
                Isect isec, minisec;
-               float co[3], minco[3];
+               float co[3], minco[3], dist, mindist=0.0f;
                int hit, sign, dir=1;
                
                /* intersect with ray going forward and backward*/
@@ -2019,15 +2023,15 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
                
                for(sign=-1; sign<=1; sign+=2) {
                        memset(&isec, 0, sizeof(isec));
-                       VECCOPY(isec.start, shi->co);
                        isec.mode= RE_RAY_MIRROR;
                        isec.faceorig= (RayFace*)vlr;
                        isec.oborig= RAY_OBJECT_SET(&R, obi);
                        isec.userdata= bs;
                        
-                       if(bake_intersect_tree(R.raytree, &isec, shi->vn, sign, co)) {
+                       if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
                                if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
                                        minisec= isec;
+                                       mindist= dist;
                                        VECCOPY(minco, co);
                                        hit= 1;
                                        dir = sign;
@@ -2036,7 +2040,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
                }
 
                if (hit && bs->type==RE_BAKE_DISPLACEMENT) {;
-                       bake_displacement(handle, shi, &minisec, dir, x, y);
+                       bake_displacement(handle, shi, mindist, x, y);
                        return;
                }
 
@@ -2249,7 +2253,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
                        for(a=0; a<re->r.bake_filter; a++)
                                IMB_filter_extend(ibuf);
                        ibuf->userflags |= IB_BITMAPDIRTY;
-                       
                        if (ibuf->rect_float) IMB_rect_from_float(ibuf);
                }
        }
index 9c81c5a5fb7e0e423eeda442724e799c7814f46d..a16f0e642d5e12bf596af516d6093d53091ef0f8 100644 (file)
@@ -2075,12 +2075,13 @@ static void render_panel_bake(void)
 
        uiBlockBeginAlign(block);
        uiDefButBitS(block, TOG, R_BAKE_TO_ACTIVE, B_DIFF, "Selected to Active", 10,120,190,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Bake shading on the surface of selected objects to the active object");
-       uiDefButF(block, NUM, B_DIFF, "Dist:", 10,100,(G.scene->r.bake_mode == RE_BAKE_NORMALS)? 95: 190,20,&G.scene->r.bake_maxdist, 0.0, 10.0, 1, 0, "Maximum distance from active object to other object");
+       uiDefButF(block, NUM, B_DIFF, "Dist:", 10,100,95,20,&G.scene->r.bake_maxdist, 0.0, 10.0, 1, 0, "Maximum distance from active object to other object");
+       uiDefButF(block, NUM, B_DIFF, "Bias:", 105,100,95,20,&G.scene->r.bake_biasdist, 0.0, 10.0, 1, 0, "Bias towards faces further away from the object");
+       uiBlockEndAlign(block);
 
        if(G.scene->r.bake_mode == RE_BAKE_NORMALS)
                uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3", 
-                       105,100,95,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
-       uiBlockEndAlign(block);
+                       10,70,190,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
 
 #if 0  
        uiBlockBeginAlign(block);