svn merge ^/trunk/blender -r42009:42053
[blender.git] / source / blender / editors / object / object_bake.c
index 07c006a..0d3d732 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -56,6 +54,7 @@
 #include "BLI_math_geom.h"
 
 #include "BKE_blender.h"
+#include "BKE_screen.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
@@ -154,8 +153,13 @@ typedef struct {
        float height_min, height_max;
        Image *ima;
        DerivedMesh *ssdm;
+       const int *origindex;
 } MHeightBakeData;
 
+typedef struct {
+       const int *origindex;
+} MNormalBakeData;
+
 static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
 {
        unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2,
@@ -360,6 +364,16 @@ static int multiresbake_test_break(MultiresBakeRender *bkr)
 static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
                              MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
 {
+#if 1 // BMESH_TODO
+       (void)bkr;
+       (void)ima;
+       (void)passKnownData;
+       (void)initBakeData;
+       (void)applyBakeData;
+       (void)freeBakeData;
+
+       printf("BMESH_TODO" AT "\n");
+#else
        DerivedMesh *dm= bkr->lores_dm;
        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
        const int lvl= bkr->lvl;
@@ -442,6 +456,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData
                if(freeBakeData)
                        freeBakeData(data.bake_data);
        }
+#endif // BMESH_TODO
 }
 
 static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
@@ -502,8 +517,19 @@ static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, f
        interp_bilinear_quad_data(data, u, v, res);
 }
 
-static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,  const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
+static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *origindex,  const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
 {
+#if 1 // BMESH_TODO
+       (void)lodm;
+       (void)hidm;
+       (void)origindex;
+       (void)lvl;
+       (void)face_index;
+       (void)u;
+       (void)v;
+       (void)co;
+       (void)n;
+#else
        MFace mface;
        DMGridData **grid_data;
        float crn_x, crn_y;
@@ -522,9 +548,8 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,  const int lvl,
                g_index= grid_offset[face_index];
                S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y);
        } else {
-               const int *index= lodm->getFaceDataArray(lodm, CD_ORIGINDEX);
                int side= (1 << (lvl-1)) + 1;
-               int grid_index= index[face_index];
+               int grid_index= origindex[face_index];
                int loc_offs= face_index % (1<<(2*lvl));
                int cell_index= loc_offs % ((side-1)*(side-1));
                int cell_side= grid_size / (side-1);
@@ -546,6 +571,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,  const int lvl,
 
        if(co != NULL)
                interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co);
+#endif
 }
 
 /* mode = 0: interpolate normals,
@@ -588,10 +614,11 @@ static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float
        interp_barycentric_tri_data(data, u, v, res);
 }
 
-static void *init_heights_data(MultiresBakeRender *bkr, Imageima)
+static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
 {
        MHeightBakeData *height_data;
        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       DerivedMesh *lodm= bkr->lores_dm;
 
        height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
 
@@ -615,9 +642,23 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image* ima)
                height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
        }
 
+       height_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+
        return (void*)height_data;
 }
 
+static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+{
+       MNormalBakeData *normal_data;
+       DerivedMesh *lodm= bkr->lores_dm;
+
+       normal_data= MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
+
+       normal_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+
+       return (void*)normal_data;
+}
+
 static void apply_heights_data(void *bake_data)
 {
        MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
@@ -675,6 +716,16 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
                                    const int face_index, const int lvl, const float st[2],
                                    float UNUSED(tangmat[3][3]), const int x, const int y)
 {
+#if 1 // BMESH_TODO
+       (void)lores_dm;
+       (void)hires_dm;
+       (void)bake_data;
+       (void)face_index;
+       (void)lvl;
+       (void)st;
+       (void)x;
+       (void)y;
+#else
        MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
        MFace mface;
        Image *ima= mtface[face_index].tpage;
@@ -699,13 +750,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
        CLAMP(uv[0], 0.0f, 1.0f);
        CLAMP(uv[1], 0.0f, 1.0f);
 
-       get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], p1, 0);
+       get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0);
 
        if(height_data->ssdm) {
-               //get_ccgdm_data_ss(lores_dm, height_data->ssdm, lvl, face_index, uv[0], uv[1], p0, n);
-               get_ccgdm_data(lores_dm, height_data->ssdm, 0, face_index, uv[0], uv[1], p0, n);
+               get_ccgdm_data(lores_dm, height_data->ssdm, height_data->origindex, 0, face_index, uv[0], uv[1], p0, n);
        } else {
-               MFace mface;
                lores_dm->getFace(lores_dm, face_index, &mface);
 
                if(mface.v4) {
@@ -718,7 +767,6 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
        }
 
        sub_v3_v3v3(vec, p1, p0);
-       //len= len_v3(vec);
        len= dot_v3v3(n, vec);
 
        height_data->heights[pixel]= len;
@@ -734,6 +782,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
                char *rrgb= (char*)ibuf->rect + pixel*4;
                rrgb[3]= 255;
        }
+#endif // BMESH_TODO
 }
 
 /* MultiresBake callback for normals' baking
@@ -741,14 +790,26 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
      - find coord and normal of point with specified UV in hi-res mesh
      - multiply it by tangmat
      - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
-static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data),
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
                                    const int face_index, const int lvl, const float st[2],
                                    float tangmat[3][3], const int x, const int y)
 {
+#if 1 // BMESH_TODO
+       (void)lores_dm;
+       (void)hires_dm;
+       (void)bake_data;
+       (void)face_index;
+       (void)lvl;
+       (void)st;
+       (void)tangmat;
+       (void)y;
+       (void)x;
+#else
        MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
        MFace mface;
        Image *ima= mtface[face_index].tpage;
        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+       MNormalBakeData *normal_data= (MNormalBakeData*)bake_data;
        float uv[2], *st0, *st1, *st2, *st3;
        int pixel= ibuf->x*y + x;
        float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5};
@@ -768,7 +829,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
        CLAMP(uv[0], 0.0f, 1.0f);
        CLAMP(uv[1], 0.0f, 1.0f);
 
-       get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n);
+       get_ccgdm_data(lores_dm, hires_dm, normal_data->origindex, lvl, face_index, uv[0], uv[1], NULL, n);
 
        mul_v3_m3v3(vec, tangmat, n);
        normalize_v3(vec);
@@ -790,6 +851,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
                rrgb[2]= FTOCHAR(vec[2]);
                rrgb[3]= 255;
        }
+#endif
 }
 
 static void count_images(MultiresBakeRender *bkr)
@@ -833,7 +895,7 @@ static void bake_images(MultiresBakeRender *bkr)
 
                        switch(bkr->mode) {
                                case RE_BAKE_NORMALS:
-                                       do_multires_bake(bkr, ima, apply_tangmat_callback, NULL, NULL, NULL);
+                                       do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, NULL);
                                        break;
                                case RE_BAKE_DISPLACEMENT:
                                        do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
@@ -883,7 +945,8 @@ static void multiresbake_start(MultiresBakeRender *bkr)
        finish_images(bkr);
 }
 
-static int multiresbake_check(bContext *C, wmOperator *op) {
+static int multiresbake_check(bContext *C, wmOperator *op)
+{
        Scene *scene= CTX_data_scene(C);
        Object *ob;
        Mesh *me;
@@ -970,12 +1033,11 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
        MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
        Mesh *me= (Mesh*)ob->data;
 
-       if(ob->mode==OB_MODE_SCULPT) *lvl= mmd->sculptlvl;
-       else *lvl= mmd->lvl;
+       *lvl= mmd->lvl;
 
        if(*lvl==0) {
                DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob);
-               dm= CDDM_copy(tmp_dm);
+               dm= CDDM_copy(tmp_dm, 0);
                tmp_dm->release(tmp_dm);
        } else {
                MultiresModifierData tmp_mmd= *mmd;
@@ -1001,6 +1063,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
        *simple= mmd->simple;
 
        tmp_mmd.lvl= mmd->totlvl;
+       tmp_mmd.sculptlvl= mmd->totlvl;
        dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
        cddm->release(cddm);
 
@@ -1022,7 +1085,7 @@ static void clear_images(MTFace *mtface, int totface)
                if((ima->id.flag&LIB_DOIT)==0) {
                        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
 
-                       IMB_rectfill(ibuf, (ibuf->depth == 32) ? vec_alpha : vec_solid);
+                       IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
                        ima->id.flag|= LIB_DOIT;
                }
        }
@@ -1203,24 +1266,6 @@ static int thread_break(void *UNUSED(arg))
        return G.afbreek;
 }
 
-static ScrArea *biggest_image_area(bScreen *screen)
-{
-       ScrArea *sa, *big= NULL;
-       int size, maxsize= 0;
-
-       for(sa= screen->areabase.first; sa; sa= sa->next) {
-               if(sa->spacetype==SPACE_IMAGE) {
-                       size= sa->winx*sa->winy;
-                       if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
-                               maxsize= size;
-                               big= sa;
-                       }
-               }
-       }
-       return big;
-}
-
-
 typedef struct BakeRender {
        Render *re;
        Main *main;
@@ -1271,7 +1316,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
        /* get editmode results */
        ED_object_exit_editmode(C, 0);  /* 0 = does not exit editmode */
 
-       bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */
+       bkr->sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_IMAGE, 10); /* can be NULL */
        bkr->main= CTX_data_main(C);
        bkr->scene= scene;
        bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;