merge with/from trunk at r35190
[blender.git] / source / blender / blenkernel / intern / multires.c
index 29726ccbc990094ae27b58ddf133f9538eecc264..f2c5a9cbf37e2937bb57c24dc613e29c70ce6ca0 100644 (file)
@@ -47,6 +47,7 @@
 #include "BKE_paint.h"
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
+#include "BKE_tessmesh.h"
 
 #include "BKE_object.h"
 
@@ -72,7 +73,7 @@ DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob
 
        dm = mti->applyModifier(md, ob, tdm, 0, 1);
        if (dm == tdm) {
-               dm = CDDM_copy(tdm);
+               dm = CDDM_copy(tdm, 0);
        }
 
        return dm;
@@ -231,7 +232,7 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm
        dm->getVertCos(dm, deformedVerts);
        mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0);
 
-       ndm= CDDM_copy(dm);
+       ndm= CDDM_copy(dm, 0);
        CDDM_apply_vert_coords(ndm, deformedVerts);
 
        MEM_freeN(deformedVerts);
@@ -250,26 +251,31 @@ int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mm
 static int get_levels_from_disps(Object *ob)
 {
        Mesh *me = ob->data;
-       MDisps *mdisp;
-       int i, totlvl= 0;
+       MDisps *mdisp, *md;
+       int i, j, totlvl= 0;
 
        mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS);
 
-       for(i = 0; i < me->totface; ++i, ++mdisp) {
-               int S = me->mface[i].v4 ? 4 : 3;
-
-               if(mdisp->totdisp == 0) continue;
-
-               while(1) {
-                       int side = (1 << (totlvl-1)) + 1;
-                       int lvl_totdisp = side*side*S;
-                       if(mdisp->totdisp == lvl_totdisp)
-                               break;
-                       else if(mdisp->totdisp < lvl_totdisp)
-                               --totlvl;
-                       else
-                               ++totlvl;
-
+       for(i = 0; i < me->totpoly; ++i) {
+               int S = me->mpoly[i].totloop;
+               
+               md = mdisp + me->mpoly[i].loopstart;
+               for (j=0; j<me->mpoly[i].totloop; j++, md++) {
+                       if(md->totdisp == 0) continue;
+       
+                       while(1) {
+                               int side = (1 << (totlvl-1)) + 1;
+                               int lvl_totdisp = side*side*S;
+                               if(md->totdisp == lvl_totdisp)
+                                       break;
+                               else if(md->totdisp < lvl_totdisp)
+                                       --totlvl;
+                               else
+                                       ++totlvl;
+       
+                       }
+                       
+                       break;
                }
        }
 
@@ -282,10 +288,10 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o
        Mesh *me = ob->data;
        MDisps *mdisp;
 
-       if(me->edit_mesh)
-               mdisp = CustomData_get_layer(&me->edit_mesh->fdata, CD_MDISPS);
+       if(me->edit_btmesh)
+               mdisp = CustomData_get_layer(&me->edit_btmesh->bm->ldata, CD_MDISPS);
        else
-               mdisp = CustomData_get_layer(&me->fdata, CD_MDISPS);
+               mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
 
        if(mdisp) {
                mmd->totlvl = get_levels_from_disps(ob);
@@ -297,15 +303,12 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o
 
 static void multires_set_tot_mdisps(Mesh *me, int lvl)
 {
-       MDisps *mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
+       MDisps *mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
        int i;
 
        if(mdisps) {
-               for(i = 0; i < me->totface; i++) {
-                       if(mdisps[i].totdisp == 0) {
-                               int nvert = (me->mface[i].v4)? 4: 3;
-                               mdisps[i].totdisp = multires_grid_tot[lvl]*nvert;
-                       }
+               for(i = 0; i < me->totloop; i++, mdisps++) {
+                       mdisps->totdisp = multires_grid_tot[lvl];
                }
        }
 }
@@ -315,9 +318,8 @@ static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
        int i;
 
        /* reallocate displacements to be filled in */
-       for(i = 0; i < me->totface; ++i) {
-               int nvert = (me->mface[i].v4)? 4: 3;
-               int totdisp = multires_grid_tot[lvl]*nvert;
+       for(i = 0; i < me->totloop; ++i) {
+               int totdisp = multires_grid_tot[lvl];
                float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
 
                if(mdisps[i].disps)
@@ -382,44 +384,43 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
        MDisps *mdisps;
 
        multires_set_tot_mdisps(me, mmd->totlvl);
-       CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
-       mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
+       CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
+       mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
 
        multires_force_update(ob);
 
        if(mdisps && levels > 0) {
                if(lvl > 0) {
+                       MLoop *ml = me->mloop;
                        int nsize = multires_side_tot[lvl];
                        int hsize = multires_side_tot[mmd->totlvl];
-                       int i;
+                       int i, j, k=0;
 
-                       for(i = 0; i < me->totface; ++i) {
-                               MDisps *mdisp= &mdisps[i];
-                               float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
-                               int nvert = (me->mface[i].v4)? 4: 3;
-                               int totdisp = multires_grid_tot[lvl]*nvert;
-                               int S;
+                       for(i = 0; i < me->totpoly; ++i) {
+                               for (j=0; j<me->mpoly[i].totloop; j++, k++) {
+                                       MDisps *mdisp= &mdisps[k];
+                                       float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
+                                       int totdisp = multires_grid_tot[lvl];
 
-                               disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
+                                       disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
 
-                               ndisps = disps;
-                               hdisps = mdisp->disps;
+                                       ndisps = disps;
+                                       hdisps = mdisp->disps;
 
-                               for(S = 0; S < nvert; S++) {
                                        multires_copy_grid(ndisps, hdisps, nsize, hsize);
 
                                        ndisps += nsize*nsize;
                                        hdisps += hsize*hsize;
-                               }
 
-                               MEM_freeN(mdisp->disps);
-                               mdisp->disps = disps;
-                               mdisp->totdisp = totdisp;
+                                       MEM_freeN(mdisp->disps);
+                                       mdisp->disps = disps;
+                                       mdisp->totdisp = totdisp;
+                               }
                        }
                }
                else {
-                       CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface);
-                       CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
+                       CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
+                       CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop);
                }
        }
 
@@ -607,9 +608,9 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
 
        multires_force_update(ob);
 
-       mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+       mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
        if(!mdisps)
-               mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
+               mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop);
 
        if(mdisps->disps && !updateblock && totlvl > 1) {
                /* upsample */
@@ -706,14 +707,14 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
        DMGridData **gridData, **subGridData;
-       MFace *mface = me->mface;
-       MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+       MPoly *mpoly = me->mpoly;
+       MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
        int *gridOffset;
-       int i, /*numGrids,*/ gridSize, dGridSize, dSkip;
+       int i, k, /*numGrids,*/ gridSize, dGridSize, dSkip;
 
        if(!mdisps) {
                if(invert)
-                       mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
+                       mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop);
                else
                        return;
        }
@@ -727,23 +728,28 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int
        dGridSize = multires_side_tot[totlvl];
        dSkip = (dGridSize-1)/(gridSize-1);
 
-       #pragma omp parallel for private(i) if(me->totface*gridSize*gridSize*4 >= CCG_OMP_LIMIT)
-       for(i = 0; i < me->totface; ++i) {
-               const int numVerts = mface[i].v4 ? 4 : 3;
-               MDisps *mdisp = &mdisps[i];
-               int S, x, y, gIndex = gridOffset[i];
+       k = 0; /*current loop/mdisp index within the mloop array*/
 
-               /* when adding new faces in edit mode, need to allocate disps */
-               if(!mdisp->disps)
-               #pragma omp critical
-               {
-                       multires_reallocate_mdisps(me, mdisps, totlvl);
-               }
+       #pragma omp parallel for private(i) if(me->totloop*gridSize*gridSize >= CCG_OMP_LIMIT)
 
-               for(S = 0; S < numVerts; ++S, ++gIndex) {
+       for(i = 0; i < me->totpoly; ++i) {
+               const int numVerts = mpoly[i].totloop;
+               int S, x, y, gIndex = gridOffset[i];
+
+               for(S = 0; S < numVerts; ++S, ++gIndex, ++k) {
+                       MDisps *mdisp = &mdisps[k];
                        DMGridData *grid = gridData[gIndex];
                        DMGridData *subgrid = subGridData[gIndex];
-                       float (*dispgrid)[3] = &mdisp->disps[S*dGridSize*dGridSize];
+                       float (*dispgrid)[3] = NULL;
+
+                       /* when adding new faces in edit mode, need to allocate disps */
+                       if(!mdisp->disps)
+                       #pragma omp critical
+                       {
+                               multires_reallocate_mdisps(me, mdisps, totlvl);
+                       }
+
+                       dispgrid = mdisp->disps;
 
                        for(y = 0; y < gridSize; y++) {
                                for(x = 0; x < gridSize; x++) {
@@ -805,9 +811,10 @@ static void multiresModifier_update(DerivedMesh *dm)
        ob = ccgdm->multires.ob;
        me = ccgdm->multires.ob->data;
        mmd = ccgdm->multires.mmd;
+
        multires_set_tot_mdisps(me, mmd->totlvl);
-       CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
-       mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+       CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
+       mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
 
        if(mdisps) {
                int lvl = ccgdm->multires.lvl;
@@ -821,7 +828,7 @@ static void multiresModifier_update(DerivedMesh *dm)
                        int i, j, numGrids, highGridSize, lowGridSize;
 
                        /* create subsurf DM from original mesh at high level */
-                       if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
+                       if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
@@ -875,7 +882,7 @@ static void multiresModifier_update(DerivedMesh *dm)
                else {
                        DerivedMesh *cddm, *subdm;
 
-                       if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
+                       if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
@@ -948,7 +955,9 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
        }
 
        multires_set_tot_mdisps(me, mmd->totlvl);
-       CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
+       CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
+
+       /*run displacement*/
        multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
 
        for(i = 0; i < numGrids; i++)
@@ -1049,15 +1058,33 @@ static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
 
 void multires_load_old_250(Mesh *me)
 {
-       MDisps *mdisps;
-       int a;
+       MDisps *mdisps, *mdisps2;
+       MFace *mf;
+       int i, j, k;
 
        mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
 
        if(mdisps) {
-               for(a=0; a<me->totface; a++)
-                       if(mdisps[a].totdisp)
-                               old_mdisps_convert(&me->mface[a], &mdisps[a]);
+               for(i=0; i<me->totface; i++)
+                       if(mdisps[i].totdisp)
+                               old_mdisps_convert(&me->mface[i], &mdisps[i]);
+               
+               CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
+               mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS);
+
+               k = 0;
+               mf = me->mface;
+               for (i=0; i<me->totface; i++, mf++) {
+                       int nvert = mf->v4 ? 4 : 3;
+                       int totdisp = mdisps[i].totdisp / nvert;
+                       
+                       for (j=0; j < mf->v4 ? 4 : 3; j++, k++) {
+                               mdisps2[k].disps = MEM_callocN(sizeof(float)*3*totdisp, "multires disp in conversion");                 
+                               mdisps2[k].totdisp = totdisp;
+                               memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp*j, totdisp);
+                       }
+
+               }
        }
 }